chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA1812;CA2007;RCS1102;VSTHRD111;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Agents.AI.Workflows" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Orchestration\Agents.Orchestration.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Runtime\InProcess\Runtime.InProcess.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,109 @@
// 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.RunStreamingAsync(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 AgentResponseUpdateEvent 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
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA1812;CA2007;RCS1102;VSTHRD111;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Agents.AI.Workflows" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Orchestration\Agents.Orchestration.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Runtime\InProcess\Runtime.InProcess.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,112 @@
// 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.RunStreamingAsync(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 AgentResponseUpdateEvent 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
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA1812;CA2007;RCS1102;VSTHRD111;VSTHRD200</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Agents.AI.Workflows" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Orchestration\Agents.Orchestration.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Runtime\InProcess\Runtime.InProcess.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,249 @@
// Copyright (c) Microsoft. All rights reserved.
#pragma warning disable MAAIW001 // Experimental: HandoffWorkflowBuilder
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.RunStreamingAsync(handoffAgentWorkflow, messages);
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
string? lastExecutorId = null;
await foreach (WorkflowEvent evt in run.WatchStreamAsync().ConfigureAwait(false))
{
if (evt is AgentResponseUpdateEvent 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
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA1812;CA2007;RCS1102;VSTHRD111</NoWarn>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.Foundry" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,114 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents.Persistent;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
#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 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 SKAgent_As_AFAgentAsync();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF 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.");
#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.
AzureAIAgent skAgent = new(definition, azureAgentClient);
var agent = skAgent.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
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 ChatClientAgentSession chatSession)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatSession.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
// AF 1.0: Use AIProjectClient.AsAIAgent() from Microsoft.Agents.AI.Foundry
var projectClient = new AIProjectClient(new Uri(azureEndpoint), new AzureCliCredential());
var agent = projectClient.AsAIAgent(
deploymentName,
instructions: "You are good at telling jokes.",
name: "GenerateStory");
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, session, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, session, agentOptions))
{
Console.Write(update);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.Foundry" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,131 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Azure.AI.Agents.Persistent;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
#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 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 SKAgent_As_AFAgentAsync();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(deploymentName, instructions: "You are a helpful assistant");
#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.
AzureAIAgent skAgent = new(definition, azureAgentClient)
{
Kernel = Kernel.CreateBuilder().Build(),
Name = "Host",
Instructions = "You are a helpful assistant",
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
};
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
skAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
var agent = skAgent.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
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 ChatClientAgentSession chatSession)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatSession.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AIProjectClient(new Uri(azureEndpoint), new AzureCliCredential())
.AsAIAgent(model: deploymentName,
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 1000 });
var result = await agent.RunAsync(userInput, session, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, session, agentOptions))
{
Console.Write(update);
}
// No cleanup needed - non-hosted path doesn't create server-side resources.
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.Foundry" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,144 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents.Persistent;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.AzureAI;
#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 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 SKAgent_As_AFAgentAsync();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF 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 skAgent = serviceProvider.GetRequiredService<AzureAIAgent>();
var agent = skAgent.AsAIAgent();
var thread = await agent.CreateSessionAsync();
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 ChatClientAgentSession chatSession)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatSession.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton((sp) => new AIProjectClient(new Uri(azureEndpoint), new AzureCliCredential()));
serviceCollection.AddTransient<AIAgent>((sp) =>
{
var client = sp.GetRequiredService<AIProjectClient>();
return client.AsAIAgent(
deploymentName,
instructions: "You are good at telling jokes.",
name: "GenerateStory");
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var session = await agent.CreateSessionAsync();
var result = await agent.RunAsync(userInput, session);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, session))
{
Console.Write(update);
}
// No cleanup needed - non-hosted path doesn't create server-side resources.
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.Foundry" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,150 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text;
using Azure.AI.Agents.Persistent;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.AzureAI;
#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 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 SKAgent_As_AFAgentAsync();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var azureAgentClient = AzureAIAgent.CreateAgentsClient(azureEndpoint, new AzureCliCredential());
PersistentAgent definition = await azureAgentClient.Administration.CreateAgentAsync(deploymentName, tools: [new CodeInterpreterToolDefinition()]);
AzureAIAgent skAgent = new(definition, azureAgentClient);
var agent = skAgent.AsAIAgent();
var thread = await agent.CreateSessionAsync();
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 ChatClientAgentSession chatSession)
{
await azureAgentClient.Threads.DeleteThreadAsync(chatSession.ConversationId);
}
await azureAgentClient.Administration.DeleteAgentAsync(agent.Id);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
// Note: Code interpreter via hosted APIs requires versioned Foundry Agents.
// This sample creates a basic agent without code interpreter capabilities.
var agent = new AIProjectClient(new Uri(azureEndpoint), new AzureCliCredential())
.AsAIAgent(deploymentName, instructions: "You are a helpful assistant with code execution capabilities.");
var session = await agent.CreateSessionAsync();
var result = await agent.RunAsync(userInput, session);
Console.WriteLine(result);
// No cleanup needed - non-hosted path doesn't create server-side resources.
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,99 @@
// 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.Chat;
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 SKAgent_As_AFAgentAsync();
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);
}
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
#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 agent = new ChatCompletionAgent()
{
Kernel = builder.Build(),
Name = "Joker",
Instructions = "You are good at telling jokes.",
}.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
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);
}
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName)
.AsAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = await agent.CreateSessionAsync();
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);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,82 @@
// 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.Chat;
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 SKAgent_As_AFAgentAsync();
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);
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
#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.
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)]));
var afAgent = agent.AsAIAgent();
#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.
var result = await afAgent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgent()
{
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential()).GetChatClient(deploymentName)
.AsAIAgent(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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,82 @@
// 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.Chat;
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 SKAgent_As_AFAgentAsync();
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);
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddKernel().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential());
#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.
serviceCollection.AddTransient((sp) => new ChatCompletionAgent()
{
Kernel = sp.GetRequiredService<Kernel>(),
Name = "Joker",
Instructions = "You are good at telling jokes."
}.AsAIAgent());
#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.
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<AIAgent>((sp) => new AzureOpenAIClient(new(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.AsAIAgent(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);
}
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Functions\Functions.OpenApi\Functions.OpenApi.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="OpenAPISpec.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
@@ -0,0 +1,354 @@
{
"openapi": "3.0.1",
"info": {
"title": "Github Versions API",
"version": "1.0.0"
},
"servers": [
{
"url": "https://api.github.com"
}
],
"components": {
"schemas": {
"basic-error": {
"title": "Basic Error",
"description": "Basic Error",
"type": "object",
"properties": {
"message": {
"type": "string"
},
"documentation_url": {
"type": "string"
},
"url": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"label": {
"title": "Label",
"description": "Color-coded labels help you categorize and filter your issues (just like labels in Gmail).",
"type": "object",
"properties": {
"id": {
"description": "Unique identifier for the label.",
"type": "integer",
"format": "int64",
"example": 208045946
},
"node_id": {
"type": "string",
"example": "MDU6TGFiZWwyMDgwNDU5NDY="
},
"url": {
"description": "URL for the label",
"example": "https://api.github.com/repositories/42/labels/bug",
"type": "string",
"format": "uri"
},
"name": {
"description": "The name of the label.",
"example": "bug",
"type": "string"
},
"description": {
"description": "Optional description of the label, such as its purpose.",
"type": "string",
"example": "Something isn't working",
"nullable": true
},
"color": {
"description": "6-character hex code, without the leading #, identifying the color",
"example": "FFFFFF",
"type": "string"
},
"default": {
"description": "Whether this label comes by default in a new repository.",
"type": "boolean",
"example": true
}
},
"required": [
"id",
"node_id",
"url",
"name",
"description",
"color",
"default"
]
},
"tag": {
"title": "Tag",
"description": "Tag",
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "v0.1"
},
"commit": {
"type": "object",
"properties": {
"sha": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
}
},
"required": [
"sha",
"url"
]
},
"zipball_url": {
"type": "string",
"format": "uri",
"example": "https://github.com/octocat/Hello-World/zipball/v0.1"
},
"tarball_url": {
"type": "string",
"format": "uri",
"example": "https://github.com/octocat/Hello-World/tarball/v0.1"
},
"node_id": {
"type": "string"
}
},
"required": [
"name",
"node_id",
"commit",
"zipball_url",
"tarball_url"
]
}
},
"examples": {
"label-items": {
"value": [
{
"id": 208045946,
"node_id": "MDU6TGFiZWwyMDgwNDU5NDY=",
"url": "https://api.github.com/repos/octocat/Hello-World/labels/bug",
"name": "bug",
"description": "Something isn't working",
"color": "f29513",
"default": true
},
{
"id": 208045947,
"node_id": "MDU6TGFiZWwyMDgwNDU5NDc=",
"url": "https://api.github.com/repos/octocat/Hello-World/labels/enhancement",
"name": "enhancement",
"description": "New feature or request",
"color": "a2eeef",
"default": false
}
]
},
"tag-items": {
"value": [
{
"name": "v0.1",
"commit": {
"sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc",
"url": "https://api.github.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc"
},
"zipball_url": "https://github.com/octocat/Hello-World/zipball/v0.1",
"tarball_url": "https://github.com/octocat/Hello-World/tarball/v0.1",
"node_id": "MDQ6VXNlcjE="
}
]
}
},
"parameters": {
"owner": {
"name": "owner",
"description": "The account owner of the repository. The name is not case sensitive.",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"repo": {
"name": "repo",
"description": "The name of the repository without the `.git` extension. The name is not case sensitive.",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"per-page": {
"name": "per_page",
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"",
"in": "query",
"schema": {
"type": "integer",
"default": 30
}
},
"page": {
"name": "page",
"description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"",
"in": "query",
"schema": {
"type": "integer",
"default": 1
}
}
},
"responses": {
"not_found": {
"description": "Resource not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/basic-error"
}
}
}
}
},
"headers": {
"link": {
"example": "<https://api.github.com/resource?page=2>; rel=\"next\", <https://api.github.com/resource?page=5>; rel=\"last\"",
"schema": {
"type": "string"
}
}
}
},
"paths": {
"/repos/{owner}/{repo}/tags": {
"get": {
"summary": "List repository tags",
"description": "",
"tags": [
"repos"
],
"operationId": "repos/list-tags",
"externalDocs": {
"description": "API method documentation",
"url": "https://docs.github.com/rest/repos/repos#list-repository-tags"
},
"parameters": [
{
"$ref": "#/components/parameters/owner"
},
{
"$ref": "#/components/parameters/repo"
},
{
"$ref": "#/components/parameters/per-page"
},
{
"$ref": "#/components/parameters/page"
}
],
"responses": {
"200": {
"description": "Response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/tag"
}
},
"examples": {
"default": {
"$ref": "#/components/examples/tag-items"
}
}
}
},
"headers": {
"Link": {
"$ref": "#/components/headers/link"
}
}
}
},
"x-github": {
"githubCloudOnly": false,
"enabledForGitHubApps": true,
"category": "repos",
"subcategory": "repos"
}
}
},
"/repos/{owner}/{repo}/labels": {
"get": {
"summary": "List labels for a repository",
"description": "Lists all labels for a repository.",
"tags": [
"issues"
],
"operationId": "issues/list-labels-for-repo",
"externalDocs": {
"description": "API method documentation",
"url": "https://docs.github.com/rest/issues/labels#list-labels-for-a-repository"
},
"parameters": [
{
"$ref": "#/components/parameters/owner"
},
{
"$ref": "#/components/parameters/repo"
},
{
"$ref": "#/components/parameters/per-page"
},
{
"$ref": "#/components/parameters/page"
}
],
"responses": {
"200": {
"description": "Response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/label"
}
},
"examples": {
"default": {
"$ref": "#/components/examples/label-items"
}
}
}
},
"headers": {
"Link": {
"$ref": "#/components/headers/link"
}
}
},
"404": {
"$ref": "#/components/responses/not_found"
}
},
"x-github": {
"githubCloudOnly": false,
"enabledForGitHubApps": true,
"category": "issues",
"subcategory": "labels"
}
}
}
}
}
@@ -0,0 +1,66 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample demonstrates how to use an Agent with function tools provided via an OpenAPI spec with both Semantic Kernel and Agent Framework.
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.Plugins.OpenApi;
using OpenAI.Chat;
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";
await SKAgent();
await AFAgent();
async Task SKAgent()
{
Console.WriteLine("\n=== SK Agent ===\n");
// Create a kernel with an Azure OpenAI chat client.
var kernel = Kernel.CreateBuilder().AddAzureOpenAIChatClient(deploymentName, endpoint, new AzureCliCredential()).Build();
// Load the OpenAPI Spec from a file.
var plugin = await kernel.ImportPluginFromOpenApiAsync("github", "OpenAPISpec.json");
// Create the agent, and provide the kernel with the OpenAPI function tools to the agent.
var agent = new ChatCompletionAgent()
{
Kernel = kernel,
Instructions = "You are a helpful assistant",
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
};
// Run the agent with the OpenAPI function tools.
await foreach (var result in agent.InvokeAsync("Please list the names, colors and descriptions of all the labels available in the microsoft/agent-framework repository on github."))
{
Console.WriteLine(result.Message);
}
}
async Task AFAgent()
{
Console.WriteLine("\n=== AF Agent ===\n");
// Load the OpenAPI Spec from a file.
KernelPlugin plugin = await OpenApiKernelPluginFactory.CreateFromOpenApiAsync("github", "OpenAPISpec.json");
// Convert the Semantic Kernel plugin to Agent Framework function tools.
// This requires a dummy Kernel instance, since KernelFunctions cannot execute without one.
Kernel kernel = new();
List<AITool> tools = plugin.Select(x => x.WithKernel(kernel)).Cast<AITool>().ToList();
// Create the chat client and agent, and provide the OpenAPI function tools to the agent.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.AsAIAgent(instructions: "You are a helpful assistant", tools: tools);
// Run the agent with the OpenAPI function tools.
Console.WriteLine(await agent.RunAsync("Please list the names, colors and descriptions of all the labels available in the microsoft/agent-framework repository on github."));
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,101 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient();
OpenAIResponseAgent agent = new(responseClient, deploymentName)
{
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient();
OpenAIResponseAgent skAgent = new(responseClient, deploymentName)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
};
var agent = skAgent.AsAIAgent();
var thread = await agent.CreateSessionAsync();
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);
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient()
.AsAIAgent(model: deploymentName, name: "Joker", instructions: "You are good at telling jokes.");
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 8000 });
var result = await agent.RunAsync(userInput, session, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, session, agentOptions))
{
Console.Write(update);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,225 @@
// 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.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient();
OpenAIResponseAgent agent = new(responseClient, deploymentName)
{
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient();
#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.
OpenAIResponseAgent skAgent = new(responseClient, deploymentName)
{
Name = "Thinker",
Instructions = "You are good at thinking hard before answering.",
StoreEnabled = true
};
var agent = skAgent.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
Reasoning = new()
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
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}]");
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient()
.AsAIAgent(model: deploymentName, name: "Thinker", instructions: "You are good at thinking hard before answering.");
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
Reasoning = new()
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
var result = await agent.RunAsync(userInput, session, 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, session, 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}]");
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,76 @@
// 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.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
OpenAIResponseAgent agent = new(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient(), deploymentName)
{ StoreEnabled = true };
// 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 SKAgent_As_AFAgentAsync()
{
OpenAIResponseAgent skAgent = new(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient(), deploymentName)
{ StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
skAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
var agent = skAgent.AsAIAgent();
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgentAsync()
{
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient()
.AsAIAgent(model: deploymentName, 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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,82 @@
// 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.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
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())
.GetResponsesClient(), deploymentName)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
});
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient(), deploymentName)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var skAgent = serviceProvider.GetRequiredService<Microsoft.SemanticKernel.Agents.Agent>();
var agent = (skAgent as OpenAIResponseAgent)!.AsAIAgent();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<AIAgent>((sp) => new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient()
.AsAIAgent(model: deploymentName, 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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI;
using OpenAI.Chat;
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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
// Example of Semantic Kernel Agent code
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);
}
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
#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 agent = new ChatCompletionAgent()
{
Kernel = builder.Build(),
Name = "Joker",
Instructions = "You are good at telling jokes.",
}.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
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);
}
}
// Example of a fully migrated Agent Framework Agent code
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetChatClient(model)
.AsAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = await agent.CreateSessionAsync();
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);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,98 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
using OpenAI.Chat;
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 SKAgent_As_AFAgentAsync();
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");
await foreach (var item in agent.InvokeAsync(userInput))
{
Console.Write(item.Message);
}
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
ChatCompletionAgent skAgent = 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).
skAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
#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 agent = skAgent.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
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);
}
Console.WriteLine("\n---\n");
await foreach (var item in skAgent.InvokeAsync(userInput))
{
Console.Write(item.Message);
}
}
async Task AFAgentAsync()
{
var agent = new OpenAIClient(apiKey).GetChatClient(model).AsAIAgent(
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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using OpenAI;
using OpenAI.Chat;
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 SKAgent_As_AFAgentAsync();
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>();
await foreach (var item in agent.InvokeAsync(userInput))
{
Console.WriteLine(item.Message);
}
}
// Example of Semantic Kernel Agent code converted as an Agent Framework Agent
async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddKernel().AddOpenAIChatClient(model, apiKey);
#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.
serviceCollection.AddTransient<AIAgent>((sp) => new ChatCompletionAgent()
{
Kernel = sp.GetRequiredService<Kernel>(),
Name = "Joker",
Instructions = "You are good at telling jokes."
}.AsAIAgent());
#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.
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var agent = serviceProvider.GetRequiredService<AIAgent>();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<AIAgent>((sp) => new OpenAIClient(apiKey)
.GetChatClient(model)
.AsAIAgent(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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,98 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetResponsesClient();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetResponsesClient();
OpenAIResponseAgent skAgent = new(responseClient)
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
StoreEnabled = true
};
var agent = skAgent.AsAIAgent();
var thread = await agent.CreateSessionAsync();
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);
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetResponsesClient()
.AsAIAgent(model: model, name: "Joker", instructions: "You are good at telling jokes.");
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new() { MaxOutputTokens = 8000 });
var result = await agent.RunAsync(userInput, session, agentOptions);
Console.WriteLine(result);
Console.WriteLine("---");
await foreach (var update in agent.RunStreamingAsync(userInput, session, agentOptions))
{
Console.Write(update);
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,222 @@
// 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;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetResponsesClient();
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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetResponsesClient();
#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.
OpenAIResponseAgent skAgent = new(responseClient)
{
Name = "Thinker",
Instructions = "You are at thinking hard before answering.",
StoreEnabled = true
};
var agent = skAgent.AsAIAgent();
#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.
var thread = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
Reasoning = new()
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
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}]");
}
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetResponsesClient()
.AsAIAgent(model: model, name: "Thinker", instructions: "You are at thinking hard before answering.");
var session = await agent.CreateSessionAsync();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
Reasoning = new()
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
var result = await agent.RunAsync(userInput, session, 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, session, 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}]");
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,76 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents.OpenAI;
using OpenAI;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
await AFAgentAsync();
async Task SKAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
OpenAIResponseAgent agent = new(new OpenAIClient(apiKey).GetResponsesClient(), model) { StoreEnabled = true };
// 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 SKAgent_As_AFAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
OpenAIResponseAgent skAgent = new(new OpenAIClient(apiKey).GetResponsesClient(), model) { StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
skAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
var agent = skAgent.AsAIAgent();
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgentAsync()
{
var agent = new OpenAIClient(apiKey).GetResponsesClient().AsAIAgent(
model: model,
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);
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Abstractions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,77 @@
// 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;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#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 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 SKAgent_As_AFAgentAsync();
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).GetResponsesClient(), 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 SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetResponsesClient(), model)
{
Name = "Joker",
Instructions = "You are good at telling jokes."
});
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
var skAgent = serviceProvider.GetRequiredService<Microsoft.SemanticKernel.Agents.Agent>();
var agent = (skAgent as OpenAIResponseAgent)!.AsAIAgent();
var result = await agent.RunAsync(userInput);
Console.WriteLine(result);
}
async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new OpenAIClient(apiKey)
.GetResponsesClient()
.AsAIAgent(model: model, 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);
}
@@ -0,0 +1,20 @@
# 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.
```
@@ -0,0 +1,89 @@
// 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;
}
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CA1707;CA2007;VSTHRD111</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents.Persistent" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Configuration" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\..\..\src\SemanticKernel.MetaPackage\SemanticKernel.MetaPackage.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="../../../../../.github/upgrades/prompts/*" />
</ItemGroup>
</Project>
@@ -0,0 +1,405 @@
# 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 10.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 different categories, each demonstrating different AI service integrations and orchestration patterns:
|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|
|[AgentOrchestrations](./AgentOrchestrations/)|Agent orchestration patterns including concurrent, sequential, and handoff workflows|
## 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
# Azure OpenAI Assistants Examples
cd "AzureOpenAIAssistants\Step01_Basics"
dotnet run
# Azure OpenAI Responses Examples
cd "AzureOpenAIResponses\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"
dotnet run
# Agent Orchestrations Examples
cd "AgentOrchestrations\Step01_Concurrent"
dotnet run
cd "AgentOrchestrations\Step02_Sequential"
dotnet run
cd "AgentOrchestrations\Step03_Handoff"
dotnet run
```