mirror of
https://github.com/Wx-2025/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 03:25:51 +00:00
Compare commits
2 Commits
0c5ac2c70b
...
bddda1802f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bddda1802f | ||
|
|
1fdbe62142 |
@@ -1,6 +1,7 @@
|
||||
import { extension_settings } from '/scripts/extensions.js';
|
||||
import { extensionName } from '../../utils/settings.js';
|
||||
import { saveSettingsDebounced } from '/script.js';
|
||||
import { configManager } from '../../utils/config/ConfigManager.js';
|
||||
import { world_names } from '/scripts/world-info.js';
|
||||
import { state } from './cwb_state.js';
|
||||
import { cwbCompleteDefaultSettings } from './cwb_config.js';
|
||||
@@ -38,7 +39,7 @@ function saveApiConfig() {
|
||||
const settings = getSettings();
|
||||
settings.cwb_api_mode = $panel.find('#cwb-api-mode').val();
|
||||
settings.cwb_api_url = $panel.find('#cwb-api-url').val().trim();
|
||||
settings.cwb_api_key = $panel.find('#cwb-api-key').val();
|
||||
configManager.set('cwb_api_key', $panel.find('#cwb-api-key').val());
|
||||
settings.cwb_api_model = $panel.find('#cwb-api-model').val();
|
||||
settings.cwb_tavern_profile = $panel.find('#cwb-tavern-profile').val();
|
||||
|
||||
@@ -63,7 +64,7 @@ function saveApiConfig() {
|
||||
function clearApiConfig() {
|
||||
const settings = getSettings();
|
||||
settings.cwb_api_url = '';
|
||||
settings.cwb_api_key = '';
|
||||
configManager.set('cwb_api_key', '');
|
||||
settings.cwb_api_model = '';
|
||||
saveSettingsDebounced();
|
||||
state.customApiConfig.url = '';
|
||||
@@ -283,13 +284,11 @@ export function bindSettingsEvents($settingsPanel) {
|
||||
$panel.on('input', '#cwb-api-key', function() {
|
||||
const apiKey = $(this).val();
|
||||
|
||||
// 同时更新设置和状态
|
||||
getSettings().cwb_api_key = apiKey;
|
||||
// 同时更新设置和状态(API Key 经 configManager 写入 localStorage)
|
||||
configManager.set('cwb_api_key', apiKey);
|
||||
state.customApiConfig.apiKey = apiKey;
|
||||
|
||||
saveSettingsDebounced();
|
||||
|
||||
console.log('[CWB] API Key已更新 - 设置长度:', getSettings().cwb_api_key?.length || 0, ', 状态长度:', state.customApiConfig.apiKey?.length || 0);
|
||||
|
||||
console.log('[CWB] API Key已更新 - 状态长度:', state.customApiConfig.apiKey?.length || 0);
|
||||
});
|
||||
|
||||
$panel.on('change', '#cwb-api-model', function() {
|
||||
@@ -489,7 +488,7 @@ function updateUiWithSettings() {
|
||||
}
|
||||
|
||||
$panel.find('#cwb-api-url').val(settings.cwb_api_url);
|
||||
$panel.find('#cwb-api-key').val(settings.cwb_api_key);
|
||||
$panel.find('#cwb-api-key').val(configManager.get('cwb_api_key') || '');
|
||||
$panel.find('#cwb-tavern-profile').val(settings.cwb_tavern_profile);
|
||||
|
||||
const $modelSelect = $panel.find('#cwb-api-model');
|
||||
@@ -574,7 +573,7 @@ export function loadSettings() {
|
||||
state.isIncrementalUpdateEnabled = finalSettings.cwb_incremental_update_enabled;
|
||||
|
||||
state.customApiConfig.url = finalSettings.cwb_api_url || '';
|
||||
state.customApiConfig.apiKey = finalSettings.cwb_api_key || '';
|
||||
state.customApiConfig.apiKey = configManager.get('cwb_api_key') || '';
|
||||
state.customApiConfig.model = finalSettings.cwb_api_model || '';
|
||||
|
||||
state.currentBreakArmorPrompt = finalSettings.cwb_break_armor_prompt;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { extension_settings } from '/scripts/extensions.js';
|
||||
import { saveSettingsDebounced } from '/script.js';
|
||||
import { amilyHelper } from '../../core/tavern-helper/main.js';
|
||||
import { configManager } from '../../utils/config/ConfigManager.js';
|
||||
|
||||
const { jQuery: $, SillyTavern } = window;
|
||||
|
||||
@@ -675,8 +676,7 @@
|
||||
|
||||
$('#cwb-api-key').off('input').on('input', function() {
|
||||
const value = $(this).val();
|
||||
extension_settings[extensionName].cwb_api_key = value;
|
||||
saveSettingsDebounced();
|
||||
configManager.set('cwb_api_key', value);
|
||||
});
|
||||
|
||||
$('#cwb-model').off('input').on('input', function() {
|
||||
|
||||
@@ -159,6 +159,13 @@
|
||||
<label for="amily2_pf_temperature">温度(Temperature)</label>
|
||||
<input id="amily2_pf_temperature" type="number" class="text_pole" min="0" max="2" step="0.1" value="1.0" />
|
||||
</div>
|
||||
<div class="amily2_settings_block" style="flex-direction:row; align-items:center; gap:8px;">
|
||||
<input id="amily2_pf_fake_stream" type="checkbox" />
|
||||
<label for="amily2_pf_fake_stream">
|
||||
启用假流式(防 CF 超时)
|
||||
<small class="notes" style="display:block; font-weight:normal;">以 stream:true 接收 SSE 后拼接,适用于经 CloudFlare 免费代理的接口</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
35
core/api.js
35
core/api.js
@@ -1,6 +1,7 @@
|
||||
import { extension_settings, getContext } from "/scripts/extensions.js";
|
||||
import { characters } from "/script.js";
|
||||
import { getSlotProfile } from './api/api-resolver.js';
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
import { world_names } from "/scripts/world-info.js";
|
||||
import { extensionName } from "../utils/settings.js";
|
||||
import { extractContentByTag, replaceContentByTag, extractFullTagBlock } from '../utils/tagProcessor.js';
|
||||
@@ -449,12 +450,44 @@ export async function getApiSettings(slot = 'main') {
|
||||
// 温度 / MaxTokens 读面板值(profile-sync 保留了这些输入框)
|
||||
maxTokens: s.maxTokens ?? profile.maxTokens ?? 65500,
|
||||
temperature: s.temperature ?? profile.temperature ?? 1.0,
|
||||
fakeStream: profile.fakeStream ?? false,
|
||||
tavernProfile: '',
|
||||
};
|
||||
}
|
||||
|
||||
// 降级:读旧 DOM 面板配置
|
||||
// 降级:按槽位读取各自的独立配置
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
// plotOpt 槽有独立 API 面板(剧情优化),优先读其专属设置
|
||||
if (slot === 'plotOpt') {
|
||||
const apiMode = settings.plotOpt_apiMode || 'openai_test';
|
||||
if (apiMode === 'sillytavern_preset') {
|
||||
const context = getContext();
|
||||
const profileId = settings.plotOpt_tavernProfile || '';
|
||||
const stProfile = context.extensionSettings?.connectionManager?.profiles?.find(p => p.id === profileId);
|
||||
return {
|
||||
apiProvider: 'sillytavern_preset',
|
||||
apiUrl: '',
|
||||
apiKey: '',
|
||||
model: stProfile?.openai_model || 'Preset Model',
|
||||
maxTokens: settings.plotOpt_max_tokens ?? 65500,
|
||||
temperature: settings.plotOpt_temperature ?? 1.0,
|
||||
tavernProfile: profileId,
|
||||
};
|
||||
}
|
||||
return {
|
||||
apiProvider: apiMode,
|
||||
apiUrl: settings.plotOpt_apiUrl?.trim() || '',
|
||||
apiKey: configManager.get('plotOpt_apiKey') || '',
|
||||
model: document.getElementById('amily2_opt_model')?.value?.trim()
|
||||
|| settings.plotOpt_model || '',
|
||||
maxTokens: settings.plotOpt_max_tokens ?? 65500,
|
||||
temperature: settings.plotOpt_temperature ?? 1.0,
|
||||
tavernProfile: '',
|
||||
};
|
||||
}
|
||||
|
||||
// main 槽(及其余未明确处理的槽):读主面板 DOM 配置
|
||||
const apiProvider = document.getElementById('amily2_api_provider')?.value || 'openai';
|
||||
|
||||
let model;
|
||||
|
||||
@@ -46,7 +46,7 @@ import { renderTables } from '../../ui/table-bindings.js';
|
||||
async function processMessageUpdate(messageId) {
|
||||
TableManager.clearHighlights();
|
||||
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
if (!tableSystemEnabled) {
|
||||
log('【表格服务】表格系统总开关已关闭,跳过所有表格处理。', 'info');
|
||||
|
||||
@@ -22,7 +22,7 @@ const MAX_RETRIES = 2;
|
||||
|
||||
|
||||
async function getWorldBookContext() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
if (!settings.table_worldbook_enabled) {
|
||||
return '';
|
||||
}
|
||||
@@ -114,7 +114,7 @@ function updateButtonState(state, batchNum = 0, attemptNum = 0) {
|
||||
|
||||
async function callTableModel(messages) {
|
||||
try {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
if (settings.nccsEnabled) {
|
||||
log('使用 Nccs API 进行表格填充...', 'info');
|
||||
@@ -141,7 +141,7 @@ async function callTableModel(messages) {
|
||||
function getRawMessagesForSummary(startFloor, endFloor) {
|
||||
const context = getContext();
|
||||
const chat = context.chat;
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
const historySlice = chat.slice(startFloor - 1, endFloor);
|
||||
if (historySlice.length === 0) return null;
|
||||
@@ -319,7 +319,7 @@ export function startBatchFilling() {
|
||||
const button = fillButton();
|
||||
if (!button) return;
|
||||
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
if (!tableSystemEnabled) {
|
||||
log('表格系统总开关已关闭,跳过批量填表。', 'info');
|
||||
@@ -387,7 +387,7 @@ export function startBatchFilling() {
|
||||
|
||||
|
||||
export async function startFloorRangeFilling(startFloor, endFloor) {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
if (!tableSystemEnabled) {
|
||||
log('表格系统总开关已关闭,跳过楼层填表。', 'info');
|
||||
|
||||
@@ -1264,7 +1264,7 @@ export function getAiFlowTemplateForInjection() {
|
||||
}
|
||||
|
||||
export async function updateTableFromText(textContent, options = {}) {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
if (settings.table_system_enabled === false) {
|
||||
log('表格系统总开关已关闭,跳过 <Amily2Edit> 标签处理。', 'info');
|
||||
return;
|
||||
@@ -1575,7 +1575,7 @@ export async function rollbackState() {
|
||||
|
||||
export async function rollbackAndRefill() {
|
||||
// 检查表格系统总开关
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
if (settings.table_system_enabled === false) {
|
||||
log('表格系统总开关已关闭,跳过回退填表。', 'info');
|
||||
toastr.info('表格系统总开关已关闭,无法执行回退填表。');
|
||||
|
||||
@@ -4,11 +4,11 @@ import { renderTables } from '../../ui/table-bindings.js';
|
||||
import { extensionName } from "../../utils/settings.js";
|
||||
import { convertTablesToCsvString, convertSelectedTablesToCsvString, saveStateToMessage, getMemoryState, updateTableFromText, getBatchFillerRuleTemplate, getBatchFillerFlowTemplate } from './manager.js';
|
||||
import { getPresetPrompts, getMixedOrder } from '../../PresetSettings/index.js';
|
||||
import { callAI, generateRandomSeed, getApiSettings } from '../api.js';
|
||||
import { callAI, generateRandomSeed } from '../api.js';
|
||||
import { callNccsAI } from '../api/NccsApi.js';
|
||||
|
||||
export async function reorganizeTableContent(selectedTableIndices) {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
if (settings.table_system_enabled === false) {
|
||||
toastr.warning('表格系统总开关已关闭。');
|
||||
@@ -20,13 +20,6 @@ export async function reorganizeTableContent(selectedTableIndices) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvedApi = await getApiSettings('main');
|
||||
const { apiUrl, apiKey, model, temperature, maxTokens, forceProxyForCustomApi } = resolvedApi ?? settings;
|
||||
if (!apiUrl || !model) {
|
||||
toastr.error("主API的URL或模型未配置,重新整理功能无法启动。", "Amily2-重新整理");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
toastr.info('正在重新整理表格内容...', 'Amily2-重新整理');
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import { updateOrInsertTableInChat } from '../../ui/message-table-renderer.js';
|
||||
import { extensionName } from "../../utils/settings.js";
|
||||
import { updateTableFromText, getBatchFillerRuleTemplate, getBatchFillerFlowTemplate, convertTablesToCsvString, saveStateToMessage, getMemoryState, clearHighlights } from './manager.js';
|
||||
import { getPresetPrompts, getMixedOrder } from '../../PresetSettings/index.js';
|
||||
import { callAI, generateRandomSeed, getApiSettings } from '../api.js';
|
||||
import { callAI, generateRandomSeed } from '../api.js';
|
||||
import { callNccsAI } from '../api/NccsApi.js';
|
||||
import { extractBlocksByTags, applyExclusionRules } from '../utils/rag-tag-extractor.js';
|
||||
import { safeLorebookEntries } from '../tavernhelper-compatibility.js';
|
||||
|
||||
|
||||
async function getWorldBookContext() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
if (!settings.table_worldbook_enabled) {
|
||||
return '';
|
||||
@@ -67,7 +67,7 @@ async function getWorldBookContext() {
|
||||
export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
clearHighlights();
|
||||
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
// 总开关关闭时,分步填表同样禁用
|
||||
if (settings.table_system_enabled === false) {
|
||||
@@ -92,15 +92,6 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvedApi = await getApiSettings('main');
|
||||
const { apiUrl, apiKey, model, temperature, maxTokens, forceProxyForCustomApi } = resolvedApi ?? settings;
|
||||
if (!apiUrl || !model) {
|
||||
if (!window.secondaryApiUrlWarned) {
|
||||
toastr.error("主API的URL或模型未配置,分步填表功能无法启动。", "Amily2-分步填表");
|
||||
window.secondaryApiUrlWarned = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const bufferSize = parseInt(settings.secondary_filler_buffer || 0, 10);
|
||||
|
||||
@@ -131,6 +131,7 @@ export {
|
||||
};
|
||||
|
||||
export const tableSystemDefaultSettings = {
|
||||
table_system_enabled: true,
|
||||
table_injection_enabled: false,
|
||||
|
||||
injection: {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { extension_settings, getContext } from "/scripts/extensions.js";
|
||||
import { saveSettingsDebounced, eventSource, event_types } from "/script.js";
|
||||
import { extensionName } from "../utils/settings.js";
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
import { SENSITIVE_KEYS } from '../utils/config/sensitive-keys.js';
|
||||
import { safeLorebooks, safeLorebookEntries, safeUpdateLorebookEntries } from '../core/tavernhelper-compatibility.js';
|
||||
import { testSybdApiConnection, fetchSybdModels } from '../core/api/SybdApi.js';
|
||||
import { handleFileUpload, processNovel } from './index.js';
|
||||
@@ -29,18 +31,21 @@ function loadSettingsToUI() {
|
||||
const inputs = container.querySelectorAll('[data-setting-key]');
|
||||
inputs.forEach(target => {
|
||||
const key = target.dataset.settingKey;
|
||||
const value = settings[key];
|
||||
// 敏感字段从 configManager(localStorage)读取,其余从 extension_settings 读取
|
||||
const value = SENSITIVE_KEYS.has(key) ? configManager.get(key) : settings[key];
|
||||
|
||||
if (value === undefined) {
|
||||
let defaultValue;
|
||||
if (target.type === 'checkbox') {
|
||||
defaultValue = target.checked;
|
||||
} else if (target.type === 'range') {
|
||||
defaultValue = target.dataset.type === 'float' ? parseFloat(target.value) : parseInt(target.value, 10);
|
||||
} else {
|
||||
defaultValue = target.value;
|
||||
if (value === undefined || value === null || value === '') {
|
||||
if (!SENSITIVE_KEYS.has(key)) {
|
||||
let defaultValue;
|
||||
if (target.type === 'checkbox') {
|
||||
defaultValue = target.checked;
|
||||
} else if (target.type === 'range') {
|
||||
defaultValue = target.dataset.type === 'float' ? parseFloat(target.value) : parseInt(target.value, 10);
|
||||
} else {
|
||||
defaultValue = target.value;
|
||||
}
|
||||
updateAndSaveSetting(key, defaultValue);
|
||||
}
|
||||
updateAndSaveSetting(key, defaultValue);
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -90,8 +95,13 @@ function bindAutoSaveEvents() {
|
||||
case 'float': value = parseFloat(value); break;
|
||||
case 'boolean': value = (typeof value === 'boolean') ? value : (value === 'true'); break;
|
||||
}
|
||||
|
||||
updateAndSaveSetting(key, value);
|
||||
|
||||
// 敏感字段(API Key)经 configManager 写入 localStorage
|
||||
if (SENSITIVE_KEYS.has(key)) {
|
||||
configManager.set(key, value);
|
||||
} else {
|
||||
updateAndSaveSetting(key, value);
|
||||
}
|
||||
|
||||
if (key === 'sybdApiMode') {
|
||||
updateConfigVisibility(value);
|
||||
|
||||
9
index.js
9
index.js
@@ -568,11 +568,12 @@ async function onPlotGenerationAfterCommands(type, params, dryRun) {
|
||||
if (globalSettings?.plotOpt_enabled === false) return false;
|
||||
|
||||
const isJqyhEnabled = globalSettings?.jqyhEnabled === true;
|
||||
const hasMainProfile = !!apiProfileManager.getAssignment('main') || !!apiProfileManager.getAssignment('plotOpt');
|
||||
const isMainApiConfigured = hasMainProfile || !!globalSettings?.apiUrl || !!globalSettings?.tavernProfile;
|
||||
const hasProfile = !!apiProfileManager.getAssignment('main') || !!apiProfileManager.getAssignment('plotOpt');
|
||||
const hasLegacyConfig = !!globalSettings?.apiUrl || !!globalSettings?.tavernProfile
|
||||
|| !!globalSettings?.plotOpt_apiUrl || !!globalSettings?.plotOpt_tavernProfile;
|
||||
|
||||
if (!isJqyhEnabled && !isMainApiConfigured) {
|
||||
console.log("[Amily2-剧情优化] 优化已启用,但Jqyh API已禁用且主API未配置(无 Profile 分配亦无旧设置)。");
|
||||
if (!isJqyhEnabled && !hasProfile && !hasLegacyConfig) {
|
||||
console.log("[Amily2-剧情优化] 优化已启用,但未配置任何可用的 API(无 Profile 分配亦无独立配置)。");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Amily2号聊天优化助手",
|
||||
"display_name": "Amily2号助手",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"author": "Wx-2025",
|
||||
"description": "一个拥有独立UI的智能引擎,正文优化、自动总结、记忆表格、rag向量、隐藏楼层、剧情推进等多功能整合。",
|
||||
"minSillyTavernVersion": "1.10.0",
|
||||
|
||||
@@ -343,6 +343,7 @@ async function openModal($c, id) {
|
||||
if (p.type === 'chat') {
|
||||
$c.find('#amily2_pf_max_tokens').val(p.maxTokens);
|
||||
$c.find('#amily2_pf_temperature').val(p.temperature);
|
||||
$c.find('#amily2_pf_fake_stream').prop('checked', p.fakeStream ?? false);
|
||||
} else if (p.type === 'embedding') {
|
||||
$c.find('#amily2_pf_dimensions').val(p.dimensions ?? '');
|
||||
$c.find('#amily2_pf_encoding_format').val(p.encodingFormat);
|
||||
@@ -362,6 +363,7 @@ async function openModal($c, id) {
|
||||
_handleProviderChange($c, 'openai');
|
||||
$c.find('#amily2_pf_max_tokens').val(65500);
|
||||
$c.find('#amily2_pf_temperature').val(1.0);
|
||||
$c.find('#amily2_pf_fake_stream').prop('checked', false);
|
||||
$c.find('#amily2_pf_dimensions').val('');
|
||||
$c.find('#amily2_pf_encoding_format').val('float');
|
||||
$c.find('#amily2_pf_top_n').val(5);
|
||||
@@ -401,6 +403,7 @@ async function saveProfile($c) {
|
||||
if (type === 'chat') {
|
||||
data.maxTokens = parseInt($c.find('#amily2_pf_max_tokens').val(), 10) || 65500;
|
||||
data.temperature = parseFloat($c.find('#amily2_pf_temperature').val()) || 1.0;
|
||||
data.fakeStream = $c.find('#amily2_pf_fake_stream').prop('checked');
|
||||
} else if (type === 'embedding') {
|
||||
const dim = $c.find('#amily2_pf_dimensions').val();
|
||||
data.dimensions = dim ? parseInt(dim, 10) : null;
|
||||
@@ -582,8 +585,39 @@ async function _testConnection($c) {
|
||||
|
||||
if (modelsResp.ok) {
|
||||
const rawData = await modelsResp.json();
|
||||
const list = Array.isArray(rawData) ? rawData : (rawData.data ?? rawData.models ?? []);
|
||||
const rawList = Array.isArray(rawData) ? rawData : (rawData.data ?? rawData.models ?? []);
|
||||
const list = Array.isArray(rawList) ? rawList : [];
|
||||
const count = list.length;
|
||||
|
||||
// chat 类型额外发一次假补全,验证 completion 端点也能正常鉴权
|
||||
const type = $c.find('#amily2_pf_type').val();
|
||||
const $sel = $c.find('#amily2_pf_model_select');
|
||||
const model = ($sel.is(':visible') ? $sel.val() : $c.find('#amily2_pf_model').val()).trim();
|
||||
|
||||
if (type === 'chat' && model) {
|
||||
$result.text('模型列表 ✓,正在验证补全端点…').css('color', 'var(--SmartThemeQuoteColor)');
|
||||
const genResp = await fetch('/api/backends/chat-completions/generate', {
|
||||
method: 'POST',
|
||||
headers: { ...getRequestHeaders(), 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
reverse_proxy: apiUrl,
|
||||
proxy_password: apiKey,
|
||||
chat_completion_source: 'openai',
|
||||
model,
|
||||
messages: [{ role: 'user', content: 'Hi' }],
|
||||
max_tokens: 1,
|
||||
stream: false,
|
||||
}),
|
||||
});
|
||||
if (!genResp.ok) {
|
||||
const genErr = await genResp.json().catch(() => ({}));
|
||||
const genMsg = genErr?.error?.message || `补全端点返回 HTTP ${genResp.status}`;
|
||||
$result.text(`模型列表 ✓,补全失败:${genMsg}`).css('color', 'var(--warning-color)');
|
||||
toastr.warning(`补全端点测试失败:${genMsg}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$result.text(`连接成功${count ? `,${count} 个可用模型` : ''}`).css('color', 'var(--green)');
|
||||
toastr.success('连接测试通过!');
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { defaultSettings, extensionName, saveSettings, extensionBasePath } from
|
||||
import { pluginAuthStatus, activatePluginAuthorization, getPasswordForDate } from "../utils/auth.js";
|
||||
import { fetchModels, testApiConnection } from "../core/api.js";
|
||||
import { safeLorebooks, safeCharLorebooks, safeLorebookEntries } from "../core/tavernhelper-compatibility.js";
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
|
||||
import { setAvailableModels, populateModelDropdown, getLatestUpdateInfo } from "./state.js";
|
||||
import { fixCommand, testReplyChecker } from "../core/commands.js";
|
||||
@@ -1038,7 +1039,12 @@ export function bindModalEvents() {
|
||||
.on("change.amily2.text", "#amily2_api_url, #amily2_api_key, #amily2_optimization_target_tag", function () {
|
||||
if (!pluginAuthStatus.authorized) return;
|
||||
const key = snakeToCamel(this.id.replace("amily2_", ""));
|
||||
updateAndSaveSetting(key, this.value);
|
||||
// apiKey 是敏感字段,必须经 configManager 写入 localStorage
|
||||
if (key === 'apiKey') {
|
||||
configManager.set(key, this.value);
|
||||
} else {
|
||||
updateAndSaveSetting(key, this.value);
|
||||
}
|
||||
toastr.success(`配置 [${key}] 已自动保存!`, "Amily2号");
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from "../utils/settings.js";
|
||||
import { showHtmlModal } from './page-window.js';
|
||||
import { applyExclusionRules, extractBlocksByTags } from '../core/utils/rag-tag-extractor.js';
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
|
||||
import {
|
||||
getAvailableWorldbooks, getLoresForWorldbook,
|
||||
@@ -459,16 +460,23 @@ function bindNgmsApiEvents() {
|
||||
// API配置字段绑定
|
||||
const apiFields = [
|
||||
{ id: 'amily2_ngms_api_url', key: 'ngmsApiUrl' },
|
||||
{ id: 'amily2_ngms_api_key', key: 'ngmsApiKey' },
|
||||
{ id: 'amily2_ngms_api_key', key: 'ngmsApiKey', sensitive: true },
|
||||
{ id: 'amily2_ngms_model', key: 'ngmsModel' }
|
||||
];
|
||||
|
||||
apiFields.forEach(field => {
|
||||
const element = document.getElementById(field.id);
|
||||
if (element) {
|
||||
element.value = extension_settings[extensionName][field.key] || '';
|
||||
// 敏感字段(API Key)从 configManager(localStorage)读取
|
||||
element.value = field.sensitive
|
||||
? (configManager.get(field.key) || '')
|
||||
: (extension_settings[extensionName][field.key] || '');
|
||||
element.addEventListener('change', function() {
|
||||
updateAndSaveSetting(field.key, this.value);
|
||||
if (field.sensitive) {
|
||||
configManager.set(field.key, this.value);
|
||||
} else {
|
||||
updateAndSaveSetting(field.key, this.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -13,6 +13,8 @@ import { testConcurrentApiConnection, fetchConcurrentModels } from '../core/api/
|
||||
import { safeLorebooks, safeCharLorebooks, safeLorebookEntries } from "../core/tavernhelper-compatibility.js";
|
||||
import { createDrawer } from '../ui/drawer.js';
|
||||
import { pluginAuthStatus } from "../utils/auth.js";
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
import { SENSITIVE_KEYS } from '../utils/config/sensitive-keys.js';
|
||||
|
||||
// ========== Prompt Cache (module-level state) ==========
|
||||
|
||||
@@ -161,6 +163,9 @@ async function opt_saveSetting(key, value) {
|
||||
console.error(`[${extensionName}] 保存角色数据失败:`, error);
|
||||
toastr.error('无法保存角色卡设置,请检查控制台。');
|
||||
}
|
||||
} else if (SENSITIVE_KEYS.has(key)) {
|
||||
// 敏感字段(API Key)经 configManager 写入 localStorage
|
||||
configManager.set(key, value);
|
||||
} else {
|
||||
if (!extension_settings[extensionName]) {
|
||||
extension_settings[extensionName] = {};
|
||||
@@ -622,7 +627,8 @@ function opt_loadSettings(panel) {
|
||||
panel.find('#amily2_opt_worldbook_enabled').prop('checked', settings.plotOpt_worldbookEnabled);
|
||||
panel.find('#amily2_opt_new_memory_logic_enabled').prop('checked', settings.plotOpt_newMemoryLogicEnabled);
|
||||
panel.find('#amily2_opt_api_url').val(settings.plotOpt_apiUrl);
|
||||
panel.find('#amily2_opt_api_key').val(settings.plotOpt_apiKey);
|
||||
// plotOpt_apiKey 是敏感字段,从 configManager(localStorage)读取
|
||||
panel.find('#amily2_opt_api_key').val(configManager.get('plotOpt_apiKey') || '');
|
||||
|
||||
const modelInput = panel.find('#amily2_opt_model');
|
||||
const modelSelect = panel.find('#amily2_opt_model_select');
|
||||
@@ -701,14 +707,17 @@ function bindConcurrentApiEvents() {
|
||||
const fields = [
|
||||
{ id: 'amily2_plotOpt_concurrentApiProvider', key: 'plotOpt_concurrentApiProvider' },
|
||||
{ id: 'amily2_plotOpt_concurrentApiUrl', key: 'plotOpt_concurrentApiUrl' },
|
||||
{ id: 'amily2_plotOpt_concurrentApiKey', key: 'plotOpt_concurrentApiKey' },
|
||||
{ id: 'amily2_plotOpt_concurrentApiKey', key: 'plotOpt_concurrentApiKey', sensitive: true },
|
||||
{ id: 'amily2_plotOpt_concurrentModel', key: 'plotOpt_concurrentModel' }
|
||||
];
|
||||
|
||||
fields.forEach(field => {
|
||||
const element = document.getElementById(field.id);
|
||||
if (element) {
|
||||
element.value = settings[field.key] || '';
|
||||
// 敏感字段(API Key)从 configManager(localStorage)读取
|
||||
element.value = field.sensitive
|
||||
? (configManager.get(field.key) || '')
|
||||
: (settings[field.key] || '');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -787,9 +796,13 @@ function bindConcurrentApiEvents() {
|
||||
const element = document.getElementById(field.id);
|
||||
if (element) {
|
||||
element.addEventListener('change', function() {
|
||||
if (!extension_settings[extensionName]) extension_settings[extensionName] = {};
|
||||
extension_settings[extensionName][field.key] = this.value;
|
||||
saveSettingsDebounced();
|
||||
if (field.sensitive) {
|
||||
configManager.set(field.key, this.value);
|
||||
} else {
|
||||
if (!extension_settings[extensionName]) extension_settings[extensionName] = {};
|
||||
extension_settings[extensionName][field.key] = this.value;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1384,16 +1397,23 @@ function bindJqyhApiEvents() {
|
||||
// API配置字段绑定
|
||||
const apiFields = [
|
||||
{ id: 'amily2_jqyh_api_url', key: 'jqyhApiUrl' },
|
||||
{ id: 'amily2_jqyh_api_key', key: 'jqyhApiKey' },
|
||||
{ id: 'amily2_jqyh_api_key', key: 'jqyhApiKey', sensitive: true },
|
||||
{ id: 'amily2_jqyh_model', key: 'jqyhModel' }
|
||||
];
|
||||
|
||||
apiFields.forEach(field => {
|
||||
const element = document.getElementById(field.id);
|
||||
if (element) {
|
||||
element.value = extension_settings[extensionName][field.key] || '';
|
||||
// 敏感字段(API Key)从 configManager(localStorage)读取
|
||||
element.value = field.sensitive
|
||||
? (configManager.get(field.key) || '')
|
||||
: (extension_settings[extensionName][field.key] || '');
|
||||
element.addEventListener('change', function() {
|
||||
updateAndSaveSetting(field.key, this.value);
|
||||
if (field.sensitive) {
|
||||
configManager.set(field.key, this.value);
|
||||
} else {
|
||||
updateAndSaveSetting(field.key, this.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,6 +29,10 @@ import { testNccsApiConnection } from '../core/api/NccsApi.js';
|
||||
// 用于通过子元素定位父 block 的选择器
|
||||
const BLOCK_SEL = '.amily2_settings_block, .control-group, .amily2_opt_settings_block';
|
||||
|
||||
// 每个槽位在回填 Profile 值前的 DOM 字段快照(用于取消分配时还原)
|
||||
// 结构:{ [slot]: { [selector]: value } }
|
||||
const _fieldSnapshots = {};
|
||||
|
||||
const CARD_CLASS = 'amily2_profile_status_card';
|
||||
const CARD_SLOT_ATTR = 'data-card-slot';
|
||||
const HIDDEN_ATTR = 'data-profile-hidden';
|
||||
@@ -115,11 +119,37 @@ export async function syncSlot(slot) {
|
||||
_removeCard(slot);
|
||||
_restoreHidden(slot);
|
||||
|
||||
if (!profile) return;
|
||||
if (!profile) {
|
||||
// 取消分配:将 DOM 字段值还原为分配 Profile 前的快照,
|
||||
// 防止残留的 Profile 回填值(尤其是 '••••••••' 的 Key 占位符)
|
||||
// 因 blur 事件被误存入 extension_settings / localStorage。
|
||||
const snap = _fieldSnapshots[slot];
|
||||
if (snap) {
|
||||
for (const [sel, val] of Object.entries(snap)) {
|
||||
const el = document.querySelector(sel);
|
||||
if (el) el.value = val;
|
||||
}
|
||||
delete _fieldSnapshots[slot];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const container = _resolveContainer(config.container);
|
||||
if (!container) return;
|
||||
|
||||
// 回填前先快照各字段当前值(即 extension_settings / configManager 中的真实值),
|
||||
// 以便取消分配时能还原,避免 Profile 值污染旧配置。
|
||||
const snap = {};
|
||||
for (const sel of Object.values(config.fields || {})) {
|
||||
const el = document.querySelector(sel);
|
||||
if (el) snap[sel] = el.value;
|
||||
}
|
||||
if (config.keyField) {
|
||||
const keyEl = document.querySelector(config.keyField);
|
||||
if (keyEl) snap[config.keyField] = keyEl.value;
|
||||
}
|
||||
_fieldSnapshots[slot] = snap;
|
||||
|
||||
// 回填值(向下兼容:部分代码仍从 DOM 读取 fallback)
|
||||
for (const [key, sel] of Object.entries(config.fields || {})) {
|
||||
const el = document.querySelector(sel);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { extension_settings } from "/scripts/extensions.js";
|
||||
import { characters, this_chid } from '/script.js';
|
||||
import { extensionName, defaultSettings } from "../utils/settings.js";
|
||||
import { pluginAuthStatus } from "../utils/auth.js";
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +83,7 @@ export function updateUI() {
|
||||
$("#amily2_api_provider").val(settings.apiProvider || 'openai');
|
||||
$("#amily2_api_url").val(settings.apiUrl);
|
||||
$("#amily2_api_url").attr('type', 'text');
|
||||
$("#amily2_api_key").val(settings.apiKey);
|
||||
$("#amily2_api_key").val(configManager.get('apiKey') || '');
|
||||
$("#amily2_model").val(settings.model);
|
||||
$("#amily2_preset_selector").val(settings.tavernProfile);
|
||||
|
||||
|
||||
@@ -13,10 +13,23 @@ import { characters, this_chid, eventSource, event_types } from "/script.js";
|
||||
import { fetchNccsModels, testNccsApiConnection } from '../core/api/NccsApi.js';
|
||||
import { showGraphVisualization } from '../core/relationship-graph/visualizer.js';
|
||||
import { escapeHTML } from '../utils/utils.js';
|
||||
import { configManager } from '../utils/config/ConfigManager.js';
|
||||
|
||||
const isTouchDevice = () => window.matchMedia('(pointer: coarse)').matches;
|
||||
const getAllTablesContainer = () => document.getElementById('all-tables-container');
|
||||
|
||||
function getLiveExtensionSettings() {
|
||||
if (!extension_settings[extensionName]) {
|
||||
extension_settings[extensionName] = {};
|
||||
}
|
||||
|
||||
return extension_settings[extensionName];
|
||||
}
|
||||
|
||||
function isTableSystemEnabled() {
|
||||
return getLiveExtensionSettings().table_system_enabled !== false;
|
||||
}
|
||||
|
||||
let isResizing = false;
|
||||
let activeTableIndex = 0; // 【V155.0】当前激活的表格索引
|
||||
|
||||
@@ -767,7 +780,7 @@ export function renderTables() {
|
||||
|
||||
|
||||
function openTableRuleEditor() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = getLiveExtensionSettings();
|
||||
const tags = settings.table_tags_to_extract || '';
|
||||
const exclusionRules = settings.table_exclusion_rules || [];
|
||||
|
||||
@@ -1010,8 +1023,6 @@ function openRuleEditor(tableIndex) {
|
||||
|
||||
|
||||
function bindInjectionSettings() {
|
||||
const settings = extension_settings[extensionName];
|
||||
|
||||
const masterSwitchCheckbox = document.getElementById('table-system-master-switch');
|
||||
const enabledCheckbox = document.getElementById('table-injection-enabled');
|
||||
const optimizationCheckbox = document.getElementById('context-optimization-enabled'); // 【V144.0】
|
||||
@@ -1023,6 +1034,15 @@ function bindInjectionSettings() {
|
||||
return;
|
||||
}
|
||||
|
||||
const getLiveSettings = () => {
|
||||
const liveSettings = getLiveExtensionSettings();
|
||||
if (!liveSettings.injection) {
|
||||
liveSettings.injection = { position: 1, depth: 0, role: 0 };
|
||||
}
|
||||
|
||||
return liveSettings;
|
||||
};
|
||||
|
||||
const updateInjectionUI = () => {
|
||||
const position = positionSelect.value;
|
||||
const masterEnabled = masterSwitchCheckbox.checked;
|
||||
@@ -1076,6 +1096,7 @@ function bindInjectionSettings() {
|
||||
}
|
||||
};
|
||||
|
||||
const settings = getLiveSettings();
|
||||
masterSwitchCheckbox.checked = settings.table_system_enabled !== false;
|
||||
enabledCheckbox.checked = settings.table_injection_enabled;
|
||||
if (optimizationCheckbox) { // 【V144.0】
|
||||
@@ -1094,7 +1115,8 @@ function bindInjectionSettings() {
|
||||
if (masterSwitchCheckbox.dataset.eventsBound) return;
|
||||
|
||||
masterSwitchCheckbox.addEventListener('change', () => {
|
||||
settings.table_system_enabled = masterSwitchCheckbox.checked;
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.table_system_enabled = masterSwitchCheckbox.checked;
|
||||
saveSettingsDebounced();
|
||||
updateInjectionUI();
|
||||
|
||||
@@ -1104,35 +1126,40 @@ function bindInjectionSettings() {
|
||||
});
|
||||
|
||||
enabledCheckbox.addEventListener('change', () => {
|
||||
settings.table_injection_enabled = enabledCheckbox.checked;
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.table_injection_enabled = enabledCheckbox.checked;
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
// 【V144.0】
|
||||
if (optimizationCheckbox) {
|
||||
optimizationCheckbox.addEventListener('change', () => {
|
||||
settings.context_optimization_enabled = optimizationCheckbox.checked;
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.context_optimization_enabled = optimizationCheckbox.checked;
|
||||
saveSettingsDebounced();
|
||||
toastr.info(`上下文优化(世界书合并)已${optimizationCheckbox.checked ? '启用' : '禁用'}。`);
|
||||
});
|
||||
}
|
||||
|
||||
positionSelect.addEventListener('change', () => {
|
||||
settings.injection.position = parseInt(positionSelect.value, 10);
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.injection.position = parseInt(positionSelect.value, 10);
|
||||
saveSettingsDebounced();
|
||||
|
||||
updateInjectionUI();
|
||||
});
|
||||
|
||||
depthInput.addEventListener('input', () => {
|
||||
settings.injection.depth = parseInt(depthInput.value, 10);
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.injection.depth = parseInt(depthInput.value, 10);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
roleRadioGroup.forEach(radio => {
|
||||
radio.addEventListener('change', () => {
|
||||
if (radio.checked) {
|
||||
settings.injection.role = parseInt(radio.value, 10);
|
||||
const currentSettings = getLiveSettings();
|
||||
currentSettings.injection.role = parseInt(radio.value, 10);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
});
|
||||
@@ -1144,15 +1171,12 @@ function bindInjectionSettings() {
|
||||
|
||||
|
||||
function updateAndSaveTableSetting(key, value) {
|
||||
if (!extension_settings[extensionName]) {
|
||||
extension_settings[extensionName] = {};
|
||||
}
|
||||
extension_settings[extensionName][key] = value;
|
||||
getLiveExtensionSettings()[key] = value;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
function bindWorldBookSettings() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = getLiveExtensionSettings();
|
||||
|
||||
if (settings.table_worldbook_enabled === undefined) settings.table_worldbook_enabled = false;
|
||||
if (settings.table_worldbook_char_limit === undefined) settings.table_worldbook_char_limit = 30000;
|
||||
@@ -1175,6 +1199,7 @@ function bindWorldBookSettings() {
|
||||
}
|
||||
|
||||
const saveSelectedEntries = () => {
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
const selected = {};
|
||||
entryListContainer.querySelectorAll('input[type="checkbox"]:checked').forEach(cb => {
|
||||
const book = cb.dataset.book;
|
||||
@@ -1184,17 +1209,18 @@ function bindWorldBookSettings() {
|
||||
}
|
||||
selected[book].push(uid);
|
||||
});
|
||||
settings.table_selected_entries = selected;
|
||||
currentSettings.table_selected_entries = selected;
|
||||
saveSettingsDebounced();
|
||||
};
|
||||
|
||||
const renderWorldBookEntries = async () => {
|
||||
entryListContainer.innerHTML = '<p>加载条目中...</p>';
|
||||
const source = settings.table_worldbook_source || 'character';
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
const source = currentSettings.table_worldbook_source || 'character';
|
||||
let bookNames = [];
|
||||
|
||||
if (source === 'manual') {
|
||||
bookNames = settings.table_selected_worldbooks || [];
|
||||
bookNames = currentSettings.table_selected_worldbooks || [];
|
||||
} else {
|
||||
if (this_chid !== undefined && this_chid >= 0 && characters[this_chid]) {
|
||||
try {
|
||||
@@ -1241,7 +1267,7 @@ function bindWorldBookSettings() {
|
||||
checkbox.dataset.book = entry.bookName;
|
||||
checkbox.dataset.uid = entry.uid;
|
||||
|
||||
const isChecked = settings.table_selected_entries[entry.bookName]?.includes(String(entry.uid));
|
||||
const isChecked = currentSettings.table_selected_entries[entry.bookName]?.includes(String(entry.uid));
|
||||
checkbox.checked = !!isChecked;
|
||||
|
||||
const label = document.createElement('label');
|
||||
@@ -1271,15 +1297,16 @@ function bindWorldBookSettings() {
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.id = `wb-check-${book.file_name}`;
|
||||
checkbox.value = book.file_name;
|
||||
checkbox.checked = settings.table_selected_worldbooks.includes(book.file_name);
|
||||
checkbox.checked = getLiveExtensionSettings().table_selected_worldbooks.includes(book.file_name);
|
||||
|
||||
checkbox.addEventListener('change', () => {
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
if (checkbox.checked) {
|
||||
if (!settings.table_selected_worldbooks.includes(book.file_name)) {
|
||||
settings.table_selected_worldbooks.push(book.file_name);
|
||||
if (!currentSettings.table_selected_worldbooks.includes(book.file_name)) {
|
||||
currentSettings.table_selected_worldbooks.push(book.file_name);
|
||||
}
|
||||
} else {
|
||||
settings.table_selected_worldbooks = settings.table_selected_worldbooks.filter(name => name !== book.file_name);
|
||||
currentSettings.table_selected_worldbooks = currentSettings.table_selected_worldbooks.filter(name => name !== book.file_name);
|
||||
}
|
||||
saveSettingsDebounced();
|
||||
renderWorldBookEntries();
|
||||
@@ -1300,7 +1327,7 @@ function bindWorldBookSettings() {
|
||||
};
|
||||
|
||||
const updateManualSelectVisibility = () => {
|
||||
const isManual = settings.table_worldbook_source === 'manual';
|
||||
const isManual = getLiveExtensionSettings().table_worldbook_source === 'manual';
|
||||
manualSelectWrapper.style.display = isManual ? 'block' : 'none';
|
||||
renderWorldBookEntries();
|
||||
if (isManual) {
|
||||
@@ -1320,20 +1347,23 @@ function bindWorldBookSettings() {
|
||||
if (enabledCheckbox.dataset.eventsBound) return;
|
||||
|
||||
enabledCheckbox.addEventListener('change', () => {
|
||||
settings.table_worldbook_enabled = enabledCheckbox.checked;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.table_worldbook_enabled = enabledCheckbox.checked;
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
limitSlider.addEventListener('input', () => { limitValueSpan.textContent = limitSlider.value; });
|
||||
limitSlider.addEventListener('change', () => {
|
||||
settings.table_worldbook_char_limit = parseInt(limitSlider.value, 10);
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.table_worldbook_char_limit = parseInt(limitSlider.value, 10);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
sourceRadios.forEach(radio => {
|
||||
radio.addEventListener('change', () => {
|
||||
if (radio.checked) {
|
||||
settings.table_worldbook_source = radio.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.table_worldbook_source = radio.value;
|
||||
updateManualSelectVisibility();
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
@@ -1684,7 +1714,7 @@ export function bindTableEvents() {
|
||||
renderAll();
|
||||
|
||||
setTimeout(() => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = getLiveExtensionSettings();
|
||||
if (settings && settings.table_worldbook_enabled) {
|
||||
try {
|
||||
bindWorldBookSettings();
|
||||
@@ -1703,8 +1733,7 @@ function bindBatchFillButton() {
|
||||
if (fillButton.dataset.batchEventBound) return;
|
||||
|
||||
fillButton.addEventListener('click', (event) => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
const tableSystemEnabled = isTableSystemEnabled();
|
||||
|
||||
if (!tableSystemEnabled) {
|
||||
event.preventDefault();
|
||||
@@ -1727,8 +1756,7 @@ function bindReorganizeButton() {
|
||||
if (reorganizeBtn.dataset.reorganizeEventBound) return;
|
||||
|
||||
reorganizeBtn.addEventListener('click', async (event) => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
const tableSystemEnabled = isTableSystemEnabled();
|
||||
|
||||
if (!tableSystemEnabled) {
|
||||
event.preventDefault();
|
||||
@@ -1842,8 +1870,7 @@ function bindFloorFillButtons() {
|
||||
if (selectedFloorsBtn.dataset.floorEventBound) return;
|
||||
|
||||
selectedFloorsBtn.addEventListener('click', (event) => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
const tableSystemEnabled = isTableSystemEnabled();
|
||||
|
||||
if (!tableSystemEnabled) {
|
||||
event.preventDefault();
|
||||
@@ -1885,8 +1912,7 @@ function bindFloorFillButtons() {
|
||||
if (currentFloorBtn.dataset.currentEventBound) return;
|
||||
|
||||
currentFloorBtn.addEventListener('click', (event) => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
const tableSystemEnabled = isTableSystemEnabled();
|
||||
|
||||
if (!tableSystemEnabled) {
|
||||
event.preventDefault();
|
||||
@@ -1907,8 +1933,7 @@ function bindFloorFillButtons() {
|
||||
if (rollbackBtn.dataset.rollbackEventBound) return;
|
||||
|
||||
rollbackBtn.addEventListener('click', async (event) => {
|
||||
const settings = extension_settings[extensionName];
|
||||
const tableSystemEnabled = settings.table_system_enabled !== false;
|
||||
const tableSystemEnabled = isTableSystemEnabled();
|
||||
|
||||
if (!tableSystemEnabled) {
|
||||
event.preventDefault();
|
||||
@@ -1988,13 +2013,12 @@ function bindTemplateEditors() {
|
||||
}
|
||||
|
||||
function bindNccsApiEvents() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = getLiveExtensionSettings();
|
||||
|
||||
if (settings.nccsEnabled === undefined) settings.nccsEnabled = false;
|
||||
if (settings.nccsFakeStreamEnabled === undefined) settings.nccsFakeStreamEnabled = false;
|
||||
if (settings.nccsApiMode === undefined) settings.nccsApiMode = 'openai_test';
|
||||
if (settings.nccsApiUrl === undefined) settings.nccsApiUrl = 'https://api.openai.com/v1';
|
||||
if (settings.nccsApiKey === undefined) settings.nccsApiKey = '';
|
||||
if (settings.nccsModel === undefined) settings.nccsModel = '';
|
||||
if (settings.nccsTavernProfile === undefined) settings.nccsTavernProfile = '';
|
||||
|
||||
@@ -2015,7 +2039,7 @@ function bindNccsApiEvents() {
|
||||
enabledFakeStreamToggle.checked = settings.nccsFakeStreamEnabled;
|
||||
if (modeSelect) modeSelect.value = settings.nccsApiMode;
|
||||
if (urlInput) urlInput.value = settings.nccsApiUrl;
|
||||
if (keyInput) keyInput.value = settings.nccsApiKey;
|
||||
if (keyInput) keyInput.value = configManager.get('nccsApiKey') || '';
|
||||
if (modelInput) modelInput.value = settings.nccsModel;
|
||||
if (presetSelect) presetSelect.value = settings.nccsTavernProfile || '';
|
||||
|
||||
@@ -2057,21 +2081,24 @@ function bindNccsApiEvents() {
|
||||
updateModeBasedVisibility();
|
||||
|
||||
enabledToggle.addEventListener('change', () => {
|
||||
settings.nccsEnabled = enabledToggle.checked;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsEnabled = enabledToggle.checked;
|
||||
saveSettingsDebounced();
|
||||
updateConfigVisibility();
|
||||
log(`Nccs API ${enabledToggle.checked ? '已启用' : '已禁用'}`, 'info');
|
||||
});
|
||||
|
||||
enabledFakeStreamToggle.addEventListener('change', () => {
|
||||
settings.nccsFakeStreamEnabled = enabledFakeStreamToggle.checked;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsFakeStreamEnabled = enabledFakeStreamToggle.checked;
|
||||
saveSettingsDebounced();
|
||||
log(`Nccs API FakeStream ${enabledFakeStreamToggle.checked ? 'Enabled' : 'Disabled'}`, 'info');
|
||||
});
|
||||
|
||||
if (modeSelect) {
|
||||
modeSelect.addEventListener('change', () => {
|
||||
settings.nccsApiMode = modeSelect.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsApiMode = modeSelect.value;
|
||||
saveSettingsDebounced();
|
||||
updateModeBasedVisibility();
|
||||
log(`Nccs API模式已切换为: ${modeSelect.value}`, 'info');
|
||||
@@ -2080,7 +2107,8 @@ function bindNccsApiEvents() {
|
||||
|
||||
if (urlInput) {
|
||||
const saveUrl = () => {
|
||||
settings.nccsApiUrl = urlInput.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsApiUrl = urlInput.value;
|
||||
saveSettingsDebounced();
|
||||
};
|
||||
|
||||
@@ -2089,16 +2117,16 @@ function bindNccsApiEvents() {
|
||||
|
||||
if (keyInput) {
|
||||
const saveKey = () => {
|
||||
settings.nccsApiKey = keyInput.value;
|
||||
saveSettingsDebounced();
|
||||
configManager.set('nccsApiKey', keyInput.value);
|
||||
};
|
||||
|
||||
|
||||
keyInput.addEventListener('blur', saveKey);
|
||||
}
|
||||
|
||||
if (modelInput) {
|
||||
const saveModel = () => {
|
||||
settings.nccsModel = modelInput.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsModel = modelInput.value;
|
||||
saveSettingsDebounced();
|
||||
};
|
||||
|
||||
@@ -2108,7 +2136,8 @@ function bindNccsApiEvents() {
|
||||
|
||||
if (presetSelect) {
|
||||
presetSelect.addEventListener('change', () => {
|
||||
settings.nccsTavernProfile = presetSelect.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsTavernProfile = presetSelect.value;
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
}
|
||||
@@ -2143,12 +2172,13 @@ function bindNccsApiEvents() {
|
||||
fetchModelsButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 获取中...';
|
||||
|
||||
if (urlInput) {
|
||||
settings.nccsApiUrl = urlInput.value;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsApiUrl = urlInput.value;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
if (keyInput) {
|
||||
settings.nccsApiKey = keyInput.value;
|
||||
configManager.set('nccsApiKey', keyInput.value);
|
||||
}
|
||||
saveSettingsDebounced();
|
||||
|
||||
try {
|
||||
const models = await fetchNccsModels();
|
||||
@@ -2177,7 +2207,8 @@ function bindNccsApiEvents() {
|
||||
|
||||
modelSelect.addEventListener('change', () => {
|
||||
const selectedModel = modelSelect.value;
|
||||
settings.nccsModel = selectedModel;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.nccsModel = selectedModel;
|
||||
modelInput.value = selectedModel;
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
@@ -2244,7 +2275,7 @@ function bindNccsApiEvents() {
|
||||
}
|
||||
|
||||
function bindChatTableDisplaySetting() {
|
||||
const settings = extension_settings[extensionName];
|
||||
const settings = getLiveExtensionSettings();
|
||||
const showInChatToggle = document.getElementById('show-table-in-chat-toggle');
|
||||
const continuousRenderToggle = document.getElementById('render-on-every-message-toggle');
|
||||
|
||||
@@ -2269,14 +2300,16 @@ function bindChatTableDisplaySetting() {
|
||||
updateContinuousRenderState();
|
||||
|
||||
showInChatToggle.addEventListener('change', () => {
|
||||
settings.show_table_in_chat = showInChatToggle.checked;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.show_table_in_chat = showInChatToggle.checked;
|
||||
saveSettingsDebounced();
|
||||
toastr.info(`聊天内表格显示已${showInChatToggle.checked ? '开启' : '关闭'}。`);
|
||||
updateContinuousRenderState();
|
||||
});
|
||||
|
||||
continuousRenderToggle.addEventListener('change', () => {
|
||||
settings.render_on_every_message = continuousRenderToggle.checked;
|
||||
const currentSettings = getLiveExtensionSettings();
|
||||
currentSettings.render_on_every_message = continuousRenderToggle.checked;
|
||||
saveSettingsDebounced();
|
||||
toastr.info(`持续渲染最新消息功能已${continuousRenderToggle.checked ? '开启' : '关闭'}。请切换聊天以应用更改。`);
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
function a0_0x4566(_0x3c4bcd,_0x462ea4){_0x3c4bcd=_0x3c4bcd-0x8d;const _0x1fe670=a0_0x1fe6();let _0x45667d=_0x1fe670[_0x3c4bcd];if(a0_0x4566['TiiNjg']===undefined){var _0x619cb9=function(_0x96a409){const _0x2aec75='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2fbd34='',_0x13f537='';for(let _0x127b81=0x0,_0x12d2a6,_0x2aa0a2,_0x386214=0x0;_0x2aa0a2=_0x96a409['charAt'](_0x386214++);~_0x2aa0a2&&(_0x12d2a6=_0x127b81%0x4?_0x12d2a6*0x40+_0x2aa0a2:_0x2aa0a2,_0x127b81++%0x4)?_0x2fbd34+=String['fromCharCode'](0xff&_0x12d2a6>>(-0x2*_0x127b81&0x6)):0x0){_0x2aa0a2=_0x2aec75['indexOf'](_0x2aa0a2);}for(let _0x28f7ec=0x0,_0x4831aa=_0x2fbd34['length'];_0x28f7ec<_0x4831aa;_0x28f7ec++){_0x13f537+='%'+('00'+_0x2fbd34['charCodeAt'](_0x28f7ec)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x13f537);};const _0x207ab0=function(_0x721ccd,_0x300873){let _0x5e8a5c=[],_0x1405a7=0x0,_0x3be183,_0x18a968='';_0x721ccd=_0x619cb9(_0x721ccd);let _0x58e1ab;for(_0x58e1ab=0x0;_0x58e1ab<0x100;_0x58e1ab++){_0x5e8a5c[_0x58e1ab]=_0x58e1ab;}for(_0x58e1ab=0x0;_0x58e1ab<0x100;_0x58e1ab++){_0x1405a7=(_0x1405a7+_0x5e8a5c[_0x58e1ab]+_0x300873['charCodeAt'](_0x58e1ab%_0x300873['length']))%0x100,_0x3be183=_0x5e8a5c[_0x58e1ab],_0x5e8a5c[_0x58e1ab]=_0x5e8a5c[_0x1405a7],_0x5e8a5c[_0x1405a7]=_0x3be183;}_0x58e1ab=0x0,_0x1405a7=0x0;for(let _0x460aff=0x0;_0x460aff<_0x721ccd['length'];_0x460aff++){_0x58e1ab=(_0x58e1ab+0x1)%0x100,_0x1405a7=(_0x1405a7+_0x5e8a5c[_0x58e1ab])%0x100,_0x3be183=_0x5e8a5c[_0x58e1ab],_0x5e8a5c[_0x58e1ab]=_0x5e8a5c[_0x1405a7],_0x5e8a5c[_0x1405a7]=_0x3be183,_0x18a968+=String['fromCharCode'](_0x721ccd['charCodeAt'](_0x460aff)^_0x5e8a5c[(_0x5e8a5c[_0x58e1ab]+_0x5e8a5c[_0x1405a7])%0x100]);}return _0x18a968;};a0_0x4566['VlxCUG']=_0x207ab0,a0_0x4566['lQXssB']={},a0_0x4566['TiiNjg']=!![];}const _0x4aafb8=_0x1fe670[0x0],_0x24d3b0=_0x3c4bcd+_0x4aafb8,_0x46e2c4=a0_0x4566['lQXssB'][_0x24d3b0];return!_0x46e2c4?(a0_0x4566['WogIJe']===undefined&&(a0_0x4566['WogIJe']=!![]),_0x45667d=a0_0x4566['VlxCUG'](_0x45667d,_0x462ea4),a0_0x4566['lQXssB'][_0x24d3b0]=_0x45667d):_0x45667d=_0x46e2c4,_0x45667d;}const a0_0x1b4874=a0_0x4566;(function(_0x50cc10,_0x361498){const _0x5ea55d=a0_0x4566,_0x1552f3=_0x50cc10();while(!![]){try{const _0x546ae9=parseInt(_0x5ea55d(0x99,'^H5X'))/0x1+-parseInt(_0x5ea55d(0xa7,'5Q$k'))/0x2*(parseInt(_0x5ea55d(0xa5,'5Q$k'))/0x3)+-parseInt(_0x5ea55d(0x91,'H1ui'))/0x4*(parseInt(_0x5ea55d(0x9d,'7$CC'))/0x5)+-parseInt(_0x5ea55d(0x9f,'$3XG'))/0x6+-parseInt(_0x5ea55d(0xa4,'5^jQ'))/0x7*(parseInt(_0x5ea55d(0x94,'9b%M'))/0x8)+parseInt(_0x5ea55d(0x8d,'5^jQ'))/0x9*(parseInt(_0x5ea55d(0x92,'(T!*'))/0xa)+parseInt(_0x5ea55d(0xa2,'@nIj'))/0xb*(parseInt(_0x5ea55d(0xa1,'gmKu'))/0xc);if(_0x546ae9===_0x361498)break;else _0x1552f3['push'](_0x1552f3['shift']());}catch(_0x5c3020){_0x1552f3['push'](_0x1552f3['shift']());}}}(a0_0x1fe6,0x7b4c5));export const SENSITIVE_KEYS=new Set([a0_0x1b4874(0x9b,'lD*1'),a0_0x1b4874(0xaa,'igl1'),a0_0x1b4874(0x93,'0$p4'),a0_0x1b4874(0xa3,'zygW'),a0_0x1b4874(0x95,'Z0Y4'),a0_0x1b4874(0x98,'XIj)'),a0_0x1b4874(0x97,'z5yh')]);function a0_0x1fe6(){const _0x1e1e6e=['WQpcUwuwuSkeWQxdTW','WPi6FvldO3VdNCoCjZRcOG','WQdcVHvVpSolWQNdRCkwtSotgq','W7VdUCkayaablCkE','WPe6Ev/dQWBcJSopeZBcP07cSG','kCkwW73cImkBq8kEW5FcMhfkWQTJWP0zxSkxxsXlW7lcP8oQxa','W5vXWR3dUCksWPyLpuBcRSkiW7FcHW','EgddH8kLgx0JWODFkW','omo1zWJdGSkmpmkVde4','amkMWQFcIIH3W7SRWRlcRG','W48+k8kMW40pF2e/WRpdOCkz','WRTHnXBcPdO4D2vNWQCuW4e','eZJcOe7dJ8oBF2vSWPNdKa','o8oAgMHcWOK3WOVcUrm','sv0PsmoztmoYgYxcOG','CbpdVSoiW5upWOqkW5ZdMq','et3cQGdcVCoquv5a','d8kenCkFW48oWQPNrY4','WPn0WOZcMrxcLCkCWOSilK4','WPPGtdhcKCk8x8khWQJcLG','WQtcSrnLoSopW7ZdHCkUsSoQoSkL','gbxdJmoPW6P3','tfGIsCowBCoZebZcSq','WQjrdMyaW4Hm','gbGptCk6W7TZ','B17dKCkWW6z2WOFdKdersmoHlq','yCkmtY9vWO4pWQRcKc4','d2JcMaFdHWHOW7JdP8kHW4PQya','d8keW7KiW7tdSuTDeq','a8oRW6tcLWXRk8keB8oV','EgxdGCkImuWJWQDJeG'];a0_0x1fe6=function(){return _0x1e1e6e;};return a0_0x1fe6();}
|
||||
const a0_0x19caf5=a0_0x19be;function a0_0x704b(){const _0x52d474=['vCktWOddMCoJWOZcNG','psnPW7TkW4hdU1RdMCklW5i','j3NcVNuApmkFabfw','nSkyzmkHCb0','W7tcImoyaZGjfCosmCkiBmob','WPFcGZ7dVCotW4icCW','W5m0W4TrnSoHWRJcTw8FW5FdV8kl','W6DGWRZcGmofW7zfWOZdNSkneXu','W4y4W77cPX4Qe8kZcSoAWOq','cmokh27cJSkOqXO5yNi2W7XslI17FItdISoigWLk','vtFdOG7cOCk2W6P8nYylka','B8kHwqDNWQNcIeNdL8kXW6DZ','WPRcH8o6WO1lpCk9wwddOW','W6xcM3nywYBcPXX2WPe','W6DKWR/cI8oaW7b5WPZdVSkTmJa','d8omW7L1pe7cSmknc8o2W6Pngq','BddcQ1GvaSkLbq','W4SSW7/cIZ4Qe8kNbmog','imomWOpdRmkjbSkuW6JdTmk6W6G','WQyxrmkhWQLPWRb4WRdcJSoJW6HruG','kColWOhdRSkpq8onW5/dSCkyW6ddQmo6','dmkkWOddUIVdRSk6WPrHitBcRa','W7JdJfJdQmofWRanAxddS8kqW4m','uCoiW5BcK8k/W4JcTdtcMmoOw0G','WOJdMfjYvx7cTW'];a0_0x704b=function(){return _0x52d474;};return a0_0x704b();}(function(_0x47544b,_0x12a798){const _0x265831=a0_0x19be,_0xf1cf88=_0x47544b();while(!![]){try{const _0x309d80=parseInt(_0x265831(0x127,'s9Zs'))/0x1+-parseInt(_0x265831(0x110,'s9Zs'))/0x2*(-parseInt(_0x265831(0x11b,'sr@l'))/0x3)+-parseInt(_0x265831(0x11e,'M)h$'))/0x4+-parseInt(_0x265831(0x120,'r7Wy'))/0x5*(-parseInt(_0x265831(0x111,'03GF'))/0x6)+-parseInt(_0x265831(0x124,'*HQN'))/0x7+parseInt(_0x265831(0x117,'M)h$'))/0x8+-parseInt(_0x265831(0x11f,'Hnai'))/0x9;if(_0x309d80===_0x12a798)break;else _0xf1cf88['push'](_0xf1cf88['shift']());}catch(_0x3ef9c2){_0xf1cf88['push'](_0xf1cf88['shift']());}}}(a0_0x704b,0x1f69e));function a0_0x19be(_0x4d0f1b,_0x415410){_0x4d0f1b=_0x4d0f1b-0x110;const _0x704b5d=a0_0x704b();let _0x19be56=_0x704b5d[_0x4d0f1b];if(a0_0x19be['IjrnPV']===undefined){var _0x7f8636=function(_0x3da96e){const _0x30c1c4='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5781a0='',_0x5dfde2='';for(let _0x2830f5=0x0,_0x5a412a,_0x119676,_0x32858f=0x0;_0x119676=_0x3da96e['charAt'](_0x32858f++);~_0x119676&&(_0x5a412a=_0x2830f5%0x4?_0x5a412a*0x40+_0x119676:_0x119676,_0x2830f5++%0x4)?_0x5781a0+=String['fromCharCode'](0xff&_0x5a412a>>(-0x2*_0x2830f5&0x6)):0x0){_0x119676=_0x30c1c4['indexOf'](_0x119676);}for(let _0x15ad50=0x0,_0x35621b=_0x5781a0['length'];_0x15ad50<_0x35621b;_0x15ad50++){_0x5dfde2+='%'+('00'+_0x5781a0['charCodeAt'](_0x15ad50)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5dfde2);};const _0x2c9918=function(_0x299231,_0x1535fd){let _0x379af2=[],_0x23d358=0x0,_0x2943b4,_0x1d0275='';_0x299231=_0x7f8636(_0x299231);let _0x23b9f5;for(_0x23b9f5=0x0;_0x23b9f5<0x100;_0x23b9f5++){_0x379af2[_0x23b9f5]=_0x23b9f5;}for(_0x23b9f5=0x0;_0x23b9f5<0x100;_0x23b9f5++){_0x23d358=(_0x23d358+_0x379af2[_0x23b9f5]+_0x1535fd['charCodeAt'](_0x23b9f5%_0x1535fd['length']))%0x100,_0x2943b4=_0x379af2[_0x23b9f5],_0x379af2[_0x23b9f5]=_0x379af2[_0x23d358],_0x379af2[_0x23d358]=_0x2943b4;}_0x23b9f5=0x0,_0x23d358=0x0;for(let _0xd0f58b=0x0;_0xd0f58b<_0x299231['length'];_0xd0f58b++){_0x23b9f5=(_0x23b9f5+0x1)%0x100,_0x23d358=(_0x23d358+_0x379af2[_0x23b9f5])%0x100,_0x2943b4=_0x379af2[_0x23b9f5],_0x379af2[_0x23b9f5]=_0x379af2[_0x23d358],_0x379af2[_0x23d358]=_0x2943b4,_0x1d0275+=String['fromCharCode'](_0x299231['charCodeAt'](_0xd0f58b)^_0x379af2[(_0x379af2[_0x23b9f5]+_0x379af2[_0x23d358])%0x100]);}return _0x1d0275;};a0_0x19be['ylbrJP']=_0x2c9918,a0_0x19be['ngItur']={},a0_0x19be['IjrnPV']=!![];}const _0x272524=_0x704b5d[0x0],_0x436fa3=_0x4d0f1b+_0x272524,_0x1984c1=a0_0x19be['ngItur'][_0x436fa3];return!_0x1984c1?(a0_0x19be['SnOIbC']===undefined&&(a0_0x19be['SnOIbC']=!![]),_0x19be56=a0_0x19be['ylbrJP'](_0x19be56,_0x415410),a0_0x19be['ngItur'][_0x436fa3]=_0x19be56):_0x19be56=_0x1984c1,_0x19be56;}export const SENSITIVE_KEYS=new Set([a0_0x19caf5(0x113,'xOe^'),a0_0x19caf5(0x123,'@P0T'),a0_0x19caf5(0x119,'PFX('),a0_0x19caf5(0x11d,'va)]'),a0_0x19caf5(0x121,'t$HW'),a0_0x19caf5(0x11c,'2NRm'),a0_0x19caf5(0x118,'t$HW'),a0_0x19caf5(0x112,'r7Wy')]);
|
||||
@@ -997,65 +997,8 @@ export const defaultSettings = {
|
||||
|
||||
|
||||
export function validateSettings() {
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
// 新版 Profile 系统管理 API 配置时,跳过旧版字段验证
|
||||
const assignments = settings.amily2_profile_assignments || {};
|
||||
if (assignments.main) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果启用了Ngms或Nccs,则跳过主API验证
|
||||
if (settings.ngmsEnabled || settings.nccsEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const apiProvider = settings.apiProvider || 'openai';
|
||||
const errors = [];
|
||||
|
||||
switch (apiProvider) {
|
||||
case 'openai':
|
||||
case 'openai_test':
|
||||
if (!settings.apiUrl) {
|
||||
errors.push("当前模式需要配置API URL");
|
||||
} else if (!/^https?:\/\//.test(settings.apiUrl)) {
|
||||
errors.push("API URL必须以http://或https://开头");
|
||||
}
|
||||
if (apiProvider === 'openai' && !settings.apiKey) {
|
||||
errors.push("当前模式需要配置API Key");
|
||||
}
|
||||
break;
|
||||
case 'sillytavern_backend':
|
||||
if (!settings.apiUrl) {
|
||||
errors.push("SillyTavern后端模式需要配置API URL");
|
||||
}
|
||||
break;
|
||||
case 'google':
|
||||
if (!settings.apiKey) {
|
||||
errors.push("Google直连模式需要配置API Key");
|
||||
}
|
||||
break;
|
||||
case 'sillytavern_preset':
|
||||
break;
|
||||
default:
|
||||
if (!settings.apiUrl) {
|
||||
errors.push("API URL未配置");
|
||||
}
|
||||
if (!settings.apiKey) {
|
||||
errors.push("API Key未配置");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!settings.model && apiProvider !== 'sillytavern_preset') {
|
||||
errors.push("未选择模型");
|
||||
}
|
||||
|
||||
if (settings.maxTokens < 100 || settings.maxTokens > 100000) {
|
||||
errors.push(`Token数超限 (${settings.maxTokens}) - 必须在100-100000之间`);
|
||||
}
|
||||
|
||||
return errors.length ? errors : null;
|
||||
// 主 API 概念已移除,各功能模块通过 Profile 槽位或独立配置管理 API。
|
||||
return null;
|
||||
}
|
||||
|
||||
export function saveSettings() {
|
||||
|
||||
Reference in New Issue
Block a user