Skip to content

Commit 6128bed

Browse files
committed
Adapt to new breaking changes in AF and new registrations
Instructions is gone from Agent, it's now only in agent's chat options. Agent catalog is likewise gone, relying solely on DI keyed services. Also, overload in MapOpenAIResponses receiving the agent is enough now to properly map responses. DevUI mapped but conversations not working as it needs. More tweaks needed, but this allows D.E.AI to build
1 parent c4bfb30 commit 6128bed

File tree

12 files changed

+73
-53
lines changed

12 files changed

+73
-53
lines changed

sample/Server/AgentDiscoveryExtensions.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
using System.Diagnostics.CodeAnalysis;
22
using System.Text.Json.Serialization;
3-
using Microsoft.Agents.AI.Hosting;
3+
using Microsoft.Agents.AI;
44

55
static class AgentDiscoveryExtensions
66
{
77
public static void MapAgentDiscovery(this IEndpointRouteBuilder endpoints, [StringSyntax("Route")] string path)
88
{
99
var routeGroup = endpoints.MapGroup(path);
10-
routeGroup.MapGet("/", async (AgentCatalog catalog, CancellationToken cancellation)
11-
=> Results.Ok(await catalog
12-
.GetAgentsAsync(cancellation)
13-
.Select(agent => new AgentDiscoveryCard(agent.Name!, agent.Description))
14-
.ToArrayAsync()))
10+
routeGroup.MapGet("/", () => Results.Ok(endpoints.ServiceProvider
11+
.GetKeyedServices<AIAgent>(KeyedService.AnyKey)
12+
.Select(agent => new AgentDiscoveryCard(agent.Name!, agent.Description)).ToArray()))
1513
.WithName("GetAgents");
1614
}
1715

sample/Server/ConsoleExtensions.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Devlooped.Agents.AI;
22
using Devlooped.Extensions.AI;
3-
using Microsoft.Agents.AI.Hosting;
3+
using Microsoft.Agents.AI;
44
using Microsoft.Extensions.AI;
55
using Newtonsoft.Json;
66
using Newtonsoft.Json.Serialization;
@@ -13,7 +13,6 @@ public static class ConsoleExtensions
1313
{
1414
public async ValueTask RenderAgentsAsync(IServiceCollection collection)
1515
{
16-
var catalog = services.GetRequiredService<AgentCatalog>();
1716
var settings = new JsonSerializerSettings
1817
{
1918
NullValueHandling = NullValueHandling.Include,
@@ -38,14 +37,24 @@ public async ValueTask RenderAgentsAsync(IServiceCollection collection)
3837
}
3938

4039
// List configured agents
41-
await foreach (var agent in catalog.GetAgentsAsync())
40+
var rendered = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
41+
foreach (var descriptor in collection.AsEnumerable().Where(x => x.ServiceType == typeof(AIAgent) && x.IsKeyedService && x.ServiceKey is string))
4242
{
43+
if (rendered.Contains((string)descriptor.ServiceKey!))
44+
continue;
45+
46+
var agent = services.GetKeyedService<AIAgent>(descriptor.ServiceKey);
47+
if (agent is null)
48+
continue;
49+
4350
var metadata = agent.GetService<ConfigurableAIAgentMetadata>();
4451

4552
AnsiConsole.Write(new Panel(new JsonText(JsonConvert.SerializeObject(new { Agent = agent, Metadata = metadata }, settings)))
4653
{
4754
Header = new PanelHeader($"| 🤖 {agent.DisplayName} from {metadata?.ConfigurationSection} |"),
4855
});
56+
57+
rendered.Add((string)descriptor.ServiceKey!);
4958
}
5059
}
5160
}

sample/Server/DotEnv.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Runtime.CompilerServices;
2+
3+
class DotEnv
4+
{
5+
[ModuleInitializer]
6+
public static void Init()
7+
{
8+
// Load environment variables from .env files in current dir and above.
9+
DotNetEnv.Env.TraversePath().Load();
10+
11+
// Load environment variables from user profile directory.
12+
var userEnv = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".env");
13+
if (File.Exists(userEnv))
14+
DotNetEnv.Env.Load(userEnv);
15+
}
16+
}

sample/Server/Program.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
using System.Text;
33
using Devlooped.Extensions.AI;
44
using Microsoft.Agents.AI;
5-
using Microsoft.Agents.AI.Hosting;
6-
using Microsoft.Agents.AI.Hosting.OpenAI;
5+
using Microsoft.Agents.AI.DevUI;
76
using Microsoft.Extensions.AI;
87
using Spectre.Console;
98

@@ -34,6 +33,9 @@
3433
builder.AddAIAgents()
3534
.WithTools<NotesTools>();
3635

36+
builder.AddOpenAIResponses();
37+
builder.AddOpenAIConversations();
38+
3739
var app = builder.Build();
3840

3941
// From ServiceDefaults.cs
@@ -42,15 +44,19 @@
4244
#if DEBUG
4345
// 👇 render all configured agents
4446
await app.Services.RenderAgentsAsync(builder.Services);
47+
app.MapDevUI();
4548
#endif
4649

4750
// Map each agent's endpoints via response API
48-
var catalog = app.Services.GetRequiredService<AgentCatalog>();
4951
// List configured agents
50-
await foreach (var agent in catalog.GetAgentsAsync())
52+
var registered = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
53+
foreach (var agent in app.Services.GetKeyedServices<AIAgent>(KeyedService.AnyKey))
5154
{
52-
if (agent.Name != null)
53-
app.MapOpenAIResponses(agent.Name);
55+
if (agent.Name != null && !registered.Contains(agent.Name))
56+
{
57+
app.MapOpenAIResponses(agent);
58+
registered.Add(agent.Name);
59+
}
5460
}
5561

5662
// Map the agents HTTP endpoints

sample/Server/Server.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Microsoft.Agents.AI.Hosting.OpenAI" Version="42.42.11-pre" />
9+
<PackageReference Include="Microsoft.Agents.AI.DevUI" Version="42.42.12-pre" />
10+
<PackageReference Include="Microsoft.Agents.AI.Hosting.OpenAI" Version="42.42.12-pre" />
1011
<PackageReference Include="ModelContextProtocol" Version="0.4.0-preview.3" />
1112
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
1213
<PackageReference Include="ThisAssembly.Project" Version="2.1.2" PrivateAssets="all" />

sample/Server/ai.toml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@ modelid = "grok-4-fast-non-reasoning"
77

88
[ai.agents.orders]
99
description = "Manage orders using catalogs for food or any other item."
10-
instructions = """\
11-
You are an AI agent responsible for processing orders for food or other items.
12-
Your primary goals are to identify user intent, extract or request provider information, manage order data using tools and friendly responses to guide users through the ordering process.
13-
"""
14-
options = { modelid = "gpt-4o-mini" }
15-
# 👇 alternative syntax to specify options
16-
# [ai.agents.orders.options]
17-
# modelid = "gpt-4o-mini"
18-
1910
# ai.clients.openai, can omit the ai.clients prefix
2011
client = "openai"
2112
use = ["tone"]
2213
tools = ["get_date", "create_order", "cancel_order"]
2314

15+
[ai.agents.orders.options]
16+
modelid = "gpt-4o-mini"
17+
instructions = """
18+
You are an AI agent responsible for processing orders for food or other items.
19+
Your primary goals are to identify user intent, extract or request provider information, manage order data using tools and friendly responses to guide users through the ordering process.
20+
"""
2421

2522
[ai.context.tone]
2623
instructions = """\

sample/Server/notes.agent.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ description: Provides free-form memory
44
beta: true
55
visibility: unlisted
66
client: grok
7-
model: grok-4-fast
7+
options:
8+
modelid: grok-4-fast
89
use: ["tone", "notes"]
910
tools: ["get_notes", "save_notes", "get_date"]
1011
---

sample/ServiceDefaults.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
using Devlooped.Agents.AI;
2-
using DotNetEnv.Configuration;
32
using OpenTelemetry;
43
using OpenTelemetry.Metrics;
54
using OpenTelemetry.Resources;
65
using OpenTelemetry.Trace;
76
using Tomlyn.Extensions.Configuration;
87

9-
10-
118
#if WEB
129
using Microsoft.Extensions.Diagnostics.HealthChecks;
1310
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
@@ -25,7 +22,6 @@ public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
2522

2623
// .env/secrets override other config, which may contain dummy API keys, for example
2724
builder.Configuration
28-
.AddDotNetEnv()
2925
.AddEnvironmentVariables()
3026
.AddUserSecrets<Program>();
3127

src/Agents/Agents.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
2424
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
2525

26-
<PackageReference Include="Microsoft.Agents.AI" Version="42.42.11-pre" />
27-
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="42.42.11-pre" />
28-
<PackageReference Include="Microsoft.Agents.AI.AzureAI" Version="42.42.11-pre" />
29-
<PackageReference Include="Microsoft.Agents.AI.OpenAI" Version="42.42.11-pre" />
26+
<PackageReference Include="Microsoft.Agents.AI" Version="42.42.12-pre" />
27+
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="42.42.12-pre" />
28+
<PackageReference Include="Microsoft.Agents.AI.AzureAI" Version="42.42.12-pre" />
29+
<PackageReference Include="Microsoft.Agents.AI.OpenAI" Version="42.42.12-pre" />
3030
<PackageReference Include="ModelContextProtocol" Version="0.4.0-preview.3" />
3131
<PackageReference Include="PolySharp" Version="1.15.0" PrivateAssets="all" />
3232
<PackageReference Include="YamlDotNet" Version="16.3.0" />

src/Agents/ConfigurableAIAgent.cs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,19 @@ public override IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(IEnum
9090
var options = configSection.Get<AgentClientOptions>();
9191
options?.Name ??= name;
9292
options?.Description = options?.Description?.Dedent();
93-
options?.Instructions = options?.Instructions?.Dedent();
9493

9594
var properties = configSection.Get<AdditionalPropertiesDictionary>();
9695
if (properties is not null)
9796
{
98-
properties?.Remove(nameof(AgentClientOptions.Name));
99-
properties?.Remove(nameof(AgentClientOptions.Description));
100-
properties?.Remove(nameof(AgentClientOptions.Instructions));
101-
properties?.Remove(nameof(AgentClientOptions.Client));
102-
properties?.Remove(nameof(AgentClientOptions.Model));
103-
properties?.Remove(nameof(AgentClientOptions.Use));
104-
properties?.Remove(nameof(AgentClientOptions.Tools));
105-
106-
AdditionalProperties = properties;
97+
properties.Remove(nameof(AgentClientOptions.Name));
98+
properties.Remove(nameof(AgentClientOptions.Description));
99+
properties.Remove(nameof(AgentClientOptions.Client));
100+
properties.Remove(nameof(AgentClientOptions.Use));
101+
properties.Remove(nameof(AgentClientOptions.Tools));
102+
properties.Remove(nameof(ChatOptions.ModelId));
103+
properties.Remove(nameof(ChatOptions.Instructions));
104+
105+
AdditionalProperties = properties.Count == 0 ? null : properties;
107106
}
108107

109108
// If there was a custom id, we must validate it didn't change since that's not supported.
@@ -120,10 +119,10 @@ public override IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(IEnum
120119
? configSection.GetSection("options").Get<GrokChatOptions>()
121120
: configSection.GetSection("options").Get<ExtendedChatOptions>();
122121

122+
chat?.Instructions = chat?.Instructions?.Dedent();
123+
123124
if (chat is not null)
124125
options.ChatOptions = chat;
125-
else if (options.Model is not null)
126-
(options.ChatOptions ??= new()).ModelId = options.Model;
127126

128127
configure?.Invoke(name, options);
129128

@@ -237,7 +236,6 @@ void OnReload(object? state)
237236
internal class AgentClientOptions : ChatClientAgentOptions
238237
{
239238
public string? Client { get; set; }
240-
public string? Model { get; set; }
241239
public IList<string>? Use { get; set; }
242240
public IList<string>? Tools { get; set; }
243241
}

0 commit comments

Comments
 (0)