feat(codex): preserve OAuth login state during third-party provider switching

Codex provider switches now only write config.toml for third-party providers,
injecting the API key as experimental_bearer_token. The user's auth.json
(ChatGPT OAuth tokens) is preserved. Official providers with login material
still write auth.json normally. Backfill restores bearer tokens into stored
provider auth.OPENAI_API_KEY to maintain canonical shape.
This commit is contained in:
Jason
2026-05-25 17:46:23 +08:00
parent 88ba908bc4
commit 95f2dd4126
17 changed files with 1664 additions and 154 deletions
+41
View File
@@ -267,6 +267,47 @@ fn test_parse_and_merge_config_claude() {
assert_eq!(merged.model, Some("claude-sonnet-4.5".to_string()));
}
#[test]
fn test_parse_and_merge_config_codex_uses_bearer_token() {
let config_toml = r#"model_provider = "rightcode"
model = "gpt-5-codex"
[model_providers.rightcode]
base_url = "https://rightcode.example/v1"
wire_api = "responses"
experimental_bearer_token = "sk-rightcode"
"#;
let config_json = serde_json::json!({
"auth": {},
"config": config_toml,
})
.to_string();
let config_b64 = BASE64_STANDARD.encode(config_json.as_bytes());
let request = DeepLinkImportRequest {
version: "v1".to_string(),
resource: "provider".to_string(),
app: Some("codex".to_string()),
name: Some("RightCode".to_string()),
config: Some(config_b64),
config_format: Some("json".to_string()),
..Default::default()
};
let merged = parse_and_merge_config(&request).unwrap();
assert_eq!(merged.api_key, Some("sk-rightcode".to_string()));
assert_eq!(
merged.endpoint,
Some("https://rightcode.example/v1".to_string())
);
assert_eq!(
merged.homepage,
Some("https://rightcode.example".to_string())
);
assert_eq!(merged.model, Some("gpt-5-codex".to_string()));
}
#[test]
fn test_parse_and_merge_config_url_override() {
let config_json = r#"{"env":{"ANTHROPIC_AUTH_TOKEN":"sk-old","ANTHROPIC_BASE_URL":"https://api.anthropic.com/v1"}}"#;