Expose internal items to Microsoft.Agents.AI.DurableTask. Other minor cleanups

This commit is contained in:
Shyju Krishnankutty
2026-01-26 17:26:52 -08:00
parent 420e7b6038
commit 35caf28239
7 changed files with 17 additions and 44 deletions
+1 -1
View File
@@ -54,7 +54,7 @@
<Project Path="samples/DurableAgents/ConsoleApps/09_Workflow_Concurrency/09_Workflow_Concurrency.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/10_Workflow_HITL/10_Workflow_HITL.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/11_WorkflowEvents/11_WorkflowEvents.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/12_WorkflowTypeHandling/12_WorkflowTypeHandling.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/12_WorkflowLoop/12_WorkflowLoop.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/">
<File Path="samples/GettingStarted/README.md" />
@@ -34,7 +34,7 @@ string dtsConnectionString = Environment.GetEnvironmentVariable("DURABLE_TASK_SC
?? "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None";
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT") ?? "gpt-4o-mini";
var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient();
// Define executors for the workflow
@@ -0,0 +1 @@

@@ -1,7 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Checkpointing;
namespace Microsoft.Agents.AI.DurableTask;
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Checkpointing;
namespace Microsoft.Agents.AI.DurableTask;
@@ -65,8 +64,7 @@ public static class WorkflowHelper
ArgumentNullException.ThrowIfNull(workflow);
Dictionary<string, ExecutorBinding> executors = workflow.ReflectExecutors();
Dictionary<string, HashSet<EdgeInfo>> edges = workflow.ReflectEdges();
Dictionary<(string SourceId, string TargetId), Func<object?, bool>?> edgeConditions = workflow.ReflectEdgeConditions();
Dictionary<string, HashSet<Edge>> edges = workflow.Edges;
WorkflowExecutionPlan plan = new()
{
@@ -90,15 +88,16 @@ public static class WorkflowHelper
plan.ExecutorOutputTypes[executor.Key] = GetExecutorOutputType(executor.Value.ExecutorType);
}
// Build the graph from edges
foreach (KeyValuePair<string, HashSet<EdgeInfo>> edgeGroup in edges)
// Build the graph from edges and extract edge conditions
Dictionary<(string SourceId, string TargetId), Func<object?, bool>?> edgeConditions = [];
foreach (KeyValuePair<string, HashSet<Edge>> edgeGroup in edges)
{
string sourceId = edgeGroup.Key;
List<string> sourceSuccessors = successors[sourceId];
foreach (EdgeInfo edge in edgeGroup.Value)
foreach (Edge edge in edgeGroup.Value)
{
foreach (string sinkId in edge.Connection.SinkIds)
foreach (string sinkId in edge.Data.Connection.SinkIds)
{
if (executorIndex.ContainsKey(sinkId))
{
@@ -106,6 +105,13 @@ public static class WorkflowHelper
predecessors[sinkId].Add(sourceId);
}
}
// Extract condition from DirectEdgeData if present
DirectEdgeData? directEdge = edge.DirectEdgeData;
if (directEdge is not null)
{
edgeConditions[(directEdge.SourceId, directEdge.SinkId)] = directEdge.Condition;
}
}
}
@@ -25,6 +25,7 @@
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.Agents.AI.DurableTask" />
<InternalsVisibleTo Include="Microsoft.Agents.AI.Workflows.UnitTests" />
<InternalsVisibleTo Include="Microsoft.Agents.AI.Workflows.Generators.UnitTests" />
</ItemGroup>
@@ -36,40 +36,6 @@ public class Workflow
);
}
/// <summary>
/// Gets a mapping of edge identifiers to their associated condition delegates.
/// </summary>
/// <remarks>The returned dictionary includes only edges that have direct edge data. The condition
/// delegate can be used to determine whether the edge is active or valid for a given input. Edges without direct
/// edge data are not included in the result.</remarks>
/// <returns>A dictionary where each key is a tuple containing the source and target node identifiers, and each value is a
/// delegate that evaluates the condition for the corresponding edge. The value is <see langword="null"/> if the
/// edge has no associated condition.</returns>
public Dictionary<(string SourceId, string TargetId), Func<object?, bool>?> ReflectEdgeConditions()
{
int capacity = 0;
foreach (HashSet<Edge> edgeSet in this.Edges.Values)
{
capacity += edgeSet.Count;
}
Dictionary<(string SourceId, string TargetId), Func<object?, bool>?> conditions = new(capacity);
foreach (HashSet<Edge> edgeSet in this.Edges.Values)
{
foreach (Edge edge in edgeSet)
{
DirectEdgeData? directEdge = edge.DirectEdgeData;
if (directEdge is not null)
{
conditions[(directEdge.SourceId, directEdge.SinkId)] = directEdge.Condition;
}
}
}
return conditions;
}
internal Dictionary<string, RequestPort> Ports { get; init; } = [];
/// <summary>