/** * Schema-constrained ("structured") output utilities. * * Provides a provider-agnostic single-shot structured call that makes JSON * output reliable even on small local models (DeepSeek / Ollama / LM Studio), * where the server may not honor a strict schema. It: * * 1. requests native structured output (`ChatParams.responseSchema`) AND * injects the schema into the system prompt — belt-and-suspenders for * models that ignore the native knob; * 2. coerces the model's raw text into JSON, tolerating the failure modes * 7B-class models exhibit (markdown fences, surrounding prose); * 3. validates the parsed value against a caller-supplied validator * (typically backed by a Zod schema); and * 4. on failure, performs up to `maxRepairs` repair round-trips, feeding the * validation error back to the model. * * See structured.test.ts for the recovery-rate fixture suite that pins the * single-shot + one-repair reliability target. */ import type { LLMClient, JsonSchemaObject } from "./types.js"; /** Raised by {@link coerceJson} when no JSON value can be extracted from text. */ export declare class JsonCoercionError extends Error { /** The raw model text that could not be coerced. */ readonly raw: string; constructor(message: string, /** The raw model text that could not be coerced. */ raw: string); } /** Raised by {@link runStructuredAgent} when every attempt fails validation. */ export declare class StructuredOutputError extends Error { /** The last raw model text seen. */ readonly raw: string; /** Total chat calls made before giving up. */ readonly attempts: number; constructor(message: string, /** The last raw model text seen. */ raw: string, /** Total chat calls made before giving up. */ attempts: number); } export type ValidationResult = { ok: true; value: T; } | { ok: false; error: string; }; /** Validates and narrows a coerced JSON value to `T`. */ export type Validator = (raw: unknown) => ValidationResult; /** * Structural shape of a Zod schema's `safeParse`. Declared here (instead of * importing `zod`) so this module stays dependency-pure and accepts any * validator exposing the same surface. */ export interface SafeParseable { safeParse(data: unknown): { success: true; data: T; } | { success: false; error: { issues: ReadonlyArray<{ path: ReadonlyArray; message: string; }>; }; }; } /** * Build a {@link Validator} from a Zod schema (or anything exposing * `safeParse`). Flattens issues into one human-readable string the model can * act on during a repair round-trip. */ export declare function zodValidator(schema: SafeParseable): Validator; /** * Extract a JSON value from a model's raw text response. * * Handles the common local-model failure modes, in order: * 1. direct `JSON.parse` (well-behaved providers / strict json mode); * 2. strip a leading/trailing markdown code fence, then parse; * 3. extract the substring spanning the first `{`/`[` to the matching last * `}`/`]` (drops surrounding prose), then parse. * * @throws {JsonCoercionError} if nothing parses. */ export declare function coerceJson(text: string): unknown; export interface RunStructuredAgentOptions { /** Provider-agnostic LLM client (any adapter from the provider factory). */ client: LLMClient; /** Model ID (resolved via the factory / model-resolver). */ model: string; /** Base system prompt. The schema instruction is appended automatically. */ system: string; /** The task / user message. */ prompt: string; /** Provider-facing JSON Schema (also injected into the system prompt). */ schema: JsonSchemaObject; /** Validates + narrows the coerced JSON. Typically `zodValidator(SomeSchema)`. */ validate: Validator; /** Max repair round-trips after the first attempt. Default 1. */ maxRepairs?: number; /** Per-call max tokens. */ maxTokens?: number; } export interface StructuredAgentResult { /** The validated, typed value. */ value: T; /** Total chat calls made (1 = first-try success). */ attempts: number; /** True if any repair round-trip was needed. */ repaired: boolean; /** Cumulative token usage across all attempts. */ usage: { inputTokens: number; outputTokens: number; }; } /** * Run a single-shot structured-output call with coercion, validation, and * bounded repair. Returns a validated, typed value. * * The returned `ChatResponse.text` is parsed via {@link coerceJson} and checked * with `validate`. If either fails and repairs remain, the bad output and the * error are fed back as a follow-up turn. * * @throws {StructuredOutputError} if no attempt produces a schema-valid value. */ export declare function runStructuredAgent(opts: RunStructuredAgentOptions): Promise>; //# sourceMappingURL=structured.d.ts.map