Codex Handbook
rollout-trace/src/model/runtime.rs 334 lines
use serde::Deserialize;use serde::Serialize;use crate::payload::RawPayloadId;use crate::raw_event::RawEventSeq;use super::AgentPath;use super::AgentThreadId;use super::CodeCellId;use super::CodeModeRuntimeToolId;use super::CodexTurnId;use super::CompactionId;use super::CompactionRequestId;use super::ConversationItemId;use super::EdgeId;use super::McpCallId;use super::ModelVisibleCallId;use super::TerminalId;use super::TerminalOperationId;use super::ToolCallId;use super::session::ExecutionWindow;/// Runtime/debug object for one model-authored `exec` cell.////// The JavaScript source and custom-tool outputs are still conversation items;/// this object tracks the code-mode runtime boundary and nested runtime work.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct CodeCell {    /// Reducer-owned graph id derived from the model-visible `exec` call id.    /// Runtime cell ids are stored separately because they are only handles for    /// later waits and nested code-mode tools.    pub code_cell_id: CodeCellId,    pub model_visible_call_id: ModelVisibleCallId,    pub thread_id: AgentThreadId,    pub codex_turn_id: CodexTurnId,    /// Conversation item containing the model-authored JavaScript.    pub source_item_id: ConversationItemId,    pub output_item_ids: Vec<ConversationItemId>,    /// Raw code-mode runtime/session id, useful when matching runtime payloads.    pub runtime_cell_id: Option<String>,    /// Full JS-cell runtime window; yielded cells can outlive the initial custom call.    pub execution: ExecutionWindow,    pub runtime_status: CodeCellRuntimeStatus,    pub initial_response_at_unix_ms: Option<i64>,    pub initial_response_seq: Option<RawEventSeq>,    pub yielded_at_unix_ms: Option<i64>,    pub yielded_seq: Option<RawEventSeq>,    pub source_js: String,    pub nested_tool_call_ids: Vec<ToolCallId>,    pub wait_tool_call_ids: Vec<ToolCallId>,}/// Code-mode runtime lifecycle.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case")]pub enum CodeCellRuntimeStatus {    /// The `exec` request has been accepted but the runtime has not yet started user code.    Starting,    /// Runtime is executing JavaScript and has not yet yielded or terminated.    Running,    /// Initial `exec` returned while JavaScript kept running in the background.    Yielded,    /// Runtime reached a normal terminal result.    Completed,    /// Runtime reached an error terminal result.    Failed,    /// Runtime was explicitly terminated.    Terminated,}/// Installed conversation-history replacement boundary.////// Duration-bearing upstream requests live in `CompactionRequest`. This object/// is the checkpoint where replacement history became the live thread history./// The boundary marker and the model-visible summary are separate conversation/// items: the marker says where history was replaced, while the summary is part/// of `replacement_item_ids` when the compact endpoint returned one.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct Compaction {    pub compaction_id: CompactionId,    pub thread_id: AgentThreadId,    pub codex_turn_id: CodexTurnId,    pub installed_at_unix_ms: i64,    /// Structural conversation item marking where pre-compaction history ended.    pub marker_item_id: ConversationItemId,    /// Upstream compaction request attempts that contributed to this checkpoint.    pub request_ids: Vec<CompactionRequestId>,    /// Logical conversation items present immediately before replacement.    pub input_item_ids: Vec<ConversationItemId>,    /// Replacement conversation items installed by the checkpoint.    pub replacement_item_ids: Vec<ConversationItemId>,}/// One upstream remote request made while computing a compaction checkpoint.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct CompactionRequest {    pub compaction_request_id: CompactionRequestId,    pub compaction_id: CompactionId,    pub thread_id: AgentThreadId,    pub codex_turn_id: CodexTurnId,    pub execution: ExecutionWindow,    pub model: String,    pub provider_name: String,    pub raw_request_payload_id: RawPayloadId,    /// Full compaction response payload. `None` while running or after pre-response failures.    pub raw_response_payload_id: Option<RawPayloadId>,}/// Runtime operation requested by the model, a JS code cell, or Codex itself.////// A `ToolCall` is not a chat transcript row. Model-visible call/output items/// link to it through `model_visible_*_item_ids`; runtime-only tools can have/// empty model-visible lists.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct ToolCall {    pub tool_call_id: ToolCallId,    /// Globally unique MCP execution ID, when this tool reached an MCP backend.    pub mcp_call_id: Option<McpCallId>,    /// Model-visible protocol call ID, if the model directly requested this tool.    pub model_visible_call_id: Option<ModelVisibleCallId>,    /// Code-mode runtime's internal tool invocation ID, if this call came from JS.    pub code_mode_runtime_tool_id: Option<CodeModeRuntimeToolId>,    pub thread_id: AgentThreadId,    /// Runtime activation that started the tool. Background work may outlive this turn.    pub started_by_codex_turn_id: Option<CodexTurnId>,    pub execution: ExecutionWindow,    pub requester: ToolCallRequester,    pub kind: ToolCallKind,    pub model_visible_call_item_ids: Vec<ConversationItemId>,    pub model_visible_output_item_ids: Vec<ConversationItemId>,    /// Terminal operation started by this tool, when the tool touched a terminal.    pub terminal_operation_id: Option<TerminalOperationId>,    pub summary: ToolCallSummary,    /// Original invocation at the Codex tool boundary.    ///    /// Direct model tools store the model's function/custom call payload here.    /// Code-mode nested tools store the JSON call made by model-authored JS.    /// Runtime protocol events are deliberately kept separate below because    /// they describe how Codex executed the request, not what the caller sent.    pub raw_invocation_payload_id: Option<RawPayloadId>,    /// Result returned to the immediate requester.    ///    /// For direct tools this is the tool output item returned to the model; for    /// code-mode nested tools this is the value returned to JavaScript.    pub raw_result_payload_id: Option<RawPayloadId>,    /// Runtime/protocol payloads observed while executing the tool.    ///    /// Examples include exec begin/end, patch begin/end, and MCP begin/end    /// events. Reducers can use these to build richer runtime objects such as    /// terminal operations without overwriting the canonical invocation/result.    pub raw_runtime_payload_ids: Vec<RawPayloadId>,}/// Requester of a runtime tool.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case", tag = "type")]pub enum ToolCallRequester {    Model,    /// Model-authored JavaScript requested the tool through code-mode.    CodeCell {        code_cell_id: CodeCellId,    },}/// Runtime tool category.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case", tag = "type")]pub enum ToolCallKind {    ExecCommand,    WriteStdin,    ApplyPatch,    Mcp {        server: String,        tool: String,    },    Web,    ImageGeneration,    SpawnAgent,    AssignAgentTask,    SendMessage,    /// Multi-agent wait operation. Code-mode wait is modeled separately.    WaitAgent,    CloseAgent,    Other {        name: String,    },}/// Bounded card/list summary for a tool call.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case", tag = "type")]pub enum ToolCallSummary {    /// Tool is summarized by its terminal operation.    Terminal { operation_id: TerminalOperationId },    Agent {        target_agent_path: AgentPath,        /// Task name/path segment when the operation creates or targets a task.        task_name: Option<String>,        message_preview: String,    },    WaitAgent {        /// Wait target, when narrower than "any child".        target_agent_path: Option<AgentPath>,        timeout_ms: Option<u64>,    },    Generic {        label: String,        input_preview: Option<String>,        output_preview: Option<String>,    },}/// Reusable terminal process/session returned by the runtime.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct TerminalSession {    pub terminal_id: TerminalId,    pub thread_id: AgentThreadId,    pub created_by_operation_id: TerminalOperationId,    pub operation_ids: Vec<TerminalOperationId>,    /// Terminal lifetime. This can outlive the operation that created it.    pub execution: ExecutionWindow,}/// One command/write/poll operation against a terminal session.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct TerminalOperation {    pub operation_id: TerminalOperationId,    /// Runtime terminal/process ID. `None` is legal only while the operation that creates it is starting.    pub terminal_id: Option<TerminalId>,    pub tool_call_id: ToolCallId,    pub kind: TerminalOperationKind,    /// Operation execution window. This is not necessarily the terminal session lifetime.    pub execution: ExecutionWindow,    pub request: TerminalRequest,    /// Runtime-observed terminal result. Model-visible output links through observations.    pub result: Option<TerminalResult>,    pub model_observations: Vec<TerminalModelObservation>,    pub raw_payload_ids: Vec<RawPayloadId>,}/// Terminal operation category.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case")]pub enum TerminalOperationKind {    ExecCommand,    WriteStdin,}/// Terminal request summary.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case", tag = "type")]pub enum TerminalRequest {    ExecCommand {        command: Vec<String>,        display_command: String,        cwd: String,        yield_time_ms: Option<u64>,        max_output_tokens: Option<usize>,    },    /// Request to interact with an existing terminal.    WriteStdin {        /// Bytes/text sent to stdin. Empty string means poll/read without writing bytes.        stdin: String,        yield_time_ms: Option<u64>,        max_output_tokens: Option<usize>,    },}/// Terminal result observed by the runtime.////// This is debugger/runtime output. It is not proof that the model saw the same/// bytes; link model-visible call/output items through `TerminalModelObservation`.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]pub struct TerminalResult {    /// Process exit code. `None` if the process is still running or no exit status was produced.    pub exit_code: Option<i32>,    pub stdout: String,    pub stderr: String,    /// Tool runtime's formatted caller-facing output, when present.    pub formatted_output: Option<String>,    /// Token count before truncation, when the tool runtime reported it.    pub original_token_count: Option<usize>,    /// Streaming chunk ID, when this result was assembled from chunked terminal output.    pub chunk_id: Option<String>,}/// Conversation items that observed a terminal operation.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]pub struct TerminalModelObservation {    pub call_item_ids: Vec<ConversationItemId>,    pub output_item_ids: Vec<ConversationItemId>,    pub source: TerminalObservationSource,}/// Source of model-visible terminal observation.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case")]pub enum TerminalObservationSource {    DirectToolCall,    CodeCellOutput,}/// Directed information-flow relationship between trace objects.#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]pub struct InteractionEdge {    pub edge_id: EdgeId,    pub kind: InteractionEdgeKind,    pub source: TraceAnchor,    pub target: TraceAnchor,    pub started_at_unix_ms: i64,    pub ended_at_unix_ms: Option<i64>,    pub carried_item_ids: Vec<ConversationItemId>,    pub carried_raw_payload_ids: Vec<RawPayloadId>,}/// Information-flow edge category.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case")]pub enum InteractionEdgeKind {    SpawnAgent,    AssignAgentTask,    SendMessage,    AgentResult,    CloseAgent,}/// Typed pointer to one stable reduced-trace object.#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]#[serde(rename_all = "snake_case", tag = "type")]pub enum TraceAnchor {    ConversationItem { item_id: ConversationItemId },    ToolCall { tool_call_id: ToolCallId },    Thread { thread_id: AgentThreadId },}