mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-04-07 14:04:35 +08:00
Merge pull request 'fix/ai-settings2' (#36) from fix/ai-settings2 into release/v9.0.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/server/pulls/36
This commit is contained in:
@ -15,7 +15,7 @@
|
||||
"version": 3,
|
||||
"timeout": "30s",
|
||||
"allowedCorsOrigins": [
|
||||
"https://onlyoffice.github.io"
|
||||
"https://onlyoffice.github.io", "https://onlyoffice-plugins.github.io"
|
||||
],
|
||||
"pluginDir" : "../branding/info/ai",
|
||||
"cache": {
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
"pluginDir" : "/var/www/onlyoffice/documentserver/server/info/ai"
|
||||
},
|
||||
"runtimeConfig": {
|
||||
"filePath": "/etc/onlyoffice/documentserver/runtime.json"
|
||||
"filePath": "/var/www/onlyoffice/documentserver/../Data/runtime.json"
|
||||
},
|
||||
"storage": {
|
||||
"fs": {
|
||||
|
||||
@ -62,14 +62,16 @@ const nodeCache = new utils.NodeCache(cfgAiApiCache);
|
||||
*/
|
||||
function handleCorsHeaders(req, res, ctx, handleOptions = true) {
|
||||
const requestOrigin = req.headers.origin;
|
||||
|
||||
const tenAiApiAllowedOrigins = ctx.getCfg('aiSettings.allowedCorsOrigins', cfgAiApiAllowedOrigins);
|
||||
|
||||
// If no origin in request or allowed origins list is empty, do nothing
|
||||
if (!requestOrigin || cfgAiApiAllowedOrigins.length === 0) {
|
||||
if (!requestOrigin || tenAiApiAllowedOrigins.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the origin is in our allowed list
|
||||
if (cfgAiApiAllowedOrigins.includes(requestOrigin)) {
|
||||
if (tenAiApiAllowedOrigins.includes(requestOrigin)) {
|
||||
res.setHeader('Access-Control-Allow-Origin', requestOrigin);
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader('Vary', 'Origin'); // Important when using dynamic origin
|
||||
@ -113,7 +115,9 @@ async function proxyRequest(req, res) {
|
||||
|
||||
try {
|
||||
ctx.logger.info('Start proxyRequest');
|
||||
await ctx.initTenantCache();
|
||||
const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser);
|
||||
const tenAiApiTimeout = ctx.getCfg('aiSettings.timeout', cfgAiApiTimeout);
|
||||
const tenAiApi = ctx.getCfg('aiSettings', cfgAiSettings);
|
||||
|
||||
// 1. Handle CORS preflight (OPTIONS) requests if necessary
|
||||
@ -134,8 +138,8 @@ async function proxyRequest(req, res) {
|
||||
|
||||
// Configure timeout options for the request
|
||||
const timeoutOptions = {
|
||||
connectionAndInactivity: cfgAiApiTimeout,
|
||||
wholeCycle: cfgAiApiTimeout
|
||||
connectionAndInactivity: tenAiApiTimeout,
|
||||
wholeCycle: tenAiApiTimeout
|
||||
};
|
||||
|
||||
// Get request size limit if configured
|
||||
|
||||
@ -134,6 +134,7 @@ const AIIntegration = {
|
||||
|
||||
/**
|
||||
* Load the current view in the iframe
|
||||
* @returns {void} No return value
|
||||
*/
|
||||
loadCurrentView() {
|
||||
if (this.isCollapsed) return;
|
||||
@ -144,27 +145,34 @@ const AIIntegration = {
|
||||
|
||||
if (!iframeSettings || !iframeEdit || !iframeList) return;
|
||||
|
||||
// Switch iframe visibility based on current view
|
||||
// Hide all iframes first
|
||||
[iframeSettings, iframeEdit, iframeList].forEach(iframe => {
|
||||
iframe.classList.add('hidden');
|
||||
});
|
||||
|
||||
// Show loading overlay
|
||||
const overlay = document.getElementById('ai-overlay');
|
||||
if (overlay) {
|
||||
overlay.classList.add('loading');
|
||||
}
|
||||
|
||||
// Always reassign src to force reload, then show the appropriate iframe
|
||||
switch (this.currentView) {
|
||||
case 'settings':
|
||||
iframeSettings.src = 'ai/settings.html';
|
||||
iframeSettings.classList.remove('hidden');
|
||||
iframeEdit.classList.add('hidden');
|
||||
iframeList.classList.add('hidden');
|
||||
break;
|
||||
case 'aiModelEdit':
|
||||
iframeSettings.classList.add('hidden');
|
||||
iframeEdit.src = 'ai/aiModelEdit.html';
|
||||
iframeEdit.classList.remove('hidden');
|
||||
iframeList.classList.add('hidden');
|
||||
break;
|
||||
case 'aiModelsList':
|
||||
iframeSettings.classList.add('hidden');
|
||||
iframeEdit.classList.add('hidden');
|
||||
iframeList.src = 'ai/aiModelsList.html';
|
||||
iframeList.classList.remove('hidden');
|
||||
break;
|
||||
default:
|
||||
iframeSettings.src = 'ai/settings.html';
|
||||
iframeSettings.classList.remove('hidden');
|
||||
iframeEdit.classList.add('hidden');
|
||||
iframeList.classList.add('hidden');
|
||||
}
|
||||
|
||||
this.updateControls();
|
||||
@ -205,11 +213,11 @@ const AIIntegration = {
|
||||
|
||||
/**
|
||||
* Handle iframe load event
|
||||
* @returns {void} No return value
|
||||
*/
|
||||
onIframeLoad() {
|
||||
this.loadedIframes++;
|
||||
const overlay = document.getElementById('ai-overlay');
|
||||
if (overlay && this.loadedIframes === this.totalIframes) {
|
||||
if (overlay) {
|
||||
// Hide loading overlay after a short delay
|
||||
setTimeout(() => {
|
||||
overlay.classList.remove('loading');
|
||||
|
||||
@ -40,6 +40,8 @@
|
||||
var urlSettings = 'plugin/settings';
|
||||
var urlModels = 'plugin/models';
|
||||
var urlConfig = 'config';
|
||||
|
||||
var tmpModel = null;
|
||||
|
||||
// Initialize AI functionality when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
@ -152,6 +154,20 @@
|
||||
name: 'onThemeChanged',
|
||||
data: {type:'light', name: 'theme-light'}
|
||||
}, source);
|
||||
const providers = Object.keys(settings.providers).map(function(key) { return settings.providers[key]; });
|
||||
var model = {id: "", name: "", provider: "", capabilities: 0};
|
||||
if (tmpModel) {
|
||||
model = settings.models.find(function(model) { return model.name === tmpModel.name; });
|
||||
tmpModel = null;
|
||||
}
|
||||
var data = {
|
||||
model : model,
|
||||
providers : providers
|
||||
}
|
||||
sendMessageToSettings({
|
||||
name: 'onModelInfo',
|
||||
data: data
|
||||
}, source);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,35 +257,8 @@
|
||||
}
|
||||
break;
|
||||
case 'onOpenEditModal':
|
||||
tmpModel = message.data.model;
|
||||
AIIntegration.navigateToView('aiModelEdit');
|
||||
var aiModelEditWindow = findIframeBySrcPart('aiModelEdit');
|
||||
if(aiModelEditWindow) {
|
||||
const providers = Object.keys(settings.providers).map(function(key) { return settings.providers[key]; });
|
||||
var model = {id: "", name: "", provider: "", capabilities: 0};
|
||||
if (message.data.model) {
|
||||
model = settings.models.find(function(model) { return model.name === message.data.model.name; });
|
||||
}
|
||||
var data = {
|
||||
model : model,
|
||||
providers : providers
|
||||
}
|
||||
sendMessageToSettings({
|
||||
name: 'onProvidersUpdate',
|
||||
data: data
|
||||
}, aiModelEditWindow.contentWindow);
|
||||
|
||||
|
||||
|
||||
sendMessageToSettings({
|
||||
name: 'onModelInfo',
|
||||
data: data
|
||||
}, aiModelEditWindow.contentWindow);
|
||||
|
||||
// sendMessageToSettings({
|
||||
// name: 'onGetModels',
|
||||
// data: {error: 1, models: []}
|
||||
// }, aiModelEditWindow.contentWindow);
|
||||
}
|
||||
break;
|
||||
case 'onDeleteAiModel':
|
||||
for (var i = 0; i < settings.models.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user