/** * Structured output repair module — reusable, runtime-agnostic schema repair loop. * * When an LLM returns valid JSON that fails TypeBox schema validation, this module * generates a bounded repair prompt containing the previous output and specific * validation errors, then calls the LLM again for a corrected response. * * Design principles: * - Generic over T — no Diagnostician-specific knowledge * - Callback-based — schemaCheck and llmCaller are injected, no pi-ai imports * - Bounded — all prompts and error summaries are size-limited * - Fail-closed — if repair output still fails schemaCheck, return repaired=false * - Lineage-safe — repair must not silently override lineage fields (PRI-200) * * PRI-71: First integration target is Diagnostician via PiAiRuntimeAdapter. * PRI-200: Evidence pack, schemaRef in prompt, lineage protection, repairAttempts[]. * Future peer runners (Dreamer, Philosopher, etc.) can reuse the same module. */ import type { OutputRepairAttempt } from './output-repair-contract.js'; /** A single TypeBox validation error from Value.Errors(). */ export interface SchemaValidationError { readonly path: string; readonly message: string; readonly value: unknown; } /** Configuration for the repair loop. */ export interface RepairConfig { /** Maximum repair attempts. Default: 3. */ readonly maxRepairAttempts?: number; /** Maximum number of errors to include in repair prompt. Default: 10. */ readonly maxErrorsInPrompt?: number; /** Maximum characters per error description. Default: 200. */ readonly maxErrorChars?: number; /** Maximum characters of raw JSON to include in prompt. Default: 2000. */ readonly maxRawOutputChars?: number; /** Schema reference for the output being repaired (PRI-200). Included in repair prompt. */ readonly schemaRef?: string; /** Original output with lineage fields to preserve during repair (PRI-200). */ readonly originalOutput?: Record; /** Human-readable schema summary to include in repair prompt (PRI-271 A2). */ readonly schemaSummary?: string; /** * Complete JSON Schema (serialized) to include in the repair prompt * (PRI-621 RC2). Preferred over schemaSummary when present: the summary * only lists top-level field names, which left the repair LLM guessing * nested enums/constraints and failing all attempts. */ readonly schemaJson?: string; /** Maximum characters of the serialized schema. Default: 8000. */ readonly maxSchemaJsonChars?: number; /** * Required top-level keys of the schema (PRI-621 RC3) — used to select the * intended object out of multi-object repair responses. Optional fallback: * when absent, keys are parsed defensively from schemaJson. */ readonly requiredKeys?: readonly string[]; /** * PRI-707: present when provider finish metadata proves the previous output * was cut by the token limit (finish_reason=length). The repair prompt then * says so — a truncated fragment must be shortened/completed structurally, * not "corrected" field by field as if the model had misunderstood the * schema. Absent when there is no truncation evidence (conservative). */ readonly truncationNotice?: string; /** Internal override for jitter between repair attempts (PRI-271 A3). Set to 0 to disable. */ readonly _testJitterMs?: number; } /** Sensible defaults for repair configuration. */ export declare const DEFAULT_REPAIR_CONFIG: Required>; /** Result of a repair attempt. */ export interface RepairResult { /** Whether repair succeeded and output passes schema validation. */ readonly repaired: boolean; /** The repaired and validated output (set when repaired=true). */ readonly output: T | null; /** Number of repair attempts made. */ readonly attemptsUsed: number; /** Bounded summary of what was tried (for telemetry). */ readonly repairSummary: string; /** Detailed repair attempt records for evidence pack (PRI-200). */ readonly repairAttempts: readonly OutputRepairAttempt[]; } /** Callback for invoking an LLM during repair. Runtime-agnostic. */ export type RepairLLMCaller = (prompt: string) => Promise; /** Callbacks injected into the repair loop. */ export interface RepairCallbacks { readonly llmCaller: RepairLLMCaller; readonly schemaCheck: (value: unknown) => boolean; /** Optional: re-validate schema errors on repaired output for evidence pack. */ readonly schemaErrors?: (value: unknown) => SchemaValidationError[]; } export { extractJsonObject } from './json-extractor.js'; import type { TSchema } from '@sinclair/typebox'; /** * Derive a human-readable schema summary from a TypeBox schema (PRI-271 A2). * * Produces a compact text description of field names, types, required status, * and enum values — suitable for inclusion in repair prompts so the LLM knows * the target schema structure without needing the full JSON Schema. */ export declare function deriveSchemaSummary(schema: TSchema): string; /** * Format TypeBox schema errors into a bounded, human-readable repair prompt. * * PRI-200: Includes schemaRef when available. */ export declare function formatRepairPrompt(invalidJson: unknown, errors: readonly SchemaValidationError[], config?: RepairConfig): string; /** * Attempt to repair structurally invalid LLM output by re-prompting * the LLM with specific validation errors. * * Returns RepairResult — either repaired+validated output or null. * Bounded by maxRepairAttempts (default 3). * * PRI-200: Returns repairAttempts[] for evidence pack, protects lineage fields. */ export declare function attemptStructuredOutputRepair(invalidOutput: unknown, schemaErrors: readonly SchemaValidationError[], callbacks: RepairCallbacks, config?: RepairConfig): Promise>; //# sourceMappingURL=structured-output-repair.d.ts.map