/** * factory.ts - EmbeddingProvider factory with config precedence. * * Resolution order (first match wins): * 1. Explicit `kind` argument or `--provider` CLI flag → forces a kind * 2. `QMD_EMBED_ENDPOINT` env var present and non-empty → "openai" * 3. Config file (`~/.config/qmd/config.json`) `embedProvider.kind` → that kind * 4. Otherwise → "local" (legacy / backward-compat) * * Backward compat invariant: when neither `QMD_EMBED_ENDPOINT` nor * `~/.config/qmd/config.json` mentions a provider, callers get the same * `LocalLlamaCppProvider` they had before this change. */ import { type LocalLlamaCppProviderConfig } from "./local.js"; import { type OpenAIProviderConfig } from "./openai.js"; import { type AutoFallbackProviderConfig } from "./autofallback.js"; import type { EmbeddingProvider, ProviderKind } from "./provider.js"; export type EmbedProviderConfigFile = { embedProvider?: { kind?: ProviderKind; endpoint?: string; apiKey?: string; modelId?: string; upstreamModel?: string; batchSize?: number; /** * Max in-flight HTTP requests during a single `embedBatch` call. Default 4 * (matches qmd-embed-worker's MAX_CONCURRENT_REQUESTS=4 semaphore). Set * to 1 to force legacy sequential dispatch. */ concurrency?: number; timeoutMs?: number; /** When true, wrap the openai provider in AutoFallback (local fallback). */ autoFallback?: boolean; }; }; export declare function defaultConfigPath(): string; /** * Load `~/.config/qmd/config.json` if present. Returns an empty object on * any read/parse error so we silently fall back to env/local. */ export declare function loadConfigFile(path?: string): EmbedProviderConfigFile; export type CreateEmbeddingProviderOptions = { /** Force a specific provider kind. Overrides env + config. */ kind?: ProviderKind; /** Override config file path (mostly for tests) */ configPath?: string; /** Local-provider overrides */ local?: LocalLlamaCppProviderConfig; /** OpenAI-provider overrides — merged on top of env/config */ openai?: Partial; /** * Wrap the chosen provider in `AutoFallbackEmbeddingProvider` so that a * remote outage transparently falls back to local llama.cpp. Default: * `false` — opt-in, since the wrapper requires both backends to be * available and the local one will warm node-llama-cpp on first call. * * Resolution: explicit `autoFallback` wins → env `QMD_EMBED_AUTO_FALLBACK` * (`1`/`true`) → config-file `embedProvider.autoFallback` → false. * * Only applies when the resolved kind is `openai` (no fallback wrap when * the primary IS local already). */ autoFallback?: boolean; /** * Override config for `AutoFallbackEmbeddingProvider` (failureStreak, * cooldownMs, etc.). Only used when `autoFallback` resolves true. * Primary + fallback are constructed automatically. */ autoFallbackOverrides?: Omit; /** * Custom env source (mostly for tests). Defaults to `process.env`. * Read keys: QMD_EMBED_PROVIDER, QMD_EMBED_ENDPOINT, QMD_EMBED_API_KEY, * QMD_EMBED_MODEL_ID, QMD_EMBED_UPSTREAM_MODEL, QMD_EMBED_BATCH_SIZE, * QMD_EMBED_TIMEOUT_MS, QMD_EMBED_AUTO_FALLBACK. */ env?: Record; }; /** * Resolve the provider kind without instantiating anything. Useful for * logging and tests. */ export declare function resolveProviderKind(opts?: CreateEmbeddingProviderOptions): ProviderKind; /** * Factory entry point — returns the appropriate `EmbeddingProvider`. * Throws if `openai` kind is requested but no endpoint is configured. */ export declare function createEmbeddingProvider(opts?: CreateEmbeddingProviderOptions): EmbeddingProvider;