fix(agents): drop strict tool schemas on Bedrock Claude past the 20-tool cap - #1050
fix(agents): drop strict tool schemas on Bedrock Claude past the 20-tool cap#1050pavel-brousek-at-usu wants to merge 2 commits into
Conversation
…ool cap AWS Bedrock's Converse API rejects a request with more than 20 strict-mode tool schemas: `ValidationException: Too many strict tools (28). The maximum number of strict tools supported is 20.` Strix's own `_BASE_TOOLS` alone is already 29 entries before agent-browser, shell, filesystem, or any registered extra tools are added, so every Bedrock Claude scan hits this on startup regardless of what skills or extra tools are loaded. Force strict_json_schema=False on every tool once the count exceeds the cap, only for Bedrock Claude routes (is_claude_model + is_bedrock_ route). Bedrock rejects the whole request over the limit, not just the tools past usestrix#20, so partial strictness isn't an option — matches how pydantic-ai, camel-ai, and other SDKs that hit this same Bedrock limit resolved it. _disable_strict_schema returns a copy via dataclasses.replace rather than mutating in place: _BASE_TOOLS/_EXTRA_TOOLS entries are shared module-level singletons reused by every build_strix_agent call, so an in-place flip would leak non-strict schemas into later non-Bedrock builds in the same process.
Greptile SummaryThe PR avoids Bedrock Claude's 20-strict-tool limit by copying oversized tool sets with strict JSON schemas disabled, while preserving shared tool singletons. It also adds coverage for route selection, threshold behavior, and cross-build isolation.
Confidence Score: 4/5The effective-model mismatch should be fixed before merging because explicit Bedrock Claude model overrides can still hit the request-rejection path this PR is intended to remove. The runner can execute agents with an explicit model that differs from configuration, while the new compatibility gate consults only configuration and can therefore apply the wrong tool-schema behavior. Files Needing Attention: strix/agents/factory.py Important Files Changed
Prompt To Fix All With AI### Issue 1
strix/agents/factory.py:641
**Effective model route mismatch**
When `run_strix_scan(model=...)` selects a Bedrock Claude model that differs from `settings.llm.model`, this gate classifies the settings model instead of the effective `RunConfig` model, leaving more than 20 strict tools enabled and causing Bedrock to reject the scan at startup.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(agents): drop strict tool schemas on..." | Re-trigger Greptile |
Addresses review feedback on usestrix#1050: when run_strix_scan(model=...) selects a model that differs from settings.llm.model, the strict-tool gate was classifying the wrong model, silently leaving >20 strict tools enabled and letting Bedrock reject the scan at startup anyway. build_strix_agent now takes an optional model_name, threaded through from runner.py's already-resolved resolved_model (falls back to settings.llm.model for callers, e.g. tests, that don't go through the runner). make_child_factory forwards the same value so children built later in the scan see the same classification as the root agent.
|
Running into this same issue! Thanks @pavel-brousek-at-usu |
1 similar comment
|
Running into this same issue! Thanks @pavel-brousek-at-usu |
Summary
AWS Bedrock's Converse API rejects any request carrying more than 20 strict-mode tool schemas:
_BASE_TOOLSinstrix/agents/factory.pyalone is already 29 entries (todos, notes, reporting, Caido proxy tools, agent graph,load_skill,web_search,think) before agent-browser, shell, filesystem, or any registered extra tools are added. Every Bedrock Claude scan hits this on startup, independent of skills or extra tools loaded —load_skillis a single registered tool regardless of how many skill.mdfiles exist, so skill content can't be the cause.Fix
build_strix_agentnow checks the final tool count against the cap once it's known which route is configured (is_claude_model+is_bedrock_route, both already instrix/config/models.py), and if it's a Bedrock Claude route past 20 tools, forcesstrict_json_schema=Falseon every tool. Bedrock rejects the whole request over the limit, not just the tools past #20, so partial strictness (e.g. keeping the first 20 strict) isn't a valid option — confirmed by how other SDKs that hit this same Bedrock limit resolved it: pydantic-ai, camel-ai#4171, and datarobot-genai#547 all disable strict mode for the whole toolset rather than trying to keep a subset strict._disable_strict_schemareturns a copy viadataclasses.replacerather than mutating in place —_BASE_TOOLS/_EXTRA_TOOLSentries are shared module-level singletons reused by everybuild_strix_agentcall, so an in-place flip would leak non-strict schemas into a later non-Bedrock build in the same process (root agent on Bedrock, then a Vertex/OpenAI child, for example). Caught this exact regression with a dedicated test while writing the fix.Related
No existing issue or PR addresses this (searched
strict tools,20 tools,strict_json_schema, and the literal error text across issues and PRs, open and closed) — this looks like a new report.Loosely related to the two open Bedrock
tool_choice/parallel_tool_callsPRs (#649, #668) and #644 in that all three are Bedrock-Claude-route-specific request-shape fixes living in/nearstrix/agents/factory.pyandstrix/core/inputs.py, but this is a distinct bug (tool count vs. tool_choice format) with no code overlap.Testing
_bedrock_claude_modelfixture + 5 tests totests/test_agent_tool_registration.py:FunctionToolhasstrict_json_schema=False_BASE_TOOLSmonkeypatched short) → default strict schemas preserved_BASE_TOOLSsingletons must be untouched afterward_disable_strict_schemaback to the in-place-mutation version and confirmed the test fails; restored the fix and confirmed it passes againuv run pytest tests/— 890 passed (883 existing + 7 new/modified)ruff check/ruff format --check— cleanbandit -r strix/agents/factory.py— no issuesTest plan