Resolve app-server model payload merge drift

This commit is contained in:
Ahmed Ibrahim
2026-02-26 18:56:02 -08:00
parent 3b0251757a
commit c5fa78fa81
9 changed files with 113 additions and 3 deletions

View File

@@ -10281,6 +10281,16 @@
"string",
"null"
]
},
"upgradeInfo": {
"anyOf": [
{
"$ref": "#/definitions/v2/ModelUpgradeInfo"
},
{
"type": "null"
}
]
}
},
"required": [
@@ -10398,6 +10408,35 @@
"title": "ModelReroutedNotification",
"type": "object"
},
"ModelUpgradeInfo": {
"properties": {
"migrationMarkdown": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"modelLink": {
"type": [
"string",
"null"
]
},
"upgradeCopy": {
"type": [
"string",
"null"
]
}
},
"required": [
"model"
],
"type": "object"
},
"NetworkAccess": {
"enum": [
"restricted",

View File

@@ -78,6 +78,16 @@
"string",
"null"
]
},
"upgradeInfo": {
"anyOf": [
{
"$ref": "#/definitions/ModelUpgradeInfo"
},
{
"type": "null"
}
]
}
},
"required": [
@@ -107,6 +117,35 @@
],
"type": "object"
},
"ModelUpgradeInfo": {
"properties": {
"migrationMarkdown": {
"type": [
"string",
"null"
]
},
"model": {
"type": "string"
},
"modelLink": {
"type": [
"string",
"null"
]
},
"upgradeCopy": {
"type": [
"string",
"null"
]
}
},
"required": [
"model"
],
"type": "object"
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [

View File

@@ -4,6 +4,7 @@
import type { InputModality } from "../InputModality";
import type { ReasoningEffort } from "../ReasoningEffort";
import type { ModelAvailabilityNux } from "./ModelAvailabilityNux";
import type { ModelUpgradeInfo } from "./ModelUpgradeInfo";
import type { ReasoningEffortOption } from "./ReasoningEffortOption";
export type Model = { id: string, model: string, upgrade: string | null, availabilityNux: ModelAvailabilityNux | null, displayName: string, description: string, hidden: boolean, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, inputModalities: Array<InputModality>, supportsPersonality: boolean, isDefault: boolean, };
export type Model = { id: string, model: string, upgrade: string | null, upgradeInfo: ModelUpgradeInfo | null, availabilityNux: ModelAvailabilityNux | null, displayName: string, description: string, hidden: boolean, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, inputModalities: Array<InputModality>, supportsPersonality: boolean, isDefault: boolean, };

View File

@@ -0,0 +1,5 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ModelUpgradeInfo = { model: string, upgradeCopy: string | null, modelLink: string | null, migrationMarkdown: string | null, };

View File

@@ -112,6 +112,7 @@ export type { ModelListParams } from "./ModelListParams";
export type { ModelListResponse } from "./ModelListResponse";
export type { ModelRerouteReason } from "./ModelRerouteReason";
export type { ModelReroutedNotification } from "./ModelReroutedNotification";
export type { ModelUpgradeInfo } from "./ModelUpgradeInfo";
export type { NetworkAccess } from "./NetworkAccess";
export type { NetworkApprovalContext } from "./NetworkApprovalContext";
export type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";

View File

@@ -1414,6 +1414,7 @@ pub struct Model {
pub id: String,
pub model: String,
pub upgrade: Option<String>,
pub upgrade_info: Option<ModelUpgradeInfo>,
pub availability_nux: Option<ModelAvailabilityNux>,
pub display_name: String,
pub description: String,
@@ -1428,6 +1429,16 @@ pub struct Model {
pub is_default: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ModelUpgradeInfo {
pub model: String,
pub upgrade_copy: Option<String>,
pub model_link: Option<String>,
pub migration_markdown: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]

View File

@@ -142,7 +142,7 @@ Example with notification opt-out:
- `thread/realtime/stop` — stop the active realtime session for the thread (experimental); returns `{}`.
- `review/start` — kick off Codexs 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 (set `includeHidden: true` to include entries with `hidden: true`), with reasoning effort options, optional `upgrade` model ids, and optional `availabilityNux` metadata.
- `model/list` — list available models (set `includeHidden: true` to include entries with `hidden: true`), with reasoning effort options, optional legacy `upgrade` model ids, optional `upgradeInfo` metadata (`model`, `upgradeCopy`, `modelLink`, `migrationMarkdown`), and optional `availabilityNux` metadata.
- `experimentalFeature/list` — list feature flags with stage metadata (`beta`, `underDevelopment`, `stable`, etc.), enabled/default-enabled state, and cursor pagination. For non-beta flags, `displayName`/`description`/`announcement` are `null`.
- `collaborationMode/list` — list available collaboration mode presets (experimental, no pagination). This response omits built-in developer instructions; clients should either pass `settings.developer_instructions: null` when setting a mode to use Codex's built-in instructions, or provide their own instructions explicitly.
- `skills/list` — list skills for one or more `cwd` values (optional `forceReload`).

View File

@@ -1,6 +1,7 @@
use std::sync::Arc;
use codex_app_server_protocol::Model;
use codex_app_server_protocol::ModelUpgradeInfo;
use codex_app_server_protocol::ReasoningEffortOption;
use codex_core::ThreadManager;
use codex_core::models_manager::manager::RefreshStrategy;
@@ -24,7 +25,13 @@ 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),
upgrade: preset.upgrade.as_ref().map(|upgrade| upgrade.id.clone()),
upgrade_info: preset.upgrade.as_ref().map(|upgrade| ModelUpgradeInfo {
model: upgrade.id.clone(),
upgrade_copy: upgrade.upgrade_copy.clone(),
model_link: upgrade.model_link.clone(),
migration_markdown: upgrade.migration_markdown.clone(),
}),
availability_nux: preset.availability_nux.map(Into::into),
display_name: preset.display_name.to_string(),
description: preset.description.to_string(),

View File

@@ -9,6 +9,7 @@ use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::Model;
use codex_app_server_protocol::ModelListParams;
use codex_app_server_protocol::ModelListResponse;
use codex_app_server_protocol::ModelUpgradeInfo;
use codex_app_server_protocol::ReasoningEffortOption;
use codex_app_server_protocol::RequestId;
use codex_protocol::openai_models::ModelPreset;
@@ -24,6 +25,12 @@ fn model_from_preset(preset: &ModelPreset) -> Model {
id: preset.id.clone(),
model: preset.model.clone(),
upgrade: preset.upgrade.as_ref().map(|upgrade| upgrade.id.clone()),
upgrade_info: preset.upgrade.as_ref().map(|upgrade| ModelUpgradeInfo {
model: upgrade.id.clone(),
upgrade_copy: upgrade.upgrade_copy.clone(),
model_link: upgrade.model_link.clone(),
migration_markdown: upgrade.migration_markdown.clone(),
}),
availability_nux: preset.availability_nux.clone().map(Into::into),
display_name: preset.display_name.clone(),
description: preset.description.clone(),