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 },}