From fd8a0d0115b9bd16038ef2301248e4dea0dbce37 Mon Sep 17 00:00:00 2001 From: zyycn Date: Sun, 26 Jul 2026 06:14:19 +0800 Subject: [PATCH] fix(models): restore OpenAI-compatible discovery Keep Codex model metadata while preserving the standard list response consumed by provider managers. Co-authored-by: Codex --- .../crates/gateway-api/src/openai/models.rs | 10 ++++++- .../crates/gateway-api/tests/openai/models.rs | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/backend/crates/gateway-api/src/openai/models.rs b/backend/crates/gateway-api/src/openai/models.rs index 7d6357526..ed42b0e9b 100644 --- a/backend/crates/gateway-api/src/openai/models.rs +++ b/backend/crates/gateway-api/src/openai/models.rs @@ -39,7 +39,15 @@ pub(crate) async fn models(State(state): State, headers: HeaderMap) -> .enumerate() .map(|(index, profile)| codex_model_json(profile, index)) .collect::>(); - return (StatusCode::OK, Json(json!({ "models": models }))).into_response(); + return ( + StatusCode::OK, + Json(json!({ + "object": "list", + "data": data, + "models": models, + })), + ) + .into_response(); } ( diff --git a/backend/crates/gateway-api/tests/openai/models.rs b/backend/crates/gateway-api/tests/openai/models.rs index 7ddb559c4..aa3ea104e 100644 --- a/backend/crates/gateway-api/tests/openai/models.rs +++ b/backend/crates/gateway-api/tests/openai/models.rs @@ -163,6 +163,33 @@ async fn models_should_encode_provider_profiles_for_current_codex_clients() { ); } +#[tokio::test] +async fn models_with_provider_profiles_should_keep_the_openai_list_contract() { + let response = api_router(ModelsExecution::with_profiles()) + .await + .oneshot(authorized_request("/v1/models")) + .await + .expect("list compatible models response"); + let body = to_bytes(response.into_body(), usize::MAX) + .await + .expect("read compatible models body"); + let value: serde_json::Value = serde_json::from_slice(&body).expect("models JSON"); + + assert_eq!( + serde_json::json!({ + "object": value["object"], + "data": value["data"], + }), + serde_json::json!({ + "object": "list", + "data": [ + {"id":"model-a","object":"model","created":1700000000_i64,"owned_by":"gateway"}, + {"id":"model-b","object":"model","created":1700000000_i64,"owned_by":"gateway"} + ] + }) + ); +} + #[tokio::test] async fn model_detail_should_keep_the_official_path_id_contract() { let response = api_router(ModelsExecution::new())