Files
AskaEth 7eb5e984c2 refactor: 认证系统重构 + DevTools CLI 重写 + 文档全面更新
- auth: Login 简化为管理员始终通过 .env 验证,GetProfile 修正 admin DB 查询
- devtools: .sh/.bat 同步重写为完整 CLI (start/stop/status/logs/build/db:*)
- docs: 新增 devtools.md,重写 Deploy.md (三种方式+Windows说明),更新 README/gateway-api
- voice-service: DashScope 实时流式 STT 支持
- gateway: Phase 6 多模型配置 + 多端客户端管理 + WebSocket 增强

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 14:55:47 +08:00

111 lines
2.5 KiB
Go

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
}