// Copyright (c) Microsoft. All rights reserved. using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Microsoft.Agents.AI.Workflows.Declarative.Extensions; using Microsoft.Agents.AI.Workflows.Declarative.Interpreter; namespace Microsoft.Agents.AI.Workflows.Declarative.Kit; /// /// Base class for action executors that do not consume the input message (most). /// /// The executor id /// Session to support formula expressions. public abstract class ActionExecutor(string id, FormulaSession session) : ActionExecutor(id, session) { /// protected override ValueTask ExecuteAsync(IWorkflowContext context, ActionExecutorResult message, CancellationToken cancellationToken = default) => this.ExecuteAsync(context, cancellationToken); /// /// Executes the core logic of the action. /// /// The workflow execution context providing messaging and state services. /// A token that can be used to observe cancellation. /// A representing the asynchronous execution operation. protected abstract ValueTask ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken = default); /// /// Test wether the provided value matches the value returned by the prior executor. /// /// The value to test against the message result. /// The message containing the prior executor result. /// True if the value matches the message result public static bool IsMatch(TValue value, object? message) where TValue : class { ActionExecutorResult executorMessage = ActionExecutorResult.ThrowIfNot(message); object? result = executorMessage.Result; if (result is TValue resultValue) { return value.Equals(resultValue); } return false; } } /// /// Base class for an action executor that receives the initial trigger message. /// /// The type of message being handled public abstract class ActionExecutor : Executor, IResettableExecutor where TMessage : notnull { private readonly FormulaSession _session; /// /// Initializes a new instance of the class. /// /// The executor id /// Session to support formula expressions. protected ActionExecutor(string id, FormulaSession session) : base(id) { this._session = session; } /// public ValueTask ResetAsync() { return default; } /// [SendsMessage(typeof(ActionExecutorResult))] public override async ValueTask HandleAsync(TMessage message, IWorkflowContext context, CancellationToken cancellationToken) { object? result = await this.ExecuteAsync(new DeclarativeWorkflowContext(context, this._session.State), message, cancellationToken).ConfigureAwait(false); Debug.WriteLine($"RESULT #{this.Id} - {result ?? "(null)"}"); await context.SendResultMessageAsync(this.Id, result, cancellationToken).ConfigureAwait(false); } /// /// Executes the core logic of the action. /// /// The workflow execution context providing messaging and state services. /// The the message handled by this executor. /// A token that can be used to observe cancellation. /// A representing the asynchronous execution operation. protected abstract ValueTask ExecuteAsync(IWorkflowContext context, TMessage message, CancellationToken cancellationToken = default); }