import { extension_settings, getContext } from "/scripts/extensions.js"; import { characters, this_chid, getRequestHeaders, saveSettingsDebounced, eventSource, event_types } from "/script.js"; import { defaultSettings, extensionName } from "../utils/settings.js"; import { pluginAuthStatus, activatePluginAuthorization, getPasswordForDate } from "../utils/auth.js"; import { fetchModels } from "../core/api.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] || {}; const currentProfileId = 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($('