| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "strings" |
| 6 | |
| 7 | "reasonix/internal/config" |
| 8 | ) |
| 9 | |
| 10 | // SetWebSearchModel uses the same admission, locking and rebuild lifecycle as |
| 11 | // other model assignments. A running controller is never mutated in place. |
| 12 | func (a *App) SetWebSearchModel(ref string) error { |
| 13 | _, err := a.applyModelConfigChangeWithSave("web search model", func(c *config.Config) error { |
| 14 | return setWebSearchModelConfig(c, ref) |
| 15 | }, func(c *config.Config, path string) error { return c.SaveWebSearchModelTo(path) }) |
| 16 | return err |
| 17 | } |
| 18 | |
| 19 | func (a *App) populateWebSearchSettings(v *SettingsView, cfg *config.Config, root string) { |
| 20 | v.WebSearchModels = []string{} |
| 21 | for _, p := range cfg.Providers { |
| 22 | if !modelProviderAccessAllowed(cfg.Desktop.ProviderAccess, p.Name) { |
| 23 | continue |
| 24 | } |
| 25 | for _, model := range p.ModelList() { |
| 26 | ref := p.Name + "/" + model |
| 27 | if _, err := cfg.ResolveWebSearchModel(ref); err == nil { |
| 28 | v.WebSearchModels = append(v.WebSearchModels, ref) |
| 29 | } |
| 30 | } |
| 31 | } |
| 32 | effective := cfg |
| 33 | path := config.SourcePathForRoot(root) |
| 34 | if !config.IsUserConfigPath(path) && config.ConfigFileDefinesWebSearchModel(path) { |
| 35 | if loaded, err := config.LoadForRootReadOnly(root); err == nil { |
| 36 | effective = loaded |
| 37 | v.WebSearchModelOverridden = true |
| 38 | } |
| 39 | } |
| 40 | v.EffectiveWebSearchModel = effective.Agent.WebSearchModel |
| 41 | current, _ := effective.ResolveModel(effective.DefaultModel) |
| 42 | result := effective.ResolveWebSearch(current) |
| 43 | v.WebSearchModelStatus, v.WebSearchModelReason = result.Status, result.Reason |
| 44 | if ref := strings.TrimSpace(effective.Agent.WebSearchModel); ref != "" && !strings.EqualFold(ref, "auto") { |
| 45 | name, _, _ := strings.Cut(ref, "/") |
| 46 | if !modelProviderAccessAllowed(effective.Desktop.ProviderAccess, name) { |
| 47 | v.WebSearchModelStatus = "invalid" |
| 48 | v.WebSearchModelReason = "Search connection is not added" |
| 49 | } |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | func setWebSearchModelConfig(c *config.Config, ref string) error { |
| 54 | ref = strings.TrimSpace(ref) |
| 55 | if ref != "" && !strings.EqualFold(ref, "auto") { |
| 56 | entry, err := c.ResolveWebSearchModel(ref) |
| 57 | if err != nil { |
| 58 | return err |
| 59 | } |
| 60 | if !modelProviderAccessAllowed(c.Desktop.ProviderAccess, entry.Name) { |
| 61 | return fmt.Errorf("search connection is not added") |
| 62 | } |
| 63 | } |
| 64 | return c.SetWebSearchModel(ref) |
| 65 | } |
| 66 |