fix(provider): handle anyOf/oneOf/const/$ref in Gemini schema sanitization#12911
fix(provider): handle anyOf/oneOf/const/$ref in Gemini schema sanitization#12911nxxxsooo wants to merge 1 commit intoanomalyco:devfrom
Conversation
…ation Gemini's generateContent API rejects JSON schemas containing anyOf, oneOf, const, $ref, and $defs — all valid JSON Schema but unsupported in Gemini's function calling format. This causes MCP tools from servers like Notion, Memory, and Obsidian mcp-tools to fail with errors like: 'only allowed for STRING type' 'Failed to process error response' Changes: - Add $ref/$defs resolution before sanitization (handles circular refs) - Flatten anyOf/oneOf with const values into enum arrays - Merge multiple object alternatives into single merged object - Pick first type for mixed-type oneOf/anyOf - Single-item unwrap for trivial anyOf/oneOf Tested against real schemas from Notion MCP (22/22 tools fixed), Memory MCP (4 tools), and old Obsidian mcp-tools plugin.
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: I found potential related PRs to PR #12911:
These PRs appear to be working on related or overlapping aspects of Gemini schema compatibility. PRs #12292 and #11968 are particularly relevant as they address similar schema transformation issues for Gemini. |
Problem
Gemini's
generateContentAPI rejects JSON schemas containinganyOf,oneOf,const,$ref, and$defs— all valid JSON Schema but unsupported by Gemini's function calling format. This causes MCP tools from servers like Notion, Memory, and Obsidian mcp-tools to fail when used with any Gemini model.Error example:
Root Cause
The
sanitizeGeminifunction intransform.tshandles integer→string enum conversion and a few other edge cases, but does not transform these unsupported JSON Schema patterns:$ref/$defs{ "$ref": "#/$defs/richTextRequest" }anyOfwithconst{ "anyOf": [{ "const": "markdown" }, { "const": "json" }] }oneOfmixed types{ "oneOf": [{ "type": "array" }, { "type": "string" }] }oneOfmultiple objects{ "oneOf": [{ "type": "object", "properties": { "page_id": ... } }, ...] }Solution
Two-phase transformation before existing sanitization:
$refresolution: Inline all$refreferences from$defs/definitions, with circular reference detectionanyOf/oneOfflattening:const→enumarrayTesting
Tested against real MCP server schemas:
anyOf/oneOfpatterns resolved)oneOftags patterns fixedanyOf+constpatterns fixedChanges
packages/opencode/src/provider/transform.ts: AddedresolveRefshelper andanyOf/oneOfflattening tosanitizeGemini