Compare commits

...
Author SHA1 Message Date
Giles OdigweandGitHub 9e3b2fa09a Python: Update package version (#3258)
* package version 260116

* removed name tags
2026-01-16 21:06:30 +00:00
Dmytro StrukandGitHub 5687e13221 Python: [BREAKING] Renamed create_agent to as_agent (#3249)
* Renamed create_agent to as_agent

* Override for as_agent

* Added override
2026-01-16 19:21:52 +00:00
eoindoherty1andGitHub a151f10cc2 .NET Purview Middleware: Improve Background Job Runner Injection (#3256)
* Clean up background job dependency injection

* Fix xml documentation grammar
2026-01-16 19:20:35 +00:00
Dmytro StrukandGitHub b773830e4b Create/Get Agent API - fixes and example improvements (#3246) 2026-01-16 04:36:34 +00:00
Hao LuoandGitHub 975884f32d Python: (AG-UI) Support service-managed thread on AG-UI (#3136)
* added service thread support

* set service_thread_id to only supplied_thread_id

* uses raw_representation to extract the conversation_id

* removed accidental edit

* updated test to use raw_representation

* resolves copilot review feedback

* revert back StubAgent, since not used

* removed relative module import

* removed hasattr check per PR feedback
2026-01-16 03:28:13 +00:00
Dmytro StrukandGitHub b5ca0c8eda Python: Create/Get Agent API for OpenAI Assistants (#3208)
* Added provider implementation

* Added example with response format

* Small improvements
2026-01-15 22:52:32 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
dd3e2b6e53 Bump azure-core from 1.37.0 to 1.38.0 in /python (#3209)
Bumps [azure-core](https://github.com/Azure/azure-sdk-for-python) from 1.37.0 to 1.38.0.
- [Release notes](https://github.com/Azure/azure-sdk-for-python/releases)
- [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-core_1.37.0...azure-core_1.38.0)

---
updated-dependencies:
- dependency-name: azure-core
  dependency-version: 1.38.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-15 22:25:41 +00:00
Dmytro StrukandGitHub 48d124efbe Python: Create/Get Agent API for Azure V1 (#3192)
* Added provider implementation for Azure AI V1

* Small fixes

* Fixed OpenAPI example

* Fixed local MCP example

* Fixed hosted MCP example

* Fixed file search sample

* Small fixes

* Resolved comments

* Doc updates
2026-01-15 22:19:03 +00:00
Dmytro StrukandGitHub 6e9420f614 Updated DurableAIAgent and fixed integration tests (#3241) 2026-01-15 21:43:26 +00:00
Dmytro StrukandGitHub 2ab859dd94 .NET: [BREAKING] Renamed CreateAIAgent/GetAIAgent to AsAIAgent (#3222)
* Renamed chat client extension method

* Additional renaming

* Updated documentation

* Fixed tests

* Small fix

* Small fix
2026-01-15 16:01:15 +00:00
CopilotGitHubrogerbarretocopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
e192af93a7 .NET: Update Google.GenAI to 0.11.0 and remove polyfill implementations (#3232)
* Initial plan

* Update Google.GenAI to 0.11.0 and remove polyfill files

Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
2026-01-15 15:16:32 +00:00
westeyandGitHub 3dbdecedda .NET: Merge AgentRunOptions.AdditionalProperties into ChatOptions.AdditionalProperties (#3184)
* Merge AgentRunOptions.AdditionalProperties into ChatOptions.AdditionalProperties

* Fix namespace and typo.
2026-01-15 12:15:24 +00:00
Evan MattsonandGitHub 15d0c34d9f Python: Properly configure structured outputs based on new options dict (#3213)
* Properly configure structured outputs based on new options dict

* Fix mypy
2026-01-15 11:41:46 +09:00
Evan MattsonandGitHub 620da7a829 Python: fix(ag-ui): add MCP tool support for AG-UI approval flows (#3212)
* add MCP tool support for AG-UI approval flows

* use attribute in place of property
2026-01-15 02:34:11 +00:00
Evan MattsonandGitHub 80b25a782b fix(workflows): rename WorkflowOutputEvent.source_executor_id to executor_id for API consistency (#3166) 2026-01-15 02:11:25 +00:00
Evan MattsonandGitHub ffe2e787ba Python: fix(core): correct FunctionResultContent ordering in WorkflowAgent.merge_updates (#3168)
* fix(core): simplify FunctionResultContent ordering in WorkflowAgent.merge_updates

* improve comment

* Fix name
2026-01-15 01:54:44 +00:00
370 changed files with 6468 additions and 2764 deletions
+1
View File
@@ -206,6 +206,7 @@ agents.md
WARP.md
**/memory-bank/
**/projectBrief.md
**/tmpclaude*
# Azurite storage emulator files
*/__azurite_db_blob__.json
+1 -1
View File
@@ -26,7 +26,7 @@
<PackageVersion Include="Azure.Identity" Version="1.17.1" />
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.4.0" />
<!-- Google Gemini -->
<PackageVersion Include="Google.GenAI" Version="0.9.0" />
<PackageVersion Include="Google.GenAI" Version="0.11.0" />
<PackageVersion Include="Mscc.GenerativeAI.Microsoft" Version="2.9.3" />
<!-- Microsoft.Azure.* -->
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.54.0" />
+1 -1
View File
@@ -21,7 +21,7 @@ var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
.AsAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Framework."));
```
@@ -29,7 +29,7 @@ internal sealed class HostClientAgent
// Create the agent that uses the remote agents as tools
this.Agent = new OpenAIClient(new ApiKeyCredential(apiKey))
.GetChatClient(modelId)
.CreateAIAgent(instructions: "You specialize in handling queries for users and using your tools to provide answers.", name: "HostClient", tools: tools);
.AsAIAgent(instructions: "You specialize in handling queries for users and using your tools to provide answers.", name: "HostClient", tools: tools);
}
catch (Exception ex)
{
@@ -35,7 +35,7 @@ internal static class HostAgentFactory
{
AIAgent agent = new OpenAIClient(apiKey)
.GetChatClient(model)
.CreateAIAgent(instructions, name, tools: tools);
.AsAIAgent(instructions, name, tools: tools);
AgentCard agentCard = agentType.ToUpperInvariant() switch
{
@@ -83,7 +83,7 @@ public static class Program
serverUrl,
jsonSerializerOptions: AGUIClientSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent",
tools: [changeBackground, readClientClimateSensors]);
@@ -33,7 +33,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
return chatClient.AsIChatClient().CreateAIAgent(
return chatClient.AsIChatClient().AsAIAgent(
name: "AgenticChat",
description: "A simple chat agent using Azure OpenAI");
}
@@ -42,7 +42,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
return chatClient.AsIChatClient().CreateAIAgent(
return chatClient.AsIChatClient().AsAIAgent(
name: "BackendToolRenderer",
description: "An agent that can render backend tools using Azure OpenAI",
tools: [AIFunctionFactory.Create(
@@ -56,7 +56,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
return chatClient.AsIChatClient().CreateAIAgent(
return chatClient.AsIChatClient().AsAIAgent(
name: "HumanInTheLoopAgent",
description: "An agent that involves human feedback in its decision-making process using Azure OpenAI");
}
@@ -65,7 +65,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
return chatClient.AsIChatClient().CreateAIAgent(
return chatClient.AsIChatClient().AsAIAgent(
name: "ToolBasedGenerativeUIAgent",
description: "An agent that uses tools to generate user interfaces using Azure OpenAI");
}
@@ -73,7 +73,7 @@ internal static class ChatClientAgentFactory
public static AIAgent CreateAgenticUI(JsonSerializerOptions options)
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
var baseAgent = chatClient.AsIChatClient().CreateAIAgent(new ChatClientAgentOptions
var baseAgent = chatClient.AsIChatClient().AsAIAgent(new ChatClientAgentOptions
{
Name = "AgenticUIAgent",
Description = "An agent that generates agentic user interfaces using Azure OpenAI",
@@ -116,7 +116,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
var baseAgent = chatClient.AsIChatClient().CreateAIAgent(
var baseAgent = chatClient.AsIChatClient().AsAIAgent(
name: "SharedStateAgent",
description: "An agent that demonstrates shared state patterns using Azure OpenAI");
@@ -127,7 +127,7 @@ internal static class ChatClientAgentFactory
{
ChatClient chatClient = s_azureOpenAIClient!.GetChatClient(s_deploymentName!);
var baseAgent = chatClient.AsIChatClient().CreateAIAgent(new ChatClientAgentOptions
var baseAgent = chatClient.AsIChatClient().AsAIAgent(new ChatClientAgentOptions
{
Name = "PredictiveStateUpdatesAgent",
Description = "An agent that demonstrates predictive state updates using Azure OpenAI",
@@ -23,7 +23,7 @@ var agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
name: "AGUIAssistant",
tools: [
AIFunctionFactory.Create(
+2 -2
View File
@@ -119,7 +119,7 @@ The `AGUIServer` uses the `MapAGUI` extension method to expose an agent through
```csharp
AIAgent agent = new OpenAIClient(apiKey)
.GetChatClient(model)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are a helpful assistant.",
name: "AGUIAssistant");
@@ -144,7 +144,7 @@ var chatClient = new AGUIChatClient(
modelId: "agui-client",
jsonSerializerOptions: null);
AIAgent agent = chatClient.CreateAIAgent(
AIAgent agent = chatClient.AsAIAgent(
instructions: null,
name: "agui-client",
description: "AG-UI Client Agent",
+2 -2
View File
@@ -74,7 +74,7 @@ AzureOpenAIClient azureOpenAIClient = new AzureOpenAIClient(
ChatClient chatClient = azureOpenAIClient.GetChatClient(deploymentName);
// Create AI agent
ChatClientAgent agent = chatClient.AsIChatClient().CreateAIAgent(
ChatClientAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "ChatAssistant",
instructions: "You are a helpful assistant.");
@@ -162,7 +162,7 @@ dotnet run
Edit the instructions in `Server/Program.cs`:
```csharp
ChatClientAgent agent = chatClient.AsIChatClient().CreateAIAgent(
ChatClientAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "ChatAssistant",
instructions: "You are a helpful coding assistant specializing in C# and .NET.");
```
+1 -1
View File
@@ -25,7 +25,7 @@ AzureOpenAIClient azureOpenAIClient = new(
ChatClient chatClient = azureOpenAIClient.GetChatClient(deploymentName);
ChatClientAgent agent = chatClient.AsIChatClient().CreateAIAgent(
ChatClientAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "ChatAssistant",
instructions: "You are a helpful assistant.");
@@ -25,7 +25,7 @@ AzureOpenAIClient client = !string.IsNullOrEmpty(azureOpenAiKey)
const string JokerName = "Joker";
const string JokerInstructions = "You are good at telling jokes.";
AIAgent agent = client.GetChatClient(deploymentName).CreateAIAgent(JokerInstructions, JokerName);
AIAgent agent = client.GetChatClient(deploymentName).AsAIAgent(JokerInstructions, JokerName);
// Configure the function app to host the AI agent.
// This will automatically generate HTTP API endpoints for the agent.
@@ -29,7 +29,7 @@ const string WriterInstructions =
when given an improved sentence you polish it further.
""";
AIAgent writerAgent = client.GetChatClient(deploymentName).CreateAIAgent(WriterInstructions, WriterName);
AIAgent writerAgent = client.GetChatClient(deploymentName).AsAIAgent(WriterInstructions, WriterName);
using IHost app = FunctionsApplication
.CreateBuilder(args)
@@ -28,8 +28,8 @@ const string PhysicistInstructions = "You are an expert in physics. You answer q
const string ChemistName = "ChemistAgent";
const string ChemistInstructions = "You are an expert in chemistry. You answer questions from a chemistry perspective.";
AIAgent physicistAgent = client.GetChatClient(deploymentName).CreateAIAgent(PhysicistInstructions, PhysicistName);
AIAgent chemistAgent = client.GetChatClient(deploymentName).CreateAIAgent(ChemistInstructions, ChemistName);
AIAgent physicistAgent = client.GetChatClient(deploymentName).AsAIAgent(PhysicistInstructions, PhysicistName);
AIAgent chemistAgent = client.GetChatClient(deploymentName).AsAIAgent(ChemistInstructions, ChemistName);
using IHost app = FunctionsApplication
.CreateBuilder(args)
@@ -29,10 +29,10 @@ const string EmailAssistantName = "EmailAssistantAgent";
const string EmailAssistantInstructions = "You are an email assistant that helps users draft responses to emails with professionalism.";
AIAgent spamDetectionAgent = client.GetChatClient(deploymentName)
.CreateAIAgent(SpamDetectionInstructions, SpamDetectionName);
.AsAIAgent(SpamDetectionInstructions, SpamDetectionName);
AIAgent emailAssistantAgent = client.GetChatClient(deploymentName)
.CreateAIAgent(EmailAssistantInstructions, EmailAssistantName);
.AsAIAgent(EmailAssistantInstructions, EmailAssistantName);
using IHost app = FunctionsApplication
.CreateBuilder(args)
@@ -29,7 +29,7 @@ const string WriterInstructions =
You write engaging, informative, and well-structured content that follows best practices for readability and accuracy.
""";
AIAgent writerAgent = client.GetChatClient(deploymentName).CreateAIAgent(WriterInstructions, WriterName);
AIAgent writerAgent = client.GetChatClient(deploymentName).AsAIAgent(WriterInstructions, WriterName);
using IHost app = FunctionsApplication
.CreateBuilder(args)
@@ -33,7 +33,7 @@ const string WriterAgentInstructions =
You write engaging, informative, and well-structured content that follows best practices for readability and accuracy.
""";
AIAgent writerAgent = client.GetChatClient(deploymentName).CreateAIAgent(WriterAgentInstructions, WriterAgentName);
AIAgent writerAgent = client.GetChatClient(deploymentName).AsAIAgent(WriterAgentInstructions, WriterAgentName);
// Agent that can start content generation workflows using tools
const string PublisherAgentName = "Publisher";
@@ -57,7 +57,7 @@ using IHost app = FunctionsApplication
// Initialize the tools to be used by the agent.
Tools publisherTools = new(sp.GetRequiredService<ILogger<Tools>>());
return client.GetChatClient(deploymentName).CreateAIAgent(
return client.GetChatClient(deploymentName).AsAIAgent(
instructions: PublisherAgentInstructions,
name: PublisherAgentName,
services: sp,
@@ -28,13 +28,13 @@ AzureOpenAIClient client = !string.IsNullOrEmpty(azureOpenAiKey)
: new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential());
// Define three AI agents we are going to use in this application.
AIAgent agent1 = client.GetChatClient(deploymentName).CreateAIAgent("You are good at telling jokes.", "Joker");
AIAgent agent1 = client.GetChatClient(deploymentName).AsAIAgent("You are good at telling jokes.", "Joker");
AIAgent agent2 = client.GetChatClient(deploymentName)
.CreateAIAgent("Check stock prices.", "StockAdvisor");
.AsAIAgent("Check stock prices.", "StockAdvisor");
AIAgent agent3 = client.GetChatClient(deploymentName)
.CreateAIAgent("Recommend plants.", "PlantAdvisor", description: "Get plant recommendations.");
.AsAIAgent("Recommend plants.", "PlantAdvisor", description: "Get plant recommendations.");
using IHost app = FunctionsApplication
.CreateBuilder(args)
@@ -70,7 +70,7 @@ FunctionsApplicationBuilder builder = FunctionsApplication
// Define the Travel Planner agent with tools for weather and events
options.AddAIAgentFactory(TravelPlannerName, sp =>
{
return client.GetChatClient(deploymentName).CreateAIAgent(
return client.GetChatClient(deploymentName).AsAIAgent(
instructions: TravelPlannerInstructions,
name: TravelPlannerName,
services: sp,
@@ -23,14 +23,14 @@ A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));
AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();
// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
AIAgent a2aAgent = agentCard.GetAIAgent();
AIAgent a2aAgent = agentCard.AsAIAgent();
// Create the main agent, and provide the a2a agent skills as a function tools.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are a helpful assistant that helps people with travel planning.",
tools: [.. CreateFunctionTools(a2aAgent, agentCard)]
);
@@ -14,7 +14,7 @@ A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));
AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();
// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
AIAgent agent = agentCard.GetAIAgent();
AIAgent agent = agentCard.AsAIAgent();
AgentThread thread = await agent.GetNewThreadAsync();
@@ -16,7 +16,7 @@ using HttpClient httpClient = new()
AGUIChatClient chatClient = new(httpClient, serverUrl);
AIAgent agent = chatClient.CreateAIAgent(
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent");
@@ -24,7 +24,7 @@ ChatClient chatClient = new AzureOpenAIClient(
new DefaultAzureCredential())
.GetChatClient(deploymentName);
AIAgent agent = chatClient.AsIChatClient().CreateAIAgent(
AIAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant.");
@@ -16,7 +16,7 @@ using HttpClient httpClient = new()
AGUIChatClient chatClient = new(httpClient, serverUrl);
AIAgent agent = chatClient.CreateAIAgent(
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent");
@@ -79,7 +79,7 @@ ChatClient chatClient = new AzureOpenAIClient(
new DefaultAzureCredential())
.GetChatClient(deploymentName);
ChatClientAgent agent = chatClient.AsIChatClient().CreateAIAgent(
ChatClientAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant with access to restaurant information.",
tools: tools);
@@ -28,7 +28,7 @@ using HttpClient httpClient = new()
AGUIChatClient chatClient = new(httpClient, serverUrl);
AIAgent agent = chatClient.CreateAIAgent(
AIAgent agent = chatClient.AsAIAgent(
name: "agui-client",
description: "AG-UI Client Agent",
tools: frontendTools);
@@ -24,7 +24,7 @@ ChatClient chatClient = new AzureOpenAIClient(
new DefaultAzureCredential())
.GetChatClient(deploymentName);
AIAgent agent = chatClient.AsIChatClient().CreateAIAgent(
AIAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant.");
@@ -16,7 +16,7 @@ using HttpClient httpClient = new()
AGUIChatClient chatClient = new(httpClient, serverUrl);
// Create agent
ChatClientAgent baseAgent = chatClient.CreateAIAgent(
ChatClientAgent baseAgent = chatClient.AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant.");
@@ -57,7 +57,7 @@ ChatClient openAIChatClient = new AzureOpenAIClient(
new DefaultAzureCredential())
.GetChatClient(deploymentName);
ChatClientAgent baseAgent = openAIChatClient.AsIChatClient().CreateAIAgent(
ChatClientAgent baseAgent = openAIChatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant in charge of approving expenses",
tools: tools);
@@ -19,7 +19,7 @@ using HttpClient httpClient = new()
AGUIChatClient chatClient = new(httpClient, serverUrl);
AIAgent baseAgent = chatClient.CreateAIAgent(
AIAgent baseAgent = chatClient.AsAIAgent(
name: "recipe-client",
description: "AG-UI Recipe Client Agent");
@@ -34,7 +34,7 @@ ChatClient chatClient = new AzureOpenAIClient(
new DefaultAzureCredential())
.GetChatClient(deploymentName);
AIAgent baseAgent = chatClient.AsIChatClient().CreateAIAgent(
AIAgent baseAgent = chatClient.AsIChatClient().AsAIAgent(
name: "RecipeAgent",
instructions: """
You are a helpful recipe assistant. When users ask you to create or suggest a recipe,
@@ -26,7 +26,7 @@ using Microsoft.Agents.AI.A2A;
A2AClient a2aClient = new(new Uri("https://your-a2a-agent-host/echo"));
// Create an AIAgent from the A2AClient
AIAgent agent = a2aClient.GetAIAgent();
AIAgent agent = a2aClient.AsAIAgent();
// Run the agent
AgentResponse response = await agent.RunAsync("Tell me a joke about a pirate.");
@@ -26,7 +26,7 @@ AnthropicClient? client = (resource is null)
? new AnthropicFoundryClient(new AnthropicFoundryApiKeyCredentials(apiKey, resource)) // If an apiKey is provided, use Foundry with ApiKey authentication
: new AnthropicFoundryClient(new AnthropicAzureTokenCredential(new AzureCliCredential(), resource)); // Otherwise, use Foundry with Azure Client authentication
AIAgent agent = client.CreateAIAgent(model: deploymentName, instructions: JokerInstructions, name: JokerName);
AIAgent agent = client.AsAIAgent(model: deploymentName, instructions: JokerInstructions, name: JokerName);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -27,7 +27,7 @@ var createdAgentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: J
// agentVersion.Name = <agentName>
// You can retrieve an AIAgent for an already created server side agent version.
AIAgent existingJokerAgent = aiProjectClient.GetAIAgent(createdAgentVersion);
AIAgent existingJokerAgent = aiProjectClient.AsAIAgent(createdAgentVersion);
// You can also create another AIAgent version by providing the same name with a different definition.
AIAgent newJokerAgent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: "You are extremely hilarious at telling jokes.");
@@ -25,7 +25,7 @@ OpenAIClient client = string.IsNullOrWhiteSpace(apiKey)
AIAgent agent = client
.GetChatClient(model)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -14,7 +14,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -14,7 +14,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetResponsesClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -1,558 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Runtime.CompilerServices;
using Google.Apis.Util;
using Google.GenAI;
using Google.GenAI.Types;
namespace Microsoft.Extensions.AI;
/// <summary>Provides an <see cref="IChatClient"/> implementation based on <see cref="Client"/>.</summary>
internal sealed class GoogleGenAIChatClient : IChatClient
{
/// <summary>The wrapped <see cref="Client"/> instance (optional).</summary>
private readonly Client? _client;
/// <summary>The wrapped <see cref="Models"/> instance.</summary>
private readonly Models _models;
/// <summary>The default model that should be used when no override is specified.</summary>
private readonly string? _defaultModelId;
/// <summary>Lazily-initialized metadata describing the implementation.</summary>
private ChatClientMetadata? _metadata;
/// <summary>Initializes a new <see cref="GoogleGenAIChatClient"/> instance.</summary>
public GoogleGenAIChatClient(Client client, string? defaultModelId)
{
this._client = client;
this._models = client.Models;
this._defaultModelId = defaultModelId;
}
/// <summary>Initializes a new <see cref="GoogleGenAIChatClient"/> instance.</summary>
public GoogleGenAIChatClient(Models client, string? defaultModelId)
{
this._models = client;
this._defaultModelId = defaultModelId;
}
/// <inheritdoc />
public async Task<ChatResponse> GetResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
{
Utilities.ThrowIfNull(messages, nameof(messages));
// Create the request.
(string? modelId, List<Content> contents, GenerateContentConfig config) = this.CreateRequest(messages, options);
// Send it.
GenerateContentResponse generateResult = await this._models.GenerateContentAsync(modelId!, contents, config).ConfigureAwait(false);
// Create the response.
ChatResponse chatResponse = new(new ChatMessage(ChatRole.Assistant, []))
{
CreatedAt = generateResult.CreateTime is { } dt ? new DateTimeOffset(dt) : null,
ModelId = !string.IsNullOrWhiteSpace(generateResult.ModelVersion) ? generateResult.ModelVersion : modelId,
RawRepresentation = generateResult,
ResponseId = generateResult.ResponseId,
};
// Populate the response messages.
chatResponse.FinishReason = PopulateResponseContents(generateResult, chatResponse.Messages[0].Contents);
// Populate usage information if there is any.
if (generateResult.UsageMetadata is { } usageMetadata)
{
chatResponse.Usage = ExtractUsageDetails(usageMetadata);
}
// Return the response.
return chatResponse;
}
/// <inheritdoc />
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
Utilities.ThrowIfNull(messages, nameof(messages));
// Create the request.
(string? modelId, List<Content> contents, GenerateContentConfig config) = this.CreateRequest(messages, options);
// Send it, and process the results.
await foreach (GenerateContentResponse generateResult in this._models.GenerateContentStreamAsync(modelId!, contents, config).WithCancellation(cancellationToken).ConfigureAwait(false))
{
// Create a response update for each result in the stream.
ChatResponseUpdate responseUpdate = new(ChatRole.Assistant, [])
{
CreatedAt = generateResult.CreateTime is { } dt ? new DateTimeOffset(dt) : null,
ModelId = !string.IsNullOrWhiteSpace(generateResult.ModelVersion) ? generateResult.ModelVersion : modelId,
RawRepresentation = generateResult,
ResponseId = generateResult.ResponseId,
};
// Populate the response update contents.
responseUpdate.FinishReason = PopulateResponseContents(generateResult, responseUpdate.Contents);
// Populate usage information if there is any.
if (generateResult.UsageMetadata is { } usageMetadata)
{
responseUpdate.Contents.Add(new UsageContent(ExtractUsageDetails(usageMetadata)));
}
// Yield the update.
yield return responseUpdate;
}
}
/// <inheritdoc />
public object? GetService(System.Type serviceType, object? serviceKey = null)
{
Utilities.ThrowIfNull(serviceType, nameof(serviceType));
if (serviceKey is null)
{
// If there's a request for metadata, lazily-initialize it and return it. We don't need to worry about race conditions,
// as there's no requirement that the same instance be returned each time, and creation is idempotent.
if (serviceType == typeof(ChatClientMetadata))
{
return this._metadata ??= new("gcp.gen_ai", new("https://generativelanguage.googleapis.com/"), defaultModelId: this._defaultModelId);
}
// Allow a consumer to "break glass" and access the underlying client if they need it.
if (serviceType.IsInstanceOfType(this._models))
{
return this._models;
}
if (this._client is not null && serviceType.IsInstanceOfType(this._client))
{
return this._client;
}
if (serviceType.IsInstanceOfType(this))
{
return this;
}
}
return null;
}
/// <inheritdoc />
void IDisposable.Dispose() { /* nop */ }
/// <summary>Creates the message parameters for <see cref="Models.GenerateContentAsync(string, List{Content}, GenerateContentConfig?)"/> from <paramref name="messages"/> and <paramref name="options"/>.</summary>
private (string? ModelId, List<Content> Contents, GenerateContentConfig Config) CreateRequest(IEnumerable<ChatMessage> messages, ChatOptions? options)
{
// Create the GenerateContentConfig object. If the options contains a RawRepresentationFactory, try to use it to
// create the request instance, allowing the caller to populate it with GenAI-specific options. Otherwise, create
// a new instance directly.
string? model = this._defaultModelId;
List<Content> contents = [];
GenerateContentConfig config = options?.RawRepresentationFactory?.Invoke(this) as GenerateContentConfig ?? new();
if (options is not null)
{
if (options.FrequencyPenalty is { } frequencyPenalty)
{
config.FrequencyPenalty ??= frequencyPenalty;
}
if (options.Instructions is { } instructions)
{
((config.SystemInstruction ??= new()).Parts ??= []).Add(new() { Text = instructions });
}
if (options.MaxOutputTokens is { } maxOutputTokens)
{
config.MaxOutputTokens ??= maxOutputTokens;
}
if (!string.IsNullOrWhiteSpace(options.ModelId))
{
model = options.ModelId;
}
if (options.PresencePenalty is { } presencePenalty)
{
config.PresencePenalty ??= presencePenalty;
}
if (options.Seed is { } seed)
{
config.Seed ??= (int)seed;
}
if (options.StopSequences is { } stopSequences)
{
(config.StopSequences ??= []).AddRange(stopSequences);
}
if (options.Temperature is { } temperature)
{
config.Temperature ??= temperature;
}
if (options.TopP is { } topP)
{
config.TopP ??= topP;
}
if (options.TopK is { } topK)
{
config.TopK ??= topK;
}
// Populate tools. Each kind of tool is added on its own, except for function declarations,
// which are grouped into a single FunctionDeclaration.
List<FunctionDeclaration>? functionDeclarations = null;
if (options.Tools is { } tools)
{
foreach (var tool in tools)
{
switch (tool)
{
case AIFunctionDeclaration af:
functionDeclarations ??= [];
functionDeclarations.Add(new()
{
Name = af.Name,
Description = af.Description ?? "",
ParametersJsonSchema = af.JsonSchema,
});
break;
case HostedCodeInterpreterTool:
(config.Tools ??= []).Add(new() { CodeExecution = new() });
break;
case HostedFileSearchTool:
(config.Tools ??= []).Add(new() { Retrieval = new() });
break;
case HostedWebSearchTool:
(config.Tools ??= []).Add(new() { GoogleSearch = new() });
break;
}
}
}
if (functionDeclarations is { Count: > 0 })
{
Tool functionTools = new();
(functionTools.FunctionDeclarations ??= []).AddRange(functionDeclarations);
(config.Tools ??= []).Add(functionTools);
}
// Transfer over the tool mode if there are any tools.
if (options.ToolMode is { } toolMode && config.Tools?.Count > 0)
{
switch (toolMode)
{
case NoneChatToolMode:
config.ToolConfig = new() { FunctionCallingConfig = new() { Mode = FunctionCallingConfigMode.NONE } };
break;
case AutoChatToolMode:
config.ToolConfig = new() { FunctionCallingConfig = new() { Mode = FunctionCallingConfigMode.AUTO } };
break;
case RequiredChatToolMode required:
config.ToolConfig = new() { FunctionCallingConfig = new() { Mode = FunctionCallingConfigMode.ANY } };
if (required.RequiredFunctionName is not null)
{
((config.ToolConfig.FunctionCallingConfig ??= new()).AllowedFunctionNames ??= []).Add(required.RequiredFunctionName);
}
break;
}
}
// Set the response format if specified.
if (options.ResponseFormat is ChatResponseFormatJson responseFormat)
{
config.ResponseMimeType = "application/json";
if (responseFormat.Schema is { } schema)
{
config.ResponseJsonSchema = schema;
}
}
}
// Transfer messages to request, handling system messages specially
Dictionary<string, string>? callIdToFunctionNames = null;
foreach (var message in messages)
{
if (message.Role == ChatRole.System)
{
string instruction = message.Text;
if (!string.IsNullOrWhiteSpace(instruction))
{
((config.SystemInstruction ??= new()).Parts ??= []).Add(new() { Text = instruction });
}
continue;
}
Content content = new() { Role = message.Role == ChatRole.Assistant ? "model" : "user" };
content.Parts ??= [];
AddPartsForAIContents(ref callIdToFunctionNames, message.Contents, content.Parts);
contents.Add(content);
}
// Make sure the request contains at least one content part (the request would always fail if empty).
if (!contents.SelectMany(c => c.Parts ?? Enumerable.Empty<Part>()).Any())
{
contents.Add(new() { Role = "user", Parts = new() { { new() { Text = "" } } } });
}
return (model, contents, config);
}
/// <summary>Creates <see cref="Part"/>s for <paramref name="contents"/> and adds them to <paramref name="parts"/>.</summary>
private static void AddPartsForAIContents(ref Dictionary<string, string>? callIdToFunctionNames, IList<AIContent> contents, List<Part> parts)
{
for (int i = 0; i < contents.Count; i++)
{
var content = contents[i];
byte[]? thoughtSignature = null;
if (content is not TextReasoningContent { ProtectedData: not null } &&
i + 1 < contents.Count &&
contents[i + 1] is TextReasoningContent nextReasoning &&
string.IsNullOrWhiteSpace(nextReasoning.Text) &&
nextReasoning.ProtectedData is { } protectedData)
{
i++;
thoughtSignature = Convert.FromBase64String(protectedData);
}
Part? part = null;
switch (content)
{
case TextContent textContent:
part = new() { Text = textContent.Text };
break;
case TextReasoningContent reasoningContent:
part = new()
{
Thought = true,
Text = !string.IsNullOrWhiteSpace(reasoningContent.Text) ? reasoningContent.Text : null,
ThoughtSignature = reasoningContent.ProtectedData is not null ? Convert.FromBase64String(reasoningContent.ProtectedData) : null,
};
break;
case DataContent dataContent:
part = new()
{
InlineData = new()
{
MimeType = dataContent.MediaType,
Data = dataContent.Data.ToArray(),
DisplayName = dataContent.Name,
}
};
break;
case UriContent uriContent:
part = new()
{
FileData = new()
{
FileUri = uriContent.Uri.AbsoluteUri,
MimeType = uriContent.MediaType,
}
};
break;
case FunctionCallContent functionCallContent:
(callIdToFunctionNames ??= [])[functionCallContent.CallId] = functionCallContent.Name;
callIdToFunctionNames[""] = functionCallContent.Name; // track last function name in case calls don't have IDs
part = new()
{
FunctionCall = new()
{
Id = functionCallContent.CallId,
Name = functionCallContent.Name,
Args = functionCallContent.Arguments is null ? null : functionCallContent.Arguments as Dictionary<string, object> ?? new(functionCallContent.Arguments!),
}
};
break;
case FunctionResultContent functionResultContent:
part = new()
{
FunctionResponse = new()
{
Id = functionResultContent.CallId,
Name = callIdToFunctionNames?.TryGetValue(functionResultContent.CallId, out string? functionName) is true || callIdToFunctionNames?.TryGetValue("", out functionName) is true ?
functionName :
null,
Response = functionResultContent.Result is null ? null : new() { ["result"] = functionResultContent.Result },
}
};
break;
}
if (part is not null)
{
part.ThoughtSignature ??= thoughtSignature;
parts.Add(part);
}
}
}
/// <summary>Creates <see cref="AIContent"/>s for <paramref name="parts"/> and adds them to <paramref name="contents"/>.</summary>
private static void AddAIContentsForParts(List<Part> parts, IList<AIContent> contents)
{
foreach (var part in parts)
{
AIContent? content = null;
if (!string.IsNullOrEmpty(part.Text))
{
content = part.Thought is true ?
new TextReasoningContent(part.Text) :
new TextContent(part.Text);
}
else if (part.InlineData is { } inlineData)
{
content = new DataContent(inlineData.Data, inlineData.MimeType ?? "application/octet-stream")
{
Name = inlineData.DisplayName,
};
}
else if (part.FileData is { FileUri: not null } fileData)
{
content = new UriContent(new Uri(fileData.FileUri), fileData.MimeType ?? "application/octet-stream");
}
else if (part.FunctionCall is { Name: not null } functionCall)
{
content = new FunctionCallContent(functionCall.Id ?? "", functionCall.Name, functionCall.Args!);
}
else if (part.FunctionResponse is { } functionResponse)
{
content = new FunctionResultContent(
functionResponse.Id ?? "",
functionResponse.Response?.TryGetValue("output", out var output) is true ? output :
functionResponse.Response?.TryGetValue("error", out var error) is true ? error :
null);
}
if (content is not null)
{
content.RawRepresentation = part;
contents.Add(content);
if (part.ThoughtSignature is { } thoughtSignature)
{
contents.Add(new TextReasoningContent(null)
{
ProtectedData = Convert.ToBase64String(thoughtSignature),
});
}
}
}
}
private static ChatFinishReason? PopulateResponseContents(GenerateContentResponse generateResult, IList<AIContent> responseContents)
{
ChatFinishReason? finishReason = null;
// Populate the response messages. There should only be at most one candidate, but if there are more, ignore all but the first.
if (generateResult.Candidates is { Count: > 0 } &&
generateResult.Candidates[0] is { Content: { } candidateContent } candidate)
{
// Grab the finish reason if one exists.
finishReason = ConvertFinishReason(candidate.FinishReason);
// Add all of the response content parts as AIContents.
if (candidateContent.Parts is { } parts)
{
AddAIContentsForParts(parts, responseContents);
}
// Add any citation metadata.
if (candidate.CitationMetadata is { Citations: { Count: > 0 } citations } &&
responseContents.OfType<TextContent>().FirstOrDefault() is TextContent textContent)
{
foreach (var citation in citations)
{
textContent.Annotations =
[
new CitationAnnotation()
{
Title = citation.Title,
Url = Uri.TryCreate(citation.Uri, UriKind.Absolute, out Uri? uri) ? uri : null,
AnnotatedRegions =
[
new TextSpanAnnotatedRegion()
{
StartIndex = citation.StartIndex,
EndIndex = citation.EndIndex,
}
],
}
];
}
}
}
// Populate error information if there is any.
if (generateResult.PromptFeedback is { } promptFeedback)
{
responseContents.Add(new ErrorContent(promptFeedback.BlockReasonMessage));
}
return finishReason;
}
/// <summary>Creates an M.E.AI <see cref="ChatFinishReason"/> from a Google <see cref="FinishReason"/>.</summary>
private static ChatFinishReason? ConvertFinishReason(FinishReason? finishReason)
{
return finishReason switch
{
null => null,
FinishReason.MAX_TOKENS =>
ChatFinishReason.Length,
FinishReason.MALFORMED_FUNCTION_CALL or
FinishReason.UNEXPECTED_TOOL_CALL =>
ChatFinishReason.ToolCalls,
FinishReason.FINISH_REASON_UNSPECIFIED or
FinishReason.STOP =>
ChatFinishReason.Stop,
_ => ChatFinishReason.ContentFilter,
};
}
/// <summary>Creates a <see cref="UsageDetails"/> populated from the supplied <paramref name="usageMetadata"/>.</summary>
private static UsageDetails ExtractUsageDetails(GenerateContentResponseUsageMetadata usageMetadata)
{
UsageDetails details = new()
{
InputTokenCount = usageMetadata.PromptTokenCount,
OutputTokenCount = usageMetadata.CandidatesTokenCount,
TotalTokenCount = usageMetadata.TotalTokenCount,
};
AddIfPresent(nameof(usageMetadata.CachedContentTokenCount), usageMetadata.CachedContentTokenCount);
AddIfPresent(nameof(usageMetadata.ThoughtsTokenCount), usageMetadata.ThoughtsTokenCount);
AddIfPresent(nameof(usageMetadata.ToolUsePromptTokenCount), usageMetadata.ToolUsePromptTokenCount);
return details;
void AddIfPresent(string key, int? value)
{
if (value is int i)
{
(details.AdditionalCounts ??= [])[key] = i;
}
}
}
}
@@ -1,36 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
using Google.Apis.Util;
using Google.GenAI;
namespace Microsoft.Extensions.AI;
/// <summary>Provides implementations of Microsoft.Extensions.AI abstractions based on <see cref="Client"/>.</summary>
public static class GoogleGenAIExtensions
{
/// <summary>
/// Creates an <see cref="IChatClient"/> wrapper around the specified <see cref="Client"/>.
/// </summary>
/// <param name="client">The <see cref="Client"/> to wrap.</param>
/// <param name="defaultModelId">The default model ID to use for chat requests if not specified in <see cref="ChatOptions.ModelId"/>.</param>
/// <returns>An <see cref="IChatClient"/> that wraps the specified client.</returns>
/// <exception cref="ArgumentNullException"><paramref name="client"/> is <see langword="null"/>.</exception>
public static IChatClient AsIChatClient(this Client client, string? defaultModelId = null)
{
Utilities.ThrowIfNull(client, nameof(client));
return new GoogleGenAIChatClient(client, defaultModelId);
}
/// <summary>
/// Creates an <see cref="IChatClient"/> wrapper around the specified <see cref="Models"/>.
/// </summary>
/// <param name="models">The <see cref="Models"/> client to wrap.</param>
/// <param name="defaultModelId">The default model ID to use for chat requests if not specified in <see cref="ChatOptions.ModelId"/>.</param>
/// <returns>An <see cref="IChatClient"/> that wraps the specified <see cref="Models"/> client.</returns>
/// <exception cref="ArgumentNullException"><paramref name="models"/> is <see langword="null"/>.</exception>
public static IChatClient AsIChatClient(this Models models, string? defaultModelId = null)
{
Utilities.ThrowIfNull(models, nameof(models));
return new GoogleGenAIChatClient(models, defaultModelId);
}
}
@@ -14,8 +14,6 @@ string apiKey = Environment.GetEnvironmentVariable("GOOGLE_GENAI_API_KEY") ?? th
string model = Environment.GetEnvironmentVariable("GOOGLE_GENAI_MODEL") ?? "gemini-2.5-flash";
// Using a Google GenAI IChatClient implementation
// Until the PR https://github.com/googleapis/dotnet-genai/pull/81 is not merged this option
// requires usage of also both GeminiChatClient.cs and GoogleGenAIExtensions.cs polyfills to work.
ChatClientAgent agentGenAI = new(
new Client(vertexAI: false, apiKey: apiKey).AsIChatClient(model),
@@ -25,12 +25,7 @@ $env:GOOGLE_GENAI_MODEL="gemini-2.5-fast" # Optional, defaults to gemini-2.5-fa
### Google GenAI (Official)
The official Google GenAI package provides direct access to Google's Generative AI models. This sample uses an extension method to convert the Google client to an `IChatClient`.
> [!NOTE]
> Until PR [googleapis/dotnet-genai#81](https://github.com/googleapis/dotnet-genai/pull/81) is merged, this option requires the additional `GeminiChatClient.cs` and `GoogleGenAIExtensions.cs` files included in this sample.
>
> We appreciate any community push by liking and commenting in the above PR to get it merged and release as part of official Google GenAI package.
The official Google GenAI package provides direct access to Google's Generative AI models. This sample uses the `AsIChatClient()` extension method to convert the Google client to an `IChatClient`.
### Mscc.GenerativeAI.Microsoft (Community)
@@ -12,7 +12,7 @@ var modelPath = Environment.GetEnvironmentVariable("ONNX_MODEL_PATH") ?? throw n
// Get a chat client for ONNX and use it to construct an AIAgent.
using OnnxRuntimeGenAIChatClient chatClient = new(modelPath);
AIAgent agent = chatClient.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
AIAgent agent = chatClient.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -11,7 +11,7 @@ var modelName = Environment.GetEnvironmentVariable("OLLAMA_MODEL_NAME") ?? throw
// Get a chat client for Ollama and use it to construct an AIAgent.
AIAgent agent = new OllamaApiClient(new Uri(endpoint), modelName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -13,7 +13,7 @@ var model = Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o-mini";
AIAgent agent = new OpenAIClient(
apiKey)
.GetChatClient(model)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -12,7 +12,7 @@ var model = Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o-mini";
AIAgent agent = new OpenAIClient(
apiKey)
.GetResponsesClient(model)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -11,7 +11,7 @@ var apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? throw ne
var model = Environment.GetEnvironmentVariable("ANTHROPIC_MODEL") ?? "claude-haiku-4-5";
AIAgent agent = new AnthropicClient(new ClientOptions { APIKey = apiKey })
.CreateAIAgent(model: model, instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(model: model, instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
var response = await agent.RunAsync("Tell me a joke about a pirate.");
@@ -14,7 +14,7 @@ var maxTokens = 4096;
var thinkingTokens = 2048;
var agent = new AnthropicClient(new ClientOptions { APIKey = apiKey })
.CreateAIAgent(
.AsAIAgent(
model: model,
clientFactory: (chatClient) => chatClient
.AsBuilder()
@@ -23,7 +23,7 @@ AITool tool = AIFunctionFactory.Create(GetWeather);
// Get anthropic client to create agents.
AIAgent agent = new AnthropicClient { APIKey = apiKey }
.CreateAIAgent(model: model, instructions: AssistantInstructions, name: AssistantName, tools: [tool]);
.AsAIAgent(model: model, instructions: AssistantInstructions, name: AssistantName, tools: [tool]);
// Non-streaming agent interaction with function tools.
AgentThread thread = await agent.GetNewThreadAsync();
@@ -30,7 +30,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
@@ -28,7 +28,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions()
.AsAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new() { Instructions = "You are a friendly travel assistant. Use known memories about the user when responding, and do not invent details." },
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(ctx.SerializedState.ValueKind is not JsonValueKind.Null and not JsonValueKind.Undefined
@@ -30,7 +30,7 @@ ChatClient chatClient = new AzureOpenAIClient(
// and preferably shared between multiple threads used by the same user, ensure that the
// factory reads the user id from the current context and scopes the memory component
// and its storage to that user id.
AIAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions()
AIAgent agent = chatClient.AsAIAgent(new ChatClientAgentOptions()
{
ChatOptions = new() { Instructions = "You are a friendly assistant. Always address the user by their name." },
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new UserInfoMemory(chatClient.AsIChatClient(), ctx.SerializedState, ctx.JsonSerializerOptions))
@@ -12,7 +12,7 @@ var model = Environment.GetEnvironmentVariable("OPENAI_MODEL") ?? "gpt-4o-mini";
AIAgent agent = new OpenAIClient(apiKey)
.GetChatClient(model)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
UserChatMessage chatMessage = new("Tell me a joke about a pirate.");
@@ -59,7 +59,7 @@ TextSearchProviderOptions textSearchOptions = new()
// Create the AI agent with the TextSearchProvider as the AI context provider.
AIAgent agent = azureOpenAIClient
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available." },
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)),
@@ -68,7 +68,7 @@ TextSearchProviderOptions textSearchOptions = new()
// Create the AI agent with the TextSearchProvider as the AI context provider.
AIAgent agent = azureOpenAIClient
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist for the Microsoft Agent Framework. Answer questions using the provided context and cite the source document when available. Keep responses brief." },
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions))
@@ -26,7 +26,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available." },
AIContextProviderFactory = (ctx, ct) => new ValueTask<AIContextProvider>(new TextSearchProvider(MockSearchAsync, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions))
@@ -14,7 +14,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -14,7 +14,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent with a multi-turn conversation, where the context is preserved in the thread object.
AgentThread thread = await agent.GetNewThreadAsync();
@@ -22,7 +22,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
.AsAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
// Non-streaming agent interaction with function tools.
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
@@ -27,7 +27,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant", tools: [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather))]);
.AsAIAgent(instructions: "You are a helpful assistant", tools: [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather))]);
// Call the agent and check if there are any user input requests to handle.
AgentThread thread = await agent.GetNewThreadAsync();
@@ -21,7 +21,7 @@ ChatClient chatClient = new AzureOpenAIClient(
.GetChatClient(deploymentName);
// Create the ChatClientAgent with the specified name and instructions.
ChatClientAgent agent = chatClient.CreateAIAgent(name: "HelpfulAssistant", instructions: "You are a helpful assistant.");
ChatClientAgent agent = chatClient.AsAIAgent(name: "HelpfulAssistant", instructions: "You are a helpful assistant.");
// Set PersonInfo as the type parameter of RunAsync method to specify the expected structured output from the agent and invoke the agent with some unstructured input.
AgentResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
@@ -33,7 +33,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 = chatClient.CreateAIAgent(new ChatClientAgentOptions()
ChatClientAgent agentWithPersonInfo = chatClient.AsAIAgent(new ChatClientAgentOptions()
{
Name = "HelpfulAssistant",
ChatOptions = new() { Instructions = "You are a helpful assistant.", ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>() }
@@ -16,7 +16,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Start a new thread for the agent conversation.
AgentThread thread = await agent.GetNewThreadAsync();
@@ -27,7 +27,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
@@ -29,7 +29,7 @@ using var tracerProvider = tracerProviderBuilder.Build();
// Create the agent, and enable OpenTelemetry instrumentation.
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are good at telling jokes.", name: "Joker")
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker")
.AsBuilder()
.UseOpenTelemetry(sourceName: sourceName)
.Build();
@@ -13,7 +13,7 @@ var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEP
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
name: "VisionAgent",
instructions: "You are a helpful agent that can analyze images");
@@ -21,7 +21,7 @@ AIAgent weatherAgent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You answer questions about the weather.",
name: "WeatherAgent",
description: "An agent that answers questions about the weather.",
@@ -32,7 +32,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant who responds in French.", tools: [weatherAgent.AsAIFunction()]);
.AsAIAgent(instructions: "You are a helpful assistant who responds in French.", tools: [weatherAgent.AsAIFunction()]);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
@@ -23,7 +23,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetResponsesClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
name: "SpaceNovelWriter",
instructions: "You are a space novel writer. Always research relevant facts and generate character profiles for the main characters before writing novels." +
"Write complete chapters without asking for approval or feedback. Do not ask the user about tone, style, pace, or format preferences - just write the novel based on the request.",
@@ -31,7 +31,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are a helpful assistant that helps people find information.",
name: "Assistant",
tools: [.. serviceProvider.GetRequiredService<AgentPlugin>().AsAITools()],
@@ -20,7 +20,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are good at telling jokes." },
Name = "Joker",
@@ -14,7 +14,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetResponsesClient(deploymentName)
.CreateAIAgent();
.AsAIAgent();
// Enable background responses (only supported by OpenAI Responses at this time).
AgentRunOptions options = new() { AllowBackgroundResponses = true };
@@ -27,7 +27,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You answer questions related to GitHub repositories only.", tools: [.. mcpTools.Cast<AITool>()]);
.AsAIAgent(instructions: "You answer questions related to GitHub repositories only.", tools: [.. mcpTools.Cast<AITool>()]);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Summarize the last four commits to the microsoft/semantic-kernel repository?"));
@@ -50,7 +50,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(instructions: "You answer questions related to the weather.", tools: [.. mcpTools]);
.AsAIAgent(instructions: "You answer questions related to the weather.", tools: [.. mcpTools]);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Get current weather alerts for New York?"));
@@ -31,7 +31,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetResponsesClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgent",
tools: [mcpTool]);
@@ -58,7 +58,7 @@ AIAgent agentWithRequiredApproval = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetResponsesClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgentWithApproval",
tools: [mcpToolWithApproval]);
@@ -27,11 +27,11 @@ public static class A2AAgentCardExtensions
/// <param name="httpClient">The <see cref="HttpClient"/> to use for HTTP requests.</param>
/// <param name="loggerFactory">The logger factory for enabling logging within the agent.</param>
/// <returns>An <see cref="AIAgent"/> instance backed by the A2A agent.</returns>
public static AIAgent GetAIAgent(this AgentCard card, HttpClient? httpClient = null, ILoggerFactory? loggerFactory = null)
public static AIAgent AsAIAgent(this AgentCard card, HttpClient? httpClient = null, ILoggerFactory? loggerFactory = null)
{
// Create the A2A client using the agent URL from the card.
var a2aClient = new A2AClient(new Uri(card.Url), httpClient);
return a2aClient.GetAIAgent(name: card.Name, description: card.Description, loggerFactory: loggerFactory);
return a2aClient.AsAIAgent(name: card.Name, description: card.Description, loggerFactory: loggerFactory);
}
}
@@ -42,6 +42,6 @@ public static class A2ACardResolverExtensions
// Obtain the agent card from the resolver.
var agentCard = await resolver.GetAgentCardAsync(cancellationToken).ConfigureAwait(false);
return agentCard.GetAIAgent(httpClient, loggerFactory);
return agentCard.AsAIAgent(httpClient, loggerFactory);
}
}
@@ -35,6 +35,6 @@ public static class A2AClientExtensions
/// <param name="description">The description of the agent.</param>
/// <param name="loggerFactory">Optional logger factory for enabling logging within the agent.</param>
/// <returns>An <see cref="AIAgent"/> instance backed by the A2A agent.</returns>
public static AIAgent GetAIAgent(this A2AClient client, string? id = null, string? name = null, string? description = null, ILoggerFactory? loggerFactory = null) =>
public static AIAgent AsAIAgent(this A2AClient client, string? id = null, string? name = null, string? description = null, ILoggerFactory? loggerFactory = null) =>
new A2AAgent(client, id, name, description, loggerFactory);
}
@@ -31,7 +31,7 @@ public static class AnthropicBetaServiceExtensions
/// <param name="loggerFactory">Optional logger factory for enabling logging within the agent.</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>The created <see cref="ChatClientAgent"/> AI agent.</returns>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IBetaService betaService,
string model,
string? instructions = null,
@@ -81,7 +81,7 @@ public static class AnthropicBetaServiceExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the Anthropic Chat Completion service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="betaService"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IBetaService betaService,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
@@ -31,7 +31,7 @@ public static class AnthropicClientExtensions
/// <param name="loggerFactory">Optional logger factory for enabling logging within the agent.</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>The created <see cref="ChatClientAgent"/> AI agent.</returns>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IAnthropicClient client,
string model,
string? instructions = null,
@@ -81,7 +81,7 @@ public static class AnthropicClientExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the Anthropic Chat Completion service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="client"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IAnthropicClient client,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
@@ -19,7 +19,7 @@ public static class PersistentAgentsClientExtensions
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</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 on the persistent agent.</returns>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this PersistentAgentsClient persistentAgentsClient,
Response<PersistentAgent> persistentAgentResponse,
ChatOptions? chatOptions = null,
@@ -31,7 +31,7 @@ public static class PersistentAgentsClientExtensions
throw new ArgumentNullException(nameof(persistentAgentResponse));
}
return GetAIAgent(persistentAgentsClient, persistentAgentResponse.Value, chatOptions, clientFactory, services);
return AsAIAgent(persistentAgentsClient, persistentAgentResponse.Value, chatOptions, clientFactory, services);
}
/// <summary>
@@ -43,7 +43,7 @@ public static class PersistentAgentsClientExtensions
/// <param name="clientFactory">Provides a way to customize the creation of the underlying <see cref="IChatClient"/> used by the agent.</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 on the persistent agent.</returns>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this PersistentAgentsClient persistentAgentsClient,
PersistentAgent persistentAgentMetadata,
ChatOptions? chatOptions = null,
@@ -112,7 +112,7 @@ public static class PersistentAgentsClientExtensions
}
var persistentAgentResponse = persistentAgentsClient.Administration.GetAgent(agentId, cancellationToken);
return persistentAgentsClient.GetAIAgent(persistentAgentResponse, chatOptions, clientFactory, services);
return persistentAgentsClient.AsAIAgent(persistentAgentResponse, chatOptions, clientFactory, services);
}
/// <summary>
@@ -145,7 +145,7 @@ public static class PersistentAgentsClientExtensions
}
var persistentAgentResponse = await persistentAgentsClient.Administration.GetAgentAsync(agentId, cancellationToken).ConfigureAwait(false);
return persistentAgentsClient.GetAIAgent(persistentAgentResponse, chatOptions, clientFactory, services);
return persistentAgentsClient.AsAIAgent(persistentAgentResponse, chatOptions, clientFactory, services);
}
/// <summary>
@@ -158,7 +158,7 @@ public static class PersistentAgentsClientExtensions
/// <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 on the persistent agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="persistentAgentResponse"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this PersistentAgentsClient persistentAgentsClient,
Response<PersistentAgent> persistentAgentResponse,
ChatClientAgentOptions options,
@@ -170,7 +170,7 @@ public static class PersistentAgentsClientExtensions
throw new ArgumentNullException(nameof(persistentAgentResponse));
}
return GetAIAgent(persistentAgentsClient, persistentAgentResponse.Value, options, clientFactory, services);
return AsAIAgent(persistentAgentsClient, persistentAgentResponse.Value, options, clientFactory, services);
}
/// <summary>
@@ -183,7 +183,7 @@ public static class PersistentAgentsClientExtensions
/// <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 on the persistent agent.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="persistentAgentMetadata"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this PersistentAgentsClient persistentAgentsClient,
PersistentAgent persistentAgentMetadata,
ChatClientAgentOptions options,
@@ -268,7 +268,7 @@ public static class PersistentAgentsClientExtensions
}
var persistentAgentResponse = persistentAgentsClient.Administration.GetAgent(agentId, cancellationToken);
return persistentAgentsClient.GetAIAgent(persistentAgentResponse, options, clientFactory, services);
return persistentAgentsClient.AsAIAgent(persistentAgentResponse, options, clientFactory, services);
}
/// <summary>
@@ -307,7 +307,7 @@ public static class PersistentAgentsClientExtensions
}
var persistentAgentResponse = await persistentAgentsClient.Administration.GetAgentAsync(agentId, cancellationToken).ConfigureAwait(false);
return persistentAgentsClient.GetAIAgent(persistentAgentResponse, options, clientFactory, services);
return persistentAgentsClient.AsAIAgent(persistentAgentResponse, options, clientFactory, services);
}
/// <summary>
@@ -91,7 +91,7 @@ public static partial class AzureAIProjectChatClientExtensions
AgentRecord agentRecord = GetAgentRecordByName(aiProjectClient, name, cancellationToken);
return GetAIAgent(
return AsAIAgent(
aiProjectClient,
agentRecord,
tools,
@@ -125,7 +125,7 @@ public static partial class AzureAIProjectChatClientExtensions
AgentRecord agentRecord = await GetAgentRecordByNameAsync(aiProjectClient, name, cancellationToken).ConfigureAwait(false);
return GetAIAgent(
return AsAIAgent(
aiProjectClient,
agentRecord,
tools,
@@ -143,7 +143,7 @@ public static partial class AzureAIProjectChatClientExtensions
/// <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="aiProjectClient"/> or <paramref name="agentRecord"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AIProjectClient aiProjectClient,
AgentRecord agentRecord,
IList<AITool>? tools = null,
@@ -174,7 +174,7 @@ public static partial class AzureAIProjectChatClientExtensions
/// <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="aiProjectClient"/> or <paramref name="agentVersion"/> is <see langword="null"/>.</exception>
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AIProjectClient aiProjectClient,
AgentVersion agentVersion,
IList<AITool>? tools = null,
@@ -36,13 +36,13 @@ This package provides a `ConfigureDurableAgents` extension method on the `Functi
// Invocable via HTTP via http://localhost:7071/api/agents/SpamDetectionAgent/run
AIAgent spamDetector = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are a spam detection assistant that identifies spam emails.",
name: "SpamDetectionAgent");
AIAgent emailAssistant = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are an email assistant that helps users draft responses to emails with professionalism.",
name: "EmailAssistantAgent");
@@ -156,7 +156,7 @@ These tools are registered with the agent using the `tools` parameter when creat
Tools tools = new();
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(
.AsAIAgent(
instructions: "You are a content generation assistant that helps users generate content.",
name: "ContentGenerationAgent",
tools: [
@@ -30,7 +30,7 @@ public static class OpenAIAssistantClientExtensions
/// <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 on the assistant.</returns>
[Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")]
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AssistantClient assistantClient,
ClientResult<Assistant> assistantClientResult,
ChatOptions? chatOptions = null,
@@ -42,7 +42,7 @@ public static class OpenAIAssistantClientExtensions
throw new ArgumentNullException(nameof(assistantClientResult));
}
return assistantClient.GetAIAgent(assistantClientResult.Value, chatOptions, clientFactory, services);
return assistantClient.AsAIAgent(assistantClientResult.Value, chatOptions, clientFactory, services);
}
/// <summary>
@@ -55,7 +55,7 @@ public static class OpenAIAssistantClientExtensions
/// <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 on the assistant.</returns>
[Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")]
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AssistantClient assistantClient,
Assistant assistantMetadata,
ChatOptions? chatOptions = null,
@@ -123,7 +123,7 @@ public static class OpenAIAssistantClientExtensions
}
var assistant = assistantClient.GetAssistant(agentId, cancellationToken);
return assistantClient.GetAIAgent(assistant, chatOptions, clientFactory, services);
return assistantClient.AsAIAgent(assistant, chatOptions, clientFactory, services);
}
/// <summary>
@@ -156,7 +156,7 @@ public static class OpenAIAssistantClientExtensions
}
var assistantResponse = await assistantClient.GetAssistantAsync(agentId, cancellationToken).ConfigureAwait(false);
return assistantClient.GetAIAgent(assistantResponse, chatOptions, clientFactory, services);
return assistantClient.AsAIAgent(assistantResponse, chatOptions, clientFactory, services);
}
/// <summary>
@@ -170,7 +170,7 @@ public static class OpenAIAssistantClientExtensions
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the assistant.</returns>
/// <exception cref="ArgumentNullException"><paramref name="assistantClientResult"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
[Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")]
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AssistantClient assistantClient,
ClientResult<Assistant> assistantClientResult,
ChatClientAgentOptions options,
@@ -182,7 +182,7 @@ public static class OpenAIAssistantClientExtensions
throw new ArgumentNullException(nameof(assistantClientResult));
}
return assistantClient.GetAIAgent(assistantClientResult.Value, options, clientFactory, services);
return assistantClient.AsAIAgent(assistantClientResult.Value, options, clientFactory, services);
}
/// <summary>
@@ -196,7 +196,7 @@ public static class OpenAIAssistantClientExtensions
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the assistant.</returns>
/// <exception cref="ArgumentNullException"><paramref name="assistantMetadata"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
[Obsolete("The Assistants API has been deprecated. Please use the Responses API instead.")]
public static ChatClientAgent GetAIAgent(
public static ChatClientAgent AsAIAgent(
this AssistantClient assistantClient,
Assistant assistantMetadata,
ChatClientAgentOptions options,
@@ -282,7 +282,7 @@ public static class OpenAIAssistantClientExtensions
}
var assistant = assistantClient.GetAssistant(agentId, cancellationToken);
return assistantClient.GetAIAgent(assistant, options, clientFactory, services);
return assistantClient.AsAIAgent(assistant, options, clientFactory, services);
}
/// <summary>
@@ -322,7 +322,7 @@ public static class OpenAIAssistantClientExtensions
}
var assistantResponse = await assistantClient.GetAssistantAsync(agentId, cancellationToken).ConfigureAwait(false);
return assistantClient.GetAIAgent(assistantResponse, options, clientFactory, services);
return assistantClient.AsAIAgent(assistantResponse, options, clientFactory, services);
}
/// <summary>
@@ -32,7 +32,7 @@ public static class OpenAIChatClientExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the OpenAI Chat Completion service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="client"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this ChatClient client,
string? instructions = null,
string? name = null,
@@ -41,7 +41,7 @@ public static class OpenAIChatClientExtensions
Func<IChatClient, IChatClient>? clientFactory = null,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null) =>
client.CreateAIAgent(
client.AsAIAgent(
new ChatClientAgentOptions()
{
Name = name,
@@ -66,7 +66,7 @@ public static class OpenAIChatClientExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the OpenAI Chat Completion service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="client"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this ChatClient client,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
@@ -32,7 +32,7 @@ public static class OpenAIResponseClientExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the OpenAI Response service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="client"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
string? instructions = null,
string? name = null,
@@ -44,7 +44,7 @@ public static class OpenAIResponseClientExtensions
{
Throw.IfNull(client);
return client.CreateAIAgent(
return client.AsAIAgent(
new ChatClientAgentOptions()
{
Name = name,
@@ -70,7 +70,7 @@ public static class OpenAIResponseClientExtensions
/// <param name="services">An optional <see cref="IServiceProvider"/> to use for resolving services required by the <see cref="AIFunction"/> instances being invoked.</param>
/// <returns>An <see cref="ChatClientAgent"/> instance backed by the OpenAI Response service.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="client"/> or <paramref name="options"/> is <see langword="null"/>.</exception>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
ChatClientAgentOptions options,
Func<IChatClient, IChatClient>? clientFactory = null,
@@ -12,7 +12,7 @@ namespace Microsoft.Agents.AI.Purview;
/// <summary>
/// Service that runs jobs in background threads.
/// </summary>
internal sealed class BackgroundJobRunner
internal sealed class BackgroundJobRunner : IBackgroundJobRunner
{
private readonly IChannelHandler _channelHandler;
private readonly IPurviewClient _purviewClient;
@@ -70,4 +70,12 @@ internal sealed class BackgroundJobRunner
break;
}
}
/// <summary>
/// Shutdown the job runners.
/// </summary>
public async Task ShutdownAsync()
{
await this._channelHandler.StopAndWaitForCompletionAsync().ConfigureAwait(false);
}
}
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Threading.Tasks;
namespace Microsoft.Agents.AI.Purview;
/// <summary>
/// An interface for a class that manages background jobs.
/// </summary>
internal interface IBackgroundJobRunner
{
/// <summary>
/// Shutdown the background jobs.
/// </summary>
Task ShutdownAsync();
}
@@ -41,7 +41,7 @@ public static class PurviewExtensions
services.AddSingleton<PurviewWrapper>();
services.AddSingleton(Channel.CreateBounded<BackgroundJobBase>(purviewSettings.PendingBackgroundJobLimit));
services.AddSingleton<IChannelHandler, ChannelHandler>();
services.AddSingleton<BackgroundJobRunner>();
services.AddSingleton<IBackgroundJobRunner, BackgroundJobRunner>();
ServiceProvider serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetRequiredService<PurviewWrapper>();
@@ -18,7 +18,7 @@ internal sealed class PurviewWrapper : IDisposable
private readonly ILogger _logger;
private readonly IScopedContentProcessor _scopedProcessor;
private readonly PurviewSettings _purviewSettings;
private readonly IChannelHandler _channelHandler;
private readonly IBackgroundJobRunner _backgroundJobRunner;
/// <summary>
/// Creates a new <see cref="PurviewWrapper"/> instance.
@@ -26,13 +26,13 @@ internal sealed class PurviewWrapper : IDisposable
/// <param name="scopedProcessor">The scoped processor used to orchestrate the calls to Purview.</param>
/// <param name="purviewSettings">The settings for Purview integration.</param>
/// <param name="logger">The logger used for logging.</param>
/// <param name="channelHandler">The channel handler used to queue background jobs and add job runners.</param>
public PurviewWrapper(IScopedContentProcessor scopedProcessor, PurviewSettings purviewSettings, ILogger logger, IChannelHandler channelHandler)
/// <param name="backgroundJobRunner">The runner used to manage background jobs.</param>
public PurviewWrapper(IScopedContentProcessor scopedProcessor, PurviewSettings purviewSettings, ILogger logger, IBackgroundJobRunner backgroundJobRunner)
{
this._scopedProcessor = scopedProcessor;
this._purviewSettings = purviewSettings;
this._logger = logger;
this._channelHandler = channelHandler;
this._backgroundJobRunner = backgroundJobRunner;
}
private static string GetThreadIdFromAgentThread(AgentThread? thread, IEnumerable<ChatMessage> messages)
@@ -203,7 +203,7 @@ internal sealed class PurviewWrapper : IDisposable
public void Dispose()
{
#pragma warning disable VSTHRD002 // Need to wait for pending jobs to complete.
this._channelHandler.StopAndWaitForCompletionAsync().GetAwaiter().GetResult();
this._backgroundJobRunner.ShutdownAsync().GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Need to wait for pending jobs to complete.
}
}
@@ -186,7 +186,7 @@ AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent("You are a helpful assistant.")
.AsAIAgent("You are a helpful assistant.")
.AsBuilder()
.WithPurview(browserCredential, new PurviewSettings("Agent Framework Test App"))
.Build();
@@ -174,7 +174,7 @@ public sealed class AzureAgentProvider(Uri projectEndpoint, TokenCredential proj
AIProjectClient client = this.GetAgentClient();
agent = client.GetAIAgent(agentVersion, tools: null, clientFactory: null, services: null);
agent = client.AsAIAgent(agentVersion, tools: null, clientFactory: null, services: null);
FunctionInvokingChatClient? functionInvokingClient = agent.GetService<FunctionInvokingChatClient>();
if (functionInvokingClient is not null)
@@ -519,16 +519,16 @@ public sealed partial class ChatClientAgent : AIAgent
{
ChatOptions? requestChatOptions = (runOptions as ChatClientAgentRunOptions)?.ChatOptions?.Clone();
// If no agent chat options were provided, return the request chat options as is.
// If no agent chat options were provided, return the request chat options with just agent run options overrides.
if (this._agentOptions?.ChatOptions is null)
{
return GetContinuationTokenAndApplyBackgroundResponsesProperties(requestChatOptions, runOptions);
return ApplyAgentRunOptionsOverrides(requestChatOptions, runOptions);
}
// If no request chat options were provided, use the agent's chat options clone.
// If no request chat options were provided, use the agent's chat options clone with agent run options overrides.
if (requestChatOptions is null)
{
return GetContinuationTokenAndApplyBackgroundResponsesProperties(this._agentOptions?.ChatOptions.Clone(), runOptions);
return ApplyAgentRunOptionsOverrides(this._agentOptions?.ChatOptions.Clone(), runOptions);
}
// If both are present, we need to merge them.
@@ -557,9 +557,9 @@ public sealed partial class ChatClientAgent : AIAgent
// Merge only the additional properties from the agent if they are not already set in the request options.
if (requestChatOptions.AdditionalProperties is not null && this._agentOptions.ChatOptions.AdditionalProperties is not null)
{
foreach (var propertyKey in this._agentOptions.ChatOptions.AdditionalProperties.Keys)
foreach (var kvp in this._agentOptions.ChatOptions.AdditionalProperties)
{
_ = requestChatOptions.AdditionalProperties.TryAdd(propertyKey, this._agentOptions.ChatOptions.AdditionalProperties[propertyKey]);
_ = requestChatOptions.AdditionalProperties.TryAdd(kvp.Key, kvp.Value);
}
}
else
@@ -624,9 +624,9 @@ public sealed partial class ChatClientAgent : AIAgent
}
}
return GetContinuationTokenAndApplyBackgroundResponsesProperties(requestChatOptions, runOptions);
return ApplyAgentRunOptionsOverrides(requestChatOptions, runOptions);
static (ChatOptions?, ChatClientAgentContinuationToken?) GetContinuationTokenAndApplyBackgroundResponsesProperties(ChatOptions? chatOptions, AgentRunOptions? agentRunOptions)
static (ChatOptions?, ChatClientAgentContinuationToken?) ApplyAgentRunOptionsOverrides(ChatOptions? chatOptions, AgentRunOptions? agentRunOptions)
{
if (agentRunOptions?.AllowBackgroundResponses is not null)
{
@@ -643,6 +643,17 @@ public sealed partial class ChatClientAgent : AIAgent
chatOptions.ContinuationToken = agentContinuationToken!.InnerToken;
}
// Add/Replace any additional properties from the AgentRunOptions, since they should always take precedence.
if (agentRunOptions?.AdditionalProperties is { Count: > 0 })
{
chatOptions ??= new ChatOptions();
chatOptions.AdditionalProperties ??= new();
foreach (var kvp in agentRunOptions.AdditionalProperties)
{
chatOptions.AdditionalProperties[kvp.Key] = kvp.Value;
}
}
return (chatOptions, agentContinuationToken);
}
}
@@ -49,7 +49,7 @@ public static class ChatClientBuilderExtensions
IList<AITool>? tools = null,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null) =>
Throw.IfNull(builder).Build(services).CreateAIAgent(
Throw.IfNull(builder).Build(services).AsAIAgent(
instructions: instructions,
name: name,
description: description,
@@ -78,7 +78,7 @@ public static class ChatClientBuilderExtensions
ChatClientAgentOptions? options,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null) =>
Throw.IfNull(builder).Build(services).CreateAIAgent(
Throw.IfNull(builder).Build(services).AsAIAgent(
options: options,
loggerFactory: loggerFactory,
services: services);
@@ -20,7 +20,7 @@ public static class ChatClientExtensions
/// </summary>
/// <inheritdoc cref="ChatClientAgent(IChatClient, string?, string?, string?, IList{AITool}?, ILoggerFactory?, IServiceProvider?)"/>
/// <returns>A new <see cref="ChatClientAgent"/> instance.</returns>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IChatClient chatClient,
string? instructions = null,
string? name = null,
@@ -42,7 +42,7 @@ public static class ChatClientExtensions
/// </summary>
/// <inheritdoc cref="ChatClientAgent(IChatClient, ChatClientAgentOptions?, ILoggerFactory?, IServiceProvider?)"/>
/// <returns>A new <see cref="ChatClientAgent"/> instance.</returns>
public static ChatClientAgent CreateAIAgent(
public static ChatClientAgent AsAIAgent(
this IChatClient chatClient,
ChatClientAgentOptions? options,
ILoggerFactory? loggerFactory = null,
@@ -34,7 +34,7 @@ public sealed class A2AAgentCardExtensionsTests
public void GetAIAgent_ReturnsAIAgent()
{
// Act
var agent = this._agentCard.GetAIAgent();
var agent = this._agentCard.AsAIAgent();
// Assert
Assert.NotNull(agent);
@@ -56,7 +56,7 @@ public sealed class A2AAgentCardExtensionsTests
Parts = [new TextPart { Text = "Response" }],
});
var agent = this._agentCard.GetAIAgent(httpClient);
var agent = this._agentCard.AsAIAgent(httpClient);
// Act
await agent.RunAsync("Test input");
@@ -21,7 +21,7 @@ public sealed class A2AClientExtensionsTests
const string TestDescription = "This is a test agent description";
// Act
var agent = a2aClient.GetAIAgent(TestId, TestName, TestDescription);
var agent = a2aClient.AsAIAgent(TestId, TestName, TestDescription);
// Assert
Assert.NotNull(agent);
@@ -30,7 +30,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -55,7 +55,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -74,7 +74,7 @@ public sealed class AGUIAgentTests
// Arrange
using HttpClient httpClient = new();
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: "Test agent", name: "agent1");
AIAgent agent = chatClient.AsAIAgent(instructions: "Test agent", name: "agent1");
// Act & Assert
await Assert.ThrowsAsync<ArgumentNullException>(() => agent.RunAsync(messages: null!));
@@ -91,7 +91,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: "Test agent", name: "agent1");
AIAgent agent = chatClient.AsAIAgent(instructions: "Test agent", name: "agent1");
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -115,7 +115,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: "Test agent", name: "agent1");
AIAgent agent = chatClient.AsAIAgent(instructions: "Test agent", name: "agent1");
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -139,7 +139,7 @@ public sealed class AGUIAgentTests
// Arrange
using HttpClient httpClient = new();
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: "Test agent", name: "agent1");
AIAgent agent = chatClient.AsAIAgent(instructions: "Test agent", name: "agent1");
// Act & Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
@@ -162,7 +162,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: "Test agent", name: "agent1");
AIAgent agent = chatClient.AsAIAgent(instructions: "Test agent", name: "agent1");
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -195,7 +195,7 @@ public sealed class AGUIAgentTests
using HttpClient httpClient = new(handler);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -227,7 +227,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Hello")];
@@ -249,7 +249,7 @@ public sealed class AGUIAgentTests
// Arrange
using var httpClient = new HttpClient();
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AgentThread originalThread = await agent.GetNewThreadAsync();
JsonElement serialized = originalThread.Serialize();
@@ -301,7 +301,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [testTool]);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [testTool]);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "What's the weather?")];
// Act
@@ -353,7 +353,7 @@ public sealed class AGUIAgentTests
using HttpClient httpClient = new(handler);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [tool1]); // Only tool1, not tool2
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [tool1]); // Only tool1, not tool2
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -403,7 +403,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [faultyTool]);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [faultyTool]);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -448,7 +448,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [tool1, tool2]);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [tool1, tool2]);
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
// Act
@@ -486,7 +486,7 @@ public sealed class AGUIAgentTests
]);
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.CreateAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [testTool]);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: [testTool]);
AgentThread thread = await agent.GetNewThreadAsync();
List<ChatMessage> messages = [new ChatMessage(ChatRole.User, "Test")];
@@ -34,7 +34,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
var testChatClient = new TestChatClient(chatClient.Beta.AsIChatClient());
// Act
var agent = chatClient.Beta.CreateAIAgent(
var agent = chatClient.Beta.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent",
@@ -63,7 +63,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
TestChatClient? testChatClient = null;
// Act
var agent = chatClient.Beta.CreateAIAgent(
var agent = chatClient.Beta.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
clientFactory: (innerClient) =>
@@ -95,7 +95,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
};
// Act
var agent = chatClient.Beta.CreateAIAgent(
var agent = chatClient.Beta.AsAIAgent(
options,
clientFactory: (innerClient) => testChatClient);
@@ -120,7 +120,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
var chatClient = new TestAnthropicChatClient();
// Act
var agent = chatClient.Beta.CreateAIAgent(
var agent = chatClient.Beta.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent");
@@ -144,7 +144,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
var chatClient = new TestAnthropicChatClient();
// Act
var agent = chatClient.Beta.CreateAIAgent(
var agent = chatClient.Beta.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent",
@@ -167,7 +167,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
{
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
((IBetaService)null!).CreateAIAgent("test-model"));
((IBetaService)null!).AsAIAgent("test-model"));
Assert.Equal("betaService", exception.ParamName);
}
@@ -183,7 +183,7 @@ public sealed class AnthropicBetaServiceExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
chatClient.Beta.CreateAIAgent((ChatClientAgentOptions)null!));
chatClient.Beta.AsAIAgent((ChatClientAgentOptions)null!));
Assert.Equal("options", exception.ParamName);
}
@@ -101,7 +101,7 @@ public sealed class AnthropicClientExtensionsTests
var testChatClient = new TestChatClient(chatClient.AsIChatClient());
// Act
var agent = chatClient.CreateAIAgent(
var agent = chatClient.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent",
@@ -130,7 +130,7 @@ public sealed class AnthropicClientExtensionsTests
TestChatClient? testChatClient = null;
// Act
var agent = chatClient.CreateAIAgent(
var agent = chatClient.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
clientFactory: (innerClient) =>
@@ -162,7 +162,7 @@ public sealed class AnthropicClientExtensionsTests
};
// Act
var agent = chatClient.CreateAIAgent(
var agent = chatClient.AsAIAgent(
options,
clientFactory: (innerClient) => testChatClient);
@@ -187,7 +187,7 @@ public sealed class AnthropicClientExtensionsTests
var chatClient = new TestAnthropicChatClient();
// Act
var agent = chatClient.CreateAIAgent(
var agent = chatClient.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent");
@@ -211,7 +211,7 @@ public sealed class AnthropicClientExtensionsTests
var chatClient = new TestAnthropicChatClient();
// Act
var agent = chatClient.CreateAIAgent(
var agent = chatClient.AsAIAgent(
model: "test-model",
instructions: "Test instructions",
name: "Test Agent",
@@ -234,7 +234,7 @@ public sealed class AnthropicClientExtensionsTests
{
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
((TestAnthropicChatClient)null!).CreateAIAgent("test-model"));
((TestAnthropicChatClient)null!).AsAIAgent("test-model"));
Assert.Equal("client", exception.ParamName);
}
@@ -250,7 +250,7 @@ public sealed class AnthropicClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
chatClient.CreateAIAgent((ChatClientAgentOptions)null!));
chatClient.AsAIAgent((ChatClientAgentOptions)null!));
Assert.Equal("options", exception.ParamName);
}
@@ -42,7 +42,7 @@ public sealed class PersistentAgentsClientExtensionsTests
// Act & Assert - null agentId
var exception1 = Assert.Throws<ArgumentException>(() =>
mockClient.Object.GetAIAgent((string)null!));
mockClient.Object.GetAIAgent(null!));
Assert.Equal("agentId", exception1.ParamName);
// Act & Assert - empty agentId
@@ -314,7 +314,7 @@ public sealed class PersistentAgentsClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(response, options);
var agent = client.AsAIAgent(response, options);
// Assert
Assert.NotNull(agent);
@@ -341,7 +341,7 @@ public sealed class PersistentAgentsClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(persistentAgent, options);
var agent = client.AsAIAgent(persistentAgent, options);
// Assert
Assert.NotNull(agent);
@@ -363,7 +363,7 @@ public sealed class PersistentAgentsClientExtensionsTests
var options = new ChatClientAgentOptions(); // Empty options
// Act
var agent = client.GetAIAgent(persistentAgent, options);
var agent = client.AsAIAgent(persistentAgent, options);
// Assert
Assert.NotNull(agent);
@@ -443,7 +443,7 @@ public sealed class PersistentAgentsClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(
var agent = client.AsAIAgent(
persistentAgent,
options,
clientFactory: (innerClient) => testChatClient);
@@ -470,7 +470,7 @@ public sealed class PersistentAgentsClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
client.GetAIAgent((Response<PersistentAgent>)null!, options));
client.AsAIAgent(null!, options));
Assert.Equal("persistentAgentResponse", exception.ParamName);
}
@@ -487,7 +487,7 @@ public sealed class PersistentAgentsClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
client.GetAIAgent((PersistentAgent)null!, options));
client.AsAIAgent((PersistentAgent)null!, options));
Assert.Equal("persistentAgentMetadata", exception.ParamName);
}
@@ -504,7 +504,7 @@ public sealed class PersistentAgentsClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
client.GetAIAgent(persistentAgent, (ChatClientAgentOptions)null!));
client.AsAIAgent(persistentAgent, (ChatClientAgentOptions)null!));
Assert.Equal("options", exception.ParamName);
}
@@ -25,13 +25,13 @@ namespace Microsoft.Agents.AI.AzureAI.UnitTests;
/// </summary>
public sealed class AzureAIProjectChatClientExtensionsTests
{
#region GetAIAgent(AIProjectClient, AgentRecord) Tests
#region AsAIAgent(AIProjectClient, AgentRecord) Tests
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when AIProjectClient is null.
/// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecord_WithNullClient_ThrowsArgumentNullException()
public void AsAIAgent_WithAgentRecord_WithNullClient_ThrowsArgumentNullException()
{
// Arrange
AIProjectClient? client = null;
@@ -39,39 +39,39 @@ public sealed class AzureAIProjectChatClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
client!.GetAIAgent(agentRecord));
client!.AsAIAgent(agentRecord));
Assert.Equal("aiProjectClient", exception.ParamName);
}
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when agentRecord is null.
/// Verify that AsAIAgent throws ArgumentNullException when agentRecord is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecord_WithNullAgentRecord_ThrowsArgumentNullException()
public void AsAIAgent_WithAgentRecord_WithNullAgentRecord_ThrowsArgumentNullException()
{
// Arrange
var mockClient = new Mock<AIProjectClient>();
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
mockClient.Object.GetAIAgent((AgentRecord)null!));
mockClient.Object.AsAIAgent((AgentRecord)null!));
Assert.Equal("agentRecord", exception.ParamName);
}
/// <summary>
/// Verify that GetAIAgent with AgentRecord creates a valid agent.
/// Verify that AsAIAgent with AgentRecord creates a valid agent.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecord_CreatesValidAgent()
public void AsAIAgent_WithAgentRecord_CreatesValidAgent()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent = client.GetAIAgent(agentRecord);
var agent = client.AsAIAgent(agentRecord);
// Assert
Assert.NotNull(agent);
@@ -79,10 +79,10 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent with AgentRecord and clientFactory applies the factory.
/// Verify that AsAIAgent with AgentRecord and clientFactory applies the factory.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecord_WithClientFactory_AppliesFactoryCorrectly()
public void AsAIAgent_WithAgentRecord_WithClientFactory_AppliesFactoryCorrectly()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
@@ -90,7 +90,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
TestChatClient? testChatClient = null;
// Act
var agent = client.GetAIAgent(
var agent = client.AsAIAgent(
agentRecord,
clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient));
@@ -103,13 +103,13 @@ public sealed class AzureAIProjectChatClientExtensionsTests
#endregion
#region GetAIAgent(AIProjectClient, AgentVersion) Tests
#region AsAIAgent(AIProjectClient, AgentVersion) Tests
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when AIProjectClient is null.
/// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_WithNullClient_ThrowsArgumentNullException()
public void AsAIAgent_WithAgentVersion_WithNullClient_ThrowsArgumentNullException()
{
// Arrange
AIProjectClient? client = null;
@@ -117,39 +117,39 @@ public sealed class AzureAIProjectChatClientExtensionsTests
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
client!.GetAIAgent(agentVersion));
client!.AsAIAgent(agentVersion));
Assert.Equal("aiProjectClient", exception.ParamName);
}
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when agentVersion is null.
/// Verify that AsAIAgent throws ArgumentNullException when agentVersion is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_WithNullAgentVersion_ThrowsArgumentNullException()
public void AsAIAgent_WithAgentVersion_WithNullAgentVersion_ThrowsArgumentNullException()
{
// Arrange
var mockClient = new Mock<AIProjectClient>();
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
mockClient.Object.GetAIAgent((AgentVersion)null!));
mockClient.Object.AsAIAgent((AgentVersion)null!));
Assert.Equal("agentVersion", exception.ParamName);
}
/// <summary>
/// Verify that GetAIAgent with AgentVersion creates a valid agent.
/// Verify that AsAIAgent with AgentVersion creates a valid agent.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_CreatesValidAgent()
public void AsAIAgent_WithAgentVersion_CreatesValidAgent()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
AgentVersion agentVersion = this.CreateTestAgentVersion();
// Act
var agent = client.GetAIAgent(agentVersion);
var agent = client.AsAIAgent(agentVersion);
// Assert
Assert.NotNull(agent);
@@ -157,10 +157,10 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent with AgentVersion and clientFactory applies the factory.
/// Verify that AsAIAgent with AgentVersion and clientFactory applies the factory.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_WithClientFactory_AppliesFactoryCorrectly()
public void AsAIAgent_WithAgentVersion_WithClientFactory_AppliesFactoryCorrectly()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
@@ -168,7 +168,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
TestChatClient? testChatClient = null;
// Act
var agent = client.GetAIAgent(
var agent = client.AsAIAgent(
agentVersion,
clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient));
@@ -183,7 +183,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
/// Verify that GetAIAgent with requireInvocableTools=true enforces invocable tools.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_WithRequireInvocableToolsTrue_EnforcesInvocableTools()
public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsTrue_EnforcesInvocableTools()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
@@ -194,7 +194,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(agentVersion, tools: tools);
var agent = client.AsAIAgent(agentVersion, tools: tools);
// Assert
Assert.NotNull(agent);
@@ -205,14 +205,14 @@ public sealed class AzureAIProjectChatClientExtensionsTests
/// Verify that GetAIAgent with requireInvocableTools=false allows declarative functions.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentVersion_WithRequireInvocableToolsFalse_AllowsDeclarativeFunctions()
public void AsAIAgent_WithAgentVersion_WithRequireInvocableToolsFalse_AllowsDeclarativeFunctions()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
AgentVersion agentVersion = this.CreateTestAgentVersion();
// Act - should not throw even without tools when requireInvocableTools is false
var agent = client.GetAIAgent(agentVersion);
var agent = client.AsAIAgent(agentVersion);
// Assert
Assert.NotNull(agent);
@@ -374,7 +374,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
#region GetAIAgent(AIProjectClient, string) Tests
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when AIProjectClient is null.
/// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null.
/// </summary>
[Fact]
public void GetAIAgent_ByName_WithNullClient_ThrowsArgumentNullException()
@@ -390,7 +390,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when name is null.
/// Verify that AsAIAgent throws ArgumentNullException when name is null.
/// </summary>
[Fact]
public void GetAIAgent_ByName_WithNullName_ThrowsArgumentNullException()
@@ -406,7 +406,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent throws ArgumentException when name is empty.
/// Verify that AsAIAgent throws ArgumentException when name is empty.
/// </summary>
[Fact]
public void GetAIAgent_ByName_WithEmptyName_ThrowsArgumentException()
@@ -422,7 +422,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent throws InvalidOperationException when agent is not found.
/// Verify that AsAIAgent throws InvalidOperationException when agent is not found.
/// </summary>
[Fact]
public void GetAIAgent_ByName_WithNonExistentAgent_ThrowsInvalidOperationException()
@@ -505,13 +505,13 @@ public sealed class AzureAIProjectChatClientExtensionsTests
#endregion
#region GetAIAgent(AIProjectClient, AgentRecord) with tools Tests
#region AsAIAgent(AIProjectClient, AgentRecord) with tools Tests
/// <summary>
/// Verify that GetAIAgent with additional tools when the definition has no tools does not throw and results in an agent with no tools.
/// Verify that AsAIAgent with additional tools when the definition has no tools does not throw and results in an agent with no tools.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecordAndAdditionalTools_WhenDefinitionHasNoTools_ShouldNotThrow()
public void AsAIAgent_WithAgentRecordAndAdditionalTools_WhenDefinitionHasNoTools_ShouldNotThrow()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
@@ -522,7 +522,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(agentRecord, tools: tools);
var agent = client.AsAIAgent(agentRecord, tools: tools);
// Assert
Assert.NotNull(agent);
@@ -536,17 +536,17 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent with null tools works correctly.
/// Verify that AsAIAgent with null tools works correctly.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentRecordAndNullTools_WorksCorrectly()
public void AsAIAgent_WithAgentRecordAndNullTools_WorksCorrectly()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent = client.GetAIAgent(agentRecord, tools: null);
var agent = client.AsAIAgent(agentRecord, tools: null);
// Assert
Assert.NotNull(agent);
@@ -1104,7 +1104,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
var shouldBeIgnoredTool = AIFunctionFactory.Create(() => "test", "additional_tool", "An additional test function that should be ignored");
// Act & Assert
var agent = client.GetAIAgent(agentVersion, tools: [invocableInlineAITool, shouldBeIgnoredTool]);
var agent = client.AsAIAgent(agentVersion, tools: [invocableInlineAITool, shouldBeIgnoredTool]);
Assert.NotNull(agent);
var version = agent.GetService<AgentVersion>();
Assert.NotNull(version);
@@ -1136,7 +1136,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
};
// Act
var agent = client.GetAIAgent(agentRecord, tools: tools);
var agent = client.AsAIAgent(agentRecord, tools: tools);
// Assert
Assert.NotNull(agent);
@@ -1632,7 +1632,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
#region AgentName Validation Tests
/// <summary>
/// Verify that GetAIAgent throws ArgumentException when agent name is invalid.
/// Verify that AsAIAgent throws ArgumentException when agent name is invalid.
/// </summary>
[Theory]
[MemberData(nameof(InvalidAgentNameTestData.GetInvalidAgentNames), MemberType = typeof(InvalidAgentNameTestData))]
@@ -1846,7 +1846,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
/// Verify that the underlying chat client created by extension methods can be wrapped with clientFactory.
/// </summary>
[Fact]
public void GetAIAgent_WithClientFactory_WrapsUnderlyingChatClient()
public void AsAIAgent_WithClientFactory_WrapsUnderlyingChatClient()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
@@ -1854,7 +1854,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
int factoryCallCount = 0;
// Act
var agent = client.GetAIAgent(
var agent = client.AsAIAgent(
agentRecord,
clientFactory: (innerClient) =>
{
@@ -1903,18 +1903,18 @@ public sealed class AzureAIProjectChatClientExtensionsTests
/// Verify that multiple clientFactory calls create independent wrapped clients.
/// </summary>
[Fact]
public void GetAIAgent_MultipleCallsWithClientFactory_CreatesIndependentClients()
public void AsAIAgent_MultipleCallsWithClientFactory_CreatesIndependentClients()
{
// Arrange
AIProjectClient client = this.CreateTestAgentClient();
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent1 = client.GetAIAgent(
var agent1 = client.AsAIAgent(
agentRecord,
clientFactory: (innerClient) => new TestChatClient(innerClient));
var agent2 = client.GetAIAgent(
var agent2 = client.AsAIAgent(
agentRecord,
clientFactory: (innerClient) => new TestChatClient(innerClient));
@@ -2165,7 +2165,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
#region GetAIAgent(AIProjectClient, AgentReference) Tests
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when AIProjectClient is null.
/// Verify that AsAIAgent throws ArgumentNullException when AIProjectClient is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentReference_WithNullClient_ThrowsArgumentNullException()
@@ -2182,7 +2182,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
}
/// <summary>
/// Verify that GetAIAgent throws ArgumentNullException when agentReference is null.
/// Verify that AsAIAgent throws ArgumentNullException when agentReference is null.
/// </summary>
[Fact]
public void GetAIAgent_WithAgentReference_WithNullAgentReference_ThrowsArgumentNullException()
@@ -2297,7 +2297,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent = client.GetAIAgent(agentRecord);
var agent = client.AsAIAgent(agentRecord);
var retrievedRecord = agent.GetService<AgentRecord>();
// Assert
@@ -2338,7 +2338,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentVersion agentVersion = this.CreateTestAgentVersion();
// Act
var agent = client.GetAIAgent(agentVersion);
var agent = client.AsAIAgent(agentVersion);
var retrievedVersion = agent.GetService<AgentVersion>();
// Assert
@@ -2379,7 +2379,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent = client.GetAIAgent(agentRecord);
var agent = client.AsAIAgent(agentRecord);
var metadata = agent.GetService<ChatClientMetadata>();
// Assert
@@ -2402,7 +2402,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentRecord agentRecord = this.CreateTestAgentRecord(definition);
// Act
var agent = client.GetAIAgent(agentRecord);
var agent = client.AsAIAgent(agentRecord);
var metadata = agent.GetService<ChatClientMetadata>();
// Assert
@@ -2423,7 +2423,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentVersion agentVersion = this.CreateTestAgentVersion();
// Act
var agent = client.GetAIAgent(agentVersion);
var agent = client.AsAIAgent(agentVersion);
var metadata = agent.GetService<ChatClientMetadata>();
// Assert
@@ -2467,7 +2467,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentRecord agentRecord = this.CreateTestAgentRecord();
// Act
var agent = client.GetAIAgent(agentRecord);
var agent = client.AsAIAgent(agentRecord);
var retrievedReference = agent.GetService<AgentReference>();
// Assert
@@ -2486,7 +2486,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
AgentVersion agentVersion = this.CreateTestAgentVersion();
// Act
var agent = client.GetAIAgent(agentVersion);
var agent = client.AsAIAgent(agentVersion);
var retrievedReference = agent.GetService<AgentReference>();
// Assert
@@ -41,7 +41,7 @@ public sealed class AgentEntityTests(ITestOutputHelper outputHelper) : IDisposab
public async Task EntityNamePrefixAsync()
{
// Setup
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).CreateAIAgent(
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).AsAIAgent(
name: "TestAgent",
instructions: "You are a helpful assistant that always responds with a friendly greeting."
);
@@ -88,7 +88,7 @@ public sealed class AgentEntityTests(ITestOutputHelper outputHelper) : IDisposab
public async Task RunAgentMethodNamesAllWorkAsync(string runAgentMethodName)
{
// Setup
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).CreateAIAgent(
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).AsAIAgent(
name: "TestAgent",
instructions: "You are a helpful assistant that always responds with a friendly greeting."
);
@@ -143,7 +143,7 @@ public sealed class AgentEntityTests(ITestOutputHelper outputHelper) : IDisposab
public async Task OrchestrationIdSetDuringOrchestrationAsync()
{
// Arrange
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).CreateAIAgent(
AIAgent simpleAgent = TestHelper.GetAzureOpenAIChatClient(s_configuration).AsAIAgent(
name: "TestAgent",
instructions: "You are a helpful assistant that always responds with a friendly greeting."
);

Some files were not shown because too many files have changed in this diff Show More