Record the SillyTavern design borrow and shipped batches
Merge pull request 'Record the SillyTavern design borrow and shipped batches' (#37) from feature/sillytavern-review into main
This commit was merged in pull request #37.
This commit is contained in:
@@ -75,6 +75,20 @@
|
||||
| 工具调用先记意图再记结果;只有两次声明都是 safe 才重放;写文件可回滚,shell 不追踪 | pi durable README 的 Tools 与 Compaction;ZCode `contracts/rewind` | Native 的 RunState 与文件检查点。不回滚对话历史,不做透明续跑 | N3 |
|
||||
| 模型写脚本批量调用工具,中间结果不进上下文;MCP 工具可延迟暴露,首条提示不等服务器连上 | pi `packages/codemode` 与 `docs/mcp.md`;本提案 §2.1 的代码编排端口 | Native 的代码编排端口与 MCP 客户端。产品开关默认关 | N2 |
|
||||
|
||||
### 2.5 SillyTavern 对照里会改产品行为的条目(2026-10-04)
|
||||
|
||||
对照 [SillyTavern 1.19.0](https://github.com/SillyTavern/SillyTavern) `06bde939`。只借设计。许可证、评级、拒绝项和暂缓项见 [2026-10-04-sillytavern-review.md](../records/2026-10-04-sillytavern-review.md)。下列条目在同一任务里落地。
|
||||
|
||||
| 借鉴 | 来源设计 | 落到本仓 |
|
||||
|---|---|---|
|
||||
| 带标签的多密钥,同时只生效一把;读出只给掩码;迁入前先留设置快照 | 密钥与设置快照 | Backend `secret_keys` / `settings_snapshots`。运行时优先读生效密钥,否则仍读设置里的旧字段 |
|
||||
| 个人指令和会话要求附在上下文末尾 | persona 与 Author's Note | `context.userInstructions` 与会话 `sessionNote`,经 `reminders.Attach` 注入 |
|
||||
| 关键词或正则、次关键词、扫描最近 N 条、常驻、预算 | 世界书的精简子集 | `context_entries`。不做概率、递归、分组和定时 |
|
||||
| 组装时给出分段估算和系统前缀哈希;估算为 UTF-8 字节 / 3.35,并用上一请求用量校准 | 提示词分段视图 | `ContextObservation.sections` / `prefixHash`。`context.contextWindow` 只丢掉最早的历史 |
|
||||
| 合并相邻同角色;严格模式再收起多余的 system | 按 endpoint 做消息整形 | agent-native `PrepareMessages`,设置 `context.messageShape` |
|
||||
| 复制、成组排除出上下文、追加式候选回复并联动文件回滚 | 对话操作 | 不删除消息。重新生成排除旧候选,新回复写入同一 `variantGroup` |
|
||||
| 用户 `/` 命令展开成提示词 | 快捷指令 | `user_commands`,登记为 agent-command 的 `user` 来源。不自动触发 |
|
||||
|
||||
## 3. 解耦
|
||||
|
||||
三个库各自能单独编译、单独测试、单独被第三方使用。配合发生在组合根,不发生在核心模块里。
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# 调研:SillyTavern 1.19.0
|
||||
|
||||
- 状态:记录(2026-10-04);owner:weichen;任务:Dev 仓 `feature/sillytavern-review`
|
||||
- 对象:[SillyTavern/SillyTavern](https://github.com/SillyTavern/SillyTavern) `06bde939`(release 1.19.0,2026-09-14)。AGPL-3.0,另有标注 GPLv3 的 RisuAI 片段。按固定提交只读对照,不建长期克隆,不拷源码。
|
||||
- 本仓事实以任务起点 Dev `4fd03eee` 为准。前序:[2026-10-03-pi-zcode-second-pass.md](2026-10-03-pi-zcode-second-pass.md)、[2026-10-02-agent-stack-completion.md](../proposals/2026-10-02-agent-stack-completion.md)。
|
||||
- 规则与 pi / ZCode 两份记录相同:只借设计。不拷代码、提示词或界面文案。本仓各子仓没有 LICENSE、以单二进制分发,拷入 AGPL 代码会让整个产品落入 AGPL,网络使用条款同样生效。
|
||||
|
||||
结论先说:上下文工程值得借的是「统一注入登记 + 按预算组装」,平台侧值得借的是带标签的密钥、设置快照、以及听口令时拒绝无认证的对外监听。本仓的 SSRF 与账户已经更严,不借。安全缺口(输出未清洗、缺响应头、不校验来源、对外监听无认证)和下面的采纳项在同一任务里落地。扩展系统、脚本宏、群聊、角色卡、自定义 CSS、JSONL 存储、删除消息和自动触发的快捷回复不借。
|
||||
|
||||
---
|
||||
|
||||
## 1. 来源现在是什么
|
||||
|
||||
SillyTavern 把要注入模型的文本放进统一登记表:每条有位置、深度、角色、顺序和扫描范围,再由一次按 token 预算的组装把它们收成请求。预算不够时只裁最老的历史。世界书、作者注、记忆和向量库都走这条登记,而不是各写一条拼接。
|
||||
|
||||
平台侧用带标签的多密钥(同一服务一把生效)、设置快照、以及「监听且未开认证就拒绝启动」。请求侧还有 Host / Origin 检查。聊天用 JSONL,带滑动候选和父指针检查点。扩展是未沙箱的同源脚本。
|
||||
|
||||
本仓已经有更严的 SSRF(`fetch_url` 和链接预览在拨号时校验解析出的 IP,黑名单含 `0.0.0.0/8` 和 `100.64.0.0/10`)和账户(argon2id、重置密码即吊销服务端会话、登录限流)。这些不改。
|
||||
|
||||
## 2. 对照时核实的安全缺口
|
||||
|
||||
行号是任务起点那一版本仓源码,实施后位置会移动。
|
||||
|
||||
| 缺口 | 起点位置 | 处置 |
|
||||
|---|---|---|
|
||||
| 模型输出、卡片和文档预览把 HTML 直接写入页面。`marked` 15.0.12 不清洗 | Frontend `Conversation.tsx`、`previewsetup.ts`;UI `UIRenderer.tsx`、`FilePreview.tsx` | `@ui` 的 `safeHtml` 成为唯一写入点。外部图片改成「外部图片 · 域名」链接。同源地址不再用 `allow-same-origin` 内嵌 |
|
||||
| 没有 CSP / nosniff。HTML 工件按页面直出 | Backend `server.go` 的静态页与 `artifactContent` | 页面 CSP、nosniff、`Referrer-Policy`。html/svg/xml 工件加 `sandbox` |
|
||||
| 不校验 Origin / Host。SQLite 档默认不开认证 | `app.go` 的认证开关 | `RequestGuard` 包在组合根。写请求核对 Origin 或 `Sec-Fetch-Site`。未开认证时 Host 只允许 IP、`localhost` 和 `allowedHosts` |
|
||||
| 对外监听且未开认证时照常启动 | `.env.dev` 曾把 dev 听在 `0.0.0.0:8788` | 非回环、未开认证、又没有 `--insecure-listen` 时,打开数据库之前拒绝启动 |
|
||||
|
||||
## 3. 采纳并已在本任务实施
|
||||
|
||||
原先记为后续批次。任务范围改为同一任务做完,落点如下。
|
||||
|
||||
| 主题 | 上游设计 | 本仓落点 |
|
||||
|---|---|---|
|
||||
| 密钥独立存储 | `src/endpoints/secrets.js`:多把带标签的 key,一把生效,读出只给掩码,迁移前备份 | `secret_keys`。GET 只返回掩码。启动时先写设置快照,再把 `models.*.apiKey` 和 `tools.tavily.apiKeys` 迁入并从表单设置清掉。运行时优先用生效密钥 |
|
||||
| 设置快照 | 启动和保存后留档。上游恢复前不留档,这一点不照搬 | `settings_snapshots`。正文与上一份相同则跳过。保存间隔短于 10 分钟则跳过 |
|
||||
| 个人指令与会话要求 | persona 与 Author's Note | `context.userInstructions` 与会话 `sessionNote`。经 agent-native `reminders.Attach` 附在最后一条用户或工具消息上,系统前缀不动 |
|
||||
| 条件注入 | 世界书的关键词、次关键词逻辑、扫描深度、常驻、顺序、预算 | `context_entries`。`matchModule` 仍只看本轮子串;条目在组装末尾另判 |
|
||||
| 上下文快照 | 提示词分段视图 | `ContextObservation` 增加 `sections` 与 `prefixHash`。界面折叠条显示估算 token 和前缀哈希 |
|
||||
| 估算口径 | 上游按 token 预算裁历史 | 统一为 UTF-8 字节 / 3.35,再用上一请求的 prompt token 校准。`context.contextWindow` 进入 schema,默认 32000,只丢掉最早的历史 |
|
||||
| 消息整形 | `src/prompt-converters.js` | `PrepareMessages`。`merge` 合并相邻同角色。`strict` 再把第一条之后的 system 收成 user。工具调用和结果不合并 |
|
||||
| 复制、排除、候选回复 | 滑动候选与检查点 | 复制在界面完成。排除按消息及其同一 run 成组,记录仍在。重新生成不删旧回复,写入同一 `variantGroup`,并按用户消息做文件回滚 |
|
||||
| 用户 `/` 命令 | 快捷指令,但不做自动触发 | `user_commands`。名称符合 `user.<slug>` 时登记为 agent-command 的 `SourceUser`。发送时把模板展开成普通用户消息 |
|
||||
|
||||
## 4. 暂缓
|
||||
|
||||
- Claude 缓存断点:等 Anthropic 原生协议。
|
||||
- 编辑重发与会话分支:等候选回复用过再看父指针方案。
|
||||
- 窗口外同会话召回、用户级知识库:等会话经常超出窗口再看。
|
||||
- 世界书的概率、递归、包含组和定时效果。
|
||||
- 密钥静态加密。
|
||||
- i18n:真要做时不能拿原文当键。
|
||||
- 出站代理:只能用于模型端点。
|
||||
- 画像导入导出。
|
||||
|
||||
## 5. 拒绝
|
||||
|
||||
- 拷代码、提示词和界面文案。
|
||||
- 扩展系统(同源 JS、没有沙箱)和带完整 Node 权限的服务器插件。
|
||||
- STscript 和宏语言。
|
||||
- 群聊、角色卡、视觉小说。
|
||||
- 自定义 CSS 和平滑打字流式:与 DESIGN.md 冲突。
|
||||
- JSONL 整文件覆盖和逐行扫描搜索。
|
||||
- 删除消息。用「排除出上下文」代替。
|
||||
- 自动执行的快捷回复触发器。
|
||||
|
||||
## 6. 不回退的既有决定
|
||||
|
||||
认证默认仍是 `auto`:显式 `on`,或不是 `off` 且配置了 DSN,才开认证。不加 CSRF token,不加 CSP 上报端点。不改 SSRF 黑名单,不改账户哈希和会话吊销。
|
||||
Reference in New Issue
Block a user