feat(e2b): add remote runtime providers

This commit is contained in:
Tianyi Cui
2026-07-28 10:05:30 +08:00
parent b9b25f81cb
commit e7b682f1f6
56 changed files with 3565 additions and 30 deletions

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-27-e2b-remote-runtime-poc.md
2026-07-27-e2b-remote-runtime-poc.md: 307a08d6ca77c83bf836bc8d50b071fbf33ac49a
2026-07-27-e2b-remote-runtime-poc.zh.md: bb4e657d999760f000949d509228bbb65f22773a

View File

@@ -0,0 +1,46 @@
# Agent Note: Shared E2B remote runtime POC
Status: implemented
English | [中文](2026-07-27-e2b-remote-runtime-poc.zh.md)
## Problem
A remote coding-agent backend is useful only when file operations and commands observe one coherent world. Attaching E2B independently at individual tools would allow a Bash command and a filesystem edit to address different sandboxes, while moving the complete harness into a remote VM would couple provider experimentation to agent, session, model, persistence, and deployment changes.
## Decision
The E2B integration is a provider-composition POC with one shared lifecycle owner and two capability implementations:
- `@deepseek-ai/dsh-e2b` creates or reconnects one secure E2B sandbox, creates its working and private runtime directories, and owns kill/pause/leave disposal.
- `@deepseek-ai/dsh-fs-e2b` implements `ctx.fs` over that sandbox's Filesystem API.
- `@deepseek-ai/dsh-subprocess-e2b` implements `ctx.subprocess` over E2B Commands and remote Linux process groups.
- The existing `@deepseek-ai/dsh-bash-local` remains the Bash implementation because it delegates all process mechanics to `ctx.subprocess`.
The owner is the sole source of sandbox identity. Providers inject it and never create private sandboxes. The composition therefore gives filesystem tools and Bash one remote cwd, process namespace, and spill/state directory while preserving the existing capability interfaces and model-facing tools.
## POC boundary
Only filesystem state, command processes during the provider lifetime, and adapter-owned remote files move into E2B. The host retains Cordis and plugin objects, the agent loop, agent/session state, session logs and persistence, model requests, skills, subagent orchestration, and E2B SDK buffers. The overlay does not upload or mount the host workspace; identical cwd strings name independent host and remote directories. Managed process groups still terminate and join when the subprocess service disposes, including before a retained-sandbox pause or leave disposition.
The POC has no PTY adapter, LSP-specific integration, session-persistence backend, code-runtime backend, template builder, volume, snapshot, network-policy layer, sandbox catalog, or workspace synchronization. Retained sandbox reconnect proves lifecycle continuity only; it does not reconstruct host process handles, output cursors, or locks.
## Verification
Package tests pin lifecycle cleanup, filesystem seam semantics, subprocess group/stdio/abort behavior, and the package-owned invariant registrations. A credential-gated real Loader composition creates one sandbox, proves FS-write→Bash-read and Bash-write→FS-read in the same remote cwd, proves neither file appears in the host cwd, disposes the composition, and confirms the sandbox id is gone.
## Alternatives considered
**A separate E2B sandbox per capability or tool** — rejected because file and command operations would not share identity or state, defeating the coding-agent use case and multiplying lifecycle ownership.
**Run the entire harness process inside E2B** — rejected because it changes deployment, credential flow, model transport, session durability, plugin loading, and supervision at once. Those questions are independent of proving the provider seams.
**Add E2B-specific Bash, PTY, LSP, persistence, and synchronization packages together** — rejected because Bash already has the required subprocess seam and the other capabilities need separate consumer evidence and lifecycle designs. Their absence is an explicit fidelity boundary, not an incomplete hidden plan.
**Implement filesystem operations through shell commands only** — rejected because that bypasses `ctx.fs` identity, structured errors, version guards, streaming reads, and atomic mutation semantics already consumed by the file tools.
## Consequences
The small composition demonstrates that existing capability seams can move an agent's mutable coding world off-host without changing the loop or model-facing tool packages. `sandboxId` plus pause/leave permits manual state retention for experiments, while kill remains the demo's cleanup policy.
The provider is not interchangeable with the local subprocess backend for every consumer: remote startup cannot synchronously expose a PID, E2B retains complete command output in SDK memory, callback output is not byte-faithful, signal attribution is inferred, and reconnect cannot restore handles. Remote process/spill artifacts accumulate in a retained sandbox. These gaps remain documented POC constraints rather than compatibility shims or new cross-cutting abstractions.

View File

@@ -0,0 +1,46 @@
# Agent Note: 共享 E2B 远程运行时 POC
Status: implemented
[English](2026-07-27-e2b-remote-runtime-poc.md) | 中文
## 问题
远程 coding agent智能体后端只有在文件操作与命令观察到同一个一致环境时才有用。若在各工具上分别接入 E2BBash 命令和文件系统编辑可能访问不同的沙箱;若把完整 harness 迁入远程 VM则会把提供方实验与 agent、会话、模型、持久化及部署变更耦合在一起。
## 决策
E2B 集成是一个提供方组合 POC由一个共享生命周期所有者和两个功能实现组成
- `@deepseek-ai/dsh-e2b` 创建或重新连接一个安全的 E2B 沙箱,创建其工作目录与私有运行时目录,并拥有 kill/pause/leave 资源释放操作。
- `@deepseek-ai/dsh-fs-e2b` 在该沙箱的 Filesystem API 之上实现 `ctx.fs`
- `@deepseek-ai/dsh-subprocess-e2b` 在 E2B Commands 和远程 Linux 进程组之上实现 `ctx.subprocess`
- 现有的 `@deepseek-ai/dsh-bash-local` 继续作为 Bash 实现,因为它把所有进程机制委托给 `ctx.subprocess`
该所有者是沙箱身份的唯一真源。提供方会注入该所有者,绝不创建私有沙箱。因此,该组合让文件系统工具与 Bash 共享一个远程 cwd、进程命名空间和 spill状态目录同时保留现有功能接口与面向模型的工具。
## POC 边界
只有文件系统状态、提供方存续期内的命令进程,以及适配器拥有的远程文件会迁入 E2B。宿主仍保留 Cordis 和插件对象、agent loop智能体循环、agent会话状态、会话日志及其持久化、模型请求、skill技能、subagent 编排和 E2B SDK 缓冲。该 overlay 不会上传或挂载宿主工作区;拼写相同的 cwd 字符串分别指向彼此独立的宿主与远程目录。受管进程组仍会在进程管理服务 dispose资源释放时终止并等待退出包括保留沙箱采用 `pause``leave` 处置方式之前。
本 POC 没有 PTY 适配器、LSP 专用集成、会话持久化后端、代码运行时后端、模板构建器、卷、快照、网络策略层、沙箱目录或工作区同步。保留沙箱后重新连接只能证明生命周期连续性;它不会重建宿主进程句柄、输出游标或锁。
## 验证
包测试固定生命周期清理、文件系统 seam 语义、进程管理的进程组stdio中止行为以及包自有不变式注册。凭据门控的真实 Loader 组合会创建一个沙箱,证明同一远程 cwd 中 FS-write→Bash-read 和 Bash-write→FS-read 双向可见,证明两个文件均未出现在宿主 cwd 中,释放组合,并确认该沙箱 id 已不存在。
## 曾考虑的替代方案
**每项功能或每个工具使用独立的 E2B 沙箱。** 不予采纳,因为文件操作和命令操作将无法共享身份或状态,既违背 coding agent 用例,也会增加生命周期所有者的数量。
**在 E2B 内运行完整 harness 进程。** 不予采纳,因为这会同时改变部署、凭据流、模型传输、会话持久性、插件加载和监管方式。要证明提供方 seam并不需要同时回答这些彼此独立的问题。
**同时添加 E2B 专用 Bash、PTY、LSP、持久化和同步包。** 不予采纳,因为 Bash 已经具备所需的进程管理 seam其他功能则需要各自的消费方证据和生命周期设计。缺少它们是显式保真边界而不是尚未公开的不完整计划。
**仅通过 shell 命令实现文件系统操作。** 不予采纳,因为这会绕过文件工具已经使用的 `ctx.fs` 身份、结构化错误、版本防护、流式读取和原子变更语义。
## 后果
这个小型组合证明,现有功能 seam 可以把 agent 的可变 coding 环境移出宿主,而无需改变循环或面向模型的工具包。`sandboxId``pause``leave` 允许实验手动保留状态,演示仍以 `kill` 作为清理策略。
该提供方并不能对所有消费方与本地进程管理后端互换:远程启动无法同步公开 PIDE2B 会在 SDK 内存中保留完整命令输出回调输出并非字节保真信号归因依靠推断重新连接也无法恢复句柄。保留沙箱后会累积远程进程spill 产物。这些缺口作为 POC 约束明确记录,而不会引入兼容垫片或新的跨领域抽象。