package modelselection import ( "voicesnap/internal/config" "voicesnap/internal/language" "voicesnap/internal/logger" "voicesnap/internal/model" ) type CurrentModel struct { ModelID string Profile model.ModelProfile SelectionMode string LanguageSettings language.LanguageSettings FallbackReason string } func Resolve(cfg *config.Config, detector language.SystemLocaleDetector) CurrentModel { if cfg == nil { cfg = config.Default() } settings := language.Resolve(cfg.LanguageMode, cfg.LanguageID, detector) selectionMode := config.NormalizeModelSelectionMode(cfg.ModelSelectionMode) modelID := settings.DefaultModelID fallbackReason := "" if selectionMode == config.ModelSelectionModeManual { if profile, err := model.GetModelProfile(cfg.SelectedModelID); err == nil { if !model.IsModelSupportedInCurrentBuild(profile.ID) { fallbackReason = "manual model not supported in current build" logger.Info("Manual SelectedModelID %q is not supported in this build, falling back to language default %q", cfg.SelectedModelID, modelID) } else if isModelAvailableForLanguage(profile.ID, settings.EffectiveLanguageID) { return CurrentModel{ ModelID: profile.ID, Profile: profile, SelectionMode: selectionMode, LanguageSettings: settings, } } else { fallbackReason = "manual model not available for language" logger.Info("Manual SelectedModelID %q is not available for language %q, falling back to language default %q", cfg.SelectedModelID, settings.EffectiveLanguageID, modelID) } } else { fallbackReason = "invalid manual model selection" logger.Info("Invalid manual SelectedModelID %q, falling back to language default %q", cfg.SelectedModelID, modelID) } } profile, err := model.GetModelProfile(modelID) if err != nil { fallbackReason = "invalid language default model" logger.Info("Invalid default model %q for language %q, falling back to %q", modelID, settings.EffectiveLanguageID, model.DefaultModelID) profile = model.DefaultModelProfile() modelID = profile.ID } else if !model.IsModelSupportedInCurrentBuild(profile.ID) { fallbackReason = "language default model not supported in current build" logger.Info("Default model %q for language %q is not supported in this build, falling back to %q", modelID, settings.EffectiveLanguageID, model.DefaultModelID) profile = model.DefaultModelProfile() modelID = profile.ID } return CurrentModel{ ModelID: modelID, Profile: profile, SelectionMode: selectionMode, LanguageSettings: settings, FallbackReason: fallbackReason, } } func isModelAvailableForLanguage(modelID, languageID string) bool { if !model.IsModelSupportedInCurrentBuild(modelID) { return false } profile, err := model.GetLanguageProfile(languageID) if err != nil { return false } if profile.DefaultModelID == modelID { return true } for _, upgradeModelID := range profile.UpgradeModelIDs { if upgradeModelID == modelID { return true } } return false }