From 88ea9d08c7575ce9165c4a2e4ee0086bc77567a8 Mon Sep 17 00:00:00 2001
From: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 14:29:29 +0000
Subject: [PATCH] .NET: Update to OpenAI 2.9.1, Azure.AI.OpenAI 2.9.0-beta.1,
Microsoft.Extensions.AI 10.4.0, and Azure.AI.Projects 2.0.0-beta.2 (#4613)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Initial plan
* Update code for Microsoft.Extensions.AI.Abstractions 10.4.0 breaking changes
- Rename FunctionApprovalRequestContent → ToolApprovalRequestContent
- Rename FunctionApprovalResponseContent → ToolApprovalResponseContent
- Rename UserInputRequestContent → ToolApprovalRequestContent
- Rename UserInputResponseContent → ToolApprovalResponseContent
- Update .FunctionCall property → .ToolCall with FunctionCallContent casts where needed
- Update .Id property → .RequestId on the renamed types
- Rename FunctionApprovalRequestEventGenerator → ToolApprovalRequestEventGenerator
- Rename FunctionApprovalResponseEventGenerator → ToolApprovalResponseEventGenerator
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update OpenAI 2.9.1, ME.AI 10.4.0, fix breaking API changes
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Fix remaining ME.AI 10.4.0 breaking changes: MCP approval types, .Output→.Outputs
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Use pattern matching with `when` for ToolApprovalRequestContent/FunctionCallContent
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Update Azure.AI.OpenAI to 2.9.0-beta.1
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Fix remaining GetResponsesClient(model) build failures for Azure.AI.OpenAI 2.9.0-beta.1
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Address review feedback: remove redundant type checks in TestRequestAgent.cs and fix error message in AIAgentHostExecutor.cs
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
* Update Azure.AI.Projects to 2.0.0-beta.2 with namespace migration
- Azure.AI.Projects 2.0.0-beta.1 → 2.0.0-beta.2
- Azure.AI.Projects.OpenAI → Azure.AI.Extensions.OpenAI (transitive)
- Agent types moved to Azure.AI.Projects.Agents namespace
- AgentRecord.Versions.Latest → AgentRecord.GetLatestVersion()
- OpenAPIFunctionDefinition → OpenApiFunctionDefinition
- BingCustomSearchToolParameters → BingCustomSearchToolOptions
- MemorySearchPreviewTool.UpdateDelay → UpdateDelayInSecs
- Azure.Identity 1.17.1 → 1.19.0
- Microsoft.Identity.Client.Extensions.Msal 4.78.0 → 4.83.1
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
* Fix remaining type renames for Azure.AI.Projects 2.0.0-beta.2
- BrowserAutomationToolParameters → BrowserAutomationToolOptions
- MemoryUpdateOptions.UpdateDelay stays as UpdateDelay (not renamed)
- WaitForMemoriesUpdateAsync parameter order: pollingInterval before options
- AIProjectAgentsOperations → AgentsClient
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
* Fix format errors and OpenTelemetry test for ME.AI 10.4.0
- Remove unused 'using Azure.AI.Extensions.OpenAI' and fix import ordering
in Agent_With_AzureAIProject/Program.cs
- Update OpenTelemetryAgentTests: gen_ai.tool.definitions is now always
emitted regardless of EnableSensitiveData per ME.AI 10.4.0 change
(dotnet/extensions#7346). Tool definitions are not considered sensitive.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix GetRepoFolder() to work in git worktrees
Use 'workflow-samples' directory as repo root marker instead of '.git',
which fails in worktrees (.git is a file) and also matches too early
when a '.github' folder exists in subdirectories.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix formatting: remove unused usings and fix import ordering
dotnet format applied across 59 impacted projects. Primarily removes
unnecessary 'using Azure.AI.Projects' where Azure.AI.Projects.Agents
provides all needed types, and fixes import ordering per editorconfig.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Disable AzureAIAgentsPersistent integration tests (#4769)
Azure.AI.Agents.Persistent 1.2.0-beta.9 references McpServerToolApprovalResponseContent
which was removed in ME.AI 10.4.0 (renamed to ToolApprovalResponseContent), causing
TypeLoadException at runtime. Mark all 6 test classes with IntegrationDisabled trait
until Persistent ships a version targeting ME.AI 10.4.0+.
Upstream fix: https://github.com/Azure/azure-sdk-for-net/pull/56929
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add README with compatibility note for AzureAI.Persistent (#4769)
Documents that Azure.AI.Agents.Persistent 1.2.0-beta.9 is only compatible
with ME.AI ≤10.3.0 and OpenAI ≤2.8.0 due to type renames in ME.AI 10.4.0.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix file encoding: restore UTF-8 BOM on Persistent test files
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Mark AzureAI.Persistent as IsPackable=false (#4769)
Prevent shipping until Azure.AI.Agents.Persistent targets ME.AI 10.4.0+.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Moving IsPackable after import
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
---
dotnet/Directory.Packages.props | 35 +++++----
.../AGUI/Step04_HumanInLoop/Client/Program.cs | 16 ++--
.../ServerFunctionApprovalClientAgent.cs | 24 +++---
.../ServerFunctionApprovalServerAgent.cs | 17 ++---
.../Agent_With_AzureAIProject/Program.cs | 2 +-
.../Program.cs | 8 +-
.../Agent_With_OpenAIResponses/Program.cs | 4 +-
.../Agent_Step01_BasicSkills/Program.cs | 5 +-
.../Agent_OpenAI_Step02_Reasoning/Program.cs | 4 +-
.../OpenAIResponseClientAgent.cs | 9 ++-
.../Program.cs | 4 +-
.../Program.cs | 2 +-
.../Program.cs | 10 +--
.../Program.cs | 3 +-
.../Agents/Agent_Step11_Middleware/Program.cs | 6 +-
.../Program.cs | 4 +-
.../FoundryAgents_Step01.1_Basics/Program.cs | 2 +-
.../FoundryAgents_Step01.2_Running/Program.cs | 2 +-
.../Program.cs | 3 +-
.../Program.cs | 6 +-
.../Program.cs | 6 +-
.../Program.cs | 2 +-
.../Program.cs | 2 +-
.../Program.cs | 2 +-
.../Program.cs | 4 +-
.../Program.cs | 4 +-
.../Program.cs | 2 +-
.../Program.cs | 2 +-
.../FoundryAgents_Step21_WebSearch/Program.cs | 2 +-
.../FoundryAgents_Step22_MemorySearch.csproj | 1 -
.../Program.cs | 9 ++-
.../FoundryAgent_Hosted_MCP/Program.cs | 11 +--
.../ResponseAgent_Hosted_MCP/Program.cs | 17 +++--
.../Agents/GroupChatToolApproval/Program.cs | 10 +--
.../Declarative/CustomerSupport/Program.cs | 2 +-
.../Declarative/DeepResearch/Program.cs | 4 +-
.../Declarative/FunctionTools/Program.cs | 2 +-
.../Declarative/HostedWorkflow/Program.cs | 3 +-
.../Declarative/InputArguments/Program.cs | 2 +-
.../Declarative/InvokeFunctionTool/Program.cs | 2 +-
.../Declarative/InvokeMcpTool/Program.cs | 2 +-
.../Declarative/Marketing/Program.cs | 2 +-
.../Declarative/StudentTeacher/Program.cs | 2 +-
.../Declarative/ToolApproval/Program.cs | 2 +-
.../OpenAIResponsesAgentClient.cs | 2 +-
.../05-end-to-end/AgentWithPurview/Program.cs | 4 +-
.../AgentThreadAndHITL.csproj | 2 +-
.../AgentWithHostedMCP.csproj | 3 +-
.../AgentWithHostedMCP/Program.cs | 3 +-
.../AgentWithLocalTools.csproj | 2 +-
.../AgentWithTextSearchRag.csproj | 2 +-
.../AgentWithTools/AgentWithTools.csproj | 2 +-
.../AgentsInWorkflows.csproj | 2 +-
.../M365Agent/AFAgentApplication.cs | 6 +-
...rosoft.Agents.AI.AzureAI.Persistent.csproj | 2 +
.../README.md | 19 +++++
.../AzureAIProjectChatClient.cs | 5 +-
.../AzureAIProjectChatClientExtensions.cs | 13 ++--
.../Microsoft.Agents.AI.AzureAI.csproj | 1 -
.../AgentResponseUpdateExtensions.cs | 4 +-
.../FunctionApprovalRequestEventGenerator.cs | 20 +++--
.../FunctionApprovalResponseEventGenerator.cs | 10 +--
...ingChatCompletionUpdateCollectionResult.cs | 2 +
.../OpenAIResponseClientExtensions.cs | 12 ++-
.../AzureAgentProvider.cs | 5 +-
.../DefaultMcpToolHandler.cs | 8 +-
.../ObjectModel/InvokeAzureAgentExecutor.cs | 2 +-
.../ObjectModel/InvokeFunctionToolExecutor.cs | 2 +-
.../ObjectModel/InvokeMcpToolExecutor.cs | 17 ++---
.../AIAgentHostOptions.cs | 2 +-
.../Specialized/AIAgentHostExecutor.cs | 20 ++---
.../src/Shared/Foundry/Agents/AgentFactory.cs | 3 +-
.../Workflows/Execution/WorkflowRunner.cs | 21 +++---
.../AIProjectClientCreateTests.cs | 6 +-
.../AIProjectClientFixture.cs | 2 +-
...IAgentsChatClientAgentRunStreamingTests.cs | 4 +
.../AzureAIAgentsChatClientAgentRunTests.cs | 4 +
.../AzureAIAgentsPersistentCreateTests.cs | 4 +
...zureAIAgentsPersistentRunStreamingTests.cs | 4 +
.../AzureAIAgentsPersistentRunTests.cs | 4 +
...gentsPersistentStructuredOutputRunTests.cs | 4 +
...AzureAIProjectChatClientExtensionsTests.cs | 19 ++---
.../TestDataUtil.cs | 2 +-
.../FunctionApprovalTests.cs | 24 +++---
.../OpenAIResponsesIntegrationTests.cs | 75 +++++++++----------
.../OpenTelemetryAgentTests.cs | 42 ++++++++++-
.../Agents/AgentProvider.cs | 2 +-
.../Agents/FunctionToolAgentProvider.cs | 2 +-
.../Agents/MarketingAgentProvider.cs | 2 +-
.../Agents/MathChatAgentProvider.cs | 2 +-
.../Agents/PoemAgentProvider.cs | 2 +-
.../Agents/TestAgentProvider.cs | 2 +-
.../Agents/VisionAgentProvider.cs | 2 +-
.../Framework/WorkflowTest.cs | 2 +-
.../InvokeToolWorkflowTest.cs | 10 +--
.../Events/ExternalInputRequestTest.cs | 17 +++--
.../Events/ExternalInputResponseTest.cs | 17 +++--
.../ObjectModel/InvokeMcpToolExecutorTest.cs | 40 +++++-----
.../AIAgentHostExecutorTests.cs | 2 +-
.../TestRequestAgent.cs | 61 ++++++---------
.../OpenAIResponseFixture.cs | 6 +-
101 files changed, 464 insertions(+), 358 deletions(-)
create mode 100644 dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/README.md
diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props
index dc840265d6..c5bd2191c4 100644
--- a/dotnet/Directory.Packages.props
+++ b/dotnet/Directory.Packages.props
@@ -19,11 +19,10 @@
-
-
-
-
-
+
+
+
+
@@ -40,12 +39,12 @@
-
+
-
-
-
+
+
+
@@ -64,12 +63,12 @@
-
-
-
-
+
+
+
+
-
+
@@ -77,11 +76,11 @@
-
+
-
+
@@ -111,9 +110,9 @@
-
+
-
+
diff --git a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/Program.cs b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/Program.cs
index fafe9ccf83..5d770ff3fd 100644
--- a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/Program.cs
+++ b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/Program.cs
@@ -59,14 +59,14 @@ while ((input = Console.ReadLine()) != null && !input.Equals("exit", StringCompa
{
switch (content)
{
- case FunctionApprovalRequestContent approvalRequest:
- DisplayApprovalRequest(approvalRequest);
+ case ToolApprovalRequestContent approvalRequest when approvalRequest.ToolCall is FunctionCallContent fcc:
+ DisplayApprovalRequest(approvalRequest, fcc);
- Console.Write($"\nApprove '{approvalRequest.FunctionCall.Name}'? (yes/no): ");
+ Console.Write($"\nApprove '{fcc.Name}'? (yes/no): ");
string? userInput = Console.ReadLine();
bool approved = userInput?.ToUpperInvariant() is "YES" or "Y";
- FunctionApprovalResponseContent approvalResponse = approvalRequest.CreateResponse(approved);
+ ToolApprovalResponseContent approvalResponse = approvalRequest.CreateResponse(approved);
if (approvalRequest.AdditionalProperties != null)
{
@@ -128,19 +128,19 @@ while ((input = Console.ReadLine()) != null && !input.Equals("exit", StringCompa
}
#pragma warning disable MEAI001
-static void DisplayApprovalRequest(FunctionApprovalRequestContent approvalRequest)
+static void DisplayApprovalRequest(ToolApprovalRequestContent approvalRequest, FunctionCallContent fcc)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine();
Console.WriteLine("============================================================");
Console.WriteLine("APPROVAL REQUIRED");
Console.WriteLine("============================================================");
- Console.WriteLine($"Function: {approvalRequest.FunctionCall.Name}");
+ Console.WriteLine($"Function: {fcc.Name}");
- if (approvalRequest.FunctionCall.Arguments != null)
+ if (fcc.Arguments != null)
{
Console.WriteLine("Arguments:");
- foreach (var arg in approvalRequest.FunctionCall.Arguments)
+ foreach (var arg in fcc.Arguments)
{
Console.WriteLine($" {arg.Key} = {arg.Value}");
}
diff --git a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/ServerFunctionApprovalClientAgent.cs b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/ServerFunctionApprovalClientAgent.cs
index ee0191fd98..866bbfad31 100644
--- a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/ServerFunctionApprovalClientAgent.cs
+++ b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Client/ServerFunctionApprovalClientAgent.cs
@@ -9,7 +9,7 @@ using ServerFunctionApproval;
///
/// A delegating agent that handles server function approval requests and responses.
-/// Transforms between FunctionApprovalRequestContent/FunctionApprovalResponseContent
+/// Transforms between ToolApprovalRequestContent/ToolApprovalResponseContent
/// and the server's request_approval tool call pattern.
///
internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
@@ -50,14 +50,14 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
}
#pragma warning disable MEAI001 // Type is for evaluation purposes only
- private static FunctionResultContent ConvertApprovalResponseToToolResult(FunctionApprovalResponseContent approvalResponse, JsonSerializerOptions jsonOptions)
+ private static FunctionResultContent ConvertApprovalResponseToToolResult(ToolApprovalResponseContent approvalResponse, JsonSerializerOptions jsonOptions)
{
return new FunctionResultContent(
- callId: approvalResponse.Id,
+ callId: approvalResponse.RequestId,
result: JsonSerializer.SerializeToElement(
new ApprovalResponse
{
- ApprovalId = approvalResponse.Id,
+ ApprovalId = approvalResponse.RequestId,
Approved = approvalResponse.Approved
},
jsonOptions));
@@ -89,7 +89,7 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
{
List? result = null;
- Dictionary approvalRequests = [];
+ Dictionary approvalRequests = [];
for (var messageIndex = 0; messageIndex < messages.Count; messageIndex++)
{
var message = messages[messageIndex];
@@ -102,21 +102,21 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
var content = message.Contents[contentIndex];
// Handle pending approval requests (transform to tool call)
- if (content is FunctionApprovalRequestContent approvalRequest &&
+ if (content is ToolApprovalRequestContent approvalRequest &&
approvalRequest.AdditionalProperties?.TryGetValue("original_function", out var originalFunction) == true &&
originalFunction is FunctionCallContent original)
{
- approvalRequests[approvalRequest.Id] = approvalRequest;
+ approvalRequests[approvalRequest.RequestId] = approvalRequest;
transformedContents ??= CopyContentsUpToIndex(message.Contents, contentIndex);
transformedContents.Add(original);
}
// Handle pending approval responses (transform to tool result)
- else if (content is FunctionApprovalResponseContent approvalResponse &&
- approvalRequests.TryGetValue(approvalResponse.Id, out var correspondingRequest))
+ else if (content is ToolApprovalResponseContent approvalResponse &&
+ approvalRequests.TryGetValue(approvalResponse.RequestId, out var correspondingRequest))
{
transformedContents ??= CopyContentsUpToIndex(message.Contents, contentIndex);
transformedContents.Add(ConvertApprovalResponseToToolResult(approvalResponse, jsonSerializerOptions));
- approvalRequests.Remove(approvalResponse.Id);
+ approvalRequests.Remove(approvalResponse.RequestId);
correspondingRequest.AdditionalProperties?.Remove("original_function");
}
// Skip historical approval content
@@ -198,8 +198,8 @@ internal sealed class ServerFunctionApprovalClientAgent : DelegatingAIAgent
var functionCallArgs = (Dictionary?)approvalRequest.FunctionArguments?
.Deserialize(jsonSerializerOptions.GetTypeInfo(typeof(Dictionary)));
- var approvalRequestContent = new FunctionApprovalRequestContent(
- id: approvalRequest.ApprovalId,
+ var approvalRequestContent = new ToolApprovalRequestContent(
+ requestId: approvalRequest.ApprovalId,
new FunctionCallContent(
callId: approvalRequest.ApprovalId,
name: approvalRequest.FunctionName,
diff --git a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs
index 62209792f6..ff3e6ffbb1 100644
--- a/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs
+++ b/dotnet/samples/02-agents/AGUI/Step04_HumanInLoop/Server/ServerFunctionApprovalServerAgent.cs
@@ -9,7 +9,7 @@ using ServerFunctionApproval;
///
/// A delegating agent that handles function approval requests on the server side.
-/// Transforms between FunctionApprovalRequestContent/FunctionApprovalResponseContent
+/// Transforms between ToolApprovalRequestContent/ToolApprovalResponseContent
/// and the request_approval tool call pattern for client communication.
///
internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
@@ -50,7 +50,7 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
}
#pragma warning disable MEAI001 // Type is for evaluation purposes only
- private static FunctionApprovalRequestContent ConvertToolCallToApprovalRequest(FunctionCallContent toolCall, JsonSerializerOptions jsonSerializerOptions)
+ private static ToolApprovalRequestContent ConvertToolCallToApprovalRequest(FunctionCallContent toolCall, JsonSerializerOptions jsonSerializerOptions)
{
if (toolCall.Name != "request_approval" || toolCall.Arguments == null)
{
@@ -67,15 +67,15 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
throw new InvalidOperationException("Failed to deserialize approval request from tool call");
}
- return new FunctionApprovalRequestContent(
- id: request.ApprovalId,
+ return new ToolApprovalRequestContent(
+ requestId: request.ApprovalId,
new FunctionCallContent(
callId: request.ApprovalId,
name: request.FunctionName,
arguments: request.FunctionArguments));
}
- private static FunctionApprovalResponseContent ConvertToolResultToApprovalResponse(FunctionResultContent result, FunctionApprovalRequestContent approval, JsonSerializerOptions jsonSerializerOptions)
+ private static ToolApprovalResponseContent ConvertToolResultToApprovalResponse(FunctionResultContent result, ToolApprovalRequestContent approval, JsonSerializerOptions jsonSerializerOptions)
{
var approvalResponse = result.Result is JsonElement je ?
(ApprovalResponse?)je.Deserialize(jsonSerializerOptions.GetTypeInfo(typeof(ApprovalResponse))) :
@@ -121,7 +121,7 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
// Track approval ID to original call ID mapping
_ = new Dictionary();
#pragma warning disable MEAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
- Dictionary trackedRequestApprovalToolCalls = new(); // Remote approvals
+ Dictionary trackedRequestApprovalToolCalls = new(); // Remote approvals
for (int messageIndex = 0; messageIndex < messages.Count; messageIndex++)
{
var message = messages[messageIndex];
@@ -181,11 +181,10 @@ internal sealed class ServerFunctionApprovalAgent : DelegatingAIAgent
{
var content = update.Contents[i];
#pragma warning disable MEAI001 // Type is for evaluation purposes only
- if (content is FunctionApprovalRequestContent request)
+ if (content is ToolApprovalRequestContent request && request.ToolCall is FunctionCallContent functionCall)
{
updatedContents ??= [.. update.Contents];
- var functionCall = request.FunctionCall;
- var approvalId = request.Id;
+ var approvalId = request.RequestId;
var approvalData = new ApprovalRequest
{
diff --git a/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureAIProject/Program.cs b/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureAIProject/Program.cs
index acdd0829ab..aab95d5b38 100644
--- a/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureAIProject/Program.cs
+++ b/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureAIProject/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to create and use a AI agents with Azure Foundry Agents as the backend.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
diff --git a/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureOpenAIResponses/Program.cs b/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureOpenAIResponses/Program.cs
index 6aca7f24b8..f29b850700 100644
--- a/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureOpenAIResponses/Program.cs
+++ b/dotnet/samples/02-agents/AgentProviders/Agent_With_AzureOpenAIResponses/Program.cs
@@ -17,8 +17,8 @@ var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
- .AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
+ .GetResponsesClient()
+ .AsAIAgent(model: deploymentName, instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -29,8 +29,8 @@ Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
AIAgent agentStoreFalse = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
- .AsIChatClientWithStoredOutputDisabled()
+ .GetResponsesClient()
+ .AsIChatClientWithStoredOutputDisabled(model: deploymentName)
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
diff --git a/dotnet/samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Program.cs b/dotnet/samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Program.cs
index 611f3f9a9a..baa6677a4f 100644
--- a/dotnet/samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Program.cs
+++ b/dotnet/samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Program.cs
@@ -11,8 +11,8 @@ var model = Environment.GetEnvironmentVariable("OPENAI_CHAT_MODEL_NAME") ?? "gpt
AIAgent agent = new OpenAIClient(
apiKey)
- .GetResponsesClient(model)
- .AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
+ .GetResponsesClient()
+ .AsAIAgent(model: model, instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
diff --git a/dotnet/samples/02-agents/AgentSkills/Agent_Step01_BasicSkills/Program.cs b/dotnet/samples/02-agents/AgentSkills/Agent_Step01_BasicSkills/Program.cs
index 290c3f9b6b..9b0a4b4f99 100644
--- a/dotnet/samples/02-agents/AgentSkills/Agent_Step01_BasicSkills/Program.cs
+++ b/dotnet/samples/02-agents/AgentSkills/Agent_Step01_BasicSkills/Program.cs
@@ -23,7 +23,7 @@ var skillsProvider = new FileAgentSkillsProvider(skillPath: Path.Combine(AppCont
// --- Agent Setup ---
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
+ .GetResponsesClient()
.AsAIAgent(new ChatClientAgentOptions
{
Name = "SkillsAgent",
@@ -32,7 +32,8 @@ AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredent
Instructions = "You are a helpful assistant.",
},
AIContextProviders = [skillsProvider],
- });
+ },
+ model: deploymentName);
// --- Example 1: Expense policy question (loads FAQ resource) ---
Console.WriteLine("Example 1: Checking expense policy FAQ");
diff --git a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Program.cs b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Program.cs
index d13d0d5346..12e30dc203 100644
--- a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Program.cs
+++ b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Program.cs
@@ -10,8 +10,8 @@ var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new I
var model = Environment.GetEnvironmentVariable("OPENAI_CHAT_MODEL_NAME") ?? "gpt-5";
var client = new OpenAIClient(apiKey)
- .GetResponsesClient(model)
- .AsIChatClient().AsBuilder()
+ .GetResponsesClient()
+ .AsIChatClient(model).AsBuilder()
.ConfigureOptions(o =>
{
o.Reasoning = new()
diff --git a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/OpenAIResponseClientAgent.cs b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/OpenAIResponseClientAgent.cs
index 196bd64922..4deb134fd7 100644
--- a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/OpenAIResponseClientAgent.cs
+++ b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/OpenAIResponseClientAgent.cs
@@ -20,19 +20,21 @@ public class OpenAIResponseClientAgent : DelegatingAIAgent
/// Optional instructions for the agent.
/// Optional name for the agent.
/// Optional description for the agent.
+ /// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Optional instance of
public OpenAIResponseClientAgent(
ResponsesClient client,
string? instructions = null,
string? name = null,
string? description = null,
+ string? model = null,
ILoggerFactory? loggerFactory = null) :
this(client, new()
{
Name = name,
Description = description,
ChatOptions = new ChatOptions() { Instructions = instructions },
- }, loggerFactory)
+ }, model, loggerFactory)
{
}
@@ -41,10 +43,11 @@ public class OpenAIResponseClientAgent : DelegatingAIAgent
///
/// Instance of
/// Options to create the agent.
+ /// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Optional instance of
public OpenAIResponseClientAgent(
- ResponsesClient client, ChatClientAgentOptions options, ILoggerFactory? loggerFactory = null) :
- base(new ChatClientAgent((client ?? throw new ArgumentNullException(nameof(client))).AsIChatClient(), options, loggerFactory))
+ ResponsesClient client, ChatClientAgentOptions options, string? model = null, ILoggerFactory? loggerFactory = null) :
+ base(new ChatClientAgent((client ?? throw new ArgumentNullException(nameof(client))).AsIChatClient(model), options, loggerFactory))
{
}
diff --git a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/Program.cs b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/Program.cs
index 8004770c21..dbd11ce3c6 100644
--- a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/Program.cs
+++ b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step04_CreateFromOpenAIResponseClient/Program.cs
@@ -10,10 +10,10 @@ var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new I
var model = Environment.GetEnvironmentVariable("OPENAI_CHAT_MODEL_NAME") ?? "gpt-4o-mini";
// Create a ResponsesClient directly from OpenAIClient
-ResponsesClient responseClient = new OpenAIClient(apiKey).GetResponsesClient(model);
+ResponsesClient responseClient = new OpenAIClient(apiKey).GetResponsesClient();
// Create an agent directly from the ResponsesClient using OpenAIResponseClientAgent
-OpenAIResponseClientAgent agent = new(responseClient, instructions: "You are good at telling jokes.", name: "Joker");
+OpenAIResponseClientAgent agent = new(responseClient, instructions: "You are good at telling jokes.", name: "Joker", model: model);
ResponseItem userMessage = ResponseItem.CreateUserMessageItem("Tell me a joke about a pirate.");
diff --git a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step05_Conversation/Program.cs b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step05_Conversation/Program.cs
index 921acbad0d..603f8b8e7b 100644
--- a/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step05_Conversation/Program.cs
+++ b/dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step05_Conversation/Program.cs
@@ -22,7 +22,7 @@ OpenAIClient openAIClient = new(apiKey);
ConversationClient conversationClient = openAIClient.GetConversationClient();
// Create an agent directly from the ResponsesClient using OpenAIResponseClientAgent
-ChatClientAgent agent = new(openAIClient.GetResponsesClient(model).AsIChatClient(), instructions: "You are a helpful assistant.", name: "ConversationAgent");
+ChatClientAgent agent = new(openAIClient.GetResponsesClient().AsIChatClient(model), instructions: "You are a helpful assistant.", name: "ConversationAgent");
ClientResult createConversationResult = await conversationClient.CreateConversationAsync(BinaryContent.Create(BinaryData.FromString("{}")));
diff --git a/dotnet/samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Program.cs b/dotnet/samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Program.cs
index 5bdfc9421c..8ff4181a51 100644
--- a/dotnet/samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Program.cs
+++ b/dotnet/samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Program.cs
@@ -36,11 +36,11 @@ AIAgent agent = new AzureOpenAIClient(
// For simplicity, we are assuming here that only function approvals are pending.
AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", session);
-List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
// For streaming use:
// var updates = await agent.RunStreamingAsync("What is the weather like in Amsterdam?", session).ToListAsync();
-// approvalRequests = updates.SelectMany(x => x.Contents).OfType().ToList();
+// approvalRequests = updates.SelectMany(x => x.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -48,18 +48,18 @@ while (approvalRequests.Count > 0)
List userInputResponses = approvalRequests
.ConvertAll(functionApprovalRequest =>
{
- Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
+ Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {((FunctionCallContent)functionApprovalRequest.ToolCall).Name}");
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
});
// Pass the user input responses back to the agent for further processing.
response = await agent.RunAsync(userInputResponses, session);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
// For streaming use:
// updates = await agent.RunStreamingAsync(userInputResponses, session).ToListAsync();
- // approvalRequests = updates.SelectMany(x => x.Contents).OfType().ToList();
+ // approvalRequests = updates.SelectMany(x => x.Contents).OfType().ToList();
}
Console.WriteLine($"\nAgent: {response}");
diff --git a/dotnet/samples/02-agents/Agents/Agent_Step10_BackgroundResponsesWithToolsAndPersistence/Program.cs b/dotnet/samples/02-agents/Agents/Agent_Step10_BackgroundResponsesWithToolsAndPersistence/Program.cs
index 5d9c70a5fd..b568ef5867 100644
--- a/dotnet/samples/02-agents/Agents/Agent_Step10_BackgroundResponsesWithToolsAndPersistence/Program.cs
+++ b/dotnet/samples/02-agents/Agents/Agent_Step10_BackgroundResponsesWithToolsAndPersistence/Program.cs
@@ -25,8 +25,9 @@ var stateStore = new Dictionary();
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
+ .GetResponsesClient()
.AsAIAgent(
+ model: deploymentName,
name: "SpaceNovelWriter",
instructions: "You are a space novel writer. Always research relevant facts and generate character profiles for the main characters before writing novels." +
"Write complete chapters without asking for approval or feedback. Do not ask the user about tone, style, pace, or format preferences - just write the novel based on the request.",
diff --git a/dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Program.cs b/dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Program.cs
index 09cd540378..18969ed66e 100644
--- a/dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Program.cs
+++ b/dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Program.cs
@@ -246,7 +246,7 @@ async Task ConsolePromptingApprovalMiddleware(IEnumerable approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -255,13 +255,13 @@ async Task ConsolePromptingApprovalMiddleware(IEnumerable
{
- Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
+ Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {((FunctionCallContent)functionApprovalRequest.ToolCall).Name}");
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
});
response = await innerAgent.RunAsync(response.Messages, session, options, cancellationToken);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
}
return response;
diff --git a/dotnet/samples/02-agents/Agents/Agent_Step14_BackgroundResponses/Program.cs b/dotnet/samples/02-agents/Agents/Agent_Step14_BackgroundResponses/Program.cs
index 62db550556..f474b938a6 100644
--- a/dotnet/samples/02-agents/Agents/Agent_Step14_BackgroundResponses/Program.cs
+++ b/dotnet/samples/02-agents/Agents/Agent_Step14_BackgroundResponses/Program.cs
@@ -16,8 +16,8 @@ var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
- .AsAIAgent();
+ .GetResponsesClient()
+ .AsAIAgent(model: deploymentName);
// Enable background responses (only supported by OpenAI Responses at this time).
AgentRunOptions options = new() { AllowBackgroundResponses = true };
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs
index 72676bed45..f4521d8898 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to create and use AI agents with Azure Foundry Agents as the backend.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs
index dd5db03b15..0bc17aff0a 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs
index 1ac51c30ad..7bf12094fc 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/Program.cs
@@ -2,8 +2,9 @@
// This sample shows how to create and use a simple AI agent with a multi-turn conversation.
+using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs
index f33fae35f4..08051a500e 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs
@@ -40,7 +40,7 @@ AgentResponse response = await agent.RunAsync("What is the weather like in Amste
// Check if there are any approval requests.
// For simplicity, we are assuming here that only function approvals are pending.
-List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -48,7 +48,7 @@ while (approvalRequests.Count > 0)
List userInputMessages = approvalRequests
.ConvertAll(functionApprovalRequest =>
{
- Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
+ Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {((FunctionCallContent)functionApprovalRequest.ToolCall).Name}");
bool approved = Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false;
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(approved)]);
});
@@ -56,7 +56,7 @@ while (approvalRequests.Count > 0)
// Pass the user input responses back to the agent for further processing.
response = await agent.RunAsync(userInputMessages, session);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
}
Console.WriteLine($"\nAgent: {response}");
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs
index 7ea6bc88a3..824e1507b3 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step12_Middleware/Program.cs
@@ -197,7 +197,7 @@ async Task ConsolePromptingApprovalMiddleware(IEnumerable approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -206,14 +206,14 @@ async Task ConsolePromptingApprovalMiddleware(IEnumerable
{
- Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
+ Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {((FunctionCallContent)functionApprovalRequest.ToolCall).Name}");
bool approved = Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false;
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(approved)]);
});
response = await innerAgent.RunAsync(response.Messages, session, options, cancellationToken);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
}
return response;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs
index 854d317495..5a27daed12 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs
@@ -4,7 +4,7 @@
using System.Text;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs
index 1c5510218a..7f6382d085 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use Computer Use Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step16_FileSearch/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step16_FileSearch/Program.cs
index 36f28c2387..5371903a9f 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step16_FileSearch/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step16_FileSearch/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use File Search Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step17_OpenAPITools/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step17_OpenAPITools/Program.cs
index 2ee5a94458..ebf66e6c2c 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step17_OpenAPITools/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step17_OpenAPITools/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use OpenAPI Tools with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
@@ -72,7 +72,7 @@ const string CountriesOpenApiSpec = """
AIProjectClient aiProjectClient = new(new Uri(endpoint), new DefaultAzureCredential());
// Create the OpenAPI function definition
-var openApiFunction = new OpenAPIFunctionDefinition(
+var openApiFunction = new OpenApiFunctionDefinition(
"get_countries",
BinaryData.FromString(CountriesOpenApiSpec),
new OpenAPIAnonymousAuthenticationDetails())
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step18_BingCustomSearch/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step18_BingCustomSearch/Program.cs
index 365bf6ed08..98ea576226 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step18_BingCustomSearch/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step18_BingCustomSearch/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use Bing Custom Search Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
@@ -25,7 +25,7 @@ const string AgentInstructions = """
AIProjectClient aiProjectClient = new(new Uri(endpoint), new DefaultAzureCredential());
// Bing Custom Search tool parameters shared by both options
-BingCustomSearchToolParameters bingCustomSearchToolParameters = new([
+BingCustomSearchToolOptions bingCustomSearchToolParameters = new([
new BingCustomSearchConfiguration(connectionId, instanceName)
]);
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step19_SharePoint/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step19_SharePoint/Program.cs
index 6d1daf85df..ad6a08abaa 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step19_SharePoint/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step19_SharePoint/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use SharePoint Grounding Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step20_MicrosoftFabric/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step20_MicrosoftFabric/Program.cs
index 2f13c2c30c..e5ab205f68 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step20_MicrosoftFabric/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step20_MicrosoftFabric/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use Microsoft Fabric Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step21_WebSearch/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step21_WebSearch/Program.cs
index 1ac312ddae..c116a975e1 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step21_WebSearch/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step21_WebSearch/Program.cs
@@ -3,7 +3,7 @@
// This sample shows how to use the Responses API Web Search Tool with AI Agents.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/FoundryAgents_Step22_MemorySearch.csproj b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/FoundryAgents_Step22_MemorySearch.csproj
index a1ccdfcd3a..d83a9d9202 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/FoundryAgents_Step22_MemorySearch.csproj
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/FoundryAgents_Step22_MemorySearch.csproj
@@ -13,7 +13,6 @@
-
diff --git a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/Program.cs b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/Program.cs
index 1f6b0f2ddc..60452b7d19 100644
--- a/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/Program.cs
+++ b/dotnet/samples/02-agents/FoundryAgents/FoundryAgents_Step22_MemorySearch/Program.cs
@@ -4,8 +4,9 @@
// The Memory Search Tool enables agents to recall information from previous conversations,
// supporting user profile persistence and chat summaries across sessions.
+using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
@@ -36,7 +37,7 @@ AIProjectClient aiProjectClient = new(new Uri(endpoint), credential);
await EnsureMemoryStoreAsync();
// Create the Memory Search tool configuration
-MemorySearchPreviewTool memorySearchTool = new(memoryStoreName, userScope) { UpdateDelay = 0 };
+MemorySearchPreviewTool memorySearchTool = new(memoryStoreName, userScope) { UpdateDelayInSecs = 0 };
// Create agent using Option 1 (MEAI) or Option 2 (Native SDK)
AIAgent agent = await CreateAgentWithMEAI();
@@ -128,8 +129,8 @@ async Task EnsureMemoryStoreAsync()
MemoryUpdateResult updateResult = await aiProjectClient.MemoryStores.WaitForMemoriesUpdateAsync(
memoryStoreName: memoryStoreName,
- options: memoryOptions,
- pollingInterval: 500);
+ pollingInterval: 500,
+ options: memoryOptions);
if (updateResult.Status == MemoryStoreUpdateStatus.Failed)
{
diff --git a/dotnet/samples/02-agents/ModelContextProtocol/FoundryAgent_Hosted_MCP/Program.cs b/dotnet/samples/02-agents/ModelContextProtocol/FoundryAgent_Hosted_MCP/Program.cs
index 99d26c103d..e34c3d932e 100644
--- a/dotnet/samples/02-agents/ModelContextProtocol/FoundryAgent_Hosted_MCP/Program.cs
+++ b/dotnet/samples/02-agents/ModelContextProtocol/FoundryAgent_Hosted_MCP/Program.cs
@@ -81,7 +81,7 @@ AIAgent agentWithRequiredApproval = await persistentAgentsClient.CreateAIAgentAs
// For simplicity, we are assuming here that only mcp tool approvals are pending.
AgentSession sessionWithRequiredApproval = await agentWithRequiredApproval.CreateSessionAsync();
AgentResponse response = await agentWithRequiredApproval.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", sessionWithRequiredApproval);
-List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -89,11 +89,12 @@ while (approvalRequests.Count > 0)
List userInputResponses = approvalRequests
.ConvertAll(approvalRequest =>
{
+ McpServerToolCallContent mcpToolCall = (McpServerToolCallContent)approvalRequest.ToolCall!;
Console.WriteLine($"""
The agent would like to invoke the following MCP Tool, please reply Y to approve.
- ServerName: {approvalRequest.ToolCall.ServerName}
- Name: {approvalRequest.ToolCall.ToolName}
- Arguments: {string.Join(", ", approvalRequest.ToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
+ ServerName: {mcpToolCall.ServerName}
+ Name: {mcpToolCall.Name}
+ Arguments: {string.Join(", ", mcpToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
""");
return new ChatMessage(ChatRole.User, [approvalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
});
@@ -101,7 +102,7 @@ while (approvalRequests.Count > 0)
// Pass the user input responses back to the agent for further processing.
response = await agentWithRequiredApproval.RunAsync(userInputResponses, sessionWithRequiredApproval);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
}
Console.WriteLine($"\nAgent: {response}");
diff --git a/dotnet/samples/02-agents/ModelContextProtocol/ResponseAgent_Hosted_MCP/Program.cs b/dotnet/samples/02-agents/ModelContextProtocol/ResponseAgent_Hosted_MCP/Program.cs
index 194952e68a..f8715e4543 100644
--- a/dotnet/samples/02-agents/ModelContextProtocol/ResponseAgent_Hosted_MCP/Program.cs
+++ b/dotnet/samples/02-agents/ModelContextProtocol/ResponseAgent_Hosted_MCP/Program.cs
@@ -33,8 +33,9 @@ var mcpTool = new HostedMcpServerTool(
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
+ .GetResponsesClient()
.AsAIAgent(
+ model: deploymentName,
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgent",
tools: [mcpTool]);
@@ -60,8 +61,9 @@ var mcpToolWithApproval = new HostedMcpServerTool(
AIAgent agentWithRequiredApproval = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
+ .GetResponsesClient()
.AsAIAgent(
+ model: deploymentName,
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgentWithApproval",
tools: [mcpToolWithApproval]);
@@ -70,7 +72,7 @@ AIAgent agentWithRequiredApproval = new AzureOpenAIClient(
// For simplicity, we are assuming here that only mcp tool approvals are pending.
AgentSession sessionWithRequiredApproval = await agentWithRequiredApproval.CreateSessionAsync();
AgentResponse response = await agentWithRequiredApproval.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", sessionWithRequiredApproval);
-List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+List approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
while (approvalRequests.Count > 0)
{
@@ -78,11 +80,12 @@ while (approvalRequests.Count > 0)
List userInputResponses = approvalRequests
.ConvertAll(approvalRequest =>
{
+ McpServerToolCallContent mcpToolCall = (McpServerToolCallContent)approvalRequest.ToolCall!;
Console.WriteLine($"""
The agent would like to invoke the following MCP Tool, please reply Y to approve.
- ServerName: {approvalRequest.ToolCall.ServerName}
- Name: {approvalRequest.ToolCall.ToolName}
- Arguments: {string.Join(", ", approvalRequest.ToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
+ ServerName: {mcpToolCall.ServerName}
+ Name: {mcpToolCall.Name}
+ Arguments: {string.Join(", ", mcpToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
""");
return new ChatMessage(ChatRole.User, [approvalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
});
@@ -90,7 +93,7 @@ while (approvalRequests.Count > 0)
// Pass the user input responses back to the agent for further processing.
response = await agentWithRequiredApproval.RunAsync(userInputResponses, sessionWithRequiredApproval);
- approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
+ approvalRequests = response.Messages.SelectMany(m => m.Contents).OfType().ToList();
}
Console.WriteLine($"\nAgent: {response}");
diff --git a/dotnet/samples/03-workflows/Agents/GroupChatToolApproval/Program.cs b/dotnet/samples/03-workflows/Agents/GroupChatToolApproval/Program.cs
index 076e764ea8..a8d42b5342 100644
--- a/dotnet/samples/03-workflows/Agents/GroupChatToolApproval/Program.cs
+++ b/dotnet/samples/03-workflows/Agents/GroupChatToolApproval/Program.cs
@@ -17,7 +17,7 @@
//
// Demonstrate:
// - Using custom GroupChatManager with agents that have approval-required tools.
-// - Handling FunctionApprovalRequestContent in group chat scenarios.
+// - Handling ToolApprovalRequestContent in group chat scenarios.
// - Multi-round group chat with tool approval interruption and resumption.
using System.ComponentModel;
@@ -101,16 +101,16 @@ public static class Program
{
case RequestInfoEvent e:
{
- if (e.Request.TryGetDataAs(out FunctionApprovalRequestContent? approvalRequestContent))
+ if (e.Request.TryGetDataAs(out ToolApprovalRequestContent? approvalRequestContent))
{
Console.WriteLine();
Console.WriteLine($"[APPROVAL REQUIRED] From agent: {e.Request.PortInfo.PortId}");
- Console.WriteLine($" Tool: {approvalRequestContent.FunctionCall.Name}");
- Console.WriteLine($" Arguments: {JsonSerializer.Serialize(approvalRequestContent.FunctionCall.Arguments)}");
+ Console.WriteLine($" Tool: {((FunctionCallContent)approvalRequestContent.ToolCall).Name}");
+ Console.WriteLine($" Arguments: {JsonSerializer.Serialize(((FunctionCallContent)approvalRequestContent.ToolCall).Arguments)}");
Console.WriteLine();
// Approve the tool call request
- Console.WriteLine($"Tool: {approvalRequestContent.FunctionCall.Name} approved");
+ Console.WriteLine($"Tool: {((FunctionCallContent)approvalRequestContent.ToolCall).Name} approved");
await run.SendResponseAsync(e.Request.CreateResponse(approvalRequestContent.CreateResponse(approved: true)));
}
diff --git a/dotnet/samples/03-workflows/Declarative/CustomerSupport/Program.cs b/dotnet/samples/03-workflows/Declarative/CustomerSupport/Program.cs
index b5df45a399..5b0458f23d 100644
--- a/dotnet/samples/03-workflows/Declarative/CustomerSupport/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/CustomerSupport/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
diff --git a/dotnet/samples/03-workflows/Declarative/DeepResearch/Program.cs b/dotnet/samples/03-workflows/Declarative/DeepResearch/Program.cs
index 98d75d250b..e415c7aad0 100644
--- a/dotnet/samples/03-workflows/Declarative/DeepResearch/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/DeepResearch/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
@@ -275,7 +275,7 @@ internal sealed class Program
Tools =
{
AgentTool.CreateOpenApiTool(
- new OpenAPIFunctionDefinition(
+ new OpenApiFunctionDefinition(
"weather-forecast",
BinaryData.FromString(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "wttr.json"))),
new OpenAPIAnonymousAuthenticationDetails()))
diff --git a/dotnet/samples/03-workflows/Declarative/FunctionTools/Program.cs b/dotnet/samples/03-workflows/Declarative/FunctionTools/Program.cs
index 8218e7c057..a1bd9de8f9 100644
--- a/dotnet/samples/03-workflows/Declarative/FunctionTools/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/FunctionTools/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
diff --git a/dotnet/samples/03-workflows/Declarative/HostedWorkflow/Program.cs b/dotnet/samples/03-workflows/Declarative/HostedWorkflow/Program.cs
index 81e2abbafe..5936aaf82f 100644
--- a/dotnet/samples/03-workflows/Declarative/HostedWorkflow/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/HostedWorkflow/Program.cs
@@ -3,8 +3,9 @@
// Uncomment this to enable JSON checkpointing to the local file system.
//#define CHECKPOINT_JSON
+using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
diff --git a/dotnet/samples/03-workflows/Declarative/InputArguments/Program.cs b/dotnet/samples/03-workflows/Declarative/InputArguments/Program.cs
index 65a365b143..0a6f99f920 100644
--- a/dotnet/samples/03-workflows/Declarative/InputArguments/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/InputArguments/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
diff --git a/dotnet/samples/03-workflows/Declarative/InvokeFunctionTool/Program.cs b/dotnet/samples/03-workflows/Declarative/InvokeFunctionTool/Program.cs
index fb20764977..8875d204f2 100644
--- a/dotnet/samples/03-workflows/Declarative/InvokeFunctionTool/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/InvokeFunctionTool/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
diff --git a/dotnet/samples/03-workflows/Declarative/InvokeMcpTool/Program.cs b/dotnet/samples/03-workflows/Declarative/InvokeMcpTool/Program.cs
index 926afcfc3c..61ce1afc70 100644
--- a/dotnet/samples/03-workflows/Declarative/InvokeMcpTool/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/InvokeMcpTool/Program.cs
@@ -5,7 +5,7 @@
// invoked to perform specific tasks, like searching documentation or executing operations.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Core;
using Azure.Identity;
using Microsoft.Agents.AI.Workflows.Declarative.Mcp;
diff --git a/dotnet/samples/03-workflows/Declarative/Marketing/Program.cs b/dotnet/samples/03-workflows/Declarative/Marketing/Program.cs
index 308303c162..5d73edd26d 100644
--- a/dotnet/samples/03-workflows/Declarative/Marketing/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/Marketing/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
diff --git a/dotnet/samples/03-workflows/Declarative/StudentTeacher/Program.cs b/dotnet/samples/03-workflows/Declarative/StudentTeacher/Program.cs
index 28523c031e..4f1d31a2ea 100644
--- a/dotnet/samples/03-workflows/Declarative/StudentTeacher/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/StudentTeacher/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
diff --git a/dotnet/samples/03-workflows/Declarative/ToolApproval/Program.cs b/dotnet/samples/03-workflows/Declarative/ToolApproval/Program.cs
index 544974e096..9e9bd65b6b 100644
--- a/dotnet/samples/03-workflows/Declarative/ToolApproval/Program.cs
+++ b/dotnet/samples/03-workflows/Declarative/ToolApproval/Program.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
diff --git a/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/OpenAIResponsesAgentClient.cs b/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/OpenAIResponsesAgentClient.cs
index 0d2470762e..839c8e75a1 100644
--- a/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/OpenAIResponsesAgentClient.cs
+++ b/dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/OpenAIResponsesAgentClient.cs
@@ -27,7 +27,7 @@ internal sealed class OpenAIResponsesAgentClient(HttpClient httpClient) : AgentC
Transport = new HttpClientPipelineTransport(httpClient)
};
- var openAiClient = new ResponsesClient(model: agentName, credential: new ApiKeyCredential("dummy-key"), options: options).AsIChatClient();
+ var openAiClient = new ResponsesClient(credential: new ApiKeyCredential("dummy-key"), options: options).AsIChatClient(agentName);
var chatOptions = new ChatOptions()
{
ConversationId = sessionId
diff --git a/dotnet/samples/05-end-to-end/AgentWithPurview/Program.cs b/dotnet/samples/05-end-to-end/AgentWithPurview/Program.cs
index fc0974c5bd..33e7001a51 100644
--- a/dotnet/samples/05-end-to-end/AgentWithPurview/Program.cs
+++ b/dotnet/samples/05-end-to-end/AgentWithPurview/Program.cs
@@ -30,8 +30,8 @@ TokenCredential browserCredential = new InteractiveBrowserCredential(
using IChatClient client = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
- .AsIChatClient()
+ .GetResponsesClient()
+ .AsIChatClient(deploymentName)
.AsBuilder()
.WithPurview(browserCredential, new PurviewSettings("Agent Framework Test App"))
.Build();
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentThreadAndHITL/AgentThreadAndHITL.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentThreadAndHITL/AgentThreadAndHITL.csproj
index 1398a60228..1afc7a7cec 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentThreadAndHITL/AgentThreadAndHITL.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentThreadAndHITL/AgentThreadAndHITL.csproj
@@ -37,7 +37,7 @@
-
+
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj
index e854cfcd40..c0e14e74b8 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj
@@ -36,9 +36,10 @@
-
+
+
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/Program.cs b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/Program.cs
index b7b610b663..8559269dff 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/Program.cs
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/Program.cs
@@ -31,7 +31,8 @@ AITool mcpTool = new HostedMcpServerTool(serverName: "microsoft_learn", serverAd
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
- .GetResponsesClient(deploymentName)
+ .GetResponsesClient()
+ .AsIChatClient(deploymentName)
.AsAIAgent(
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgent",
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithLocalTools/AgentWithLocalTools.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithLocalTools/AgentWithLocalTools.csproj
index 975333e584..ccda3156e5 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithLocalTools/AgentWithLocalTools.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithLocalTools/AgentWithLocalTools.csproj
@@ -38,7 +38,7 @@
-
+
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj
index 32e00f832b..19e5015912 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj
@@ -36,7 +36,7 @@
-
+
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTools/AgentWithTools.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTools/AgentWithTools.csproj
index 959cca1db5..19e5015912 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTools/AgentWithTools.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentWithTools/AgentWithTools.csproj
@@ -36,7 +36,7 @@
-
+
diff --git a/dotnet/samples/05-end-to-end/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj b/dotnet/samples/05-end-to-end/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj
index 56a55a428d..3b3af40664 100644
--- a/dotnet/samples/05-end-to-end/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj
+++ b/dotnet/samples/05-end-to-end/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj
@@ -36,7 +36,7 @@
-
+
diff --git a/dotnet/samples/05-end-to-end/M365Agent/AFAgentApplication.cs b/dotnet/samples/05-end-to-end/M365Agent/AFAgentApplication.cs
index 7e58819a65..502c57204e 100644
--- a/dotnet/samples/05-end-to-end/M365Agent/AFAgentApplication.cs
+++ b/dotnet/samples/05-end-to-end/M365Agent/AFAgentApplication.cs
@@ -122,7 +122,7 @@ internal sealed class AFAgentApplication : AgentApplication
&& valueElement.GetProperty("requestJson") is JsonElement requestJsonElement
&& requestJsonElement.ValueKind == JsonValueKind.String)
{
- var requestContent = JsonSerializer.Deserialize(requestJsonElement.GetString()!, JsonUtilities.DefaultOptions);
+ var requestContent = JsonSerializer.Deserialize(requestJsonElement.GetString()!, JsonUtilities.DefaultOptions);
return new ChatMessage(ChatRole.User, [requestContent!.CreateResponse(approvedJsonElement.ValueKind == JsonValueKind.True)]);
}
@@ -138,7 +138,7 @@ internal sealed class AFAgentApplication : AgentApplication
/// The list of to which the adaptive cards will be added.
private static void HandleUserInputRequests(AgentResponse response, ref List? attachments)
{
- foreach (FunctionApprovalRequestContent functionApprovalRequest in response.Messages.SelectMany(m => m.Contents).OfType())
+ foreach (ToolApprovalRequestContent functionApprovalRequest in response.Messages.SelectMany(m => m.Contents).OfType())
{
var functionApprovalRequestJson = JsonSerializer.Serialize(functionApprovalRequest, JsonUtilities.DefaultOptions);
@@ -152,7 +152,7 @@ internal sealed class AFAgentApplication : AgentApplication
});
card.Body.Add(new AdaptiveTextBlock
{
- Text = $"Function: {functionApprovalRequest.FunctionCall.Name}"
+ Text = $"Function: {((FunctionCallContent)functionApprovalRequest.ToolCall).Name}"
});
card.Body.Add(new AdaptiveActionSet()
{
diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/Microsoft.Agents.AI.AzureAI.Persistent.csproj b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/Microsoft.Agents.AI.AzureAI.Persistent.csproj
index 31785a8fa9..bb02f3065a 100644
--- a/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/Microsoft.Agents.AI.AzureAI.Persistent.csproj
+++ b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/Microsoft.Agents.AI.AzureAI.Persistent.csproj
@@ -20,6 +20,8 @@
Microsoft Agent Framework AzureAI Persistent Agents
Provides Microsoft Agent Framework support for Azure AI Persistent Agents.
+
+ false
diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/README.md b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/README.md
new file mode 100644
index 0000000000..a01debc5ca
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.AzureAI.Persistent/README.md
@@ -0,0 +1,19 @@
+# Microsoft.Agents.AI.AzureAI.Persistent
+
+Provides integration between the Microsoft Agent Framework and Azure AI Agents Persistent (`Azure.AI.Agents.Persistent`).
+
+## ⚠️ Known Compatibility Limitation
+
+The underlying `Azure.AI.Agents.Persistent` package (currently 1.2.0-beta.9) targets `Microsoft.Extensions.AI.Abstractions` 10.1.x and references types that were renamed in 10.4.0 (e.g., `McpServerToolApprovalResponseContent` → `ToolApprovalResponseContent`). This causes `TypeLoadException` at runtime when used with ME.AI 10.4.0+.
+
+**Compatible versions:**
+
+| Package | Compatible Version |
+|---|---|
+| `Azure.AI.Agents.Persistent` | 1.2.0-beta.9 (targets ME.AI 10.1.x) |
+| `Microsoft.Extensions.AI.Abstractions` | ≤ 10.3.0 |
+| `OpenAI` | ≤ 2.8.0 |
+
+**Resolution:** An updated version of `Azure.AI.Agents.Persistent` targeting ME.AI 10.4.0+ is expected in 1.2.0-beta.10. The upstream fix is tracked in [Azure/azure-sdk-for-net#56929](https://github.com/Azure/azure-sdk-for-net/pull/56929).
+
+**Tracking issue:** [microsoft/agent-framework#4769](https://github.com/microsoft/agent-framework/issues/4769)
diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClient.cs b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClient.cs
index 51ddf0054c..32bb08674b 100644
--- a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClient.cs
+++ b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClient.cs
@@ -2,8 +2,9 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
+using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Microsoft.Extensions.AI;
using Microsoft.Shared.DiagnosticIds;
using Microsoft.Shared.Diagnostics;
@@ -57,7 +58,7 @@ internal sealed class AzureAIProjectChatClient : DelegatingChatClient
/// The provided should be decorated with a for proper functionality.
///
internal AzureAIProjectChatClient(AIProjectClient aiProjectClient, AgentRecord agentRecord, ChatOptions? chatOptions)
- : this(aiProjectClient, Throw.IfNull(agentRecord).Versions.Latest, chatOptions)
+ : this(aiProjectClient, Throw.IfNull(agentRecord).GetLatestVersion(), chatOptions)
{
this._agentRecord = agentRecord;
}
diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs
index 5d2c67695f..b129f4b1f2 100644
--- a/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs
+++ b/dotnet/src/Microsoft.Agents.AI.AzureAI/AzureAIProjectChatClientExtensions.cs
@@ -9,7 +9,8 @@ using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Extensions.OpenAI;
+using Azure.AI.Projects.Agents;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AzureAI;
using Microsoft.Extensions.AI;
@@ -189,7 +190,7 @@ public static partial class AzureAIProjectChatClientExtensions
ThrowIfInvalidAgentName(options.Name);
AgentRecord agentRecord = await GetAgentRecordByNameAsync(aiProjectClient, options.Name, cancellationToken).ConfigureAwait(false);
- var agentVersion = agentRecord.Versions.Latest;
+ var agentVersion = agentRecord.GetLatestVersion();
var agentOptions = CreateChatClientAgentOptions(agentVersion, options, requireInvocableTools: !options.UseProvidedChatClientAsIs);
@@ -361,7 +362,7 @@ public static partial class AzureAIProjectChatClientExtensions
{
ClientResult protocolResponse = await aiProjectClient.Agents.GetAgentAsync(agentName, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
var rawResponse = protocolResponse.GetRawResponse();
- AgentRecord? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
+ AgentRecord? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsAgentsContext.Default);
return result ?? throw new InvalidOperationException($"Agent with name '{agentName}' not found.");
}
@@ -370,11 +371,11 @@ public static partial class AzureAIProjectChatClientExtensions
///
private static async Task CreateAgentVersionWithProtocolAsync(AIProjectClient aiProjectClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
{
- BinaryData serializedOptions = ModelReaderWriter.Write(creationOptions, s_modelWriterOptionsWire, AzureAIProjectsContext.Default);
+ BinaryData serializedOptions = ModelReaderWriter.Write(creationOptions, s_modelWriterOptionsWire, AzureAIProjectsAgentsContext.Default);
BinaryContent content = BinaryContent.Create(serializedOptions);
ClientResult protocolResponse = await aiProjectClient.Agents.CreateAgentVersionAsync(agentName, content, foundryFeatures: null, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
var rawResponse = protocolResponse.GetRawResponse();
- AgentVersion? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
+ AgentVersion? result = ModelReaderWriter.Read(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsAgentsContext.Default);
return result ?? throw new InvalidOperationException($"Failed to create agent version for agent '{agentName}'.");
}
@@ -485,7 +486,7 @@ public static partial class AzureAIProjectChatClientExtensions
=> AsChatClientAgent(
AIProjectClient,
agentRecord,
- CreateChatClientAgentOptions(agentRecord.Versions.Latest, new ChatOptions() { Tools = tools }, requireInvocableTools),
+ CreateChatClientAgentOptions(agentRecord.GetLatestVersion(), new ChatOptions() { Tools = tools }, requireInvocableTools),
clientFactory,
services);
diff --git a/dotnet/src/Microsoft.Agents.AI.AzureAI/Microsoft.Agents.AI.AzureAI.csproj b/dotnet/src/Microsoft.Agents.AI.AzureAI/Microsoft.Agents.AI.AzureAI.csproj
index 2fde79e32b..0cd8690126 100644
--- a/dotnet/src/Microsoft.Agents.AI.AzureAI/Microsoft.Agents.AI.AzureAI.csproj
+++ b/dotnet/src/Microsoft.Agents.AI.AzureAI/Microsoft.Agents.AI.AzureAI.csproj
@@ -15,7 +15,6 @@
-
diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/AgentResponseUpdateExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/AgentResponseUpdateExtensions.cs
index f4c1e3c7a0..ac63237d56 100644
--- a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/AgentResponseUpdateExtensions.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/AgentResponseUpdateExtensions.cs
@@ -196,8 +196,8 @@ internal static class AgentResponseUpdateExtensions
TextReasoningContent => new TextReasoningContentEventGenerator(context.IdGenerator, seq, outputIndex),
FunctionCallContent => new FunctionCallEventGenerator(context.IdGenerator, seq, outputIndex, context.JsonSerializerOptions),
FunctionResultContent => new FunctionResultEventGenerator(context.IdGenerator, seq, outputIndex),
- FunctionApprovalRequestContent => new FunctionApprovalRequestEventGenerator(context.IdGenerator, seq, outputIndex, context.JsonSerializerOptions),
- FunctionApprovalResponseContent => new FunctionApprovalResponseEventGenerator(context.IdGenerator, seq, outputIndex),
+ ToolApprovalRequestContent => new ToolApprovalRequestEventGenerator(context.IdGenerator, seq, outputIndex, context.JsonSerializerOptions),
+ ToolApprovalResponseContent => new ToolApprovalResponseEventGenerator(context.IdGenerator, seq, outputIndex),
ErrorContent => new ErrorContentEventGenerator(context.IdGenerator, seq, outputIndex),
UriContent uriContent when uriContent.HasTopLevelMediaType("image") => new ImageContentEventGenerator(context.IdGenerator, seq, outputIndex),
DataContent dataContent when dataContent.HasTopLevelMediaType("image") => new ImageContentEventGenerator(context.IdGenerator, seq, outputIndex),
diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalRequestEventGenerator.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalRequestEventGenerator.cs
index 4e565b0784..f68fa12e4d 100644
--- a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalRequestEventGenerator.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalRequestEventGenerator.cs
@@ -12,33 +12,37 @@ namespace Microsoft.Agents.AI.Hosting.OpenAI.Responses.Streaming;
/// A generator for streaming events from function approval request content.
/// This is a non-standard DevUI extension for human-in-the-loop scenarios.
///
-internal sealed class FunctionApprovalRequestEventGenerator(
+internal sealed class ToolApprovalRequestEventGenerator(
IdGenerator idGenerator,
SequenceNumber seq,
int outputIndex,
JsonSerializerOptions jsonSerializerOptions) : StreamingEventGenerator
{
- public override bool IsSupported(AIContent content) => content is FunctionApprovalRequestContent;
+ public override bool IsSupported(AIContent content) => content is ToolApprovalRequestContent;
public override IEnumerable ProcessContent(AIContent content)
{
- if (content is not FunctionApprovalRequestContent approvalRequest)
+ if (content is not ToolApprovalRequestContent approvalRequest)
{
- throw new InvalidOperationException("FunctionApprovalRequestEventGenerator only supports FunctionApprovalRequestContent.");
+ throw new InvalidOperationException("ToolApprovalRequestEventGenerator only supports ToolApprovalRequestContent.");
}
+ if (approvalRequest.ToolCall is not FunctionCallContent functionCall)
+ {
+ yield break;
+ }
yield return new StreamingFunctionApprovalRequested
{
SequenceNumber = seq.Increment(),
OutputIndex = outputIndex,
- RequestId = approvalRequest.Id,
+ RequestId = approvalRequest.RequestId,
ItemId = idGenerator.GenerateMessageId(),
FunctionCall = new FunctionCallInfo
{
- Id = approvalRequest.FunctionCall.CallId,
- Name = approvalRequest.FunctionCall.Name,
+ Id = functionCall.CallId,
+ Name = functionCall.Name,
Arguments = JsonSerializer.SerializeToElement(
- approvalRequest.FunctionCall.Arguments,
+ functionCall.Arguments,
jsonSerializerOptions.GetTypeInfo(typeof(IDictionary)))
}
};
diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalResponseEventGenerator.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalResponseEventGenerator.cs
index ab4af8f408..df1379cfbb 100644
--- a/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalResponseEventGenerator.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI/Responses/Streaming/FunctionApprovalResponseEventGenerator.cs
@@ -11,25 +11,25 @@ namespace Microsoft.Agents.AI.Hosting.OpenAI.Responses.Streaming;
/// A generator for streaming events from function approval response content.
/// This is a non-standard DevUI extension for human-in-the-loop scenarios.
///
-internal sealed class FunctionApprovalResponseEventGenerator(
+internal sealed class ToolApprovalResponseEventGenerator(
IdGenerator idGenerator,
SequenceNumber seq,
int outputIndex) : StreamingEventGenerator
{
- public override bool IsSupported(AIContent content) => content is FunctionApprovalResponseContent;
+ public override bool IsSupported(AIContent content) => content is ToolApprovalResponseContent;
public override IEnumerable ProcessContent(AIContent content)
{
- if (content is not FunctionApprovalResponseContent approvalResponse)
+ if (content is not ToolApprovalResponseContent approvalResponse)
{
- throw new InvalidOperationException("FunctionApprovalResponseEventGenerator only supports FunctionApprovalResponseContent.");
+ throw new InvalidOperationException("ToolApprovalResponseEventGenerator only supports ToolApprovalResponseContent.");
}
yield return new StreamingFunctionApprovalResponded
{
SequenceNumber = seq.Increment(),
OutputIndex = outputIndex,
- RequestId = approvalResponse.Id,
+ RequestId = approvalResponse.RequestId,
Approved = approvalResponse.Approved,
ItemId = idGenerator.GenerateMessageId()
};
diff --git a/dotnet/src/Microsoft.Agents.AI.OpenAI/ChatClient/AsyncStreamingChatCompletionUpdateCollectionResult.cs b/dotnet/src/Microsoft.Agents.AI.OpenAI/ChatClient/AsyncStreamingChatCompletionUpdateCollectionResult.cs
index db0c7a8673..34c07ea73f 100644
--- a/dotnet/src/Microsoft.Agents.AI.OpenAI/ChatClient/AsyncStreamingChatCompletionUpdateCollectionResult.cs
+++ b/dotnet/src/Microsoft.Agents.AI.OpenAI/ChatClient/AsyncStreamingChatCompletionUpdateCollectionResult.cs
@@ -1,5 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
+#pragma warning disable OPENAI001 // Experimental OpenAI features
+
using System.ClientModel;
using OpenAI.Chat;
diff --git a/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIResponseClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIResponseClientExtensions.cs
index 09046e1822..5aee8eb046 100644
--- a/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIResponseClientExtensions.cs
+++ b/dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIResponseClientExtensions.cs
@@ -26,6 +26,7 @@ public static class OpenAIResponseClientExtensions
/// Creates an AI agent from an using the OpenAI Response API.
///
/// The to use for the agent.
+ /// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Optional system instructions that define the agent's behavior and personality.
/// Optional name for the agent for identification purposes.
/// Optional description of the agent's capabilities and purpose.
@@ -37,6 +38,7 @@ public static class OpenAIResponseClientExtensions
/// Thrown when is .
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
+ string? model = null,
string? instructions = null,
string? name = null,
string? description = null,
@@ -58,6 +60,7 @@ public static class OpenAIResponseClientExtensions
Tools = tools,
}
},
+ model,
clientFactory,
loggerFactory,
services);
@@ -68,6 +71,7 @@ public static class OpenAIResponseClientExtensions
///
/// The to use for the agent.
/// Full set of options to configure the agent.
+ /// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Provides a way to customize the creation of the underlying used by the agent.
/// Optional logger factory for enabling logging within the agent.
/// An optional to use for resolving services required by the instances being invoked.
@@ -76,6 +80,7 @@ public static class OpenAIResponseClientExtensions
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
ChatClientAgentOptions options,
+ string? model = null,
Func? clientFactory = null,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null)
@@ -83,7 +88,7 @@ public static class OpenAIResponseClientExtensions
Throw.IfNull(client);
Throw.IfNull(options);
- var chatClient = client.AsIChatClient();
+ var chatClient = client.AsIChatClient(model);
if (clientFactory is not null)
{
@@ -100,6 +105,7 @@ public static class OpenAIResponseClientExtensions
/// This corresponds to setting the "store" property in the JSON representation to false.
///
/// The client.
+ /// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
///
/// Includes an encrypted version of reasoning tokens in reasoning item outputs.
/// This enables reasoning items to be used in multi-turn conversations when using the Responses API statelessly
@@ -109,10 +115,10 @@ public static class OpenAIResponseClientExtensions
/// An that can be used to converse via the that does not store responses for later retrieval.
/// is .
[Experimental(DiagnosticIds.Experiments.AgentsAIExperiments)]
- public static IChatClient AsIChatClientWithStoredOutputDisabled(this ResponsesClient responseClient, bool includeReasoningEncryptedContent = true)
+ public static IChatClient AsIChatClientWithStoredOutputDisabled(this ResponsesClient responseClient, string? model = null, bool includeReasoningEncryptedContent = true)
{
return Throw.IfNull(responseClient)
- .AsIChatClient()
+ .AsIChatClient(model)
.AsBuilder()
.ConfigureOptions(x => x.RawRepresentationFactory = _ => includeReasoningEncryptedContent
? new CreateResponseOptions() { StoredOutputEnabled = false, IncludedProperties = { IncludedResponseProperty.ReasoningEncryptedContent } }
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.AzureAI/AzureAgentProvider.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.AzureAI/AzureAgentProvider.cs
index 9f909ad84e..bfc7bd36ff 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.AzureAI/AzureAgentProvider.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.AzureAI/AzureAgentProvider.cs
@@ -10,8 +10,9 @@ using System.Runtime.CompilerServices;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
+using Azure.AI.Extensions.OpenAI;
using Azure.AI.Projects;
-using Azure.AI.Projects.OpenAI;
+using Azure.AI.Projects.Agents;
using Azure.Core;
using Microsoft.Extensions.AI;
using OpenAI.Responses;
@@ -149,7 +150,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
agentName,
cancellationToken).ConfigureAwait(false);
- targetAgent = agentRecord.Versions.Latest;
+ targetAgent = agentRecord.GetLatestVersion();
}
else
{
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs
index 107f4f0260..681cd5dc85 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs
@@ -185,8 +185,8 @@ public sealed class DefaultMcpToolHandler : IMcpToolHandler, IAsyncDisposable
private static void PopulateResultContent(McpServerToolResultContent resultContent, CallToolResult result)
{
- // Ensure Output list is initialized
- resultContent.Output ??= [];
+ // Ensure Outputs list is initialized
+ resultContent.Outputs ??= [];
if (result.IsError == true)
{
@@ -203,7 +203,7 @@ public sealed class DefaultMcpToolHandler : IMcpToolHandler, IAsyncDisposable
}
}
- resultContent.Output.Add(new TextContent($"Error: {errorText ?? "Unknown error from MCP Server call"}"));
+ resultContent.Outputs.Add(new TextContent($"Error: {errorText ?? "Unknown error from MCP Server call"}"));
return;
}
@@ -218,7 +218,7 @@ public sealed class DefaultMcpToolHandler : IMcpToolHandler, IAsyncDisposable
AIContent content = ConvertContentBlock(block);
if (content is not null)
{
- resultContent.Output.Add(content);
+ resultContent.Outputs.Add(content);
}
}
}
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs
index c8cde902fa..24653af0f2 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeAzureAgentExecutor.cs
@@ -150,7 +150,7 @@ internal sealed class InvokeAzureAgentExecutor(InvokeAzureAgent model, ResponseA
foreach (ChatMessage responseMessage in agentResponse.Messages)
{
- if (responseMessage.Contents.Any(content => content is UserInputRequestContent))
+ if (responseMessage.Contents.Any(content => content is ToolApprovalRequestContent))
{
yield return responseMessage;
continue;
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs
index 0e95bebe63..baa6f9c6b8 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs
@@ -68,7 +68,7 @@ internal sealed class InvokeFunctionToolExecutor(
// If approval is required, add user input request content
if (requireApproval)
{
- requestMessage.Contents.Add(new FunctionApprovalRequestContent(this.Id, functionCall));
+ requestMessage.Contents.Add(new ToolApprovalRequestContent(this.Id, functionCall));
}
AgentResponse agentResponse = new([requestMessage]);
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs
index 45929f20f7..b1d9a44269 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs
@@ -85,7 +85,7 @@ internal sealed class InvokeMcpToolExecutor(
toolCall.AdditionalProperties.Add(headers);
}
- McpServerToolApprovalRequestContent approvalRequest = new(this.Id, toolCall);
+ ToolApprovalRequestContent approvalRequest = new(this.Id, toolCall);
ChatMessage requestMessage = new(ChatRole.Assistant, [approvalRequest]);
AgentResponse agentResponse = new([requestMessage]);
@@ -127,11 +127,10 @@ internal sealed class InvokeMcpToolExecutor(
ExternalInputResponse response,
CancellationToken cancellationToken)
{
- // Check for approval response
- McpServerToolApprovalResponseContent? approvalResponse = response.Messages
+ ToolApprovalResponseContent? approvalResponse = response.Messages
.SelectMany(m => m.Contents)
- .OfType()
- .FirstOrDefault(r => r.Id == this.Id);
+ .OfType()
+ .FirstOrDefault(r => r.RequestId == this.Id);
if (approvalResponse?.Approved != true)
{
@@ -174,7 +173,7 @@ internal sealed class InvokeMcpToolExecutor(
string? conversationId = this.GetConversationId();
await this.AssignResultAsync(context, resultContent).ConfigureAwait(false);
- ChatMessage resultMessage = new(ChatRole.Tool, resultContent.Output);
+ ChatMessage resultMessage = new(ChatRole.Tool, resultContent.Outputs);
// Store messages if output path is configured
if (this.Model.Output?.Messages is not null)
@@ -192,20 +191,20 @@ internal sealed class InvokeMcpToolExecutor(
// Add messages to conversation if conversationId is provided
if (conversationId is not null)
{
- ChatMessage assistantMessage = new(ChatRole.Assistant, resultContent.Output);
+ ChatMessage assistantMessage = new(ChatRole.Assistant, resultContent.Outputs);
await agentProvider.CreateMessageAsync(conversationId, assistantMessage, cancellationToken).ConfigureAwait(false);
}
}
private async ValueTask AssignResultAsync(IWorkflowContext context, McpServerToolResultContent toolResult)
{
- if (this.Model.Output?.Result is null || toolResult.Output is null || toolResult.Output.Count == 0)
+ if (this.Model.Output?.Result is null || toolResult.Outputs is null || toolResult.Outputs.Count == 0)
{
return;
}
List