/** * Composer that wraps a primary `IntentClassifyFn` with a synchronous * heuristic fallback. * * Common shape: * * - **primary**: an LLM call (Vercel AI SDK `generateObject`, OpenAI * tool-calling, Workers AI). Costs money + latency; sometimes errors. * - **fallback**: a regex/keyword classifier. Free, deterministic, * covers the common cases. Fires when the primary throws OR when it * returns null/undefined (e.g. the SDK couldn't parse the response). * * Either composition path works: * * const composed = new HeuristicFallbackClassifier({ primary: llmFn, fallback: kwFn }); * const llm = new LLMIntentClassifier({ intents, fallback: 'other', classify: composed.classify }); * * Or use the composer directly anywhere an `IntentClassifyFn` is expected: * * new LLMIntentClassifier({ intents, fallback: 'other', classify: heuristicFallback(llmFn, kwFn).classify }); * * Out of scope for now: confidence-threshold fallback (primary returned a * value but with low confidence → use the heuristic instead). Add * `minConfidence` in 0.6 if needed; v0.5 ships error-only. * * Why this exists: aysu's `TextClassifier` (`ai/classifier.ts:78`) wraps * an Azure OpenAI call with a `heuristicClassify` regex fallback. The * pattern fits any classifier surface — generalizing it here lets aysu's * 113-line module shrink to ~30 LOC of regex tables. */ import type { IntentClassifyFn, IntentResult } from '../pipeline/intent.js'; /** * The sync-or-async fallback. Receives the input text + the intent * vocabulary and returns an `IntentResult` or null. Null is a signal to * propagate the primary's failure (which surfaces as the * `LLMIntentClassifier`'s configured fallback intent). */ export type HeuristicFn = (text: string, intents: readonly I[]) => IntentResult | null | Promise | null>; export interface HeuristicFallbackClassifierOptions { primary: IntentClassifyFn; fallback: HeuristicFn; /** Fires once per primary failure for observability. Errors here are swallowed. */ onPrimaryError?: (err: unknown) => void; } export declare class HeuristicFallbackClassifier { readonly primary: IntentClassifyFn; readonly fallback: HeuristicFn; readonly onPrimaryError: (err: unknown) => void; constructor({ primary, fallback, onPrimaryError }: HeuristicFallbackClassifierOptions); /** * `IntentClassifyFn`-shaped — drop-in replacement for the bare LLM * function in `LLMIntentClassifier({ classify: ... })`. */ readonly classify: IntentClassifyFn; } /** * Functional sugar — returns an `IntentClassifyFn` directly without the * class wrapper. Useful for one-shot inline composition. * * classify: heuristicFallback(llmFn, kwFn), */ export declare function heuristicFallback(primary: IntentClassifyFn, fallback: HeuristicFn, onPrimaryError?: (err: unknown) => void): IntentClassifyFn; //# sourceMappingURL=heuristic_fallback_classifier.d.ts.map