diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.cs index 9910222793..4a71073d4c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.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 CreateConversationTemplate : ActionTemplate { /// @@ -59,8 +59,8 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.CodeGen string conversationId = await agentProvider.CreateConversationAsync(cancellationToken).ConfigureAwait(false);"); AssignVariable(this.ConversationId, "conversationId"); - - this.Write("\n return default;\n }\n}\n"); + this.Write("\n await context.AddEventAsync(new ConversationUpdateEvent(conversationId))" + + ".ConfigureAwait(false);\n\n return default;\n }\n}\n"); return this.GenerationEnvironment.ToString(); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.tt b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.tt index 1f935c855f..859f25a56a 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.tt +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/CodeGen/CreateConversationTemplate.tt @@ -10,8 +10,9 @@ internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowA protected override async ValueTask ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken) { string conversationId = await agentProvider.CreateConversationAsync(cancellationToken).ConfigureAwait(false);<# - AssignVariable(this.ConversationId, "conversationId"); - #> + AssignVariable(this.ConversationId, "conversationId");#> + await context.AddEventAsync(new ConversationUpdateEvent(conversationId)).ConfigureAwait(false); + return default; } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs index 0fafa4e9db..92769ef60f 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/DeclarativeWorkflowBuilder.cs @@ -69,7 +69,7 @@ public static class DeclarativeWorkflowBuilder state.Initialize(workflowElement.WrapWithBot(), options.Configuration); DeclarativeWorkflowExecutor rootExecutor = new(rootId, - options.AgentProvider, + options, state, message => inputTransform?.Invoke(message) ?? DefaultTransform(message)); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Events/ConversationUpdateEvent.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Events/ConversationUpdateEvent.cs index 94dd651ea4..f10f2c2fa2 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Events/ConversationUpdateEvent.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Events/ConversationUpdateEvent.cs @@ -12,7 +12,11 @@ public sealed class ConversationUpdateEvent : WorkflowEvent /// public string ConversationId { get; } - internal ConversationUpdateEvent(string conversationId) + /// + /// Initializes a new instance of . + /// + /// The identifier of the associated conversation. + public ConversationUpdateEvent(string conversationId) : base(conversationId) { this.ConversationId = conversationId; diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Extensions/AgentProviderExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Extensions/AgentProviderExtensions.cs index e6c717791c..3d2ab82664 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Extensions/AgentProviderExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Extensions/AgentProviderExtensions.cs @@ -41,7 +41,7 @@ internal static class AgentProviderExtensions // Enable "autoSend" behavior if this is the workflow conversation. bool isWorkflowConversation = context.IsWorkflowConversation(conversationId); - autoSend &= isWorkflowConversation; + autoSend |= isWorkflowConversation; // Process the agent response updates. List updates = []; diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeWorkflowExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeWorkflowExecutor.cs index bfb73e644e..df93c2b60c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeWorkflowExecutor.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeWorkflowExecutor.cs @@ -13,7 +13,7 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.Interpreter; /// internal sealed class DeclarativeWorkflowExecutor( string workflowId, - WorkflowAgentProvider agentProvider, + DeclarativeWorkflowOptions options, WorkflowFormulaState state, Func inputTransform) : Executor(workflowId), IModeledAction where TInput : notnull @@ -26,10 +26,14 @@ internal sealed class DeclarativeWorkflowExecutor( DeclarativeWorkflowContext declarativeContext = new(context, state); ChatMessage input = inputTransform.Invoke(message); - string conversationId = await agentProvider.CreateConversationAsync(cancellationToken: default).ConfigureAwait(false); + string? conversationId = options.ConversationId; + if (string.IsNullOrWhiteSpace(conversationId)) + { + conversationId = await options.AgentProvider.CreateConversationAsync(cancellationToken: default).ConfigureAwait(false); + } await declarativeContext.QueueConversationUpdateAsync(conversationId).ConfigureAwait(false); - await agentProvider.CreateMessageAsync(conversationId, input, cancellationToken: default).ConfigureAwait(false); + await options.AgentProvider.CreateMessageAsync(conversationId, input, cancellationToken: default).ConfigureAwait(false); await declarativeContext.SetLastMessageAsync(input).ConfigureAwait(false); await context.SendResultMessageAsync(this.Id).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/RootExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/RootExecutor.cs index eca5404f84..90b67a5be8 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/RootExecutor.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/RootExecutor.cs @@ -23,6 +23,8 @@ public abstract class RootExecutor : Executor where TInput : not private readonly WorkflowFormulaState _state; private readonly Func? _inputTransform; + private string? _conversationId; + /// /// Get the shared formula session to provide to workflow instances. /// @@ -39,6 +41,7 @@ public abstract class RootExecutor : Executor where TInput : not { this._configuration = options.Configuration; this._agentProvider = options.AgentProvider; + this._conversationId = options.ConversationId; this._inputTransform = inputTransform; this._state = new WorkflowFormulaState(options.CreateRecalcEngine()); this._state.InitializeSystem(); @@ -53,10 +56,13 @@ public abstract class RootExecutor : Executor where TInput : not ChatMessage input = (this._inputTransform ?? DefaultInputTransform).Invoke(message); - string conversationId = await this._agentProvider.CreateConversationAsync(cancellationToken: default).ConfigureAwait(false); - await declarativeContext.QueueConversationUpdateAsync(conversationId).ConfigureAwait(false); + if (string.IsNullOrWhiteSpace(this._conversationId)) + { + this._conversationId = await this._agentProvider.CreateConversationAsync(cancellationToken: default).ConfigureAwait(false); + } + await declarativeContext.QueueConversationUpdateAsync(this._conversationId).ConfigureAwait(false); - await this._agentProvider.CreateMessageAsync(conversationId, input, cancellationToken: default).ConfigureAwait(false); + await this._agentProvider.CreateMessageAsync(this._conversationId, input, cancellationToken: default).ConfigureAwait(false); await declarativeContext.SetLastMessageAsync(input).ConfigureAwait(false); await declarativeContext.SendMessageAsync(new ActionExecutorResult(this.Id)).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/CreateConversationExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/CreateConversationExecutor.cs index b291ba677c..1da428f931 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/CreateConversationExecutor.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/CreateConversationExecutor.cs @@ -2,6 +2,7 @@ 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.PowerFx; using Microsoft.Bot.ObjectModel; @@ -16,6 +17,7 @@ internal sealed class CreateConversationExecutor(CreateConversation model, Workf { string conversationId = await agentProvider.CreateConversationAsync(cancellationToken).ConfigureAwait(false); await this.AssignAsync(this.Model.ConversationId?.Path, FormulaValue.New(conversationId), context).ConfigureAwait(false); + await context.QueueConversationUpdateAsync(conversationId).ConfigureAwait(false); return default; } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeCodeGenTest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeCodeGenTest.cs index d3beda47ce..7ec28e10ec 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeCodeGenTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeCodeGenTest.cs @@ -18,17 +18,20 @@ public sealed class DeclarativeCodeGenTest(ITestOutputHelper output) : WorkflowT [Theory] [InlineData("SendActivity.yaml", "SendActivity.json")] [InlineData("InvokeAgent.yaml", "InvokeAgent.json")] + [InlineData("InvokeAgent.yaml", "InvokeAgent.json", true)] [InlineData("ConversationMessages.yaml", "ConversationMessages.json")] - public Task ValidateCaseAsync(string workflowFileName, string testcaseFileName) => - this.RunWorkflowAsync(Path.Combine(Environment.CurrentDirectory, "Workflows", workflowFileName), testcaseFileName); + [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); [Theory] [InlineData("Marketing.yaml", "Marketing.json")] - [InlineData("MathChat.yaml", "MathChat.json")] + [InlineData("Marketing.yaml", "Marketing.json", true)] + [InlineData("MathChat.yaml", "MathChat.json", true)] [InlineData("DeepResearch.yaml", "DeepResearch.json", Skip = "Long running")] [InlineData("HumanInLoop.yaml", "HumanInLoop.json", Skip = "Needs test support")] - public Task ValidateScenarioAsync(string workflowFileName, string testcaseFileName) => - this.RunWorkflowAsync(Path.Combine(GetRepoFolder(), "workflow-samples", workflowFileName), testcaseFileName); + public Task ValidateScenarioAsync(string workflowFileName, string testcaseFileName, bool externalConveration = false) => + this.RunWorkflowAsync(Path.Combine(GetRepoFolder(), "workflow-samples", workflowFileName), testcaseFileName, externalConveration); protected override async Task RunAndVerifyAsync(Testcase testcase, string workflowPath, DeclarativeWorkflowOptions workflowOptions) { @@ -46,6 +49,7 @@ public sealed class DeclarativeCodeGenTest(ITestOutputHelper output) : WorkflowT Assert.Empty(workflowEvents.ActionInvokeEvents); Assert.Empty(workflowEvents.ActionCompleteEvents); + AssertWorkflow.Conversation(workflowOptions.ConversationId, testcase.Validation.ConversationCount, workflowEvents.ConversationEvents); AssertWorkflow.EventCounts(workflowEvents.ExecutorInvokeEvents.Count - 2, testcase); AssertWorkflow.EventCounts(workflowEvents.ExecutorCompleteEvents.Count - 2, testcase); AssertWorkflow.EventSequence(workflowEvents.ExecutorInvokeEvents.Select(e => e.ExecutorId), testcase); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeWorkflowTest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeWorkflowTest.cs index 38c590fb43..d016e1d4bd 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeWorkflowTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/DeclarativeWorkflowTest.cs @@ -18,17 +18,20 @@ public sealed class DeclarativeWorkflowTest(ITestOutputHelper output) : Workflow [Theory] [InlineData("SendActivity.yaml", "SendActivity.json")] [InlineData("InvokeAgent.yaml", "InvokeAgent.json")] + [InlineData("InvokeAgent.yaml", "InvokeAgent.json", true)] [InlineData("ConversationMessages.yaml", "ConversationMessages.json")] - public Task ValidateCaseAsync(string workflowFileName, string testcaseFileName) => - this.RunWorkflowAsync(Path.Combine(Environment.CurrentDirectory, "Workflows", workflowFileName), testcaseFileName); + [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); [Theory] [InlineData("Marketing.yaml", "Marketing.json")] - [InlineData("MathChat.yaml", "MathChat.json")] + [InlineData("Marketing.yaml", "Marketing.json", true)] + [InlineData("MathChat.yaml", "MathChat.json", true)] [InlineData("DeepResearch.yaml", "DeepResearch.json", Skip = "Long running")] [InlineData("HumanInLoop.yaml", "HumanInLoop.json", Skip = "Needs test support")] - public Task ValidateScenarioAsync(string workflowFileName, string testcaseFileName) => - this.RunWorkflowAsync(Path.Combine(GetRepoFolder(), "workflow-samples", workflowFileName), testcaseFileName); + public Task ValidateScenarioAsync(string workflowFileName, string testcaseFileName, bool externalConveration = false) => + this.RunWorkflowAsync(Path.Combine(GetRepoFolder(), "workflow-samples", workflowFileName), testcaseFileName, externalConveration); protected override async Task RunAndVerifyAsync(Testcase testcase, string workflowPath, DeclarativeWorkflowOptions workflowOptions) { @@ -42,6 +45,7 @@ public sealed class DeclarativeWorkflowTest(ITestOutputHelper output) : Workflow Assert.NotEmpty(workflowEvents.ExecutorInvokeEvents); Assert.NotEmpty(workflowEvents.ExecutorCompleteEvents); + AssertWorkflow.Conversation(workflowOptions.ConversationId, testcase.Validation.ConversationCount, workflowEvents.ConversationEvents); AssertWorkflow.EventCounts(workflowEvents.ActionInvokeEvents.Count, testcase); AssertWorkflow.EventCounts(workflowEvents.ActionCompleteEvents.Count, testcase); AssertWorkflow.EventSequence(workflowEvents.ActionInvokeEvents.Select(e => e.ActionId), testcase); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/Testcase.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/Testcase.cs index 8fb7721ebd..cfe7b7cc98 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/Testcase.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/Testcase.cs @@ -51,14 +51,16 @@ public sealed class TestcaseInput public sealed class TestcaseValidation { [JsonConstructor] - public TestcaseValidation(int minActionCount, int? maxActionCount = null, TestcaseValidationActions? actions = null) + public TestcaseValidation(int conversationCount, int minActionCount, int? maxActionCount = null, TestcaseValidationActions? actions = null) { + this.ConversationCount = conversationCount; this.MinActionCount = minActionCount; this.MaxActionCount = maxActionCount; this.Actions = actions ?? new TestcaseValidationActions([]); } public TestcaseValidationActions Actions { get; } + public int ConversationCount { get; } public int MinActionCount { get; } public int? MaxActionCount { get; } } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowEvents.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowEvents.cs index d933dd2af9..ff572373bc 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowEvents.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowEvents.cs @@ -14,12 +14,14 @@ internal sealed class WorkflowEvents this.EventCounts = workflowEvents.GroupBy(e => e.GetType()).ToDictionary(e => e.Key, e => e.Count()); this.ActionInvokeEvents = workflowEvents.OfType().ToList(); this.ActionCompleteEvents = workflowEvents.OfType().ToList(); + this.ConversationEvents = workflowEvents.OfType().ToList(); this.ExecutorInvokeEvents = workflowEvents.OfType().ToList(); this.ExecutorCompleteEvents = workflowEvents.OfType().ToList(); } public IReadOnlyList Events { get; } public IReadOnlyDictionary EventCounts { get; } + public IReadOnlyList ConversationEvents { get; } public IReadOnlyList ActionInvokeEvents { get; } public IReadOnlyList ActionCompleteEvents { get; } public IReadOnlyList ExecutorInvokeEvents { get; } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowTest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowTest.cs index 0e3af235c0..b4310ff4cb 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowTest.cs @@ -21,9 +21,15 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Framework; /// public abstract class WorkflowTest(ITestOutputHelper output) : IntegrationTest(output) { - protected abstract Task RunAndVerifyAsync(Testcase testcase, string workflowPath, DeclarativeWorkflowOptions workflowOptions) where TInput : notnull; + protected abstract Task RunAndVerifyAsync( + Testcase testcase, + string workflowPath, + DeclarativeWorkflowOptions workflowOptions) where TInput : notnull; - protected Task RunWorkflowAsync(string workflowPath, string testcaseFileName) + protected Task RunWorkflowAsync( + string workflowPath, + string testcaseFileName, + bool externalConversation = false) { this.Output.WriteLine($"WORKFLOW: {workflowPath}"); this.Output.WriteLine($"TESTCASE: {testcaseFileName}"); @@ -45,7 +51,8 @@ public abstract class WorkflowTest(ITestOutputHelper output) : IntegrationTest(o protected async Task TestWorkflowAsync( Testcase testcase, string workflowPath, - IConfiguration configuration) where TInput : notnull + IConfiguration configuration, + bool externalConversation = false) where TInput : notnull { this.Output.WriteLine($"INPUT: {testcase.Setup.Input.Value}"); @@ -59,12 +66,22 @@ public abstract class WorkflowTest(ITestOutputHelper output) : IntegrationTest(o .AddInMemoryCollection(agentMap) .Build(); + AzureAgentProvider agentProvider = new(foundryConfig.Endpoint, new AzureCliCredential()); + + string? conversationId = null; + if (externalConversation) + { + conversationId = await agentProvider.CreateConversationAsync().ConfigureAwait(false); + } + DeclarativeWorkflowOptions workflowOptions = - new(new AzureAgentProvider(foundryConfig.Endpoint, new AzureCliCredential())) + new(agentProvider) { Configuration = workflowConfig, + ConversationId = conversationId, LoggerFactory = this.Output }; + await this.RunAndVerifyAsync(testcase, workflowPath, workflowOptions); } @@ -103,6 +120,18 @@ public abstract class WorkflowTest(ITestOutputHelper output) : IntegrationTest(o protected static class AssertWorkflow { + public static void Conversation(string? conversationId, int expectedCount, IReadOnlyList conversationEvents) + { + if (string.IsNullOrEmpty(conversationId)) + { + Assert.Equal(expectedCount, conversationEvents.Count); + } + else + { + Assert.Equal(expectedCount - 1, conversationEvents.Count); + } + } + public static void EventCounts(int actualCount, Testcase testcase) { Assert.True(actualCount >= testcase.Validation.MinActionCount, $"Event count less than expected: {testcase.Validation.MinActionCount} ({actualCount})."); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/ConversationMessages.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/ConversationMessages.json index 4e4108fab3..b110188740 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/ConversationMessages.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/ConversationMessages.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 3, "min_action_count": 7, "actions": { "start": [ 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 5eb4d25313..72b602a851 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,6 +7,7 @@ } }, "validation": { + "conversation_count": 2, "min_action_count": 25, "max_action_count": 56, "actions": { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/HumanInLoop.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/HumanInLoop.json index ea0a6ebdea..4c79083c88 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/HumanInLoop.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/HumanInLoop.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 1, "min_action_count": 1, "actions": { "start": [ diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/InvokeAgent.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/InvokeAgent.json index 3984811290..0be58aecc7 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/InvokeAgent.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/InvokeAgent.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 2, "min_action_count": 1, "actions": { "start": [ diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/Marketing.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/Marketing.json index cb6bfd8b66..96b459d293 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/Marketing.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/Marketing.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 1, "min_action_count": 4, "actions": { "start": [ diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/MathChat.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/MathChat.json index 4d6a0e69d9..0ad0465396 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/MathChat.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/MathChat.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 1, "min_action_count": 6, "max_action_count": 56, "actions": { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/SendActivity.json b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/SendActivity.json index f5303d0676..7a896be4ec 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/SendActivity.json +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Testcases/SendActivity.json @@ -7,6 +7,7 @@ } }, "validation": { + "conversation_count": 1, "min_action_count": 3, "actions": { "start": [ diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/InvokeAgent.yaml b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/InvokeAgent.yaml index 00539953d1..27f195ee36 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/InvokeAgent.yaml +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/InvokeAgent.yaml @@ -12,4 +12,5 @@ trigger: input: messages: =[UserMessage(System.LastMessageText)] output: + autoSend: false messages: Local.Answer diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs index 32e2f3d92c..3126eb6bc1 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs @@ -216,7 +216,7 @@ public sealed class DeclarativeWorkflowTest(ITestOutputHelper output) : Workflow WorkflowFormulaState state = new(RecalcEngineFactory.Create()); Mock mockAgentProvider = CreateMockProvider(); DeclarativeWorkflowOptions options = new(mockAgentProvider.Object); - WorkflowActionVisitor visitor = new(new DeclarativeWorkflowExecutor(WorkflowActionVisitor.Steps.Root("anything"), mockAgentProvider.Object, state, (message) => DeclarativeWorkflowBuilder.DefaultTransform(message)), state, options); + WorkflowActionVisitor visitor = new(new DeclarativeWorkflowExecutor(WorkflowActionVisitor.Steps.Root("anything"), options, state, (message) => DeclarativeWorkflowBuilder.DefaultTransform(message)), state, options); WorkflowElementWalker walker = new(visitor); walker.Visit(dialog); Assert.True(visitor.HasUnsupportedActions); diff --git a/workflow-samples/DeepResearch.yaml b/workflow-samples/DeepResearch.yaml index b2ac893b0e..e1db3cc5c5 100644 --- a/workflow-samples/DeepResearch.yaml +++ b/workflow-samples/DeepResearch.yaml @@ -92,6 +92,7 @@ trigger: agent: name: =Env.FOUNDRY_AGENT_RESEARCHANALYST output: + autoSend: false messages: Local.TaskFacts input: messages: =UserMessage(Local.InputTask) @@ -126,6 +127,7 @@ trigger: agent: name: =Env.FOUNDRY_AGENT_RESEARCHMANAGER output: + autoSend: false messages: Local.Plan input: messages: =UserMessage(Local.InputTask) @@ -179,6 +181,7 @@ trigger: agent: name: =Env.FOUNDRY_AGENT_RESEARCHMANAGER output: + autoSend: false messages: Local.ProgressLedgerUpdate input: messages: =UserMessage(Local.AgentResponseText) @@ -366,6 +369,7 @@ trigger: agent: name: =Env.FOUNDRY_AGENT_RESEARCHANALYST output: + autoSend: false messages: Local.TaskFacts input: messages: |- @@ -395,6 +399,7 @@ trigger: agent: name: =Env.FOUNDRY_AGENT_RESEARCHMANAGER output: + autoSend: false messages: Local.Plan input: additionalInstructions: |-