use codex_protocol::ConversationId; use codex_protocol::account::PlanType; use codex_protocol::config_types::ReasoningEffort; use mcp_types::ContentBlock as McpContentBlock; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use serde_json::Value as JsonValue; use ts_rs::TS; use uuid::Uuid; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] pub enum SortOrder { Asc, Desc, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(tag = "type", rename_all = "camelCase")] #[ts(tag = "type")] #[ts(export_to = "v2/")] pub enum Account { #[serde(rename = "apiKey", rename_all = "camelCase")] #[ts(rename = "apiKey", rename_all = "camelCase")] ApiKey { api_key: String }, #[serde(rename = "chatgpt", rename_all = "camelCase")] #[ts(rename = "chatgpt", rename_all = "camelCase")] ChatGpt { email: Option, plan_type: PlanType, }, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(tag = "type")] #[ts(tag = "type")] #[ts(export_to = "v2/")] pub enum LoginAccountParams { #[serde(rename = "apiKey")] #[ts(rename = "apiKey")] ApiKey { #[serde(rename = "apiKey")] #[ts(rename = "apiKey")] api_key: String, }, #[serde(rename = "chatgpt")] #[ts(rename = "chatgpt")] ChatGpt, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct LoginAccountResponse { /// Only set if the login method is ChatGPT. #[schemars(with = "String")] pub login_id: Option, /// URL the client should open in a browser to initiate the OAuth flow. /// Only set if the login method is ChatGPT. pub auth_url: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct LogoutAccountResponse {} #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct GetAccountRateLimitsResponse { pub rate_limits: RateLimitSnapshot, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct GetAccountResponse { pub account: Account, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ModelListParams { /// Opaque pagination cursor returned by a previous call. pub cursor: Option, /// Optional page size; defaults to a reasonable server-side value. pub limit: Option, /// Optional sort order; defaults to descending. pub order: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct Model { pub id: String, pub model: String, pub display_name: String, pub description: String, pub supported_reasoning_efforts: Vec, pub default_reasoning_effort: ReasoningEffort, // Only one model should be marked as default. pub is_default: bool, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ReasoningEffortOption { pub reasoning_effort: ReasoningEffort, pub description: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ModelListResponse { pub data: Vec, /// Opaque cursor to pass to the next call to continue after the last item. /// if None, there are no more items to return. pub next_cursor: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct FeedbackUploadParams { pub classification: String, pub reason: Option, pub conversation_id: Option, pub include_logs: bool, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct FeedbackUploadResponse { pub thread_id: String, } // === Threads, Turns, and Items === // Thread APIs #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadStartParams {} #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadStartResponse { pub thread_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadResumeParams { pub thread_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadResumeResponse { pub thread: Thread, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadArchiveParams { pub thread_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadArchiveResponse {} #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadListParams { /// Opaque pagination cursor returned by a previous call. pub cursor: Option, /// Optional page size; defaults to a reasonable server-side value. pub limit: Option, /// Optional sort order; defaults to descending. pub order: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadListResponse { pub data: Vec, /// Opaque cursor to pass to the next call to continue after the last item. /// if None, there are no more items to return. pub next_cursor: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadCompactParams { pub thread_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct ThreadCompactResponse {} #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct Thread { pub id: String, pub turn: Vec, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct Turn { pub items: Vec, pub status: TurnStatus, pub error: Option, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TurnError { pub message: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum TurnStatus { Completed, Interrupted, Failed, InProgress, } // Turn APIs #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TurnStartParams { pub thread_id: String, pub input: Vec, pub model: String, pub effort: ReasoningEffort, pub summary: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TurnStartResponse { pub turn_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TurnInterruptParams { pub turn_id: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TurnInterruptResponse {} // User input types #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(tag = "type", rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum UserInput { Text(String), Image(ImageInput), } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(tag = "type", rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum ImageInput { #[serde(rename = "image")] Image { url: String }, } // Thread items #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(tag = "type", rename_all = "camelCase")] #[ts(tag = "type")] #[ts(export_to = "v2/")] pub enum ThreadItem { UserMessage { id: String, content: Vec, }, AgentMessage { id: String, text: String, }, Reasoning { id: String, text: String, }, CommandExecution { id: String, command: String, aggregated_output: String, exit_code: Option, status: CommandExecutionStatus, duration_ms: Option, }, FileChange { id: String, changes: Vec, status: PatchApplyStatus, }, McpToolCall { id: String, server: String, tool: String, status: McpToolCallStatus, arguments: JsonValue, result: Option, error: Option, }, WebSearch { id: String, query: String, }, TodoList { id: String, items: Vec, }, ImageView { id: String, path: String, }, CodeReview { id: String, review: String, }, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum CommandExecutionStatus { InProgress, Completed, Failed, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct FileUpdateChange { pub path: String, pub kind: PatchChangeKind, pub diff: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum PatchChangeKind { Add, Delete, Update, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum PatchApplyStatus { Completed, Failed, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum McpToolCallStatus { InProgress, Completed, Failed, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct McpToolCallResult { pub content: Vec, pub structured_content: JsonValue, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct McpToolCallError { pub message: String, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct TodoItem { pub id: String, pub text: String, pub completed: bool, } // === Server Notifications === #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct AccountRateLimitsUpdatedNotification { pub rate_limits: RateLimitSnapshot, } // CamelCased copy of codex_protocol::protocol::{RateLimitSnapshot, RateLimitWindow} // for the v2 surface. This avoids leaking snake_case into the v2 wire format. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct RateLimitSnapshot { pub primary: Option, pub secondary: Option, } impl From for RateLimitSnapshot { fn from(value: codex_protocol::protocol::RateLimitSnapshot) -> Self { Self { primary: value.primary.map(RateLimitWindow::from), secondary: value.secondary.map(RateLimitWindow::from), } } } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct RateLimitWindow { /// Percentage (0-100) of the window that has been consumed. pub used_percent: f64, /// Rolling window duration, in minutes. #[ts(type = "number | null")] pub window_minutes: Option, /// Unix timestamp (seconds since epoch) when the window resets. #[ts(type = "number | null")] pub resets_at: Option, } impl From for RateLimitWindow { fn from(value: codex_protocol::protocol::RateLimitWindow) -> Self { Self { used_percent: value.used_percent, window_minutes: value.window_minutes, resets_at: value.resets_at, } } }