Skip to content
目录

02 — 分层设计:核心 Crate 职责

Workspace 成员(如何读 Cargo.toml)

codex-rs/Cargo.toml[workspace] members 列表即 官方划分的模块边界。可按「用户可见产物」反向映射 crate:

用户可见主要 crate
codex 主程序cli
交互终端tui
codex exec / 非交互exec
codex app-serverapp-serverapp-server-protocolapp-server-client
codex mcp-servermcp-server(与 protocol 类型共用)
业务逻辑库core
类型与序列化protocol

此外还有大量 竖切能力 crateapply-patchsandboxinglinux-sandboxexec-serverexecpolicyskillshooksfile-searchotel 等,体现 把 codex-core 变瘦 的演进方向(见根目录 AGENTS.md:「resist adding code to codex-core」)。

codex-core:#![deny(clippy::print_stdout, clippy::print_stderr)]

codex-rs/core/src/lib.rs 在 crate 根上 禁止 标准输出/错误:

  • 原因:库代码若直接打印,会破坏 exec 的 JSONL 模式(stdout 必须是纯 JSON 行)、破坏 TUI 画面,且难以测试与归因。
  • 实践:用户可见输出走 TUI、tracing,或由上层 CLI 明确处理。

这是典型的 「库与二进制 IO 契约」 设计,可联系:Node 里 library 不应 console.log、浏览器 SDK 不应直接操作 document

codex-protocol:Op 与 Event 的「单一事实来源」

Op 定义在 codex-rs/protocol/src/protocol.rs,表示 提交给会话的操作(用户回合、中断、shutdown、实时对话等)。使用 #[serde(tag = "type", rename_all = "snake_case")]#[non_exhaustive]

  • tagged enum:序列化稳定、跨语言易对齐。
  • non_exhaustive:允许后续加 variant 而不破坏下游穷尽匹配(Rust 侧强制有 _ 分支或升级)。

codex-app-server-protocol:v2 API 规范

AGENTS.md 规定:新 API 只加在 v2,命名用 *Params / *Response / *Notification,wire 上 camelCase(配置类除外 mirror config.toml)。

这与前端 OpenAPI / GraphQL schema 演进 规则一致:老客户端继续用 v1,新能力走 v2。

依赖方向(简述)

理想依赖图(简化):

cli / exec / tui  →  core, app-server-client, protocol
app-server        →  core, app-server-protocol
core              →  protocol, 各 *-utils, apply-patch, sandboxing, ...
protocol          →  尽量少

禁止:protocol 依赖 core(避免循环、保持类型层纯净)。

小结(一句话)

Codex 用 protocol 定契约、core 做状态机与安全落地、多 UI crate 复用同一核心,并通过 独立 crate 拆沙箱/补丁/策略,控制 codex-core 体积与编译耦合。

延伸阅读

MIT License.