Skip to content

Commit dd32a6d

Browse files
authored
Add extension methods to get an AF agent from a Foundry Client (#191)
* Add helpers to go from foundry client to agent more easily. * Fix xml docs.
1 parent 95a3264 commit dd32a6d

6 files changed

Lines changed: 140 additions & 11 deletions

File tree

dotnet/agent-framework-dotnet.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
<Folder Name="/src/">
114114
<Project Path="src/Microsoft.Agents.Orchestration/Microsoft.Agents.Orchestration.csproj" />
115115
<Project Path="src/Microsoft.Extensions.AI.Agents.Abstractions/Microsoft.Extensions.AI.Agents.Abstractions.csproj" />
116+
<Project Path="src/Microsoft.Extensions.AI.Agents.AzureAI/Microsoft.Extensions.AI.Agents.AzureAI.csproj" />
116117
<Project Path="src/Microsoft.Extensions.AI.Agents.CopilotStudio/Microsoft.Extensions.AI.Agents.CopilotStudio.csproj" />
117118
<Project Path="src/Microsoft.Extensions.AI.Agents.Runtime.Abstractions/Microsoft.Extensions.AI.Agents.Runtime.Abstractions.csproj" />
118119
<Project Path="src/Microsoft.Extensions.AI.Agents/Microsoft.Extensions.AI.Agents.csproj" />

dotnet/samples/GettingStarted/GettingStarted.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
<ItemGroup>
3131
<ProjectReference Include="..\..\src\Microsoft.Agents.Orchestration\Microsoft.Agents.Orchestration.csproj" />
32+
<ProjectReference Include="..\..\src\Microsoft.Extensions.AI.Agents.AzureAI\Microsoft.Extensions.AI.Agents.AzureAI.csproj" />
3233
<ProjectReference Include="..\..\src\Microsoft.Extensions.AI.Agents\Microsoft.Extensions.AI.Agents.csproj" />
3334
</ItemGroup>
3435

dotnet/samples/GettingStarted/Providers/ChatClientAgent_With_AzureAIAgentsPersistent.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
using Azure.AI.Agents.Persistent;
44
using Azure.Identity;
5-
using Microsoft.Extensions.AI;
65
using Microsoft.Extensions.AI.Agents;
76
using Microsoft.Shared.Samples;
87

@@ -25,19 +24,14 @@ public async Task RunWithAzureAIAgentsPersistent()
2524
// Get a client to create server side agents with.
2625
var persistentAgentsClient = new PersistentAgentsClient(TestConfiguration.AzureAI.Endpoint, new AzureCliCredential());
2726

28-
// Create a server side agent to work with.
29-
var persistentAgentResponse = await persistentAgentsClient.Administration.CreateAgentAsync(
27+
// Create a server side persistent agent.
28+
var createPersistentAgentResponse = await persistentAgentsClient.Administration.CreateAgentAsync(
3029
model: TestConfiguration.AzureAI.DeploymentName,
3130
name: JokerName,
3231
instructions: JokerInstructions);
3332

34-
var persistentAgent = persistentAgentResponse.Value;
35-
36-
// Get the chat client to use for the agent.
37-
using var chatClient = persistentAgentsClient.AsIChatClient(persistentAgent.Id);
38-
39-
// Define the agent.
40-
ChatClientAgent agent = new(chatClient);
33+
// Get a local proxy for the agent to work with.
34+
Agent agent = await persistentAgentsClient.GetRunnableAgentAsync(createPersistentAgentResponse.Value.Id);
4135

4236
// Start a new thread for the agent conversation.
4337
AgentThread thread = agent.GetNewThread();
@@ -58,6 +52,6 @@ async Task RunAgentAsync(string input)
5852

5953
// Cleanup
6054
await persistentAgentsClient.Threads.DeleteThreadAsync(thread.Id);
61-
await persistentAgentsClient.Administration.DeleteAgentAsync(persistentAgent.Id);
55+
await persistentAgentsClient.Administration.DeleteAgentAsync(createPersistentAgentResponse.Value.Id);
6256
}
6357
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
5+
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
6+
<VersionSuffix>alpha</VersionSuffix>
7+
</PropertyGroup>
8+
9+
<Import Project="$(RepoRoot)/dotnet/nuget/nuget-package.props" />
10+
11+
<ItemGroup>
12+
<PackageReference Include="Azure.AI.Agents.Persistent" />
13+
<PackageReference Include="Microsoft.Extensions.AI" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\Microsoft.Extensions.AI.Agents\Microsoft.Extensions.AI.Agents.csproj" />
18+
</ItemGroup>
19+
20+
<PropertyGroup>
21+
<!-- NuGet Package Settings -->
22+
<Title>Microsoft.Extensions.AI.Agents.AzureAI</Title>
23+
<Description>Implementation of generative AI abstractions for Azure AI Persistent Agents.</Description>
24+
</PropertyGroup>
25+
26+
</Project>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Microsoft.Extensions.AI;
7+
using Microsoft.Extensions.AI.Agents;
8+
9+
namespace Azure.AI.Agents.Persistent;
10+
11+
/// <summary>
12+
/// Provides extension methods for <see cref="PersistentAgentsClient"/>.
13+
/// </summary>
14+
public static class PersistentAgentsClientExtensions
15+
{
16+
/// <summary>
17+
/// Retrieves an existing server side agent, wrapped as a <see cref="ChatClientAgent"/> using the provided <see cref="PersistentAgentsClient"/>.
18+
/// </summary>
19+
/// <param name="persistentAgentsClient">The <see cref="PersistentAgentsClient"/> to create the <see cref="ChatClientAgent"/> with.</param>
20+
/// <returns>A <see cref="ChatClientAgent"/> for the persistent agent.</returns>
21+
/// <param name="agentId"> The ID of the server side agent to create a <see cref="ChatClientAgent"/> for.</param>
22+
/// <param name="chatOptions">Options that should apply to all runs of the agent.</param>
23+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
24+
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the persistent agent.</returns>
25+
public static async Task<ChatClientAgent> GetRunnableAgentAsync(
26+
this PersistentAgentsClient persistentAgentsClient,
27+
string agentId,
28+
ChatOptions? chatOptions = null,
29+
CancellationToken cancellationToken = default)
30+
{
31+
if (persistentAgentsClient is null)
32+
{
33+
throw new ArgumentNullException(nameof(persistentAgentsClient));
34+
}
35+
36+
if (string.IsNullOrWhiteSpace(agentId))
37+
{
38+
throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId));
39+
}
40+
41+
var persistentAgentResponse = await persistentAgentsClient.Administration.GetAgentAsync(agentId, cancellationToken).ConfigureAwait(false);
42+
return persistentAgentResponse.AsRunnableAgent(persistentAgentsClient, chatOptions);
43+
}
44+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using Microsoft.Extensions.AI;
5+
using Microsoft.Extensions.AI.Agents;
6+
7+
namespace Azure.AI.Agents.Persistent;
8+
9+
/// <summary>
10+
/// Provides extension methods for working with <see cref="Response{PersistentAgent}"/>.
11+
/// </summary>
12+
internal static class PersistentAgentResponseExtensions
13+
{
14+
/// <summary>
15+
/// Converts a response containing persistent agent metadata into a runnable agent instance.
16+
/// </summary>
17+
/// <param name="persistentAgentResponse">The response containing the persistent agent to be converted. Cannot be <see langword="null"/>.</param>
18+
/// <param name="persistentAgentsClient">The client used to interact with persistent agents. Cannot be <see langword="null"/>.</param>
19+
/// <param name="chatOptions">The default <see cref="ChatOptions"/> to use when interacting with the agent.</param>
20+
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the persistent agent.</returns>
21+
public static ChatClientAgent AsRunnableAgent(this Response<PersistentAgent> persistentAgentResponse, PersistentAgentsClient persistentAgentsClient, ChatOptions? chatOptions = null)
22+
{
23+
if (persistentAgentResponse is null)
24+
{
25+
throw new ArgumentNullException(nameof(persistentAgentResponse));
26+
}
27+
28+
return AsRunnableAgent(persistentAgentResponse.Value, persistentAgentsClient, chatOptions);
29+
}
30+
31+
/// <summary>
32+
/// Converts a <see cref="PersistentAgent"/> containing metadata about a persistent agent into a runnable agent instance.
33+
/// </summary>
34+
/// <param name="persistentAgentMetadata">The persistent agent metadata to be converted. Cannot be <see langword="null"/>.</param>
35+
/// <param name="persistentAgentsClient">The client used to interact with persistent agents. Cannot be <see langword="null"/>.</param>
36+
/// <param name="chatOptions">The default <see cref="ChatOptions"/> to use when interacting with the agent.</param>
37+
/// <returns>A <see cref="ChatClientAgent"/> instance that can be used to perform operations on the persistent agent.</returns>
38+
public static ChatClientAgent AsRunnableAgent(this PersistentAgent persistentAgentMetadata, PersistentAgentsClient persistentAgentsClient, ChatOptions? chatOptions = null)
39+
{
40+
if (persistentAgentMetadata is null)
41+
{
42+
throw new ArgumentNullException(nameof(persistentAgentMetadata));
43+
}
44+
45+
if (persistentAgentsClient is null)
46+
{
47+
throw new ArgumentNullException(nameof(persistentAgentsClient));
48+
}
49+
50+
#pragma warning disable CA2000 // Dispose objects before losing scope
51+
var chatClient = persistentAgentsClient.AsIChatClient(persistentAgentMetadata.Id);
52+
#pragma warning restore CA2000 // Dispose objects before losing scope
53+
54+
return new ChatClientAgent(chatClient, options: new()
55+
{
56+
Id = persistentAgentMetadata.Id,
57+
Name = persistentAgentMetadata.Name,
58+
Description = persistentAgentMetadata.Description,
59+
Instructions = persistentAgentMetadata.Instructions,
60+
ChatOptions = chatOptions
61+
});
62+
}
63+
}

0 commit comments

Comments
 (0)