Skip to content

.NET: dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 br…#5450

Merged
alliscode merged 11 commits intomicrosoft:mainfrom
alliscode:toolbox-improvements
Apr 23, 2026
Merged

.NET: dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 br…#5450
alliscode merged 11 commits intomicrosoft:mainfrom
alliscode:toolbox-improvements

Conversation

@alliscode
Copy link
Copy Markdown
Member

Add FoundryToolbox and AIProjectClient extensions to Microsoft.Agents.AI.Foundry.Hosting for server-side toolbox tool integration matching Python's FoundryChatClient.get_toolbox() pattern. Tools are fetched from the Foundry project SDK and passed as server-side tools in the Responses API request.

New files:

  • FoundryToolbox.cs: Core implementation using AgentAdministrationClient SDK
  • AIProjectClientToolboxExtensions.cs: Extension methods on AIProjectClient
  • Agent_Step25_ToolboxServerSideTools sample with create helper and combine flow
  • 19 unit tests covering param validation, conversion, sanitization, and extensions

SDK breaking changes (Azure.AI.AgentServer.Responses beta.3 -> beta.4):

  • FunctionToolCallOutputResource renamed to OutputItemFunctionToolCallOutput
  • AzureAIAgentServerResponsesModelFactory made internal, replaced with direct constructors
  • ResponseUsage constructor now requires non-null token details parameters

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

…eaking changes

Add FoundryToolbox and AIProjectClient extensions to Microsoft.Agents.AI.Foundry.Hosting
for server-side toolbox tool integration matching Python's FoundryChatClient.get_toolbox()
pattern. Tools are fetched from the Foundry project SDK and passed as server-side tools
in the Responses API request.

New files:
- FoundryToolbox.cs: Core implementation using AgentAdministrationClient SDK
- AIProjectClientToolboxExtensions.cs: Extension methods on AIProjectClient
- Agent_Step25_ToolboxServerSideTools sample with create helper and combine flow
- 19 unit tests covering param validation, conversion, sanitization, and extensions

SDK breaking changes (Azure.AI.AgentServer.Responses beta.3 -> beta.4):
- FunctionToolCallOutputResource renamed to OutputItemFunctionToolCallOutput
- AzureAIAgentServerResponsesModelFactory made internal, replaced with direct constructors
- ResponseUsage constructor now requires non-null token details parameters

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 23, 2026 16:30
@moonbox3 moonbox3 added documentation Improvements or additions to documentation .NET labels Apr 23, 2026
@github-actions github-actions Bot changed the title dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 br… .NET: dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 br… Apr 23, 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

Adds .NET support for Foundry “toolbox” server-side tools (matching the Python get_toolbox() pattern) and updates the codebase to accommodate Azure.AI.AgentServer.Responses beta.4 SDK breaking changes.

Changes:

  • Introduces FoundryToolbox + AIProjectClient extension methods to fetch toolbox versions/tools and convert them to AITool instances for Responses API server-side tools.
  • Updates Foundry.Hosting converters/tests for Azure.AI.AgentServer.Responses beta.4 model/type renames and constructor changes.
  • Adds a new Foundry toolbox sample and expands unit test coverage + test data for toolbox scenarios.
Show a summary per file
File Description
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/TestDataUtil.cs Adds helpers to load new toolbox-related JSON fixtures.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/TestData/ToolboxRecordResponse.json Adds mock toolbox record payload (default version resolution).
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/TestData/ToolboxVersionResponse.json Adds mock toolbox version payload for conversion tests.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/TestData/ToolboxVersionWithDecorationFields.json Adds payload exercising sanitization of decoration fields on hosted tools.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Microsoft.Agents.AI.Foundry.UnitTests.csproj Pins Azure.AI.Projects beta for toolbox APIs; copies new test data.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/WorkflowIntegrationTests.cs Replaces removed model factory usage with direct CreateResponse construction.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/OutputConverterTests.cs Updates tests to construct CreateResponse directly.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/InputConverterTests.cs Updates tests for renamed output item types and direct constructors.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/FoundryToolboxTests.cs Adds unit tests covering toolbox fetch, conversion, and sanitization behavior.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs Updates request creation patterns for beta.4 SDK changes.
dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTelemetryTests.cs Updates request creation patterns for beta.4 SDK changes.
dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/OutputConverter.cs Adjusts ResponseUsage creation for new required token-details parameters.
dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/InputConverter.cs Updates output item handling for renamed tool-call output type.
dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/FoundryToolbox.cs Adds the core toolbox fetch + tool sanitization/conversion implementation.
dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/AIProjectClientToolboxExtensions.cs Adds AIProjectClient extension methods to fetch toolbox versions/tools.
dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/README.md Documents the new toolbox server-side tools sample.
dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/Program.cs Implements sample flows for loading/combining toolboxes and running an agent.
dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/Agent_Step25_ToolboxServerSideTools.csproj Adds the new sample project and pins Azure.AI.Projects beta.
dotnet/agent-framework-dotnet.slnx Adds the new sample project to the solution.
dotnet/Directory.Packages.props Bumps Azure.AI.AgentServer.* package versions to beta.4-compatible set.

Copilot's findings

  • Files reviewed: 20/20 changed files
  • Comments generated: 3

Comment thread dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/FoundryToolbox.cs
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 89%

✓ Correctness

This PR bumps Azure.AI.AgentServer.* package versions, adds Foundry toolbox support (FoundryToolbox, AIProjectClientToolboxExtensions), adapts to SDK type renames (FunctionToolCallOutputResource → OutputItemFunctionToolCallOutput, factory → direct constructors), and adds comprehensive unit tests. The changes are internally consistent and correctly handle the SDK API migration. No correctness bugs were found.

✓ Security Reliability

This PR adds Foundry toolbox support (new FoundryToolbox class and AIProjectClient extensions), bumps Azure SDK package versions, and adapts existing code to renamed/changed API types. From a security and reliability perspective, the changes are sound: input validation uses Throw.IfNull/IfNullOrWhitespace consistently, JSON round-tripping in SanitizeAndConvert uses standard Azure SDK ModelReaderWriter patterns, no secrets are hardcoded, environment variables are used for configuration in the sample, and DefaultAzureCredential is used for authentication. The VersionOverride in sample/test csproj files (2.1.0-beta.1 vs central 2.0.0) is intentional for toolbox API access. No security or reliability issues found.

✓ Test Coverage

The PR adds substantial test coverage for the new FoundryToolbox functionality (parameter validation, conversion, HTTP integration, extension methods). However, there are two notable test coverage gaps: (1) the error path where GetToolboxVersionCoreAsync throws InvalidOperationException when a toolbox has no default version is untested, and (2) the test named GetToolsAsync_ReturnsConvertedAIToolsAsync actually calls GetToolboxVersionAsync + ToAITools() instead of the GetToolsAsync convenience method, leaving that method without a functional test. Additionally, the SanitizeAndConvert decoration-stripping test uses a weak assertion that only checks NotNull rather than verifying the fields were actually removed.

✗ Design Approach

The toolbox-loading API addition is directionally sound, but two parts of the change take the wrong design approach: the new sample provisions its toolbox by deleting any existing fixed-name toolbox on every run, which is destructive for shared Foundry projects, and the ResponseUsage update adapts to the new SDK shape by hardcoding detail objects to zero instead of preserving the cached/reasoning token counts the framework already carries through UsageDetails elsewhere.

Flagged Issues

  • dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/Program.cs:117 unconditionally deletes and recreates a fixed-name toolbox on every run, destroying existing project state in shared Foundry projects. Use create-if-missing semantics or a unique sample-specific toolbox name so the sample doesn't mutate real resources.
  • dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/OutputConverter.cs:261-265 hardcodes token detail objects to zero, discarding UsageDetails.AdditionalCounts data that the framework preserves elsewhere (e.g., MessageMerger.cs:278-303). Map these counts into ResponseUsageInputTokensDetails and ResponseUsageOutputTokensDetails, following the same pattern used in AgentResponseExtensions.cs:247-262.

Automated review by alliscode's agents

Comment thread dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/OutputConverter.cs Outdated
Copy link
Copy Markdown
Member Author

@alliscode alliscode left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 78%

✓ Correctness

This PR bumps Azure.AI.AgentServer.* SDK packages, adapts code to breaking API changes (type renames, constructor signature changes), and adds new FoundryToolbox functionality for fetching and converting Foundry toolbox tools into AITool instances for server-side use. The changes are well-structured with thorough parameter validation, proper error handling, and comprehensive tests. I found no correctness bugs — the type renames (FunctionToolCallOutputResource → OutputItemFunctionToolCallOutput), constructor changes (ResponseUsage), and new toolbox sanitization logic all appear correct based on verified code patterns in the repository.

✓ Security Reliability

This PR adapts to Azure SDK version bumps (Azure.AI.AgentServer.Core/Invocations/Responses), adds new FoundryToolbox functionality for fetching and converting Foundry toolbox tools to AITool instances, and updates tests for renamed SDK types (FunctionToolCallOutputResource → OutputItemFunctionToolCallOutput, factory methods → direct constructors). The code follows established patterns: proper input validation via Throw.IfNull/IfNullOrWhitespace, correct async/ConfigureAwait(false) usage, and comprehensive test coverage including parameter validation, mock HTTP integration, and sanitization of decoration fields. No security vulnerabilities, injection risks, resource leaks, or unhandled failure modes were identified.

✓ Test Coverage

The PR adds Foundry toolbox support (FoundryToolbox, AIProjectClientToolboxExtensions) with good test coverage including parameter validation, conversion, mock HTTP integration, and extension method tests. Existing tests were updated to accommodate SDK type renames. However, there are two notable test coverage gaps: (1) no test for GetToolboxVersionCoreAsync when DefaultVersion is null on the toolbox record (which throws InvalidOperationException), and (2) the SanitizeAndConvert tests only cover function and code_interpreter tool types but not the custom tool type (which is also exempted from stripping) or other non-function types like mcp/web_search/file_search. Additionally, the GetToolsAsync path through the static FoundryToolbox class is only tested indirectly — the direct static method is never exercised end-to-end with mock HTTP.

✓ Design Approach

This PR adds Foundry toolbox support via a new FoundryToolbox class and AIProjectClientToolboxExtensions, bumps three Azure.AI.AgentServer.* package versions, and adapts to breaking SDK changes (type renames, removed factory methods). The design is generally sound. One notable issue: ConvertUsage in OutputConverter.cs now hardcodes 0 for inputTokensDetails and outputTokensDetails while also failing to carry forward existing.InputTokensDetails/existing.OutputTokensDetails during accumulation — meaning that if a future UsageDetails source ever provides cached or audio token counts, they will be silently dropped on the second and subsequent accumulation pass. The SanitizeAndConvert JSON round-trip workaround is an unavoidable consequence of an external API mismatch (toolbox API adds decoration fields that the Responses API rejects on hosted tool types), is clearly documented, and has no cleaner alternative given sealed SDK model types. The shift from AzureAIAgentServerResponsesModelFactory factory methods to direct object initializers throughout tests is correctly driven by the SDK bump removing those factory overloads.

Suggestions

  • Expand SanitizeAndConvert test coverage beyond "function" and "code_interpreter" to include the "custom" tool type (which shares the preservation path at FoundryToolbox.cs line 162) and an MCP tool type with decoration fields to verify stripping works for the real-world hosted tool scenario mentioned in the sample and code comments.
  • In ConvertUsage (OutputConverter.cs), the accumulation of existing discards existing.InputTokensDetails and existing.OutputTokensDetails, replacing them with hardcoded 0. The accumulation loop already carries forward raw token counts from existing; the details should be treated consistently so that if UsageDetails gains cached/audio token fields, the second call in a multi-update stream does not silently zero out values from the first call.

Automated review by alliscode's agents

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@alliscode alliscode marked this pull request as ready for review April 23, 2026 17:17
Static local functions cannot capture top-level variables. Thread the
endpoint parameter through Main, CombineToolboxes, and CreateSampleToolboxAsync.

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

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 87%

✗ Correctness

The PR adds Foundry toolbox support with new extension methods, tests, and a sample. Beyond the existing unresolved review comments (which I will not duplicate), I found two new issues: (1) the sample's CreateSampleToolboxAsync is a static local function that references the enclosing top-level variable endpoint, which is a C# compile error (CS8421), and (2) the README documents env var names (AZURE_AI_PROJECT_ENDPOINT, AZURE_AI_MODEL_DEPLOYMENT_NAME) that don't match the code (FOUNDRY_PROJECT_ENDPOINT_2, FOUNDRY_MODEL), and the error message at line 28 also references the wrong env var name.

✗ Security Reliability

The PR adds Foundry toolbox support with new extension methods, a sample, and corresponding tests. The most notable new issue is a misleading environment variable name in the sample: the code reads FOUNDRY_PROJECT_ENDPOINT_2 but the error message and README both reference AZURE_AI_PROJECT_ENDPOINT, which will confuse users who follow the documentation. The existing unresolved comments about hardcoded zero usage details, whitespace validation on DefaultVersion, the sample re-creating clients, and README wording remain valid and are not restated here.

✗ Test Coverage

The new FoundryToolbox feature has good test coverage for the happy paths (parameter validation, tool conversion, HTTP integration with mocks, extension methods). However, there are two notable test coverage gaps: (1) the error path in GetToolboxVersionCoreAsync where DefaultVersion is null is not tested, and (2) the existing usage/token tests in OutputConverterTests only assert that a ResponseCompletedEvent exists — none verify the actual token counts or the newly added inputTokensDetails/outputTokensDetails fields, making the ConvertUsage change effectively untested beyond 'no exception'.

✗ Design Approach

Beyond the issues already raised on this PR, I found one additional design problem: the new Step25 sample exposes a one-off environment-variable contract (FOUNDRY_PROJECT_ENDPOINT_2 / FOUNDRY_MODEL) that diverges from the rest of the Foundry samples and from its own README. That leaks a local setup detail into a public sample, so readers who follow the documented sample conventions will configure the wrong variables and fail before they reach the toolbox scenario itself.

Flagged Issues

  • Program.cs: CreateSampleToolboxAsync is declared static but captures the top-level variable endpoint, producing CS8421. Either remove static or pass endpoint as a parameter.

Suggestions

  • The existing usage tests (ConvertUpdatesToEventsAsync_UsageContent_IncludesUsageInCompletedAsync, MultipleUsageUpdates_AccumulatesTokensAsync) only assert that a ResponseCompletedEvent is emitted — they never verify actual InputTokens/OutputTokens/TotalTokens values. Adding assertions on the Usage property would catch regressions, especially given the ConvertUsage changes adding detail objects.

Automated review by alliscode's agents

alliscode and others added 2 commits April 23, 2026 10:28
…sync

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…xServerSideTools/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
alliscode and others added 2 commits April 23, 2026 10:30
…xServerSideTools/Program.cs

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
…xServerSideTools/Program.cs

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
Comment thread dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/FoundryToolbox.cs
…dcoding zeros

Extract InputTokenDetails.CachedTokenCount and OutputTokenDetails.ReasoningTokenCount
from UsageDetails.AdditionalCounts, matching the pattern in AgentResponseExtensions.
Also accumulate detail counts when merging with existing usage.

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

documentation Improvements or additions to documentation .NET

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants