// 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.Kit; using Microsoft.Agents.AI.Workflows.Declarative.PowerFx; namespace Microsoft.Agents.AI.Workflows.Declarative.Interpreter; internal sealed class DelegateActionExecutor(string actionId, WorkflowFormulaState state, DelegateAction? action = null, bool emitResult = true) : DelegateActionExecutor(actionId, state, action, emitResult) { public override ValueTask HandleAsync(ActionExecutorResult message, IWorkflowContext context, CancellationToken cancellationToken) { Debug.WriteLine($"RESULT #{this.Id} - {message.Result ?? "(null)"}"); return base.HandleAsync(message, context, cancellationToken); } } internal class DelegateActionExecutor : Executor, IResettableExecutor, IModeledAction where TMessage : notnull { private readonly WorkflowFormulaState _state; private readonly DelegateAction? _action; private readonly bool _emitResult; public DelegateActionExecutor(string actionId, WorkflowFormulaState state, DelegateAction? action = null, bool emitResult = true) : base(actionId) { this._state = state; this._action = action; this._emitResult = emitResult; } protected override ProtocolBuilder ConfigureProtocol(ProtocolBuilder protocolBuilder) { ProtocolBuilder baseBuilder = base.ConfigureProtocol(protocolBuilder); if (this._emitResult) { baseBuilder.SendsMessage(); } // We chain to the provided delegate, so let the protocol know we have additional Send/Yield types that may not be // available on the HandleAsync override. return (this._action != null) ? baseBuilder.AddDelegateAttributeTypes(this._action) : baseBuilder; } /// public ValueTask ResetAsync() { return default; } [SendsMessage(typeof(ActionExecutorResult))] public override async ValueTask HandleAsync(TMessage message, IWorkflowContext context, CancellationToken cancellationToken = default) { if (this._action is not null) { await this._action.Invoke(new DeclarativeWorkflowContext(context, this._state), message, cancellationToken).ConfigureAwait(false); } if (this._emitResult) { await context.SendResultMessageAsync(this.Id, cancellationToken).ConfigureAwait(false); } } }