Skip to content

Commit a4d5212

Browse files
committed
feat: add external web access to WebSearchTool
1 parent c2f6690 commit a4d5212

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

src/agents/models/openai_responses.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,15 +1935,16 @@ def _convert_tool(
19351935
if isinstance(tool, FunctionTool):
19361936
return cls._convert_function_tool(tool)
19371937
elif isinstance(tool, WebSearchTool):
1938+
web_search_tool: dict[str, Any] = {
1939+
"type": "web_search",
1940+
"filters": tool.filters.model_dump() if tool.filters is not None else None,
1941+
"user_location": tool.user_location,
1942+
"search_context_size": tool.search_context_size,
1943+
}
1944+
if tool.external_web_access is not None:
1945+
web_search_tool["external_web_access"] = tool.external_web_access
19381946
return (
1939-
_require_responses_tool_param(
1940-
{
1941-
"type": "web_search",
1942-
"filters": tool.filters.model_dump() if tool.filters is not None else None,
1943-
"user_location": tool.user_location,
1944-
"search_context_size": tool.search_context_size,
1945-
}
1946-
),
1947+
_require_responses_tool_param(web_search_tool),
19471948
None,
19481949
)
19491950
elif isinstance(tool, FileSearchTool):

src/agents/tool.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,13 @@ class WebSearchTool:
499499
search_context_size: Literal["low", "medium", "high"] = "medium"
500500
"""The amount of context to use for the search."""
501501

502+
external_web_access: bool | None = None
503+
"""Whether the web search tool may fetch live internet content.
504+
505+
When omitted, the API default is used. Set to `False` to request cached or
506+
indexed-only behavior where supported.
507+
"""
508+
502509
@property
503510
def name(self):
504511
return "web_search"

tests/test_openai_responses_converter.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ def test_convert_tools_basic_types_and_includes():
437437
web_params = next(ct for ct in converted.tools if ct["type"] == "web_search")
438438
assert web_params.get("user_location") == web_tool.user_location
439439
assert web_params.get("search_context_size") == web_tool.search_context_size
440+
assert "external_web_access" not in web_params
440441
# Verify computer tool uses the GA built-in tool payload.
441442
comp_params = next(ct for ct in converted.tools if ct["type"] == "computer")
442443
assert comp_params == {"type": "computer"}
@@ -450,6 +451,23 @@ def test_convert_tools_basic_types_and_includes():
450451
Converter.convert_tools(tools=[comp_tool, comp_tool], handoffs=[])
451452

452453

454+
def test_convert_tools_includes_explicit_false_external_web_access() -> None:
455+
web_tool = WebSearchTool(external_web_access=False)
456+
457+
converted = Converter.convert_tools([web_tool], handoffs=[], model="gpt-5.4")
458+
459+
assert converted.includes == []
460+
assert converted.tools == [
461+
{
462+
"type": "web_search",
463+
"filters": None,
464+
"user_location": None,
465+
"search_context_size": "medium",
466+
"external_web_access": False,
467+
}
468+
]
469+
470+
453471
def test_convert_tools_uses_preview_computer_payload_for_preview_model() -> None:
454472
comp_tool = ComputerTool(computer=DummyComputer())
455473

0 commit comments

Comments
 (0)