diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index a82cfe0e15..ee110f56e2 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -871,6 +871,7 @@ dependencies = [ "anyhow", "clap", "codex-protocol", + "mcp-types", "paste", "pretty_assertions", "schemars 0.8.22", diff --git a/codex-rs/app-server-protocol/Cargo.toml b/codex-rs/app-server-protocol/Cargo.toml index 58b0b9d607..5aa1c765e7 100644 --- a/codex-rs/app-server-protocol/Cargo.toml +++ b/codex-rs/app-server-protocol/Cargo.toml @@ -14,6 +14,7 @@ workspace = true anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } codex-protocol = { workspace = true } +mcp-types = { workspace = true } paste = { workspace = true } schemars = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index ccd89e6a1f..66aace0cde 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -2,9 +2,11 @@ use codex_protocol::ConversationId; use codex_protocol::account::PlanType; use codex_protocol::config_types::ReasoningEffort; use codex_protocol::protocol::RateLimitSnapshot; +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; @@ -120,3 +122,168 @@ pub struct UploadFeedbackParams { pub struct UploadFeedbackResponse { pub thread_id: String, } + +// === Threads, Turns, and Items === + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct Thread { + pub id: String, + pub turn: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct Turn { + pub items: Vec, + pub status: TurnStatus, + pub error: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct TurnError { + pub message: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub enum TurnStatus { + Completed, + Interrupted, + Failed, + InProgress, +} + +// User input types +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(untagged)] +pub enum UserInput { + Text(String), + Image(ImageInput), +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(tag = "type")] +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")] +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")] +pub enum CommandExecutionStatus { + InProgress, + Completed, + Failed, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct FileUpdateChange { + pub path: String, + pub kind: PatchChangeKind, + pub diff: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub enum PatchChangeKind { + Add, + Delete, + Update, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub enum PatchApplyStatus { + Completed, + Failed, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub enum McpToolCallStatus { + InProgress, + Completed, + Failed, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct McpToolCallResult { + pub content: Vec, + pub structured_content: JsonValue, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct McpToolCallError { + pub message: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[serde(rename_all = "camelCase")] +pub struct TodoItem { + pub id: String, + pub text: String, + pub completed: bool, +}