import { type Schema as JTDSchemaJson } from './jtd/index.js'; /** * 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 { SignalDescriptorJson, SignalFormatJson } from './proto/index.js'; export declare const MAX_REF_DEPTH = 32; export declare const INTEGER_BOUNDS: Record; 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 | 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): Set; 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; } 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 | undefined, depth: number) => unknown): ConvertResult; /** * Wrap a signal's value schema in a discriminated anyOf with two variants: * - `{ _kind: "_value", _value: }` — inline data * - `{ _kind: "_ref", _ref: }` — file reference * * Field names are prefixed with `_` to avoid collisions with user-defined * signal properties (e.g. a signal named "data" or "kind"). * The `_kind` value matches its sibling field name for clarity. * * 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: "", 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 | 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", _value: }` → caller extracts `_value`, passes here * - `{ _kind: "_ref", _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 | 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 | undefined, depth: number) => unknown): ConvertResult; /** Minimal shape for $ref-bearing schemas (satisfied by OpenAISchema and AnthropicSchema). */ interface RefNode { properties?: Record; items?: RefNode; anyOf?: RefNode[]; $defs?: Record; $ref?: string; } export declare function walkSchema(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; 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