litellm/tests/unit/proxy/db
JeongCheolLee febbe38326
fix(anthropic)!: do not surface server_tool_use as client tool_calls (#48385)
* fix(anthropic): do not surface server_tool_use as client tool_calls

Anthropic server-executed tools (web search, tool search, code execution)
were returned in chat completions tool_calls with srvtoolu_ ids, so
OpenAI-protocol agent clients treated them as pending work and re-invoked
the model until their recursion limit.

Move them to provider_specific_fields.server_tool_calls on both the
non-streaming and streaming paths. History replay, the /v1/responses
bridge and the /v1/messages streaming guardrail read that field, so
multi-turn reconstruction, web_search_call output items and the
guardrail's fail-closed check on server tool blocks keep working.

* fix(responses): return Claude web_fetch calls as web_search_call open_page items

* fix(responses): keep Claude server web calls without a result as hosted items

A non-streamed Claude turn that calls web_search or web_fetch next to a
client tool can return the server call before its result. Build an
in_progress web_search_call for it, so the Responses bridge no longer
returns it as a client function_call

* fix(anthropic): keep pending server calls native and hide server calls from client tool paths

Replaying a server call that has no result yet now sends it back as
server_tool_use, so Anthropic accepts the next turn. The tool permission
guardrail checks server calls again and rewrite mode removes a denied one.
The /v1/messages adapter keeps Claude's server blocks, and the Responses
bridge never returns a server call as a client function_call.

* fix(anthropic): let guardrails, tool usage, tracing, and Responses replay see Claude's server calls

Claude's server tool calls moved out of tool_calls into provider_specific_fields.server_tool_calls,
so every reader of tool_calls stopped seeing them. The chat guardrail handler now passes them to
output guardrails and writes rewrites back to server_tool_calls (stream and non-stream), tool usage
and registry discovery count them, otel, Datadog and the Logs Tools panel list them, and a pending
Claude web search or fetch item replayed to /v1/responses goes back to Anthropic as its own
server_tool_use instead of running again

* fix(anthropic): let guardrails and loggers read Claude's server tool calls again

Guardrails, tool policies, tracing loggers and the Responses guardrail
translation read only client tool calls after server calls moved to
provider_specific_fields. They now read server calls first, then client
calls, through one shared helper, and the Responses guardrail treats
Claude's web_search_call items as web_search or web_fetch calls.
Non-streaming splits server calls by block type, as streaming does.

* fix(anthropic): keep Claude server calls visible to guardrails, redaction and tracing

A guardrail rewrite of a Claude server call now also updates its hosted web_search_calls copy,
streamed or not. Redaction with message logging off hides server call arguments and hosted web
call actions on chat and Responses. Pillar and Pangea scan server calls, transform-mode streaming
guardrails keep server call chunks, and OTEL v2 Responses spans list Claude's web calls.

* fix(anthropic): keep the legacy hook view of streamed /v1/messages web search after the main merge

Main's legacy post-call hooks see Claude's server call as tool_use with its search results first. The streamed /v1/messages response now keeps that view while native scans keep server_tool_use.

* fix(guardrails): let Cisco AI Defense scan Claude's web calls on Responses

Claude's web search and fetch now come back from /v1/responses as web_search_call items, so Cisco AI Defense reads and clears their query or URL the way it did for the old function_call arguments. The helpers that read and rewrite those items move to the shared guardrail utils so the Responses guardrail handler and Cisco use one copy.

* test(guardrails): inject Pillar's HTTP client and type the Cisco web call actions

* test(guardrails): type the fake Pillar client like its Protocol

* fix(anthropic): keep a pending server call and its thinking when the turn also waits on a client tool

Only a turn with no client tool_use is a paused turn. A tool_use turn that also started web_fetch or
web_search still needs that call and its thinking replayed, or Claude loses the fetch result

* fix(guardrails): scan replayed Claude server calls and hosted web calls

Request guardrails now see and rewrite server_tool_calls replayed in chat
messages. Cato and Purview scan Claude web_search and web_fetch calls on
Responses output, and a function tool call with an extra custom key is no
longer dropped from Cisco, Purview, Repello and PANW scans.

* fix(guardrails): scan replayed Claude server tool calls in Lasso, Lakera and Qualifire request checks

* fix(anthropic): apply streamed guardrail tool call rewrites to their own block when a server tool call follows

* test: annotate the new server tool call test locals with Final and type their parameters

* test: type the new guardrail test helpers with litellm's tool call types instead of Any

* test: narrow the remaining new test helper parameters from bare dict and object

* fix(anthropic): keep server calls in Responses streams, guardrail masks, OTEL and Logs

Streamed /v1/responses now emits Claude's tool search and paused web search calls, text guardrail masks rewrite replayed server calls, OTEL gen_ai messages and the Logs pretty view list server calls next to client calls, and integration tests read server calls from server_tool_calls

* fix(guardrails): keep hosted web call copies in sync on request masks and denied server calls, and accept null tool_calls in Lakera

* fix(anthropic): serialize masked hosted web call copies through their adapter so a replay before the OpenAI model is built does not 500

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-11-06 03:54:34 -08:00
..
db_transaction_queue fix(proxy): treat Postgres restart and shutdown errors as DB unavailable, not poison spend-log rows (#50132) 2026-11-04 17:39:30 -08:00
mcp_server refactor(mcp): drop the experimental label from the MCP server and client paths (#48513) 2026-10-27 17:47:50 +00:00
__init__.py
conftest.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
fake_prisma_engine.py fix(proxy): cancel the Admin UI's raw spend-log reads in Postgres after 30s (#49965) 2026-11-03 16:07:00 -08:00
test_autorouter_session_rollup.py test: migrate tests/proxy_behavior into integration and unit tiers (#45939) 2026-10-11 08:28:42 -07:00
test_budget_window_spend_writer.py feat(accounting): add opt-in SpendLogs ledger (#49856) 2026-11-04 17:49:15 -08:00
test_check_migration.py feat(proxy)!: add suppress_startup_output to turn off startup prints (#47708) 2026-10-29 03:47:04 -07:00
test_create_views.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_daily_spend_bulk_upsert.py fix(proxy): bound daily spend rollup row-lock waits with lock_timeout and requeue 55P03 (#44450) 2026-10-06 17:38:55 -05:00
test_db_lookup_gate.py test: make three flaky unit tests deterministic (#50114) 2026-11-04 14:38:44 -08:00
test_db_span.py fix(otel): name postgres service spans by operation and table (#44240) 2026-10-03 09:20:28 -07:00
test_db_spend_update_writer.py feat(accounting)!: make the SpendLogs ledger the default accounting path (#49872) 2026-11-05 09:14:10 -08:00
test_db_url_settings.py fix(proxy): sign RDS IAM tokens for the database's own region (#44782) 2026-10-09 15:41:07 -07:00
test_exception_handler.py fix(proxy): treat Postgres restart and shutdown errors as DB unavailable, not poison spend-log rows (#50132) 2026-11-04 17:39:30 -08:00
test_exception_handler_reconnect_retry.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_gateway_request_tracking.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
test_health_check_latest.py fix(proxy): show the newest health check per model group on the model hub (#47552) 2026-10-20 16:42:53 -07:00
test_log_db_metrics.py fix(proxy): keep the database error when the log_db_metrics failure hook raises (#44383) 2026-10-03 16:38:15 +00:00
test_log_db_metrics_service_spans.py test: replace 61 live logging and otel tests with offline unit and integration coverage (#45362) 2026-10-08 15:55:57 -07:00
test_master_key_migration.py fix(security): remove the publicly known master key from the repo (#44718) 2026-10-06 10:55:24 -07:00
test_model_access_group_spend.py refactor(router): move router callers onto the entry points and invert the proxy imports (#48847) 2026-10-29 17:26:33 +00:00
test_model_insights_tasks.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_model_usage_rollup.py fix(responses): bill a background response once, on the first read or poll that sees it finished (#45703) 2026-10-15 11:00:14 -07:00
test_object_permission_repository.py refactor(types): replace Any with proven types in 137 files (#44478) 2026-10-05 11:01:45 -07:00
test_pgbouncer.py test(unit): keep unix socket paths in unit tests under the macOS AF_UNIX limit (#45040) 2026-10-28 20:23:22 -07:00
test_prisma_client.py feat(proxy): replace the pre-migration row check with a rolled-back dry run of the pending migrations (#48961) 2026-10-29 09:39:26 -07:00
test_prisma_planned_engine_restart.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_prisma_query_span.py fix(proxy): cancel the Admin UI's raw spend-log reads in Postgres after 30s (#49965) 2026-11-03 16:07:00 -08:00
test_prisma_self_heal.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_proxy_worker_heartbeat.py fix(otel): name postgres service spans by operation and table (#44240) 2026-10-03 09:20:28 -07:00
test_query_engine_reaper.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_rds_iam_token_expiry.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_replica_identity.py test: migrate proxy security, schema migration and MCP legacy tests (#45937) 2026-10-11 16:17:24 -07:00
test_request_error_tracking.py feat(proxy): track failed requests by HTTP status and caller (#45244) 2026-10-09 14:27:56 -07:00
test_routing_prisma_wrapper.py refactor(proxy): give database shutdown one lifespan owner (#48506) 2026-10-30 22:57:53 +00:00
test_shadow_eval_funnel.py fix(otel): name postgres service spans by operation and table (#44240) 2026-10-03 09:20:28 -07:00
test_spend_counter_reseed.py feat(redis): serve the proxy's common Redis call with Rust stores (#50170) 2026-11-06 06:01:11 +00:00
test_spend_log_batching.py test(proxy): move proxy_server, _experimental and db tests into tests/unit/proxy (#44012) 2026-10-01 18:14:24 +00:00
test_spend_log_tool_index.py fix(anthropic)!: do not surface server_tool_use as client tool_calls (#48385) 2026-11-06 03:54:34 -08:00
test_token_auth.py fix(proxy): sign RDS IAM tokens for the database's own region (#44782) 2026-10-09 15:41:07 -07:00
test_tool_registry_writer.py fix(proxy): treat Postgres restart and shutdown errors as DB unavailable, not poison spend-log rows (#50132) 2026-11-04 17:39:30 -08:00
test_tool_table_bulk_upsert.py fix(proxy): buffer tool discoveries in Redis and write LiteLLM_ToolTable in one statement per drain, on its own lock (#48089) 2026-10-24 12:34:13 -07:00
test_update_daily_tag_spend.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00