第 7 章:Agent 集成——把不兼容的 CLI 变成统一体验
1. Orca 选择“适配 CLI”,而不是重写 Agent
每个 Agent 都有自己的模型、工具、权限与上下文系统。Orca 保留这些原生能力,只统一外围生命周期:
2. TUI_AGENT_CONFIG:差异收敛表
tui-agent-config.ts 为每种 Agent 定义:
- 检测命令与 alias;
- 平台特定 launch command;
- 预期前台进程;
- Prompt 注入模式;
- trust preflight;
- draft-ready signal;
- Windows Shift+Enter 编码。
当前快照覆盖 Claude、Codex、OpenCode、Pi、OMP、Gemini、Droid、Cursor、Copilot、Grok、Devin、Kimi、Qwen、Rovo、Hermes 等大量 CLI。
3. 五类 Prompt 注入
| 模式 | 语义 | 示例风险 |
|---|---|---|
argv | Prompt 作为位置参数 | 以 - 开头需 -- 防误解析 |
flag-prompt | 通过 --prompt 类参数 | 有些模式执行后直接退出 |
flag-prompt-interactive | flag + 保持交互 | 版本参数差异 |
stdin-after-start | TUI 就绪后粘贴 | 启动竞态、bracketed paste |
hermes-query | 专有 startup query | 需要 query authority |
此外 draftPromptFlag / draftPromptEnvVar 可把文字放入 composer 而不提交。例如 Claude 使用 --prefill,Pi 使用 Orca 扩展读取 ORCA_PI_PREFILL。
4. “TUI 已就绪”不是固定延时
直接 sleep 后写 stdin 很脆弱。Orca 根据 Agent 使用不同信号:
- Codex composer prompt;
- bracketed paste 开启后出现可见光标;
- render quiet window;
- shell-ready marker;
- foreground process confirmation。
启动期间还要处理 terminal resize、首帧 grid settle 和 Windows/SSH paste 编码。Prompt delivery 是一个有 generation 与 timeout 的事务,而不是 pty.write(text)。
5. Trust 与账户环境必须在 spawn 前准备
部分 Agent 第一次进入目录会弹 trust 菜单,可能吞掉自动粘贴。Orca 对 Cursor、Copilot、Codex 写入受控 trust artifact。
账户方面:
- Codex 可选择系统 home 或 Orca 管理的 account home;
- Claude 有 runtime auth service 与 live PTY gate;
- launch env 需要删除继承的旧 hook、session stamp 或
CODEX_HOME; - Windows native shell、WSL 和 SSH 的 home 语义不同。
因此环境构建集中在 main 的 PTY 启动路径,客户端不能自由传任意 env 抢走 PATH/loader 权限。
6. Agent Hooks:明确状态的事实源
Agent hook server 是本地 HTTP server。Orca 为支持的 Agent 安装 hook/plugin 配置,Agent 生命周期事件再回传到 server。
典型事件被归一化成四态:
working -> waiting / blocked -> working -> doneAgentStatusEntry 还包含:
- prompt 与 stateStartedAt;
- agent type、model;
- tool name/input;
- interactive question;
- assistant preview;
- provider session;
- orchestration context;
- in-process subagents;
- interrupt 标记与状态历史。
7. Hook 事件怎样绑定到正确 pane
仅凭 cwd 或 terminal title 不足以归属事件。Orca 使用:
- 稳定
paneKey; tabId/worktreeId一致性;- connection scope;
- launch token 的 hash commitment;
- PTY / terminal handle;
- provider session identity。
launch token 不以明文持久化;跨重启保留 hash commitment。损坏、过期或 pane 不一致的 hydrated row 会被丢弃。
8. 状态历史与内存边界
每个 Agent 只保留有限条 stateHistory,当前上限 20。状态持久化使用 trailing debounce,quit 时同步 flush;超过 7 天的旧 row 不会复活。
关闭 tab/pane 的集合也有上限,防止长会话中一关闭一次就永久增长。
这说明状态系统既是 UI 功能,也是长期运行进程的内存管理问题。
9. 中断与缺失 hook 的窄 fallback
明确状态来自 hook,但 Agent 可能在 Ctrl+C 时漏发 cancellation hook。Orca 只在窄条件下根据用户输入和前后状态推断最终 done(interrupted),并抑制迟到的旧 working。
它没有把 terminal title 升格为主事实源,因为标题可能由 shell、tmux、TUI 或用户脚本改变。
10. 子 Agent 与 Agent Teams
两类“子 Agent”需要区分:
- 同一进程/会话内部的 subagent:hook payload 中的
subagents[],没有独立 PTY; - Orca orchestration worker:有独立 pane/PTY/workspace 与 dispatch context。
Claude Agent Teams 还可通过 Orca 的 native pane / tmux shim 把团队成员映射成独立 UI surface。Windows/WSL 则使用不同 fallback。
11. Provider session 与 AI Vault
Agent 会话文件分散在不同目录和格式。AI Vault scanner:
- 扫描 Claude/Codex/Gemini/Grok/Kimi/OpenCode 等来源;
- 解析 JSONL、SQLite 或索引;
- 归一化 title、preview、cwd、timestamp;
- 缓存 parse 结果;
- 支持本地和 remote runtime 扫描;
- 生成精确 resume metadata。
扫描到历史会话不等于直接启动。恢复前还要选择执行 host、账户 home,并判断原 PTY 是否已经在跑。
12. Native Chat 是 transcript 的投影
Orca 的原生聊天视图没有替代 Agent CLI;它读取 Agent 自己的 transcript:
- Claude、Codex、Grok 各有 line decoder;
- tail reader 处理大文件和不完整行;
- watcher 处理 append、rotation 与原生文件事件;
- incremental reader 批量投递;
- tool call/result、image ref、thinking 转成统一 block。
因此 terminal view 与 native chat view 可以展示同一会话的两种投影。输入仍最终进入 Agent CLI 的 composer/PTY。
13. 休眠、恢复与“唯一执行者”
休眠希望释放界面或进程资源,但保留可恢复 session。恢复决策:
网络超时、SSH 断开都属于 unknown,不得直接当 no。
14. 账户用量与 rate limits
Codex、Claude、OpenCode、MiniMax、Grok 等有独立 account/usage service。renderer store 只持有展示用 snapshot;fetch、cookie/token 和 reset 逻辑在 main/runtime。
运行中的 PTY 还会约束账户切换。例如单次 refresh token 被轮换时,不能让一个后台刷新破坏仍在使用旧凭证的 live Claude daemon。
15. 源码导航
- Agent 配置:
src/shared/tui-agent-config.ts - 启动默认值:
src/shared/tui-agent-launch-defaults.ts - hook server:
src/main/agent-hooks/server.ts - hook parser:
src/shared/agent-hook-listener.ts - managed hooks:
src/main/agent-hooks/managed-agent-hook-registry.ts - AI Vault:
src/main/ai-vault/ - Native Chat:
src/main/native-chat/