Skip to content

Commit aaa924e

Browse files
authored
Prepare 2.2.0-beta.4 release (Part 1) (#378)
1 parent dcf3838 commit aaa924e

File tree

286 files changed

+7121
-4368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

286 files changed

+7121
-4368
lines changed

api/OpenAI.net8.0.cs

Lines changed: 214 additions & 96 deletions
Large diffs are not rendered by default.

api/OpenAI.netstandard2.0.cs

Lines changed: 202 additions & 96 deletions
Large diffs are not rendered by default.

examples/Responses/Example01_CuaFlow.cs

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
5+
namespace OpenAI.Examples;
6+
7+
public partial class ResponseExamples
8+
{
9+
[Test]
10+
public void Example01_HelloWorld()
11+
{
12+
OpenAIResponseClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
13+
14+
OpenAIResponse response = client.CreateResponse("Say 'this is a test.'");
15+
16+
Console.WriteLine($"[ASSISTANT]: {response.GetOutputText()}");
17+
}
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
using System.Threading.Tasks;
5+
6+
namespace OpenAI.Examples;
7+
8+
public partial class ResponseExamples
9+
{
10+
[Test]
11+
public async Task Example01_HelloWorldAsync()
12+
{
13+
OpenAIResponseClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
14+
15+
OpenAIResponse response = await client.CreateResponseAsync("Say 'this is a test.'");
16+
17+
Console.WriteLine($"[ASSISTANT]: {response.GetOutputText()}");
18+
}
19+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
5+
namespace OpenAI.Examples;
6+
7+
public partial class ResponseExamples
8+
{
9+
[Test]
10+
public void Example02_HelloWorldStreaming()
11+
{
12+
OpenAIResponseClient client = new(
13+
model: "gpt-4o-mini",
14+
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
15+
16+
Console.Write($"Streaming text: ");
17+
18+
foreach (StreamingResponseUpdate update
19+
in client.CreateResponseStreaming("Hello, world!"))
20+
{
21+
if (update is StreamingResponseOutputTextDeltaUpdate outputTextUpdate)
22+
{
23+
// Streamed text will arrive as it's generated via delta events
24+
Console.Write(outputTextUpdate.Delta);
25+
}
26+
else if (update is StreamingResponseCompletedUpdate responseCompletedUpdate)
27+
{
28+
// Item and response completed events have aggregated text available
29+
Console.WriteLine();
30+
Console.WriteLine($"Final text: {responseCompletedUpdate.Response.GetOutputText()}");
31+
}
32+
}
33+
}
34+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using NUnit.Framework;
2+
using OpenAI.Responses;
3+
using System;
4+
using System.Threading.Tasks;
5+
6+
namespace OpenAI.Examples;
7+
8+
public partial class ResponseExamples
9+
{
10+
[Test]
11+
public async Task Example02_HelloWorldStreamingAsync()
12+
{
13+
OpenAIResponseClient client = new(
14+
model: "gpt-4o-mini",
15+
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
16+
17+
Console.Write($"Streaming text: ");
18+
19+
await foreach (StreamingResponseUpdate update
20+
in client.CreateResponseStreamingAsync("Hello, world!"))
21+
{
22+
if (update is StreamingResponseOutputTextDeltaUpdate outputTextUpdate)
23+
{
24+
// Streamed text will arrive as it's generated via delta events
25+
Console.Write(outputTextUpdate.Delta);
26+
}
27+
else if (update is StreamingResponseCompletedUpdate responseCompletedUpdate)
28+
{
29+
// Item and response completed events have aggregated text available
30+
Console.WriteLine();
31+
Console.WriteLine($"Final text: {responseCompletedUpdate.Response.GetOutputText()}");
32+
}
33+
}
34+
}
35+
}

src/Custom/Chat/ChatMessageContentPart.Serialization.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ internal static void WriteCoreContentPart(ChatMessageContentPart instance, Utf8J
3838
writer.WritePropertyName("input_audio"u8);
3939
writer.WriteObjectValue(instance._inputAudio, options);
4040
}
41+
else if (instance._kind == ChatMessageContentPartKind.File)
42+
{
43+
writer.WritePropertyName("file"u8);
44+
writer.WriteObjectValue(instance._fileFile, options);
45+
}
4146
writer.WriteSerializedAdditionalRawData(instance._additionalBinaryDataProperties, options);
4247
writer.WriteEndObject();
4348
}
@@ -56,6 +61,7 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle
5661
string refusal = default;
5762
InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default;
5863
InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default;
64+
InternalChatCompletionRequestMessageContentPartFileFile fileFile = default;
5965
IDictionary<string, BinaryData> serializedAdditionalRawData = default;
6066
Dictionary<string, BinaryData> rawDataDictionary = new Dictionary<string, BinaryData>();
6167
foreach (var property in element.EnumerateObject())
@@ -86,12 +92,18 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle
8692
.DeserializeInternalChatCompletionRequestMessageContentPartAudioInputAudio(property.Value, options);
8793
continue;
8894
}
95+
if (property.NameEquals("file"u8))
96+
{
97+
fileFile = InternalChatCompletionRequestMessageContentPartFileFile
98+
.DeserializeInternalChatCompletionRequestMessageContentPartFileFile(property.Value, options);
99+
continue;
100+
}
89101
if (true)
90102
{
91103
rawDataDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText()));
92104
}
93105
}
94106
serializedAdditionalRawData = rawDataDictionary;
95-
return new ChatMessageContentPart(kind, text, imageUri, refusal, inputAudio, serializedAdditionalRawData);
107+
return new ChatMessageContentPart(kind, text, imageUri, refusal, inputAudio, fileFile, serializedAdditionalRawData);
96108
}
97109
}

src/Custom/Chat/ChatMessageContentPart.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public partial class ChatMessageContentPart
3333
private readonly string _text;
3434
private readonly InternalChatCompletionRequestMessageContentPartImageImageUrl _imageUri;
3535
private readonly InternalChatCompletionRequestMessageContentPartAudioInputAudio _inputAudio;
36+
private readonly InternalChatCompletionRequestMessageContentPartFileFile _fileFile;
3637
private readonly string _refusal;
3738

3839
// CUSTOM: Made internal.
@@ -47,13 +48,15 @@ internal ChatMessageContentPart(
4748
InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default,
4849
string refusal = default,
4950
InternalChatCompletionRequestMessageContentPartAudioInputAudio inputAudio = default,
51+
InternalChatCompletionRequestMessageContentPartFileFile fileFile = default,
5052
IDictionary<string, BinaryData> serializedAdditionalRawData = default)
5153
{
5254
_kind = kind;
5355
_text = text;
5456
_imageUri = imageUri;
5557
_refusal = refusal;
5658
_inputAudio = inputAudio;
59+
_fileFile = fileFile;
5760
_additionalBinaryDataProperties = serializedAdditionalRawData;
5861
}
5962

@@ -98,6 +101,26 @@ internal ChatMessageContentPart(
98101
/// </remarks>
99102
public ChatInputAudioFormat? InputAudioFormat => _inputAudio?.Format;
100103

104+
// CUSTOM: Spread.
105+
/// <summary> The ID of the previously uploaded file that the content part represents. </summary>
106+
/// <remarks> Present when <see cref="Kind"/> is <see cref="ChatMessageContentPartKind.File"/> and the content part refers to a previously uploaded file. </remarks>
107+
public string FileId => _fileFile?.FileId;
108+
109+
// CUSTOM: Spread.
110+
/// <summary> The binary file content of the file content part. </summary>
111+
/// <remarks> Present when <see cref="Kind"/> is <see cref="ChatMessageContentPartKind.File"/> and the content refers to data for a new file. </remarks>
112+
public BinaryData FileBytes => _fileFile?.FileBytes;
113+
114+
// CUSTOM: Spread.
115+
/// <summary> The MIME type of the file, e.g., <c>application/pdf</c>. </summary>
116+
/// <remarks> Present when <see cref="Kind"/> is <see cref="ChatMessageContentPartKind.File"/> and the content refers to data for a new file. </remarks>
117+
public string FileBytesMediaType => _fileFile?.FileBytesMediaType;
118+
119+
// CUSTOM: Spread.
120+
/// <summary> The filename for the new file content creation that the content part encapsulates. </summary>
121+
/// <remarks> Present when <see cref="Kind"/> is <see cref="ChatMessageContentPartKind.File"/> and the content refers to data for a new file. </remarks>
122+
public string Filename => _fileFile?.Filename;
123+
101124
// CUSTOM: Spread.
102125
/// <summary>
103126
/// The level of detail with which the model should process the image and generate its textual understanding of
@@ -184,6 +207,40 @@ public static ChatMessageContentPart CreateInputAudioPart(BinaryData inputAudioB
184207
inputAudio: new(inputAudioBytes, inputAudioFormat));
185208
}
186209

210+
/// <summary> Creates a new <see cref="ChatMessageContentPart"/> that represents a previously uploaded file. </summary>
211+
/// <exception cref="ArgumentException"> <paramref name="fileId"/> is null or empty. </exception>
212+
public static ChatMessageContentPart CreateFilePart(string fileId)
213+
{
214+
Argument.AssertNotNullOrEmpty(fileId, nameof(fileId));
215+
216+
return new ChatMessageContentPart(
217+
kind: ChatMessageContentPartKind.File,
218+
fileFile: new()
219+
{
220+
FileId = fileId,
221+
});
222+
}
223+
224+
/// <summary> Creates a new <see cref="ChatMessageContentPart"/> that encapsulates new file data to upload. </summary>
225+
/// <param name="fileBytes"> The binary content of the file. </param>
226+
/// <param name="fileBytesMediaType"> The MIME type of the file, e.g., <c>application/pdf</c>. </param>
227+
/// <param name="filename"> The filename to use for the file that will be created. </param>
228+
/// <exception cref="ArgumentNullException"> <paramref name="fileBytes"/> or <paramref name="fileBytesMediaType"/> is null. </exception>
229+
/// <exception cref="ArgumentException"> <paramref name="fileBytesMediaType"/> or <paramref name="filename"/>> is an empty string, and was expected to be non-empty. </exception>
230+
public static ChatMessageContentPart CreateFilePart(BinaryData fileBytes, string fileBytesMediaType, string filename)
231+
{
232+
Argument.AssertNotNull(fileBytes, nameof(fileBytes));
233+
Argument.AssertNotNullOrEmpty(fileBytesMediaType, nameof(fileBytesMediaType));
234+
Argument.AssertNotNullOrEmpty(filename, nameof(filename));
235+
236+
return new ChatMessageContentPart(
237+
kind: ChatMessageContentPartKind.File,
238+
fileFile: new(fileBytes, fileBytesMediaType)
239+
{
240+
Filename = filename,
241+
});
242+
}
243+
187244
/// <summary>
188245
/// Implicitly instantiates a new <see cref="ChatMessageContentPart"/> from a <see cref="string"/>. As such,
189246
/// using a <see cref="string"/> in place of a <see cref="ChatMessageContentPart"/> is equivalent to calling the

src/Custom/Chat/ChatMessageContentPartKind.Serialization.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ internal static partial class ChatMessageContentPartKindExtensions
1414
ChatMessageContentPartKind.Refusal => "refusal",
1515
ChatMessageContentPartKind.Image => "image_url",
1616
ChatMessageContentPartKind.InputAudio => "input_audio",
17+
ChatMessageContentPartKind.File => "file",
1718
_ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ChatMessageContentPartKind value.")
1819
};
1920

@@ -23,6 +24,7 @@ public static ChatMessageContentPartKind ToChatMessageContentPartKind(this strin
2324
if (StringComparer.OrdinalIgnoreCase.Equals(value, "refusal")) return ChatMessageContentPartKind.Refusal;
2425
if (StringComparer.OrdinalIgnoreCase.Equals(value, "image_url")) return ChatMessageContentPartKind.Image;
2526
if (StringComparer.OrdinalIgnoreCase.Equals(value, "input_audio")) return ChatMessageContentPartKind.InputAudio;
27+
if (StringComparer.OrdinalIgnoreCase.Equals(value, "file")) return ChatMessageContentPartKind.File;
2628
throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ChatMessageContentPartKind value.");
2729
}
2830
}

0 commit comments

Comments
 (0)