UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

58 lines (57 loc) • 2.22 kB
import { debugLog } from "./shared.js"; import { decodeStringRow, queryRows } from "./shared/index.js"; import { errorMessage } from "./utils.js"; /** Throttle delay between embedding requests in the background embed loop. */ const BACKGROUND_EMBED_THROTTLE_MS = 50; async function loadWarmupDeps() { const { checkOllamaAvailable, embedText, getEmbeddingModel, getOllamaUrl } = await import("./shared/ollama.js"); return { checkOllamaAvailable, embedText, getEmbeddingModel, getOllamaUrl, sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)), }; } export function startEmbeddingWarmup(db, cache, deps) { const loadPromise = cache.load().catch((err) => { debugLog(`Embedding cache startup load failed: ${errorMessage(err)}`); }); const backgroundPromise = backgroundEmbedMissingDocs(db, cache, deps); return { loadPromise, backgroundPromise }; } export async function backgroundEmbedMissingDocs(db, cache, deps) { try { const resolved = { ...(await loadWarmupDeps()), ...deps }; if (!resolved.getOllamaUrl()) return 0; if (!await resolved.checkOllamaAvailable()) return 0; const rows = queryRows(db, "SELECT path, content FROM docs", []); if (!rows) return 0; const model = resolved.getEmbeddingModel(); let count = 0; for (const row of rows) { const [docPath, content] = decodeStringRow(row, 2, "backgroundEmbedMissingDocs"); if (cache.get(docPath, model)) continue; const vec = await resolved.embedText(content.slice(0, 8000)); if (vec) { cache.set(docPath, model, vec); count++; if (count % 10 === 0) await cache.flush(); } await resolved.sleep(BACKGROUND_EMBED_THROTTLE_MS); } if (count > 0) await cache.flush(); debugLog(`backgroundEmbedMissingDocs: embedded ${count} new docs`); return count; } catch (err) { debugLog(`backgroundEmbedMissingDocs error: ${errorMessage(err)}`); return 0; } }