feat(catalog): 统一模型调用身份并梳理生命周期
新增官方调用名、供应商真实名、显示名和兼容别名的独立契约,调整路由、目录聚合、管理端与 OpenAPI。 增加 Gemini、Qwen、DeepSeek、Claude 和 MiniMax 生命周期迁移、别名观测及引用保护,并补充数据库与聚合测试。
This commit is contained in:
@@ -62,17 +62,19 @@ type ModelCatalogProviderSummary struct {
|
||||
}
|
||||
|
||||
type ModelCatalogSource struct {
|
||||
ID string `json:"id"`
|
||||
PlatformID string `json:"platformId,omitempty"`
|
||||
PlatformName string `json:"platformName,omitempty"`
|
||||
ProviderKey string `json:"providerKey"`
|
||||
ProviderName string `json:"providerName"`
|
||||
ModelName string `json:"modelName"`
|
||||
ModelAlias string `json:"modelAlias,omitempty"`
|
||||
DisplayName string `json:"displayName"`
|
||||
ModelType []string `json:"modelType"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RateLimits ModelCatalogRateLimits `json:"rateLimits"`
|
||||
ID string `json:"id"`
|
||||
PlatformID string `json:"platformId,omitempty"`
|
||||
PlatformName string `json:"platformName,omitempty"`
|
||||
ProviderKey string `json:"providerKey"`
|
||||
ProviderName string `json:"providerName"`
|
||||
ModelName string `json:"modelName"`
|
||||
ProviderModelName string `json:"providerModelName,omitempty"`
|
||||
ModelAlias string `json:"modelAlias,omitempty"`
|
||||
LegacyAliases []string `json:"legacyAliases,omitempty"`
|
||||
DisplayName string `json:"displayName"`
|
||||
ModelType []string `json:"modelType"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RateLimits ModelCatalogRateLimits `json:"rateLimits"`
|
||||
}
|
||||
|
||||
type ModelCatalogText struct {
|
||||
@@ -202,10 +204,10 @@ func buildModelCatalog(
|
||||
sourceCount := 0
|
||||
for _, model := range models {
|
||||
platform := platformMap[model.PlatformID]
|
||||
if !catalogSourceEnabled(model, platform) {
|
||||
baseModel := baseModelMap[model.BaseModelID]
|
||||
if !catalogSourceEnabled(model, platform, baseModel) {
|
||||
continue
|
||||
}
|
||||
baseModel := baseModelMap[model.BaseModelID]
|
||||
providerKey := modelProviderKey(model, baseModel, platform)
|
||||
provider := providerMap[providerKey]
|
||||
providerName := firstNonEmpty(
|
||||
@@ -232,14 +234,14 @@ func buildModelCatalog(
|
||||
rateLimits: effectiveModelRateLimits(model, platform, runtimePolicyMap),
|
||||
}
|
||||
|
||||
key := catalogAliasKey(model)
|
||||
key := catalogIdentityKey(model, baseModel)
|
||||
current := groups[key]
|
||||
if current == nil {
|
||||
current = &catalogGroup{
|
||||
key: key,
|
||||
alias: firstNonEmpty(model.ModelAlias, model.DisplayName, model.ModelName),
|
||||
displayName: firstNonEmpty(model.DisplayName, model.ModelAlias, model.ModelName),
|
||||
modelName: model.ModelName,
|
||||
alias: firstNonEmpty(baseModel.InvocationName, model.ModelName),
|
||||
displayName: firstNonEmpty(baseModel.DisplayName, model.DisplayName, baseModel.InvocationName, model.ModelName),
|
||||
modelName: firstNonEmpty(baseModel.InvocationName, model.ModelName),
|
||||
modelType: cloneStringSlice(model.ModelType),
|
||||
capabilities: cloneObject(model.Capabilities),
|
||||
}
|
||||
@@ -274,8 +276,8 @@ func buildModelCatalog(
|
||||
}
|
||||
}
|
||||
|
||||
func catalogSourceEnabled(model store.PlatformModel, platform store.Platform) bool {
|
||||
return model.Enabled && platform.ID != "" && platform.Status == "enabled"
|
||||
func catalogSourceEnabled(model store.PlatformModel, platform store.Platform, baseModel store.BaseModel) bool {
|
||||
return model.Enabled && platform.ID != "" && platform.Status == "enabled" && (baseModel.ID == "" || baseModel.Status == "" || baseModel.Status == "active")
|
||||
}
|
||||
|
||||
func modelCatalogItem(group *catalogGroup, accessRuleGroups map[string]accessRuleGroup) ModelCatalogItem {
|
||||
@@ -304,17 +306,19 @@ func modelCatalogItem(group *catalogGroup, accessRuleGroups map[string]accessRul
|
||||
itemSources := make([]ModelCatalogSource, 0, len(sources))
|
||||
for _, source := range sources {
|
||||
itemSources = append(itemSources, ModelCatalogSource{
|
||||
ID: source.model.ID,
|
||||
PlatformID: source.model.PlatformID,
|
||||
PlatformName: firstNonEmpty(source.platform.Name, source.model.PlatformName),
|
||||
ProviderKey: source.providerKey,
|
||||
ProviderName: source.providerName,
|
||||
ModelName: source.model.ModelName,
|
||||
ModelAlias: source.model.ModelAlias,
|
||||
DisplayName: firstNonEmpty(source.model.DisplayName, source.model.ModelAlias, source.model.ModelName),
|
||||
ModelType: cloneStringSlice(source.model.ModelType),
|
||||
Enabled: source.model.Enabled && source.platform.Status == "enabled",
|
||||
RateLimits: source.rateLimits,
|
||||
ID: source.model.ID,
|
||||
PlatformID: source.model.PlatformID,
|
||||
PlatformName: firstNonEmpty(source.platform.Name, source.model.PlatformName),
|
||||
ProviderKey: source.providerKey,
|
||||
ProviderName: source.providerName,
|
||||
ModelName: firstNonEmpty(source.baseModel.InvocationName, source.model.ModelName),
|
||||
ProviderModelName: source.model.ProviderModelName,
|
||||
ModelAlias: firstNonEmpty(source.baseModel.InvocationName, source.model.ModelName),
|
||||
LegacyAliases: cloneStringSlice(source.baseModel.LegacyAliases),
|
||||
DisplayName: firstNonEmpty(source.baseModel.DisplayName, source.model.DisplayName, source.baseModel.InvocationName, source.model.ModelName),
|
||||
ModelType: cloneStringSlice(source.model.ModelType),
|
||||
Enabled: source.model.Enabled && source.platform.Status == "enabled",
|
||||
RateLimits: source.rateLimits,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1260,8 +1264,8 @@ func modelIconPath(model store.PlatformModel, baseModel store.BaseModel, provide
|
||||
)
|
||||
}
|
||||
|
||||
func catalogAliasKey(model store.PlatformModel) string {
|
||||
key := strings.ToLower(strings.TrimSpace(firstNonEmpty(model.ModelAlias, model.DisplayName, model.ModelName)))
|
||||
func catalogIdentityKey(model store.PlatformModel, baseModel store.BaseModel) string {
|
||||
key := strings.ToLower(strings.TrimSpace(firstNonEmpty(baseModel.InvocationName, baseModel.CanonicalModelKey, model.ModelName)))
|
||||
if key == "" {
|
||||
return model.ID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user