Cell - Ta Exec
Agent 执行命令、读写文件的地方,作用相当于 Codex 的 exec-server:Agent 循环留在宿主,进程与文件操作交给执行环境。不依赖 pi。
ts
interface ExecEnvironment {
readonly cwd: string; // 执行环境里的路径
readonly local: boolean; // 是否就是本机
exec(command, options?): Promise<ExecResult>; // 一次性执行,流式输出,超时/中止时杀掉整个进程组
spawn(command, args, options?): ExecProcess; // 长驻进程,stdin/stdout 通信(MCP、LSP)
readFile / writeFile / stat / readdir / mkdir / remove
connect?(port, host?): Promise<ExecSocket>; // 环境所在机器上的 TCP 连接(只有非本机环境有),用于端口转发
}路径一律是执行环境里的路径:不要交给 node:fs,交给模型的也只能是这些路径。
实现
LocalExecEnvironment | 本机 |
RemoteExecEnvironment + ExecClient | 另一台机器(容器、沙箱)上的 ta exec-server |
ExecServer | ta exec-server 本身:一个不加载 Cell 的 HTTP 服务(空载约 60 MB) |
ExecStdio | 同一个服务器跑在标准输入输出上(一行一条消息),只服务一个宿主;输入结束或 60 秒收不到消息(宿主每 15 秒 ping)时结束它启动的一切 |
SshHost | 经系统 ssh 连到另一台机器:自己的 ControlMaster 登录一次,其余命令共享;ssh 要问用户的经 SSH_ASKPASS 交给 ask;探测主机,没有 Node.js 18+ 时在本机下载(按 SHASUMS256 校验)后经 ssh 装到 ~/.ta/server/node;把 EXEC_REMOTE_SOURCE(scripts/remote-server.ts 打包的 ExecStdio,约 7 KB,按哈希命名)放到 ~/.ta/server/<哈希>/,在用户的登录 shell 里启动,client 就是它的 ExecClient |
SshConfig | ~/.ssh/config(含 Include)里没有通配符的 Host |
bash
# 执行机(容器里)
TA_EXEC_TOKEN=... ta exec-server --host 0.0.0.0 --port 4200 --cwd /workspace
# 宿主
TA_EXEC_TOKEN=... ta serve --exec ws://exec-host:4200/exec协议(ExecRpc)对标 Codex exec-server:WebSocket 上(或标准输入输出上,一行一条)的 JSON-RPC 2.0,process/exec、process/spawn、process/write、process/kill、fs/readFile、fs/writeFile、fs/stat、fs/readdir、fs/mkdir、fs/remove;net/connect、net/write、net/close;进程输出以 process/output、process/stderr、process/exit 通知推送,连接的数据以 net/data、net/closed 推送,字节用 base64。ExecClient 不管传输:ExecClient.webSocket(url, token) 或 SshHost 给它连接。
- 鉴权:token(
Authorization: Bearer或?token=)。安全边界是执行机本身(与 pi 一致:不在工具调用前审批,靠操作系统/容器隔离)。 - 环境变量:工具传入的环境只发送它在宿主环境之上新增或改动的变量(
RemoteExecEnvironment.delta),宿主的变量(API key 等)不会到执行机。 - epoch 隔离:宿主连接时带 epoch(默认是宿主启动时间)。更大的 epoch 连上后,执行机断开更小 epoch 的连接、杀掉它们启动的进程,之后它们的调用一律报
CELL_TA_EXEC_STALE_EPOCH:会话迁到新的宿主实例后,旧实例不能再执行工具。 - 进程归属连接:连接断开即结束该连接启动的进程;
ExecClient在下一次调用时重连。
宿主侧的 pi 内置工具(read、bash、edit、write、ls、find、! 命令)与 stdio MCP 服务都经执行环境运行(见 @celljs/ta-harness 的 ExecExtension、ExecMcpTransport);ripgrep 版的 grep 只能在本机运行,远程时去掉,模型改用 bash 里的 rg。