mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
feat: route Codex Chat providers through Stream Check
Codex Chat providers (apiFormat=openai_chat, e.g. DeepSeek, MiniMax, Kimi) were incorrectly probed via /v1/responses by Stream Check, which the upstream rejects. Detect chat routing via codex_provider_uses_chat_completions and issue the probe against /chat/completions with a Chat-shaped body. Also align URL fallback order with the production CodexAdapter::build_url: origin-only base URLs (https://api.deepseek.com) must hit /v1/<endpoint> first; bare /<endpoint> only as a fallback. The previous order made any non-404 error on the bare path (401/400/405) flag the provider as down even though /v1/<endpoint> would have succeeded. - Lift origin-only detection into proxy::providers::is_origin_only_url so both build_url and Stream Check share a single source of truth. - Collapse resolve_codex_stream_urls and resolve_codex_chat_stream_urls into a generic resolve_codex_endpoint_urls(base_url, is_full_url, endpoint), which also gives the Responses path a symmetric "full endpoint without is_full_url flag" fallback for free. - Restrict reasoning_effort propagation in the Chat branch to OpenAI o-series models, mirroring transform_codex_chat's runtime check.
This commit is contained in:
@@ -166,6 +166,16 @@ fn is_chat_completions_url(value: &str) -> bool {
|
||||
.ends_with("/chat/completions")
|
||||
}
|
||||
|
||||
/// `scheme://host` 之后没有路径段的纯 origin 形式。`build_url` 在这种情况下
|
||||
/// 会自动补 `/v1`;Stream Check 等同步生产路径的代码也需要同一判定。
|
||||
pub fn is_origin_only_url(value: &str) -> bool {
|
||||
let trimmed = value.trim_end_matches('/');
|
||||
match trimmed.split_once("://") {
|
||||
Some((_scheme, rest)) => !rest.contains('/'),
|
||||
None => !trimmed.contains('/'),
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_codex_wire_api_from_toml(config_text: &str) -> Option<String> {
|
||||
let doc = config_text.parse::<TomlValue>().ok()?;
|
||||
|
||||
@@ -342,12 +352,7 @@ impl ProviderAdapter for CodexAdapter {
|
||||
|
||||
// 检查 base_url 是否已经包含 /v1
|
||||
let already_has_v1 = base_trimmed.ends_with("/v1");
|
||||
|
||||
// 检查是否是纯 origin(没有路径部分)
|
||||
let origin_only = match base_trimmed.split_once("://") {
|
||||
Some((_scheme, rest)) => !rest.contains('/'),
|
||||
None => !base_trimmed.contains('/'),
|
||||
};
|
||||
let origin_only = is_origin_only_url(base_trimmed);
|
||||
|
||||
let mut url = if already_has_v1 {
|
||||
// 已经有 /v1,直接拼接
|
||||
|
||||
Reference in New Issue
Block a user