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)
|
result.required = result.required.filter((field: any) => field in result.properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.type === "array" && result.items == null) {
|
if (result.type === "array") {
|
||||||
result.items = {}
|
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)
|
// 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", () => {
|
describe("ProviderTransform.schema - gemini non-object properties removal", () => {
|
||||||
const geminiModel = {
|
const geminiModel = {
|
||||||
providerID: "google",
|
providerID: "google",
|
||||||
|
|||||||
Reference in New Issue
Block a user