Skip to content
Draft
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
1 change: 1 addition & 0 deletions dotnet/agent-framework-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
<Project Path="samples/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj" />
<Project Path="samples/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj" />
<Project Path="samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj" />
<Project Path="samples/HostedAgents/AgentCatalogMinimalAPI/AgentCatalogMinimalAPI.csproj" />
</Folder>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

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

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

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

// This sample demonstrates how to create a minimal API that uses AgentCatalog to retrieve all registered agents
// and return their metadata including custom additional properties.

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;

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-4o-mini";

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Add a chat client to the service collection
builder.Services.AddSingleton(sp => new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.AsIChatClient());

// Configure multiple agents with additional properties
builder.AddAIAgent("weather-agent", (sp, key) =>
{
IChatClient chatClient = sp.GetRequiredService<IChatClient>();
ChatClientAgentOptions options = new ChatClientAgentOptions
{
Name = key,
Instructions = "You are a helpful weather assistant that provides weather information.",
Description = "An agent that helps users with weather-related queries.",
AdditionalProperties = new AdditionalPropertiesDictionary
{
["icon"] = "https://example.com/icons/weather.png",
["beta"] = false,
["visibility"] = "Visible"
}
};
return new ChatClientAgent(chatClient, options);
});

builder.AddAIAgent("travel-agent", (sp, key) =>
{
IChatClient chatClient = sp.GetRequiredService<IChatClient>();
ChatClientAgentOptions options = new ChatClientAgentOptions
{
Name = key,
Instructions = "You are a helpful travel assistant that helps plan trips.",
Description = "An agent that helps users plan their travel and vacations.",
AdditionalProperties = new AdditionalPropertiesDictionary
{
["icon"] = "https://example.com/icons/travel.png",
["beta"] = true,
["visibility"] = "Visible"
}
};
return new ChatClientAgent(chatClient, options);
});

builder.AddAIAgent("experimental-agent", (sp, key) =>
{
IChatClient chatClient = sp.GetRequiredService<IChatClient>();
ChatClientAgentOptions options = new ChatClientAgentOptions
{
Name = key,
Instructions = "You are an experimental assistant for testing new features.",
Description = "An experimental agent for internal testing only.",
AdditionalProperties = new AdditionalPropertiesDictionary
{
["icon"] = "https://example.com/icons/experimental.png",
["beta"] = true,
["visibility"] = "Unlisted"
}
};
return new ChatClientAgent(chatClient, options);
});

WebApplication app = builder.Build();

app.MapGet("/agents", async (AgentCatalog agentCatalog, CancellationToken cancellationToken) =>
{
List<object> agents = new List<object>();

await foreach (AIAgent agent in agentCatalog.GetAgentsAsync(cancellationToken))
{
agents.Add(new { name = agent.Name, properties = agent.AdditionalProperties });
}

return agents;
});

app.Run();
93 changes: 93 additions & 0 deletions dotnet/samples/HostedAgents/AgentCatalogMinimalAPI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Agent Catalog Minimal API Sample

This sample demonstrates how to create a minimal API application that uses the `AgentCatalog` to retrieve all registered AI agents and expose their metadata through a REST endpoint.

## Overview

The sample creates an absolutely minimal ASP.NET Core web API with:
- Multiple AI agents registered with custom metadata
- An `/agents` endpoint that returns a JSON array of all agents with their names and additional properties

## Features

- **AgentCatalog Integration**: Uses the `AgentCatalog` to enumerate all registered agents
- **Custom Metadata**: Each agent includes additional properties stored in `AdditionalProperties` dictionary
- **Simple API**: Returns anonymous objects with agent name and properties - clients can handle the data as needed

## Prerequisites

- .NET 9.0 or later
- Azure OpenAI resource with a deployed model
- Azure CLI for authentication

## Configuration

Set the following environment variables:

```bash
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
```

## Running the Sample

1. Navigate to the sample directory:
```bash
cd dotnet/samples/HostedAgents/AgentCatalogMinimalAPI
```

2. Run the application:
```bash
dotnet run
```

3. Test the `/agents` endpoint:
```bash
curl http://localhost:5000/agents
```

## Example Response

```json
[
{
"name": "weather-agent",
"properties": {
"icon": "https://example.com/icons/weather.png",
"beta": false,
"visibility": "Visible"
}
},
{
"name": "travel-agent",
"properties": {
"icon": "https://example.com/icons/travel.png",
"beta": true,
"visibility": "Visible"
}
},
{
"name": "experimental-agent",
"properties": {
"icon": "https://example.com/icons/experimental.png",
"beta": true,
"visibility": "Unlisted"
}
}
]
```

## Code Structure

The sample demonstrates:

1. **Agent Registration**: Multiple agents are registered using `builder.AddAIAgent()` with custom additional properties
2. **AgentCatalog Usage**: The `AgentCatalog` service is injected into the endpoint handler
3. **Simple Response**: Returns anonymous objects with `name` and `properties` - clients handle parsing as needed

## Key Concepts

- **AgentCatalog**: Provides enumeration of all registered agents in the application
- **AdditionalProperties**: A dictionary that can store custom metadata on agents
- **Minimal APIs**: Uses ASP.NET Core minimal API syntax for clean, concise endpoint definitions
- **Dependency Injection**: Agents are registered in DI and resolved through the `AgentCatalog`