/** * LLM backend resolver for the transcript extraction pipeline. * * Resolves the best available LLM backend using a priority-ordered fallback * chain. Warm-tier prefers local inference (Ollama → transformers.js) before * escalating to the cloud (Claude Sonnet). Cold-tier uses Claude Sonnet * exclusively (owner-mandated, NOT Haiku). * * ## Unified resolver convergence (T11757) * * Before walking the legacy fallback chain, `resolveLlmBackend` FIRST consults * the unified role/profile resolver (`resolveLLMForRole('extraction')` in * `../llm/role-resolver.ts`). This honours a pinned `extraction`-role profile — * e.g. an openai-compatible provider (`openai`/`ollama`, optionally with a * `baseUrl` override) or `anthropic` — so the sentient loop uses the SAME * provider/credential machinery as the rest of CLEO. When the unified resolver * yields nothing usable (no pinned profile, no credential, or a client that * cannot be constructed), the call falls through to the legacy warm/cold chain * below — no behavioural regression for unconfigured installs. * * Fallback chain (warm): * 0. Unified resolver (`extraction` role profile) — anthropic OR openai-compatible * 1. Ollama daemon running at localhost:11434 (gemma4:e4b-it or fallback model) * 2. @huggingface/transformers (already installed; ONNX pipeline, zero extra deps) * 3. Claude Sonnet via Anthropic API (cold escalation) * 4. null — no backend; caller must skip extraction * * Fallback chain (cold): * 0. Unified resolver (`extraction` role profile) * 1. Claude Sonnet via Anthropic API (ANTHROPIC_API_KEY required) * 2. null — no API key; caller must skip extraction * * OWNER OVERRIDE 2026-04-15: Cold tier MUST use claude-sonnet-4-6, NOT Haiku. * * Research basis: `.cleo/agent-outputs/T750-research-local-llm.md` * Spec reference: `docs/specs/memory-architecture-spec.md` §7 * * @task T730 * @task T11757 * @epic T726 */ import type { LanguageModel } from 'ai'; /** Extraction tier — warm prefers local inference, cold uses cloud. */ export type ExtractionTier = 'warm' | 'cold'; /** * The resolved backend name. Used for telemetry and logging. * * - `ollama` — Ollama daemon (local), reached via its OpenAI-compatible `/v1` shim * - `openai` — an OpenAI-compatible provider resolved from the unified * role/profile resolver (T11757) — covers a pinned `openai` * profile, including one whose `baseUrl` points at a local * server. `ollama` is reported separately when the unified * profile provider is literally `ollama`. * - `transformers` — @huggingface/transformers ONNX pipeline (local, in-process) * - `anthropic` — Claude (Sonnet) via Anthropic API (cloud) * - `none` — No backend available; extraction must be skipped */ export type ExtractionBackendName = 'ollama' | 'openai' | 'transformers' | 'anthropic' | 'none'; /** * Resolved backend descriptor returned by `resolveLlmBackend`. * * `model` is a Vercel AI SDK `LanguageModel` for use with `generateObject()`. * `name` identifies which backend was selected for logging and telemetry. */ export interface ResolvedBackend { /** Vercel AI SDK LanguageModel instance ready to use. */ model: LanguageModel; /** Which backend was selected. */ name: ExtractionBackendName; /** Model identifier string (e.g. `gemma4:e4b-it`, `claude-sonnet-4-6`). */ modelId: string; } /** * Resolve the best available LLM backend for transcript extraction. * * Returns a `ResolvedBackend` with a Vercel AI SDK `LanguageModel` ready for * `generateObject()`, or `null` if no backend is available and the caller * should skip extraction. * * Never throws — all errors are caught internally. * * @param tier - Extraction tier: `warm` (prefer local) or `cold` (cloud). * @returns Resolved backend descriptor, or `null` if nothing is available. * * @example * ```ts * const backend = await resolveLlmBackend('warm'); * if (!backend) { return; } // no backend available * const { object } = await generateObject({ model: backend.model, ... }); * ``` */ export declare function resolveLlmBackend(tier: ExtractionTier): Promise; /** * Check whether the Ollama daemon is reachable and has a usable model. * * Returns `null` on any failure — never throws. */ export declare function isOllamaAvailable(): Promise; //# sourceMappingURL=llm-backend-resolver.d.ts.map