fix: handle nested array items for Gemini schema validation (#11952)
This commit is contained in:
committed by
GitHub
parent
76381f33d5
commit
3741516fe3
@@ -768,8 +768,15 @@ export namespace ProviderTransform {
|
||||
result.required = result.required.filter((field: any) => field in result.properties)
|
||||
}
|
||||
|
||||
if (result.type === "array" && result.items == null) {
|
||||
result.items = {}
|
||||
if (result.type === "array") {
|
||||
if (result.items == null) {
|
||||
result.items = {}
|
||||
}
|
||||
// Ensure items has at least a type if it's an empty object
|
||||
// This handles nested arrays like { type: "array", items: { type: "array", items: {} } }
|
||||
if (typeof result.items === "object" && !Array.isArray(result.items) && !result.items.type) {
|
||||
result.items.type = "string"
|
||||
}
|
||||
}
|
||||
|
||||
// Remove properties/required from non-object types (Gemini rejects these)
|
||||
|
||||
@@ -293,6 +293,119 @@ describe("ProviderTransform.schema - gemini array items", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("ProviderTransform.schema - gemini nested array items", () => {
|
||||
const geminiModel = {
|
||||
providerID: "google",
|
||||
api: {
|
||||
id: "gemini-3-pro",
|
||||
},
|
||||
} as any
|
||||
|
||||
test("adds type to 2D array with empty inner items", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
values: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "array",
|
||||
items: {}, // Empty items object
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
// Inner items should have a default type
|
||||
expect(result.properties.values.items.items.type).toBe("string")
|
||||
})
|
||||
|
||||
test("adds items and type to 2D array with missing inner items", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
data: {
|
||||
type: "array",
|
||||
items: { type: "array" }, // No items at all
|
||||
},
|
||||
},
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
expect(result.properties.data.items.items).toBeDefined()
|
||||
expect(result.properties.data.items.items.type).toBe("string")
|
||||
})
|
||||
|
||||
test("handles deeply nested arrays (3D)", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
matrix: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "array",
|
||||
// No items
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
expect(result.properties.matrix.items.items.items).toBeDefined()
|
||||
expect(result.properties.matrix.items.items.items.type).toBe("string")
|
||||
})
|
||||
|
||||
test("preserves existing item types in nested arrays", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
numbers: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "array",
|
||||
items: { type: "number" }, // Has explicit type
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
// Should preserve the explicit type
|
||||
expect(result.properties.numbers.items.items.type).toBe("number")
|
||||
})
|
||||
|
||||
test("handles mixed nested structures with objects and arrays", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
spreadsheetData: {
|
||||
type: "object",
|
||||
properties: {
|
||||
rows: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "array",
|
||||
items: {}, // Empty items
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
expect(result.properties.spreadsheetData.properties.rows.items.items.type).toBe("string")
|
||||
})
|
||||
})
|
||||
|
||||
describe("ProviderTransform.schema - gemini non-object properties removal", () => {
|
||||
const geminiModel = {
|
||||
providerID: "google",
|
||||
|
||||
Reference in New Issue
Block a user