diff --git a/Common/config/default.json b/Common/config/default.json index 57be3751..41df46fb 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -17,12 +17,7 @@ "allowedCorsOrigins": [ "https://onlyoffice.github.io", "https://onlyoffice-plugins.github.io" ], - "pluginDir" : "../branding/info/ai", - "cache": { - "enable": true, - "ttl": 300, - "cachesize": 1000 - } + "pluginDir" : "../branding/info/ai" }, "log": { "filePath": "", diff --git a/DocService/sources/ai/aiEngineWrapper.js b/DocService/sources/ai/aiEngineWrapper.js index e910465c..c09341b3 100644 --- a/DocService/sources/ai/aiEngineWrapper.js +++ b/DocService/sources/ai/aiEngineWrapper.js @@ -42,10 +42,10 @@ const vm = require('vm'); // Configuration constants const cfgAiApiTimeout = config.get('aiSettings.timeout'); -const cfgAiApiModels = config.get('aiSettings.models'); -const cfgAiApiActions = config.get('aiSettings.actions'); const cfgAiPluginDir = config.get('aiSettings.pluginDir'); +const engineScriptsDir = path.join(cfgAiPluginDir, 'scripts/engine'); + function setCtx(ctx) { sandbox.ctx = ctx; console.log = ctx.logger.debug.bind(ctx.logger);//todo make default in logger @@ -55,14 +55,29 @@ function setCtx(ctx) { // Set up the environment for the client-side engine.js const sandbox = { ctx: null, - window: {AI: {}}, + window: { + AI: { + TmpProviderForModels: null, + Providers: {}, + InternalProviders: [], + _getHeaders: function() {return {};}, + serializeProviders: function() {return [];}, + ActionsGetSorted: function() {return [];}, + getModels: function() {return [];}, + onLoadInternalProviders: function() {}, + Storage: { + serializeModels: function() {return [];} + }, + CapabilitiesUI: {} + } + }, Asc: { plugin: { - tr: function(text) { - // Just return the original text in the stub - return text; + tr: function(text) { + // Just return the original text in the stub + return text; + } } - } }, /** @@ -89,7 +104,7 @@ const sandbox = { options.headers || {}, options.body || null, timeoutOptions, - 10 * 1024 * 1024, + null, false ) .then(async (result) => { @@ -110,7 +125,7 @@ const sandbox = { }; // Initialize minimal AI object with required functionality -const AI = sandbox.AI = sandbox.window.AI; +sandbox.AI = sandbox.window.AI; setCtx(operationContext.global); /** @@ -118,8 +133,15 @@ setCtx(operationContext.global); */ function loadInternalProviders() { // Add simple provider loading logic - const enginePath = path.join(cfgAiPluginDir, 'scripts/engine/providers/internal'); + const enginePath = path.join(engineScriptsDir, 'providers/internal'); + // Check if the providers directory exists before trying to read it + if (!fs.existsSync(enginePath)) { + sandbox.ctx.logger.warn('Internal providers directory not found:', enginePath); + sandbox.AI.onLoadInternalProviders(); + return; + } + try { // Read providers directory const files = fs.readdirSync(enginePath); @@ -150,27 +172,28 @@ function loadInternalProviders() { sandbox.ctx.logger.error('Error loading internal providers:', error); } } -/** - * Simple loadInternalProviders implementation - */ -function fillConfigObjects() { - AI.Models = cfgAiApiModels; - for(let id in cfgAiApiActions) { - let action = cfgAiApiActions[id]; - if (action.model && AI.Actions[id]) { - AI.Actions[id].model = action.model; - } - } -} // Load engine.js let engineCode = ''; -engineCode += fs.readFileSync(path.join(cfgAiPluginDir, 'scripts/engine/storage.js'), 'utf8'); -engineCode += fs.readFileSync(path.join(cfgAiPluginDir, 'scripts/engine/local_storage.js'), 'utf8'); -engineCode += fs.readFileSync(path.join(cfgAiPluginDir, 'scripts/engine/providers/base.js'), 'utf8'); -engineCode += fs.readFileSync(path.join(cfgAiPluginDir, 'scripts/engine/providers/provider.js'), 'utf8'); -engineCode += fs.readFileSync(path.join(cfgAiPluginDir, 'scripts/engine/engine.js'), 'utf8'); -vm.runInNewContext(engineCode, sandbox); + +try { + engineCode += fs.readFileSync(path.join(engineScriptsDir, 'storage.js'), 'utf8'); + engineCode += fs.readFileSync(path.join(engineScriptsDir, 'local_storage.js'), 'utf8'); + engineCode += fs.readFileSync(path.join(engineScriptsDir, 'providers/base.js'), 'utf8'); + engineCode += fs.readFileSync(path.join(engineScriptsDir, 'providers/provider.js'), 'utf8'); + engineCode += fs.readFileSync(path.join(engineScriptsDir, 'engine.js'), 'utf8'); +} catch (error) { + sandbox.ctx.logger.warn('Error reading engine script files:', error); +} + +// Run engine code if available +if (engineCode) { + try { + vm.runInNewContext(engineCode, sandbox); + } catch (error) { + sandbox.ctx.logger.error('Error executing engine scripts:', error); + } +} //start from engine/register.js (function() { @@ -240,7 +263,6 @@ vm.runInNewContext(engineCode, sandbox); sandbox.AI.loadInternalProviders = loadInternalProviders; loadInternalProviders(); -fillConfigObjects(); exports.setCtx = setCtx; exports.AI = sandbox.AI; diff --git a/DocService/sources/ai/aiProxyHandler.js b/DocService/sources/ai/aiProxyHandler.js index 9bda5dd8..84cde9aa 100644 --- a/DocService/sources/ai/aiProxyHandler.js +++ b/DocService/sources/ai/aiProxyHandler.js @@ -33,7 +33,6 @@ 'use strict'; const { pipeline } = require('stream/promises'); -const { buffer } = require('node:stream/consumers'); const config = require('config'); const utils = require('./../../../Common/sources/utils'); const operationContext = require('./../../../Common/sources/operationContext'); @@ -45,12 +44,10 @@ const aiEngine = require('./aiEngineWrapper'); const cfgAiApiAllowedOrigins = config.get('aiSettings.allowedCorsOrigins'); const cfgAiApiTimeout = config.get('aiSettings.timeout'); -const cfgAiApiCache = config.get('aiSettings.cache'); const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.browser'); const cfgAiSettings = config.get('aiSettings'); const AI = aiEngine.AI; -const nodeCache = new utils.NodeCache(cfgAiApiCache); /** * Helper function to set CORS headers if the request origin is allowed * @@ -103,7 +100,7 @@ function handleCorsHeaders(req, res, ctx, handleOptions = true) { /** * Makes an HTTP request to an AI API endpoint using the provided request and response objects - * + * * @param {object} req - Express request object * @param {object} res - Express response object * @returns {Promise} - Promise resolving when the request is complete @@ -142,10 +139,6 @@ async function proxyRequest(req, res) { wholeCycle: tenAiApiTimeout }; - // Get request size limit if configured - const sizeLimit = 10 * 1024 * 1024; // Default to 10MB - - let providerHeaders; // Determine which API key to use based on the target URL if (body.target) { @@ -171,21 +164,13 @@ async function proxyRequest(req, res) { headers, body: body.data, timeout: timeoutOptions, - limit: sizeLimit, + limit: null, filterPrivate: false }; - // Create a safe copy for logging without sensitive info - const safeLogParams = { ...requestParams }; - // if (safeLogParams.headers) { - // safeLogParams.headers = { ...safeLogParams.headers }; - // if (safeLogParams.headers.Authorization) { - // safeLogParams.headers.Authorization = '[REDACTED]'; - // } - // } // Log the sanitized request parameters - ctx.logger.debug(`Proxying request: %j`, safeLogParams); + ctx.logger.debug(`Proxying request: %j`, requestParams); // Use utils.httpRequest to make the request const result = await utils.httpRequest( @@ -221,9 +206,9 @@ async function proxyRequest(req, res) { } }); } - } finally { - ctx.logger.info('End proxyRequest'); - } + } finally { + ctx.logger.info('End proxyRequest'); + } } /** @@ -243,7 +228,7 @@ async function processProvider(ctx, provider) { let engineModelsUI = []; try { // Call getModels from engine.js - if (provider.key) { + if (provider.key && AI.Providers[provider.name]) { AI.Providers[provider.name].key = provider.key; // aiEngine.setCtx(ctx); // await AI.getModels(provider); @@ -275,11 +260,6 @@ async function processProvider(ctx, provider) { async function getPluginSettings(ctx) { const logger = ctx.logger; logger.info('Starting getPluginSettings'); - let res = nodeCache.get(ctx.tenant); - if (res) { - ctx.logger.debug('getPluginSettings from cache'); - return res; - } const result = { version: 3, actions: {}, @@ -337,7 +317,6 @@ async function getPluginSettings(ctx) { } const tenVersion = ctx.getCfg('aiSettings.version', cfgAiSettings.version); result.version = tenVersion; - // nodeCache.set(ctx.tenant, result); } catch (error) { logger.error('Error retrieving AI models from config:', error); } @@ -392,9 +371,9 @@ async function requestModels(req, res) { if (AI.Providers[body.name]) { AI.Providers[body.name].key = body.key; AI.Providers[body.name].url = body.url; - } + } let getRes = await AI.getModels(body); - getRes.modelsApi = AI.TmpProviderForModels?.models; + getRes.modelsApi = AI.TmpProviderForModels?.models; res.json(getRes); } catch (error) { ctx.logger.error('getModels error: %s', error.stack);