Skip to content

Commit

Permalink
docs: Added new examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
HavenDV committed Aug 31, 2024
1 parent 4d76474 commit 0c4910b
Show file tree
Hide file tree
Showing 66 changed files with 583 additions and 1,923 deletions.
4 changes: 2 additions & 2 deletions src/helpers/GenerateDocs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Path.Combine(solutionDirectory, "docs", "index.md"));

Console.WriteLine($"Generating samples from {sampleDirectory}...");
foreach (var path in Directory.EnumerateFiles(sampleDirectory, "*.cs", SearchOption.AllDirectories))
foreach (var path in Directory.EnumerateFiles(sampleDirectory, "Examples.*.cs", SearchOption.AllDirectories))
{
var code = await File.ReadAllTextAsync(path);

Expand All @@ -21,7 +21,7 @@
var lines = code.Split('\n')[1..^2];
code = string.Join('\n', lines.Select(x => x.Length > 8 ? x[8..] : string.Empty));

var newPath = Path.Combine(newDir, $"{Path.GetExtension(Path.GetFileNameWithoutExtension(path)).TrimStart('.')}.md");
var newPath = Path.Combine(newDir, $"{Path.GetFileNameWithoutExtension(path).Replace("Examples.", string.Empty)}.md");
await File.WriteAllTextAsync(newPath, $@"```csharp
{code}
```");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task ListAssistantsWithPagination()
{
using var api = GetAuthenticatedClient();

int count = 0;

ListAssistantsResponse response = await api.Assistants.ListAssistantsAsync();
foreach (AssistantObject assistant in response.Data)
{
Console.WriteLine($"[{count,3}] {assistant.Id} {assistant.CreatedAt:s} {assistant.Name}");

count++;

//_ = await api.Assistants.DeleteAssistantAsync(assistant.Id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task ListFiles()
{
using var api = GetAuthenticatedClient();

int count = 0;

ListFilesResponse files = await api.Files.ListFilesAsync(purpose: CreateFileRequestPurpose.Assistants.ToValueString());
foreach (OpenAIFile file in files.Data)
{
Console.WriteLine($"[{count,3}] {file.Id} {file.CreatedAt:s} {file.Filename}");

count++;

//_ = await api.Files.DeleteFileAsync(file.Id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System.Text;

namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task RetrievalAugmentedGeneration()
{
using var api = GetAuthenticatedClient();

// First, let's contrive a document we'll use retrieval with and upload it.
string document = /* language=json */
"""
{
"description": "This document contains the sale history data for Contoso products.",
"sales": [
{
"month": "January",
"by_product": {
"113043": 15,
"113045": 12,
"113049": 2
}
},
{
"month": "February",
"by_product": {
"113045": 22
}
},
{
"month": "March",
"by_product": {
"113045": 16,
"113055": 5
}
}
]
}
""";

OpenAIFile salesFile = await api.Files.CreateFileAsync(
file: Encoding.UTF8.GetBytes(document),
filename: "monthly_sales.json",
purpose: CreateFileRequestPurpose.Assistants);

AssistantObject assistant = await api.Assistants.CreateAssistantAsync(
model: CreateAssistantRequestModel.Gpt4o,
name: "Example: Contoso sales RAG",
instructions: "You are an assistant that looks up sales data and helps visualize the information based"
+ " on user queries. When asked to generate a graph, chart, or other visualization, use"
+ " the code interpreter tool to do so.",
tools:
[
new AssistantToolsFileSearch(),
new AssistantToolsCode(),
],
toolResources: new CreateAssistantRequestToolResources
{
FileSearch = new CreateAssistantRequestToolResourcesFileSearch
{
VectorStores =
[
new CreateAssistantRequestToolResourcesFileSearchVectorStore
{
FileIds = [salesFile.Id],
}
],
}
});

// Now we'll create a thread with a user query about the data already associated with the assistant, then run it
RunObject threadRun = await api.Assistants.CreateThreadAndRunAsync(
assistantId: assistant.Id,
thread: new CreateThreadRequest
{
Messages = new List<CreateMessageRequest>
{
new()
{
Role = CreateMessageRequestRole.User,
Content = "How well did product 113045 sell in February? Graph its trend over time.",
},
},
});

// Check back to see when the run is done
do
{
await Task.Delay(TimeSpan.FromSeconds(1));

threadRun = await api.Assistants.GetRunAsync(
threadId: threadRun.ThreadId,
runId: threadRun.Id);
} while (threadRun.Status is RunObjectStatus.Queued or RunObjectStatus.InProgress);

// Finally, we'll print out the full history for the thread that includes the augmented generation
// TODO: IAsyncEnumerable pagination
ListMessagesResponse messages
= await api.Assistants.ListMessagesAsync(
threadId: threadRun.ThreadId); // ListOrder.OldestFirst

foreach (MessageObject message in messages.Data)
{
Console.Write($"[{message.Role.ToString().ToUpper()}]: ");
foreach (OneOf<
MessageContentImageFileObject,
MessageContentImageUrlObject,
MessageContentTextObject,
MessageContentRefusalObject> contentItem in message.Content)
{
if (contentItem.IsValue3)
{
Console.WriteLine($"{contentItem.Value3.Text.Value}");

if (contentItem.Value3.Text.Annotations.Count > 0)
{
Console.WriteLine();
}

// Include annotations, if any.
foreach (OneOf<
MessageContentTextAnnotationsFileCitationObject,
MessageContentTextAnnotationsFilePathObject> annotation in contentItem.Value3.Text.Annotations)
{
if (annotation.IsValue1 && !string.IsNullOrEmpty(annotation.Value1.FileCitation.FileId))
{
Console.WriteLine($"* File citation, file ID: {annotation.Value1.FileCitation.FileId}");
}
if (annotation.IsValue2 && !string.IsNullOrEmpty(annotation.Value2.FilePath.FileId))
{
Console.WriteLine($"* File output, new file ID: {annotation.Value2.FilePath.FileId}");
}
}
}
if (contentItem.IsValue1)
{
OpenAIFile imageInfo = await api.Files.RetrieveFileAsync(contentItem.Value1.ImageFile.FileId);
byte[] imageBytes = await api.Files.DownloadFileAsync(contentItem.Value1.ImageFile.FileId);

FileInfo fileInfo = new($"{imageInfo.Filename}.png");

await File.WriteAllBytesAsync(fileInfo.FullName, imageBytes);

Console.WriteLine($"<image: {new Uri(fileInfo.FullName).AbsoluteUri}>");
}
}
Console.WriteLine();
}

// Optionally, delete any persistent resources you no longer need.
_ = await api.Assistants.DeleteThreadAsync(threadRun.ThreadId);
_ = await api.Assistants.DeleteAssistantAsync(assistant.Id);
_ = await api.Files.DeleteFileAsync(salesFile.Id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task SimpleTextToSpeech()
{
using var api = GetAuthenticatedClient();

byte[] bytes = await api.Audio.CreateSpeechAsync(
model: CreateSpeechRequestModel.Tts1,
input: "Overwatering is a common issue for those taking care of houseplants. To prevent it, it is"
+ " crucial to allow the soil to dry out between waterings. Instead of watering on a fixed schedule,"
+ " consider using a moisture meter to accurately gauge the soil’s wetness. Should the soil retain"
+ " moisture, it is wise to postpone watering for a couple more days. When in doubt, it is often safer"
+ " to water sparingly and maintain a less-is-more approach.",
voice: CreateSpeechRequestVoice.Alloy);

FileInfo fileInfo = new($"{Guid.NewGuid()}.mp3");

await File.WriteAllBytesAsync(fileInfo.FullName, bytes);

Console.WriteLine($"Audio available at:\n{new Uri(fileInfo.FullName).AbsoluteUri}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task SimpleTranscription()
{
using var api = GetAuthenticatedClient();

OneOf<CreateTranscriptionResponseJson, CreateTranscriptionResponseVerboseJson> response = await api.Audio.CreateTranscriptionAsync(
file: H.Resources.audio_houseplant_care_mp3.AsBytes(),
filename: H.Resources.audio_houseplant_care_mp3.FileName,
model: CreateTranscriptionRequestModel.Whisper1);

Console.WriteLine($"{response.Value1?.Text}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task SimpleTranslation()
{
using var api = GetAuthenticatedClient();

OneOf<CreateTranslationResponseJson, CreateTranslationResponseVerboseJson> response = await api.Audio.CreateTranslationAsync(
file: H.Resources.audio_french_wav.AsBytes(),
filename: H.Resources.audio_french_wav.FileName,
model: CreateTranslationRequestModel.Whisper1);

Console.WriteLine($"{response.Value1?.Text}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
// TODO: Does not work yet
public async Task VerboseTranscription()
{
using var api = GetAuthenticatedClient();

OneOf<CreateTranscriptionResponseJson, CreateTranscriptionResponseVerboseJson> response = await api.Audio.CreateTranscriptionAsync(
file: H.Resources.audio_houseplant_care_mp3.AsBytes(),
filename: H.Resources.audio_houseplant_care_mp3.FileName,
model: CreateTranscriptionRequestModel.Whisper1,
responseFormat: CreateTranscriptionRequestResponseFormat.VerboseJson,
timestampGranularities: [
CreateTranscriptionRequestTimestampGranularitie.Word,
CreateTranscriptionRequestTimestampGranularitie.Segment
]);

response.Value2.Should().NotBeNull();

Console.WriteLine("Transcription:");
Console.WriteLine($"{response.Value2!.Text}");

Console.WriteLine();
Console.WriteLine($"Words:");
foreach (TranscriptionWord word in response.Value2.Words ?? [])
{
Console.WriteLine($" {word.Word,15} : {word.Start * 1000,5:0} - {word.End * 1000,5:0}");
}

Console.WriteLine();
Console.WriteLine($"Segments:");
foreach (TranscriptionSegment segment in response.Value2.Segments ?? [])
{
Console.WriteLine($" {segment.Text,90} : {segment.Start * 1000,5:0} - {segment.End * 1000,5:0}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task ChatWithVision()
{
using var api = GetAuthenticatedClient();

CreateChatCompletionResponse response = await api.Chat.CreateChatCompletionAsync(
messages: [
"Please describe the following image.",
H.Resources.images_dog_and_cat_png.AsBytes().AsUserMessage(mimeType: "image/png"),
],
model: CreateChatCompletionRequestModel.Gpt4o);

Console.WriteLine("[ASSISTANT]:");
Console.WriteLine($"{response.Choices[0].Message.Content}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task SimpleChat()
{
using var api = GetAuthenticatedClient();

CreateChatCompletionResponse response = await api.Chat.CreateChatCompletionAsync(
messages: ["Say 'this is a test.'"],
model: CreateChatCompletionRequestModel.Gpt4o);

Console.WriteLine("[ASSISTANT]:");
Console.WriteLine($"{response.Choices[0].Message.Content}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace OpenAI.IntegrationTests.Examples;

public partial class Examples
{
[Test]
[Explicit]
public async Task SimpleChatStreaming()
{
using var api = GetAuthenticatedClient();

IAsyncEnumerable<CreateChatCompletionStreamResponse> enumerable = api.Chat.CreateChatCompletionAsStreamAsync(
messages: ["Say 'this is a test.'"],
model: CreateChatCompletionRequestModel.Gpt4o);

Console.WriteLine("[ASSISTANT]:");
await foreach (CreateChatCompletionStreamResponse chatUpdate in enumerable)
{
Console.Write(chatUpdate.Choices[0].Delta.Content);
}
}
}
Loading

0 comments on commit 0c4910b

Please sign in to comment.