/** * Layer 2 (v1.7.5): bundled-seed JSON loader. * * Reads `data/seed-models.json` (committed anchor; refreshed by * `scripts/build-seed.py` at release time) and exposes a typed Map for * O(1) lookups. Pure read; no DB; no fetch. * * **Schema v2** (current): three load-bearing fields per entry — * `maxTokens`, `queryPrefix`, `documentPrefix`. Everything else * (`dim`, `sizeBytes`, `prefixSource`, `modelType`, `baseModel`, * `hasDenseLayer`, `hasNormalize`, `runnableViaTransformersJs`) was dropped * because runtime probes `dim` from the loaded ONNX, and the rest is * informational. We also can't trust MTEB's curated `embed_dim` — verified * across the canonical presets, BAAI/bge-small-en-v1.5 has `embed_dim=512` * in MTEB but the actual model dim is 384. * * **Schema v1** (older anchors / pre-Python build script): superset shape * with all the cosmetic fields. Loaded transparently — the v1→v2 adapter * pulls the three fields we still care about and discards the rest. * * Bad shape / missing file → returns an empty map + writes a single stderr * warning. Resolver falls through to the live HF fetcher; we never crash. */ export interface SeedEntry { /** Effective max input tokens (from MTEB-curated `max_tokens`). Always set. */ maxTokens: number; /** Query-side prefix (sentence-transformer `prompts.query`), or null for symmetric. */ queryPrefix: string | null; /** Document-side prefix; '' for asymmetric models that prepend to queries only. */ documentPrefix: string | null; } /** v1 entry shape — superset of v2 plus cosmetic fields we now drop on read. */ interface SeedEntryV1 { dim?: number; maxTokens: number; queryPrefix: string | null; documentPrefix: string | null; prefixSource?: string; modelType?: string; baseModel?: string | null; hasDenseLayer?: boolean; hasNormalize?: boolean; sizeBytes?: number | null; runnableViaTransformersJs?: boolean; } /** * Project a v1 seed entry down to the v2 shape — drops every field except * the load-bearing trio (`maxTokens`, `queryPrefix`, `documentPrefix`). * * Exported for tests because the committed anchor is always v2, so the * live `loadSeed()` path never exercises this adapter; without a direct * test, an accidental break would only surface when (a) someone restores * a v1 anchor by mistake, or (b) ships an older committed seed via a * cherry-pick. Direct unit coverage costs ~10 lines of test and makes * the back-compat branch genuinely tested rather than aspirational. */ export declare function _adaptV1Entry(entry: SeedEntryV1): SeedEntry; /** Reset the in-process cache (tests). Production code never calls this. */ export declare function _resetSeedCache(): void; /** * Load the seed JSON once per process. Subsequent calls hit the in-memory * cache. Empty map on any load failure. */ export declare function loadSeed(): Map; /** Diagnostic — exposed for `index_status` / CLI to surface freshness. */ export declare function getSeedMeta(): { generatedAt: number; source: string | null; entries: number; } | null; export {};