2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- story-summary.html -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="zh-CN">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
|
|
|
|
<title>剧情总结 · Story Summary</title>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<link rel="stylesheet" href="story-summary.css">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="container">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Header -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<header>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h1>剧情<span>总结</span></h1>
|
|
|
|
|
|
<div class="subtitle">Story Summary · Timeline · Character Arcs</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stats">
|
|
|
|
|
|
<div class="stat">
|
|
|
|
|
|
<div class="stat-val" id="stat-events">0</div>
|
|
|
|
|
|
<div class="stat-lbl">已记录事件</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stat">
|
|
|
|
|
|
<div class="stat-val" id="stat-summarized">0</div>
|
|
|
|
|
|
<div class="stat-lbl">已总结楼层</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="stat">
|
|
|
|
|
|
<div class="stat-val"><span class="hl" id="stat-pending">0</span></div>
|
|
|
|
|
|
<div class="stat-lbl">待总结</div>
|
|
|
|
|
|
<div class="stat-warning hidden" id="pending-warning">再删1条将回滚</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</header>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Controls -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="controls">
|
|
|
|
|
|
<label class="chk-label">
|
|
|
|
|
|
<input type="checkbox" id="hide-summarized">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<span>聊天时隐藏已总结 · <strong id="summarized-count">0</strong> 楼(保留<input type="number" id="keep-visible-count" min="0" max="50" value="3">楼)</span>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</label>
|
|
|
|
|
|
<span class="spacer"></span>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="btn-group">
|
|
|
|
|
|
<button class="btn btn-icon" id="btn-settings">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<circle cx="12" cy="12" r="3"/>
|
|
|
|
|
|
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
<span>设置</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn btn-recall" id="btn-recall">涌现</button>
|
|
|
|
|
|
<button class="btn" id="btn-clear">清空</button>
|
|
|
|
|
|
<button class="btn btn-p" id="btn-generate">总结</button>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Main Content -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<main>
|
|
|
|
|
|
<div class="left">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Keywords -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<section class="card">
|
|
|
|
|
|
<div class="sec-head">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="sec-title">核心关键词</div>
|
|
|
|
|
|
<button class="sec-btn" data-section="keywords">编辑</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="keywords" id="keywords-cloud"></div>
|
|
|
|
|
|
</section>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Timeline -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<section class="card timeline">
|
|
|
|
|
|
<div class="sec-head">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="sec-title">剧情时间线</div>
|
|
|
|
|
|
<button class="sec-btn" data-section="events">编辑</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="tl-list scroll" id="timeline-list"></div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="right">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- World State -->
|
|
|
|
|
|
<section class="card world-state">
|
|
|
|
|
|
<div class="sec-head">
|
|
|
|
|
|
<div class="sec-title">世界状态</div>
|
|
|
|
|
|
<button class="sec-btn" data-section="world">编辑</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="world-state-list scroll" id="world-state-list"></div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Relations -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<section class="card relations">
|
|
|
|
|
|
<div class="sec-head">
|
|
|
|
|
|
<div class="sec-title">人物关系</div>
|
|
|
|
|
|
<div class="sec-actions">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<button class="sec-btn sec-icon" id="btn-fullscreen-relations" title="全屏查看">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<button class="sec-btn" data-section="characters">编辑</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="relation-chart"></div>
|
|
|
|
|
|
</section>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Profile -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<section class="card profile">
|
|
|
|
|
|
<div class="sec-head">
|
|
|
|
|
|
<div class="sec-title">人物档案</div>
|
|
|
|
|
|
<div class="sec-actions">
|
|
|
|
|
|
<div class="custom-select" id="char-sel">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="sel-trigger" id="char-sel-trigger">
|
|
|
|
|
|
<span id="sel-char-text">选择角色</span>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="sel-opts" id="char-sel-opts">
|
|
|
|
|
|
<div class="sel-opt" data-value="">暂无角色</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button class="sec-btn" data-section="arcs">编辑</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="profile-content scroll" id="profile-content"></div>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</main>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Editor Modal -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="modal" id="editor-modal">
|
|
|
|
|
|
<div class="modal-bg" id="editor-backdrop"></div>
|
|
|
|
|
|
<div class="modal-box">
|
|
|
|
|
|
<div class="modal-head">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<h2 id="editor-title">编辑</h2>
|
|
|
|
|
|
<button class="modal-close" id="editor-close">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
|
<div class="editor-hint" id="editor-hint"></div>
|
|
|
|
|
|
<div id="editor-struct" class="hidden"></div>
|
|
|
|
|
|
<textarea class="editor-ta" id="editor-ta"></textarea>
|
|
|
|
|
|
<div class="editor-err" id="editor-err"></div>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="modal-foot">
|
|
|
|
|
|
<button class="btn" id="editor-cancel">取消</button>
|
|
|
|
|
|
<button class="btn btn-p" id="editor-save">保存</button>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Settings Modal -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="modal" id="settings-modal">
|
|
|
|
|
|
<div class="modal-bg" id="settings-backdrop"></div>
|
|
|
|
|
|
<div class="modal-box">
|
|
|
|
|
|
<div class="modal-head">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<h2>设置</h2>
|
|
|
|
|
|
<button class="modal-close" id="settings-close">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-body">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- API Config -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="settings-section">
|
|
|
|
|
|
<div class="settings-section-title">API 配置</div>
|
|
|
|
|
|
<div class="settings-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>渠道</label>
|
|
|
|
|
|
<select id="api-provider">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<option value="st">酒馆主 API(沿用当前)</option>
|
|
|
|
|
|
<option value="openai">OpenAI 兼容</option>
|
|
|
|
|
|
<option value="google">Google (Gemini)</option>
|
|
|
|
|
|
<option value="claude">Claude (Anthropic)</option>
|
|
|
|
|
|
<option value="custom">自定义</option>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row hidden" id="api-url-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>API URL</label>
|
|
|
|
|
|
<input type="text" id="api-url" placeholder="https://api.openai.com 或代理地址">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="settings-hint">不同渠道默认端点:OpenAI 用 /v1,Gemini 用 /v1beta,Claude 用 /v1</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row hidden" id="api-key-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>API KEY</label>
|
|
|
|
|
|
<input type="password" id="api-key" placeholder="仅保存在本地,不会上传">
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row hidden" id="api-model-manual-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>模型</label>
|
|
|
|
|
|
<input type="text" id="api-model-text" placeholder="如 gemini-1.5-pro、claude-3-haiku">
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row hidden" id="api-model-select-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>可用模型</label>
|
|
|
|
|
|
<select id="api-model-select">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<option value="">请先拉取模型列表</option>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-btn-row hidden" id="api-connect-row">
|
|
|
|
|
|
<button class="btn btn-sm btn-p" id="btn-connect">连接 / 拉取模型列表</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Gen Params -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="settings-section">
|
|
|
|
|
|
<div class="settings-section-title">生成参数</div>
|
|
|
|
|
|
<div class="settings-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>Temperature</label>
|
|
|
|
|
|
<input type="number" id="gen-temp" step="0.01" min="0" max="2" placeholder="未设置">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>Top P</label>
|
|
|
|
|
|
<input type="number" id="gen-top-p" step="0.01" min="0" max="1" placeholder="未设置">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>Top K</label>
|
|
|
|
|
|
<input type="number" id="gen-top-k" step="1" min="1" placeholder="未设置">
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>存在惩罚</label>
|
|
|
|
|
|
<input type="number" id="gen-presence" step="0.01" min="-2" max="2" placeholder="未设置">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>频率惩罚</label>
|
|
|
|
|
|
<input type="number" id="gen-frequency" step="0.01" min="-2" max="2" placeholder="未设置">
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Trigger Settings -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="settings-section">
|
|
|
|
|
|
<div class="settings-section-title">总结设置</div>
|
2026-01-29 17:45:20 +08:00
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>注入角色</label>
|
|
|
|
|
|
<select id="trigger-role">
|
|
|
|
|
|
<option value="system">System</option>
|
|
|
|
|
|
<option value="user">User</option>
|
|
|
|
|
|
<option value="assistant">Assistant</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="settings-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>自动总结间隔(楼)</label>
|
|
|
|
|
|
<input type="number" id="trigger-interval" min="5" step="5" value="20">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>触发时机</label>
|
|
|
|
|
|
<select id="trigger-timing">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<option value="after_ai">AI 回复后</option>
|
2026-01-29 17:45:20 +08:00
|
|
|
|
<option value="before_user" selected>用户发送前</option>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<option value="manual">仅手动</option>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field">
|
|
|
|
|
|
<label>单次最大总结(楼)</label>
|
|
|
|
|
|
<select id="trigger-max-per-run">
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<option value="50">50</option>
|
|
|
|
|
|
<option value="100" selected>100</option>
|
|
|
|
|
|
<option value="150">150</option>
|
|
|
|
|
|
<option value="200">200</option>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>头部包裹词(应对NoAss配置)</label>
|
|
|
|
|
|
<input type="text" id="trigger-wrapper-head" placeholder="添加到开头">
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>尾部包裹词(应对NoAss配置)</label>
|
|
|
|
|
|
<input type="text" id="trigger-wrapper-tail" placeholder="添加到结尾">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field-inline">
|
|
|
|
|
|
<input type="checkbox" id="trigger-enabled">
|
|
|
|
|
|
<label for="trigger-enabled">启用自动总结</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field-inline">
|
|
|
|
|
|
<input type="checkbox" id="trigger-stream" checked>
|
|
|
|
|
|
<label for="trigger-stream">启用流式生成</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-field-inline">
|
|
|
|
|
|
<input type="checkbox" id="trigger-insert-at-end">
|
|
|
|
|
|
<label for="trigger-insert-at-end">强制插入到聊天最后</label>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-hint" style="margin-top:8px">若 API 不支持非流式请求,请勾选"启用流式生成"</div>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- Vector Settings -->
|
|
|
|
|
|
<div class="settings-section">
|
|
|
|
|
|
<div class="settings-section-title">智能记忆(向量检索)</div>
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field-inline">
|
|
|
|
|
|
<input type="checkbox" id="vector-enabled">
|
|
|
|
|
|
<label for="vector-enabled">启用向量检索</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="vector-config-area" class="hidden">
|
|
|
|
|
|
<div class="settings-row" style="margin-top:16px">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>Embedding 引擎</label>
|
|
|
|
|
|
<div class="engine-selector">
|
|
|
|
|
|
<label class="engine-option">
|
|
|
|
|
|
<input type="radio" name="vector-engine" value="local">
|
|
|
|
|
|
<span>本地模型</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<label class="engine-option">
|
|
|
|
|
|
<input type="radio" name="vector-engine" value="online" checked>
|
|
|
|
|
|
<span>在线服务</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Local Engine -->
|
|
|
|
|
|
<div id="local-engine-area" class="engine-area hidden">
|
|
|
|
|
|
<div class="model-select-row">
|
|
|
|
|
|
<select id="local-model-select">
|
|
|
|
|
|
<option value="bge-small-zh">中文轻量 (51MB)</option>
|
|
|
|
|
|
<option value="bge-base-zh">中文标准 (102MB)</option>
|
|
|
|
|
|
<option value="e5-small">多语言 (118MB)</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="model-desc" id="local-model-desc">手机/低配适用</div>
|
|
|
|
|
|
<div class="engine-status" id="local-model-status">
|
|
|
|
|
|
<span class="status-dot"></span>
|
|
|
|
|
|
<span class="status-text">检查中...</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="engine-progress hidden" id="local-model-progress">
|
|
|
|
|
|
<div class="progress-bar"><div class="progress-inner"></div></div>
|
|
|
|
|
|
<span class="progress-text">0%</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="engine-actions" id="local-model-actions">
|
|
|
|
|
|
<button class="btn btn-sm btn-p" id="btn-download-model">下载模型</button>
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-cancel-download" style="display:none">取消下载</button>
|
|
|
|
|
|
<button class="btn btn-sm btn-del" id="btn-delete-model" style="display:none">删除缓存</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Online Engine -->
|
|
|
|
|
|
<div id="online-engine-area" class="engine-area">
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>服务渠道</label>
|
|
|
|
|
|
<select id="online-provider">
|
|
|
|
|
|
<option value="siliconflow">硅基流动(推荐)</option>
|
|
|
|
|
|
<option value="cohere">Cohere</option>
|
|
|
|
|
|
<option value="openai">OpenAI 兼容(可自建)</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row" id="online-url-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>API URL</label>
|
|
|
|
|
|
<input type="text" id="vector-api-url" placeholder="https://api.siliconflow.cn">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>API Key</label>
|
|
|
|
|
|
<input type="password" id="vector-api-key" placeholder="sk-xxx">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>模型</label>
|
|
|
|
|
|
<div style="display:flex;gap:8px">
|
|
|
|
|
|
<select id="vector-model-select" style="flex:1">
|
|
|
|
|
|
<option value="">请选择模型</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-fetch-models" style="display:none">拉取</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="engine-status" id="online-api-status">
|
|
|
|
|
|
<span class="status-dot"></span>
|
|
|
|
|
|
<span class="status-text">未测试</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-btn-row" style="justify-content:center">
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-test-vector-api">测试连接</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="provider-hint" id="provider-hint">
|
|
|
|
|
|
💡 <a href="https://siliconflow.cn" target="_blank">硅基流动</a> 免费、速度快、质量好,推荐 BAAI/bge-m3
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-29 17:02:51 +08:00
|
|
|
|
<!-- 文本过滤规则 -->
|
|
|
|
|
|
<div class="settings-row" style="margin-top:16px">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>文本过滤规则</label>
|
|
|
|
|
|
<p class="settings-hint" style="margin-bottom:8px">
|
|
|
|
|
|
遇到「起始」后跳过,直到「结束」。起始或结束可单独留空。用于过滤思考标签等干扰内容。
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<div id="filter-rules-list" style="display:flex;flex-direction:column;gap:6px"></div>
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-add-filter-rule" style="margin-top:8px">+ 添加规则</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Vector Stats -->
|
|
|
|
|
|
<div class="vector-chat-section">
|
|
|
|
|
|
<div class="settings-row">
|
|
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>当前聊天向量</label>
|
|
|
|
|
|
<div class="vector-stats" id="vector-stats">
|
|
|
|
|
|
<span>事件向量: <strong id="vector-event-count">0</strong>/<strong id="vector-event-total">0</strong></span>
|
|
|
|
|
|
<span>·</span>
|
|
|
|
|
|
<span>Chunks: <strong id="vector-chunk-count">0</strong> 个(<span id="vector-chunk-floors">0</span>/<span id="vector-chunk-total">0</span> 层)</span>
|
|
|
|
|
|
<span>·</span>
|
|
|
|
|
|
<span>消息: <strong id="vector-message-count">0</strong></span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="vector-mismatch-warning hidden" id="vector-mismatch-warning">
|
|
|
|
|
|
⚠ 引擎/模型已变更,需重新生成向量
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="engine-progress hidden" id="vector-gen-progress-l1">
|
|
|
|
|
|
<div style="font-size:.75rem;color:var(--txt3);margin-bottom:4px">L1 片段</div>
|
|
|
|
|
|
<div class="progress-bar"><div class="progress-inner"></div></div>
|
|
|
|
|
|
<span class="progress-text">0/0</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="engine-progress hidden" id="vector-gen-progress-l2">
|
|
|
|
|
|
<div style="font-size:.75rem;color:var(--txt3);margin-bottom:4px">L2 事件</div>
|
|
|
|
|
|
<div class="progress-bar"><div class="progress-inner"></div></div>
|
|
|
|
|
|
<span class="progress-text">0/0</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-hint" id="vector-perf-l1"></div>
|
|
|
|
|
|
<div class="settings-hint" id="vector-perf-l2"></div>
|
|
|
|
|
|
<div class="settings-btn-row" id="vector-action-row">
|
|
|
|
|
|
<button class="btn btn-sm btn-p" id="btn-gen-vectors">生成向量</button>
|
|
|
|
|
|
<button class="btn btn-sm btn-del" id="btn-clear-vectors">清除向量</button>
|
|
|
|
|
|
<button class="btn btn-sm hidden" id="btn-cancel-vectors">取消</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="settings-hint" style="margin-top:8px">首次生成向量可能耗时较久,页面短暂卡顿属正常。若本地模型重进酒馆后需重下。</div>
|
2026-01-29 17:02:51 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 向量导入导出 -->
|
|
|
|
|
|
<div class="vector-io-section" style="border-top:1px solid var(--bdr);padding-top:16px;margin-top:16px">
|
|
|
|
|
|
<div class="settings-row">
|
2026-01-29 17:45:20 +08:00
|
|
|
|
<div class="settings-field full">
|
|
|
|
|
|
<label>向量迁移(跨设备 / 防清缓存)</label>
|
|
|
|
|
|
<div class="settings-hint" style="margin-bottom:8px">导出/导入均为 zip 格式,勿解压</div>
|
|
|
|
|
|
<div class="settings-btn-row" id="vector-io-row" style="margin-top:8px">
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-export-vectors">导出向量</button>
|
|
|
|
|
|
<button class="btn btn-sm" id="btn-import-vectors">导入向量</button>
|
|
|
|
|
|
</div>
|
2026-01-29 17:02:51 +08:00
|
|
|
|
<div class="settings-hint" id="vector-io-status"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-26 01:16:35 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-foot">
|
|
|
|
|
|
<button class="btn" id="settings-cancel">取消</button>
|
|
|
|
|
|
<button class="btn btn-p" id="settings-save">保存</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Fullscreen Relations Modal -->
|
2026-01-17 16:34:39 +08:00
|
|
|
|
<div class="modal fullscreen" id="rel-fs-modal">
|
|
|
|
|
|
<div class="modal-bg" id="rel-fs-backdrop"></div>
|
|
|
|
|
|
<div class="modal-box">
|
|
|
|
|
|
<div class="modal-head">
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<h2>人物关系图</h2>
|
|
|
|
|
|
<button class="modal-close" id="rel-fs-close">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
|
<div id="relation-chart-fullscreen"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- HF Guide Modal -->
|
|
|
|
|
|
<div class="modal" id="hf-guide-modal">
|
|
|
|
|
|
<div class="modal-bg" id="hf-guide-backdrop"></div>
|
|
|
|
|
|
<div class="modal-box" style="max-width:900px">
|
|
|
|
|
|
<div class="modal-head">
|
|
|
|
|
|
<h2>🤗 Hugging Face Space 部署指南</h2>
|
|
|
|
|
|
<button class="modal-close" id="hf-guide-close">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-body" id="hf-guide-body"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<!-- Recall Log Modal -->
|
|
|
|
|
|
<div class="modal" id="recall-log-modal">
|
|
|
|
|
|
<div class="modal-bg" id="recall-log-backdrop"></div>
|
|
|
|
|
|
<div class="modal-box" style="max-width:900px">
|
|
|
|
|
|
<div class="modal-head">
|
|
|
|
|
|
<h2>✨ 涌现 · 记忆召回日志</h2>
|
|
|
|
|
|
<button class="modal-close" id="recall-log-close">
|
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-body" style="padding:0">
|
|
|
|
|
|
<pre id="recall-log-content"></pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-26 01:16:35 +08:00
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
|
|
|
|
|
<script src="story-summary-ui.js"></script>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</body>
|
2026-01-29 17:02:51 +08:00
|
|
|
|
</html>
|