落档自动把产物挂进 context_order;创作期用 declare_variable/declare_map 钉目录与分档;真值变更持续重投影。顺带强制 tools 请求 reasoning_effort=none,并支持消息 restart。 Co-authored-by: Cursor <cursoragent@cursor.com>
175 lines
7.0 KiB
HTML
175 lines
7.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>设置 · Writing Agent</title>
|
|
<link rel="stylesheet" href="/settings.css" />
|
|
</head>
|
|
<body class="settings-page">
|
|
<header class="st-top">
|
|
<a class="st-brand" href="/">Writing Agent</a>
|
|
<nav class="st-nav" aria-label="主导航">
|
|
<a href="/">对话</a>
|
|
<a href="/modules.html">技能</a>
|
|
<a href="/shells.html">呈现壳</a>
|
|
<a href="/stats.html">Token</a>
|
|
<a href="/settings.html" aria-current="page">设置</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<div class="st-shell">
|
|
<aside class="st-rail" aria-label="设置分类">
|
|
<p class="st-rail-label">设置</p>
|
|
<button type="button" class="st-rail-item active" data-section="api">API</button>
|
|
<button type="button" class="st-rail-item" data-section="preset">预设</button>
|
|
<button type="button" class="st-rail-item" data-section="storage">上下文</button>
|
|
<p class="st-rail-note">保存在本机 <code>~/.writing-agent/</code>,明文、不同步。</p>
|
|
</aside>
|
|
|
|
<main class="st-main">
|
|
<header class="st-main-head">
|
|
<div>
|
|
<h1 id="panel-title">API</h1>
|
|
<p class="st-sub" id="panel-subtitle">管理 LLM 连接</p>
|
|
</div>
|
|
<div class="st-main-actions" id="panel-actions"></div>
|
|
</header>
|
|
|
|
<div class="st-status" id="active-settings-bar"></div>
|
|
<div class="settings-toast" id="settings-toast" hidden></div>
|
|
|
|
<div class="st-body">
|
|
<section class="settings-section" id="section-api">
|
|
<div id="profiles-list" class="card-list"></div>
|
|
</section>
|
|
|
|
<section class="settings-section hidden" id="section-preset">
|
|
<div id="presets-list" class="card-list"></div>
|
|
<pre id="import-report" class="import-report" hidden></pre>
|
|
</section>
|
|
|
|
<section class="settings-section hidden" id="section-storage">
|
|
<div class="settings-card storage-card">
|
|
<h3>LLM 请求上下文</h3>
|
|
<p class="settings-help">
|
|
每次模型调用可保存完整 prompt。默认每个对话只保留最新若干条;更早消息仍在,但去掉上下文痕迹。可在对话里查看上下文。
|
|
</p>
|
|
<label class="field">
|
|
每个对话保留最新条数
|
|
<input
|
|
type="number"
|
|
id="context-trace-keep"
|
|
min="0"
|
|
max="50"
|
|
step="1"
|
|
value="5"
|
|
/>
|
|
</label>
|
|
<p class="settings-help muted">0 = 不保存;最大 50。保存后对新回复立即生效。</p>
|
|
<div class="storage-actions">
|
|
<button type="button" class="btn-primary" id="btn-save-context-keep">保存</button>
|
|
<button type="button" class="btn-secondary" id="btn-prune-context">修剪已打开会话</button>
|
|
<button type="button" class="btn-secondary danger-outline" id="btn-clear-context">清除全部痕迹</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<dialog id="preset-probe-dialog" class="probe-dialog">
|
|
<header class="probe-head">
|
|
<div>
|
|
<h3>试跑预设</h3>
|
|
<p class="probe-sub" id="probe-preset-name"></p>
|
|
</div>
|
|
<button type="button" class="btn-secondary" id="probe-close">关闭</button>
|
|
</header>
|
|
<div class="probe-body">
|
|
<section class="probe-composer">
|
|
<label>
|
|
本轮输入
|
|
<textarea id="probe-message" rows="4" placeholder="发给模型的这一轮"></textarea>
|
|
</label>
|
|
<details class="probe-extras">
|
|
<summary>试跑用设定 / 历史</summary>
|
|
<label>
|
|
历史前(设定)
|
|
<textarea id="probe-lore-before" rows="3"></textarea>
|
|
</label>
|
|
<label>
|
|
对话历史
|
|
<textarea id="probe-history" rows="4"></textarea>
|
|
</label>
|
|
<label>
|
|
历史后(状态)
|
|
<textarea id="probe-lore-after" rows="3"></textarea>
|
|
</label>
|
|
<label>
|
|
本轮后(可选)
|
|
<textarea id="probe-post-turn" rows="2"></textarea>
|
|
</label>
|
|
</details>
|
|
<div class="probe-composer-actions">
|
|
<button type="button" class="btn-primary" id="probe-send">发送一轮</button>
|
|
<p class="probe-status" id="probe-status" hidden></p>
|
|
</div>
|
|
</section>
|
|
<section class="probe-inspect" aria-live="polite">
|
|
<h4>发出的上下文</h4>
|
|
<div id="probe-messages" class="probe-messages">
|
|
<p class="probe-empty">发送后显示实际拼进请求的消息。</p>
|
|
</div>
|
|
<div id="probe-reply-wrap" class="probe-reply" hidden>
|
|
<h4>模型回复</h4>
|
|
<pre id="probe-reply"></pre>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</dialog>
|
|
|
|
<dialog id="profile-dialog" class="profile-dialog">
|
|
<form id="profile-form" method="dialog">
|
|
<h3 id="profile-dialog-title">新增 API</h3>
|
|
<label>
|
|
名称
|
|
<input name="name" required placeholder="例如 DeepSeek" autocomplete="off" />
|
|
</label>
|
|
<label>
|
|
Base URL
|
|
<input name="baseUrl" required placeholder="https://api.deepseek.com" />
|
|
</label>
|
|
<label>
|
|
API Key
|
|
<input name="apiKey" type="password" placeholder="sk-…" autocomplete="off" />
|
|
</label>
|
|
<label>
|
|
Model
|
|
<input name="model" required placeholder="deepseek-chat" />
|
|
</label>
|
|
<label>
|
|
思考强度
|
|
<select name="reasoningEffort">
|
|
<option value="">默认(不发送)</option>
|
|
<option value="none">none · 关闭思考(带 tools 时自动用)</option>
|
|
<option value="low">low · 轻量</option>
|
|
<option value="medium">medium</option>
|
|
<option value="high">high · 增强</option>
|
|
<option value="max">max · 深度</option>
|
|
</select>
|
|
<span class="field-hint">写入 reasoning_effort;「探测」始终用 low,与此项无关。带 function tools 的请求会强制 none(兼容 gpt-5.6-luna 等)。GLM 建议 low / high / max。</span>
|
|
</label>
|
|
<div class="dialog-actions">
|
|
<button type="button" id="profile-cancel" class="btn-secondary">取消</button>
|
|
<button type="button" id="profile-save" class="btn-secondary">仅保存</button>
|
|
<button type="submit" class="btn-primary">保存并选用</button>
|
|
</div>
|
|
</form>
|
|
</dialog>
|
|
|
|
<input type="file" id="preset-file" accept=".json,application/json" hidden />
|
|
<script src="/settings.js" type="module"></script>
|
|
</body>
|
|
</html>
|