Skip to content

fix(anthropic): set supports_web_search on current Claude models priced for web search - #33920

Open
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_fix_anthropic_supports_web_search
Open

fix(anthropic): set supports_web_search on current Claude models priced for web search#33920
devin-ai-integration[bot] wants to merge 1 commit into
litellm_internal_stagingfrom
litellm_fix_anthropic_supports_web_search

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes #33919

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Screenshots / Proof of Fix

Every current-generation Anthropic-direct entry already carries search_context_cost_per_query (the billing metadata for Anthropic's web_search_20250305 tool), yet omitted supports_web_search, so litellm.supports_web_search(...) returned False and Router web-search filtering excluded the deployments.

Before (base litellm_internal_staging), the issue repro printed False for all listed models except claude-3-7-sonnet-20250219

After (commit 68a3a56f70cee50d45cc5d7c0e6a423876c07674):

$ LITELLM_LOCAL_MODEL_COST_MAP=True python -c "
import litellm
for m in ['claude-sonnet-4-20250514','claude-sonnet-4-5','claude-sonnet-4-6','claude-sonnet-5','claude-opus-4-1','claude-opus-4-8','claude-fable-5','claude-3-7-sonnet-20250219']:
    print(m, litellm.supports_web_search(model=m))"
claude-sonnet-4-20250514 True
claude-sonnet-4-5 True
claude-sonnet-4-6 True
claude-sonnet-5 True
claude-opus-4-1 True
claude-opus-4-8 True
claude-fable-5 True
claude-3-7-sonnet-20250219 True

Live Anthropic web search confirming the flag is accurate (real API calls, commit 68a3a56f70cee50d45cc5d7c0e6a423876c07674):

$ python -c "
import litellm
for m in ['claude-sonnet-4-5','claude-opus-4-1']:
    r=litellm.completion(model='anthropic/'+m,
        messages=[{'role':'user','content':'What was a major world news headline today? Use web search.'}],
        tools=[{'type':'web_search_20250305','name':'web_search','max_uses':2}], max_tokens=1024)
    print(m, r.model_dump()['usage']['server_tool_use'])"
claude-sonnet-4-5 {'web_search_requests': 1, 'tool_search_requests': None}
claude-opus-4-1 {'web_search_requests': 1, 'tool_search_requests': None}

Type

🐛 Bug Fix

Changes

Added "supports_web_search": true to every Anthropic-direct (litellm_provider: anthropic) entry that already prices the web search tool via search_context_cost_per_query but was missing the capability flag; this covers claude-sonnet-4-20250514, claude-sonnet-4-5, claude-sonnet-4-6, claude-sonnet-5, claude-opus-4-1, claude-opus-4-1-20250805, claude-opus-4-20250514, claude-4-opus-20250514, claude-opus-4-5, claude-opus-4-5-20251101, claude-opus-4-6, claude-opus-4-6-20260205, claude-opus-4-7, claude-opus-4-7-20260416, claude-fable-5 and claude-opus-4-8. The same entries were updated in the bundled backup map so the two stay in sync

Added tests/test_litellm/test_anthropic_web_search_model_metadata.py. Beyond checking the specific models from the issue, it enforces the invariant that any Anthropic-direct entry priced for web search (search_context_cost_per_query present) must set supports_web_search, so future model additions can't silently reintroduce the drift; it also verifies the flag resolves through litellm.supports_web_search and that the backup map matches the canonical file

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/a3ffe74142e640118168500f7431c768

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a metadata gap where Anthropic-direct model entries priced for the built-in web-search tool (search_context_cost_per_query present) were missing "supports_web_search": true, causing litellm.supports_web_search(...) to return False and router web-search filtering to exclude those deployments.

  • JSON fixes"supports_web_search": true is added to 16 Anthropic-direct entries in both model_prices_and_context_window.json and its bundled backup, keeping the two files in sync.
  • New testtest_anthropic_web_search_model_metadata.py verifies the specific issue models, enforces a forward-looking invariant (billing flag ⟹ capability flag, main file only), and spot-checks backup parity for the named models.
  • Test isolation defecttest_supports_web_search_resolves_true directly assigns litellm.model_cost without using monkeypatch.setattr, so the overwritten module-level state is never restored and can affect subsequent tests in the session.

Confidence Score: 4/5

The JSON changes are correct and targeted; the test file introduces a module-level state mutation without rollback that can affect other tests in the same session.

The core fix — adding supports_web_search to the 16 affected model entries in both JSON files — is straightforward and correct. The new test's invariant check is a good guard for future regressions. The concern is in test_supports_web_search_resolves_true: litellm.model_cost is overwritten by direct assignment, which pytest's monkeypatch does not track and therefore does not restore after each parametrized run.

tests/test_litellm/test_anthropic_web_search_model_metadata.py — the litellm.model_cost assignment on line 45 should use monkeypatch.setattr for proper teardown.

Important Files Changed

Filename Overview
model_prices_and_context_window.json Adds "supports_web_search": true to 16 Anthropic-direct entries that already carried search_context_cost_per_query; no unrelated models touched and no existing flags removed.
litellm/model_prices_and_context_window_backup.json Mirror of main file changes — identical "supports_web_search": true additions for the same 16 models; backup is kept in sync.
tests/test_litellm/test_anthropic_web_search_model_metadata.py New test file verifying the flag fix and a forward-looking invariant; litellm.model_cost is mutated without monkeypatch rollback (test isolation defect), and the invariant is not applied to the backup file.

Reviews (1): Last reviewed commit: "fix(anthropic): set supports_web_search ..." | Re-trigger Greptile

Comment on lines +43 to +46
def test_supports_web_search_resolves_true(monkeypatch, model):
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
litellm.model_cost = litellm.get_model_cost_map(url="")
assert litellm.supports_web_search(model=model) is True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 litellm.model_cost mutation not rolled back after test

litellm.model_cost is overwritten with a direct assignment, which monkeypatch does not track and therefore does not restore after the test finishes. Every test that runs later in the same pytest session will see the local-backup cost map instead of whatever was in litellm.model_cost before. Swapping to monkeypatch.setattr(litellm, "model_cost", litellm.get_model_cost_map(url="")) lets pytest restore the original value automatically.

Comment on lines +49 to +64
def test_anthropic_entries_with_search_billing_advertise_web_search():
"""Any Anthropic-direct model priced for the web search tool must set the flag.

``search_context_cost_per_query`` is the billing metadata for Anthropic's web
search tool, so an entry that carries it while omitting ``supports_web_search``
would be silently excluded by ``supports_web_search`` / router web-search filtering.
"""
missing = tuple(
model
for model, info in _main().items()
if isinstance(info, dict)
and info.get("litellm_provider") == "anthropic"
and "search_context_cost_per_query" in info
and info.get("supports_web_search") is not True
)
assert missing == (), f"Anthropic entries priced for web search but missing the flag: {missing}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Invariant not enforced for the backup map

test_anthropic_entries_with_search_billing_advertise_web_search verifies that every anthropic-provider entry in the main file with search_context_cost_per_query also sets supports_web_search, but only checks model_prices_and_context_window.json. The backup file has an equivalent enforcement gap: test_backup_matches_main only spot-checks ISSUE_MODELS, so a future model added to the main file that accidentally omits supports_web_search in the backup would pass all tests.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Aayush-engineer added a commit to Aayush-engineer/litellm that referenced this pull request Jul 19, 2026
…5 entries

Bedrock and bedrock_converse regional entries for claude-sonnet-4,
claude-sonnet-4-5, claude-sonnet-4-6, and claude-sonnet-5 were missing
supports_web_search: true, even though every other capability flag
(vision, function_calling, prompt_caching) was correctly set and
Anthropic's web_search_20250305 tool works identically on Bedrock as
on the direct API.

This caused litellm.supports_web_search() to return False and
Router.filter_web_search_deployments() to incorrectly exclude these
Bedrock deployments from web-search-tagged requests.

Complementary to BerriAI#33920, which covers the Anthropic-direct
(litellm_provider: anthropic) entries for the same underlying issue;
this PR covers the Bedrock/bedrock_converse regional variants that
PR does not touch.

Fixes BerriAI#33919 (Bedrock half)
@codspeed-hq

codspeed-hq Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_fix_anthropic_supports_web_search (68a3a56) with litellm_internal_staging (bd44c9e)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

supports_web_search flag missing across the current Claude model family, not just claude-sonnet-5

1 participant