Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion dotnet/agent-framework-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@
</Folder>
<Folder Name="/Samples/02-agents/A2A/">
<File Path="samples/02-agents/A2A/README.md" />
<Project Path="samples/02-agents/A2A/A2AAgent_AsFunctionTools/A2AAgent_AsFunctionTools.csproj" />
<Project Path="samples/02-agents/A2A/A2AAgent_AsFunctionTool/A2AAgent_AsFunctionTool.csproj" />
<Project Path="samples/02-agents/A2A/A2AAgent_Skills/A2AAgent_Skills.csproj" />
<Project Path="samples/02-agents/A2A/A2AAgent_PollingForTaskCompletion/A2AAgent_PollingForTaskCompletion.csproj" />
<Project Path="samples/02-agents/A2A/A2AAgent_ProtocolSelection/A2AAgent_ProtocolSelection.csproj" />
<Project Path="samples/02-agents/A2A/A2AAgent_StreamReconnection/A2AAgent_StreamReconnection.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@

<ItemGroup>
<PackageReference Include="A2A" />
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.A2A\Microsoft.Agents.AI.A2A.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Foundry\Microsoft.Agents.AI.Foundry.csproj" />
</ItemGroup>

</Project>
35 changes: 35 additions & 0 deletions dotnet/samples/02-agents/A2A/A2AAgent_AsFunctionTool/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft. All rights reserved.

// This sample shows how to expose an A2A agent as a function tool that another agent can call.

using A2A;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
var model = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";
var a2aAgentHost = Environment.GetEnvironmentVariable("A2A_AGENT_HOST") ?? throw new InvalidOperationException("A2A_AGENT_HOST is not set.");

// Initialize an A2ACardResolver to get an A2A agent card.
A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));

// Get the agent card
AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();

// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
AIAgent a2aAgent = agentCard.AsAIAgent();

// Create the main agent, and provide the A2A agent as a function tool.
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
.AsAIAgent(
model: model,
instructions: "You are a helpful assistant. Use the available tools to answer the user's questions.",
tools: [a2aAgent.AsAIFunction()]
Comment thread
SergeyMenshykh marked this conversation as resolved.
);

// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("What can you help me with?"));
30 changes: 30 additions & 0 deletions dotnet/samples/02-agents/A2A/A2AAgent_AsFunctionTool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# A2A Agent as a Function Tool

This sample demonstrates how to expose an A2A agent as a single function tool that another AI agent can call.

The sample:

- Discovers a remote A2A agent from its agent card
- Converts the agent card to an `AIAgent`
- Converts that agent to one function tool with `AsAIFunction()`
- Registers the function tool with a main AI agent

## Prerequisites

Before you begin, ensure you have the following prerequisites:

- .NET 10 SDK or later
- Access to the A2A agent host service
- A Microsoft Foundry project with a deployed model

**Note**: These samples need to be run against a valid A2A server. If no A2A server is available, they can be run against the echo-agent that can be spun up locally by following the guidelines at: https://github.com/a2aproject/a2a-dotnet/blob/main/samples/AgentServer/README.md

Set the following environment variables:

Authenticate with Azure CLI by running `az login`, then set:

```powershell
$env:A2A_AGENT_HOST="https://your-a2a-agent-host" # Replace with your A2A agent host endpoint
$env:FOUNDRY_PROJECT_ENDPOINT="https://your-project.services.ai.azure.com/api/projects/your-project" # Replace with your Foundry project endpoint
$env:FOUNDRY_MODEL="gpt-5.4-mini" # Optional, defaults to gpt-5.4-mini
```
22 changes: 0 additions & 22 deletions dotnet/samples/02-agents/A2A/A2AAgent_AsFunctionTools/README.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net10.0</TargetFrameworks>

<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="A2A" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.A2A\Microsoft.Agents.AI.A2A.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Foundry\Microsoft.Agents.AI.Foundry.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
// Copyright (c) Microsoft. All rights reserved.

// This sample shows how to represent an A2A agent as a set of function tools, where each function tool
// corresponds to a skill of the A2A agent, and register these function tools with another AI agent so
// it can leverage the A2A agent's skills.
// This sample shows how to expose each skill advertised by an A2A agent as a separate function tool.

using System.Text.RegularExpressions;
using A2A;
using Azure.AI.OpenAI;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Chat;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-5.4-mini";
var endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
var model = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";
var a2aAgentHost = Environment.GetEnvironmentVariable("A2A_AGENT_HOST") ?? throw new InvalidOperationException("A2A_AGENT_HOST is not set.");

// Initialize an A2ACardResolver to get an A2A agent card.
// Resolve the remote A2A agent and its advertised skills.
A2ACardResolver agentCardResolver = new(new Uri(a2aAgentHost));

// Get the agent card
AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();

// Create an instance of the AIAgent for an existing A2A agent specified by the agent card.
AIAgent a2aAgent = agentCard.AsAIAgent();

// Create the main agent, and provide the a2a agent skills as a function tools.
// Create the main agent, and provide each A2A skill as a separate function tool.
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
.AsAIAgent(
model: model,
instructions: "You are a helpful assistant that helps people with travel planning.",
tools: [.. CreateFunctionTools(a2aAgent, agentCard)]
);
Expand Down
34 changes: 34 additions & 0 deletions dotnet/samples/02-agents/A2A/A2AAgent_Skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# A2A Agent Skills

This sample demonstrates how to expose each skill advertised by an A2A agent as a separate function tool for another AI agent.

Unlike exposing the whole A2A agent as one tool, this approach gives the model a distinct tool for each skill. The sample uses the skill metadata from the A2A agent card to name and describe those tools.

All generated tools invoke the same A2A agent. Their names and descriptions help the main agent choose an advertised capability; they do not invoke separate skill-specific endpoints.

The sample:

- Discovers a remote A2A agent and its skills from the agent card
- Creates one function tool for each advertised skill
- Adds the skill's description, tags, examples, and supported modes to the function description
- Registers all generated function tools with a main AI agent

## Prerequisites

Before you begin, ensure you have the following prerequisites:

- .NET 10 SDK or later
- Access to the A2A agent host service
- A Microsoft Foundry project with a deployed model

**Note**: These samples need to be run against a valid A2A server. If no A2A server is available, they can be run against the echo-agent that can be spun up locally by following the guidelines at: https://github.com/a2aproject/a2a-dotnet/blob/main/samples/AgentServer/README.md

Set the following environment variables:

Authenticate with Azure CLI by running `az login`, then set:

```powershell
$env:A2A_AGENT_HOST="https://your-a2a-agent-host" # Replace with your A2A agent host endpoint
$env:FOUNDRY_PROJECT_ENDPOINT="https://your-project.services.ai.azure.com/api/projects/your-project" # Replace with your Foundry project endpoint
$env:FOUNDRY_MODEL="gpt-5.4-mini" # Optional, defaults to gpt-5.4-mini
```
5 changes: 3 additions & 2 deletions dotnet/samples/02-agents/A2A/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ See the README.md for each sample for the prerequisites for that sample.

|Sample|Description|
|---|---|
|[A2A Agent As Function Tools](./A2AAgent_AsFunctionTools/)|This sample demonstrates how to represent an A2A agent as a set of function tools, where each function tool corresponds to a skill of the A2A agent, and register these function tools with another AI agent so it can leverage the A2A agent's skills.|
|[A2A Agent as a Function Tool](./A2AAgent_AsFunctionTool/)|This sample demonstrates how to expose an A2A agent as a single function tool that another AI agent can call.|
|[A2A Agent Skills](./A2AAgent_Skills/)|This sample demonstrates how to expose each skill advertised by an A2A agent as a separate function tool.|
|[A2A Agent Polling For Task Completion](./A2AAgent_PollingForTaskCompletion/)|This sample demonstrates how to poll for long-running task completion using continuation tokens with an A2A agent.|
|[A2A Agent Stream Reconnection](./A2AAgent_StreamReconnection/)|This sample demonstrates how to reconnect to an A2A agent's streaming response using continuation tokens, allowing recovery from stream interruptions.|
|[A2A Agent Protocol Selection](./A2AAgent_ProtocolSelection/)|This sample demonstrates how to select the A2A protocol binding (HTTP+JSON vs JSON-RPC) when creating an AIAgent from an A2A agent card using A2AClientOptions.|
Expand All @@ -23,7 +24,7 @@ See the README.md for each sample for the prerequisites for that sample.
To run the samples, navigate to the desired sample directory, e.g.

```powershell
cd A2AAgent_AsFunctionTools
cd A2AAgent_AsFunctionTool
```

Set the required environment variables as documented in the sample readme.
Expand Down
Loading