Repository navigation
Description
I'm working on a PAI-to-OpenCode port using non-Claude models (MiniMax, Gemini, Qwen via MLX) and have been tracing tool-calling failures back to schema conversion inconsistencies. While investigating #4357 and filing #20807, I found that the codebase has 6 separate places that convert tool schemas, using 3 different methods, with inconsistent provider transform application.
The problem in brief:
prompt.ts:440— usesz.toJSONSchema()+ProviderTransform.schema()(correct)prompt.ts:480— usesasSchema().jsonSchema+ProviderTransform.schema()(correct)prompt.ts:1884— hardcoded JSON, no provider transformsllm.ts:220— hardcoded JSON, no provider transformsexperimental.ts:87— useszodToJsonSchema()which is broken with Zod v4 (experimental.ts uses zodToJsonSchema which is broken with Zod v4 #20807)mcp/index.ts:146— raw JSON, no provider transforms (Gemini users with MCP tools get unsanitized schemas — see Gemini schema sanitizer doesn't strip contentEncoding from MCP tool schemas #15408)
Each new consumer has to independently decide how to convert, whether to apply provider transforms, and which converter to use. The zodToJsonSchema breakage proves the pattern fails at scale.
What I'd like to propose: A tool/schema.ts module with one toJsonSchema(schema, model?) function that all 6 paths use. It would handle Zod detection, provider-specific transforms, and (if needed) cross-instance plugin metadata rehydration in one place.
I have a detailed test plan covering baseline behavior snapshots, provider transform application, cross-instance Zod metadata, and end-to-end acceptance tests. Happy to share if the team is interested.
Before putting in the implementation work, I wanted to check: is this a direction the team would accept? Or is the scattered approach intentional?
Related issues this would address:
- Tool argument descriptions lost in schema conversion #4357 — Tool argument descriptions lost in schema conversion
- experimental.ts uses zodToJsonSchema which is broken with Zod v4 #20807 —
experimental.tsuses brokenzodToJsonSchemawith Zod v4 - Gemini schema sanitizer doesn't strip contentEncoding from MCP tool schemas #15408 — Gemini schema sanitizer doesn't strip
contentEncodingfrom MCP tool schemas - MCP tool schema optional fields become required in OpenCode (jira_add_comment) #20661 — MCP tool schema optional fields become required
- MCP tool schema resolution: RecursionError on circular schema references #16899 — MCP tool schema: RecursionError on circular schema references
- OpenCode warns on nonstandard MCP schema formats before jsonSchema() #20749 — OpenCode warns on nonstandard MCP schema formats before
jsonSchema() - Claude API rejects tool schemas: missing 'required' field causes 'JSON schema is invalid' error #13618 — Claude API rejects tool schemas: missing
requiredfield
Related PRs:
- fix(opencode): missing custom tool arg descriptions #15957 — Cross-instance Zod metadata rehydration in
fromPlugin(correct diagnosis of plugin description loss) - fix(opencode): preserve custom tool arg descriptions in LLM prompts #13417, fix: preserve tool argument descriptions in schema conversion #14476, fix(opencode): preserve tool argument descriptions in schema conversion #19974 — Attempts to switch
prompt.tstozodToJsonSchema(would regress on Zod v4) - fix(opencode): replace zodToJsonSchema with z.toJSONSchema for Zod v4 compat #20809 — My fix for
experimental.ts(addresses one call site)
Activity
github-actions commentedon Apr 3, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
[FEATURE]:and the issue should include the required verification checkbox confirming you've searched for existing issues.Please edit this issue to address the above within 2 hours, or it will be automatically closed.
If you believe this was flagged incorrectly, please let a maintainer know.
jbmml commentedon Apr 3, 2026
Closing to refile with the correct feature request template.