Files
semantic-kernel/dotnet/samples/AgentFrameworkMigration/AzureOpenAIResponses/Step03_ToolCall/Program.cs
T
Roger BarretoandCopilot fdc6e68f58 .Net: Semantic Kernel -> Agent Framework - Migration/Samples Update (AF 1.0 Compatible) (#13852)
## Description

Updates the SK → Agent Framework migration document, samples, and bridge
code from AF preview (`1.0.0-preview.251009.1`) to GA (`1.0.0`).

### Breaking changes addressed

| Preview API | AF 1.0 GA | Scope |
|---|---|---|
| `AgentThread` | `AgentSession` | Core type rename |
| `GetNewThread()` | `CreateSessionAsync()` | Now async |
| `AgentRunResponse` | `AgentResponse` | Return type rename |
| `AgentRunResponseUpdate` | `AgentResponseUpdate` | Streaming type
rename |
| `CreateAIAgent()` | `AsAIAgent()` | Extension method rename |
| `AssistantClient.CreateAIAgentAsync()` | **Removed** | Redirect to
Responses API |
| `PersistentAgentsClient` | **Obsolete** | Use `AIProjectClient` via
`Microsoft.Agents.AI.Foundry` |
| `Microsoft.Agents.AI.AzureAI` | `Microsoft.Agents.AI.Foundry` |
Package rename |
| `InProcessExecution.StreamAsync` | `RunStreamingAsync` | Workflow API
|
| `AgentRunUpdateEvent` | `AgentResponseUpdateEvent` | Workflow event |
| `AIAgent.Id` (virtual) | `IdCore` (protected virtual) | Override
pattern |

### Additional discoveries
- `using OpenAI.Chat;` required for `ChatClient.AsAIAgent()` extension
to resolve
- `using OpenAI.Responses;` required for `ResponsesClient.AsAIAgent()`
extension to resolve

### What changed

**Package versions** (`dotnet/Directory.Packages.props`)
- AF packages updated to `1.0.0`
- `Microsoft.Agents.AI.AzureAI` → `Microsoft.Agents.AI.Foundry`

**Bridge code** (`dotnet/src/Agents/Abstractions/AIAgent/`)
- `SemanticKernelAIAgent.cs`: New `Core` method overrides
(`CreateSessionCoreAsync`, `RunCoreAsync`, etc.)
- `SemanticKernelAIAgentThread` → `SemanticKernelAIAgentSession`
(extends `AgentSession`)

**31 migration samples** (all compile ✅)
- OpenAI/AzureOpenAI: `AsAIAgent`, `CreateSessionAsync`, `using
OpenAI.Chat;`
- Assistants (8): AF sections rewritten to Responses API
- Responses (8): Direct `ResponsesClient.AsAIAgent()`
- Foundry (4): `AIProjectClient.AsAIAgent()` via
`Microsoft.Agents.AI.Foundry`
- Orchestrations (3): `RunStreamingAsync`, `AgentResponseUpdateEvent`

**Migration document**
(`.github/upgrades/prompts/SemanticKernelToAgentFramework.md`)
- All AF preview API references updated to 1.0 GA patterns

**Unit/integration tests** (~15 files)
- Mechanical renames for `AgentSession`, `AgentResponse`,
`CreateSessionAsync`

### Validation

8 standalone console programs were created and executed against AF 1.0.0
NuGet packages with real API keys, validating all migration patterns
end-to-end:
1. OpenAI Basics (ChatClient → AsAIAgent, CreateSessionAsync,
Run/RunStreaming)
2. OpenAI ToolCall (AIFunctionFactory.Create, tool invocation)
3. OpenAI DI (ServiceProvider registration)
4. OpenAI Responses (ResponsesClient.AsAIAgent)
5. Azure AI Foundry (AIProjectClient.AsAIAgent)
6. Workflows Handoff (HandoffWorkflowBuilder,
InProcessExecution.RunStreamingAsync)
7. Session Lifecycle (Create, Serialize, Deserialize, multi-turn)
8. Assistants Migration Path (Responses API as replacement)

---------

Co-authored-by: Copilot <[email protected]>
2026-05-12 14:49:47 +00:00

77 lines
3.0 KiB
C#

// 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);
}