mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET Workflows - Fix code generation cases (#1242)
* Updated * Passing * Ready * Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/ConversationMessages.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Comment * Code analysis * Unit-tests/provider signature * Comment * Consistent * Checkpoint * Fixed * Revert * Test display name * Enable tests --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
+2
-2
@@ -60,8 +60,8 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen
|
||||
"is.Id}\");\n }\n ChatMessage newMessage = new(ChatRole.");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(FormatEnum(this.Model.Role, RoleMap)));
|
||||
this.Write(", await this.GetContentAsync(context).ConfigureAwait(false)) { AdditionalProperti" +
|
||||
"es = this.GetMetadata() };\n await agentProvider.CreateMessageAsync(conver" +
|
||||
"sationId, newMessage, cancellationToken).ConfigureAwait(false);");
|
||||
"es = this.GetMetadata() };\n newMessage = await agentProvider.CreateMessag" +
|
||||
"eAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);");
|
||||
|
||||
AssignVariable(this.Message, "newMessage");
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA
|
||||
throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}");
|
||||
}
|
||||
ChatMessage newMessage = new(ChatRole.<#= FormatEnum(this.Model.Role, RoleMap) #>, await this.GetContentAsync(context).ConfigureAwait(false)) { AdditionalProperties = this.GetMetadata() };
|
||||
await agentProvider.CreateMessageAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);<#
|
||||
newMessage = await agentProvider.CreateMessageAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);<#
|
||||
AssignVariable(this.Message, "newMessage");
|
||||
#>
|
||||
return default;
|
||||
|
||||
+13
-8
@@ -1,7 +1,7 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version: 18.0.0.0
|
||||
// Runtime Version: 17.0.0.0
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -19,7 +19,7 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen
|
||||
/// <summary>
|
||||
/// Class to produce the template output
|
||||
/// </summary>
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "18.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")]
|
||||
internal partial class RetrieveConversationMessagesTemplate : ActionTemplate
|
||||
{
|
||||
/// <summary>
|
||||
@@ -44,8 +44,8 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen
|
||||
this.Write("\n");
|
||||
this.Write("\n");
|
||||
this.Write("\n");
|
||||
this.Write("f\n/// <summary>\n/// Retrieves a specific message from an agent conversation.\n/// " +
|
||||
"</summary>\ninternal sealed class ");
|
||||
this.Write("\n/// <summary>\n/// Retrieves a specific message from an agent conversation.\n/// <" +
|
||||
"/summary>\ninternal sealed class ");
|
||||
this.Write(this.ToStringHelper.ToStringWithCulture(this.Name));
|
||||
this.Write("Executor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExe" +
|
||||
"cutor(id: \"");
|
||||
@@ -60,14 +60,19 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen
|
||||
EvaluateStringExpression(this.Model.MessageBefore, "before", isNullable: true);
|
||||
EvaluateEnumExpression<AgentMessageSortOrderWrapper, bool>(this.Model.SortOrder, "newestFirst", SortMap, defaultValue: DefaultSort);
|
||||
this.Write(@"
|
||||
ChatMessage messages =
|
||||
await agentProvider.GetMessageAsync(
|
||||
converationId,
|
||||
IAsyncEnumerable<ChatMessage> messagesResult =
|
||||
agentProvider.GetMessagesAsync(
|
||||
conversationId,
|
||||
limit,
|
||||
after,
|
||||
before,
|
||||
newestFirst,
|
||||
cancellationToken).ConfigureAwait(false);");
|
||||
cancellationToken);
|
||||
List<ChatMessage> messages = [];
|
||||
await foreach (ChatMessage message in messagesResult.ConfigureAwait(false))
|
||||
{
|
||||
messages.Add(message);
|
||||
}");
|
||||
|
||||
AssignVariable(this.Model.Messages, "messages");
|
||||
|
||||
|
||||
+10
-5
@@ -1,7 +1,7 @@
|
||||
<#@ template language="C#" inherits="ActionTemplate" visibility="internal" linePragmas="false" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ include file="Snippets/Index.tt" once="true" #>f
|
||||
<#@ include file="Snippets/Index.tt" once="true" #>
|
||||
/// <summary>
|
||||
/// Retrieves a specific message from an agent conversation.
|
||||
/// </summary>
|
||||
@@ -15,14 +15,19 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA
|
||||
EvaluateStringExpression(this.Model.MessageAfter, "after", isNullable: true);
|
||||
EvaluateStringExpression(this.Model.MessageBefore, "before", isNullable: true);
|
||||
EvaluateEnumExpression<AgentMessageSortOrderWrapper, bool>(this.Model.SortOrder, "newestFirst", SortMap, defaultValue: DefaultSort); #>
|
||||
ChatMessage messages =
|
||||
await agentProvider.GetMessageAsync(
|
||||
converationId,
|
||||
IAsyncEnumerable<ChatMessage> messagesResult =
|
||||
agentProvider.GetMessagesAsync(
|
||||
conversationId,
|
||||
limit,
|
||||
after,
|
||||
before,
|
||||
newestFirst,
|
||||
cancellationToken).ConfigureAwait(false);<#
|
||||
cancellationToken);
|
||||
List<ChatMessage> messages = [];
|
||||
await foreach (ChatMessage message in messagesResult.ConfigureAwait(false))
|
||||
{
|
||||
messages.Add(message);
|
||||
}<#
|
||||
AssignVariable(this.Model.Messages, "messages");
|
||||
#>
|
||||
return default;
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ public sealed class DeclarativeCodeGenTest(ITestOutputHelper output) : WorkflowT
|
||||
[InlineData("SendActivity.yaml", "SendActivity.json")]
|
||||
[InlineData("InvokeAgent.yaml", "InvokeAgent.json")]
|
||||
[InlineData("InvokeAgent.yaml", "InvokeAgent.json", true)]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json", Skip = "Issue #1236")]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json", true, Skip = "Issue #1236")]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json")]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json", true)]
|
||||
public Task ValidateCaseAsync(string workflowFileName, string testcaseFileName, bool externalConveration = false) =>
|
||||
this.RunWorkflowAsync(Path.Combine(Environment.CurrentDirectory, "Workflows", workflowFileName), testcaseFileName, externalConveration);
|
||||
|
||||
|
||||
+12
-2
@@ -10,15 +10,25 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.UnitTests.CodeGen;
|
||||
public class CopyConversationMessagesTemplateTest(ITestOutputHelper output) : WorkflowActionTemplateTest(output)
|
||||
{
|
||||
[Fact]
|
||||
public void CopyConversationMessages()
|
||||
public void CopyConversationMessagesLiteral()
|
||||
{
|
||||
// Act, Assert
|
||||
this.ExecuteTest(
|
||||
nameof(CopyConversationMessages),
|
||||
nameof(CopyConversationMessagesLiteral),
|
||||
StringExpression.Literal("#conv_dm99"),
|
||||
ValueExpression.Variable(PropertyPath.TopicVariable("MyMessages")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyConversationMessagesVariable()
|
||||
{
|
||||
// Act, Assert
|
||||
this.ExecuteTest(
|
||||
nameof(CopyConversationMessagesVariable),
|
||||
StringExpression.Variable(PropertyPath.TopicVariable("TestConversation")),
|
||||
ValueExpression.Variable(PropertyPath.TopicVariable("MyMessages")));
|
||||
}
|
||||
|
||||
private void ExecuteTest(
|
||||
string displayName,
|
||||
StringExpression conversation,
|
||||
|
||||
+5
@@ -14,9 +14,12 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.UnitTests.CodeGen;
|
||||
public sealed class DeclarativeEjectionTest(ITestOutputHelper output) : WorkflowTest(output)
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("AddConversationMessage.yaml")]
|
||||
[InlineData("ClearAllVariables.yaml")]
|
||||
[InlineData("CopyConversationMessages.yaml")]
|
||||
[InlineData("Condition.yaml")]
|
||||
[InlineData("ConditionElse.yaml")]
|
||||
[InlineData("CreateConversation.yaml")]
|
||||
[InlineData("EditTable.yaml")]
|
||||
[InlineData("EditTableV2.yaml")]
|
||||
[InlineData("EndConversation.yaml")]
|
||||
@@ -28,6 +31,8 @@ public sealed class DeclarativeEjectionTest(ITestOutputHelper output) : Workflow
|
||||
[InlineData("LoopEach.yaml")]
|
||||
[InlineData("ParseValue.yaml")]
|
||||
[InlineData("ResetVariable.yaml")]
|
||||
[InlineData("RetrieveConversationMessage.yaml")]
|
||||
[InlineData("RetrieveConversationMessages.yaml")]
|
||||
[InlineData("SendActivity.yaml")]
|
||||
[InlineData("SetVariable.yaml")]
|
||||
[InlineData("SetTextVariable.yaml")]
|
||||
|
||||
+13
-3
@@ -10,14 +10,24 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.UnitTests.CodeGen;
|
||||
public class RetrieveConversationMessageTemplateTest(ITestOutputHelper output) : WorkflowActionTemplateTest(output)
|
||||
{
|
||||
[Fact]
|
||||
public void RetrieveMessageLiteral()
|
||||
public void RetrieveConversationVariable()
|
||||
{
|
||||
// Act, Assert
|
||||
this.ExecuteTest(
|
||||
nameof(RetrieveMessageLiteral),
|
||||
nameof(RetrieveConversationVariable),
|
||||
"TestVariable",
|
||||
StringExpression.Variable(PropertyPath.TopicVariable("TestConversation")),
|
||||
StringExpression.Literal("#mid_43"));
|
||||
}
|
||||
[Fact]
|
||||
public void RetrieveMessageVariable()
|
||||
{
|
||||
// Act, Assert
|
||||
this.ExecuteTest(
|
||||
nameof(RetrieveMessageVariable),
|
||||
"TestVariable",
|
||||
StringExpression.Literal("#cid_3"),
|
||||
StringExpression.Literal("#mid_43"));
|
||||
StringExpression.Variable(PropertyPath.TopicVariable("TestMessage")));
|
||||
}
|
||||
|
||||
private void ExecuteTest(
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ public class RetrieveConversationMessagesTemplateTest(ITestOutputHelper output)
|
||||
this.ExecuteTest(
|
||||
nameof(DefaultQuery),
|
||||
"TestVariable",
|
||||
StringExpression.Literal("#cid_3"));
|
||||
StringExpression.Variable(PropertyPath.TopicVariable("TestConversation")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable IDE0005 // Extra using directive is ok.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Test.WorkflowProviders;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides a factory method to create a <see cref="Workflow" /> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The workflow defined here was generated from a declarative workflow definition.
|
||||
/// Declarative workflows utilize Power FX for defining conditions and expressions.
|
||||
/// To learn more about Power FX, see:
|
||||
/// https://learn.microsoft.com/power-platform/power-fx/formula-reference-copilot-studio
|
||||
/// </remarks>
|
||||
public static class WorkflowProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The root executor for a declarative workflow.
|
||||
/// </summary>
|
||||
internal sealed class WorkflowTestRootExecutor<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage> inputTransform) :
|
||||
RootExecutor<TInput>("workflow_test_Root", options, inputTransform)
|
||||
where TInput : notnull
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
// Initialize variables
|
||||
await context.QueueStateUpdateAsync("MyMessage1", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync("TestInput", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new message to the specified agent conversation
|
||||
/// </summary>
|
||||
internal sealed class AddMessageExecutor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "add_message", session)
|
||||
{
|
||||
// <inheritdoc />
|
||||
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
string? conversationId = await context.ReadStateAsync<string>(key: "ConversationId", scopeName: "System").ConfigureAwait(false);
|
||||
if (string.IsNullOrWhiteSpace(conversationId))
|
||||
{
|
||||
throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}");
|
||||
}
|
||||
ChatMessage newMessage = new(ChatRole.User, await this.GetContentAsync(context).ConfigureAwait(false)) { AdditionalProperties = this.GetMetadata() };
|
||||
newMessage = await agentProvider.CreateMessageAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync(key: "MyMessage1", value: newMessage, scopeName: "Local").ConfigureAwait(false);
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private async ValueTask<IList<AIContent>> GetContentAsync(IWorkflowContext context)
|
||||
{
|
||||
List<AIContent> content = [];
|
||||
|
||||
string contentValue1 =
|
||||
await context.FormatTemplateAsync(
|
||||
"""
|
||||
{Local.TestInput}
|
||||
""");
|
||||
content.Add(new TextContent(contentValue1));
|
||||
return content;
|
||||
}
|
||||
|
||||
private AdditionalPropertiesDictionary? GetMetadata()
|
||||
{
|
||||
Dictionary<string, object?>? metadata = null;
|
||||
|
||||
if (metadata is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AdditionalPropertiesDictionary(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
public static Workflow CreateWorkflow<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage>? inputTransform = null)
|
||||
where TInput : notnull
|
||||
{
|
||||
// Create root executor to initialize the workflow.
|
||||
inputTransform ??= (message) => DeclarativeWorkflowBuilder.DefaultTransform(message);
|
||||
WorkflowTestRootExecutor<TInput> workflowTestRoot = new(options, inputTransform);
|
||||
DelegateExecutor workflowTest = new(id: "workflow_test", workflowTestRoot.Session);
|
||||
AddMessageExecutor addMessage = new(workflowTestRoot.Session, options.AgentProvider);
|
||||
|
||||
// Define the workflow builder
|
||||
WorkflowBuilder builder = new(workflowTestRoot);
|
||||
|
||||
// Connect executors
|
||||
builder.AddEdge(workflowTestRoot, workflowTest);
|
||||
builder.AddEdge(workflowTest, addMessage);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
kind: Workflow
|
||||
trigger:
|
||||
|
||||
kind: OnConversationStart
|
||||
id: workflow_test
|
||||
actions:
|
||||
|
||||
- kind: AddConversationMessage
|
||||
id: add_message
|
||||
message: Local.MyMessage1
|
||||
role: User
|
||||
conversationId: =System.ConversationId
|
||||
content:
|
||||
- type: Text
|
||||
value: {Local.TestInput}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable IDE0005 // Extra using directive is ok.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Test.WorkflowProviders;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides a factory method to create a <see cref="Workflow" /> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The workflow defined here was generated from a declarative workflow definition.
|
||||
/// Declarative workflows utilize Power FX for defining conditions and expressions.
|
||||
/// To learn more about Power FX, see:
|
||||
/// https://learn.microsoft.com/power-platform/power-fx/formula-reference-copilot-studio
|
||||
/// </remarks>
|
||||
public static class WorkflowProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The root executor for a declarative workflow.
|
||||
/// </summary>
|
||||
internal sealed class WorkflowTestRootExecutor<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage> inputTransform) :
|
||||
RootExecutor<TInput>("workflow_test_Root", options, inputTransform)
|
||||
where TInput : notnull
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies one or more messages into the specified agent conversation.
|
||||
/// </summary>
|
||||
internal sealed class CopyMessagesExecutor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "copy_messages", session)
|
||||
{
|
||||
// <inheritdoc />
|
||||
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
string? conversationId = await context.ReadStateAsync<string>(key: "ConversationId", scopeName: "System").ConfigureAwait(false);
|
||||
if (string.IsNullOrWhiteSpace(conversationId))
|
||||
{
|
||||
throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}");
|
||||
}
|
||||
ChatMessage[]? messages = await context.EvaluateValueAsync<ChatMessage[]>("""[UserMessage("Hello, how can I assist you today?")]""").ConfigureAwait(false);
|
||||
if (messages is not null)
|
||||
{
|
||||
foreach (ChatMessage message in messages)
|
||||
{
|
||||
await agentProvider.CreateMessageAsync(conversationId, message, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static Workflow CreateWorkflow<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage>? inputTransform = null)
|
||||
where TInput : notnull
|
||||
{
|
||||
// Create root executor to initialize the workflow.
|
||||
inputTransform ??= (message) => DeclarativeWorkflowBuilder.DefaultTransform(message);
|
||||
WorkflowTestRootExecutor<TInput> workflowTestRoot = new(options, inputTransform);
|
||||
DelegateExecutor workflowTest = new(id: "workflow_test", workflowTestRoot.Session);
|
||||
CopyMessagesExecutor copyMessages = new(workflowTestRoot.Session, options.AgentProvider);
|
||||
|
||||
// Define the workflow builder
|
||||
WorkflowBuilder builder = new(workflowTestRoot);
|
||||
|
||||
// Connect executors
|
||||
builder.AddEdge(workflowTestRoot, workflowTest);
|
||||
builder.AddEdge(workflowTest, copyMessages);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
kind: Workflow
|
||||
trigger:
|
||||
|
||||
kind: OnConversationStart
|
||||
id: workflow_test
|
||||
actions:
|
||||
|
||||
- kind: CopyConversationMessages
|
||||
id: copy_messages
|
||||
conversationId: =System.ConversationId
|
||||
messages: =[UserMessage("Hello, how can I assist you today?")]
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable IDE0005 // Extra using directive is ok.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Test.WorkflowProviders;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides a factory method to create a <see cref="Workflow" /> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The workflow defined here was generated from a declarative workflow definition.
|
||||
/// Declarative workflows utilize Power FX for defining conditions and expressions.
|
||||
/// To learn more about Power FX, see:
|
||||
/// https://learn.microsoft.com/power-platform/power-fx/formula-reference-copilot-studio
|
||||
/// </remarks>
|
||||
public static class WorkflowProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The root executor for a declarative workflow.
|
||||
/// </summary>
|
||||
internal sealed class WorkflowTestRootExecutor<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage> inputTransform) :
|
||||
RootExecutor<TInput>("workflow_test_Root", options, inputTransform)
|
||||
where TInput : notnull
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
// Initialize variables
|
||||
await context.QueueStateUpdateAsync("PrivateConversationId", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new conversation and stores the identifier value to the "Local.PrivateConversationId" variable.
|
||||
/// </summary>
|
||||
internal sealed class ConversationCreateExecutor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "conversation_create", session)
|
||||
{
|
||||
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
string conversationId = await agentProvider.CreateConversationAsync(cancellationToken).ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync(key: "PrivateConversationId", value: conversationId, scopeName: "Local").ConfigureAwait(false);
|
||||
|
||||
await context.AddEventAsync(new ConversationUpdateEvent(conversationId)).ConfigureAwait(false);
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static Workflow CreateWorkflow<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage>? inputTransform = null)
|
||||
where TInput : notnull
|
||||
{
|
||||
// Create root executor to initialize the workflow.
|
||||
inputTransform ??= (message) => DeclarativeWorkflowBuilder.DefaultTransform(message);
|
||||
WorkflowTestRootExecutor<TInput> workflowTestRoot = new(options, inputTransform);
|
||||
DelegateExecutor workflowTest = new(id: "workflow_test", workflowTestRoot.Session);
|
||||
ConversationCreateExecutor conversationCreate = new(workflowTestRoot.Session, options.AgentProvider);
|
||||
|
||||
// Define the workflow builder
|
||||
WorkflowBuilder builder = new(workflowTestRoot);
|
||||
|
||||
// Connect executors
|
||||
builder.AddEdge(workflowTestRoot, workflowTest);
|
||||
builder.AddEdge(workflowTest, conversationCreate);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
kind: Workflow
|
||||
trigger:
|
||||
|
||||
kind: OnConversationStart
|
||||
id: workflow_test
|
||||
actions:
|
||||
|
||||
- kind: CreateConversation
|
||||
id: conversation_create
|
||||
conversationId: Local.PrivateConversationId
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable IDE0005 // Extra using directive is ok.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Test.WorkflowProviders;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides a factory method to create a <see cref="Workflow" /> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The workflow defined here was generated from a declarative workflow definition.
|
||||
/// Declarative workflows utilize Power FX for defining conditions and expressions.
|
||||
/// To learn more about Power FX, see:
|
||||
/// https://learn.microsoft.com/power-platform/power-fx/formula-reference-copilot-studio
|
||||
/// </remarks>
|
||||
public static class WorkflowProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The root executor for a declarative workflow.
|
||||
/// </summary>
|
||||
internal sealed class WorkflowTestRootExecutor<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage> inputTransform) :
|
||||
RootExecutor<TInput>("workflow_test_Root", options, inputTransform)
|
||||
where TInput : notnull
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
// Initialize variables
|
||||
await context.QueueStateUpdateAsync("MyMessage1Copy", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync("MyMessageId", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync("PrivateConversationId", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of messages from an agent conversation.
|
||||
/// </summary>
|
||||
internal sealed class GetMessageSingleExecutor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "get_message_single", session)
|
||||
{
|
||||
// <inheritdoc />
|
||||
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
string conversationId = await context.ReadStateAsync<string>(key: "PrivateConversationId", scopeName: "Local").ConfigureAwait(false);
|
||||
string messageId = await context.ReadStateAsync<string>(key: "MyMessageId", scopeName: "Local").ConfigureAwait(false);
|
||||
ChatMessage message = await agentProvider.GetMessageAsync(conversationId, messageId, cancellationToken).ConfigureAwait(false);
|
||||
await context.QueueStateUpdateAsync(key: "MyMessage1Copy", value: message, scopeName: "Local").ConfigureAwait(false);
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static Workflow CreateWorkflow<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage>? inputTransform = null)
|
||||
where TInput : notnull
|
||||
{
|
||||
// Create root executor to initialize the workflow.
|
||||
inputTransform ??= (message) => DeclarativeWorkflowBuilder.DefaultTransform(message);
|
||||
WorkflowTestRootExecutor<TInput> workflowTestRoot = new(options, inputTransform);
|
||||
DelegateExecutor workflowTest = new(id: "workflow_test", workflowTestRoot.Session);
|
||||
GetMessageSingleExecutor getMessageSingle = new(workflowTestRoot.Session, options.AgentProvider);
|
||||
|
||||
// Define the workflow builder
|
||||
WorkflowBuilder builder = new(workflowTestRoot);
|
||||
|
||||
// Connect executors
|
||||
builder.AddEdge(workflowTestRoot, workflowTest);
|
||||
builder.AddEdge(workflowTest, getMessageSingle);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
kind: Workflow
|
||||
trigger:
|
||||
|
||||
kind: OnConversationStart
|
||||
id: workflow_test
|
||||
actions:
|
||||
|
||||
- kind: RetrieveConversationMessage
|
||||
id: get_message_single
|
||||
message: Local.MyMessage1Copy
|
||||
conversationId: =Local.PrivateConversationId
|
||||
messageId: =Local.MyMessageId
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#nullable enable
|
||||
#pragma warning disable IDE0005 // Extra using directive is ok.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative;
|
||||
using Microsoft.Agents.AI.Workflows.Declarative.Kit;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Test.WorkflowProviders;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides a factory method to create a <see cref="Workflow" /> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The workflow defined here was generated from a declarative workflow definition.
|
||||
/// Declarative workflows utilize Power FX for defining conditions and expressions.
|
||||
/// To learn more about Power FX, see:
|
||||
/// https://learn.microsoft.com/power-platform/power-fx/formula-reference-copilot-studio
|
||||
/// </remarks>
|
||||
public static class WorkflowProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The root executor for a declarative workflow.
|
||||
/// </summary>
|
||||
internal sealed class WorkflowTestRootExecutor<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage> inputTransform) :
|
||||
RootExecutor<TInput>("workflow_test_Root", options, inputTransform)
|
||||
where TInput : notnull
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(TInput message, IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
// Initialize variables
|
||||
await context.QueueStateUpdateAsync("AllMessages", UnassignedValue.Instance, "Local").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a specific message from an agent conversation.
|
||||
/// </summary>
|
||||
internal sealed class GetMessagesAllExecutor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "get_messages_all", session)
|
||||
{
|
||||
// <inheritdoc />
|
||||
protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
string conversationId = await context.ReadStateAsync<string>(key: "ConversationId", scopeName: "System").ConfigureAwait(false);
|
||||
int limit = 20;
|
||||
string? after = null;
|
||||
string? before = null;
|
||||
bool newestFirst = false;
|
||||
IAsyncEnumerable<ChatMessage> messagesResult =
|
||||
agentProvider.GetMessagesAsync(
|
||||
conversationId,
|
||||
limit,
|
||||
after,
|
||||
before,
|
||||
newestFirst,
|
||||
cancellationToken);
|
||||
List<ChatMessage> messages = [];
|
||||
await foreach (ChatMessage message in messagesResult.ConfigureAwait(false))
|
||||
{
|
||||
messages.Add(message);
|
||||
}
|
||||
await context.QueueStateUpdateAsync(key: "AllMessages", value: messages, scopeName: "Local").ConfigureAwait(false);
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static Workflow CreateWorkflow<TInput>(
|
||||
DeclarativeWorkflowOptions options,
|
||||
Func<TInput, ChatMessage>? inputTransform = null)
|
||||
where TInput : notnull
|
||||
{
|
||||
// Create root executor to initialize the workflow.
|
||||
inputTransform ??= (message) => DeclarativeWorkflowBuilder.DefaultTransform(message);
|
||||
WorkflowTestRootExecutor<TInput> workflowTestRoot = new(options, inputTransform);
|
||||
DelegateExecutor workflowTest = new(id: "workflow_test", workflowTestRoot.Session);
|
||||
GetMessagesAllExecutor getMessagesAll = new(workflowTestRoot.Session, options.AgentProvider);
|
||||
|
||||
// Define the workflow builder
|
||||
WorkflowBuilder builder = new(workflowTestRoot);
|
||||
|
||||
// Connect executors
|
||||
builder.AddEdge(workflowTestRoot, workflowTest);
|
||||
builder.AddEdge(workflowTest, getMessagesAll);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
kind: Workflow
|
||||
trigger:
|
||||
|
||||
kind: OnConversationStart
|
||||
id: workflow_test
|
||||
actions:
|
||||
|
||||
- kind: RetrieveConversationMessages
|
||||
id: get_messages_all
|
||||
messages: Local.AllMessages
|
||||
conversationId: =System.ConversationId
|
||||
Reference in New Issue
Block a user