/** * Metadata extracted from a field in a Zod schema */ interface FieldMetadata { name: string; description?: string; type: string; properties?: Record; items?: FieldMetadata; } /** * Schema metadata with structured field information */ export interface SchemaMetadata { fields: Record; description?: string; } /** * Converts a Zod schema to JSON Schema format * * Uses Zod 4's built-in z.toJSONSchema() for native conversion. * * @param zodSchema - The Zod schema to convert * @returns JSON Schema object */ export declare function convertZodToJsonSchema(zodSchema: any): any; /** * Converts a Zod schema to a draft 2020-12 JSON Schema — the dialect OpenAI's * structured outputs expect. * * Distinct from {@link convertZodToJsonSchema}, which targets OpenAPI 3.0 for * Gemini. The difference matters for strict mode: OpenAPI 3.0 expresses "may be * null" as `nullable: true`, which OpenAI ignores, whereas draft 2020-12 uses a * real `{ type: "null" }` branch — the form {@link makeSchemaStrictCompatible} * produces. * * @param zodSchema - The Zod schema to convert * @returns JSON Schema in draft 2020-12 */ export declare function convertZodToDraftJsonSchema(zodSchema: any): any; /** * Extracts structured metadata from a Zod schema * * This function: * 1. Converts Zod schema to JSON Schema * 2. Extracts field names, types, and descriptions * 3. Returns structured metadata for prompt injection * * The extracted metadata can be used to: * - Generate schema-guided instructions * - Create input context prompts * - Validate input parameters * * @param zodSchema - The Zod schema to extract metadata from * @returns Structured metadata with field information * * @example * ```typescript * const schema = z.object({ * name: z.string().describe("The user's name"), * age: z.number().describe("The user's age"), * }); * * const metadata = extractSchemaMetadata(schema); * // { * // fields: { * // name: { name: "name", description: "The user's name", type: "string" }, * // age: { name: "age", description: "The user's age", type: "number" } * // } * // } * ``` */ export declare function extractSchemaMetadata(zodSchema: any): SchemaMetadata; /** * Formats a single field value with its description for prompt injection * * Creates a natural-reading format that combines the field description * with its value, making it clear to the LLM what each input represents. * * @param fieldName - The name of the field * @param fieldValue - The value of the field * @param description - Optional description from the schema * @returns Formatted string for prompt injection * * @example Without description: * ```typescript * formatFieldWithDescription("name", "Alice") * // Returns: "name: Alice" * ``` * * @example With description: * ```typescript * formatFieldWithDescription( * "recentActions", * ["smiles", "waves"], * "FORBIDDEN actions - NEVER repeat these" * ) * // Returns: "recentActions (FORBIDDEN actions - NEVER repeat these): [...]" * ``` */ export declare function formatFieldWithDescription(fieldName: string, fieldValue: any, description?: string): string; /** * Removes JSON Schema properties not supported by Gemini API. * * Gemini uses a subset of OpenAPI 3.0 schema that doesn't support: * - $schema, $id, $defs, $ref, $comment * - allOf, anyOf, oneOf (need flattening) * * This function recursively sanitizes a JSON Schema to make it Gemini-compatible. * Use this when calling Gemini models through proxies like Requesty that don't * automatically sanitize schemas. * * @param schema - JSON Schema object (typically from zodToJsonSchema or convertZodToJsonSchema) * @returns Sanitized schema compatible with Gemini API * * @example * ```typescript * const jsonSchema = convertZodToJsonSchema(myZodSchema); * const geminiSchema = sanitizeSchemaForGemini(jsonSchema); * // geminiSchema has no $schema, $defs, etc. * ``` */ export declare function sanitizeSchemaForGemini(schema: any): any; /** * Reports whether a schema can be sent through OpenAI's STRICT structured-output * mode (`response_format: { type: "json_schema", strict: true }`). * * Strict mode has two rules that ordinary Zod schemas routinely break: * 1. every key in `properties` must also appear in `required` — strict mode * cannot express an absent field, only a null one, so `.optional()` and * `.default()` both violate it; * 2. `additionalProperties` must be `false` — so open records cannot qualify. * * This matters because LangChain hands any Zod schema to `interopZodResponseFormat`, * which hardcodes `strict: true`; passing `strict: false` does nothing. A schema * that fails these rules must therefore go through tool/function calling instead, * which imposes neither rule AND keeps LangChain's Zod validation of the result. * * Deciding from the schema — rather than from a model or provider name — means no * model taxonomy lives in this codebase, and any schema authored strict-clean later * automatically earns the stronger guaranteed-conformance path. * * @param schema - JSON Schema object (typically from {@link convertZodToJsonSchema}) * @returns true when strict mode would accept the schema */ export declare function isStrictStructuredOutputCompatible(schema: any): boolean; /** * Rewrites a JSON Schema so OpenAI's STRICT structured-output mode accepts it. * * Strict mode cannot express "this key may be absent" — only "this key may be * null". So every property becomes required, and any property that was NOT * originally required is widened to `anyOf: [, { type: "null" }]`. * `additionalProperties` is closed on every object. * * This is the request half of a pair: {@link stripSyntheticNulls} undoes it on the * response, so the caller's original Zod schema still validates the result. * * Why bother, rather than routing non-strict schemas to tool calling: strict mode * is the only path that GUARANTEES the payload matches the schema. Measured against * a live gpt-5-nano deployment, tool calling returned a string where the schema * declared `assumptions: string[]` in roughly half of all runs; strict mode cannot * do that by construction. * * @param schema - JSON Schema object (draft 2020-12 shape) * @returns A structurally equivalent schema that satisfies strict mode */ export declare function makeSchemaStrictCompatible(schema: any): any; /** * Removes the nulls that {@link makeSchemaStrictCompatible} forced the model to emit, * so a value produced under strict mode validates against the ORIGINAL schema again. * * Only keys the transform actually widened are stripped: a key the author declared * `.nullable()` was already required, so its null is meaningful and is preserved. * Stripping restores absence, which is what `.optional()` expects and what `.default()` * needs in order to apply its default. * * NOT HANDLED — four node kinds this walk never reaches, where an author-intended * null could be dropped (or a synthetic one kept). None occur in this repo today, and * each would need BOTH this function and {@link isStrictStructuredOutputCompatible}'s * traversal extended before it could be trusted: * * 1. `.nullable().optional()` — the key is absent from `required`, so its null is * read as synthetic and stripped, even though the author declared null to be a * legitimate value. (`.nullable()` alone is safe: it stays required.) * 2. Nulls inside `anyOf` / `oneOf` branches — the walk descends only through * `properties` and `items`, so a null-bearing union branch is never visited and * its object properties are compared against no schema at all. * 3. Nulls behind `$ref` / `$defs` — there is no ref resolution here, so a * referenced subschema contributes no `required` set and every null under it * survives, synthetic or not. * 4. Tuples / `prefixItems` — only the single `items` schema is followed, so a * positional tuple's element schemas are never applied. * * @param value - The parsed model output * @param originalSchema - The schema BEFORE strictification (the source of truth for * which keys were genuinely required) */ export declare function stripSyntheticNulls(value: any, originalSchema: any): any; export {}; //# sourceMappingURL=schema.utils.d.ts.map