mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Expand Workflow Unit Test Coverage (#5390)
* refactor: remove dead code * refactor: remove ignore YieldsMessageAttribute - the correct one to use is YieldsOutputAttribute - fixes a comment that mistakenly refers to `.YieldsMessage()` which does not exist. * fix: ChatForwardingExecutor does not use correct role for string messages - make ChatForwardingExecutor use its configured role for string messages rather than always use ChatRole.User - add ChatForwardingExecutor tests * fixup: remove unused attribute * test: Add tests for failure when .AsAgent used on a non-ChatProtocol workflow * test: Add FunctionExecutor tests - also fixes Send and YieldOutput type registration for synchronous output-returning delegates * test: Suppress CodeCoverage for obsolete names * fix: Re-add Obsolete attributes - avoid hard-breaking change - properly notify users that these attributes get ignored
This commit is contained in:
committed by
GitHub
Unverified
parent
adcd2d33f5
commit
267351b760
@@ -254,7 +254,7 @@ internal static class SemanticAnalyzer
|
||||
|
||||
/// <summary>
|
||||
/// Combines ClassProtocolInfo results into an AnalysisResult for classes that only have IO attributes
|
||||
/// (no [MessageHandler] methods). This generates only .SendsMessage/.YieldsMessage calls in the protocol
|
||||
/// (no [MessageHandler] methods). This generates only .SendsMessage/.YieldsOutput calls in the protocol
|
||||
/// configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
|
||||
@@ -9,17 +9,6 @@ namespace Microsoft.Agents.AI.Workflows;
|
||||
|
||||
internal static class AIAgentsAbstractionsExtensions
|
||||
{
|
||||
public static ChatMessage ToChatMessage(this AgentResponseUpdate update) =>
|
||||
new()
|
||||
{
|
||||
AuthorName = update.AuthorName,
|
||||
Contents = update.Contents,
|
||||
Role = update.Role ?? ChatRole.User,
|
||||
CreatedAt = update.CreatedAt,
|
||||
MessageId = update.MessageId,
|
||||
RawRepresentation = update.RawRepresentation ?? update,
|
||||
};
|
||||
|
||||
public static ChatMessage ChatAssistantToUserIfNotFromNamed(this ChatMessage message, string agentName)
|
||||
=> message.ChatAssistantToUserIfNotFromNamed(agentName, out _, false);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public sealed class ChatForwardingExecutor(string id, ChatForwardingExecutorOpti
|
||||
if (this._stringMessageChatRole.HasValue)
|
||||
{
|
||||
routeBuilder = routeBuilder.AddHandler<string>(
|
||||
(message, context) => context.SendMessageAsync(new ChatMessage(ChatRole.User, message)));
|
||||
(message, context) => context.SendMessageAsync(new ChatMessage(this._stringMessageChatRole.Value, message)));
|
||||
}
|
||||
|
||||
routeBuilder.AddHandler<ChatMessage>(ForwardMessageAsync)
|
||||
|
||||
@@ -73,7 +73,14 @@ public class FunctionExecutor<TInput>(string id,
|
||||
ExecutorOptions? options = null,
|
||||
IEnumerable<Type>? sentMessageTypes = null,
|
||||
IEnumerable<Type>? outputTypes = null,
|
||||
bool declareCrossRunShareable = false) : this(id, WrapAction(handlerSync, out var attributeSentTypes, out var attributeYieldTypes), options, attributeSentTypes.Concat(sentMessageTypes ?? []), attributeYieldTypes.Concat(outputTypes ?? []), declareCrossRunShareable)
|
||||
bool declareCrossRunShareable = false) : this(id,
|
||||
WrapAction(handlerSync,
|
||||
out var attributeSentTypes,
|
||||
out var attributeYieldTypes),
|
||||
options,
|
||||
attributeSentTypes.Concat(sentMessageTypes ?? []),
|
||||
attributeYieldTypes.Concat(outputTypes ?? []),
|
||||
declareCrossRunShareable)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -96,8 +103,18 @@ public class FunctionExecutor<TInput, TOutput>(string id,
|
||||
IEnumerable<Type>? outputTypes = null,
|
||||
bool declareCrossRunShareable = false) : Executor<TInput, TOutput>(id, options, declareCrossRunShareable)
|
||||
{
|
||||
internal static Func<TInput, IWorkflowContext, CancellationToken, ValueTask<TOutput>> WrapFunc(Func<TInput, IWorkflowContext, CancellationToken, TOutput> handlerSync)
|
||||
internal static Func<TInput, IWorkflowContext, CancellationToken, ValueTask<TOutput>> WrapFunc(Func<TInput, IWorkflowContext, CancellationToken, TOutput> handlerSync, out IEnumerable<Type> sentTypes, out IEnumerable<Type> yieldedTypes)
|
||||
{
|
||||
if (handlerSync.Method != null)
|
||||
{
|
||||
MethodInfo method = handlerSync.Method;
|
||||
(sentTypes, yieldedTypes) = method.GetAttributeTypes();
|
||||
}
|
||||
else
|
||||
{
|
||||
sentTypes = yieldedTypes = [];
|
||||
}
|
||||
|
||||
return RunFuncAsync;
|
||||
|
||||
ValueTask<TOutput> RunFuncAsync(TInput input, IWorkflowContext workflowContext, CancellationToken cancellationToken)
|
||||
@@ -133,7 +150,14 @@ public class FunctionExecutor<TInput, TOutput>(string id,
|
||||
ExecutorOptions? options = null,
|
||||
IEnumerable<Type>? sentMessageTypes = null,
|
||||
IEnumerable<Type>? outputTypes = null,
|
||||
bool declareCrossRunShareable = false) : this(id, WrapFunc(handlerSync), options, sentMessageTypes, outputTypes, declareCrossRunShareable)
|
||||
bool declareCrossRunShareable = false) : this(id,
|
||||
WrapFunc(handlerSync,
|
||||
out var attributeSentTypes,
|
||||
out var attributeYieldTypes),
|
||||
options,
|
||||
attributeSentTypes.Concat(sentMessageTypes ?? []),
|
||||
attributeYieldTypes.Concat(outputTypes ?? []),
|
||||
declareCrossRunShareable)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ internal static class DiagnosticConstants
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[ExcludeFromCodeCoverage] // This is obsolete, and 1:1 equivalent to HandoffWorkflowBuilder (no "s")
|
||||
[Obsolete("Prefer HandoffWorkflowBuilder (no 's') instead, which has the same API but the preferred name. This will be removed in a future release before GA.")]
|
||||
#pragma warning disable MAAIW001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
|
||||
public sealed class HandoffsWorkflowBuilder(AIAgent initialAgent) : HandoffWorkflowBuilderCore<HandoffsWorkflowBuilder>(initialAgent)
|
||||
|
||||
+23
@@ -29,6 +29,7 @@ namespace Microsoft.Agents.AI.Workflows;
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
[Obsolete("Use YieldsOutput instead. The Code Generator and the runtime attribute-based type mapping ignore this attribute.")]
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
|
||||
public sealed class YieldsMessageAttribute : Attribute
|
||||
{
|
||||
@@ -47,3 +48,25 @@ public sealed class YieldsMessageAttribute : Attribute
|
||||
this.Type = Throw.IfNull(type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This attribute indicates that a message handler streams messages during its execution.
|
||||
/// </summary>
|
||||
[Obsolete("This attribute does not do anything. The Code Generator and the runtime attribute-based type mapping ignore this attribute.")]
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class StreamsMessageAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the message that the handler yields.
|
||||
/// </summary>
|
||||
public Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message handler yields streaming messages during the course of execution.
|
||||
/// </summary>
|
||||
public StreamsMessageAttribute(Type type)
|
||||
{
|
||||
// This attribute is used to mark executors that yield messages.
|
||||
this.Type = Throw.IfNull(type);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
|
||||
namespace Microsoft.Agents.AI.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// This attribute indicates that a message handler streams messages during its execution.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class StreamsMessageAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the message that the handler yields.
|
||||
/// </summary>
|
||||
public Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message handler yields streaming messages during the course of execution.
|
||||
/// </summary>
|
||||
public StreamsMessageAttribute(Type type)
|
||||
{
|
||||
// This attribute is used to mark executors that yield messages.
|
||||
this.Type = Throw.IfNull(type);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user