fix(opencode): omit tool_choice for zai providers when tools are empty - #7245
Open
AceRothstein71 wants to merge 1 commit into
Open
fix(opencode): omit tool_choice for zai providers when tools are empty#7245AceRothstein71 wants to merge 1 commit into
AceRothstein71 wants to merge 1 commit into
Conversation
Z.AI/GLM endpoints reject chat-completion requests that carry tool_choice with an empty or missing tools array (HTTP 400, code 1210, 'API 调用参数有误'). The bundled @ai-sdk/openai-compatible provider serializes tool_choice unconditionally, so Atlas/Sisyphus turns that force tool_choice:"required" fail intermittently on zai-coding-plan/glm-5.2 when MCP/provider-defined tools leave the function list empty. Inject a sanitizing fetch wrapper into the options.fetch of the four zai-family provider entries (zai, zai-coding-plan, zhipuai, zhipuai-coding-plan) during the plugin config hook. opencode reads provider entries after plugin config hooks run and forwards options.fetch to createOpenAICompatible, so request bodies are sanitized in-process: tool_choice is dropped when tools are absent/empty or name a missing function; valid requests and SSE responses pass through byte-identical. User-set fetch functions are wrapped, never replaced, and the wrapper is idempotent. Verified: 19 new failing-first regression tests green (scoped suite 71 pass), wider scoped net 266 pass, bun run typecheck exit 0. Evidence under .omo/evidence/20260824-6753-glm52-tool-choice/. Fixes code-yeongyu#6753
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Injects a sanitizing fetch wrapper into the
options.fetchof the four Z.AI/Zhipu provider entries (zai,zai-coding-plan,zhipuai,zhipuai-coding-plan) during the plugin config hook, so thattool_choiceis dropped from chat-completion request bodies when the effectivetoolslist is empty/absent or whentool_choicenames a function not present intools. Valid requests and SSE responses pass through byte-identical.New module:
packages/omo-opencode/src/features/zai-tool-choice-guard/wired intoconfig-handler.tsnext toapplyOpenGatewayProviderConfig.Why
The bundled
@ai-sdk/openai-compatibleprovider serializestool_choiceunconditionally. Z.AI/GLM endpoints reject such bodies with HTTP 400 code 1210 (AI_APICallError: API 调用参数有误), so Atlas/Sisyphus turns that forcetool_choice:"required"fail intermittently onzai-coding-plan/glm-5.2whenever MCP/provider-defined tools leave the function-tool list empty (#6753).OMO cannot patch the vendored SDK, but opencode's provider pipeline makes an in-process fix possible (verified against opencode dev source and the installed 1.18.16 binary):
config()hooks run beforecfg.provideris read (packages/opencode/src/provider/provider.ts~1420-1424)options.fetchthrough tocreateOpenAICompatibleSo the guard covers every request path for those providers without a local proxy, and stays inert for all other providers.
Verified
Cannot find module './index'), then green after implementing.options.fetch, preserves existing models/options on them, leavesanthropic/github-copilotuntouched, second pass is a no-op.config-handler.test.ts= 71 pass / 0 fail; wider net (plugin-handlers + opengateway-provider) = 266 pass / 0 fail.bun run typecheckexit 0 (tsgo root + script + packages)..omo/evidence/20260824-6753-glm52-tool-choice/(WHAT TESTED / OBSERVED / WHY ENOUGH / OMITTED), committed withgit add -f.Risk
Low and contained: only zai-family provider entries gain an
options.fetchwrapper; every other provider is untouched. If a future opencode stops honoringoptions.fetch, the wrapper becomes inert rather than breaking requests. The upstream SDK-level fix remains the complete remedy for non-zai openai-compatible providers with the same validation behavior.Fixes #6753
Summary by cubic
Drops invalid tool_choice from Z.AI/Zhipu chat-completion requests to prevent GLM 400 (code 1210) when tools are empty or missing. Previously we always sent tool_choice from
@ai-sdk/openai-compatible; now a sanitizing fetch runs only for zai-family providers, leaving valid requests and streaming unchanged.applyZaiToolChoiceGuardinconfig-handler.tsto wrapoptions.fetchforzai,zai-coding-plan,zhipuai, andzhipuai-coding-plan. User-defined fetch is wrapped, not replaced; wrapper is idempotent and passes non-JSON bodies and SSE through unchanged.packages/omo-opencode/src/features/zai-tool-choice-guard/(sanitizer + tests). Only these providers are mutated; existing models/options are preserved; other providers are untouched. Verified by scoped tests (71 pass), broader suites (266 pass), and repo typecheck.Written for commit fc943f2. Summary will update on new commits.