Skip to content

Commit 0f19b1e

Browse files
committed
Fix Azure.AI.OpenAI to work with the latest OpenAI package.
1 parent d20a92a commit 0f19b1e

File tree

7 files changed

+521
-70
lines changed

7 files changed

+521
-70
lines changed

sdk/openai/Azure.AI.OpenAI/src/Custom/Chat/AzureChatClient.cs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma warning disable AOAI001
1010
#pragma warning disable AZC0112
11+
#pragma warning disable SCME0001
1112

1213
namespace Azure.AI.OpenAI.Chat;
1314

@@ -86,16 +87,14 @@ public override CollectionResult<StreamingChatCompletionUpdate> CompleteChatStre
8687
*/
8788
private static void PostfixClearStreamOptions(IEnumerable<ChatMessage> messages, ref ChatCompletionOptions options)
8889
{
89-
if (AdditionalPropertyHelpers
90-
.GetAdditionalPropertyAsListOfChatDataSource(options?.SerializedAdditionalRawData, "data_sources")?.Count > 0
90+
if (options?.GetDataSources()?.Count > 0
9191
|| messages?.Any(
9292
message => message?.Content?.Any(
9393
contentPart => contentPart?.Kind == ChatMessageContentPartKind.Image) == true)
9494
== true)
9595
{
9696
options ??= new();
97-
options.SerializedAdditionalRawData ??= new Dictionary<string, BinaryData>();
98-
AdditionalPropertyHelpers.SetEmptySentinelValue(options.SerializedAdditionalRawData, "stream_options");
97+
options.Patch.Remove("$.stream_options"u8);
9998
}
10099
}
101100

@@ -114,14 +113,13 @@ private static void PostfixSwapMaxTokens(ref ChatCompletionOptions options)
114113
{
115114
options ??= new();
116115
bool valueIsSet = options.MaxOutputTokenCount is not null;
117-
bool oldPropertyBlocked = AdditionalPropertyHelpers.GetIsEmptySentinelValue(options.SerializedAdditionalRawData, "max_tokens");
116+
bool oldPropertyBlocked = !options.Patch.Contains("$.max_tokens"u8);
118117

119118
if (valueIsSet)
120119
{
121120
if (!oldPropertyBlocked)
122121
{
123-
options.SerializedAdditionalRawData ??= new ChangeTrackingDictionary<string, BinaryData>();
124-
AdditionalPropertyHelpers.SetEmptySentinelValue(options.SerializedAdditionalRawData, "max_completion_tokens");
122+
options.Patch.Remove("$.max_completion_tokens"u8);
125123

126124
using MemoryStream stream = new();
127125
using Utf8JsonWriter writer = new(stream);
@@ -137,28 +135,26 @@ private static void PostfixSwapMaxTokens(ref ChatCompletionOptions options)
137135

138136
writer.Flush();
139137

140-
options.SerializedAdditionalRawData["max_tokens"] = BinaryData.FromBytes(stream.ToArray());
138+
options.Patch.Set("$.max_tokens"u8, BinaryData.FromBytes(stream.ToArray()));
141139
}
142140
else
143141
{
144142
// Allow standard serialization to the new property to occur; remove overrides
145-
if (options.SerializedAdditionalRawData.ContainsKey("max_completion_tokens"))
143+
if (options.Patch.Contains("$.max_completion_tokens"u8))
146144
{
147-
options.SerializedAdditionalRawData.Remove("max_completion_tokens");
145+
options.Patch.Remove("$.max_completion_tokens"u8);
148146
}
149147
}
150148
}
151149
else
152150
{
153-
if (!AdditionalPropertyHelpers.GetIsEmptySentinelValue(options.SerializedAdditionalRawData, "max_tokens")
154-
&& options.SerializedAdditionalRawData?.ContainsKey("max_tokens") == true)
151+
if (options.Patch.Contains("$.max_tokens"u8))
155152
{
156-
options.SerializedAdditionalRawData.Remove("max_tokens");
153+
options.Patch.Remove("$.max_tokens"u8);
157154
}
158-
if (!AdditionalPropertyHelpers.GetIsEmptySentinelValue(options.SerializedAdditionalRawData, "max_completion_tokens")
159-
&& options.SerializedAdditionalRawData?.ContainsKey("max_completion_tokens") == true)
155+
if (options.Patch.Contains("$.max_completion_tokens"u8))
160156
{
161-
options.SerializedAdditionalRawData.Remove("max_completion_tokens");
157+
options.Patch.Remove("$.max_completion_tokens"u8);
162158
}
163159
}
164160
}
Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
using Azure.AI.OpenAI.Internal;
4+
using System.ClientModel;
5+
using System.ClientModel.Primitives;
56
using System.Diagnostics.CodeAnalysis;
7+
using System.Text;
8+
using System.Text.Json;
9+
using System.Text.Json.Nodes;
610

711
#pragma warning disable AZC0112
812

@@ -14,26 +18,40 @@ public static partial class AzureChatExtensions
1418
[Experimental("AOAI001")]
1519
public static void AddDataSource(this ChatCompletionOptions options, ChatDataSource dataSource)
1620
{
17-
options.SerializedAdditionalRawData ??= new Dictionary<string, BinaryData>();
18-
19-
IList<ChatDataSource> existingSources =
20-
AdditionalPropertyHelpers.GetAdditionalPropertyAsListOfChatDataSource(
21-
options.SerializedAdditionalRawData,
22-
"data_sources")
23-
?? new ChangeTrackingList<ChatDataSource>();
24-
existingSources.Add(dataSource);
25-
AdditionalPropertyHelpers.SetAdditionalProperty(
26-
options.SerializedAdditionalRawData,
27-
"data_sources",
28-
existingSources);
21+
JsonArray doc;
22+
if (options.Patch.TryGetJson("$.data_sources"u8, out ReadOnlyMemory<byte> jsonBytes))
23+
{
24+
using var stream = new MemoryStream();
25+
stream.Write(jsonBytes.ToArray(), 0, jsonBytes.Length);
26+
string json = Encoding.UTF8.GetString(stream.ToArray());
27+
doc = JsonObject.Parse(json).AsObject().AsArray();
28+
}
29+
else
30+
{
31+
doc = new();
32+
}
33+
using var objectStream = new MemoryStream();
34+
using BinaryContent contentBytes = BinaryContent.Create(dataSource, ModelSerializationExtensions.WireOptions);
35+
contentBytes.WriteTo(objectStream);
36+
string newJson = Encoding.UTF8.GetString(objectStream.ToArray());
37+
doc.Append(JsonObject.Parse(newJson));
38+
options.Patch.Set("$.data_sources"u8, BinaryData.FromString(doc.ToJsonString()));
2939
}
3040

3141
[Experimental("AOAI001")]
3242
public static IReadOnlyList<ChatDataSource> GetDataSources(this ChatCompletionOptions options)
3343
{
34-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsListOfChatDataSource(
35-
options.SerializedAdditionalRawData,
36-
"data_sources") as IReadOnlyList<ChatDataSource>;
44+
if (options.Patch.TryGetJson("$.data_sources"u8, out ReadOnlyMemory<byte> mem))
45+
{
46+
using JsonDocument doc = JsonDocument.Parse(mem);
47+
List<ChatDataSource> chats = [];
48+
foreach (JsonElement dataSource in doc.RootElement.EnumerateArray())
49+
{
50+
chats.Add(ChatDataSource.DeserializeChatDataSource(dataSource, ModelSerializationExtensions.WireOptions));
51+
}
52+
return chats;
53+
}
54+
return null;
3755
}
3856

3957
[Experimental("AOAI001")]
@@ -42,99 +60,110 @@ public static void SetNewMaxCompletionTokensPropertyEnabled(this ChatCompletionO
4260
if (newPropertyEnabled)
4361
{
4462
// Blocking serialization of max_tokens via dictionary acts as a signal to skip pre-serialization fixup
45-
options.SerializedAdditionalRawData ??= new Dictionary<string, BinaryData>();
46-
AdditionalPropertyHelpers.SetEmptySentinelValue(options.SerializedAdditionalRawData, "max_tokens");
63+
options.Patch.Remove("$.max_tokens"u8);
4764
}
4865
else
4966
{
5067
// In the absence of a dictionary serialization block to max_tokens, the newer property name will
5168
// automatically be blocked and the older property name will be used via dictionary override
52-
if (options?.SerializedAdditionalRawData?.ContainsKey("max_tokens") == true)
69+
if (options.Patch.Contains("$.max_tokens"u8))
5370
{
54-
options?.SerializedAdditionalRawData?.Remove("max_tokens");
71+
options.Patch.Remove("$.max_tokens"u8);
5572
}
5673
}
5774
}
5875

5976
[Experimental("AOAI001")]
6077
public static RequestContentFilterResult GetRequestContentFilterResult(this ChatCompletion chatCompletion)
6178
{
62-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsListOfRequestContentFilterResult(
63-
chatCompletion.SerializedAdditionalRawData,
64-
"prompt_filter_results")?[0];
79+
if (chatCompletion.Patch.TryGetJson("$.prompt_filter_results"u8, out ReadOnlyMemory<byte> mem))
80+
{
81+
using JsonDocument doc = JsonDocument.Parse(mem);
82+
return RequestContentFilterResult.DeserializeRequestContentFilterResult(doc.RootElement, ModelSerializationExtensions.WireOptions);
83+
}
84+
return null;
6585
}
6686

6787
[Experimental("AOAI001")]
6888
public static ResponseContentFilterResult GetResponseContentFilterResult(this ChatCompletion chatCompletion)
6989
{
70-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsResponseContentFilterResult(
71-
chatCompletion.Choices?[0]?.SerializedAdditionalRawData,
72-
"content_filter_results");
90+
if (chatCompletion.Choices?[0]?.Patch.TryGetJson("$.content_filter_results"u8, out ReadOnlyMemory<byte> mem) ?? false)
91+
{
92+
using JsonDocument doc = JsonDocument.Parse(mem);
93+
return ResponseContentFilterResult.DeserializeResponseContentFilterResult(doc.RootElement, ModelSerializationExtensions.WireOptions);
94+
}
95+
return null;
7396
}
7497

7598
[Experimental("AOAI001")]
7699
public static ChatMessageContext GetMessageContext(this ChatCompletion chatCompletion)
77100
{
78-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsChatMessageContext(
79-
chatCompletion.Choices?[0]?.Message?.SerializedAdditionalRawData,
80-
"context");
101+
if (chatCompletion.Choices?[0]?.Message?.Patch.TryGetJson("$.context"u8, out ReadOnlyMemory<byte> mem) ?? false)
102+
{
103+
using JsonDocument doc = JsonDocument.Parse(mem);
104+
return ChatMessageContext.DeserializeChatMessageContext(doc.RootElement, ModelSerializationExtensions.WireOptions);
105+
}
106+
return null;
81107
}
82108

83109
[Experimental("AOAI001")]
84110
public static ChatMessageContext GetMessageContext(this StreamingChatCompletionUpdate chatUpdate)
85111
{
86-
if (chatUpdate.Choices?.Count > 0)
112+
if (chatUpdate.Choices?.Count > 0 && chatUpdate.Choices[0].Delta.Patch.TryGetJson("$.content_filter_results"u8, out ReadOnlyMemory<byte> mem))
87113
{
88-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsChatMessageContext(
89-
chatUpdate.Choices[0].Delta?.SerializedAdditionalRawData,
90-
"context");
114+
using JsonDocument doc = JsonDocument.Parse(mem);
115+
return ChatMessageContext.DeserializeChatMessageContext(doc.RootElement, ModelSerializationExtensions.WireOptions);
91116
}
92117
return null;
93118
}
94119

95120
[Experimental("AOAI001")]
96121
public static RequestContentFilterResult GetRequestContentFilterResult(this StreamingChatCompletionUpdate chatUpdate)
97122
{
98-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsListOfRequestContentFilterResult(
99-
chatUpdate.SerializedAdditionalRawData,
100-
"prompt_filter_results")?[0];
123+
if (chatUpdate.Patch.TryGetJson("$.prompt_filter_results"u8, out ReadOnlyMemory<byte> mem))
124+
{
125+
using JsonDocument doc = JsonDocument.Parse(mem);
126+
return RequestContentFilterResult.DeserializeRequestContentFilterResult(doc.RootElement, ModelSerializationExtensions.WireOptions);
127+
}
128+
return null;
101129
}
102130

103131
[Experimental("AOAI001")]
104132
public static ResponseContentFilterResult GetResponseContentFilterResult(this StreamingChatCompletionUpdate chatUpdate)
105133
{
106-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsResponseContentFilterResult(
107-
chatUpdate?.Choices?.ElementAtOrDefault(0)?.SerializedAdditionalRawData,
108-
"content_filter_results");
134+
if (chatUpdate?.Choices?.ElementAtOrDefault(0)?.Patch.TryGetJson("$.content_filter_results"u8, out ReadOnlyMemory<byte> mem) ?? false)
135+
{
136+
using JsonDocument doc = JsonDocument.Parse(mem);
137+
return ResponseContentFilterResult.DeserializeResponseContentFilterResult(doc.RootElement, ModelSerializationExtensions.WireOptions);
138+
}
139+
return null;
109140
}
110141

111142
[Experimental("AOAI001")]
112143
public static void SetUserSecurityContext(this ChatCompletionOptions options, UserSecurityContext userSecurityContext)
113144
{
114-
options.SerializedAdditionalRawData ??= new Dictionary<string, BinaryData>();
115-
116-
AdditionalPropertyHelpers.SetAdditionalProperty(
117-
options.SerializedAdditionalRawData,
118-
"user_security_context",
119-
userSecurityContext);
145+
BinaryData bin = ModelReaderWriter.Write(userSecurityContext, ModelSerializationExtensions.WireOptions);
146+
options.Patch.Set("$.user_security_context"u8, bin);
120147
}
121148

122149
[Experimental("AOAI001")]
123150
public static UserSecurityContext GetUserSecurityContext(this ChatCompletionOptions options)
124151
{
125-
return AdditionalPropertyHelpers.GetAdditionalPropertyAsUserSecurityContext(
126-
options.SerializedAdditionalRawData,
127-
"user_security_context");
152+
if (options.Patch.TryGetJson("$.user_security_context"u8, out ReadOnlyMemory<byte> mem))
153+
{
154+
using JsonDocument doc = JsonDocument.Parse(mem);
155+
return UserSecurityContext.DeserializeUserSecurityContext(doc.RootElement, ModelSerializationExtensions.WireOptions);
156+
}
157+
return null;
128158
}
129159

130160
[Experimental("AOAI001")]
131161
public static string GetMessageReasoningContent(this ChatCompletion chatCompletion)
132162
{
133-
if (chatCompletion?.Choices?.FirstOrDefault()?.Message?.SerializedAdditionalRawData?.TryGetValue("reasoning_content", out BinaryData reasoningContentData) == true
134-
&& reasoningContentData?.ToString() is string retrievedReasoningContent)
163+
if (chatCompletion?.Choices?.FirstOrDefault()?.Message?.Patch.TryGetValue("$.reasoning_content"u8, out string retrievedReasoningContent) ?? false)
135164
{
136165
return retrievedReasoningContent;
137166
}
138167
return null;
139168
}
140-
}
169+
}

0 commit comments

Comments
 (0)