/**
 * Shared utilities for JSON Schema providers (OpenAI, Anthropic, Gemini).
 *
 * Contains constants, types, convert output pipeline, definition pooling,
 * and schema inspection helpers used identically across providers.
 */
import type { JTDSchemaJson, SignalDescriptorJson, SignalFormatJson } from './api';
export declare const MAX_REF_DEPTH = 32;
export declare const INTEGER_BOUNDS: Record<string, {
    minimum: number;
    maximum: number;
}>;
export declare const FLOAT32_BOUNDS: {
    minimum: number;
    maximum: number;
};
export declare const UNSTRUCTURED_DESC: string;
export declare const UNSTRUCTURED_VARIANT_DESC: string;
export declare const VALUES_ARRAY_DESC: string;
export declare function nullableType(baseType: string, nullable: boolean): string | string[];
export declare function deepEqual(a: unknown, b: unknown): boolean;
export declare function isUnstructuredSchema(schema: JTDSchemaJson): boolean;
export declare function isRootUnstructured(schema: JTDSchemaJson, defs: Record<string, JTDSchemaJson> | undefined): boolean;
/**
 * Walk one or more JTD root schemas and return the set of definition names
 * that are transitively reachable via `ref`.  Definitions not in this set
 * are unreferenced and should be pruned from `$defs`.
 */
export declare function findReferencedJTDDefs(roots: JTDSchemaJson[], defs: Record<string, JTDSchemaJson>): Set<string>;
export interface ConvertSuccessJson {
    success: true;
    kind: 'json';
    data: unknown;
}
export interface ConvertSuccessBinary {
    success: true;
    kind: 'binary';
    mimeType: string;
    data: Uint8Array;
    filename?: string;
}
export interface ConvertSuccessSignals {
    success: true;
    kind: 'signals';
    signals: Record<string, unknown>;
}
export interface ConvertFailure {
    success: false;
    errors: string[];
}
export type ConvertSuccess = ConvertSuccessJson | ConvertSuccessBinary | ConvertSuccessSignals;
export type ConvertResult = ConvertSuccess | ConvertFailure;
export declare function convertJTDOutput(jtdSchema: JTDSchemaJson, json: unknown, coerce: (value: unknown, schema: JTDSchemaJson, defs: Record<string, JTDSchemaJson> | undefined, depth: number) => unknown): ConvertResult;
/**
 * Wrap a signal's value schema in a discriminated anyOf with two variants:
 * - `{ kind: "value", data: <valueSchema> }` — inline data
 * - `{ kind: "reference", ref: <string> }` — file reference
 *
 * The caller resolves references before calling convert.
 *
 * Returns a plain object — cast to the provider's schema type at the call site.
 *
 * @param valueSchema - The signal's original schema (JTD, MIME, or multi-format anyOf).
 * @param description - Optional signal description to include.
 * @param strict - When false, omits `additionalProperties` (required by GeminiFC).
 */
export declare function buildReferenceAnyOf(valueSchema: unknown, description?: string, strict?: boolean): {
    anyOf: unknown[];
};
/**
 * Check if a concrete MIME type matches an accepted MIME pattern.
 *
 * - `*​/*` matches everything
 * - `image/*` matches any `image/...` subtype
 * - Exact string match otherwise
 */
export declare function mimeTypeMatches(concrete: string, accepted: string): boolean;
/**
 * Convert a MIME-format signal value to dispatch-ready binary SignalData.
 *
 * Accepts two data shapes:
 * - **Inline (from LLM):** `{ data: "<base64>", mimeType: "image/png", filename?: "..." }`
 * - **Resolved (from file reference):** `{ data: Uint8Array, mimeType: "image/png", filename?: "..." }`
 *
 * The input's `mimeType` field is the concrete type and ends up in the result.
 * It is validated against the format's accepted pattern (which may be a wildcard).
 *
 * @param acceptedMimeType - MIME pattern from the signal format declaration.
 * @param value - The signal value to convert.
 */
export declare function convertMimeOutput(acceptedMimeType: string, value: unknown): ConvertResult;
/**
 * Convert a single format's value. Dispatches to JTD or MIME conversion.
 *
 * @param fmt - The signal format (has either `jtdSchema` or `mimeType`).
 * @param value - The signal value. JSON for JTD formats, or `{ data, mimeType, filename }` for MIME.
 * @param coerce - Provider-specific JTD coercion function.
 */
export declare function convertSingleFormatOutput(fmt: SignalFormatJson, value: unknown, coerce: (value: unknown, schema: JTDSchemaJson, defs: Record<string, JTDSchemaJson> | undefined, depth: number) => unknown): ConvertResult;
/**
 * Convert a signal's value against its declared formats.
 *
 * The value is already resolved — this function knows nothing about file
 * references. When `referenceMode` is used, the **caller** handles the
 * `kind` discriminator:
 *
 * - `{ kind: "value", data: <inline> }` → caller extracts `data`, passes here
 * - `{ kind: "reference", ref: "..." }` → caller resolves the ref, passes:
 *   - Parsed JSON object (for JTD formats)
 *   - `{ data: Uint8Array, mimeType, filename }` (for MIME formats)
 *
 * For **single-format** signals, the value is validated directly.
 * For **multi-format** signals, each format is tried in order (anyOf — first match wins).
 *
 * @param descriptor - The signal descriptor with one or more formats.
 * @param value - The resolved signal value (JSON for JTD, or `{ data, mimeType, filename }` for MIME).
 * @param coerce - Provider-specific JTD coercion function.
 */
export declare function convertSignalOutput(descriptor: SignalDescriptorJson, value: unknown, coerce: (value: unknown, schema: JTDSchemaJson, defs: Record<string, JTDSchemaJson> | undefined, depth: number) => unknown): ConvertResult;
/**
 * Convert multiple signals from a compound output.
 *
 * Expects `input` to be an object keyed by signal name. Each signal's
 * value is passed to {@link convertSignalOutput} — it can be JSON (for
 * JTD formats) or `{ data, mimeType, filename }` (for MIME formats).
 *
 * When using `referenceMode`, the **caller** must unwrap the `kind`
 * discriminator for each signal before calling this function.
 * See {@link convertSignalOutput} for the full reference-mode contract.
 */
export declare function convertSignalsOutput(descriptors: SignalDescriptorJson[], input: unknown, coerce: (value: unknown, schema: JTDSchemaJson, defs: Record<string, JTDSchemaJson> | undefined, depth: number) => unknown): ConvertResult;
/** Minimal shape for $ref-bearing schemas (satisfied by OpenAISchema and AnthropicSchema). */
interface RefNode {
    properties?: Record<string, RefNode>;
    items?: RefNode;
    anyOf?: RefNode[];
    $defs?: Record<string, RefNode>;
    $ref?: string;
}
export declare function walkSchema<T extends RefNode>(schema: T, fn: (node: T) => void): void;
/**
 * Pre-scan all signal descriptors, pool their JTD definitions.
 * Deduplicates identical definition SETS; renames conflicts with `_N` suffix.
 *
 * Equivalence is checked per-format: all definitions within a single format's
 * `definitions` block are treated as a unit. Two formats with the same set of
 * definition names and identical schemas (deep-equal) share their defs.
 * If ANY definition name conflicts (same name, different schema), ALL defs
 * from that format get their own namespace to preserve internal cross-references.
 *
 * Returns the merged JTD definitions and signal copies with:
 * - refs rewritten to match merged names
 * - definitions stripped (they live in the merged pool now)
 */
export declare function poolSignalDefinitions(signals: SignalDescriptorJson[]): {
    mergedDefs: Record<string, JTDSchemaJson>;
    signalsCopy: SignalDescriptorJson[];
};
/**
 * Build a human-readable description of a JTD definition for use as a
 * fallback at recursive ref break points. Used by both Anthropic and Gemini
 * converters when a cycle is detected.
 */
export declare function describeDefinitionForCycle(defName: string, def: JTDSchemaJson): string;
export {};
//# sourceMappingURL=schema-utils.d.ts.map