fix(opencode): avoid gemini combiner schema sibling injection (#15318)

This commit is contained in:
Shoubhit Dash
2026-03-03 10:11:05 +05:30
committed by GitHub
parent e41b53504f
commit 7e3e85ba59
2 changed files with 130 additions and 5 deletions

View File

@@ -897,6 +897,32 @@ export namespace ProviderTransform {
// Convert integer enums to string enums for Google/Gemini
if (model.providerID === "google" || model.api.id.includes("gemini")) {
const isPlainObject = (node: unknown): node is Record<string, any> =>
typeof node === "object" && node !== null && !Array.isArray(node)
const hasCombiner = (node: unknown) =>
isPlainObject(node) &&
(Array.isArray(node.anyOf) || Array.isArray(node.oneOf) || Array.isArray(node.allOf))
const hasSchemaIntent = (node: unknown) => {
if (!isPlainObject(node)) return false
if (hasCombiner(node)) return true
return [
"type",
"properties",
"items",
"prefixItems",
"enum",
"const",
"$ref",
"additionalProperties",
"patternProperties",
"required",
"not",
"if",
"then",
"else",
].some((key) => key in node)
}
const sanitizeGemini = (obj: any): any => {
if (obj === null || typeof obj !== "object") {
return obj
@@ -927,19 +953,18 @@ export namespace ProviderTransform {
result.required = result.required.filter((field: any) => field in result.properties)
}
if (result.type === "array") {
if (result.type === "array" && !hasCombiner(result)) {
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) {
// Ensure items has a type only when it's still schema-empty.
if (isPlainObject(result.items) && !hasSchemaIntent(result.items)) {
result.items.type = "string"
}
}
// Remove properties/required from non-object types (Gemini rejects these)
if (result.type && result.type !== "object") {
if (result.type && result.type !== "object" && !hasCombiner(result)) {
delete result.properties
delete result.required
}