mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-10-26 01:34:51 +08:00
fix(models): support Zhipu OpenAI Responses model lists (#7330)
Zhipu's Responses endpoint (open.bigmodel.cn/api/v1) serves its model list in the Codex remote catalog shape (models[].slug) instead of the OpenAI-compatible data[].id shape, so the Codex form's model fetch came back empty. The parser now falls back to models[].slug when data is absent.
This commit is contained in:
3 files changed
+36
-11
No files matched your search
@@ -1478,7 +1478,8 @@ pub fn run() {
|
||||
commands::delete_profile,
|
||||
commands::clear_current_profile,
|
||||
commands::apply_profile,
|
||||
// model list fetch (OpenAI-compatible /v1/models)
|
||||
// Fetch OpenAI-compatible and Anthropic model lists. Response data structure:
|
||||
// data[].id, data[]?.owned_by. Special: supports Zhipu OpenAI Responses models[].slug.
|
||||
commands::fetch_models_for_config,
|
||||
commands::get_opencode_models,
|
||||
// ours: endpoint speed test + custom endpoint management
|
||||
|
||||
@@ -18,10 +18,14 @@ pub struct FetchedModel {
|
||||
pub owned_by: Option<String>,
|
||||
}
|
||||
|
||||
/// OpenAI 兼容的 /v1/models 响应格式
|
||||
/// 模型列表响应的兼容格式。
|
||||
///
|
||||
/// OpenAI 兼容接口和 Anthropic 接口使用 `data` 字段,智谱 OpenAI Responses
|
||||
/// 接口使用 `models` 字段,此结构同时兼容这两种格式。
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ModelsResponse {
|
||||
data: Option<Vec<ModelEntry>>,
|
||||
models: Option<Vec<ZhipuModelEntry>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -30,6 +34,11 @@ struct ModelEntry {
|
||||
owned_by: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ZhipuModelEntry {
|
||||
slug: String,
|
||||
}
|
||||
|
||||
const FETCH_TIMEOUT_SECS: u64 = 15;
|
||||
const MAX_REQUEST_HEADERS: usize = 64;
|
||||
const MAX_HEADER_NAME_BYTES: usize = 256;
|
||||
@@ -98,15 +107,23 @@ pub async fn fetch_models(
|
||||
.await
|
||||
.map_err(|e| format!("Failed to parse response: {e}"))?;
|
||||
|
||||
let mut models: Vec<FetchedModel> = resp
|
||||
.data
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|m| FetchedModel {
|
||||
id: m.id,
|
||||
owned_by: m.owned_by,
|
||||
})
|
||||
.collect();
|
||||
let mut models: Vec<FetchedModel> = if let Some(data) = resp.data {
|
||||
data.into_iter()
|
||||
.map(|m| FetchedModel {
|
||||
id: m.id,
|
||||
owned_by: m.owned_by,
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
resp.models
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|m| FetchedModel {
|
||||
id: m.slug,
|
||||
owned_by: None,
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
models.sort_by(|a, b| a.id.cmp(&b.id));
|
||||
return Ok(models);
|
||||
|
||||
@@ -17,6 +17,13 @@ export interface ModelFetchOptions {
|
||||
*
|
||||
* 使用 OpenAI 兼容的 GET /v1/models 端点。优先用 `modelsUrl` 精确覆写;
|
||||
* 否则后端会对 baseURL 生成候选列表并按序尝试(含"剥离 /anthropic 等兼容子路径"兜底)。
|
||||
*
|
||||
* 该接口可以获取数据格式为
|
||||
* OpenAI Chat Completion {"data": [{"id": "xxx","owned_by": "xxx"}]} 文档:https://developers.openai.com/api/reference/resources/models/methods/list
|
||||
* 和
|
||||
* Anthropic兼容 {"data":[{"id":"xxx"}]} 文档:https://platform.claude.com/docs/en/api/models/list
|
||||
* 这两种端点的模型列表
|
||||
* 特别支持智谱 OpenAI Responses {"models":[{"slug":"xxx"}]} 端点:https://open.bigmodel.cn/api/v1/models
|
||||
*/
|
||||
export async function fetchModelsForConfig(
|
||||
baseUrl: string,
|
||||
|
||||
Reference in new issue
Block a user