Delete @deepseek-ai/dsh-invariants, every package's ./invariant companion and its tests, the invariant gates and Vitest setup, the scoped-event resolver generator, and the INVARIANT-coded listener rethrow paths. Update docs, READMEs, Agent Notes, and add an upgrade guide.
9.7 KiB
description, kind
| description | kind |
|---|---|
| 面向开发者与维护者的 shell 执行器 seam 说明,用于选择、组合或实现基于 ctx.shell 的命令执行。 | package-reference |
@deepseek-ai/dsh-shell
English | 中文
概述
使用 ctx.shell 运行输出有界的 shell 命令,或让命令作为后台工作继续运行。同一个执行句柄支持前台结果与后台读取。配置文件可以选择本地或沙箱化的 Bash 或 PowerShell 执行方式,而无需更改调用方。执行前解析请求,以显式确定工作目录、超时与输出上限。命令退出、超时和调用方中止都会作为结果返回;只有基础设施故障才会 reject,模型可见的渲染与沙箱指引由 bash 和 pwsh 工具负责。
目录
使用本包
当 agent(智能体)或进程内插件需要运行 shell 命令并读取输出、保持进程运行并轮询它,或让前台命令有办法活过自己的 deadline 时,使用 ctx.shell。执行方法只有一个——execute(spec) 在准备完成后返回句柄——「前台」是调用方等待什么的属性,而不是 spawn 的属性。它是每个 shell 执行器与面向模型的 bash/pwsh 工具共同依赖的约定,因此基于它编写的代码可以运行在任意执行器实现之上。
前台命令
等待句柄的 result() 投影即可在前台执行命令。promise 在命令结束时 resolve:非零退出、执行器超时终止或调用方中止终止都是结果,绝不是 rejection。result() 只在基础设施失败时 reject,例如工作目录不可用或缺少 shell。结果携带退出码或信号、是超时还是中止截断了运行(首因归类),以及收集到的 stdout/stderr;流超出预算时还附带 spill 文件路径。
const execution = await ctx.shell.execute(ctx.shell.resolve({ command: 'ls -la' }))
const result = await execution.result()
console.log(result.exitCode, result.stdout.text)
后台进程
以 onExpiry: 'none' 解析请求并保留句柄:不布置任何 deadline,进程一直跑到被 kill 或自行结束。用 readOutput() 增量读取输出——连续读取绝不会重复交付,有损读取会指向完整流的 spill 文件。用 kill() 终止由提供方管理的进程范围(直接命令结束后返回 false),并等待 done 完成直接命令结算。job id、所有权、轮询与通知属于通用 ctx.jobs 运行时,工具层会把句柄注册进去。ShellProcess.observed 在同一份捕获流上暴露非消费的偏移读取器——供独立于消费游标的观察者使用,例如任务注册表的拉取源——包括被拒绝的 spawn 留在 stderr 上的 spawn failed: … 提示。
deadline 与有界等待
deadline 包含异步准备耗时。进程启动前到期会返回已结算的句柄,其结果为 timedOut: true,输出为空。取消或准备失败会在发布句柄前拒绝 execute;迟到的准备结果不会启动进程。
seam 只有两种到期策略,没有任何移交协议。'kill' 在 deadline 停下命令并把结果归类为 timedOut;'none' 不设 deadline,只有调用方的信号和 kill() 能停下命令。只想等一段时间的调用方以 'none' 运行命令并自己限定等待时长:调用方停止等待后句柄依然有效,那一刻没有任何东西易手。bash/pwsh 工具正是这样做的——组合中有 job registry 时,每条命令一启动就登记到 ctx.jobs 并等待该 job,所以超时后仍在运行的前台命令只是继续作为它本来就是的那个 job 运行。
请求与已解析 spec
每次执行都从带可选字段的 ShellExecRequest 开始;执行器的 resolve() 在任何东西运行之前,把它变成默认值与上限都已显式填好的 ShellExecSpec。这一请求/spec 拆分正是仓库在包边界显式解析的模板:调用方绝不依赖 execute 内部隐藏的默认值。resolve() 从执行器配置与请求填充工作目录、超时与到期策略(默认 'kill')、对每次调用的覆盖值设上限,并按原样携带可选输入——stdin、普通 env 与受信任的 DSH_* 快照。
选择并组合一个执行器
seam 本身不是执行器:每个组合只挂载一个提供方,工具即可不加改动地工作。在 POSIX 上,dsh-bash-local 以全新的 bash -c 进程运行命令,dsh-bash-sandbox 则通过沙箱能力限制每条命令;在 Windows 上,对应实现是 dsh-pwsh-local 与 dsh-pwsh-sandbox。bash 与 pwsh 工具只在挂载沙箱执行器时公布升权字段。最小的组合只需执行器本身:
- id: bash
name: '@deepseek-ai/dsh-bash-local'
config:
cwd: /path/to/workspace
共享的退出状态约定
工具结果以机器可读的退出标记结尾——[exit code: N] 或 [killed by signal: X]——模型因此总能知道命令如何结束。seam 拥有该标记格式,以及把渲染结果拆回输出正文与结构化退出状态的 parseExitStatus 辅助函数,使 bash 与 pwsh 两个工具永远不会在此漂移。
理解实现
实现细节——点击展开
本节解释 seam 的设计并指出实现它们的代码位置;可观察行为已在使用本包中完整说明。
设计理念
本包是标准能力 seam 中的一个角色:命名执行器约定的 Service Definition,Service Provider 与 Consumer 各自拆分,使每个角色都能独立演进(见能力 seam 笔记)。两项决策锚定了该约定:
- 边界处的显式解析。
resolve(request)是应用默认值与上限的唯一位置;execute只接受已解析的 spec,绝不再次默认化,因此实现内部不会藏有隐藏的兜底值。 - 一次执行,多个投影。
execute在准备完成后返回句柄;前台结果与后台游标读取都是同一个已 spawn 进程上的投影,前台/后台是调用方的选择,绝不是第二条 spawn 路径。句柄不带 id 或所有者;job 身份、所有权与生命周期属于通用ctx.jobs运行时,使执行器与会话保持独立。
源码地图
| 文件 | 职责 |
|---|---|
src/index.ts |
插件入口:抽象 ShellExecutor 服务与共享设置命名空间 |
src/types.ts |
请求/spec 词汇、ShellExecution、ShellRunResult 与沙箱事实 |
src/render.ts |
parseExitStatus:shell 工具共享的退出状态标记约定 |
设置命名空间
SHELL_SETTINGS_NAMESPACE 由此处导出而非由某个提供方导出,因为它命名的是能力而不是实现:一个宿主只组装一个 ctx.shell 提供方,因此各提供方共享同一个命名空间而永不冲突,在平台间携带的设置文档也能在两边继续解析。
后台生命周期与归属
已 spawn 的进程属于 subprocess 服务而非执行器:它能在仅重载执行器后存活,并在组合拆解时被终止并 join。实现必须遵守 seam 的语义——result() 只在基础设施失败时 reject;句柄在准备完成后发布且其 done 绝不 reject(无论同步还是异步的 provider rejection 都把句柄结算为 killed、把不声明阶段的提示写入 stderr,同时 result() 以同一失败 reject;活句柄在本次执行自己的 kill() 或 abort 之后才到来的 rejection 则结算为其终态);readOutput 是消费式的,有损读取会报告 spill 文件。
进一步探索
当 seam 约定不够用时阅读以下页面。它们从共享子系统参考逐步进入具体执行器与面向模型的工具。
- Bash 执行器子系统 —— 请求/spec 词汇、结果与完整的服务约定。
- bash-local —— 默认 POSIX 执行器:全新的
bash -c进程、预算与 deadline。 - bash-sandbox —— 沙箱执行器:沙箱模式、拒绝与升权。
- tool-bash —— 基于该 seam 的面向模型
bash工具。 - 能力 seam 笔记 —— 本 seam 遵循的 Service Definition / Provider / Consumer 拆分。
模型体验
通过 dsh-tool-bash 间接影响;该工具会将执行器输出与沙箱事实转为指引和保留的工具结果 token。
KV Cache 影响
不会直接导致 KV Cache 失效;请求前缀的任何变更由具名消费方负责。
已知限制与延期工作
这些限制说明该 seam 不提供什么。它们是当前包约束,不是路线图。
- 没有交互式输入词汇——
stdin只在 spawn 时写入一次并关闭;seam 没有向运行中任务继续输入的通道,也没有 PTY 会话概念。 - 前台超时始终由执行器负责——seam 上由调用方负责 deadline 的模式已由工具调用超时策略笔记明确延期。
开发备注
维护者的工作上下文——点击展开
None.