Skip to content

Commit 1ccc842

Browse files
committed
Mark Microsoft.Extensions.AI and Microsoft.Extensions.AI.Abstractions as stable (#6446)
* Bump ICSharpCode.Decompiler for record struct support in ApiChief tool Needed the fix for icsharpcode/ILSpy#3159 to fix "record struct" formatting (it was "recordstruct" before the fix). * Generate ApiChief baselines for MEAI libraries Ran .\scripts\MakeApiBaselines.ps1 and discarded other libraries' updates. * Hand-edit MEAI ApiChief baseline to fix params ReadOnlySpan Params collections are not yet supported in ICSharpCode.Decompiler: icsharpcode/ILSpy#829 The result is an emitted 'scoped' keyword instead of 'params'. This was edited by hand in the baseline MEAI file. * Mark Microsoft.Extensions.AI and Microsoft.Extensions.AI.Abstractions as stable * Update MEAI and MEAI.Abstractions NuGet package documentation * Update NuGet package documentation for MEAI implementation packages * Update MEAI.Templates package references, including SemanticKernel for a coherent build. * Lower OllamaSharp for integration tests to use version available on feed * Empty the ApiChief baselines for Ollama, AzureAIInference, and OpenAI adapters since they are not shipping stable * Apply code review feedback to the MEAI package READMEs * Update MEAI.Templates test snapshots for version bumps * Apply documentation review feedback to the MEAI package READMEs * Add comments to the MEAI API baseline file for the hand-editing required * Restore documentation blurb into Microsoft.Extensions.AI.AzureAIInference per other feedback
1 parent e9f87c5 commit 1ccc842

16 files changed

Lines changed: 3188 additions & 894 deletions

File tree

eng/Versions.props

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,19 @@
160160
<AspireAzureAIOpenAIVersion>9.2.1-preview.1.25222.1</AspireAzureAIOpenAIVersion>
161161
<AzureAIProjectsVersion>1.0.0-beta.6</AzureAIProjectsVersion>
162162
<AzureAIOpenAIVersion>2.2.0-beta.4</AzureAIOpenAIVersion>
163-
<AzureIdentityVersion>1.13.2</AzureIdentityVersion>
163+
<AzureIdentityVersion>1.14.0</AzureIdentityVersion>
164164
<AzureSearchDocumentsVersion>11.6.0</AzureSearchDocumentsVersion>
165165
<CommunityToolkitAspireHostingOllamaVersion>9.4.1-beta.277</CommunityToolkitAspireHostingOllamaVersion>
166166
<CommunityToolkitAspireHostingSqliteVersion>9.4.1-beta.277</CommunityToolkitAspireHostingSqliteVersion>
167167
<CommunityToolkitAspireMicrosoftEntityFrameworkCoreSqliteVersion>9.4.1-beta.277</CommunityToolkitAspireMicrosoftEntityFrameworkCoreSqliteVersion>
168168
<CommunityToolkitAspireOllamaSharpVersion>9.4.1-beta.277</CommunityToolkitAspireOllamaSharpVersion>
169169
<MicrosoftExtensionsServiceDiscoveryVersion>9.2.0</MicrosoftExtensionsServiceDiscoveryVersion>
170-
<MicrosoftSemanticKernelConnectorsAzureAISearchVersion>1.49.0-preview</MicrosoftSemanticKernelConnectorsAzureAISearchVersion>
171-
<MicrosoftSemanticKernelConnectorsQdrantVersion>1.49.0-preview</MicrosoftSemanticKernelConnectorsQdrantVersion>
172-
<MicrosoftSemanticKernelCoreVersion>1.49.0</MicrosoftSemanticKernelCoreVersion>
173-
<OllamaSharpVersion>5.1.13</OllamaSharpVersion>
170+
<MicrosoftSemanticKernelConnectorsAzureAISearchVersion>1.50.0-preview</MicrosoftSemanticKernelConnectorsAzureAISearchVersion>
171+
<MicrosoftSemanticKernelConnectorsQdrantVersion>1.50.0-preview</MicrosoftSemanticKernelConnectorsQdrantVersion>
172+
<MicrosoftSemanticKernelCoreVersion>1.50.0</MicrosoftSemanticKernelCoreVersion>
173+
<OllamaSharpVersion>5.1.16</OllamaSharpVersion>
174174
<OpenTelemetryVersion>1.9.0</OpenTelemetryVersion>
175-
<PdfPigVersion>0.1.9</PdfPigVersion>
175+
<PdfPigVersion>0.1.10</PdfPigVersion>
176176
<SystemLinqAsyncVersion>6.0.1</SystemLinqAsyncVersion>
177177
<!--
178178
xUnit version is configured by the Arcade SDK.

eng/packages/General.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<PackageVersion Include="Azure.Identity" Version="1.13.2" />
66
<PackageVersion Include="Azure.Storage.Files.DataLake" Version="12.21.0" />
77
<PackageVersion Include="Azure.AI.Inference" Version="1.0.0-beta.4" />
8-
<PackageVersion Include="ICSharpCode.Decompiler" Version="8.2.0.7535" />
8+
<PackageVersion Include="ICSharpCode.Decompiler" Version="9.1.0.7988" />
99
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
1010
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="$(MicrosoftCodeAnalysisAnalyzersVersion)" />
1111
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="$(MicrosoftCodeAnalysisVersion)" />

eng/packages/TestOnly.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<PackageVersion Include="Moq.AutoMock" Version="3.1.0" />
1919
<PackageVersion Include="Moq" Version="4.18.4" />
2020
<PackageVersion Include="OpenTelemetry.Exporter.InMemory" Version="1.9.0" />
21-
<PackageVersion Include="PdfPig" Version="0.1.10-alpha-20250203-fdb88" />
21+
<PackageVersion Include="PdfPig" Version="0.1.10" />
2222
<PackageVersion Include="Polly.Testing" Version="8.4.2" />
2323
<PackageVersion Include="StrongNamer" Version="0.2.5" />
2424
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerVersion)" />

src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
<PropertyGroup>
44
<RootNamespace>Microsoft.Extensions.AI</RootNamespace>
5-
<Description>Abstractions for generative AI.</Description>
5+
<Description>Abstractions representing generative AI components.</Description>
66
<Workstream>AI</Workstream>
77
</PropertyGroup>
88

99
<PropertyGroup>
10-
<Stage>preview</Stage>
10+
<Stage>normal</Stage>
1111
<EnablePackageValidation>false</EnablePackageValidation>
1212
<MinCodeCoverage>82</MinCodeCoverage>
13-
<MinMutationScore>0</MinMutationScore>
13+
<MinMutationScore>85</MinMutationScore>
1414
</PropertyGroup>
1515

1616
<PropertyGroup>

src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.json

Lines changed: 2285 additions & 0 deletions
Large diffs are not rendered by default.

src/Libraries/Microsoft.Extensions.AI.Abstractions/README.md

Lines changed: 16 additions & 594 deletions
Large diffs are not rendered by default.

src/Libraries/Microsoft.Extensions.AI.AzureAIInference/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ app.MapPost("/chat", async (IChatClient client, string message) =>
281281
app.Run();
282282
```
283283

284+
## Documentation
285+
286+
Refer to the [Microsoft.Extensions.AI libraries documentation](https://learn.microsoft.com/dotnet/ai/microsoft-extensions-ai) for more information and API usage examples.
287+
284288
## Feedback & Contributing
285289

286290
We welcome feedback and contributions in [our GitHub repo](https://github.com/dotnet/extensions).

src/Libraries/Microsoft.Extensions.AI.Ollama/Microsoft.Extensions.AI.Ollama.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<RootNamespace>Microsoft.Extensions.AI</RootNamespace>
5-
<Description>Implementation of generative AI abstractions for Ollama.</Description>
5+
<Description>Implementation of generative AI abstractions for Ollama. This package is deprecated, and the OllamaSharp package is recommended.</Description>
66
<Workstream>AI</Workstream>
77
</PropertyGroup>
88

Lines changed: 6 additions & 275 deletions
Original file line numberDiff line numberDiff line change
@@ -1,280 +1,11 @@
11
# Microsoft.Extensions.AI.Ollama
22

3-
Provides an implementation of the `IChatClient` interface for Ollama.
3+
This package is deprecated and the [OllamaSharp](https://www.nuget.org/packages/ollamasharp) package is recommended. `OllamaSharp` provides .NET bindings for the [Ollama API](https://github.com/jmorganca/ollama/blob/main/docs/api.md), simplifying interactions with Ollama both locally and remotely.
44

5-
## Install the package
5+
No further updates, features, or fixes are planned for the `Microsoft.Extensions.AI.Ollama` package.
66

7-
From the command-line:
7+
## Related packages
88

9-
```console
10-
dotnet add package Microsoft.Extensions.AI.Ollama
11-
```
12-
13-
Or directly in the C# project file:
14-
15-
```xml
16-
<ItemGroup>
17-
<PackageReference Include="Microsoft.Extensions.AI.Ollama" Version="[CURRENTVERSION]" />
18-
</ItemGroup>
19-
```
20-
21-
## Usage Examples
22-
23-
### Chat
24-
25-
```csharp
26-
using Microsoft.Extensions.AI;
27-
28-
IChatClient client = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
29-
30-
Console.WriteLine(await client.GetResponseAsync("What is AI?"));
31-
```
32-
33-
### Chat + Conversation History
34-
35-
```csharp
36-
using Microsoft.Extensions.AI;
37-
38-
IChatClient client = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
39-
40-
Console.WriteLine(await client.GetResponseAsync(
41-
[
42-
new ChatMessage(ChatRole.System, "You are a helpful AI assistant"),
43-
new ChatMessage(ChatRole.User, "What is AI?"),
44-
]));
45-
```
46-
47-
### Chat Streaming
48-
49-
```csharp
50-
using Microsoft.Extensions.AI;
51-
52-
IChatClient client = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
53-
54-
await foreach (var update in client.GetStreamingResponseAsync("What is AI?"))
55-
{
56-
Console.Write(update);
57-
}
58-
```
59-
60-
### Tool Calling
61-
62-
Known limitations:
63-
64-
- Only a subset of models provided by Ollama support tool calling.
65-
- Tool calling is currently not supported with streaming requests.
66-
67-
```csharp
68-
using System.ComponentModel;
69-
using Microsoft.Extensions.AI;
70-
71-
IChatClient ollamaClient = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
72-
73-
IChatClient client = new ChatClientBuilder(ollamaClient)
74-
.UseFunctionInvocation()
75-
.Build();
76-
77-
ChatOptions chatOptions = new()
78-
{
79-
Tools = [AIFunctionFactory.Create(GetWeather)]
80-
};
81-
82-
Console.WriteLine(await client.GetResponseAsync("Do I need an umbrella?", chatOptions));
83-
84-
[Description("Gets the weather")]
85-
static string GetWeather() => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
86-
```
87-
88-
### Caching
89-
90-
```csharp
91-
using Microsoft.Extensions.AI;
92-
using Microsoft.Extensions.Caching.Distributed;
93-
using Microsoft.Extensions.Caching.Memory;
94-
using Microsoft.Extensions.Options;
95-
96-
IDistributedCache cache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
97-
98-
IChatClient ollamaClient = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
99-
100-
IChatClient client = new ChatClientBuilder(ollamaClient)
101-
.UseDistributedCache(cache)
102-
.Build();
103-
104-
for (int i = 0; i < 3; i++)
105-
{
106-
await foreach (var message in client.GetStreamingResponseAsync("In less than 100 words, what is AI?"))
107-
{
108-
Console.Write(message);
109-
}
110-
111-
Console.WriteLine();
112-
Console.WriteLine();
113-
}
114-
```
115-
116-
### Telemetry
117-
118-
```csharp
119-
using Microsoft.Extensions.AI;
120-
using OpenTelemetry.Trace;
121-
122-
// Configure OpenTelemetry exporter
123-
var sourceName = Guid.NewGuid().ToString();
124-
var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
125-
.AddSource(sourceName)
126-
.AddConsoleExporter()
127-
.Build();
128-
129-
IChatClient ollamaClient = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
130-
131-
IChatClient client = new ChatClientBuilder(ollamaClient)
132-
.UseOpenTelemetry(sourceName: sourceName, configure: c => c.EnableSensitiveData = true)
133-
.Build();
134-
135-
Console.WriteLine(await client.GetResponseAsync("What is AI?"));
136-
```
137-
138-
### Telemetry, Caching, and Tool Calling
139-
140-
```csharp
141-
using System.ComponentModel;
142-
using Microsoft.Extensions.AI;
143-
using Microsoft.Extensions.Caching.Distributed;
144-
using Microsoft.Extensions.Caching.Memory;
145-
using Microsoft.Extensions.Options;
146-
using OpenTelemetry.Trace;
147-
148-
// Configure telemetry
149-
var sourceName = Guid.NewGuid().ToString();
150-
var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
151-
.AddSource(sourceName)
152-
.AddConsoleExporter()
153-
.Build();
154-
155-
// Configure caching
156-
IDistributedCache cache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
157-
158-
// Configure tool calling
159-
var chatOptions = new ChatOptions
160-
{
161-
Tools = [AIFunctionFactory.Create(GetPersonAge)]
162-
};
163-
164-
IChatClient ollamaClient = new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1");
165-
166-
IChatClient client = new ChatClientBuilder(ollamaClient)
167-
.UseDistributedCache(cache)
168-
.UseFunctionInvocation()
169-
.UseOpenTelemetry(sourceName: sourceName, configure: c => c.EnableSensitiveData = true)
170-
.Build();
171-
172-
for (int i = 0; i < 3; i++)
173-
{
174-
Console.WriteLine(await client.GetResponseAsync("How much older is Alice than Bob?", chatOptions));
175-
}
176-
177-
[Description("Gets the age of a person specified by name.")]
178-
static int GetPersonAge(string personName) =>
179-
personName switch
180-
{
181-
"Alice" => 42,
182-
"Bob" => 35,
183-
_ => 26,
184-
};
185-
```
186-
187-
### Text embedding generation
188-
189-
```csharp
190-
using Microsoft.Extensions.AI;
191-
192-
IEmbeddingGenerator<string, Embedding<float>> generator =
193-
new OllamaEmbeddingGenerator(new Uri("http://localhost:11434/"), "all-minilm");
194-
195-
var embeddings = await generator.GenerateAsync("What is AI?");
196-
197-
Console.WriteLine(string.Join(", ", embeddings[0].Vector.ToArray()));
198-
```
199-
200-
### Text embedding generation with caching
201-
202-
```csharp
203-
using Microsoft.Extensions.AI;
204-
using Microsoft.Extensions.Caching.Distributed;
205-
using Microsoft.Extensions.Caching.Memory;
206-
using Microsoft.Extensions.Options;
207-
208-
IDistributedCache cache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
209-
210-
IEmbeddingGenerator<string, Embedding<float>> ollamaGenerator =
211-
new OllamaEmbeddingGenerator(new Uri("http://localhost:11434/"), "all-minilm");
212-
213-
IEmbeddingGenerator<string, Embedding<float>> generator = new EmbeddingGeneratorBuilder<string, Embedding<float>>(ollamaGenerator)
214-
.UseDistributedCache(cache)
215-
.Build();
216-
217-
foreach (var prompt in new[] { "What is AI?", "What is .NET?", "What is AI?" })
218-
{
219-
var embeddings = await generator.GenerateAsync(prompt);
220-
221-
Console.WriteLine(string.Join(", ", embeddings[0].Vector.ToArray()));
222-
}
223-
```
224-
225-
### Dependency Injection
226-
227-
```csharp
228-
using Microsoft.Extensions.AI;
229-
using Microsoft.Extensions.DependencyInjection;
230-
using Microsoft.Extensions.Hosting;
231-
using Microsoft.Extensions.Logging;
232-
233-
// App Setup
234-
var builder = Host.CreateApplicationBuilder();
235-
builder.Services.AddDistributedMemoryCache();
236-
builder.Services.AddLogging(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace));
237-
238-
builder.Services.AddChatClient(new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1"))
239-
.UseDistributedCache()
240-
.UseLogging();
241-
242-
var app = builder.Build();
243-
244-
// Elsewhere in the app
245-
var chatClient = app.Services.GetRequiredService<IChatClient>();
246-
Console.WriteLine(await chatClient.GetResponseAsync("What is AI?"));
247-
```
248-
249-
### Minimal Web API
250-
251-
```csharp
252-
using Microsoft.Extensions.AI;
253-
254-
var builder = WebApplication.CreateBuilder(args);
255-
256-
builder.Services.AddChatClient(
257-
new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.1"));
258-
259-
builder.Services.AddEmbeddingGenerator(new OllamaEmbeddingGenerator(endpoint, "all-minilm"));
260-
261-
var app = builder.Build();
262-
263-
app.MapPost("/chat", async (IChatClient client, string message) =>
264-
{
265-
var response = await client.GetResponseAsync(message, cancellationToken: default);
266-
return response.Message;
267-
});
268-
269-
app.MapPost("/embedding", async (IEmbeddingGenerator<string,Embedding<float>> client, string message) =>
270-
{
271-
var response = await client.GenerateAsync(message);
272-
return response[0].Vector;
273-
});
274-
275-
app.Run();
276-
```
277-
278-
## Feedback & Contributing
279-
280-
We welcome feedback and contributions in [our GitHub repo](https://github.com/dotnet/extensions).
9+
* [OllamaSharp](https://www.nuget.org/packages/OllamaSharp)
10+
* [Microsoft.Extensions.AI](https://www.nuget.org/packages/Microsoft.Extensions.AI)
11+
* [Microsoft.Extensions.AI.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.AI.Abstractions)

src/Libraries/Microsoft.Extensions.AI.OpenAI/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ app.MapPost("/embedding", async (IEmbeddingGenerator<string, Embedding<float>> c
291291
app.Run();
292292
```
293293

294+
## Documentation
295+
296+
Learn how to create a conversational .NET console chat app using an OpenAI or Azure OpenAI model with the [Quickstart - Build an AI chat app with .NET](https://learn.microsoft.com/dotnet/ai/quickstarts/build-chat-app?pivots=openai) documentation.
297+
294298
## Feedback & Contributing
295299

296300
We welcome feedback and contributions in [our GitHub repo](https://github.com/dotnet/extensions).

0 commit comments

Comments
 (0)