Skip to content

Cell - Ta Agents ​

Ta 自带的 pi 包(默认开启,可在 Web 客户端的 设置 → 扩展 关闭):把别的 coding agent 当作模型来选。选了 CodeBuddy Code、Claude Code 或 Codex 的对话,每一轮都由那个 Agent 在它自己的 harness 上完成——它自己的系统提示、工具、上下文管理、子 Agent 和登录,所以拿到的就是它在自家模型上的完整体验。只有一个 pi 扩展(src/extension.ts → extension/index.mjs),不改 Ta 的核心,pi 也能装:

bash
pi install npm:@celljs/ta-agents

经 Agent Client Protocol(ACP,stdio)接入:

Agent何时出现怎么启动
CodeBuddy Code装了 cbc 或 codebuddycbc --acp
Claude Code装了 claudenpx -y @agentclientprotocol/claude-agent-acp(ACP 官方适配器,用 Claude Code 自己的登录)
Codex装了 codexnpx -y @agentclientprotocol/codex-acp(同上,用 Codex 自己的登录)

CodeBuddy Code 和在它自己的终端里一样:用 PTC(代码模式,工具都经 REPL 调用;启动时声明 mainAgentSupport / toolModeSupport 并设 CODEBUDDY_CODE_MODE_ENABLED=1,不声明的 ACP 客户端只能用标准模式),新会话的权限模式是 Full Access(options.mode,可在设置里改)。适配器第一次用到时由 npx 下载,版本固定在包里。登录由各 Agent 自己管:没登录时,对话里会提示要在终端执行的命令(cbc、claude、codex login)。

用法 ​

在输入框左侧 + 号的模型列表里选,Agent 的模型在列表里写模型名,旁边标着 Agent(比如 Claude-Opus-5.5 codebuddy-code)。每个 Agent 是一个 provider(codebuddy-code、claude-code、codex),模型就是这个 Agent 自己列出的模型;default(列表里只写 Agent 名字的那一项)表示用 Agent 自己设置的默认模型。Agent 第一次运行后才知道它有哪些模型,之后缓存在 ~/.cache/ta-agents/models.json。思考强度会换成 Agent 自己的档位(例如 xhigh 对应 CodeBuddy Code 的 xhigh 或 max)。

在 pi 的 settings.json 里用 agents 改动内置的 Agent 或加别的 ACP Agent:

json
{
  "agents": {
    "codex": false,
    "claude-code": { "permissions": "ask" },
    "gemini": { "name": "Gemini", "command": "gemini", "args": ["--experimental-acp"] }
  }
}

字段:name、command、args、env、login(提示用户执行的登录命令)、permissions、options(新会话的 Agent 设置,按选项的 id 或类别,如 { "mode": "default" })、clientMeta(initialize 里客户端能力的 _meta)。内置 Agent 的 env、options 与设置里的合并。false 关掉一个内置 Agent。设置里写了某个内置 Agent,即使没找到它的程序也会提供,适合改用别的程序:适配器认环境变量 CLAUDE_CODE_EXECUTABLE(Claude Code 的可执行文件)和 CODEX_PATH(codex 命令),比如用同源的包装版:

json
{
  "agents": {
    "claude-code": { "env": { "CLAUDE_CODE_EXECUTABLE": "/usr/local/bin/tclaude" }, "login": "tclaude login" },
    "codex": { "env": { "CODEX_PATH": "tcodex" }, "login": "tcodex login" }
  }
}

机制 ​

  • 一轮怎么走:pi 每次请求模型时,只把用户自上次回答以来说的话发给 Agent(session/prompt),因为 Agent 自己保存历史。Agent 的文字和思考按流式转成 pi 的消息。
  • 工具调用:Agent 用自己的工具,每次调用在 pi 里记成一次 agent_tool 工具调用(参数是标题、种类和对象,例如 { kind: "execute", target: "npm test" }),所以 Ta 显示成和自己的工具一样的一行,结果就是 Agent 工具的输出。种类是 edit、delete、move 的调用一说出要改的文件(locations 或参数里的 file_path 等),或者带来 ACP diff,扩展就经 pi.events 发 ta:file-write({ path, before? },见 ta-protocol 的 TA_FILE_WRITE_EVENT),让 ta-changes 在 Agent 动手前留下文件原样。具体做法:Agent 开始一次调用时,结束当前这条 assistant 消息(toolUse);pi “执行”agent_tool 时只是等 Agent 把这次调用做完;pi 下一次请求时接着流同一轮。有的 Agent(CodeBuddy Code)先流式发参数,等它说参数齐了(_meta 的 toolArgumentsComplete,或带着参数以 pending 再报一次这次调用)才显示;没有这类信号时,1.5 秒没有新消息或 Agent 开始说别的,也算齐了;同时开始的几次调用放进同一条消息,并行显示。agent_tool 只在当前模型是 Agent 时启用。
  • 会话:一个 pi 会话对一个 Agent 用一个 Agent 会话,它的 id 记在 pi 会话里(自定义条目 ta-agents.session),重新打开对话时用 session/load 接上。分叉,或在 pi 里回退到之前的消息(/tree),都会让下一轮新开一个 Agent 会话,并把到此为止的对话作为文字交给它;中途换到 Agent 时也一样(最多 3 万字)。
  • 进程:同一个 Agent 在同一个目录下的所有会话共用一个进程(CodeBuddy Code 一个进程约 650 MB);按目录分开,是因为 CodeBuddy Code 在启动目录里执行命令,不看会话的目录。10 分钟没有任何一轮就停掉进程,下次用时再启动并加载会话。只在有请求等待回复时保持 pi 进程不退出,所以 pi -p 回答完就退出。
  • Agent 自己继续时:后台任务结束后,Agent 可能自己开始一轮(CodeBuddy Code 用 session_info_update 的 unsolicitedTurn 开始、session_end 收尾;其他 Agent 没有明确的结束标志,就在 3 秒没有消息后收尾)。扩展发一条不显示的消息让 pi 开一轮,把这一轮显示出来。
  • 用户在 Agent 干活时说话:ACP 没有“插话”,所以先存下,这一轮结束后马上作为下一轮发出。停止(中止)会发 session/cancel,下一轮会等 Agent 把被取消的这轮收尾(最多 5 秒)。
  • 权限:和 pi 一样默认不拦:Agent 请求权限时选“允许一次”。设置 permissions: "ask" 后,改为在界面上让用户选。Agent 自己的权限模式(例如 CodeBuddy Code 的配置)照常生效。
  • 压缩:Agent 自己管理上下文。pi 的自动压缩对 Agent 对话一律取消;手动压缩(+ 菜单里的“压缩”或 /compact)改为把 /compact 发给 Agent,由它用自己的命令压缩。
  • 标题:Agent 给会话起了标题(session_info_update)而对话还没有名字时,用它作对话名,标题晚到也会补上。
  • 一轮何时结束:一般是 Agent 回答 session/prompt 时。CodeBuddy Code 要先给会话起完标题才回答(约 5 秒),所以它报告的阶段(_meta 的 agentPhase)从工作中回到 idle 时就算结束;之前请求的阶段(_meta 的 requestId 属于更早的 prompt,比如 /compact 收尾)不算;下一轮发出前再等它把上一轮回答完(最多 15 秒)。
  • 报错的语言:跟随 Ta 页面的语言(页面经 TaSettingsServer.setLanguage 告诉 Ta 服务,即进程的 TA_LANGUAGE),否则跟随这台电脑(LC_ALL、LC_MESSAGES、LANG,再否则 Node 的区域设置)。
  • 斜杠命令:/命令 原样发给 Agent。只在 Agent 自己界面里起作用的命令(CodeBuddy Code 的 /skills、/doctor、/clear 等)在 ACP 里什么都不返回,这时补一句“已执行,没有返回内容”,免得看起来没反应。CodeBuddy Code 在 /compact 之后,本地命令(/cost、/todos)也不再返回内容,这是它那边的行为。
  • 用量:Agent 报告的 token(usage_update)记在每轮最后一条消息上。Claude Code 和 Codex 的适配器只报上下文用量,没有输出 token,所以显示的输出是 0。
  • 多个会话:同一进程的会话共用一个模型运行时,后注册的 provider 会盖掉先注册的;provider 的 streamSimple 按 pi 传来的 sessionId 找到发起请求的那个会话的扩展。加载时就从 settings.json 读 agents,这样恢复到某个 Agent 模型的会话找得到它。
  • ACP 方言:CodeBuddy Code 先流式发参数(_meta.toolArgumentsComplete 表示齐了);Codex 把命令输出放在 _meta.terminal_output_delta,最终结果只有退出码;Claude Code 的结果在最后一次更新的 content 里。

还不支持 ​

  • ssh:// 远程目录里的对话(Agent 跑在本机,看不到远端文件)。
  • Agent 自带的斜杠命令列表(available_commands_update)还没进 + 菜单;在输入框里直接输入 /命令 会原样发给 Agent。
  • 不提供 ACP 的客户端文件系统和终端能力,Agent 用自己的工具读写文件、跑命令。