| | |
| | | |
| | | func (s *EngineService) ListModelOptions() []map[string]interface{} { |
| | | current := s.currentModel() |
| | | return s.listModelOptionsForCurrent(current) |
| | | } |
| | | |
| | | func (s *EngineService) ListModelOptionsForLanguage(languageID string) []map[string]interface{} { |
| | | current := s.currentModel() |
| | | activeLanguageID := current.LanguageSettings.EffectiveLanguageID |
| | | current.LanguageSettings = language.Resolve(config.LanguageModeManual, model.NormalizeLanguageID(languageID), nil) |
| | | if current.LanguageSettings.EffectiveLanguageID != activeLanguageID { |
| | | current.ModelID = "" |
| | | } |
| | | return s.listModelOptionsForCurrent(current) |
| | | } |
| | | |
| | | func (s *EngineService) listModelOptionsForCurrent(current modelselection.CurrentModel) []map[string]interface{} { |
| | | languageProfile, err := model.GetLanguageProfile(current.LanguageSettings.EffectiveLanguageID) |
| | | if err != nil { |
| | | return nil |
| | |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) SelectModelForLanguage(languageID, modelID string) error { |
| | | languageID = model.NormalizeLanguageID(languageID) |
| | | profile, languageProfile, err := s.allowedModelProfileForLanguage(languageID, modelID) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | resolved, err := model.ResolveModel(profile.ID) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | if !resolved.IsUsable() { |
| | | return fmt.Errorf("model %s is not installed", profile.ID) |
| | | } |
| | | |
| | | s.persistLanguageModelSelection(languageID, profile, languageProfile) |
| | | s.ReloadCurrentModel() |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) DownloadModelByID(modelID string) error { |
| | | profile, err := s.allowedModelProfile(modelID) |
| | | if err != nil { |
| | |
| | | config.Save(s.cfg) |
| | | s.ReloadCurrentModel() |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) DownloadModelByIDForLanguage(languageID, modelID string) error { |
| | | languageID = model.NormalizeLanguageID(languageID) |
| | | profile, languageProfile, err := s.allowedModelProfileForLanguage(languageID, modelID) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | if len(profile.DownloadURLs) == 0 { |
| | | return fmt.Errorf("no download URL configured for model %s", profile.ID) |
| | | } |
| | | |
| | | ctx, finish, err := s.beginModelDownload(profile.ID) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | defer finish() |
| | | |
| | | err = model.DownloadProfileWithContext(ctx, profile, profile.DownloadURLs, paths.ModelsRoot(), func(percent float64, downloaded, total int64) { |
| | | s.updateModelDownloadProgress(profile.ID, percent, downloaded, total) |
| | | if s.app != nil { |
| | | s.app.Event.Emit("model:download-progress", map[string]interface{}{ |
| | | "percent": percent, |
| | | "downloaded": downloaded, |
| | | "total": total, |
| | | "modelID": profile.ID, |
| | | "modelName": profile.DisplayName, |
| | | }) |
| | | } |
| | | }) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | |
| | | s.persistLanguageModelSelection(languageID, profile, languageProfile) |
| | | s.ReloadCurrentModel() |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) persistLanguageModelSelection(languageID string, profile model.ModelProfile, languageProfile model.LanguageProfile) { |
| | | s.cfg.LanguageMode = config.LanguageModeManual |
| | | s.cfg.LanguageID = languageID |
| | | if profile.ID == languageProfile.DefaultModelID { |
| | | s.cfg.ModelSelectionMode = config.ModelSelectionModeAuto |
| | | s.cfg.SelectedModelID = "" |
| | | } else { |
| | | s.cfg.ModelSelectionMode = config.ModelSelectionModeManual |
| | | s.cfg.SelectedModelID = profile.ID |
| | | } |
| | | config.Save(s.cfg) |
| | | } |
| | | |
| | | func (s *EngineService) CancelModelDownload(modelID string) bool { |
| | |
| | | } |
| | | |
| | | func (s *EngineService) allowedModelProfile(modelID string) (model.ModelProfile, error) { |
| | | current := s.currentModel() |
| | | profile, _, err := s.allowedModelProfileForLanguage(current.LanguageSettings.EffectiveLanguageID, modelID) |
| | | return profile, err |
| | | } |
| | | |
| | | func (s *EngineService) allowedModelProfileForLanguage(languageID, modelID string) (model.ModelProfile, model.LanguageProfile, error) { |
| | | profile, err := model.GetModelProfile(modelID) |
| | | if err != nil { |
| | | return model.ModelProfile{}, err |
| | | return model.ModelProfile{}, model.LanguageProfile{}, err |
| | | } |
| | | switch model.ModelUnsupportedReason(profile.ID) { |
| | | case "": |
| | | case model.UnsupportedReasonRequiresMacOS14: |
| | | return model.ModelProfile{}, fmt.Errorf("model %s requires macOS 14 or later", profile.ID) |
| | | return model.ModelProfile{}, model.LanguageProfile{}, fmt.Errorf("model %s requires macOS 14 or later", profile.ID) |
| | | case model.UnsupportedReasonWindowsPreview: |
| | | return model.ModelProfile{}, fmt.Errorf("model %s is not supported in the Windows preview build; use SenseVoice", profile.ID) |
| | | return model.ModelProfile{}, model.LanguageProfile{}, fmt.Errorf("model %s is not supported in the Windows preview build; use SenseVoice", profile.ID) |
| | | default: |
| | | return model.ModelProfile{}, fmt.Errorf("model %s is not supported in this build", profile.ID) |
| | | return model.ModelProfile{}, model.LanguageProfile{}, fmt.Errorf("model %s is not supported in this build", profile.ID) |
| | | } |
| | | |
| | | current := s.currentModel() |
| | | languageProfile, err := model.GetLanguageProfile(current.LanguageSettings.EffectiveLanguageID) |
| | | languageProfile, err := model.GetLanguageProfile(model.NormalizeLanguageID(languageID)) |
| | | if err != nil { |
| | | return model.ModelProfile{}, err |
| | | return model.ModelProfile{}, model.LanguageProfile{}, err |
| | | } |
| | | if profile.ID == languageProfile.DefaultModelID { |
| | | return profile, nil |
| | | return profile, languageProfile, nil |
| | | } |
| | | for _, id := range languageProfile.UpgradeModelIDs { |
| | | if profile.ID == id { |
| | | return profile, nil |
| | | return profile, languageProfile, nil |
| | | } |
| | | } |
| | | return model.ModelProfile{}, fmt.Errorf("model %s is not available for language %s", profile.ID, current.LanguageSettings.EffectiveLanguageID) |
| | | return model.ModelProfile{}, model.LanguageProfile{}, fmt.Errorf("model %s is not available for language %s", profile.ID, languageProfile.ID) |
| | | } |