Merge branch 'main' into feature-foundry-agents

This commit is contained in:
Chris
2025-11-05 15:49:58 -08:00
committed by GitHub
Unverified
65 changed files with 4215 additions and 4031 deletions
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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>
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -8,6 +8,7 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Agents.AI.Workflows.Checkpointing;
using Microsoft.Agents.AI.Workflows.Execution;
using Microsoft.Agents.AI.Workflows.Specialized;
using Microsoft.Extensions.AI;
@@ -196,4 +197,50 @@ public class SpecializedExecutorSmokeTests
collected.Text.Should().Be(expectedText);
}
}
[Fact]
public async Task Test_AIAgent_ExecutorId_Use_Agent_NameAsync()
{
const string AgentAName = "TestAgentAName";
const string AgentBName = "TestAgentBName";
TestAIAgent agentA = new(name: AgentAName);
TestAIAgent agentB = new(name: AgentBName);
var workflow = new WorkflowBuilder(agentA).AddEdge(agentA, agentB).Build();
var definition = workflow.ToWorkflowInfo();
// Verify that the agent host executor registration IDs in the workflow definition
// match the agent names when agent names are provided.
// The property DisplayName falls back to using the agent ID when Name is not set.
agentA.GetDescriptiveId().Should().Contain(AgentAName);
agentB.GetDescriptiveId().Should().Contain(AgentBName);
definition.Executors[agentA.GetDescriptiveId()].ExecutorId.Should().Be(agentA.GetDescriptiveId());
definition.Executors[agentB.GetDescriptiveId()].ExecutorId.Should().Be(agentB.GetDescriptiveId());
// This will create an instance of the start agent and verify that the ID
// of the executor instance matches the ID of the registration.
var protocolDescriptor = await workflow.DescribeProtocolAsync();
protocolDescriptor.Accepts.Should().Contain(typeof(ChatMessage));
}
[Fact]
public async Task Test_AIAgent_ExecutorId_Use_Agent_ID_When_Name_Not_ProvidedAsync()
{
TestAIAgent agentA = new();
TestAIAgent agentB = new();
var workflow = new WorkflowBuilder(agentA).AddEdge(agentA, agentB).Build();
var definition = workflow.ToWorkflowInfo();
// Verify that the agent host executor registration IDs in the workflow definition
// match the agent IDs when agent names are not provided.
// The property DisplayName falls back to using the agent ID when Name is not set.
agentA.GetDescriptiveId().Should().Contain(agentA.Id);
agentB.GetDescriptiveId().Should().Contain(agentB.Id);
definition.Executors[agentA.GetDescriptiveId()].ExecutorId.Should().Be(agentA.GetDescriptiveId());
definition.Executors[agentB.GetDescriptiveId()].ExecutorId.Should().Be(agentB.GetDescriptiveId());
// This will create an instance of the start agent and verify that the ID
// of the executor instance matches the ID of the registration.
var protocolDescriptor = await workflow.DescribeProtocolAsync();
protocolDescriptor.Accepts.Should().Contain(typeof(ChatMessage));
}
}
@@ -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()
{