From f5ca4f42c00aa5cfaaee9d9bd346f917021a18f3 Mon Sep 17 00:00:00 2001 From: Chris <66376200+crickman@users.noreply.github.com> Date: Wed, 1 Oct 2025 09:15:46 -0700 Subject: [PATCH] .NET Workflows -Fix Declarative Workflow Tests (#1065) * Fixed * Restore generated workflow * Project * Fine tune * Update baseline * Adjust test-case --- .../Workflows/DeclarativeCode/Generated.cs | 46 +++++++++---------- .../CodeGen/AddConversationMessageTemplate.cs | 9 ++-- .../CodeGen/AddConversationMessageTemplate.tt | 5 +- .../CopyConversationMessagesTemplate.cs | 9 ++-- .../CopyConversationMessagesTemplate.tt | 5 +- .../CodeGen/InvokeAzureAgentTemplate.cs | 8 ++-- .../CodeGen/InvokeAzureAgentTemplate.tt | 2 +- .../Testcases/DeepResearch.json | 2 +- .../Workflows/InvokeAgent.cs | 2 +- workflow-samples/DeepResearch.yaml | 2 +- 10 files changed, 49 insertions(+), 41 deletions(-) diff --git a/dotnet/samples/GettingStarted/Workflows/DeclarativeCode/Generated.cs b/dotnet/samples/GettingStarted/Workflows/DeclarativeCode/Generated.cs index 32ba92bb66..b16f3dc2f2 100644 --- a/dotnet/samples/GettingStarted/Workflows/DeclarativeCode/Generated.cs +++ b/dotnet/samples/GettingStarted/Workflows/DeclarativeCode/Generated.cs @@ -48,9 +48,9 @@ public static class TestWorkflowProvider context, "FOUNDRY_AGENT_RESEARCHWEB", "FOUNDRY_AGENT_RESEARCHANALYST", + "FOUNDRY_AGENT_RESEARCHCODER", "FOUNDRY_AGENT_RESEARCHMANAGER", - "FOUNDRY_AGENT_RESEARCHWEATHER", - "FOUNDRY_AGENT_RESEARCHCODER").ConfigureAwait(false); + "FOUNDRY_AGENT_RESEARCHWEATHER").ConfigureAwait(false); // Initialize variables await context.QueueStateUpdateAsync("AgentResponse", UnassignedValue.Instance, "Local").ConfigureAwait(false); @@ -476,27 +476,27 @@ public static class TestWorkflowProvider protected override async ValueTask ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken) { VariableType targetType = - VariableType.Record( - ("instruction_or_question", - VariableType.Record( - ("reason", typeof(string)), - ("answer", typeof(string)))), - ("next_speaker", - VariableType.Record( - ("reason", typeof(string)), - ("answer", typeof(string)))), - ("is_request_satisfied", - VariableType.Record( - ("reason", typeof(string)), - ("answer", typeof(bool)))), - ("is_progress_being_made", - VariableType.Record( - ("reason", typeof(string)), - ("answer", typeof(bool)))), - ("is_in_loop", - VariableType.Record( - ("reason", typeof(string)), - ("answer", typeof(bool))))); + VariableType.Record( + ("is_progress_being_made", + VariableType.Record( + ("reason", typeof(string)), + ("answer", typeof(bool)))), + ("is_request_satisfied", + VariableType.Record( + ("reason", typeof(string)), + ("answer", typeof(bool)))), + ("is_in_loop", + VariableType.Record( + ("reason", typeof(string)), + ("answer", typeof(bool)))), + ("next_speaker", + VariableType.Record( + ("reason", typeof(string)), + ("answer", typeof(string)))), + ("instruction_or_question", + VariableType.Record( + ("reason", typeof(string)), + ("answer", typeof(string))))); object? parsedValue = await context.ConvertValueAsync(targetType, "Last(Local.ProgressLedgerUpdate).Text", cancellationToken).ConfigureAwait(false); await context.QueueStateUpdateAsync(key: "TypedProgressLedger", value: parsedValue, scopeName: "Local").ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.cs index 11eb1fa62c..6e231f7c66 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // // 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 /// /// Class to produce the template output /// - [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 AddConversationMessageTemplate : ActionTemplate { /// @@ -55,8 +55,9 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen " {"); EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); - this.Write("\n ArgumentNullException.ThrowIfNull(conversationId, nameof(conversationId)" + - ");\n ChatMessage newMessage = new(ChatRole."); + this.Write("\n if (string.IsNullOrWhiteSpace(conversationId))\n {\n thr" + + "ow new DeclarativeActionException($\"Conversation identifier must be defined: {th" + + "is.Id}\");\n }\n ChatMessage newMessage = new(ChatRole."); this.Write(this.ToStringHelper.ToStringWithCulture(FormatEnum(this.Model.Role, RoleMap))); this.Write(", [.. this.GetContentAsync(context).ToEnumerable()]) { AdditionalProperties = thi" + "s.GetMetadata() };\n await agentProvider.CreateMessageAsync(conversationId" + diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.tt b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.tt index 6ef39d2f00..1d75665098 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.tt +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/AddConversationMessageTemplate.tt @@ -12,7 +12,10 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA protected override async ValueTask ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken) {<# EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); #> - ArgumentNullException.ThrowIfNull(conversationId, nameof(conversationId)); + if (string.IsNullOrWhiteSpace(conversationId)) + { + throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}"); + } ChatMessage newMessage = new(ChatRole.<#= FormatEnum(this.Model.Role, RoleMap) #>, [.. this.GetContentAsync(context).ToEnumerable()]) { AdditionalProperties = this.GetMetadata() }; await agentProvider.CreateMessageAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);<# AssignVariable(this.Message, "newMessage"); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.cs index 809de19802..044baa45b4 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // // 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 /// /// Class to produce the template output /// - [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 CopyConversationMessagesTemplate : ActionTemplate { /// @@ -55,8 +55,9 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen " {"); EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); - this.Write("\n ArgumentNullException.ThrowIfNull(conversationId, nameof(conversationId)" + - ");"); + this.Write("\n if (string.IsNullOrWhiteSpace(conversationId))\n {\n thr" + + "ow new DeclarativeActionException($\"Conversation identifier must be defined: {th" + + "is.Id}\");\n }"); EvaluateValueExpression(this.Model.Messages, "messages"); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.tt b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.tt index aeb653db09..8014af3f8b 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.tt +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CopyConversationMessagesTemplate.tt @@ -11,7 +11,10 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA protected override async ValueTask ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken) {<# EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); #> - ArgumentNullException.ThrowIfNull(conversationId, nameof(conversationId));<# + if (string.IsNullOrWhiteSpace(conversationId)) + { + throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}"); + }<# EvaluateValueExpression(this.Model.Messages, "messages"); #> if (messages is not null) diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.cs index 75815f722a..2fe387a5f6 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.cs @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------ // // 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 /// /// Class to produce the template output /// - [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 InvokeAzureAgentTemplate : ActionTemplate { /// @@ -56,8 +56,8 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen EvaluateStringExpression(this.Model.Agent.Name, "agentName", isNullable: true); this.Write("\n\n if (string.IsNullOrWhiteSpace(agentName))\n {\n throw n" + - "ew InvalidOperationException($\"Agent name must be defined: {this.Id}\");\n " + - "}\n "); + "ew DeclarativeActionException($\"Agent name must be defined: {this.Id}\");\n " + + " }\n "); EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); EvaluateBoolExpression(this.Model.Output?.AutoSend, "autoSend", defaultValue: true); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.tt b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.tt index d2fcbcd46c..b46e88588a 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.tt +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/InvokeAzureAgentTemplate.tt @@ -14,7 +14,7 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA if (string.IsNullOrWhiteSpace(agentName)) { - throw new InvalidOperationException($"Agent name must be defined: {this.Id}"); + throw new DeclarativeActionException($"Agent name must be defined: {this.Id}"); } <# EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/DeepResearch.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/DeepResearch.json index 17c5806640..5eb4d25313 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/DeepResearch.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/DeepResearch.json @@ -7,7 +7,7 @@ } }, "validation": { - "min_action_count": 28, + "min_action_count": 25, "max_action_count": 56, "actions": { "start": [ diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Workflows/InvokeAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Workflows/InvokeAgent.cs index b75cd445ed..780d45e583 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Workflows/InvokeAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Workflows/InvokeAgent.cs @@ -63,7 +63,7 @@ public static class WorkflowProvider if (string.IsNullOrWhiteSpace(agentName)) { - throw new InvalidOperationException($"Agent name must be defined: {this.Id}"); + throw new DeclarativeActionException($"Agent name must be defined: {this.Id}"); } string? conversationId = await context.ReadStateAsync(key: "ConversationId", scopeName: "System").ConfigureAwait(false); diff --git a/workflow-samples/DeepResearch.yaml b/workflow-samples/DeepResearch.yaml index 24113ffff8..b2ac893b0e 100644 --- a/workflow-samples/DeepResearch.yaml +++ b/workflow-samples/DeepResearch.yaml @@ -314,7 +314,7 @@ trigger: conditions: - id: conditionItem_fpaNL9 - condition: =.TypedProgressLedger.is_in_loop.answer + condition: =Local.TypedProgressLedger.is_in_loop.answer displayName: Is Loop actions: - kind: SendActivity