新增: 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:
@@ -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"));
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user