Ariver
2026-06-03 4e7591ebb1294f611e7b85082be55313dd53820f
privatevoice.src/services/engine_service.go
@@ -1,9 +1,13 @@
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"
@@ -38,6 +42,36 @@
   }
}
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()
@@ -67,6 +101,39 @@
   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
@@ -76,3 +143,11 @@
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())
}