refactor(e2b): group remote providers

This commit is contained in:
Tianyi Cui
2026-07-28 14:52:37 +08:00
parent 6667102890
commit e64d40837c
81 changed files with 171 additions and 249 deletions

View File

@@ -2,5 +2,5 @@
# 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: 730e6f0e1958ccab43a5a6a11931f9407b38ef16
2026-07-27-e2b-remote-runtime-poc.zh.md: 5f1ae07b985787a7dc1bd61f2a5b7ff0512d85c1
2026-07-27-e2b-remote-runtime-poc.md: a713cca3fd9e7ee11a2c487bf6ed2c3a205dc502
2026-07-27-e2b-remote-runtime-poc.zh.md: 7afd54f72622d51a3d71719b3b4975ccd7f83e3a

View File

@@ -6,29 +6,43 @@ 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.
A remote coding-agent backend is useful only when filesystem operations, one-shot commands, persistent terminals, language servers, and model-written programs observe one coherent world. Attaching E2B independently at individual tools would let those capabilities address different sandboxes, while retaining host PTY, LSP, or worker backends would split state across machines even when the cwd strings match.
Moving the complete harness into a remote VM would unify that state but also couple provider experimentation to plugin loading, credentials, model transport, agent/session durability, supervision, and deployment. The POC needs to test the existing capability boundaries without taking on those independent concerns.
## Decision
The E2B integration is a provider-composition POC with one shared lifecycle owner and two capability implementations:
The E2B integration is an opt-in provider-composition POC. Its six E2B-specific packages live under `packages/e2b/` while retaining seam-specific npm names:
- `@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.
- `@deepseek-ai/dsh-pty-e2b` registers an E2B byte-PTY backend on `ctx.pty` while the existing registry retains exact-Agent ownership.
- `@deepseek-ai/dsh-lsp-e2b` registers configured remote language servers on `ctx.lsp`, reads source through E2B Filesystem APIs, and runs servers through `dsh-subprocess-e2b`.
- `@deepseek-ai/dsh-code-runtime-e2b` registers `ctx.codeRuntime`, runs each model program in a fresh remote worker, and dispatches binding functions in the host process.
- The existing `@deepseek-ai/dsh-bash-local` remains the Bash implementation because it delegates all process mechanics to `ctx.subprocess`.
- PTY, LSP, and Code Runtime remain separate capability providers over the same owner, with their runtime split recorded in the [extension decision](2026-07-28-e2b-interactive-semantic-code-runtime-poc.md).
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.
The owner is the sole source of sandbox identity. Providers inject it and never create private sandboxes, so filesystem tools, Bash, interactive shells, language servers, and code workers share one remote cwd, process namespace, and adapter-private directory while preserving the existing capability interfaces and model-facing tools.
The providers reuse the PTY, LSP, Code Runtime, and subprocess seams without changing their model-facing consumers or the agent loop. Backend-neutral PTY text handling lives in `dsh-pty`; the LSP protocol engine accepts `processId: null` for a server in another process namespace; Code Runtime exports its output-ledger and lossless-JSON helpers for backend parity.
## POC boundary
Filesystem state, managed commands, interactive shells, language servers, code workers, and adapter-owned 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, capability protocol state, 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 their provider disposes, including before a retained-sandbox pause or leave disposition.
E2B owns the mutable filesystem, command and Bash processes, PTY shell and foreground process groups, language-server processes and source reads, the Code Runtime runner and worker, and adapter-private files under `.dsh-e2b`.
The POC has no session-persistence 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 PTY/LSP/code-runtime state, process handles, output cursors, pending calls, or locks.
The host owns Cordis and plugin objects, the agent loop, agent/session/goal state, session logs and persistence, LLM calls, prompts and tools, authority decisions, skills, subagent orchestration, PTY buffers and readiness state, LSP JSON-RPC ids/queues/protocol state, Code Runtime type stripping/output accounting/binding dispatch, and E2B SDK/network orchestration. The overlay does not upload, mount, or synchronize the host workspace; identical cwd strings name independent host and remote directories.
Byte-sensitive protocols use the narrowest adapter required by E2B's callback shapes. PTY consumes the SDK's byte callback directly. LSP and Code Runtime install dependency-free remote helpers that encode raw payloads as validated newline-delimited base64 JSON, keeping E2B's decoded command callbacks on an ASCII transport.
Retaining a sandbox preserves remote files and unmanaged remote state only. Reconnect does not reconstruct host PTY sessions, buffers, process handles, LSP connections or requests, code workers, binding calls, timers, output cursors, or locks. Managed groups terminate and join when their provider disposes before the shared owner pauses, leaves, or kills the sandbox.
The POC has no session-persistence backend, template builder, volume, snapshot, network-policy layer, sandbox catalog, workspace synchronization, durable remote handles, or whole-harness execution.
## Verification
Package tests pin lifecycle cleanup, filesystem semantics, subprocess groups, byte framing, PTY readiness/signals, LSP transport and containment, Code Runtime binding/output behavior, and package-owned invariant registrations. A credential-gated real Loader composition creates one sandbox, exercises filesystem, Bash/subprocess, PTY, LSP, and Code Runtime through source and built package paths, proves host-workspace isolation, disposes the composition, and confirms the sandbox id is gone.
Focused package suites pin owner lifecycle cleanup, filesystem semantics, subprocess process groups, configuration and publication rollback, byte framing and multibyte boundaries, PTY readiness/signals, LSP transport and source containment, Code Runtime bindings, hostile traffic, output limits, timeout/abort ordering, disposal to quiescence, and package-owned invariant registrations. Adjacent local-backend suites pin the shared PTY utilities and the LSP cross-namespace `processId` behavior.
A credential-gated Loader composition creates one real E2B sandbox and exercises FS-to-Bash and Bash-to-FS visibility, multibyte PTY output and `SIGINT`, multibyte LSP hover and definition results, Code Runtime host bindings and typed rejection under mutation of adapter-captured intrinsics, wall timeout, abort, runner cleanup, host-workspace isolation, and final sandbox deletion. The same scenario runs through source imports and built package exports.
## Alternatives considered
@@ -40,8 +54,16 @@ Package tests pin lifecycle cleanup, filesystem semantics, subprocess groups, by
**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.
**Use the host PTY, LSP, and worker backends unchanged** — rejected because they use host process and filesystem APIs; sharing an absolute cwd string does not share state across machines.
**Expose E2B Commands as one generic transport and bypass capability providers** — rejected because PTY needs byte callbacks and foreground signaling, LSP needs byte-faithful stdio plus remote source containment, and Code Runtime needs bidirectional host binding calls and hostile-peer validation. Bypassing their registries would also fork model-facing behavior.
**Add a generic distributed-runtime abstraction first** — rejected because the existing capability seams already carry the required contracts. A new cross-cutting interface would speculate about persistence, synchronization, and reconnect semantics beyond the POC.
**Restore live capability handles after `sandboxId` reconnect** — rejected because remote identity alone cannot reconstruct host callbacks, pending promises, authority, protocol state, or output cursors. Claiming continuity would make stale remote processes appear managed when they are not.
## 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 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 remote-file retention for experiments, while kill remains the demo's cleanup policy.
The provider is not interchangeable with local backends for every consumer: remote startup cannot synchronously expose a PID, E2B retains complete command output in SDK memory, ordinary command callbacks are not byte-faithful, signal attribution is partly inferred, and reconnect cannot restore handles or protocol state. PTY uses E2B's byte API; LSP and Code Runtime add validated ASCII framing where protocol bytes matter. Remote process/spill artifacts accumulate in a retained sandbox. These gaps remain documented POC constraints rather than compatibility shims or new cross-cutting abstractions.
The providers are not interchangeable with local backends for every consumer: remote startup cannot synchronously expose a PID, E2B retains complete command output in SDK memory, ordinary command callbacks are not byte-faithful, signal attribution is partly inferred, and reconnect cannot restore handles or protocol state. PTY uses E2B's byte API; LSP and Code Runtime add validated ASCII framing where protocol bytes matter. Remote process/spill artifacts accumulate in a retained sandbox, Code programs share a JavaScript realm with Node worker internals, and a process that deliberately escapes a captured remote process group does not become reconnectable or owned. These gaps remain documented POC constraints rather than compatibility shims or new cross-cutting abstractions.

View File

@@ -6,29 +6,43 @@ Status: implemented
## 问题
远程 coding agent智能体后端只有在文件操作与命令观察到同一个一致环境时才有用。若在各工具上分别接入 E2BBash 命令和文件系统编辑可能访问不同的沙箱;若把完整 harness 迁入远程 VM则会把提供方实验与 agent、会话、模型、持久化及部署变更耦合在一起
远程 coding agent智能体后端只有在文件系统操作、一次性命令、持久终端、语言服务器和模型编写的程序观察到同一个一致环境时才有用。若在各工具上分别接入 E2B这些功能可能访问不同的沙箱;即使 cwd 字符串相同,保留宿主 PTY、LSP 或 worker 后端也会让状态分散在不同机器上
把完整 harness 迁入远程 VM 可以统一这些状态但也会把提供方实验与插件加载、凭据、模型传输、agent会话持久性、监管和部署耦合在一起。这个 POC 只需测试现有功能边界,不应把这些彼此独立的问题纳入范围。
## 决策
E2B 集成是一个提供方组合 POC,由一个共享生命周期所有者和两个功能实现组成
E2B 集成是一个选择性启用的提供方组合 POC。它的 6 个 E2B 专用包package位于 `packages/e2b/` 下,同时保留按 seam 区分的 npm 名称
- `@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-pty-e2b``ctx.pty` 上注册 E2B 字节 PTY 后端,并把精确的 Agent 所有权保留在现有注册表中。
- `@deepseek-ai/dsh-lsp-e2b``ctx.lsp` 上注册已配置的远程语言服务器,通过 E2B Filesystem API 读取源代码,并通过 `dsh-subprocess-e2b` 运行服务器。
- `@deepseek-ai/dsh-code-runtime-e2b` 注册 `ctx.codeRuntime`,在全新的远程 worker 中运行每个模型程序,并在宿主进程中分发绑定函数。
- 现有的 `@deepseek-ai/dsh-bash-local` 继续作为 Bash 实现,因为它把所有进程机制委托给 `ctx.subprocess`
- PTY、LSP 与 Code Runtime 仍是基于同一所有者的独立功能提供方;其运行时划分见[扩展决策](2026-07-28-e2b-interactive-semantic-code-runtime-poc.md)。
该所有者是沙箱身份的唯一真源。提供方会注入该所有者,绝不创建私有沙箱因此,该组合让文件系统工具Bash 共享一个远程 cwd、进程命名空间和 spill状态目录,同时保留现有功能接口与面向模型的工具。
该所有者是沙箱身份的唯一真源。提供方会注入该所有者,绝不创建私有沙箱因此文件系统工具Bash、交互式 shell、语言服务器和代码 worker 会共享一个远程 cwd、进程命名空间和适配器私有目录,同时保留现有功能接口与面向模型的工具。
这些提供方复用 PTY、LSP、Code Runtime 与进程管理 seam不更改面向模型的消费方或 agent loop智能体循环。后端无关的 PTY 文本处理位于 `dsh-pty`LSP 协议引擎允许位于另一个进程命名空间的服务器使用 `processId: null`Code Runtime 导出输出账本与无损 JSON 辅助函数,以保持各后端一致。
## POC 边界
文件系统状态、受管命令、交互式 shell、语言服务器、代码 worker 和适配器拥有的文件会迁入 E2B。宿主仍保留 Cordis 和插件对象、agent loop智能体循环、agent会话状态、会话日志及其持久化、模型请求、skill技能、subagent 编排、功能协议状态和 E2B SDK 缓冲。该 overlay 不会上传或挂载宿主工作区;拼写相同的 cwd 字符串分别指向彼此独立的宿主与远程目录。受管进程组仍会在所属提供方 dispose资源释放时终止并等待退出包括保留沙箱采用 `pause``leave` 处置方式之前
E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与前台进程组、语言服务器进程及源码读取、Code Runtime 运行器和 worker以及 `.dsh-e2b` 下的适配器私有文件
本 POC 没有会话持久化后端、模板构建器、卷、快照、网络策略层、沙箱目录或工作区同步。保留沙箱后重新连接只能证明生命周期连续性;它不会重建宿主 PTYLSPCode Runtime 状态、进程句柄、输出游标、待处理调用或锁
宿主拥有 Cordis 与插件对象、agent loop、agent会话goal 状态、会话日志及持久化、LLM大语言模型调用、提示词与工具、权限决策、skill技能、subagent 编排、PTY 缓冲与就绪状态、LSP JSON-RPC id队列协议状态、Code Runtime 类型剥离/输出计量/绑定分发,以及 E2B SDK网络编排。该 overlay 不会上传、挂载或同步宿主工作区;拼写相同的 cwd 字符串分别指向彼此独立的宿主与远程目录
对字节敏感的协议只使用适配 E2B 回调形状所需的最窄适配器。PTY 直接消费 SDK 的字节回调。LSP 与 Code Runtime 会安装无依赖的远程辅助程序,把原始载荷编码为经过验证、以换行分隔的 base64 JSON并通过 ASCII 传输承载 E2B 已解码的命令回调。
保留沙箱只会保存远程文件与未受管的远程状态。重新连接不会重建宿主 PTY 会话、缓冲、进程句柄、LSP 连接或请求、代码 worker、绑定调用、定时器、输出游标或锁。受管进程组会在所属提供方 dispose资源释放时终止并等待退出之后共享所有者才会暂停、脱离或终止沙箱。
本 POC 没有会话持久化后端、模板构建器、卷、快照、网络策略层、沙箱目录、工作区同步、持久远程句柄或完整 harness 执行。
## 验证
包测试固定生命周期清理、文件系统语义、进程管理的进程组、字节分帧、PTY 就绪状态信号、LSP 传输与源码路径约束、Code Runtime 绑定/输出行为,以及包自有不变式注册。凭据门控的真实 Loader 组合会创建一个沙箱通过源代码与已构建包路径演练文件系统、Bash进程管理、PTY、LSP 和 Code Runtime证明宿主工作区隔离释放组合并确认该沙箱 id 已不存在
聚焦包测试套件固定所有者生命周期清理、文件系统语义、进程管理的进程组、配置与发布回滚、字节分帧与多字节边界、PTY 就绪状态信号、LSP 传输与源码路径约束、Code Runtime 绑定、恶意通信、输出上限、超时/中止顺序、等待完全停稳的资源释放,以及包自有不变式注册。相邻本地后端测试套件固定共享 PTY 工具函数,以及 LSP 跨命名空间 `processId` 行为
凭据门控的 Loader 组合会创建一个真实 E2B 沙箱,并演练 FS-to-Bash 与 Bash-to-FS 可见性、多字节 PTY 输出和 `SIGINT`、多字节 LSP 悬停与定义结果、Code Runtime 宿主绑定,以及适配器已捕获 intrinsic 被修改时的类型化 reject、墙钟超时、中止、运行器清理、宿主工作区隔离以及最终删除沙箱。同一场景分别通过源代码导入与已构建包导出运行。
## 曾考虑的替代方案
@@ -40,8 +54,16 @@ E2B 集成是一个提供方组合 POC由一个共享生命周期所有者和
**仅通过 shell 命令实现文件系统操作。** 不予采纳,因为这会绕过文件工具已经使用的 `ctx.fs` 身份、结构化错误、版本防护、流式读取和原子变更语义。
**原样使用宿主 PTY、LSP 与 worker 后端。** 不予采纳,因为它们使用宿主的进程与文件系统 API在不同机器上复用同一个绝对 cwd 字符串并不会共享状态。
**把 E2B Commands 公开为通用传输并绕过功能提供方。** 不予采纳,因为 PTY 需要字节回调和前台信号LSP 需要字节保真的 stdio 与远程源码路径约束Code Runtime 则需要双向宿主绑定调用与不可信对等方验证。绕过其注册表还会使面向模型的行为产生分叉。
**先添加通用分布式运行时抽象。** 不予采纳,因为现有功能 seam 已承载所需契约。新的跨领域接口会预先假定 POC 范围之外的持久化、同步与重连语义。
**在 `sandboxId` 重连后恢复活动功能句柄。** 不予采纳,因为只有远程身份,无法重建宿主回调、待处理 promise、权限、协议状态或输出游标。若声称保持连续性就会让陈旧的远程进程看似仍受管理实际并非如此。
## 后果
这个小型组合证明,现有功能 seam 可以把 agent 的可变 coding 环境移出宿主,而无需改变循环或面向模型的工具包。`sandboxId``pause``leave` 允许实验手动保留状态,演示仍以 `kill` 作为清理策略。
这个小型组合证明,现有功能 seam 可以把 agent 的可变 coding 环境移出宿主,而无需改变循环或面向模型的工具包。`sandboxId``pause``leave` 允许实验手动保留远程文件,演示仍以 `kill` 作为清理策略。
提供方并不能对所有消费方与本地后端互换:远程启动无法同步公开 PIDE2B 会在 SDK 内存中保留完整命令输出普通命令回调并非字节保真信号归因部分依靠推断重新连接也无法恢复句柄或协议状态。PTY 使用 E2B 的字节 APILSP 与 Code Runtime 则在必须保真处理协议字节之处增加经过验证的 ASCII 分帧。保留沙箱后会累积远程进程spill 产物。这些缺口作为 POC 约束明确记录,而不会引入兼容垫片或新的跨领域抽象。
这些提供方并不能对所有消费方与本地后端互换:远程启动无法同步公开 PIDE2B 会在 SDK 内存中保留完整命令输出普通命令回调并非字节保真信号归因部分依靠推断重新连接也无法恢复句柄或协议状态。PTY 使用 E2B 的字节 APILSP 与 Code Runtime 则在必须保真处理协议字节之处增加经过验证的 ASCII 分帧。保留沙箱后会累积远程进程spill 产物,模型程序与 Node worker 内部机制共享一个 JavaScript realm有意逃离已捕获远程进程组的进程也不会因此变得可重新连接或由该组合管理。这些缺口作为 POC 约束明确记录,而不会引入兼容垫片或新的跨领域抽象。

View File

@@ -1,6 +0,0 @@
# 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-28-e2b-interactive-semantic-code-runtime-poc.md
2026-07-28-e2b-interactive-semantic-code-runtime-poc.md: befaa47dd56b7f425e72978ae040bd0815cc9f92
2026-07-28-e2b-interactive-semantic-code-runtime-poc.zh.md: 677c3a09f6846320d3e000e9607becb3dee865cf

View File

@@ -1,57 +0,0 @@
# Agent Note: E2B interactive, semantic, and code-runtime POC
Status: implemented
English | [中文](2026-07-28-e2b-interactive-semantic-code-runtime-poc.zh.md)
## Problem
The [shared E2B runtime](2026-07-27-e2b-remote-runtime-poc.md) proves that filesystem operations and one-shot commands can inhabit one remote coding world, but an assembled coding agent also uses persistent terminals, language servers, and model-written Code Mode programs. Falling back to host implementations for those capabilities splits observable state: a Bash edit exists in E2B while a host PTY, LSP process, or code worker addresses a different filesystem and process namespace.
Moving the complete harness process into E2B would unify that state but also changes plugin loading, credentials, model transport, session durability, supervision, and deployment. The POC needs to test the existing capability boundaries without taking on those independent concerns.
## Decision
Three opt-in providers extend the existing shared sandbox:
- `@deepseek-ai/dsh-pty-e2b` registers an E2B byte-PTY backend on `ctx.pty` and keeps exact-Agent ownership in the existing registry.
- `@deepseek-ai/dsh-lsp-e2b` registers configured remote language servers on `ctx.lsp`, reads source through E2B Filesystem APIs, and runs servers through `dsh-subprocess-e2b`.
- `@deepseek-ai/dsh-code-runtime-e2b` registers `ctx.codeRuntime`, runs each model program in a fresh remote worker, and dispatches binding functions in the host process.
All three inject `ctx.e2b`; none creates another sandbox. The opt-in overlay composes them with `dsh-fs-e2b`, `dsh-subprocess-e2b`, and the existing `dsh-bash-local`, so files, foreground commands, interactive shell processes, language servers, and code workers observe one remote cwd.
The providers reuse the PTY, LSP, Code Runtime, and subprocess seams without changing their model-facing consumers or the agent loop. Backend-neutral PTY text handling moves into `dsh-pty`; the LSP protocol engine accepts `processId: null` for a server in another process namespace; Code Runtime exports its output-ledger and lossless-JSON helpers for backend parity.
## Runtime boundary
E2B owns the mutable filesystem, command and Bash processes, PTY shell and foreground process groups, language-server processes and source reads, the Code Runtime runner and worker, and adapter-private files under `.dsh-e2b`.
The host owns Cordis and plugin objects, agent/session/goal state, session logs and persistence, LLM calls, prompts and tools, authority decisions, PTY buffers and readiness state, LSP JSON-RPC ids/queues/protocol state, Code Runtime type stripping/output accounting/binding dispatch, and E2B SDK/network orchestration. The host workspace is not mounted or synchronized merely because its absolute cwd string is reused remotely.
Byte-sensitive protocols use the narrowest adapter needed for E2B's callback shapes. PTY consumes the SDK's byte callback directly. LSP and Code Runtime install dependency-free remote helpers that encode raw payloads as validated newline-delimited base64 JSON, keeping E2B's decoded command callbacks on an ASCII transport.
Retaining a sandbox preserves remote files and any unmanaged remote state only. Reconnect does not reconstruct host PTY sessions, buffers, process handles, LSP connections or requests, code workers, binding calls, timers, output cursors, or locks. Managed groups are terminated and awaited when their provider disposes before the shared owner pauses, leaves, or kills the sandbox.
## Verification
Focused unit suites pin configuration, publication rollback, byte framing, multibyte boundaries, readiness, signals, timeout/abort ordering, output limits, hostile Code Runtime traffic, and disposal to quiescence. Adjacent local-backend suites pin the shared PTY utilities and the LSP cross-namespace `processId` behavior.
A credential-gated Loader composition creates one real E2B sandbox and exercises FS-to-Bash and Bash-to-FS visibility, multibyte PTY output and `SIGINT`, multibyte LSP hover and definition results, Code Runtime host bindings and typed rejection under mutation of adapter-captured intrinsics, wall timeout, abort, runner cleanup, host-workspace isolation, and final sandbox deletion. The same scenario runs through source imports and built package exports.
## Alternatives considered
**Run the complete harness inside E2B** — rejected because it couples this provider experiment to credentials, LLM transport, plugin deployment, session persistence, supervision, and remote package installation. None is necessary to prove the capability seams.
**Use the host PTY, LSP, and worker backends unchanged** — rejected because they use host process and filesystem APIs; sharing an absolute cwd string does not share state across machines.
**Expose E2B Commands as one generic transport and bypass capability providers** — rejected because PTY needs byte callbacks and foreground signaling, LSP needs byte-faithful stdio plus remote source containment, and Code Runtime needs bidirectional host binding calls and hostile-peer validation. Bypassing their registries would also fork model-facing behavior.
**Add a generic distributed-runtime abstraction first** — rejected because the three existing capability seams already carry the required contracts. A new cross-cutting interface would speculate about persistence, synchronization, and reconnect semantics beyond the POC.
**Restore live capability handles after `sandboxId` reconnect** — rejected because remote identity alone cannot reconstruct host callbacks, pending promises, authority, protocol state, or output cursors. Claiming continuity would make stale remote processes appear managed when they are not.
## Consequences
The assembled POC keeps the coding world remote without moving the agent runtime or changing model-visible tool contracts. It demonstrates that PTY, LSP, and Code Runtime can share E2B state through existing plugins, while making the remaining host state explicit.
This is not a deployment platform. Language-server installation, templates, volumes, snapshots, network policy, workspace synchronization, durable remote handles, and whole-harness execution remain outside scope. E2B SDK buffering and host protocol state remain memory costs. Code programs share a JavaScript realm with Node worker internals, and a process that deliberately escapes a captured remote process group is not made reconnectable or owned by this composition.

View File

@@ -1,57 +0,0 @@
# Agent Note: E2B 交互式、语义与代码运行时 POC
Status: implemented
[English](2026-07-28-e2b-interactive-semantic-code-runtime-poc.md) | 中文
## 问题
[共享 E2B 运行时](2026-07-27-e2b-remote-runtime-poc.md)证明,文件系统操作与一次性命令可以共处一个远程 coding 环境,但组装完成的 coding agent智能体还会使用持久终端、语言服务器以及模型编写的 Code Mode 程序。若这些功能回退到宿主实现可观测状态就会分裂Bash 修改存在于 E2B 中,而宿主 PTY、LSP 进程或代码 worker 面向的却是另一个文件系统与进程命名空间。
把完整 harness 进程迁入 E2B 可以统一这些状态,但也会改变插件加载、凭据、模型传输、会话持久性、监管和部署。这个 POC 只需测试现有功能边界,不应把这些彼此独立的问题纳入范围。
## 决策
三个可选提供方扩展现有共享沙箱:
- `@deepseek-ai/dsh-pty-e2b``ctx.pty` 上注册 E2B 字节 PTY 后端,并把精确的 Agent 所有权保留在现有注册表中。
- `@deepseek-ai/dsh-lsp-e2b``ctx.lsp` 上注册已配置的远程语言服务器,通过 E2B Filesystem API 读取源代码,并通过 `dsh-subprocess-e2b` 运行服务器。
- `@deepseek-ai/dsh-code-runtime-e2b` 注册 `ctx.codeRuntime`,在全新的远程 worker 中运行每个模型程序,并在宿主进程中分发绑定函数。
三个提供方均注入 `ctx.e2b`,无一创建其他沙箱。可选叠加配置将它们与 `dsh-fs-e2b``dsh-subprocess-e2b` 和现有的 `dsh-bash-local` 组合,使文件、前台命令、交互式 shell 进程、语言服务器和代码 worker 观察到同一个远程 cwd。
这些提供方复用 PTY、LSP、Code Runtime 与进程管理 seam不更改面向模型的消费方或 agent loop智能体循环。后端无关的 PTY 文本处理移入 `dsh-pty`LSP 协议引擎允许位于另一个进程命名空间的服务器使用 `processId: null`Code Runtime 导出输出账本与无损 JSON 辅助函数,以保持各后端一致。
## 运行时边界
E2B 拥有可变文件系统、命令和 Bash 进程、PTY shell 与前台进程组、语言服务器进程及源码读取、Code Runtime 运行器和 worker以及 `.dsh-e2b` 下的适配器私有文件。
宿主拥有 Cordis 与插件对象、agent会话goal 状态、会话日志及持久化、LLM大语言模型调用、提示词与工具、权限决策、PTY 缓冲与就绪状态、LSP JSON-RPC id队列协议状态、Code Runtime 类型剥离/输出计量/绑定分发,以及 E2B SDK网络编排。宿主工作区不会仅因远程复用了其绝对 cwd 字符串就被挂载或同步。
对字节敏感的协议只使用适配 E2B 回调形状所需的最窄适配器。PTY 直接消费 SDK 的字节回调。LSP 与 Code Runtime 会安装无依赖的远程辅助程序,把原始载荷编码为经过验证、以换行分隔的 base64 JSON并通过 ASCII 传输承载 E2B 已解码的命令回调。
保留沙箱只会保存远程文件与任何未受管的远程状态。重新连接不会重建宿主 PTY 会话、缓冲、进程句柄、LSP 连接或请求、代码 worker、绑定调用、定时器、输出游标或锁。受管进程组会在所属提供方 dispose资源释放时终止并等待退出之后共享所有者才会暂停、脱离或终止沙箱。
## 验证
聚焦单元测试固定配置、发布回滚、字节分帧、多字节边界、就绪状态、信号、超时/中止顺序、输出上限、恶意 Code Runtime 通信,以及等待完全停稳的资源释放。相邻本地后端测试固定共享 PTY 工具函数,以及 LSP 跨命名空间 `processId` 行为。
凭据门控的 Loader 组合会创建一个真实 E2B 沙箱,并演练 FS-to-Bash 与 Bash-to-FS 可见性、多字节 PTY 输出和 `SIGINT`、多字节 LSP 悬停与定义结果、Code Runtime 宿主绑定,以及适配器已捕获 intrinsic 被修改时的类型化 reject、墙钟超时、中止、运行器清理、宿主工作区隔离以及最终删除沙箱。同一场景分别通过源代码导入与已构建包导出运行。
## 曾考虑的替代方案
**在 E2B 内运行完整 harness。** 不予采纳因为这会把这项提供方实验与凭据、LLM 传输、插件部署、会话持久化、监管和远程包安装耦合。要证明功能 seam无需引入任何一项。
**原样使用宿主 PTY、LSP 与 worker 后端。** 不予采纳,因为它们使用宿主的进程与文件系统 API在不同机器上复用同一个绝对 cwd 字符串并不会共享状态。
**把 E2B Commands 公开为通用传输并绕过功能提供方。** 不予采纳,因为 PTY 需要字节回调和前台信号LSP 需要字节保真的 stdio 与远程源码路径约束Code Runtime 则需要双向宿主绑定调用与不可信对等方验证。绕过其注册表还会使面向模型的行为产生分叉。
**先添加通用分布式运行时抽象。** 不予采纳,因为现有三个功能 seam 已承载所需契约。新的跨领域接口会预先假定 POC 范围之外的持久化、同步与重连语义。
**在 `sandboxId` 重连后恢复活动功能句柄。** 不予采纳,因为只有远程身份,无法重建宿主回调、待处理 promise、权限、协议状态或输出游标。若声称保持连续性就会让陈旧的远程进程看似仍受管理实际并非如此。
## 后果
组装后的 POC 在不迁移 agent 运行时、不改变模型可见工具契约的前提下,把 coding 环境保留在远程。它证明 PTY、LSP 与 Code Runtime 可以通过现有插件共享 E2B 状态,同时明确列出仍留在宿主的状态。
这不是部署平台。语言服务器安装、模板、卷、快照、网络策略、工作区同步、持久远程句柄和完整 harness 执行仍不在范围内。E2B SDK 缓冲与宿主协议状态仍会占用内存。模型程序与 Node worker 内部机制共享一个 JavaScript realm有意逃离已捕获远程进程组的进程也不会因此变得可重新连接或由该组合管理。