import { type Schema as JTDSchemaJson } from '../jtd/index.js'; import type { SignalDescriptorJson } from '../proto/index.js'; import { type ConvertFailure, type ConvertSuccess, type ConvertSuccessBinary, type ConvertSuccessJson, type ConvertSuccessSignals } from '../schema-utils.js'; /** * JSON Schema subset accepted by the Gemini structured-output API. * * This is the provider-specific representation produced by {@link GeminiConversion}. * It covers the keywords that Gemini 3+ actually inspects when constraining * model output: `type`, `properties`, `required`, `enum`, `items`, * `additionalProperties`, `format`, `minimum`/`maximum`, `title`, and * `description`. */ export interface GeminiSchema { type?: string | string[]; nullable?: boolean; title?: string; description?: string; properties?: Record; required?: string[]; additionalProperties?: boolean | GeminiSchema; enum?: (string | number | null)[]; format?: string; items?: GeminiSchema; minimum?: number; maximum?: number; minItems?: number; maxItems?: number; anyOf?: GeminiSchema[]; } /** * Schema subset matching the Gemini v1beta Schema protobuf message. * Used for function calling `parameters` field in `FunctionDeclaration`. * * Key differences from {@link GeminiSchema}: * - `type` is always a single string (no type arrays) * - Uses `nullable: true` instead of `["type", "null"]` type arrays * - Does NOT include `additionalProperties` * - Supports `anyOf` for discriminator unions * - Supports `minItems`/`maxItems` for array bounds */ export interface GeminiFCSchema { type?: string; nullable?: boolean; title?: string; description?: string; properties?: Record; required?: string[]; enum?: string[]; format?: string; items?: GeminiFCSchema; minimum?: number; maximum?: number; minItems?: number; maxItems?: number; anyOf?: GeminiFCSchema[]; } export type { ConvertFailure, ConvertResult, ConvertSuccess, ConvertSuccessBinary, ConvertSuccessJson, ConvertSuccessSignals } from '../schema-utils.js'; /** * Converts JTD schemas or Adapt signal descriptors into Gemini-compatible * JSON Schema, and converts raw LLM output back into validated data. * * ### JTD form mapping * - **type** -- mapped to the corresponding JSON Schema `type` (`string`, * `number`, `integer`, `boolean`). Integer sub-types (int8 .. uint32) add * `minimum`/`maximum` bounds. `timestamp` becomes `string` with * `format: "date-time"`. * - **enum** -- mapped to `type: "string"` with an `enum` array. * - **elements** -- mapped to `type: "array"` with `items`. * - **properties / optionalProperties** -- mapped to `type: "object"` with * `properties`, `required`, and `additionalProperties: false`. Optional * properties are included but not listed in `required`. * - **values** -- mapped to `type: "object"` with `additionalProperties` set * to the value schema (Gemini supports free-form object keys natively). * - **discriminator** -- mapped to `anyOf` with a flat tagged object per variant. * - **ref** -- inlined; recursive subtrees use JSON strings, decoded and validated * against the original JTD by `convert()` to avoid Gemini recursion limits. * * ### MIME formats * MIME signal formats become `type: "string"` with a description requesting * base64-encoded content. On {@link convert}, the base64 string is decoded * into a {@link ConvertSuccessBinary} result. * * ### Serialization * `JSON.stringify(conv)` produces a JSON-safe object via {@link toJSON}. * Use {@link fromJSON} to restore a fully functional instance from the * serialized form (string or parsed object). * * ```ts * const conv = GeminiStructuredOutputConversion.fromJTD(jtdSchema); * conv.schema; // Gemini JSON Schema to pass to the LLM * conv.convert(output); // coerce + validate -> ConvertResult * * // Serialize & restore * const cached = JSON.stringify(conv); * const restored = GeminiStructuredOutputConversion.fromJSON(cached); * ``` */ export declare class GeminiStructuredOutputConversion { /** The Gemini-specific JSON Schema to pass to the Gemini API as the response schema. */ readonly schema: GeminiSchema; /** * The original JTD schema used to build this conversion. * Set when created via {@link fromJTD}; `undefined` when created via {@link fromSignal}. */ readonly jtdSchema?: JTDSchemaJson; /** * The original signal descriptor used to build this conversion. * Set when created via {@link fromSignal}; `undefined` when created via {@link fromJTD}. */ readonly descriptor?: SignalDescriptorJson; /** * The original signal descriptors used to build this conversion. * Set when created via {@link fromSignals}; `undefined` otherwise. */ readonly descriptors?: SignalDescriptorJson[]; /** When true, MIME signals use file-reference schemas instead of base64. */ readonly referenceMode: boolean; /** * Build a conversion from a JTD schema. * * Recursively converts every JTD form into the equivalent Gemini JSON Schema * node. Shared definitions are inlined. Recursive subtrees use JSON strings * because Gemini truncates required recursive references. * * @param jtdSchema - A valid JTD schema (RFC 8927). * @returns A new {@link GeminiStructuredOutputConversion} with `jtdSchema` set. * @throws If the schema contains an unknown JTD type, an unresolved `ref`, * or circular / excessively deep refs (exceeding 32 levels). */ static fromJTD(input: unknown): GeminiStructuredOutputConversion; /** * Build a conversion from an Adapt signal descriptor. * * If the descriptor has a single format, its schema is used directly * (unwrapped). If it has multiple formats, a wrapper object schema is * produced with `format_0`, `format_1`, ... properties -- the LLM must * populate exactly one. MIME formats become base64 string schemas. * * @param descriptor - An Adapt signal descriptor with one or more formats. * @returns A new {@link GeminiStructuredOutputConversion} with `descriptor` set. * @throws If the descriptor has no formats, or a format has neither * `jtdSchema` nor `mimeType`. */ static fromSignal(descriptor: SignalDescriptorJson, referenceMode?: boolean): GeminiStructuredOutputConversion; /** * Build a conversion from multiple signal descriptors. * * Produces an object schema with one property per signal, suitable for * use as structured output parameters. Each signal's schema is built via * {@link fromSignal} internally. * * Optional signals are omitted from `required` (Gemini does not use the * required+nullable pattern). * * Receiver/transceiver compatible: * ```ts * const conv = GeminiStructuredOutputConversion.fromSignals( * receiver.signals!, * receiver.description, * receiver.name * ); * ``` * * @param signals - Array of signal descriptors. * @param description - Optional description for the compound schema. * @param label - Optional label (mapped to `title` on the schema). * @returns A new {@link GeminiStructuredOutputConversion} with `descriptors` set. * @throws If any signal has no formats or an invalid format. */ static fromSignals(signals: SignalDescriptorJson[], description?: string, label?: string, referenceMode?: boolean): GeminiStructuredOutputConversion; /** * Restore a {@link GeminiStructuredOutputConversion} from its serialized form. * * Accepts either the JSON string produced by `JSON.stringify(conv)` or the * already-parsed plain object. The original `jtdSchema` or `descriptor` is * re-processed through the corresponding factory, so the restored instance * is fully functional. * * @param data - A JSON string or parsed object previously produced by {@link toJSON}. * @returns A fully reconstructed {@link GeminiStructuredOutputConversion}. * @throws If the serialized data contains neither `jtdSchema` nor `descriptor`. */ static fromJSON(data: string | Record): GeminiStructuredOutputConversion; private constructor(); /** * Convert raw LLM output into a validated result. * * For JTD-based conversions, the value is coerced (e.g. non-integer numbers * are rounded for integer types, discriminator wrapper objects are unwrapped * into flat tagged unions), then validated against the original JTD schema. * Returns {@link ConvertSuccessJson} on success. * * For MIME-based conversions, the value is expected to be a base64 string * which is decoded into raw bytes. Returns {@link ConvertSuccessBinary} on * success. * * For multi-format signals, the first non-null `format_N` property is * selected and converted individually. * * @param value - The value to convert. JSON for JTD, or `{ data, mimeType, filename }` for MIME. * @returns A {@link ConvertResult} indicating success or failure with errors. */ convert: (value: unknown) => T | ConvertFailure; /** * Produce a JSON-serializable representation of this conversion. * * The output includes the Gemini `schema` and either the original * `jtdSchema` or `descriptor` (whichever was used to create this instance), * which is sufficient to fully restore the conversion via {@link fromJSON}. * * Called automatically by `JSON.stringify(conv)`. */ toJSON(): Record; } /** * Converts JTD schemas or Adapt signal descriptors into Gemini v1beta Schema * protobuf-compatible schemas for use with function calling `parameters`. * * ### Differences from {@link GeminiStructuredOutputConversion} * - Uses `nullable: true` instead of `["type", "null"]` type arrays * - Does NOT emit `additionalProperties` * - Uses `anyOf` for discriminator unions instead of wrapper objects * - Uses key-value array pattern for `values` form (maps/dictionaries) * - Unstructured/empty schemas are encoded as JSON strings * * ### JTD form mapping * - **type** -- mapped to the corresponding JSON Schema `type` with * `minimum`/`maximum` for integers, `format: "date-time"` for timestamps. * - **enum** -- mapped to `type: "string"` with an `enum` array. * - **elements** -- mapped to `type: "array"` with `items`. * - **properties / optionalProperties** -- mapped to `type: "object"` with * - **values** -- mapped to `type: "array"` with items of * `{key: string, value: ...}` objects (key-value array pattern). * - **discriminator** -- mapped to `anyOf` with single-value `enum` for the * discriminator tag on each variant. * - **empty / unstructured** -- mapped to `type: "string"` with a description * requesting JSON-encoded content. * * ### MIME formats * MIME signal formats become `type: "object"` with `data` and `filename` * properties (same as structured output). On {@link convert}, the base64 * string is decoded into a {@link ConvertSuccessBinary} result. * * ### Serialization * `JSON.stringify(conv)` produces a JSON-safe object via {@link toJSON}. * The serialized form includes `mode: 'fc'` to distinguish it from * {@link GeminiStructuredOutputConversion} during deserialization. * * ```ts * const conv = GeminiFunctionCallingConversion.fromJTD(jtdSchema); * conv.schema; // FC-compatible schema for FunctionDeclaration.parameters * conv.convert(output); // coerce + validate -> ConvertResult * * // Serialize & restore * const cached = JSON.stringify(conv); * const restored = GeminiFunctionCallingConversion.fromJSON(cached); * ``` */ export declare class GeminiFunctionCallingConversion { /** The FC-specific schema to pass as `parameters` in a `FunctionDeclaration`. */ readonly schema: GeminiFCSchema; /** * The original JTD schema used to build this conversion. * Set when created via {@link fromJTD}; `undefined` when created via {@link fromSignal}. */ readonly jtdSchema?: JTDSchemaJson; /** * The original signal descriptor used to build this conversion. * Set when created via {@link fromSignal}; `undefined` when created via {@link fromJTD}. */ readonly descriptor?: SignalDescriptorJson; /** * The original signal descriptors used to build this conversion. * Set when created via {@link fromSignals}; `undefined` otherwise. */ readonly descriptors?: SignalDescriptorJson[]; /** When true, MIME signals use file-reference schemas instead of base64. */ readonly referenceMode: boolean; /** * Build a conversion from a JTD schema. * * Recursively converts every JTD form into the equivalent Gemini FC schema * node. Definitions (`jtdSchema.definitions`) are resolved inline because * the FC protobuf schema does not support `$ref`. * * @param jtdSchema - A valid JTD schema (RFC 8927). * @returns A new {@link GeminiFunctionCallingConversion} with `jtdSchema` set. * @throws If the schema contains an unknown JTD type, an unresolved `ref`, * or circular / excessively deep refs (exceeding 32 levels). */ static fromJTD(input: unknown): GeminiFunctionCallingConversion; /** * Build a conversion from an Adapt signal descriptor. * * If the descriptor has a single format, its schema is used directly * (unwrapped). If it has multiple formats, a wrapper object schema is * produced with `format_0`, `format_1`, ... properties -- the LLM must * populate exactly one. MIME formats become base64 string schemas. * * @param descriptor - An Adapt signal descriptor with one or more formats. * @returns A new {@link GeminiFunctionCallingConversion} with `descriptor` set. * @throws If the descriptor has no formats, or a format has neither * `jtdSchema` nor `mimeType`. */ static fromSignal(descriptor: SignalDescriptorJson, referenceMode?: boolean): GeminiFunctionCallingConversion; /** * Build a conversion from multiple signal descriptors. * * Produces an object schema with one property per signal, suitable for * use as function calling parameters. Each signal's schema is built via * {@link fromSignal} internally. * * Optional signals are omitted from `required`. * * Receiver/transceiver compatible: * ```ts * const conv = GeminiFunctionCallingConversion.fromSignals( * receiver.signals!, * receiver.description, * receiver.name * ); * ``` * * @param signals - Array of signal descriptors. * @param description - Optional description for the compound schema. * @param label - Optional label (mapped to `title` on the schema). * @returns A new {@link GeminiFunctionCallingConversion} with `descriptors` set. * @throws If any signal has no formats or an invalid format. */ static fromSignals(signals: SignalDescriptorJson[], description?: string, label?: string, referenceMode?: boolean): GeminiFunctionCallingConversion; /** * Restore a {@link GeminiFunctionCallingConversion} from its serialized form. * * Accepts either the JSON string produced by `JSON.stringify(conv)` or the * already-parsed plain object. The original `jtdSchema` or `descriptor` is * re-processed through the corresponding factory, so the restored instance * is fully functional. * * @param data - A JSON string or parsed object previously produced by {@link toJSON}. * @returns A fully reconstructed {@link GeminiFunctionCallingConversion}. * @throws If the serialized data contains neither `jtdSchema` nor `descriptor`, * or if `mode` is not `'fc'`. */ static fromJSON(data: string | Record): GeminiFunctionCallingConversion; private constructor(); /** * Convert raw LLM output into a validated result. * * For JTD-based conversions, the value is coerced to conform to the original * JTD schema: * - Non-integer numbers are rounded for integer types. * - `{key, value}` arrays from the values form are reassembled into Records. * - Unstructured/empty schemas parse the raw JSON string via `JSON.parse`. * - Discriminator variants are coerced from flat objects. * * The coerced value is then validated against the JTD schema. Returns * {@link ConvertSuccessJson} on success. * * For MIME-based conversions, the value is expected to be a base64 string * which is decoded into raw bytes. Returns {@link ConvertSuccessBinary} on * success. * * For multi-format signals, the first non-null `format_N` property is * selected and converted individually. * * @param value - The value to convert. JSON for JTD, or `{ data, mimeType, filename }` for MIME. * @returns A {@link ConvertResult} indicating success or failure with errors. */ convert: (value: unknown) => T | ConvertFailure; /** * Produce a JSON-serializable representation of this conversion. * * The output includes the FC `schema`, `mode: 'fc'`, and either the * original `jtdSchema` or `descriptor` (whichever was used to create this * instance), which is sufficient to fully restore the conversion via * {@link fromJSON}. * * Called automatically by `JSON.stringify(conv)`. */ toJSON(): Record; } /** @deprecated Use {@link GeminiStructuredOutputConversion} instead. */ export { GeminiStructuredOutputConversion as GeminiConversion }; /** * Convenience alias for {@link GeminiStructuredOutputConversion.fromJTD}. * * @param jtdSchema - A valid JTD schema (RFC 8927). * @returns A new {@link GeminiStructuredOutputConversion}. */ export declare function convertToGeminiSchema(jtdSchema: unknown): GeminiStructuredOutputConversion; /** * Convenience alias for {@link GeminiStructuredOutputConversion.fromSignal}. * * @param descriptor - An Adapt signal descriptor. * @returns A new {@link GeminiStructuredOutputConversion}. */ export declare function convertSignalToGeminiSchema(descriptor: SignalDescriptorJson): GeminiStructuredOutputConversion; /** * Convenience alias for {@link GeminiFunctionCallingConversion.fromJTD}. * * @param jtdSchema - A valid JTD schema (RFC 8927). * @returns A new {@link GeminiFunctionCallingConversion}. */ export declare function convertToGeminiFCSchema(jtdSchema: unknown): GeminiFunctionCallingConversion; //# sourceMappingURL=index.d.ts.map