安装
在 DeepSeek Harness 里通过 dsh-market 安装
dsh plugin --profile web add dshmarket
或使用命令行
dsh plugin --profile web add dsh-session-bridge
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。
README
适配 DSH 0.1.7-0 及之后的版本:peerDependencies 只声明下限(>=0.1.7-0),
不设上限,当前实测于 0.2.0-rc.2。详见兼容性变更与
AGENTS.md(版本策略是硬性规则,有 pnpm test 守卫)。
一个 DSH 插件:让当前 agent 能通过提示词驱动其它真实的 DSH 会话—— 创建主会话、向任意会话发消息、等待并读取回复、恢复离线会话、跨工作区按名称或 id 查找会话。 在此之上,它还能监控并调度一个主任务(观察进度、卡住时催办、偏离时纠偏、必要时终止), 以及像 DSH 侧边栏的 Archive 一样归档会话。
English docs: README.md.
功能
- 创建真实 DSH 会话。
session_bridge_create在当前工作区创建新的主会话(顶层 UI 会话), 传workspaceId/cwd则跨工作区;可选发送首条 prompt 并阻塞等待首条回复。provider / model / reasoning effort 默认继承调用会话。异步创建(不带waitForReply)会返回sinceSeq锚点, 之后可用它精确地session_bridge_wait取回首条回复。 - 向任意会话发消息。
session_bridge_send追加一轮(mode=queue)或向运行中的步骤注入 steering(mode=steer),可选等待下一条回复;异步发送同样返回sinceSeq锚点。 - 等待回复或段落。
session_bridge_wait阻塞直至sinceSeq之后出现新的 assistant 输出 (默认sinceSeq= 调用时刻的最新事件 seq):waitFor=reply(默认)在有新的文本回复可读时 立即返回;waitFor=segment在任意新已完成输出步骤出现时立即返回(一个assistant/message——文本、推理或工具调用段),无需等整个 turn 结束,从而可以按段落逐段观察输出。开requireTurnEnd则同时等待回合收尾。超时 / 中止返回部分结果,而非抛错。 回复早已落地也不会丢:预算内没等到新输出时,会返回预算前就存在的最新回复/段落并置stale: true(不会再出现(no text))。要精确取回"某次发送之后的回复",把session_bridge_send/session_bridge_create异步返回的sinceSeq作为锚点传进来即可(与调用方延迟无关);sinceSeq: -1表示"连既有事件也算",即新建会话的锚点。 - 读取任意会话。
session_bridge_read把会话事件日志折叠为可读行——live 或离线(持久化)均可; 支持sinceSeq分页、role 过滤、limit(默认 20,最大 100)。 - 按段落读取输出。
session_bridge_segments返回会话的已完成输出段落——每个已完成的 assistant 步骤(一个assistant/message:其文本、推理与请求的工具调用)作为一行,用sinceSeq增量翻页并返回下一游标。live 或离线均可用,无需等整个 turn 结束,因此可以逐步跟踪长 agentic 任务(模型流式推理时,段落中一并包含思维链)。 - 恢复离线会话。
session_bridge_resume让持久化会话重新上线(幂等),可覆盖 provider / model。 - 查找会话。
session_bridge_find跨全部工作区按 标题 / id / workspace / 目录 匹配,返回 live/running 状态、标题、工作目录;bridge 登记的标题作为别名参与匹配。 - 监控并调度主任务。
session_bridge_status读取会话实时进度(running/idle、是否openTurn、 距最近事件毫秒数做卡住检测、待处理消息、最新回复);只有 running 会话才会被标[STALLED](空闲会话没有进展是正常状态,与守护循环判定一致)。session_bridge_cancel停止一个运行中的会话;session_bridge_monitor_start运行一个后台守护循环,轮询任务、卡住时催办、偏离时纠偏、 持续卡住则终止、完成即收尾。 - 归档 / 取消归档会话。
session_bridge_archive把会话加入 DSH workspace 归档集合(从所有分组视图隐藏, 历史与位置保留)——目标仍在跑时默认拒绝归档,传stopActivity: true则先归档再按官方路径停掉它的 运行中工作(turn、子 agent、job、schedule);session_bridge_unarchive把会话移出归档集合、回到原位 置重新可见;session_bridge_archived列出归档集合,可选解析标题——解析不出标题的会话 只省略标题,不会让整个调用失败。归档集合会无限增长,因此 archive/unarchive 的结果只报 受影响 id + 集合规模并摘要最新若干条,session_bridge_archived支持可选limit(默认 50、从最新往回取,total始终是真实规模)。
监控守护循环
session_bridge_monitor_start 安装一个定时器驱动的循环。每轮对目标会话执行
「观察 → 判定 → 调度 → 落日志」:
| 判定 | 动作 |
|---|---|
回复命中 doneKeywords 且会话空闲 |
收尾并停止守护(日志 DONE) |
| 空闲且无待处理 | 收尾(settled)——不无谓催办 / 取消 |
running 且距最近事件超过 stalledMs |
记一次卡住 → steer 催办(开 useLlm 时先判 offtrack/stuck) |
连续卡住 ≥ maxStuckCycles |
cancel 终止 |
| 正常推进 | 重置卡住计数(steady) |
守护只对 running 会话判定"卡住",因此已完成/空闲的任务会被收尾而非无限催办
(session_bridge_status 的 [STALLED] 标注同理,只对 running 会话显示)。日志写入
~/.dsh/super-injector/dsh-session-bridge-monitor.log(可用 logFile 覆盖)。
用 session_bridge_monitor_start / _stop / _list 控制。
思维链(CoT)监控与规则
会话桥可以实时监控另一个会话的思维链(chain-of-thought / reasoning),而不只等它的最终回复:
实时观察:
session_bridge_status对运行中会话返回三块思维链字段——lastReasoning(最近一条已定型推理块)、liveReasoning(当前正在处理的 turn 的进行中推理,来自assistant/chunk的reasoning-delta流)、reasoningTail(紧凑、受字符上限的合并预览)。 用reasoning参数(none | last | live | tail)选择返回哪些字段,默认tail最省 token。按段落读取:
session_bridge_segments把每个已完成输出步骤(一个assistant/message——文本、推理或工具调用段)当作一个段落返回,用sinceSeq增量翻页,无需等整个 turn。按消息读取:
session_bridge_read带includeReasoning可返回每条 assistant 消息的已定型推理。规则执行:
session_bridge_monitor_start接受coRules(数组,元素为 { match: contains|not-contains, field: reasoning|text|both, value: string, action: steer|cancel, message?: string })与cotMinHits。每次轮询守护用规则的匹配条件对照实时思维链/文本, 连续命中cotMinHits次(默认 1)后触发动作:steer注入引导性用户消息,cancel终止会话。 示例——"思维链一旦不再包含 I'm 就停止该会话":coRules: [{ "match": "not-contains", "field": "reasoning", "value": "I'm", "action": "cancel" }]注意:作用在
reasoning上的not-contains规则在目标会话完全不产生推理时故意不触发 (如非推理模型或 reasoningEffort off),避免误 cancel 根本不流式思维链的会话。重复触发有冷却 节流,每次评估/触发都会写入监控日志。
环境要求
构建
# 安装锁定的 DSH 发布依赖,再类型检查并构建
pnpm install --frozen-lockfile
pnpm build
# 针对"实际安装的 dsh"做类型检查(不需要 checkout)
npm run check:compat
# peer 下限守卫、核心 wait/卡住判定、archived 工具 handler、V3→V4 迁移的回归测试
npm test
# 或经注入器工具链
dev_build_plugin dsh-session-bridge
build.sh 按本地 dsh 源码 checkout 做类型链接,仅用于本地开发。该 checkout 常常
落后于插件实际加载进的 harness,因此 build.sh 通过并不代表插件在运行中的
DSH 上可用——两者版本不一致时 build.sh 会给出警告。要验证运行版本请用
npm run check:compat:它按已安装 DSH 包内随附的 lib/types/*.d.ts(即插件真正
加载的 API 面)对 src/ 做类型检查,随后把产物内联的 DSH 版本与已安装 harness
比对——内联版本低于声明下限(0.1.7-0)才判失败,其余漂移只给提示(传
--strict 可恢复"必须完全一致"的严格判定),因为本插件声明的是"下限及之后"。
内联的 cordis 单独成组,与已安装的 cordis 比对。
部署
DSH web 从活动 profile 加载外部插件。本包是一个 bundle:package.json 声明了
dsh.bundle.patch → cordis.patch.yml,其 insert 行挂载插件。
正是这一声明让 dsh plugin add 能一步安装并激活本包。
从 npm 安装
本包已发布到 npmjs.com。
发布由 publish.yml GitHub Actions 工作流在 v* 标签触发;发布前会把
package.json 与 dsh.plugin.json 的版本同步到该标签。
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-session-bridge
预发布标签(v0.3.2-alpha.1)会发布到自己的 dist-tag(alpha/beta/rc),
而不会占用 latest,因此不会顶掉其他用户使用的稳定版。需要显式选用:
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-session-bridge@alpha
pnpm 会安装发布的 tarball 并运行其 prepare 脚本(tsdown)以确保 lib/ 就绪,
随后 dsh 激活该 bundle。
新版本发布后约 24 小时内,
@latest会解析到旧版本。 pnpm 11 默认开启供应链保护 (minimumReleaseAge默认 1440 分钟),发布不满 24h 的版本不参与解析;minimumReleaseAgeStrict默认为false,所以 pnpm 会静默回退到 最新一个"够老"的版本,不报错也不提示。此时pnpm view dsh-session-bridge dist-tags仍显示latest是新版,但实际装到的是旧版——而旧版的 peer 范围可能已被新的 DSH 拒绝,于是出现 "指定了 latest 却说版本不兼容"。三种解法:
- 在使用方 profile 的
pnpm-workspace.yaml里排除本包,@latest立刻生效:minimumReleaseAgeExclude: - dsh-session-bridge- 装本地 tarball(不经 registry 解析):
dsh plugin --profile <p> add <路径>/dsh-session-bridge-x.y.z.tgz;- 等满 24 小时。指定精确版本不能绕过该策略(会硬报
ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION)。
从 GitHub 安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:heartmove/dsh-session-bridge
dsh plugin 在 ~/.dsh/profiles/web/ 内转发给 pnpm,然后把本 bundle 归并到 profile 的
dsh.profile.bundles 层列表。git 安装会拉取源码,因此 pnpm 会在 checkout 后运行本包的
prepare 脚本(tsdown)从 src/ 构建 lib/。
pnpm ≥ 10 默认拒绝运行 git 依赖的 prepare 脚本,首次 add 会报 "Ignored build scripts" 提示。
把 pnpm 打印出的包名复制到 profile 的 pnpm-workspace.yaml
(~/.dsh/profiles/web/pnpm-workspace.yaml):
allowBuilds:
dsh-session-bridge: true
然后重新运行 add。该放行表示"在安装时运行这个包的代码"——只放行源码可信的包,并锁定 commit
(github:heartmove/dsh-session-bridge#<sha>)以避免后续推送静默改变运行内容。
之后重启 dsh web,并强制刷新页面(Ctrl/Cmd+Shift+R)。
从本地 checkout 安装
在包含本 checkout 的目录下:
npx -p @deepseek-ai/dsh dsh plugin --profile web add ./dsh-session-bridge
pnpm 链接该 checkout,dsh 以同样的方式激活 bundle。
手动 link
想手动管理 profile 时,把本包链接并列入 ~/.dsh/profiles/web/package.json 的 bundles
(bundle 自带的 cordis.patch.yml 提供 loader 行,无需额外的 insert 条目):
{
"dependencies": {
"dsh-session-bridge": "link:D:\\path\\to\\dsh-session-bridge"
},
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-session-bridge"]
}
}
}
(POSIX 系统用 link:/path/to/dsh-session-bridge。)然后在 profile 目录运行 pnpm install 并重启 dsh web。
直接注入(开发用)
开发调试阶段也可经注入器工具链直接加载(无需 bundle 条目):
dev_inject_plugin D:\code\dsh-session-bridge
卸载用 dev_uninject_plugin dsh-session-bridge(清除注入器注册与 junction;重启不再自动装配)。
工具清单
| 工具 | 作用 |
|---|---|
session_bridge_create |
创建主会话(当前或其它工作区,经 workspaceId / cwd);可选首条 prompt + waitForReply;异步时返回 sinceSeq 锚点。 |
session_bridge_send |
发消息(mode=queue/steer);可选等待回复;异步时返回 sinceSeq 锚点。 |
session_bridge_wait |
等待 sinceSeq 之后新输出(默认 = 调用时刻最新 seq,-1 = 从头发算):waitFor=reply(文本)或 waitFor=segment(任一已完成步骤即返回,无需等整个 turn);可选 requireTurnEnd;零新输出时回落既有回复并置 stale。 |
session_bridge_read |
读取消息 —— live 或离线;sinceSeq 分页、role 过滤、limit。 |
session_bridge_segments |
增量读取已完成输出段落(每个已完成的 assistant 步骤)—— live 或离线。 |
session_bridge_resume |
让持久化会话重新上线(幂等)。 |
session_bridge_find |
跨工作区按 标题 / id / workspace / 目录 查找会话。 |
session_bridge_status |
读取会话实时进度(running、openTurn、卡住检测、待处理、最新回复)及实时/已定型思维链(reasoning 参数);[STALLED] 仅对 running 会话显示。 |
session_bridge_cancel |
停止运行中的会话(中止活动 turn;keepInbox 保留排队/steering 输入)。 |
session_bridge_monitor_start |
对一个主会话启动后台守护(轮询、催办、纠偏、终止、收尾);支持思维链 coRules(如 reasoning not-contains "I'm" → cancel)。 |
session_bridge_monitor_stop |
停止守护(会话本身不终止)。 |
session_bridge_monitor_list |
列出活动守护及其状态。 |
session_bridge_archive |
归档会话(从分组隐藏;历史与位置保留);对运行中的会话需显式 stopActivity: true。返回受影响 id、集合规模与最新若干条。 |
session_bridge_unarchive |
取消归档(回到原位置重新可见;未知/未归档 id 为幂等空操作)。 |
session_bridge_archived |
列出归档集合(从最新往回,可选 limit,默认 50),可选为返回的 id 解析标题。 |
所有工具输出 lossless JSON;等待类工具超时不抛错,返回 timedOut / aborted / stale 标记。
项目结构
src/
index.ts host 插件入口(注册工具;挂载监控)
core.ts 共享 host 逻辑(create/send/wait/read/find、status 快照、archive 记账)
tools.ts 工具注册(bridge + status/cancel + monitor + archive)
monitor.ts 后台守护循环(statusSnapshot + 规则 + 可选 LLM 判定)
registry.ts 桥侧标题/workspace 登记表(~/.dsh/session-bridge-registry.json)
scripts/
build.sh 类型检查 + 链接 DSH checkout 类型
test-bridge-core.mjs wait/卡住判定回归测试(npm test)
test-tools-archived.mjs 归档 / 取消归档 + archived handler 回归测试(npm test)
check-dsh-compat.mjs 对已安装 DSH 做 src/ 类型检查 + 校验产物来源(npm run check:compat)
smoke-bundle.mjs 挂载构建产物 lib/index.js 并断言工具全部注册(npm run smoke)
生命周期与卸载
DSH ≥ 0.1.6 支持运行时挂载/卸载插件(设置 → 插件页开关、注入器热重载)。
本插件可干净卸载:不注册 loader 级状态,工具随插件 fiber 一并释放,监控定时器
经 ctx.effect 在卸载时清理。
该所有权模型带来一个后果:session_bridge_create 创建的会话归插件 fiber 所有
(agent 在插件上下文下创建),因此卸载/重载插件会停止这些会话的活动 agent。
会话本身已持久化并显示为离线,可用 session_bridge_resume 重新上线;守护循环
同样在卸载时停止。
License
MIT
评论
评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。