feat(codex): expose official routing and restore the built-in provider

Let users switch between the built-in OpenAI provider and third-party Codex providers directly from the provider panel while takeover mode remains active.

Centralize the frontend capability predicate so only the fixed codex-official seed receives native-login routing support, and keep copied UUID-based official entries clearly marked as unsupported.

Add an idempotent backend command that recreates the deleted official seed, wire it into the add-provider flow, refresh localized guidance, and add mutation and provider-action regression coverage.
This commit is contained in:
Jason
2026-07-12 17:52:12 +08:00
parent f2c6d48e19
commit f15184edb0
15 changed files with 228 additions and 21 deletions
+8
View File
@@ -231,6 +231,14 @@ pub fn ensure_claude_desktop_official_provider(state: State<'_, AppState>) -> Re
.map_err(|e| e.to_string())
}
#[tauri::command]
pub fn ensure_codex_official_provider(state: State<'_, AppState>) -> Result<bool, String> {
state
.db
.ensure_official_seed_by_id(crate::database::CODEX_OFFICIAL_PROVIDER_ID, AppType::Codex)
.map_err(|e| e.to_string())
}
fn claude_provider_models_are_claude_safe(provider: &Provider) -> bool {
let Some(env) = provider
.settings_config
+22 -1
View File
@@ -710,7 +710,9 @@ impl Database {
#[cfg(test)]
mod ensure_official_seed_tests {
use crate::app_config::AppType;
use crate::database::{Database, CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID};
use crate::database::{
Database, CLAUDE_DESKTOP_OFFICIAL_PROVIDER_ID, CODEX_OFFICIAL_PROVIDER_ID,
};
#[test]
fn ensure_inserts_when_missing() {
@@ -769,6 +771,25 @@ mod ensure_official_seed_tests {
);
}
#[test]
fn ensure_recreates_codex_official_seed_after_deletion() {
let db = Database::memory().expect("memory db");
db.init_default_official_providers().expect("seed");
db.delete_provider(AppType::Codex.as_str(), CODEX_OFFICIAL_PROVIDER_ID)
.expect("delete Codex official");
let inserted = db
.ensure_official_seed_by_id(CODEX_OFFICIAL_PROVIDER_ID, AppType::Codex)
.expect("ensure Codex official");
assert!(inserted);
let provider = db
.get_provider_by_id(CODEX_OFFICIAL_PROVIDER_ID, AppType::Codex.as_str())
.expect("query")
.expect("Codex official restored");
assert_eq!(provider.category.as_deref(), Some("official"));
assert_eq!(provider.settings_config["auth"], serde_json::json!({}));
}
#[test]
fn ensure_rejects_unknown_seed() {
let db = Database::memory().expect("memory db");
+1
View File
@@ -1199,6 +1199,7 @@ pub fn run() {
commands::get_claude_desktop_default_routes,
commands::import_claude_desktop_providers_from_claude,
commands::ensure_claude_desktop_official_provider,
commands::ensure_codex_official_provider,
commands::get_claude_config_status,
commands::get_config_status,
commands::get_claude_code_config_path,