.NET: Remove Semantic Kernel Migration instructions (moved already to SK Repository) (#1485)

* Moved SK->AF migrations

* Update dotnet/samples/SemanticKernelMigration/README.md

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>

* Removing extra jump for migration

---------

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
This commit is contained in:
Roger Barreto
2025-10-15 17:13:11 +01:00
committed by GitHub
Unverified
parent f593bb535a
commit 5333cce63c
64 changed files with 1 additions and 3903 deletions
-49
View File
@@ -133,55 +133,6 @@
<Folder Name="/Samples/SemanticKernelMigration/">
<File Path="samples/SemanticKernelMigration/README.md" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AzureAIFoundry/">
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step01_Basics/AzureAIFoundry_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step02_ToolCall/AzureAIFoundry_Step02_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step03_DependencyInjection/AzureAIFoundry_Step03_DependencyInjection.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step04_CodeInterpreter/AzureAIFoundry_Step04_CodeInterpreter.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/Playground/">
<File Path="samples/SemanticKernelMigration/Playground/README.md" />
<Project Path="samples/SemanticKernelMigration/Playground/SemanticKernelBasic/SemanticKernelBasic.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/OpenAI/">
<Project Path="samples/SemanticKernelMigration/OpenAI/Step01_Basics/OpenAI_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAI/Step02_ToolCall/OpenAI_Step02_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAI/Step03_DependencyInjection/OpenAI_Step03_DependencyInjection.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/OpenAIAssistants/">
<Project Path="samples/SemanticKernelMigration/OpenAIAssistants/Step01_Basics/OpenAIAssistants_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIAssistants/Step02_ToolCall/OpenAIAssistants_Step02_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIAssistants/Step03_DependencyInjection/OpenAIAssistants_Step03_DependencyInjection.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIAssistants/Step04_CodeInterpreter/OpenAIAssistants_Step04_CodeInterpreter.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/OpenAIResponses/">
<Project Path="samples/SemanticKernelMigration/OpenAIResponses/Step01_Basics/OpenAIResponses_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIResponses/Step02_ReasoningModel/OpenAIResponses_Step02_ReasoningModel.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIResponses/Step03_ToolCall/OpenAIResponses_Step03_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAIResponses/Step04_DependencyInjection/OpenAIResponses_Step04_DependencyInjection.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AzureOpenAI/">
<Project Path="samples/SemanticKernelMigration/AzureOpenAI/Step01_Basics/AzureOpenAI_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAI/Step02_ToolCall/AzureOpenAI_Step02_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAI/Step03_DependencyInjection/AzureOpenAI_Step03_DependencyInjection.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AzureOpenAIAssistants/">
<Project Path="samples/SemanticKernelMigration/AzureOpenAIAssistants/Step01_Basics/AzureOpenAIAssistants_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIAssistants/Step02_ToolCall/AzureOpenAIAssistants_Step02_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIAssistants/Step03_DependencyInjection/AzureOpenAIAssistants_Step03_DependencyInjection.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIAssistants/Step04_CodeInterpreter/AzureOpenAIAssistants_Step04_CodeInterpreter.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AzureOpenAIResponses/">
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step01_Basics/AzureOpenAIResponses_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step02_ReasoningModel/AzureOpenAIResponses_Step02_ReasoningModel.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step03_ToolCall/AzureOpenAIResponses_Step03_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step04_DependencyInjection/AzureOpenAIResponses_Step04_DependencyInjection.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AgentOrchestrations/">
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step01_Concurrent/AgentOrchestrations_Step01_Concurrent.csproj" />
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step02_Sequential/AgentOrchestrations_Step02_Sequential.csproj" />
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step03_Handoff/AgentOrchestrations_Step03_Handoff.csproj" />
</Folder>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path=".gitignore" />
+1 -1
View File
@@ -18,7 +18,7 @@ The samples are subdivided into the following categories:
`AIAgent` and can be used with any underlying service that provides an `AIAgent` implementation.
- [Getting Started - Agent Providers](./GettingStarted/AgentProviders/README.md): Shows how to create an AIAgent instance for a selection of providers.
- [Getting Started - Agent Telemetry](./GettingStarted/AgentOpenTelemetry/README.md): Demo which showcases the integration of OpenTelemetry with the Microsoft Agent Framework using Azure OpenAI and .NET Aspire Dashboard for telemetry visualization.
- [Semantic Kernel Migration](./SemanticKernelMigration/): Semantic Kernel to Agent Framework migration guide
- [Semantic Kernel to Agent Framework Migration](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/samples/AgentFrameworkMigration): For instructions and samples describing how to migrate from Semantic Kernel to Microsoft Agent Framework
## Prerequisites
@@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1812;RCS1102;CA1707;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Orchestration" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Runtime.InProcess" VersionOverride="1.*-*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Workflows\Microsoft.Agents.AI.Workflows.csproj" />
</ItemGroup>
</Project>
@@ -1,109 +0,0 @@
// 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;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Orchestration;
using Microsoft.SemanticKernel.Agents.Orchestration.Concurrent;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
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 agentInstructions = "You are a translation assistant who only responds in {0}. Respond to any input by outputting the name of the input language and then translating the input to {0}.";
// This sample compares running concurrent orchestrations using
// Semantic Kernel and the Agent Framework.
Console.WriteLine("=== Semantic Kernel Concurrent Orchestration ===");
await SKConcurrentOrchestration();
Console.WriteLine("\n=== Agent Framework Concurrent Agent Workflow ===");
await AFConcurrentAgentWorkflow();
# region SKConcurrentOrchestration
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
async Task SKConcurrentOrchestration()
{
ConcurrentOrchestration orchestration = new([
GetSKTranslationAgent("French"),
GetSKTranslationAgent("Spanish")])
{
StreamingResponseCallback = StreamingResultCallback,
};
InProcessRuntime runtime = new();
await runtime.StartAsync();
// Run the orchestration
OrchestrationResult<string[]> result = await orchestration.InvokeAsync("Hello, world!", runtime);
string[] texts = await result.GetValueAsync(TimeSpan.FromSeconds(20));
await runtime.RunUntilIdleAsync();
}
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
ChatCompletionAgent GetSKTranslationAgent(string targetLanguage)
{
var kernel = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, new AzureCliCredential()).Build();
return new ChatCompletionAgent()
{
Kernel = kernel,
Instructions = string.Format(agentInstructions, targetLanguage),
Description = $"Agent that translates texts to {targetLanguage}",
Name = $"SKTranslationAgent_{targetLanguage}"
};
}
ValueTask StreamingResultCallback(StreamingChatMessageContent streamedResponse, bool isFinal)
{
Console.Write(streamedResponse.Content);
if (isFinal)
{
Console.WriteLine();
}
return ValueTask.CompletedTask;
}
# endregion
# region AFConcurrentAgentWorkflow
async Task AFConcurrentAgentWorkflow()
{
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient();
var frenchAgent = GetAFTranslationAgent("French", client);
var spanishAgent = GetAFTranslationAgent("Spanish", client);
var concurrentAgentWorkflow = AgentWorkflowBuilder.BuildConcurrent([frenchAgent, spanishAgent]);
await using StreamingRun run = await InProcessExecution.StreamAsync(concurrentAgentWorkflow, "Hello, world!");
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
string? lastExecutorId = null;
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentRunUpdateEvent e)
{
if (string.IsNullOrEmpty(e.Update.Text))
{
continue;
}
if (e.ExecutorId != lastExecutorId)
{
lastExecutorId = e.ExecutorId;
Console.WriteLine();
Console.Write($"{e.Update.AuthorName}: ");
}
Console.Write(e.Update.Text);
}
}
}
ChatClientAgent GetAFTranslationAgent(string targetLanguage, IChatClient chatClient) =>
new(chatClient, string.Format(agentInstructions, targetLanguage), name: $"AFTranslationAgent_{targetLanguage}");
# endregion
@@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1812;RCS1102;CA1707;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Orchestration" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Runtime.InProcess" VersionOverride="1.*-*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Workflows\Microsoft.Agents.AI.Workflows.csproj" />
</ItemGroup>
</Project>
@@ -1,112 +0,0 @@
// 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;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Orchestration;
using Microsoft.SemanticKernel.Agents.Orchestration.Sequential;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
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 agentInstructions = "You are a translation assistant who only responds in {0}. Respond to any input by outputting the name of the input language and then translating the input to {0}.";
// This sample compares running sequential orchestrations using
// Semantic Kernel and the Agent Framework.
Console.WriteLine("=== Semantic Kernel Sequential Orchestration ===");
await SKSequentialOrchestration();
Console.WriteLine("\n=== Agent Framework Sequential Agent Workflow ===");
await AFSequentialAgentWorkflow();
# region SKSequentialOrchestration
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
async Task SKSequentialOrchestration()
{
SequentialOrchestration orchestration = new([
GetSKTranslationAgent("French"),
GetSKTranslationAgent("Spanish"),
GetSKTranslationAgent("English")])
{
StreamingResponseCallback = StreamingResultCallback,
};
InProcessRuntime runtime = new();
await runtime.StartAsync();
// Run the orchestration
OrchestrationResult<string> result = await orchestration.InvokeAsync("Hello, world!", runtime);
string text = await result.GetValueAsync(TimeSpan.FromSeconds(20));
await runtime.RunUntilIdleAsync();
}
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
ChatCompletionAgent GetSKTranslationAgent(string targetLanguage)
{
var kernel = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, new AzureCliCredential()).Build();
return new ChatCompletionAgent()
{
Kernel = kernel,
Instructions = string.Format(agentInstructions, targetLanguage),
Description = $"Agent that translates texts to {targetLanguage}",
Name = $"SKTranslationAgent_{targetLanguage}"
};
}
ValueTask StreamingResultCallback(StreamingChatMessageContent streamedResponse, bool isFinal)
{
Console.Write(streamedResponse.Content);
if (isFinal)
{
Console.WriteLine();
}
return ValueTask.CompletedTask;
}
# endregion
# region AFSequentialAgentWorkflow
async Task AFSequentialAgentWorkflow()
{
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient();
var frenchAgent = GetAFTranslationAgent("French", client);
var spanishAgent = GetAFTranslationAgent("Spanish", client);
var englishAgent = GetAFTranslationAgent("English", client);
var sequentialAgentWorkflow = AgentWorkflowBuilder.BuildSequential(
[frenchAgent, spanishAgent, englishAgent]);
await using StreamingRun run = await InProcessExecution.StreamAsync(sequentialAgentWorkflow, "Hello, world!");
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
string? lastExecutorId = null;
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentRunUpdateEvent e)
{
if (string.IsNullOrEmpty(e.Update.Text))
{
continue;
}
if (e.ExecutorId != lastExecutorId)
{
lastExecutorId = e.ExecutorId;
Console.WriteLine();
Console.Write($"{e.Update.AuthorName}: ");
}
Console.Write(e.Update.Text);
}
}
}
ChatClientAgent GetAFTranslationAgent(string targetLanguage, IChatClient chatClient) =>
new(chatClient, string.Format(agentInstructions, targetLanguage), name: $"AFTranslationAgent_{targetLanguage}");
# endregion
@@ -1,26 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1812;RCS1102;CA1707;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Orchestration" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Runtime.InProcess" VersionOverride="1.*-*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Workflows\Microsoft.Agents.AI.Workflows.csproj" />
</ItemGroup>
</Project>
@@ -1,247 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using System.Text.Json;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Orchestration;
using Microsoft.SemanticKernel.Agents.Orchestration.Handoff;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
using Microsoft.SemanticKernel.ChatCompletion;
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";
// Queries to simulate user input during the interactive orchestration
List<string> Queries = [
"I'd like to track the status of my first order 123.",
"I want to return another order of mine whose ID is 456 because it arrived damaged.",
];
// This sample compares running handoff orchestrations using
// Semantic Kernel and the Agent Framework.
Console.WriteLine("=== Semantic Kernel Handoff Orchestration ===");
// State to help format the streaming output
bool newAgentTurn = true;
string previousFunctionCallId = string.Empty;
await SKHandoffOrchestration();
Console.WriteLine("\n=== Agent Framework Handoff Agent Workflow ===");
await AFHandoffAgentWorkflow();
# region SKHandoffOrchestration
[KernelFunction]
string SKCheckOrderStatus(string orderId) => $"Order {orderId} is shipped and will arrive in 2-3 days.";
[KernelFunction]
string SKProcessReturn(string orderId, string reason) => $"Return for order {orderId} has been processed successfully.";
[KernelFunction]
string SKProcessRefund(string orderId, string reason) => $"Refund for order {orderId} has been processed successfully.";
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
async Task SKHandoffOrchestration()
{
// Create agents
var triageAgent = GetSKAgent(
instructions: "You are a customer support agent that triages issues.",
name: "TriageAgent",
description: "Handle customer requests.");
var statusAgent = GetSKAgent(
instructions: "You are a customer support agent that checks order status.",
name: "OrderStatusAgent",
description: "Handle order status requests.");
statusAgent.Kernel.Plugins.AddFromFunctions("OrderStatusPlugin", [KernelFunctionFactory.CreateFromMethod(SKCheckOrderStatus)]);
var returnAgent = GetSKAgent(
instructions: "You are a customer support agent that handles order returns.",
name: "OrderReturnAgent",
description: "Handle order return requests.");
returnAgent.Kernel.Plugins.AddFromFunctions("OrderReturnPlugin", [KernelFunctionFactory.CreateFromMethod(SKProcessReturn)]);
var refundAgent = GetSKAgent(
instructions: "You are a customer support agent that handles order refunds.",
name: "OrderRefundAgent",
description: "Handle order refund requests.");
refundAgent.Kernel.Plugins.AddFromFunctions("OrderRefundPlugin", [KernelFunctionFactory.CreateFromMethod(SKProcessRefund)]);
Queue<string> queries = new(Queries);
// Create orchestration with handoffs
HandoffOrchestration orchestration =
new(OrchestrationHandoffs
.StartWith(triageAgent)
.Add(triageAgent, statusAgent, returnAgent, refundAgent)
.Add(statusAgent, triageAgent, "Transfer to this agent if the issue is not status related")
.Add(returnAgent, triageAgent, "Transfer to this agent if the issue is not return related")
.Add(refundAgent, triageAgent, "Transfer to this agent if the issue is not refund related"),
triageAgent,
statusAgent,
returnAgent,
refundAgent)
{
InteractiveCallback = () =>
{
string input = queries.Count > 0 ? queries.Dequeue() : "exit";
Console.WriteLine($"\nUser: {input}");
return ValueTask.FromResult(new ChatMessageContent(AuthorRole.User, input));
},
StreamingResponseCallback = StreamingResultCallback,
};
InProcessRuntime runtime = new();
await runtime.StartAsync();
// Run the orchestration
OrchestrationResult<string> result = await orchestration.InvokeAsync(
"I am a customer that needs help with my two orders",
runtime);
string text = await result.GetValueAsync();
Console.WriteLine($"\nFinal Result: {text}");
await runtime.RunUntilIdleAsync();
}
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
ChatCompletionAgent GetSKAgent(string instructions, string name, string description)
{
var kernel = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(deploymentName, endpoint, new AzureCliCredential()).Build();
return new ChatCompletionAgent()
{
Kernel = kernel,
Instructions = instructions,
Description = description,
Name = name
};
}
ValueTask StreamingResultCallback(StreamingChatMessageContent streamedResponse, bool isFinal)
{
if (newAgentTurn)
{
Console.Write($"\n{streamedResponse.AuthorName}: ");
newAgentTurn = false;
}
Console.Write(streamedResponse.Content);
if (streamedResponse.Items.OfType<StreamingFunctionCallUpdateContent>().FirstOrDefault()
is StreamingFunctionCallUpdateContent call)
{
if (call.CallId is not null && previousFunctionCallId != call.CallId)
{
Console.Write($"\nCalling function '{call.Name}' with arguments: ");
previousFunctionCallId = call.CallId;
}
if (!string.IsNullOrEmpty(call.Arguments))
{
Console.Write($"{call.Arguments}");
}
}
if (isFinal)
{
newAgentTurn = true;
previousFunctionCallId = string.Empty;
Console.WriteLine();
}
return ValueTask.CompletedTask;
}
# endregion
# region AFHandoffAgentWorkflow
[Description("Get the order status for a given order ID.")]
static string AFCheckOrderStatus([Description("The order ID to check the status for.")] string orderId)
=> $"Order {orderId} is shipped and will arrive in 2-3 days.";
[Description("Process a return for a given order ID.")]
static string AFProcessReturn(
[Description("The order ID to process the return for.")] string orderId,
[Description("The reason for the return.")] string reason)
=> $"Return for order {orderId} has been processed successfully for the following reason: {reason}.";
[Description("Process a refund for a given order ID.")]
static string AFProcessRefund([Description("The order ID to process the refund for.")] string orderId)
=> $"Refund for order {orderId} has been processed successfully.";
async Task AFHandoffAgentWorkflow()
{
// Create agents
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName).AsIChatClient();
ChatClientAgent triageAgent = new(client,
instructions: "A customer support agent that triages issues.",
name: "TriageAgent",
description: "Handle customer requests.");
ChatClientAgent statusAgent = new(client,
name: "OrderStatusAgent",
instructions: "Handle order status requests.",
description: "A customer support agent that checks order status.",
tools: [AIFunctionFactory.Create(AFCheckOrderStatus)]);
ChatClientAgent returnAgent = new(client,
name: "OrderReturnAgent",
instructions: "Handle order return requests.",
description: "A customer support agent that handles order returns.",
tools: [AIFunctionFactory.Create(AFProcessReturn)]);
ChatClientAgent refundAgent = new(client,
name: "OrderRefundAgent",
instructions: "Handle order refund requests.",
description: "A customer support agent that handles order refund.",
tools: [AIFunctionFactory.Create(AFProcessRefund)]);
// Create workflow with handoffs
var handoffAgentWorkflow = AgentWorkflowBuilder.CreateHandoffBuilderWith(triageAgent)
.WithHandoffs(triageAgent, [statusAgent, returnAgent, refundAgent])
.WithHandoff(statusAgent, triageAgent, "Transfer to this agent if the issue is not status related")
.WithHandoff(returnAgent, triageAgent, "Transfer to this agent if the issue is not return related")
.WithHandoff(refundAgent, triageAgent, "Transfer to this agent if the issue is not refund related")
.Build();
// Run the workflow
List<ChatMessage> messages = [];
foreach (var query in Queries)
{
Console.WriteLine($"User: {query}");
messages.Add(new(ChatRole.User, query));
await using var run = await InProcessExecution.StreamAsync(handoffAgentWorkflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
string? lastExecutorId = null;
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentRunUpdateEvent e)
{
if (string.IsNullOrEmpty(e.Update.Text) && e.Update.Contents.Count == 0)
{
continue;
}
if (e.ExecutorId != lastExecutorId)
{
lastExecutorId = e.ExecutorId;
Console.WriteLine();
Console.Write($"{e.Update.AuthorName}: ");
}
Console.Write(e.Update.Text);
if (e.Update.Contents.OfType<Microsoft.Extensions.AI.FunctionCallContent>().FirstOrDefault()
is Microsoft.Extensions.AI.FunctionCallContent call)
{
Console.WriteLine();
Console.WriteLine($"Calling function '{call.Name}' with arguments: {JsonSerializer.Serialize(call.Arguments)}");
}
}
else if (evt is WorkflowOutputEvent output)
{
Console.WriteLine("\n");
messages.AddRange(output.As<List<ChatMessage>>()!);
}
}
}
}
# endregion
@@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1812;RCS1102</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
</ItemGroup>
</Project>
@@ -1,77 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
var azureEndpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(
deploymentName,
name: "GenerateStory",
instructions: "You are good at telling jokes.");
AzureAIAgent agent = new(definition, azureAgentClient);
var thread = new AzureAIAgentThread(azureAgentClient);
AzureAIAgentInvokeOptions options = new() { MaxPromptTokens = 1000 };
var result = await agent.InvokeAsync(userInput, thread, options).FirstAsync();
Console.WriteLine(result.Message);
Console.WriteLine("---");
await foreach (StreamingChatMessageContent update in agent.InvokeStreamingAsync(userInput, thread))
{
Console.Write(update);
}
// Clean up
await thread.DeleteAsync();
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var azureAgentClient = new PersistentAgentsClient(azureEndpoint, new AzureCliCredential());
var agent = await azureAgentClient.CreateAIAgentAsync(
deploymentName,
name: "GenerateStory",
instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatThread.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
</ItemGroup>
</Project>
@@ -1,86 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
var azureEndpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
Console.WriteLine($"User Input: {userInput}");
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(deploymentName, instructions: "You are a helpful assistant");
AzureAIAgent agent = new(definition, azureAgentClient)
{
Kernel = Kernel.CreateBuilder().Build(),
Name = "Host",
Instructions = "You are a helpful assistant",
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
};
var thread = new AzureAIAgentThread(azureAgentClient);
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
Console.WriteLine("---");
await foreach (ChatMessageContent update in agent.InvokeAsync(userInput, thread))
{
Console.Write(update);
}
// Clean up
await thread.DeleteAsync();
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var azureAgentClient = new PersistentAgentsClient(azureEndpoint, new AzureCliCredential());
var agent = await azureAgentClient.CreateAIAgentAsync(deploymentName, instructions: "Answer questions about the menu");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { Tools = [AIFunctionFactory.Create(GetWeather)] });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatThread.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
</ItemGroup>
</Project>
@@ -1,99 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
var azureEndpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential()));
serviceCollection.AddTransient<AzureAIAgent>((sp) =>
{
var azureAgentClient = sp.GetRequiredService<PersistentAgentsClient>();
Console.Write("Creating agent in the cloud...");
PersistentAgent definition = azureAgentClient.Administration
.CreateAgent(deploymentName,
name: "GenerateStory",
instructions: "You are good at telling jokes.");
Console.Write("Done\n");
return new(definition, azureAgentClient);
});
serviceCollection.AddKernel();
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AzureAIAgent>();
var thread = new AzureAIAgentThread(agent.Client);
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
Console.WriteLine("---");
await foreach (ChatMessageContent update in agent.InvokeAsync(userInput, thread))
{
Console.Write(update);
}
// Clean up
await thread.DeleteAsync();
await agent.Client.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new PersistentAgentsClient(azureEndpoint, new AzureCliCredential()));
serviceCollection.AddTransient<AIAgent>((sp) =>
{
var azureAgentClient = sp.GetRequiredService<PersistentAgentsClient>();
return azureAgentClient.CreateAIAgent(
deploymentName,
name: "GenerateStory",
instructions: "You are good at telling jokes.");
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var thread = agent.GetNewThread();
var result = await agent.RunAsync(userInput, thread);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread))
{
Console.Write(update);
}
// Clean up
var azureAgentClient = serviceProvider.GetRequiredService<PersistentAgentsClient>();
if (thread is ChatClientAgentThread chatThread)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatThread.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
</ItemGroup>
</Project>
@@ -1,123 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.AzureAI;
var azureEndpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Create a python code file using the code interpreter tool with a code ready to determine the values in the Fibonacci sequence that are less then the value of 101";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(deploymentName, tools: [new CodeInterpreterToolDefinition()]);
AzureAIAgent agent = new(definition, azureAgentClient);
var thread = new AzureAIAgentThread(azureAgentClient);
// SK Azure AI Agent provides the code interpreter content and the assistant message as different contents in the call iteration.
await foreach (var content in agent.InvokeAsync(userInput, thread))
{
if (!string.IsNullOrWhiteSpace(content.Message.Content))
{
bool isCode = content.Message.Metadata?.ContainsKey(AzureAIAgent.CodeInterpreterMetadataKey) ?? false;
Console.WriteLine($"\n# {content.Message.Role}{(isCode ? "\n# Generated Code:\n" : ":")}{content.Message.Content}");
}
// Check for the citations
foreach (var item in content.Message.Items)
{
// Process each item in the message
if (item is AnnotationContent annotation)
{
if (annotation.Kind != AnnotationKind.UrlCitation)
{
Console.WriteLine($" [{item.GetType().Name}] {annotation.Label}: File #{annotation.ReferenceId}");
}
}
else if (item is FileReferenceContent fileReference)
{
Console.WriteLine($" [{item.GetType().Name}] File #{fileReference.FileId}");
}
}
}
// Clean up
await thread.DeleteAsync();
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var azureAgentClient = new PersistentAgentsClient(azureEndpoint, new AzureCliCredential());
var agent = await azureAgentClient.CreateAIAgentAsync(deploymentName, tools: [new CodeInterpreterToolDefinition()]);
var thread = agent.GetNewThread();
var result = await agent.RunAsync(userInput, thread);
Console.WriteLine(result);
// Extracts via breaking glass the code generated by code interpreter tool
var chatResponse = result.RawRepresentation as ChatResponse;
StringBuilder generatedCode = new();
foreach (object? updateRawRepresentation in chatResponse?.RawRepresentation as IEnumerable<object?> ?? [])
{
// To capture the code interpreter input we need to break glass all the updates raw representations, to check for the RunStepDetailsUpdate type and
// get the CodeInterpreterInput property which contains the generated code.
// Note: Similar logic would needed for each individual update if used in the agent.RunStreamingAsync streaming API to aggregate or yield the generated code.
if (updateRawRepresentation is RunStepDetailsUpdate update && update.CodeInterpreterInput is not null)
{
generatedCode.Append(update.CodeInterpreterInput);
}
}
if (!string.IsNullOrEmpty(generatedCode.ToString()))
{
Console.WriteLine($"\n# {chatResponse?.Messages[0].Role}:Generated Code:\n{generatedCode}");
}
// Update the citations
foreach (var textContent in result.Messages[0].Contents.OfType<Microsoft.Extensions.AI.TextContent>())
{
foreach (var annotation in textContent.Annotations ?? [])
{
if (annotation is CitationAnnotation citation)
{
if (citation.Url is null)
{
Console.WriteLine($" [{citation.GetType().Name}] {citation.Snippet}: File #{citation.FileId}");
}
foreach (var region in citation.AnnotatedRegions ?? [])
{
if (region is TextSpanAnnotatedRegion textSpanRegion)
{
Console.WriteLine($"\n[TextSpan Region] {textSpanRegion.StartIndex}-{textSpanRegion.EndIndex}");
}
}
}
}
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatThread.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,67 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
var agent = new ChatCompletionAgent()
{
Kernel = builder.Build(),
Name = "Joker",
Instructions = "You are good at telling jokes.",
};
var thread = new ChatHistoryAgentThread();
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new AgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
Console.WriteLine($"User Input: {userInput}");
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
await SKAgent();
await AFAgent();
async Task SKAgent()
{
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
ChatCompletionAgent agent = new()
{
Instructions = "You are a helpful assistant",
Kernel = builder.Build(),
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
};
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
Console.WriteLine("\n=== SK Agent Response ===\n");
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgent()
{
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine("\n=== AF Agent Response ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,55 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddKernel().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
serviceCollection.AddTransient((sp) => new ChatCompletionAgent()
{
Kernel = sp.GetRequiredService<Kernel>(),
Name = "Joker",
Instructions = "You are good at telling jokes."
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<ChatCompletionAgent>();
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new AzureOpenAIClient(new(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,81 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var _ = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
var assistantsClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient();
// Define the assistant
Assistant assistant = await assistantsClient.CreateAssistantAsync(deploymentName, name: "Joker", instructions: "You are good at telling jokes.");
// Create the agent
OpenAIAssistantAgent agent = new(assistant, assistantsClient);
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new OpenAIAssistantAgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var assistantClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient();
var agent = await assistantClient.CreateAIAgentAsync(deploymentName, name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,98 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var builder = Kernel.CreateBuilder();
var assistantsClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient();
Assistant assistant = await assistantsClient.CreateAssistantAsync(deploymentName,
instructions: "You are a helpful assistant");
OpenAIAssistantAgent agent = new(assistant, assistantsClient)
{
Kernel = builder.Build(),
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings()
{
MaxTokens = 1000,
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
}),
};
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
await foreach (var result in agent.InvokeAsync(userInput, thread))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var assistantClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient();
var agent = await assistantClient.CreateAIAgentAsync(deploymentName,
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,98 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient());
serviceCollection.AddKernel().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
serviceCollection.AddTransient((sp) =>
{
var assistantsClient = sp.GetRequiredService<AssistantClient>();
Assistant assistant = assistantsClient.CreateAssistant(deploymentName, new() { Name = "Joker", Instructions = "You are good at telling jokes." });
return new OpenAIAssistantAgent(assistant, assistantsClient);
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<OpenAIAssistantAgent>();
// Create a thread for the agent conversation.
var assistantsClient = serviceProvider.GetRequiredService<AssistantClient>();
var thread = new OpenAIAssistantAgentThread(assistantsClient);
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new OpenAIAssistantAgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient());
serviceCollection.AddTransient((sp) =>
{
var assistantClient = sp.GetRequiredService<AssistantClient>();
return assistantClient.CreateAIAgent(deploymentName, name: "Joker", instructions: "You are good at telling jokes.");
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
var assistantClient = serviceProvider.GetRequiredService<AssistantClient>();
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,127 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Create a python code file using the code interpreter tool with a code ready to determine the values in the Fibonacci sequence that are less then the value of 101";
var assistantsClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetAssistantClient();
Console.WriteLine($"User Input: {userInput}");
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
var _ = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
// Define the assistant
Assistant assistant = await assistantsClient.CreateAssistantAsync(deploymentName, enableCodeInterpreter: true);
// Create the agent
OpenAIAssistantAgent agent = new(assistant, assistantsClient);
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
// Respond to user input
await foreach (var content in agent.InvokeAsync(userInput, thread))
{
if (!string.IsNullOrWhiteSpace(content.Message.Content))
{
bool isCode = content.Message.Metadata?.ContainsKey(OpenAIAssistantAgent.CodeInterpreterMetadataKey) ?? false;
Console.WriteLine($"\n# {content.Message.Role}{(isCode ? "\n# Generated Code:\n" : ":")}{content.Message.Content}");
}
// Check for the citations
foreach (var item in content.Message.Items)
{
// Process each item in the message
if (item is AnnotationContent annotation)
{
if (annotation.Kind != AnnotationKind.UrlCitation)
{
Console.WriteLine($" [{item.GetType().Name}] {annotation.Label}: File #{annotation.ReferenceId}");
}
}
else if (item is FileReferenceContent fileReference)
{
Console.WriteLine($" [{item.GetType().Name}] File #{fileReference.FileId}");
}
}
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = await assistantsClient.CreateAIAgentAsync(deploymentName, tools: [new HostedCodeInterpreterTool()]);
var thread = agent.GetNewThread();
var result = await agent.RunAsync(userInput, thread);
Console.WriteLine(result);
// Extracts via breaking glass the code generated by code interpreter tool
var chatResponse = result.RawRepresentation as ChatResponse;
StringBuilder generatedCode = new();
foreach (object? updateRawRepresentation in chatResponse?.RawRepresentation as IEnumerable<object?> ?? [])
{
if (updateRawRepresentation is RunStepDetailsUpdate update && update.CodeInterpreterInput is not null)
{
generatedCode.Append(update.CodeInterpreterInput);
}
}
if (!string.IsNullOrEmpty(generatedCode.ToString()))
{
Console.WriteLine($"\n# {chatResponse?.Messages[0].Role}:Generated Code:\n{generatedCode}");
}
// Check for the citations
foreach (var textContent in result.Messages[0].Contents.OfType<Microsoft.Extensions.AI.TextContent>())
{
foreach (var annotation in textContent.Annotations ?? [])
{
if (annotation is CitationAnnotation citation)
{
if (citation.Url is null)
{
Console.WriteLine($" [{citation.GetType().Name}] {citation.Snippet}: File #{citation.FileId}");
}
foreach (var region in citation.AnnotatedRegions ?? [])
{
if (region is TextSpanAnnotatedRegion textSpanRegion)
{
Console.WriteLine($"\n[TextSpan Region] {textSpanRegion.StartIndex}-{textSpanRegion.EndIndex}");
}
}
}
}
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantsClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,67 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
};
var agentOptions = new OpenAIResponseAgentInvokeOptions() { ResponseCreationOptions = new() { MaxOutputTokenCount = 1000 } };
Microsoft.SemanticKernel.Agents.AgentThread? thread = null;
await foreach (var item in agent.InvokeAsync(userInput, thread, agentOptions))
{
thread = item.Thread;
Console.WriteLine(item.Message);
}
Console.WriteLine("---");
await foreach (var item in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
thread = item.Thread;
Console.Write(item.Message);
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 8000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,165 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.ChatCompletion;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "o4-mini";
var userInput =
"""
Instructions:
- Given the React component below, think about it and change it so that nonfiction books have red
text.
- Return only the code in your reply
- Do not include any additional formatting, such as markdown code blocks
- For formatting, use four space tabs, and do not allow any lines of code to
exceed 80 columns
const books = [
{ title: 'Dune', category: 'fiction', id: 1 },
{ title: 'Frankenstein', category: 'fiction', id: 2 },
{ title: 'Moneyball', category: 'nonfiction', id: 3 },
];
export default function BookList() {
const listItems = books.map(book =>
<li>
{book.title}
</li>
);
return (
<ul>{listItems}</ul>
);
}
""";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Thinker",
Instructions = "You are good at thinking hard before answering.",
StoreEnabled = true
};
var agentOptions = new OpenAIResponseAgentInvokeOptions()
{
ResponseCreationOptions = new()
{
MaxOutputTokenCount = 8000,
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
}
};
Microsoft.SemanticKernel.Agents.AgentThread? thread = null;
await foreach (var item in agent.InvokeAsync(userInput, thread, agentOptions))
{
thread = item.Thread;
foreach (var content in item.Message.Items)
{
if (content is ReasoningContent thinking)
{
Console.Write($"Thinking: \n{thinking}\n---\n");
}
else if (content is Microsoft.SemanticKernel.TextContent text)
{
Console.Write($"Assistant: {text}");
}
}
Console.WriteLine(item.Message);
}
Console.WriteLine("---");
var userMessage = new ChatMessageContent(AuthorRole.User, userInput);
await foreach (var item in agent.InvokeStreamingAsync(userMessage, thread, agentOptions))
{
thread = item.Thread;
foreach (var content in item.Message.Items)
{
// Currently SK Agent doesn't output thinking in streaming mode.
// SK Issue: https://github.com/microsoft/semantic-kernel/issues/13046
// OpenAI SDK Issue: https://github.com/openai/openai-dotnet/issues/643
if (content is StreamingReasoningContent thinking)
{
Console.WriteLine($"Thinking: [{thinking}]");
continue;
}
if (content is StreamingTextContent text)
{
Console.WriteLine($"Response: [{text}]");
}
}
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(name: "Thinker", instructions: "You are good at thinking hard before answering.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
}
});
var result = await agent.RunAsync(userInput, thread, agentOptions);
// Retrieve the thinking as a full text block requires flattening multiple TextReasoningContents from multiple messages content lists.
string assistantThinking = string.Join("\n", result.Messages
.SelectMany(m => m.Contents)
.OfType<TextReasoningContent>()
.Select(trc => trc.Text));
var assistantText = result.Text;
Console.WriteLine($"Thinking: \n{assistantThinking}\n---\n");
Console.WriteLine($"Assistant: \n{assistantText}\n---\n");
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
var thinkingContents = update.Contents
.OfType<TextReasoningContent>()
.Select(trc => trc.Text)
.ToList();
if (thinkingContents.Count != 0)
{
Console.WriteLine($"Thinking: [{string.Join("\n", thinkingContents)}]");
continue;
}
Console.WriteLine($"Response: [{update.Text}]");
}
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
Console.WriteLine($"User Input: {userInput}");
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
OpenAIResponseAgent agent = new(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName));
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
Console.WriteLine("\n=== SK Agent Response ===\n");
await foreach (ChatMessageContent responseItem in agent.InvokeAsync(userInput))
{
if (!string.IsNullOrWhiteSpace(responseItem.Content))
{
Console.WriteLine(responseItem);
}
}
}
async Task AFAgentAsync()
{
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine("\n=== AF Agent Response ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,54 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName))
{
Name = "Joker",
Instructions = "You are good at telling jokes."
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<Microsoft.SemanticKernel.Agents.Agent>();
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,65 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
var agent = new ChatCompletionAgent()
{
Kernel = builder.Build(),
Name = "Joker",
Instructions = "You are good at telling jokes.",
};
var thread = new ChatHistoryAgentThread();
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new AgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetChatClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,53 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
Console.WriteLine($"User Input: {userInput}");
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
ChatCompletionAgent agent = new()
{
Instructions = "You are a helpful assistant",
Kernel = builder.Build(),
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
};
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
Console.WriteLine("\n=== SK Agent Response ===\n");
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgentAsync()
{
var agent = new OpenAIClient(apiKey).GetChatClient(model).CreateAIAgent(
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine("\n=== AF Agent Response ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,53 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddKernel().AddOpenAIChatClient(model, apiKey);
serviceCollection.AddTransient((sp) => new ChatCompletionAgent()
{
Kernel = sp.GetRequiredService<Kernel>(),
Name = "Joker",
Instructions = "You are good at telling jokes."
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<ChatCompletionAgent>();
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new OpenAIClient(apiKey)
.GetChatClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,77 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var assistantsClient = new AssistantClient(apiKey);
// Define the assistant
Assistant assistant = await assistantsClient.CreateAssistantAsync(model, name: "Joker", instructions: "You are good at telling jokes.");
// Create the agent
OpenAIAssistantAgent agent = new(assistant, assistantsClient);
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new OpenAIAssistantAgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var assistantClient = new AssistantClient(apiKey);
var agent = await assistantClient.CreateAIAgentAsync(model, name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,96 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var builder = Kernel.CreateBuilder();
var assistantsClient = new AssistantClient(apiKey);
Assistant assistant = await assistantsClient.CreateAssistantAsync(model,
instructions: "You are a helpful assistant");
OpenAIAssistantAgent agent = new(assistant, assistantsClient)
{
Kernel = builder.Build(),
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings()
{
MaxTokens = 1000,
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
}),
};
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
await foreach (var result in agent.InvokeAsync(userInput, thread))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var assistantClient = new AssistantClient(apiKey);
var agent = await assistantClient.CreateAIAgentAsync(model,
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,96 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new AssistantClient(apiKey));
serviceCollection.AddKernel().AddOpenAIChatClient(model, apiKey);
serviceCollection.AddTransient((sp) =>
{
var assistantsClient = sp.GetRequiredService<AssistantClient>();
Assistant assistant = assistantsClient.CreateAssistant(model, new() { Name = "Joker", Instructions = "You are good at telling jokes." });
return new OpenAIAssistantAgent(assistant, assistantsClient);
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<OpenAIAssistantAgent>();
// Create a thread for the agent conversation.
var assistantsClient = serviceProvider.GetRequiredService<AssistantClient>();
var thread = new OpenAIAssistantAgentThread(assistantsClient);
var settings = new OpenAIPromptExecutionSettings() { MaxTokens = 1000 };
var agentOptions = new OpenAIAssistantAgentInvokeOptions() { KernelArguments = new(settings) };
await foreach (var result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
Console.WriteLine("---");
await foreach (var update in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update.Message);
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new AssistantClient(apiKey));
serviceCollection.AddTransient((sp) =>
{
var assistantClient = sp.GetRequiredService<AssistantClient>();
return assistantClient.CreateAIAgent(model, name: "Joker", instructions: "You are good at telling jokes.");
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
// Clean up
var assistantClient = serviceProvider.GetRequiredService<AssistantClient>();
if (thread is ChatClientAgentThread chatThread)
{
await assistantClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,124 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
using OpenAI.Assistants;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Create a python code file using the code interpreter tool with a code ready to determine the values in the Fibonacci sequence that are less then the value of 101";
var assistantsClient = new AssistantClient(apiKey);
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
// Define the assistant
Assistant assistant = await assistantsClient.CreateAssistantAsync(model, enableCodeInterpreter: true);
// Create the agent
OpenAIAssistantAgent agent = new(assistant, assistantsClient);
// Create a thread for the agent conversation.
var thread = new OpenAIAssistantAgentThread(assistantsClient);
// Respond to user input
await foreach (var content in agent.InvokeAsync(userInput, thread))
{
if (!string.IsNullOrWhiteSpace(content.Message.Content))
{
bool isCode = content.Message.Metadata?.ContainsKey(OpenAIAssistantAgent.CodeInterpreterMetadataKey) ?? false;
Console.WriteLine($"\n# {content.Message.Role}{(isCode ? "\n# Generated Code:\n" : ":")}{content.Message.Content}");
}
// Check for the citations
foreach (var item in content.Message.Items)
{
// Process each item in the message
if (item is AnnotationContent annotation)
{
if (annotation.Kind != AnnotationKind.UrlCitation)
{
Console.WriteLine($" [{item.GetType().Name}] {annotation.Label}: File #{annotation.ReferenceId}");
}
}
else if (item is FileReferenceContent fileReference)
{
Console.WriteLine($" [{item.GetType().Name}] File #{fileReference.FileId}");
}
}
}
// Clean up
await thread.DeleteAsync();
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = await assistantsClient.CreateAIAgentAsync(model, tools: [new HostedCodeInterpreterTool()]);
var thread = agent.GetNewThread();
var result = await agent.RunAsync(userInput, thread);
Console.WriteLine(result);
// Extracts via breaking glass the code generated by code interpreter tool
var chatResponse = result.RawRepresentation as ChatResponse;
StringBuilder generatedCode = new();
foreach (object? updateRawRepresentation in chatResponse?.RawRepresentation as IEnumerable<object?> ?? [])
{
if (updateRawRepresentation is RunStepDetailsUpdate update && update.CodeInterpreterInput is not null)
{
generatedCode.Append(update.CodeInterpreterInput);
}
}
if (!string.IsNullOrEmpty(generatedCode.ToString()))
{
Console.WriteLine($"\n# {chatResponse?.Messages[0].Role}:Generated Code:\n{generatedCode}");
}
// Check for the citations
foreach (var textContent in result.Messages[0].Contents.OfType<Microsoft.Extensions.AI.TextContent>())
{
foreach (var annotation in textContent.Annotations ?? [])
{
if (annotation is CitationAnnotation citation)
{
if (citation.Url is null)
{
Console.WriteLine($" [{citation.GetType().Name}] {citation.Snippet}: File #{citation.FileId}");
}
foreach (var region in citation.AnnotatedRegions ?? [])
{
if (region is TextSpanAnnotatedRegion textSpanRegion)
{
Console.WriteLine($"\n[TextSpan Region] {textSpanRegion.StartIndex}-{textSpanRegion.EndIndex}");
}
}
}
}
}
// Clean up
if (thread is ChatClientAgentThread chatThread)
{
await assistantsClient.DeleteThreadAsync(chatThread.ConversationId);
}
await assistantsClient.DeleteAssistantAsync(agent.Id);
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,64 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
};
var agentOptions = new OpenAIResponseAgentInvokeOptions() { ResponseCreationOptions = new() { MaxOutputTokenCount = 1000 } };
Microsoft.SemanticKernel.Agents.AgentThread? thread = null;
await foreach (var item in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(item.Message);
thread = item.Thread;
}
Console.WriteLine("---");
await foreach (var item in agent.InvokeStreamingAsync(userInput, thread, agentOptions))
{
// Thread need to be updated for subsequent calls
thread = item.Thread;
Console.Write(item.Message);
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 8000 });
var result = await agent.RunAsync(userInput, thread, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
Console.Write(update);
}
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,162 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.ChatCompletion;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "o4-mini";
var userInput =
"""
Instructions:
- Given the React component below, think about it and change it so that nonfiction books have red
text.
- Return only the code in your reply
- Do not include any additional formatting, such as markdown code blocks
- For formatting, use four space tabs, and do not allow any lines of code to
exceed 80 columns
const books = [
{ title: 'Dune', category: 'fiction', id: 1 },
{ title: 'Frankenstein', category: 'fiction', id: 2 },
{ title: 'Moneyball', category: 'nonfiction', id: 3 },
];
export default function BookList() {
const listItems = books.map(book =>
<li>
{book.title}
</li>
);
return (
<ul>{listItems}</ul>
);
}
""";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Thinker",
Instructions = "You are good at thinking hard before answering.",
StoreEnabled = true
};
var agentOptions = new OpenAIResponseAgentInvokeOptions()
{
ResponseCreationOptions = new()
{
MaxOutputTokenCount = 8000,
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
}
};
Microsoft.SemanticKernel.Agents.AgentThread? thread = null;
await foreach (var item in agent.InvokeAsync(userInput, thread, agentOptions))
{
thread = item.Thread;
foreach (var content in item.Message.Items)
{
if (content is ReasoningContent thinking)
{
Console.Write($"Thinking: \n{thinking}\n---\n");
}
else if (content is Microsoft.SemanticKernel.TextContent text)
{
Console.Write($"Assistant: {text}");
}
}
Console.WriteLine(item.Message);
}
Console.WriteLine("---");
var userMessage = new ChatMessageContent(AuthorRole.User, userInput);
thread = null;
await foreach (var item in agent.InvokeStreamingAsync(userMessage, thread, agentOptions))
{
thread = item.Thread;
foreach (var content in item.Message.Items)
{
// Currently SK Agent doesn't output thinking in streaming mode.
// SK Issue: https://github.com/microsoft/semantic-kernel/issues/13046
// OpenAI SDK Issue: https://github.com/openai/openai-dotnet/issues/643
if (content is StreamingReasoningContent thinking)
{
Console.WriteLine($"Thinking: [{thinking}]");
continue;
}
if (content is StreamingTextContent text)
{
Console.WriteLine($"Response: [{text}]");
}
}
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model)
.CreateAIAgent(name: "Thinker", instructions: "You are at thinking hard before answering.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
}
});
var result = await agent.RunAsync(userInput, thread, agentOptions);
// Retrieve the thinking as a full text block requires flattening multiple TextReasoningContents from multiple messages content lists.
string assistantThinking = string.Join("\n", result.Messages
.SelectMany(m => m.Contents)
.OfType<TextReasoningContent>()
.Select(trc => trc.Text));
var assistantText = result.Text;
Console.WriteLine($"Thinking: \n{assistantThinking}\n---\n");
Console.WriteLine($"Assistant: \n{assistantText}\n---\n");
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, thread, agentOptions))
{
var thinkingContents = update.Contents
.OfType<TextReasoningContent>()
.Select(trc => trc.Text)
.ToList();
if (thinkingContents.Count != 0)
{
Console.WriteLine($"Thinking: [{string.Join("\n", thinkingContents)}]");
continue;
}
Console.WriteLine($"Response: [{update.Text}]");
}
}
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,53 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "What is the weather like in Amsterdam?";
Console.WriteLine($"User Input: {userInput}");
[KernelFunction]
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
OpenAIResponseAgent agent = new(new OpenAIClient(apiKey).GetOpenAIResponseClient(model));
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
Console.WriteLine("\n=== SK Agent Response ===\n");
await foreach (ChatMessageContent responseItem in agent.InvokeAsync(userInput))
{
if (!string.IsNullOrWhiteSpace(responseItem.Content))
{
Console.WriteLine(responseItem);
}
}
}
async Task AFAgentAsync()
{
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model).CreateAIAgent(
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine("\n=== AF Agent Response ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.OpenAI" VersionOverride="1.*-*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,51 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY is not set.");
var model = System.Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o";
var userInput = "Tell me a joke about a pirate.";
Console.WriteLine($"User Input: {userInput}");
await SKAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetOpenAIResponseClient(model))
{
Name = "Joker",
Instructions = "You are good at telling jokes."
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<Microsoft.SemanticKernel.Agents.Agent>();
var result = await agent.InvokeAsync(userInput).FirstAsync();
Console.WriteLine(result.Message);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new OpenAIClient(apiKey)
.GetOpenAIResponseClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
@@ -1,20 +0,0 @@
# Semantic Kernel Migration Playground
This is a playground folder with different **Semantic Kernel** projects that can be used to test automatic AI migration to the new **Agent Framework (AF)**.
## Prompting
Open your IDE Agentic extension and create a new chat providing the following prompt:
```
I need to convert code from Semantic Kernel to the Agent Framework.
Please use the migration guide provided in the #SemanticKernelToAgentFramework.md as a reference.
The current solution is using central package manager, when referencing the projects in the csproj don't provide the versions.
Check external references provided by the migration guide if needed.
You don't need to look for the Central Package Management file, just focus on the project file and the code files.
When you need help or don't know how to proceed, please ask.
```
@@ -1,89 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.AzureAI;
using Microsoft.SemanticKernel.ChatCompletion;
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var client = new PersistentAgentsClient(Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT"), new AzureCliCredential());
// Define the agent
PersistentAgent definition = await client.Administration.CreateAgentAsync(
Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME"),
instructions: "You are a coding assistant that always generates code using the code interpreter tool.",
tools: [new CodeInterpreterToolDefinition()]);
AzureAIAgent agent = new(definition, client);
// Create a thread for the agent conversation.
AgentThread thread = new AzureAIAgentThread(client);
try
{
await InvokeAgentAsync("Create a python file where it determines the values in the Fibonacci sequence that that are less then the value of 101.");
}
finally
{
await thread.DeleteAsync();
await client.Administration.DeleteAgentAsync(agent.Id);
}
async Task InvokeAgentAsync(string input)
{
ChatMessageContent message = new(AuthorRole.User, input);
WriteAgentChatMessage(message);
await foreach (ChatMessageContent response in agent.InvokeAsync(message, thread))
{
WriteAgentChatMessage(response);
}
}
void WriteAgentChatMessage(ChatMessageContent message)
{
// Include ChatMessageContent.AuthorName in output, if present.
string authorExpression = message.Role == AuthorRole.User ? string.Empty : FormatAuthor();
// Include TextContent (via ChatMessageContent.Content), if present.
string contentExpression = string.IsNullOrWhiteSpace(message.Content) ? string.Empty : message.Content;
bool isCode = message.Metadata?.ContainsKey(AzureAIAgent.CodeInterpreterMetadataKey) ?? false;
string codeMarker = isCode ? "\n [CODE]\n" : " ";
Console.WriteLine($"\n# {message.Role}{authorExpression}:{codeMarker}{contentExpression}");
// Provide visibility for inner content (that isn't TextContent).
foreach (KernelContent item in message.Items)
{
if (item is AnnotationContent annotation)
{
if (annotation.Kind == AnnotationKind.UrlCitation)
{
Console.WriteLine($" [{item.GetType().Name}] {annotation.Label}: {annotation.ReferenceId} - {annotation.Title}");
}
else
{
Console.WriteLine($" [{item.GetType().Name}] {annotation.Label}: File #{annotation.ReferenceId}");
}
}
else if (item is ActionContent action)
{
Console.WriteLine($" [{item.GetType().Name}] {action.Text}");
}
else if (item is ReasoningContent reasoning)
{
Console.WriteLine($" [{item.GetType().Name}] {reasoning.Text ?? "Thinking..."}");
}
else if (item is FileReferenceContent fileReference)
{
Console.WriteLine($" [{item.GetType().Name}] File #{fileReference.FileId}");
}
}
if ((message.Metadata?.TryGetValue("Usage", out object? usage) ?? false) && usage is RunStepCompletionUsage agentUsage)
{
Console.WriteLine($" [Usage] Tokens: {agentUsage.TotalTokens}, Input: {agentUsage.PromptTokens}, Output: {agentUsage.CompletionTokens}");
}
string FormatAuthor() => message.AuthorName is not null ? $" - {message.AuthorName ?? " * "}" : string.Empty;
}
@@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents.Persistent" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Configuration" />
<PackageReference Include="Microsoft.SemanticKernel" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" VersionOverride="1.*" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" VersionOverride="1.*-*" />
</ItemGroup>
<ItemGroup>
<Content Include="../../../../../.github/upgrades/prompts/*" />
</ItemGroup>
</Project>
@@ -1,393 +0,0 @@
# Semantic Kernel to Agent Framework Migration Guide
## What's Changed?
- **Namespace Updates**: From `Microsoft.SemanticKernel.Agents` to `Microsoft.Agents.AI`
- **Agent Creation**: Single fluent API calls vs multi-step builder patterns
- **Thread Management**: Built-in thread management vs manual thread creation
- **Tool Registration**: Direct function registration vs plugin wrapper systems
- **Dependency Injection**: Simplified service registration patterns
- **Invocation Patterns**: Streamlined options and result handling
## Benefits of Migration
- **Simplified API**: Reduced complexity and boilerplate code
- **Better Performance**: Optimized object creation and memory usage
- **Unified Interface**: Consistent patterns across different AI providers
- **Enhanced Developer Experience**: More intuitive and discoverable APIs
## Key Changes
### 1. Namespace Updates
#### Semantic Kernel
```csharp
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
```
#### Agent Framework
Agent Framework namespaces are under `Microsoft.Agents.AI`.
Agent Framework uses the core AI message and content types from `Microsoft.Extensions.AI` for communication between components.
```csharp
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;
```
### 2. Agent Creation Simplification
#### Semantic Kernel
Every agent in Semantic Kernel depends on a `Kernel` instance and will have
an empty `Kernel` if not provided.
```csharp
Kernel kernel = Kernel
.AddOpenAIChatClient(modelId, apiKey)
.Build();
ChatCompletionAgent agent = new() { Instructions = ParrotInstructions, Kernel = kernel };
```
Azure AI Foundry requires an agent resource to be created in the cloud before creating a local agent class that uses it.
```csharp
PersistentAgentsClient azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(
deploymentName,
instructions: ParrotInstructions);
AzureAIAgent agent = new(definition, azureAgentClient);
```
#### Agent Framework
Agent creation in Agent Framework is made simpler with extensions provided by all main providers.
```csharp
AIAgent openAIAgent = chatClient.CreateAIAgent(instructions: ParrotInstructions);
AIAgent azureFoundryAgent = await persistentAgentsClient.CreateAIAgentAsync(instructions: ParrotInstructions);
AIAgent openAIAssistantAgent = await assistantClient.CreateAIAgentAsync(instructions: ParrotInstructions);
```
Additionally for hosted agent providers you can also use the `GetAIAgent` to retrieve an agent from an existing hosted agent.
```csharp
AIAgent azureFoundryAgent = await persistentAgentsClient.GetAIAgentAsync(agentId);
```
### 3. Agent Thread Creation
#### Semantic Kernel
The caller has to know the thread type and create it manually.
```csharp
// Create a thread for the agent conversation.
AgentThread thread = new OpenAIAssistantAgentThread(this.AssistantClient);
AgentThread thread = new AzureAIAgentThread(this.Client);
AgentThread thread = new OpenAIResponseAgentThread(this.Client);
```
#### Agent Framework
The agent is responsible for creating the thread.
```csharp
// New
AgentThread thread = agent.GetNewThread();
```
### 4. Hosted Agent Thread Cleanup
This case applies exclusively to a few AI providers that still provide hosted threads.
#### Semantic Kernel
Threads have a `self` deletion method
i.e: OpenAI Assistants Provider
```csharp
await thread.DeleteAsync();
```
#### Agent Framework
> [!NOTE]
> OpenAI Responses introduced a new conversation model that simplifies how conversations are handled. This simplifies hosted thread management compared to the now deprecated OpenAI Assistants model. For more information see the [OpenAI Assistants migration guide](https://platform.openai.com/docs/assistants/migration).
Agent Framework doesn't have a thread deletion API in the `AgentThread` type as not all providers support hosted threads or thread deletion and this will become more common as more providers shift to responses based architectures.
If you require thread deletion and the provider allows this, the caller **should** keep track of the created threads and delete them later when necessary via the provider's sdk.
i.e: OpenAI Assistants Provider
```csharp
await assistantClient.DeleteThreadAsync(thread.ConversationId);
```
### 5. Tool Registration
#### Semantic Kernel
In semantic kernel to expose a function as a tool you must:
1. Decorate the function with a `[KernelFunction]` attribute.
2. Have a `Plugin` class or use the `KernelPluginFactory` to wrap the function.
3. Have a `Kernel` to add your plugin to.
4. Pass the `Kernel` to the agent.
```csharp
KernelFunction function = KernelFunctionFactory.CreateFromMethod(GetWeather);
KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("KernelPluginName", [function]);
Kernel kernel = ... // Create kernel
kernel.Plugins.Add(plugin);
ChatCompletionAgent agent = new() { Kernel = kernel, ... };
```
#### Agent Framework
In agent framework in a single call you can register tools directly in the agent creation process.
```csharp
AIAgent agent = chatClient.CreateAIAgent(tools: [AIFunctionFactory.Create(GetWeather)]);
```
### 6. Agent Non-Streaming Invocation
Key differences can be seen in the method names from `Invoke` to `Run`, return types and parameters `AgentRunOptions`.
#### Semantic Kernel
The Non-Streaming uses a streaming pattern `IAsyncEnumerable<AgentResponseItem<ChatMessageContent>>` for returning multiple agent messages.
```csharp
await foreach (AgentResponseItem<ChatMessageContent> result in agent.InvokeAsync(userInput, thread, agentOptions))
{
Console.WriteLine(result.Message);
}
```
#### Agent Framework
The Non-Streaming returns a single `AgentRunResponse` with the agent response that can contain multiple messages.
The text result of the run is available in `AgentRunResponse.Text` or `AgentRunResponse.ToString()`.
All messages created as part of the response is returned in the `AgentRunResponse.Messages` list.
This may include tool call messages, function results, reasoning updates and final results.
```csharp
AgentRunResponse agentResponse = await agent.RunAsync(userInput, thread);
```
### 7. Agent Streaming Invocation
Key differences in the method names from `Invoke` to `Run`, return types and parameters `AgentRunOptions`.
#### Semantic Kernel
```csharp
await foreach (StreamingChatMessageContent update in agent.InvokeStreamingAsync(userInput, thread))
{
Console.Write(update);
}
```
#### Agent Framework
Similar streaming API pattern with the key difference being that it returns `AgentRunResponseUpdate` objects including more agent related information per update.
All updates produced by any service underlying the AIAgent is returned. The textual result of the agent is available by concatenating the `AgentRunResponse.Text` values.
```csharp
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(userInput, thread))
{
Console.Write(update); // Update is ToString() friendly
}
```
### 8. Tool Function Signatures
**Problem**: SK plugin methods need `[KernelFunction]` attributes
```csharp
public class MenuPlugin
{
[KernelFunction] // Required for SK
public static MenuItem[] GetMenu() => ...;
}
```
**Solution**: AF can use methods directly without attributes
```csharp
public class MenuTools
{
[Description("Get menu items")] // Optional description
public static MenuItem[] GetMenu() => ...;
}
```
### 9. Options Configuration
**Problem**: Complex options setup in SK
```csharp
OpenAIPromptExecutionSettings settings = new() { MaxTokens = 1000 };
AgentInvokeOptions options = new() { KernelArguments = new(settings) };
```
**Solution**: Simplified options in AF
```csharp
ChatClientAgentRunOptions options = new(new() { MaxOutputTokens = 1000 });
```
> [!IMPORTANT]
> This example shows passing implementation specific options to a `ChatClientAgent`. Not all `AIAgents` support `ChatClientAgentRunOptions`.
> `ChatClientAgent` is provided to build agents based on underlying inference services, and therefore supports inference options like `MaxOutputTokens`.
### 10. Dependency Injection
#### Semantic Kernel
A `Kernel` registration is required in the service container to be able to create an agent
as every agent abstractions needs to be initialized with a `Kernel` property.
Semantic Kernel uses the `Agent` type as the base abstraction class for agents.
```csharp
services.AddKernel().AddProvider(...);
serviceContainer.AddKeyedSingleton<SemanticKernel.Agents.Agent>(
TutorName,
(sp, key) =>
new ChatCompletionAgent()
{
// Passing the kernel is required
Kernel = sp.GetRequiredService<Kernel>(),
});
```
### 11. **Agent Type Consolidation**
#### Semantic Kernel
Semantic kernel provides specific agent classes for various services, e.g.
- `ChatCompletionAgent` for use with chat-completion-based inference services.
- `OpenAIAssistantAgent` for use with the OpenAI Assistants service.
- `AzureAIAgent` for use with the Azure AI Foundry Agents service.
#### Agent Framework
The agent framework supports all the abovementioned services via a single agent type, `ChatClientAgent`.
`ChatClientAgent` can be used to build agents using any underlying service that provides an SDK implementing the `Microsoft.Extensions.AI.IChatClient` interface.
#### Agent Framework
The Agent framework provides the `AIAgent` type as the base abstraction class.
```csharp
services.AddKeyedSingleton<AIAgent>(() => client.CreateAIAgent(...));
```
## Migration Samples
This folder contains **separate console application projects** demonstrating how to transition from **Semantic Kernel (SK)** to the new **Agent Framework (AF)**.
Each project shows side-by-side comparisons of equivalent functionality in both frameworks and can be run independently.
Each sample code contains the following:
1. **SK Agent** (Semantic Kernel before)
2. **AF Agent** (Agent Framework after)
### Running the samples from Visual Studio
Open the solution in Visual Studio and set the desired sample project as the startup project. Then, run the project using the built-in debugger or by pressing `F5`.
You will be prompted for any required environment variables if they are not already set.
### Prerequisites
Before you begin, ensure you have the following:
- [.NET 8.0 SDK or later](https://dotnet.microsoft.com/download)
- For Azure AI Foundry samples: Azure OpenAI service endpoint and deployment configured
- For OpenAI samples: OpenAI API key
- For OpenAI Assistants samples: OpenAI API key with Assistant API access
### Environment Variables
Set the appropriate environment variables based on the sample type you want to run:
**For Azure AI Foundry projects:**
```powershell
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT = "https://<your-project>-resource.services.ai.azure.com/api/projects/<your-project>"
```
**For OpenAI and OpenAI Assistants projects:**
```powershell
$env:OPENAI_API_KEY = "sk-..."
```
**For Azure OpenAI and Azure OpenAI Assistants projects:**
```powershell
$env:AZURE_OPENAI_ENDPOINT = "https://<your-project>.cognitiveservices.azure.com/"
$env:AZURE_OPENAI_DEPLOYMENT_NAME = "gpt-4o" # Optional, defaults to gpt-4o
```
**Optional debug mode:**
```powershell
$env:AF_SHOW_ALL_DEMO_SETTING_VALUES = "Y"
```
If environment variables are not set, the demos will prompt you to enter values interactively.
### Samples
The migration samples are organized into three categories, each demonstrating different AI service integrations:
|Category|Description|
|---|---|
|[AzureAIFoundry](./AzureAIFoundry/)|Azure OpenAI service integration samples|
|[AzureOpenAI](./AzureOpenAI/)|Direct Azure OpenAI API integration samples|
|[AzureOpenAIAssistants](./AzureOpenAIAssistants/)|Azure OpenAI Assistants API integration samples|
|[AzureOpenAIResponses](./AzureOpenAIResponses/)|Azure OpenAI Responses API integration samples|
|[OpenAI](./OpenAI/)|Direct OpenAI API integration samples|
|[OpenAIAssistants](./OpenAIAssistants/)|OpenAI Assistants API integration samples|
|[OpenAIResponses](./OpenAIResponses/)|OpenAI Responses API integration samples|
## Running the samples from the console
To run any migration sample, navigate to the desired sample directory:
```powershell
# Azure AI Foundry Examples
cd "AzureAIFoundry\Step01_Basics"
dotnet run
# Azure OpenAI Examples
cd "AzureOpenAI\Step01_Basics"
dotnet run
# OpenAI Examples
cd "OpenAI\Step01_Basics"
dotnet run
# OpenAI Assistants Examples
cd "OpenAIAssistants\Step01_Basics"
dotnet run
# OpenAI Responses Examples
cd "OpenAIResponses\Step01_Basics"
# Azure OpenAI Examples
cd "AzureOpenAI\Step01_Basics"
dotnet run
# Azure OpenAI Assistants Examples
cd "AzureOpenAIAssistants\Step01_Basics"
dotnet run
```