diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 83a7c781b..b813b5946 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -11938,6 +11938,12 @@ "supportsPersonality": { "default": false, "type": "boolean" + }, + "upgrade": { + "type": [ + "string", + "null" + ] } }, "required": [ diff --git a/codex-rs/app-server-protocol/schema/json/v2/ModelListResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ModelListResponse.json index 8c8126bb6..a1b3f7114 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ModelListResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ModelListResponse.json @@ -59,6 +59,12 @@ "supportsPersonality": { "default": false, "type": "boolean" + }, + "upgrade": { + "type": [ + "string", + "null" + ] } }, "required": [ diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/Model.ts b/codex-rs/app-server-protocol/schema/typescript/v2/Model.ts index 72daa93ed..7528a8fad 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/Model.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/Model.ts @@ -5,4 +5,4 @@ import type { InputModality } from "../InputModality"; import type { ReasoningEffort } from "../ReasoningEffort"; import type { ReasoningEffortOption } from "./ReasoningEffortOption"; -export type Model = { id: string, model: string, displayName: string, description: string, supportedReasoningEfforts: Array, defaultReasoningEffort: ReasoningEffort, inputModalities: Array, supportsPersonality: boolean, isDefault: boolean, }; +export type Model = { id: string, model: string, upgrade: string | null, displayName: string, description: string, supportedReasoningEfforts: Array, defaultReasoningEffort: ReasoningEffort, inputModalities: Array, supportsPersonality: boolean, isDefault: boolean, }; diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index 67e7013a3..dbc51fa9f 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -998,6 +998,7 @@ pub struct ModelListParams { pub struct Model { pub id: String, pub model: String, + pub upgrade: Option, pub display_name: String, pub description: String, pub supported_reasoning_efforts: Vec, diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index d6fae4846..78a4f3cf9 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -90,7 +90,7 @@ Example (from OpenAI's official VSCode extension): - `turn/interrupt` — request cancellation of an in-flight turn by `(thread_id, turn_id)`; success is an empty `{}` response and the turn finishes with `status: "interrupted"`. - `review/start` — kick off Codex’s automated reviewer for a thread; responds like `turn/start` and emits `item/started`/`item/completed` notifications with `enteredReviewMode` and `exitedReviewMode` items, plus a final assistant `agentMessage` containing the review. - `command/exec` — run a single command under the server sandbox without starting a thread/turn (handy for utilities and validation). -- `model/list` — list available models (with reasoning effort options). +- `model/list` — list available models (with reasoning effort options and optional `upgrade` model ids). - `collaborationMode/list` — list available collaboration mode presets (experimental, no pagination). - `skills/list` — list skills for one or more `cwd` values (optional `forceReload`). - `skills/remote/read` — list public remote skills (**under development; do not call from production clients yet**). diff --git a/codex-rs/app-server/src/models.rs b/codex-rs/app-server/src/models.rs index 133dc73cc..350b86f92 100644 --- a/codex-rs/app-server/src/models.rs +++ b/codex-rs/app-server/src/models.rs @@ -22,6 +22,7 @@ fn model_from_preset(preset: ModelPreset) -> Model { Model { id: preset.id.to_string(), model: preset.model.to_string(), + upgrade: preset.upgrade.map(|upgrade| upgrade.id), display_name: preset.display_name.to_string(), description: preset.description.to_string(), supported_reasoning_efforts: reasoning_efforts_from_preset( diff --git a/codex-rs/app-server/tests/suite/v2/model_list.rs b/codex-rs/app-server/tests/suite/v2/model_list.rs index c3b4ec708..c2431d24d 100644 --- a/codex-rs/app-server/tests/suite/v2/model_list.rs +++ b/codex-rs/app-server/tests/suite/v2/model_list.rs @@ -51,6 +51,7 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> { Model { id: "gpt-5.2-codex".to_string(), model: "gpt-5.2-codex".to_string(), + upgrade: None, display_name: "gpt-5.2-codex".to_string(), description: "Latest frontier agentic coding model.".to_string(), supported_reasoning_efforts: vec![ @@ -80,6 +81,7 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> { Model { id: "gpt-5.1-codex-max".to_string(), model: "gpt-5.1-codex-max".to_string(), + upgrade: Some("gpt-5.2-codex".to_string()), display_name: "gpt-5.1-codex-max".to_string(), description: "Codex-optimized flagship for deep and fast reasoning.".to_string(), supported_reasoning_efforts: vec![ @@ -109,6 +111,7 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> { Model { id: "gpt-5.1-codex-mini".to_string(), model: "gpt-5.1-codex-mini".to_string(), + upgrade: Some("gpt-5.2-codex".to_string()), display_name: "gpt-5.1-codex-mini".to_string(), description: "Optimized for codex. Cheaper, faster, but less capable.".to_string(), supported_reasoning_efforts: vec![ @@ -130,6 +133,7 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> { Model { id: "gpt-5.2".to_string(), model: "gpt-5.2".to_string(), + upgrade: Some("gpt-5.2-codex".to_string()), display_name: "gpt-5.2".to_string(), description: "Latest frontier model with improvements across knowledge, reasoning and coding" diff --git a/codex-rs/docs/codex_mcp_interface.md b/codex-rs/docs/codex_mcp_interface.md index edd693d5e..8847b6b4e 100644 --- a/codex-rs/docs/codex_mcp_interface.md +++ b/codex-rs/docs/codex_mcp_interface.md @@ -100,6 +100,7 @@ Each response yields: - `defaultReasoningEffort` – suggested effort for the UI - `supportsPersonality` – whether the model supports personality-specific instructions - `isDefault` – whether the model is recommended for most users + - `upgrade` – optional recommended upgrade model id - `nextCursor` – pass into the next request to continue paging (optional) ## Collaboration modes (experimental)