Skip to content

Commit d8c079f

Browse files
committed
Decouple from the agent framework (AF)
The agent framework is still going through API churn as it heads to GA (see microsoft/agent-framework#2542). Rather than delaying v1 of Devlooped.Extensions.AI (and Grok support), declouple the two and ship from independent repos. The MS.E.AI API is far more stable at this point.
1 parent 0c32f69 commit d8c079f

27 files changed

+3
-1938
lines changed

AI.slnx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44
<Platform Name="x64" />
55
<Platform Name="x86" />
66
</Configurations>
7-
<Folder Name="/Sample/">
8-
<Project Path="sample/Aspire/Aspire.csproj" Id="6166be22-a13f-4074-91a9-b0f3b3a6c4fe" />
9-
<Project Path="sample/Client/Client.csproj" />
10-
<Project Path="sample/Server/Server.csproj" Id="34619937-085f-453d-bc12-9ab2d4abccb7" />
11-
</Folder>
12-
<Project Path="src/Agents/Agents.csproj" Id="90827430-b415-47d6-aac9-2dbe4911b348" />
137
<Project Path="src/Extensions.CodeAnalysis/Extensions.CodeAnalysis.csproj" />
148
<Project Path="src/Extensions.Grok/Extensions.Grok.csproj" Id="3590dc05-72f0-4ada-823b-60cb7b5ea828" />
159
<Project Path="src/Extensions/Extensions.csproj" />

readme.md

Lines changed: 3 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
[![EULA](https://img.shields.io/badge/EULA-OSMF-blue?labelColor=black&color=C9FF30)](osmfeula.txt)
55
[![OSS](https://img.shields.io/github/license/devlooped/oss.svg?color=blue)](license.txt)
6+
[![Version](https://img.shields.io/nuget/vpre/Devlooped.Extensions.AI.svg?color=royalblue)](https://www.nuget.org/packages/Devlooped.Extensions.AI)
7+
[![Downloads](https://img.shields.io/nuget/dt/Devlooped.Extensions.AI.svg?color=green)](https://www.nuget.org/packages/Devlooped.Extensions.AI)
68

7-
Extensions for Microsoft.Agents.AI and Microsoft.Extensions.AI.
9+
Extensions for Microsoft.Extensions.AI.
810

911
<!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
1012
## Open Source Maintenance Fee
@@ -19,270 +21,6 @@ OSMF tier. A single fee covers all of [Devlooped packages](https://www.nuget.org
1921

2022
<!-- https://github.com/devlooped/.github/raw/main/osmf.md -->
2123

22-
# Devlooped.Agents.AI
23-
24-
[![Version](https://img.shields.io/nuget/vpre/Devlooped.Agents.AI.svg?color=royalblue)](https://www.nuget.org/packages/Devlooped.Agents.AI)
25-
[![Downloads](https://img.shields.io/nuget/dt/Devlooped.Agents.AI.svg?color=green)](https://www.nuget.org/packages/Devlooped.Agents.AI)
26-
27-
<!-- #agents-title -->
28-
Extensions for Microsoft.Agents.AI, such as configuration-driven auto-reloading agents.
29-
<!-- #agents-title -->
30-
31-
<!-- #agents -->
32-
## Overview
33-
34-
Microsoft.Agents.AI (aka [Agent Framework](https://learn.microsoft.com/en-us/agent-framework/overview/agent-framework-overview)
35-
is a comprehensive API for building AI agents. Its programatic model (which follows closely
36-
the [Microsoft.Extensions.AI](https://learn.microsoft.com/en-us/dotnet/ai/microsoft-extensions-ai)
37-
approach) provides maximum flexibility with little prescriptive structure.
38-
39-
This package provides additional extensions to make developing agents easier and more
40-
declarative.
41-
42-
## Configurable Agents
43-
44-
Tweaking agent options such as description, instructions, chat client to use and its
45-
options, etc. is very common during development/testing. This package provides the ability to
46-
drive those settings from configuration (with auto-reload support). This makes it far easier
47-
to experiment with various combinations of agent instructions, chat client providers and
48-
options, and model parameters without changing code, recompiling or even restarting the application:
49-
50-
> [!NOTE]
51-
> This example shows integration with configurable chat clients feature from the
52-
> Devlooped.Extensions.AI package, but any `IChatClient` registered in the DI container
53-
> with a matching key can be used.
54-
55-
```json
56-
{
57-
"AI": {
58-
"Agents": {
59-
"MyAgent": {
60-
"Description": "An AI agent that helps with customer support.",
61-
"Instructions": "You are a helpful assistant for customer support.",
62-
"Client": "Grok",
63-
"Options": {
64-
"ModelId": "grok-4",
65-
"Temperature": 0.5,
66-
}
67-
}
68-
},
69-
"Clients": {
70-
"Grok": {
71-
"Endpoint": "https://api.grok.ai/v1",
72-
"ModelId": "grok-4-fast-non-reasoning",
73-
"ApiKey": "xai-asdf"
74-
}
75-
}
76-
}
77-
}
78-
````
79-
80-
```csharp
81-
var host = new HostApplicationBuilder(args);
82-
host.Configuration.AddJsonFile("appsettings.json, optional: false, reloadOnChange: true);
83-
84-
// 👇 implicitly calls AddChatClients
85-
host.AddAIAgents();
86-
87-
var app = host.Build();
88-
var agent = app.Services.GetRequiredKeyedService<AIAgent>("MyAgent");
89-
```
90-
91-
Agents are also properly registered in the corresponding Microsoft Agent Framework
92-
[AgentCatalog](https://learn.microsoft.com/en-us/dotnet/api/microsoft.agents.ai.hosting.agentcatalog):
93-
94-
```csharp
95-
var catalog = app.Services.GetRequiredService<AgentCatalog>();
96-
await foreach (AIAgent agent in catalog.GetAgentsAsync())
97-
{
98-
var metadata = agent.GetService<AIAgentMetadata>();
99-
Console.WriteLine($"Agent: {agent.Name} by {metadata.ProviderName}");
100-
}
101-
```
102-
103-
You can of course use any config format supported by .NET configuration, such as
104-
TOML which is arguably more human-friendly for hand-editing:
105-
106-
```toml
107-
[ai.clients.openai]
108-
modelid = "gpt-4.1"
109-
110-
[ai.clients.grok]
111-
endpoint = "https://api.x.ai/v1"
112-
modelid = "grok-4-fast-non-reasoning"
113-
114-
[ai.agents.orders]
115-
description = "Manage orders using catalogs for food or any other item."
116-
instructions = """
117-
You are an AI agent responsible for processing orders for food or other items.
118-
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.
119-
"""
120-
121-
# ai.clients.openai, can omit the ai.clients prefix
122-
client = "openai"
123-
124-
[ai.agents.orders.options]
125-
modelid = "gpt-4o-mini"
126-
```
127-
128-
This can be used by leveraging [Tomlyn.Extensions.Configuration](https://www.nuget.org/packages/Tomlyn.Extensions.Configuration).
129-
130-
> [!NOTE]
131-
> This package will automatically dedent and trim start and end newlines from
132-
> multi-line instructions and descriptions when applying the configuration,
133-
> avoiding unnecessary tokens being used for indentation while allowing flexible
134-
> formatting in the config file.
135-
136-
You can also leverage the format pioneered by [VS Code Chat Modes](https://code.visualstudio.com/docs/copilot/customization/custom-chat-modes),
137-
(por "custom agents") by using markdown format plus YAML front-matter for better readability:
138-
139-
```yaml
140-
---
141-
id: ai.agents.notes
142-
description: Provides free-form memory
143-
client: grok
144-
model: grok-4-fast
145-
---
146-
You organize and keep notes for the user.
147-
# Some header
148-
More content
149-
```
150-
151-
Visual Studio Code will ignore the additional attributes used by this project. In particular, the `model`
152-
property is a shorthand for setting the `options.modelid`, but in our implementation, the latter takes
153-
precedence over the former, which allows you to rely on `model` to drive the VSCode testing, and the
154-
longer form for run-time with the Agents Framework:
155-
156-
```yaml
157-
---
158-
id: ai.agents.notes
159-
description: Provides free-form memory
160-
model: Grok Code Fast 1 (copilot)
161-
client: grok
162-
options:
163-
modelid: grok-code-fast-1
164-
---
165-
// Instructions
166-
```
167-
168-
![agent model picker](assets/img/agent-model.png)
169-
170-
Use the provided `AddAgentMarkdown` extension method to load instructions from files as follows:
171-
172-
```csharp
173-
var host = new HostApplicationBuilder(args);
174-
host.Configuration.AddAgentMarkdown("notes.agent.md", optional: false, reloadOnChange: true);
175-
```
176-
177-
The `id` field in the front-matter is required and specifies the configuration section name, and
178-
all other fields are added as if they were specified under it in the configuration.
179-
180-
### Extensible AI Contexts
181-
182-
The Microsoft [agent framework](https://learn.microsoft.com/en-us/agent-framework/overview/agent-framework-overview) allows extending
183-
agents with dynamic context via [AIContextProvider](https://learn.microsoft.com/en-us/dotnet/api/microsoft.agents.ai.aicontextprovider)
184-
and `AIContext`. This package supports dynamic extension of a configured agent in the following ways (in order of priority):
185-
186-
1. A keyed service `AIContextProviderFactory` with the same name as the agent will be set up just as if you had
187-
set it manually as the [ChatClientAgentOptions.AIContextProviderFactory](https://learn.microsoft.com/en-us/dotnet/api/microsoft.agents.ai.chatclientagentoptions.aicontextproviderfactory)
188-
in code.
189-
2. Aggregate of AI contexts from:
190-
a. Keyed service `AIContextProvider` with the same name as the agent.
191-
b. Keyed service `AIContext` with the same name as the agent.
192-
c. Other services pulled in via `use` setting for an agent registered as either `AIContextProvider` or `AIContext`
193-
with a matching key.
194-
195-
The first option assumes you want full control of the context, so it does not allow futher composition.
196-
The second alternative allows more declarative scenarios involving reusable and cross-cutting
197-
context definitions.
198-
199-
For example, let's say you want to provide consistent tone for all your agents. It would be tedious, repetitive and harder
200-
to maintain if you had to set that in each agent's instructions. Instead, you can define a reusable context named `tone` such as:
201-
202-
```toml
203-
[ai.context.tone]
204-
instructions = """\
205-
Default to using spanish language, using argentinean "voseo" in your responses \
206-
(unless the user explicitly talks in a different language). \
207-
This means using "vos" instead of "tú" and conjugating verbs accordingly. \
208-
Don't use the expression "pa'" instead of "para". Don't mention the word "voseo".
209-
"""
210-
```
211-
212-
Then, you can reference that context in any agent using the `use` setting:
213-
```toml
214-
[ai.agents.support]
215-
description = "An AI agent that helps with customer support."
216-
instructions = "..."
217-
client = "grok"
218-
use = ["tone"]
219-
220-
[ai.agents.sales]
221-
description = "An AI agent that helps with sales inquiries."
222-
instructions = "..."
223-
client = "openai"
224-
use = ["tone"]
225-
```
226-
227-
Configured contexts can provide all three components of an `AIContext`: instructions, messages and tools, such as:
228-
229-
```toml
230-
[ai.context.timezone]
231-
instructions = "Always assume the user's timezone is America/Argentina/Buenos_Aires unless specified otherwise."
232-
messages = [
233-
{ system = "You are aware of the current date and time in America/Argentina/Buenos_Aires." }
234-
]
235-
tools = ["get_date"]
236-
```
237-
238-
If multiple contexts are specified in `use`, they are applied in order, concatenating their instructions, messages and tools.
239-
240-
In addition to configured sections, the `use` property can also reference exported contexts as either `AIContext`
241-
(for static context) or `AIContextProvider` (for dynamic context) registered in DI with a matching name.
242-
243-
244-
### Extensible Tools
245-
246-
The `tools` section allows specifying tool names registered in the DI container, such as:
247-
248-
```csharp
249-
services.AddKeyedSingleton("get_date", AIFunctionFactory.Create(() => DateTimeOffset.Now, "get_date"));
250-
```
251-
252-
This tool will be automatically wired into any agent that uses the `timezone` context above.
253-
254-
Agents themselves can also add tools from DI into an agent's context without having to define an entire
255-
section just for that, by specifying the tool name directly in the `tools` array:
256-
257-
```toml
258-
[ai.agents.support]
259-
description = "An AI agent that helps with customer support."
260-
instructions = "..."
261-
client = "grok"
262-
use = ["tone"]
263-
tools = ["get_date"]
264-
```
265-
266-
This enables a flexible and convenient mix of static and dynamic context for agents, all driven
267-
from configuration.
268-
269-
In addition to registering your own tools in DI, you can also use leverage the MCP C# SDK and reuse
270-
the same tool declarations:
271-
272-
```csharp
273-
builder.Services.AddMcpServer().WithTools<NotesTools>();
274-
275-
// 👇 Reuse same tool definitions in agents
276-
builder.AddAIAgents().WithTools<NotesTools>();
277-
```
278-
279-
<!-- #agents -->
280-
281-
# Devlooped.Extensions.AI
282-
283-
[![Version](https://img.shields.io/nuget/vpre/Devlooped.Extensions.AI.svg?color=royalblue)](https://www.nuget.org/packages/Devlooped.Extensions.AI)
284-
[![Downloads](https://img.shields.io/nuget/dt/Devlooped.Extensions.AI.svg?color=green)](https://www.nuget.org/packages/Devlooped.Extensions.AI)
285-
28624
<!-- #extensions-title -->
28725
Extensions for Microsoft.Extensions.AI
28826
<!-- #extensions-title -->

sample/Aspire/AppHost.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

sample/Aspire/Aspire.csproj

Lines changed: 0 additions & 19 deletions
This file was deleted.

sample/Aspire/Properties/launchSettings.json

Lines changed: 0 additions & 29 deletions
This file was deleted.

sample/Aspire/appsettings.Development.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

sample/Aspire/appsettings.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)