fix(providers): normalize tool schemas for JSON Schema 2020-12 compliance (Bedrock/LiteLLM)#879
fix(providers): normalize tool schemas for JSON Schema 2020-12 compliance (Bedrock/LiteLLM)#879umi008 wants to merge 3 commits into
Conversation
…nAI Compatible path Call normalizeToolSchema() before applying OpenAI-specific strict mode transforms in convertToolSchemaForOpenAI(). This ensures tool schemas are 2020-12 compliant (type arrays -> anyOf, unsupported formats stripped) before backends like Bedrock validate them through OpenAI-compatible proxies like LiteLLM. Previously, only the direct provider paths (bedrock, vscode-lm) applied this normalization. The 15+ providers that inherit from BaseProvider and use convertToolsForOpenAI() were sending raw schemas that Bedrock rejects with 'maxItems is not supported' errors. Fixes Zoo-Code-Org#869
|
Warning Review limit reached
Next review available in: 6 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesOpenAI tool schema normalization
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/api/providers/base-provider.ts`:
- Around line 70-84: Update the schema handling around normalizeToolSchema so
object-like normalized schemas with properties and additionalProperties: false
are processed even when type is absent, rather than returning early; use an
object-shape check that also covers flattened compositions and nullable object
conversions. In the same logic, remove the redundant Array.isArray(prop.type)
branch and rely on normalizeToolSchema’s recursive type-array normalization
before applying strict required-field and nested-property processing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8f75b99a-dfae-41c8-8a20-c5926d1ab896
📒 Files selected for processing (1)
src/api/providers/base-provider.ts
… call
The spread of normalied (Record<string, unknown>) caused TS7053
because the inferred type was {} and string indexing was not allowed.
Added explicit Record<string, any> type annotation to fix compilation.
1a45e3a to
feb79dd
Compare
…ation Two test updates after adding normalizeToolSchema() to the schema pipeline: 1. Nullable types test: Now asserts anyOf conversion instead of null stripping. normalizeToolSchema() converts type arrays to anyOf for JSON Schema 2020-12 compliance, which is correct behavior. 2. Non-object schemas test: Verifies type preservation through normalization. additionalProperties is NOT added to non-object schemas (strings, numbers, etc.) because the JSON Schema spec says it's only valid on object types.
9c7204b to
826eb83
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Related GitHub Issue
Closes: #869
Description
Tool requests through the OpenAI Compatible provider path (used by 15+ providers including LiteLLM, OpenRouter, DeepSeek, xAI, etc.) were sending raw tool schemas without JSON Schema 2020-12 normalization. When the backend is AWS Bedrock (directly or through a LiteLLM proxy), it rejects schemas containing keywords like
maxItemson array properties because Bedrock enforces strict 2020-12 compliance.normalizeToolSchema()was already applied in the direct Bedrock and VSCode LM provider paths, butBaseProvider.convertToolSchemaForOpenAI()— the shared method used by all OpenAI-compatible providers — was not calling it.Fix:
convertToolSchemaForOpenAI()now callsnormalizeToolSchema()first to convert deprecated type arrays toanyOf, strip unsupported format values, and enforceadditionalProperties: false, before applying OpenAI-specific strict mode transforms (all-required, null removal). The two passes compose safely: normalization handles 2020-12 compliance, and the existing OpenAI pass adds the strict-mode constraints on top.Test Procedure
maxItemsManual verification of schema transformation:
Pre-Submission Checklist
Screenshots / Videos
N/A — backend schema normalization, no UI changes.
Documentation Updates
Additional Notes
This fix benefits all providers that inherit from
BaseProviderand useconvertToolsForOpenAI()— OpenRouter, DeepSeek, xAI, Groq, Fireworks, Together, SambaNova, Baseten, Friendli, and others. The normalization is idempotent for well-formed schemas, so the risk of regression is minimal.Summary by CodeRabbit