From 806a8d6193cb2ed04db69a7a820f360d2ba46520 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Sat, 7 Jun 2025 12:17:31 +0300 Subject: [PATCH] [bug] Add missing runtimeConfigManager.js in 6d980409d9e305cf1833cbda830df7c567061de6 --- Common/sources/runtimeConfigManager.js | 133 ++++++++++++++++++ .../engine/providers/internal/ollama.js | 2 +- 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 Common/sources/runtimeConfigManager.js diff --git a/Common/sources/runtimeConfigManager.js b/Common/sources/runtimeConfigManager.js new file mode 100644 index 00000000..abbe669c --- /dev/null +++ b/Common/sources/runtimeConfigManager.js @@ -0,0 +1,133 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2024 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +'use strict'; + +const fs = require('fs/promises'); +const fsWatch = require('fs'); +const path = require('path'); +const config = require('config'); +const NodeCache = require("node-cache"); +const operationContext = require('./operationContext'); +const utils = require('./utils'); + +const cfgRuntimeConfig = config.get('runtimeConfig'); +const configFilePath = cfgRuntimeConfig.filePath; +const configFileName = path.basename(configFilePath); + +// Initialize cache with TTL and check for expired keys every minute +const nodeCache = new NodeCache(cfgRuntimeConfig.cache); +let isInitConfigWatcher = false; + +/** + * Get runtime configuration for the current context + * @param {operationContext} ctx - Operation context + * @returns {Object} Runtime configuration object + */ +async function getConfigFromFile(ctx) { + if (!isInitConfigWatcher) { + isInitConfigWatcher = true; + initConfigWatcher(ctx); + } + try { + const configData = await fs.readFile(configFilePath, 'utf8'); + return JSON.parse(configData); + } catch (err) { + ctx.logger.debug('getConfigFromFile error: %s', err.stack); + return null; + } +} + +/** + * Get cached configuration for the current context + * @param {operationContext} ctx - Operation context + * @returns {Object} Cached configuration object + */ +async function getConfig(ctx) { + let config = nodeCache.get(configFileName); + if (!config) { + config = await getConfigFromFile(ctx); + nodeCache.set(configFileName, config); + } + return config; +} +/** + * Save runtime configuration for the current context + * @param {operationContext} ctx - Operation context + * @param {Object} config - Configuration data to save + * @returns {Object} Saved configuration object + */ +async function saveConfig(ctx, config) { + await fs.mkdir(path.dirname(configFilePath), { recursive: true }); + let newConfig = await getConfig(ctx); + newConfig = utils.deepMergeObjects(newConfig, config); + await fs.writeFile(configFilePath, JSON.stringify(newConfig, null, 2), 'utf8'); + nodeCache.set(configFileName, newConfig); + return newConfig; +} + +/** + * Handle configuration file change events + * @param {string} eventType - Type of file system event (change, rename) + * @param {string} filename - Name of the file that triggered the event + */ +function handleConfigFileChange(eventType, filename) { + try { + if (configFileName === filename) { + nodeCache.del(configFileName); + operationContext.global.logger.info(`handleConfigFileChange configuration ${eventType}: ${configFileName}`); + } + } catch (err) { + operationContext.global.logger.error(`handleConfigFileChange error: ${err.message}`); + } +} + +/** + * Initialize the configuration directory watcher + */ +function initConfigWatcher(ctx) { + try { + const configDir = path.dirname(configFilePath); + const watcher = fsWatch.watch(configDir, handleConfigFileChange); + watcher.on('error', (err) => { + ctx.logger.error(`initConfigWatcher error: ${err.message}`); + }); + ctx.logger.info(`initConfigWatcherWatching for changes in: ${configDir}`); + } catch (watchErr) { + ctx.logger.error(`initConfigWatcher error: ${watchErr.message}`); + } +} + +module.exports = { + getConfig, + saveConfig +}; diff --git a/branding/info/ai/scripts/engine/providers/internal/ollama.js b/branding/info/ai/scripts/engine/providers/internal/ollama.js index 93e44a4f..8480b496 100644 --- a/branding/info/ai/scripts/engine/providers/internal/ollama.js +++ b/branding/info/ai/scripts/engine/providers/internal/ollama.js @@ -3,7 +3,7 @@ class Provider extends AI.Provider { constructor() { - super("Ollama", "http://localhost:11434", "", "v1"); + super("Ollama", "http://127.0.0.1:11434", "", "v1"); } getImageGeneration(message, model) {