Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 45 additions & 25 deletions .github/upgrades/prompts/SemanticKernelToAgentFramework.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;
// Provider-specific namespaces (add only if needed):
using OpenAI; // For OpenAI provider
using Azure.AI.OpenAI; // For Azure OpenAI provider
using OpenAI; // For OpenAI and Azure OpenAI providers
using System.ClientModel.Primitives; // For BearerTokenPolicy with Azure OpenAI
using Azure.AI.Agents.Persistent; // For Microsoft Foundry provider
using Azure.Identity; // For Azure authentication
```
Expand Down Expand Up @@ -545,9 +545,13 @@ AIAgent agent = new OpenAIClient(apiKey)

**Azure OpenAI:**
```csharp
AIAgent agent = new AzureOpenAIClient(endpoint, credential)
Uri openAIEndpoint = new($"{endpoint.ToString().TrimEnd('/')}/openai/v1/");

AIAgent agent = new OpenAIClient(
new BearerTokenPolicy(credential, "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = openAIEndpoint })
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: instructions);
.AsAIAgent(instructions: instructions);
```

**Microsoft Foundry (New):**
Expand All @@ -571,9 +575,13 @@ AIAgent agent = new OpenAIClient(apiKey)

**Azure OpenAI Responses:** *(Recommended for Azure OpenAI)*
```csharp
AIAgent agent = new AzureOpenAIClient(endpoint, credential)
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(instructions: instructions);
Uri openAIEndpoint = new($"{endpoint.ToString().TrimEnd('/')}/openai/v1/");

AIAgent agent = new OpenAIClient(
new BearerTokenPolicy(credential, "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = openAIEndpoint })
.GetResponsesClient()
.AsAIAgent(model: deploymentName, instructions: instructions);
```

**A2A:**
Expand Down Expand Up @@ -979,11 +987,11 @@ AgentThread thread = agent.GetNewThread();
**Add Agent Framework Packages:**
```xml
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="OpenAI" />
<PackageReference Include="Azure.Identity" />
```

**Note**: If not using `AzureCliCredential`, you can use `ApiKeyCredential` instead without the `Azure.Identity` package.
**Note**: If not using Entra ID (`AzureCliCredential` / `DefaultAzureCredential`), you can use `ApiKeyCredential` instead without the `Azure.Identity` package.
</configuration_changes>

**Before (Semantic Kernel):**
Expand All @@ -1005,13 +1013,18 @@ ChatCompletionAgent agent = new()

**After (Agent Framework):**
```csharp
using Microsoft.Agents.AI;
using Azure.AI.OpenAI;
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
using OpenAI.Chat;

AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
var openAIEndpoint = $"{endpoint.TrimEnd('/')}/openai/v1/";
AIAgent agent = new OpenAIClient(
new BearerTokenPolicy(new AzureCliCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = new Uri(openAIEndpoint) })
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant");
.AsAIAgent(instructions: "You are a helpful assistant");
```

### 3. OpenAI Assistants Migration
Expand Down Expand Up @@ -1273,14 +1286,15 @@ var result = await agent.RunAsync(userInput, thread);
**Add Agent Framework Packages:**
```xml
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="OpenAI" />
<PackageReference Include="Azure.Identity" />
```
</configuration_changes>

<api_changes>
**Replace this Semantic Kernel pattern:**

Azure OpenAI Responses uses `AzureOpenAIClient` instead of `OpenAIClient`. The thread management is done manually where the thread needs to be passed to the `InvokeAsync` method and updated with the `item.Thread` from the response.
Azure OpenAI Responses uses the OpenAI SDK with a custom endpoint and Entra token policy. The thread management is done manually where the thread needs to be passed to the `InvokeAsync` method and updated with the `item.Thread` from the response.

```csharp
using Microsoft.SemanticKernel.Agents.OpenAI;
Expand Down Expand Up @@ -1311,21 +1325,28 @@ await foreach (AgentResponseItem<ChatMessageContent> responseItem in responseIte
Agent Framework automatically manages the thread, so there's no need to manually update it.

```csharp
using Microsoft.Agents.AI.OpenAI;
using Azure.AI.OpenAI;

AIAgent agent = new AzureOpenAIClient(endpoint, new AzureCliCredential())
.GetOpenAIResponseClient(modelId)
.CreateAIAgent(
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
using OpenAI.Responses;

Uri openAIEndpoint = new($"{endpoint.ToString().TrimEnd('/')}/openai/v1/");
AIAgent agent = new OpenAIClient(
new BearerTokenPolicy(new AzureCliCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = openAIEndpoint })
.GetResponsesClient()
.AsAIAgent(
model: modelId,
name: "ResponseAgent",
instructions: "Answer all queries in English and French.",
tools: [/* AITools */]);

AgentThread thread = agent.GetNewThread();
AgentSession session = await agent.CreateSessionAsync();

var result = await agent.RunAsync(userInput, thread);
var result = await agent.RunAsync(userInput, session);

// The thread will be automatically updated with the new response id from this point
// The session is updated with the new response id.
```
</api_changes>

Expand Down Expand Up @@ -1608,4 +1629,3 @@ var filteredAgent = originalAgent
.Build();
```


3 changes: 1 addition & 2 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<!-- Enable central package management -->
<!-- https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management -->
Expand Down Expand Up @@ -29,7 +29,6 @@
<PackageVersion Include="Azure.Search.Documents" Version="12.0.0" />
<PackageVersion Include="Azure.AI.Projects" Version="2.1.0-beta.4" />
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.2.0-beta.10" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.9.0-beta.1" />
<PackageVersion Include="Azure.Core" Version="1.62.0" />
<PackageVersion Include="Azure.Identity" Version="1.21.0" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.29.1" />
Expand Down
14 changes: 9 additions & 5 deletions dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@
### Basic Agent - .NET

```c#
using Azure.AI.OpenAI;
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
using OpenAI.Responses;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
// Use the Azure OpenAI v1 route with the OpenAI SDK (resource root + /openai/v1).
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!; // e.g. https://YOUR.openai.azure.com/openai/v1/
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME")!;

var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetResponsesClient(deploymentName)
.AsAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
var agent = new OpenAIClient(
new BearerTokenPolicy(new AzureCliCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = new Uri(endpoint) })
.GetResponsesClient()
.AsAIAgent(model: deploymentName, name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");

Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Framework."));
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

<ItemGroup>
<PackageReference Include="A2A" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -10,7 +10,6 @@

<ItemGroup>
<PackageReference Include="A2A" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) Microsoft. All rights reserved.

using Azure.AI.OpenAI;
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using OpenAI;
using OpenAI.Chat;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
Expand All @@ -16,7 +17,8 @@

WebApplication app = builder.Build();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
Uri endpoint = AzureOpenAIEndpoint.From(
builder.Configuration["AZURE_OPENAI_ENDPOINT"])
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
Expand All @@ -25,9 +27,9 @@
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
ChatClient chatClient = new OpenAIClient(
new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = endpoint })
.GetChatClient(deploymentName);

AIAgent agent = chatClient.AsAIAgent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -8,7 +8,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Copyright (c) Microsoft. All rights reserved.

using System.ClientModel.Primitives;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Options;
using OpenAI;
using OpenAI.Chat;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
Expand All @@ -22,7 +23,8 @@

WebApplication app = builder.Build();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
Uri endpoint = AzureOpenAIEndpoint.From(
builder.Configuration["AZURE_OPENAI_ENDPOINT"])
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
Expand Down Expand Up @@ -82,9 +84,9 @@ static RestaurantSearchResponse SearchRestaurants(
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
ChatClient chatClient = new OpenAIClient(
new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = endpoint })
.GetChatClient(deploymentName);

ChatClientAgent agent = chatClient.AsAIAgent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -8,7 +8,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c) Microsoft. All rights reserved.

using Azure.AI.OpenAI;
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using OpenAI;
using OpenAI.Chat;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
Expand All @@ -16,7 +17,8 @@

WebApplication app = builder.Build();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
Uri endpoint = AzureOpenAIEndpoint.From(
builder.Configuration["AZURE_OPENAI_ENDPOINT"])
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
Expand All @@ -25,9 +27,9 @@
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
ChatClient chatClient = new OpenAIClient(
new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = endpoint })
.GetChatClient(deploymentName);

AIAgent agent = chatClient.AsAIAgent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -8,7 +8,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.

using System.ClientModel.Primitives;
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Chat;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
Expand All @@ -18,7 +19,8 @@

WebApplication app = builder.Build();

string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
Uri endpoint = AzureOpenAIEndpoint.From(
builder.Configuration["AZURE_OPENAI_ENDPOINT"])
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
Expand All @@ -41,9 +43,9 @@ static string ApproveExpenseReport(string expenseReportId)
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
ChatClient openAIChatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
ChatClient openAIChatClient = new OpenAIClient(
new BearerTokenPolicy(new DefaultAzureCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions { Endpoint = endpoint })
.GetChatClient(deploymentName);

ChatClientAgent baseAgent = openAIChatClient.AsAIAgent(
Expand Down
Loading
Loading