English | 中文
@deepseek-ai/dsh-subprocess seam 的 E2B 实现。先加载 @deepseek-ai/dsh-e2b,再用本服务取代 dsh-subprocess-local。现有的 Bash、PTY 和 LSP 消费方随后会在共享远程沙箱中执行,无需 E2B 专用的能力包。
| 键 | 默认值 | 含义 |
|---|---|---|
pollMs |
20 |
远程状态/存活轮询间隔(毫秒);每个 tick 是一次控制面请求,调大该值以牺牲退出观察延迟换取更少的请求。 |
Sandbox.commands.run(..., { background: true }) 在远程启动进程。包装层发布进程组 ID 并由适配器完成验证之前,pid 为 -1;stdin 和常规观察会等待该发布。自有启动信号会在分配前中止环境和私有状态准备;分配开始后,取消会等待可清理的临时 SDK 句柄。cwd 和私有 runtimeRoot 来自共享所有者;可执行文件查找会验证绝对路径,或根据沙箱 PATH 加显式覆盖来解析裸名称,并与所有 subprocess 提供方一致地拒绝含分隔符的相对路径。exec setsid --wait 下启动每组 argv,并在 ctx.e2b.runtimeRoot/processes 下记录实际进程组 ID 和私有状态文件。句柄会等待该文件,而不会把 SDK 命令 PID 当作已发布的身份。终止操作以记录的负数 ID 发送 SIGTERM,等待调用方的 graceMs,再升级到 SIGKILL 和 SDK kill 回退;TERM 信号发送或探测失败也会强制触发该升级。进程表探测会把仅含僵尸或已死亡条目的进程组视为完全停稳。强制清理只有在有界探测发现进程组为空后才算成功;否则 waitForExit() 会公开可重试的失败,而已证明的完全停稳会让后续终止操作不再执行任何动作。发布失败与监控失败都会在拒绝前执行同一清理事务。服务 dispose(资源释放)会拒绝新的启动请求、终止并等待每个保留进程组退出,再等待 SDK 结算和私有清理完成,之后沙箱所有者才会释放沙箱。DSH_* 和形似凭据的名称(*KEY*、*SECRET*、*TOKEN*),并把每个有效的 spec.env 条目恢复为调用方显式选择。空名称、= 和违反 NUL 分帧规则的条目会在启动前被拒绝。在用户 profile 脚本运行前,此后的 E2B 命令 shell 与 PTY 登录 shell 会获得位于根目录下、全新随机生成的 HOME,并为每个被清理的环境变量名设置空值覆盖;之后,请求的 argv 会在不改变沙箱用户 umask 的前提下接收序列化环境。宿主环境变量绝不会隐式进入沙箱。私有环境文件在使用后会被删除;命令或终端设置失败时,会先删除其私有状态再拒绝。graceMs 后,适配器会断开未完成的 SDK 流,不公开其中不完整的 spill,并返回该状态,同时保留远程进程组供 waitForExit() 和终止操作使用。原始 pipe 自然完成时,会等待无损传输完成并保留背压;显式终止则会销毁宿主 pipe,并在远程清理前释放受阻的输出写入。批量 stdin 和流式 stdin 都使用 SDK 句柄。spawnTerminal() 使用 E2B 的字节 PTY API,以 mode 为 0600 的私有文件传入原样 argv 与清理后的环境,报告前台进程组,发送真实信号,并通过一项可重试且须等待的 terminate() 清理远程终端会话中仍存活的每个进程组;终止会拒绝新的句柄操作,中止并等待在途写入、检查和信号操作结算,并把仅含僵尸进程的进程组视为已经完全停稳。私有随机输出边界会丢弃 E2B 引导 shell 的提示符和回显的 runner 命令,同时保留请求进程的每个字节,包括其第一个提示符。终端输出推入句柄流时不等待宿主背压:流动的消费方(PTY 后端在构造时就挂上一个)把字节折叠进自身的有界状态,而暂停的消费方会在宿主内存中缓冲。在句柄发布前会一直等待 PTY 分配完成,之后才观察取消,以便由承担清理责任的回滚清理已发布句柄。setup 与 teardown 负责私有状态事务,在服务 dispose 期间中止待处理的 setup 并阻止发布;若 setup 回滚也失败,则由沙箱 dispose 或超时约束其存活时间。提示符检测、scrollback、就绪状态与所有者策略仍归 dsh-terminal-bash 所有。SandboxNotFoundError,证明远程执行环境无法保留工作,因此清理会将其视为完全停稳;其他故障仍可观察。E2B 默认基础镜像提供该适配器调用的运行时和 Bash/GNU 工具:node、bash、setsid、ps、awk、tr、env、base64、chmod、tee、head、rm、kill、id 和 getent。
通过 Consumer 间接影响模型,例如 dsh-tool-bash 背后的 Bash 执行器;这些 Consumer 会渲染远程输出、退出事实、后台增量和 spill 路径。
不会直接失效;请求前缀变更由具名消费方负责。
CommandHandle.stdout 和 .stderr 仍会累积 base64 传输内容,因此无法达到进程管理 seam 通常提供的宿主内存边界,而且传输保留量大于源数据流。pid 保持为 -1;包括 ACP(Agent Client Protocol)子进程后端在内,要求立即获得正 PID 的消费方无法原样使用本提供方。.dsh-e2b 下,直到所有者删除沙箱;本 POC 不提供沙箱内清理。0700/0600 权限无法把 .dsh-e2b 控制文件与并发运行的沙箱进程隔离开。后台进程可以改写 pid/exit-code,或读取尚未被消费的 environment 文件。适配器会验证已发布的值,并拒绝取负后不安全的进程组 ID(<= 1),但真正的隔离需要 E2B 提供按命令用户或带外控制通道。SIGTERM 或 SIGKILL 只有在包装层发布的直接退出码没有胜出时才报告为信号;其他未请求的 SDK 退出始终保留为退出码,包括等于 128 + signal 的值。