()
| 229 | } |
| 230 | |
| 231 | private backfillMemoryEmbeddings(): void { |
| 232 | if (!this.opts.embedder) return; |
| 233 | try { |
| 234 | const all = this.opts.store.listHubMemories({ limit: 500 }); |
| 235 | const missing = all.filter(m => { |
| 236 | try { return !this.opts.store.getHubMemoryEmbedding(m.id); } catch { return true; } |
| 237 | }); |
| 238 | if (missing.length === 0) return; |
| 239 | this.opts.log.info(`hub: backfilling embeddings for ${missing.length} hub memories`); |
| 240 | const texts = missing.map(m => (m.summary || m.content || "").slice(0, 500)); |
| 241 | this.opts.embedder.embed(texts).then((vectors) => { |
| 242 | let count = 0; |
| 243 | for (let i = 0; i < vectors.length; i++) { |
| 244 | if (vectors[i]) { |
| 245 | this.opts.store.upsertHubMemoryEmbedding(missing[i].id, new Float32Array(vectors[i])); |
| 246 | count++; |
| 247 | } |
| 248 | } |
| 249 | this.opts.log.info(`hub: backfilled ${count}/${missing.length} memory embeddings`); |
| 250 | }).catch((err) => { |
| 251 | this.opts.log.warn(`hub: backfill memory embeddings failed: ${err}`); |
| 252 | }); |
| 253 | } catch (err) { |
| 254 | this.opts.log.warn(`hub: backfill memory embeddings error: ${err}`); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | private embedMemoryAsync(memoryId: string, summary: string, content: string): void { |
| 259 | const embedder = this.opts.embedder; |
no test coverage detected