协议与线程模型

codex-rs/protocol/src/protocol.rs 在文件顶部明确写着:Codex session 使用 SQ / EQ 模式,也就是 Submission Queue / Event Queue。这是一种很适合 agent 的异步协议:用户、UI、审批、工具、模型流式输出都可以用事件关联,而不是把一次请求简化成一个同步函数调用。

Submission Queue

Submission 包含:

  • id:提交 ID,用于关联事件。
  • op:实际操作。
  • client_user_message_id:客户端生成的用户消息 ID。
  • trace:可选 W3C trace context。

这种设计让 Codex 可以在一次 turn 中处理多种异步事件:用户中断、审批响应、外部工具回调、配置变化、后台续跑等。

Event Queue

EventMsg 是 UI 和宿主感知 agent 状态的主通道。它覆盖:

  • session configured、turn started、turn completed、turn aborted。
  • agent message delta、reasoning delta、plan delta。
  • tool call lifecycle、approval request、MCP elicitation。
  • warning、error、token usage、thread goal updated。

对 UI 来说,事件流比“最终字符串”更重要,因为 coding agent 的真实体验来自中间过程:执行命令、申请权限、展示 diff、等待用户输入、压缩上下文。

ThreadManager

ThreadManager 负责 live thread 的创建和维护。它保存:

  • threads: HashMap<ThreadId, Arc<CodexThread>>
  • auth、models manager、environment manager
  • skills service、plugins manager、MCP manager
  • extension registry
  • thread store 和 state DB

源码入口:codex-rs/core/src/thread_manager.rs

ForkSnapshot

线程 fork 不是简单复制整个数组。ForkSnapshot 提供两种语义:

  • TruncateBeforeNthUserMessage(usize):切到第 N 个用户消息之前。
  • Interrupted:按“现在中断”的语义复制当前持久化历史,必要时追加 <turn_aborted> marker。

相关辅助逻辑在 codex-rs/core/src/thread_rollout_truncation.rs。它不是按原始 JSONL 行数切,而是识别 user turn boundary、inter-agent trigger turn、rollback marker,从“有效历史”角度计算保留范围。

为什么这套模型适合 agent

Agent 的运行不是线性的:

  • 模型可能请求多个工具。
  • 工具可能触发审批。
  • 用户可能在模型运行时追加输入。
  • 扩展可能在 idle 时启动自动 turn。
  • 长线程可能在中途压缩并替换历史。
  • 子 agent 可能 fork 父线程的一段历史。

Submission/Event + Thread + SessionTask 的分层,把这些非线性行为变成了可记录、可回放、可恢复的事件系统。