Skip to content

Commit 1949193

Browse files
authored
.NET: Update the migration guidelines with latest changes (#2703)
* Update the migration guidelines with latest changes * Update code interpreter sample
1 parent bc8dbe4 commit 1949193

File tree

1 file changed

+58
-86
lines changed

1 file changed

+58
-86
lines changed

.github/upgrades/prompts/SemanticKernelToAgentFramework.md

Lines changed: 58 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ Replace these Semantic Kernel agent classes with their Agent Framework equivalen
142142
|----------------------|----------------------------|-------------------|
143143
| `IChatCompletionService` | `IChatClient` | Convert to `IChatClient` using `chatService.AsChatClient()` extensions |
144144
| `ChatCompletionAgent` | `ChatClientAgent` | Remove `Kernel` parameter, add `IChatClient` parameter |
145-
| `OpenAIAssistantAgent` | `AIAgent` (via extension) | **New**: `OpenAIClient.GetAssistantClient().CreateAIAgent()` <br> **Existing**: `OpenAIClient.GetAssistantClient().GetAIAgent(assistantId)` |
145+
| `OpenAIAssistantAgent` | `AIAgent` (via extension) | ⚠️ **Deprecated** - Use Responses API instead. <br> **New**: `OpenAIClient.GetAssistantClient().CreateAIAgent()` <br> **Existing**: `OpenAIClient.GetAssistantClient().GetAIAgent(assistantId)` |
146146
| `AzureAIAgent` | `AIAgent` (via extension) | **New**: `PersistentAgentsClient.CreateAIAgent()` <br> **Existing**: `PersistentAgentsClient.GetAIAgent(agentId)` |
147-
| `OpenAIResponseAgent` | `AIAgent` (via extension) | Replace with `OpenAIClient.GetOpenAIResponseClient().CreateAIAgent()` |
147+
| `OpenAIResponseAgent` | `AIAgent` (via extension) | Replace with `OpenAIClient.GetOpenAIResponseClient(modelId).CreateAIAgent()` |
148148
| `A2AAgent` | `AIAgent` (via extension) | Replace with `A2ACardResolver.GetAIAgentAsync()` |
149149
| `BedrockAgent` | Not supported | Custom implementation required |
150150

@@ -529,14 +529,14 @@ AIAgent agent = new OpenAIClient(apiKey)
529529
.CreateAIAgent(instructions: instructions);
530530
```
531531

532-
**OpenAI Assistants (New):**
532+
**OpenAI Assistants (New):** ⚠️ *Deprecated - Use Responses API instead*
533533
```csharp
534534
AIAgent agent = new OpenAIClient(apiKey)
535535
.GetAssistantClient()
536536
.CreateAIAgent(modelId, instructions: instructions);
537537
```
538538

539-
**OpenAI Assistants (Existing):**
539+
**OpenAI Assistants (Existing):** ⚠️ *Deprecated - Use Responses API instead*
540540
```csharp
541541
AIAgent agent = new OpenAIClient(apiKey)
542542
.GetAssistantClient()
@@ -562,6 +562,20 @@ AIAgent agent = await new PersistentAgentsClient(endpoint, credential)
562562
.GetAIAgentAsync(agentId);
563563
```
564564

565+
**OpenAI Responses:** *(Recommended for OpenAI)*
566+
```csharp
567+
AIAgent agent = new OpenAIClient(apiKey)
568+
.GetOpenAIResponseClient(modelId)
569+
.CreateAIAgent(instructions: instructions);
570+
```
571+
572+
**Azure OpenAI Responses:** *(Recommended for Azure OpenAI)*
573+
```csharp
574+
AIAgent agent = new AzureOpenAIClient(endpoint, credential)
575+
.GetOpenAIResponseClient(deploymentName)
576+
.CreateAIAgent(instructions: instructions);
577+
```
578+
565579
**A2A:**
566580
```csharp
567581
A2ACardResolver resolver = new(new Uri(agentHost));
@@ -762,35 +776,57 @@ await foreach (var content in agent.InvokeAsync(userInput, thread))
762776

763777
**With this Agent Framework CodeInterpreter pattern:**
764778
```csharp
779+
using System.Text;
780+
using Microsoft.Agents.AI;
781+
using Microsoft.Extensions.AI;
782+
765783
var result = await agent.RunAsync(userInput, thread);
766784
Console.WriteLine(result);
767785

768-
// Extract chat response MEAI type via first level breaking glass
769-
var chatResponse = result.RawRepresentation as ChatResponse;
786+
// Get the CodeInterpreterToolCallContent (code input)
787+
CodeInterpreterToolCallContent? toolCallContent = result.Messages
788+
.SelectMany(m => m.Contents)
789+
.OfType<CodeInterpreterToolCallContent>()
790+
.FirstOrDefault();
791+
792+
if (toolCallContent?.Inputs is not null)
793+
{
794+
DataContent? codeInput = toolCallContent.Inputs.OfType<DataContent>().FirstOrDefault();
795+
if (codeInput?.HasTopLevelMediaType("text") ?? false)
796+
{
797+
Console.WriteLine($"Code Input: {Encoding.UTF8.GetString(codeInput.Data.ToArray())}");
798+
}
799+
}
770800

771-
// Extract underlying SDK updates via second level breaking glass
772-
var underlyingStreamingUpdates = chatResponse?.RawRepresentation as IEnumerable<object?> ?? [];
801+
// Get the CodeInterpreterToolResultContent (code output)
802+
CodeInterpreterToolResultContent? toolResultContent = result.Messages
803+
.SelectMany(m => m.Contents)
804+
.OfType<CodeInterpreterToolResultContent>()
805+
.FirstOrDefault();
773806

774-
StringBuilder generatedCode = new();
775-
foreach (object? underlyingUpdate in underlyingStreamingUpdates ?? [])
807+
if (toolResultContent?.Outputs is not null)
776808
{
777-
if (underlyingUpdate is RunStepDetailsUpdate stepDetailsUpdate && stepDetailsUpdate.CodeInterpreterInput is not null)
809+
TextContent? resultOutput = toolResultContent.Outputs.OfType<TextContent>().FirstOrDefault();
810+
if (resultOutput is not null)
778811
{
779-
generatedCode.Append(stepDetailsUpdate.CodeInterpreterInput);
812+
Console.WriteLine($"Code Tool Result: {resultOutput.Text}");
780813
}
781814
}
782815

783-
if (!string.IsNullOrEmpty(generatedCode.ToString()))
816+
// Getting any annotations generated by the tool
817+
foreach (AIAnnotation annotation in result.Messages
818+
.SelectMany(m => m.Contents)
819+
.SelectMany(c => c.Annotations ?? []))
784820
{
785-
Console.WriteLine($"\n# {chatResponse?.Messages[0].Role}:Generated Code:\n{generatedCode}");
821+
Console.WriteLine($"Annotation: {annotation}");
786822
}
787823
```
788824

789825
**Functional differences:**
790-
1. Code interpreter output is separate from text content, not a metadata property
791-
2. Access code via `RunStepDetailsUpdate.CodeInterpreterInput` instead of metadata
792-
3. Use breaking glass pattern to access underlying SDK objects
793-
4. Process text content and code interpreter output independently
826+
1. Code interpreter content is now available via MEAI abstractions - no breaking glass required
827+
2. Use `CodeInterpreterToolCallContent` to access code inputs (the generated code)
828+
3. Use `CodeInterpreterToolResultContent` to access code outputs (execution results)
829+
4. Annotations are accessible via `AIAnnotation` on content items
794830
</behavioral_changes>
795831

796832
#### Provider-Specific Options Configuration
@@ -980,6 +1016,8 @@ AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential(
9801016

9811017
### 3. OpenAI Assistants Migration
9821018

1019+
> ⚠️ **DEPRECATION WARNING**: The OpenAI Assistants API has been deprecated. The Agent Framework extension methods for Assistants are marked as `[Obsolete]`. **Please use the Responses API instead** (see Section 6: OpenAI Responses Migration).
1020+
9831021
<configuration_changes>
9841022
**Remove Semantic Kernel Packages:**
9851023
```xml
@@ -1291,52 +1329,7 @@ var result = await agent.RunAsync(userInput, thread);
12911329
```
12921330
</api_changes>
12931331

1294-
### 8. A2A Migration
1295-
1296-
<configuration_changes>
1297-
**Remove Semantic Kernel Packages:**
1298-
```xml
1299-
<PackageReference Include="Microsoft.SemanticKernel.Agents.A2A" />
1300-
```
1301-
1302-
**Add Agent Framework Packages:**
1303-
```xml
1304-
<PackageReference Include="Microsoft.Agents.AI.A2A" />
1305-
```
1306-
</configuration_changes>
1307-
1308-
<api_changes>
1309-
**Replace this Semantic Kernel pattern:**
1310-
```csharp
1311-
using A2A;
1312-
using Microsoft.SemanticKernel;
1313-
using Microsoft.SemanticKernel.Agents;
1314-
using Microsoft.SemanticKernel.Agents.A2A;
1315-
1316-
using var httpClient = CreateHttpClient();
1317-
var client = new A2AClient(agentUrl, httpClient);
1318-
var cardResolver = new A2ACardResolver(url, httpClient);
1319-
var agentCard = await cardResolver.GetAgentCardAsync();
1320-
Console.WriteLine(JsonSerializer.Serialize(agentCard, s_jsonSerializerOptions));
1321-
var agent = new A2AAgent(client, agentCard);
1322-
```
1323-
1324-
**With this Agent Framework pattern:**
1325-
```csharp
1326-
using System;
1327-
using A2A;
1328-
using Microsoft.Agents.AI;
1329-
using Microsoft.Agents.AI.A2A;
1330-
1331-
// Initialize an A2ACardResolver to get an A2A agent card.
1332-
A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));
1333-
1334-
// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
1335-
AIAgent agent = await agentCardResolver.GetAIAgentAsync();
1336-
```
1337-
</api_changes>
1338-
1339-
### 9. Unsupported Providers (Require Custom Implementation)
1332+
### 8. Unsupported Providers (Require Custom Implementation)
13401333

13411334
<behavioral_changes>
13421335
#### BedrockAgent Migration
@@ -1507,7 +1500,7 @@ Console.WriteLine(result);
15071500
```
15081501
</behavioral_changes>
15091502

1510-
### 10. Function Invocation Filtering
1503+
### 9. Function Invocation Filtering
15111504

15121505
**Invocation Context**
15131506

@@ -1615,25 +1608,4 @@ var filteredAgent = originalAgent
16151608
.Build();
16161609
```
16171610

1618-
### 11. Function Invocation Contexts
16191611

1620-
**Invocation Context**
1621-
1622-
Semantic Kernel's `IAutoFunctionInvocationFilter` provides a `AutoFunctionInvocationContext` where Agent Framework provides `FunctionInvocationContext`
1623-
1624-
The property mapping guide from a `AutoFunctionInvocationContext` to a `FunctionInvocationContext` is as follows:
1625-
1626-
| Semantic Kernel | Agent Framework |
1627-
| --- | --- |
1628-
| RequestSequenceIndex | Iteration |
1629-
| FunctionSequenceIndex | FunctionCallIndex |
1630-
| ToolCallId | CallContent.CallId |
1631-
| ChatMessageContent | Messages[0] |
1632-
| ExecutionSettings | Options |
1633-
| ChatHistory | Messages |
1634-
| Function | Function |
1635-
| Kernel | N/A |
1636-
| Result | Use `return` from the delegate |
1637-
| Terminate | Terminate |
1638-
| CancellationToken | provided via argument to middleware delegate |
1639-
| Arguments | Arguments |

0 commit comments

Comments
 (0)