🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

酒馆角色扮演 LingyeSoul/DSH-SoulMojito

DeepSeek Harness
LingyeSoul13 天前有提交已提供中文文档扫描:含敏感能力

把 DSHdeepseek-harness扩展成兼容 SillyTavern 生态的原生角色扮演工作区。

44.9/100
综合分
28
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/19 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add LingyeSoul/DSH-SoulMojito
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · skill
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 13 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-soulmojito(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/25 15:01:08

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 53 处,展示前 44 条)
  • 读取本地文件
    packages/plugin/agent.mjs:6437
    return readdirSync(root).length > 0;
  • 读取本地文件
    packages/plugin/agent.mjs:6459
    for (const entry of readdirSync2(modelDir).sort()) {
  • 读取本地文件
    packages/plugin/agent.mjs:6461
    const info = statSync(full);
  • 读取本地文件
    packages/plugin/agent.mjs:6465
    for (const child of readdirSync2(full).sort()) {
  • 读取本地文件
    packages/plugin/agent.mjs:6466
    const childInfo = statSync(join7(full, child));
  • 读取本地文件
    packages/plugin/agent.mjs:6497
    names = readdirSync2(join7(modelDir, "onnx"));
  • 读取本地文件
    packages/plugin/card-workbench.mjs:4431
    return readdirSync(root).length > 0;
  • 读取本地文件
    packages/plugin/compaction.mjs:74
    return readdirSync(root).length > 0;
  • 执行外部命令固定命令
    packages/plugin/novel.mjs:5936
    execFile("powershell.exe", ["-NoProfile", "-Command", `(Get-CimInstance Win32_Process -Filter "ProcessId = ${pid}").CommandLine`], { timeout: 5e3, win
  • 执行外部命令固定命令
    packages/plugin/novel.mjs:5953
    execFile("ps", ["-p", String(pid), "-o", "command="], { timeout: 5e3 }, (error, stdout) => {
  • 读取本地文件
    packages/plugin/novel.mjs:8193
    return readdirSync(root).length > 0;
  • 读取本地文件
    packages/plugin/src/build-info.ts:28
    const packageData = JSON.parse(readFileSync(packagePath, 'utf8'))
  • 读取本地文件
    packages/plugin/src/build-info.ts:43
    const generated = JSON.parse(readFileSync(resolve(import.meta.dirname, 'version.json'), 'utf8'))
  • 执行外部命令固定命令
    packages/plugin/src/build-info.ts:72
    const git = (args: string[]) => execFileSync('git', args, {
  • 读取本地文件
    packages/plugin/src/dsh-home.ts:47
    return readdirSync(root).length > 0
  • 发起网络请求
    packages/plugin/src/frontend-generation.ts:187
    response = await fetch(endpoint, {
  • 发起网络请求
    packages/plugin/src/frontend-generation.ts:440
    response = await fetch(`${target.baseUrl}/chat/completions`, {
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:79
    for (const entry of readdirSync(modelDir).sort()) {
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:81
    const info = statSync(full)
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:85
    for (const child of readdirSync(full).sort()) {
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:86
    const childInfo = statSync(join(full, child))
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:152
    names = readdirSync(join(modelDir, 'onnx'))
  • 读取本地文件
    packages/plugin/src/memory-embed-local.ts:160
    const info = statSync(join(modelDir, file))
  • 执行外部命令来自配置/变量
    packages/plugin/src/memory-embed-local.ts:434
    const child = spawn(command, [...args], {
  • 写入本地文件
    packages/plugin/src/workspace.ts:11
    await mkdir(path, { recursive: true })
  • 写入本地文件
    packages/plugin/src/workspace.ts:17
    await mkdir(path, { recursive: true })
  • 读取本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:158
    const text = await readFile(metaPath(dir), 'utf8')
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:192
    await rename(source, target)
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:196
    await rm(target, { force: true })
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:197
    await rename(source, target)
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:211
    await mkdir(dir, { recursive: true })
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:215
    await writeFile(temporary, `${JSON.stringify(database)}`, 'utf8')
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:219
    await rm(temporary, { force: true })
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:325
    await rename(source, destination)
  • 写入本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:347
    await copyFile(source, staged)
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:351
    await rm(staged, { force: true })
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:356
    await rm(source, { force: true })
  • 读取本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:378
    const size = (await stat(temporaryPath)).size
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:393
    await rm(destination, { force: true })
  • 读取本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:435
    const info = await stat(path)
  • 删除本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:463
    await rm(recordPath(root, character, name, store, key), { force: true })
  • 读取本地文件
    packages/tavern-frontend-storage/src/idb-store.ts:493
    existed = (await stat(directory)).isDirectory()
  • 执行外部命令固定命令
    packages/tavern-store/src/novel-owner.ts:30
    execFile('powershell.exe', ['-NoProfile', '-Command', `(Get-CimInstance Win32_Process -Filter "ProcessId = ${pid}").CommandLine`], { timeout: 5000, wi
  • 执行外部命令固定命令
    packages/tavern-store/src/novel-owner.ts:44
    execFile('ps', ['-p', String(pid), '-o', 'command='], { timeout: 5000 }, (error, stdout) => {
扫描于 2026/10/29(2 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 扩展为角色扮演工作区
展开完整介绍(126 字)↓

把 DSH(deepseek-harness)扩展成兼容 SillyTavern 生态的角色扮演工作区。角色卡、世界书、预设、MVU变量结算、Mod 扩展——资产与数据都在你自己的机器上,LLM 跑在你自己的 DSH 路由与原生 AgentLoop 里

README

由 DeepSeek 最新模型翻译生成
DSH-SoulMojito 把 DSH(deepseek-harness)扩展成兼容 SillyTavern 生态的原生角色扮演工作区。 v0.6.7 · 面向 DSH 0.2.1-rc.2(兼容 0.2.0-rc.2) · GPL-3.0 这是什么 DSH-SoulMojito 是 DSH 官方 bundle 形态的插件包(dsh-soulmojito)。它做四件事: 1. 接住 SillyTavern 生态 —— 角色卡、世界书、预设、正则脚本、STscript、EJS Prompt Template、群聊、persona 与 JSONL 聊天记录都可导入、编辑、导出,尽量无损往返。 2. 把角色扮演交给 DSH 原生 AgentLoop —— 单角色新聊天默认跑在宿主原生 conversation 上;插件只提供角色资产、工具面与投影,不拥有第二个主循环。 3. 补齐 DSH 没有的内容生产面 —— 全自动小说推演、对话改卡的卡片工作台、剧本游玩、MVU 变量结算、提示词查看器。 4. 留出扩展位 —— Mod 扩展接口(五相位 hook + 能力面)与 Agent 游戏桥(标准引擎契约 + 九款内置)。 插件复用 DSH 的 LLM 路由、默认模型、密钥管理、Web 容器与插件安装机制,不引入第二套模型配置。Fabric 不在运行路径中,仅作架构调研。
展开完整文档(README 剩余 1 节)
DSH-SoulMojito

把 DSH(deepseek-harness)扩展成兼容 SillyTavern 生态的原生角色扮演工作区。

v0.6.7 · 面向 DSH 0.2.1-rc.2(兼容 0.2.0-rc.2) · GPL-3.0

这是什么

DSH-SoulMojito 是 DSH 官方 bundle 形态的插件包(dsh-soulmojito)。它做四件事:

1. 接住 SillyTavern 生态 —— 角色卡、世界书、预设、正则脚本、STscript、EJS Prompt Template、群聊、persona 与 JSONL 聊天记录都可导入、编辑、导出,尽量无损往返。
2. 把角色扮演交给 DSH 原生 AgentLoop —— 单角色新聊天默认跑在宿主原生 conversation 上;插件只提供角色资产、工具面与投影,不拥有第二个主循环。
3. 补齐 DSH 没有的内容生产面 —— 全自动小说推演、对话改卡的卡片工作台、剧本游玩、MVU 变量结算、提示词查看器。
4. 留出扩展位 —— Mod 扩展接口(五相位 hook + 能力面)与 Agent 游戏桥(标准引擎契约 + 九款内置)。

插件复用 DSH 的 LLM 路由、默认模型、密钥管理、Web 容器与插件安装机制,不引入第二套模型配置。Fabric 不在运行路径中,仅作架构调研。

三种会话架构

| 架构 | 一句话 | 生成循环 | 适合什么 |
| agent-tavern | 原生 Agent 模式,单角色新聊天默认 | DSH AgentLoop | 模型自己决定何时查角色、查世界书、写记忆、掷骰 |
| st | SillyTavern 兼容模式 | 插件自建 /generate | 需要 swipe / regenerate / STscript / 群聊的 ST 工作流 |
| agent-novel | 全自动小说推演 | DSH AgentLoop(写手子代理可选) | 先落大纲再分单元写作的长篇生产 |

三套架构并存、按聊天选择;同一份资产在哪个架构里都能用。

各模式的状态:

| 组合 | 状态 | 说明 |
| agent-tavern + dsh-native | 可用(默认) | 模型、工具调用、Stop、错误与统计全部由宿主处理;激活预设以 systemPrompt 段注入 |
| agent-tavern + agent-managed | 保持关闭 | 宿主尚未提供 agent/context 历史投影与 projection-aware compaction。插件不会把普通 compaction 冒充成主动遗忘,也不静默回退到伪 managed 模式 |
| 群聊 | 固定 st | 宿主提供可靠的 actor 元数据之前,不创建群聊 AgentTavern 会话 |

设置页会如实展示不可用模式的原因;服务端同样拒绝该组合。

能力地图

资产与 SillyTavern 兼容

- 角色卡 V1/V2/V3 — JSON、PNG chara/ccv3、CHARX card.json 与 embeded:// 资源;导出尽量保留原始容器与内嵌资源;未知字段原样透传。
- 世界书 / Lorebook — 递归扫描、副键逻辑、概率、预算、inclusion group、sticky/cooldown/delay 与位置分发。
- Chat Completion preset — prompts[] / prompt_order[] / marker 与采样参数;context、instruct、textgen 走高级 JSON 编辑全部字段。
- 正则脚本 — ST regex 扩展形态导入,全局 + 卡级合并,USER_INPUT/AI_OUTPUT/WORLD_INFO/REASONING placement、minDepth/maxDepth、substituteRegex、trimStrings。
- STscript — 管道、变量(聊天局部 + 全局)、/if 条件、随机/掷骰与聊天动作(/send、/trigger、/regenerate、/cut),composer / 前缀触发。
- Prompt Template(EJS) — node:vm 沙箱执行 <% %>;getvar/setvar 族作用域变量、[GENERATE:]/[RENDER:] 注入、@INJECT 整消息插队、getwi/getchar/getpreset 资产读取。详见 docs/proposals/0008-prompt-template.md。
- Persona — PNG 导入(内嵌描述提取)、头像、增删改、激活选择与 position/depth/role 注入。
- 群聊 — 成员管理、talkativeness 加权 / 列表激活、成员点触发言、group_only_greetings、group nudge 与 {{group}} 宏。
- 聊天记录 — ST JSONL(header / messages / swipes / swipe_id / swipe_info);任意消息一键分支为新聊天(bookmark 回链,视图可跳回父聊天)。
- 并发保护 — 内容 revision compare-and-swap;跨标签页冲突返回 409,客户端重载最新内容,不静默覆盖。

原生 Agent 模式(AgentTavern)

- 工具面 25 件:角色/世界书/历史/场景读面 4 件、记忆 5 件、变量 5 件、剧本 2 件、多 Agent 推演 1 件、MVU 结算 1 件、游戏 7 件。身份一律来自真实 session binding,模型无法通过参数伪造 sessionId、scopeId、角色或聊天身份。
- 记忆 — 词法检索为基线;配置 embed 来源后升级为词法 + 语义混合检索(RRF 融合)。两种来源:OpenAI 兼容远程端点(提案 0016)或本地 ONNX 模型目录(提案 0017,离线零网络,面板一键安装运行时)。
- 记忆维护 — 面板可对单个聊天手动发起维护 run:按原文依据合并重复事件、纠正冲突陈述、删除被证伪记录;收据记录楼面指纹与版本快照,原文再变即退役重扫。
- 变量作用域 — turn(单轮 scratch,回合结束清空)/ chat / character / agent / global(默认关闭,需设置开启);写入带 expected revision CAS。
- 宿主分叉收养 — 用宿主会话菜单分叉一个 AgentTavern 会话,子会话首次运行时自动物化新 Tavern 聊天,继承 guides、变量、记忆与向量,并把继承前缀投影回填为新楼层。详见 decisions/2026-10-11-agent-tavern-host-fork.md。
- 锚定提醒 — 首个真实用户轮注入一次性开场装载引导;此后默认每 5 turn 注入周期维护提醒,把工具职责拉回注意力。追加写在 durable log 之后永不改写,对 KV 前缀缓存透明。
- compaction curator — AgentTavern 会话使用 RP 检查点摘要模板(Story So Far / Characters / World Canon / Open Threads / Current Scene / Memory Maintenance / Critical Context),其余会话原样透传宿主默认摘要。
- 多 Agent 推演 — tavern_deduce 为 2-5 个命名角色各派生一个纯推理子 Agent,按 1-3 轮交叉站位,结论由主 Agent 织入叙事,保持单一叙事声音。
- 边界不伪装 — 缺宿主能力时保持 native 或 ST 的明确边界,不把 compaction 误称为 managed context。

内容生产

- AgentNovel(全自动小说推演) — 先落盘大纲再分单元写作,正文只经 novel_body_commit 原子提交;作者指令走台账 + 修订协议,冲突指令必须引用用户澄清/撤回消息才能解除。写手子代理支持 inline | subagent 两种模式(默认 inline)。详见 docs/proposals/0005-agent-novel-architecture.md。
- 卡片工作台 — dsh-soulmojito/card-workbench preset。用对话描述想改什么,Agent 先给方案,经 diff 确认面板确认后才写入(写入工具必须携带已确认方案的 planId)。支持修改人物卡/世界书/预设、空白建卡、从素材或剧本提取人物制卡、card-to-mvu 转换,以及把指定聊天连同楼层范围交给工作台排错。导入时写一次原版快照,随时可恢复;写卡 Agent 落盘后写卡工作台面板自动吸收——打开面板即重取最新资产,页面可见期间按 store 变更水位(3s)轮询,写入到列表可见不需手动刷新。详见 docs/proposals/0013-card-workbench.md。
- 剧本游玩 — TXT/Markdown/EPUB 导入为剧本资产,自动分块,与人物卡一对一绑定,新开局按剧本推进;只按进度召回附近片段,不整本注入上下文。剧本块是参考不是约束:玩家可偏离,只有正文实际覆盖当前片段关键事件才推进进度。详见 docs/proposals/0014-script-play.md。

对话交互增强

- 持续指引(Guides) — 把长期生效的写作/节奏要求(如「多写心理活动」「好感度涨得慢一点」)存为 Guide,本局正文、行动候选与带意见重写自动参考。上限 8 条、单条 ≤500 字符,删除即时生效,正文中不回显。提案 0009
- 行动候选 — 一键生成 3-6 个「人物行动 / 场景变化」候选,点击填入输入框(可改再发)或带反馈重新生成。候选是建议不是指令,没有自动执行路径。提案 0010
- 带意见重写 — 对当前轮回复附一句修改意见后重写,结果作为新 swipe 追加,可左右切换比较;意见只存在于该次请求与 swipe 元数据,不落盘为聊天楼层。提案 0011
- 思考 + 正文双通道流式 — reasoning 增量实时流式显示、保存后可折叠回看,各 swipe 候选的思考随切换跟随。详见 decisions/2026-10-11-st-reasoning-stream.md。
- MVU 变量结算 — 变量由后台按卡内规则做确定性脚本结算(与 flizzywine 的后台 LLM 结算是不同的架构选择,日常结算零额外模型开销)。每轮产出回执(每项变更前后值、原因、失败项),失败项可单独重试而不动正文;固定状态栏由变量渲染,不随流式生成掉格式;回执可撤销(newest-first 链)。变量树可选 $schema 写入守卫(结构/类型锁定、$range/$step clamp、$enum 拒绝、$ro 只读)与 $rules 条件规则(阈值触发、派生值、连锁修正)。提案 0012 · decisions/2026-10-11-mvu-schema-guard.md
- 提示词查看器 — 查看 ST 生成循环每轮实发给 LLM 的最终请求(pre-llm 改写之后)与世界书激活轨迹;Agent 模式记录插件预注入面(systemPrompt 分面、本步注入消息、agent/request 链尾实发参数)。进程内环形缓冲:每聊天最近 10 条、总量 50,记录失败绝不影响生成。详见 decisions/2026-10-11-prompt-viewer.md。
- 试写预览 — 选定聊天与一句用户语,按当前激活预设/人设/世界书完整装配后跑一次真实生成,零副作用:不落楼、不结算、不触发事件。详见 decisions/2026-10-11-preview-generation.md。

游戏与 Mod 扩展

- Agent 游戏桥 — 标准游戏引擎契约(game.json 清单 + 零依赖纯函数 engine.mjs + 自包含 view.html),三源注册(内置 / 导入 / Mod)。棋盘自动显示在与 MVU 状态同位处;Agent 在自己回合内用阻塞等待挂起,人类落子跨 bundle 写穿唤醒,用户无需发送聊天消息触发下一步。游戏包可直接从面板导入(zip 上传 / git 安装),制作指南见 docs/games/game-package.md,设计契约见 docs/proposals/0018-agent-game-bridge.md。
- 九款内置游戏 — 井字棋、五子棋、中国象棋、军棋、21 点、记忆翻牌对战、大富翁、地牢爬行、中国跳棋,开箱可玩。
- 游戏工具 7 件 — game_list / game_start / game_state / game_history / game_move / game_wait / game_wait_full,按 token 经济设计:读归读、写归写,wait/move 只回增量。
- Mod 扩展接口 — 把带 mod.json 的目录放进 $DSH_HOME/tavern/mods/(或面板内 git 一键安装)即可被识别,默认禁用。首启弹确认层如实展示声明的能力面(知情同意,含无沙箱告知)。启用后可注册:五相位生成 hook(user-input / pre-assemble / pre-llm / post-output / post-save,顺序 waterfall,抛错/超时/忘 return 统一降级不中断生成)、Agent 工具(强制 <modId>_ 前缀,与内置工具三层查重,冲突即拒)、宿主宏与 STscript 命令、prompt 分区(order 钳制 -50..0)、配额存储(单值 256KB / 总量 1MB)、HTTP 子路由、沙箱化面板 UI(sandbox="allow-scripts",无 same-origin,CSP connect-src 'none')。坏 Mod 只记审计跳过、不拖垮本体;禁用/卸载全注册面回收,全部装载与调用行为落审计日志;DSH_SOULMOJITO_DISABLE_MODS 可硬关整个 Mod 系统。Mod 还可声明按钮(manifest buttons → 面板与 ST 聊天视图渲染 chip,点击分发到 api.onButton)、接收本客户端写入的下行事件推送(聊天保存/资产保存/guides/按钮点击),Mod UI 的 console 输出自动回投宿主的 per-mod 日志查看器。开发者文档见 docs/mods/mod-api.md,官方示例覆盖 v1 全部能力面。
- 示例 Mod — 四个官方示例覆盖 v1 全部能力面:asset-stats(资产只读统计)、mood-tracker(post-output hook + 情绪工具对 + iframe 面板)、story-clock(聊天变量 clock + {{clock}} 宏 + /clock 命令族 + llm 门控摘要)、rps。

Tavern 管理面板

两栏布局(左侧导航 + 右侧内容),窄屏折叠为横向滚动栏;导航品牌块常驻不滚,分区清单独占滚动。18 个分区:

| 分区 | 内容 |
| 总览 | 当前角色 / 预设 / 人设 / 世界书开关与各类资产数量 |
| 角色卡 / 世界书 / 预设 | 导入(PNG / CHARX / JSON)、编辑、搜索、设为当前、导出、删除;保存经服务端格式校验后写回 $DSH_HOME/tavern/ |
| 聊天 / 群组 / 人设 / 持续指引 / 正则 / 变量 | 各资产的管理面,从设置页统一归位到这里 |
| 小说 / 剧本 | AgentNovel 小说库;剧本资产的分块、绑定与进度 |
| 工作台 | 方案确认入口(逐字段 diff → 批准并应用 / 拒绝)与试写 |
| 游戏 / Mod | 游戏清单与对局面、游戏包导入(zip 上传 / git 安装);Mod 清单、能力声明 Pill、两层开关、git 安装与审计计数 |
| 记忆检索 | embed 来源三态(关闭 / 远程 / 本地)与探针 |
| 提示词 | 实发请求 + 世界书激活轨迹的只读查看器 |
| 关于 | 版本 stamp 与官网 / 源码外链 |

编辑器显示未保存状态,取消离开时提示确认,页面关闭提供浏览器级离开保护。

入口是 DSH 原生侧栏底部的 SoulMojito 按钮(自绘品牌图标),或「设置 → DSH-SoulMojito」。品牌图标是 assets/logo.svg,同一组件落四处:面板品牌块、侧栏按钮、设置页入口、面板「关于」分区头部。

与 DSH 的原生集成

插件不替换 DSH 原生表面,而是挂进官方 slot:

| DSH slot | 用途 |
| conversation.view | Tavern JSONL transcript |
| conversation.composer | Tavern session 的 RP 输入框、模型选择与 Stop |
| conversation.session.header.actions | 当前角色、regenerate 与原生 session stats |
| settings.section | Active setup 快速切换与面板入口 |
| shell.overlay | Tavern 管理面板 Modal,以及侧栏聊天树 adapter 的生命周期承载 |
| sidebar.footer.action | 常驻 Tavern 面板按钮,与原生 Settings 并列 |

- 每聊天一个正式会话 — 每个 Tavern 聊天绑定一个正式 DSH session;view/composer/标题栏只接管带有效 Tavern marker 的会话,普通 DSH 会话保持原生表面。生成循环把 turn/step、流式 chunk、assistant message 与 provider usage 镜像进同一 session,因此标题栏直接复用宿主的 sessionStats / tokenUsage projection。
- Composer 模型选择 — 复刻 DSH 原生 model seat 的 provider 分组目录与 Effort 二级菜单,按 session 持久化,未选择时回落 DSH 默认模型。
- 内部工作区 — ST 与 AgentTavern 新聊天共用 $DSH_HOME/tavern/workspace/ 下的 Tavern (internal) 工作区,插件按 workspace 路径/ID 从原生侧边栏隐藏该分组。宿主 rc.6 没有可追加到原生 session tree 的正式 list slot,侧栏因此使用一个集中、版本敏感但失败关闭的 DOM adapter(只匹配可见左侧 [role="tree"],解绑或卸载时可逆恢复);面板入口本身走官方 slot,不依赖 adapter 是否挂载成功。
- 语言 — 插件 UI 跟随 DSH 的语言设置(zh/en),切换后无需刷新即时生效。
- 设置页开关 — 「新聊天架构」、「AgentTavern 上下文」、「压缩总结模型」;worldFollowsCharacter(世界书跟随角色卡激活)、preloadAssets(新 AgentTavern 会话开始时一次性预载角色信息与常驻世界书条目,默认关闭且不追溯已有会话)、allowGlobalWrites(允许工具写 global 作用域,默认关闭)、gamesDisableResign(禁用投降),以及 nativePersona(在标准 DSH Agent 会话中使用当前角色,默认关闭)。设置页标题下显示当前构建的版本与 commit。

美化前端(消息内 HTML/JS)

把完整 HTML 文档、/<body> 片段放进助手消息,或使用 html Markdown 代码块,消息保存后会在隔离 iframe 中运行;流式生成与编辑时仍显示源码,避免半成品脚本被重复执行。

- 完整文档:...,或同时包含 与 /<body>。
- HTML 片段:包含 或 <body>;缺外壳时运行时自动补齐 doctype、viewport 与基础样式。
- Markdown 代码块:语言标记写 html。

每个前端使用 sandbox="allow-scripts" 且不授予 allow-same-origin:脚本不能读写宿主 DOM、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:。不支持:fetch/XHR/WebSocket(connect-src 'none')、嵌套 iframe、object/插件、表单提交。高度由 ResizeObserver 回传并限制在 80-1200px;TUI/headless 显示原始消息文本,不执行脚本。

快速开始

要求 Node.js 22+,并已安装 DSH。

安装

git clone https://github.com/LingyeSoul/DSH-SoulMojito.git
cd DSH-SoulMojito
pnpm install
pnpm run build:plugin
dsh plugin --profile web add ./packages/plugin
dsh --profile web

桌面版(desktop profile)在「设置 → 插件 → Git 仓库」填子目录 spec:

github:LingyeSoul/DSH-SoulMojito#path:/packages/plugin

也可以直接命令行安装到 desktop profile:

dsh plugin --profile desktop add github:LingyeSoul/DSH-SoulMojito#path:/packages/plugin
dsh --profile desktop

spec 必须落到 packages/plugin:仓库根是 monorepo 容器,不声明 dsh.bundle.patch,插件管理器会以「这个包没有声明组合包,不能作为插件管理」拒绝并回滚配置。已有源码检出时也可挂本地绝对路径。

git spec 固定到安装时的提交、不跟随源码更新;version.json 不纳入 Git,设置页显示的是构建期注入的版本与 commit。

首次使用

1. 点击侧栏底部的 SoulMojito 按钮(或「设置 → DSH-SoulMojito」)打开管理面板。
2. 在「角色卡 / 世界书 / 预设」分区导入资产;导入后可直接编辑、保存、搜索、设为当前或导出。
3. 在设置中选择新聊天架构(单角色新聊天默认 AgentTavern/native,群聊始终 ST)。
4. 在左侧 Tavern 分支展开角色并创建或打开聊天:AgentTavern 使用 DSH 原生 conversation,ST 使用原生 Tavern tab。
5. ST 聊天里验证编辑、swipe、regenerate 与 STscript;AgentTavern 聊天里验证原生 composer、工具调用、Stop 与会话统计。

验证

pnpm run check

该命令依次跑 tsc -b、vitest 全量、build:plugin 与 15 个插件 gates,是提交前的唯一权威口径。

更新

内置自更新

插件自带从 GitHub 发现新版本与一键更新,桌面版不必手敲 dsh plugin。

- 发现 — 「设置 → DSH-SoulMojito」标题下与管理面板「总览」显示当前构建、GitHub 最新构建、待合入的 commit 列表与上次检查时间。启动后延迟 12s 首查、每 6h 复查,结果缓存在 $DSH_HOME/tavern/update-state.json;「检查更新」按钮穿透缓存立即查。
- 判定 — 仓库不发 release/tag,以 main 分支最新 commit + packages/plugin/package.json 的 version 为准。
- 落地 — 「立即更新」按 dsh plugin → 宿主 plugin-manager 服务 → GitHub checkout 覆写的顺序执行,进度日志实时显示。三条路径都需要重启 DSH:包替换要新的 JS module generation,宿主 HMR 不监听 node_modules。
- 来源降级 — api.github.com → raw.githubusercontent.com + git ls-remote → commits atom feed;每个 HTTP 请求在 fetch 失败后自动用系统 curl 重试(企业 TLS 中间人会让 node 的证书校验失败)。
- 开关 — profile 的 dsh-soulmojito 行写 checkForUpdates: false,或设 DSH_SOULMOJITO_DISABLE_UPDATE_CHECK=1;DSH_SOULMOJITO_DISABLE_CURL=1 关闭 curl 兜底;GITHUB_TOKEN/GH_TOKEN 可提高 GitHub 限流配额。
- HTTP 端点 — GET /api/dsh-soulmojito/update(缓存快照,?refresh=1 穿透 TTL)、POST .../update/check、POST .../update/install({ "wait": false } 立刻返回,进度轮询 GET update)。

实现细节与实测证据见 decisions/2026-10-05-desktop-plugin-self-update.md。

源码检出

dsh plugin add 以本地 link 方式挂载插件,代码更新后重新构建并重启即可:

git pull
pnpm install
pnpm run build:plugin
dsh --profile web

依赖残留或版本不一致时,移除后重新添加:

dsh plugin --profile web remove dsh-soulmojito
dsh plugin --profile web add ./packages/plugin

已安装插件建议使用 plugin-registry 的薄控制台管理 profile 中的 bundle 层栈、insert 行与启停状态,避免手改配置(<plugin-registry> 替换为该工具仓库的本地路径):

dsh plugin --profile web add <plugin-registry>/packages/plugin/console

从旧名迁移(dsh-tavern → DSH-SoulMojito)

2026-10-16 项目改名:包名 dsh-tavern → dsh-soulmojito、工作区 @dsh-tavern/ → @dsh-soulmojito/、插件挂载名与 API 前缀同步更名。存量安装与数据读取端兼容,一次性动作只有「换包名重装」:

dsh plugin --profile web remove dsh-tavern
dsh plugin --profile web add ./packages/plugin

- GitHub 旧地址自动重定向到新仓库,存量安装的自更新链路不断。
- 数据目录($DSH_HOME/tavern/)与既有资产零迁移;旧写入标记(dsh-tavern / plugin:dsh-tavern)、旧环境变量(DSH_TAVERN_)、旧游戏命名空间 id(dsh-tavern.)与新名双认——老会话、老对局、老配置行为不断。
- 新写入与新文档一律用新名;旧名只作读取兼容存在。完整映射见 decisions/2026-10-16-project-rename-dsh-soulmojito.md。

架构与代码结构

包结构

| Package | 说明 |
| @dsh-soulmojito/format | 卡、PNG/CHARX、世界书、preset、群组文件、regex 脚本与 chat JSONL 的解析与无损往返 |
| @dsh-soulmojito/lore | World Info 激活与 timed effects 引擎 |
| @dsh-soulmojito/macros | 角色、时间、随机、变量等宏引擎 |
| @dsh-soulmojito/pipeline | preset 顺序、lore、persona、历史与 token budget 的 prompt 装配(chat completion + 群聊回合) |
| @dsh-soulmojito/script | ST regex 脚本执行器与 STscript 解释器 |
| @dsh-soulmojito/store | $DSH_HOME/tavern/ 原子文件存储、revision 与 session binding |
| @dsh-soulmojito/template | EJS Prompt Template 引擎:node:vm 沙箱执行、作用域变量与内容注入 |
| @dsh-soulmojito/bind | 跨 DSH 版本的宿主形状兼容层:会话事件探测、宿主包锚解析、client 连接双面回退与宿主形状诊断 |
| dsh-soulmojito | 插件本体(Node half + Web client half + 随附示例 Mod 与游戏) |

构建产物

Node half 是六个自包含 bundle:index.mjs 主入口,加 agent / compaction / novel / card-workbench / reasoning 五个子代理入口(见 packages/plugin/package.json 的 exports;reasoning 是内部无工具推理组合,DSH 0.2.1+ 的 spawn 子代理隔离面)。所有 @dsh-soulmojito/ 工作区库全部内联,无运行时依赖,不需要用户额外安装公共 @deepseek-ai/ 运行时依赖;client closure 由 DSH profile 注入。

这些产物有意入库:仓库不发 release/tag,git spec 安装与自更新 checkout 兜底都以分支头为发布通道,产物不入库即装完即坏。唯一例外是 version.json(带本地 commit 戳,每次构建不同,不入库)。

适配新宿主版本时

跨版本兼容层集中在 packages/bind,更新版本适配先改这里。client half 的源文件是 packages/plugin/client/main.js;client/index.js 是 build:plugin 的拼接产物(把 bind 的 client 探测模块注入 __DSH_BIND_CLIENT_SLOT__ 标记处),不要手改,改了会被下次构建覆盖。

插件激活时输出一行 dsh-soulmojito host shape: {...} 日志,报告命中的宿主形状绑定路径——排查宿主版本差异从它读起。

测试与质量基线

pnpm run check

当前基线(2026-10-18 实测):

Test Files 109 passed (109)
Tests 1811 passed (1811)
15 gates 全部 PASS built v0.6.7 (2243f56)

- 1 项跳过是 skipIf 环境条件项:Windows 检出上的 host-package.spec.ts POSIX-only 用例。
- 15 个 gates 覆盖 update-routes、package-contract、patch-reference、server-bundle、client-bundle、frontend-runtime、native-header-adapter、mvu-surface、client-architecture-split、internal-workspace、agent-tavern-isolation、client-vm-mount、node-half-mount、v4-session-admission 与 mod-loader。
- 完整 pnpm run check 需要可解析 DSH 官方运行时;本仓库验证使用隔离 runtime(.npm-cache/dsh-runtime,受限环境依次回落 NODE_PATH 与全局安装)。
- 会话事件写入的宿主契约(V4 关系准入、assistant 结算 usage/stream)由 packages/plugin/tests/agent-tavern-session-admission.spec.ts 直接对真实宿主代码回归。
- 示例 Mod 的 engines 与随仓库发布的宿主版本由防漂移守卫锁定(先例:decisions/2026-10-12-story-clock-engines-drift.md);面板布局、品牌 logo 与内置游戏规则面同样各有 spec + gate marker 锁定。

GUI 已在桌面与 390x844 移动视口验证,覆盖原生 sidebar、管理面板、资产编辑器、conversation view/composer、流式生成、Stop、edit、swipe、regenerate、rename/delete 与 revision 冲突。

文档

项目文档按四类分放,完整索引见 docs/README.md:

| 目录 | 内容 |
| docs/proposals/ | 18 篇架构级设计契约(提案 0001-0018),实现后在此登记 |
| decisions/ | 90 篇单次落地决策:问题、方案、否决项、与规格的偏差 |
| docs/exploration/ | 调研归档,结论必须带证据坐标(文件:行号) |
| docs/plans/ · docs/adr/ · docs/mods/ · docs/games/ | 施工计划 · 架构决策记录 · Mod 开发者文档 · 标准游戏包制作指南 |

从这几篇读起:

- docs/proposals/0001-tavern-architecture.md — 当前架构、边界与后备路线。
- docs/proposals/0004-agent-tavern-architecture.md — AgentTavern 原生 AgentLoop 架构、记忆/变量工具、遗忘策略。
- docs/proposals/0018-agent-game-bridge.md — 游戏桥标准与权威状态论证。
- docs/games/game-package.md — 标准游戏包制作指南(三件套、引擎契约、视图桥、打包导入与排错)。
- CONTEXT.md — 项目架构语言的统一词表(AgentTavern / ST 架构 / 上下文 / 记忆 / 遗忘 / 作用域),动手前先读。
- docs/exploration/2026-10-11-jsr-lwb-reference.md — 竞品参考与不复刻清单。

许可

GPL-3.0。项目只实现公开规范和可观察行为语义,不复制 SillyTavern 的 AGPL 源码。Fabric 与 dsh-ads 仅用于架构调研,第一版运行时不依赖它们。
预览分享卡片长什么样 ↓LingyeSoul/DSH-SoulMojito
分享 · DeepSeek Harness Hub
LingyeSoul/DSH-SoulMojito

把 DSHdeepseek-harness扩展成兼容 SillyTavern 生态的原生角色扮演工作区。

回到顶部