import { extension_settings, getContext } from "/scripts/extensions.js"; import { characters, this_chid, getRequestHeaders, saveSettingsDebounced, eventSource, event_types } from "/script.js"; import { defaultSettings, extensionName, saveSettings } from "../utils/settings.js"; import { pluginAuthStatus, activatePluginAuthorization, getPasswordForDate } from "../utils/auth.js"; import { fetchModels } from "../core/api.js"; import { getJqyhApiSettings, testJqyhApiConnection, fetchJqyhModels } from '../core/api/JqyhApi.js'; import { safeLorebooks, safeCharLorebooks, safeLorebookEntries, isTavernHelperAvailable } from "../core/tavernhelper-compatibility.js"; import { setAvailableModels, populateModelDropdown, getLatestUpdateInfo } from "./state.js"; import { fixCommand, testReplyChecker } from "../core/commands.js"; import { createDrawer } from '../ui/drawer.js'; import { messageFormatting } from '/script.js'; import { executeManualCommand } from '../core/autoHideManager.js'; import { showContentModal, showHtmlModal } from './page-window.js'; function displayDailyAuthCode() { const displayEl = document.getElementById('amily2_daily_code_display'); const copyBtn = document.getElementById('amily2_copy_daily_code'); if (displayEl && copyBtn) { const todayCode = getPasswordForDate(new Date()); displayEl.textContent = todayCode; copyBtn.addEventListener('click', () => { navigator.clipboard.writeText(todayCode).then(() => { toastr.success('授权码已复制到剪贴板!'); }, () => { toastr.error('复制失败,请手动复制。'); }); }); } } async function loadSillyTavernPresets() { console.log('[Amily2号-UI] 正在加载SillyTavern预设列表'); const select = $('#amily2_preset_selector'); const settings = extension_settings[extensionName] || {}; // 统一使用 tavernProfile 作为主要的预设存储键 const currentProfileId = settings.tavernProfile || settings.selectedPreset; select.empty().append(new Option('-- 请选择一个酒馆预设 --', '')); try { const context = getContext(); const tavernProfiles = context.extensionSettings?.connectionManager?.profiles || []; if (!tavernProfiles || tavernProfiles.length === 0) { select.append($(''); }); container .off("change.amily2.text") .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); toastr.success(`配置 [${key}] 已自动保存!`, "Amily2号"); }); container .off("change.amily2.select") .on("change.amily2.select", "select#amily2_model, select#amily2_preset_selector", function () { if (!pluginAuthStatus.authorized) return; const key = snakeToCamel(this.id.replace("amily2_", "")); let valueToSave = this.value; if (this.id === 'amily2_preset_selector') { updateAndSaveSetting('tavernProfile', valueToSave); } else { updateAndSaveSetting(key, valueToSave); } if (this.id === 'amily2_model') { populateModelDropdown(); } }); container .off("input.amily2.range") .on( "input.amily2.range", 'input[type="range"][id^="amily2_"]', function () { if (!pluginAuthStatus.authorized) return; const key = snakeToCamel(this.id.replace("amily2_", "")); const value = this.id.includes("temperature") ? parseFloat(this.value) : parseInt(this.value, 10); $(`#${this.id}_value`).text(value); updateAndSaveSetting(key, value); }, ); const promptMap = { mainPrompt: "#amily2_main_prompt", systemPrompt: "#amily2_system_prompt", outputFormatPrompt: "#amily2_output_format_prompt", }; const selector = "#amily2_prompt_selector"; const editor = "#amily2_unified_editor"; const unifiedSaveButton = "#amily2_unified_save_button"; function updateEditorView() { if (!$(selector).length) return; const selectedKey = $(selector).val(); if (!selectedKey) return; const content = extension_settings[extensionName][selectedKey] || ""; $(editor).val(content); } container .off("change.amily2.prompt_selector") .on("change.amily2.prompt_selector", selector, updateEditorView); container .off("click.amily2.unified_save") .on("click.amily2.unified_save", unifiedSaveButton, function () { const selectedKey = $(selector).val(); if (!selectedKey) return; const newContent = $(editor).val(); updateAndSaveSetting(selectedKey, newContent); toastr.success(`谕令 [${selectedKey}] 已镌刻!`, "Amily2号"); }); container .off("click.amily2.unified_restore") .on("click.amily2.unified_restore", "#amily2_unified_restore_button", function () { const selectedKey = $(selector).val(); if (!selectedKey) return; const defaultValue = defaultSettings[selectedKey]; $(editor).val(defaultValue); updateAndSaveSetting(selectedKey, defaultValue); toastr.success(`谕令 [${selectedKey}] 已成功恢复为帝国初始蓝图。`, "Amily2号"); }); container .off("change.amily2.lore_settings") .on("change.amily2.lore_settings", 'select[id^="amily2_lore_"], input#amily2_lore_depth_input', function () { if (!pluginAuthStatus.authorized) return; let key = snakeToCamel(this.id.replace("amily2_", "")); if (key === 'loreDepthInput') { key = 'loreDepth'; } const value = (this.type === 'number') ? parseInt(this.value, 10) : this.value; updateAndSaveSetting(key, value); if (this.id === 'amily2_lore_insertion_position') { const depthContainer = $('#amily2_lore_depth_container'); if (this.value === 'at_depth') { depthContainer.slideDown(200); } else { depthContainer.slideUp(200); } } } ); container .off("click.amily2.lore_save") .on("click.amily2.lore_save", '#amily2_save_lore_settings', function () { if (!pluginAuthStatus.authorized) return; const button = $(this); const statusElement = $('#amily2_lore_save_status'); button.prop('disabled', true).html(' 已确认'); statusElement.text('圣意已在您每次更改时自动镌刻。').stop().fadeIn(); setTimeout(() => { button.prop('disabled', false).html(' 确认敕令'); statusElement.fadeOut(); }, 2500); }); setTimeout(updateEditorView, 100); updateModelInputView(); container.data("events-bound", true); } export function opt_saveAllSettings() { const panel = $('#amily2_plot_optimization_panel'); if (panel.length === 0) return; console.log(`[${extensionName}] 手动触发所有剧情优化设置的保存...`); panel.find('input[type="checkbox"], input[type="radio"], input[type="text"], input[type="password"], textarea, select').trigger('change.amily2_opt'); panel.find('input[type="range"]').trigger('change.amily2_opt'); opt_saveEnabledEntries(); toastr.info('剧情优化设置已自动保存。'); } function opt_toCamelCase(str) { return str.replace(/[-_]([a-z])/g, (g) => g[1].toUpperCase()); } function opt_updateApiUrlVisibility(panel, apiMode) { const customApiSettings = panel.find('#amily2_opt_custom_api_settings_block'); const tavernProfileSettings = panel.find('#amily2_opt_tavern_api_profile_block'); const apiUrlInput = panel.find('#amily2_opt_api_url'); customApiSettings.hide(); tavernProfileSettings.hide(); if (apiMode === 'tavern') { tavernProfileSettings.show(); } else { customApiSettings.show(); if (apiMode === 'google') { panel.find('#amily2_opt_api_url_block').hide(); const googleUrl = 'https://generativelanguage.googleapis.com'; if (apiUrlInput.val() !== googleUrl) { apiUrlInput.val(googleUrl).attr('type', 'text').trigger('change'); } } else { panel.find('#amily2_opt_api_url_block').show(); } } } function opt_updateWorldbookSourceVisibility(panel, source) { const manualSelectionWrapper = panel.find('#amily2_opt_worldbook_select_wrapper'); if (source === 'manual') { manualSelectionWrapper.show(); const selectBox = manualSelectionWrapper.find('#amily2_opt_selected_worldbooks'); selectBox.css({ 'height': 'auto', 'background-color': 'var(--bg1)', 'appearance': 'none', '-webkit-appearance': 'none' }); } else { manualSelectionWrapper.hide(); } } async function opt_loadTavernApiProfiles(panel) { const select = panel.find('#amily2_opt_tavern_api_profile_select'); const apiSettings = opt_getMergedSettings(); const currentProfileId = apiSettings.plotOpt_tavernProfile; const currentValue = select.val(); select.empty().append(new Option('-- 请选择一个酒馆预设 --', '')); try { const tavernProfiles = getContext().extensionSettings?.connectionManager?.profiles || []; if (!tavernProfiles || tavernProfiles.length === 0) { select.append($(''; models.forEach(model => { const option = document.createElement('option'); option.value = model.id || model.name || model; option.textContent = model.name || model.id || model; modelSelect.appendChild(option); }); // 显示下拉框,隐藏输入框 modelSelect.style.display = 'block'; modelInput.style.display = 'none'; // 绑定模型选择事件 modelSelect.addEventListener('change', function() { const selectedModel = this.value; modelInput.value = selectedModel; updateAndSaveSetting('jqyhModel', selectedModel); console.log(`[Amily2-Jqyh] 已选择模型: ${selectedModel}`); }); toastr.success(`成功获取 ${models.length} 个模型`, 'Jqyh 模型获取'); } else { toastr.warning('未获取到任何模型', 'Jqyh 模型获取'); } } catch (error) { console.error('[Amily2号-Jqyh] 获取模型列表失败:', error); toastr.error(`获取模型失败: ${error.message}`, 'Jqyh 模型获取'); } finally { button.prop('disabled', false).html(originalHtml); } }); } } // 加载SillyTavern预设列表 async function loadJqyhTavernPresets() { const select = document.getElementById('amily2_jqyh_tavern_profile'); if (!select) return; const currentValue = select.value; select.innerHTML = ''; try { const context = getContext(); const tavernProfiles = context.extensionSettings?.connectionManager?.profiles || []; select.innerHTML = ''; if (tavernProfiles.length > 0) { tavernProfiles.forEach(profile => { if (profile.api && profile.preset) { const option = document.createElement('option'); option.value = profile.id; option.textContent = profile.name || profile.id; if (profile.id === currentValue) { option.selected = true; } select.appendChild(option); } }); } else { select.innerHTML = ''; } } catch (error) { console.error('[Amily2号-Jqyh] 加载SillyTavern预设失败:', error); select.innerHTML = ''; } } $(document).on('change', 'input[name="amily2_icon_location"]', function() { if (!pluginAuthStatus.authorized) return; const newLocation = $(this).val(); extension_settings[extensionName]['iconLocation'] = newLocation; saveSettingsDebounced(); console.log(`[Amily-禁卫军] 收到迁都指令 -> ${newLocation}。圣意已存档。`); toastr.info(`正在将帝国徽记迁往 [${newLocation === 'topbar' ? '顶栏' : '扩展区'}]...`, "迁都令", { timeOut: 2000 }); $('#amily2_main_drawer').remove(); $(document).off("mousedown.amily2Drawer"); $('#amily2_extension_frame').remove(); setTimeout(createDrawer, 50); });