Skip to content

Commit e387f11

Browse files
committed
Add support for stable "web_search"
1 parent 87964c3 commit e387f11

File tree

9 files changed

+15000
-14629
lines changed

9 files changed

+15000
-14629
lines changed

specification/base/typespec/responses/models.tsp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ union ToolType {
459459
file_search: "file_search",
460460
function: "function",
461461
computer_use_preview: "computer_use_preview",
462+
web_search: "web_search",
462463
web_search_preview: "web_search_preview",
463464
mcp: "mcp",
464465
code_interpreter: "code_interpreter",

src/Custom/Responses/Tools/ResponseTool.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,14 @@ public static FileSearchTool CreateFileSearchTool(IEnumerable<string> vectorStor
5050
}
5151

5252
// CUSTOM: Added factory method as a convenience.
53-
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null)
53+
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null, bool usePreview = false)
5454
{
55+
var kind = usePreview
56+
? InternalToolType.WebSearchPreview
57+
: InternalToolType.WebSearch;
58+
5559
return new WebSearchTool(
56-
kind: InternalToolType.WebSearchPreview,
60+
kind: kind,
5761
patch: default,
5862
userLocation: userLocation,
5963
searchContextSize: searchContextSize);

src/Generated/Models/Responses/InternalToolType.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace OpenAI.Responses
1414
private const string FileSearchValue = "file_search";
1515
private const string FunctionValue = "function";
1616
private const string ComputerUsePreviewValue = "computer_use_preview";
17+
private const string WebSearchValue = "web_search";
1718
private const string WebSearchPreviewValue = "web_search_preview";
1819
private const string McpValue = "mcp";
1920
private const string CodeInterpreterValue = "code_interpreter";
@@ -33,6 +34,8 @@ public InternalToolType(string value)
3334

3435
internal static InternalToolType ComputerUsePreview { get; } = new InternalToolType(ComputerUsePreviewValue);
3536

37+
internal static InternalToolType WebSearch { get; } = new InternalToolType(WebSearchValue);
38+
3639
internal static InternalToolType WebSearchPreview { get; } = new InternalToolType(WebSearchPreviewValue);
3740

3841
internal static InternalToolType Mcp { get; } = new InternalToolType(McpValue);

tests/Responses/ResponsesTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,32 @@ public async Task WebSearchCall()
160160
Assert.That(message.Content[0].OutputTextAnnotations, Has.Count.GreaterThan(0));
161161
}
162162

163+
[RecordedTest]
164+
public async Task WebSearchCallPreview()
165+
{
166+
OpenAIResponseClient client = GetTestClient();
167+
OpenAIResponse response = await client.CreateResponseAsync(
168+
"What was a positive news story from today?",
169+
new ResponseCreationOptions()
170+
{
171+
Tools =
172+
{
173+
ResponseTool.CreateWebSearchTool(usePreview: true)
174+
},
175+
ToolChoice = ResponseToolChoice.CreateWebSearchChoice()
176+
});
177+
178+
Assert.That(response.OutputItems, Has.Count.EqualTo(2));
179+
Assert.That(response.OutputItems[0], Is.InstanceOf<WebSearchCallResponseItem>());
180+
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());
181+
182+
MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
183+
Assert.That(message.Content, Has.Count.GreaterThan(0));
184+
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));
185+
Assert.That(message.Content[0].Text, Is.Not.Null.And.Not.Empty);
186+
Assert.That(message.Content[0].OutputTextAnnotations, Has.Count.GreaterThan(0));
187+
}
188+
163189
[RecordedTest]
164190
public async Task WebSearchCallStreaming()
165191
{

tests/SessionRecords/ResponsesTests/WebSearchCall.json

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
"RequestHeaders": {
77
"Accept": "application/json, text/event-stream",
88
"Authorization": "Sanitized",
9-
"Content-Length": "236",
9+
"Content-Length": "228",
1010
"Content-Type": "application/json",
11-
"User-Agent": "OpenAI/2.4.0 (.NET 9.0.9; Microsoft Windows 10.0.26100)"
11+
"User-Agent": "OpenAI/2.6.0 (.NET 9.0.10; Microsoft Windows 10.0.26200)"
1212
},
1313
"RequestBody": {
1414
"model": "gpt-4o-mini",
1515
"tools": [
1616
{
17-
"type": "web_search_preview"
17+
"type": "web_search"
1818
}
1919
],
2020
"tool_choice": {
@@ -37,27 +37,34 @@
3737
"ResponseHeaders": {
3838
"Alt-Svc": "h3=\":443\"",
3939
"cf-cache-status": "DYNAMIC",
40-
"CF-RAY": "98040fceddbcba46-SEA",
40+
"CF-RAY": "99a7d1efdcb6d44d-SEA",
4141
"Connection": "keep-alive",
42-
"Content-Length": "4945",
42+
"Content-Length": "3350",
4343
"Content-Type": "application/json",
44-
"Date": "Tue, 16 Sep 2025 23:14:48 GMT",
44+
"Date": "Thu, 06 Nov 2025 21:52:51 GMT",
4545
"openai-organization": "Sanitized",
46-
"openai-processing-ms": "4434",
46+
"openai-processing-ms": "2655",
4747
"openai-project": "Sanitized",
4848
"openai-version": "2020-10-01",
4949
"Server": "cloudflare",
50+
"Set-Cookie": [
51+
"Sanitized",
52+
"Sanitized"
53+
],
5054
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
5155
"X-Content-Type-Options": "nosniff",
52-
"x-envoy-upstream-service-time": "4438",
56+
"x-envoy-upstream-service-time": "2661",
5357
"X-Request-ID": "Sanitized"
5458
},
5559
"ResponseBody": {
56-
"id": "resp_08daec5da3ea01920068c9ef63b59881939f16cb89ba475b15",
60+
"id": "resp_07885cf5d4d5749500690d18b13b4081908aa0b6b0542c3203",
5761
"object": "response",
58-
"created_at": 1758064483,
62+
"created_at": 1762465969,
5963
"status": "completed",
6064
"background": false,
65+
"billing": {
66+
"payer": "developer"
67+
},
6168
"error": null,
6269
"incomplete_details": null,
6370
"instructions": null,
@@ -66,7 +73,7 @@
6673
"model": "gpt-4o-mini-2024-07-18",
6774
"output": [
6875
{
69-
"id": "ws_08daec5da3ea01920068c9ef63cef48193b088fe2431d5c527",
76+
"id": "ws_07885cf5d4d5749500690d18b1506881908da29ed6fb7f2f63",
7077
"type": "web_search_call",
7178
"status": "completed",
7279
"action": {
@@ -75,7 +82,7 @@
7582
}
7683
},
7784
{
78-
"id": "msg_08daec5da3ea01920068c9ef64aebc8193bde7c1b30f0dd5ac",
85+
"id": "msg_07885cf5d4d5749500690d18b20c888190a884974642062a6e",
7986
"type": "message",
8087
"status": "completed",
8188
"content": [
@@ -84,28 +91,14 @@
8491
"annotations": [
8592
{
8693
"type": "url_citation",
87-
"end_index": 761,
88-
"start_index": 648,
89-
"title": "Good News This Week: September 13, 2025 - LEGO, Koalas, & Scientists",
90-
"url": "https://www.goodgoodgood.co/articles/good-news-this-week-september-13-2025?utm_source=openai"
91-
},
92-
{
93-
"type": "url_citation",
94-
"end_index": 1334,
95-
"start_index": 1191,
96-
"title": "GNR for Tuesday, September 16, 2025 — More and more good news!",
97-
"url": "https://www.dailykos.com/story/2025/9/16/2342576/-GNR-for-Tuesday-September-16-2025-More-and-more-good-news?utm_source=openai"
98-
},
99-
{
100-
"type": "url_citation",
101-
"end_index": 1873,
102-
"start_index": 1791,
103-
"title": "The Christian Science Monitor Daily for September 16, 2025",
104-
"url": "https://www.csmonitor.com/Daily/2025/20250916?utm_source=openai"
94+
"end_index": 1063,
95+
"start_index": 978,
96+
"title": "Earthshot Prize",
97+
"url": "https://en.wikipedia.org/wiki/Earthshot_Prize?utm_source=openai"
10598
}
10699
],
107100
"logprobs": [],
108-
"text": "On September 16, 2025, several positive news stories emerged:\n\n**Environmental Conservation in Australia**\n\nThe New South Wales government in Australia announced the creation of a significant national park to protect thousands of koalas and halt logging activities. This initiative adds 176,000 hectares of forest to existing reserves, forming one of the state's largest national parks. The park aims to safeguard over 12,000 koalas and includes an immediate moratorium on logging within its boundaries. This decision follows months of advocacy from local environmental groups concerned about ongoing logging and the need for conservation efforts. ([goodgoodgood.co](https://www.goodgoodgood.co/articles/good-news-this-week-september-13-2025?utm_source=openai))\n\n**Advancements in Renewable Energy**\n\nSingapore is set to begin constructing an 86-megawatt floating solar farm on the country's largest reservoir. This project will be the third such floating solar farm in Singapore, joining two others already operational on different reservoirs. The initiative is part of Singapore's efforts to decarbonize the city-state and generate clean energy in an urban environment with limited space. ([dailykos.com](https://www.dailykos.com/story/2025/9/16/2342576/-GNR-for-Tuesday-September-16-2025-More-and-more-good-news?utm_source=openai))\n\n**Global Agreement to Curb Overfishing**\n\nA global agreement to curb overfishing took effect, requiring governments to cut subsidies to fishing fleets to help protect dwindling stocks. The World Trade Organization deal entered into force after Brazil, Kenya, Tonga, and Vietnam signed on, bringing the total to 112 countries. The organization touts the deal as its first environmental pact and the first binding multilateral deal on ocean sustainability. ([csmonitor.com](https://www.csmonitor.com/Daily/2025/20250916?utm_source=openai))\n\nThese stories highlight significant strides in environmental conservation and sustainable development worldwide. "
101+
"text": "On November 5, 2025, the Earthshot Prize 2025 awards ceremony took place at the Museum of Tomorrow in Rio de Janeiro, Brazil. The event celebrated innovative solutions to environmental challenges across five categories:\n\n- **Protect and Restore Nature**: *re.green* (Brazil) was recognized for using AI and satellite data to restore Brazil’s Atlantic Forest, planting millions of trees and creating jobs while protecting biodiversity.\n\n- **Build a Waste-Free World**: *Lagos Fashion Week* (Nigeria) was honored for promoting sustainable fashion, training designers, and reviving local craftsmanship across Africa.\n\n- **Fix our Climate**: *Friendship* (Bangladesh) received the award for providing healthcare, education, and climate resilience, restoring mangroves, and reaching millions of people.\n\nThese initiatives highlight the global commitment to environmental sustainability and the innovative approaches being implemented to address climate change and biodiversity loss. ([en.wikipedia.org](https://en.wikipedia.org/wiki/Earthshot_Prize?utm_source=openai)) "
109102
}
110103
],
111104
"role": "assistant"
@@ -114,6 +107,7 @@
114107
"parallel_tool_calls": true,
115108
"previous_response_id": null,
116109
"prompt_cache_key": null,
110+
"prompt_cache_retention": null,
117111
"reasoning": {
118112
"effort": null,
119113
"summary": null
@@ -133,7 +127,8 @@
133127
},
134128
"tools": [
135129
{
136-
"type": "web_search_preview",
130+
"type": "web_search",
131+
"filters": null,
137132
"search_context_size": "medium",
138133
"user_location": {
139134
"type": "approximate",
@@ -148,15 +143,15 @@
148143
"top_p": 1.0,
149144
"truncation": "disabled",
150145
"usage": {
151-
"input_tokens": 312,
146+
"input_tokens": 8504,
152147
"input_tokens_details": {
153148
"cached_tokens": 0
154149
},
155-
"output_tokens": 400,
150+
"output_tokens": 206,
156151
"output_tokens_details": {
157152
"reasoning_tokens": 0
158153
},
159-
"total_tokens": 712
154+
"total_tokens": 8710
160155
},
161156
"user": null,
162157
"metadata": {}

0 commit comments

Comments
 (0)