Skip to content

Fix Namespace gaps in HostedToolSearchTool#7500

Merged
jozkee merged 3 commits intomainfrom
dacantu/fix/hosted-tool-search-namespace-description
May 1, 2026
Merged

Fix Namespace gaps in HostedToolSearchTool#7500
jozkee merged 3 commits intomainfrom
dacantu/fix/hosted-tool-search-namespace-description

Conversation

@jozkee
Copy link
Copy Markdown
Member

@jozkee jozkee commented May 1, 2026

  • We were not sending a Namespace Description which is required by OpenAI.
  • We support defining multiple namespaces by passing one HostedToolSearchTool for each one, this was causing that multiple tool_search tools were being sent on the wire, which was also being rejected by OpenAI.
Microsoft Reviewers: Open in CodeFlow

Copilot AI added 2 commits May 1, 2026 14:09
Adds a NamespaceDescription property to HostedToolSearchTool and threads it through OpenAIResponsesChatClient so the namespace wrapper sent to the OpenAI Responses API includes a 'description' field when one is provided. The description is conditionally emitted only when non-null/non-empty (the live service rejects empty strings).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…stances are supplied

The OpenAI Responses API rejects requests with more than one tool_search tool in tools[] (HTTP 400: 'Only one tool_search tool is allowed in tools parameter'). When callers attach multiple HostedToolSearchTool instances - typically to scope different DeferredTools to different namespaces - AsCreateResponseOptions now emits only the first tool_search ResponseTool while still letting every instance contribute its Namespace/NamespaceDescription/DeferredTools to the namespace-grouping lookup.

The dedupe is scoped to the request-building loop rather than the shared ToResponseTool helper so the public AsOpenAIResponseTool extension still converts every HostedToolSearchTool independently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jozkee jozkee self-assigned this May 1, 2026
@jozkee jozkee requested a review from a team as a code owner May 1, 2026 19:29
Copilot AI review requested due to automatic review settings May 1, 2026 19:29
@jozkee jozkee added the area-ai Microsoft.Extensions.AI libraries label May 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the OpenAI Responses tool-search serialization to better support namespaced deferred tools, addressing service rejections due to missing namespace metadata and duplicated tool_search tool entries.

Changes:

  • Added HostedToolSearchTool.NamespaceDescription (experimental) to allow emitting a namespace description in the OpenAI payload.
  • Updated OpenAIResponsesChatClient to (a) include namespace descriptions when constructing {"type":"namespace"} tools and (b) avoid sending multiple tool_search entries when multiple HostedToolSearchTool instances are provided.
  • Expanded unit and integration tests to validate namespace descriptions and multi-namespace scenarios.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientTests.cs Updates expected JSON to avoid duplicate tool_search entries; adds non-streaming coverage for namespace descriptions and merge behavior.
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientIntegrationTests.cs Adds live round-trip tests for tool search with one/two namespaces including descriptions.
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedToolSearchToolTests.cs Adds tests for NamespaceDescription default and round-trip behavior.
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs Adds namespace description emission, tool_search deduplication, and namespace description merge behavior.
src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedToolSearchTool.cs Introduces NamespaceDescription API with XML docs clarifying behavior.
src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.json Updates API surface baseline for the new experimental property.

Comment thread src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs Outdated
…ol instances

When several HostedToolSearchTool instances share a namespace name and only some supply a NamespaceDescription, the wrapper now uses the first non-empty description rather than first-writer-wins. ToolSearchLookup.Namespace is now a class with a settable Description so all entries in _namespacedToolNames sharing a namespace name reference the same instance and pick up later upgrades automatically; this also keeps namespaceGroups (keyed by reference equality) collapsed to one bucket per namespace name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the OpenAI Responses chat client and tool-search abstractions to correctly support OpenAI “namespace” tool wrappers by allowing a namespace description to be sent, and to avoid emitting multiple tool_search entries when multiple HostedToolSearchTool instances are provided.

Changes:

  • Add NamespaceDescription to HostedToolSearchTool and include it when emitting OpenAI {"type":"namespace"} tools.
  • Ensure only one tool_search tool is sent on the wire even if multiple HostedToolSearchTool instances are configured.
  • Expand unit and integration test coverage for namespace descriptions and multi-namespace tool search scenarios.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs Emits namespace tool description (when provided) and dedupes tool_search; tracks namespaces with name+description.
src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedToolSearchTool.cs Adds NamespaceDescription API surface with remarks.
src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.json Adds API baseline entry for NamespaceDescription (Experimental).
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientTests.cs Updates expected JSON to include only one tool_search; adds tests for namespace description behaviors.
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientIntegrationTests.cs Adds live tests to validate namespace wrappers with descriptions round-trip with tool search enabled.
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedToolSearchToolTests.cs Adds unit tests for NamespaceDescription default/roundtrip.

@jozkee jozkee enabled auto-merge (squash) May 1, 2026 20:35
@jozkee jozkee merged commit 6dc5a77 into main May 1, 2026
10 checks passed
@jozkee jozkee deleted the dacantu/fix/hosted-tool-search-namespace-description branch May 1, 2026 20:38
jeffhandley pushed a commit that referenced this pull request May 1, 2026
* Add HostedToolSearchTool.NamespaceDescription support

Adds a NamespaceDescription property to HostedToolSearchTool and threads it through OpenAIResponsesChatClient so the namespace wrapper sent to the OpenAI Responses API includes a 'description' field when one is provided. The description is conditionally emitted only when non-null/non-empty (the live service rejects empty strings).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Emit a single tool_search entry when multiple HostedToolSearchTool instances are supplied

The OpenAI Responses API rejects requests with more than one tool_search tool in tools[] (HTTP 400: 'Only one tool_search tool is allowed in tools parameter'). When callers attach multiple HostedToolSearchTool instances - typically to scope different DeferredTools to different namespaces - AsCreateResponseOptions now emits only the first tool_search ResponseTool while still letting every instance contribute its Namespace/NamespaceDescription/DeferredTools to the namespace-grouping lookup.

The dedupe is scoped to the request-building loop rather than the shared ToResponseTool helper so the public AsOpenAIResponseTool extension still converts every HostedToolSearchTool independently.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Prefer first non-empty NamespaceDescription across HostedToolSearchTool instances

When several HostedToolSearchTool instances share a namespace name and only some supply a NamespaceDescription, the wrapper now uses the first non-empty description rather than first-writer-wins. ToolSearchLookup.Namespace is now a class with a settable Description so all entries in _namespacedToolNames sharing a namespace name reference the same instance and pick up later upgrades automatically; this also keeps namespaceGroups (keyed by reference equality) collapsed to one bucket per namespace name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants