/**
 * outputSchema — declarative terminal contract for an Agent's final answer.
 *
 * The Block A6 piece. Lets a consumer say:
 *
 *   "Whatever this agent says at the end of a run, it MUST be JSON
 *    matching this Zod (or Zod-like) schema. Auto-instruct the LLM,
 *    parse + validate the final answer for me."
 *
 * Why a typed contract matters: agentic code that calls an LLM and
 * then JSON.parses the string answer is brittle. The schema serves
 * three jobs at once:
 *
 *   1. **Instruction**: a system-prompt sentence telling the LLM the
 *      output shape (auto-generated from `schema.description` /
 *      JSON-schema introspection where available, or from a consumer-
 *      supplied `instruction` override).
 *
 *   2. **Validation**: a `parser.parse(rawString)` step on the run's
 *      final answer, throwing `OutputSchemaError` on parse / shape
 *      failure rather than returning malformed data.
 *
 *   3. **Type narrowing**: `agent.runTyped({...})` returns the inferred
 *      shape `T` instead of `string`, so callers stop reaching for
 *      `as MyType` casts.
 *
 * Pattern: Strategy (GoF) over the parser interface; structural
 *          duck-typing (Zod / Valibot / ArkType / hand-written —
 *          anything with a `parse(unknown): T` method satisfies it).
 *
 * Role:    Layer-6 (Agent) — terminal contract on the run output.
 *          NOT a context-engineering Injection per se, but composes
 *          with the InjectionEngine (auto-injects an Instruction).
 *
 * @example  zod schema
 *   import { z } from 'zod';
 *   const Output = z.object({ status: z.enum(['ok', 'err']), items: z.array(z.string()) });
 *
 *   const agent = Agent.create({ ... })
 *     .system('You answer support tickets.')
 *     .outputSchema(Output)
 *     .build();
 *
 *   const typed = await agent.runTyped({ message: 'list pending tickets' });
 *   typed.status; // narrowed to 'ok' | 'err'
 *
 * @example  valibot / arktype / hand-written parser
 *   const Output = { parse(v: unknown): MyType { ... } };
 *   const agent = Agent.create({...}).outputSchema(Output, { instruction: '...' }).build();
 */
/**
 * Minimum shape any validation library must expose to satisfy
 * `outputSchema`. Covers Zod (`schema.parse`), Valibot
 * (`v.parse(schema, value)` — pass `{ parse: v => v.parse(schema, v) }`),
 * ArkType (`type.assert`), and hand-written parsers.
 *
 * Implementations MUST throw on validation failure (the runtime
 * catches the throw, wraps it in `OutputSchemaError`, and emits the
 * diagnostic event).
 */
export interface OutputSchemaParser<T> {
    parse(value: unknown): T;
    /**
     * Human-readable description of the output shape. Used by
     * `outputSchema` to auto-build the system-prompt instruction when
     * `opts.instruction` is not provided. Zod schemas expose this via
     * `.describe('...')`; consumers can attach the field directly on
     * hand-written parsers.
     */
    readonly description?: string;
}
/**
 * How the schema reaches the model.
 *
 *   • `'auto'` (default) — use native structured output when the effective
 *     provider positively declares that known model supports it and an explicit
 *     or parser-derived JSON Schema
 *     can be lowered safely. Otherwise use instruction plus local validation.
 *     Selection is repeated for configured models and reliability fallbacks;
 *     `answerGuarantee` records the strategy actually used. No extra retry is
 *     introduced. An unavailable schema or known native-schema refusal falls
 *     back; unexpected wire-lowering errors still throw. Unknown/opaque model
 *     names stay on instructions. Set `'instruct'` to retain the previous
 *     generation strategy explicitly. API errors never trigger a downgrade.
 *   • `'instruct'` — the shape is described in the system prompt
 *     and the model is asked for JSON. Works on every provider, because it
 *     is only words.
 *   • `'tool-forced'` — the shape is presented as a synthetic tool and the
 *     provider's tool choice is FORCED to it, so generation is constrained
 *     at the source instead of requested in prose. Requires a provider that
 *     declares `carriesForcedToolChoice` and permits the selected model
 *     through its optional `supportsForcedToolChoice`; a provider that does not is
 *     refused BY NAME at run start rather than quietly downgraded, because
 *     a strategy that silently falls back to the other one is config that
 *     lies.
 *   • `'native'` — the provider's own structured output: the schema rides the
 *     request as Anthropic's `output_config.format` (`{ type: 'json_schema',
 *     schema }`) and the model's text answer is decoded under it. Unlike
 *     `'tool-forced'` it keeps the agent's tools: the model may still call a
 *     tool first, and answers in JSON when it answers. Requires a provider
 *     that declares `carriesNativeOutputSchema` and permits the selected model
 *     through its optional `supportsNativeOutputSchema`; the same refusal BY
 *     NAME applies at run start. The schema sent is a wire copy made
 *     API-compatible by `nativeOutputFormat.ts · nativeOutputFormat` (every
 *     object closed with `additionalProperties: false`, the constraints the
 *     API does not take moved into the description); a schema the API cannot
 *     express is refused at build. The parser still judges every answer
 *     against the full contract, and a `stop_reason` of `'refusal'`,
 *     `'max_tokens'` or `'model_context_window_exceeded'` fails the attempt by
 *     name even when the text parses (a refusal is not re-asked).
 */
export type OutputSchemaStrategy = 'auto' | 'instruct' | 'tool-forced' | 'native';
/**
 * Optional configuration for `outputSchema`.
 */
export interface OutputSchemaOptions {
    /**
     * Injection id for the auto-generated "respond with this shape"
     * instruction. Defaults to `'output-schema'`. Override when you
     * have multiple agents with different schemas in one process and
     * want the diagnostic events to disambiguate.
     */
    readonly name?: string;
    /**
     * Custom system-prompt instruction text. Defaults to a generic
     * "Respond with valid JSON matching the output schema. Do not
     * include prose." sentence (extended with `parser.description`
     * when present). Override when the LLM benefits from a
     * domain-specific framing.
     */
    readonly instruction?: string;
    /**
     * How many corrective re-asks the run may spend when the final answer
     * fails the schema. Default `0` — the historical behaviour, where the
     * first answer is the only answer and `runTyped()` throws on a bad one.
     *
     * Each retry is a REAL turn: the failed answer and an authored corrective
     * message join the conversation, the ReAct loop re-enters, and the next
     * attempt gets its own `llm_start`/`llm_end` bracket and its own
     * `cost.tick` against `costBudget`. A retry therefore consumes one
     * iteration of the agent's budget, the same way a tool call does.
     *
     * When the cap is spent the last answer stands and `runTyped()` throws
     * `OutputSchemaError` exactly as it always has — `.outputFallback()`
     * composes on top, unchanged.
     */
    readonly retries?: number;
    /**
     * How the schema reaches the model. Default `'auto'`.
     * See {@link OutputSchemaStrategy}.
     */
    readonly strategy?: OutputSchemaStrategy;
    /**
     * The JSON Schema for the synthetic tool (`strategy: 'tool-forced'`) or
     * for the provider's structured output (`strategy: 'native'` or `'auto'`).
     * Required by explicit native and tool-forced unless the parser can produce
     * one itself (a `toJsonSchema()` method, which ArkType has). The library will not
     * infer a shape from a `parse()` function — guessing what your schema
     * means is not a thing it gets to do. Under `'auto'`, absence keeps instruction
     * plus local validation without a native guarantee.
     *
     * @example  `'native'` on Anthropic
     *   .outputSchema(Verdict, {
     *     strategy: 'native',
     *     retries: 1,
     *     jsonSchema: {
     *       type: 'object',
     *       properties: { status: { type: 'string', enum: ['ok', 'err'] } },
     *       required: ['status'],
     *     },
     *   })
     *
     * This value and the parser CAN disagree. Nothing here prevents that,
     * and nothing needs to: the forced shape satisfies the wire, the parser
     * still judges the answer, and a disagreement surfaces as an ordinary
     * validation failure that the retry loop corrects using the validator's
     * own words. The schema constrains generation; the parser remains the
     * judge.
     */
    readonly jsonSchema?: Readonly<Record<string, unknown>>;
}
/**
 * Thrown by `agent.parseOutput(...)` / `agent.runTyped(...)` when the
 * agent's final answer fails JSON parsing OR schema validation.
 *
 * `cause` carries the underlying parse error (Zod's ZodError, etc.).
 * `rawOutput` carries the agent's untyped string output so callers
 * can log / persist the failed response for triage.
 */
export declare class OutputSchemaError extends Error {
    readonly rawOutput: string;
    readonly stage: 'json-parse' | 'schema-validate';
    readonly cause?: unknown;
    constructor(message: string, opts: {
        rawOutput: string;
        stage: 'json-parse' | 'schema-validate';
        cause?: unknown;
    });
}
/**
 * Default instruction template — used when `opts.instruction` is not
 * provided. Concatenates the parser's `.description` (if present) so
 * Zod schemas authored with `.describe('...')` propagate naturally.
 */
export declare function buildDefaultInstruction(parser: OutputSchemaParser<unknown>): string;
/**
 * Parse + validate a raw string answer against a parser. Used by
 * `agent.parseOutput()` / `agent.runTyped()`. Centralized here so
 * both call sites share identical error-mapping behavior.
 *
 * Two-stage error reporting:
 *   - JSON parse failure → `stage: 'json-parse'` (LLM emitted prose
 *     or malformed JSON)
 *   - Schema validation failure → `stage: 'schema-validate'` (JSON
 *     was valid but didn't match the contracted shape)
 */
export declare function applyOutputSchema<T>(raw: string, parser: OutputSchemaParser<T>): T;
//# sourceMappingURL=outputSchema.d.ts.map