// Copyright (c) Microsoft. All rights reserved. using System.Threading.Tasks; using AgentConformance.IntegrationTests; using AgentConformance.IntegrationTests.Support; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; using Shared.IntegrationTests; namespace Foundry.IntegrationTests; public class ResponsesAgentStructuredOutputRunTests() : StructuredOutputRunTests>(() => new()) { private const string NotSupported = "The direct Responses AsAIAgent path does not support specifying structured output type at invocation time."; /// /// Verifies that response format provided at agent initialization is used when invoking RunAsync. /// [RetryFact(Constants.RetryCount, Constants.RetryDelay)] public async Task RunWithResponseFormatAtAgentInitializationReturnsExpectedResultAsync() { // Arrange AIAgent agent = this.Fixture.Agent; AgentSession session = await agent.CreateSessionAsync(); await using var cleanup = new SessionCleanup(session, this.Fixture); // Act AgentResponse response = await agent.RunAsync(new ChatMessage(ChatRole.User, "Provide information about the capital of France."), session); // Assert Assert.NotNull(response); Assert.Single(response.Messages); Assert.Contains("Paris", response.Text); Assert.True(TryDeserialize(response.Text, AgentAbstractionsJsonUtilities.DefaultOptions, out CityInfo cityInfo)); Assert.Equal("Paris", cityInfo.Name); } /// /// Verifies that generic RunAsync works when structured output is configured at agent initialization. /// [RetryFact(Constants.RetryCount, Constants.RetryDelay)] public async Task RunGenericWithResponseFormatAtAgentInitializationReturnsExpectedResultAsync() { // Arrange AIAgent agent = this.Fixture.Agent; AgentSession session = await agent.CreateSessionAsync(); await using var cleanup = new SessionCleanup(session, this.Fixture); // Act AgentResponse response = await agent.RunAsync( new ChatMessage(ChatRole.User, "Provide information about the capital of France."), session); // Assert Assert.NotNull(response); Assert.Single(response.Messages); Assert.Contains("Paris", response.Text); Assert.NotNull(response.Result); Assert.Equal("Paris", response.Result.Name); } public override Task RunWithGenericTypeReturnsExpectedResultAsync() { Assert.Skip(NotSupported); return base.RunWithGenericTypeReturnsExpectedResultAsync(); } public override Task RunWithResponseFormatReturnsExpectedResultAsync() { Assert.Skip(NotSupported); return base.RunWithResponseFormatReturnsExpectedResultAsync(); } public override Task RunWithPrimitiveTypeReturnsExpectedResultAsync() { Assert.Skip(NotSupported); return base.RunWithPrimitiveTypeReturnsExpectedResultAsync(); } } /// /// Fixture for testing the direct Responses path with structured output of type provided at agent initialization. /// public class ResponsesAgentStructuredOutputFixture : ResponsesAgentFixture { public override ValueTask InitializeAsync() { ChatClientAgentOptions agentOptions = new() { ChatOptions = new ChatOptions() { ModelId = TestConfiguration.GetRequiredValue(TestSettings.AzureAIModelDeploymentName), ResponseFormat = ChatResponseFormat.ForJsonSchema(AgentAbstractionsJsonUtilities.DefaultOptions) }, }; return this.InitializeAsync(agentOptions); } }