feat(catalog): 统一模型调用身份并梳理生命周期
新增官方调用名、供应商真实名、显示名和兼容别名的独立契约,调整路由、目录聚合、管理端与 OpenAPI。 增加 Gemini、Qwen、DeepSeek、Claude 和 MiniMax 生命周期迁移、别名观测及引用保护,并补充数据库与聚合测试。
This commit is contained in:
@@ -131,13 +131,24 @@ func TestBuildModelCatalogKeepsDisplayNameSeparateFromCallAlias(t *testing.T) {
|
||||
platforms := []store.Platform{
|
||||
{ID: "platform-volces", Provider: "volces", Name: "火山引擎", Status: "enabled"},
|
||||
}
|
||||
baseModels := []store.BaseModel{
|
||||
{
|
||||
ID: "base-seedream-pro",
|
||||
CanonicalModelKey: "seedream:seedream-5.0-pro",
|
||||
InvocationName: "seedream-5.0-pro",
|
||||
ProviderModelName: "doubao-seedream-5-0-pro-260628",
|
||||
DisplayName: "Seedream 5.0 Pro",
|
||||
Status: "active",
|
||||
},
|
||||
}
|
||||
models[0].BaseModelID = "base-seedream-pro"
|
||||
|
||||
response := buildModelCatalog(models, platforms, nil, nil, nil, nil, nil)
|
||||
response := buildModelCatalog(models, platforms, nil, nil, nil, nil, baseModels)
|
||||
if len(response.Items) != 1 {
|
||||
t.Fatalf("expected one Seedream Pro catalog item, got %+v", response.Items)
|
||||
}
|
||||
item := response.Items[0]
|
||||
if item.Alias != "Seedream-5.0-Pro" || item.DisplayName != "Seedream 5.0 Pro" || item.ModelName != "Seedream-5.0-Pro" {
|
||||
if item.Alias != "seedream-5.0-pro" || item.DisplayName != "Seedream 5.0 Pro" || item.ModelName != "seedream-5.0-pro" {
|
||||
t.Fatalf("catalog should separate the call alias from the display name, got %+v", item)
|
||||
}
|
||||
if strings.Contains(item.Alias, " ") {
|
||||
@@ -145,6 +156,46 @@ func TestBuildModelCatalogKeepsDisplayNameSeparateFromCallAlias(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildModelCatalogAggregatesByInvocationNameNotDisplayName(t *testing.T) {
|
||||
models := []store.PlatformModel{
|
||||
{ID: "official-a", PlatformID: "platform-a", BaseModelID: "base-a", ModelName: "provider/a", ModelType: store.StringList{"text_generate"}, DisplayName: "同名营销标题", Enabled: true},
|
||||
{ID: "official-b", PlatformID: "platform-b", BaseModelID: "base-b", ModelName: "provider/b", ModelType: store.StringList{"text_generate"}, DisplayName: "同名营销标题", Enabled: true},
|
||||
{ID: "official-a-mirror", PlatformID: "platform-b", BaseModelID: "base-a-mirror", ModelName: "mirror/a", ModelType: store.StringList{"text_generate"}, DisplayName: "另一个展示标题", Enabled: true},
|
||||
}
|
||||
platforms := []store.Platform{
|
||||
{ID: "platform-a", Provider: "provider-a", Status: "enabled"},
|
||||
{ID: "platform-b", Provider: "provider-b", Status: "enabled"},
|
||||
}
|
||||
baseModels := []store.BaseModel{
|
||||
{ID: "base-a", CanonicalModelKey: "provider-a:official-a", InvocationName: "official-a", DisplayName: "模型 A", Status: "active"},
|
||||
{ID: "base-a-mirror", CanonicalModelKey: "provider-b:official-a", InvocationName: "official-a", DisplayName: "模型 A 镜像", Status: "active"},
|
||||
{ID: "base-b", CanonicalModelKey: "provider-b:official-b", InvocationName: "official-b", DisplayName: "同名营销标题", Status: "active"},
|
||||
}
|
||||
|
||||
response := buildModelCatalog(models, platforms, nil, nil, nil, nil, baseModels)
|
||||
if response.Summary.ModelCount != 2 || response.Summary.SourceCount != 3 {
|
||||
t.Fatalf("expected two official identities and three sources, got %+v", response.Summary)
|
||||
}
|
||||
for _, item := range response.Items {
|
||||
if item.ModelName == "official-a" && item.SourceCount != 2 {
|
||||
t.Fatalf("official-a mirrors should aggregate into one card: %+v", item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildModelCatalogExcludesDeprecatedBaseModels(t *testing.T) {
|
||||
models := []store.PlatformModel{
|
||||
{ID: "preview", PlatformID: "platform", BaseModelID: "base-preview", ModelName: "gemini-preview", ModelType: store.StringList{"text_generate"}, Enabled: true},
|
||||
}
|
||||
platforms := []store.Platform{{ID: "platform", Provider: "gemini", Status: "enabled"}}
|
||||
baseModels := []store.BaseModel{{ID: "base-preview", InvocationName: "gemini-preview", Status: "deprecated"}}
|
||||
|
||||
response := buildModelCatalog(models, platforms, nil, nil, nil, nil, baseModels)
|
||||
if response.Summary.ModelCount != 0 || response.Summary.SourceCount != 0 {
|
||||
t.Fatalf("deprecated base models must not create new catalog cards: %+v", response.Summary)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildModelCatalogUsesBaseModelProviderForProviderFilters(t *testing.T) {
|
||||
models := []store.PlatformModel{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user