/** * Intent detection (`detect_flow`) ⇄ TypeSafe System One — mapping only, zero imports. * * jsfe hands aiCallback a 4th argument on intent detection: the call in structured form, * `{ task: 'detect_flow', input, conversation, flows }`, each flow with its parameters and any * declared `enum`. That is what a classifier needs, so this module maps it to System One questions * and the answers back to the reply jsfe expects: `{ flowName, parameters }`. Two stages: * * 1. one noul per flow: "should `latest_message` start this workflow?" — argmax, if it clears * INTENT_YES_THRESHOLD, else "None". * 2. only for the chosen flow, and only if it declares one: a noul per ENUM value and per * BOOLEAN parameter. * Every other parameter (free text: a city, an account number…) is not the classifier's; the * host decides whether to take it from a text model — see freeTextParameters(). * * The host sends the bodies (POST …/v1/systemone) and owns the HTTP, the key and the timeouts. * * A question that comes back without a usable answer FAILS the call, so the host can fall back * to a text model. A missing flow answer read as "no" would silently send the turn nowhere. */ import type { DetectFlowRequest } from '../index.js'; /** One flow entry of the structured intent-detection request. */ export type DetectFlowRequestFlow = DetectFlowRequest['flows'][number]; /** A noul at or above this is a yes. */ export declare const INTENT_YES_THRESHOLD = 0.5; /** One System One request body plus the index that maps each question id back to what it asks. */ export interface SystemOneCall { body: { model: string; state: Record; questions: Record; }; index: I[]; } export interface FlowQuestion { id: string; flow: number; } export type ParameterQuestion = { id: string; kind: 'enum'; param: string; value: string; } | { id: string; kind: 'boolean'; param: string; }; /** System One's answers, keyed by question id. */ export type SystemOneAnswers = Record | undefined; export interface IntentReply { flowName: string; parameters: Record; } export interface MapOptions { model: string; assistantInstructions: string; } /** Is this a jsfe intent-detection request this module can map? */ export declare function isDetectFlowRequest(request: unknown): request is DetectFlowRequest; /** Parameters of `flow` the classifier does not answer: neither an enum nor a boolean. */ export declare function freeTextParameters(flow: DetectFlowRequestFlow | null | undefined): string[]; /** * STAGE 1 — which flow. One noul per flow. `assistantInstructions` is jsfe's own task + rules (the * text prompt's system instruction without its JSON-schema tail), so a classifier and a text model * judge by one rule set. */ export declare function toFlowRequest(request: DetectFlowRequest, { model, assistantInstructions }: MapOptions): SystemOneCall; /** * Decodes stage 1. Throws if any question is unanswered. Returns `{ flow, scores }` — `flow` is the * chosen request entry, or null for "None"; `scores` the top three, for logging. */ export declare function fromFlowAnswers(answers: SystemOneAnswers, index: FlowQuestion[], request: DetectFlowRequest, threshold?: number): { flow: DetectFlowRequestFlow | null; scores: { name: string; p: number; }[]; }; /** Does `flow` declare anything stage 2 answers (an enum or a boolean)? */ export declare function hasJevParameters(flow: DetectFlowRequestFlow | null | undefined): boolean; /** * STAGE 2 — the chosen flow's enum and boolean parameters: one noul per enum value, one per * boolean. Each parameter's description is its rule. Free text is not asked. * * The flow and the rules are stated ONCE, in `assistant_instructions`; each question names its * parameter only. Repeating a long rule in every question of its enum multiplies the body size * and the latency for identical answers. */ export declare function toParameterRequest(request: DetectFlowRequest, flow: DetectFlowRequestFlow, { model, assistantInstructions }: MapOptions): SystemOneCall; /** * Decodes stage 2 into parameters: an enum takes its argmax value if it clears the cut, a boolean is * true if it clears it; otherwise the parameter is OMITTED (the flow asks / its default applies), * never set false. Throws if any question is unanswered. */ export declare function fromParameterAnswers(answers: SystemOneAnswers, index: ParameterQuestion[], threshold?: number): Record; /** * Merges a text model's free-text parameters into the classifier's reply — only when the text model * chose the SAME flow (its parameters were extracted for its own choice), and only the parameters * the classifier does not answer. The classifier's enum/boolean values always win. */ export declare function mergeTextParameters(jevReply: IntentReply, jevFlow: DetectFlowRequestFlow | null | undefined, textReply: { flowName?: unknown; parameters?: Record; } | null | undefined): IntentReply; //# sourceMappingURL=systemone-intent.d.ts.map