第五部分:事件出口与多入口适配
四个组件的边界
text
TUI / IDE / Desktop
↓ 请求与通知
App Server
↓ 调用
Core
↓
Session、模型、工具
| 组件 | 定位 | 主要职责 |
|---|---|---|
codex-rs/core |
Agent 运行时核心 | 组织 Turn、编译上下文、调用模型、执行工具、写入历史、判断继续或结束 |
codex-rs/app-server |
对外服务适配层 | 接收客户端请求、调用 Core、把 Core 事件转换成客户端协议 |
ThreadState |
App Server 的实时状态视图 | 记录当前 Turn、事件历史、订阅配置、连接和实时观察状态 |
| TUI / IDE / Desktop | 交互客户端 | 接收用户输入,展示文本、工具进度、审批和错误 |
一次事件如何到达界面
text
Core 执行模型或工具
↓
产生完成项或流式事件
├─ 完成的 ResponseItem / 工具结果 → 写入 Session 历史
├─ 文本增量 / 状态事件 → 直接发布 EventMsg
└─ 必要时另行写入 rollout 日志
↓
App Server 的 ThreadState 同步实时视图
↓
事件过滤与协议转换
↓
发送给订阅连接
↓
TUI / IDE / Desktop 渲染
例如工具调用完成时,Core 同时做两件事:
text
工具结果
├─ 写入 SessionState.history,作为下一次模型请求的历史
└─ 发布具体事件(如 ExecCommandEnd、McpToolCallEnd 或 PatchApplyEnd),通知外部界面
因此,界面看到的是事件通知;模型下一轮读取的是 SessionState.history。流式增量可以先到界面,完成项与工具结果再进入会话历史;两条路径不是固定先后。

三类数据不要混淆
| 数据 | 作用 | 是否是下一次模型输入 |
|---|---|---|
| Session 历史 | 保存用户消息、模型消息、工具调用和工具结果 | 是 |
ThreadState |
App Server 维护的当前 Thread 实时运行视图 | 通常不是直接输入 |
EventMsg |
表示"刚刚发生了什么"的瞬时通知 | 不是 |
EventMsg 不是事实数据库,也不是 UI 状态本身。它更像状态变化通知:TurnStarted、文本增量、工具调用、工具结果、TurnComplete 等。
代码锚点
app-server/src/request_processors/thread_lifecycle.rs:331:收到 Core 事件后,先调用track_current_turn_event,再进行实时效果处理和客户端事件转换。app-server/src/thread_state.rs:183:维护当前 Turn 的事件状态和终止状态;连接订阅路由由ThreadStateManager管理。app-server/src/request_processors/thread_lifecycle.rs:370:调用apply_bespoke_event_handling,把内部事件转换为对外业务通知。app-server/src/in_process.rs:425:进程内客户端通过事件通道接收服务端通知;TUI 通过 App Server 抽象接 Core,不等于一定经过网络。
最重要的结论
text
Core = Agent 真正执行的地方
App Server = 把 Core 接给外部客户端
ThreadState = App Server 的实时运行视图
TUI / IDE = 事件的消费者和展示者
下一次模型请求不会从界面或 EventMsg 重新构造上下文,而是由 Core 重新读取 Session 历史并编译 prompt。
源码基线:OpenAI Codex
d58d0e5841e0de08e251673db2d5af8cf3a1ad51。文中的流程图用于标出本篇所处的运行阶段。