From df6a06ee90e163b6a8edfc44064665527cb913dc Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 20 Feb 2025 16:01:30 -0800 Subject: [PATCH 1/5] Updated --- .../Agents/OpenAIAssistant_Templating.cs | 6 ++-- .../AzureAIAgent/Step01_AzureAIAgent.cs | 2 +- .../OpenAIAssistant/Step01_Assistant.cs | 2 +- dotnet/src/Agents/Abstractions/KernelAgent.cs | 10 +++---- dotnet/src/Agents/AzureAI/AzureAIAgent.cs | 29 ++++++++++++++----- dotnet/src/Agents/Core/ChatCompletionAgent.cs | 9 +++--- .../src/Agents/OpenAI/OpenAIAssistantAgent.cs | 20 ++++++++----- 7 files changed, 49 insertions(+), 29 deletions(-) diff --git a/dotnet/samples/Concepts/Agents/OpenAIAssistant_Templating.cs b/dotnet/samples/Concepts/Agents/OpenAIAssistant_Templating.cs index 4bd33e676622..3bb5a1d04c46 100644 --- a/dotnet/samples/Concepts/Agents/OpenAIAssistant_Templating.cs +++ b/dotnet/samples/Concepts/Agents/OpenAIAssistant_Templating.cs @@ -86,8 +86,8 @@ Always state the requested style of the poem. private async Task InvokeAssistantAgentWithTemplateAsync( string instructionTemplate, - string? templateFormat = null, - IPromptTemplateFactory? templateFactory = null) + string templateFormat, + IPromptTemplateFactory templateFactory) { PromptTemplateConfig config = new() { @@ -103,7 +103,7 @@ await this.AssistantClient.CreateAssistantFromTemplateAsync( metadata: SampleMetadata); // Create the agent - OpenAIAssistantAgent agent = new(assistant, this.AssistantClient, plugins: null, config, templateFactory) + OpenAIAssistantAgent agent = new(assistant, this.AssistantClient, plugins: null, templateFactory, templateFormat) { Arguments = { diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs index 1f7c0a18f8a3..c3968834b9df 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs @@ -22,7 +22,7 @@ public async Task UseTemplateForAzureAgentAsync() Agent definition = await this.AgentsClient.CreateAgentAsync("gpt-4o", templateConfig.Name, templateConfig.Description, templateConfig.Template); // Instructions, Name and Description properties defined via the config. - AzureAIAgent agent = new(definition, this.AgentsClient) + AzureAIAgent agent = new(definition, this.AgentsClient, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { Arguments = { diff --git a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs index 0196bdd122e9..568f1a310a47 100644 --- a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs +++ b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs @@ -20,7 +20,7 @@ public async Task UseTemplateForAssistantAgentAsync() // Instructions, Name and Description properties defined via the config. Assistant definition = await this.AssistantClient.CreateAssistantFromTemplateAsync(this.Model, templateConfig, metadata: SampleMetadata); - OpenAIAssistantAgent agent = new(definition, this.AssistantClient) + OpenAIAssistantAgent agent = new(definition, this.AssistantClient, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { Arguments = { diff --git a/dotnet/src/Agents/Abstractions/KernelAgent.cs b/dotnet/src/Agents/Abstractions/KernelAgent.cs index 4ee3dc332c10..ff75aa49631c 100644 --- a/dotnet/src/Agents/Abstractions/KernelAgent.cs +++ b/dotnet/src/Agents/Abstractions/KernelAgent.cs @@ -50,14 +50,14 @@ public abstract class KernelAgent : Agent /// The formatted system instructions for the agent. protected async Task FormatInstructionsAsync(Kernel kernel, KernelArguments? arguments, CancellationToken cancellationToken) { - // Use the provided template as the instructions - if (this.Template is not null) + if (this.Template is null) { - return await this.Template.RenderAsync(kernel, arguments, cancellationToken).ConfigureAwait(false); + // Use the instructions as-is + return this.Instructions; } - // Use the instructions as-is - return this.Instructions; + // Use the provided template as the instructions + return await this.Template.RenderAsync(kernel, arguments, cancellationToken).ConfigureAwait(false); } /// diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs index dfee5cccfb77..655686dfbfa0 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs @@ -54,25 +54,38 @@ public static class Tools /// /// The agent model definition. /// An instance. - /// The prompt template configuration. - /// An optional template factory. + /// Optional collection of plugins to add to the kernel. + /// An optional factory to produce the for the agent. + /// The format of the prompt template used when "templateFactory" paramater is supplied. public AzureAIAgent( Azure.AI.Projects.Agent model, AgentsClient client, - PromptTemplateConfig? templateConfig = null, - IPromptTemplateFactory? templateFactory = null) + IEnumerable? plugins = null, + IPromptTemplateFactory? templateFactory = null, + string? templateFormat = null) { this.Client = client; this.Definition = model; this.Description = this.Definition.Description; this.Id = this.Definition.Id; this.Name = this.Definition.Name; - this.Instructions = templateConfig?.Template ?? this.Definition.Instructions; + this.Instructions = this.Definition.Instructions; - if (templateConfig is not null) + if (templateFactory != null) { - this.Template = templateFactory?.Create(templateConfig) - ?? throw new KernelException($"Invalid prompt template factory {templateFactory} for format {templateConfig.TemplateFormat}"); + Verify.NotNullOrWhiteSpace(templateFormat); + + PromptTemplateConfig templateConfig = new(this.Instructions) + { + TemplateFormat = templateFormat + }; + + this.Template = templateFactory.Create(templateConfig); + } + + if (plugins != null) + { + this.Kernel.Plugins.AddRange(plugins); } } diff --git a/dotnet/src/Agents/Core/ChatCompletionAgent.cs b/dotnet/src/Agents/Core/ChatCompletionAgent.cs index 9aa85da55c52..527e633bf443 100644 --- a/dotnet/src/Agents/Core/ChatCompletionAgent.cs +++ b/dotnet/src/Agents/Core/ChatCompletionAgent.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; @@ -62,7 +63,7 @@ public override IAsyncEnumerable InvokeAsync( Kernel? kernel = null, CancellationToken cancellationToken = default) { - var agentName = this.GetDisplayName(); + string agentName = this.GetDisplayName(); return ActivityExtensions.RunWithActivityAsync( () => ModelDiagnostics.StartAgentInvocationActivity(this.Id, agentName, this.Description), @@ -77,7 +78,7 @@ public override IAsyncEnumerable InvokeStreamingAsy Kernel? kernel = null, CancellationToken cancellationToken = default) { - var agentName = this.GetDisplayName(); + string agentName = this.GetDisplayName(); return ActivityExtensions.RunWithActivityAsync( () => ModelDiagnostics.StartAgentInvocationActivity(this.Id, agentName, this.Description), @@ -143,7 +144,7 @@ private async IAsyncEnumerable InternalInvokeAsync( int messageCount = chat.Count; - var serviceType = chatCompletionService.GetType(); + Type serviceType = chatCompletionService.GetType(); this.Logger.LogAgentChatServiceInvokingAgent(nameof(InvokeAsync), this.Id, agentName, serviceType); @@ -190,7 +191,7 @@ private async IAsyncEnumerable InternalInvokeStream int messageCount = chat.Count; - var serviceType = chatCompletionService.GetType(); + Type serviceType = chatCompletionService.GetType(); this.Logger.LogAgentChatServiceInvokingAgent(nameof(InvokeAsync), this.Id, agentName, serviceType); diff --git a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs index cb0fbd0bc3eb..e00cce278c60 100644 --- a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs +++ b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs @@ -35,14 +35,14 @@ public sealed partial class OpenAIAssistantAgent : KernelAgent /// The assistant definition. /// The OpenAI provider for accessing the Assistant API service. /// Optional collection of plugins to add to the kernel. - /// The prompt template configuration. /// An optional factory to produce the for the agent. + /// The format of the prompt template used when "templateFactory" paramater is supplied. public OpenAIAssistantAgent( Assistant definition, AssistantClient client, IEnumerable? plugins = null, - PromptTemplateConfig? templateConfig = null, - IPromptTemplateFactory? templateFactory = null) + IPromptTemplateFactory? templateFactory = null, + string? templateFormat = null) { this.Client = client; @@ -51,12 +51,18 @@ public OpenAIAssistantAgent( this.Description = this.Definition.Description; this.Id = this.Definition.Id; this.Name = this.Definition.Name; - this.Instructions = templateConfig?.Template ?? this.Definition.Instructions; + this.Instructions = this.Definition.Instructions; - if (templateConfig is not null) + if (templateFactory != null) { - this.Template = templateFactory?.Create(templateConfig) - ?? throw new KernelException($"Invalid prompt template factory {templateFactory} for format {templateConfig.TemplateFormat}"); + Verify.NotNullOrWhiteSpace(templateFormat); + + PromptTemplateConfig templateConfig = new(this.Instructions) + { + TemplateFormat = templateFormat + }; + + this.Template = templateFactory?.Create(templateConfig); } if (plugins != null) From f24a3c60c9bf734e4daccd22b2577cef3b366cce Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 20 Feb 2025 16:05:58 -0800 Subject: [PATCH 2/5] Nullability --- dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs index e00cce278c60..69d4673f40a6 100644 --- a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs +++ b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs @@ -62,7 +62,7 @@ public OpenAIAssistantAgent( TemplateFormat = templateFormat }; - this.Template = templateFactory?.Create(templateConfig); + this.Template = templateFactory.Create(templateConfig); } if (plugins != null) From 0ad55be0832813665688bfc57eedc816abc12bcd Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 20 Feb 2025 16:08:32 -0800 Subject: [PATCH 3/5] Readability --- .../AzureAIAgent/Step01_AzureAIAgent.cs | 13 ++++++++----- .../OpenAIAssistant/Step01_Assistant.cs | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs index c3968834b9df..6e1fe2aef210 100644 --- a/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs +++ b/dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step01_AzureAIAgent.cs @@ -19,16 +19,19 @@ public async Task UseTemplateForAzureAgentAsync() // Define the agent string generateStoryYaml = EmbeddedResource.Read("GenerateStory.yaml"); PromptTemplateConfig templateConfig = KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml); - + // Instructions, Name and Description properties defined via the PromptTemplateConfig. Agent definition = await this.AgentsClient.CreateAgentAsync("gpt-4o", templateConfig.Name, templateConfig.Description, templateConfig.Template); - // Instructions, Name and Description properties defined via the config. - AzureAIAgent agent = new(definition, this.AgentsClient, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) + AzureAIAgent agent = new( + definition, + this.AgentsClient, + templateFactory: new KernelPromptTemplateFactory(), + templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { Arguments = { { "topic", "Dog" }, - { "length", "3" }, - }, + { "length", "3" } + } }; // Create a thread for the agent conversation. diff --git a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs index 568f1a310a47..312edc9e7c6f 100644 --- a/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs +++ b/dotnet/samples/GettingStartedWithAgents/OpenAIAssistant/Step01_Assistant.cs @@ -17,16 +17,19 @@ public async Task UseTemplateForAssistantAgentAsync() // Define the agent string generateStoryYaml = EmbeddedResource.Read("GenerateStory.yaml"); PromptTemplateConfig templateConfig = KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml); - - // Instructions, Name and Description properties defined via the config. + // Instructions, Name and Description properties defined via the PromptTemplateConfig. Assistant definition = await this.AssistantClient.CreateAssistantFromTemplateAsync(this.Model, templateConfig, metadata: SampleMetadata); - OpenAIAssistantAgent agent = new(definition, this.AssistantClient, templateFactory: new KernelPromptTemplateFactory(), templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) + OpenAIAssistantAgent agent = new( + definition, + this.AssistantClient, + templateFactory: new KernelPromptTemplateFactory(), + templateFormat: PromptTemplateConfig.SemanticKernelTemplateFormat) { Arguments = { { "topic", "Dog" }, - { "length", "3" }, - }, + { "length", "3" } + } }; // Create a thread for the agent conversation. From e2824209f9099be5c3f64e83c765eb271d056a43 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 20 Feb 2025 16:09:37 -0800 Subject: [PATCH 4/5] Typo --- dotnet/src/Agents/AzureAI/AzureAIAgent.cs | 2 +- dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs index 655686dfbfa0..912bd83778fe 100644 --- a/dotnet/src/Agents/AzureAI/AzureAIAgent.cs +++ b/dotnet/src/Agents/AzureAI/AzureAIAgent.cs @@ -56,7 +56,7 @@ public static class Tools /// An instance. /// Optional collection of plugins to add to the kernel. /// An optional factory to produce the for the agent. - /// The format of the prompt template used when "templateFactory" paramater is supplied. + /// The format of the prompt template used when "templateFactory" parameter is supplied. public AzureAIAgent( Azure.AI.Projects.Agent model, AgentsClient client, diff --git a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs index 69d4673f40a6..7beb380f5bc4 100644 --- a/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs +++ b/dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs @@ -36,7 +36,7 @@ public sealed partial class OpenAIAssistantAgent : KernelAgent /// The OpenAI provider for accessing the Assistant API service. /// Optional collection of plugins to add to the kernel. /// An optional factory to produce the for the agent. - /// The format of the prompt template used when "templateFactory" paramater is supplied. + /// The format of the prompt template used when "templateFactory" parameter is supplied. public OpenAIAssistantAgent( Assistant definition, AssistantClient client, From 2955c5f308ed2cf8dcdc539957b1a8bb4691de89 Mon Sep 17 00:00:00 2001 From: Chris Rickman Date: Thu, 20 Feb 2025 16:16:59 -0800 Subject: [PATCH 5/5] Format --- dotnet/src/Agents/Abstractions/KernelAgent.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Agents/Abstractions/KernelAgent.cs b/dotnet/src/Agents/Abstractions/KernelAgent.cs index ff75aa49631c..aac75e2fd62f 100644 --- a/dotnet/src/Agents/Abstractions/KernelAgent.cs +++ b/dotnet/src/Agents/Abstractions/KernelAgent.cs @@ -52,8 +52,8 @@ public abstract class KernelAgent : Agent { if (this.Template is null) { - // Use the instructions as-is - return this.Instructions; + // Use the instructions as-is + return this.Instructions; } // Use the provided template as the instructions