dsh-tavern
把 DSH(deepseek-harness)扩展成兼容 SillyTavern 生态的原生角色扮演工作区。
当前状态
第一版主线已经可用:插件复用 DSH 的 LLM 路由、默认模型、密钥管理、Web 容器和插件安装机制,同时在 DSH 原生侧边栏和 conversation 区域提供 Tavern 角色扮演体验。管理入口是独立的 Tavern 面板;设置页保留当前配置的快速切换,不再承载全部资产管理表单。
当前面向 DSH 0.1.0-rc.6 验证。Fabric 不在第一版运行路径中。
能力
- Character Card V1/V2/V3:JSON、PNG
chara/ccv3,以及 CHARXcard.json和embeded://assets。 - World Info / Lorebook:递归扫描、副键逻辑、概率、预算、inclusion group、sticky/cooldown/delay 和位置分发。
- Chat Completion preset:
prompts[]、prompt_order[]、marker 和采样参数。 - SillyTavern chat JSONL:header、messages、
swipes、swipe_id、swipe_info。 - RP 交互:流式生成、Stop、消息编辑、swipe、regenerate、聊天创建、重命名和确认删除。
- 消息分支 / bookmark:任意消息一键分支为新聊天,
chat_metadata.bookmark_link回链,视图可跳回父聊天。 - Persona 管理:PNG 导入(内嵌描述提取)、头像、增删改、激活选择与
position/depth/role注入。 - 群聊:成员管理、自然(talkativeness 加权)/列表激活策略、成员点触发言、
group_only_greetings、group nudge 和{{group}}宏。 - 正则脚本:ST regex 扩展形态导入,全局 + 卡级合并,
USER_INPUT/AI_OUTPUT/WORLD_INFO/REASONINGplacement、minDepth/maxDepth、substituteRegex、trimStrings。 - STscript:管道、变量(聊天局部 + 全局)、
/if条件、随机/掷骰和聊天动作(/send、/trigger、/regenerate、/cut),composer/前缀触发。 - Text Completion / Kobold:context(story_string
{{#if}}子集)、instruct、textgen 采样器 preset 装配单串 prompt,KoboldAI/KoboldCpp SSE 流式 + 单发回退,端点/密钥/预设配置与连接测试。 - Composer 模型选择:复刻 DSH 原生 model seat 的 provider 分组目录与 Effort 二级菜单,按 session 持久化,未选择时回落 DSH 默认模型。
- 并发保护:聊天使用内容 revision 做 compare-and-swap;跨标签页冲突返回
409,客户端重新加载最新内容,不静默覆盖。 - 可选的普通 Agent 人格注入,默认关闭。
- AgentTavern 原生模式:单角色新聊天默认复用 DSH AgentLoop、原生 composer、Stop、错误处理和统计;角色、世界书、场景、记忆和变量通过会话级工具按需读取,原生事件幂等投影回 Tavern JSONL。可选开关会在新 AgentTavern 会话初始化时一次性预载角色信息和常驻世界书条目,默认关闭且不追溯修改已有会话。现有 ST 兼容架构继续保留。
- AgentTavern managed 模式:在 DSH
0.1.0-rc.6上保持关闭。宿主尚未提供agent/context历史投影和 projection-aware compaction,插件不会把普通 compaction 冒充为主动遗忘,也不会静默回退到伪 managed 模式。详见docs/exploration/2026-08-16-dsh-agentloop-native-audit.md。 - 美化前端:助手消息中的完整 HTML 文档或
html代码块会在隔离 iframe 中运行,支持内联 CSS、JavaScript 和常用 CDN 资源;普通文本与不完整流式内容仍按文本显示。
酒馆美化前端
把完整 HTML 文档、<head>/<body> 片段放进助手消息,或使用 html Markdown 代码块。消息保存后,
Tavern transcript 会识别并挂载前端;流式生成和编辑消息时仍显示源码,避免半成品脚本被重复执行。
支持的输入形式:
- 完整文档:
<!doctype html>...或同时包含<html>与<head>/<body>的文档。 - HTML 片段:包含
<head>或<body>的片段;缺少外层文档时,运行时会自动补齐doctype、viewport 和基础样式。 - Markdown fenced code block:代码块语言可以写成
html;普通代码块和不完整 HTML 仍按文本显示。
例如:
```html
<!doctype html>
<html>
<body>
<button id="counter">0</button>
<script>
let count = 0
document.querySelector('#counter').onclick = () => {
document.querySelector('#counter').textContent = String(++count)
}
</script>
</body>
</html>
```
每个前端使用 sandbox="allow-scripts" 的独立 iframe,且不授予 allow-same-origin:脚本不能读取或操作宿主页面、
Cookie、window.parent、TavernHelper 和 DSH API(高度回传仅使用受校验的 postMessage)。运行时 CSP 允许内联 CSS/JavaScript,
以及以下静态资源源:cdn.jsdelivr.net、testingcf.jsdelivr.net、cdn.tailwindcss.com、
cdnjs.cloudflare.com、unpkg.com、esm.sh、fonts.googleapis.com 和 fonts.gstatic.com;图片、字体和媒体
可使用 https:、data: 或 blob: URL。
以下能力明确不在运行时范围内:
fetch、XHR、WebSocket 等业务网络连接(connect-src 'none')。- 嵌套 iframe、
object/插件、表单提交和访问宿主 DOM、Cookie、存储或 API。 - 依赖 SillyTavern 宿主注入对象的脚本;需要这些对象时应改为自包含 HTML/JS。
iframe 高度由 ResizeObserver 回传,并限制在 80-1200px;超出部分在 iframe 内滚动。TUI/headless
仍显示原始消息文本,不执行前端脚本。
安装插件并重启 DSH 后,可以在 Tavern 聊天中发送上面的示例,或让模型生成一个带按钮的 html 代码块,
保存消息后点击按钮即可验证 HTML、CSS 和 JavaScript 是否正常运行。
Tavern 管理面板
点击 DSH 原生侧栏底部的 Tavern 按钮即可打开管理面板。面板采用与 DSH Settings 接近的两栏布局,左侧切换分区,右侧集中处理资产和行为配置;窄屏会自动将分区导航折叠为横向滚动栏。
面板包含以下分区:
- 总览:查看当前角色、预设、人设、世界书开关和各类资产数量。
- 角色卡:导入 PNG、CHARX、JSON;查看卡面;编辑名称、昵称、描述、性格、场景、开场白、示例对话、系统提示词、作者信息和高级 JSON;保存时尽量保留原始 PNG/CHARX 容器及内嵌资源;可导出原格式并删除角色及其聊天。
- 世界书:导入和导出原生世界书 JSON;编辑世界书名称、条目关键词、次关键词、备注、正文、排序、深度、概率、启用、常驻和选择性匹配;支持新增、删除和搜索条目。
- 预设:导入和导出原生 preset JSON;聊天补全预设可以编辑提示词堆栈、标识符、角色、内容和 marker;context、instruct、textgen sampler 等预设可以通过高级 JSON 编辑全部字段。
- 聊天、群组、人设、正则、变量、生成:沿用原有管理能力,并统一放在同一面板中,避免在设置页堆叠长表单。
编辑器会显示未保存状态,取消离开时提示确认,页面关闭时提供浏览器级离开保护。角色卡、世界书和预设的保存都经过服务端格式校验,再写回 $DSH_HOME/tavern/。
原生集成
插件保留独立的 RP prompt/生成循环,但 UI 进入 DSH 原生表面:
| DSH slot | 用途 |
|---|---|
conversation.view |
Tavern JSONL transcript |
conversation.composer |
Tavern session 的 RP 输入框、模型选择与 Stop |
conversation.session.header.actions |
当前角色、regenerate 与原生 session stats |
settings.section |
Active setup 快速切换与打开 Tavern 面板的入口 |
shell.overlay |
Tavern 管理面板 Modal,以及侧栏聊天树 adapter 的生命周期承载 |
sidebar.footer.action |
常驻 Tavern 面板按钮,与原生 Settings 并列 |
DSH rc.6 没有可追加到原生 session tree 的正式 list slot。侧边栏因此使用一个集中、版本敏感但失败关闭的 DOM adapter:只匹配可见左侧 [role="tree"],按 workspace 路径/ID 隐藏 Tavern (internal) 分组,并按 state.sessionBindings 过滤旧版 Tavern 会话行;同时插入具名 data-dsh-tavern-sidebar-host。宿主重绘或虚拟列表更新时会重新应用过滤,解绑或卸载时可逆恢复。面板入口本身走官方 sidebar.footer.action,不会替换 Settings,也不依赖 adapter 是否成功挂载。
每个 Tavern chat 绑定一个正式 DSH session。绑定 API 通过插件内部桥接追加 plugin notice marker,使 session 进入 active 状态而不调用模型;Tavern view、composer 和标题栏 action 仅接管带有效 Tavern marker 的 session,普通 DSH 会话保持原生表面。酒馆标题栏会局部隐藏 DSH 自带的 agent preset 标签,并在切换回普通会话时恢复;Tavern 自建生成循环会把 turn/step、流式 chunk、assistant message 和 provider usage 镜像进同一 session,因此标题栏直接复用 DSH 的 sessionStats / tokenUsage projection。删除聊天时会追加 close marker 并归档对应 DSH session。
AgentTavern 当前状态
| 架构 / 模式 | 状态 | 实际行为 |
|---|---|---|
agent-tavern + dsh-native |
rc.6 可用,单角色新聊天默认启用 | 使用 DSH 原生 AgentLoop 和 composer;模型、工具调用、Stop、错误与统计都由宿主处理,原生 user/final assistant 事件投影到 Tavern JSONL。 |
agent-tavern + agent-managed |
rc.6 不可用 | 设置页显示宿主缺少 agent/context 与 projection-aware compaction 的原因并禁用选项;服务端也会拒绝该模式。 |
st |
保留并兼容 | 使用 Tavern 自有 /generate、流式生成、swipe、regenerate、STscript 和 Text Completion 路径。 |
| 群聊 | 固定使用 st |
宿主尚未提供可靠的 actor 元数据前,不创建群聊 AgentTavern 会话。 |
AgentTavern 工具的身份来自真实 DSH agent binding,模型不能通过参数伪造 sessionId、scopeId、角色或聊天身份。当前工具面如下:
| 工具 | 作用 |
|---|---|
tavern_character_get |
读取当前绑定角色的名称、昵称、描述、性格、场景和角色卡版本。 |
tavern_lore_search |
按查询词和预算检索全局启用、角色关联及卡内嵌世界书。 |
tavern_scene_get |
读取当前绑定聊天的场景、消息数量和聊天元数据。 |
memory_search |
在当前 chat、character 或 agent 作用域做有来源的词法记忆检索。 |
memory_write |
在选定作用域写入带来源、标签、置信度和 revision 的记忆。 |
variable_get |
读取当前作用域中的 typed JSON 变量。 |
variable_set |
写入变量并支持 expected revision 的 CAS 冲突保护。 |
ST 与 AgentTavern 新聊天共用 $DSH_HOME/tavern/workspace/ 下的 Tavern (internal) 工作区;插件按 workspace 路径/ID 从原生侧边栏隐藏整个分组,旧宿主没有身份属性时仅在标题唯一时回退。升级前已经存在的宿主会话不会跨工作区迁移,但绑定的 Tavern 会话行仍会按插件过滤。
Packages
| Package | 说明 |
|---|---|
@dsh-tavern/format |
卡、PNG/CHARX、世界书、preset(chat completion / context / instruct / textgen)、群组文件、regex 脚本和 chat JSONL 的解析与无损往返 |
@dsh-tavern/lore |
World Info 激活和 timed effects 引擎 |
@dsh-tavern/macros |
角色、时间、随机、变量等宏引擎 |
@dsh-tavern/pipeline |
preset 顺序、lore、persona、历史和 token budget 的 prompt 装配(chat completion + text completion + 群聊回合) |
@dsh-tavern/script |
ST regex 脚本执行器与 STscript 解释器 |
@dsh-tavern/store |
$DSH_HOME/tavern/ 原子文件存储、revision 和 session binding |
dsh-tavern |
自包含 Node half、Web client half、安装元数据和 gates |
安装
要求 Node.js 22+,并已安装 DSH。
首次安装
git clone https://github.com/LingyeSoul/dsh-tavern.git
cd dsh-tavern
pnpm install
pnpm run build:plugin
dsh plugin --profile web add ./packages/plugin
dsh --profile web
更新
dsh plugin add 以本地 link 方式挂载插件,因此代码更新后只需重新构建并重启 DSH:
cd dsh-tavern
git pull
pnpm install
pnpm run build:plugin
dsh --profile web
若遇到依赖残留或版本不一致,可先移除再重新添加:
dsh plugin --profile web remove dsh-tavern
dsh plugin --profile web add ./packages/plugin
验证
pnpm run check
打开 DSH 后:
- 点击侧栏底部的 Tavern 按钮,或从“设置 -> dsh-tavern”打开 Tavern 面板。
- 在“角色卡 / 世界书 / 预设”分区导入资产;导入后可以直接编辑、保存、搜索、设为当前或导出。
- 在设置中选择新聊天架构(rc.6 默认是 AgentTavern/native);群聊始终使用 ST。
- 在原生左侧 Tavern 分支展开角色并创建或打开单角色聊天:AgentTavern 使用 DSH 原生 conversation,ST 使用原生
Taverntab。 - 在 ST 聊天中验证编辑、swipe、regenerate 和 STscript;在 AgentTavern 聊天中验证原生 composer、工具调用、Stop 和会话统计。
插件 Node bundle 是单一 packages/plugin/index.mjs,五个纯库均已内联。无需用户额外安装公共 @deepseek-ai/* 运行时依赖;client closure 由 DSH profile 注入。
验证
pnpm run check
当前基线:21 个测试文件、169 项测试通过;11 个插件 gates(含 AgentTavern 隔离、native header adapter、内部工作区和 client VM mount)全部通过。完整 pnpm run check 需要可解析 DSH 官方运行时;本仓库验证使用 DSH 0.1.0-rc.6 的隔离 runtime。
GUI 已在桌面和 390x844 移动视口验证,包括原生 sidebar、Tavern 管理面板、角色卡/世界书/预设编辑器、conversation view/composer、流式生成、Stop、edit、swipe、regenerate、rename/delete 和 revision 冲突。
文档
docs/proposals/0001-tavern-architecture.md:当前架构、边界与后备路线。docs/proposals/0002-branch-persona-groups-script-textcompletion.md:branch/bookmark、persona 管理、群聊、STscript/regex 与 Text Completion/Kobold 的范围与格式。docs/exploration/2026-08-14-fabric-architecture.md:Fabric 调研与后备定位。docs/exploration/2026-08-14-st-formats.md:SillyTavern 互操作格式与行为参考。decisions/2026-08-14-card-raw-passthrough.md:角色卡未知字段透传决策。decisions/2026-08-15-v2-feature-scope.md:v2 功能面的范围与形态选择。docs/proposals/0003-tavern-management-panel.md:Tavern 管理面板的信息架构、slot 选择和交互范围。docs/proposals/0004-agent-tavern-architecture.md:AgentTavern 原生 AgentLoop 架构、记忆/变量工具、遗忘策略和 ST 兼容模式。docs/plans/2026-08-16-agent-tavern-implementation.md:AgentTavern 的分阶段施工计划、宿主门禁、迁移规则与验证矩阵。docs/exploration/2026-08-16-dsh-agentloop-native-audit.md:DSH0.1.0-rc.6原生注入、compaction 与 Fabric fallback 审计。decisions/2026-08-15-tavern-management-panel.md:面板入口、角色删除级联、变量与侧栏共存的落地决策。
插件管理
已安装插件建议使用 plugin-registry 的薄控制台管理 profile 中的 bundle 层栈、insert 行和启停状态,避免手改配置。将 <plugin-registry> 替换为该工具仓库的本地路径:
dsh plugin --profile web add <plugin-registry>/packages/plugin/console
许可
GPL-3.0。项目只实现公开规范和可观察行为语义,不复制 SillyTavern 的 AGPL 源码。Fabric 与 dsh-ads 仅用于架构调研;第一版运行时不依赖它们。
还没有评论,来写第一条。