Repository navigation
[AISAGE-736] fix(ai-gateway): drop top-level schema combinators from Claude tools - #7646
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit Files Reviewed (3 files)
This incremental review re-checked the changes on top of Previous Review Summary (commit de694db)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit de694db)Status: No Issues Found | Recommendation: Merge I reviewed all four changed files in this PR: the new The helper mirrors the established Files Reviewed (4 files)
Reviewed by deepseek-v4.1-flash · Input: 60.2K · Output: 13.4K · Cached: 680.6K Review guidance: REVIEW.md from base branch |
Summary
Anthropic rejects tools whose schema has
oneOf,allOforanyOfat the root:This is hit by e.g. the nteract MCP
nteract_create_celltool, which uses a rootoneOfto require eithernotebook_handleornotebook_id.Like the existing Muse (recursive
$ref) and Gemini ($refin tool results) workarounds,applyProviderSpecificLogicnow rewrites tool schemas for Claude models (isClaudeModel) across Chat Completions, Responses and Messages requests viaremoveTopLevelToolSchemaCombinators:allOf/anyOf/oneOfare removed. The flattened schema accepts every input the original accepted; the tool server still validates its own input.additionalProperties: falsedoes not forbid them. Root property definitions win over branch ones.requiredfollows the combinator semantics, as in fix: remove top-level anyOf/oneOf/allOf from tool input schemas for Anthropic API compatibility zereight/gitlab-mcp#558: the union of allallOfbranches, and the intersection ofanyOf/oneOfbranches (a property only stays required if every branch requires it).type, it getstype: "object".The input must also match exactly one of these JSON schemas: [...]. Without strict mode Anthropic only shows the schema to the model and does not validate inputs, so this keeps the information the model would have seen. Anthropic's tool docs call descriptions the most important factor and ask for caveats to be included. The text is the same for every request, so prompt caching is unaffected, and the total size stays roughly the same since the branches move from the schema to the description.strictis kept. Because the flattened schema is a superset of the original, strict mode still enforces types, required properties andadditionalPropertiesof what remains; droppingstrictwould only loosen validation further.The Kilo CLI's
agent_managertool does the same thing by hand: it advertises a flatWireParamsobject, describes per-operation rules in field descriptions, and validates the real union on execution.Verification
nteract_create_cellschema,requiredmerging per combinator, description appending (with and without an existing description),strictpreservation, each request kind, and the Claude-only gating inapplyProviderSpecificLogic.Visual Changes
N/A
Reviewer Notes