litellm/tests/test_litellm/integrations/websearch_interception
Krrish Dholakia ada9ef88ac
fix(websearch): websearch_interception agentic loop fixes for chat completions and anthropic messages (#31669)
* fix(websearch): wire chat completion agentic loop to correct hooks

maybe_run_chat_completion_agentic_loop was calling async_should_run_agentic_loop (Anthropic format) and async_run_agentic_loop (Anthropic path) instead of the chat-completion variants. This meant WebSearchInterceptionLogger never intercepted chat completion requests — the LLM returned a litellm_web_search tool_call but the agentic loop never executed, so the raw tool_calls response was returned to the caller.

Fix: gate on async_should_run_chat_completion_agentic_loop override, call that hook and async_build_chat_completion_agentic_loop_plan / async_run_chat_completion_agentic_loop in the execution path.

Regression test added.

* fix(websearch): strip tool_choice from follow-up request

When the original request forces tool_choice to litellm_web_search,
the follow-up request after search execution inherited that tool_choice,
causing the model to call the search tool again instead of synthesizing
an answer from the results.

* fix(websearch): inject api_key into agentic hook kwargs for anthropic messages

Follow-up calls inside async_run_agentic_loop (e.g. websearch interception's
synthesis call after executing Exa/Perplexity searches) were missing api_key
because the named api_key param in async_anthropic_messages_handler was never
merged into the kwargs dict forwarded downstream. Result: every /v1/messages
websearch follow-up failed with "x-api-key header is required" and the caller
received the raw tool_use response instead of the synthesized answer.

* ci: trigger CI run

* fix(websearch): support unified agentic hooks alongside chat-completion-specific hooks

CodeInterpreterInterceptionLogger uses async_should_run_agentic_loop with
_agentic_loop_api_surface to handle both surfaces from one hook. The chat
completion loop must also check _gate_overridden so callbacks using the
unified hook pattern still fire for chat completions.

* fix(websearch): strip tool_choice from legacy chat completion follow-up call

The _execute_chat_completion_agentic_loop path merged original optional_params
(which includes forced tool_choice) into follow-up params without explicit
removal. _build_chat_completion_request_patch already excluded tool_choice from
its optional_params output, but dict.update() with a missing key leaves the
original value intact. Explicit pop after the merge removes it.

* fix(websearch): always strip tool_choice from plan-path follow-up params

The tool_choice removal was gated on patch.tools is not None. WebSearch sets
tools via patch.optional_params not patch.tools, so the gate was False and
forced tool_choice from the original request survived into the synthesis call.
Move the pop outside the patch.tools branch so it applies unconditionally.
2026-07-01 09:36:40 +08:00
..
test_websearch_chat_completion.py fix(websearch): websearch_interception agentic loop fixes for chat completions and anthropic messages (#31669) 2026-07-01 09:36:40 +08:00
test_websearch_interception_handler.py fix(websearch): sync tool_choice when converting web_search tools (#31375) 2026-06-26 19:44:57 -07:00
test_websearch_interception_thinking.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_websearch_native_blocks.py Emit native web_search_tool_result blocks for Anthropic clients (Claude Desktop / Cowork citations) (#27886) 2026-05-14 12:30:47 -07:00
test_websearch_short_circuit.py Emit native web_search_tool_result blocks for Anthropic clients (Claude Desktop / Cowork citations) (#27886) 2026-05-14 12:30:47 -07:00
test_websearch_streaming_wrap.py fix(websearch): wrap agentic loop response in fake stream for streaming requests (#31484) 2026-06-26 18:45:53 -07:00
test_websearch_thinking_constraint.py Emit native web_search_tool_result blocks for Anthropic clients (Claude Desktop / Cowork citations) (#27886) 2026-05-14 12:30:47 -07:00