Skip to content

Commit bf92eaa

Browse files
authored
fix: #5240 remove all additionalProperties for gemini (#5247)
1 parent ba8decf commit bf92eaa

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

libs/langchain-google-common/src/tests/utils.test.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ test("zodToGeminiParameters can convert zod schema to gemini schema", () => {
1010
.describe("The type of operation to execute"),
1111
number1: z.number().describe("The first number to operate on."),
1212
number2: z.number().describe("The second number to operate on."),
13+
childObject: z.object({}),
1314
})
1415
.describe("A simple calculator tool");
1516

1617
const convertedSchema = zodToGeminiParameters(zodSchema);
1718

1819
expect(convertedSchema.type).toBe("object");
1920
expect(convertedSchema.description).toBe("A simple calculator tool");
21+
expect(convertedSchema).not.toContain("additionalProperties");
2022
expect(convertedSchema.properties).toEqual({
2123
operation: {
2224
type: "string",
@@ -31,6 +33,15 @@ test("zodToGeminiParameters can convert zod schema to gemini schema", () => {
3133
type: "number",
3234
description: "The second number to operate on.",
3335
},
36+
childObject: {
37+
type: "object",
38+
properties: {},
39+
},
3440
});
35-
expect(convertedSchema.required).toEqual(["operation", "number1", "number2"]);
41+
expect(convertedSchema.required).toEqual([
42+
"operation",
43+
"number1",
44+
"number2",
45+
"childObject",
46+
]);
3647
});

libs/langchain-google-common/src/types.ts

+10
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,13 @@ export interface GoogleAISafetyHandler {
274274
export interface GoogleAISafetyParams {
275275
safetyHandler?: GoogleAISafetyHandler;
276276
}
277+
278+
export type GeminiJsonSchema = Record<string, unknown> & {
279+
properties?: Record<string, GeminiJsonSchema>;
280+
type: GeminiFunctionSchemaType;
281+
};
282+
283+
export interface GeminiJsonSchemaDirty extends GeminiJsonSchema {
284+
properties?: Record<string, GeminiJsonSchemaDirty>;
285+
additionalProperties?: boolean;
286+
}

libs/langchain-google-common/src/utils/zod_to_gemini_parameters.ts

+40-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,41 @@
22

33
import type { z } from "zod";
44
import { zodToJsonSchema } from "zod-to-json-schema";
5-
import { GeminiFunctionSchema } from "../types.js";
5+
import {
6+
GeminiFunctionSchema,
7+
GeminiJsonSchema,
8+
GeminiJsonSchemaDirty,
9+
} from "../types.js";
10+
11+
function removeAdditionalProperties(
12+
schema: GeminiJsonSchemaDirty
13+
): GeminiJsonSchema {
14+
const updatedSchema: GeminiJsonSchemaDirty = { ...schema };
15+
if (Object.hasOwn(updatedSchema, "additionalProperties")) {
16+
delete updatedSchema.additionalProperties;
17+
}
18+
if (updatedSchema.properties) {
19+
const keys = Object.keys(updatedSchema.properties);
20+
removeProperties(updatedSchema.properties, keys, 0);
21+
}
22+
23+
return updatedSchema;
24+
}
25+
26+
function removeProperties(
27+
properties: Record<string, GeminiJsonSchemaDirty>,
28+
keys: string[],
29+
index: number
30+
): void {
31+
if (index >= keys.length) {
32+
return;
33+
}
34+
35+
const key = keys[index];
36+
// eslint-disable-next-line no-param-reassign
37+
properties[key] = removeAdditionalProperties(properties[key]);
38+
removeProperties(properties, keys, index + 1);
39+
}
640

741
export function zodToGeminiParameters(
842
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -11,8 +45,11 @@ export function zodToGeminiParameters(
1145
// Gemini doesn't accept either the $schema or additionalProperties
1246
// attributes, so we need to explicitly remove them.
1347
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14-
const jsonSchema = zodToJsonSchema(zodObj) as any;
15-
const { $schema, additionalProperties, ...rest } = jsonSchema;
48+
// const jsonSchema = zodToJsonSchema(zodObj) as any;
49+
const jsonSchema = removeAdditionalProperties(
50+
zodToJsonSchema(zodObj) as GeminiJsonSchemaDirty
51+
);
52+
const { $schema, ...rest } = jsonSchema;
1653

1754
return rest;
1855
}

0 commit comments

Comments
 (0)