Compare commits

...

1 Commits

Author SHA1 Message Date
Yuning Wang 65468d87c9 feat: add image search content types to WebSearchTool 2026-07-16 20:55:54 +00:00
3 changed files with 47 additions and 2 deletions
+8 -1
View File
@@ -2022,9 +2022,16 @@ class Converter:
}
if tool.external_web_access is not None:
web_search_tool["external_web_access"] = tool.external_web_access
if tool.search_content_types is not None:
web_search_tool["search_content_types"] = list(tool.search_content_types)
web_search_include: ResponseIncludable | None = (
"web_search_call.results"
if tool.search_content_types is not None and "image" in tool.search_content_types
else None
)
return (
_require_responses_tool_param(web_search_tool),
None,
web_search_include,
)
elif isinstance(tool, FileSearchTool):
file_search_tool_param: FileSearchToolParam = {
+4 -1
View File
@@ -8,7 +8,7 @@ import inspect
import json
import math
import weakref
from collections.abc import Awaitable, Callable, Mapping
from collections.abc import Awaitable, Callable, Mapping, Sequence
from dataclasses import dataclass, field
from enum import Enum
from types import UnionType
@@ -706,6 +706,9 @@ class WebSearchTool:
indexed-only behavior where supported.
"""
search_content_types: Sequence[Literal["text", "image"]] | None = None
"""The content types to include in the search results. Omitting this uses the API default."""
@property
def name(self):
return "web_search"
@@ -438,6 +438,7 @@ def test_convert_tools_basic_types_and_includes():
assert web_params.get("user_location") == web_tool.user_location
assert web_params.get("search_context_size") == web_tool.search_context_size
assert "external_web_access" not in web_params
assert "search_content_types" not in web_params
# Verify computer tool uses the GA built-in tool payload.
comp_params = next(ct for ct in converted.tools if ct["type"] == "computer")
assert comp_params == {"type": "computer"}
@@ -468,6 +469,40 @@ def test_convert_tools_includes_explicit_false_external_web_access() -> None:
]
def test_convert_tools_forwards_web_search_content_types() -> None:
web_tool = WebSearchTool(search_content_types=["text", "image"])
converted = Converter.convert_tools([web_tool], handoffs=[], model="gpt-5.4")
assert converted.includes == ["web_search_call.results"]
assert converted.tools == [
{
"type": "web_search",
"filters": None,
"user_location": None,
"search_context_size": "medium",
"search_content_types": ["text", "image"],
}
]
def test_convert_tools_includes_results_for_image_only_web_search() -> None:
web_tool = WebSearchTool(search_content_types=["image"])
converted = Converter.convert_tools([web_tool], handoffs=[], model="gpt-5.4")
assert converted.includes == ["web_search_call.results"]
assert converted.tools == [
{
"type": "web_search",
"filters": None,
"user_location": None,
"search_context_size": "medium",
"search_content_types": ["image"],
}
]
def test_convert_tools_uses_preview_computer_payload_for_preview_model() -> None:
comp_tool = ComputerTool(computer=DummyComputer())