
Security News
vlt 1.5.0 Adds Agent Skills Management
vlt 1.5.0 links skills from JavaScript dependencies to coding agents, with lockfile versioning and Socket data to filter out known malicious packages.
dsh-session-conductor
Advanced tools
DSH session management enhancement: archive/restore sessions, batch & conditional delete, AI auto-rename, interrupted-session auto-resume, release idle sessions, workspace grouping, undo last message, repair damaged session logs, value analysis, full-text
DSH(DeepSeek Harness)会话管理增强插件:让会话列表可管理、可修复、可自动续跑。
侧边栏新增「会话管理」面板,归档会话可恢复、支持批量删除、AI 自动重命名、中断自动续跑、按工作区分组显示;设置页提供方案/收尾模板注入与自动重命名模型选择。
| 功能 | 说明 | 入口 |
|---|---|---|
| 会话管理面板 | 全部/已归档/活跃/回收站/说明五视图;归档、恢复、删除(批量/筛选)、置为不活跃、释放全部空闲 | 侧边栏「会话管理」按钮 |
| 回收站 | 删除只打标记、不动会话文件:删掉的会话进回收站,可单条还原、多选还原、按批次撤销(还原最近一次删除),到期(保留天数可设,默认 7 天)或「一键清空」才真正删盘。真正删盘由每小时一次的到期清理执行 | 面板「回收站」标签页 |
| 自动重命名 | 每个回合后 AI 分析会话内容,主题明显偏离时自动生成新标题(带运行状态后缀) | 面板逐会话开关 |
| 自动续跑 | 识别非人为中断(崩溃/限流/超时/错误),自动继续原任务;失败后 30s 重试 | 面板逐会话开关(临时设置,重启即默认关) |
| 会话分组 | 按工作区分组显示;「在分组下新建会话」 | 设置 → 插件 → 会话分组 |
| 撤回最后一条消息 | 删除最后一条用户消息及整轮回复(先预览 + 二次确认 + .undo-backup 备份) | 面板按钮 |
| 损坏修复 | 会话日志修复,四类判据:seq-gap / EIO 坏块 / 双格式(jsonl+zstd 并存)/ zstd 帧级损坏。最后这类原先修不了(尾部垃圾 + 末帧内容坏 ⇒ 整体放弃),现在支持截断到最长可解码前缀:逐帧解码定位安全点、保留原始帧不重编码、备份后原子写回(代价是丢掉不可解码的尾部帧,会如实报告丢了多少)。另:supportsRepair 的后端探测原先按 0.1.x 的接口判,0.2.x 已移除该接口 ⇒ 判据恒 false、面板扫描恒 501;现改用文件系统判据,内容修复不可用时回退帧修复 | 面板「说明」页按钮 + 插件 HTTP /repair 系列 |
| 价值分析 | LLM 按规则给会话分类(已完成/未完成/久未活跃/活跃中) | 面板按钮 |
| 全文搜索 | 官方 FTS5 优先 + 内置 zstd 扫描兜底 | 面板搜索框 |
| 压缩模型选择 | 上下文自动压缩用模型独立选择(省成本) | 设置 → 插件 → 压缩模型 |
| 模板注入 | 方案模板 / 收尾模板:本地设备上传 / 在线网址 / DSH 目录浏览三种导入,内容可再编辑,注入系统提示词(方案/收尾各一条上下文注入) | 设置 → 会话管理 → 模板注入 |
| 自动重命名模型 | 指定便宜/专用模型做标题分析 | 设置 → 会话管理 |
| 成员模型切换 | 给队友/子代理单独切模型(只动该成员会话,不影响其他成员):先用 list_models 拿确切模型 id,再 set_member_model 按成员名/sessionId 切换(写 model/selection 事件交给官方投影接管,跨轮持久;未挂载成员也能切,运行中会先等它暂停)。返回值直接带「切没切成」的查证:立刻给「最近一次实际请求的 provider/model(取自 request/header,请求级权威记录)+ 最近一次切换意图 + 一行判定」,并注册查证任务(不阻塞)——该成员下次发起请求时按 agent/request 事件判定,确认结果在下一次 step 注入给发起方(不轮询、不等待);另附可复制的复核命令 node scripts/check-member-model.mjs <sessionId>。判定只认请求时真实使用的模型,不信注入的 [model changed: …] 提示。另提供用户聊天框指令 /model-switch(注册在宿主 ctx.commands):无参 = 列成员与各自模型;/model-switch <成员> = 查该成员实际在用哪个模型(读请求级权威记录);/model-switch <成员> <provider>/<模型> = 切换并回显查证快照 —— 与 AI 工具共用同一条切换 + 查证路径,用户自己就能操作,不必绕道求 AI | AI 工具 list_models / set_member_model + 聊天框指令 /model-switch + 脚本 scripts/check-member-model.mjs |
| 记忆取回 | 检测到上下文用量明显下降(默认 ≥10%,可配)即判定「上下文疑似丢失」——压缩、截断、实例重启后快照未加载都算(比只盯压缩更全)。此时自动把最近 3 轮(可配) 的用户消息文本 + 该轮 AI 的第一条回应(优先取当时的 reasoning)重新注入,让 AI 立刻恢复状态。实现要点:按 zstd 帧流式读日志(常量内存)、只认真实用户消息(排除插件自身注入,防反馈环)、同回合连发合并成一轮、注入总长与单条都有上限。配置项 retrieveMemory*(默认开)。另提供 AI 工具 recall_memory(参数 rounds = 取几轮,默认取配置、上限 50;参数 session = 目标会话:完整 id / 唯一前缀 / 标题子串,缺省或留空即取自身)让 AI 自己按需回溯,也能取其它会话(跨会话排查时在会话内直接看到对方上下文;命中多个候选会给出候选清单,不随便挑一个) | 每轮注入(agent/pre-step)+ AI 工具 recall_memory |
| 上下文用量自查 | AI 按需查自己会话的上下文占用(百分比、已用/容量 tokens)与构成(系统提示词/工具定义/消息文本),占用达 85% 时附收敛建议。数据与界面圆环同源(官方 contextPressure / contextBreakdown 投影),只读、无参数。另:每轮把实时用量注入消息尾部(AI 每轮都能直接看到数字;注入在尾部而非系统提示词前缀 ⇒ 前缀稳定、prompt cache 仍命中;按 turn 门控,一回合只注一次;配置 injectContextUsage 可关) | AI 工具 context_usage + 每轮注入 |
| 跨会话消息 | AI 直接给另一个会话发消息(不经过人转达):先 list_sessions 挑目标,再 send_to_session 投递;目标空闲时由本体自动唤醒它跑一个回合,运行中则排到其下一回合边界(mode:"steer" 改为注入当前回合)。全部走本体官方 prompt API(幂等 requestId、不自己写会话日志)。支持 dryRun 预览(报告目标状态与限流余量,不投递、不消耗配额)。list_sessions 支持 query 子串过滤 + limit/offset 分页(默认只给 20 条,避免整表塞进调用方上下文)。索引快路径 + 后台化:fromIndex=true 直接读落盘索引(秒回、不重建,不含 live 状态与归档态),默认刷新路径先等 3 秒拿热缓存结果、超时就把同一次在途构建交给宿主后台 job 并立刻返回 jobId(冷缓存全量构建实测 226 秒 / 201 会话 / 1.5 GB 日志,热缓存 47 毫秒;job 注册失败会同步降级并带回原因)。硬约束:禁自投、协作链跳数 ≥3 拒绝、同一对会话 60s 内最多 5 条 | AI 工具 list_sessions / send_to_session |
| 创建成员并选模型 | 一条命令完成「创建团队成员 + 让第一轮真实任务就用指定模型」。宿主的 spawn_teammate 参数里没有 provider/model(服务层 SpawnTeammateRequest 也只有 provider,模型来自 agent-team 插件的 freshProvider/forkProvider 配置),直接创建的话首轮一定用默认模型把真实任务跑掉。本工具因此拆成四步:① 用占位任务创建(只消耗一条极短提示)② 立刻中断把这一轮停掉 ③ 等它真正空闲(用宿主 waitForChange 等状态变化,不睡固定时间;否则取消信号会串到下一轮)④ 写 model/selection(与 set_member_model 同一条链路,默认不碰任何 @Remote)然后投递真实任务。参数里 provider/model 是模型 provider(agnes / wb / sa6400 …);创建成员另需子代理 provider(ctx.subagents 注册表,通常 spawn),默认自动取第一个,也可用可选参数 subagentProvider 指定 —— 两者是不同命名空间,混用会报 no subagent provider registered。设模型失败时不投递(否则等于用默认模型白跑),投递失败也如实回执。要彻底「创建前定模型」只能改宿主 agent-team(把 model 加进 request),宿主升级会被覆盖 | AI 工具 create_teammate_with_model |
| 指定模型新建会话 | AI 新建会话并可直接指定 provider/model(建完即切到该模型),可选带一条初始消息让它立刻开始干活。缺省工作目录 = 调用方会话自己的 cwd(不落在 DSH 安装目录里)。本体 create 本身不带模型,所以是 create → selectModel 两步;任一步失败会如实回执(如「会话已建,但模型未设置」),不谎报成功。支持 dryRun 预览(含模型是否存在于目录的核对),不建会话 | AI 工具 create_session |
会话管理面板(侧边栏入口):

设置页 · 模板注入(设置 → 会话管理):

| 项 | 要求 |
|---|---|
| DSH 版本 | 0.2.1 及以上(推荐);0.2.x 早期版本功能可用,但列表缓存不生效(见下) |
| Node | 与宿主 DSH 自带的 Node 一致(无需额外安装) |
| 平台 | Linux(群晖 DSM / fnOS 等);纯 Node 实现,无原生依赖 |
为什么 0.2.1 是推荐下限:本插件的会话列表缓存依赖 sessionPersistence.list() 返回的
SessionPersistenceSnapshot({ header, revision, eventCount?, sizeBytes? })里的 revision
作为「日志变过没有」的变更令牌。0.2.1 起该 API 稳定提供 revision;更早的版本里
list() 只给裸 header(没有 revision),插件会优雅降级:功能全部正常,
只是每次列表构建都要重新解析会话日志(会话多、日志大时会明显变慢、内存占用高)。
早期代码曾探测
persistence.listSnapshots()并期望它返回{ header, revision }—— 该 session 级方法在任何 DSH 版本里都不存在(0.1.6 里同名的listSnapshots(profileDir)是 profile 快照,另一套东西),所以那个探测永远失败、缓存从未生效过。 1.2.0 起统一改用list()并按快照解析。
装到哪个 profile 由 --profile 指定。dsh plugin 会把后面的参数转发给该 profile 目录下的 pnpm,
因此第 2 步与「直接在该 profile 目录执行 pnpm」等价(该命令会初始化首次使用的 profile)。
<DSH_HOME>/profiles/<profile>/local-plugins/dsh-session-conductor/
package.json 与 node_modules/):
dsh plugin --profile <profile> add file:local-plugins/dsh-session-conductor
dsh plugin --profile <profile> install
装完 profile package.json 的 dependencies 里应出现
"dsh-session-conductor": "file:local-plugins/dsh-session-conductor"。package.json 的 dsh.profile.bundles;
插件自带的 cordis.patch.yml 必须用顶层 - insert: 新建 loader 行 —— 顶层 - id: 是"覆盖已有行",
基座没有该 id 时市场会报 patch target not found。loaded。为什么放在 profile 的
local-plugins/而不是全局:插件与宿主版本强绑定,放在 profile 内可随实例 独立升级,也不会让多个 profile 互相污染。
本仓库是公开仓库,可直接用 GitHub 源安装。
⚠️ dsh plugin --profile <名> add … 当前实测会挂死且零输出(两次都以 timeout 结束、日志为空)⇒
安装请在该 profile 目录里直跑 pnpm(dsh plugin 的设计是把参数转发给 profile 的 pnpm,两者本应等价,
但转发这条路目前不可用):
cd <DSH_HOME>/profiles/<profile>
pnpm add github:EIGHTfs/dsh-session-conductor#<commit>
# 等价写法:pnpm add git+https://github.com/EIGHTfs/dsh-session-conductor.git#<commit>
前置条件:
npm —— pnpm 构建 git 来源的包时会在临时目录执行 npm install;
缺 npm 时表现为 ERR_PNPM_PREPARE_PACKAGE + spawn ENOENT: npm: command not found。prepare/prepack 的插件需要放行
(例:dsh-git-push 的 prepare 构建不入库的 lib/client.js)。本仓库没有 prepare/prepack ⇒ 无需这一步;
若安装的是那类插件,先在 profile 的 pnpm-workspace.yaml 里加:allowBuilds:
<包名>@https://codeload.github.com/<owner>/<repo>/tar.gz/<commit>: true
⚠️ key 里带 commit 哈希 ⇒ 换版本/换提交要同步改这一行;否则报 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED。
#<commit> 固定版本(本仓库远端暂无 tag,写 #v1.0.x 会拉不到);公开仓库匿名可装,私有仓库才需凭据。dsh.profile.bundles + cordis.patch.yml 的 - insert: + 重启确认 loaded)。点击侧边栏底部「会话管理」按钮展开浮层面板:
删除语义:面板上的「删除」= 在索引里打标记 + 从列表隐藏,会话日志文件原样保留, 所以还原是秒级且零风险。真正删盘只发生在回收站到期(
trashRetentionDays,默认 7 天) 或「一键清空」,由purgeExpiredTrash执行。
左侧栏「会话管理」独立页:
改 UI 后免重启查看效果 —— 预览能力已移出本插件,统一用独立插件 dsh-useful-tools(0.1.11)的 preview / minihost 工具。
最短三行(实测可用;本仓库没有 assets/preview.spec.mjs 也能出真实界面):
minihost { action: "start", plugin: "<插件根>", port: 31177, services: "<插件根>/test/api/helpers/fake-services.mjs" }
preview { action: "gen", plugin: "<插件根>" }
preview { action: "serve", file: "<插件根>/assets/preview.html", backend: "http://127.0.0.1:31177" }
停止:minihost { action:"stop", port:31177 } + preview { action:"stop", port:31188 };状态:两者都用 action:"status"。
要点:
services 必须传(0.1.11 新增):本插件 apply() 依赖 storageDomain 等宿主服务,不注入时 /templates 会 500、页面显示「storageDomain 不可用」;注入 test/api/helpers/fake-services.mjs 后 /templates 返回 200 真实数据(已实测)。__ModuleLoader__ / require / ctx(slots / locale / effect),调插件 apply(ctx),把 slots.register(def, component) 捕获到的组件 createRoot().render() 到 #root。限制:组件若依赖 useSettings / useSession 这类宿主 hooks 会渲染失败(页面会显示错误与已捕获插槽清单,不白屏);要 100% 还原仍需 spec 提供 mock。locale 取插件自己 ctx.locale.register 的字典,键名不一致会回退成 key。gen 默认产物是 <插件根>/assets/preview.html(会写进仓库)⇒ 不想入库就传 out(如 out: "<临时目录>/preview.html"),并让 serve 的 file 指向同一路径。本仓库已把该产物加进 .gitignore。serve 默认端口 31188,显式传 port 才用你给的;backend 可指向 minihost 的端口(/api/* 反代到模拟后端),也可指向真实 DSH 后端。spec 但文件不存在会直接报错(不静默降级)—— 故意的,避免指错文件还生成一个看不懂的页面。browser_screenshot;「自包含快照」形态不做(理由见 dsh-useful-tools 的 docs/NOT-DONE.md)。test_env { action:"create"|"start"|"stop"|"status", plugin, pluginName } 起独立 DSH_HOME + 自动端口的实例;sync_plugin { write:true, register:true, dshHome:"<测试环境 DSH_HOME>" } 把插件装进去(写 profile 的 dependencies + dsh.profile.bundles,并对齐 node_modules 副本)。minihost { action: "stop", port: 31177 } + preview { action: "stop", port: 31200 };状态:两者都用 action: "status"。browser_screenshot;「自包含快照」形态不做(理由见 dsh-useful-tools 的 docs/NOT-DONE.md)。/model-switch在用户聊天框里直接看/切成员(子代理)的模型,不必求 AI。指令由插件注册到宿主的
ctx.commands 服务,在插件加载时生效 —— 装好或更新后需重载一次实例,输入框里敲 /model 才有补全。
① 看有哪些成员、各自在用什么
/model-switch
成员模型(共 2 个)
· model-test(session-aaaa-1111) — 最近请求=wb/cn:deepseek-v4-flash
· writer(session-bbbb-2222) — 最近请求=n/deepseek-v4.1-flash
要查**实际**在用什么(含历史请求,不只本次进程)或切换:
/model-switch <成员名或 sessionId> ← 查实际模型
/model-switch <成员名或 sessionId> <provider>/<模型> ← 切换并回显查证
「最近请求」取自进程内真实请求记录(瞬时、不扫日志);显示「未知」说明本进程还没见它请求过,用 ② 查历史。若同时显示目标与最近请求且不一致,会附 ⚠️ 与目标不一致(下一回合生效前属正常)。
② 查某个成员实际在用什么
/model-switch writer
成员 writer(session-bbbb-2222)
实际请求使用:n/deepseek-v4.1-flash(2026/10/17 05:18:00)
最近切换意图:n/deepseek-v4.1-flash
切换:/model-switch writer <provider>/<模型>
判定只认请求时真实使用的模型(日志里 request/header 的 data.header.config.{provider,model}),不拿「切换意图」当结论 —— 实测出现过「提示是 agni、请求头仍是 wb」的不一致。日志尚无记录时会回退显示「本次进程内观察到的最近请求」,而不是武断地说没有。
③ 切换,并回显查证结果
/model-switch writer n/deepseek-v4.1-flash
已把成员 writer(session-bbbb-2222) 切到 n/deepseek-v4.1-flash
生效方式:model/selection 事件(官方投影接管)…
最近一次实际请求:wb/cn:deepseek-v4-flash(2026/10/17 05:18:00)
判定:⏳ 待下一回合生效(最近一次请求是切换前发出的,属正常)
确认结果会在该成员下次发起请求时注入回发起方(事件驱动,不阻塞)。
看到 ⏳ 不代表失败:切换本就下一回合生效(当前那次请求早已发出)。该成员下次请求时插件按事件判定,并把 【切换查证】✅ 已确认生效:…(或 ❌ 未生效:期望 X,实际 Y —— 不假装成功)注入回发起方。定位可用成员名或 sessionId(名字支持唯一子串,重名会要求写全);模型必须写成 provider/model,写错会直接给正确格式。
插件以 /api/session-conductor/* 前缀注册宿主路由:
| 端点 | 方法 | 用途 |
|---|---|---|
/list | GET | 会话列表(标题/目录/时间/状态,落盘缓存按 revision 增量)。?fromIndex=true:与工具 list_sessions 的 fromIndex 同义 —— 直接读落盘索引、不做全量构建,秒回精简列表({ok, fromIndex, sessions, hint},不含 live 状态与归档态)。加 ?job=1 或请求头 Accept: application/x-job 改为注册宿主后台 job 并即刻返回 jobId(构建慢时不阻塞请求);HTTP 入口没有执行主体,宿主 job 控制器可能拒绝无主注册(实测回 no job controller serves this agent)—— 此时不再直接 501,而是回退为落盘索引快照(async:false + fromIndex:true + jobUnavailable 原因),索引也没有才如实 501 |
/archive / /restore | POST | 归档 / 恢复会话 |
/delete | POST | 删除会话(拒绝运行中) |
/undo | POST | 撤回最后一条消息 |
/auto-rename | POST | 自动重命名开关 |
/auto-continue | POST | 自动续跑开关 |
/auto-continue-gate | GET/POST | 全局续跑闸门 |
/release | POST | 释放空闲会话 |
/value-analysis | POST | 价值分析 |
/repair / /repair-eio / /repair-dual | POST | 三类损坏修复 |
/search | GET | 全文搜索 |
/compaction-model | GET/POST | 压缩模型 |
/templates | GET/POST | 模板注入(slots 元信息 + 内容) |
/templates/dir | GET | 目录浏览 |
/auto-rename-model | GET | 自动重命名模型(透传官方 modelCatalog) |
/i18n | GET | 语言包(zh/en 外置 JSON) |
示例:
curl http://<host>/api/session-conductor/list
# → { "ok": true, "sessions": [ { "id": "...", "title": "...", "cwd": "...", "updatedAt": 172... } ], "total": N }
curl -X POST http://<host>/api/session-conductor/archive \
-H "Content-Type: application/json" -d '{"id":"<sessionId>"}'
# → { "ok": true, "archived": true }
文件目录结构、版本列表、函数列表由 dsh-git-push 的 doc-tree / doc-version / doc-func 工具维护(独立 md,README 只引用):
FAQs
DSH session management enhancement: archive/restore sessions, batch & conditional delete, AI auto-rename, interrupted-session auto-resume, release idle sessions, workspace grouping, undo last message, repair damaged session logs, value analysis, full-text
The npm package dsh-session-conductor receives a total of 0 weekly downloads. As such, dsh-session-conductor popularity was classified as not popular.
We found that dsh-session-conductor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
vlt 1.5.0 links skills from JavaScript dependencies to coding agents, with lockfile versioning and Socket data to filter out known malicious packages.

Security News
Rust 1.100 will add opt-in dependency cooldowns to Cargo, giving security scanners and maintainers time to catch malicious crate releases.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.