Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/OpenAI.net8.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6057,7 +6057,7 @@ public class ResponseTool : IJsonModel<ResponseTool>, IPersistableModel<Response
public static ImageGenerationTool CreateImageGenerationTool(string model, ImageGenerationToolQuality? quality = null, ImageGenerationToolSize? size = null, ImageGenerationToolOutputFileFormat? outputFileFormat = null, int? outputCompressionFactor = null, ImageGenerationToolModerationLevel? moderationLevel = null, ImageGenerationToolBackground? background = null, ImageGenerationToolInputFidelity? inputFidelity = null, ImageGenerationToolInputImageMask inputImageMask = null, int? partialImageCount = null);
public static McpTool CreateMcpTool(string serverLabel, McpToolConnectorId connectorId, string authorizationToken = null, string serverDescription = null, IDictionary<string, string> headers = null, McpToolFilter allowedTools = null, McpToolCallApprovalPolicy toolCallApprovalPolicy = null);
public static McpTool CreateMcpTool(string serverLabel, Uri serverUri, string authorizationToken = null, string serverDescription = null, IDictionary<string, string> headers = null, McpToolFilter allowedTools = null, McpToolCallApprovalPolicy toolCallApprovalPolicy = null);
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null);
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null, bool usePreview = false);
protected virtual ResponseTool JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
protected virtual ResponseTool PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
Expand Down
2 changes: 1 addition & 1 deletion api/OpenAI.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5319,7 +5319,7 @@ public class ResponseTool : IJsonModel<ResponseTool>, IPersistableModel<Response
public static ImageGenerationTool CreateImageGenerationTool(string model, ImageGenerationToolQuality? quality = null, ImageGenerationToolSize? size = null, ImageGenerationToolOutputFileFormat? outputFileFormat = null, int? outputCompressionFactor = null, ImageGenerationToolModerationLevel? moderationLevel = null, ImageGenerationToolBackground? background = null, ImageGenerationToolInputFidelity? inputFidelity = null, ImageGenerationToolInputImageMask inputImageMask = null, int? partialImageCount = null);
public static McpTool CreateMcpTool(string serverLabel, McpToolConnectorId connectorId, string authorizationToken = null, string serverDescription = null, IDictionary<string, string> headers = null, McpToolFilter allowedTools = null, McpToolCallApprovalPolicy toolCallApprovalPolicy = null);
public static McpTool CreateMcpTool(string serverLabel, Uri serverUri, string authorizationToken = null, string serverDescription = null, IDictionary<string, string> headers = null, McpToolFilter allowedTools = null, McpToolCallApprovalPolicy toolCallApprovalPolicy = null);
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null);
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null, bool usePreview = false);
protected virtual ResponseTool JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
protected virtual ResponseTool PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options);
Expand Down
1 change: 1 addition & 0 deletions specification/base/typespec/responses/models.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ union ToolType {
file_search: "file_search",
function: "function",
computer_use_preview: "computer_use_preview",
web_search: "web_search",
web_search_preview: "web_search_preview",
mcp: "mcp",
code_interpreter: "code_interpreter",
Expand Down
8 changes: 6 additions & 2 deletions src/Custom/Responses/Tools/ResponseTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ public static FileSearchTool CreateFileSearchTool(IEnumerable<string> vectorStor
}

// CUSTOM: Added factory method as a convenience.
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null)
public static WebSearchTool CreateWebSearchTool(WebSearchToolLocation userLocation = null, WebSearchToolContextSize? searchContextSize = null, bool usePreview = false)
{
var kind = usePreview
? InternalToolType.WebSearchPreview
: InternalToolType.WebSearch;

return new WebSearchTool(
kind: InternalToolType.WebSearchPreview,
kind: kind,
patch: default,
userLocation: userLocation,
searchContextSize: searchContextSize);
Expand Down
3 changes: 3 additions & 0 deletions src/Generated/Models/Responses/InternalToolType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace OpenAI.Responses
private const string FileSearchValue = "file_search";
private const string FunctionValue = "function";
private const string ComputerUsePreviewValue = "computer_use_preview";
private const string WebSearchValue = "web_search";
private const string WebSearchPreviewValue = "web_search_preview";
private const string McpValue = "mcp";
private const string CodeInterpreterValue = "code_interpreter";
Expand All @@ -33,6 +34,8 @@ public InternalToolType(string value)

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

internal static InternalToolType WebSearch { get; } = new InternalToolType(WebSearchValue);

internal static InternalToolType WebSearchPreview { get; } = new InternalToolType(WebSearchPreviewValue);

internal static InternalToolType Mcp { get; } = new InternalToolType(McpValue);
Expand Down
26 changes: 26 additions & 0 deletions tests/Responses/ResponsesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,32 @@ public async Task WebSearchCall()
Assert.That(message.Content[0].OutputTextAnnotations, Has.Count.GreaterThan(0));
}

[RecordedTest]
public async Task WebSearchCallPreview()
{
OpenAIResponseClient client = GetTestClient();
OpenAIResponse response = await client.CreateResponseAsync(
"What was a positive news story from today?",
new ResponseCreationOptions()
{
Tools =
{
ResponseTool.CreateWebSearchTool(usePreview: true)
},
ToolChoice = ResponseToolChoice.CreateWebSearchChoice()
});

Assert.That(response.OutputItems, Has.Count.EqualTo(2));
Assert.That(response.OutputItems[0], Is.InstanceOf<WebSearchCallResponseItem>());
Assert.That(response.OutputItems[1], Is.InstanceOf<MessageResponseItem>());

MessageResponseItem message = (MessageResponseItem)response.OutputItems[1];
Assert.That(message.Content, Has.Count.GreaterThan(0));
Assert.That(message.Content[0].Kind, Is.EqualTo(ResponseContentPartKind.OutputText));
Assert.That(message.Content[0].Text, Is.Not.Null.And.Not.Empty);
Assert.That(message.Content[0].OutputTextAnnotations, Has.Count.GreaterThan(0));
}

[RecordedTest]
public async Task WebSearchCallStreaming()
{
Expand Down
65 changes: 30 additions & 35 deletions tests/SessionRecords/ResponsesTests/WebSearchCall.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
"RequestHeaders": {
"Accept": "application/json, text/event-stream",
"Authorization": "Sanitized",
"Content-Length": "236",
"Content-Length": "228",
"Content-Type": "application/json",
"User-Agent": "OpenAI/2.4.0 (.NET 9.0.9; Microsoft Windows 10.0.26100)"
"User-Agent": "OpenAI/2.6.0 (.NET 9.0.10; Microsoft Windows 10.0.26200)"
},
"RequestBody": {
"model": "gpt-4o-mini",
"tools": [
{
"type": "web_search_preview"
"type": "web_search"
}
],
"tool_choice": {
Expand All @@ -37,27 +37,34 @@
"ResponseHeaders": {
"Alt-Svc": "h3=\":443\"",
"cf-cache-status": "DYNAMIC",
"CF-RAY": "98040fceddbcba46-SEA",
"CF-RAY": "99a7d1efdcb6d44d-SEA",
"Connection": "keep-alive",
"Content-Length": "4945",
"Content-Length": "3350",
"Content-Type": "application/json",
"Date": "Tue, 16 Sep 2025 23:14:48 GMT",
"Date": "Thu, 06 Nov 2025 21:52:51 GMT",
"openai-organization": "Sanitized",
"openai-processing-ms": "4434",
"openai-processing-ms": "2655",
"openai-project": "Sanitized",
"openai-version": "2020-10-01",
"Server": "cloudflare",
"Set-Cookie": [
"Sanitized",
"Sanitized"
],
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
"X-Content-Type-Options": "nosniff",
"x-envoy-upstream-service-time": "4438",
"x-envoy-upstream-service-time": "2661",
"X-Request-ID": "Sanitized"
},
"ResponseBody": {
"id": "resp_08daec5da3ea01920068c9ef63b59881939f16cb89ba475b15",
"id": "resp_07885cf5d4d5749500690d18b13b4081908aa0b6b0542c3203",
"object": "response",
"created_at": 1758064483,
"created_at": 1762465969,
"status": "completed",
"background": false,
"billing": {
"payer": "developer"
},
"error": null,
"incomplete_details": null,
"instructions": null,
Expand All @@ -66,7 +73,7 @@
"model": "gpt-4o-mini-2024-07-18",
"output": [
{
"id": "ws_08daec5da3ea01920068c9ef63cef48193b088fe2431d5c527",
"id": "ws_07885cf5d4d5749500690d18b1506881908da29ed6fb7f2f63",
"type": "web_search_call",
"status": "completed",
"action": {
Expand All @@ -75,7 +82,7 @@
}
},
{
"id": "msg_08daec5da3ea01920068c9ef64aebc8193bde7c1b30f0dd5ac",
"id": "msg_07885cf5d4d5749500690d18b20c888190a884974642062a6e",
"type": "message",
"status": "completed",
"content": [
Expand All @@ -84,28 +91,14 @@
"annotations": [
{
"type": "url_citation",
"end_index": 761,
"start_index": 648,
"title": "Good News This Week: September 13, 2025 - LEGO, Koalas, & Scientists",
"url": "https://www.goodgoodgood.co/articles/good-news-this-week-september-13-2025?utm_source=openai"
},
{
"type": "url_citation",
"end_index": 1334,
"start_index": 1191,
"title": "GNR for Tuesday, September 16, 2025 — More and more good news!",
"url": "https://www.dailykos.com/story/2025/9/16/2342576/-GNR-for-Tuesday-September-16-2025-More-and-more-good-news?utm_source=openai"
},
{
"type": "url_citation",
"end_index": 1873,
"start_index": 1791,
"title": "The Christian Science Monitor Daily for September 16, 2025",
"url": "https://www.csmonitor.com/Daily/2025/20250916?utm_source=openai"
"end_index": 1063,
"start_index": 978,
"title": "Earthshot Prize",
"url": "https://en.wikipedia.org/wiki/Earthshot_Prize?utm_source=openai"
}
],
"logprobs": [],
"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. "
"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)) "
}
],
"role": "assistant"
Expand All @@ -114,6 +107,7 @@
"parallel_tool_calls": true,
"previous_response_id": null,
"prompt_cache_key": null,
"prompt_cache_retention": null,
"reasoning": {
"effort": null,
"summary": null
Expand All @@ -133,7 +127,8 @@
},
"tools": [
{
"type": "web_search_preview",
"type": "web_search",
"filters": null,
"search_context_size": "medium",
"user_location": {
"type": "approximate",
Expand All @@ -148,15 +143,15 @@
"top_p": 1.0,
"truncation": "disabled",
"usage": {
"input_tokens": 312,
"input_tokens": 8504,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 400,
"output_tokens": 206,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 712
"total_tokens": 8710
},
"user": null,
"metadata": {}
Expand Down
Loading
Loading