Files
agent-framework/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/ConditionGroupExecutor.cs
T
CopilotGitHubcrickmancopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Chris Rickman
349d645cfc .NET Workflows - Add unit tests for ConditionGroupExecutor (#3893)
* Initial plan

* Add ConditionGroupExecutorTest with comprehensive test coverage

Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>

* Address code review feedback - extract reflection helper and improve comments

Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>

* Ready

* Namespace

* Cleanup

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
Co-authored-by: Chris Rickman <crickman@microsoft.com>
2026-02-17 16:35:23 +00:00

75 lines
2.7 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Agents.AI.Workflows.Declarative.Extensions;
using Microsoft.Agents.AI.Workflows.Declarative.Interpreter;
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
using Microsoft.Agents.AI.Workflows.Declarative.PowerFx;
using Microsoft.Agents.ObjectModel;
using Microsoft.Agents.ObjectModel.Abstractions;
namespace Microsoft.Agents.AI.Workflows.Declarative.ObjectModel;
internal sealed class ConditionGroupExecutor : DeclarativeActionExecutor<ConditionGroup>
{
public static class Steps
{
public static string Item(ConditionGroup model, ConditionItem conditionItem)
{
if (conditionItem.Id is not null)
{
return conditionItem.Id;
}
int index = model.Conditions.IndexOf(conditionItem);
return $"{model.Id}_Items{index}";
}
public static string Else(ConditionGroup model) => model.ElseActions.Id.Value;
}
public ConditionGroupExecutor(ConditionGroup model, WorkflowFormulaState state)
: base(model, state)
{
}
protected override bool IsDiscreteAction => false;
public bool IsMatch(ConditionItem conditionItem, object? message)
{
ActionExecutorResult executorMessage = ActionExecutorResult.ThrowIfNot(message);
return string.Equals(Steps.Item(this.Model, conditionItem), executorMessage.Result as string, StringComparison.Ordinal);
}
public bool IsElse(object? message)
{
ActionExecutorResult executorMessage = ActionExecutorResult.ThrowIfNot(message);
return string.Equals(Steps.Else(this.Model), executorMessage.Result as string, StringComparison.Ordinal);
}
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken = default)
{
for (int index = 0; index < this.Model.Conditions.Length; ++index)
{
ConditionItem conditionItem = this.Model.Conditions[index];
if (conditionItem.Condition is null)
{
continue; // Skip if no condition is defined
}
EvaluationResult<bool> expressionResult = this.Evaluator.GetValue(conditionItem.Condition);
if (expressionResult.Value)
{
return Steps.Item(this.Model, conditionItem);
}
}
return Steps.Else(this.Model);
}
public async ValueTask DoneAsync(IWorkflowContext context, ActionExecutorResult _, CancellationToken cancellationToken) =>
await context.RaiseCompletionEventAsync(this.Model, cancellationToken).ConfigureAwait(false);
}