// Copyright (c) Microsoft. All rights reserved. using Azure.AI.OpenAI; using Azure.Identity; using Microsoft.Agents.AI; using Microsoft.Agents.AI.Workflows; using Microsoft.Extensions.AI; namespace WorkflowAsAnAgentSample; /// /// This sample introduces the concepts workflows as agents, where a workflow can be /// treated as an . This allows you to interact with a workflow /// as if it were a single agent. /// /// In this example, we create a workflow that uses two language agents to process /// input concurrently, one that responds in French and another that responds in English. /// /// You will interact with the workflow in an interactive loop, sending messages and receiving /// streaming responses from the workflow as if it were an agent who responds in both languages. /// /// /// Pre-requisites: /// - Foundational samples should be completed first. /// - This sample uses concurrent processing. /// - An Azure OpenAI endpoint and deployment name. /// public static class Program { 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"; 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.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 while (true) { Console.WriteLine(); Console.Write("User (or 'exit' to quit): "); string? input = Console.ReadLine(); if (string.IsNullOrWhiteSpace(input) || input.Equals("exit", StringComparison.OrdinalIgnoreCase)) { break; } await ProcessInputAsync(agent, session, input); } // Helper method to process user input and display streaming responses. To display // multiple interleaved responses correctly, we buffer updates by message ID and // re-render all messages on each update. static async Task ProcessInputAsync(AIAgent agent, AgentSession? session, string input) { Dictionary> buffer = []; await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(input, session)) { if (update.MessageId is null || string.IsNullOrEmpty(update.Text)) { // skip updates that don't have a message ID or text continue; } Console.Clear(); if (!buffer.TryGetValue(update.MessageId, out List? value)) { value = []; buffer[update.MessageId] = value; } value.Add(update); foreach (var (messageId, segments) in buffer) { string combinedText = string.Concat(segments); Console.WriteLine($"{segments[0].AuthorName}: {combinedText}"); Console.WriteLine(); } } } } }