Skip to content
目录

03 — 协议、Op 与 Thread / Turn / Item 模型

App-Server 的三层抽象

codex-rs/app-server/README.md 定义:

  • Thread:用户与 agent 的一段对话,包含多轮 Turn
  • Turn:一轮交互,通常以用户消息开始、以 agent 产出结束;内部有多条 Item
  • Item:持久化、可重放的原子记录(用户消息、推理、工具调用、shell 输出、文件编辑等)。

该模型直接映射到 IDE 线程列表、时间线视图、审计日志,比单纯 messages[] 更易做 增量同步与断线续传

Op:提交语义

Opprotocol/src/protocol.rs 中声明,节选设计要点:

207:247:codex-rs/protocol/src/protocol.rs
/// Submission operation
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
#[non_exhaustive]
pub enum Op {
    /// Abort current task without terminating background terminal processes.
    /// This server sends [`EventMsg::TurnAborted`] in response.
    Interrupt,
    // ...
    /// Legacy user input.
    ///
    /// Prefer [`Op::UserTurn`] so the caller provides full turn context
    /// (cwd/approval/sandbox/model/etc.) for each turn.
    UserInput {
        items: Vec<UserInput>,
        #[serde(skip_serializing_if = "Option::is_none")]
        final_output_json_schema: Option<Value>,
    },

    /// Similar to [`Op::UserInput`], but contains additional context required
    /// for a turn of a [`crate::codex_thread::CodexThread`].
    UserTurn {
        items: Vec<UserInput>,
        cwd: PathBuf,
        approval_policy: AskForApproval,
        // ...
        sandbox_policy: SandboxPolicy,
        model: String,

设计原因(可背诵)

  1. UserTurn 携带 cwd / sandbox / approval / model`:同一 Thread 在不同回合可以改变工作目录与策略,符合「工具调用依赖环境」的真实场景;也避免全局可变配置带来的竞态。
  2. InterruptCleanBackgroundTerminals 分离:中断当前推理/流式任务时,未必希望杀掉用户刻意留着的长期 shell;需要「停任务」与「清后台」两种语义。
  3. Legacy UserInput:兼容旧调用方;注释明确引导迁移到 UserTurn

CodexThread:对外 API 壳

CodexThread 包装 Codex,提供 submit(Op)shutdown_and_waitsteer_input 等:

46:71:codex-rs/core/src/codex_thread.rs
pub struct CodexThread {
    pub(crate) codex: Codex,
    rollout_path: Option<PathBuf>,
    out_of_band_elicitation_count: Mutex<u64>,
    _watch_registration: WatchRegistration,
}

impl CodexThread {
    pub async fn submit(&self, op: Op) -> CodexResult<String> {
        self.codex.submit(op).await
    }

依据:Thread 层附加 rollout 持久化路径文件监视带外 elicitation 计数 等「会话级」 concern,而 Codex 专注执行循环。

延伸追问:steer_input 解决什么问题?

SteerInputError(见 codex.rs)包含:无活跃 Turn、Turn ID 不匹配、当前 Turn 不可 steer、空输入等。典型用途是 在流式生成过程中注入补充说明(类似 ChatGPT 的「编辑上次请求」但发生在 agent 执行期),需要严格的 Turn 状态机 防止错乱写入。

延伸阅读

MIT License.