use codex_protocol::models::WebSearchAction;use serde::Deserialize;use serde::Serialize;use serde_json::Value as JsonValue;use std::collections::HashMap;use ts_rs::TS;/// Top-level JSONL events emitted by codex exec#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]#[serde(tag = "type")]pub enum ThreadEvent { /// Emitted when a new thread is started as the first event. #[serde(rename = "thread.started")] ThreadStarted(ThreadStartedEvent), /// Emitted when a turn is started by sending a new prompt to the model. /// A turn encompasses all events that happen while agent is processing the prompt. #[serde(rename = "turn.started")] TurnStarted(TurnStartedEvent), /// Emitted when a turn is completed. Typically right after the assistant's response. #[serde(rename = "turn.completed")] TurnCompleted(TurnCompletedEvent), /// Indicates that a turn failed with an error. #[serde(rename = "turn.failed")] TurnFailed(TurnFailedEvent), /// Emitted when a new item is added to the thread. Typically the item will be in an "in progress" state. #[serde(rename = "item.started")] ItemStarted(ItemStartedEvent), /// Emitted when an item is updated. #[serde(rename = "item.updated")] ItemUpdated(ItemUpdatedEvent), /// Signals that an item has reached a terminal state—either success or failure. #[serde(rename = "item.completed")] ItemCompleted(ItemCompletedEvent), /// Represents an unrecoverable error emitted directly by the event stream. #[serde(rename = "error")] Error(ThreadErrorEvent),}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ThreadStartedEvent { /// The identified of the new thread. Can be used to resume the thread later. pub thread_id: String,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS, Default)]pub struct TurnStartedEvent {}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct TurnCompletedEvent { pub usage: Usage,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct TurnFailedEvent { pub error: ThreadErrorEvent,}/// Describes the usage of tokens during a turn.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS, Default)]pub struct Usage { /// The number of input tokens used during the turn. pub input_tokens: i64, /// The number of cached input tokens used during the turn. pub cached_input_tokens: i64, /// The number of output tokens used during the turn. pub output_tokens: i64, /// The number of reasoning output tokens used during the turn. pub reasoning_output_tokens: i64,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ItemStartedEvent { pub item: ThreadItem,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ItemCompletedEvent { pub item: ThreadItem,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ItemUpdatedEvent { pub item: ThreadItem,}/// Fatal error emitted by the stream.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ThreadErrorEvent { pub message: String,}/// Canonical representation of a thread item and its domain-specific payload.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ThreadItem { pub id: String, #[serde(flatten)] pub details: ThreadItemDetails,}/// Typed payloads for each supported thread item type.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]#[serde(tag = "type", rename_all = "snake_case")]pub enum ThreadItemDetails { /// Response from the agent. /// Either a natural-language response or a JSON string when structured output is requested. AgentMessage(AgentMessageItem), /// Agent's reasoning summary. Reasoning(ReasoningItem), /// Tracks a command executed by the agent. The item starts when the command is /// spawned, and completes when the process exits with an exit code. CommandExecution(CommandExecutionItem), /// Represents a set of file changes by the agent. The item is emitted only as a /// completed event once the patch succeeds or fails. FileChange(FileChangeItem), /// Represents a call to an MCP tool. The item starts when the invocation is /// dispatched and completes when the MCP server reports success or failure. McpToolCall(McpToolCallItem), /// Represents a call to a collab tool. The item starts when the collab tool is /// invoked and completes when the collab tool reports success or failure. CollabToolCall(CollabToolCallItem), /// Captures a web search request. It starts when the search is kicked off /// and completes when results are returned to the agent. WebSearch(WebSearchItem), /// Tracks the agent's running to-do list. It starts when the plan is first /// issued, updates as steps change state, and completes when the turn ends. TodoList(TodoListItem), /// Describes a non-fatal error surfaced as an item. Error(ErrorItem),}/// Response from the agent./// Either a natural-language response or a JSON string when structured output is requested.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct AgentMessageItem { pub text: String,}/// Agent's reasoning summary.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ReasoningItem { pub text: String,}/// The status of a command execution.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default, TS)]#[serde(rename_all = "snake_case")]pub enum CommandExecutionStatus { #[default] InProgress, Completed, Failed, Declined,}/// A command executed by the agent.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct CommandExecutionItem { pub command: String, pub aggregated_output: String, pub exit_code: Option<i32>, pub status: CommandExecutionStatus,}/// A set of file changes by the agent.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct FileUpdateChange { pub path: String, pub kind: PatchChangeKind,}/// The status of a file change.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]#[serde(rename_all = "snake_case")]pub enum PatchApplyStatus { InProgress, Completed, Failed,}/// A set of file changes by the agent.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct FileChangeItem { pub changes: Vec<FileUpdateChange>, pub status: PatchApplyStatus,}/// Indicates the type of the file change.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]#[serde(rename_all = "snake_case")]pub enum PatchChangeKind { Add, Delete, Update,}/// The status of an MCP tool call.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default, TS)]#[serde(rename_all = "snake_case")]pub enum McpToolCallStatus { #[default] InProgress, Completed, Failed,}/// The status of a collab tool call.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default, TS)]#[serde(rename_all = "snake_case")]pub enum CollabToolCallStatus { #[default] InProgress, Completed, Failed,}/// Supported collab tools.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]#[serde(rename_all = "snake_case")]pub enum CollabTool { SpawnAgent, SendInput, Wait, CloseAgent,}/// The status of a collab agent.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]#[serde(rename_all = "snake_case")]pub enum CollabAgentStatus { PendingInit, Running, Interrupted, Completed, Errored, Shutdown, NotFound,}/// Last known state of a collab agent.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]pub struct CollabAgentState { pub status: CollabAgentStatus, pub message: Option<String>,}/// A call to a collab tool.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct CollabToolCallItem { pub tool: CollabTool, pub sender_thread_id: String, pub receiver_thread_ids: Vec<String>, pub prompt: Option<String>, pub agents_states: HashMap<String, CollabAgentState>, pub status: CollabToolCallStatus,}/// Result payload produced by an MCP tool invocation.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct McpToolCallItemResult { // NOTE: `rmcp::model::Content` (and its `RawContent` variants) would be a // more precise Rust representation of MCP content blocks. We intentionally // use `serde_json::Value` here because this crate exports JSON schema + TS // types (`schemars`/`ts-rs`), and the rmcp model types aren't set up to be // schema/TS friendly (and would introduce heavier coupling to rmcp's Rust // representations). Using `JsonValue` keeps the payload wire-shaped and // easy to export. pub content: Vec<JsonValue>, #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")] #[ts(optional)] pub meta: Option<JsonValue>, pub structured_content: Option<JsonValue>,}/// Error details reported by a failed MCP tool invocation.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct McpToolCallItemError { pub message: String,}/// A call to an MCP tool.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct McpToolCallItem { pub server: String, pub tool: String, #[serde(default)] pub arguments: JsonValue, pub result: Option<McpToolCallItemResult>, pub error: Option<McpToolCallItemError>, pub status: McpToolCallStatus,}/// A web search request.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct WebSearchItem { pub id: String, pub query: String, pub action: WebSearchAction,}/// An error notification.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct ErrorItem { pub message: String,}/// An item in agent's to-do list.#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct TodoItem { pub text: String, pub completed: bool,}#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]pub struct TodoListItem { pub items: Vec<TodoItem>,}