fix: forward strict mode to Anthropic and Bedrock providers#5388
fix: forward strict mode to Anthropic and Bedrock providers#5388greysonlalonde merged 4 commits intomainfrom
Conversation
The OpenAI-format tool schema sets strict: true but this was dropped during conversion to Anthropic/Bedrock formats, so neither provider used constrained decoding. Without it, the model can return string "None" instead of JSON null for nullable fields, causing Pydantic validation failures.
iris-clawd
left a comment
There was a problem hiding this comment.
Clean surgical fix. +10/-1.
The pattern is consistent: both Anthropic and Bedrock now check function.strict and forward it to their native tool specs, matching what OpenAI already does. The ToolSpec TypedDict update for Bedrock is correct.
One minor observation: the Anthropic API docs show strict was only recently GA'd — worth verifying that older SDK versions don't reject the field. But since it's only set conditionally (if func_info.get("strict")), tools without strict mode are unaffected.
Also: good catch removing the # type: ignore[import-untyped] on aiobotocore — that's a nice cleanup.
LGTM 🚀
The strict flag on toolSpec was added in botocore 1.42.42 as part of Bedrock's structured outputs GA. Bumping boto3 to ~=1.42.79 and aiobotocore to ~=3.4.0 (which supports botocore 1.42.79-1.42.84) so the previous commit's strict forwarding actually reaches the API.
aiobotocore ships without py.typed, so the import needs the import-untyped ignore to keep mypy clean.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e84a104. Configure here.
iris-clawd
left a comment
There was a problem hiding this comment.
Re-reviewed — clean fix, CI all green. The strict forwarding pattern is consistent across both providers and the conditional guard means non-strict tools are unaffected. boto3/aiobotocore bumps are necessary for Bedrock's strict field support (botocore 1.42.42+).
One thing worth addressing from Bugbot's review: the OpenAI provider calls force_additional_properties_false(params_dict) before setting strict: True (completion.py L1574), but neither Anthropic nor Bedrock do this. Both Anthropic and Bedrock strict mode require additionalProperties: false on all object types in the schema — without it, the API will reject the tool definition. Might want to add that call in both conversion paths before shipping.
LGTM otherwise 🚀 💬 205

Summary
strict: truefrom the OpenAI-format tool schema during conversion, so neither provider used constrained decoding for tool calls"None"instead of JSONnullfor nullableOptionalfields, causing Pydantic validation failures downstreamstrict: trueforwarding in_convert_tools_for_interference(Anthropic) and_format_tools_for_converse(Bedrock), plus addedstrictto the BedrockToolSpecTypedDictContext
The native tool calling path builds tool schemas via
convert_tools_to_openai_schemawhich setsstrict: True. The OpenAI provider already forwards this. Anthropic and Bedrock providers were written before those APIs supported strict mode and were never updated after the feature shipped (Anthropic GA, Bedrock GA Feb 2026).Test plan
Optionalfields returnnullinstead of"None"Optionalfields returnnullinstead of"None"Note
Medium Risk
Behavior changes in tool-calling for Anthropic/Bedrock by enabling provider-side strict/constrained decoding when requested, and bumps AWS SDK dependencies (plus lockfile updates) which may introduce compatibility/regression risk.
Overview
Fixes tool conversion for the Anthropic and Bedrock LLM providers so OpenAI-style tools with
function.strict: truenow propagate that flag into each provider’s tool spec (AnthropicCompletion._convert_tools_for_interferenceandBedrockCompletion._format_tools_for_converse, withstrictadded to Bedrock’sToolSpec). This enables strict/constrained tool-call decoding on those providers.Updates AWS optional dependency pins in
pyproject.toml(notablyboto3/aiobotocore) and refreshesuv.lockwith the resulting dependency/version changes.Reviewed by Cursor Bugbot for commit e84a104. Bugbot is set up for automated code reviews on this repo. Configure here.