Skip to content

Commit

Permalink
Add serialization/deserialization example with chat completions (open…
Browse files Browse the repository at this point in the history
…ai#124)

Added example illustrating how to serialize and deserialize a list of `ChatMessage`. We are also working to make this simpler in the future.

This change also refactors a few examples and tests.
  • Loading branch information
joseharriaga authored Sep 22, 2024
1 parent bbac88f commit 7a8bc8b
Show file tree
Hide file tree
Showing 22 changed files with 384 additions and 129 deletions.
34 changes: 9 additions & 25 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,16 @@ body:
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: checkboxes
id: non_python
- type: dropdown
id: service-kind
attributes:
label: Confirm this is not an issue with the OpenAI Python Library
description: Issues with the OpenAI Python Library should be reported in our [OpenAI Python SDK repo](https://github.com/openai/openai-python/issues)
label: Service
description: Select whether you are using OpenAI or Azure OpenAI
options:
- label: This is not an issue with the OpenAI Python Library
required: true
- type: checkboxes
id: non_api
attributes:
label: Confirm this is not an issue with the underlying OpenAI API
description: Issues with the underlying OpenAI API should be reported in our [Developer Community](https://community.openai.com/c/api/7)
options:
- label: This is not an issue with the OpenAI API
required: true
- type: checkboxes
id: non_azure
attributes:
label: Confirm this is not an issue with Azure OpenAI
description: Issues related to Azure OpenAI should be reported in the [Azure SDK repo](https://github.com/Azure/azure-sdk-for-net/issues)
options:
- label: This is not an issue with Azure OpenAI
required: true
- OpenAI
- Azure OpenAI
validations:
required: true
- type: textarea
id: what-happened
attributes:
Expand All @@ -41,7 +27,7 @@ body:
- type: textarea
id: repro-steps
attributes:
label: To Reproduce
label: Steps to reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Fetch a '...'
Expand All @@ -68,13 +54,11 @@ body:
id: language-version
attributes:
label: .NET version
placeholder:
validations:
required: true
- type: input
id: lib-version
attributes:
label: Library version
placeholder:
validations:
required: true
16 changes: 4 additions & 12 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,15 @@ body:
- type: checkboxes
id: non_api
attributes:
label: Confirm this is not a feature request for the underlying OpenAI API.
description: Feature requests for the underlying OpenAI API should be reported in our [Developer Community](https://community.openai.com/c/api/7)
label: Confirm this is a feature request for the .NET library and not the underlying OpenAI API
description: Feature requests for the underlying OpenAI API should be reported on our [Developer Community](https://community.openai.com/c/api/7)
options:
- label: This is not a feature request for the underlying OpenAI API
required: true
- type: checkboxes
id: non_azure
attributes:
label: Confirm this is not a feature request for Azure OpenAI.
description: Feature requests for Azure OpenAI should be reported reported in the [Azure SDK repo](https://github.com/Azure/azure-sdk-for-net/issues)
options:
- label: This is not a feature request for Azure OpenAI
- label: This is a feature request for the .NET library
required: true
- type: textarea
id: feature
attributes:
label: Describe the feature or improvement you're requesting
label: Describe the feature or improvement you are requesting
description: A clear and concise description of what you want to happen.
validations:
required: true
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ It is generated from our [OpenAPI specification](https://github.com/openai/opena
- [Using the `OpenAIClient` class](#using-the-openaiclient-class)
- [How to use chat completions with streaming](#how-to-use-chat-completions-with-streaming)
- [How to use chat completions with tools and function calling](#how-to-use-chat-completions-with-tools-and-function-calling)
- [How to use structured outputs](#how-to-use-structured-outputs)
- [How to use chat completions with structured outputs](#how-to-use-structured-outputs)
- [How to generate text embeddings](#how-to-generate-text-embeddings)
- [How to generate images](#how-to-generate-images)
- [How to transcribe audio](#how-to-transcribe-audio)
Expand Down Expand Up @@ -65,19 +65,19 @@ While you can pass your API key directly as a string, it is highly recommended t

The library is organized into several namespaces corresponding to OpenAI feature areas. Each namespace contains a corresponding client class.

| Namespace | Client class | Notes |
| ------------------------------|------------------------------|---------------------|
| `OpenAI.Assistants` | `AssistantClient` | \[Experimental\] |
| `OpenAI.Audio` | `AudioClient` | |
| `OpenAI.Batch` | `BatchClient` | |
| `OpenAI.Chat` | `ChatClient` | |
| `OpenAI.Embeddings` | `EmbeddingClient` | |
| `OpenAI.FineTuning` | `FineTuningClient` | |
| `OpenAI.Files` | `FileClient` | |
| `OpenAI.Images` | `ImageClient` | |
| `OpenAI.Models` | `ModelClient` | |
| `OpenAI.Moderations` | `ModerationClient` | |
| `OpenAI.VectorStores` | `VectorStoreClient` | \[Experimental\] |
| Namespace | Client class | Notes |
| ------------------------------|------------------------------|-------------------------------------------------------------------|
| `OpenAI.Assistants` | `AssistantClient` | ![Experimental](https://img.shields.io/badge/experimental-purple) |
| `OpenAI.Audio` | `AudioClient` | |
| `OpenAI.Batch` | `BatchClient` | ![Experimental](https://img.shields.io/badge/experimental-purple) |
| `OpenAI.Chat` | `ChatClient` | |
| `OpenAI.Embeddings` | `EmbeddingClient` | |
| `OpenAI.FineTuning` | `FineTuningClient` | ![Experimental](https://img.shields.io/badge/experimental-purple) |
| `OpenAI.Files` | `FileClient` | |
| `OpenAI.Images` | `ImageClient` | |
| `OpenAI.Models` | `ModelClient` | |
| `OpenAI.Moderations` | `ModerationClient` | |
| `OpenAI.VectorStores` | `VectorStoreClient` | ![Experimental](https://img.shields.io/badge/experimental-purple) |

### Using the async API

Expand Down Expand Up @@ -297,7 +297,7 @@ do
} while (requiresAction);
```

## How to use structured outputs
## How to use chat completions with structured outputs

Beginning with the `gpt-4o-mini`, `gpt-4o-mini-2024-07-18`, and `gpt-4o-2024-08-06` model snapshots, structured outputs are available for both top-level response content and tool calls in the chat completion and assistants APIs.

Expand Down
2 changes: 1 addition & 1 deletion examples/Chat/Example01_SimpleChat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public partial class ChatExamples
[Test]
public void Example01_SimpleChat()
{
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

ChatCompletion completion = client.CompleteChat("Say 'this is a test.'");

Expand Down
2 changes: 1 addition & 1 deletion examples/Chat/Example01_SimpleChatAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public partial class ChatExamples
[Test]
public async Task Example01_SimpleChatAsync()
{
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

ChatCompletion completion = await client.CompleteChatAsync("Say 'this is a test.'");

Expand Down
2 changes: 1 addition & 1 deletion examples/Chat/Example02_SimpleChatStreaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public partial class ChatExamples
[Test]
public void Example02_SimpleChatStreaming()
{
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

CollectionResult<StreamingChatCompletionUpdate> updates
= client.CompleteChatStreaming("Say 'this is a test.'");
Expand Down
2 changes: 1 addition & 1 deletion examples/Chat/Example02_SimpleChatStreamingAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class ChatExamples
[Test]
public async Task Example02_SimpleChatStreamingAsync()
{
ChatClient client = new(model: "gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatClient client = new(model: "gpt-4o", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

AsyncCollectionResult<StreamingChatCompletionUpdate> updates
= client.CompleteChatStreamingAsync("Say 'this is a test.'");
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 @@ -151,9 +151,9 @@ public void Example03_FunctionCalling()
#endregion

#region
foreach (ChatMessage requestMessage in messages)
foreach (ChatMessage message in messages)
{
switch (requestMessage)
switch (message)
{
case SystemChatMessage systemMessage:
Console.WriteLine($"[SYSTEM]:");
Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example03_FunctionCallingAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ public async Task Example03_FunctionCallingAsync()
#endregion

#region
foreach (ChatMessage requestMessage in messages)
foreach (ChatMessage message in messages)
{
switch (requestMessage)
switch (message)
{
case SystemChatMessage systemMessage:
Console.WriteLine($"[SYSTEM]:");
Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example04_FunctionCallingStreaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ StringBuilder argumentsBuilder
#endregion

#region
foreach (ChatMessage requestMessage in messages)
foreach (ChatMessage message in messages)
{
switch (requestMessage)
switch (message)
{
case SystemChatMessage systemMessage:
Console.WriteLine($"[SYSTEM]:");
Expand Down
4 changes: 2 additions & 2 deletions examples/Chat/Example04_FunctionCallingStreamingAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ StringBuilder argumentsBuilder
#endregion

#region
foreach (ChatMessage requestMessage in messages)
foreach (ChatMessage message in messages)
{
switch (requestMessage)
switch (message)
{
case SystemChatMessage systemMessage:
Console.WriteLine($"[SYSTEM]:");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace OpenAI.Examples;
public partial class ChatExamples
{
[Test]
public void Example05_ChatWithVision()
public void Example05_Vision()
{
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace OpenAI.Examples;
public partial class ChatExamples
{
[Test]
public async Task Example05_ChatWithVisionAsync()
public async Task Example05_VisionAsync()
{
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using NUnit.Framework;
using OpenAI.Chat;
using System;
using System.Collections.Generic;
using System.Text.Json;

namespace OpenAI.Examples;

public partial class ChatExamples
{
[Test]
public void Example07_StructuredOutputs()
public void Example06_StructuredOutputs()
{
ChatClient client = new("gpt-4o-mini", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

List<ChatMessage> messages = [
new UserChatMessage("How can I solve 8x + 7 = -23?"),
];

ChatCompletionOptions options = new()
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
Expand Down Expand Up @@ -41,9 +46,7 @@ public void Example07_StructuredOutputs()
jsonSchemaIsStrict: true)
};

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

using JsonDocument structuredJson = JsonDocument.Parse(chatCompletion.ToString());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NUnit.Framework;
using OpenAI.Chat;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;

Expand All @@ -9,10 +10,14 @@ namespace OpenAI.Examples;
public partial class ChatExamples
{
[Test]
public async Task Example07_StructuredOutputsAsync()
public async Task Example06_StructuredOutputsAsync()
{
ChatClient client = new("gpt-4o-mini", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

List<ChatMessage> messages = [
new UserChatMessage("How can I solve 8x + 7 = -23?"),
];

ChatCompletionOptions options = new()
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
Expand Down Expand Up @@ -42,9 +47,7 @@ public async Task Example07_StructuredOutputsAsync()
jsonSchemaIsStrict: true)
};

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

using JsonDocument structuredJson = JsonDocument.Parse(chatCompletion.ToString());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace OpenAI.Examples;
public partial class ChatExamples
{
[Test]
public void Example06_SimpleChatProtocol()
public void Example07_ChatProtocol()
{
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace OpenAI.Examples;
public partial class ChatExamples
{
[Test]
public async Task Example06_SimpleChatProtocolAsync()
public async Task Example07_ChatProtocolAsync()
{
ChatClient client = new("gpt-4o", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));

Expand Down
Loading

0 comments on commit 7a8bc8b

Please sign in to comment.