mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-02 02:05:57 +08:00
feat(codex): route native ChatGPT sessions through proxy takeover
Allow the built-in Codex official provider to participate in takeover mode while preserving Codex's native OAuth or API-key credentials instead of persisting them into provider records. Project official routing into a dedicated TOML provider, normalize inline tables, clean stale managed placeholders, and fail closed when the live configuration cannot be transformed safely. Validate forwarded authorization, make official 401/403 responses non-retryable, avoid circuit-breaker pollution, and share the first-party ChatGPT endpoint across the Codex and Claude adapters.
This commit is contained in:
@@ -206,6 +206,14 @@ pub fn should_convert_codex_responses_to_anthropic(provider: &Provider, endpoint
|
||||
) && codex_provider_uses_anthropic(provider)
|
||||
}
|
||||
|
||||
/// The single built-in official Codex provider. Unlike managed Codex OAuth
|
||||
/// providers used by Claude, this route receives authentication from the
|
||||
/// calling Codex client (`requires_openai_auth = true`).
|
||||
pub fn is_codex_official_provider(provider: &Provider) -> bool {
|
||||
provider.id == crate::database::CODEX_OFFICIAL_PROVIDER_ID
|
||||
&& provider.category.as_deref() == Some("official")
|
||||
}
|
||||
|
||||
/// Resolve the model-catalog tool profile for a Codex provider using the SAME
|
||||
/// Anthropic detection as the proxy router ([`codex_provider_uses_anthropic`]), so the
|
||||
/// generated catalog never disagrees with the routed transform. A provider whose
|
||||
@@ -217,6 +225,9 @@ pub fn resolve_codex_catalog_tool_profile(
|
||||
provider: &Provider,
|
||||
) -> crate::codex_config::CodexCatalogToolProfile {
|
||||
use crate::codex_config::CodexCatalogToolProfile;
|
||||
if is_codex_official_provider(provider) {
|
||||
return CodexCatalogToolProfile::NativeResponses;
|
||||
}
|
||||
if codex_provider_uses_anthropic(provider) {
|
||||
return CodexCatalogToolProfile::Anthropic;
|
||||
}
|
||||
@@ -634,6 +645,10 @@ impl ProviderAdapter for CodexAdapter {
|
||||
}
|
||||
|
||||
fn extract_base_url(&self, provider: &Provider) -> Result<String, ProxyError> {
|
||||
if is_codex_official_provider(provider) {
|
||||
return Ok(super::CHATGPT_CODEX_BASE_URL.to_string());
|
||||
}
|
||||
|
||||
// 1. 尝试直接获取 base_url 字段
|
||||
if let Some(url) = provider
|
||||
.settings_config
|
||||
@@ -781,6 +796,30 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn official_provider_uses_fixed_chatgpt_backend_without_stored_key() {
|
||||
let mut provider = create_provider(json!({ "auth": {}, "config": "" }));
|
||||
provider.id = "codex-official".to_string();
|
||||
provider.category = Some("official".to_string());
|
||||
let adapter = CodexAdapter::new();
|
||||
|
||||
assert!(is_codex_official_provider(&provider));
|
||||
assert_eq!(
|
||||
adapter
|
||||
.extract_base_url(&provider)
|
||||
.expect("official base url"),
|
||||
"https://chatgpt.com/backend-api/codex"
|
||||
);
|
||||
assert!(adapter.extract_auth(&provider).is_none());
|
||||
assert_eq!(
|
||||
adapter.build_url(
|
||||
"https://chatgpt.com/backend-api/codex",
|
||||
"/responses/compact"
|
||||
),
|
||||
"https://chatgpt.com/backend-api/codex/responses/compact"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_cache_routing_auto_enables_known_upstreams_only() {
|
||||
let kimi = create_provider(json!({
|
||||
|
||||
Reference in New Issue
Block a user