Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Misc. fixes
  • Loading branch information
joseharriaga committed Nov 1, 2024
commit f3b6a4b3fc270809139030d7797d789d53e2e17b
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is used to automatically assign reviewers to PRs.
# For more information, see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

# The '*' pattern represents global owners.
* @joseharriaga @trrwilson @ShivangiReja
30 changes: 13 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,22 @@

### Features added

- `ChatCompletionOptions` now has an `StoredOutputEnabled` property (reflecting [the REST `store` property](https://platform.openai.com/docs/api-reference/chat/create#chat-create-store)) as well as a `Metadata` property ([`metadata` in REST](https://platform.openai.com/docs/api-reference/chat/create#chat-create-metadata))
- `ChatTokenUsage` (`Usage` on `ChatCompletion`) has been expanded:
- A new `InputTokenDetails` property (of new type `ChatInputTokenUsageDetails`) has been added, containing breakdowns of `AudioTokenCount` and `CachedTokenCount` for usage with supported models
- The existing `OutputTokenDetails` has been expanded to include `AudioTokenCount` for supported models
- `ModerationResult` now includes `Illicit` and `IllictViolent` categories
- `ModerationCategory` now includes a (bitmasked flag enum) `ApplicableInputKinds` property, representing applied input types for the category

**Realtime**

***Note**: the `/realtime` area is under rapid development and not all changes may be reflected here.*

- `ConversationRateLimitsUpdate` (previously `ConversationRateLimitsUpdatedUpdate`) now includes named `RequestDetails` and `TokenDetails` properties, mapping to the corresponding named items in the underlying `rate_limits` command payload
- Several types have been renamed for consistency and clarity

## 2.0.1 (Unreleased)
- Added a `StoredOutputEnabled` property to `ChatCompletionOptions` ([`store` in the REST API](https://platform.openai.com/docs/api-reference/chat/create#chat-create-store)). (commit_hash)
- Use this property to indicate whether or not to store the output of the chat completion for use in model distillation or evals.
- Added a `Metadata` property to `ChatCompletionOptions` ([`metadata` in the REST API](https://platform.openai.com/docs/api-reference/chat/create#chat-create-metadata)). (commit_hash)
- Use this property to add custom tags and values to the chat completions for filtering in the OpenAI dashboard.
- Added an `InputTokenDetails` property to `ChatTokenUsage` ([`usage.prompt_token_details` in the REST API](https://platform.openai.com/docs/api-reference/chat/object#chat/object-usage)). (commit_hash)
- The property is of a new type called `ChatInputTokenUsageDetails`, which contains properties for `AudioTokenCount` and `CachedTokenCount` for usage with supported models.
- Added an `AudioTokenCount` property to `ChatOutputTokenUsageDetails` ([`usage.completion_token_details` in the REST API](https://platform.openai.com/docs/api-reference/chat/object#chat/object-usage)). Audio support in chat completions is coming soon. (commit_hash)
- Added `Illicit` and `IllictViolent` properties `ModerationResult` to represent these two new moderation categories. (commit_hash)
- Made improvements to the experimental Realtime API. Please note this features area is currently under rapid development and not all changes may be reflected here. (commit_hash)
- Several types have been renamed for consistency and clarity.
- `ConversationRateLimitsUpdate` (previously `ConversationRateLimitsUpdatedUpdate`) now includes named `RequestDetails` and `TokenDetails` properties, mapping to the corresponding named items in the underlying `rate_limits` command payload.

### Other Changes

- Updated the referenced version of `System.ClientModel` to the latest `1.21.0`
- This transitively updates an inherited `System.Text.Json` dependency from `6.0.9` to `6.0.10`, resolving security compliance with [CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4). Please note that the described vulnerability was not directly applicable to this library as `[ExtensionData]` is not used.
- Updated the `System.ClientModel` dependency to version `1.21.0`. (commit_hash)
- This updates the `System.Text.Json` transitive dependency to version `6.0.10`, which includes a security compliance fix for [CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4). Please note that the OpenAI library was not impacted by this vulnerability since it does not use the `[JsonExtensionData]` feature.

## 2.1.0-beta.1 (2024-10-01)

Expand Down
6 changes: 3 additions & 3 deletions examples/Assistants/Example01_RetrievalAugmentedGeneration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ public partial class AssistantExamples
public void Example01_RetrievalAugmentedGeneration()
{
// Assistants is a beta API and subject to change; acknowledge its experimental status by suppressing the matching warning.
#pragma warning disable OPENAI001
#pragma warning disable OPENAI001
OpenAIClient openAIClient = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
AssistantClient assistantClient = openAIClient.GetAssistantClient();

// First, let's contrive a document we'll use retrieval with and upload it.
using Stream document = BinaryData.FromString("""
using Stream document = BinaryData.FromBytes("""
{
"description": "This document contains the sale history data for Contoso products.",
"sales": [
Expand All @@ -47,7 +47,7 @@ public void Example01_RetrievalAugmentedGeneration()
}
]
}
""").ToStream();
"""u8.ToArray()).ToStream();

OpenAIFile salesFile = fileClient.UploadFile(
document,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ public partial class AssistantExamples
public async Task Example01_RetrievalAugmentedGenerationAsync()
{
// Assistants is a beta API and subject to change; acknowledge its experimental status by suppressing the matching warning.
#pragma warning disable OPENAI001
#pragma warning disable OPENAI001
OpenAIClient openAIClient = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
AssistantClient assistantClient = openAIClient.GetAssistantClient();

// First, let's contrive a document we'll use retrieval with and upload it.
using Stream document = BinaryData.FromString("""
using Stream document = BinaryData.FromBytes("""
{
"description": "This document contains the sale history data for Contoso products.",
"sales": [
Expand All @@ -48,7 +48,7 @@ public async Task Example01_RetrievalAugmentedGenerationAsync()
}
]
}
""").ToStream();
"""u8.ToArray()).ToStream();

OpenAIFile salesFile = await fileClient.UploadFileAsync(
document,
Expand Down
7 changes: 4 additions & 3 deletions examples/Assistants/Example05_AssistantsWithVision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ public partial class AssistantExamples
public void Example05_AssistantsWithVision()
{
// Assistants is a beta API and subject to change; acknowledge its experimental status by suppressing the matching warning.
#pragma warning disable OPENAI001
#pragma warning disable OPENAI001
OpenAIClient openAIClient = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
AssistantClient assistantClient = openAIClient.GetAssistantClient();

OpenAIFile pictureOfAppleFile = fileClient.UploadFile(
Path.Combine("Assets", "picture-of-apple.png"),
Path.Combine("Assets", "images_apple.png"),
FileUploadPurpose.Vision);
Uri linkToPictureOfOrange = new("https://raw.githubusercontent.com/openai/openai-dotnet/refs/heads/main/examples/Assets/picture-of-orange.png");

Uri linkToPictureOfOrange = new("https://raw.githubusercontent.com/openai/openai-dotnet/refs/heads/main/examples/Assets/images_orange.png");

Assistant assistant = assistantClient.CreateAssistant(
"gpt-4o",
Expand Down
7 changes: 4 additions & 3 deletions examples/Assistants/Example05_AssistantsWithVisionAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ public partial class AssistantExamples
public async Task Example05_AssistantsWithVisionAsync()
{
// Assistants is a beta API and subject to change; acknowledge its experimental status by suppressing the matching warning.
#pragma warning disable OPENAI001
#pragma warning disable OPENAI001
OpenAIClient openAIClient = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
AssistantClient assistantClient = openAIClient.GetAssistantClient();

OpenAIFile pictureOfAppleFile = await fileClient.UploadFileAsync(
Path.Combine("Assets", "picture-of-apple.png"),
Path.Combine("Assets", "images_apple.png"),
FileUploadPurpose.Vision);
Uri linkToPictureOfOrange = new("https://raw.githubusercontent.com/openai/openai-dotnet/refs/heads/main/examples/Assets/picture-of-orange.png");

Uri linkToPictureOfOrange = new("https://raw.githubusercontent.com/openai/openai-dotnet/refs/heads/main/examples/Assets/images_orange.png");

Assistant assistant = await assistantClient.CreateAssistantAsync(
"gpt-4o",
Expand Down
3 changes: 1 addition & 2 deletions examples/Chat/Example02_SimpleChatStreaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ public void Example02_SimpleChatStreaming()
{
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

CollectionResult<StreamingChatCompletionUpdate> completionUpdates
= client.CompleteChatStreaming("Say 'this is a test.'");
CollectionResult<StreamingChatCompletionUpdate> completionUpdates = client.CompleteChatStreaming("Say 'this is a test.'");

Console.Write($"[ASSISTANT]: ");
foreach (StreamingChatCompletionUpdate completionUpdate in completionUpdates)
Expand Down
3 changes: 1 addition & 2 deletions examples/Chat/Example02_SimpleChatStreamingAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public async Task Example02_SimpleChatStreamingAsync()
{
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

AsyncCollectionResult<StreamingChatCompletionUpdate> completionUpdates
= client.CompleteChatStreamingAsync("Say 'this is a test.'");
AsyncCollectionResult<StreamingChatCompletionUpdate> completionUpdates = client.CompleteChatStreamingAsync("Say 'this is a test.'");

Console.Write($"[ASSISTANT]: ");
await foreach (StreamingChatCompletionUpdate completionUpdate in completionUpdates)
Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example03_FunctionCalling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static string GetCurrentWeather(string location, string unit = "celsius"
private static readonly ChatTool getCurrentWeatherTool = ChatTool.CreateFunctionTool(
functionName: nameof(GetCurrentWeather),
functionDescription: "Get the current weather in a given location",
functionParameters: BinaryData.FromString("""
functionParameters: BinaryData.FromBytes("""
{
"type": "object",
"properties": {
Expand All @@ -47,7 +47,7 @@ private static string GetCurrentWeather(string location, string unit = "celsius"
},
"required": [ "location" ]
}
""")
"""u8.ToArray())
);
#endregion

Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example06_StructuredOutputs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void Example06_StructuredOutputs()
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
jsonSchemaFormatName: "math_reasoning",
jsonSchema: BinaryData.FromString("""
jsonSchema: BinaryData.FromBytes("""
{
"type": "object",
"properties": {
Expand All @@ -43,7 +43,7 @@ public void Example06_StructuredOutputs()
"required": ["steps", "final_answer"],
"additionalProperties": false
}
"""),
"""u8.ToArray()),
jsonSchemaIsStrict: true)
};

Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example06_StructuredOutputsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public async Task Example06_StructuredOutputsAsync()
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
jsonSchemaFormatName: "math_reasoning",
jsonSchema: BinaryData.FromString("""
jsonSchema: BinaryData.FromBytes("""
{
"type": "object",
"properties": {
Expand All @@ -44,7 +44,7 @@ public async Task Example06_StructuredOutputsAsync()
"required": ["steps", "final_answer"],
"additionalProperties": false
}
"""),
"""u8.ToArray()),
jsonSchemaIsStrict: true)
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public async Task Example01_AudioFromFileWithToolsAsync()
await session.AddItemAsync(
ConversationItem.CreateUserMessage(["I'm trying to decide what to wear on my trip."]));

string inputAudioPath = FindFile("Assets\\whats_the_weather_pcm16_24khz_mono.wav");
string inputAudioPath = FindFile("Assets\\realtime_whats_the_weather_pcm16_24khz_mono.wav");
using Stream inputAudioStream = File.OpenRead(inputAudioPath);
_ = session.SendInputAudioAsync(inputAudioStream);

Expand Down
4 changes: 2 additions & 2 deletions tests/RealtimeConversation/ConversationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public async Task AudioWithToolsWorks()

await session.ConfigureSessionAsync(options, CancellationToken);

using Stream audioStream = File.OpenRead(Path.Join("Assets", "whats_the_weather_pcm16_24khz_mono.wav"));
using Stream audioStream = File.OpenRead(Path.Join("Assets", "realtime_whats_the_weather_pcm16_24khz_mono.wav"));
_ = session.SendInputAudioAsync(audioStream, CancellationToken);

string userTranscript = null;
Expand Down Expand Up @@ -348,7 +348,7 @@ await session.ConfigureSessionAsync(
CancellationToken);

const string folderName = "Assets";
const string fileName = "whats_the_weather_pcm16_24khz_mono.wav";
const string fileName = "realtime_whats_the_weather_pcm16_24khz_mono.wav";
#if NET6_0_OR_GREATER
using Stream audioStream = File.OpenRead(Path.Join(folderName, fileName));
#else
Expand Down
Loading