fix(gemini): prevent gemini incompatibility with some tools - #31877
Conversation
|
The following comment was made by an LLM, it may be inaccurate: I found a potentially related PR: Related PR: This PR appears related as it also addresses Gemini schema issues. While #31877 focuses on preventing Gemini incompatibility with tools, PR #27641 specifically handles sanitizing Gemini schema references, which could be addressing a similar underlying compatibility problem with Gemini's type schema handling. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
2ed7b0d to
99504d1
Compare
|
Looks nice! Is this something you could look at to get Gemini working with opencode? @thdxr |
|
I don't think this matches how ai-sdk/google behaves |
|
99504d1 to
35581b1
Compare
|
@rekram1-node tried to align it more to how the adapter works |
|
@Killusions thx, also do u mind adding a test case for this by chance? Im sure there are prolly some more cases we need to handle better too but for now just adding a new test will be nice |
Some MCPs fail with Gemini (at least via GitHub Copilot) Close anomalyco#19276
35581b1 to
612607c
Compare
|
@rekram1-node Added one |
|
Amazing! Thank you very much for all the work you're doing here! |
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
…branches Port from anomalyco/opencode#31877: JSON Schema type arrays like ["number","string"] (common in MCP tool schemas) were collapsed to the first non-null type, silently dropping every other branch. Several tool-call backends reject the array form outright — llama.cpp's grammar generator and Gemini via OpenAI-compatible transports (e.g. GitHub Copilot proxying to Gemini) 400 on it. _sanitize_node now mirrors @ai-sdk/google: a single non-null type stays type:X (+nullable if null was present), multiple non-null types become an anyOf of single-type schemas so no branch is lost, and an all-null array becomes type:null. Single-null collapse is unchanged. Verified nested (object props, array items) survive the full sanitize pipeline — combinator stripping is top-level-only and nullable-union collapse only fires on single-survivor unions, so multi-type anyOf is left intact.
Issue for this PR
Closes #19276
Type of change
What does this PR do?
Fixes a type schema incompatibility with Gemini and some tools/MCPs (occured through GitHub Copilot).
How did you verify your code works?
Tested locally.
Screenshots / recordings
None
Checklist
⚒️ with ❤️ by @siemens