Compare commits

...
4 Commits
Author SHA1 Message Date
zyycnandCodex ea684dceeb chore: bump version to 3.0.10
Co-authored-by: Codex <noreply@openai.com>
2026-07-26 06:17:28 +08:00
zyycnandCodex dfd496b41a fix(ui): restore standard Codex API key setup
Remove command-backed provider auth from the generated configuration and use auth.json again.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 06:17:21 +08:00
zyycnandCodex 6125b10276 chore: bump version to 3.0.9
Co-authored-by: Codex <noreply@openai.com>
2026-07-26 06:14:26 +08:00
zyycnandCodex 071271f003 fix(models): restore OpenAI-compatible discovery
Keep Codex model metadata while preserving the standard list response consumed by provider managers.

Co-authored-by: Codex <noreply@openai.com>
2026-07-26 06:14:19 +08:00
4 changed files with 42 additions and 18 deletions
@@ -39,7 +39,15 @@ pub(crate) async fn models(State(state): State<ApiState>, headers: HeaderMap) ->
.enumerate()
.map(|(index, profile)| codex_model_json(profile, index))
.collect::<Vec<_>>();
return (StatusCode::OK, Json(json!({ "models": models }))).into_response();
return (
StatusCode::OK,
Json(json!({
"object": "list",
"data": data,
"models": models,
})),
)
.into_response();
}
(
@@ -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())
@@ -35,23 +35,13 @@ const configPath = computed(() =>
? '%userprofile%\\.codex\\config.toml'
: '~/.codex/config.toml',
)
const tokenPath = computed(() =>
activePlatform.value === 'windows'
? '%userprofile%\\.codex\\codex-proxy.token'
: '~/.codex/codex-proxy.token',
const authPath = computed(() =>
activePlatform.value === 'windows' ? '%userprofile%\\.codex\\auth.json' : '~/.codex/auth.json',
)
const codexAuthJson = computed(() => JSON.stringify({ OPENAI_API_KEY: keyValue.value }, null, 2))
const defaultModel = computed(() =>
props.apiKey?.providerKind?.trim().toLowerCase() === 'xai' ? 'grok-4.5' : 'gpt-5.5',
)
const providerAuthToml = computed(() =>
activePlatform.value === 'windows'
? `[model_providers.OpenAI.auth]
command = "powershell.exe"
args = ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", "Get-Content -Raw (Join-Path (Join-Path $env:USERPROFILE '.codex') 'codex-proxy.token')"]`
: `[model_providers.OpenAI.auth]
command = "sh"
args = ["-c", 'cat "$HOME/.codex/codex-proxy.token"']`,
)
const codexConfigToml = computed(
() => `model_provider = "OpenAI"
@@ -67,8 +57,7 @@ windows_wsl_setup_acknowledged = true
name = "OpenAI"
base_url = "${props.apiBaseUrl}"
wire_api = "responses"
${providerAuthToml.value}
requires_openai_auth = true
[features]
goals = true`,
@@ -76,7 +65,7 @@ goals = true`,
const visibleFiles = computed(() => [
{ path: configPath.value, content: codexConfigToml.value },
{ path: tokenPath.value, content: keyValue.value },
{ path: authPath.value, content: codexAuthJson.value },
])
</script>
+1 -1
View File
@@ -1 +1 @@
version: "3.0.8"
version: "3.0.10"