为 DeepSeek Harness 增加会话管理工具与侧边聊天:列出/读取/创建/发送会话,并能开一个挂载在主会话旁、保持可继续对话的子会话面板。
- 语言
- Python
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:Ephemeral-AI-Lab/dsh-plugins/sessions在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
落地页对应的仓库子路径是
sessions,仓库中的承载目录也叫sessions,npm 包名dsh-sessions(package.json:3),是Ephemeral-AI-Lab/dsh-pluginsmonorepo 下的子包之一。本百科聚焦sessions路径对应的能力。
一句话定位
为 DeepSeek Harness 增加"会话管理"与"侧边聊天"能力:让 agent 和用户能够列出历史会话、按窗口读取对话内容、创建新会话、把消息投给已有会话(steer 或 followup),以及在不离开主会话的情况下开一个挂载在旁的、可继续对话的子会话面板。
核心能力
- 列出最近会话或查看单个会话状态:
session_status({ session_id?, recent_n? })默认按最近更新时间倒序返回 50 条,状态分 running / idle / cold / missing(src/service.ts:22-60、SPEC §2 session_status)。 - 按窗口读取会话历史:
session_read({ session_id, offset?, limit? })只读、不恢复、不重启生成,跳过 token 流、生命周期事件等 trace-only 数据(src/service.ts:85-102)。 - 创建新会话并排队初始 prompt:
session_create({ prompt, preset?, model?, cwd? })返回新 session_id 和status: "queued",不等待生成结束(src/creation-service.ts:26-68)。 - 向已有会话投递消息:
session_send({ session_id, message, mode? })支持 steer(唤醒/插入下一个步骤)和 followup(排队成下一轮),冷会话会被本插件恢复后投消息(src/send-service.ts:18-61)。 - 开启一个真实可继续的子会话:
session_open_sidechat({ prompt })返回 subagent_id(不是另造的 ID),复用 DSH 现有的 send_message 继续对话(src/sidechat/sidechat-service.ts:29-49、SIDE_CHAT_SPEC §2)。 - 等价的用户命令
/sessions加 Web 可视化:命令覆盖 status / read / create / send / sidechat 五个动作(/sessions create支持--preset/--provider/--model/--effort/--cwd与 JSON 两种形式,src/commands.ts:11,72-118,212-325);Web 端把侧边聊天渲染成标签化、状态/常驻分离、关闭再打开恢复标签的独立 panel,并把/sessions命令结果以浮层 popup 形式呈现(src/ui/SideChatPanel.tsx、src/ui/index.ts:42-91)。
技术实现
- 语言: TypeScript(
tsc -p tsconfig.json编译到lib/,package.json:11声明"type": "module") - 关键依赖:
@deepseek-ai/cordis(>=4.0.0):宿主插件框架,apply(ctx)走标准 Cordis effect@deepseek-ai/dsh-tools/@deepseek-ai/dsh-commands:用defineTool注册五个工具、用ctx.commands.register注册/sessions命令@deepseek-ai/dsh-agent+@deepseek-ai/dsh-subagent+@deepseek-ai/dsh-session-persistence+@deepseek-ai/dsh-session-query+@deepseek-ai/dsh-workspace+@deepseek-ai/dsh-llm:分别负责创建/恢复 Agent、subagent 启动、会话存储/恢复、标题快照、workspace 解析、消息构造@deepseek-ai/dsh-client-ui-*+@deepseek-ai/dsh-client-runtime+react(>=18.2.0):Web 端把侧边聊天 panel 注入shell.overlay槽位、命令结果浮层注入conversation.input.overlay槽位
- 架构模式: 双端 Cordis 插件。Server 端
apply(ctx)在sessions/src/index.ts:15-29注入tools / commands / agents / subagents / llm / sessionPersistence / sessionQuery / workspaceRegistry八个服务,组合四个 Service(SessionsService、SessionCreationService、SessionSendService、SideChatService)并通过registerSessionTools+registerSessionsCommand暴露能力;Client 端apply(ctx)在src/ui/index.ts:18-102监听command/executed事件、把侧边聊天注入shell.overlay槽位、把/sessions命令的瞬态结果用conversation.input.overlay槽位渲染成浮层 popup。cordis.patch.yml给宿主注入一个名为dsh-sessions的 bundle patch,让宿主在加载时挂载这个插件。 - 入口文件:
sessions/src/index.ts(服务端)+sessions/src/ui/index.ts(客户端),均通过package.json#dsh字段bundle.patch+client.inject注入 DSH。
适用场景
当用户希望 agent 把"管多个会话"这件事做得正式一些——比如在长项目里随时跳回 3 天前的会话读上下文、临时拉一个并行 agent 出去查资料而不打断当前主任务、在不离开当前聊天窗口的情况下并排看两个子任务的进度——这个插件提供标准化的工具/命令和 Web 面板,让"会话列表、读取、创建、发送、并行子会话"成为 agent 可以直接调用的能力。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
@deepseek-ai/dsh-tools | >=0.1.0-rc.5 | peerDependencies,注册五个 agent 工具依赖 |
@deepseek-ai/dsh-commands | >=0.1.0-rc.5 | peerDependencies,注册 /sessions 命令依赖 |
@deepseek-ai/dsh-agent | >=0.1.0-rc.5 | peerDependencies,SessionCreationService / SessionSendService 直接持有 Agent |
@deepseek-ai/dsh-subagent | >=0.1.0-rc.7 | peerDependencies,侧边聊天走 ctx.subagents.startContinuable |
@deepseek-ai/dsh-session-persistence | >=0.1.0-rc.5 | peerDependencies,session_status 列举冷会话、session_send 恢复冷会话都依赖 |
@deepseek-ai/dsh-session-query | >=0.1.0-rc.5 | peerDependencies,标题快照通过 readTitleSnapshots 读 |
@deepseek-ai/dsh-workspace | >=0.1.0-rc.7 | peerDependencies,cwd 通过 workspaceRegistry.resolveByPath 解析 |
@deepseek-ai/dsh-agent-presets | >=0.1.0-rc.7 | peerDependencies,session_create 解析 preset 依赖 |
@deepseek-ai/dsh-agent-default-model | >=0.1.0-rc.7 | peerDependencies,根调用无显式 model 时回落部署默认依赖 |
@deepseek-ai/dsh-llm | >=0.1.0-rc.5 | peerDependencies,createUserMessage + ReasoningEffortId 来源 |
@deepseek-ai/dsh-client-runtime + @deepseek-ai/dsh-client-ui-commands + @deepseek-ai/dsh-client-ui-conversation + @deepseek-ai/dsh-client-ui-primitives + @deepseek-ai/dsh-client-ui-tool + @deepseek-ai/dsh-client-ui-slots + @deepseek-ai/dsh-api-remotes + @deepseek-ai/dsh-client-connection | 各 >=0.1.0-rc.5 | peerDependencies,Web 端侧边聊天 panel 与浮层 popup 必需;package.json:19-26 列入 dsh.client.inject,缺一加载不到 Web UI |
@deepseek-ai/cordis | >=4.0.0 | peerDependencies,宿主插件框架 |
react | >=18.2.0 | peerDependencies,侧边聊天 panel 是 React 组件 |
| 平台 | DSH Web | package.json:27 显式声明 dsh.client.platform: "web",命令行/桌面端未声明 |
| Node.js | 未声明 | package.json 没有 engines 字段;只有 devDependencies 里有 @types/node ^22.20.0 |
| 原生模块 | 无 | 全部是纯 JS 依赖,无 node-gyp 构建项;插件本身只用到 node:crypto / node:fs/promises / node:path 这些 Node 内置模块 |
安装方式
dsh plugin --profile web add github:Ephemeral-AI-Lab/dsh-plugins/sessions
配置项
本插件无需额外配置。安装后重启 DSH 并新建会话即可使用,会话相关参数(prompt、session_id、cwd、model、preset、reasoningEffort、recent_n、offset、limit、mode、subagent_id 等)全部在运行时通过工具调用或 /sessions 命令传递,源码中无 .env / settings 配置文件读取逻辑(grep 全文未发现 process.env / config.get / Schema 等运行时配置入口)。
唯一会被校验的字段是工具/命令入参的硬约束:session_id/message/prompt/provider/model/preset/reasoningEffort/cwd 都必须是非空字符串、recent_n/offset/limit 必须是正整数、limit 上限 200(src/service.ts:16,134-151、src/creation-service.ts:267-274、src/sidechat/sidechat-service.ts:79-83),这些是入参校验,不算可配置项。
常见问题
Q: 装完之后怎么用?
A: 重启 DSH 并新建会话即可。Agent 可在自然语言里调用 session_status / session_read / session_create / session_send / session_open_sidechat 五个工具;用户也可直接在输入框打 /sessions status、 /sessions read <ID>、 /sessions create <prompt>、 /sessions send <ID> <msg>、 /sessions sidechat "PROMPT" 这几条命令,操作的是同一套后端(src/commands.ts:21-70)。无需新建 preset 或开关任何宿主配置。
Q: session_create 会等模型生成完才返回吗?
A: 不会。README §5 与 SPEC §2 session_create 都明确说明它只创建新会话并把初始 prompt 投到收件箱就立即返回,返回的 status: "queued" 表示"已入队、未完成";想看生成结果请用 session_status 查当前状态,或 session_read 读窗口消息。followup() 在失败时会回滚 handle 并重新抛错(src/creation-service.ts:52-60),所以要么拿到 session_id 要么抛错,不会留下半成品。
Q: session_send 的 steer 和 followup 有什么区别?
A: steer(默认)会唤醒空闲 agent,并对运行中 agent 投到最近一个步骤边界;followup 则排队成普通的下一轮(src/send-service.ts:50-51、 SPEC §2 session_send)。两者都不会打断 agent 当前正在跑的步骤,返回的 message_id 只是收件箱里的接受凭证,不代表模型已处理完。
Q: 侧边聊天 / sessions sidechat 跟 session_create 是一回事吗?
A: 不是。session_open_sidechat 走 Harness 自带的 continuable subagent 服务(ctx.subagents.startContinuable,src/sidechat/sidechat-service.ts:33-49),返回的是真实可继续的 subagent_id,跟 list_agents({ scope: "children" }) 看到的子 agent 是同一套;session_create 返回的是新的顶层 session_id。侧边聊天在 Web 端有专门的标签化 panel(src/ui/SideChatPanel.tsx),关闭再打开标签保留,主会话不会被导航走;普通 session_create 出来的子会话没有这个 panel。
Q: 怎么选择 session_create 的模型或工作目录?
A: 在创建时显式传 model: { provider, model, reasoningEffort? }、preset、cwd 即可。模型解析顺序:显式 > 调用方 agent 路由 > 部署默认;preset 解析顺序:显式 > 调用方 preset > 部署默认;cwd 缺省时子会话继承调用方 cwd,根调用则不绑工作区(SPEC §2 session_create 的解析表)。cwd 必须是已存在的绝对目录,会被 realpath canonicalize,否则抛 cwd must be an absolute path / cwd 'X' is not a directory(src/creation-service.ts:267-274)。
Q: session_read 能读整段历史吗?
A: 不能,是有界读取。limit 默认且上限 200 条 message block(src/service.ts:16 READ_SESSION_LIMIT = 200、src/service.ts:144 校验),offset 是 1-based,超出会被 offset X is out of range 拒掉。读冷会话走 sessionPersistence.inspect 不恢复、不重启生成(src/service.ts:88-90);只投影会话规范消息块,跳过原始 stream chunk、token delta、lifecycle 等 trace-only 事件(src/service.ts:153-162、SPEC §2 session_read)。
Q: 跟 dsh-loop 是什么关系?
A: 职责互补。dsh-sessions 拥有跨会话的发现/读取/创建/发送(SPEC §1);dsh-loop 拥有当前会话内的循环闹钟(详见 _wiki/Ephemeral-AI-Lab_dsh-plugins_loop.md)。dsh-loop 用本插件的会话列表能力填它面板上的"已有会话"选项(SPEC §5),两者不会重复实现同一份会话状态。
Q: 怎么卸载?
A: 用 dsh plugin --profile web remove 对应的安装源即可。卸载后这五个工具名(session_status / session_read / session_create / session_send / session_open_sidechat)和 /sessions 命令从新会话的工具表中消失(src/index.ts:23-28 提供的 dispose 会撤销注册);已创建/已发送的会话和侧边聊天仍保留在 DSH 会话存储里,不会被删除。
上手难度
入门 — 装好就能用,没有配置文件、没有原生模块、没有特殊 preset 要建;最快 30 秒就能在输入框打 /sessions status 看到最近会话列表,或 /sessions sidechat "帮我查一下" 开一个侧边聊天面板。
已知问题与限制
- v1 没有"会话修改/删除/重命名"工具:
session_status是只读的,session_send只投递消息,session_create只创建新会话,没有提供 delete / rename / archive 这一类操作(README §5与SPEC §1把"create + send + inspect"明确列为职责边界)。 session_create不等待模型生成结束:返回status: "queued"后调用方需要自己用session_status轮询或session_read拉窗口(README §5/SPEC §2 session_create);想在同一次工具调用里拿到完整回复做不到。session_send不会创建新会话:传入一个不存在的session_id会抛missing,不会自动建(SPEC §2 session_send);冷会话会被本插件恢复(src/send-service.ts:30-42),但不会补建不存在的会话。session_read窗口上限 200:limit超过READ_SESSION_LIMIT = 200直接抛limit must be less than or equal to 200(src/service.ts:144),要分段读只能多次调用。session_open_sidechat必须有 calling agent:在没有当前 agent 的工具调用上下文里会抛session_open_sidechat requires a calling agent(src/sidechat/sidechat-service.ts:31);这是因为它要复用 subagent 框架的 parent 关系。- 侧边聊天仅 Web 端可见:底层
session_open_sidechat工具在命令端也能跑,但没有 panel,只返回 JSON;UI 端的标签化和状态/常驻分离体验是 DSH Web 专属(src/ui/SideChatPanel.tsx、package.json:27 dsh.client.platform: "web")。 - 命令行/桌面端是否可用未声明:
package.json:27只声明dsh.client.platform: "web",CLI / TUI / Desktop bundle 是否会自动挂载这个插件源码中未明确(同样适用于dsh-loop,见_wiki/..._loop.md的同条限制)。 - 不修改 DeepSeek Harness 宿主代码,全部走 Cordis effect 和 DSH 公共 API(
README §5/SPEC §1);这意味着宿主一旦变更dsh-session/dsh-subagent/dsh-llm等公开 API 形状,插件需要同步升级 peerDependencies(当前要求dsh-agent-presets/dsh-agent-default-model/dsh-workspace/dsh-subagent都>=0.1.0-rc.7)。 - 侧边聊天
subagent_id与session_id是同一类 ID:它是真实 child Session ID,跟list_agents({ scope: "children" })列出来的一致(SIDE_CHAT_SPEC §2),但也意味着session_send({ session_id: <subagent_id>, message })走的是普通会话投递而不是 subagent 的send_message,如果你想用 send_message 的"按 subagent ID 投递"语义需要直接调宿主工具,不要被本插件的session_send替代(README §6明确警告)。
Small, focused plugins that make DeepSeek Harness more capable, expressive, and pleasant to use.
Quick start · Packages · Development · Documentation
🧠 Give your DSH sessions better tools, durable workflows, and a cleaner path from idea to execution.
⚡ Quick start
Published plugins install directly into a DSH profile with one command. The
examples below target the web profile; replace web with the profile you use.
🐚 Codex Terminal
# With the DSH CLI:
dsh plugin --profile web add dsh-codex-terminal@0.1.3
# Without the `dsh` CLI:
npm install dsh-codex-terminal@0.1.3
🔐 Codex Coding Plan
Reuse an existing file-backed codex login from the DSH Models page:
dsh plugin --profile web add ./coding-plan/codex
# Grok Coding Plan models from the existing `grok login`
dsh plugin --profile web add ./coding-plan/grok
⏰ Loop
# With the DSH CLI:
dsh plugin --profile web add dsh-loop@0.1.3
# Without the `dsh` CLI:
npm install dsh-loop@0.1.3
🧪 Mock — unstable
dsh-mock is published for early testing. Its commands, API, and UI may
change before a stable release.
# With the DSH CLI:
dsh plugin --profile web add dsh-mock@0.1.0
# Without the `dsh` CLI:
npm install dsh-mock@0.1.0
🧭 Sessions
Inspect, create, read, and message DSH sessions with the current session tools:
# With the DSH CLI:
dsh plugin --profile web add dsh-sessions@0.1.1
# Without the `dsh` CLI:
npm install dsh-sessions@0.1.1
Restart DSH and create a new session after installing a plugin. If dsh is not
on your PATH, run the same command from a DeepSeek Harness source checkout with
pnpm dsh instead.
Direct npm installation downloads the package for use by your project. DSH profile installation is still required when you want DSH to load the plugin as part of a profile.
📦 Packages
| Package | Status | What it adds | Docs |
|---|---|---|---|
dsh-codex-coding-plan | 🧪 Local · 0.1.0 | Reuses a file-backed Codex ChatGPT login through the existing openai-codex pi-ai provider. | README |
dsh-grok-coding-plan | 🧪 Local · 0.1.0 | Reuses a file-backed Grok subscription login through the existing xai pi-ai provider. | README |
dsh-codex-terminal | ✅ Published · 0.1.3 | Codex-compatible exec_command and write_stdin tools with persistent command sessions. | README · npm |
dsh-loop | ✅ Published · 0.1.3 | Session-scoped recurring alarms, loop tools, slash commands, and a web UI. | README · npm |
dsh-mock | ⚠️ Unstable · ✅ Published · 0.1.0 | Deterministic mock model turns and replay commands routed through the real DSH AgentLoop and ToolRuntime. | README · SPEC · npm |
dsh-sessions | ✅ Published · 0.1.1 | Session discovery, bounded reads, creation, and delivery through session tools and /sessions. | README · SPEC · npm |
🐚 dsh-codex-terminal
Run shell commands like a Codex-style agent: start long-running processes, poll for output, and send input to persistent sessions. PTY transport is used by default with a configured pipe fallback when PTY allocation is unavailable.
⏰ dsh-loop
Create durable, session-local recurring prompts that can be managed through
agent tools, /loop commands, and the web UI. Loops resume with the session
and keep each alarm independent from the others.
🧪 dsh-mock
Exercise deterministic mock model turns through /mock run and /mock replay
while preserving the real DSH AgentLoop, ToolRuntime, policy, and event flow.
⚠️ Unstable: published as
dsh-mock@0.1.0for early testing. The command, API, and UI surface may change before a stable release.
Install it into the DSH web profile with one command:
dsh plugin --profile web add dsh-mock@0.1.0
🛠️ Development
Each plugin is independently installable and testable. For example:
cd loop
pnpm install
pnpm test
pnpm build
The source tree intentionally stays outside the DeepSeek Harness repository; DSH composes plugins through profile-scoped installation and patch layers.
📚 Documentation
- Codex Terminal documentation
- Coding Plan core
- Codex Coding Plan documentation
- Grok Coding Plan documentation
- Loop documentation
- Mock documentation
- Mock implementation specification
- Sessions documentation
- Sessions specification
- DeepSeek Harness
🤝 Contributing
Issues, ideas, and pull requests are welcome. Keep plugins focused, document their runtime contracts, and include tests for changes to tools, persistence, or UI behavior.
📄 License
Released under the MIT License.