Skip to content

Add hostedtool.ToolSearch type and map it to OpenAI Responses ToolSearchToolParam - #641

Open
PratikDhanave (PratikDhanave) wants to merge 2 commits into
microsoft:mainfrom
PratikDhanaveFork:add-hostedtool-toolsearch
Open

Add hostedtool.ToolSearch type and map it to OpenAI Responses ToolSearchToolParam#641
PratikDhanave (PratikDhanave) wants to merge 2 commits into
microsoft:mainfrom
PratikDhanaveFork:add-hostedtool-toolsearch

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

What

Add a hostedtool.ToolSearch type and wire it through the OpenAI Responses provider so a deferred tool-search request can be sent to the service.

  • tool/hostedtool/hostedtool.go: new ToolSearch marker tool (fields DeferredTools, Namespace, NamespaceDescription, AdditionalProperties; Name() returns tool_search), with the usual var _ tool.Tool assertion.
  • provider/openaiprovider/responses.go: new case *hostedtool.ToolSearch that builds a responses.ToolSearchToolParam and appends responses.ToolUnionParam{OfToolSearch: &variant}, mirroring the existing WebSearch/FileSearch/CodeInterpreter/MCPServer cases.

Why

Parity with the .NET/Python stacks: Microsoft.Extensions.AI.HostedToolSearchTool exposes a hosted tool-search marker with deferred tools, but the Go port had no equivalent — the only ToolSearch occurrences were unwired auto-generated internal/azaiprojects constants. The OpenAI Go SDK (responses.ToolSearchToolParam / ToolUnionParam.OfToolSearch) already supports the wire shape, so nothing but the mapping was missing.

How tested

provider/openaiprovider/responses_test.go adds TestResponsesToolSearchTool_SerializesCorrectly, a black-box test that drives a *hostedtool.ToolSearch through RunText against the existing fake-transport harness and asserts the serialized request contains a tool_search tool (with description/execution/parameters). It fails when the provider case is removed (the tool is silently dropped) and passes with it. go build ./..., go vet, and go test ./provider/openaiprovider/... ./tool/hostedtool/... are green.

Open design questions (draft)

  • Field mapping scope. The current OpenAI ToolSearchToolParam only exposes Description, Execution, and Parameters. NamespaceDescription maps to Description, and execution/parameters are read from AdditionalProperties. DeferredTools and Namespace are carried on the type for .NET parity but have no direct field in this SDK version — should they be folded into Parameters, or is carrying them for other providers/future SDK versions the right call?
  • API shape. Should Execution be a first-class typed field on hostedtool.ToolSearch rather than an AdditionalProperties key, matching how other providers might consume it?
  • Follow-ups. Wire the same tool through the response/streaming output path (tool_search_call items) if/when needed.

@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the parity-approved Go API consistency review found no parity issues label Jul 23, 2026
@github-actions github-actions Bot added the public-api-change Pull Request changes public APIs label Jul 24, 2026
Introduce a ToolSearch hosted tool mirroring the .NET
HostedToolSearchTool, and convert it in the Responses provider to the
OpenAI ToolSearchToolParam (OfToolSearch) so deferred tool search can be
requested from the service.
@github-actions

This comment has been minimized.

@github-actions github-actions Bot removed the parity-approved Go API consistency review found no parity issues label Jul 24, 2026
# Conflicts:
#	tool/hostedtool/hostedtool.go
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Parity Review — hostedtool.ToolSearch and OpenAI Responses mapping

Summary

This PR adds a new exported type hostedtool.ToolSearch and wires it through the OpenAI Responses provider. The public-api-change label is already present and correct.

I reviewed the PR against the upstream microsoft/agent-framework (.NET) and dotnet/extensions (Microsoft.Extensions.AI) implementations. Overall semantic parity is solid, but there is one notable field-mapping gap worth calling out before this leaves draft.


✅ What aligns well

Go (hostedtool.ToolSearch) .NET (Microsoft.Extensions.AI.HostedToolSearchTool) Notes
Name()"tool_search" Name"tool_search" ✅ identical wire name
DeferredTools []string DeferredTools IList<string>? ✅ same concept
Namespace string Namespace string? ✅ same concept
NamespaceDescription string NamespaceDescription string? ✅ same concept
AdditionalProperties map[string]any AdditionalProperties IReadOnlyDictionary<string,object?> ✅ same escape hatch
var _ tool.Tool = (*ToolSearch)(nil) guard class HostedToolSearchTool : AITool ✅ both implement the common tool interface

The Go type is also structurally parallel to the other hosted-tool types already in hostedtool.go (WebSearch, FileSearch, CodeInterpreter, MCPServer), which is the right pattern for this package.


⚠️ Parity gap: Namespace and DeferredTools are silently dropped on the wire

In the .NET Microsoft.Extensions.AI.OpenAI implementation (OpenAIResponsesChatClient.cs), HostedToolSearchTool is mapped to a bare {"type": "tool_search"} object because the OpenAI .NET SDK does not yet expose a typed ToolSearchTool (openai/openai-dotnet#1053). The Namespace and DeferredTools fields drive a ToolSearchLookup mechanism that patches defer_loading: true onto other (function) tools in the list — that logic is separate from the HostedToolSearchTool → JSON conversion.

The Go PR carries Namespace and DeferredTools on the struct for future parity, and currently drops them from the wire, which is consistent with how .NET behaves today. However, .NET does apply the defer_loading patch to peer tools automatically when a HostedToolSearchTool is present. The Go provider has no equivalent, so a caller setting DeferredTools: ["read_file"] will not see defer_loading applied to that function tool on the wire.

Recommendation: Not a blocker for this PR — the wire shape (tool_search with description/execution/parameters) is correct and consistent with the OpenAI Go SDK's ToolSearchToolParam. Track the defer_loading peer-tool patching as a follow-up; this matches the open design question already noted in the PR description.


✅ Python status

No typed HostedToolSearchTool equivalent exists in python/packages/core/agent_framework/ or the foundry provider packages. Python uses a pass-through sanitization approach for hosted tools, so no Python parity issue is raised by this PR.


Verdict

The exported API shape is consistent with the upstream .NET abstraction (Microsoft.Extensions.AI.HostedToolSearchTool). The public-api-change label is correctly applied. No parity-blocking issues found; the DeferredTools/Namespacedefer_loading behavior gap is a known forward follow-up, not a regression introduced by this PR.

Generated by Go API Consistency Review Agent · sonnet46 · 72.3 AIC · ⌖ 5.95 AIC · ⊞ 5.7K ·

@PratikDhanave
PratikDhanave (PratikDhanave) marked this pull request as ready for review August 4, 2026 06:06
@PratikDhanave
PratikDhanave (PratikDhanave) requested a review from a team as a code owner August 4, 2026 06:06
Copilot AI lite review requested due to automatic review settings August 4, 2026 06:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

The new ToolSearch type’s documentation/usage implies DeferredTools/Namespace participate in provider behavior, but they are currently ignored by the OpenAI mapping (and unused elsewhere), which should be clarified to avoid misleading API consumers.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR introduces a new hosted-tool marker (hostedtool.ToolSearch) and wires it into the OpenAI Responses provider so callers can serialize a tool_search tool entry in Responses API requests, aligning the Go stack with existing .NET/Python support.

Changes:

  • Added hostedtool.ToolSearch marker type (with parity fields like DeferredTools / Namespace).
  • Updated the OpenAI Responses tool-mapping switch to serialize tool_search via responses.ToolSearchToolParam.
  • Added a black-box serialization test ensuring tool_search is emitted in the outbound request payload.
File summaries
File Description
tool/hostedtool/hostedtool.go Adds the new ToolSearch hosted tool marker type.
provider/openaiprovider/responses.go Maps *hostedtool.ToolSearch into responses.ToolSearchToolParam and appends it to params.Tools.
provider/openaiprovider/responses_test.go Adds a request-serialization test covering the new tool_search mapping.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment on lines +446 to +447
case *hostedtool.ToolSearch:
var variant responses.ToolSearchToolParam
Comment on lines +70 to +74
// ToolSearch represents a hosted tool that can be specified to an AI service
// to enable it to search over a set of deferred tools, mirroring the .NET
// Microsoft.Extensions.AI.HostedToolSearchTool. The service searches the
// deferred tools on the model's behalf so that large tool sets do not all
// need to be sent to the model up front.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

public-api-change Pull Request changes public APIs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants