Skip to content

Commit dbee707

Browse files
authored
Update to OpenAI 2.6.0 (#6996)
* Update to OpenAI 2.6.0 In addition to updating the dependency, it now enables us to do additional things: - Propagate ChatOptions/EmbeddingGeneratorOptions.ModelID to allow overriding the model per-request. - Propagate AIContent results of tool invocations using non-string tool results. - Add support for container file annotations. - Fixed handling of GetResponse{Streaming}Async to use RequestOptions - Remove hacky serialization code around ResponseCreationOptions. A previous PR added HostedFileContent.Name/MediaType, but we missed adding HasTopLevelMediaType (which both DataContent and UriContent have). I had a need for that here, so included it. * Add more tests based on code coverage gaps * Fix handling of role in AsChatMessages
1 parent 8cc763f commit dbee707

File tree

15 files changed

+1822
-87
lines changed

15 files changed

+1822
-87
lines changed

eng/packages/General.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="$(MicrosoftMLTokenizersVersion)" />
2121
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
2222
<PackageVersion Include="OllamaSharp" Version="5.1.9" />
23-
<PackageVersion Include="OpenAI" Version="2.5.0" />
23+
<PackageVersion Include="OpenAI" Version="2.6.0" />
2424
<PackageVersion Include="Polly" Version="8.4.2" />
2525
<PackageVersion Include="Polly.Core" Version="8.4.2" />
2626
<PackageVersion Include="Polly.Extensions" Version="8.4.2" />

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Updated `AIFunctionFactory` to respect `[DisplayName(...)]` on functions as a way to override the function name.
66
- Updated `AIFunctionFactory` to respect `[DefaultValue(...)]` on function parameters as a way to specify default values.
77
- Added `CodeInterpreterToolCallContent`/`CodeInterpreterToolResultContent` for representing code interpreter tool calls and results.
8+
- Added `Name`, `MediaType`, and `HasTopLevelMediaType` to `HostedFileContent`.
89
- Fixed the serialization/deserialization of variables typed as `UserInputRequestContent`/`UserInputResponseContent`.
910

1011
## 9.10.1

src/Libraries/Microsoft.Extensions.AI.Abstractions/Contents/HostedFileContent.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@ public string? MediaType
5050
/// <summary>Gets or sets an optional name associated with the file.</summary>
5151
public string? Name { get; set; }
5252

53+
/// <summary>
54+
/// Determines whether the <see cref="MediaType"/>'s top-level type matches the specified <paramref name="topLevelType"/>.
55+
/// </summary>
56+
/// <param name="topLevelType">The type to compare against <see cref="MediaType"/>.</param>
57+
/// <returns><see langword="true"/> if the type portion of <see cref="MediaType"/> matches the specified value; otherwise, false.</returns>
58+
/// <remarks>
59+
/// <para>
60+
/// A media type is primarily composed of two parts, a "type" and a "subtype", separated by a slash ("/").
61+
/// The type portion is also referred to as the "top-level type"; for example,
62+
/// "image/png" has a top-level type of "image". <see cref="HasTopLevelMediaType"/> compares
63+
/// the specified <paramref name="topLevelType"/> against the type portion of <see cref="MediaType"/>.
64+
/// </para>
65+
/// <para>
66+
/// If <see cref="MediaType"/> is <see langword="null"/>, this method returns <see langword="false"/>.
67+
/// </para>
68+
/// </remarks>
69+
public bool HasTopLevelMediaType(string topLevelType) => MediaType is not null && DataUriParser.HasTopLevelMediaType(MediaType, topLevelType);
70+
5371
/// <summary>Gets a string representing this instance to display in the debugger.</summary>
5472
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
5573
private string DebuggerDisplay

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,10 @@
20062006
{
20072007
"Member": "Microsoft.Extensions.AI.HostedFileContent.HostedFileContent(string fileId);",
20082008
"Stage": "Stable"
2009+
},
2010+
{
2011+
"Member": "bool Microsoft.Extensions.AI.HostedFileContent.HasTopLevelMediaType(string topLevelType);",
2012+
"Stage": "Stable"
20092013
}
20102014
],
20112015
"Properties": [

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@
22

33
## NOT YET RELEASED
44

5-
- Updated the `IChatClient` for the OpenAI Responses API to allow either conversation or response ID for `ChatOptions.ConversationId`.
5+
- Updated to depend on OpenAI 2.6.0.
6+
- Updated the OpenAI Responses `IChatClient` to allow either conversation or response ID for `ChatOptions.ConversationId`.
7+
- Updated the OpenAI Responses `IChatClient` to support `AIFunction`s that return `AIContent` like `DataContent`.
8+
- Updated the OpenAI Chat Completion `IChatClient`, the Responses `IChatClient`, and the `IEmbeddingGenerator` to support per-request `ModelId` overrides.
69
- Added an `AITool` to `ResponseTool` conversion utility.
710
- Updated to accommodate the additions in `Microsoft.Extensions.AI.Abstractions`.
811

912
## 9.10.1-preview.1.25521.4
1013

11-
- Updated the `IChatClient` for the OpenAI Responses API to support connectors with `HostedMcpServerTool`.
12-
- Fixed the `IChatClient` for the OpenAI Responses API to roundtrip a `ResponseItem` stored in an `AIContent` in a `ChatRole.User` message.
14+
- Updated the OpenAI Responses `IChatClient` to support connectors with `HostedMcpServerTool`.
15+
- Fixed the OpenAI Responses `IChatClient` to roundtrip a `ResponseItem` stored in an `AIContent` in a `ChatRole.User` message.
1316
- Updated to accommodate the additions in `Microsoft.Extensions.AI.Abstractions`.
1417

1518
## 9.10.0-preview.1.25513.3
1619

17-
- Fixed issue with `IChatClient` for the OpenAI Assistants API where a chat history including unrelated function calls would cause an exception.
18-
- Fixed issue with `IChatClient` for the OpenAI Assistants API sending a tool in `ChatOptions.Tools` that had the same name as a function configured with the Assistant would cause an exception.
20+
- Fixed issue with the OpenAI Assistants `IChatClient` where a chat history including unrelated function calls would cause an exception.
21+
- Fixed issue with the OpenAI Assistants `IChatClient` sending a tool in `ChatOptions.Tools` that had the same name as a function configured with the Assistant would cause an exception.
1922
- Updated to accommodate the additions in `Microsoft.Extensions.AI.Abstractions`.
2023

2124
## 9.9.1-preview.1.25474.6
@@ -38,7 +41,7 @@
3841

3942
- Updated to depend on OpenAI 2.3.0.
4043
- Added more conversion helpers for converting bidirectionally between Microsoft.Extensions.AI messages and OpenAI messages.
41-
- Fixed handling of multiple response messages in the Responses `IChatClient`.
44+
- Fixed handling of multiple response messages in the OpenAI Responses `IChatClient`.
4245
- Updated to accommodate the additions in `Microsoft.Extensions.AI.Abstractions`.
4346

4447
## 9.7.1-preview.1.25365.4

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<PropertyGroup>
1717
<TargetFrameworks>$(TargetFrameworks);netstandard2.0</TargetFrameworks>
1818
<NoWarn>$(NoWarn);CA1063</NoWarn>
19-
<NoWarn>$(NoWarn);OPENAI001;OPENAI002;MEAI001</NoWarn>
19+
<NoWarn>$(NoWarn);OPENAI001;OPENAI002;MEAI001;SCME0001</NoWarn>
2020
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
2121
<DisableNETStandardCompatErrors>true</DisableNETStandardCompatErrors>
2222
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -26,8 +26,6 @@
2626
<InjectCompilerFeatureRequiredOnLegacy>true</InjectCompilerFeatureRequiredOnLegacy>
2727
<InjectExperimentalAttributeOnLegacy>true</InjectExperimentalAttributeOnLegacy>
2828
<InjectRequiredMemberOnLegacy>true</InjectRequiredMemberOnLegacy>
29-
<InjectSharedEmptyCollections>true</InjectSharedEmptyCollections>
30-
<InjectSharedServerSentEvents>true</InjectSharedServerSentEvents>
3129
<InjectStringHashOnLegacy>true</InjectStringHashOnLegacy>
3230
</PropertyGroup>
3331

src/Libraries/Microsoft.Extensions.AI.OpenAI/MicrosoftExtensionsAIChatExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ public static async IAsyncEnumerable<StreamingChatCompletionUpdate> AsOpenAIStre
183183
switch (message)
184184
{
185185
case AssistantChatMessage acm:
186+
resultMessage.Role = ChatRole.Assistant;
186187
resultMessage.AuthorName = acm.ParticipantName;
187188
OpenAIChatClient.ConvertContentParts(acm.Content, resultMessage.Contents);
188189
foreach (var toolCall in acm.ToolCalls)
@@ -195,21 +196,25 @@ public static async IAsyncEnumerable<StreamingChatCompletionUpdate> AsOpenAIStre
195196
break;
196197

197198
case UserChatMessage ucm:
199+
resultMessage.Role = ChatRole.User;
198200
resultMessage.AuthorName = ucm.ParticipantName;
199201
OpenAIChatClient.ConvertContentParts(ucm.Content, resultMessage.Contents);
200202
break;
201203

202204
case DeveloperChatMessage dcm:
205+
resultMessage.Role = ChatRole.System;
203206
resultMessage.AuthorName = dcm.ParticipantName;
204207
OpenAIChatClient.ConvertContentParts(dcm.Content, resultMessage.Contents);
205208
break;
206209

207210
case SystemChatMessage scm:
211+
resultMessage.Role = ChatRole.System;
208212
resultMessage.AuthorName = scm.ParticipantName;
209213
OpenAIChatClient.ConvertContentParts(scm.Content, resultMessage.Contents);
210214
break;
211215

212216
case ToolChatMessage tcm:
217+
resultMessage.Role = ChatRole.Tool;
213218
resultMessage.Contents.Add(new FunctionResultContent(tcm.ToolCallId, ToToolResult(tcm.Content))
214219
{
215220
RawRepresentation = tcm,

src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,12 @@ private ChatCompletionOptions ToOpenAIOptions(ChatOptions? options)
554554
{
555555
if (options is null)
556556
{
557-
return new ChatCompletionOptions();
557+
return new();
558558
}
559559

560560
if (options.RawRepresentationFactory?.Invoke(this) is not ChatCompletionOptions result)
561561
{
562-
result = new ChatCompletionOptions();
562+
result = new();
563563
}
564564

565565
result.FrequencyPenalty ??= options.FrequencyPenalty;
@@ -568,6 +568,7 @@ private ChatCompletionOptions ToOpenAIOptions(ChatOptions? options)
568568
result.PresencePenalty ??= options.PresencePenalty;
569569
result.Temperature ??= options.Temperature;
570570
result.Seed ??= options.Seed;
571+
OpenAIClientExtensions.PatchModelIfNotSet(ref result.Patch, options.ModelId);
571572

572573
if (options.StopSequences is { Count: > 0 } stopSequences)
573574
{

src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIClientExtensions.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.ClientModel.Primitives;
56
using System.Collections.Generic;
67
using System.Diagnostics.CodeAnalysis;
78
using System.Text;
@@ -228,6 +229,19 @@ internal static string ImageUriToMediaType(Uri uri)
228229
"image/*";
229230
}
230231

232+
/// <summary>Sets $.model in <paramref name="patch"/> to <paramref name="modelId"/> if not already set.</summary>
233+
internal static void PatchModelIfNotSet(ref JsonPatch patch, string? modelId)
234+
{
235+
if (modelId is not null)
236+
{
237+
_ = patch.TryGetValue("$.model"u8, out string? existingModel);
238+
if (existingModel is null)
239+
{
240+
patch.Set("$.model"u8, modelId);
241+
}
242+
}
243+
}
244+
231245
/// <summary>Used to create the JSON payload for an OpenAI tool description.</summary>
232246
internal sealed class ToolJson
233247
{

src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIEmbeddingGenerator.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,12 @@ private OpenAI.Embeddings.EmbeddingGenerationOptions ToOpenAIOptions(EmbeddingGe
107107
{
108108
if (options?.RawRepresentationFactory?.Invoke(this) is not OpenAI.Embeddings.EmbeddingGenerationOptions result)
109109
{
110-
result = new OpenAI.Embeddings.EmbeddingGenerationOptions();
110+
result = new();
111111
}
112112

113113
result.Dimensions ??= options?.Dimensions ?? _dimensions;
114+
OpenAIClientExtensions.PatchModelIfNotSet(ref result.Patch, options?.ModelId);
115+
114116
return result;
115117
}
116118
}

0 commit comments

Comments
 (0)