diff --git a/dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example10_SemanticKernel.cs b/dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example10_SemanticKernel.cs index 209b3dc58252..dbdcbf0411c1 100644 --- a/dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example10_SemanticKernel.cs +++ b/dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example10_SemanticKernel.cs @@ -50,7 +50,7 @@ public static async Task RunAsync() kernel.Plugins.AddFromObject(new LightPlugin()); var skAgent = kernel - .ToSemanticKernelAgent(name: "assistant", systemMessage: "You control the light", settings); + .ToSemanticKernelAgent(name: "assistant", systemMessage: "You control the light", settings: settings); // Send a message to the skAgent, the skAgent supports the following message types: // - IMessage diff --git a/dotnet/src/AutoGen.SemanticKernel/Extension/KernelExtension.cs b/dotnet/src/AutoGen.SemanticKernel/Extension/KernelExtension.cs index 4a27f1d221f4..0ef4d0748d51 100644 --- a/dotnet/src/AutoGen.SemanticKernel/Extension/KernelExtension.cs +++ b/dotnet/src/AutoGen.SemanticKernel/Extension/KernelExtension.cs @@ -8,9 +8,9 @@ namespace AutoGen.SemanticKernel.Extension; public static class KernelExtension { - public static SemanticKernelAgent ToSemanticKernelAgent(this Kernel kernel, string name, string systemMessage = "You are a helpful AI assistant", PromptExecutionSettings? settings = null) + public static SemanticKernelAgent ToSemanticKernelAgent(this Kernel kernel, string name, string systemMessage = "You are a helpful AI assistant", string? modelServiceId = null, PromptExecutionSettings? settings = null) { - return new SemanticKernelAgent(kernel, name, systemMessage, settings); + return new SemanticKernelAgent(kernel, name, systemMessage, modelServiceId, settings); } /// diff --git a/dotnet/src/AutoGen.SemanticKernel/SemanticKernelAgent.cs b/dotnet/src/AutoGen.SemanticKernel/SemanticKernelAgent.cs index ae7251e148a2..b8f2d6f18111 100644 --- a/dotnet/src/AutoGen.SemanticKernel/SemanticKernelAgent.cs +++ b/dotnet/src/AutoGen.SemanticKernel/SemanticKernelAgent.cs @@ -32,17 +32,28 @@ public class SemanticKernelAgent : IStreamingAgent { private readonly Kernel _kernel; private readonly string _systemMessage; + private readonly string? _modelServiceId; private readonly PromptExecutionSettings? _settings; + /// + /// Create a new instance of + /// + /// The Semantic Kernel - Kernel object + /// The name of the agent. + /// The system message. + /// Optional serviceId for the model. + /// The prompt execution settings. public SemanticKernelAgent( Kernel kernel, string name, string systemMessage = "You are a helpful AI assistant", + string? modelServiceId = null, PromptExecutionSettings? settings = null) { _kernel = kernel; this.Name = name; _systemMessage = systemMessage; + _modelServiceId = modelServiceId; _settings = settings; } @@ -52,7 +63,7 @@ public async Task GenerateReplyAsync(IEnumerable messages, G { var chatHistory = BuildChatHistory(messages); var option = BuildOption(options); - var chatService = _kernel.GetRequiredService(); + var chatService = GetChatCompletionService(); var reply = await chatService.GetChatMessageContentsAsync(chatHistory, option, _kernel, cancellationToken); @@ -71,7 +82,7 @@ public async IAsyncEnumerable GenerateStreamingReplyAsync( { var chatHistory = BuildChatHistory(messages); var option = BuildOption(options); - var chatService = _kernel.GetRequiredService(); + var chatService = GetChatCompletionService(); var response = chatService.GetStreamingChatMessageContentsAsync(chatHistory, option, _kernel, cancellationToken); await foreach (var content in response) @@ -108,6 +119,13 @@ private PromptExecutionSettings BuildOption(GenerateReplyOptions? options) }; } + private IChatCompletionService GetChatCompletionService() + { + return string.IsNullOrEmpty(_modelServiceId) + ? _kernel.GetRequiredService() + : _kernel.GetRequiredService(_modelServiceId); + } + private IEnumerable ProcessMessage(IEnumerable messages) { return messages.Select(m => m switch diff --git a/dotnet/test/AutoGen.SemanticKernel.Tests/SemanticKernelAgentTest.cs b/dotnet/test/AutoGen.SemanticKernel.Tests/SemanticKernelAgentTest.cs index cb7d83ed8a77..de56080dc0db 100644 --- a/dotnet/test/AutoGen.SemanticKernel.Tests/SemanticKernelAgentTest.cs +++ b/dotnet/test/AutoGen.SemanticKernel.Tests/SemanticKernelAgentTest.cs @@ -37,25 +37,25 @@ public async Task BasicConversationTestAsync() .AddAzureOpenAIChatCompletion(deploymentName, endpoint, key); var kernel = builder.Build(); - - kernel.GetRequiredService(); - var skAgent = new SemanticKernelAgent(kernel, "assistant"); - var chatMessageContent = MessageEnvelope.Create(new ChatMessageContent(AuthorRole.Assistant, "Hello")); - var reply = await skAgent.SendAsync(chatMessageContent); + await TestBasicConversationAsync(skAgent); + } - reply.Should().BeOfType>(); - reply.As>().From.Should().Be("assistant"); + [ApiKeyFact("AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_DEPLOY_NAME")] + public async Task BasicConversationTestWithKeyedServiceAsync() + { + var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new Exception("Please set AZURE_OPENAI_ENDPOINT environment variable."); + var key = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? throw new Exception("Please set AZURE_OPENAI_API_KEY environment variable."); + var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOY_NAME") ?? throw new Exception("Please set AZURE_OPENAI_DEPLOY_NAME environment variable."); + var modelServiceId = "my-service-id"; + var builder = Kernel.CreateBuilder() + .AddAzureOpenAIChatCompletion(deploymentName, endpoint, key, modelServiceId); - // test streaming - var streamingReply = skAgent.GenerateStreamingReplyAsync(new[] { chatMessageContent }); + var kernel = builder.Build(); + var skAgent = new SemanticKernelAgent(kernel, "assistant", modelServiceId: modelServiceId); - await foreach (var streamingMessage in streamingReply) - { - streamingMessage.Should().BeOfType>(); - streamingMessage.As>().From.Should().Be("assistant"); - } + await TestBasicConversationAsync(skAgent); } [ApiKeyFact("AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT", "AZURE_OPENAI_DEPLOY_NAME")] @@ -241,4 +241,22 @@ public async Task SkChatCompletionAgentPluginTestAsync() reply.GetContent()!.ToLower().Should().Contain("seattle"); reply.GetContent()!.ToLower().Should().Contain("sunny"); } + + private static async Task TestBasicConversationAsync(SemanticKernelAgent agent) + { + var chatMessageContent = MessageEnvelope.Create(new ChatMessageContent(AuthorRole.Assistant, "Hello")); + var reply = await agent.SendAsync(chatMessageContent); + + reply.Should().BeOfType>(); + reply.As>().From.Should().Be("assistant"); + + // test streaming + var streamingReply = agent.GenerateStreamingReplyAsync(new[] { chatMessageContent }); + + await foreach (var streamingMessage in streamingReply) + { + streamingMessage.Should().BeOfType>(); + streamingMessage.As>().From.Should().Be("assistant"); + } + } }