Files
llm-intelligence/internal/collectors/provider_mapper.go
2026-05-13 14:42:45 +08:00

116 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// internal/collectors/provider_mapper.go
// ProviderMapper: 将 OpenRouter 模型 ID 映射为标准厂商/模型名称
package collectors
import (
"fmt"
"strings"
)
// ProviderInfo 标准厂商信息
type ProviderInfo struct {
ID string // 标准ID: "openai", "anthropic", "deepseek"...
Name string // 英文名
NameCN string // 中文名
Country string // "US" / "CN" / "EU"
}
// ModelMapping 模型映射结果
type ModelMapping struct {
Provider ProviderInfo
ModelName string // 纯模型名,不含厂商前缀
RawID string // 原始 OpenRouter ID
IsFree bool // 是否免费版(:free 后缀)
}
// providerNameMap 标准厂商名称映射表
// key 为标准ID也兼容 OpenRouter 原始格式作为别名)
var providerNameMap = map[string]ProviderInfo{
"openai": {ID: "openai", Name: "OpenAI", NameCN: "OpenAI", Country: "US"},
"anthropic": {ID: "anthropic", Name: "Anthropic", NameCN: "Anthropic", Country: "US"},
"google": {ID: "google", Name: "Google", NameCN: "谷歌", Country: "US"},
"meta": {ID: "meta", Name: "Meta", NameCN: "Meta", Country: "US"},
"xai": {ID: "xai", Name: "xAI", NameCN: "xAI", Country: "US"},
"x-ai": {ID: "xai", Name: "xAI", NameCN: "xAI", Country: "US"}, // OpenRouter别名
"deepseek": {ID: "deepseek", Name: "DeepSeek", NameCN: "深度求索", Country: "CN"},
"qwen": {ID: "qwen", Name: "Qwen", NameCN: "通义千问", Country: "CN"},
"alibaba": {ID: "alibaba", Name: "Alibaba", NameCN: "阿里巴巴", Country: "CN"},
"moonshot": {ID: "moonshot", Name: "Moonshot AI", NameCN: "月之暗面", Country: "CN"},
"moonshotai": {ID: "moonshot", Name: "Moonshot AI", NameCN: "月之暗面", Country: "CN"}, // OpenRouter别名
"zhipu": {ID: "zhipu", Name: "Zhipu AI", NameCN: "智谱AI", Country: "CN"},
"zhipuai": {ID: "zhipu", Name: "Zhipu AI", NameCN: "智谱AI", Country: "CN"}, // OpenRouter别名
"bytedance": {ID: "bytedance", Name: "ByteDance", NameCN: "字节跳动", Country: "CN"},
"baidu": {ID: "baidu", Name: "Baidu", NameCN: "百度", Country: "CN"},
"tencent": {ID: "tencent", Name: "Tencent", NameCN: "腾讯", Country: "CN"},
"mistral": {ID: "mistral", Name: "Mistral AI", NameCN: "Mistral", Country: "EU"},
"cohere": {ID: "cohere", Name: "Cohere", NameCN: "Cohere", Country: "US"},
"ai21": {ID: "ai21", Name: "AI21 Labs", NameCN: "AI21", Country: "US"},
"perplexity": {ID: "perplexity", Name: "Perplexity", NameCN: "Perplexity", Country: "US"},
"nvidia": {ID: "nvidia", Name: "NVIDIA", NameCN: "英伟达", Country: "US"},
"microsoft": {ID: "microsoft", Name: "Microsoft", NameCN: "微软", Country: "US"},
"openrouter": {ID: "openrouter", Name: "OpenRouter", NameCN: "OpenRouter", Country: "US"},
}
// MapOpenRouterID 将 OpenRouter 模型 ID 映射为标准信息
// OpenRouter ID 格式: "provider/model-name" 或 "provider/model-name:free"
func MapOpenRouterID(rawID string) (ModelMapping, error) {
if rawID == "" {
return ModelMapping{}, fmt.Errorf("empty model ID")
}
// 检测 :free 后缀
isFree := false
modelPart := rawID
if strings.HasSuffix(rawID, ":free") {
isFree = true
modelPart = rawID[:len(rawID)-5]
}
// 分割 provider / model
parts := strings.SplitN(modelPart, "/", 2)
if len(parts) < 2 {
return ModelMapping{}, fmt.Errorf("invalid model ID format: %s", rawID)
}
providerKey := strings.ToLower(parts[0])
modelName := parts[1]
// 查找厂商信息
provider, ok := providerNameMap[providerKey]
if !ok {
// 未识别厂商,返回通用信息
provider = ProviderInfo{
ID: providerKey,
Name: providerKey,
NameCN: providerKey,
Country: "unknown",
}
}
return ModelMapping{
Provider: provider,
ModelName: modelName,
RawID: rawID,
IsFree: isFree,
}, nil
}
// GetAllProviderNames 返回所有已注册的厂商ID列表用于测试覆盖度检查
func GetAllProviderNames() []string {
names := make([]string, 0, len(providerNameMap))
for k := range providerNameMap {
names = append(names, k)
}
return names
}
// RegisterProvider 动态注册新厂商(用于扩展)
func RegisterProvider(key string, info ProviderInfo) {
providerNameMap[strings.ToLower(key)] = info
}
// ProviderCount 返回已注册厂商数量
func ProviderCount() int {
return len(providerNameMap)
}