Skip to content

Commit ea00f4f

Browse files
rojistephentoub
andauthored
.Net: Sync to MEAI 9.3.0-preview.1.25114.11 (#10989)
A good review would be much appreciated, including considering the higher-level implications of the MEAI-side change for SK (I know very little about SK outside of MEVD!). See specific comments below. --------- Co-authored-by: Stephen Toub <stoub@microsoft.com>
1 parent a01a31b commit ea00f4f

File tree

15 files changed

+114
-106
lines changed

15 files changed

+114
-106
lines changed

dotnet/Directory.Packages.props

+12-11
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@
5151
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0" />
5252
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="8.0.1" />
5353
<PackageVersion Include="Microsoft.Identity.Client" Version="4.67.2" />
54-
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.20.1" />
54+
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.21.0" />
5555
<PackageVersion Include="MSTest.TestFramework" Version="3.8.0" />
5656
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
5757
<PackageVersion Include="Npgsql" Version="8.0.6" />
58-
<PackageVersion Include="OllamaSharp" Version="5.0.7" />
58+
<PackageVersion Include="OllamaSharp" Version="5.1.7" />
5959
<PackageVersion Include="OpenAI" Version="[2.2.0-beta.1]" />
6060
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
6161
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
@@ -74,17 +74,17 @@
7474
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
7575
<PackageVersion Include="System.Memory.Data" Version="8.0.1" />
7676
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
77-
<PackageVersion Include="System.Numerics.Tensors" Version="8.0.0" />
77+
<PackageVersion Include="System.Numerics.Tensors" Version="9.0.0" />
7878
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
7979
<!-- Tokenizers -->
8080
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="1.0.1" />
8181
<PackageVersion Include="Microsoft.DeepDev.TokenizerLib" Version="1.3.3" />
8282
<PackageVersion Include="SharpToken" Version="2.0.3" />
8383
<!-- Microsoft.Extensions.* -->
84-
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.3.0-preview.1.25114.11" />
85-
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="9.3.0-preview.1.25114.11" />
86-
<PackageVersion Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.3.0-preview.1.25114.11" />
87-
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="9.3.0-preview.1.25114.11" />
84+
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.3.0-preview.1.25161.3" />
85+
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="9.3.0-preview.1.25161.3" />
86+
<PackageVersion Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.3.0-preview.1.25161.3" />
87+
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="9.3.0-preview.1.25161.3" />
8888
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
8989
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
9090
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
@@ -150,7 +150,8 @@
150150
<!-- Symbols -->
151151
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
152152
<!-- Toolset -->
153-
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0-preview.24415.1" />
153+
<PackageVersion Include="Microsoft.Net.Compilers.Toolset" Version="4.12.0" />
154+
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
154155
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers">
155156
<PrivateAssets>all</PrivateAssets>
156157
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -186,9 +187,9 @@
186187
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
187188
</PackageReference>
188189
<!-- OnnxRuntimeGenAI -->
189-
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.7.0-rc1" />
190-
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.Cuda" Version="0.7.0-rc1" />
191-
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.DirectML" Version="0.7.0-rc1" />
190+
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.7.0-rc2" />
191+
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.Cuda" Version="0.7.0-rc2" />
192+
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.DirectML" Version="0.7.0-rc2" />
192193
<!-- SpectreConsole-->
193194
<PackageVersion Include="Spectre.Console" Version="0.49.1" />
194195
<PackageVersion Include="Spectre.Console.Cli" Version="0.49.1" />

dotnet/samples/Concepts/ChatCompletion/HybridCompletion_Fallback.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@ public FallbackChatClient(IList<IChatClient> chatClients)
166166
public ChatClientMetadata Metadata => new();
167167

168168
/// <inheritdoc/>
169-
public async Task<Microsoft.Extensions.AI.ChatResponse> GetResponseAsync(IList<ChatMessage> chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
169+
public async Task<Microsoft.Extensions.AI.ChatResponse> GetResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
170170
{
171171
for (int i = 0; i < this._chatClients.Count; i++)
172172
{
173173
var chatClient = this._chatClients.ElementAt(i);
174174

175175
try
176176
{
177-
return await chatClient.GetResponseAsync(chatMessages, options, cancellationToken).ConfigureAwait(false);
177+
return await chatClient.GetResponseAsync(messages, options, cancellationToken).ConfigureAwait(false);
178178
}
179179
catch (Exception ex)
180180
{
@@ -192,13 +192,13 @@ public FallbackChatClient(IList<IChatClient> chatClients)
192192
}
193193

194194
/// <inheritdoc/>
195-
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IList<ChatMessage> chatMessages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
195+
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
196196
{
197197
for (int i = 0; i < this._chatClients.Count; i++)
198198
{
199199
var chatClient = this._chatClients.ElementAt(i);
200200

201-
IAsyncEnumerable<ChatResponseUpdate> completionStream = chatClient.GetStreamingResponseAsync(chatMessages, options, cancellationToken);
201+
IAsyncEnumerable<ChatResponseUpdate> completionStream = chatClient.GetStreamingResponseAsync(messages, options, cancellationToken);
202202

203203
ConfiguredCancelableAsyncEnumerable<ChatResponseUpdate>.Enumerator enumerator = completionStream.ConfigureAwait(false).GetAsyncEnumerator();
204204

dotnet/samples/Concepts/Concepts.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</PropertyGroup>
1515

1616
<ItemGroup>
17+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
1718
<PackageReference Include="Docker.DotNet" />
1819
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
1920
<PackageReference Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" />

dotnet/samples/Concepts/Plugins/CreatePluginFromOpenApiSpec_Github.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public async Task RunOpenAIPluginWithMetadataAsync()
9797
}
9898
}
9999

100-
private static void WriteStringToStream(Stream stream, string input)
100+
private static void WriteStringToStream(MemoryStream stream, string input)
101101
{
102102
using var writer = new StreamWriter(stream, leaveOpen: true);
103103
writer.Write(input);

dotnet/samples/Demos/AIModelRouter/AIModelRouter.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
1314
<PackageReference Include="Azure.Identity" />
1415
<PackageReference Include="Microsoft.Extensions.Configuration" />
1516
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />

dotnet/samples/Demos/CopilotAgentPlugins/CopilotAgentPluginsDemoSample/CopilotAgentPluginsDemoSample.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
</ItemGroup>
4242

4343
<ItemGroup>
44+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
4445
<PackageReference Include="Microsoft.Extensions.Configuration"/>
4546
<PackageReference Include="Microsoft.Extensions.Configuration.Json"/>
4647
<PackageReference Include="Microsoft.Extensions.Logging"/>

dotnet/samples/Demos/OllamaFunctionCalling/OllamaFunctionCalling.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
1011
<ProjectReference Include="..\..\..\src\Connectors\Connectors.Ollama\Connectors.Ollama.csproj" />
1112
<ProjectReference Include="..\..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
1213
</ItemGroup>

dotnet/src/Connectors/Connectors.Ollama.UnitTests/Connectors.Ollama.UnitTests.csproj

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
</PropertyGroup>
1515

1616
<ItemGroup>
17+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
1718
<PackageReference Include="Microsoft.NET.Test.Sdk" />
1819
<PackageReference Include="Moq" />
19-
<PackageReference Include="OllamaSharp" />
20+
<PackageReference Include="OllamaSharp">
21+
<ExcludeAssets>analyzers</ExcludeAssets>
22+
</PackageReference>
2023
<PackageReference Include="xunit" />
2124
<PackageReference Include="xunit.runner.visualstudio">
2225
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

dotnet/src/Connectors/Connectors.Ollama.UnitTests/Services/OllamaChatCompletionTests.cs

+2-12
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ public async Task GetStreamingChatMessageContentsExecutionSettingsMustBeSentAsyn
205205
""";
206206

207207
var executionSettings = JsonSerializer.Deserialize<PromptExecutionSettings>(jsonSettings);
208+
#pragma warning disable CS0612 // OllamaPromptExecutionSettings is obsolete
208209
var ollamaExecutionSettings = OllamaPromptExecutionSettings.FromExecutionSettings(executionSettings);
210+
#pragma warning restore CS0612
209211

210212
// Act
211213
await sut.GetStreamingChatMessageContentsAsync(chat, ollamaExecutionSettings).GetAsyncEnumerator().MoveNextAsync();
@@ -302,12 +304,6 @@ public async Task GetChatMessageContentsShouldAdvertiseToolAsync()
302304
Assert.NotNull(requestPayload.Tools);
303305
Assert.NotEmpty(requestPayload.Tools);
304306
Assert.Equal(1, requestPayload.Tools?.Count());
305-
var firstTool = requestPayload.Tools?.First()!;
306-
Assert.Equal("TestPlugin_TestFunction", firstTool.Function!.Name);
307-
Assert.Single(firstTool.Function!.Parameters!.Properties!);
308-
Assert.Equal("testInput", firstTool.Function!.Parameters!.Properties!.First().Key);
309-
Assert.Equal("string", firstTool.Function!.Parameters!.Properties!.First().Value.Type);
310-
Assert.Equal("testInput", firstTool.Function!.Parameters!.Required!.First());
311307

312308
Assert.NotNull(message.ModelId);
313309
Assert.Equal(targetModel, message.ModelId);
@@ -378,12 +374,6 @@ public async Task GetChatMessageContentsShouldAdvertiseAndTriggerToolAsync()
378374
Assert.NotNull(requestPayload.Tools);
379375
Assert.NotEmpty(requestPayload.Tools);
380376
Assert.Equal(1, requestPayload.Tools?.Count());
381-
var firstTool = requestPayload.Tools?.First()!;
382-
Assert.Equal("TestPlugin_TestFunction", firstTool.Function!.Name);
383-
Assert.Single(firstTool.Function!.Parameters!.Properties!);
384-
Assert.Equal("testInput", firstTool.Function!.Parameters!.Properties!.First().Key);
385-
Assert.Equal("string", firstTool.Function!.Parameters!.Properties!.First().Value.Type);
386-
Assert.Equal("testInput", firstTool.Function!.Parameters!.Required!.First());
387377

388378
Assert.Equal(1, invocationCount);
389379

dotnet/src/Connectors/Connectors.Ollama/Connectors.Ollama.csproj

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424

2525
<ItemGroup>
2626
<PackageReference Include="Microsoft.Extensions.AI" />
27-
<PackageReference Include="OllamaSharp" />
27+
<PackageReference Include="OllamaSharp">
28+
<ExcludeAssets>analyzers</ExcludeAssets>
29+
</PackageReference>
30+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
2831
</ItemGroup>
2932

3033
<ItemGroup>

dotnet/src/IntegrationTests/IntegrationTests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<None Remove="skills\FunSkill\Joke\skprompt.txt" />
4242
</ItemGroup>
4343
<ItemGroup>
44+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" />
4445
<PackageReference Include="Azure.Identity" />
4546
<PackageReference Include="Microsoft.Extensions.Configuration" />
4647
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />

dotnet/src/SemanticKernel.Abstractions/AI/ChatCompletion/ChatClientChatCompletionService.cs

+23-10
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,24 @@ public async Task<IReadOnlyList<ChatMessageContent>> GetChatMessageContentsAsync
5454
{
5555
Verify.NotNull(chatHistory);
5656

57-
var messageList = ChatCompletionServiceExtensions.ToChatMessageList(chatHistory);
58-
var currentSize = messageList.Count;
59-
6057
var completion = await this._chatClient.GetResponseAsync(
61-
messageList,
58+
ChatCompletionServiceExtensions.ToChatMessageList(chatHistory),
6259
ToChatOptions(executionSettings, kernel),
6360
cancellationToken).ConfigureAwait(false);
6461

65-
chatHistory.AddRange(
66-
messageList
67-
.Skip(currentSize)
68-
.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m)));
62+
if (completion.Messages.Count > 0)
63+
{
64+
// Add all but the last message into the chat history.
65+
for (int i = 0; i < completion.Messages.Count - 1; i++)
66+
{
67+
chatHistory.Add(ChatCompletionServiceExtensions.ToChatMessageContent(completion.Messages[i], completion));
68+
}
6969

70-
return completion.Choices.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m, completion)).ToList();
70+
// Return the last message as the result.
71+
return [ChatCompletionServiceExtensions.ToChatMessageContent(completion.Messages[completion.Messages.Count - 1], completion)];
72+
}
73+
74+
return [];
7175
}
7276

7377
/// <inheritdoc/>
@@ -76,13 +80,23 @@ public async IAsyncEnumerable<StreamingChatMessageContent> GetStreamingChatMessa
7680
{
7781
Verify.NotNull(chatHistory);
7882

83+
List<AIContent> fcContents = [];
84+
ChatRole? role = null;
85+
7986
await foreach (var update in this._chatClient.GetStreamingResponseAsync(
8087
ChatCompletionServiceExtensions.ToChatMessageList(chatHistory),
8188
ToChatOptions(executionSettings, kernel),
8289
cancellationToken).ConfigureAwait(false))
8390
{
91+
role ??= update.Role;
92+
93+
fcContents.AddRange(update.Contents.Where(c => c is Microsoft.Extensions.AI.FunctionCallContent or Microsoft.Extensions.AI.FunctionResultContent));
94+
8495
yield return ToStreamingChatMessageContent(update);
8596
}
97+
98+
// Add function call content/results to chat history, as other IChatCompletionService streaming implementations do.
99+
chatHistory.Add(ChatCompletionServiceExtensions.ToChatMessageContent(new ChatMessage(role ?? ChatRole.Assistant, fcContents)));
86100
}
87101

88102
/// <summary>Converts a pair of <see cref="PromptExecutionSettings"/> and <see cref="Kernel"/> to a <see cref="ChatOptions"/>.</summary>
@@ -283,7 +297,6 @@ private static StreamingChatMessageContent ToStreamingChatMessageContent(ChatRes
283297
null)
284298
{
285299
InnerContent = update.RawRepresentation,
286-
ChoiceIndex = update.ChoiceIndex,
287300
Metadata = update.AdditionalProperties,
288301
ModelId = update.ModelId
289302
};

dotnet/src/SemanticKernel.Abstractions/AI/ChatCompletion/ChatCompletionServiceChatClient.cs

+21-8
Original file line numberDiff line numberDiff line change
@@ -35,30 +35,44 @@ public ChatCompletionServiceChatClient(IChatCompletionService chatCompletionServ
3535
public ChatClientMetadata Metadata { get; }
3636

3737
/// <inheritdoc />
38-
public async Task<Extensions.AI.ChatResponse> GetResponseAsync(IList<ChatMessage> chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
38+
public async Task<Extensions.AI.ChatResponse> GetResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
3939
{
40-
Verify.NotNull(chatMessages);
40+
Verify.NotNull(messages);
41+
42+
ChatHistory chatHistory = new(messages.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m)));
43+
int preCount = chatHistory.Count;
4144

4245
var response = await this._chatCompletionService.GetChatMessageContentAsync(
43-
new ChatHistory(chatMessages.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m))),
46+
chatHistory,
4447
ToPromptExecutionSettings(options),
4548
kernel: null,
4649
cancellationToken).ConfigureAwait(false);
4750

48-
return new(ChatCompletionServiceExtensions.ToChatMessage(response))
51+
ChatResponse chatResponse = new()
4952
{
5053
ModelId = response.ModelId,
5154
RawRepresentation = response.InnerContent,
5255
};
56+
57+
// Add all messages that were added to the history.
58+
// Then add the result message.
59+
for (int i = preCount; i < chatHistory.Count; i++)
60+
{
61+
chatResponse.Messages.Add(ChatCompletionServiceExtensions.ToChatMessage(chatHistory[i]));
62+
}
63+
64+
chatResponse.Messages.Add(ChatCompletionServiceExtensions.ToChatMessage(response));
65+
66+
return chatResponse;
5367
}
5468

5569
/// <inheritdoc />
56-
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IList<ChatMessage> chatMessages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
70+
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default)
5771
{
58-
Verify.NotNull(chatMessages);
72+
Verify.NotNull(messages);
5973

6074
await foreach (var update in this._chatCompletionService.GetStreamingChatMessageContentsAsync(
61-
new ChatHistory(chatMessages.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m))),
75+
new ChatHistory(messages.Select(m => ChatCompletionServiceExtensions.ToChatMessageContent(m))),
6276
ToPromptExecutionSettings(options),
6377
kernel: null,
6478
cancellationToken).ConfigureAwait(false))
@@ -200,7 +214,6 @@ private static ChatResponseUpdate ToStreamingChatCompletionUpdate(StreamingChatM
200214
{
201215
AdditionalProperties = content.Metadata is not null ? new AdditionalPropertiesDictionary(content.Metadata) : null,
202216
AuthorName = content.AuthorName,
203-
ChoiceIndex = content.ChoiceIndex,
204217
ModelId = content.ModelId,
205218
RawRepresentation = content,
206219
Role = content.Role is not null ? new ChatRole(content.Role.Value.Label) : null,

0 commit comments

Comments
 (0)