refreshEmbeddingProvider rebuilds the embedding provider from the (re-loaded) environment and rewires every consumer that captured the previous instance: /context semantic retrieval and the memory vector index. Called by /config reload so a CHATCLI_EMBED_PROVIDER change takes effect without restarti
()
| 62 | // takes effect without restarting the process. Returns the previous and |
| 63 | // current provider names so the caller can surface the transition. |
| 64 | func (cli *ChatCLI) refreshEmbeddingProvider() (oldName, newName string) { |
| 65 | hydeMu.Lock() |
| 66 | old := hydeProvider |
| 67 | fresh := cli.buildEmbeddingProviderLocked() |
| 68 | hydeProvider = fresh |
| 69 | hydeProviderReady = true |
| 70 | hydeMu.Unlock() |
| 71 | |
| 72 | if cli.contextHandler != nil { |
| 73 | if mgr := cli.contextHandler.GetManager(); mgr != nil { |
| 74 | mgr.AttachEmbeddingProvider(fresh) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | // Swap the memory vector index only when one was already attached: a |
| 79 | // fresh index for the new provider (vindex auto-migrates on provider |
| 80 | // or dimension change), or a detach when embeddings were turned off. |
| 81 | // When none was attached, ensureHyDEVectors lazily attaches on the |
| 82 | // next turn and picks up the new provider by itself. |
| 83 | if cli.memoryStore != nil && cli.memoryStore.VectorIndex() != nil { |
| 84 | if embedding.IsNull(fresh) { |
| 85 | cli.memoryStore.AttachVectorIndex(nil) |
| 86 | } else if mgr := cli.memoryStore.Manager(); mgr != nil && mgr.MemoryDir() != "" { |
| 87 | cli.memoryStore.AttachVectorIndex(memory.NewVectorIndex(mgr.MemoryDir(), fresh, cli.logger)) |
| 88 | } |
| 89 | } |
| 90 | return embeddingProviderLabel(old), embeddingProviderLabel(fresh) |
| 91 | } |
| 92 | |
| 93 | // embeddingProviderLabel renders a provider name for status output; |
| 94 | // nil/Null collapse to "null" so transitions compare cleanly. |