From d0ac79dc96a426819e453bd8259088533e782009 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:05:22 +0800 Subject: [PATCH] fix: ASR/VLM/TTS models not selectable in default model settings (#17024) --- internal/entity/types.go | 12 +++---- internal/service/model_service.go | 29 +++++++++++++++- internal/service/tenant.go | 56 +++++++++++++++++-------------- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/internal/entity/types.go b/internal/entity/types.go index da267f39b0..debde74114 100644 --- a/internal/entity/types.go +++ b/internal/entity/types.go @@ -20,7 +20,7 @@ import "strings" // ModelType represents the type of model as a bitmask, matching Python's // ModelTypeBinary enum (common/constants.py). -// Bit flags (LSB->MSB): 1=chat, 2=embedding, 4=speech2text, 8=image2text, 16=rerank, 32=tts, 64=ocr. +// Bit flags (LSB->MSB): 1=chat, 2=embedding, 4=asr, 8=vision, 16=rerank, 32=tts, 64=ocr. // A model can belong to multiple types simultaneously. type ModelType int @@ -91,10 +91,10 @@ func (mt ModelType) HumanReadable() []string { parts = append(parts, "embedding") } if mt.Has(ModelTypeSpeech2Text) { - parts = append(parts, "speech2text") + parts = append(parts, "asr") } if mt.Has(ModelTypeImage2Text) { - parts = append(parts, "image2text") + parts = append(parts, "vision") } if mt.Has(ModelTypeRerank) { parts = append(parts, "rerank") @@ -115,11 +115,9 @@ func ModelTypeFromString(s string) ModelType { return ModelTypeChat case "embedding": return ModelTypeEmbedding - case "speech2text": + case "asr", "speech2text": return ModelTypeSpeech2Text - case "image2text": - return ModelTypeImage2Text - case "vision": + case "vision", "image2text": return ModelTypeImage2Text case "rerank": return ModelTypeRerank diff --git a/internal/service/model_service.go b/internal/service/model_service.go index 27ce1bd8e0..6ded690a9d 100644 --- a/internal/service/model_service.go +++ b/internal/service/model_service.go @@ -1159,6 +1159,34 @@ func (m *ModelProviderService) ListTenantAddedModels(userID, ownerTenantID, mode return nil, common.CodeServerError, err } + // Repair records that have model_type == 0. Before the ModelTypeFromString + // fix that added "asr" support, models whose factory catalog used the + // canonical name "asr" (instead of the legacy "speech2text") were stored + // with model_type = 0. Re-derive the correct bitmask from the factory + // catalog and persist it so the model shows up in typed queries. + providerManager := dao.GetModelProviderManager() + for _, rec := range modelRecords { + if rec.ModelType != 0 { + continue + } + provInfo := providerInfoByID[rec.ProviderID] + if provInfo == nil { + continue + } + factoryModel, lookupErr := providerManager.GetModelByName(provInfo.ProviderName, rec.ModelName) + if lookupErr != nil || len(factoryModel.ModelTypes) == 0 { + continue + } + combinedType := entity.ModelType(0) + for _, t := range factoryModel.ModelTypes { + combinedType |= entity.ModelTypeFromString(t) + } + if combinedType != 0 { + rec.ModelType = int(combinedType) + _ = m.modelDAO.UpdateByID(rec.ID, map[string]interface{}{"model_type": int(combinedType)}) + } + } + var targetRecords []*entity.TenantModel if modelTypeFilterBin != 0 { for _, rec := range modelRecords { @@ -1171,7 +1199,6 @@ func (m *ModelProviderService) ListTenantAddedModels(userID, ownerTenantID, mode } // Build model rank map from factory catalog (mirrors Python's model_rank_map). - providerManager := dao.GetModelProviderManager() modelRankMap := make(map[string]int) // key: "providerName@modelName" factoryRankMapping := make(map[string]int) for i := range providerManager.Providers { diff --git a/internal/service/tenant.go b/internal/service/tenant.go index d54fa19c4a..ffee7b83ef 100644 --- a/internal/service/tenant.go +++ b/internal/service/tenant.go @@ -450,10 +450,14 @@ func ptrStringValue(s *string) string { } func factoryModelTypeName(modelType string) string { - if modelType == "image2text" { + switch modelType { + case "image2text": return "vision" + case "speech2text": + return "asr" + default: + return modelType } - return modelType } // GetDefaultModelName returns the full default model ID for a tenant and model type @@ -662,32 +666,32 @@ func (s *TenantService) ListTenantDefaultModels(userID string) ([]ModelItem, err }) } - if ownedTenant.OCRID == "" { - return result, nil + if ownedTenant.OCRID != "" { + defaultOCRModelProvider, defaultOCRModelInstance, defaultOCRModelName, defaultOCRModelEnable, err := s.GetModelInfo(ownedTenant.TenantID, ownedTenant.OCRID, "ocr") + if err == nil { + result = append(result, ModelItem{ + ModelProvider: defaultOCRModelProvider, + ModelInstance: defaultOCRModelInstance, + ModelName: defaultOCRModelName, + ModelID: ptrStringValue(ownedTenant.TenantOCRID), + ModelType: "ocr", + Enable: defaultOCRModelEnable, + }) + } } - defaultOCRModelProvider, defaultOCRModelInstance, defaultOCRModelName, defaultOCRModelEnable, err := s.GetModelInfo(ownedTenant.TenantID, ownedTenant.OCRID, "ocr") - if err == nil { - result = append(result, ModelItem{ - ModelProvider: defaultOCRModelProvider, - ModelInstance: defaultOCRModelInstance, - ModelName: defaultOCRModelName, - ModelID: ptrStringValue(ownedTenant.TenantOCRID), - ModelType: "ocr", - Enable: defaultOCRModelEnable, - }) - } - - defaultTTSModelProvider, defaultTTSModelInstance, defaultTTSModelName, defaultTTSModelEnable, err := s.GetModelInfo(ownedTenant.TenantID, ownedTenant.TTSID, "tts") - if err == nil { - result = append(result, ModelItem{ - ModelProvider: defaultTTSModelProvider, - ModelInstance: defaultTTSModelInstance, - ModelName: defaultTTSModelName, - ModelID: ptrStringValue(ownedTenant.TenantTTSID), - ModelType: "tts", - Enable: defaultTTSModelEnable, - }) + if ownedTenant.TTSID != "" { + defaultTTSModelProvider, defaultTTSModelInstance, defaultTTSModelName, defaultTTSModelEnable, err := s.GetModelInfo(ownedTenant.TenantID, ownedTenant.TTSID, "tts") + if err == nil { + result = append(result, ModelItem{ + ModelProvider: defaultTTSModelProvider, + ModelInstance: defaultTTSModelInstance, + ModelName: defaultTTSModelName, + ModelID: ptrStringValue(ownedTenant.TenantTTSID), + ModelType: "tts", + Enable: defaultTTSModelEnable, + }) + } } return result, nil