Files
ST-Amily2-Chat-Optimisation/assets/api-config-panel.html

283 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="amily2-header">
<div class="additional-features-title">
<i class="fas fa-key"></i> API 连接配置
</div>
<button id="amily2_back_to_main_from_api_config" class="menu_button secondary small_button interactable amily2-vbtn">
<span class="vbtn-icon"><i class="fas fa-arrow-right"></i></span><span class="vbtn-label">返回主殿</span>
</button>
</div>
<hr class="header-divider" style="margin-top: 5px; margin-bottom: 10px;">
<!-- 存储模式 -->
<fieldset class="settings-group">
<legend><i class="fas fa-shield-alt"></i> 密钥存储模式</legend>
<div class="control-pair-container" style="align-items: center; gap: 12px;">
<div class="amily2_settings_block" style="flex: 1;">
<label for="amily2_keystore_mode">存储方式</label>
<select id="amily2_keystore_mode" class="text_pole">
<option value="local">本地存储(推荐)</option>
<option value="cloud">加密云同步</option>
</select>
<small class="notes" id="amily2_keystore_mode_note">
本地存储API Key 仅存于本设备浏览器,绝不上传。换设备需重新填写。
</small>
</div>
<div class="amily2_settings_block" id="amily2_cloud_key_section" style="display:none; flex: 1;">
<label>当前密钥对指纹</label>
<div style="display:flex; gap:6px; align-items:center;">
<code id="amily2_keypair_fingerprint" style="flex:1; padding:4px 8px; background:var(--black30a); border-radius:4px; font-size:0.85em;">(未生成)</code>
<button id="amily2_generate_keypair" class="menu_button interactable small_button amily2-vbtn" title="生成新密钥对(会清除所有已加密的 Key">
<span class="vbtn-icon"><i class="fas fa-sync-alt"></i></span><span class="vbtn-label">重新生成</span>
</button>
</div>
<div style="display:flex; gap:6px; margin-top:6px; flex-wrap:wrap;">
<button id="amily2_export_key_bundle" class="menu_button interactable small_button amily2-vbtn" title="导出当前设备的私钥包,用于新设备恢复解密权限">
<span class="vbtn-icon"><i class="fas fa-download"></i></span><span class="vbtn-label">导出私钥</span>
</button>
<button id="amily2_import_key_bundle" class="menu_button interactable small_button amily2-vbtn" title="导入先前导出的私钥包,恢复云同步密钥的解密能力">
<span class="vbtn-icon"><i class="fas fa-upload"></i></span><span class="vbtn-label">导入私钥</span>
</button>
<input id="amily2_import_key_bundle_input" type="file" accept=".json,application/json" style="display:none;" />
</div>
<small class="notes" style="color: var(--warning-color);">
⚠️ 重新生成密钥对后,所有已加密存储的 API Key 将失效,需重新输入。
</small>
</div>
</div>
</fieldset>
<!-- Profile 列表 -->
<fieldset class="settings-group">
<legend><i class="fas fa-server"></i> 连接配置列表</legend>
<div style="display:flex; gap:6px; margin-bottom:10px; flex-wrap:wrap;">
<button class="menu_button small_button amily2_profile_type_filter active" data-type="all">全部</button>
<button class="menu_button small_button amily2_profile_type_filter amily2-vbtn" data-type="chat">
<span class="vbtn-icon"><i class="fas fa-comments"></i></span><span class="vbtn-label">对话模型</span>
</button>
<button class="menu_button small_button amily2_profile_type_filter amily2-vbtn" data-type="embedding">
<span class="vbtn-icon"><i class="fas fa-project-diagram"></i></span><span class="vbtn-label">向量嵌入</span>
</button>
<button class="menu_button small_button amily2_profile_type_filter amily2-vbtn" data-type="rerank">
<span class="vbtn-icon"><i class="fas fa-sort-amount-down"></i></span><span class="vbtn-label">重排序</span>
</button>
<button id="amily2_add_profile" class="menu_button small_button interactable amily2-vbtn" style="margin-left:auto;">
<span class="vbtn-icon"><i class="fas fa-plus"></i></span><span class="vbtn-label">新建配置</span>
</button>
</div>
<div id="amily2_profile_list" style="display:flex; flex-direction:column; gap:8px;">
<div class="amily2_profile_empty" style="color:var(--SmartThemeQuoteColor); text-align:center; padding:20px;">
暂无连接配置,点击「新建配置」添加。
</div>
</div>
</fieldset>
<!-- 功能槽分配 -->
<fieldset class="settings-group">
<legend><i class="fas fa-plug"></i> 功能分配</legend>
<small class="notes" style="display:block; margin-bottom:10px;">
为每个系统功能指定使用的连接配置。选单只会显示类型匹配的配置。
</small>
<div id="amily2_slot_assignments" style="display:flex; flex-direction:column; gap:6px;">
</div>
</fieldset>
<!-- 旧配置清理 -->
<fieldset class="settings-group">
<legend><i class="fas fa-broom"></i> 旧配置清理</legend>
<small class="notes" style="display:block; margin-bottom:10px;">
旧版各模块独立的 API 配置URL / Key / Model / 温度等)已自动迁移到上方"连接配置"。
若上方分配无误且使用一切正常,可点击下方按钮清除 <code>extension_settings</code> 中的旧字段
<code>localStorage</code> 中的旧 API Key避免残留卡 bug。<br/>
<strong>清理前会校验所有旧字段所属槽位都已分配 profile</strong>,未分配的槽位会阻止清理并提示。
</small>
<button id="amily2_clear_legacy_config" class="menu_button caution interactable small_button amily2-vbtn">
<span class="vbtn-icon"><i class="fas fa-trash-alt"></i></span><span class="vbtn-label">清除旧配置残留</span>
</button>
</fieldset>
<!-- 新建/编辑 Profile 表单details 折叠) -->
<details id="amily2_profile_form_details" class="settings-group amily2-profile-form">
<summary>
<i id="amily2_profile_form_icon" class="fas fa-plus"></i>
<span id="amily2_profile_modal_title">新建连接配置</span>
</summary>
<div style="padding-top:10px;">
<!-- 类型选择 -->
<div class="amily2_settings_block">
<label for="amily2_pf_type">配置类型</label>
<select id="amily2_pf_type" class="text_pole">
<option value="chat">对话模型Chat</option>
<option value="embedding">向量嵌入Embedding</option>
<option value="rerank">重排序Rerank</option>
</select>
</div>
<!-- 基础字段 -->
<div class="amily2_settings_block">
<label for="amily2_pf_name">配置名称</label>
<input id="amily2_pf_name" type="text" class="text_pole" placeholder="例如:我的 DeepSeek" />
</div>
<div class="amily2_settings_block">
<label for="amily2_pf_provider">接口类型</label>
<select id="amily2_pf_provider" class="text_pole">
<optgroup label="官方预设(自动填默认 URL">
<option value="openai">OpenAI (GPT)</option>
<option value="anthropic">Anthropic Claude</option>
<option value="google">Google Gemini</option>
<option value="openrouter">OpenRouter (聚合)</option>
<option value="deepseek">DeepSeek</option>
<option value="xai">xAI Grok</option>
</optgroup>
<optgroup label="自定义 / 高级">
<option value="custom_oai">Custom OpenAI 兼容(自填 URL</option>
<option value="sillytavern_backend">SillyTavern 后端代理</option>
<option value="sillytavern_preset">SillyTavern 预设转发</option>
</optgroup>
</select>
</div>
<div class="amily2_settings_block" id="amily2_pf_url_row">
<label for="amily2_pf_url">API 地址</label>
<input id="amily2_pf_url" type="text" class="text_pole" placeholder="https://api.example.com/v1" />
</div>
<!-- Vendor 提示(动态内容由 JS 填充) -->
<div id="amily2_pf_vendor_note" style="display:none; margin-bottom:8px;">
<small class="notes" style="display:block; padding:6px 10px; background:var(--black10a); border-radius:4px; border-left:3px solid var(--SmartThemeQuoteColor);">
<i class="fas fa-info-circle"></i>
<span id="amily2_pf_vendor_note_text"></span>
<span id="amily2_pf_vendor_note_link_wrap" style="display:none;">
<a id="amily2_pf_vendor_note_link" href="#" target="_blank" rel="noopener" style="color:var(--SmartThemeQuoteColor);"></a>
</span>
</small>
</div>
<div class="amily2_settings_block">
<label for="amily2_pf_key">API Key <span style="color:var(--SmartThemeQuoteColor); font-size:0.85em;">(加密存储)</span></label>
<input id="amily2_pf_key" type="password" class="text_pole" placeholder="sk-..." autocomplete="off" />
<small class="notes">留空则不修改现有 Key。</small>
</div>
<!-- 模型选择 -->
<div class="amily2_settings_block">
<label for="amily2_pf_model">模型</label>
<div style="display:flex; gap:6px; align-items:stretch;">
<input id="amily2_pf_model" type="text" class="text_pole" placeholder="手动填写或点击「获取」" style="flex:1;" />
<select id="amily2_pf_model_select" class="text_pole" style="flex:1; display:none;"></select>
<button id="amily2_pf_fetch_models" class="menu_button small_button interactable amily2-vbtn" type="button" title="从 API 获取可用模型列表(需先填写地址和 Key">
<span class="vbtn-icon"><i class="fas fa-list"></i></span><span class="vbtn-label">获取</span>
</button>
</div>
</div>
<!-- 测试连接 -->
<div style="display:flex; align-items:center; gap:10px; margin-bottom:10px;">
<button id="amily2_pf_test_conn" class="menu_button small_button interactable amily2-vbtn" type="button">
<span class="vbtn-icon"><i class="fas fa-plug"></i></span><span class="vbtn-label">测试连接</span>
</button>
<span id="amily2_pf_test_result" style="font-size:0.85em;"></span>
</div>
<!-- Chat 高级参数 -->
<div id="amily2_pf_chat_params">
<details class="amily2_advanced_section" style="margin-top:4px;">
<summary style="cursor:pointer; font-size:0.88em; color:var(--SmartThemeQuoteColor); user-select:none; padding:4px 0;">
<i class="fas fa-sliders-h"></i> 高级参数
</summary>
<div style="padding-top:8px;">
<div class="amily2_settings_block">
<label for="amily2_pf_max_tokens">最大 Token 数</label>
<input id="amily2_pf_max_tokens" type="number" class="text_pole" min="100" max="200000" value="65500" />
</div>
<div class="amily2_settings_block">
<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 class="amily2_settings_block">
<label for="amily2_pf_custom_params">
自定义参数 (JSON)
<small class="notes" style="display:block; font-weight:normal;">
透传到 LLM 请求 body 的额外参数。留空或 <code>{}</code> 表示不附加。
</small>
</label>
<textarea id="amily2_pf_custom_params"
class="text_pole"
rows="6"
spellcheck="false"
style="font-family:monospace; font-size:0.85em;"
placeholder='{
"top_p": 0.9,
"frequency_penalty": 0.3,
"stop": ["\n###"]
}'></textarea>
<small id="amily2_pf_custom_params_hint"
class="notes"
style="display:block; margin-top:4px; color:var(--SmartThemeQuoteColor); font-size:0.82em;"></small>
<small id="amily2_pf_custom_params_error"
class="notes"
style="display:none; margin-top:4px; color:var(--warning, #d9534f); font-size:0.82em;"></small>
</div>
</div>
</details>
</div>
<!-- Embedding 高级参数 -->
<div id="amily2_pf_embedding_params" style="display:none;">
<details class="amily2_advanced_section" style="margin-top:4px;">
<summary style="cursor:pointer; font-size:0.88em; color:var(--SmartThemeQuoteColor); user-select:none; padding:4px 0;">
<i class="fas fa-sliders-h"></i> 高级参数
</summary>
<div style="padding-top:8px;">
<div class="amily2_settings_block">
<label for="amily2_pf_dimensions">输出维度 <span style="color:var(--SmartThemeQuoteColor); font-size:0.85em;">(留空 = 模型默认)</span></label>
<input id="amily2_pf_dimensions" type="number" class="text_pole" min="1" placeholder="例如1536" />
</div>
<div class="amily2_settings_block">
<label for="amily2_pf_encoding_format">编码格式</label>
<select id="amily2_pf_encoding_format" class="text_pole">
<option value="float">float默认</option>
<option value="base64">base64</option>
</select>
</div>
</div>
</details>
</div>
<!-- Rerank 参数 -->
<div id="amily2_pf_rerank_params" style="display:none;">
<div class="amily2_settings_block">
<label for="amily2_pf_top_n">返回结果数量Top N</label>
<input id="amily2_pf_top_n" type="number" class="text_pole" min="1" max="100" value="5" />
</div>
<details class="amily2_advanced_section" style="margin-top:4px;">
<summary style="cursor:pointer; font-size:0.88em; color:var(--SmartThemeQuoteColor); user-select:none; padding:4px 0;">
<i class="fas fa-sliders-h"></i> 高级参数
</summary>
<div style="padding-top:8px;">
<div class="amily2_settings_block" style="flex-direction:row; align-items:center; gap:8px;">
<input id="amily2_pf_return_documents" type="checkbox" />
<label for="amily2_pf_return_documents">返回原始文档内容</label>
</div>
</div>
</details>
</div>
<!-- 操作按钮 -->
<div style="display:flex; gap:8px; margin-top:16px;">
<button id="amily2_profile_modal_cancel" class="menu_button secondary interactable amily2-vbtn">
<span class="vbtn-icon"><i class="fas fa-times"></i></span><span class="vbtn-label">取消</span>
</button>
<button id="amily2_profile_modal_save" class="menu_button interactable amily2-vbtn">
<span class="vbtn-icon"><i class="fas fa-save"></i></span><span class="vbtn-label">保存</span>
</button>
</div>
</div>
</details>