package config import ( "encoding/json" "os" "path/filepath" ) // ModelsJSON 映射 models.json 文件结构(仅提取语音相关字段)。 type ModelsJSON struct { Providers map[string]ModelsProvider `json:"providers"` Models map[string]ModelsModel `json:"models"` Routing map[string]ModelsRouting `json:"routing"` } type ModelsProvider struct { Name string `json:"name"` BaseURL string `json:"base_url"` APIKey string `json:"api_key"` } type ModelsModel struct { ID string `json:"id"` Name string `json:"name"` Provider string `json:"provider"` } type ModelsRouting struct { Purpose string `json:"purpose"` FallbackChain []string `json:"fallback_chain"` } // LoadModelsConfig 从 backend/models.json 加载模型配置。 // 返回 provider API key 和 ASR 模型名称。如果文件不存在则返回零值。 func LoadModelsConfig() (apiKey string, offlineModel string, realtimeModel string) { // 尝试多个可能的路径 candidates := []string{ "models.json", "../models.json", "../../models.json", filepath.Join("..", "models.json"), } var data []byte var err error for _, p := range candidates { data, err = os.ReadFile(p) if err == nil { break } } if data == nil { return } var cfg ModelsJSON if err := json.Unmarshal(data, &cfg); err != nil { return } // 从 speech_recognition_offline 路由取离线模型 if r, ok := cfg.Routing["speech_recognition_offline"]; ok && len(r.FallbackChain) > 0 { modelID := r.FallbackChain[0] if m, ok := cfg.Models[modelID]; ok { offlineModel = m.Name if m.Name == "" { offlineModel = m.ID } // 从 provider 取 API key if p, ok := cfg.Providers[m.Provider]; ok && apiKey == "" { apiKey = p.APIKey } } } // 从 speech_recognition 路由取实时模型 if r, ok := cfg.Routing["speech_recognition"]; ok && len(r.FallbackChain) > 0 { modelID := r.FallbackChain[0] if m, ok := cfg.Models[modelID]; ok { realtimeModel = m.Name if realtimeModel == "" { realtimeModel = m.ID } // 从 provider 取 API key if p, ok := cfg.Providers[m.Provider]; ok && apiKey == "" { apiKey = p.APIKey } } } // 如果 routing 里没有,尝试从所有 models 中找带有 ASR tag 的模型 if offlineModel == "" { for _, m := range cfg.Models { if m.Provider == "dashscope" && m.Name != "" { if offlineModel == "" { offlineModel = m.Name } } } } // 从 provider 取 API key (兜底) if apiKey == "" { if p, ok := cfg.Providers["dashscope"]; ok { apiKey = p.APIKey } } return }