mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
This allows us to connect individual tool calls to the logs of the invocations.
335 lines
13 KiB
Rust
335 lines
13 KiB
Rust
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 },
|
|
}
|