Skip to content

.NET: Throw if structured output is not supported#3726

Closed
SergeyMenshykh wants to merge 2 commits intomicrosoft:feature-sofrom
SergeyMenshykh:so-throw-if-not-supported
Closed

.NET: Throw if structured output is not supported#3726
SergeyMenshykh wants to merge 2 commits intomicrosoft:feature-sofrom
SergeyMenshykh:so-throw-if-not-supported

Conversation

@SergeyMenshykh
Copy link
Member

Motivation and Context

Currently, to use structured output (SO) with AF agents, users need to know whether a particular agent, or in the case of the ChatClientAgent, a particular chat client supports SO. If the agent supports SO, the RunAsync<T> methods can be used safely. If the agent does not support SO, then SO middleware can be used; otherwise, the user may receive a plain text response instead of an SO response, causing deserialization (accessing the response.Result property) to fail.

If users mistakenly try to get SO from an agent that does not natively support it and no SO middleware is used, it would be helpful to fail early and notify the RunAsync<T> caller that SO is not supported. However, this can only be done with agents that AF "knows" do not support SO. It won't work with agents like the ChatClientAgent, whose SO capabilities depend on the chat client being used. In those cases, it is still the user's responsibility to either use an SO-capable chat client or use middleware.

Description

  • Add the SupportsStructuredOutput property to the AIAgentMetadata class.
  • Set the property to true for two agents: ChatClientAgent and DurableAIAgent.
  • Throw an exception in the RunAsync<T> method if SO is not supported.

Copilot AI review requested due to automatic review settings February 6, 2026 12:01
@SergeyMenshykh SergeyMenshykh changed the title .NET: So throw if not supported .NET: Throw if structured output is not supported Feb 6, 2026
@SergeyMenshykh SergeyMenshykh self-assigned this Feb 6, 2026
@SergeyMenshykh SergeyMenshykh moved this to In Review in Agent Framework Feb 6, 2026
Copy link
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 pull request adds structured output support detection to the agent framework by introducing a SupportsStructuredOutput property to AIAgentMetadata. The goal is to fail early when users attempt to use RunAsync<T> with agents that don't natively support structured output, helping them understand they need to add structured output middleware.

Changes:

  • Added SupportsStructuredOutput boolean property to AIAgentMetadata with a default value of false
  • Added runtime validation in RunAsync<T> methods to throw NotSupportedException when structured output is not supported
  • Marked ChatClientAgent and DurableAIAgent as supporting structured output

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
dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgentMetadata.cs Added SupportsStructuredOutput property and constructor parameter with comprehensive XML documentation
dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgentStructuredOutput.cs Added validation to check metadata and throw NotSupportedException before processing structured output requests
dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs Set supportsStructuredOutput: true when creating agent metadata
dotnet/src/Microsoft.Agents.AI.DurableTask/DurableAIAgent.cs Added static metadata with supportsStructuredOutput: true, overrode GetService to return metadata, and added Name property override
dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/AIAgentTests.cs Added comprehensive tests for structured output support detection and metadata behavior
dotnet/tests/Microsoft.Agents.AI.DurableTask.UnitTests/DurableAIAgentTests.cs Added tests for DurableAIAgent metadata, GetService implementation, and name property

@markwallace-microsoft markwallace-microsoft added the documentation Improvements or additions to documentation label Feb 6, 2026
this._agentOptions = options?.Clone();

this._agentMetadata = new AIAgentMetadata(chatClient.GetService<ChatClientMetadata>()?.ProviderName);
this._agentMetadata = new AIAgentMetadata(chatClient.GetService<ChatClientMetadata>()?.ProviderName, supportsStructuredOutput: true);

Choose a reason for hiding this comment

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

Given we don't know the capabilities of the model associated with the chatClient what is the thinking behind setting this to be true?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm also in two minds whether it makes sense. Providing true here is technically misleading, and if the service/model does not support structured output the call will eventually fail anyway when we try and deserialize the results. If this property was only for our own consumption to fail early, it may not be as bad, but the fact that it is public to all users isn't great.
Consider for example, if a user uses this metadata to decide whether to decorate a random AIAgent from DI with a Structured Output Agent to add structured output capabilities. They would expect it to always work, but in some cases it may still fail, since we said true here, but the model may not actually support it.

Copy link
Member Author

Choose a reason for hiding this comment

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

There's no way the functionality is going to work reliably with the chat client agent. Even if the chat client exposes a way to check if SO is supported and the chat client agent uses it, it will still be up to the developer to configure the particular chat client with the model and specify if SO is supported by the model or not. If the developer mistakenly specifies that the model supports SO but it does not, AF will fail in the same way as it would without this functionality at the point of accessing the agent's SO result - response.Result. Therefore, I would suggest keeping it simple and not adding this feature.

@github-project-automation github-project-automation bot moved this from In Review to Done in Agent Framework Feb 9, 2026
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

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants