dsh-resource-lease:用租约机制回收 Agent 遗留资源

前言

在 DeepSeek Harness(DSH)里跑 Agent 时,常见情况是:模型调用了 browser_tab_new、把 bash 或 subagent 丢到后台、或在 run_code 里起了临时进程和端口,会话结束或任务被打断后,这些资源仍留在宿主机上。靠提示词提醒「记得关掉」并不稳定,也不适合作为唯一治理手段。

dsh-resource-lease(维护者 r-ayin)把「打开即登记、到期或会话结束即回收」做成插件机制:资源在打开时自动或手动写入租约表,归属当前会话并带 TTL;回收由会话销毁、定时扫描和启动补偿等多条路径触发,不依赖模型是否记得收尾。插件在 SkillHub 分类为 admin-security(安全管理),当前版本 v0.0.1,许可证 MIT。

这是什么

一句话:资源租约治理——把浏览器标签页、后台 job、进程与端口等待回收对象登记为「会话拥有的租约」,用 TTL 与清扫逻辑自动收回;需要长期保留的条目可升级为 pinned。

DSH 社区插件由独立目录站点收录,与 DeepSeek / 幻方无官方从属关系;安装前请自行审阅源码与许可证。插件在当前 dsh 进程权限下执行回收(关 tab、杀 job、对进程发 SIGTERM),权限范围与宿主一致。

三层防线

下面按 README 中的设计,从登记、回收到策略分层说明。

1. 自动登记(零提示词依赖)

通过 tools/result 观察钩子,在资源创建时写入租约,无需在提示词里反复强调「登记资源」:

来源 租约类型 默认 TTL
browser_tab_new browser-tab(tabId + 会话) 240 分钟
bash / subagent / workflow 且 run_in_background job(jobId) 360 分钟
run_code 等其它资源 需 Agent 调用 lease_register 按登记参数

lease_register 支持 kind=process|port|custom;process/port 需带 pid。

2. 自动回收(多触发点冗余)

  1. 会话正常结束:session/disposed 时关闭该会话下全部 session 级租约。
  2. Daemon 周期扫:默认每 60s 处理 TTL 已过期的租约(会话挂死时的兜底)。
  3. 启动补偿:宿主启动约 10s 后扫一遍过期账;注册表持久化在 ~/.dsh/resource-lease/leases.json(重启后仍能回收遗留项)。
  4. 浏览器空闲关实例:在 autoCloseBrowser 为 true 时,空闲 10 分钟且实查无未登记 tab 才调用 browser 关闭;有未登记 tab 时不关,避免误伤共享 Chrome。

回收执行路径(README 实测说明):

  • 浏览器 tab → ctx.tools.execute('browser_tab_close')
  • job → ctx.jobs.kill(jobId, sessionId, reason)(README 注明不宜依赖仅 Agent 作用域可见的 job_kill 工具)
  • process/port → process.kill(pid, SIGTERM)
  • 资源已不存在(not found / ESRCH / already-finished)视为成功;'unknown tool' 不算成功——连续失败 3 次标 failed 并停止重试,可在面板中人工处理

3. 分类策略

  • session(默认):随会话结束或 TTL 自动回收。
  • pinned:用户表示「这个留着」时,通过 lease_pin 升级,不参与自动回收。
  • system:白名单(如 cron/watchdog、外部 Chrome 等不登记项天然豁免)。

Agent 工具面

工具 用途
lease_list 列租约;默认当前会话活跃项,all=true 可看全部
lease_register 手动登记 process/port/custom
lease_pin pinned 升级或降级
lease_release 立即关闭;force=true 时连 pinned 也关
lease_sweep 立即扫一轮;可指定 sessionId 只清该会话

典型流程:后台起服务后 lease_register 登记端口与 pid → 任务结束用 lease_list 核对 → 临时资源 lease_release,长期保留 lease_pin。

对话面板

插件在 conversation.view 槽位提供 「资源租约」 面板:活跃租约表、单条关闭/固定、清扫过期,约 10s 自动刷新。宿主 HTTP API 路径为 /resource-lease/api/{leases,release,pin,sweep}。

配置

默认行为可通过包内 cordis.patch.yml 覆盖,README 给出的项包括:

配置项 含义(README 默认值)
sweepIntervalMs 清扫间隔,60s
tabTtlMinutes 浏览器 tab TTL,240 分钟
jobTtlMinutes 后台 job TTL,360 分钟
autoCloseBrowser 是否启用浏览器空闲关闭
browserIdleCloseMs 浏览器空闲判定,10 分钟
keepClosedHours 已关闭记录保留,72 小时

修改后按你当前的 DSH 插件加载方式重载配置即可。

安装与构建

已抓取资料中未给出 SkillHub 或 README 里的单行 dsh plugin add … 安装命令,此处不凭仓库名拼接命令。请从 SkillHub 目录页 或 GitHub 仓库 按页面说明安装到 DSH 环境。

若你需要从源码构建(README 说明可离线构建、无需 npm install 依赖安装步骤作为主路径):

# 宿主侧
bash scripts/build.sh
# DSH_CHECKOUT 会自动探测 ~/dsh-harness

# 客户端
bash scripts/build-client.sh
# tsc 输出 CJS,并用手工 __ModuleLoader__ 包装

# 开发热重载(DSH 内置流程)
dev_build_plugin → dev_inject_plugin / dev_reload_package

package.json 中 scripts.build 同样指向 bash scripts/build.sh。

适用场景与注意

适合:长时间跑 Agent、频繁开浏览器调试、大量 run_in_background job 或本地临时服务的开发与运维场景;需要一眼看到「当前会话占用了什么」并在 UI 或工具里收尾时。

注意:

  1. 自动登记覆盖 README 列出的钩子路径;其它资源务必 lease_register,否则不会进入租约表。
  2. 浏览器整实例关闭有「无未登记 tab」安全闸,不能替代你对共享环境的 tab 管理习惯。
  3. pinned 资源只有 lease_release(且 force=true)或人工操作才会释放。
  4. 安装前检查源码与 MIT 许可证;回收动作与 dsh 同权限,生产环境请评估影响面。

结尾

dsh-resource-lease 把 Agent 遗留的 tab、job、进程和端口收成可查询、可 TTL、可固定的租约,用会话销毁、定时扫和启动补偿多条路径做回收,并暴露工具与「资源租约」面板。若你正在 DSH 里治理半自动资源生命周期,可从目录页或仓库 README 安装并核对 cordis.patch.yml。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜