mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
a3a9147e61
* Rename AgentThread to AgentSession * Add more renames * Update readme files * Revert nullable variable change and further fixes. * Revert change in header name * Fix some comments and tests * Update changelog. * Address PR feedback. * Fixing code review comments. * Fix new errors after merging latest code.
115 lines
4.2 KiB
C#
115 lines
4.2 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using FluentAssertions;
|
|
using Microsoft.Extensions.AI;
|
|
|
|
namespace Microsoft.Agents.AI.Workflows.UnitTests;
|
|
|
|
public sealed class ExpectedException : Exception
|
|
{
|
|
public ExpectedException(string message)
|
|
: base(message)
|
|
{
|
|
}
|
|
|
|
public ExpectedException() : base()
|
|
{
|
|
}
|
|
|
|
public ExpectedException(string? message, Exception? innerException) : base(message, innerException)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class WorkflowHostSmokeTests
|
|
{
|
|
private sealed class AlwaysFailsAIAgent(bool failByThrowing) : AIAgent
|
|
{
|
|
private sealed class Session : InMemoryAgentSession
|
|
{
|
|
public Session() { }
|
|
|
|
public Session(JsonElement serializedSession, JsonSerializerOptions? jsonSerializerOptions = null)
|
|
: base(serializedSession, jsonSerializerOptions)
|
|
{ }
|
|
}
|
|
|
|
public override ValueTask<AgentSession> DeserializeSessionAsync(JsonElement serializedSession, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
|
|
{
|
|
return new(new Session(serializedSession, jsonSerializerOptions));
|
|
}
|
|
|
|
public override ValueTask<AgentSession> GetNewSessionAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
return new(new Session());
|
|
}
|
|
|
|
protected override async Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
|
|
{
|
|
return await this.RunStreamingAsync(messages, session, options, cancellationToken)
|
|
.ToAgentResponseAsync(cancellationToken);
|
|
}
|
|
|
|
protected override async IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
const string ErrorMessage = "Simulated agent failure.";
|
|
if (failByThrowing)
|
|
{
|
|
throw new ExpectedException(ErrorMessage);
|
|
}
|
|
|
|
yield return new AgentResponseUpdate(ChatRole.Assistant, [new ErrorContent(ErrorMessage)]);
|
|
}
|
|
}
|
|
|
|
private static Workflow CreateWorkflow(bool failByThrowing)
|
|
{
|
|
ExecutorBinding agent = new AlwaysFailsAIAgent(failByThrowing).BindAsExecutor(emitEvents: true);
|
|
|
|
return new WorkflowBuilder(agent).Build();
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true, true)]
|
|
[InlineData(true, false)]
|
|
[InlineData(false, true)]
|
|
[InlineData(false, false)]
|
|
public async Task Test_AsAgent_ErrorContentStreamedOutAsync(bool includeExceptionDetails, bool failByThrowing)
|
|
{
|
|
string expectedMessage = !failByThrowing || includeExceptionDetails
|
|
? "Simulated agent failure."
|
|
: "An error occurred while executing the workflow.";
|
|
|
|
// Arrange is done by the caller.
|
|
Workflow workflow = CreateWorkflow(failByThrowing);
|
|
|
|
// Act
|
|
List<AgentResponseUpdate> updates = await workflow.AsAgent("WorkflowAgent", includeExceptionDetails: includeExceptionDetails)
|
|
.RunStreamingAsync(new ChatMessage(ChatRole.User, "Hello"))
|
|
.ToListAsync();
|
|
|
|
// Assert
|
|
bool hadErrorContent = false;
|
|
foreach (AgentResponseUpdate update in updates)
|
|
{
|
|
if (update.Contents.Any())
|
|
{
|
|
// We should expect a single update which contains the error content.
|
|
update.Contents.Should().ContainSingle()
|
|
.Which.Should().BeOfType<ErrorContent>()
|
|
.Which.Message.Should().Be(expectedMessage);
|
|
hadErrorContent = true;
|
|
}
|
|
}
|
|
|
|
hadErrorContent.Should().BeTrue();
|
|
}
|
|
}
|