| | |
| | | package services |
| | | |
| | | import ( |
| | | "fmt" |
| | | "sync" |
| | | "voicesnap/internal/config" |
| | | "voicesnap/internal/engine" |
| | | "voicesnap/internal/language" |
| | | "voicesnap/internal/model" |
| | | "voicesnap/internal/modelselection" |
| | | "voicesnap/internal/paths" |
| | | |
| | | "github.com/wailsapp/wails/v3/pkg/application" |
| | |
| | | } |
| | | } |
| | | |
| | | func (s *EngineService) GetCurrentModelStatus() map[string]interface{} { |
| | | current := s.currentModel() |
| | | resolved, err := model.ResolveModel(current.ModelID) |
| | | installed := err == nil && resolved.IsUsable() |
| | | status := model.ModelNotInstalled |
| | | var missing []string |
| | | var problems []string |
| | | if err == nil { |
| | | status = resolved.Status |
| | | missing = resolved.Missing |
| | | problems = resolved.Problems |
| | | } |
| | | |
| | | return map[string]interface{}{ |
| | | "modelID": current.ModelID, |
| | | "displayName": current.Profile.DisplayName, |
| | | "backendKind": current.Profile.BackendKind, |
| | | "languageID": current.LanguageSettings.EffectiveLanguageID, |
| | | "selectionMode": current.SelectionMode, |
| | | "installed": installed, |
| | | "installStatus": status, |
| | | "missing": missing, |
| | | "problems": problems, |
| | | "fallbackReason": current.FallbackReason, |
| | | "downloadSize": current.Profile.ApproxSize, |
| | | "supportedLanguages": current.Profile.SupportedLanguageIDs, |
| | | "recommendedLanguage": current.Profile.RecommendedFor, |
| | | } |
| | | } |
| | | |
| | | func (s *EngineService) SetStatus(status, hardwareInfo, lastError string) { |
| | | s.mu.Lock() |
| | | defer s.mu.Unlock() |
| | |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) DownloadCurrentModel() error { |
| | | current := s.currentModel() |
| | | if len(current.Profile.DownloadURLs) == 0 { |
| | | return fmt.Errorf("no download URL configured for model %s", current.ModelID) |
| | | } |
| | | |
| | | err := model.DownloadProfile(current.Profile, current.Profile.DownloadURLs, paths.ModelsRoot(), func(percent float64, downloaded, total int64) { |
| | | if s.app != nil { |
| | | s.app.Event.Emit("model:download-progress", map[string]interface{}{ |
| | | "percent": percent, |
| | | "downloaded": downloaded, |
| | | "total": total, |
| | | "modelID": current.ModelID, |
| | | "modelName": current.Profile.DisplayName, |
| | | }) |
| | | } |
| | | }) |
| | | if err != nil { |
| | | return err |
| | | } |
| | | |
| | | if s.initCallback != nil { |
| | | go s.initCallback() |
| | | } |
| | | return nil |
| | | } |
| | | |
| | | func (s *EngineService) ReloadCurrentModel() { |
| | | if s.initCallback != nil { |
| | | go s.initCallback() |
| | | } |
| | | } |
| | | |
| | | // SetInitCallback sets the callback to re-initialize the engine after model download. |
| | | func (s *EngineService) SetInitCallback(cb func()) { |
| | | s.initCallback = cb |
| | |
| | | func (s *EngineService) SetApp(app *application.App) { |
| | | s.app = app |
| | | } |
| | | |
| | | func (s *EngineService) currentModel() modelselection.CurrentModel { |
| | | cfg, err := config.Load() |
| | | if err != nil { |
| | | cfg = config.Default() |
| | | } |
| | | return modelselection.Resolve(cfg, language.NewSystemDetector()) |
| | | } |