diff --git a/dotnet/samples/AgentWebChat/AgentWebChat.AgentHost/Program.cs b/dotnet/samples/AgentWebChat/AgentWebChat.AgentHost/Program.cs index e7262345d7..15e7cbbd86 100644 --- a/dotnet/samples/AgentWebChat/AgentWebChat.AgentHost/Program.cs +++ b/dotnet/samples/AgentWebChat/AgentWebChat.AgentHost/Program.cs @@ -70,7 +70,7 @@ Once the user has deduced what type (knight or knave) both Alice and Bob are, te If the user asks a general question about their surrounding, make something up which is consistent with the scenario. """, "Narrator"); - return AgentWorkflowBuilder.BuildConcurrent([knight, knave, narrator]).AsAgent(name: key); + return AgentWorkflowBuilder.BuildConcurrent([knight, knave, narrator]).AsAIAgent(name: key); }); // Workflow consisting of multiple specialized agents diff --git a/dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/Program.cs b/dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/Program.cs index 242c02e7cd..e2dec8505b 100644 --- a/dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/Program.cs @@ -34,10 +34,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create the executors var sloganWriter = new SloganWriterExecutor("SloganWriter", chatClient); @@ -51,7 +48,7 @@ private static async Task Main() .Build(); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input: "Create a slogan for a new electric SUV that is affordable and fun to drive."); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input: "Create a slogan for a new electric SUV that is affordable and fun to drive."); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { if (evt is SloganGeneratedEvent or FeedbackEvent) diff --git a/dotnet/samples/GettingStarted/Workflows/Agents/FoundryAgent/Program.cs b/dotnet/samples/GettingStarted/Workflows/Agents/FoundryAgent/Program.cs index 48a41b73d6..016138aeea 100644 --- a/dotnet/samples/GettingStarted/Workflows/Agents/FoundryAgent/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Agents/FoundryAgent/Program.cs @@ -24,10 +24,7 @@ private static async Task Main() var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set."); var deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var persistentAgentsClient = new PersistentAgentsClient(endpoint, new DefaultAzureCredential()); + var persistentAgentsClient = new PersistentAgentsClient(endpoint, new AzureCliCredential()); // Create agents AIAgent frenchAgent = await GetTranslationAgentAsync("French", persistentAgentsClient, deploymentName); @@ -41,7 +38,7 @@ private static async Task Main() .Build(); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, "Hello World!")); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new ChatMessage(ChatRole.User, "Hello World!")); // Must send the turn token to trigger the agents. // The agents are wrapped as executors. When they receive messages, // they will cache the messages and only start processing when they receive a TurnToken. diff --git a/dotnet/samples/GettingStarted/Workflows/Agents/GroupChatToolApproval/Program.cs b/dotnet/samples/GettingStarted/Workflows/Agents/GroupChatToolApproval/Program.cs index 0508ad80a8..076e764ea8 100644 --- a/dotnet/samples/GettingStarted/Workflows/Agents/GroupChatToolApproval/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Agents/GroupChatToolApproval/Program.cs @@ -91,7 +91,7 @@ private static async Task Main() List messages = [new(ChatRole.User, "We need to deploy version 2.4.0 to production. Please coordinate the deployment.")]; - await using StreamingRun run = await InProcessExecution.Lockstep.StreamAsync(workflow, messages); + await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, messages); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); string? lastExecutorId = null; @@ -101,7 +101,7 @@ private static async Task Main() { case RequestInfoEvent e: { - if (e.Request.DataIs(out FunctionApprovalRequestContent? approvalRequestContent)) + if (e.Request.TryGetDataAs(out FunctionApprovalRequestContent? approvalRequestContent)) { Console.WriteLine(); Console.WriteLine($"[APPROVAL REQUIRED] From agent: {e.Request.PortInfo.PortId}"); diff --git a/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/Program.cs b/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/Program.cs index ff402e2e66..07ba96989a 100644 --- a/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/Program.cs @@ -32,14 +32,11 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create the workflow and turn it into an agent var workflow = WorkflowFactory.BuildWorkflow(chatClient); - var agent = workflow.AsAgent("workflow-agent", "Workflow Agent"); + var agent = workflow.AsAIAgent("workflow-agent", "Workflow Agent"); var session = await agent.CreateSessionAsync(); // Start an interactive loop to interact with the workflow as if it were an agent diff --git a/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/WorkflowFactory.cs b/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/WorkflowFactory.cs index e418ca7131..669b9ac87c 100644 --- a/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/WorkflowFactory.cs +++ b/dotnet/samples/GettingStarted/Workflows/Agents/WorkflowAsAnAgent/WorkflowFactory.cs @@ -24,7 +24,7 @@ internal static Workflow BuildWorkflow(IChatClient chatClient) // Build the workflow by adding executors and connecting them return new WorkflowBuilder(startExecutor) .AddFanOutEdge(startExecutor, [frenchAgent, englishAgent]) - .AddFanInEdge([frenchAgent, englishAgent], aggregationExecutor) + .AddFanInBarrierEdge([frenchAgent, englishAgent], aggregationExecutor) .WithOutputFrom(aggregationExecutor) .Build(); } diff --git a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndRehydrate/Program.cs b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndRehydrate/Program.cs index c3a1e705fb..7bc5621fbe 100644 --- a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndRehydrate/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndRehydrate/Program.cs @@ -33,7 +33,7 @@ private static async Task Main() // Execute the workflow and save checkpoints await using StreamingRun checkpointedRun = await InProcessExecution - .StreamAsync(workflow, NumberSignal.Init, checkpointManager); + .RunStreamingAsync(workflow, NumberSignal.Init, checkpointManager); await foreach (WorkflowEvent evt in checkpointedRun.WatchStreamAsync()) { @@ -73,7 +73,7 @@ private static async Task Main() CheckpointInfo savedCheckpoint = checkpoints[CheckpointIndex]; await using StreamingRun newCheckpointedRun = - await InProcessExecution.ResumeStreamAsync(newWorkflow, savedCheckpoint, checkpointManager); + await InProcessExecution.ResumeStreamingAsync(newWorkflow, savedCheckpoint, checkpointManager); await foreach (WorkflowEvent evt in newCheckpointedRun.WatchStreamAsync()) { diff --git a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndResume/Program.cs b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndResume/Program.cs index 80881310e1..07be486620 100644 --- a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndResume/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointAndResume/Program.cs @@ -31,9 +31,7 @@ private static async Task Main() var checkpoints = new List(); // Execute the workflow and save checkpoints - await using StreamingRun checkpointedRun = await InProcessExecution - .StreamAsync(workflow, NumberSignal.Init, checkpointManager) - ; + await using StreamingRun checkpointedRun = await InProcessExecution.RunStreamingAsync(workflow, NumberSignal.Init, checkpointManager); await foreach (WorkflowEvent evt in checkpointedRun.WatchStreamAsync()) { if (evt is ExecutorCompletedEvent executorCompletedEvt) diff --git a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointWithHumanInTheLoop/Program.cs b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointWithHumanInTheLoop/Program.cs index 8621d40574..56b4da9911 100644 --- a/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointWithHumanInTheLoop/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Checkpoint/CheckpointWithHumanInTheLoop/Program.cs @@ -35,7 +35,7 @@ private static async Task Main() // Execute the workflow and save checkpoints await using StreamingRun checkpointedRun = await InProcessExecution - .StreamAsync(workflow, new SignalWithNumber(NumberSignal.Init), checkpointManager) + .RunStreamingAsync(workflow, new SignalWithNumber(NumberSignal.Init), checkpointManager) ; await foreach (WorkflowEvent evt in checkpointedRun.WatchStreamAsync()) { @@ -98,8 +98,7 @@ private static async Task Main() private static ExternalResponse HandleExternalRequest(ExternalRequest request) { - var signal = request.DataAs(); - if (signal is not null) + if (request.TryGetDataAs(out var signal)) { switch (signal.Signal) { diff --git a/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs b/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs index bed7d3fe6d..8ed879c685 100644 --- a/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs @@ -34,10 +34,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create the executors ChatClientAgent physicist = new( @@ -56,12 +53,12 @@ private static async Task Main() // Build the workflow by adding executors and connecting them var workflow = new WorkflowBuilder(startExecutor) .AddFanOutEdge(startExecutor, [physicist, chemist]) - .AddFanInEdge([physicist, chemist], aggregationExecutor) + .AddFanInBarrierEdge([physicist, chemist], aggregationExecutor) .WithOutputFrom(aggregationExecutor) .Build(); // Execute the workflow in streaming mode - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input: "What is temperature?"); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input: "What is temperature?"); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { if (evt is WorkflowOutputEvent output) diff --git a/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs b/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs index 1b36b3eeb0..81fbb6b28a 100644 --- a/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs @@ -63,9 +63,9 @@ public static Workflow BuildWorkflow() // Step 4: Build the concurrent workflow with fan-out/fan-in pattern return new WorkflowBuilder(splitter) .AddFanOutEdge(splitter, [.. mappers]) // Split -> many mappers - .AddFanInEdge([.. mappers], shuffler) // All mappers -> shuffle + .AddFanInBarrierEdge([.. mappers], shuffler) // All mappers -> shuffle .AddFanOutEdge(shuffler, [.. reducers]) // Shuffle -> many reducers - .AddFanInEdge([.. reducers], completion) // All reducers -> completion + .AddFanInBarrierEdge([.. reducers], completion) // All reducers -> completion .WithOutputFrom(completion) .Build(); } @@ -99,7 +99,7 @@ private static async Task RunWorkflowAsync(Workflow workflow) // Step 2: Run the workflow Console.WriteLine("\n=== RUNNING WORKFLOW ===\n"); - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input: rawText); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input: rawText); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { Console.WriteLine($"Event: {evt}"); diff --git a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/01_EdgeCondition/Program.cs b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/01_EdgeCondition/Program.cs index a04f081ef2..f22ab6e269 100644 --- a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/01_EdgeCondition/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/01_EdgeCondition/Program.cs @@ -37,10 +37,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create agents AIAgent spamDetectionAgent = GetSpamDetectionAgent(chatClient); @@ -64,7 +61,7 @@ private static async Task Main() string email = Resources.Read("spam.txt"); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, email)); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new ChatMessage(ChatRole.User, email)); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { diff --git a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/02_SwitchCase/Program.cs b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/02_SwitchCase/Program.cs index 4919bcea09..69a8ec0826 100644 --- a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/02_SwitchCase/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/02_SwitchCase/Program.cs @@ -38,10 +38,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create agents AIAgent spamDetectionAgent = GetSpamDetectionAgent(chatClient); @@ -80,7 +77,7 @@ private static async Task Main() string email = Resources.Read("ambiguous_email.txt"); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, email)); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new ChatMessage(ChatRole.User, email)); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { diff --git a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/03_MultiSelection/Program.cs b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/03_MultiSelection/Program.cs index 32a727f8b7..22eb589dbb 100644 --- a/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/03_MultiSelection/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/ConditionalEdges/03_MultiSelection/Program.cs @@ -40,10 +40,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create agents AIAgent emailAnalysisAgent = GetEmailAnalysisAgent(chatClient); @@ -88,7 +85,7 @@ private static async Task Main() string email = Resources.Read("email.txt"); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, email)); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new ChatMessage(ChatRole.User, email)); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { diff --git a/dotnet/samples/GettingStarted/Workflows/HumanInTheLoop/HumanInTheLoopBasic/Program.cs b/dotnet/samples/GettingStarted/Workflows/HumanInTheLoop/HumanInTheLoopBasic/Program.cs index b7d2da6144..0b85757435 100644 --- a/dotnet/samples/GettingStarted/Workflows/HumanInTheLoop/HumanInTheLoopBasic/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/HumanInTheLoop/HumanInTheLoopBasic/Program.cs @@ -27,7 +27,7 @@ private static async Task Main() var workflow = WorkflowFactory.BuildWorkflow(); // Execute the workflow - await using StreamingRun handle = await InProcessExecution.StreamAsync(workflow, NumberSignal.Init); + await using StreamingRun handle = await InProcessExecution.RunStreamingAsync(workflow, NumberSignal.Init); await foreach (WorkflowEvent evt in handle.WatchStreamAsync()) { switch (evt) @@ -48,9 +48,9 @@ private static async Task Main() private static ExternalResponse HandleExternalRequest(ExternalRequest request) { - if (request.DataIs()) + if (request.TryGetDataAs(out var signal)) { - switch (request.DataAs()) + switch (signal) { case NumberSignal.Init: int initialGuess = ReadIntegerFromConsole("Please provide your initial guess: "); diff --git a/dotnet/samples/GettingStarted/Workflows/Loop/Program.cs b/dotnet/samples/GettingStarted/Workflows/Loop/Program.cs index a4004f333e..00f20191b8 100644 --- a/dotnet/samples/GettingStarted/Workflows/Loop/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Loop/Program.cs @@ -32,7 +32,7 @@ private static async Task Main() .Build(); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, NumberSignal.Init); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, NumberSignal.Init); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { if (evt is WorkflowOutputEvent outputEvent) diff --git a/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/Program.cs b/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/Program.cs index c61e690adb..19a3339754 100644 --- a/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/Program.cs @@ -73,10 +73,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()) + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()) .GetChatClient(deploymentName) .AsIChatClient() .AsBuilder() @@ -89,7 +86,7 @@ private static async Task Main() // Create the workflow and turn it into an agent with OpenTelemetry instrumentation var workflow = WorkflowHelper.GetWorkflow(chatClient, SourceName); - var agent = new OpenTelemetryAgent(workflow.AsAgent("workflow-agent", "Workflow Agent"), SourceName) + var agent = new OpenTelemetryAgent(workflow.AsAIAgent("workflow-agent", "Workflow Agent"), SourceName) { EnableSensitiveData = true // enable sensitive data at the agent level such as prompts and responses }; diff --git a/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowHelper.cs b/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowHelper.cs index 04eb68a325..54e3eb40f2 100644 --- a/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowHelper.cs +++ b/dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowHelper.cs @@ -25,7 +25,7 @@ internal static Workflow GetWorkflow(IChatClient chatClient, string sourceName) // Build the workflow by adding executors and connecting them return new WorkflowBuilder(startExecutor) .AddFanOutEdge(startExecutor, [frenchAgent, englishAgent]) - .AddFanInEdge([frenchAgent, englishAgent], aggregationExecutor) + .AddFanInBarrierEdge([frenchAgent, englishAgent], aggregationExecutor) .WithOutputFrom(aggregationExecutor) .Build(); } diff --git a/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs b/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs index b7cbc25515..1ee842fd84 100644 --- a/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs @@ -27,7 +27,7 @@ private static async Task Main() // Build the workflow by connecting executors sequentially var workflow = new WorkflowBuilder(fileRead) .AddFanOutEdge(fileRead, [wordCount, paragraphCount]) - .AddFanInEdge([wordCount, paragraphCount], aggregate) + .AddFanInBarrierEdge([wordCount, paragraphCount], aggregate) .WithOutputFrom(aggregate) .Build(); diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/02_Streaming/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/02_Streaming/Program.cs index 3406e361ff..81ca2f3276 100644 --- a/dotnet/samples/GettingStarted/Workflows/_Foundational/02_Streaming/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/02_Streaming/Program.cs @@ -28,7 +28,7 @@ private static async Task Main() var workflow = builder.Build(); // Execute the workflow in streaming mode - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input: "Hello, World!"); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input: "Hello, World!"); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { if (evt is ExecutorCompletedEvent executorCompleted) diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/03_AgentsInWorkflows/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/03_AgentsInWorkflows/Program.cs index 126401250c..990b5f9f17 100644 --- a/dotnet/samples/GettingStarted/Workflows/_Foundational/03_AgentsInWorkflows/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/03_AgentsInWorkflows/Program.cs @@ -30,10 +30,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create agents AIAgent frenchAgent = GetTranslationAgent("French", chatClient); @@ -47,7 +44,7 @@ private static async Task Main() .Build(); // Execute the workflow - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, "Hello World!")); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new ChatMessage(ChatRole.User, "Hello World!")); // Must send the turn token to trigger the agents. // The agents are wrapped as executors. When they receive messages, diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/04_AgentWorkflowPatterns/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/04_AgentWorkflowPatterns/Program.cs index 0df9d34913..ae8208e964 100644 --- a/dotnet/samples/GettingStarted/Workflows/_Foundational/04_AgentWorkflowPatterns/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/04_AgentWorkflowPatterns/Program.cs @@ -25,10 +25,7 @@ private static async Task Main() // Set up the Azure OpenAI client. 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var client = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); Console.Write("Choose workflow type ('sequential', 'concurrent', 'handoffs', 'groupchat'): "); switch (Console.ReadLine()) @@ -87,7 +84,7 @@ static async Task> RunWorkflowAsync(Workflow workflow, List Fact-Checker -> Reporter -AIAgent workflowAgent = AgentWorkflowBuilder.BuildSequential(researcher, factChecker, reporter).AsAgent(); +AIAgent workflowAgent = AgentWorkflowBuilder.BuildSequential(researcher, factChecker, reporter).AsAIAgent(); // Run the workflow, streaming the output as it arrives. string? lastAuthor = null; diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/07_MixedWorkflowAgentsAndExecutors/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/07_MixedWorkflowAgentsAndExecutors/Program.cs index 5269b5b974..7b961d1a4c 100644 --- a/dotnet/samples/GettingStarted/Workflows/_Foundational/07_MixedWorkflowAgentsAndExecutors/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/07_MixedWorkflowAgentsAndExecutors/Program.cs @@ -43,10 +43,7 @@ private static async Task Main() // Set up the Azure OpenAI client 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"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + var chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create executors for text processing UserInputExecutor userInput = new(); @@ -135,7 +132,7 @@ private static async Task ExecuteWorkflowAsync(Workflow workflow, string input) const bool ShowAgentThinking = true; // Execute in streaming mode to see real-time progress - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input); // Watch the workflow events await foreach (WorkflowEvent evt in run.WatchStreamAsync()) diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.cs index d9382ba93f..f93372bc54 100644 --- a/dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.cs +++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.cs @@ -50,10 +50,7 @@ private static async Task Main() // Set up the Azure OpenAI client string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set."); string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; - // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. - // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid - // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. - IChatClient chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential()).GetChatClient(deploymentName).AsIChatClient(); + IChatClient chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient(); // Create executors for content creation and review WriterExecutor writer = new(chatClient); @@ -92,7 +89,7 @@ private static async Task Main() private static async Task ExecuteWorkflowAsync(Workflow workflow, string input) { // Execute in streaming mode to see real-time progress - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, input); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input); // Watch the workflow events await foreach (WorkflowEvent evt in run.WatchStreamAsync()) diff --git a/dotnet/src/Microsoft.Agents.AI.CosmosNoSql/CosmosCheckpointStore.cs b/dotnet/src/Microsoft.Agents.AI.CosmosNoSql/CosmosCheckpointStore.cs index e0073feaf9..461027dfa5 100644 --- a/dotnet/src/Microsoft.Agents.AI.CosmosNoSql/CosmosCheckpointStore.cs +++ b/dotnet/src/Microsoft.Agents.AI.CosmosNoSql/CosmosCheckpointStore.cs @@ -95,11 +95,11 @@ public CosmosCheckpointStore(CosmosClient cosmosClient, string databaseId, strin public string ContainerId => this._container.Id; /// - public override async ValueTask CreateCheckpointAsync(string runId, JsonElement value, CheckpointInfo? parent = null) + public override async ValueTask CreateCheckpointAsync(string sessionId, JsonElement value, CheckpointInfo? parent = null) { - if (string.IsNullOrWhiteSpace(runId)) + if (string.IsNullOrWhiteSpace(sessionId)) { - throw new ArgumentException("Cannot be null or whitespace", nameof(runId)); + throw new ArgumentException("Cannot be null or whitespace", nameof(sessionId)); } #pragma warning disable CA1513 // Use ObjectDisposedException.ThrowIf - not available on all target frameworks @@ -110,28 +110,28 @@ public override async ValueTask CreateCheckpointAsync(string run #pragma warning restore CA1513 var checkpointId = Guid.NewGuid().ToString("N"); - var checkpointInfo = new CheckpointInfo(runId, checkpointId); + var checkpointInfo = new CheckpointInfo(sessionId, checkpointId); var document = new CosmosCheckpointDocument { - Id = $"{runId}_{checkpointId}", - RunId = runId, + Id = $"{sessionId}_{checkpointId}", + SessionId = sessionId, CheckpointId = checkpointId, Value = JToken.Parse(value.GetRawText()), ParentCheckpointId = parent?.CheckpointId, Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }; - await this._container.CreateItemAsync(document, new PartitionKey(runId)).ConfigureAwait(false); + await this._container.CreateItemAsync(document, new PartitionKey(sessionId)).ConfigureAwait(false); return checkpointInfo; } /// - public override async ValueTask RetrieveCheckpointAsync(string runId, CheckpointInfo key) + public override async ValueTask RetrieveCheckpointAsync(string sessionId, CheckpointInfo key) { - if (string.IsNullOrWhiteSpace(runId)) + if (string.IsNullOrWhiteSpace(sessionId)) { - throw new ArgumentException("Cannot be null or whitespace", nameof(runId)); + throw new ArgumentException("Cannot be null or whitespace", nameof(sessionId)); } if (key is null) @@ -146,26 +146,26 @@ public override async ValueTask RetrieveCheckpointAsync(string runI } #pragma warning restore CA1513 - var id = $"{runId}_{key.CheckpointId}"; + var id = $"{sessionId}_{key.CheckpointId}"; try { - var response = await this._container.ReadItemAsync(id, new PartitionKey(runId)).ConfigureAwait(false); + var response = await this._container.ReadItemAsync(id, new PartitionKey(sessionId)).ConfigureAwait(false); using var document = JsonDocument.Parse(response.Resource.Value.ToString()); return document.RootElement.Clone(); } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { - throw new InvalidOperationException($"Checkpoint with ID '{key.CheckpointId}' for run '{runId}' not found."); + throw new InvalidOperationException($"Checkpoint with ID '{key.CheckpointId}' for session '{sessionId}' not found."); } } /// - public override async ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null) + public override async ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) { - if (string.IsNullOrWhiteSpace(runId)) + if (string.IsNullOrWhiteSpace(sessionId)) { - throw new ArgumentException("Cannot be null or whitespace", nameof(runId)); + throw new ArgumentException("Cannot be null or whitespace", nameof(sessionId)); } #pragma warning disable CA1513 // Use ObjectDisposedException.ThrowIf - not available on all target frameworks @@ -176,10 +176,10 @@ public override async ValueTask> RetrieveIndexAsync( #pragma warning restore CA1513 QueryDefinition query = withParent == null - ? new QueryDefinition("SELECT c.runId, c.checkpointId FROM c WHERE c.runId = @runId ORDER BY c.timestamp ASC") - .WithParameter("@runId", runId) - : new QueryDefinition("SELECT c.runId, c.checkpointId FROM c WHERE c.runId = @runId AND c.parentCheckpointId = @parentCheckpointId ORDER BY c.timestamp ASC") - .WithParameter("@runId", runId) + ? new QueryDefinition("SELECT c.sessionId, c.checkpointId FROM c WHERE c.sessionId = @sessionId ORDER BY c.timestamp ASC") + .WithParameter("@sessionId", sessionId) + : new QueryDefinition("SELECT c.sessionId, c.checkpointId FROM c WHERE c.sessionId = @sessionId AND c.parentCheckpointId = @parentCheckpointId ORDER BY c.timestamp ASC") + .WithParameter("@sessionId", sessionId) .WithParameter("@parentCheckpointId", withParent.CheckpointId); var iterator = this._container.GetItemQueryIterator(query); @@ -188,7 +188,7 @@ public override async ValueTask> RetrieveIndexAsync( while (iterator.HasMoreResults) { var response = await iterator.ReadNextAsync().ConfigureAwait(false); - checkpoints.AddRange(response.Select(r => new CheckpointInfo(r.RunId, r.CheckpointId))); + checkpoints.AddRange(response.Select(r => new CheckpointInfo(r.SessionId, r.CheckpointId))); } return checkpoints; @@ -223,8 +223,8 @@ internal sealed class CosmosCheckpointDocument [JsonProperty("id")] public string Id { get; set; } = string.Empty; - [JsonProperty("runId")] - public string RunId { get; set; } = string.Empty; + [JsonProperty("sessionId")] + public string SessionId { get; set; } = string.Empty; [JsonProperty("checkpointId")] public string CheckpointId { get; set; } = string.Empty; @@ -245,7 +245,7 @@ internal sealed class CosmosCheckpointDocument [SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Instantiated by Cosmos DB query deserialization")] private sealed class CheckpointQueryResult { - public string RunId { get; set; } = string.Empty; + public string SessionId { get; set; } = string.Empty; public string CheckpointId { get; set; } = string.Empty; } } diff --git a/dotnet/src/Microsoft.Agents.AI.DevUI/ServiceCollectionsExtensions.cs b/dotnet/src/Microsoft.Agents.AI.DevUI/ServiceCollectionsExtensions.cs index 6971e3d2e0..827a7f6c4d 100644 --- a/dotnet/src/Microsoft.Agents.AI.DevUI/ServiceCollectionsExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.DevUI/ServiceCollectionsExtensions.cs @@ -32,7 +32,7 @@ public static IServiceCollection AddDevUI(this IServiceCollection services) var workflow = sp.GetKeyedService(keyAsStr); if (workflow is not null) { - return workflow.AsAgent(name: workflow.Name); + return workflow.AsAIAgent(name: workflow.Name); } // another thing we can do is resolve a non-keyed workflow. @@ -41,7 +41,7 @@ public static IServiceCollection AddDevUI(this IServiceCollection services) workflow = sp.GetService(); if (workflow is not null && workflow.Name?.Equals(keyAsStr, StringComparison.Ordinal) == true) { - return workflow.AsAgent(name: workflow.Name); + return workflow.AsAIAgent(name: workflow.Name); } // and it's possible to lookup at the default-registered AIAgent diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting/HostedWorkflowBuilderExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting/HostedWorkflowBuilderExtensions.cs index ca3d84fa86..f01a12c7ea 100644 --- a/dotnet/src/Microsoft.Agents.AI.Hosting/HostedWorkflowBuilderExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Hosting/HostedWorkflowBuilderExtensions.cs @@ -30,6 +30,6 @@ public static IHostedAgentBuilder AddAsAIAgent(this IHostedWorkflowBuilder build var agentName = name ?? workflowName; return builder.HostApplicationBuilder.AddAIAgent(agentName, (sp, key) => - sp.GetRequiredKeyedService(workflowName).AsAgent(name: key)); + sp.GetRequiredKeyedService(workflowName).AsAIAgent(name: key)); } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/AgentWorkflowBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/AgentWorkflowBuilder.cs index e2046d41e5..501c7df230 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/AgentWorkflowBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/AgentWorkflowBuilder.cs @@ -135,7 +135,7 @@ private static Workflow BuildConcurrentCore( ExecutorBinding end = endFactory.BindExecutor(ConcurrentEndExecutor.ExecutorId); - builder.AddFanInEdge(accumulators, end); + builder.AddFanInBarrierEdge(accumulators, end); builder = builder.WithOutputFrom(end); if (workflowName is not null) diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointInfo.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointInfo.cs index 25b1d8ce82..290aaa697f 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointInfo.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointInfo.cs @@ -7,14 +7,14 @@ namespace Microsoft.Agents.AI.Workflows; /// -/// Represents a checkpoint with a unique identifier and a timestamp indicating when it was created. +/// Represents a checkpoint with a unique identifier. /// public sealed class CheckpointInfo : IEquatable { /// - /// Gets the unique identifier for the current run. + /// Gets the unique identifier for the current session. /// - public string RunId { get; } + public string SessionId { get; } /// /// The unique identifier for the checkpoint. @@ -22,37 +22,34 @@ public sealed class CheckpointInfo : IEquatable public string CheckpointId { get; } /// - /// Initializes a new instance of the class with a unique identifier and the current - /// UTC timestamp. + /// Initializes a new instance of the class with a unique identifier. /// - /// This constructor generates a new unique identifier using a GUID in a 32-character, lowercase, - /// hexadecimal format and sets the timestamp to the current UTC time. - internal CheckpointInfo(string runId) : this(runId, Guid.NewGuid().ToString("N")) { } + internal CheckpointInfo(string sessionId) : this(sessionId, Guid.NewGuid().ToString("N")) { } /// - /// Initializes a new instance of the CheckpointInfo class with the specified run and checkpoint identifiers. + /// Initializes a new instance of the CheckpointInfo class with the specified session and checkpoint identifiers. /// - /// The unique identifier for the run. Cannot be null or empty. + /// The unique identifier for the session. Cannot be null or empty. /// The unique identifier for the checkpoint. Cannot be null or empty. [JsonConstructor] - public CheckpointInfo(string runId, string checkpointId) + public CheckpointInfo(string sessionId, string checkpointId) { - this.RunId = Throw.IfNullOrEmpty(runId); + this.SessionId = Throw.IfNullOrEmpty(sessionId); this.CheckpointId = Throw.IfNullOrEmpty(checkpointId); } /// public bool Equals(CheckpointInfo? other) => other is not null && - this.RunId == other.RunId && + this.SessionId == other.SessionId && this.CheckpointId == other.CheckpointId; /// public override bool Equals(object? obj) => this.Equals(obj as CheckpointInfo); /// - public override int GetHashCode() => HashCode.Combine(this.RunId, this.CheckpointId); + public override int GetHashCode() => HashCode.Combine(this.SessionId, this.CheckpointId); /// - public override string ToString() => $"CheckpointInfo(RunId: {this.RunId}, CheckpointId: {this.CheckpointId})"; + public override string ToString() => $"CheckpointInfo(SessionId: {this.SessionId}, CheckpointId: {this.CheckpointId})"; } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointManager.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointManager.cs index 57aed944c5..2b5bb5b034 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointManager.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/CheckpointManager.cs @@ -50,12 +50,12 @@ public static CheckpointManager CreateJson(ICheckpointStore store, return new(CreateImpl(marshaller, store)); } - ValueTask ICheckpointManager.CommitCheckpointAsync(string runId, Checkpoint checkpoint) - => this._impl.CommitCheckpointAsync(runId, checkpoint); + ValueTask ICheckpointManager.CommitCheckpointAsync(string sessionId, Checkpoint checkpoint) + => this._impl.CommitCheckpointAsync(sessionId, checkpoint); - ValueTask ICheckpointManager.LookupCheckpointAsync(string runId, CheckpointInfo checkpointInfo) - => this._impl.LookupCheckpointAsync(runId, checkpointInfo); + ValueTask ICheckpointManager.LookupCheckpointAsync(string sessionId, CheckpointInfo checkpointInfo) + => this._impl.LookupCheckpointAsync(sessionId, checkpointInfo); - ValueTask> ICheckpointManager.RetrieveIndexAsync(string runId, CheckpointInfo? withParent) - => this._impl.RetrieveIndexAsync(runId, withParent); + ValueTask> ICheckpointManager.RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent) + => this._impl.RetrieveIndexAsync(sessionId, withParent); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointInfoConverter.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointInfoConverter.cs index 53c277d822..86e25e3f2a 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointInfoConverter.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointInfoConverter.cs @@ -15,7 +15,7 @@ internal sealed partial class CheckpointInfoConverter() : JsonConverterDictionar protected override JsonTypeInfo TypeInfo => WorkflowsJsonUtilities.JsonContext.Default.CheckpointInfo; - private const string CheckpointInfoPropertyNamePattern = @"^(?(((\|\|)|([^\|]))*))\|(?(((\|\|)|([^\|]))*)?)$"; + private const string CheckpointInfoPropertyNamePattern = @"^(?(((\|\|)|([^\|]))*))\|(?(((\|\|)|([^\|]))*)?)$"; #if NET [GeneratedRegex(CheckpointInfoPropertyNamePattern, RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture)] public static partial Regex CheckpointInfoPropertyNameRegex(); @@ -33,17 +33,17 @@ protected override CheckpointInfo Parse(string propertyName) throw new JsonException($"Invalid CheckpointInfo property name format. Got '{propertyName}'."); } - string runId = scopeKeyPatternMatch.Groups["runId"].Value; + string sessionId = scopeKeyPatternMatch.Groups["sessionId"].Value; string checkpointId = scopeKeyPatternMatch.Groups["checkpointId"].Value; - return new(Unescape(runId)!, Unescape(checkpointId)!); + return new(Unescape(sessionId)!, Unescape(checkpointId)!); } protected override string Stringify([DisallowNull] CheckpointInfo value) { - string? runIdEscaped = Escape(value.RunId); + string? sessionIdEscaped = Escape(value.SessionId); string? checkpointIdEscaped = Escape(value.CheckpointId); - return $"{runIdEscaped}|{checkpointIdEscaped}"; + return $"{sessionIdEscaped}|{checkpointIdEscaped}"; } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointManagerImpl.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointManagerImpl.cs index 086945c2b2..3b93d72517 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointManagerImpl.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/CheckpointManagerImpl.cs @@ -16,19 +16,19 @@ public CheckpointManagerImpl(IWireMarshaller marshaller, ICheckpoi this._store = store; } - public ValueTask CommitCheckpointAsync(string runId, Checkpoint checkpoint) + public ValueTask CommitCheckpointAsync(string sessionId, Checkpoint checkpoint) { TStoreObject storeObject = this._marshaller.Marshal(checkpoint); - return this._store.CreateCheckpointAsync(runId, storeObject, checkpoint.Parent); + return this._store.CreateCheckpointAsync(sessionId, storeObject, checkpoint.Parent); } - public async ValueTask LookupCheckpointAsync(string runId, CheckpointInfo checkpointInfo) + public async ValueTask LookupCheckpointAsync(string sessionId, CheckpointInfo checkpointInfo) { - TStoreObject result = await this._store.RetrieveCheckpointAsync(runId, checkpointInfo).ConfigureAwait(false); + TStoreObject result = await this._store.RetrieveCheckpointAsync(sessionId, checkpointInfo).ConfigureAwait(false); return this._marshaller.Marshal(result); } - public ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null) - => this._store.RetrieveIndexAsync(runId, withParent); + public ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) + => this._store.RetrieveIndexAsync(sessionId, withParent); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/FileSystemJsonCheckpointStore.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/FileSystemJsonCheckpointStore.cs index 611c1896cf..543fdeb530 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/FileSystemJsonCheckpointStore.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/FileSystemJsonCheckpointStore.cs @@ -93,15 +93,15 @@ private void CheckDisposed() } } - private string GetFileNameForCheckpoint(string runId, CheckpointInfo key) - => Path.Combine(this.Directory.FullName, $"{runId}_{key.CheckpointId}.json"); + private string GetFileNameForCheckpoint(string sessionId, CheckpointInfo key) + => Path.Combine(this.Directory.FullName, $"{sessionId}_{key.CheckpointId}.json"); - private CheckpointInfo GetUnusedCheckpointInfo(string runId) + private CheckpointInfo GetUnusedCheckpointInfo(string sessionId) { CheckpointInfo key; do { - key = new(runId); + key = new(sessionId); } while (!this.CheckpointIndex.Add(key)); return key; @@ -110,12 +110,12 @@ private CheckpointInfo GetUnusedCheckpointInfo(string runId) /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1835:Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'", Justification = "Memory-based overload is missing for 4.7.2")] - public override async ValueTask CreateCheckpointAsync(string runId, JsonElement value, CheckpointInfo? parent = null) + public override async ValueTask CreateCheckpointAsync(string sessionId, JsonElement value, CheckpointInfo? parent = null) { this.CheckDisposed(); - CheckpointInfo key = this.GetUnusedCheckpointInfo(runId); - string fileName = this.GetFileNameForCheckpoint(runId, key); + CheckpointInfo key = this.GetUnusedCheckpointInfo(sessionId); + string fileName = this.GetFileNameForCheckpoint(sessionId, key); try { using Stream checkpointStream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None); @@ -145,10 +145,10 @@ public override async ValueTask CreateCheckpointAsync(string run } /// - public override async ValueTask RetrieveCheckpointAsync(string runId, CheckpointInfo key) + public override async ValueTask RetrieveCheckpointAsync(string sessionId, CheckpointInfo key) { this.CheckDisposed(); - string fileName = this.GetFileNameForCheckpoint(runId, key); + string fileName = this.GetFileNameForCheckpoint(sessionId, key); if (!this.CheckpointIndex.Contains(key) || !File.Exists(fileName)) @@ -163,7 +163,7 @@ public override async ValueTask RetrieveCheckpointAsync(string runI } /// - public override ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null) + public override ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) { this.CheckDisposed(); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointManager.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointManager.cs index caf1403e86..19ccc7dfef 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointManager.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointManager.cs @@ -13,30 +13,30 @@ internal interface ICheckpointManager /// /// Commits the specified checkpoint and returns information that can be used to retrieve it later. /// - /// The identifier for the current run or execution context. + /// The identifier for the current session or execution context. /// The checkpoint to commit. /// A representing the incoming checkpoint. - ValueTask CommitCheckpointAsync(string runId, Checkpoint checkpoint); + ValueTask CommitCheckpointAsync(string sessionId, Checkpoint checkpoint); /// /// Retrieves the checkpoint associated with the specified checkpoint information. /// - /// The identifier for the current run of execution context. + /// The identifier for the current session of execution context. /// The information used to identify the checkpoint. /// A representing the asynchronous operation. The result contains the associated with the specified . /// Thrown if the checkpoint is not found. - ValueTask LookupCheckpointAsync(string runId, CheckpointInfo checkpointInfo); + ValueTask LookupCheckpointAsync(string sessionId, CheckpointInfo checkpointInfo); /// - /// Asynchronously retrieves the collection of checkpoint information for the specified run identifier, optionally + /// Asynchronously retrieves the collection of checkpoint information for the specified session identifier, optionally /// filtered by a parent checkpoint. /// - /// The unique identifier of the run for which to retrieve checkpoint information. Cannot be null or empty. + /// The unique identifier of the session for which to retrieve checkpoint information. Cannot be null or empty. /// An optional parent checkpoint to filter the results. If specified, only checkpoints with the given parent are - /// returned; otherwise, all checkpoints for the run are included. + /// returned; otherwise, all checkpoints for the session are included. /// A value task representing the asynchronous operation. The result contains a collection of objects associated with the specified run. The collection is empty if no checkpoints are + /// cref="CheckpointInfo"/> objects associated with the specified session. The collection is empty if no checkpoints are /// found. - ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null); + ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointStore.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointStore.cs index 042d374b7e..af2fa5423e 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointStore.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/ICheckpointStore.cs @@ -6,44 +6,41 @@ namespace Microsoft.Agents.AI.Workflows.Checkpointing; /// -/// Defines a contract for storing and retrieving checkpoints associated with a specific run and key. +/// Defines a contract for storing and retrieving checkpoints associated with a specific session and key. /// -/// Implementations of this interface enable durable or in-memory storage of checkpoints, which can be -/// used to resume or audit long-running processes. The interface is generic to support different storage object types -/// depending on the application's requirements. /// The type of object to be stored as the value for each checkpoint. public interface ICheckpointStore { /// - /// Asynchronously retrieves the collection of checkpoint information for the specified run identifier, optionally + /// Asynchronously retrieves the collection of checkpoint information for the specified session identifier, optionally /// filtered by a parent checkpoint. /// - /// The unique identifier of the run for which to retrieve checkpoint information. Cannot be null or empty. + /// The unique identifier of the session for which to retrieve checkpoint information. Cannot be null or empty. /// An optional parent checkpoint to filter the results. If specified, only checkpoints with the given parent are - /// returned; otherwise, all checkpoints for the run are included. + /// returned; otherwise, all checkpoints for the session are included. /// A value task representing the asynchronous operation. The result contains a collection of objects associated with the specified run. The collection is empty if no checkpoints are + /// cref="CheckpointInfo"/> objects associated with the specified session. The collection is empty if no checkpoints are /// found. - ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null); + ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null); /// - /// Asynchronously creates a checkpoint for the specified run and key, associating it with the provided value and + /// Asynchronously creates a checkpoint for the specified session and key, associating it with the provided value and /// optional parent checkpoint. /// - /// The unique identifier of the run for which the checkpoint is being created. Cannot be null or empty. + /// The unique identifier of the session for which the checkpoint is being created. Cannot be null or empty. /// The value to associate with the checkpoint. Cannot be null. /// The optional parent checkpoint information. If specified, the new checkpoint will be linked as a child of this /// parent. /// A ValueTask that represents the asynchronous operation. The result contains the /// object representing this stored checkpoint. - ValueTask CreateCheckpointAsync(string runId, TStoreObject value, CheckpointInfo? parent = null); + ValueTask CreateCheckpointAsync(string sessionId, TStoreObject value, CheckpointInfo? parent = null); /// - /// Asynchronously retrieves a checkpoint object associated with the specified run and checkpoint key. + /// Asynchronously retrieves a checkpoint object associated with the specified session and checkpoint key. /// - /// The unique identifier of the run for which the checkpoint is to be retrieved. Cannot be null or empty. + /// The unique identifier of the session for which the checkpoint is to be retrieved. Cannot be null or empty. /// The key identifying the specific checkpoint to retrieve. Cannot be null. /// A ValueTask that represents the asynchronous operation. The result contains the checkpoint object associated - /// with the specified run and key. - ValueTask RetrieveCheckpointAsync(string runId, CheckpointInfo key); + /// with the specified session and key. + ValueTask RetrieveCheckpointAsync(string sessionId, CheckpointInfo key); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/InMemoryCheckpointManager.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/InMemoryCheckpointManager.cs index cbb4af227a..f17e8f9aa4 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/InMemoryCheckpointManager.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/InMemoryCheckpointManager.cs @@ -13,54 +13,54 @@ namespace Microsoft.Agents.AI.Workflows.Checkpointing; internal sealed class InMemoryCheckpointManager : ICheckpointManager { [JsonInclude] - internal Dictionary> Store { get; } = []; + internal Dictionary> Store { get; } = []; public InMemoryCheckpointManager() { } [JsonConstructor] - internal InMemoryCheckpointManager(Dictionary> store) + internal InMemoryCheckpointManager(Dictionary> store) { this.Store = store; } - private RunCheckpointCache GetRunStore(string runId) + private SessionCheckpointCache GetSessionStore(string sessionId) { - if (!this.Store.TryGetValue(runId, out RunCheckpointCache? runStore)) + if (!this.Store.TryGetValue(sessionId, out SessionCheckpointCache? sessionStore)) { - runStore = this.Store[runId] = new(); + sessionStore = this.Store[sessionId] = new(); } - return runStore; + return sessionStore; } - public ValueTask CommitCheckpointAsync(string runId, Checkpoint checkpoint) + public ValueTask CommitCheckpointAsync(string sessionId, Checkpoint checkpoint) { - RunCheckpointCache runStore = this.GetRunStore(runId); + SessionCheckpointCache sessionStore = this.GetSessionStore(sessionId); CheckpointInfo key; do { - key = new(runId); - } while (!runStore.Add(key, checkpoint)); + key = new(sessionId); + } while (!sessionStore.Add(key, checkpoint)); return new(key); } - public ValueTask LookupCheckpointAsync(string runId, CheckpointInfo checkpointInfo) + public ValueTask LookupCheckpointAsync(string sessionId, CheckpointInfo checkpointInfo) { - if (!this.GetRunStore(runId).TryGet(checkpointInfo, out Checkpoint? value)) + if (!this.GetSessionStore(sessionId).TryGet(checkpointInfo, out Checkpoint? value)) { - throw new KeyNotFoundException($"Could not retrieve checkpoint with id {checkpointInfo.CheckpointId} for run {runId}"); + throw new KeyNotFoundException($"Could not retrieve checkpoint with id {checkpointInfo.CheckpointId} for session {sessionId}"); } return new(value); } - internal bool HasCheckpoints(string runId) => this.GetRunStore(runId).HasCheckpoints; + internal bool HasCheckpoints(string sessionId) => this.GetSessionStore(sessionId).HasCheckpoints; - public bool TryGetLastCheckpoint(string runId, [NotNullWhen(true)] out CheckpointInfo? checkpoint) - => this.GetRunStore(runId).TryGetLastCheckpointInfo(out checkpoint); + public bool TryGetLastCheckpoint(string sessionId, [NotNullWhen(true)] out CheckpointInfo? checkpoint) + => this.GetSessionStore(sessionId).TryGetLastCheckpointInfo(out checkpoint); - public ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null) - => new(this.GetRunStore(runId).CheckpointIndex.AsReadOnly()); + public ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) + => new(this.GetSessionStore(sessionId).CheckpointIndex.AsReadOnly()); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/JsonCheckpointStore.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/JsonCheckpointStore.cs index 7da28bdee9..a014daf326 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/JsonCheckpointStore.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/JsonCheckpointStore.cs @@ -18,11 +18,11 @@ public abstract class JsonCheckpointStore : ICheckpointStore protected static JsonTypeInfo KeyTypeInfo => WorkflowsJsonUtilities.JsonContext.Default.CheckpointInfo; /// - public abstract ValueTask CreateCheckpointAsync(string runId, JsonElement value, CheckpointInfo? parent = null); + public abstract ValueTask CreateCheckpointAsync(string sessionId, JsonElement value, CheckpointInfo? parent = null); /// - public abstract ValueTask RetrieveCheckpointAsync(string runId, CheckpointInfo key); + public abstract ValueTask RetrieveCheckpointAsync(string sessionId, CheckpointInfo key); /// - public abstract ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null); + public abstract ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/RunCheckpointCache.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/SessionCheckpointCache.cs similarity index 83% rename from dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/RunCheckpointCache.cs rename to dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/SessionCheckpointCache.cs index 6dd5da9f9c..14adbeb0f4 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/RunCheckpointCache.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/SessionCheckpointCache.cs @@ -6,7 +6,7 @@ namespace Microsoft.Agents.AI.Workflows.Checkpointing; -internal sealed class RunCheckpointCache +internal sealed class SessionCheckpointCache { [JsonInclude] internal List CheckpointIndex { get; } = []; @@ -14,10 +14,10 @@ internal sealed class RunCheckpointCache [JsonInclude] internal Dictionary Cache { get; } = []; - public RunCheckpointCache() { } + public SessionCheckpointCache() { } [JsonConstructor] - internal RunCheckpointCache(List checkpointIndex, Dictionary cache) + internal SessionCheckpointCache(List checkpointIndex, Dictionary cache) { this.CheckpointIndex = checkpointIndex; this.Cache = cache; @@ -29,13 +29,13 @@ internal RunCheckpointCache(List checkpointIndex, Dictionary this.Cache.ContainsKey(key); public bool TryGet(CheckpointInfo key, [MaybeNullWhen(false)] out TStoreObject value) => this.Cache.TryGetValue(key, out value); - public CheckpointInfo Add(string runId, TStoreObject value) + public CheckpointInfo Add(string sessionId, TStoreObject value) { CheckpointInfo key; do { - key = new(runId); + key = new(sessionId); } while (!this.Add(key, value)); return key; diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/ConfigurationExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/ConfigurationExtensions.cs index ada1263ebd..e18bae72a5 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/ConfigurationExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/ConfigurationExtensions.cs @@ -16,7 +16,7 @@ public static class ConfigurationExtensions /// The existing configuration for the subject type to be upcast to its parent type. Cannot be null. /// A new instance that applies the original configuration logic to the parent type. public static Configured Super(this Configured configured) where TSubject : TParent - => new(async (config, runId) => await configured.FactoryAsync(config, runId).ConfigureAwait(false), configured.Id, configured.Raw); + => new(async (config, sessionId) => await configured.FactoryAsync(config, sessionId).ConfigureAwait(false), configured.Id, configured.Raw); /// /// Creates a new configuration that treats the subject as its base type, allowing configuration to be applied at diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Configured.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Configured.cs index 77e5e59029..3f876926be 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Configured.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Configured.cs @@ -79,7 +79,7 @@ public class Configured(Func> fact /// Gets a "partially" applied factory function that only requires no parameters to create an instance of /// with the provided instance. /// - internal Func> BoundFactoryAsync => (runId) => this.FactoryAsync(this.Configuration, runId); + internal Func> BoundFactoryAsync => (sessionId) => this.FactoryAsync(this.Configuration, sessionId); } /// @@ -122,20 +122,20 @@ public class Configured(Func, string, Value /// Gets a "partially" applied factory function that only requires no parameters to create an instance of /// with the provided instance. /// - internal Func> BoundFactoryAsync => (runId) => this.CreateValidatingMemoizedFactory()(this.Configuration, runId); + internal Func> BoundFactoryAsync => (sessionId) => this.CreateValidatingMemoizedFactory()(this.Configuration, sessionId); private Func> CreateValidatingMemoizedFactory() { return FactoryAsync; - async ValueTask FactoryAsync(Config configuration, string runId) + async ValueTask FactoryAsync(Config configuration, string sessionId) { if (this.Id != configuration.Id) { throw new InvalidOperationException($"Requested instance ID '{configuration.Id}' does not match configured ID '{this.Id}'."); } - TSubject subject = await this.FactoryAsync(this.Configuration, runId).ConfigureAwait(false); + TSubject subject = await this.FactoryAsync(this.Configuration, sessionId).ConfigureAwait(false); if (this.Id is not null && subject is IIdentified identified && identified.Id != this.Id) { diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/AsyncRunHandle.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/AsyncRunHandle.cs index 184be98bcb..f5d1d40370 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/AsyncRunHandle.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/AsyncRunHandle.cs @@ -44,7 +44,7 @@ internal AsyncRunHandle(ISuperStepRunner stepRunner, ICheckpointingHandle checkp } } - public string RunId => this._stepRunner.RunId; + public string SessionId => this._stepRunner.SessionId; public bool IsCheckpointingEnabled => this._checkpointingHandle.IsCheckpointingEnabled; diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ISuperStepRunner.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ISuperStepRunner.cs index fce4d9636a..9b8c3c460c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ISuperStepRunner.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ISuperStepRunner.cs @@ -9,7 +9,7 @@ namespace Microsoft.Agents.AI.Workflows.Execution; internal interface ISuperStepRunner { - string RunId { get; } + string SessionId { get; } string StartExecutorId { get; } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs index 250a9ee612..f26f27ad96 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/LockstepRunEventStream.cs @@ -51,7 +51,7 @@ public async IAsyncEnumerable TakeEventStreamAsync(bool blockOnPe this._stepRunner.OutgoingEvents.EventRaised += OnWorkflowEventAsync; using Activity? activity = this._stepRunner.TelemetryContext.StartWorkflowRunActivity(); - activity?.SetTag(Tags.WorkflowId, this._stepRunner.StartExecutorId).SetTag(Tags.RunId, this._stepRunner.RunId); + activity?.SetTag(Tags.WorkflowId, this._stepRunner.StartExecutorId).SetTag(Tags.SessionId, this._stepRunner.SessionId); try { diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StreamingRunEventStream.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StreamingRunEventStream.cs index 4cce8df844..a6c34f2b9f 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StreamingRunEventStream.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StreamingRunEventStream.cs @@ -61,7 +61,7 @@ private async Task RunLoopAsync(CancellationToken cancellationToken) this._stepRunner.OutgoingEvents.EventRaised += OnEventRaisedAsync; using Activity? activity = this._stepRunner.TelemetryContext.StartWorkflowRunActivity(); - activity?.SetTag(Tags.WorkflowId, this._stepRunner.StartExecutorId).SetTag(Tags.RunId, this._stepRunner.RunId); + activity?.SetTag(Tags.WorkflowId, this._stepRunner.StartExecutorId).SetTag(Tags.SessionId, this._stepRunner.SessionId); try { diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBinding.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBinding.cs index f4c196426c..c14f3d1a34 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBinding.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBinding.cs @@ -58,9 +58,9 @@ private Executor CheckId(Executor executor) return executor; } - internal async ValueTask CreateInstanceAsync(string runId) + internal async ValueTask CreateInstanceAsync(string sessionId) => !this.IsPlaceholder - ? this.CheckId(await this.FactoryAsync(runId).ConfigureAwait(false)) + ? this.CheckId(await this.FactoryAsync(sessionId).ConfigureAwait(false)) : throw new InvalidOperationException( $"Cannot create executor with ID '{this.Id}': Binding ({this.GetType().Name}) is a placeholder."); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBindingExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBindingExtensions.cs index edaf959ba7..a0170e7757 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBindingExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/ExecutorBindingExtensions.cs @@ -40,7 +40,7 @@ public static ExecutorBinding BindExecutor(this Executor executor) /// An instance that resolves to the result of the factory call when messages get sent to it. public static ExecutorBinding BindExecutor(this Func> factoryAsync) where TExecutor : Executor - => BindExecutor((config, runId) => factoryAsync(config.Id, runId), id: typeof(TExecutor).Name, options: null); + => BindExecutor((config, sessionId) => factoryAsync(config.Id, sessionId), id: typeof(TExecutor).Name, options: null); /// /// Configures a factory method for creating an of type , using the @@ -77,7 +77,7 @@ public static ExecutorBinding ConfigureFactory(this FuncAn instance that resolves to the result of the factory call when messages get sent to it. public static ExecutorBinding BindExecutor(this Func> factoryAsync, string id) where TExecutor : Executor - => BindExecutor((_, runId) => factoryAsync(id, runId), id, options: null); + => BindExecutor((_, sessionId) => factoryAsync(id, sessionId), id, options: null); /// /// Configures a factory method for creating an of type , with diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalRequest.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalRequest.cs index 2dbba50bf1..e1c1765349 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalRequest.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalRequest.cs @@ -15,26 +15,28 @@ namespace Microsoft.Agents.AI.Workflows; /// The data contained in the request. public record ExternalRequest(RequestPortInfo PortInfo, string RequestId, PortableValue Data) { - /// - /// Attempts to retrieve the underlying data as the specified type. - /// - /// The type to which the data should be cast or converted. - /// The data cast to the specified type, or null if the data cannot be cast to the specified type. - public TValue? DataAs() => this.Data.As(); - /// /// Determines whether the underlying data is of the specified type. /// /// The type to compare with the underlying data. /// true if the underlying data is of type TValue; otherwise, false. - public bool DataIs() => this.Data.Is(); + public bool IsDataOfType() => this.Data.Is(); /// /// Determines whether the underlying data is of the specified type and outputs the value if it is. /// /// The type to compare with the underlying data. /// true if the underlying data is of type TValue; otherwise, false. - public bool DataIs([NotNullWhen(true)] out TValue? value) => this.Data.Is(out value); + public bool TryGetDataAs([NotNullWhen(true)] out TValue? value) => this.Data.Is(out value); + + /// + /// Attempts to retrieve the underlying data as the specified type. + /// + /// The type to which the data should be cast or converted. + /// When this method returns , contains the value of type + /// if the data is available and compatible. + /// true if the data is present and can be cast to ; otherwise, false. + public bool TryGetDataAs(Type targetType, [NotNullWhen(true)] out object? value) => this.Data.IsType(targetType, out value); /// /// Creates a new for the specified input port and data payload. diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalResponse.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalResponse.cs index a26650cedc..b1aa88f902 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalResponse.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/ExternalResponse.cs @@ -14,19 +14,12 @@ namespace Microsoft.Agents.AI.Workflows; /// The data contained in the response. public record ExternalResponse(RequestPortInfo PortInfo, string RequestId, PortableValue Data) { - /// - /// Attempts to retrieve the underlying data as the specified type. - /// - /// The type to which the data should be cast or converted. - /// The data cast to the specified type, or null if the data cannot be cast to the specified type. - public TValue? DataAs() => this.Data.As(); - /// /// Determines whether the underlying data is of the specified type. /// /// The type to compare with the underlying data. /// true if the underlying data is of type TValue; otherwise, false. - public bool DataIs() => this.Data.Is(); + public bool IsDataOfType() => this.Data.Is(); /// /// Determines whether the underlying data can be retrieved as the specified type. @@ -35,14 +28,7 @@ public record ExternalResponse(RequestPortInfo PortInfo, string RequestId, Porta /// When this method returns, contains the value of type if the data is /// available and compatible. /// true if the data is present and can be cast to ; otherwise, false. - public bool DataIs([NotNullWhen(true)] out TValue? value) => this.Data.Is(out value); - - /// - /// Attempts to retrieve the underlying data as the specified type. - /// - /// The type to which the data should be cast or converted. - /// The data cast to the specified type, or null if the data cannot be cast to the specified type. - public object? DataAs(Type targetType) => this.Data.AsType(targetType); + public bool TryGetDataAs([NotNullWhen(true)] out TValue? value) => this.Data.Is(out value); /// /// Attempts to retrieve the underlying data as the specified type. @@ -51,5 +37,5 @@ public record ExternalResponse(RequestPortInfo PortInfo, string RequestId, Porta /// When this method returns , contains the value of type /// if the data is available and compatible. /// true if the data is present and can be cast to ; otherwise, false. - public bool DataIs(Type targetType, [NotNullWhen(true)] out object? value) => this.Data.IsType(targetType, out value); + public bool TryGetDataAs(Type targetType, [NotNullWhen(true)] out object? value) => this.Data.IsType(targetType, out value); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/GroupChatWorkflowBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/GroupChatWorkflowBuilder.cs index 9a09f22617..79a7b35498 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/GroupChatWorkflowBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/GroupChatWorkflowBuilder.cs @@ -60,7 +60,7 @@ public Workflow Build() Dictionary agentMap = agents.ToDictionary(a => a, a => a.BindAsExecutor(options)); Func> groupChatHostFactory = - (id, runId) => new(new GroupChatHost(id, agents, agentMap, this._managerFactory)); + (id, sessionId) => new(new GroupChatHost(id, agents, agentMap, this._managerFactory)); ExecutorBinding host = groupChatHostFactory.BindExecutor(nameof(GroupChatHost)); WorkflowBuilder builder = new(host); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/IWorkflowExecutionEnvironment.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/IWorkflowExecutionEnvironment.cs index ff9fd0ad86..3e8d5cd892 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/IWorkflowExecutionEnvironment.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/IWorkflowExecutionEnvironment.cs @@ -21,11 +21,11 @@ public interface IWorkflowExecutionEnvironment /// will not be invoked until an input message is received. /// /// The workflow to execute. Cannot be null. - /// An optional identifier for the run. If null, a new run identifier will be generated. + /// An optional identifier for the session. If null, a new identifier will be generated. /// A cancellation token that can be used to cancel the streaming operation. /// A ValueTask that represents the asynchronous operation. The result contains a StreamingRun object for accessing /// the streamed workflow output. - ValueTask OpenStreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default); + ValueTask OpenStreamingAsync(Workflow workflow, string? sessionId = null, CancellationToken cancellationToken = default); /// /// Initiates an asynchronous streaming execution using the specified input. @@ -36,11 +36,11 @@ public interface IWorkflowExecutionEnvironment /// A type of input accepted by the workflow. Must be non-nullable. /// The workflow to be executed. Must not be null. /// The input message to be processed as part of the streaming run. - /// An optional unique identifier for the run. If not provided, a new identifier will be generated. + /// An optional unique identifier for the session. If not provided, a new identifier will be generated. /// The to monitor for cancellation requests. The default is . /// A that represents the asynchronous operation. The result contains a for managing and interacting with the streaming run. - ValueTask StreamAsync(Workflow workflow, TInput input, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull; + ValueTask RunStreamingAsync(Workflow workflow, TInput input, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull; /// /// Resumes an asynchronous streaming execution for the specified input from a checkpoint. @@ -51,7 +51,7 @@ public interface IWorkflowExecutionEnvironment /// The corresponding to the checkpoint from which to resume. /// The to monitor for cancellation requests. The default is . /// A that provides access to the results of the streaming run. - ValueTask ResumeStreamAsync(Workflow workflow, CheckpointInfo fromCheckpoint, CancellationToken cancellationToken = default); + ValueTask ResumeStreamingAsync(Workflow workflow, CheckpointInfo fromCheckpoint, CancellationToken cancellationToken = default); /// /// Initiates a non-streaming execution of the workflow with the specified input. @@ -61,11 +61,11 @@ public interface IWorkflowExecutionEnvironment /// The type of input accepted by the workflow. Must be non-nullable. /// The workflow to be executed. Must not be null. /// The input message to be processed as part of the run. - /// An optional unique identifier for the run. If not provided, a new identifier will be generated. + /// An optional unique identifier for the session. If not provided, a new identifier will be generated. /// The to monitor for cancellation requests. The default is . /// A that represents the asynchronous operation. The result contains a for managing and interacting with the streaming run. - ValueTask RunAsync(Workflow workflow, TInput input, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull; + ValueTask RunAsync(Workflow workflow, TInput input, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull; /// /// Resumes a non-streaming execution of the workflow from a checkpoint. diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessExecutionEnvironment.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessExecutionEnvironment.cs index 04198e7a23..1eccb391fd 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessExecutionEnvironment.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessExecutionEnvironment.cs @@ -44,38 +44,38 @@ public InProcessExecutionEnvironment WithCheckpointing(CheckpointManager? checkp /// public bool IsCheckpointingEnabled => this.CheckpointManager != null; - internal ValueTask BeginRunAsync(Workflow workflow, string? runId, IEnumerable knownValidInputTypes, CancellationToken cancellationToken) + internal ValueTask BeginRunAsync(Workflow workflow, string? sessionId, IEnumerable knownValidInputTypes, CancellationToken cancellationToken) { - InProcessRunner runner = InProcessRunner.CreateTopLevelRunner(workflow, this.CheckpointManager, runId, this.EnableConcurrentRuns, knownValidInputTypes); + InProcessRunner runner = InProcessRunner.CreateTopLevelRunner(workflow, this.CheckpointManager, sessionId, this.EnableConcurrentRuns, knownValidInputTypes); return runner.BeginStreamAsync(this.ExecutionMode, cancellationToken); } internal ValueTask ResumeRunAsync(Workflow workflow, CheckpointInfo fromCheckpoint, IEnumerable knownValidInputTypes, CancellationToken cancellationToken) { - InProcessRunner runner = InProcessRunner.CreateTopLevelRunner(workflow, this.CheckpointManager, fromCheckpoint.RunId, this.EnableConcurrentRuns, knownValidInputTypes); + InProcessRunner runner = InProcessRunner.CreateTopLevelRunner(workflow, this.CheckpointManager, fromCheckpoint.SessionId, this.EnableConcurrentRuns, knownValidInputTypes); return runner.ResumeStreamAsync(this.ExecutionMode, fromCheckpoint, cancellationToken); } /// - public async ValueTask OpenStreamAsync( + public async ValueTask OpenStreamingAsync( Workflow workflow, - string? runId = null, + string? sessionId = null, CancellationToken cancellationToken = default) { - AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, runId, [], cancellationToken) + AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, sessionId, [], cancellationToken) .ConfigureAwait(false); return new(runHandle); } /// - public async ValueTask StreamAsync( + public async ValueTask RunStreamingAsync( Workflow workflow, TInput input, - string? runId = null, + string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull { - AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, runId, [], cancellationToken) + AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, sessionId, [], cancellationToken) .ConfigureAwait(false); return await runHandle.EnqueueAndStreamAsync(input, cancellationToken).ConfigureAwait(false); @@ -91,7 +91,7 @@ private void VerifyCheckpointingConfigured() } /// - public async ValueTask ResumeStreamAsync( + public async ValueTask ResumeStreamingAsync( Workflow workflow, CheckpointInfo fromCheckpoint, CancellationToken cancellationToken = default) @@ -106,11 +106,11 @@ public async ValueTask ResumeStreamAsync( private async ValueTask BeginRunHandlingChatProtocolAsync(Workflow workflow, TInput input, - string? runId = null, + string? sessionId = null, CancellationToken cancellationToken = default) { ProtocolDescriptor descriptor = await workflow.DescribeProtocolAsync(cancellationToken).ConfigureAwait(false); - AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, runId, descriptor.Accepts, cancellationToken) + AsyncRunHandle runHandle = await this.BeginRunAsync(workflow, sessionId, descriptor.Accepts, cancellationToken) .ConfigureAwait(false); await runHandle.EnqueueMessageAsync(input, cancellationToken).ConfigureAwait(false); @@ -127,13 +127,13 @@ private async ValueTask BeginRunHandlingChatProtocolAsync RunAsync( Workflow workflow, TInput input, - string? runId = null, + string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull { AsyncRunHandle runHandle = await this.BeginRunHandlingChatProtocolAsync( workflow, input, - runId, + sessionId, cancellationToken) .ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunner.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunner.cs index beae7060f4..2a61f80ced 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunner.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunner.cs @@ -22,27 +22,27 @@ namespace Microsoft.Agents.AI.Workflows.InProc; /// scenarios where workflow execution does not require executor distribution. internal sealed class InProcessRunner : ISuperStepRunner, ICheckpointingHandle { - public static InProcessRunner CreateTopLevelRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? runId = null, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) + public static InProcessRunner CreateTopLevelRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? sessionId = null, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) { return new InProcessRunner(workflow, checkpointManager, - runId, + sessionId, enableConcurrentRuns: enableConcurrentRuns, knownValidInputTypes: knownValidInputTypes); } - public static InProcessRunner CreateSubworkflowRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? runId = null, object? existingOwnerSignoff = null, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) + public static InProcessRunner CreateSubworkflowRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? sessionId = null, object? existingOwnerSignoff = null, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) { return new InProcessRunner(workflow, checkpointManager, - runId, + sessionId, existingOwnerSignoff: existingOwnerSignoff, enableConcurrentRuns: enableConcurrentRuns, knownValidInputTypes: knownValidInputTypes, subworkflow: true); } - private InProcessRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? runId = null, object? existingOwnerSignoff = null, bool subworkflow = false, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) + private InProcessRunner(Workflow workflow, ICheckpointManager? checkpointManager, string? sessionId = null, object? existingOwnerSignoff = null, bool subworkflow = false, bool enableConcurrentRuns = false, IEnumerable? knownValidInputTypes = null) { if (enableConcurrentRuns && !workflow.AllowConcurrent) { @@ -50,11 +50,11 @@ private InProcessRunner(Workflow workflow, ICheckpointManager? checkpointManager $"not supporting concurrent: {string.Join(", ", workflow.NonConcurrentExecutorIds)}"); } - this.RunId = runId ?? Guid.NewGuid().ToString("N"); + this.SessionId = sessionId ?? Guid.NewGuid().ToString("N"); this.StartExecutorId = workflow.StartExecutorId; this.Workflow = Throw.IfNull(workflow); - this.RunContext = new InProcessRunnerContext(workflow, this.RunId, checkpointingEnabled: checkpointManager != null, this.OutgoingEvents, this.StepTracer, existingOwnerSignoff, subworkflow, enableConcurrentRuns); + this.RunContext = new InProcessRunnerContext(workflow, this.SessionId, checkpointingEnabled: checkpointManager != null, this.OutgoingEvents, this.StepTracer, existingOwnerSignoff, subworkflow, enableConcurrentRuns); this.CheckpointManager = checkpointManager; this._knownValidInputTypes = knownValidInputTypes != null @@ -65,8 +65,8 @@ private InProcessRunner(Workflow workflow, ICheckpointManager? checkpointManager this.EdgeMap = new EdgeMap(this.RunContext, this.Workflow.Edges, this.Workflow.Ports.Values, this.Workflow.StartExecutorId, this.StepTracer); } - /// - public string RunId { get; } + /// + public string SessionId { get; } /// public string StartExecutorId { get; } @@ -303,7 +303,7 @@ internal async ValueTask CheckpointAsync(CancellationToken cancellationToken = d Dictionary stateData = await this.RunContext.StateManager.ExportStateAsync().ConfigureAwait(false); Checkpoint checkpoint = new(this.StepTracer.StepNumber, this._workflowInfoCache, runnerData, stateData, edgeData, this._lastCheckpointInfo); - this._lastCheckpointInfo = await this.CheckpointManager.CommitCheckpointAsync(this.RunId, checkpoint).ConfigureAwait(false); + this._lastCheckpointInfo = await this.CheckpointManager.CommitCheckpointAsync(this.SessionId, checkpoint).ConfigureAwait(false); this.StepTracer.TraceCheckpointCreated(this._lastCheckpointInfo); this._checkpoints.Add(this._lastCheckpointInfo); } @@ -317,7 +317,7 @@ public async ValueTask RestoreCheckpointAsync(CheckpointInfo checkpointInfo, Can throw new InvalidOperationException("This run was not configured with a CheckpointManager, so it cannot restore checkpoints."); } - Checkpoint checkpoint = await this.CheckpointManager.LookupCheckpointAsync(this.RunId, checkpointInfo) + Checkpoint checkpoint = await this.CheckpointManager.LookupCheckpointAsync(this.SessionId, checkpointInfo) .ConfigureAwait(false); // Validate the checkpoint is compatible with this workflow @@ -346,7 +346,7 @@ await Task.WhenAll(executorNotifyTask, async ValueTask UpdateCheckpointIndexAsync() { this._checkpoints.Clear(); - this._checkpoints.AddRange(await this.CheckpointManager!.RetrieveIndexAsync(this.RunId).ConfigureAwait(false)); + this._checkpoints.AddRange(await this.CheckpointManager!.RetrieveIndexAsync(this.SessionId).ConfigureAwait(false)); } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunnerContext.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunnerContext.cs index ccddef5ab8..eda7b90a80 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunnerContext.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunnerContext.cs @@ -22,7 +22,7 @@ namespace Microsoft.Agents.AI.Workflows.InProc; internal sealed class InProcessRunnerContext : IRunnerContext { private int _runEnded; - private readonly string _runId; + private readonly string _sessionId; private readonly Workflow _workflow; private readonly object? _previousOwnership; private bool _ownsWorkflow; @@ -40,7 +40,7 @@ internal sealed class InProcessRunnerContext : IRunnerContext public InProcessRunnerContext( Workflow workflow, - string runId, + string sessionId, bool checkpointingEnabled, IEventSink outgoingEvents, IStepTracer? stepTracer, @@ -61,7 +61,7 @@ public InProcessRunnerContext( } this._workflow = workflow; - this._runId = runId; + this._sessionId = sessionId; this._edgeMap = new(this, this._workflow, stepTracer); this._outputFilter = new(workflow); @@ -94,7 +94,7 @@ async Task CreateExecutorAsync(string id) throw new InvalidOperationException($"Executor with ID '{executorId}' is not registered."); } - Executor executor = await registration.CreateInstanceAsync(this._runId).ConfigureAwait(false); + Executor executor = await registration.CreateInstanceAsync(this._sessionId).ConfigureAwait(false); executor.AttachRequestContext(this.BindExternalRequestContext(executorId)); await executor.InitializeAsync(this.BindWorkflowContext(executorId), cancellationToken: cancellationToken) @@ -438,7 +438,7 @@ internal void CheckEnded() { if (Volatile.Read(ref this._runEnded) == 1) { - throw new InvalidOperationException($"Workflow run '{this._runId}' has been ended. Please start a new Run or StreamingRun."); + throw new InvalidOperationException($"Workflow run for session '{this._sessionId}' has been ended. Please start a new Run or StreamingRun."); } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/InProcessExecution.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/InProcessExecution.cs index b57e8597f7..ee71872252 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/InProcessExecution.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/InProcessExecution.cs @@ -41,33 +41,33 @@ public static class InProcessExecution /// internal static InProcessExecutionEnvironment Subworkflow { get; } = new(ExecutionMode.Subworkflow); - /// - public static ValueTask OpenStreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default) - => Default.OpenStreamAsync(workflow, runId, cancellationToken); + /// + public static ValueTask OpenStreamingAsync(Workflow workflow, string? sessionId = null, CancellationToken cancellationToken = default) + => Default.OpenStreamingAsync(workflow, sessionId, cancellationToken); - /// - public static ValueTask StreamAsync(Workflow workflow, TInput input, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull - => Default.StreamAsync(workflow, input, runId, cancellationToken); + /// + public static ValueTask RunStreamingAsync(Workflow workflow, TInput input, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull + => Default.RunStreamingAsync(workflow, input, sessionId, cancellationToken); - /// - public static ValueTask OpenStreamAsync(Workflow workflow, CheckpointManager checkpointManager, string? runId = null, CancellationToken cancellationToken = default) - => Default.WithCheckpointing(checkpointManager).OpenStreamAsync(workflow, runId, cancellationToken); + /// + public static ValueTask OpenStreamingAsync(Workflow workflow, CheckpointManager checkpointManager, string? sessionId = null, CancellationToken cancellationToken = default) + => Default.WithCheckpointing(checkpointManager).OpenStreamingAsync(workflow, sessionId, cancellationToken); - /// - public static ValueTask StreamAsync(Workflow workflow, TInput input, CheckpointManager checkpointManager, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull - => Default.WithCheckpointing(checkpointManager).StreamAsync(workflow, input, runId, cancellationToken); + /// + public static ValueTask RunStreamingAsync(Workflow workflow, TInput input, CheckpointManager checkpointManager, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull + => Default.WithCheckpointing(checkpointManager).RunStreamingAsync(workflow, input, sessionId, cancellationToken); - /// - public static ValueTask ResumeStreamAsync(Workflow workflow, CheckpointInfo fromCheckpoint, CheckpointManager checkpointManager, CancellationToken cancellationToken = default) - => Default.WithCheckpointing(checkpointManager).ResumeStreamAsync(workflow, fromCheckpoint, cancellationToken); + /// + public static ValueTask ResumeStreamingAsync(Workflow workflow, CheckpointInfo fromCheckpoint, CheckpointManager checkpointManager, CancellationToken cancellationToken = default) + => Default.WithCheckpointing(checkpointManager).ResumeStreamingAsync(workflow, fromCheckpoint, cancellationToken); /// - public static ValueTask RunAsync(Workflow workflow, TInput input, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull - => Default.RunAsync(workflow, input, runId, cancellationToken); + public static ValueTask RunAsync(Workflow workflow, TInput input, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull + => Default.RunAsync(workflow, input, sessionId, cancellationToken); /// - public static ValueTask RunAsync(Workflow workflow, TInput input, CheckpointManager checkpointManager, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull - => Default.WithCheckpointing(checkpointManager).RunAsync(workflow, input, runId, cancellationToken); + public static ValueTask RunAsync(Workflow workflow, TInput input, CheckpointManager checkpointManager, string? sessionId = null, CancellationToken cancellationToken = default) where TInput : notnull + => Default.WithCheckpointing(checkpointManager).RunAsync(workflow, input, sessionId, cancellationToken); /// public static ValueTask ResumeAsync(Workflow workflow, CheckpointInfo fromCheckpoint, CheckpointManager checkpointManager, CancellationToken cancellationToken = default) diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Observability/Tags.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Observability/Tags.cs index 4b40e46f8c..88c68eceb9 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Observability/Tags.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Observability/Tags.cs @@ -11,7 +11,7 @@ internal static class Tags public const string BuildErrorMessage = "build.error.message"; public const string BuildErrorType = "build.error.type"; public const string ErrorType = "error.type"; - public const string RunId = "run.id"; + public const string SessionId = "session.id"; public const string ExecutorId = "executor.id"; public const string ExecutorType = "executor.type"; public const string ExecutorInput = "executor.input"; diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/PortableValue.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/PortableValue.cs index 5110294171..57e541ef4c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/PortableValue.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/PortableValue.cs @@ -96,7 +96,8 @@ public override int GetHashCode() /// /// If the underlying value implements delayed deserialization, this method will attempt to /// deserialize it to the specified type. If the value is already of the requested type, it is returned directly. - /// Otherwise, the default value for TValue is returned. + /// Otherwise, the default value for TValue is returned. For value types, the default is not , + /// UNLESS is nullable, e.g. int?. /// /// The type to which the value should be cast or deserialized. /// The value cast or deserialized to type TValue if possible; otherwise, the default value for type TValue. diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/RouteBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/RouteBuilder.cs index 2b71169268..fea7138332 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/RouteBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/RouteBuilder.cs @@ -158,7 +158,7 @@ internal RouteBuilder AddPortHandler(string id, Func InvokeHandlerAsync(ExternalResponse response, IWorkflowContext context, CancellationToken cancellationToken) { - if (!response.DataIs(out TResponse? typedResponse)) + if (!response.TryGetDataAs(out TResponse? typedResponse)) { throw new InvalidOperationException($"Received response data is not of expected type {typeof(TResponse).FullName} for port {port.Id}."); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Run.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Run.cs index 46eeaed950..3ee6184610 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Run.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Run.cs @@ -36,9 +36,9 @@ internal async ValueTask RunToNextHaltAsync(CancellationToken cancellation } /// - /// A unique identifier for the run. Can be provided at the start of the run, or auto-generated. + /// A unique identifier for the session. Can be provided at the start of the session, or auto-generated. /// - public string RunId => this._runHandle.RunId; + public string SessionId => this._runHandle.SessionId; /// /// Gets the current execution status of the workflow run. diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/WorkflowHostExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/WorkflowHostExecutor.cs index 120fed8bab..107dc3fd7a 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/WorkflowHostExecutor.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/WorkflowHostExecutor.cs @@ -15,7 +15,7 @@ namespace Microsoft.Agents.AI.Workflows.Specialized; internal class WorkflowHostExecutor : Executor, IAsyncDisposable { - private readonly string _runId; + private readonly string _sessionId; private readonly Workflow _workflow; private readonly ProtocolDescriptor _workflowProtocol; private readonly object _ownershipToken; @@ -31,12 +31,11 @@ internal class WorkflowHostExecutor : Executor, IAsyncDisposable [MemberNotNullWhen(true, nameof(_checkpointManager))] private bool WithCheckpointing => this._checkpointManager != null; - public WorkflowHostExecutor(string id, Workflow workflow, ProtocolDescriptor workflowProtocol, string runId, object ownershipToken, ExecutorOptions? options = null) : base(id, options) + public WorkflowHostExecutor(string id, Workflow workflow, ProtocolDescriptor workflowProtocol, string sessionId, object ownershipToken, ExecutorOptions? options = null) : base(id, options) { this._options = options ?? new(); - //Throw.IfNull(workflow); - this._runId = Throw.IfNull(runId); + this._sessionId = Throw.IfNull(sessionId); this._ownershipToken = Throw.IfNull(ownershipToken); this._workflow = Throw.IfNull(workflow); this._workflowProtocol = Throw.IfNull(workflowProtocol); @@ -92,7 +91,7 @@ internal async ValueTask EnsureRunnerAsync() this._activeRunner = InProcessRunner.CreateSubworkflowRunner(this._workflow, this._checkpointManager, - this._runId, + this._sessionId, this._ownershipToken, this.JoinContext.ConcurrentRunsEnabled); } @@ -122,7 +121,7 @@ internal async ValueTask EnsureRunSendMessageAsync(object? incomin if (resume) { // Attempting to resume from checkpoint - if (!this._checkpointManager.TryGetLastCheckpoint(this._runId, out CheckpointInfo? lastCheckpoint)) + if (!this._checkpointManager.TryGetLastCheckpoint(this._sessionId, out CheckpointInfo? lastCheckpoint)) { throw new InvalidOperationException("No checkpoints available to resume from."); } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/StreamingRun.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/StreamingRun.cs index 9adbed7358..b479cae75e 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/StreamingRun.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/StreamingRun.cs @@ -24,9 +24,9 @@ internal StreamingRun(AsyncRunHandle runHandle) : base(runHandle) } /// - /// A unique identifier for the run. Can be provided at the start of the run, or auto-generated. + /// A unique identifier for the session. Can be provided at the start of the session, or auto-generated. /// - public string RunId => this._runHandle.RunId; + public string SessionId => this._runHandle.SessionId; /// /// Gets the current execution status of the workflow run. diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/SubworkflowBinding.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/SubworkflowBinding.cs index 8d67e62e4a..11f7cf493c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/SubworkflowBinding.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/SubworkflowBinding.cs @@ -27,11 +27,11 @@ private static Func> CreateWorkflowExecutorFactory(W return InitHostExecutorAsync; - async ValueTask InitHostExecutorAsync(string runId) + async ValueTask InitHostExecutorAsync(string sessionId) { ProtocolDescriptor workflowProtocol = await workflow.DescribeProtocolAsync().ConfigureAwait(false); - return new WorkflowHostExecutor(id, workflow, workflowProtocol, runId, ownershipToken, options); + return new WorkflowHostExecutor(id, workflow, workflowProtocol, sessionId, ownershipToken, options); } } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs index b8cd6b6e78..14e6ed4f7c 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs @@ -84,9 +84,9 @@ internal WorkflowBuilder ReduceToFanOut(WorkflowBuilder builder, ExecutorBinding List<(Func Predicate, HashSet OutgoingIndicies)> caseMap = this._caseMap; HashSet defaultIndicies = this._defaultIndicies; - return builder.AddFanOutEdge(source, this._executors, CasePartitioner); + return builder.AddFanOutEdge(source, this._executors, EdgeSelector); - IEnumerable CasePartitioner(object? input, int targetCount) + IEnumerable EdgeSelector(object? input, int targetCount) { Debug.Assert(targetCount == this._executors.Count); diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilder.cs index 36a3468e2d..e29abca5ab 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilder.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowBuilder.cs @@ -422,30 +422,26 @@ public WorkflowBuilder AddFanOutEdge(ExecutorBinding source, IEnumerable - /// Adds a fan-in edge to the workflow, connecting multiple source executors to a single target executor with an - /// optional trigger condition. + /// Adds a fan-in "barrier" edge to the workflow, connecting multiple source executors to a single target executor. Messages + /// will be held until every source executor has generated at least one message, then they will be streamed to the target + /// executor in the following step. /// - /// This method establishes a fan-in relationship, allowing the target executor to be activated - /// based on the completion or state of multiple sources. The trigger parameter can be used to customize activation - /// behavior. /// One or more source executors that provide input to the target. Cannot be null or empty. /// The target executor that receives input from the specified source executors. Cannot be null. /// The current instance of . - public WorkflowBuilder AddFanInEdge(IEnumerable sources, ExecutorBinding target) - => this.AddFanInEdge(sources, target, label: null); + public WorkflowBuilder AddFanInBarrierEdge(IEnumerable sources, ExecutorBinding target) + => this.AddFanInBarrierEdge(sources, target, label: null); /// - /// Adds a fan-in edge to the workflow, connecting multiple source executors to a single target executor with an - /// optional trigger condition. + /// Adds a fan-in "barrier" edge to the workflow, connecting multiple source executors to a single target executor. Messages + /// will be held until every source executor has generated at least one message, then they will be streamed to the target + /// executor in the following step. /// - /// This method establishes a fan-in relationship, allowing the target executor to be activated - /// based on the completion or state of multiple sources. The trigger parameter can be used to customize activation - /// behavior. /// One or more source executors that provide input to the target. Cannot be null or empty. /// The target executor that receives input from the specified source executors. Cannot be null. /// An optional label for the edge. Will be used in visualizations. /// The current instance of . - public WorkflowBuilder AddFanInEdge(IEnumerable sources, ExecutorBinding target, string? label = null) + public WorkflowBuilder AddFanInBarrierEdge(IEnumerable sources, ExecutorBinding target, string? label = null) { Throw.IfNull(target); Throw.IfNull(sources); @@ -472,10 +468,10 @@ public WorkflowBuilder AddFanInEdge(IEnumerable sources, Execut return this; } - /// - [Obsolete("Use AddFanInEdge(IEnumerable, ExecutorBinding) instead.")] - public WorkflowBuilder AddFanInEdge(ExecutorBinding target, params IEnumerable sources) - => this.AddFanInEdge(sources, target); + /// + [Obsolete("Use AddFanInBarrierEdge(IEnumerable, ExecutorBinding) instead.")] + public WorkflowBuilder AddFanInBarrierEdge(ExecutorBinding target, params IEnumerable sources) + => this.AddFanInBarrierEdge(sources, target); private void Validate(bool validateOrphans) { diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostAgent.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostAgent.cs index f77fe2b231..7679123970 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostAgent.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostAgent.cs @@ -22,7 +22,7 @@ internal sealed class WorkflowHostAgent : AIAgent private readonly bool _includeWorkflowOutputsInResponse; private readonly Task _describeTask; - private readonly ConcurrentDictionary _assignedRunIds = []; + private readonly ConcurrentDictionary _assignedSessionIds = []; public WorkflowHostAgent(Workflow workflow, string? id = null, string? name = null, string? description = null, IWorkflowExecutionEnvironment? executionEnvironment = null, bool includeExceptionDetails = false, bool includeWorkflowOutputsInResponse = false) { @@ -62,7 +62,7 @@ private string GenerateNewId() do { result = Guid.NewGuid().ToString("N"); - } while (!this._assignedRunIds.TryAdd(result, result)); + } while (!this._assignedSessionIds.TryAdd(result, result)); return result; } diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostingExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostingExtensions.cs index 4587ed6037..281d0694ac 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostingExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowHostingExtensions.cs @@ -25,7 +25,7 @@ public static class WorkflowHostingExtensions /// If , will transform outgoing workflow outputs /// into into content in s or the as appropriate. /// - public static AIAgent AsAgent( + public static AIAgent AsAIAgent( this Workflow workflow, string? id = null, string? name = null, diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowSession.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowSession.cs index 041561fd13..40a18dbadb 100644 --- a/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowSession.cs +++ b/dotnet/src/Microsoft.Agents.AI.Workflows/WorkflowSession.cs @@ -41,7 +41,7 @@ internal static bool VerifyCheckpointingConfiguration(IWorkflowExecutionEnvironm return true; } - public WorkflowSession(Workflow workflow, string runId, IWorkflowExecutionEnvironment executionEnvironment, bool includeExceptionDetails = false, bool includeWorkflowOutputsInResponse = false) + public WorkflowSession(Workflow workflow, string sessionId, IWorkflowExecutionEnvironment executionEnvironment, bool includeExceptionDetails = false, bool includeWorkflowOutputsInResponse = false) { this._workflow = Throw.IfNull(workflow); this._executionEnvironment = Throw.IfNull(executionEnvironment); @@ -55,7 +55,7 @@ public WorkflowSession(Workflow workflow, string runId, IWorkflowExecutionEnviro this._executionEnvironment = inProcEnv.WithCheckpointing(this.EnsureExternalizedInMemoryCheckpointing()); } - this.RunId = Throw.IfNullOrEmpty(runId); + this.SessionId = Throw.IfNullOrEmpty(sessionId); this.ChatHistoryProvider = new WorkflowChatHistoryProvider(); } @@ -85,7 +85,7 @@ public WorkflowSession(Workflow workflow, JsonElement serializedSession, IWorkfl throw new ArgumentException("The session was saved with an externalized checkpoint manager, but the incoming execution environment does not support it.", nameof(executionEnvironment)); } - this.RunId = sessionState.RunId; + this.SessionId = sessionState.SessionId; this.ChatHistoryProvider = new WorkflowChatHistoryProvider(); this.LastCheckpoint = sessionState.LastCheckpoint; @@ -98,7 +98,7 @@ internal JsonElement Serialize(JsonSerializerOptions? jsonSerializerOptions = nu { JsonMarshaller marshaller = new(jsonSerializerOptions); SessionState info = new( - this.RunId, + this.SessionId, this.LastCheckpoint, this._inMemoryCheckpointManager, this.StateBag); @@ -149,7 +149,7 @@ private async ValueTask CreateOrResumeRunAsync(List m { StreamingRun run = await this._executionEnvironment - .ResumeStreamAsync(this._workflow, + .ResumeStreamingAsync(this._workflow, this.LastCheckpoint, cancellationToken) .ConfigureAwait(false); @@ -159,9 +159,9 @@ await this._executionEnvironment } return await this._executionEnvironment - .StreamAsync(this._workflow, + .RunStreamingAsync(this._workflow, messages, - this.RunId, + this.SessionId, cancellationToken) .ConfigureAwait(false); } @@ -262,18 +262,18 @@ IAsyncEnumerable InvokeStageAsync( public string? LastResponseId { get; set; } - public string RunId { get; } + public string SessionId { get; } /// public WorkflowChatHistoryProvider ChatHistoryProvider { get; } internal sealed class SessionState( - string runId, + string sessionId, CheckpointInfo? lastCheckpoint, InMemoryCheckpointManager? checkpointManager = null, AgentSessionStateBag? stateBag = null) { - public string RunId { get; } = runId; + public string SessionId { get; } = sessionId; public CheckpointInfo? LastCheckpoint { get; } = lastCheckpoint; public InMemoryCheckpointManager? CheckpointManager { get; } = checkpointManager; public AgentSessionStateBag StateBag { get; } = stateBag ?? new(); diff --git a/dotnet/src/Shared/Workflows/Execution/WorkflowRunner.cs b/dotnet/src/Shared/Workflows/Execution/WorkflowRunner.cs index 55d9c7d6cc..0f4f0c9217 100644 --- a/dotnet/src/Shared/Workflows/Execution/WorkflowRunner.cs +++ b/dotnet/src/Shared/Workflows/Execution/WorkflowRunner.cs @@ -68,7 +68,7 @@ public async Task ExecuteAsync(Func workflowProvider, string input) checkpointManager = CheckpointManager.CreateInMemory(); } - StreamingRun run = await InProcessExecution.StreamAsync(workflow, input, checkpointManager).ConfigureAwait(false); + StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input, checkpointManager).ConfigureAwait(false); bool isComplete = false; ExternalResponse? requestResponse = null; @@ -95,7 +95,7 @@ public async Task ExecuteAsync(Func workflowProvider, string input) Debug.WriteLine($"RESTORE #{this.LastCheckpoint.CheckpointId}"); Notify("WORKFLOW: Restore", ConsoleColor.DarkYellow); - run = await InProcessExecution.ResumeStreamAsync(workflow, this.LastCheckpoint, checkpointManager).ConfigureAwait(false); + run = await InProcessExecution.ResumeStreamingAsync(workflow, this.LastCheckpoint, checkpointManager).ConfigureAwait(false); } else { @@ -272,9 +272,10 @@ public async Task ExecuteAsync(Func workflowProvider, string input) /// private async ValueTask HandleExternalRequestAsync(ExternalRequest request) { - ExternalInputRequest inputRequest = - request.DataAs() ?? - throw new InvalidOperationException($"Expected external request type: {request.GetType().Name}."); + if (!request.TryGetDataAs(out var inputRequest)) + { + throw new InvalidOperationException($"Expected external request type: {request.PortInfo.RequestType}."); + } List responseMessages = []; diff --git a/dotnet/tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/CosmosCheckpointStoreTests.cs b/dotnet/tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/CosmosCheckpointStoreTests.cs index dc75b34758..f1f840cebf 100644 --- a/dotnet/tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/CosmosCheckpointStoreTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/CosmosCheckpointStoreTests.cs @@ -74,7 +74,7 @@ public async Task InitializeAsync() this._database = await this._cosmosClient.CreateDatabaseIfNotExistsAsync(s_testDatabaseId); await this._database.CreateContainerIfNotExistsAsync( TestContainerId, - "/runId", + "/sessionId", throughput: 400); this._emulatorAvailable = true; @@ -184,15 +184,15 @@ public async Task CreateCheckpointAsync_NewCheckpoint_CreatesSuccessfullyAsync() // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); var checkpointValue = JsonSerializer.SerializeToElement(new { data = "test checkpoint" }, s_jsonOptions); // Act - var checkpointInfo = await store.CreateCheckpointAsync(runId, checkpointValue); + var checkpointInfo = await store.CreateCheckpointAsync(sessionId, checkpointValue); // Assert Assert.NotNull(checkpointInfo); - Assert.Equal(runId, checkpointInfo.RunId); + Assert.Equal(sessionId, checkpointInfo.SessionId); Assert.NotNull(checkpointInfo.CheckpointId); Assert.NotEmpty(checkpointInfo.CheckpointId); } @@ -204,13 +204,13 @@ public async Task RetrieveCheckpointAsync_ExistingCheckpoint_ReturnsCorrectValue // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); var originalData = new { message = "Hello, World!", timestamp = DateTimeOffset.UtcNow }; var checkpointValue = JsonSerializer.SerializeToElement(originalData, s_jsonOptions); // Act - var checkpointInfo = await store.CreateCheckpointAsync(runId, checkpointValue); - var retrievedValue = await store.RetrieveCheckpointAsync(runId, checkpointInfo); + var checkpointInfo = await store.CreateCheckpointAsync(sessionId, checkpointValue); + var retrievedValue = await store.RetrieveCheckpointAsync(sessionId, checkpointInfo); // Assert Assert.Equal(JsonValueKind.Object, retrievedValue.ValueKind); @@ -225,12 +225,12 @@ public async Task RetrieveCheckpointAsync_NonExistentCheckpoint_ThrowsInvalidOpe // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); - var fakeCheckpointInfo = new CheckpointInfo(runId, "nonexistent-checkpoint"); + var sessionId = Guid.NewGuid().ToString(); + var fakeCheckpointInfo = new CheckpointInfo(sessionId, "nonexistent-checkpoint"); // Act & Assert await Assert.ThrowsAsync(() => - store.RetrieveCheckpointAsync(runId, fakeCheckpointInfo).AsTask()); + store.RetrieveCheckpointAsync(sessionId, fakeCheckpointInfo).AsTask()); } [SkippableFact] @@ -240,10 +240,10 @@ public async Task RetrieveIndexAsync_EmptyStore_ReturnsEmptyCollectionAsync() // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); // Act - var index = await store.RetrieveIndexAsync(runId); + var index = await store.RetrieveIndexAsync(sessionId); // Assert Assert.NotNull(index); @@ -257,16 +257,16 @@ public async Task RetrieveIndexAsync_WithCheckpoints_ReturnsAllCheckpointsAsync( // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); var checkpointValue = JsonSerializer.SerializeToElement(new { data = "test" }, s_jsonOptions); // Create multiple checkpoints - var checkpoint1 = await store.CreateCheckpointAsync(runId, checkpointValue); - var checkpoint2 = await store.CreateCheckpointAsync(runId, checkpointValue); - var checkpoint3 = await store.CreateCheckpointAsync(runId, checkpointValue); + var checkpoint1 = await store.CreateCheckpointAsync(sessionId, checkpointValue); + var checkpoint2 = await store.CreateCheckpointAsync(sessionId, checkpointValue); + var checkpoint3 = await store.CreateCheckpointAsync(sessionId, checkpointValue); // Act - var index = (await store.RetrieveIndexAsync(runId)).ToList(); + var index = (await store.RetrieveIndexAsync(sessionId)).ToList(); // Assert Assert.Equal(3, index.Count); @@ -282,17 +282,17 @@ public async Task CreateCheckpointAsync_WithParent_CreatesHierarchyAsync() // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); var checkpointValue = JsonSerializer.SerializeToElement(new { data = "test" }, s_jsonOptions); // Act - var parentCheckpoint = await store.CreateCheckpointAsync(runId, checkpointValue); - var childCheckpoint = await store.CreateCheckpointAsync(runId, checkpointValue, parentCheckpoint); + var parentCheckpoint = await store.CreateCheckpointAsync(sessionId, checkpointValue); + var childCheckpoint = await store.CreateCheckpointAsync(sessionId, checkpointValue, parentCheckpoint); // Assert Assert.NotEqual(parentCheckpoint.CheckpointId, childCheckpoint.CheckpointId); - Assert.Equal(runId, parentCheckpoint.RunId); - Assert.Equal(runId, childCheckpoint.RunId); + Assert.Equal(sessionId, parentCheckpoint.SessionId); + Assert.Equal(sessionId, childCheckpoint.SessionId); } [SkippableFact] @@ -302,20 +302,20 @@ public async Task RetrieveIndexAsync_WithParentFilter_ReturnsFilteredResultsAsyn // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); var checkpointValue = JsonSerializer.SerializeToElement(new { data = "test" }, s_jsonOptions); // Create parent and child checkpoints - var parent = await store.CreateCheckpointAsync(runId, checkpointValue); - var child1 = await store.CreateCheckpointAsync(runId, checkpointValue, parent); - var child2 = await store.CreateCheckpointAsync(runId, checkpointValue, parent); + var parent = await store.CreateCheckpointAsync(sessionId, checkpointValue); + var child1 = await store.CreateCheckpointAsync(sessionId, checkpointValue, parent); + var child2 = await store.CreateCheckpointAsync(sessionId, checkpointValue, parent); // Create an orphan checkpoint - var orphan = await store.CreateCheckpointAsync(runId, checkpointValue); + var orphan = await store.CreateCheckpointAsync(sessionId, checkpointValue); // Act - var allCheckpoints = (await store.RetrieveIndexAsync(runId)).ToList(); - var childrenOfParent = (await store.RetrieveIndexAsync(runId, parent)).ToList(); + var allCheckpoints = (await store.RetrieveIndexAsync(sessionId)).ToList(); + var childrenOfParent = (await store.RetrieveIndexAsync(sessionId, parent)).ToList(); // Assert Assert.Equal(4, allCheckpoints.Count); // parent + 2 children + orphan @@ -338,16 +338,16 @@ public async Task CheckpointOperations_DifferentRuns_IsolatesDataAsync() // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId1 = Guid.NewGuid().ToString(); - var runId2 = Guid.NewGuid().ToString(); + var sessionId1 = Guid.NewGuid().ToString(); + var sessionId2 = Guid.NewGuid().ToString(); var checkpointValue = JsonSerializer.SerializeToElement(new { data = "test" }, s_jsonOptions); // Act - var checkpoint1 = await store.CreateCheckpointAsync(runId1, checkpointValue); - var checkpoint2 = await store.CreateCheckpointAsync(runId2, checkpointValue); + var checkpoint1 = await store.CreateCheckpointAsync(sessionId1, checkpointValue); + var checkpoint2 = await store.CreateCheckpointAsync(sessionId2, checkpointValue); - var index1 = (await store.RetrieveIndexAsync(runId1)).ToList(); - var index2 = (await store.RetrieveIndexAsync(runId2)).ToList(); + var index1 = (await store.RetrieveIndexAsync(sessionId1)).ToList(); + var index2 = (await store.RetrieveIndexAsync(sessionId2)).ToList(); // Assert Assert.Single(index1); @@ -362,7 +362,7 @@ public async Task CheckpointOperations_DifferentRuns_IsolatesDataAsync() #region Error Handling Tests [SkippableFact] - public async Task CreateCheckpointAsync_WithNullRunId_ThrowsArgumentExceptionAsync() + public async Task CreateCheckpointAsync_WithNullSessionId_ThrowsArgumentExceptionAsync() { this.SkipIfEmulatorNotAvailable(); @@ -376,7 +376,7 @@ await Assert.ThrowsAsync(() => } [SkippableFact] - public async Task CreateCheckpointAsync_WithEmptyRunId_ThrowsArgumentExceptionAsync() + public async Task CreateCheckpointAsync_WithEmptySessionId_ThrowsArgumentExceptionAsync() { this.SkipIfEmulatorNotAvailable(); @@ -396,11 +396,11 @@ public async Task RetrieveCheckpointAsync_WithNullCheckpointInfo_ThrowsArgumentN // Arrange using var store = new CosmosCheckpointStore(this._cosmosClient!, s_testDatabaseId, TestContainerId); - var runId = Guid.NewGuid().ToString(); + var sessionId = Guid.NewGuid().ToString(); // Act & Assert await Assert.ThrowsAsync(() => - store.RetrieveCheckpointAsync(runId, null!).AsTask()); + store.RetrieveCheckpointAsync(sessionId, null!).AsTask()); } #endregion diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowHarness.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowHarness.cs index c803a60d98..ee2a3b4815 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowHarness.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowHarness.cs @@ -45,7 +45,7 @@ public async Task RunTestcaseAsync(Testcase testcase, TI public async Task RunWorkflowAsync(TInput input, bool useJson = false) where TInput : notnull { Console.WriteLine("RUNNING WORKFLOW..."); - StreamingRun run = await InProcessExecution.StreamAsync(workflow, input, this.GetCheckpointManager(useJson), runId); + StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input, this.GetCheckpointManager(useJson), runId); IReadOnlyList workflowEvents = await MonitorAndDisposeWorkflowRunAsync(run).ToArrayAsync(); this._lastCheckpoint = workflowEvents.OfType().LastOrDefault()?.CompletionInfo?.Checkpoint; return new WorkflowEvents(workflowEvents); @@ -55,7 +55,7 @@ public async Task ResumeAsync(ExternalResponse response) { Console.WriteLine("\nRESUMING WORKFLOW..."); Assert.NotNull(this._lastCheckpoint); - StreamingRun run = await InProcessExecution.ResumeStreamAsync(workflow, this._lastCheckpoint, this.GetCheckpointManager()); + StreamingRun run = await InProcessExecution.ResumeStreamingAsync(workflow, this._lastCheckpoint, this.GetCheckpointManager()); IReadOnlyList workflowEvents = await MonitorAndDisposeWorkflowRunAsync(run, response).ToArrayAsync(); this._lastCheckpoint = workflowEvents.OfType().LastOrDefault()?.CompletionInfo?.Checkpoint; return new WorkflowEvents(workflowEvents); 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 392988b07b..09c984ca05 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/DeclarativeWorkflowTest.cs @@ -272,7 +272,7 @@ public async Task CancelRunAsync(string workflowPath, string expectedExecutedId) // Arrange const string WorkflowInput = "Test input message"; Workflow workflow = this.CreateWorkflow(workflowPath, WorkflowInput); - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow: workflow, input: WorkflowInput); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow: workflow, input: WorkflowInput); // Act await foreach (WorkflowEvent workflowEvent in run.WatchStreamAsync()) @@ -330,7 +330,7 @@ private Task RunWorkflowAsync(string workflowPath) => private async Task RunWorkflowAsync(string workflowPath, TInput workflowInput) where TInput : notnull { Workflow workflow = this.CreateWorkflow(workflowPath, workflowInput); - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, workflowInput); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, workflowInput); await foreach (WorkflowEvent workflowEvent in run.WatchStreamAsync()) { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/WorkflowActionExecutorTest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/WorkflowActionExecutorTest.cs index 2a0949c452..6c87668bbf 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/WorkflowActionExecutorTest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/WorkflowActionExecutorTest.cs @@ -51,7 +51,7 @@ internal async Task ExecuteAsync(Executor[] executors, bool isD prevExecutor = executor; } - await using StreamingRun run = await InProcessExecution.StreamAsync(workflowBuilder.Build(), this.State); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflowBuilder.Build(), this.State); WorkflowEvent[] events = await run.WatchStreamAsync().ToArrayAsync(); if (isDiscrete) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentEventsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentEventsTests.cs index 3e1ecfe9ba..aadef98bac 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentEventsTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentEventsTests.cs @@ -25,7 +25,7 @@ public async Task WorkflowBuilder_WithAgents_EmitsWorkflowOutputEventAsync() .Build(); // Act - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new List { new(ChatRole.User, "Hello") }); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new List { new(ChatRole.User, "Hello") }); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); List outputEvents = new(); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.cs index ba969d95c7..01ce7c3441 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.cs @@ -642,7 +642,7 @@ public async Task BuildGroupChat_AgentsRunInOrderAsync(int maxIterations) StringBuilder sb = new(); InProcessExecutionEnvironment environment = executionEnvironment.ToWorkflowExecutionEnvironment(); - await using StreamingRun run = await environment.StreamAsync(workflow, input); + await using StreamingRun run = await environment.RunStreamingAsync(workflow, input); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); WorkflowOutputEvent? output = null; diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/CheckpointParentTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/CheckpointParentTests.cs index 66648a6e99..0ecf3c993f 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/CheckpointParentTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/CheckpointParentTests.cs @@ -33,7 +33,7 @@ internal async Task Checkpoint_FirstCheckpoint_ShouldHaveNullParentAsync(Executi // Act StreamingRun run = - await env.WithCheckpointing(checkpointManager).StreamAsync(workflow, "Hello"); + await env.WithCheckpointing(checkpointManager).RunStreamingAsync(workflow, "Hello"); List checkpoints = []; await foreach (WorkflowEvent evt in run.WatchStreamAsync()) @@ -49,7 +49,7 @@ internal async Task Checkpoint_FirstCheckpoint_ShouldHaveNullParentAsync(Executi CheckpointInfo firstCheckpoint = checkpoints[0]; Checkpoint storedFirst = await ((ICheckpointManager)checkpointManager) - .LookupCheckpointAsync(firstCheckpoint.RunId, firstCheckpoint); + .LookupCheckpointAsync(firstCheckpoint.SessionId, firstCheckpoint); storedFirst.Parent.Should().BeNull("the first checkpoint should have no parent"); } @@ -72,7 +72,7 @@ internal async Task Checkpoint_SubsequentCheckpoints_ShouldChainParentsAsync(Exe InProcessExecutionEnvironment env = environment.ToWorkflowExecutionEnvironment(); // Act - await using StreamingRun run = await env.WithCheckpointing(checkpointManager).StreamAsync(workflow, "Hello"); + await using StreamingRun run = await env.WithCheckpointing(checkpointManager).RunStreamingAsync(workflow, "Hello"); List checkpoints = []; using CancellationTokenSource cts = new(); @@ -94,16 +94,16 @@ internal async Task Checkpoint_SubsequentCheckpoints_ShouldChainParentsAsync(Exe // Verify the parent chain Checkpoint stored0 = await ((ICheckpointManager)checkpointManager) - .LookupCheckpointAsync(checkpoints[0].RunId, checkpoints[0]); + .LookupCheckpointAsync(checkpoints[0].SessionId, checkpoints[0]); stored0.Parent.Should().BeNull("the first checkpoint should have no parent"); Checkpoint stored1 = await ((ICheckpointManager)checkpointManager) - .LookupCheckpointAsync(checkpoints[1].RunId, checkpoints[1]); + .LookupCheckpointAsync(checkpoints[1].SessionId, checkpoints[1]); stored1.Parent.Should().NotBeNull("the second checkpoint should have a parent"); stored1.Parent.Should().Be(checkpoints[0], "the second checkpoint's parent should be the first checkpoint"); Checkpoint stored2 = await ((ICheckpointManager)checkpointManager) - .LookupCheckpointAsync(checkpoints[2].RunId, checkpoints[2]); + .LookupCheckpointAsync(checkpoints[2].SessionId, checkpoints[2]); stored2.Parent.Should().NotBeNull("the third checkpoint should have a parent"); stored2.Parent.Should().Be(checkpoints[1], "the third checkpoint's parent should be the second checkpoint"); } @@ -126,7 +126,7 @@ internal async Task Checkpoint_AfterResume_ShouldHaveResumedCheckpointAsParentAs InProcessExecutionEnvironment env = environment.ToWorkflowExecutionEnvironment(); // First run: collect a checkpoint to resume from - await using StreamingRun run = await env.WithCheckpointing(checkpointManager).StreamAsync(workflow, "Hello"); + await using StreamingRun run = await env.WithCheckpointing(checkpointManager).RunStreamingAsync(workflow, "Hello"); List firstRunCheckpoints = []; using CancellationTokenSource cts = new(); @@ -149,7 +149,7 @@ internal async Task Checkpoint_AfterResume_ShouldHaveResumedCheckpointAsParentAs await run.DisposeAsync(); // Act: Resume from the first checkpoint - StreamingRun resumed = await env.WithCheckpointing(checkpointManager).ResumeStreamAsync(workflow, resumePoint); + StreamingRun resumed = await env.WithCheckpointing(checkpointManager).ResumeStreamingAsync(workflow, resumePoint); List resumedCheckpoints = []; using CancellationTokenSource cts2 = new(); @@ -168,7 +168,7 @@ internal async Task Checkpoint_AfterResume_ShouldHaveResumedCheckpointAsParentAs // Assert: The first checkpoint after resume should have the resume point as its parent. resumedCheckpoints.Should().NotBeEmpty(); Checkpoint storedResumed = await ((ICheckpointManager)checkpointManager) - .LookupCheckpointAsync(resumedCheckpoints[0].RunId, resumedCheckpoints[0]); + .LookupCheckpointAsync(resumedCheckpoints[0].SessionId, resumedCheckpoints[0]); storedResumed.Parent.Should().NotBeNull("checkpoint created after resume should have a parent"); storedResumed.Parent.Should().Be(resumePoint, "checkpoint after resume should reference the checkpoint we resumed from"); } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InMemoryJsonStore.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InMemoryJsonStore.cs index 6746dc01d4..93acecb5c9 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InMemoryJsonStore.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InMemoryJsonStore.cs @@ -9,35 +9,35 @@ namespace Microsoft.Agents.AI.Workflows.UnitTests; internal sealed class InMemoryJsonStore : JsonCheckpointStore { - private readonly Dictionary> _store = []; + private readonly Dictionary> _store = []; - private RunCheckpointCache EnsureRunStore(string runId) + private SessionCheckpointCache EnsureSessionStore(string sessionId) { - if (!this._store.TryGetValue(runId, out RunCheckpointCache? runStore)) + if (!this._store.TryGetValue(sessionId, out SessionCheckpointCache? runStore)) { - runStore = this._store[runId] = new(); + runStore = this._store[sessionId] = new(); } return runStore; } - public override ValueTask CreateCheckpointAsync(string runId, JsonElement value, CheckpointInfo? parent = null) + public override ValueTask CreateCheckpointAsync(string sessionId, JsonElement value, CheckpointInfo? parent = null) { - return new(this.EnsureRunStore(runId).Add(runId, value)); + return new(this.EnsureSessionStore(sessionId).Add(sessionId, value)); } - public override ValueTask RetrieveCheckpointAsync(string runId, CheckpointInfo key) + public override ValueTask RetrieveCheckpointAsync(string sessionId, CheckpointInfo key) { - if (!this.EnsureRunStore(runId).TryGet(key, out JsonElement result)) + if (!this.EnsureSessionStore(sessionId).TryGet(key, out JsonElement result)) { - throw new KeyNotFoundException("Could not retrieve checkpoint with id {key.CheckpointId} for run {runId}"); + throw new KeyNotFoundException($"Could not retrieve checkpoint with id {key.CheckpointId} for session {sessionId}"); } return new(result); } - public override ValueTask> RetrieveIndexAsync(string runId, CheckpointInfo? withParent = null) + public override ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) { - return new(this.EnsureRunStore(runId).Index); + return new(this.EnsureSessionStore(sessionId).Index); } } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InProcessExecutionTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InProcessExecutionTests.cs index e45cc39d2f..76f37714fd 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InProcessExecutionTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InProcessExecutionTests.cs @@ -59,7 +59,7 @@ public async Task StreamAsyncWithTurnTokenShouldExecuteWorkflowAsync() var inputMessage = new ChatMessage(ChatRole.User, "Hello"); // Act: Execute using streaming version with TurnToken - await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new List { inputMessage }); + await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, new List { inputMessage }); // Send TurnToken to actually trigger execution (this is the key step) bool messageSent = await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); @@ -108,7 +108,7 @@ public async Task RunAsyncAndStreamAsyncShouldProduceSimilarResultsAsync() var nonStreamingEvents = nonStreamingRun.OutgoingEvents.ToList(); // Act 2: Execute using StreamAsync (streaming) with TurnToken - await using StreamingRun streamingRun = await InProcessExecution.StreamAsync(workflow2, new List { inputMessage }); + await using StreamingRun streamingRun = await InProcessExecution.RunStreamingAsync(workflow2, new List { inputMessage }); await streamingRun.TrySendMessageAsync(new TurnToken(emitEvents: true)); List streamingEvents = []; diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/RepresentationTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/RepresentationTests.cs index 26983c930e..c86d8efc8a 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/RepresentationTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/RepresentationTests.cs @@ -47,7 +47,7 @@ private static async ValueTask RunExecutorBindingInfoMatchTestAsync(ExecutorBind { ExecutorInfo info = binding.ToExecutorInfo(); - info.IsMatch(await binding.CreateInstanceAsync(runId: string.Empty)).Should().BeTrue(); + info.IsMatch(await binding.CreateInstanceAsync(sessionId: string.Empty)).Should().BeTrue(); } [Fact] diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01_Simple_Workflow_Sequential.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01_Simple_Workflow_Sequential.cs index 3eb5b8cbef..5e6e9c222a 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01_Simple_Workflow_Sequential.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01_Simple_Workflow_Sequential.cs @@ -28,8 +28,7 @@ public static Workflow WorkflowInstance public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment environment) { - // TODO: Potentially normalize terminology viz Agent.RunStreamingAsync - StreamingRun run = await environment.StreamAsync(WorkflowInstance, input: "Hello, World!").ConfigureAwait(false); + StreamingRun run = await environment.RunStreamingAsync(WorkflowInstance, input: "Hello, World!").ConfigureAwait(false); await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false)) { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/02_Simple_Workflow_Condition.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/02_Simple_Workflow_Condition.cs index 79135e4906..ac19e1c505 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/02_Simple_Workflow_Condition.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/02_Simple_Workflow_Condition.cs @@ -33,7 +33,7 @@ public static Workflow WorkflowInstance public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment environment, string input = "This is a spam message.") { - StreamingRun handle = await environment.StreamAsync(WorkflowInstance, input: input).ConfigureAwait(false); + StreamingRun handle = await environment.RunStreamingAsync(WorkflowInstance, input: input).ConfigureAwait(false); await foreach (WorkflowEvent evt in handle.WatchStreamAsync().ConfigureAwait(false)) { switch (evt) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/03_Simple_Workflow_Loop.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/03_Simple_Workflow_Loop.cs index 7dadad1847..65e2a4af69 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/03_Simple_Workflow_Loop.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/03_Simple_Workflow_Loop.cs @@ -28,7 +28,7 @@ public static Workflow WorkflowInstance public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment environment) { - StreamingRun run = await environment.StreamAsync(WorkflowInstance, NumberSignal.Init).ConfigureAwait(false); + StreamingRun run = await environment.RunStreamingAsync(WorkflowInstance, NumberSignal.Init).ConfigureAwait(false); await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false)) { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/04_Simple_Workflow_ExternalRequest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/04_Simple_Workflow_ExternalRequest.cs index 1bda1e7a77..83d155d408 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/04_Simple_Workflow_ExternalRequest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/04_Simple_Workflow_ExternalRequest.cs @@ -37,7 +37,7 @@ public static async ValueTask RunAsync(TextWriter writer, Func requests = []; await foreach (WorkflowEvent evt in handle.WatchStreamAsync().ConfigureAwait(false)) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/05_Simple_Workflow_Checkpointing.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/05_Simple_Workflow_Checkpointing.cs index 8b02a14cea..2d26062c78 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/05_Simple_Workflow_Checkpointing.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/05_Simple_Workflow_Checkpointing.cs @@ -25,7 +25,7 @@ public static async ValueTask RunAsync(TextWriter writer, Func checkpoints = []; @@ -38,13 +38,13 @@ await environment.WithCheckpointing(checkpointManager) CheckpointInfo targetCheckpoint = checkpoints[2]; - Console.WriteLine($"Restoring to checkpoint {targetCheckpoint} from run {targetCheckpoint.RunId}"); + Console.WriteLine($"Restoring to checkpoint {targetCheckpoint} from session {targetCheckpoint.SessionId}"); if (rehydrateToRestore) { await handle.DisposeAsync().ConfigureAwait(false); handle = await environment.WithCheckpointing(checkpointManager) - .ResumeStreamAsync(workflow, targetCheckpoint, CancellationToken.None) + .ResumeStreamingAsync(workflow, targetCheckpoint, CancellationToken.None) .ConfigureAwait(false); } else diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/06_GroupChat_Workflow.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/06_GroupChat_Workflow.cs index 1e00e2e649..4cc04df641 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/06_GroupChat_Workflow.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/06_GroupChat_Workflow.cs @@ -29,7 +29,7 @@ public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvi { Workflow workflow = CreateWorkflow(maxSteps); - StreamingRun run = await environment.StreamAsync(workflow, Array.Empty()) + StreamingRun run = await environment.RunStreamingAsync(workflow, Array.Empty()) .ConfigureAwait(false); await run.TrySendMessageAsync(new TurnToken(emitEvents: true)); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/07_GroupChat_Workflow_HostAsAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/07_GroupChat_Workflow_HostAsAgent.cs index 950ce70806..8e361f8ee3 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/07_GroupChat_Workflow_HostAsAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/07_GroupChat_Workflow_HostAsAgent.cs @@ -15,7 +15,7 @@ public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvi { Workflow workflow = Step6EntryPoint.CreateWorkflow(maxSteps); - AIAgent agent = workflow.AsAgent("group-chat-agent", "Group Chat Agent"); + AIAgent agent = workflow.AsAIAgent("group-chat-agent", "Group Chat Agent"); for (int i = 0; i < numIterations; i++) { diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/09_Subworkflow_ExternalRequest.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/09_Subworkflow_ExternalRequest.cs index 9e16b8a45d..eca800594a 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/09_Subworkflow_ExternalRequest.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/09_Subworkflow_ExternalRequest.cs @@ -69,10 +69,10 @@ public static WorkflowBuilder AddPassthroughRequestHandler( var requestPort = RequestPort.Create(id); - return builder.ForwardMessage(source, targets: [filter], condition: message => message.DataIs()) - .ForwardMessage(filter, targets: [requestPort], condition: message => message.DataIs()) - .ForwardMessage(requestPort, targets: [filter], condition: message => message.DataIs()) - .ForwardMessage(filter, targets: [source], condition: message => message.DataIs()); + return builder.ForwardMessage(source, targets: [filter], condition: message => message.IsDataOfType()) + .ForwardMessage(filter, targets: [requestPort], condition: message => message.IsDataOfType()) + .ForwardMessage(requestPort, targets: [filter], condition: message => message.IsDataOfType()) + .ForwardMessage(filter, targets: [source], condition: message => message.IsDataOfType()); } public static WorkflowBuilder AddExternalRequest(this WorkflowBuilder builder, ExecutorBinding source, string? id = null) @@ -207,11 +207,11 @@ public static async ValueTask> RunAsync(TextWriter writer, } else if (evt is RequestInfoEvent requestInfoEvent) { - if (requestInfoEvent.Request.DataIs()) + if (requestInfoEvent.Request.IsDataOfType()) { resourceRequests.Add(requestInfoEvent.Request); } - else if (requestInfoEvent.Request.DataIs()) + else if (requestInfoEvent.Request.IsDataOfType()) { policyRequests.Add(requestInfoEvent.Request); } @@ -237,14 +237,14 @@ public static async ValueTask> RunAsync(TextWriter writer, foreach (ExternalRequest request in resourceRequests) { - ResourceRequest resourceRequest = request.DataAs()!; + ResourceRequest resourceRequest = request.Data.As()!; resourceRequest.Id.Should().BeOneOf(ResourceMissIds); responses.Add(request.CreateResponse(Part2FinishedResponses[resourceRequest.Id].ResourceResponse!)); } foreach (ExternalRequest request in policyRequests) { - PolicyCheckRequest policyRequest = request.DataAs()!; + PolicyCheckRequest policyRequest = request.Data.As()!; policyRequest.Id.Should().BeOneOf(PolicyMissIds); responses.Add(request.CreateResponse(Part2FinishedResponses[policyRequest.Id].PolicyResponse!)); } @@ -372,7 +372,7 @@ void ConfigureRoutes(RouteBuilder routeBuilder) private async ValueTask UnwrapAndHandleRequestAsync(ExternalRequest request, IWorkflowContext context, CancellationToken cancellationToken = default) { - if (request.DataIs(out ResourceRequest? resourceRequest)) + if (request.TryGetDataAs(out ResourceRequest? resourceRequest)) { ResourceResponse? response = await this.TryHandleResourceRequestAsync(resourceRequest, context, cancellationToken) .ConfigureAwait(false); @@ -421,7 +421,7 @@ await this.QueueStateUpdateAsync(availableResources, context, cancellationToken) private ValueTask CollectResultAsync(ExternalResponse response, IWorkflowContext context) { - if (response.DataIs()) + if (response.IsDataOfType()) { // Normally we'd update the cache according to whatever logic we want here. return context.SendMessageAsync(response); @@ -459,7 +459,7 @@ void ConfigureRoutes(RouteBuilder routeBuilder) private async ValueTask UnwrapAndHandleRequestAsync(ExternalRequest request, IWorkflowContext context) { - if (request.DataIs(out PolicyCheckRequest? policyRquest)) + if (request.TryGetDataAs(out PolicyCheckRequest? policyRquest)) { PolicyResponse? response = await this.TryHandlePolicyCheckRequestAsync(policyRquest, context) .ConfigureAwait(false); @@ -507,7 +507,7 @@ private async ValueTask UnwrapAndHandleRequestAsync(ExternalRequest request, IWo } private ValueTask CollectAndForwardAsync(ExternalResponse response, IWorkflowContext context) { - if (response.DataIs()) + if (response.IsDataOfType()) { return context.SendMessageAsync(response); } @@ -569,7 +569,7 @@ async ValueTask CountFinishedRequestAndYieldResultAsync(int state, IWorkflo internal async ValueTask RunWorkflowHandleEventsAsync(Workflow workflow, TInput input) where TInput : notnull { - StreamingRun run = await InProcessExecution.StreamAsync(workflow, input); + StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input); await foreach (WorkflowEvent evt in run.WatchStreamAsync()) { switch (evt) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/10_Sequential_HostAsAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/10_Sequential_HostAsAgent.cs index 7dd454ed59..6b57aaa455 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/10_Sequential_HostAsAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/10_Sequential_HostAsAgent.cs @@ -19,7 +19,7 @@ public static Workflow CreateWorkflow() public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment executionEnvironment, IEnumerable inputs) { - AIAgent hostAgent = WorkflowInstance.AsAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); + AIAgent hostAgent = WorkflowInstance.AsAIAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); AgentSession session = await hostAgent.CreateSessionAsync(); foreach (string input in inputs) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/11_Concurrent_HostAsAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/11_Concurrent_HostAsAgent.cs index 71b5692d2b..cd0c3eb7c6 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/11_Concurrent_HostAsAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/11_Concurrent_HostAsAgent.cs @@ -31,7 +31,7 @@ public static Workflow CreateWorkflow() public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment executionEnvironment, IEnumerable inputs) { - AIAgent hostAgent = WorkflowInstance.AsAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); + AIAgent hostAgent = WorkflowInstance.AsAIAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); AgentSession session = await hostAgent.CreateSessionAsync(); foreach (string input in inputs) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/12_HandOff_HostAsAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/12_HandOff_HostAsAgent.cs index e73873ca90..3d88ed22ab 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/12_HandOff_HostAsAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/12_HandOff_HostAsAgent.cs @@ -67,7 +67,7 @@ public static Workflow CreateWorkflow() public static async ValueTask RunAsync(TextWriter writer, IWorkflowExecutionEnvironment executionEnvironment, IEnumerable inputs) { - AIAgent hostAgent = WorkflowInstance.AsAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); + AIAgent hostAgent = WorkflowInstance.AsAIAgent("echo-workflow", "EchoW", executionEnvironment: executionEnvironment); AgentSession session = await hostAgent.CreateSessionAsync(); foreach (string input in inputs) diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/13_Subworkflow_Checkpointing.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/13_Subworkflow_Checkpointing.cs index 1f2d9f9f51..795d634cb1 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/13_Subworkflow_Checkpointing.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/13_Subworkflow_Checkpointing.cs @@ -30,7 +30,7 @@ public static Workflow WorkflowInstance public static async ValueTask RunAsAgentAsync(TextWriter writer, string input, IWorkflowExecutionEnvironment environment, AgentSession? session) { - AIAgent hostAgent = WorkflowInstance.AsAgent("echo-workflow", "EchoW", executionEnvironment: environment, includeWorkflowOutputsInResponse: true); + AIAgent hostAgent = WorkflowInstance.AsAIAgent("echo-workflow", "EchoW", executionEnvironment: environment, includeWorkflowOutputsInResponse: true); session ??= await hostAgent.CreateSessionAsync(); AgentResponse response; @@ -83,10 +83,10 @@ async ValueTask BeginAsync() { if (resumeFrom == null) { - return await environment.StreamAsync(WorkflowInstance, input); + return await environment.RunStreamingAsync(WorkflowInstance, input); } - StreamingRun run = await environment.ResumeStreamAsync(WorkflowInstance, resumeFrom); + StreamingRun run = await environment.ResumeStreamingAsync(WorkflowInstance, resumeFrom); await run.TrySendMessageAsync(input); return run; } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs index 0b49f4de05..4faeff29a1 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRequestAgent.cs @@ -325,7 +325,7 @@ internal IEnumerable ValidateUnpairedRequests(List(ExternalRequest request) { - request.DataIs(out TRequest? content).Should().BeTrue(); + request.TryGetDataAs(out TRequest? content).Should().BeTrue(); return content!; } } diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowHostSmokeTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowHostSmokeTests.cs index a68a5bac75..40e4f2098f 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowHostSmokeTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowHostSmokeTests.cs @@ -92,7 +92,7 @@ public async Task Test_AsAgent_ErrorContentStreamedOutAsync(bool includeExceptio Workflow workflow = CreateWorkflow(failByThrowing); // Act - List updates = await workflow.AsAgent("WorkflowAgent", includeExceptionDetails: includeExceptionDetails) + List updates = await workflow.AsAIAgent("WorkflowAgent", includeExceptionDetails: includeExceptionDetails) .RunStreamingAsync(new ChatMessage(ChatRole.User, "Hello")) .ToListAsync(); diff --git a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowVisualizerTests.cs b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowVisualizerTests.cs index 15f0216230..f6740cc48e 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowVisualizerTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowVisualizerTests.cs @@ -114,7 +114,7 @@ public void Test_WorkflowViz_FanIn_EdgeGroup() // Build a connected workflow: start fans out to s1 and s2, which then fan-in to t var workflow = new WorkflowBuilder("start") .AddFanOutEdge(start, [s1, s2]) - .AddFanInEdge([s1, s2], t) // AddFanInEdge(target, sources) + .AddFanInBarrierEdge([s1, s2], t) // AddFanInBarrierEdge(target, sources) .Build(); var dotContent = workflow.ToDotString(); @@ -202,7 +202,7 @@ public void Test_WorkflowViz_Mixed_EdgeTypes() var workflow = new WorkflowBuilder("start") .AddEdge(start, a, Condition) // Conditional edge .AddFanOutEdge(a, [b, c]) // Fan-out - .AddFanInEdge([b, c], end) // Fan-in - AddFanInEdge(target, sources) + .AddFanInBarrierEdge([b, c], end) // Fan-in - AddFanInEdge(target, sources) .Build(); var dotContent = workflow.ToDotString(); @@ -310,7 +310,7 @@ public void Test_WorkflowViz_Mermaid_FanIn_EdgeGroup() var workflow = new WorkflowBuilder("start") .AddFanOutEdge(start, [s1, s2]) - .AddFanInEdge([s1, s2], t) + .AddFanInBarrierEdge([s1, s2], t) .Build(); var mermaidContent = workflow.ToMermaidString(); @@ -381,7 +381,7 @@ public void Test_WorkflowViz_Mermaid_Mixed_EdgeTypes() var workflow = new WorkflowBuilder("start") .AddEdge(start, a, Condition) // Conditional edge .AddFanOutEdge(a, [b, c]) // Fan-out - .AddFanInEdge([b, c], end) // Fan-in + .AddFanInBarrierEdge([b, c], end) // Fan-in .Build(); var mermaidContent = workflow.ToMermaidString();