.NET: Feature foundry agent/update breaking v2.0 to v1.2 (#2212)

* Migration WIP Checkpoint 1

* Build + UT + Workflow passing

* Address latest commits after break

* Revert rename in unrelated files

* Address PR comments

* Class renames
This commit is contained in:
Roger Barreto
2025-11-14 12:20:56 +00:00
committed by GitHub
Unverified
parent 7c90690067
commit 0746d7751a
66 changed files with 652 additions and 669 deletions
+2 -1
View File
@@ -17,7 +17,8 @@
<PackageVersion Include="Aspire.Microsoft.Azure.Cosmos" Version="$(AspireAppHostSdkVersion)" />
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="13.0.0-beta.435" />
<!-- Azure.* -->
<PackageVersion Include="Azure.AI.Agents" Version="2.0.0-alpha.20251107.3" />
<PackageVersion Include="Azure.AI.Projects" Version="1.2.0-alpha.20251113.7" />
<PackageVersion Include="Azure.AI.Projects.OpenAI" Version="1.0.0-alpha.20251113.7" />
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.2.0-beta.7" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
<PackageVersion Include="Azure.Identity" Version="1.17.0" />
+2 -2
View File
@@ -44,8 +44,8 @@
<Folder Name="/Samples/GettingStarted/AgentProviders/">
<File Path="samples/GettingStarted/AgentProviders/README.md" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_A2A/Agent_With_A2A.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureAIAgent/Agent_With_AzureAIAgent.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureFoundryAgent/Agent_With_AzureFoundryAgent.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureAIAgentsPersistent/Agent_With_AzureAIAgentsPersistent.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Agent_With_AzureAIProject.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureFoundryModel/Agent_With_AzureFoundryModel.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureOpenAIChatCompletion/Agent_With_AzureOpenAIChatCompletion.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureOpenAIResponses/Agent_With_AzureOpenAIResponses.csproj" />
+1 -1
View File
@@ -10,7 +10,7 @@
<package pattern="*" />
</packageSource>
<packageSource key="azure-sdk-for-net">
<package pattern="Azure.AI.Agents" />
<package pattern="Azure.AI.Project*" />
</packageSource>
</packageSourceMapping>
</configuration>
@@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -2,7 +2,8 @@
// This sample shows how to create and use a AI agents with Azure Foundry Agents as the backend.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -13,13 +14,13 @@ const string JokerInstructions = "You are good at telling jokes.";
const string JokerName = "JokerAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
var agentsClient = new AgentClient(new Uri(endpoint), new AzureCliCredential());
var aiProjectClient = new AIProjectClient(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
var agentVersionCreationOptions = new AgentVersionCreationOptions(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
// Azure.AI.Agents SDK creates and manages agent by name and versions.
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
var agentVersion = agentsClient.CreateAgentVersion(agentName: JokerName, options: agentVersionCreationOptions);
var agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options: agentVersionCreationOptions);
// Note:
// agentVersion.Id = "<agentName>:<versionNumber>",
@@ -27,13 +28,13 @@ var agentVersion = agentsClient.CreateAgentVersion(agentName: JokerName, options
// agentVersion.Name = <agentName>
// You can retrieve an AIAgent for a already created server side agent version.
AIAgent jokerAgentV1 = agentsClient.GetAIAgent(agentVersion);
AIAgent jokerAgentV1 = aiProjectClient.GetAIAgent(agentVersion);
// You can also create another AIAgent version (V2) by providing the same name with a different definition.
AIAgent jokerAgentV2 = agentsClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2");
AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2");
// You can also get the AIAgent latest version just providing its name.
AIAgent jokerAgentLatest = agentsClient.GetAIAgent(name: JokerName);
AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName);
var latestVersion = jokerAgentLatest.GetService<AgentVersion>()!;
// The AIAgent version can be accessed via the GetService method.
@@ -47,7 +48,4 @@ Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate
Console.WriteLine(await jokerAgentLatest.RunAsync("Now tell me a joke about a cat and a dog using last joke as the anchor.", thread));
// Cleanup by agent name removes both agent versions created (jokerAgentV1 + jokerAgentV2).
agentsClient.DeleteAgent(jokerAgentV1.Name);
// It is also possible delete just a specific agent version by the composition (name + version number).
// agentsClient.DeleteAgentVersion(latestVersion.Name, latestVersion.Version);
aiProjectClient.Agents.DeleteAgent(jokerAgentV1.Name);
@@ -15,7 +15,8 @@ See the README.md for each sample for the prerequisites for that sample.
|Sample|Description|
|---|---|
|[Creating an AIAgent with A2A](./Agent_With_A2A/)|This sample demonstrates how to create AIAgent for an existing A2A agent.|
|[Creating an AIAgent with AzureFoundry Agent](./Agent_With_AzureFoundryAgent/)|This sample demonstrates how to create an Azure Foundry agent and expose it as an AIAgent|
|[Creating an AIAgent with Foundry Agents using Azure.AI.Agents.Persistent](./Agent_With_AzureAIAgentsPersistent/)|This sample demonstrates how to create a Foundry Persistent agent and expose it as an AIAgent using the Azure.AI.Agents.Persistent SDK|
|[Creating an AIAgent with Foundry Agents using Azure.AI.Project](./Agent_With_AzureAIProject/)|This sample demonstrates how to create an Foundry Project agent and expose it as an AIAgent using the Azure.AI.Project SDK|
|[Creating an AIAgent with AzureFoundry Model](./Agent_With_AzureFoundryModel/)|This sample demonstrates how to use any model deployed to Azure Foundry to create an AIAgent|
|[Creating an AIAgent with Azure OpenAI ChatCompletion](./Agent_With_AzureOpenAIChatCompletion/)|This sample demonstrates how to create an AIAgent using Azure OpenAI ChatCompletion as the underlying inference service|
|[Creating an AIAgent with Azure OpenAI Responses](./Agent_With_AzureOpenAIResponses/)|This sample demonstrates how to create an AIAgent using Azure OpenAI Responses as the underlying inference service|
@@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -2,7 +2,8 @@
// This sample shows how to create and use AI agents with Azure Foundry Agents as the backend.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -14,14 +15,14 @@ const string JokerInstructions = "You are good at telling jokes.";
const string JokerName = "JokerAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
// Azure.AI.Agents SDK creates and manages agent by name and versions.
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
AgentVersion agentVersion = agentClient.CreateAgentVersion(agentName: JokerName, options);
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
// Note:
// agentVersion.Id = "<agentName>:<versionNumber>",
@@ -29,13 +30,13 @@ AgentVersion agentVersion = agentClient.CreateAgentVersion(agentName: JokerName,
// agentVersion.Name = <agentName>
// You can retrieve an AIAgent for an already created server side agent version.
AIAgent jokerAgentV1 = agentClient.GetAIAgent(agentVersion);
AIAgent jokerAgentV1 = aiProjectClient.GetAIAgent(agentVersion);
// You can also create another AIAgent version (V2) by providing the same name with a different definition.
AIAgent jokerAgentV2 = agentClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2");
AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2");
// You can also get the AIAgent latest version by just providing its name.
AIAgent jokerAgentLatest = agentClient.GetAIAgent(name: JokerName);
AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName);
AgentVersion latestVersion = jokerAgentLatest.GetService<AgentVersion>()!;
// The AIAgent version can be accessed via the GetService method.
@@ -49,7 +50,4 @@ Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate
Console.WriteLine(await jokerAgentLatest.RunAsync("Now tell me a joke about a cat and a dog using last joke as the anchor.", thread));
// Cleanup by agent name removes both agent versions created (jokerAgentV1 + jokerAgentV2).
await agentClient.DeleteAgentAsync(jokerAgentV1.Name);
// It is also possible delete just a specific agent version by the composition (name + version number).
// agentClient.DeleteAgentVersion(latestVersion.Name, latestVersion.Version);
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgentV1.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -2,7 +2,8 @@
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -13,17 +14,17 @@ const string JokerInstructions = "You are good at telling jokes.";
const string JokerName = "JokerAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
// Azure.AI.Agents SDK creates and manages agent by name and versions.
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
AgentVersion agentVersion = agentClient.CreateAgentVersion(agentName: JokerName, options);
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
// You can retrieve an AIAgent for a already created server side agent version.
AIAgent jokerAgent = agentClient.GetAIAgent(agentVersion);
AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion);
// Invoke the agent and output the text result.
AgentThread thread = jokerAgent.GetNewThread();
@@ -37,4 +38,4 @@ await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Te
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(jokerAgent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -2,7 +2,8 @@
// This sample shows how to create and use a simple AI agent with a multi-turn conversation.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -13,16 +14,16 @@ const string JokerInstructions = "You are good at telling jokes.";
const string JokerName = "JokerAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
// Create a server side agent version with the Azure.AI.Agents SDK client.
AgentVersion agentVersion = agentClient.CreateAgentVersion(agentName: JokerName, options);
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
// Retrieve an AIAgent for the created server side agent version.
AIAgent jokerAgent = agentClient.GetAIAgent(agentVersion);
AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion);
// Invoke the agent with a multi-turn conversation, where the context is preserved in the thread object.
AgentThread thread = jokerAgent.GetNewThread();
@@ -41,4 +42,4 @@ await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("No
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(jokerAgent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -4,7 +4,7 @@
// It shows both non-streaming and streaming agent interactions using weather-related tools.
using System.ComponentModel;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -20,13 +20,13 @@ const string AssistantInstructions = "You are a helpful assistant that can get w
const string AssistantName = "WeatherAssistant";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent with function tools.
AITool tool = AIFunctionFactory.Create(GetWeather);
// Create AIAgent directly
AIAgent agent = await agentClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [tool]);
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [tool]);
// Non-streaming agent interaction with function tools.
AgentThread thread = agent.GetNewThread();
@@ -40,4 +40,4 @@ await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("What is
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.OpenApi" />
</ItemGroup>
@@ -3,7 +3,7 @@
// This sample demonstrates how to use an agent with function tools provided via an OpenAPI spec.
// It uses functionality from Semantic Kernel to parse the OpenAPI spec and create function tools to use with the Agent Framework Agent.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -25,14 +25,14 @@ const string AssistantInstructions = "You are a helpful assistant that can query
const string AssistantName = "GitHubAssistant";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Create AIAgent directly
AIAgent agent = await agentClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: tools);
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: tools);
// Run the agent with the OpenAPI function tools.
AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("Please list the names, colors and descriptions of all the labels available in the microsoft/agent-framework repository on github.", thread));
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -6,7 +6,7 @@
// while the agent is waiting for user input.
using System.ComponentModel;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -23,12 +23,12 @@ const string AssistantInstructions = "You are a helpful assistant that can get w
const string AssistantName = "WeatherAssistant";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
ApprovalRequiredAIFunction approvalTool = new(AIFunctionFactory.Create(GetWeather));
// Create AIAgent directly
AIAgent agent = await agentClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [approvalTool]);
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [approvalTool]);
// Call the agent with approval-required function tools.
// The agent will request approval before invoking the function.
@@ -61,4 +61,4 @@ while (userInputRequests.Count > 0)
Console.WriteLine($"\nAgent: {response}");
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -5,7 +5,7 @@
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using SampleApp;
@@ -19,10 +19,10 @@ const string AssistantInstructions = "You are a helpful assistant that extracts
const string AssistantName = "StructuredOutputAssistant";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Create ChatClientAgent directly
ChatClientAgent agent = await agentClient.CreateAIAgentAsync(
ChatClientAgent agent = await aiProjectClient.CreateAIAgentAsync(
model: deploymentName,
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
{
@@ -42,7 +42,7 @@ Console.WriteLine($"Age: {response.Result.Age}");
Console.WriteLine($"Occupation: {response.Result.Occupation}");
// Create the ChatClientAgent with the specified name, instructions, and expected structured output the agent should produce.
ChatClientAgent agentWithPersonInfo = agentClient.CreateAIAgent(
ChatClientAgent agentWithPersonInfo = aiProjectClient.CreateAIAgent(
model: deploymentName,
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
{
@@ -65,7 +65,7 @@ Console.WriteLine($"Age: {personInfo.Age}");
Console.WriteLine($"Occupation: {personInfo.Occupation}");
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
namespace SampleApp
{
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -3,7 +3,7 @@
// This sample shows how to create and use a simple AI agent with a conversation that can be persisted to disk.
using System.Text.Json;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -14,9 +14,9 @@ const string JokerInstructions = "You are good at telling jokes.";
const string JokerName = "JokerAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
AIAgent agent = await agentClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: JokerInstructions);
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: JokerInstructions);
// Start a new thread for the agent conversation.
AgentThread thread = agent.GetNewThread();
@@ -41,4 +41,4 @@ AgentThread resumedThread = agent.DeserializeThread(reloadedSerializedThread);
Console.WriteLine(await agent.RunAsync("Now tell the same joke in the voice of a pirate, and add some emojis to the joke.", resumedThread));
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" />
<PackageReference Include="OpenTelemetry" />
@@ -2,7 +2,7 @@
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend that logs telemetry using OpenTelemetry.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Agents.AI;
@@ -29,10 +29,10 @@ if (!string.IsNullOrWhiteSpace(applicationInsightsConnectionString))
using var tracerProvider = tracerProviderBuilder.Build();
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
AIAgent agent = agentClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions)
AIAgent agent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions)
.AsBuilder()
.UseOpenTelemetry(sourceName: sourceName)
.Build();
@@ -49,4 +49,4 @@ await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("Tell me
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
@@ -2,7 +2,7 @@
// This sample shows how to use dependency injection to register an AIAgent and use it from a hosted service with a user input chat loop.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
@@ -18,11 +18,11 @@ const string JokerName = "JokerAgent";
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
// Add the agents client to the service collection.
builder.Services.AddSingleton((sp) => new AgentClient(new Uri(endpoint), new AzureCliCredential()));
builder.Services.AddSingleton((sp) => new AIProjectClient(new Uri(endpoint), new AzureCliCredential()));
// Add the AI agent to the service collection.
builder.Services.AddSingleton<AIAgent>((sp)
=> sp.GetRequiredService<AgentClient>()
=> sp.GetRequiredService<AIProjectClient>()
.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions));
// Add a sample service that will use the agent to respond to user input.
@@ -35,7 +35,7 @@ await host.RunAsync().ConfigureAwait(false);
/// <summary>
/// A sample service that uses an AI agent to respond to user input.
/// </summary>
internal sealed class SampleService(AgentClient client, AIAgent agent, IHostApplicationLifetime appLifetime) : IHostedService
internal sealed class SampleService(AIProjectClient client, AIAgent agent, IHostApplicationLifetime appLifetime) : IHostedService
{
private AgentThread? _thread;
@@ -77,6 +77,6 @@ internal sealed class SampleService(AgentClient client, AIAgent agent, IHostAppl
public async Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("\nDeleting agent ...");
await client.DeleteAgentAsync(agent.Name, cancellationToken).ConfigureAwait(false);
await client.Agents.DeleteAgentAsync(agent.Name, cancellationToken).ConfigureAwait(false);
}
}
@@ -5,7 +5,7 @@ This sample demonstrates how to use dependency injection to register and manage
## What this sample demonstrates
- Setting up dependency injection with HostApplicationBuilder
- Registering AgentClient as a singleton service
- Registering AIProjectClient as a singleton service
- Registering AIAgent as a singleton service
- Using agents in hosted services
- Interactive chat loop with streaming responses
@@ -42,7 +42,7 @@ dotnet run --project .\FoundryAgents_Step08_DependencyInjection
The sample will:
1. Create a host with dependency injection configured
2. Register AgentClient and AIAgent as services
2. Register AIProjectClient and AIAgent as services
3. Create an agent named "JokerAgent" with instructions to tell jokes
4. Start an interactive chat loop where you can ask the agent questions
5. The agent will respond with streaming output
@@ -2,7 +2,7 @@
// This sample shows how to expose an AI agent as an MCP tool.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -25,12 +25,12 @@ await using var mcpClient = await McpClient.CreateAsync(new StdioClientTransport
IList<McpClientTool> mcpTools = await mcpClient.ListToolsAsync();
string agentName = "AgentWithMCP";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
Console.WriteLine($"Creating the agent '{agentName}' ...");
// Define the agent you want to create. (Prompt Agent in this case)
AIAgent agent = agentClient.CreateAIAgent(
AIAgent agent = aiProjectClient.CreateAIAgent(
name: agentName,
model: deploymentName,
instructions: "You answer questions related to GitHub repositories only.",
@@ -44,4 +44,4 @@ Console.WriteLine($"Invoking agent '{agent.Name}' with prompt: {prompt} ...");
Console.WriteLine(await agent.RunAsync(prompt));
// Clean up the agent after use.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -2,7 +2,7 @@
// This sample shows how to use Image Multi-Modality with an AI agent.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -14,10 +14,10 @@ const string VisionInstructions = "You are a helpful agent that can analyze imag
const string VisionName = "VisionAgent";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent you want to create. (Prompt Agent in this case)
AIAgent agent = agentClient.CreateAIAgent(name: VisionName, model: deploymentName, instructions: VisionInstructions);
AIAgent agent = aiProjectClient.CreateAIAgent(name: VisionName, model: deploymentName, instructions: VisionInstructions);
ChatMessage message = new(ChatRole.User, [
new TextContent("What do you see in this image?"),
@@ -32,4 +32,4 @@ await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(message,
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
@@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
@@ -3,7 +3,7 @@
// This sample shows how to create and use an Azure Foundry Agents AI agent as a function tool.
using System.ComponentModel;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -21,18 +21,18 @@ static string GetWeather([Description("The location to get the weather for.")] s
=> $"The weather in {location} is cloudy with a high of 15°C.";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Create the weather agent with function tools.
AITool weatherTool = AIFunctionFactory.Create(GetWeather);
AIAgent weatherAgent = agentClient.CreateAIAgent(
AIAgent weatherAgent = aiProjectClient.CreateAIAgent(
name: WeatherName,
model: deploymentName,
instructions: WeatherInstructions,
tools: [weatherTool]);
// Create the main agent, and provide the weather agent as a function tool.
AIAgent agent = agentClient.CreateAIAgent(
AIAgent agent = aiProjectClient.CreateAIAgent(
name: MainName,
model: deploymentName,
instructions: MainInstructions,
@@ -43,5 +43,5 @@ AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", thread));
// Cleanup by agent name removes the agent versions created.
await agentClient.DeleteAgentAsync(agent.Name);
await agentClient.DeleteAgentAsync(weatherAgent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(weatherAgent.Name);
@@ -11,7 +11,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
</ItemGroup>
<ItemGroup>
@@ -7,7 +7,7 @@
using System.ComponentModel;
using System.Text.RegularExpressions;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -20,7 +20,7 @@ const string AssistantInstructions = "You are an AI assistant that helps people
const string AssistantName = "InformationAssistant";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
@@ -34,7 +34,7 @@ AITool dateTimeTool = AIFunctionFactory.Create(GetDateTime, name: nameof(GetDate
AITool getWeatherTool = AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather));
// Define the agent you want to create. (Prompt Agent in this case)
AIAgent originalAgent = agentClient.CreateAIAgent(
AIAgent originalAgent = aiProjectClient.CreateAIAgent(
name: AssistantName,
model: deploymentName,
instructions: AssistantInstructions,
@@ -69,7 +69,7 @@ Console.WriteLine($"Function calling response: {functionCallResponse}");
// Special per-request middleware agent.
Console.WriteLine("\n\n=== Example 4: Middleware with human in the loop function approval ===");
AIAgent humamInTheLoopAgent = agentClient.CreateAIAgent(
AIAgent humanInTheLoopAgent = aiProjectClient.CreateAIAgent(
name: "HumanInTheLoopAgent",
model: deploymentName,
instructions: "You are an Human in the loop testing AI assistant that helps people find information.",
@@ -78,13 +78,13 @@ AIAgent humamInTheLoopAgent = agentClient.CreateAIAgent(
tools: [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather)))]);
// Using the ConsolePromptingApprovalMiddleware for a specific request to handle user approval during function calls.
AgentRunResponse response = await humamInTheLoopAgent
AgentRunResponse response = await humanInTheLoopAgent
.AsBuilder()
.Use(ConsolePromptingApprovalMiddleware, null)
.Build()
.RunAsync("What's the current time and the weather in Seattle?");
Console.WriteLine($"HumamInTheLoopAgent agent middleware response: {response}");
Console.WriteLine($"HumanInTheLoopAgent agent middleware response: {response}");
// Function invocation middleware that logs before and after function calls.
async ValueTask<object?> FunctionCallMiddleware(AIAgent agent, FunctionInvocationContext context, Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next, CancellationToken cancellationToken)
@@ -220,4 +220,4 @@ async Task<AgentRunResponse> ConsolePromptingApprovalMiddleware(IEnumerable<Chat
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(middlewareEnabledAgent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(middlewareEnabledAgent.Name);
@@ -4,7 +4,7 @@ This sample demonstrates how to add middleware to intercept agent runs and funct
## What This Sample Shows
1. Azure Foundry Agents integration via `AgentClient` and `AzureCliCredential`
1. Azure Foundry Agents integration via `AIProjectClient` and `AzureCliCredential`
2. Agent run middleware (logging and monitoring)
3. Function invocation middleware (logging and overriding tool results)
4. Per-request agent run middleware
@@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
</ItemGroup>
<ItemGroup>
@@ -9,7 +9,7 @@
// as AI functions. The AsAITools method of the plugin class shows how to specify
// which methods should be exposed to the AI agent.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -30,11 +30,11 @@ services.AddSingleton<AgentPlugin>(); // The plugin depends on WeatherProvider a
IServiceProvider serviceProvider = services.BuildServiceProvider();
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Define the agent with plugin tools
// Define the agent you want to create. (Prompt Agent in this case)
AIAgent agent = agentClient.CreateAIAgent(
AIAgent agent = aiProjectClient.CreateAIAgent(
name: AssistantName,
model: deploymentName,
instructions: AssistantInstructions,
@@ -46,7 +46,7 @@ AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("Tell me current time and weather in Seattle.", thread));
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agent.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
/// <summary>
/// The agent plugin that provides weather and current time information.
@@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
</ItemGroup>
<ItemGroup>
@@ -3,7 +3,8 @@
// This sample shows how to use Code Interpreter Tool with AI Agents.
using System.Text;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -18,11 +19,11 @@ const string AgentNameMEAI = "CoderAgent-MEAI";
const string AgentNameNative = "CoderAgent-NATIVE";
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
AgentClient agentClient = new(new Uri(endpoint), new AzureCliCredential());
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
// Option 1 - Using HostedCodeInterpreterTool + AgentOptions (MEAI + AgentFramework)
// Create the server side agent version
AIAgent agentOption1 = await agentClient.CreateAIAgentAsync(
AIAgent agentOption1 = await aiProjectClient.CreateAIAgentAsync(
model: deploymentName,
name: AgentNameMEAI,
instructions: AgentInstructions,
@@ -30,7 +31,7 @@ AIAgent agentOption1 = await agentClient.CreateAIAgentAsync(
// Option 2 - Using PromptAgentDefinition SDK native type
// Create the server side agent version
AIAgent agentOption2 = await agentClient.CreateAIAgentAsync(
AIAgent agentOption2 = await aiProjectClient.CreateAIAgentAsync(
name: AgentNameNative,
creationOptions: new AgentVersionCreationOptions(
new PromptAgentDefinition(model: deploymentName)
@@ -85,5 +86,5 @@ foreach (AIAnnotation annotation in response.Messages.SelectMany(m => m.Contents
}
// Cleanup by agent name removes the agent version created.
await agentClient.DeleteAgentAsync(agentOption1.Name);
await agentClient.DeleteAgentAsync(agentOption2.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agentOption1.Name);
await aiProjectClient.Agents.DeleteAgentAsync(agentOption2.Name);
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
@@ -60,34 +61,34 @@ internal sealed class Program
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration, TicketingPlugin plugin)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "SelfServiceAgent",
agentDefinition: DefineSelfServiceAgent(configuration),
agentDescription: "Service agent for CustomerSupport workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TicketingAgent",
agentDefinition: DefineTicketingAgent(configuration, plugin),
agentDescription: "Ticketing agent for CustomerSupport workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TicketRoutingAgent",
agentDefinition: DefineTicketRoutingAgent(configuration, plugin),
agentDescription: "Routing agent for CustomerSupport workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "WindowsSupportAgent",
agentDefinition: DefineWindowsSupportAgent(configuration, plugin),
agentDescription: "Windows support agent for CustomerSupport workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TicketResolutionAgent",
agentDefinition: DefineResolutionAgent(configuration, plugin),
agentDescription: "Resolution agent for CustomerSupport workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TicketEscalationAgent",
agentDefinition: TicketEscalationAgent(configuration, plugin),
agentDescription: "Escalate agent for human support");
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
@@ -46,39 +47,39 @@ internal sealed class Program
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "ResearchAgent",
agentDefinition: DefineResearchAgent(configuration),
agentDescription: "Planner agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "PlannerAgent",
agentDefinition: DefinePlannerAgent(configuration),
agentDescription: "Planner agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "ManagerAgent",
agentDefinition: DefineManagerAgent(configuration),
agentDescription: "Manager agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "SummaryAgent",
agentDefinition: DefineSummaryAgent(configuration),
agentDescription: "Summary agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "KnowledgeAgent",
agentDefinition: DefineKnowledgeAgent(configuration),
agentDescription: "Research agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "CoderAgent",
agentDefinition: DefineCoderAgent(configuration),
agentDescription: "Coder agent for DeepResearch workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "WeatherAgent",
agentDefinition: DefineWeatherAgent(configuration),
agentDescription: "Weather agent for DeepResearch workflow");
@@ -271,10 +272,10 @@ internal sealed class Program
Tools =
{
AgentTool.CreateOpenApiTool(
new OpenApiFunctionDefinition(
new OpenAPIFunctionDefinition(
"weather-forecast",
BinaryData.FromString(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "wttr.json"))),
new OpenApiAnonymousAuthDetails()))
new OpenAPIAnonymousAuthenticationDetails()))
}
};
}
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
@@ -55,9 +56,9 @@ internal sealed class Program
private static async Task CreateAgentAsync(Uri foundryEndpoint, IConfiguration configuration, AIFunction[] functions)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "MenuAgent",
agentDefinition: DefineMenuAgent(configuration, functions),
agentDescription: "Provides information about the restaurant menu");
@@ -3,7 +3,8 @@
// Uncomment this to enable JSON checkpointing to the local file system.
//#define CHECKPOINT_JSON
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
@@ -34,23 +35,26 @@ internal sealed class Program
Uri foundryEndpoint = new(configuration.GetValue(Application.Settings.FoundryEndpoint));
// Create the agent service client
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
// Ensure sample agents exist in Foundry.
await CreateAgentsAsync(agentClient, configuration);
await CreateAgentsAsync(aiProjectClient, configuration);
// Ensure workflow agent exists in Foundry.
AgentVersion agentVersion = await CreateWorkflowAsync(agentClient, configuration);
AgentVersion agentVersion = await CreateWorkflowAsync(aiProjectClient, configuration);
string workflowInput = GetWorkflowInput(args);
AIAgent agent = agentClient.GetAIAgent(agentVersion);
AIAgent agent = aiProjectClient.GetAIAgent(agentVersion);
AgentThread thread = agent.GetNewThread();
AgentConversation conversation =
await agentClient.GetConversationClient()
.CreateConversationAsync().ConfigureAwait(false);
ProjectConversation conversation =
await aiProjectClient
.GetProjectOpenAIClient()
.GetProjectConversationsClient()
.CreateProjectConversationAsync()
.ConfigureAwait(false);
Console.WriteLine($"CONVERSATION: {conversation.Id}");
@@ -77,7 +81,7 @@ internal sealed class Program
}
}
private static async Task<AgentVersion> CreateWorkflowAsync(AgentClient agentClient, IConfiguration configuration)
private static async Task<AgentVersion> CreateWorkflowAsync(AIProjectClient agentClient, IConfiguration configuration)
{
string workflowYaml = File.ReadAllText("MathChat.yaml");
@@ -90,7 +94,7 @@ internal sealed class Program
agentDescription: "The student attempts to solve the input problem and the teacher provides guidance.");
}
private static async Task CreateAgentsAsync(AgentClient agentClient, IConfiguration configuration)
private static async Task CreateAgentsAsync(AIProjectClient agentClient, IConfiguration configuration)
{
await agentClient.CreateAgentAsync(
agentName: "StudentAgent",
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
@@ -46,19 +47,19 @@ internal sealed class Program
private static async Task CreateAgentAsync(Uri foundryEndpoint, IConfiguration configuration)
{
AgentClient agentsClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentsClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "LocationTriageAgent",
agentDefinition: DefineLocationTriageAgent(configuration),
agentDescription: "Chats with the user to solicit a location of interest.");
await agentsClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "LocationCaptureAgent",
agentDefinition: DefineLocationCaptureAgent(configuration),
agentDescription: "Evaluate the status of soliciting the location.");
await agentsClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "LocationAwareAgent",
agentDefinition: DefineLocationAwareAgent(configuration),
agentDescription: "Chats with the user with location awareness.");
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -45,19 +46,19 @@ internal sealed class Program
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "AnalystAgent",
agentDefinition: DefineAnalystAgent(configuration),
agentDescription: "Analyst agent for Marketing workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "WriterAgent",
agentDefinition: DefineWriterAgent(configuration),
agentDescription: "Writer agent for Marketing workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "EditorAgent",
agentDefinition: DefineEditorAgent(configuration),
agentDescription: "Editor agent for Marketing workflow");
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -45,14 +46,14 @@ internal sealed class Program
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "StudentAgent",
agentDefinition: DefineStudentAgent(configuration),
agentDescription: "Student agent for MathChat workflow");
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TeacherAgent",
agentDefinition: DefineTeacherAgent(configuration),
agentDescription: "Teacher agent for MathChat workflow");
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using OpenAI.Responses;
@@ -46,9 +47,9 @@ internal sealed class Program
private static async Task CreateAgentAsync(Uri foundryEndpoint, IConfiguration configuration)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "DocumentSearchAgent",
agentDefinition: DefineSearchAgent(configuration),
agentDescription: "Searches documents on Microsoft Learn");
@@ -1,12 +1,10 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ClientModel.Primitives;
using System.Runtime.CompilerServices;
using System.Text;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Microsoft.Extensions.AI;
using Microsoft.Shared.Diagnostics;
using OpenAI;
using OpenAI.Responses;
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
@@ -17,10 +15,10 @@ namespace Microsoft.Agents.AI.AzureAI;
/// Provides a chat client implementation that integrates with Azure AI Agents, enabling chat interactions using
/// Azure-specific agent capabilities.
/// </summary>
internal sealed class AzureAIAgentChatClient : DelegatingChatClient
internal sealed class AzureAIProjectChatClient : DelegatingChatClient
{
private readonly ChatClientMetadata? _metadata;
private readonly AgentClient _agentClient;
private readonly AIProjectClient _agentClient;
private readonly AgentVersion? _agentVersion;
private readonly AgentRecord? _agentRecord;
private readonly ChatOptions? _chatOptions;
@@ -32,51 +30,48 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
private const string NoOpModel = "no-op";
/// <summary>
/// Initializes a new instance of the <see cref="AzureAIAgentChatClient"/> class.
/// Initializes a new instance of the <see cref="AzureAIProjectChatClient"/> class.
/// </summary>
/// <param name="agentClient">An instance of <see cref="AgentClient"/> to interact with Azure AI Agents services.</param>
/// <param name="aiProjectClient">An instance of <see cref="AIProjectClient"/> to interact with Azure AI Agents services.</param>
/// <param name="agentReference">An instance of <see cref="AgentReference"/> representing the specific agent to use.</param>
/// <param name="defaultModelId">The default model to use for the agent, if applicable.</param>
/// <param name="chatOptions">An instance of <see cref="ChatOptions"/> representing the options on how the agent was predefined.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <remarks>
/// The <see cref="IChatClient"/> provided should be decorated with a <see cref="AzureAIAgentChatClient"/> for proper functionality.
/// The <see cref="IChatClient"/> provided should be decorated with a <see cref="AzureAIProjectChatClient"/> for proper functionality.
/// </remarks>
internal AzureAIAgentChatClient(AgentClient agentClient, AgentReference agentReference, string? defaultModelId, ChatOptions? chatOptions, OpenAIClientOptions? openAIClientOptions = null)
: base(Throw.IfNull(agentClient)
.GetOpenAIClient(openAIClientOptions)
internal AzureAIProjectChatClient(AIProjectClient aiProjectClient, AgentReference agentReference, string? defaultModelId, ChatOptions? chatOptions)
: base(Throw.IfNull(aiProjectClient)
.GetProjectOpenAIClient()
.GetOpenAIResponseClient(defaultModelId ?? NoOpModel)
.AsIChatClient())
{
this._agentClient = agentClient;
this._agentClient = aiProjectClient;
this._agentReference = Throw.IfNull(agentReference);
this._metadata = new ChatClientMetadata("azure.ai.agents", defaultModelId: defaultModelId);
this._chatOptions = chatOptions;
}
/// <summary>
/// Initializes a new instance of the <see cref="AzureAIAgentChatClient"/> class.
/// Initializes a new instance of the <see cref="AzureAIProjectChatClient"/> class.
/// </summary>
/// <param name="agentClient">An instance of <see cref="AgentClient"/> to interact with Azure AI Agents services.</param>
/// <param name="aiProjectClient">An instance of <see cref="AIProjectClient"/> to interact with Azure AI Agents services.</param>
/// <param name="agentRecord">An instance of <see cref="AgentRecord"/> representing the specific agent to use.</param>
/// <param name="chatOptions">An instance of <see cref="ChatOptions"/> representing the options on how the agent was predefined.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <remarks>
/// The <see cref="IChatClient"/> provided should be decorated with a <see cref="AzureAIAgentChatClient"/> for proper functionality.
/// The <see cref="IChatClient"/> provided should be decorated with a <see cref="AzureAIProjectChatClient"/> for proper functionality.
/// </remarks>
internal AzureAIAgentChatClient(AgentClient agentClient, AgentRecord agentRecord, ChatOptions? chatOptions, OpenAIClientOptions? openAIClientOptions = null)
: this(agentClient, Throw.IfNull(agentRecord).Versions.Latest, chatOptions, openAIClientOptions)
internal AzureAIProjectChatClient(AIProjectClient aiProjectClient, AgentRecord agentRecord, ChatOptions? chatOptions)
: this(aiProjectClient, Throw.IfNull(agentRecord).Versions.Latest, chatOptions)
{
this._agentRecord = agentRecord;
}
internal AzureAIAgentChatClient(AgentClient agentClient, AgentVersion agentVersion, ChatOptions? chatOptions, OpenAIClientOptions? openAIClientOptions = null)
internal AzureAIProjectChatClient(AIProjectClient aiProjectClient, AgentVersion agentVersion, ChatOptions? chatOptions)
: this(
agentClient,
new AgentReference(Throw.IfNull(agentVersion).Name) { Version = agentVersion.Version },
aiProjectClient,
new AgentReference(Throw.IfNull(agentVersion).Name, agentVersion.Version),
(agentVersion.Definition as PromptAgentDefinition)?.Model,
chatOptions,
openAIClientOptions)
chatOptions)
{
this._agentVersion = agentVersion;
}
@@ -86,7 +81,7 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
{
return (serviceKey is null && serviceType == typeof(ChatClientMetadata))
? this._metadata
: (serviceKey is null && serviceType == typeof(AgentClient))
: (serviceKey is null && serviceType == typeof(AIProjectClient))
? this._agentClient
: (serviceKey is null && serviceType == typeof(AgentVersion))
? this._agentVersion
@@ -142,27 +137,12 @@ internal sealed class AzureAIAgentChatClient : DelegatingChatClient
responseCreationOptions = new ResponseCreationOptions();
}
this.SetAgentReference(responseCreationOptions);
ResponseCreationOptionsExtensions.set_Agent(responseCreationOptions, this._agentReference);
ResponseCreationOptionsExtensions.set_Model(responseCreationOptions, null);
return responseCreationOptions;
};
return agentEnabledChatOptions;
}
// Since the SetAdditionalProperty/SetAgentReference/SetConversationReference extensions in Azure.AI.Agents does not yet support the recent updates in OpenAI 2.6.0
// The methods below are copied and adapted to the new OpenAI SDK 2.6.0 structure where the Patch property is now exposed directly on ResponseCreationOptions and
// may be removed once the Azure.AI.Agents package is updated to support OpenAI SDK 2.6+.
#pragma warning disable SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
private static void SetAdditionalProperty(ResponseCreationOptions responseCreationOptions, string key, BinaryData value)
{
responseCreationOptions.Patch.Set([.. "$."u8, .. Encoding.UTF8.GetBytes(key)], value);
}
private void SetAgentReference(ResponseCreationOptions responseCreationOptions)
{
SetAdditionalProperty(responseCreationOptions, "agent", ModelReaderWriter.Write(this._agentReference, new ModelReaderWriterOptions("W"), AzureAIAgentsContext.Default));
responseCreationOptions.Patch.Remove([.. "$."u8, .. Encoding.UTF8.GetBytes("model")]);
}
#pragma warning restore SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
}
@@ -8,6 +8,7 @@ using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Azure.AI.Projects.OpenAI;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AzureAI;
using Microsoft.Extensions.AI;
@@ -18,43 +19,41 @@ using OpenAI.Responses;
#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.
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
namespace Azure.AI.Agents;
namespace Azure.AI.Projects;
/// <summary>
/// Provides extension methods for <see cref="AgentClient"/>.
/// Provides extension methods for <see cref="AIProjectClient"/>.
/// </summary>
public static partial class AgentClientExtensions
public static partial class AzureAIProjectChatClientExtensions
{
/// <summary>
/// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AgentClient"/>.
/// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AIProjectClient"/>.
/// </summary>
/// <param name="agentClient">The <see cref="AgentClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The <see cref="AIProjectClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="agentReference">The <see cref="AgentReference"/> representing the name and version of the server side agent to create a <see cref="ChatClientAgent"/> for. Cannot be <see langword="null"/>.</param>
/// <param name="tools">The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations based on the latest version of the named Azure AI Agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="agentReference"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="agentReference"/> is <see langword="null"/>.</exception>
/// <exception cref="InvalidOperationException">The agent with the specified name was not found.</exception>
/// <remarks>
/// When retrieving an agent by using an <see cref="AgentReference"/>, minimal information will be available about the agent in the instance level, and any logic that relies
/// on <see cref="AIAgent.GetService(Type, object?)"/> to retrieve information about the agent like <see cref="AgentVersion" /> will receive <see langword="null"/> as the result.
/// </remarks>
public static ChatClientAgent GetAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
AgentReference agentReference,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(agentReference);
ThrowIfInvalidAgentName(agentReference.Name);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentReference,
new ChatClientAgentOptions()
{
@@ -63,114 +62,104 @@ public static partial class AgentClientExtensions
ChatOptions = new() { Tools = tools },
},
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AgentClient"/>.
/// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AIProjectClient"/>.
/// </summary>
/// <param name="agentClient">The <see cref="AgentClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The <see cref="AIProjectClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name of the server side agent to create a <see cref="ChatClientAgent"/> for. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="tools">The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations based on the latest version of the named Azure AI Agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="name"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="name"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is empty or whitespace, or when the agent with the specified name was not found.</exception>
/// <exception cref="InvalidOperationException">The agent with the specified name was not found.</exception>
public static ChatClientAgent GetAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
AgentRecord agentRecord = GetAgentRecordByName(agentClient, name, cancellationToken);
AgentRecord agentRecord = GetAgentRecordByName(aiProjectClient, name, cancellationToken);
return GetAIAgent(
agentClient,
aiProjectClient,
agentRecord,
tools,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Asynchronously retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AgentClient"/>.
/// Asynchronously retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="AIProjectClient"/>.
/// </summary>
/// <param name="agentClient">The <see cref="AgentClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The <see cref="AIProjectClient"/> to create the <see cref="ChatClientAgent"/> with. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name of the server side agent to create a <see cref="ChatClientAgent"/> for. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="tools">The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations based on the latest version of the named Azure AI Agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="name"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="name"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is empty or whitespace, or when the agent with the specified name was not found.</exception>
/// <exception cref="InvalidOperationException">The agent with the specified name was not found.</exception>
public static async Task<ChatClientAgent> GetAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
AgentRecord agentRecord = await GetAgentRecordByNameAsync(agentClient, name, cancellationToken).ConfigureAwait(false);
AgentRecord agentRecord = await GetAgentRecordByNameAsync(aiProjectClient, name, cancellationToken).ConfigureAwait(false);
return GetAIAgent(
agentClient,
aiProjectClient,
agentRecord,
tools,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Gets a runnable agent instance from the provided agent record.
/// </summary>
/// <param name="agentClient">The client used to interact with Azure AI Agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to interact with Azure AI Agents. Cannot be <see langword="null"/>.</param>
/// <param name="agentRecord">The agent record to be converted. The latest version will be used. Cannot be <see langword="null"/>.</param>
/// <param name="tools">The tools to use when interacting with the agent. This is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations based on the latest version of the Azure AI Agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="agentRecord"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="agentRecord"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
AgentRecord agentRecord,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(agentRecord);
var allowDeclarativeMode = tools is not { Count: > 0 };
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentRecord,
tools,
clientFactory,
openAIClientOptions,
!allowDeclarativeMode,
services);
}
@@ -178,57 +167,52 @@ public static partial class AgentClientExtensions
/// <summary>
/// Gets a runnable agent instance from a <see cref="AgentVersion"/> containing metadata about an Azure AI Agent.
/// </summary>
/// <param name="agentClient">The client used to interact with Azure AI Agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to interact with Azure AI Agents. Cannot be <see langword="null"/>.</param>
/// <param name="agentVersion">The agent version to be converted. Cannot be <see langword="null"/>.</param>
/// <param name="tools">In-process invocable tools to be provided. If no tools are provided manual handling will be necessary to invoke in-process tools.</param>
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations based on the provided version of the Azure AI Agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="agentVersion"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="agentVersion"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
AgentVersion agentVersion,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(agentVersion);
var allowDeclarativeMode = tools is not { Count: > 0 };
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
tools,
clientFactory,
openAIClientOptions,
!allowDeclarativeMode,
services);
}
/// <summary>
/// Creates a new Prompt AI Agent using the provided <see cref="AgentClient"/> and options.
/// Creates a new Prompt AI Agent using the provided <see cref="AIProjectClient"/> and options.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="options">The options for creating the agent. Cannot be <see langword="null"/>.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the operation if needed.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(options);
if (string.IsNullOrWhiteSpace(options.Name))
@@ -238,40 +222,37 @@ public static partial class AgentClientExtensions
ThrowIfInvalidAgentName(options.Name);
AgentRecord agentRecord = GetAgentRecordByName(agentClient, options.Name, cancellationToken);
AgentRecord agentRecord = GetAgentRecordByName(aiProjectClient, options.Name, cancellationToken);
var agentVersion = agentRecord.Versions.Latest;
var agentOptions = CreateChatClientAgentOptions(agentVersion, options, requireInvocableTools: true);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
agentOptions,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Creates a new Prompt AI Agent using the provided <see cref="AgentClient"/> and options.
/// Creates a new Prompt AI Agent using the provided <see cref="AIProjectClient"/> and options.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="options">The options for creating the agent. Cannot be <see langword="null"/>.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the operation if needed.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static async Task<ChatClientAgent> GetAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(options);
if (string.IsNullOrWhiteSpace(options.Name))
@@ -281,61 +262,57 @@ public static partial class AgentClientExtensions
ThrowIfInvalidAgentName(options.Name);
AgentRecord agentRecord = await GetAgentRecordByNameAsync(agentClient, options.Name, cancellationToken).ConfigureAwait(false);
AgentRecord agentRecord = await GetAgentRecordByNameAsync(aiProjectClient, options.Name, cancellationToken).ConfigureAwait(false);
var agentVersion = agentRecord.Versions.Latest;
var agentOptions = CreateChatClientAgentOptions(agentVersion, options, requireInvocableTools: true);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
agentOptions,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Creates a new Prompt AI agent using the specified configuration parameters.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name for the agent.</param>
/// <param name="model">The name of the model to use for the agent. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="instructions">The instructions that guide the agent's behavior. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="description">The description for the agent.</param>
/// <param name="tools">The tools to use when interacting with the agent, this is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/>, <paramref name="model"/>, or <paramref name="instructions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/>, <paramref name="model"/>, or <paramref name="instructions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="model"/> or <paramref name="instructions"/> is empty or whitespace.</exception>
/// <remarks>When using prompt agent definitions with tools the parameter <paramref name="tools"/> needs to be provided.</remarks>
public static ChatClientAgent CreateAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
string model,
string instructions,
string? description = null,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
Throw.IfNullOrWhitespace(model);
Throw.IfNullOrWhitespace(instructions);
return CreateAIAgent(
agentClient,
aiProjectClient,
name,
tools,
new AgentVersionCreationOptions(new PromptAgentDefinition(model) { Instructions = instructions }) { Description = description },
clientFactory,
openAIClientOptions,
services,
cancellationToken);
}
@@ -343,71 +320,66 @@ public static partial class AgentClientExtensions
/// <summary>
/// Creates a new Prompt AI agent using the specified configuration parameters.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name for the agent.</param>
/// <param name="model">The name of the model to use for the agent. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="instructions">The instructions that guide the agent's behavior. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="description">The description for the agent.</param>
/// <param name="tools">The tools to use when interacting with the agent, this is required when using prompt agent definitions with tools.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/>, <paramref name="model"/>, or <paramref name="instructions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/>, <paramref name="model"/>, or <paramref name="instructions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="model"/> or <paramref name="instructions"/> is empty or whitespace.</exception>
/// <remarks>When using prompt agent definitions with tools the parameter <paramref name="tools"/> needs to be provided.</remarks>
public static Task<ChatClientAgent> CreateAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
string model,
string instructions,
string? description = null,
IList<AITool>? tools = null,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
Throw.IfNullOrWhitespace(model);
Throw.IfNullOrWhitespace(instructions);
return CreateAIAgentAsync(
agentClient,
aiProjectClient,
name,
tools,
new AgentVersionCreationOptions(new PromptAgentDefinition(model) { Instructions = instructions }) { Description = description },
clientFactory,
openAIClientOptions,
services,
cancellationToken);
}
/// <summary>
/// Creates a new Prompt AI Agent using the provided <see cref="AgentClient"/> and options.
/// Creates a new Prompt AI Agent using the provided <see cref="AIProjectClient"/> and options.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="model">The name of the model to use for the agent. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="options">The options for creating the agent. Cannot be <see langword="null"/>.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the operation if needed.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="model"/> is empty or whitespace, or when the agent name is not provided in the options.</exception>
public static ChatClientAgent CreateAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string model,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(options);
Throw.IfNullOrWhitespace(model);
const bool RequireInvocableTools = true;
@@ -441,42 +413,39 @@ public static partial class AgentClientExtensions
creationOptions.Description = options.Description;
}
AgentVersion agentVersion = CreateAgentVersionWithProtocol(agentClient, options.Name, creationOptions, cancellationToken);
AgentVersion agentVersion = CreateAgentVersionWithProtocol(aiProjectClient, options.Name, creationOptions, cancellationToken);
var agentOptions = CreateChatClientAgentOptions(agentVersion, options, RequireInvocableTools);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
agentOptions,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Creates a new Prompt AI Agent using the provided <see cref="AgentClient"/> and options.
/// Creates a new Prompt AI Agent using the provided <see cref="AIProjectClient"/> and options.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="model">The name of the model to use for the agent. Cannot be <see langword="null"/> or whitespace.</param>
/// <param name="options">The options for creating the agent. Cannot be <see langword="null"/>.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the operation if needed.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="model"/> is empty or whitespace, or when the agent name is not provided in the options.</exception>
public static async Task<ChatClientAgent> CreateAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string model,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
IServiceProvider? services = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
Throw.IfNull(options);
Throw.IfNullOrWhitespace(model);
const bool RequireInvocableTools = true;
@@ -510,53 +479,49 @@ public static partial class AgentClientExtensions
creationOptions.Description = options.Description;
}
AgentVersion agentVersion = await CreateAgentVersionWithProtocolAsync(agentClient, options.Name, creationOptions, cancellationToken).ConfigureAwait(false);
AgentVersion agentVersion = await CreateAgentVersionWithProtocolAsync(aiProjectClient, options.Name, creationOptions, cancellationToken).ConfigureAwait(false);
var agentOptions = CreateChatClientAgentOptions(agentVersion, options, RequireInvocableTools);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
agentOptions,
clientFactory,
openAIClientOptions,
services);
}
/// <summary>
/// Creates a new AI agent using the specified agent definition and optional configuration parameters.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name for the agent.</param>
/// <param name="creationOptions">Settings that control the creation of the agent.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="creationOptions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="creationOptions"/> is <see langword="null"/>.</exception>
/// <remarks>
/// When using this extension method with a <see cref="PromptAgentDefinition"/> the tools are only declarative and not invocable.
/// Invocation of any in-process tools will need to be handled manually.
/// </remarks>
public static ChatClientAgent CreateAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
AgentVersionCreationOptions creationOptions,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
Throw.IfNull(creationOptions);
return CreateAIAgent(
agentClient,
aiProjectClient,
name,
tools: null,
creationOptions,
clientFactory,
openAIClientOptions,
services: null,
cancellationToken);
}
@@ -565,90 +530,98 @@ public static partial class AgentClientExtensions
/// Asynchronously creates a new AI agent using the specified agent definition and optional configuration
/// parameters.
/// </summary>
/// <param name="agentClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="aiProjectClient">The client used to manage and interact with AI agents. Cannot be <see langword="null"/>.</param>
/// <param name="name">The name for the agent.</param>
/// <param name="creationOptions">Settings that control the creation of the agent.</param>
/// <param name="clientFactory">A factory function to customize the creation of the chat client used by the agent.</param>
/// <param name="openAIClientOptions">An optional <see cref="OpenAIClientOptions"/> for configuring the underlying OpenAI client.</param>
/// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the newly created agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentClient"/> or <paramref name="creationOptions"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="aiProjectClient"/> or <paramref name="creationOptions"/> is <see langword="null"/>.</exception>
/// <remarks>
/// When using this extension method with a <see cref="PromptAgentDefinition"/> the tools are only declarative and not invocable.
/// Invocation of any in-process tools will need to be handled manually.
/// </remarks>
public static Task<ChatClientAgent> CreateAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
AgentVersionCreationOptions creationOptions,
Func<IChatClient, IChatClient>? clientFactory = null,
OpenAIClientOptions? openAIClientOptions = null,
CancellationToken cancellationToken = default)
{
Throw.IfNull(agentClient);
Throw.IfNull(aiProjectClient);
ThrowIfInvalidAgentName(name);
Throw.IfNull(creationOptions);
return CreateAIAgentAsync(
agentClient,
aiProjectClient,
name,
tools: null,
creationOptions,
clientFactory,
openAIClientOptions,
services: null,
cancellationToken);
}
#region Private
private static readonly ModelReaderWriterOptions s_modelWriterOptionsWire = new("W");
/// <summary>
/// Retrieves an agent record by name using the Protocol method with user-agent header.
/// </summary>
private static AgentRecord GetAgentRecordByName(AgentClient agentClient, string agentName, CancellationToken cancellationToken)
private static AgentRecord GetAgentRecordByName(AIProjectClient aiProjectClient, string agentName, CancellationToken cancellationToken)
{
ClientResult protocolResponse = agentClient.GetAgent(agentName, cancellationToken.ToRequestOptions(false));
return ClientResult.FromOptionalValue((AgentRecord)protocolResponse, protocolResponse.GetRawResponse()).Value
ClientResult protocolResponse = aiProjectClient.Agents.GetAgent(agentName, cancellationToken.ToRequestOptions(false));
var rawResponse = protocolResponse.GetRawResponse();
AgentRecord? result = ModelReaderWriter.Read<AgentRecord>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
return ClientResult.FromOptionalValue(result, rawResponse).Value!
?? throw new InvalidOperationException($"Agent with name '{agentName}' not found.");
}
/// <summary>
/// Asynchronously retrieves an agent record by name using the Protocol method with user-agent header.
/// </summary>
private static async Task<AgentRecord> GetAgentRecordByNameAsync(AgentClient agentClient, string agentName, CancellationToken cancellationToken)
private static async Task<AgentRecord> GetAgentRecordByNameAsync(AIProjectClient aiProjectClient, string agentName, CancellationToken cancellationToken)
{
ClientResult protocolResponse = await agentClient.GetAgentAsync(agentName, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
return ClientResult.FromOptionalValue((AgentRecord)protocolResponse, protocolResponse.GetRawResponse()).Value
ClientResult protocolResponse = await aiProjectClient.Agents.GetAgentAsync(agentName, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
var rawResponse = protocolResponse.GetRawResponse();
AgentRecord? result = ModelReaderWriter.Read<AgentRecord>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
return ClientResult.FromOptionalValue(result, rawResponse).Value!
?? throw new InvalidOperationException($"Agent with name '{agentName}' not found.");
}
/// <summary>
/// Creates an agent version using the Protocol method with user-agent header.
/// </summary>
private static AgentVersion CreateAgentVersionWithProtocol(AgentClient agentClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
private static AgentVersion CreateAgentVersionWithProtocol(AIProjectClient aiProjectClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
{
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIAgentsContext.Default));
ClientResult protocolResponse = agentClient.CreateAgentVersion(agentName, protocolRequest, cancellationToken.ToRequestOptions(false));
return ClientResult.FromValue((AgentVersion)protocolResponse, protocolResponse.GetRawResponse()).Value;
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIProjectsContext.Default));
ClientResult protocolResponse = aiProjectClient.Agents.CreateAgentVersion(agentName, protocolRequest, cancellationToken.ToRequestOptions(false));
var rawResponse = protocolResponse.GetRawResponse();
AgentVersion? result = ModelReaderWriter.Read<AgentVersion>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
return ClientResult.FromValue(result, rawResponse).Value!;
}
/// <summary>
/// Asynchronously creates an agent version using the Protocol method with user-agent header.
/// </summary>
private static async Task<AgentVersion> CreateAgentVersionWithProtocolAsync(AgentClient agentClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
private static async Task<AgentVersion> CreateAgentVersionWithProtocolAsync(AIProjectClient aiProjectClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
{
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIAgentsContext.Default));
ClientResult protocolResponse = await agentClient.CreateAgentVersionAsync(agentName, protocolRequest, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
return ClientResult.FromValue((AgentVersion)protocolResponse, protocolResponse.GetRawResponse()).Value;
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIProjectsContext.Default));
ClientResult protocolResponse = await aiProjectClient.Agents.CreateAgentVersionAsync(agentName, protocolRequest, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
var rawResponse = protocolResponse.GetRawResponse();
AgentVersion? result = ModelReaderWriter.Read<AgentVersion>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
return ClientResult.FromValue(result, rawResponse).Value!;
}
private static ChatClientAgent CreateAIAgent(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
IList<AITool>? tools,
AgentVersionCreationOptions creationOptions,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
IServiceProvider? services,
CancellationToken cancellationToken)
{
@@ -659,25 +632,23 @@ public static partial class AgentClientExtensions
ApplyToolsToAgentDefinition(creationOptions.Definition, tools);
}
AgentVersion agentVersion = CreateAgentVersionWithProtocol(agentClient, name, creationOptions, cancellationToken);
AgentVersion agentVersion = CreateAgentVersionWithProtocol(aiProjectClient, name, creationOptions, cancellationToken);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
tools,
clientFactory,
openAIClientOptions,
!allowDeclarativeMode,
services);
}
private static async Task<ChatClientAgent> CreateAIAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string name,
IList<AITool>? tools,
AgentVersionCreationOptions creationOptions,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
IServiceProvider? services,
CancellationToken cancellationToken)
{
@@ -688,28 +659,26 @@ public static partial class AgentClientExtensions
ApplyToolsToAgentDefinition(creationOptions.Definition, tools);
}
AgentVersion agentVersion = await CreateAgentVersionWithProtocolAsync(agentClient, name, creationOptions, cancellationToken).ConfigureAwait(false);
AgentVersion agentVersion = await CreateAgentVersionWithProtocolAsync(aiProjectClient, name, creationOptions, cancellationToken).ConfigureAwait(false);
return CreateChatClientAgent(
agentClient,
aiProjectClient,
agentVersion,
tools,
clientFactory,
openAIClientOptions,
!allowDeclarativeMode,
services);
}
/// <summary>This method creates an <see cref="ChatClientAgent"/> with the specified ChatClientAgentOptions.</summary>
private static ChatClientAgent CreateChatClientAgent(
AgentClient agentClient,
AIProjectClient aiProjectClient,
AgentVersion agentVersion,
ChatClientAgentOptions agentOptions,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
IServiceProvider? services)
{
IChatClient chatClient = new AzureAIAgentChatClient(agentClient, agentVersion, agentOptions.ChatOptions, openAIClientOptions);
IChatClient chatClient = new AzureAIProjectChatClient(aiProjectClient, agentVersion, agentOptions.ChatOptions);
if (clientFactory is not null)
{
@@ -721,14 +690,13 @@ public static partial class AgentClientExtensions
/// <summary>This method creates an <see cref="ChatClientAgent"/> with the specified ChatClientAgentOptions.</summary>
private static ChatClientAgent CreateChatClientAgent(
AgentClient agentClient,
AIProjectClient aiProjectClient,
AgentRecord agentRecord,
ChatClientAgentOptions agentOptions,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
IServiceProvider? services)
{
IChatClient chatClient = new AzureAIAgentChatClient(agentClient, agentRecord, agentOptions.ChatOptions, openAIClientOptions);
IChatClient chatClient = new AzureAIProjectChatClient(aiProjectClient, agentRecord, agentOptions.ChatOptions);
if (clientFactory is not null)
{
@@ -740,14 +708,13 @@ public static partial class AgentClientExtensions
/// <summary>This method creates an <see cref="ChatClientAgent"/> with the specified ChatClientAgentOptions.</summary>
private static ChatClientAgent CreateChatClientAgent(
AgentClient agentClient,
AIProjectClient aiProjectClient,
AgentReference agentReference,
ChatClientAgentOptions agentOptions,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
IServiceProvider? services)
{
IChatClient chatClient = new AzureAIAgentChatClient(agentClient, agentReference, defaultModelId: null, agentOptions.ChatOptions, openAIClientOptions);
IChatClient chatClient = new AzureAIProjectChatClient(aiProjectClient, agentReference, defaultModelId: null, agentOptions.ChatOptions);
if (clientFactory is not null)
{
@@ -759,36 +726,32 @@ public static partial class AgentClientExtensions
/// <summary>This method creates an <see cref="ChatClientAgent"/> with a auto-generated ChatClientAgentOptions from the specified configuration parameters.</summary>
private static ChatClientAgent CreateChatClientAgent(
AgentClient AgentClient,
AIProjectClient AIProjectClient,
AgentVersion agentVersion,
IList<AITool>? tools,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
bool requireInvocableTools,
IServiceProvider? services)
=> CreateChatClientAgent(
AgentClient,
AIProjectClient,
agentVersion,
CreateChatClientAgentOptions(agentVersion, new ChatOptions() { Tools = tools }, requireInvocableTools),
clientFactory,
openAIClientOptions,
services);
/// <summary>This method creates an <see cref="ChatClientAgent"/> with a auto-generated ChatClientAgentOptions from the specified configuration parameters.</summary>
private static ChatClientAgent CreateChatClientAgent(
AgentClient AgentClient,
AIProjectClient AIProjectClient,
AgentRecord agentRecord,
IList<AITool>? tools,
Func<IChatClient, IChatClient>? clientFactory,
OpenAIClientOptions? openAIClientOptions,
bool requireInvocableTools,
IServiceProvider? services)
=> CreateChatClientAgent(
AgentClient,
AIProjectClient,
agentRecord,
CreateChatClientAgentOptions(agentRecord.Versions.Latest, new ChatOptions() { Tools = tools }, requireInvocableTools),
clientFactory,
openAIClientOptions,
services);
/// <summary>
@@ -11,7 +11,8 @@
<Import Project="$(RepoRoot)/dotnet/nuget/nuget-package.props" />
<ItemGroup>
<PackageReference Include="Azure.AI.Agents" />
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Azure.AI.Projects.OpenAI" />
<PackageReference Include="Microsoft.Extensions.AI" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
<PackageReference Include="OpenAI" />
@@ -10,10 +10,10 @@ using System.Runtime.CompilerServices;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Core;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Responses;
namespace Microsoft.Agents.AI.Workflows.Declarative;
@@ -30,18 +30,18 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
private readonly Dictionary<string, AgentVersion> _versionCache = [];
private readonly Dictionary<string, AIAgent> _agentCache = [];
private AgentClient? _agentClient;
private ConversationClient? _conversationClient;
private AIProjectClient? _agentClient;
private ProjectConversationsClient? _conversationClient;
/// <summary>
/// Optional options used when creating the <see cref="AgentClient"/>.
/// Optional options used when creating the <see cref="AIProjectClient"/>.
/// </summary>
public AgentClientOptions? AgentClientOptions { get; init; }
public AIProjectClientOptions? AIProjectClientOptions { get; init; }
/// <summary>
/// Optional options used when invoking the <see cref="AIAgent"/>.
/// </summary>
public OpenAIClientOptions? OpenAIClientOptions { get; init; }
public ProjectOpenAIClientOptions? OpenAIClientOptions { get; init; }
/// <summary>
/// An optional <see cref="HttpClient"/> instance to be used for making HTTP requests.
@@ -52,9 +52,9 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
/// <inheritdoc/>
public override async Task<string> CreateConversationAsync(CancellationToken cancellationToken = default)
{
AgentConversation conversation =
ProjectConversation conversation =
await this.GetConversationClient()
.CreateConversationAsync(options: null, cancellationToken).ConfigureAwait(false);
.CreateProjectConversationAsync(options: null, cancellationToken).ConfigureAwait(false);
return conversation.Id;
}
@@ -63,7 +63,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
public override async Task<ChatMessage> CreateMessageAsync(string conversationId, ChatMessage conversationMessage, CancellationToken cancellationToken = default)
{
ReadOnlyCollection<ResponseItem> newItems =
await this.GetConversationClient().CreateConversationItemsAsync(
await this.GetConversationClient().CreateProjectConversationItemsAsync(
conversationId,
items: GetResponseItems(),
include: null,
@@ -112,7 +112,9 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
{
JsonNode jsonNode = ConvertDictionaryToJson(inputArguments);
ResponseCreationOptions responseCreationOptions = new();
responseCreationOptions.SetStructuredInputs(BinaryData.FromString(jsonNode.ToJsonString()));
#pragma warning disable SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
responseCreationOptions.Patch.Set("$.structured_inputs"u8, BinaryData.FromString(jsonNode.ToJsonString()));
#pragma warning restore SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
chatOptions.RawRepresentationFactory = (_) => responseCreationOptions;
}
@@ -138,12 +140,12 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
return targetAgent;
}
AgentClient client = this.GetAgentClient();
AIProjectClient client = this.GetAgentClient();
if (string.IsNullOrEmpty(agentVersion))
{
AgentRecord agentRecord =
await client.GetAgentAsync(
await client.Agents.GetAgentAsync(
agentName,
cancellationToken).ConfigureAwait(false);
@@ -152,7 +154,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
else
{
targetAgent =
await client.GetAgentVersionAsync(
await client.Agents.GetAgentVersionAsync(
agentName,
agentVersion,
cancellationToken).ConfigureAwait(false);
@@ -170,9 +172,9 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
return agent;
}
AgentClient client = this.GetAgentClient();
AIProjectClient client = this.GetAgentClient();
agent = client.GetAIAgent(agentVersion, tools: null, clientFactory: null, this.OpenAIClientOptions, services: null);
agent = client.GetAIAgent(agentVersion, tools: null, clientFactory: null, services: null);
FunctionInvokingChatClient? functionInvokingClient = agent.GetService<FunctionInvokingChatClient>();
if (functionInvokingClient is not null)
@@ -203,7 +205,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
/// <inheritdoc/>
public override async Task<ChatMessage> GetMessageAsync(string conversationId, string messageId, CancellationToken cancellationToken = default)
{
AgentResponseItem responseItem = await this.GetConversationClient().GetConversationItemAsync(conversationId, messageId, cancellationToken).ConfigureAwait(false);
AgentResponseItem responseItem = await this.GetConversationClient().GetProjectConversationItemAsync(conversationId, messageId, include: null, cancellationToken).ConfigureAwait(false);
ResponseItem[] items = [responseItem.AsOpenAIResponseItem()];
return items.AsChatMessages().Single();
}
@@ -218,7 +220,8 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
AgentListOrder order = newestFirst ? AgentListOrder.Ascending : AgentListOrder.Descending;
await foreach (AgentResponseItem responseItem in this.GetConversationClient().GetConversationItemsAsync(conversationId, limit, order, after, before, itemType: null, cancellationToken).ConfigureAwait(false))
await foreach (AgentResponseItem responseItem in this.GetConversationClient().GetProjectConversationItemsAsync(conversationId, null, limit, order.ToString(), after, before, include: null, cancellationToken).ConfigureAwait(false))
{
ResponseItem[] items = [responseItem.AsOpenAIResponseItem()];
foreach (ChatMessage message in items.AsChatMessages())
@@ -228,18 +231,18 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
}
}
private AgentClient GetAgentClient()
private AIProjectClient GetAgentClient()
{
if (this._agentClient is null)
{
AgentClientOptions clientOptions = this.AgentClientOptions ?? new();
AIProjectClientOptions clientOptions = this.AIProjectClientOptions ?? new();
if (this.HttpClient is not null)
{
clientOptions.Transport = new HttpClientPipelineTransport(this.HttpClient);
}
AgentClient newClient = new(projectEndpoint, projectCredentials, clientOptions);
AIProjectClient newClient = new(projectEndpoint, projectCredentials, clientOptions);
Interlocked.CompareExchange(ref this._agentClient, newClient, null);
}
@@ -247,11 +250,11 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
return this._agentClient;
}
private ConversationClient GetConversationClient()
private ProjectConversationsClient GetConversationClient()
{
if (this._conversationClient is null)
{
ConversationClient conversationClient = this.GetAgentClient().GetConversationClient();
ProjectConversationsClient conversationClient = this.GetAgentClient().GetProjectOpenAIClient().GetProjectConversationsClient();
Interlocked.CompareExchange(ref this._conversationClient, conversationClient, null);
}
@@ -4,14 +4,15 @@
using System;
using System.Threading.Tasks;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
namespace Shared.Foundry;
internal static class AgentFactory
{
public static async ValueTask<AgentVersion> CreateAgentAsync(
this AgentClient agentClient,
this AIProjectClient aiProjectClient,
string agentName,
AgentDefinition agentDefinition,
string agentDescription)
@@ -27,7 +28,7 @@ internal static class AgentFactory
},
};
AgentVersion agentVersion = await agentClient.CreateAgentVersionAsync(agentName, options).ConfigureAwait(false);
AgentVersion agentVersion = await aiProjectClient.Agents.CreateAgentVersionAsync(agentName, options).ConfigureAwait(false);
Console.ForegroundColor = ConsoleColor.Cyan;
try
@@ -6,11 +6,11 @@ using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Azure.AI.Agents;
using Azure.AI.Projects;
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
public class AzureAIChatClientTests
public class AzureAIProjectChatClientTests
{
/// <summary>
/// Verify that when the ChatOptions has a "conv_" prefixed conversation ID, the chat client uses conversation in the http requests via the chat client
@@ -43,7 +43,7 @@ public class AzureAIChatClientTests
using var httpClient = new HttpClient(httpHandler);
#pragma warning restore CA5399
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var agent = await client.GetAIAgentAsync(
new ChatClientAgentOptions
@@ -51,7 +51,7 @@ public class AzureAIChatClientTests
Name = "test-agent",
Instructions = "Test instructions",
ChatOptions = new() { ConversationId = "conv_12345" }
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
});
// Act
var thread = agent.GetNewThread();
@@ -93,14 +93,14 @@ public class AzureAIChatClientTests
using var httpClient = new HttpClient(httpHandler);
#pragma warning restore CA5399
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var agent = await client.GetAIAgentAsync(
new ChatClientAgentOptions
{
Name = "test-agent",
Instructions = "Test instructions",
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
});
// Act
var thread = agent.GetNewThread();
@@ -142,7 +142,7 @@ public class AzureAIChatClientTests
using var httpClient = new HttpClient(httpHandler);
#pragma warning restore CA5399
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var agent = await client.GetAIAgentAsync(
new ChatClientAgentOptions
@@ -150,7 +150,7 @@ public class AzureAIChatClientTests
Name = "test-agent",
Instructions = "Test instructions",
ChatOptions = new() { ConversationId = "conv_should_not_use_default" }
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
});
// Act
var thread = agent.GetNewThread();
@@ -192,14 +192,14 @@ public class AzureAIChatClientTests
using var httpClient = new HttpClient(httpHandler);
#pragma warning restore CA5399
var client = new AgentClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var client = new AIProjectClient(new Uri("https://test.openai.azure.com/"), new FakeAuthenticationTokenProvider(), new() { Transport = new HttpClientPipelineTransport(httpClient) });
var agent = await client.GetAIAgentAsync(
new ChatClientAgentOptions
{
Name = "test-agent",
Instructions = "Test instructions",
}, openAIClientOptions: new() { Transport = new HttpClientPipelineTransport(httpClient) });
});
// Act
var thread = agent.GetNewThread();
@@ -2,7 +2,7 @@
using System.ClientModel.Primitives;
using System.IO;
using Azure.AI.Agents;
using Azure.AI.Projects.OpenAI;
namespace Microsoft.Agents.AI.AzureAI.UnitTests;
@@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure.AI.Agents;
using Azure.AI.Projects.OpenAI;
using Microsoft.Extensions.Configuration;
namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Agents;
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
@@ -23,10 +24,10 @@ internal sealed class FunctionToolAgentProvider(IConfiguration configuration) :
AIFunctionFactory.Create(menuPlugin.GetItemPrice),
];
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "MenuAgent",
agentDefinition: this.DefineMenuAgent(functions),
agentDescription: "Provides information about the restaurant menu");
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -13,22 +14,22 @@ internal sealed class MarketingAgentProvider(IConfiguration configuration) : Age
{
protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri foundryEndpoint)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "AnalystAgent",
agentDefinition: this.DefineAnalystAgent(),
agentDescription: "Analyst agent for Marketing workflow");
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "WriterAgent",
agentDefinition: this.DefineWriterAgent(),
agentDescription: "Writer agent for Marketing workflow");
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "EditorAgent",
agentDefinition: this.DefineEditorAgent(),
agentDescription: "Editor agent for Marketing workflow");
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -13,16 +14,16 @@ internal sealed class MathChatAgentProvider(IConfiguration configuration) : Agen
{
protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri foundryEndpoint)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "StudentAgent",
agentDefinition: this.DefineStudentAgent(),
agentDescription: "Student agent for MathChat workflow");
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TeacherAgent",
agentDefinition: this.DefineTeacherAgent(),
agentDescription: "Teacher agent for MathChat workflow");
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -13,10 +14,10 @@ internal sealed class PoemAgentProvider(IConfiguration configuration) : AgentPro
{
protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri foundryEndpoint)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "PoemAgent",
agentDefinition: this.DefinePoemAgent(),
agentDescription: "Authors original poems");
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Shared.Foundry;
@@ -13,10 +14,10 @@ internal sealed class TestAgentProvider(IConfiguration configuration) : AgentPro
{
protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri foundryEndpoint)
{
AgentClient agentClient = new(foundryEndpoint, new AzureCliCredential());
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
yield return
await agentClient.CreateAgentAsync(
await aiProjectClient.CreateAgentAsync(
agentName: "TestAgent",
agentDefinition: this.DefineMenuAgent(),
agentDescription: "Provides information about the restaurant menu");
@@ -4,7 +4,7 @@ using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Azure.AI.Agents;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Framework;
using Microsoft.Extensions.AI;
@@ -42,9 +42,9 @@ public sealed class MediaInputTest(ITestOutputHelper output) : IntegrationTest(o
public async Task ValidateImageUploadAsync()
{
byte[] imageData = await DownloadFileAsync();
AgentClient client = new(this.TestEndpoint, new AzureCliCredential());
AIProjectClient client = new(this.TestEndpoint, new AzureCliCredential());
using MemoryStream contentStream = new(imageData);
OpenAIFileClient fileClient = client.GetOpenAIClient().GetOpenAIFileClient();
OpenAIFileClient fileClient = client.GetProjectOpenAIClient().GetOpenAIFileClient();
OpenAIFile fileInfo = await fileClient.UploadFileAsync(contentStream, "basic-text.pdf", FileUploadPurpose.Assistants);
try
{