Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .dotnet.azure/sdk/openai/Azure.AI.OpenAI/tests/ChatTests.Vision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ public async Task ChatWithImages(bool useUri)
ChatMessageContentPart imagePart;
if (useUri)
{
imagePart = ChatMessageContentPart.CreateImageMessageContentPart(
imageAsset.Url, ImageChatMessageContentPartDetail.Low);
imagePart = ChatMessageContentPart.CreateImagePart(
imageAsset.Url, ChatImageDetailLevel.Low);
}
else
{
using var stream = File.OpenRead(imageAsset.RelativePath);
var imageData = BinaryData.FromStream(stream);

imagePart = ChatMessageContentPart.CreateImageMessageContentPart(
imageData, imageAsset.MimeType, ImageChatMessageContentPartDetail.Low);
imagePart = ChatMessageContentPart.CreateImagePart(
imageData, imageAsset.MimeType, ChatImageDetailLevel.Low);
}

ChatMessage[] messages =
[
new SystemChatMessage("You are a helpful assistant that helps describe images."),
new UserChatMessage(imagePart, ChatMessageContentPart.CreateTextMessageContentPart("describe this image"))
new UserChatMessage(imagePart, ChatMessageContentPart.CreateTextPart("describe this image"))
];

ChatCompletionOptions options = new()
Expand Down Expand Up @@ -94,22 +94,22 @@ public async Task ChatWithImagesStreaming(bool useUri)
var imageAsset = Assets.DogAndCat;
if (useUri)
{
imagePart = ChatMessageContentPart.CreateImageMessageContentPart(
imageAsset.Url, ImageChatMessageContentPartDetail.Low);
imagePart = ChatMessageContentPart.CreateImagePart(
imageAsset.Url, ChatImageDetailLevel.Low);
}
else
{
using var stream = File.OpenRead(imageAsset.RelativePath);
var imageData = BinaryData.FromStream(stream);

imagePart = ChatMessageContentPart.CreateImageMessageContentPart(
imageData, imageAsset.MimeType, ImageChatMessageContentPartDetail.Low);
imagePart = ChatMessageContentPart.CreateImagePart(
imageData, imageAsset.MimeType, ChatImageDetailLevel.Low);
}

ChatMessage[] messages =
[
new SystemChatMessage("You are a helpful assistant that helps describe images."),
new UserChatMessage(imagePart, ChatMessageContentPart.CreateTextMessageContentPart("describe this image"))
new UserChatMessage(imagePart, ChatMessageContentPart.CreateTextPart("describe this image"))
];

ChatCompletionOptions options = new()
Expand Down
12 changes: 12 additions & 0 deletions .dotnet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

## 2.0.0-beta.12 (Unreleased)

### Features Added

### Breaking Changes

- Renamed `ChatMessageContentPart`'s `CreateTextMessageContentPart` factory method to `CreateTextPart`.
- Renamed `ChatMessageContentPart`'s `CreateImageMessageContentPart` factory method to `CreateImagePart`.
- Renamed `ChatMessageContentPart`'s `CreateRefusalMessageContentPart` factory method to `CreateRefusalPart`.
- Renamed `ImageChatMessageContentPartDetail` to `ChatImageDetailLevel`.
- Removed `ChatMessageContentPart`'s `ToString` overload.

### Bugs Fixed

- Addressed an issue that caused multi-page queries of fine-tuning jobs, checkpoints, and events to fail. (commit_hash)

### Other Changes

## 2.0.0-beta.11 (2024-09-03)

### Features Added
Expand Down
47 changes: 23 additions & 24 deletions .dotnet/api/OpenAI.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,23 @@ public class ChatFunctionChoice : IJsonModel<ChatFunctionChoice>, IPersistableMo
string IPersistableModel<ChatFunctionChoice>.GetFormatFromOptions(ModelReaderWriterOptions options);
BinaryData IPersistableModel<ChatFunctionChoice>.Write(ModelReaderWriterOptions options);
}
public readonly partial struct ChatImageDetailLevel : IEquatable<ChatImageDetailLevel> {
private readonly object _dummy;
private readonly int _dummyPrimitive;
public ChatImageDetailLevel(string value);
public static ChatImageDetailLevel Auto { get; }
public static ChatImageDetailLevel High { get; }
public static ChatImageDetailLevel Low { get; }
public readonly bool Equals(ChatImageDetailLevel other);
[EditorBrowsable(EditorBrowsableState.Never)]
public override readonly bool Equals(object obj);
[EditorBrowsable(EditorBrowsableState.Never)]
public override readonly int GetHashCode();
public static bool operator ==(ChatImageDetailLevel left, ChatImageDetailLevel right);
public static implicit operator ChatImageDetailLevel(string value);
public static bool operator !=(ChatImageDetailLevel left, ChatImageDetailLevel right);
public override readonly string ToString();
}
public abstract class ChatMessage : IJsonModel<ChatMessage>, IPersistableModel<ChatMessage> {
protected ChatMessage();
protected internal ChatMessage(ChatMessageRole role, IEnumerable<ChatMessageContentPart> contentParts);
Expand Down Expand Up @@ -1352,22 +1369,21 @@ public abstract class ChatMessage : IJsonModel<ChatMessage>, IPersistableModel<C
public class ChatMessageContentPart : IJsonModel<ChatMessageContentPart>, IPersistableModel<ChatMessageContentPart> {
public BinaryData ImageBytes { get; }
public string ImageBytesMediaType { get; }
public ImageChatMessageContentPartDetail? ImageDetail { get; }
public ChatImageDetailLevel? ImageDetailLevel { get; }
public Uri ImageUri { get; }
public ChatMessageContentPartKind Kind { get; }
public string Refusal { get; }
public string Text { get; }
public static ChatMessageContentPart CreateImageMessageContentPart(BinaryData imageBytes, string imageBytesMediaType, ImageChatMessageContentPartDetail? imageDetail = null);
public static ChatMessageContentPart CreateImageMessageContentPart(Uri imageUri, ImageChatMessageContentPartDetail? imageDetail = null);
public static ChatMessageContentPart CreateRefusalMessageContentPart(string refusal);
public static ChatMessageContentPart CreateTextMessageContentPart(string text);
public static implicit operator ChatMessageContentPart(string content);
public static ChatMessageContentPart CreateImagePart(BinaryData imageBytes, string imageBytesMediaType, ChatImageDetailLevel? imageDetailLevel = null);
public static ChatMessageContentPart CreateImagePart(Uri imageUri, ChatImageDetailLevel? imageDetailLevel = null);
public static ChatMessageContentPart CreateRefusalPart(string refusal);
public static ChatMessageContentPart CreateTextPart(string text);
public static implicit operator ChatMessageContentPart(string text);
ChatMessageContentPart IJsonModel<ChatMessageContentPart>.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options);
void IJsonModel<ChatMessageContentPart>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options);
ChatMessageContentPart IPersistableModel<ChatMessageContentPart>.Create(BinaryData data, ModelReaderWriterOptions options);
string IPersistableModel<ChatMessageContentPart>.GetFormatFromOptions(ModelReaderWriterOptions options);
BinaryData IPersistableModel<ChatMessageContentPart>.Write(ModelReaderWriterOptions options);
public override string ToString();
}
public readonly partial struct ChatMessageContentPartKind : IEquatable<ChatMessageContentPartKind> {
private readonly object _dummy;
Expand Down Expand Up @@ -1525,23 +1541,6 @@ public class FunctionChatMessage : ChatMessage, IJsonModel<FunctionChatMessage>,
BinaryData IPersistableModel<FunctionChatMessage>.Write(ModelReaderWriterOptions options);
protected internal override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options);
}
public readonly partial struct ImageChatMessageContentPartDetail : IEquatable<ImageChatMessageContentPartDetail> {
private readonly object _dummy;
private readonly int _dummyPrimitive;
public ImageChatMessageContentPartDetail(string value);
public static ImageChatMessageContentPartDetail Auto { get; }
public static ImageChatMessageContentPartDetail High { get; }
public static ImageChatMessageContentPartDetail Low { get; }
public readonly bool Equals(ImageChatMessageContentPartDetail other);
[EditorBrowsable(EditorBrowsableState.Never)]
public override readonly bool Equals(object obj);
[EditorBrowsable(EditorBrowsableState.Never)]
public override readonly int GetHashCode();
public static bool operator ==(ImageChatMessageContentPartDetail left, ImageChatMessageContentPartDetail right);
public static implicit operator ImageChatMessageContentPartDetail(string value);
public static bool operator !=(ImageChatMessageContentPartDetail left, ImageChatMessageContentPartDetail right);
public override readonly string ToString();
}
public static class OpenAIChatModelFactory {
public static ChatCompletion ChatCompletion(string id = null, ChatFinishReason finishReason = ChatFinishReason.Stop, IEnumerable<ChatMessageContentPart> content = null, string refusal = null, IEnumerable<ChatToolCall> toolCalls = null, ChatMessageRole role = ChatMessageRole.System, ChatFunctionCall functionCall = null, IEnumerable<ChatTokenLogProbabilityInfo> contentTokenLogProbabilities = null, IEnumerable<ChatTokenLogProbabilityInfo> refusalTokenLogProbabilities = null, DateTimeOffset createdAt = default, string model = null, string systemFingerprint = null, ChatTokenUsage usage = null);
public static ChatTokenLogProbabilityInfo ChatTokenLogProbabilityInfo(string token = null, float logProbability = 0, IEnumerable<int> utf8ByteValues = null, IEnumerable<ChatTokenTopLogProbabilityInfo> topLogProbabilities = null);
Expand Down
41 changes: 0 additions & 41 deletions .dotnet/examples/Chat/Example01_SimpleChat_Cancellations.cs

This file was deleted.

4 changes: 2 additions & 2 deletions .dotnet/examples/Chat/Example05_ChatWithVision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public void Example05_ChatWithVision()

List<ChatMessage> messages = [
new UserChatMessage(
ChatMessageContentPart.CreateTextMessageContentPart("Please describe the following image."),
ChatMessageContentPart.CreateImageMessageContentPart(imageBytes, "image/png"))
ChatMessageContentPart.CreateTextPart("Please describe the following image."),
ChatMessageContentPart.CreateImagePart(imageBytes, "image/png"))
];

ChatCompletion chatCompletion = client.CompleteChat(messages);
Expand Down
4 changes: 2 additions & 2 deletions .dotnet/examples/Chat/Example05_ChatWithVisionAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public async Task Example05_ChatWithVisionAsync()

List<ChatMessage> messages = [
new UserChatMessage(
ChatMessageContentPart.CreateTextMessageContentPart("Please describe the following image."),
ChatMessageContentPart.CreateImageMessageContentPart(imageBytes, "image/png"))
ChatMessageContentPart.CreateTextPart("Please describe the following image."),
ChatMessageContentPart.CreateImagePart(imageBytes, "image/png"))
];

ChatCompletion chatCompletion = await client.CompleteChatAsync(messages);
Expand Down
2 changes: 1 addition & 1 deletion .dotnet/examples/Chat/Example07_StructuredOutputs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void Example07_StructuredOutputs()
};

ChatCompletion chatCompletion = client.CompleteChat(
["How can I solve 8x + 7 = -23?"],
[ new UserChatMessage("How can I solve 8x + 7 = -23?") ],
options);

using JsonDocument structuredJson = JsonDocument.Parse(chatCompletion.ToString());
Expand Down
2 changes: 1 addition & 1 deletion .dotnet/examples/Chat/Example07_StructuredOutputsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async Task Example07_StructuredOutputsAsync()
};

ChatCompletion chatCompletion = await client.CompleteChatAsync(
["How can I solve 8x + 7 = -23?"],
[ new UserChatMessage("How can I solve 8x + 7 = -23?") ],
options);

using JsonDocument structuredJson = JsonDocument.Parse(chatCompletion.ToString());
Expand Down
8 changes: 4 additions & 4 deletions .dotnet/examples/CombinationExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public void AlpacaArtAssessor()
new SystemChatMessage("Assume the role of a cranky art critic. When asked to describe or "
+ "evaluate imagery, focus on criticizing elements of subject, composition, and other details."),
new UserChatMessage(
ChatMessageContentPart.CreateTextMessageContentPart("describe the following image in a few sentences"),
ChatMessageContentPart.CreateImageMessageContentPart(imageGeneration.ImageUri)),
ChatMessageContentPart.CreateTextPart("describe the following image in a few sentences"),
ChatMessageContentPart.CreateImagePart(imageGeneration.ImageUri)),
],
new ChatCompletionOptions()
{
Expand Down Expand Up @@ -120,8 +120,8 @@ public async Task CuriousCreatureCreator()
[
new SystemChatMessage("Assume the role of an art critic. Although usually cranky and occasionally even referred to as a 'curmudgeon', you're somehow entirely smitten with the subject presented to you and, despite your best efforts, can't help but lavish praise when you're asked to appraise a provided image."),
new UserChatMessage(
ChatMessageContentPart.CreateTextMessageContentPart("Evaluate this image for me. What is it, and what do you think of it?"),
ChatMessageContentPart.CreateImageMessageContentPart(imageLocation)),
ChatMessageContentPart.CreateTextPart("Evaluate this image for me. What is it, and what do you think of it?"),
ChatMessageContentPart.CreateImagePart(imageLocation)),
],
new ChatCompletionOptions()
{
Expand Down
4 changes: 2 additions & 2 deletions .dotnet/src/Custom/Chat/ChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public virtual AsyncCollectionResult<StreamingChatCompletionUpdate> CompleteChat

async Task<ClientResult> getResultAsync() =>
await CompleteChatAsync(content, cancellationToken.ToRequestOptions(streaming: true)).ConfigureAwait(false);
return new AsyncStreamingChatCompletionUpdateCollection(getResultAsync);
return new InternalAsyncStreamingChatCompletionUpdateCollection(getResultAsync);
}

/// <summary>
Expand All @@ -206,7 +206,7 @@ public virtual CollectionResult<StreamingChatCompletionUpdate> CompleteChatStrea

using BinaryContent content = options.ToBinaryContent();
ClientResult getResult() => CompleteChat(content, cancellationToken.ToRequestOptions(streaming: true));
return new StreamingChatCompletionUpdateCollection(getResult);
return new InternalStreamingChatCompletionUpdateCollection(getResult);
}

/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions .dotnet/src/Custom/Chat/ChatImageDetailLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace OpenAI.Chat;

/// <summary>
/// The level of detail with which the model should process the image and generate its textual understanding of
/// it. Learn more in the <see href="https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding">vision guide</see>.
/// </summary>
[CodeGenModel("ChatCompletionRequestMessageContentPartImageImageUrlDetail")]
public readonly partial struct ChatImageDetailLevel
{
}
2 changes: 1 addition & 1 deletion .dotnet/src/Custom/Chat/ChatMessage.Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static void DeserializeContentValue(JsonProperty property, ref IList<Ch
}
else if (property.Value.ValueKind == JsonValueKind.String)
{
content.Add(ChatMessageContentPart.CreateTextMessageContentPart(property.Value.GetString()));
content.Add(ChatMessageContentPart.CreateTextPart(property.Value.GetString()));
}
else if (property.Value.ValueKind == JsonValueKind.Array)
{
Expand Down
5 changes: 3 additions & 2 deletions .dotnet/src/Custom/Chat/ChatMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ protected internal ChatMessage(ChatMessageRole role, IEnumerable<ChatMessageCont
}

protected internal ChatMessage(ChatMessageRole role, string content)
: this(role, content is null ? null : [ChatMessageContentPart.CreateTextMessageContentPart(content)])
{ }
: this(role, content is null ? null : [ChatMessageContentPart.CreateTextPart(content)])
{
}

/// <summary>
/// The content associated with the message. The interpretation of this content will vary depending on the message type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal static void WriteCoreContentPart(ChatMessageContentPart instance, Utf8J
else if (instance._kind == ChatMessageContentPartKind.Image)
{
writer.WritePropertyName("image_url"u8);
writer.WriteObjectValue(instance._imageUrl, options);
writer.WriteObjectValue(instance._imageUri, options);
}
writer.WriteSerializedAdditionalRawData(instance.SerializedAdditionalRawData, options);
writer.WriteEndObject();
Expand Down Expand Up @@ -71,7 +71,7 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle
string kind = default;
string text = default;
string refusal = default;
InternalChatCompletionRequestMessageContentPartImageImageUrl imageUrl = default;
InternalChatCompletionRequestMessageContentPartImageImageUrl imageUri = default;
IDictionary<string, BinaryData> serializedAdditionalRawData = default;
Dictionary<string, BinaryData> rawDataDictionary = new Dictionary<string, BinaryData>();
foreach (var property in element.EnumerateObject())
Expand All @@ -88,7 +88,7 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle
}
if (property.NameEquals("image_url"u8))
{
imageUrl = InternalChatCompletionRequestMessageContentPartImageImageUrl.DeserializeInternalChatCompletionRequestMessageContentPartImageImageUrl(property.Value, options);
imageUri = InternalChatCompletionRequestMessageContentPartImageImageUrl.DeserializeInternalChatCompletionRequestMessageContentPartImageImageUrl(property.Value, options);
continue;
}
if (property.NameEquals("refusal"u8))
Expand All @@ -102,6 +102,6 @@ internal static ChatMessageContentPart DeserializeChatMessageContentPart(JsonEle
}
}
serializedAdditionalRawData = rawDataDictionary;
return new ChatMessageContentPart(kind, text, refusal, imageUrl, serializedAdditionalRawData);
return new ChatMessageContentPart(kind, text, imageUri, refusal, serializedAdditionalRawData);
}
}
Loading