Skip to content

fix: forward strict mode to Anthropic and Bedrock providers#5388

Merged
greysonlalonde merged 4 commits intomainfrom
fix/forward-strict-mode-to-providers
Apr 10, 2026
Merged

fix: forward strict mode to Anthropic and Bedrock providers#5388
greysonlalonde merged 4 commits intomainfrom
fix/forward-strict-mode-to-providers

Conversation

@greysonlalonde
Copy link
Copy Markdown
Contributor

@greysonlalonde greysonlalonde commented Apr 10, 2026

Summary

  • Anthropic and Bedrock providers were not forwarding strict: true from the OpenAI-format tool schema during conversion, so neither provider used constrained decoding for tool calls
  • Without constrained decoding, the model can return string "None" instead of JSON null for nullable Optional fields, causing Pydantic validation failures downstream
  • Added strict: true forwarding in _convert_tools_for_interference (Anthropic) and _format_tools_for_converse (Bedrock), plus added strict to the Bedrock ToolSpec TypedDict

Context

The native tool calling path builds tool schemas via convert_tools_to_openai_schema which sets strict: 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

  • Verify Anthropic tool calls with Optional fields return null instead of "None"
  • Verify Bedrock tool calls with Optional fields return null instead of "None"
  • Confirm no regression on tools without nullable fields

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: true now propagate that flag into each provider’s tool spec (AnthropicCompletion._convert_tools_for_interference and BedrockCompletion._format_tools_for_converse, with strict added to Bedrock’s ToolSpec). This enables strict/constrained tool-call decoding on those providers.

Updates AWS optional dependency pins in pyproject.toml (notably boto3/aiobotocore) and refreshes uv.lock with 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.

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.
Copy link
Copy Markdown
Contributor

@iris-clawd iris-clawd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 🚀

greysonlalonde and others added 3 commits April 10, 2026 14:24
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.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Copy link
Copy Markdown
Contributor

@iris-clawd iris-clawd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@greysonlalonde greysonlalonde merged commit 6efa142 into main Apr 10, 2026
54 checks passed
@greysonlalonde greysonlalonde deleted the fix/forward-strict-mode-to-providers branch April 10, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants