mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: [BREAKING] .NET: Add Workflow on-Build() Orphan Validation (#1943)
* fix: Workflow Validation * adds orphan validation to workflow builder * adds tests for workflow validation * expands on the underlying reasoning why type validation is not supported * fixup: CodeGen template
This commit is contained in:
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -114,6 +114,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(workflowTest, addMessage);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -80,6 +80,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, clearAll);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -175,6 +175,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(conditionItemEvenactionsPost, conditionItemEvenPost);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -167,6 +167,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(conditionGroupTestelseactionsPost, conditionGroupTestPost);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -90,6 +90,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(workflowTest, copyMessages);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -83,6 +83,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(workflowTest, conversationCreate);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -82,6 +82,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, setVar);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -82,6 +82,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, setVar);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -89,6 +89,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(endAllRestart, sendActivity1);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -89,6 +89,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(endAllRestart, sendActivity1);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -138,6 +138,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(sendActivity3, endAll);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -109,6 +109,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, invokeAgent);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -180,6 +180,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(foreachLoopEnd, foreachLoopNext);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -180,6 +180,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(foreachLoopEnd, foreachLoopNext);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -176,6 +176,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(foreachLoopEnd, foreachLoopNext);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -101,6 +101,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(setVar, parseVar);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -98,6 +98,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(setVar, clearVar);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -86,6 +86,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(workflowTest, getMessageSingle);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -99,6 +99,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(workflowTest, getMessagesAll);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -105,6 +105,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(setInput, activityInput);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -85,6 +85,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, setText);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// </auto-generated>
|
||||
@@ -82,6 +82,6 @@ public static class WorkflowProvider
|
||||
builder.AddEdge(myWorkflow, setVar);
|
||||
|
||||
// Build the workflow
|
||||
return builder.Build();
|
||||
return builder.Build(validateOrphans: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,51 @@ public partial class WorkflowBuilderSmokeTests
|
||||
(msg, ctx) => ctx.SendMessageAsync(msg));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test_Validation_FailsWhenUnboundExecutors()
|
||||
{
|
||||
Func<Workflow> act = () =>
|
||||
{
|
||||
return new WorkflowBuilder("start")
|
||||
.AddEdge(new NoOpExecutor("start"), "unbound")
|
||||
.Build();
|
||||
};
|
||||
|
||||
act.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test_Validation_FailsWhenUnreachableExecutors()
|
||||
{
|
||||
Func<Workflow> act = () =>
|
||||
{
|
||||
return new WorkflowBuilder("start")
|
||||
.BindExecutor(new NoOpExecutor("start"))
|
||||
.AddEdge(new NoOpExecutor("unreachable"), new NoOpExecutor("also-unreachable"))
|
||||
.Build();
|
||||
};
|
||||
act.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test_Validation_AddEdgesOutOfOrderDoesNotImpactReachability()
|
||||
{
|
||||
Workflow workflow = new WorkflowBuilder("start")
|
||||
.BindExecutor(new NoOpExecutor("start"))
|
||||
.AddEdge(new NoOpExecutor("not-unreachable"), new NoOpExecutor("also-not-unreachable"))
|
||||
.AddEdge("start", "not-unreachable")
|
||||
.Build();
|
||||
|
||||
workflow.StartExecutorId.Should().Be("start");
|
||||
|
||||
workflow.ExecutorBindings.Should().HaveCount(3);
|
||||
workflow.ExecutorBindings.Should().ContainKey("start");
|
||||
workflow.ExecutorBindings.Should().ContainKey("not-unreachable");
|
||||
workflow.ExecutorBindings.Should().ContainKey("also-not-unreachable");
|
||||
|
||||
workflow.ExecutorBindings.Values.Should().AllSatisfy(binding => binding.ExecutorType.Should().Be<NoOpExecutor>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Test_LateBinding_Executor()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user