新增: provider 支持(11 厂商预设 + modalities 修正 + defaultModel 更新 + 噪音过滤 + UI 提示)

providerPresets 扩展 6 厂商(Qwen/Kimi/ERNIE/Spark/Doubao/Gemini)+ SenseNova base_url 修正;
modalities 预设表补 SenseNova flash-lite vision;defaultModel 过时更新;sensenova-u1 图像生成
噪音过滤;ProviderPanel defaultModel UI 提示。
This commit is contained in:
lxy
2026-08-02 02:21:33 +08:00
parent b999f79fdf
commit 50c232643d
7 changed files with 196 additions and 12 deletions
+16
View File
@@ -127,6 +127,22 @@
"weight": 65,
"context_window": 128000
},
{
"model_id": "sensenova-6.7-flash-lite",
"enabled": true,
"modalities": ["text", "vision"],
"capabilities": ["tool_use"],
"weight": 85,
"context_window": 262144
},
{
"model_id": "deepseek-v4-flash",
"enabled": true,
"modalities": ["text"],
"capabilities": ["tool_use"],
"weight": 80,
"context_window": 1048576
},
{
"model_id": "embedding-3",
"enabled": true,
+27 -1
View File
@@ -41,7 +41,7 @@ pub fn build_models_url(base_url: &str) -> String {
/// 判断是否为非 chat 模型(应从列表中剔除)。
///
/// 规则(设计 §5.4 + 合理扩展,见 issues):
/// - 图片生成:dall-e / midjourney / stable-diffusion / imagen
/// - 图片生成:dall-e / midjourney / stable-diffusion / imagen / sensenova-u1 / infographic / image-generation
/// - 语音:tts / whisper / audio / speech / voice(语音合成/识别)
/// - 实时:realtime(OpenAI Realtime API 语音对话,非 chat completions)
/// - 转写:transcribe / transcription
@@ -50,6 +50,9 @@ pub fn build_models_url(base_url: &str) -> String {
///
/// embedding 设计 §5.4 注释「保留(知识库需要)」— 此处遵循设计保留 embedding,
/// 不在 `is_non_chat_model` 剔除(知识库 embedding 路由用得着)。
///
/// 注:`sensenova-u1` 用厂商前缀限定而非裸 `u1`,避免误伤未来含 `u1` 词素的 chat 模型
/// (SenseNova U1 系列走 `/v1/images/generations` 端点,非 chat completions)。
pub fn is_non_chat_model(id: &str) -> bool {
let id = id.to_lowercase();
// 图片生成
@@ -57,6 +60,11 @@ pub fn is_non_chat_model(id: &str) -> bool {
|| id.contains("midjourney")
|| id.contains("stable-diffusion")
|| id.contains("imagen")
// SenseNova U1 系列(图像生成,如 sensenova-u1-fast,走 /v1/images/generations 非 chat)
|| id.contains("sensenova-u1")
// 通用图像生成命名(infographic 海报生成 / image-generation 直白命名)
|| id.contains("infographic")
|| id.contains("image-generation")
// 语音(tts 合成 / whisper 识别 / 通用 audio / speech / voice)
|| id.contains("tts")
|| id.contains("whisper")
@@ -226,6 +234,24 @@ mod tests {
assert!(is_non_chat_model("stable-diffusion-xl"));
}
#[test]
fn non_chat_sensenova_u1_image_filtered() {
// SenseNova U1 系列是图像生成模型(走 /v1/images/generations,非 chat completions),
// /v1/models 会返回但不应留为 chat 模型,否则用户选它对话会失败。
assert!(is_non_chat_model("sensenova-u1-fast"));
assert!(is_non_chat_model("SenseNova-U1-Fast")); // 大小写无关
assert!(is_non_chat_model("sensenova-u1-pro"));
// 通用图像生成命名也剔
assert!(is_non_chat_model("infographic-v1"));
assert!(is_non_chat_model("image-generation-latest"));
// 对照组:同厂商的 chat 模型 sensenova-6.7-flash-lite 不应被误剔
// (它是原生多模态 chat,见 model_probe.rs 预设表)
assert!(
!is_non_chat_model("sensenova-6.7-flash-lite"),
"sensenova-6.7-flash-lite 是 chat 模型,不应被当图像生成剔除"
);
}
#[test]
fn non_chat_speech_filtered() {
assert!(is_non_chat_model("tts-1"));
+27
View File
@@ -130,6 +130,33 @@ mod tests {
);
}
// ── 预设表:已知多模态模型(命名无 vision 词素,靠预设显式标 vision) ──
// SenseNova flash-lite 原生多模态(商汤文档:支持图像输入理解),
// 但模型名不含 vision/vl/-v 词素,启发式 has_vision_token 无法识别 →
// 必须靠预设表显式标 vision,否则 modalities 漏 vision 致路由误判。
#[test]
fn probe_preset_sensenova_flash_lite_has_vision() {
let m = probe("sensenova-6.7-flash-lite");
assert_eq!(m.probe_source, Some(ProbeSource::PresetTable));
assert!(
m.modalities.contains(&Modality::Vision),
"sensenova-6.7-flash-lite 应有 Vision(原生多模态): {:?}",
m.modalities
);
assert!(m.modalities.contains(&Modality::Text));
// context_window 应为预设的 256K
assert_eq!(m.context_window, 262144);
}
#[test]
fn probe_preset_deepseek_v4_flash_text_only() {
// SenseNova 上的 deepseek-v4-flash:纯文本对话 + 1M 上下文,无 vision
let m = probe("deepseek-v4-flash");
assert_eq!(m.probe_source, Some(ProbeSource::PresetTable));
assert_eq!(m.modalities, vec![Modality::Text]);
assert_eq!(m.context_window, 1_048_576);
}
// ── 预设模糊匹配 ──
#[test]