Use openai compatible as vendor

This commit is contained in:
Xin Wang
2026-02-12 18:44:55 +08:00
parent 260ff621bf
commit ff3a03b1ad
23 changed files with 822 additions and 905 deletions

View File

@@ -5,32 +5,37 @@ import { Button, Input, Badge, Drawer, Dialog } from '../components/UI';
import { ASRModel, Assistant, KnowledgeBase, LLMModel, TabValue, Tool, Voice } from '../types';
import { createAssistant, deleteAssistant, fetchASRModels, fetchAssistants, fetchKnowledgeBases, fetchLLMModels, fetchTools, fetchVoices, updateAssistant as updateAssistantApi } from '../services/backendApi';
const isSiliconflowVendor = (vendor?: string) => {
const isOpenAICompatibleVendor = (vendor?: string) => {
const normalized = String(vendor || '').trim().toLowerCase();
return normalized === 'siliconflow' || normalized === '硅基流动';
return (
normalized === 'siliconflow' ||
normalized === '硅基流动' ||
normalized === 'openai compatible' ||
normalized === 'openai-compatible'
);
};
const SILICONFLOW_DEFAULT_MODEL = 'FunAudioLLM/CosyVoice2-0.5B';
const OPENAI_COMPATIBLE_DEFAULT_MODEL = 'FunAudioLLM/CosyVoice2-0.5B';
const buildSiliconflowVoiceKey = (voiceId: string, model?: string) => {
const buildOpenAICompatibleVoiceKey = (voiceId: string, model?: string) => {
const id = String(voiceId || '').trim();
if (!id) return '';
if (id.includes(':')) return id;
return `${model || SILICONFLOW_DEFAULT_MODEL}:${id}`;
return `${model || OPENAI_COMPATIBLE_DEFAULT_MODEL}:${id}`;
};
const resolveRuntimeTtsVoice = (selectedVoiceId: string, voice: Voice) => {
const explicitKey = String(voice.voiceKey || '').trim();
if (!isSiliconflowVendor(voice.vendor)) {
if (!isOpenAICompatibleVendor(voice.vendor)) {
return explicitKey || selectedVoiceId;
}
if (voice.isSystem) {
const canonical = buildSiliconflowVoiceKey(selectedVoiceId, voice.model);
const canonical = buildOpenAICompatibleVoiceKey(selectedVoiceId, voice.model);
if (!explicitKey) return canonical;
const explicitSuffix = explicitKey.includes(':') ? explicitKey.split(':').pop() : explicitKey;
if (explicitSuffix && explicitSuffix !== selectedVoiceId) return canonical;
}
return explicitKey || buildSiliconflowVoiceKey(selectedVoiceId, voice.model);
return explicitKey || buildOpenAICompatibleVoiceKey(selectedVoiceId, voice.model);
};
const renderToolIcon = (icon: string) => {
@@ -1830,11 +1835,11 @@ export const DebugDrawer: React.FC<{
if (assistant.asrModelId) {
const asr = asrModels.find((item) => item.id === assistant.asrModelId);
if (asr) {
const asrProvider = isSiliconflowVendor(asr.vendor) ? 'siliconflow' : 'buffered';
const asrProvider = isOpenAICompatibleVendor(asr.vendor) ? 'openai_compatible' : 'buffered';
services.asr = {
provider: asrProvider,
model: asr.modelName || asr.name,
apiKey: asrProvider === 'siliconflow' ? asr.apiKey : null,
apiKey: asrProvider === 'openai_compatible' ? asr.apiKey : null,
};
} else {
warnings.push(`ASR model not found in loaded list: ${assistant.asrModelId}`);
@@ -1844,12 +1849,12 @@ export const DebugDrawer: React.FC<{
if (assistant.voice) {
const voice = voices.find((item) => item.id === assistant.voice);
if (voice) {
const ttsProvider = isSiliconflowVendor(voice.vendor) ? 'siliconflow' : 'edge';
const ttsProvider = isOpenAICompatibleVendor(voice.vendor) ? 'openai_compatible' : 'edge';
services.tts = {
enabled: ttsEnabled,
provider: ttsProvider,
model: voice.model,
apiKey: ttsProvider === 'siliconflow' ? voice.apiKey : null,
apiKey: ttsProvider === 'openai_compatible' ? voice.apiKey : null,
voice: resolveRuntimeTtsVoice(assistant.voice, voice),
speed: assistant.speed || voice.speed || 1.0,
};