From eb429c474e208d04699cd6b5701b753b80f8ae92 Mon Sep 17 00:00:00 2001 From: Silence_Lurker Date: Tue, 20 Jan 2026 10:03:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20callNccsAI=20=E5=87=BD?= =?UTF-8?q?=E6=95=B0=EF=BC=8C=E5=A2=9E=E5=BC=BA=E9=85=8D=E7=BD=AE=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=92=8C=E5=85=BC=E5=AE=B9=E6=80=A7=EF=BC=8C=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=94=B6=E9=9B=86=E9=A2=9D=E5=A4=96=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E8=BF=9B=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/api/NccsApi.js | 87 ++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 24 deletions(-) diff --git a/core/api/NccsApi.js b/core/api/NccsApi.js index 0d75a70..d51f50c 100644 --- a/core/api/NccsApi.js +++ b/core/api/NccsApi.js @@ -60,43 +60,69 @@ export async function callNccsAI(messages, options = {}) { return null; } - const apiSettings = getNccsApiSettings(); - const finalOptions = { - ...apiSettings, - ...options - }; + const settings = getNccsApiSettings(); - if (finalOptions.apiMode !== 'sillytavern_preset') { - if (!finalOptions.apiUrl || !finalOptions.model || !finalOptions.apiKey) { + // 0. 全局开关检查 + if (settings.nccsEnabled === false) { + // 暂不阻断,仅作为配置读取,保持兼容性 + } + + // 1. 基础配置确定 (options 覆盖 settings) + const activeMode = options.apiMode || settings.apiMode; + const activeUrl = options.apiUrl || settings.apiUrl; + const activeKey = options.apiKey || settings.apiKey; + const activeModel = options.model || settings.model; + const activeProfile = options.tavernProfile || settings.tavernProfile; + const activeMaxTokens = options.maxTokens ?? settings.maxTokens; + const activeTemperature = options.temperature ?? settings.temperature; + const activeFakeStream = options.useFakeStream ?? settings.useFakeStream; + + if (activeMode !== 'sillytavern_preset') { + if (!activeUrl || !activeModel || !activeKey) { console.warn("[Amily2-Nccs外交部] API配置不完整,无法调用AI"); toastr.error("API配置不完整,请检查URL、Key和模型配置。", "Nccs-外交部"); return null; } } + // [兼容性修复] 自动收集 options 中的额外参数到 params,防止 ModelCaller 丢失 top_p 等参数 + const standardKeys = [ + 'apiMode', 'apiUrl', 'apiKey', 'model', + 'maxTokens', 'temperature', 'tavernProfile', 'useFakeStream', + 'params' + ]; + const extraParams = {}; + Object.keys(options).forEach(key => { + if (!standardKeys.includes(key)) { + extraParams[key] = options[key]; + } + }); + // 合并显式的 options.params 和 收集到的 extraParams + const finalParams = { ...extraParams, ...(options.params || {}) }; + + // ============================================================ // 尝试路径 A: 新版 Amily2Bus ModelCaller (支持 FakeStream) // ============================================================ if (nccsCtx && nccsCtx.model) { try { - nccsCtx.log('Main', 'info', `[v2 尝试通过 ModelCaller 调用 (${finalOptions.useFakeStream ? 'FakeStream' : 'Standard'})...`); + nccsCtx.log('Main', 'info', `[v2] 尝试通过 ModelCaller 调用 (${activeFakeStream ? 'FakeStream' : 'Standard'})...`); - const Options = nccsCtx.model.Options; - const builder = Options.builder() - .setFakeStream(finalOptions.useFakeStream) - .setMaxTokens(finalOptions.maxTokens) - .setTemperature(finalOptions.temperature) - .setParams(options.params || {}); + const builder = nccsCtx.model.Options.builder() + .setFakeStream(activeFakeStream) + .setMaxTokens(activeMaxTokens) + .setTemperature(activeTemperature) + .setParams(finalParams); - if (finalOptions.apiMode === 'sillytavern_preset') { + if (activeMode === 'sillytavern_preset') { builder.setMode('preset') - .setPresetId(finalOptions.tavernProfile) - .setModel(finalOptions.model); + .setPresetId(activeProfile) + .setModel(activeModel); } else { builder.setMode('direct') - .setApiUrl(finalOptions.apiUrl) - .setApiKey(finalOptions.apiKey) - .setModel(finalOptions.model); + .setApiUrl(activeUrl) + .setApiKey(activeKey) + .setModel(activeModel); } // 发起请求 @@ -123,21 +149,34 @@ export async function callNccsAI(messages, options = {}) { // ============================================================ // 尝试路径 B: 旧版 Legacy 方法 (Fallback) // ============================================================ + // 构建 Legacy 兼容对象 + const legacyOptions = { + apiMode: activeMode, + apiUrl: activeUrl, + apiKey: activeKey, + model: activeModel, + tavernProfile: activeProfile, + maxTokens: activeMaxTokens, + temperature: activeTemperature, + useFakeStream: activeFakeStream, + ...finalParams // 将额外参数直接展平回 legacyOptions 根目录 + }; + try { console.groupCollapsed(`[Amily2-Nccs] 降级使用 Legacy API 调用`); console.log("Fallback Mode Active"); let responseContent; - switch (finalOptions.apiMode) { + switch (activeMode) { case 'openai_test': - responseContent = await callNccsOpenAITest(messages, finalOptions); + responseContent = await callNccsOpenAITest(messages, legacyOptions); break; case 'sillytavern_preset': - responseContent = await callNccsSillyTavernPreset(messages, finalOptions); + responseContent = await callNccsSillyTavernPreset(messages, legacyOptions); break; default: - console.error(`未支持的 API 模式: ${finalOptions.apiMode}`); + console.error(`未支持的 API 模式: ${activeMode}`); return null; }