diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props
index a49f0fc277..62793f39fd 100644
--- a/dotnet/Directory.Packages.props
+++ b/dotnet/Directory.Packages.props
@@ -11,6 +11,8 @@
+
+
@@ -169,4 +171,4 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
\ No newline at end of file
diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx
index 7f4a6eb4d1..f1efae7ba8 100644
--- a/dotnet/agent-framework-dotnet.slnx
+++ b/dotnet/agent-framework-dotnet.slnx
@@ -45,6 +45,7 @@
+
@@ -82,6 +83,12 @@
+
+
+
+
+
+
@@ -312,6 +319,7 @@
+
@@ -336,6 +344,7 @@
+
@@ -358,6 +367,7 @@
+
@@ -374,6 +384,7 @@
+
diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Agent_With_Anthropic.csproj b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Agent_With_Anthropic.csproj
new file mode 100644
index 0000000000..002bd066fe
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Agent_With_Anthropic.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ net10.0
+
+ enable
+ enable
+ $(NoWarn);IDE0059
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Program.cs b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Program.cs
new file mode 100644
index 0000000000..531b56e1a1
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/Program.cs
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+// This sample shows how to create and use an AI agent with Anthropic as the backend.
+
+using System.ClientModel;
+using System.Net.Http.Headers;
+using Anthropic;
+using Anthropic.Core;
+using Azure.Core;
+using Azure.Identity;
+using Microsoft.Agents.AI;
+using Sample;
+
+var deploymentName = Environment.GetEnvironmentVariable("ANTHROPIC_DEPLOYMENT_NAME") ?? "claude-haiku-4-5";
+
+// The resource is the subdomain name / first name coming before '.services.ai.azure.com' in the endpoint Uri
+// ie: https://(resource name).services.ai.azure.com/anthropic/v1/chat/completions
+var resource = Environment.GetEnvironmentVariable("ANTHROPIC_RESOURCE");
+var apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY");
+
+const string JokerInstructions = "You are good at telling jokes.";
+const string JokerName = "JokerAgent";
+
+AnthropicClient? client = (resource is null)
+ ? new AnthropicClient() { APIKey = apiKey ?? throw new InvalidOperationException("ANTHROPIC_API_KEY is required when no ANTHROPIC_RESOURCE is provided") } // If no resource is provided, use Anthropic public API
+ : (apiKey is not null)
+ ? new AnthropicFoundryClient(resource, new ApiKeyCredential(apiKey)) // If an apiKey is provided, use Foundry with ApiKey authentication
+ : new AnthropicFoundryClient(resource, new AzureCliCredential()); // Otherwise, use Foundry with Azure Client authentication
+
+AIAgent agent = client.CreateAIAgent(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."));
+
+namespace Sample
+{
+ ///
+ /// Provides methods for invoking the Azure hosted Anthropic api.
+ ///
+ public class AnthropicFoundryClient : AnthropicClient
+ {
+ private readonly TokenCredential _tokenCredential;
+ private readonly string _resourceName;
+
+ ///
+ /// Creates a new instance of the .
+ ///
+ /// The service resource subdomain name to use in the anthropic azure endpoint
+ /// The credential provider. Use any specialization of to get your access token in supported environments.
+ /// Set of client option configurations
+ /// Resource is null
+ /// TokenCredential is null
+ ///
+ /// Any APIKey or Bearer token provided will be ignored in favor of the provided in the constructor
+ ///
+ public AnthropicFoundryClient(string resourceName, TokenCredential tokenCredential, Anthropic.Core.ClientOptions? options = null) : base(options ?? new())
+ {
+ this._resourceName = resourceName ?? throw new ArgumentNullException(nameof(resourceName));
+ this._tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential));
+ this.BaseUrl = new Uri($"https://{this._resourceName}.services.ai.azure.com/anthropic", UriKind.Absolute);
+ }
+
+ ///
+ /// Creates a new instance of the .
+ ///
+ /// The service resource subdomain name to use in the anthropic azure endpoint
+ /// The api key.
+ /// Set of client option configurations
+ /// Resource is null
+ /// Api key is null
+ ///
+ /// Any APIKey or Bearer token provided will be ignored in favor of the provided in the constructor
+ ///
+ public AnthropicFoundryClient(string resourceName, ApiKeyCredential apiKeyCredential, Anthropic.Core.ClientOptions? options = null) :
+ this(resourceName, apiKeyCredential is null
+ ? throw new ArgumentNullException(nameof(apiKeyCredential))
+ : DelegatedTokenCredential.Create((_, _) =>
+ {
+ apiKeyCredential.Deconstruct(out string dangerousCredential);
+ return new AccessToken(dangerousCredential, DateTimeOffset.MaxValue);
+ }),
+ options)
+ { }
+
+ public override IAnthropicClient WithOptions(Func modifier)
+ => this;
+
+ protected override ValueTask BeforeSend(
+ HttpRequest request,
+ HttpRequestMessage requestMessage,
+ CancellationToken cancellationToken
+ )
+ {
+ var accessToken = this._tokenCredential.GetToken(new TokenRequestContext(scopes: ["https://ai.azure.com/.default"]), cancellationToken);
+
+ requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken.Token);
+
+ return default;
+ }
+ }
+}
diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/README.md b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/README.md
new file mode 100644
index 0000000000..afcf391572
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_Anthropic/README.md
@@ -0,0 +1,53 @@
+# Creating an AIAgent with Anthropic
+
+This sample demonstrates how to create an AIAgent using Anthropic Claude models as the underlying inference service.
+
+The sample supports three deployment scenarios:
+
+1. **Anthropic Public API** - Direct connection to Anthropic's public API
+2. **Azure Foundry with API Key** - Anthropic models deployed through Azure Foundry using API key authentication
+3. **Azure Foundry with Azure CLI** - Anthropic models deployed through Azure Foundry using Azure CLI credentials
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites:
+
+- .NET 8.0 SDK or later
+
+### For Anthropic Public API
+
+- Anthropic API key
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+$env:ANTHROPIC_DEPLOYMENT_NAME="claude-haiku-4-5" # Optional, defaults to claude-haiku-4-5
+```
+
+### For Azure Foundry with API Key
+
+- Azure Foundry service endpoint and deployment configured
+- Anthropic API key
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_RESOURCE="your-foundry-resource-name" # Replace with your Azure Foundry resource name (subdomain before .services.ai.azure.com)
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+$env:ANTHROPIC_DEPLOYMENT_NAME="claude-haiku-4-5" # Optional, defaults to claude-haiku-4-5
+```
+
+### For Azure Foundry with Azure CLI
+
+- Azure Foundry service endpoint and deployment configured
+- Azure CLI installed and authenticated (for Azure credential authentication)
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_RESOURCE="your-foundry-resource-name" # Replace with your Azure Foundry resource name (subdomain before .services.ai.azure.com)
+$env:ANTHROPIC_DEPLOYMENT_NAME="claude-haiku-4-5" # Optional, defaults to claude-haiku-4-5
+```
+
+**Note**: When using Azure Foundry with Azure CLI, make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Agent_With_OpenAIChatCompletion.csproj b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Agent_With_OpenAIChatCompletion.csproj
index eeda3eef6f..4ea7a45b8a 100644
--- a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Agent_With_OpenAIChatCompletion.csproj
+++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Agent_With_OpenAIChatCompletion.csproj
@@ -2,7 +2,7 @@
Exe
- net10.0
+ net10.0
enable
enable
diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Program.cs b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Program.cs
index 9b03c989e1..331109fba9 100644
--- a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Program.cs
+++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_OpenAIChatCompletion/Program.cs
@@ -3,6 +3,7 @@
// This sample shows how to create and use a simple AI agent with OpenAI Chat Completion as the backend.
using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
using OpenAI;
var apiKey = Environment.GetEnvironmentVariable("OPENAI_APIKEY") ?? throw new InvalidOperationException("OPENAI_APIKEY is not set.");
diff --git a/dotnet/samples/GettingStarted/AgentProviders/README.md b/dotnet/samples/GettingStarted/AgentProviders/README.md
index 5d32f2542b..964e560c9a 100644
--- a/dotnet/samples/GettingStarted/AgentProviders/README.md
+++ b/dotnet/samples/GettingStarted/AgentProviders/README.md
@@ -15,6 +15,7 @@ See the README.md for each sample for the prerequisites for that sample.
|Sample|Description|
|---|---|
|[Creating an AIAgent with A2A](./Agent_With_A2A/)|This sample demonstrates how to create AIAgent for an existing A2A agent.|
+|[Creating an AIAgent with Anthropic](./Agent_With_Anthropic/)|This sample demonstrates how to create an AIAgent using Anthropic Claude models as the underlying inference service|
|[Creating an AIAgent with Foundry Agents using Azure.AI.Agents.Persistent](./Agent_With_AzureAIAgentsPersistent/)|This sample demonstrates how to create a Foundry Persistent agent and expose it as an AIAgent using the Azure.AI.Agents.Persistent SDK|
|[Creating an AIAgent with Foundry Agents using Azure.AI.Project](./Agent_With_AzureAIProject/)|This sample demonstrates how to create an Foundry Project agent and expose it as an AIAgent using the Azure.AI.Project SDK|
|[Creating an AIAgent with AzureFoundry Model](./Agent_With_AzureFoundryModel/)|This sample demonstrates how to use any model deployed to Azure Foundry to create an AIAgent|
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Agent_Anthropic_Step01_Running.csproj b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Agent_Anthropic_Step01_Running.csproj
new file mode 100644
index 0000000000..09359c5e78
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Agent_Anthropic_Step01_Running.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net10.0
+
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Program.cs b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Program.cs
new file mode 100644
index 0000000000..cf7e29c2fe
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Program.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+// This sample shows how to create and use a simple AI agent with Anthropic as the backend.
+
+using Anthropic;
+using Anthropic.Core;
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+
+var apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? throw new InvalidOperationException("ANTHROPIC_API_KEY is not set.");
+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");
+
+// Invoke the agent and output the text result.
+var response = await agent.RunAsync("Tell me a joke about a pirate.");
+Console.WriteLine(response);
+
+// Invoke the agent with streaming support.
+await foreach (var update in agent.RunStreamingAsync("Tell me a joke about a pirate."))
+{
+ Console.WriteLine(update);
+}
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/README.md b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/README.md
new file mode 100644
index 0000000000..4800650bd9
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/README.md
@@ -0,0 +1,43 @@
+# Running a simple agent with Anthropic
+
+This sample demonstrates how to create and run a basic agent with Anthropic Claude models.
+
+## What this sample demonstrates
+
+- Creating an AI agent with Anthropic Claude
+- Running a simple agent with instructions
+- Managing agent lifecycle
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites:
+
+- .NET 8.0 SDK or later
+- Anthropic API key configured
+
+**Note**: This sample uses Anthropic Claude models. For more information, see [Anthropic documentation](https://docs.anthropic.com/).
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+$env:ANTHROPIC_MODEL="your-anthropic-model" # Replace with your Anthropic model
+```
+
+## Run the sample
+
+Navigate to the AgentWithAnthropic sample directory and run:
+
+```powershell
+cd dotnet\samples\GettingStarted\AgentWithAnthropic
+dotnet run --project .\Agent_Anthropic_Step01_Running
+```
+
+## Expected behavior
+
+The sample will:
+
+1. Create an agent with Anthropic Claude
+2. Run the agent with a simple prompt
+3. Display the agent's response
+
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Agent_Anthropic_Step02_Reasoning.csproj b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Agent_Anthropic_Step02_Reasoning.csproj
new file mode 100644
index 0000000000..fc0914f1fc
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Agent_Anthropic_Step02_Reasoning.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net10.0
+
+ enable
+ enable
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Program.cs b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Program.cs
new file mode 100644
index 0000000000..d362a9dd0d
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Program.cs
@@ -0,0 +1,59 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+// This sample shows how to create and use an AI agent with reasoning capabilities.
+
+using Anthropic;
+using Anthropic.Core;
+using Anthropic.Models.Messages;
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+
+var apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? throw new InvalidOperationException("ANTHROPIC_API_KEY is not set.");
+var model = Environment.GetEnvironmentVariable("ANTHROPIC_MODEL") ?? "claude-haiku-4-5";
+var maxTokens = 4096;
+var thinkingTokens = 2048;
+
+var agent = new AnthropicClient(new ClientOptions { APIKey = apiKey })
+ .CreateAIAgent(
+ model: model,
+ clientFactory: (chatClient) => chatClient
+ .AsBuilder()
+ .ConfigureOptions(
+ options => options.RawRepresentationFactory = (_) => new MessageCreateParams()
+ {
+ Model = options.ModelId ?? model,
+ MaxTokens = options.MaxOutputTokens ?? maxTokens,
+ Messages = [],
+ Thinking = new ThinkingConfigParam(new ThinkingConfigEnabled(budgetTokens: thinkingTokens))
+ })
+ .Build());
+
+Console.WriteLine("1. Non-streaming:");
+var response = await agent.RunAsync("Solve this problem step by step: If a train travels 60 miles per hour and needs to cover 180 miles, how long will the journey take? Show your reasoning.");
+
+Console.WriteLine("#### Start Thinking ####");
+Console.WriteLine($"\e[92m{string.Join("\n", response.Messages.SelectMany(m => m.Contents.OfType().Select(c => c.Text)))}\e[0m");
+Console.WriteLine("#### End Thinking ####");
+
+Console.WriteLine("\n#### Final Answer ####");
+Console.WriteLine(response.Text);
+
+Console.WriteLine("Token usage:");
+Console.WriteLine($"Input: {response.Usage?.InputTokenCount}, Output: {response.Usage?.OutputTokenCount}, {string.Join(", ", response.Usage?.AdditionalCounts ?? [])}");
+Console.WriteLine();
+
+Console.WriteLine("2. Streaming");
+await foreach (var update in agent.RunStreamingAsync("Explain the theory of relativity in simple terms."))
+{
+ foreach (var item in update.Contents)
+ {
+ if (item is TextReasoningContent reasoningContent)
+ {
+ Console.WriteLine($"\e[92m{reasoningContent.Text}\e[0m");
+ }
+ else if (item is TextContent textContent)
+ {
+ Console.WriteLine(textContent.Text);
+ }
+ }
+}
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/README.md b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/README.md
new file mode 100644
index 0000000000..ae088b2386
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/README.md
@@ -0,0 +1,46 @@
+# Using reasoning with Anthropic agents
+
+This sample demonstrates how to use extended thinking/reasoning capabilities with Anthropic Claude agents.
+
+## What this sample demonstrates
+
+- Creating an AI agent with Anthropic Claude extended thinking
+- Using reasoning capabilities for complex problem solving
+- Extracting thinking and response content from agent output
+- Managing agent lifecycle
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites:
+
+- .NET 8.0 SDK or later
+- Anthropic API key configured
+- Access to Anthropic Claude models with extended thinking support
+
+**Note**: This sample uses Anthropic Claude models with extended thinking. For more information, see [Anthropic documentation](https://docs.anthropic.com/).
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+$env:ANTHROPIC_MODEL="your-anthropic-model" # Replace with your Anthropic model
+```
+
+## Run the sample
+
+Navigate to the AgentWithAnthropic sample directory and run:
+
+```powershell
+cd dotnet\samples\GettingStarted\AgentWithAnthropic
+dotnet run --project .\Agent_Anthropic_Step02_Reasoning
+```
+
+## Expected behavior
+
+The sample will:
+
+1. Create an agent with Anthropic Claude extended thinking enabled
+2. Run the agent with a complex reasoning prompt
+3. Display the agent's thinking process
+4. Display the agent's final response
+
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Agent_Anthropic_Step03_UsingFunctionTools.csproj b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Agent_Anthropic_Step03_UsingFunctionTools.csproj
new file mode 100644
index 0000000000..fdb9a2f50f
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Agent_Anthropic_Step03_UsingFunctionTools.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net10.0
+
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Program.cs b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Program.cs
new file mode 100644
index 0000000000..a56db8d4a2
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Program.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+// This sample demonstrates how to use an agent with function tools.
+// It shows both non-streaming and streaming agent interactions using weather-related tools.
+
+using System.ComponentModel;
+using Anthropic;
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+
+var apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? throw new InvalidOperationException("ANTHROPIC_API_KEY is not set.");
+var model = Environment.GetEnvironmentVariable("ANTHROPIC_MODEL") ?? "claude-haiku-4-5";
+
+[Description("Get the weather for a given location.")]
+static string GetWeather([Description("The location to get the weather for.")] string location)
+ => $"The weather in {location} is cloudy with a high of 15°C.";
+
+const string AssistantInstructions = "You are a helpful assistant that can get weather information.";
+const string AssistantName = "WeatherAssistant";
+
+// Define the agent with function tools.
+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]);
+
+// Non-streaming agent interaction with function tools.
+AgentThread thread = agent.GetNewThread();
+Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", thread));
+
+// Streaming agent interaction with function tools.
+thread = agent.GetNewThread();
+await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
+{
+ Console.WriteLine(update);
+}
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/README.md b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/README.md
new file mode 100644
index 0000000000..6c905864ef
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/README.md
@@ -0,0 +1,47 @@
+# Using Function Tools with Anthropic agents
+
+This sample demonstrates how to use function tools with Anthropic Claude agents, allowing agents to call custom functions to retrieve information.
+
+## What this sample demonstrates
+
+- Creating function tools using AIFunctionFactory
+- Passing function tools to an Anthropic Claude agent
+- Running agents with function tools (text output)
+- Running agents with function tools (streaming output)
+- Managing agent lifecycle
+
+## Prerequisites
+
+Before you begin, ensure you have the following prerequisites:
+
+- .NET 8.0 SDK or later
+- Anthropic API key configured
+
+**Note**: This sample uses Anthropic Claude models. For more information, see [Anthropic documentation](https://docs.anthropic.com/).
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+$env:ANTHROPIC_MODEL="your-anthropic-model" # Replace with your Anthropic model
+```
+
+## Run the sample
+
+Navigate to the AgentWithAnthropic sample directory and run:
+
+```powershell
+cd dotnet\samples\GettingStarted\AgentWithAnthropic
+dotnet run --project .\Agent_Anthropic_Step03_UsingFunctionTools
+```
+
+## Expected behavior
+
+The sample will:
+
+1. Create an agent named "WeatherAssistant" with a GetWeather function tool
+2. Run the agent with a text prompt asking about weather
+3. The agent will invoke the GetWeather function tool to retrieve weather information
+4. Run the agent again with streaming to display the response as it's generated
+5. Clean up resources by deleting the agent
+
diff --git a/dotnet/samples/GettingStarted/AgentWithAnthropic/README.md b/dotnet/samples/GettingStarted/AgentWithAnthropic/README.md
new file mode 100644
index 0000000000..44c15b384b
--- /dev/null
+++ b/dotnet/samples/GettingStarted/AgentWithAnthropic/README.md
@@ -0,0 +1,72 @@
+# Getting started with agents using Anthropic
+
+The getting started with agents using Anthropic samples demonstrate the fundamental concepts and functionalities
+of single agents using Anthropic as the AI provider.
+
+These samples use Anthropic Claude models as the AI provider and use ChatCompletion as the type of service.
+
+For other samples that demonstrate how to create and configure each type of agent that come with the agent framework,
+see the [How to create an agent for each provider](../AgentProviders/README.md) samples.
+
+## Getting started with agents using Anthropic prerequisites
+
+Before you begin, ensure you have the following prerequisites:
+
+- .NET 8.0 SDK or later
+- Anthropic API key configured
+- User has access to Anthropic Claude models
+
+**Note**: These samples use Anthropic Claude models. For more information, see [Anthropic documentation](https://docs.anthropic.com/).
+
+## Using Anthropic with Azure Foundry
+
+To use Anthropic with Azure Foundry, you can check the sample [AgentProviders/Agent_With_Anthropic](../AgentProviders/Agent_With_Anthropic/README.md) for more details.
+
+## Samples
+
+|Sample|Description|
+|---|---|
+|[Running a simple agent](./Agent_Anthropic_Step01_Running/)|This sample demonstrates how to create and run a basic agent with Anthropic Claude|
+|[Using reasoning with an agent](./Agent_Anthropic_Step02_Reasoning/)|This sample demonstrates how to use extended thinking/reasoning capabilities with Anthropic Claude agents|
+|[Using function tools with an agent](./Agent_Anthropic_Step03_UsingFunctionTools/)|This sample demonstrates how to use function tools with an Anthropic Claude agent|
+
+## Running the samples from the console
+
+To run the samples, navigate to the desired sample directory, e.g.
+
+```powershell
+cd Agent_Anthropic_Step01_Running
+```
+
+Set the following environment variables:
+
+```powershell
+$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
+```
+
+If the variables are not set, you will be prompted for the values when running the samples.
+
+Execute the following command to build the sample:
+
+```powershell
+dotnet build
+```
+
+Execute the following command to run the sample:
+
+```powershell
+dotnet run --no-build
+```
+
+Or just build and run in one step:
+
+```powershell
+dotnet run
+```
+
+## Running the samples from Visual Studio
+
+Open the solution in Visual Studio and set the desired sample project as the startup project. Then, run the project using the built-in debugger or by pressing `F5`.
+
+You will be prompted for any required environment variables if they are not already set.
+
diff --git a/dotnet/samples/GettingStarted/README.md b/dotnet/samples/GettingStarted/README.md
index 4e349c7742..7a46d81a62 100644
--- a/dotnet/samples/GettingStarted/README.md
+++ b/dotnet/samples/GettingStarted/README.md
@@ -15,5 +15,6 @@ of the agent framework.
|[A2A](./A2A/README.md)|Getting started with A2A (Agent-to-Agent) specific features|
|[Agent Open Telemetry](./AgentOpenTelemetry/README.md)|Getting started with OpenTelemetry for agents|
|[Agent With OpenAI exchange types](./AgentWithOpenAI/README.md)|Using OpenAI exchange types with agents|
+|[Agent With Anthropic](./AgentWithAnthropic/README.md)|Getting started with agents using Anthropic Claude|
|[Workflow](./Workflows/README.md)|Getting started with Workflow|
|[Model Context Protocol](./ModelContextProtocol/README.md)|Getting started with Model Context Protocol|
diff --git a/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicBetaServiceExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicBetaServiceExtensions.cs
new file mode 100644
index 0000000000..9bf698bded
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicBetaServiceExtensions.cs
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+
+namespace Anthropic.Services;
+
+///
+/// Provides extension methods for the class.
+///
+public static class AnthropicBetaServiceExtensions
+{
+ ///
+ /// Specifies the default maximum number of tokens allowed for processing operations.
+ ///
+ public static int DefaultMaxTokens { get; set; } = 4096;
+
+ ///
+ /// Creates a new AI agent using the specified model and options.
+ ///
+ /// The Anthropic beta service.
+ /// The model to use for chat completions.
+ /// The instructions for the AI agent.
+ /// The name of the AI agent.
+ /// The description of the AI agent.
+ /// The tools available to the AI agent.
+ /// The default maximum tokens for chat completions. Defaults to if not provided.
+ /// Provides a way to customize the creation of the underlying used by the agent.
+ /// Optional logger factory for enabling logging within the agent.
+ /// An optional to use for resolving services required by the instances being invoked.
+ /// The created AI agent.
+ public static ChatClientAgent CreateAIAgent(
+ this IBetaService betaService,
+ string model,
+ string? instructions = null,
+ string? name = null,
+ string? description = null,
+ IList? tools = null,
+ int? defaultMaxTokens = null,
+ Func? clientFactory = null,
+ ILoggerFactory? loggerFactory = null,
+ IServiceProvider? services = null)
+ {
+ var options = new ChatClientAgentOptions
+ {
+ Instructions = instructions,
+ Name = name,
+ Description = description,
+ };
+
+ if (tools is { Count: > 0 })
+ {
+ options.ChatOptions = new ChatOptions { Tools = tools };
+ }
+
+ var chatClient = betaService.AsIChatClient(model, defaultMaxTokens ?? DefaultMaxTokens);
+
+ if (clientFactory is not null)
+ {
+ chatClient = clientFactory(chatClient);
+ }
+
+ return new ChatClientAgent(chatClient, options, loggerFactory, services);
+ }
+
+ ///
+ /// Creates an AI agent from an using the Anthropic Chat Completion API.
+ ///
+ /// The Anthropic to use for the agent.
+ /// Full set of options to configure the agent.
+ /// Provides a way to customize the creation of the underlying used by the agent.
+ /// Optional logger factory for enabling logging within the agent.
+ /// An optional to use for resolving services required by the instances being invoked.
+ /// An instance backed by the Anthropic Chat Completion service.
+ /// Thrown when or is .
+ public static ChatClientAgent CreateAIAgent(
+ this IBetaService betaService,
+ ChatClientAgentOptions options,
+ Func? clientFactory = null,
+ ILoggerFactory? loggerFactory = null,
+ IServiceProvider? services = null)
+ {
+ Throw.IfNull(betaService);
+ Throw.IfNull(options);
+
+ var chatClient = betaService.AsIChatClient();
+
+ if (clientFactory is not null)
+ {
+ chatClient = clientFactory(chatClient);
+ }
+
+ return new ChatClientAgent(chatClient, options, loggerFactory, services);
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientExtensions.cs
new file mode 100644
index 0000000000..f43f4bd0ce
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientExtensions.cs
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+using Microsoft.Extensions.Logging;
+using Microsoft.Shared.Diagnostics;
+
+namespace Anthropic;
+
+///
+/// Provides extension methods for the class.
+///
+public static class AnthropicClientExtensions
+{
+ ///
+ /// Specifies the default maximum number of tokens allowed for processing operations.
+ ///
+ public static int DefaultMaxTokens { get; set; } = 4096;
+
+ ///
+ /// Creates a new AI agent using the specified model and options.
+ ///
+ /// An Anthropic to use with the agent..
+ /// The model to use for chat completions.
+ /// The instructions for the AI agent.
+ /// The name of the AI agent.
+ /// The description of the AI agent.
+ /// The tools available to the AI agent.
+ /// The default maximum tokens for chat completions. Defaults to if not provided.
+ /// Provides a way to customize the creation of the underlying used by the agent.
+ /// Optional logger factory for enabling logging within the agent.
+ /// An optional to use for resolving services required by the instances being invoked.
+ /// The created AI agent.
+ public static ChatClientAgent CreateAIAgent(
+ this IAnthropicClient client,
+ string model,
+ string? instructions = null,
+ string? name = null,
+ string? description = null,
+ IList? tools = null,
+ int? defaultMaxTokens = null,
+ Func? clientFactory = null,
+ ILoggerFactory? loggerFactory = null,
+ IServiceProvider? services = null)
+ {
+ var options = new ChatClientAgentOptions
+ {
+ Instructions = instructions,
+ Name = name,
+ Description = description,
+ };
+
+ if (tools is { Count: > 0 })
+ {
+ options.ChatOptions = new ChatOptions { Tools = tools };
+ }
+
+ var chatClient = client.AsIChatClient(model, defaultMaxTokens ?? DefaultMaxTokens);
+
+ if (clientFactory is not null)
+ {
+ chatClient = clientFactory(chatClient);
+ }
+
+ return new ChatClientAgent(chatClient, options, loggerFactory, services);
+ }
+
+ ///
+ /// Creates an AI agent from an using the Anthropic Chat Completion API.
+ ///
+ /// An Anthropic to use with the agent..
+ /// Full set of options to configure the agent.
+ /// Provides a way to customize the creation of the underlying used by the agent.
+ /// Optional logger factory for enabling logging within the agent.
+ /// An optional to use for resolving services required by the instances being invoked.
+ /// An instance backed by the Anthropic Chat Completion service.
+ /// Thrown when or is .
+ public static ChatClientAgent CreateAIAgent(
+ this IAnthropicClient client,
+ ChatClientAgentOptions options,
+ Func? clientFactory = null,
+ ILoggerFactory? loggerFactory = null,
+ IServiceProvider? services = null)
+ {
+ Throw.IfNull(client);
+ Throw.IfNull(options);
+
+ var chatClient = client.AsIChatClient();
+
+ if (clientFactory is not null)
+ {
+ chatClient = clientFactory(chatClient);
+ }
+
+ return new ChatClientAgent(chatClient, options, loggerFactory, services);
+ }
+}
diff --git a/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientJsonContext.cs b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientJsonContext.cs
new file mode 100644
index 0000000000..080745f148
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Anthropic/AnthropicClientJsonContext.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+#pragma warning disable CA1812
+
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Microsoft.Agents.AI.Anthropic;
+
+[JsonSerializable(typeof(JsonElement))]
+[JsonSerializable(typeof(string))]
+[JsonSerializable(typeof(Dictionary))]
+internal sealed partial class AnthropicClientJsonContext : JsonSerializerContext;
diff --git a/dotnet/src/Microsoft.Agents.AI.Anthropic/Microsoft.Agents.AI.Anthropic.csproj b/dotnet/src/Microsoft.Agents.AI.Anthropic/Microsoft.Agents.AI.Anthropic.csproj
new file mode 100644
index 0000000000..60b90a0212
--- /dev/null
+++ b/dotnet/src/Microsoft.Agents.AI.Anthropic/Microsoft.Agents.AI.Anthropic.csproj
@@ -0,0 +1,26 @@
+
+
+
+ preview
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Microsoft Agent Framework Anthropic Agents
+ Provides Microsoft Agent Framework support for Anthropic Agents.
+
+
+
diff --git a/dotnet/src/Shared/IntegrationTests/AnthropicConfiguration.cs b/dotnet/src/Shared/IntegrationTests/AnthropicConfiguration.cs
new file mode 100644
index 0000000000..2230be95ed
--- /dev/null
+++ b/dotnet/src/Shared/IntegrationTests/AnthropicConfiguration.cs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Shared.IntegrationTests;
+
+#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
+#pragma warning disable CA1812 // Internal class that is apparently never instantiated.
+
+internal sealed class AnthropicConfiguration
+{
+ public string? ServiceId { get; set; }
+
+ public string ChatModelId { get; set; }
+
+ public string ChatReasoningModelId { get; set; }
+
+ public string ApiKey { get; set; }
+}
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletion.IntegrationTests.csproj b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletion.IntegrationTests.csproj
new file mode 100644
index 0000000000..929eafe998
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletion.IntegrationTests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunStreamingTests.cs b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunStreamingTests.cs
new file mode 100644
index 0000000000..992db5380b
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunStreamingTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Threading.Tasks;
+using AgentConformance.IntegrationTests;
+
+namespace AnthropicChatCompletion.IntegrationTests;
+
+public abstract class SkipAllChatClientRunStreaming(Func func) : ChatClientAgentRunStreamingTests(func)
+{
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithFunctionsInvokesFunctionsAndReturnsExpectedResultsAsync()
+ => base.RunWithFunctionsInvokesFunctionsAndReturnsExpectedResultsAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithInstructionsAndNoMessageReturnsExpectedResultAsync()
+ => base.RunWithInstructionsAndNoMessageReturnsExpectedResultAsync();
+}
+
+public class AnthropicBetaChatCompletionChatClientAgentReasoningRunStreamingTests() : SkipAllChatClientRunStreaming(() => new(useReasoningChatModel: true, useBeta: true));
+
+public class AnthropicBetaChatCompletionChatClientAgentRunStreamingTests() : SkipAllChatClientRunStreaming(() => new(useReasoningChatModel: false, useBeta: true));
+
+public class AnthropicChatCompletionChatClientAgentRunStreamingTests() : SkipAllChatClientRunStreaming(() => new(useReasoningChatModel: false, useBeta: false));
+
+public class AnthropicChatCompletionChatClientAgentReasoningRunStreamingTests() : SkipAllChatClientRunStreaming(() => new(useReasoningChatModel: true, useBeta: false));
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunTests.cs b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunTests.cs
new file mode 100644
index 0000000000..e2ce6e5d04
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionChatClientAgentRunTests.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Threading.Tasks;
+using AgentConformance.IntegrationTests;
+
+namespace AnthropicChatCompletion.IntegrationTests;
+
+public abstract class SkipAllChatClientAgentRun(Func func) : ChatClientAgentRunTests(func)
+{
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithFunctionsInvokesFunctionsAndReturnsExpectedResultsAsync()
+ => base.RunWithFunctionsInvokesFunctionsAndReturnsExpectedResultsAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithInstructionsAndNoMessageReturnsExpectedResultAsync()
+ => base.RunWithInstructionsAndNoMessageReturnsExpectedResultAsync();
+}
+
+public class AnthropicBetaChatCompletionChatClientAgentRunTests()
+ : SkipAllChatClientAgentRun(() => new(useReasoningChatModel: false, useBeta: true));
+
+public class AnthropicBetaChatCompletionChatClientAgentReasoningRunTests()
+ : SkipAllChatClientAgentRun(() => new(useReasoningChatModel: true, useBeta: true));
+
+public class AnthropicChatCompletionChatClientAgentRunTests()
+ : SkipAllChatClientAgentRun(() => new(useReasoningChatModel: false, useBeta: false));
+
+public class AnthropicChatCompletionChatClientAgentReasoningRunTests()
+ : SkipAllChatClientAgentRun(() => new(useReasoningChatModel: true, useBeta: false));
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionFixture.cs b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionFixture.cs
new file mode 100644
index 0000000000..76ca18d3de
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionFixture.cs
@@ -0,0 +1,105 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using AgentConformance.IntegrationTests;
+using AgentConformance.IntegrationTests.Support;
+using Anthropic;
+using Anthropic.Models.Beta.Messages;
+using Anthropic.Models.Messages;
+using Microsoft.Agents.AI;
+using Microsoft.Extensions.AI;
+using Shared.IntegrationTests;
+
+namespace AnthropicChatCompletion.IntegrationTests;
+
+public class AnthropicChatCompletionFixture : IChatClientAgentFixture
+{
+ // All tests for Anthropic are intended to be ran locally as the CI pipeline for Anthropic is not setup.
+ internal const string SkipReason = "Integrations tests for local execution only";
+
+ private static readonly AnthropicConfiguration s_config = TestConfiguration.LoadSection();
+ private readonly bool _useReasoningModel;
+ private readonly bool _useBeta;
+
+ private ChatClientAgent _agent = null!;
+
+ public AnthropicChatCompletionFixture(bool useReasoningChatModel, bool useBeta)
+ {
+ this._useReasoningModel = useReasoningChatModel;
+ this._useBeta = useBeta;
+ }
+
+ public AIAgent Agent => this._agent;
+
+ public IChatClient ChatClient => this._agent.ChatClient;
+
+ public async Task> GetChatHistoryAsync(AgentThread thread)
+ {
+ var typedThread = (ChatClientAgentThread)thread;
+
+ return typedThread.MessageStore is null ? [] : (await typedThread.MessageStore.GetMessagesAsync()).ToList();
+ }
+
+ public Task CreateChatClientAgentAsync(
+ string name = "HelpfulAssistant",
+ string instructions = "You are a helpful assistant.",
+ IList? aiTools = null)
+ {
+ var anthropicClient = new AnthropicClient() { APIKey = s_config.ApiKey };
+
+ IChatClient? chatClient = this._useBeta
+ ? anthropicClient
+ .Beta
+ .AsIChatClient()
+ .AsBuilder()
+ .ConfigureOptions(options
+ => options.RawRepresentationFactory = _
+ => new Anthropic.Models.Beta.Messages.MessageCreateParams()
+ {
+ Model = options.ModelId ?? (this._useReasoningModel ? s_config.ChatReasoningModelId : s_config.ChatModelId),
+ MaxTokens = options.MaxOutputTokens ?? 4096,
+ Messages = [],
+ Thinking = this._useReasoningModel
+ ? new BetaThinkingConfigParam(new BetaThinkingConfigEnabled(2048))
+ : new BetaThinkingConfigParam(new BetaThinkingConfigDisabled())
+ }).Build()
+
+ : anthropicClient
+ .AsIChatClient()
+ .AsBuilder()
+ .ConfigureOptions(options
+ => options.RawRepresentationFactory = _
+ => new Anthropic.Models.Messages.MessageCreateParams()
+ {
+ Model = options.ModelId ?? (this._useReasoningModel ? s_config.ChatReasoningModelId : s_config.ChatModelId),
+ MaxTokens = options.MaxOutputTokens ?? 4096,
+ Messages = [],
+ Thinking = this._useReasoningModel
+ ? new ThinkingConfigParam(new ThinkingConfigEnabled(2048))
+ : new ThinkingConfigParam(new ThinkingConfigDisabled())
+ }).Build();
+
+ return Task.FromResult(new ChatClientAgent(chatClient, options: new()
+ {
+ Name = name,
+ Instructions = instructions,
+ ChatOptions = new() { Tools = aiTools }
+ }));
+ }
+
+ public Task DeleteAgentAsync(ChatClientAgent agent) =>
+ // Chat Completion does not require/support deleting agents, so this is a no-op.
+ Task.CompletedTask;
+
+ public Task DeleteThreadAsync(AgentThread thread) =>
+ // Chat Completion does not require/support deleting threads, so this is a no-op.
+ Task.CompletedTask;
+
+ public async Task InitializeAsync() =>
+ this._agent = await this.CreateChatClientAgentAsync();
+
+ public Task DisposeAsync() =>
+ Task.CompletedTask;
+}
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunStreamingTests.cs b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunStreamingTests.cs
new file mode 100644
index 0000000000..f1bbbe47e9
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunStreamingTests.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Threading.Tasks;
+using AgentConformance.IntegrationTests;
+
+namespace AnthropicChatCompletion.IntegrationTests;
+
+public abstract class SkipAllRunStreaming(Func func) : RunStreamingTests(func)
+{
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithChatMessageReturnsExpectedResultAsync() => base.RunWithChatMessageReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithNoMessageDoesNotFailAsync() => base.RunWithNoMessageDoesNotFailAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithChatMessagesReturnsExpectedResultAsync() => base.RunWithChatMessagesReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithStringReturnsExpectedResultAsync() => base.RunWithStringReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task ThreadMaintainsHistoryAsync() => base.ThreadMaintainsHistoryAsync();
+}
+
+public class AnthropicBetaChatCompletionRunStreamingTests()
+ : SkipAllRunStreaming(() => new(useReasoningChatModel: false, useBeta: true));
+
+public class AnthropicBetaChatCompletionReasoningRunStreamingTests()
+ : SkipAllRunStreaming(() => new(useReasoningChatModel: true, useBeta: true));
+
+public class AnthropicChatCompletionRunStreamingTests()
+ : SkipAllRunStreaming(() => new(useReasoningChatModel: false, useBeta: false));
+
+public class AnthropicChatCompletionReasoningRunStreamingTests()
+ : SkipAllRunStreaming(() => new(useReasoningChatModel: true, useBeta: false));
diff --git a/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunTests.cs b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunTests.cs
new file mode 100644
index 0000000000..aadbf747c2
--- /dev/null
+++ b/dotnet/tests/AnthropicChatCompletion.IntegrationTests/AnthropicChatCompletionRunTests.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Threading.Tasks;
+using AgentConformance.IntegrationTests;
+
+namespace AnthropicChatCompletion.IntegrationTests;
+
+public abstract class SkipAllRun(Func func) : RunTests(func)
+{
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithChatMessageReturnsExpectedResultAsync() => base.RunWithChatMessageReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithNoMessageDoesNotFailAsync() => base.RunWithNoMessageDoesNotFailAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithChatMessagesReturnsExpectedResultAsync() => base.RunWithChatMessagesReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task RunWithStringReturnsExpectedResultAsync() => base.RunWithStringReturnsExpectedResultAsync();
+
+ [Fact(Skip = AnthropicChatCompletionFixture.SkipReason)]
+ public override Task ThreadMaintainsHistoryAsync() => base.ThreadMaintainsHistoryAsync();
+}
+
+public class AnthropicBetaChatCompletionRunTests()
+ : SkipAllRun(() => new(useReasoningChatModel: false, useBeta: true));
+
+public class AnthropicBetaChatCompletionReasoningRunTests()
+ : SkipAllRun(() => new(useReasoningChatModel: true, useBeta: true));
+
+public class AnthropicChatCompletionRunTests()
+ : SkipAllRun(() => new(useReasoningChatModel: false, useBeta: false));
+
+public class AnthropicChatCompletionReasoningRunTests()
+ : SkipAllRun(() => new(useReasoningChatModel: true, useBeta: false));
diff --git a/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicBetaServiceExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicBetaServiceExtensionsTests.cs
new file mode 100644
index 0000000000..af778c03c9
--- /dev/null
+++ b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicBetaServiceExtensionsTests.cs
@@ -0,0 +1,290 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+#pragma warning disable IDE0052 // Remove unread private members
+
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Anthropic;
+using Anthropic.Core;
+using Anthropic.Services;
+using Microsoft.Extensions.AI;
+using Moq;
+using IBetaMessageService = Anthropic.Services.Beta.IMessageService;
+using IMessageService = Anthropic.Services.IMessageService;
+
+namespace Microsoft.Agents.AI.Anthropic.UnitTests.Extensions;
+
+///
+/// Unit tests for the AnthropicClientExtensions class.
+///
+public sealed class AnthropicBetaServiceExtensionsTests
+{
+ ///
+ /// Verify that CreateAIAgent with clientFactory parameter correctly applies the factory.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ var testChatClient = new TestChatClient(chatClient.Beta.AsIChatClient());
+
+ // Act
+ var agent = chatClient.Beta.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent",
+ description: "Test description",
+ clientFactory: (innerClient) => testChatClient);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+ Assert.Equal("Test description", agent.Description);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with clientFactory using AsBuilder pattern works correctly.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ TestChatClient? testChatClient = null;
+
+ // Act
+ var agent = chatClient.Beta.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ clientFactory: (innerClient) =>
+ innerClient.AsBuilder().Use((innerClient) => testChatClient = new TestChatClient(innerClient)).Build());
+
+ // Assert
+ Assert.NotNull(agent);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with options and clientFactory parameter correctly applies the factory.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ var testChatClient = new TestChatClient(chatClient.Beta.AsIChatClient());
+ var options = new ChatClientAgentOptions
+ {
+ Name = "Test Agent",
+ Description = "Test description",
+ Instructions = "Test instructions"
+ };
+
+ // Act
+ var agent = chatClient.Beta.CreateAIAgent(
+ options,
+ clientFactory: (innerClient) => testChatClient);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+ Assert.Equal("Test description", agent.Description);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent without clientFactory works normally.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithoutClientFactory_WorksNormally()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act
+ var agent = chatClient.Beta.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent");
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+
+ // Verify that no TestChatClient is available since no factory was provided
+ var retrievedTestClient = agent.GetService();
+ Assert.Null(retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with null clientFactory works normally.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullClientFactory_WorksNormally()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act
+ var agent = chatClient.Beta.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent",
+ clientFactory: null);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+
+ // Verify that no TestChatClient is available since no factory was provided
+ var retrievedTestClient = agent.GetService();
+ Assert.Null(retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent throws ArgumentNullException when client is null.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullClient_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ var exception = Assert.Throws(() =>
+ ((IBetaService)null!).CreateAIAgent("test-model"));
+
+ Assert.Equal("betaService", exception.ParamName);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with options throws ArgumentNullException when options is null.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullOptions_ThrowsArgumentNullException()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act & Assert
+ var exception = Assert.Throws(() =>
+ chatClient.Beta.CreateAIAgent((ChatClientAgentOptions)null!));
+
+ Assert.Equal("options", exception.ParamName);
+ }
+
+ ///
+ /// Test custom chat client that can be used to verify clientFactory functionality.
+ ///
+ private sealed class TestChatClient : IChatClient
+ {
+ private readonly IChatClient _innerClient;
+
+ public TestChatClient(IChatClient innerClient)
+ {
+ this._innerClient = innerClient;
+ }
+
+ public Task GetResponseAsync(IEnumerable messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
+ => this._innerClient.GetResponseAsync(messages, options, cancellationToken);
+
+ public async IAsyncEnumerable GetStreamingResponseAsync(
+ IEnumerable messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ await foreach (var update in this._innerClient.GetStreamingResponseAsync(messages, options, cancellationToken))
+ {
+ yield return update;
+ }
+ }
+
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ // Return this instance when requested
+ if (serviceType == typeof(TestChatClient))
+ {
+ return this;
+ }
+
+ return this._innerClient.GetService(serviceType, serviceKey);
+ }
+
+ public void Dispose() => this._innerClient.Dispose();
+ }
+
+ ///
+ /// Creates a test ChatClient implementation for testing.
+ ///
+ private sealed class TestAnthropicChatClient : IAnthropicClient
+ {
+ public TestAnthropicChatClient()
+ {
+ this.BetaService = new TestBetaService(this);
+ }
+
+ public HttpClient HttpClient { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public Uri BaseUrl { get => new("http://localhost"); init => throw new NotImplementedException(); }
+ public bool ResponseValidation { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public int? MaxRetries { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public TimeSpan? Timeout { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public string? APIKey { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public string? AuthToken { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+
+ public IMessageService Messages => throw new NotImplementedException();
+
+ public IModelService Models => throw new NotImplementedException();
+
+ public IBetaService Beta => this.BetaService;
+
+ public IBetaService BetaService { get; }
+
+ IMessageService IAnthropicClient.Messages => new Mock().Object;
+
+ public Task Execute(HttpRequest request, CancellationToken cancellationToken = default) where T : ParamsBase
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAnthropicClient WithOptions(Func modifier)
+ {
+ throw new NotImplementedException();
+ }
+
+ private sealed class TestBetaService : IBetaService
+ {
+ private readonly IAnthropicClient _client;
+
+ public TestBetaService(IAnthropicClient client)
+ {
+ this._client = client;
+ }
+
+ public global::Anthropic.Services.Beta.IModelService Models => throw new NotImplementedException();
+
+ public global::Anthropic.Services.Beta.IFileService Files => throw new NotImplementedException();
+
+ public global::Anthropic.Services.Beta.ISkillService Skills => throw new NotImplementedException();
+
+ public IBetaMessageService Messages => new Mock().Object;
+
+ public IBetaService WithOptions(Func modifier)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicClientExtensionsTests.cs b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicClientExtensionsTests.cs
new file mode 100644
index 0000000000..7a9c34a508
--- /dev/null
+++ b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Extensions/AnthropicClientExtensionsTests.cs
@@ -0,0 +1,257 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Anthropic;
+using Anthropic.Core;
+using Anthropic.Services;
+using Microsoft.Extensions.AI;
+
+namespace Microsoft.Agents.AI.Anthropic.UnitTests.Extensions;
+
+///
+/// Unit tests for the AnthropicClientExtensions class.
+///
+public sealed class AnthropicClientExtensionsTests
+{
+ ///
+ /// Test custom chat client that can be used to verify clientFactory functionality.
+ ///
+ private sealed class TestChatClient : IChatClient
+ {
+ private readonly IChatClient _innerClient;
+
+ public TestChatClient(IChatClient innerClient)
+ {
+ this._innerClient = innerClient;
+ }
+
+ public Task GetResponseAsync(IEnumerable messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
+ => this._innerClient.GetResponseAsync(messages, options, cancellationToken);
+
+ public async IAsyncEnumerable GetStreamingResponseAsync(
+ IEnumerable messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ await foreach (var update in this._innerClient.GetStreamingResponseAsync(messages, options, cancellationToken))
+ {
+ yield return update;
+ }
+ }
+
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ // Return this instance when requested
+ if (serviceType == typeof(TestChatClient))
+ {
+ return this;
+ }
+
+ return this._innerClient.GetService(serviceType, serviceKey);
+ }
+
+ public void Dispose() => this._innerClient.Dispose();
+ }
+
+ ///
+ /// Creates a test ChatClient implementation for testing.
+ ///
+ private sealed class TestAnthropicChatClient : IAnthropicClient
+ {
+ public TestAnthropicChatClient()
+ {
+ }
+
+ public HttpClient HttpClient { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public Uri BaseUrl { get => new("http://localhost"); init => throw new NotImplementedException(); }
+ public bool ResponseValidation { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public int? MaxRetries { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public TimeSpan? Timeout { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public string? APIKey { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+ public string? AuthToken { get => throw new NotImplementedException(); init => throw new NotImplementedException(); }
+
+ public IMessageService Messages => throw new NotImplementedException();
+
+ public IModelService Models => throw new NotImplementedException();
+
+ public IBetaService Beta => throw new NotImplementedException();
+
+ public Task Execute(HttpRequest request, CancellationToken cancellationToken = default) where T : ParamsBase
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAnthropicClient WithOptions(Func modifier)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ ///
+ /// Verify that CreateAIAgent with clientFactory parameter correctly applies the factory.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithClientFactory_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ var testChatClient = new TestChatClient(chatClient.AsIChatClient());
+
+ // Act
+ var agent = chatClient.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent",
+ description: "Test description",
+ clientFactory: (innerClient) => testChatClient);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+ Assert.Equal("Test description", agent.Description);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with clientFactory using AsBuilder pattern works correctly.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithClientFactoryUsingAsBuilder_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ TestChatClient? testChatClient = null;
+
+ // Act
+ var agent = chatClient.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ clientFactory: (innerClient) =>
+ innerClient.AsBuilder().Use((innerClient) => testChatClient = new TestChatClient(innerClient)).Build());
+
+ // Assert
+ Assert.NotNull(agent);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with options and clientFactory parameter correctly applies the factory.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithOptionsAndClientFactory_AppliesFactoryCorrectly()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+ var testChatClient = new TestChatClient(chatClient.AsIChatClient());
+ var options = new ChatClientAgentOptions
+ {
+ Name = "Test Agent",
+ Description = "Test description",
+ Instructions = "Test instructions"
+ };
+
+ // Act
+ var agent = chatClient.CreateAIAgent(
+ options,
+ clientFactory: (innerClient) => testChatClient);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+ Assert.Equal("Test description", agent.Description);
+
+ // Verify that the custom chat client can be retrieved from the agent's service collection
+ var retrievedTestClient = agent.GetService();
+ Assert.NotNull(retrievedTestClient);
+ Assert.Same(testChatClient, retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent without clientFactory works normally.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithoutClientFactory_WorksNormally()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act
+ var agent = chatClient.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent");
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+
+ // Verify that no TestChatClient is available since no factory was provided
+ var retrievedTestClient = agent.GetService();
+ Assert.Null(retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with null clientFactory works normally.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullClientFactory_WorksNormally()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act
+ var agent = chatClient.CreateAIAgent(
+ model: "test-model",
+ instructions: "Test instructions",
+ name: "Test Agent",
+ clientFactory: null);
+
+ // Assert
+ Assert.NotNull(agent);
+ Assert.Equal("Test Agent", agent.Name);
+
+ // Verify that no TestChatClient is available since no factory was provided
+ var retrievedTestClient = agent.GetService();
+ Assert.Null(retrievedTestClient);
+ }
+
+ ///
+ /// Verify that CreateAIAgent throws ArgumentNullException when client is null.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullClient_ThrowsArgumentNullException()
+ {
+ // Act & Assert
+ var exception = Assert.Throws(() =>
+ ((TestAnthropicChatClient)null!).CreateAIAgent("test-model"));
+
+ Assert.Equal("client", exception.ParamName);
+ }
+
+ ///
+ /// Verify that CreateAIAgent with options throws ArgumentNullException when options is null.
+ ///
+ [Fact]
+ public void CreateAIAgent_WithNullOptions_ThrowsArgumentNullException()
+ {
+ // Arrange
+ var chatClient = new TestAnthropicChatClient();
+
+ // Act & Assert
+ var exception = Assert.Throws(() =>
+ chatClient.CreateAIAgent((ChatClientAgentOptions)null!));
+
+ Assert.Equal("options", exception.ParamName);
+ }
+}
diff --git a/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Microsoft.Agents.AI.Anthropic.UnitTests.csproj b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Microsoft.Agents.AI.Anthropic.UnitTests.csproj
new file mode 100644
index 0000000000..291c56f879
--- /dev/null
+++ b/dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Microsoft.Agents.AI.Anthropic.UnitTests.csproj
@@ -0,0 +1,11 @@
+
+
+
+ true
+
+
+
+
+
+
+