mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-03 07:33:45 +00:00
fix(opencode): avoid gemini combiner schema sibling injection (#15318)
This commit is contained in:
@@ -510,6 +510,106 @@ describe("ProviderTransform.schema - gemini nested array items", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("ProviderTransform.schema - gemini combiner nodes", () => {
|
||||
const geminiModel = {
|
||||
providerID: "google",
|
||||
api: {
|
||||
id: "gemini-3-pro",
|
||||
},
|
||||
} as any
|
||||
|
||||
const walk = (node: any, cb: (node: any, path: (string | number)[]) => void, path: (string | number)[] = []) => {
|
||||
if (node === null || typeof node !== "object") {
|
||||
return
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
node.forEach((item, i) => walk(item, cb, [...path, i]))
|
||||
return
|
||||
}
|
||||
cb(node, path)
|
||||
Object.entries(node).forEach(([key, value]) => walk(value, cb, [...path, key]))
|
||||
}
|
||||
|
||||
test("keeps edits.items.anyOf without adding type", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
edits: {
|
||||
type: "array",
|
||||
items: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
old_string: { type: "string" },
|
||||
new_string: { type: "string" },
|
||||
},
|
||||
required: ["old_string", "new_string"],
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
old_string: { type: "string" },
|
||||
new_string: { type: "string" },
|
||||
replace_all: { type: "boolean" },
|
||||
},
|
||||
required: ["old_string", "new_string"],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ["edits"],
|
||||
} as any
|
||||
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
expect(Array.isArray(result.properties.edits.items.anyOf)).toBe(true)
|
||||
expect(result.properties.edits.items.type).toBeUndefined()
|
||||
})
|
||||
|
||||
test("does not add sibling keys to combiner nodes during sanitize", () => {
|
||||
const schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
edits: {
|
||||
type: "array",
|
||||
items: {
|
||||
anyOf: [{ type: "string" }, { type: "number" }],
|
||||
},
|
||||
},
|
||||
value: {
|
||||
oneOf: [{ type: "string" }, { type: "boolean" }],
|
||||
},
|
||||
meta: {
|
||||
allOf: [
|
||||
{
|
||||
type: "object",
|
||||
properties: { a: { type: "string" } },
|
||||
},
|
||||
{
|
||||
type: "object",
|
||||
properties: { b: { type: "string" } },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
} as any
|
||||
const input = JSON.parse(JSON.stringify(schema))
|
||||
const result = ProviderTransform.schema(geminiModel, schema) as any
|
||||
|
||||
walk(result, (node, path) => {
|
||||
const hasCombiner = Array.isArray(node.anyOf) || Array.isArray(node.oneOf) || Array.isArray(node.allOf)
|
||||
if (!hasCombiner) {
|
||||
return
|
||||
}
|
||||
const before = path.reduce((acc: any, key) => acc?.[key], input)
|
||||
const added = Object.keys(node).filter((key) => !(key in before))
|
||||
expect(added).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("ProviderTransform.schema - gemini non-object properties removal", () => {
|
||||
const geminiModel = {
|
||||
providerID: "google",
|
||||
|
||||
Reference in New Issue
Block a user