@jaypie/llm 1.2.24 → 1.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,6 +72,7 @@ export interface GeminiGenerateContentConfig {
72
72
  };
73
73
  responseMimeType?: string;
74
74
  responseJsonSchema?: JsonObject;
75
+ responseSchema?: JsonObject;
75
76
  temperature?: number;
76
77
  topP?: number;
77
78
  topK?: number;
@@ -2,6 +2,7 @@ export * from "./determineModelProvider.js";
2
2
  export * from "./extractReasoning.js";
3
3
  export * from "./formatOperateInput.js";
4
4
  export * from "./formatOperateMessage.js";
5
+ export * from "./jsonSchemaToOpenApi3.js";
5
6
  export * from "./logger.js";
6
7
  export * from "./maxTurnsFromOptions.js";
7
8
  export * from "./naturalZodSchema.js";
@@ -0,0 +1,10 @@
1
+ import { JsonObject } from "@jaypie/types";
2
+ /**
3
+ * Converts a JSON Schema (Draft 2020-12) object to the OpenAPI 3.0 schema subset
4
+ * that Gemini's `responseSchema` accepts. This constrains generation (not just validation)
5
+ * and avoids the `items`-keyword leakage bug in `responseJsonSchema`.
6
+ *
7
+ * Strips: $schema, additionalProperties, $defs, $ref (inlines where possible), const
8
+ * Preserves: type, properties, required, items, enum, description, nullable
9
+ */
10
+ export declare function jsonSchemaToOpenApi3(schema: JsonObject): JsonObject;
package/dist/esm/index.js CHANGED
@@ -552,6 +552,50 @@ function formatOperateInput(input, options) {
552
552
  return [input];
553
553
  }
554
554
 
555
+ /**
556
+ * Converts a JSON Schema (Draft 2020-12) object to the OpenAPI 3.0 schema subset
557
+ * that Gemini's `responseSchema` accepts. This constrains generation (not just validation)
558
+ * and avoids the `items`-keyword leakage bug in `responseJsonSchema`.
559
+ *
560
+ * Strips: $schema, additionalProperties, $defs, $ref (inlines where possible), const
561
+ * Preserves: type, properties, required, items, enum, description, nullable
562
+ */
563
+ function jsonSchemaToOpenApi3(schema) {
564
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
565
+ return schema;
566
+ }
567
+ const result = {};
568
+ for (const [key, value] of Object.entries(schema)) {
569
+ // Strip JSON Schema keywords not in OpenAPI 3.0 subset
570
+ if (key === "$schema" ||
571
+ key === "$defs" ||
572
+ key === "additionalProperties" ||
573
+ key === "const" ||
574
+ key === "$ref") {
575
+ continue;
576
+ }
577
+ if (key === "properties" &&
578
+ typeof value === "object" &&
579
+ value !== null &&
580
+ !Array.isArray(value)) {
581
+ const convertedProps = {};
582
+ for (const [propKey, propValue] of Object.entries(value)) {
583
+ convertedProps[propKey] = jsonSchemaToOpenApi3(propValue);
584
+ }
585
+ result[key] = convertedProps;
586
+ }
587
+ else if (key === "items" &&
588
+ typeof value === "object" &&
589
+ value !== null) {
590
+ result[key] = jsonSchemaToOpenApi3(value);
591
+ }
592
+ else {
593
+ result[key] = value;
594
+ }
595
+ }
596
+ return result;
597
+ }
598
+
555
599
  const getLogger$5 = () => log$1.lib({ lib: JAYPIE.LIB.LLM });
556
600
 
557
601
  // Turn policy constants
@@ -1538,11 +1582,21 @@ class GeminiAdapter extends BaseProviderAdapter {
1538
1582
  // Gemini doesn't support combining function calling with responseMimeType: 'application/json'
1539
1583
  // When tools are present, structured output is handled via the structured_output tool
1540
1584
  if (request.format && !(request.tools && request.tools.length > 0)) {
1541
- geminiRequest.config = {
1542
- ...geminiRequest.config,
1543
- responseMimeType: "application/json",
1544
- responseJsonSchema: request.format,
1545
- };
1585
+ const useJsonSchema = request.providerOptions?.useJsonSchema === true;
1586
+ if (useJsonSchema) {
1587
+ geminiRequest.config = {
1588
+ ...geminiRequest.config,
1589
+ responseMimeType: "application/json",
1590
+ responseJsonSchema: request.format,
1591
+ };
1592
+ }
1593
+ else {
1594
+ geminiRequest.config = {
1595
+ ...geminiRequest.config,
1596
+ responseMimeType: "application/json",
1597
+ responseSchema: jsonSchemaToOpenApi3(request.format),
1598
+ };
1599
+ }
1546
1600
  }
1547
1601
  // When format is specified with tools, add instruction to use structured_output tool
1548
1602
  if (request.format && request.tools && request.tools.length > 0) {
@@ -1610,11 +1664,7 @@ class GeminiAdapter extends BaseProviderAdapter {
1610
1664
  : naturalZodSchema(schema);
1611
1665
  jsonSchema = z.toJSONSchema(zodSchema);
1612
1666
  }
1613
- // Remove $schema property (Gemini doesn't need it)
1614
- if (jsonSchema.$schema) {
1615
- delete jsonSchema.$schema;
1616
- }
1617
- return jsonSchema;
1667
+ return jsonSchemaToOpenApi3(jsonSchema);
1618
1668
  }
1619
1669
  //
1620
1670
  // API Execution