From 55045b5c1e774be7a09ce2754bebc2db3c550f5e Mon Sep 17 00:00:00 2001 From: westey <164392973+westey-m@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:15:46 +0100 Subject: [PATCH] Basic agent invocation sample (#175) * Basic agent invocation sample * Simplify sample further. * Add additional comment. * Address code review comments. * Suppress CA2000 and remove using from most basic sample, since the IChatClient instances involved do not do any disposal. --- dotnet/samples/.editorconfig | 3 +- dotnet/samples/GettingStarted/AgentSample.cs | 7 +++-- .../Steps/Step01_ChatClientAgent_Running.cs | 28 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/dotnet/samples/.editorconfig b/dotnet/samples/.editorconfig index 348c57a8b1..0e87de9ec1 100644 --- a/dotnet/samples/.editorconfig +++ b/dotnet/samples/.editorconfig @@ -4,4 +4,5 @@ dotnet_diagnostic.CA2007.severity = none # Do not directly await a Task dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member dotnet_diagnostic.IDE1006.severity = warning # Naming rule violations dotnet_diagnostic.VSTHRD111.severity = none # Use .ConfigureAwait(bool) is hidden by default, set to none to prevent IDE from changing on autosave -dotnet_diagnostic.CA1716.severity = none # Add summary to documentation comment. \ No newline at end of file +dotnet_diagnostic.CA1716.severity = none # Add summary to documentation comment. +dotnet_diagnostic.CA2000.severity = none # Call System.IDisposable.Dispose on object before all references to it are out of scope diff --git a/dotnet/samples/GettingStarted/AgentSample.cs b/dotnet/samples/GettingStarted/AgentSample.cs index 0be5aa1551..4194cc2b02 100644 --- a/dotnet/samples/GettingStarted/AgentSample.cs +++ b/dotnet/samples/GettingStarted/AgentSample.cs @@ -6,6 +6,7 @@ using Azure.AI.OpenAI; using Azure.Identity; using Microsoft.Extensions.AI; using Microsoft.Extensions.AI.Agents; +using Microsoft.Shared.Diagnostics; using Microsoft.Shared.Samples; using OpenAI.Assistants; using OpenAI.Chat; @@ -31,13 +32,13 @@ public class AgentSample(ITestOutputHelper output) : BaseSample(output) AzureAIAgentsPersistent } - protected IChatClient GetChatClient(ChatClientProviders provider, ChatClientAgentOptions options) + protected IChatClient GetChatClient(ChatClientProviders provider, ChatClientAgentOptions? options = null) => provider switch { ChatClientProviders.OpenAIChatCompletion => GetOpenAIChatClient(), - ChatClientProviders.OpenAIAssistant => GetOpenAIAssistantChatClient(options), + ChatClientProviders.OpenAIAssistant => GetOpenAIAssistantChatClient(Throw.IfNull(options)), ChatClientProviders.AzureOpenAI => GetAzureOpenAIChatClient(), - ChatClientProviders.AzureAIAgentsPersistent => GetAzureAIAgentPersistentClient(options), + ChatClientProviders.AzureAIAgentsPersistent => GetAzureAIAgentPersistentClient(Throw.IfNull(options)), ChatClientProviders.OpenAIResponses or ChatClientProviders.OpenAIResponses_InMemoryMessageThread or ChatClientProviders.OpenAIResponses_ConversationIdThread diff --git a/dotnet/samples/GettingStarted/Steps/Step01_ChatClientAgent_Running.cs b/dotnet/samples/GettingStarted/Steps/Step01_ChatClientAgent_Running.cs index 5d2b5b130f..8951ee4c17 100644 --- a/dotnet/samples/GettingStarted/Steps/Step01_ChatClientAgent_Running.cs +++ b/dotnet/samples/GettingStarted/Steps/Step01_ChatClientAgent_Running.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. +using Microsoft.Extensions.AI; using Microsoft.Extensions.AI.Agents; namespace Steps; @@ -15,6 +16,33 @@ public sealed class Step01_ChatClientAgent_Running(ITestOutputHelper output) : A private const string ParrotName = "Parrot"; private const string ParrotInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound."; + /// + /// Demonstrate the most basic Agent case, where we do not have a server-side agent + /// but just an in-memory agent, backed by an inference service, + /// and we are invoking with text input, and getting back a text response. + /// + [Theory] + [InlineData(ChatClientProviders.AzureOpenAI)] + [InlineData(ChatClientProviders.OpenAIChatCompletion)] + [InlineData(ChatClientProviders.OpenAIResponses)] + public async Task RunBasic(ChatClientProviders provider) + { + // Get the chat client to communicate with the inference service backing our agent. + // Any implementation of Microsoft.Extensions.AI.Agents.IChatClient can be used with the ChatClientAgent. + // See the Providers folder for examples on how to create chat clients for some sample providers. + IChatClient chatClient = base.GetChatClient(provider); + + // Define the agent + Agent agent = new ChatClientAgent(chatClient, options: new() + { + Name = ParrotName, + Instructions = ParrotInstructions, + }); + + // Invoke the agent and output the text result. + Console.WriteLine(await agent.RunAsync("Fortune favors the bold.")); + } + /// /// Demonstrate the usage of where each invocation is /// a unique interaction with no conversation history between them.