Files
agent-framework/dotnet/tests/AgentConformance.IntegrationTests/RunTests.cs
T
westey 715769e649 Run Response ADR & Updates (#104)
* Add ADR for different run response options

* Add another option to the list.

* Update agno non-streaming with further clarification

* Add another option

* Adding optional includeUpdates option

* Adding Pros/Cons for each option

* Make pros/cons a list

* Add some thoughts on structured outputs and custom AIContent types

* Update design doc to clarify primary and secondary better and split out custom response types with it's own options

* Add structured outputs competitive comparison and suggestion

* Address PR comments.

* Remove AgentRunFinishReason until we can find a good use case for it.

* Add finish reason to list of excluded properties.

* Add custom agent run response types.
Usage to follow.

* Update Agent run response types

* Add additional code coverage

* Remove onIntermediateMessage since it is unecessary with the new response approach.

* Add AgentId to response.

* Rename ParseAsStructuredOutput to Deserialize

* Update decision doc.

* Fix formatting.

* Update CopilotStudio to return new response types

* Address PR comment

Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>

---------

Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2025-07-11 11:39:18 +00:00

119 lines
4.1 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Linq;
using System.Threading.Tasks;
using AgentConformance.IntegrationTests.Support;
using Microsoft.Extensions.AI;
namespace AgentConformance.IntegrationTests;
/// <summary>
/// Conformance tests for run methods on agents.
/// </summary>
/// <typeparam name="TAgentFixture">The type of test fixture used by the concrete test implementation.</typeparam>
/// <param name="createAgentFixture">Function to create the test fixture with.</param>
public abstract class RunTests<TAgentFixture>(Func<TAgentFixture> createAgentFixture) : AgentTests<TAgentFixture>(createAgentFixture)
where TAgentFixture : IAgentFixture
{
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
public virtual async Task RunWithNoMessageDoesNotFailAsync()
{
// Arrange
var agent = this.Fixture.Agent;
var thread = agent.GetNewThread();
await using var cleanup = new ThreadCleanup(thread, this.Fixture);
// Act
var chatResponse = await agent.RunAsync(thread);
// Assert
Assert.NotNull(chatResponse);
}
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
public virtual async Task RunWithStringReturnsExpectedResultAsync()
{
// Arrange
var agent = this.Fixture.Agent;
var thread = agent.GetNewThread();
await using var cleanup = new ThreadCleanup(thread, this.Fixture);
// Act
var response = await agent.RunAsync("What is the capital of France.", thread);
// Assert
Assert.NotNull(response);
Assert.Single(response.Messages);
Assert.Contains("Paris", response.Text);
Assert.Equal(agent.Id, response.AgentId);
}
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
public virtual async Task RunWithChatMessageReturnsExpectedResultAsync()
{
// Arrange
var agent = this.Fixture.Agent;
var thread = agent.GetNewThread();
await using var cleanup = new ThreadCleanup(thread, this.Fixture);
// Act
var response = await agent.RunAsync(new ChatMessage(ChatRole.User, "What is the capital of France."), thread);
// Assert
Assert.NotNull(response);
Assert.Single(response.Messages);
Assert.Contains("Paris", response.Text);
}
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
public virtual async Task RunWithChatMessagesReturnsExpectedResultAsync()
{
// Arrange
var agent = this.Fixture.Agent;
var thread = agent.GetNewThread();
await using var cleanup = new ThreadCleanup(thread, this.Fixture);
// Act
var response = await agent.RunAsync(
[
new ChatMessage(ChatRole.User, "Hello."),
new ChatMessage(ChatRole.User, "What is the capital of France.")
],
thread);
// Assert
Assert.NotNull(response);
Assert.Single(response.Messages);
Assert.Contains("Paris", response.Text);
}
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
public virtual async Task ThreadMaintainsHistoryAsync()
{
// Arrange
var q1 = "What is the capital of France.";
var q2 = "And Austria?";
var agent = this.Fixture.Agent;
var thread = agent.GetNewThread();
await using var cleanup = new ThreadCleanup(thread, this.Fixture);
// Act
var result1 = await agent.RunAsync(q1, thread);
var result2 = await agent.RunAsync(q2, thread);
// Assert
Assert.Contains("Paris", result1.Text);
Assert.Contains("Vienna", result2.Text);
var chatHistory = await this.Fixture.GetChatHistoryAsync(thread);
Assert.Equal(4, chatHistory.Count);
Assert.Equal(2, chatHistory.Count(x => x.Role == ChatRole.User));
Assert.Equal(2, chatHistory.Count(x => x.Role == ChatRole.Assistant));
Assert.Equal(q1, chatHistory[0].Text);
Assert.Equal(q2, chatHistory[2].Text);
Assert.Contains("Paris", chatHistory[1].Text);
Assert.Contains("Vienna", chatHistory[3].Text);
}
}