import { NeuromcpConfig } from '../config.js'; import { Logger } from '../observability/logger.js'; import { EmbeddingProvider } from './types.js'; /** * Outcome of one pass over the provider cascade. * * `provider === null` means nothing usable was found. `explicitError` then * carries the message the strict entrypoint (createEmbeddingProvider) * throws; `rejected` lists providers that WERE reachable but were skipped * because their dimension does not match the existing vector index (see * `requireDimension`). The index-aware caller uses that list to explain a * degraded start instead of crashing. */ interface ProviderSelection { readonly provider: EmbeddingProvider | null; readonly rejected: readonly string[]; readonly explicitError: string | null; } interface SelectProviderOptions { /** * Only accept a provider whose `dimensions` equal this value. Used when * the database already holds a vector index of a fixed width: a provider * with a different width cannot write into that index, and swapping it in * silently is exactly the corruption validate.ts exists to prevent. */ readonly requireDimension?: number; /** * Only accept a provider whose `name` equals the model that produced the * stored embeddings. Two models can share a width while their vector * spaces are unrelated — without this, the cascade stopped at the first * width match and degraded on the model check even when the RIGHT * provider was one step further down. */ readonly requireModel?: string; } type AcceptVerdict = { readonly ok: true; } | { readonly ok: false; readonly reason: string; }; /** * Pure compatibility rule between a candidate provider and the existing * index. Exported so the selection cascade, its static short-circuits and * the tests all share ONE definition of "acceptable". */ declare function providerAcceptable(provider: { readonly name: string; readonly dimensions: number; }, options: SelectProviderOptions): AcceptVerdict; /** * Rule the ONNX fallback out BEFORE probing it, when the requirements make * a match impossible. The probe is not free: with the model file absent it * starts a ~33 MB lazy download — pointless (and startup-delaying) when the * fixed 384 width can never match the existing index anyway. */ declare function staticOnnxSkipReason(options: SelectProviderOptions): string | null; /** * Walk the provider cascade (Ollama → OpenAI → ONNX) and return the first * usable provider. Never throws: the strict wrapper below turns a null * result into the historical error message, while the degraded-start path * in runtime.ts uses the structured result to keep the server alive. */ declare function selectEmbeddingProvider(config: NeuromcpConfig, logger: Logger, options?: SelectProviderOptions): Promise; /** * Strict entrypoint: returns a provider or throws. Behaviour (and error * text) is unchanged from 0.29.2 for every caller that does not care about * the existing index width — bin/embed.mjs, bin/query.mjs, the backfill * script, and the fresh-database path in runtime.ts. */ declare function createEmbeddingProvider(config: NeuromcpConfig, logger: Logger): Promise; export { type AcceptVerdict, type ProviderSelection, type SelectProviderOptions, createEmbeddingProvider, providerAcceptable, selectEmbeddingProvider, staticOnnxSkipReason };