Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenAI-DotNet 7.4.2 #202

Merged
merged 4 commits into from
Dec 7, 2023
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
7 changes: 4 additions & 3 deletions OpenAI-DotNet-Tests/TestFixture_02_Completions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

namespace OpenAI.Tests
{
[Obsolete("Deprecated")]
internal class TestFixture_02_Completions : AbstractTestFixture
{
private const string CompletionPrompts = "One Two Three Four Five Six Seven Eight Nine One Two Three Four Five Six Seven Eight";

[Test]
//[Test]
public async Task Test_01_GetBasicCompletion()
{
Assert.IsNotNull(OpenAIClient.CompletionsEndpoint);
Expand All @@ -29,7 +30,7 @@ public async Task Test_01_GetBasicCompletion()
Console.WriteLine(result);
}

[Test]
//[Test]
public async Task Test_02_GetStreamingCompletion()
{
Assert.IsNotNull(OpenAIClient.CompletionsEndpoint);
Expand All @@ -47,7 +48,7 @@ await OpenAIClient.CompletionsEndpoint.StreamCompletionAsync(result =>
Console.WriteLine(allCompletions.FirstOrDefault());
}

[Test]
//[Test]
public async Task Test_03_GetStreamingEnumerableCompletion()
{
Assert.IsNotNull(OpenAIClient.CompletionsEndpoint);
Expand Down
40 changes: 26 additions & 14 deletions OpenAI-DotNet-Tests/TestFixture_11_Assistants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public async Task Test_02_ListAssistants()

foreach (var assistant in assistantsList.Items)
{
var retrieved = OpenAIClient.AssistantsEndpoint.RetrieveAssistantAsync(assistant);
var retrieved = await OpenAIClient.AssistantsEndpoint.RetrieveAssistantAsync(assistant);
Assert.IsNotNull(retrieved);
Console.WriteLine($"{assistant} -> {assistant.CreatedAt}");
Console.WriteLine($"{retrieved} -> {retrieved.CreatedAt}");
}
}

Expand Down Expand Up @@ -90,8 +90,9 @@ public async Task Test_04_01_UploadAssistantFile()
const string testFilePath = "assistant_test_2.txt";
await File.WriteAllTextAsync(testFilePath, "Knowledge is power!");
Assert.IsTrue(File.Exists(testFilePath));
var file = testAssistant.UploadFileAsync(testFilePath);
var file = await testAssistant.UploadFileAsync(testFilePath);
Assert.IsNotNull(file);
Console.WriteLine($"uploaded -> {file.Id}");
}

[Test]
Expand All @@ -102,6 +103,7 @@ public async Task Test_04_02_ListAssistantFiles()
var filesList = await testAssistant.ListFilesAsync();
Assert.IsNotNull(filesList);
Assert.IsNotEmpty(filesList.Items);
Assert.IsTrue(filesList.Items.Count == 2);

foreach (var file in filesList.Items)
{
Expand All @@ -120,25 +122,35 @@ public async Task Test_04_02_ListAssistantFiles()
}

[Test]
public async Task Test_04_03_DeleteAssistantFiles()
public async Task Test_04_03_RemoveAssistantFile()
{
Assert.IsNotNull(testAssistant);
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var filesList = await testAssistant.ListFilesAsync();
Assert.IsNotNull(filesList);
Assert.IsNotEmpty(filesList.Items);
Assert.IsTrue(filesList.Items.Count == 2);
var assistantFile = filesList.Items[0];
Assert.IsNotNull(assistantFile);
var isRemoved = await testAssistant.RemoveFileAsync(assistantFile);
Assert.IsTrue(isRemoved);
var isDeleted = await OpenAIClient.FilesEndpoint.DeleteFileAsync(assistantFile);
Assert.IsTrue(isDeleted);
}

foreach (var file in filesList.Items)
{
Assert.IsNotNull(file);
var isDeleted = await testAssistant.DeleteFileAsync(file);
Assert.IsTrue(isDeleted);
Console.WriteLine($"Deleted {file.Id}");
}

filesList = await testAssistant.ListFilesAsync();
[Test]
public async Task Test_04_04_DeleteAssistantFiles()
{
Assert.IsNotNull(testAssistant);
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var filesList = await testAssistant.ListFilesAsync();
Assert.IsNotNull(filesList);
Assert.IsEmpty(filesList.Items);
Assert.IsNotEmpty(filesList.Items);
Assert.IsTrue(filesList.Items.Count == 1);
var assistantFile = filesList.Items[0];
Assert.IsNotNull(assistantFile);
var isDeleted = await testAssistant.DeleteFileAsync(assistantFile);
Assert.IsTrue(isDeleted);
}

[Test]
Expand Down
12 changes: 7 additions & 5 deletions OpenAI-DotNet-Tests/TestFixture_12_Threads.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,6 @@ public async Task Test_05_DeleteThread()
Console.WriteLine($"Deleted thread {testThread.Id}");
}



[Test]
public async Task Test_06_01_CreateRun()
{
Expand All @@ -225,12 +223,13 @@ public async Task Test_06_01_CreateRun()

try
{
var message = thread.CreateMessageAsync("I need to solve the equation `3x + 11 = 14`. Can you help me?");
var message = await thread.CreateMessageAsync("I need to solve the equation `3x + 11 = 14`. Can you help me?");
Assert.NotNull(message);
var run = await thread.CreateRunAsync(assistant);
Assert.IsNotNull(run);
var threadRun = thread.CreateRunAsync();
Assert.NotNull(threadRun);
run = await run.WaitForStatusChangeAsync();
Assert.IsNotNull(run);
Assert.IsTrue(run.Status == RunStatus.Completed);
}
finally
{
Expand Down Expand Up @@ -269,6 +268,9 @@ public async Task Test_06_03_ListRunsAndSteps()
Assert.IsNotNull(run.Client);
var retrievedRun = await run.UpdateAsync();
Assert.IsNotNull(retrievedRun);
var threadRun = await testThread.RetrieveRunAsync(run.Id);
Assert.IsNotNull(threadRun);
Assert.IsTrue(retrievedRun.Id == threadRun.Id);
Console.WriteLine($"[{retrievedRun.Id}] {retrievedRun.Status} | {retrievedRun.CreatedAt}");
}
}
Expand Down
3 changes: 2 additions & 1 deletion OpenAI-DotNet/Assistants/AssistantExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ public static async Task<bool> DeleteFileAsync(this AssistantFileResponse file,
public static async Task<bool> DeleteFileAsync(this AssistantResponse assistant, string fileId, CancellationToken cancellationToken = default)
{
var isRemoved = await assistant.Client.AssistantsEndpoint.RemoveFileAsync(assistant.Id, fileId, cancellationToken).ConfigureAwait(false);
return isRemoved && await assistant.Client.FilesEndpoint.DeleteFileAsync(fileId, cancellationToken).ConfigureAwait(false);
if (!isRemoved) { return false; }
return await assistant.Client.FilesEndpoint.DeleteFileAsync(fileId, cancellationToken).ConfigureAwait(false);
}

#endregion Files
Expand Down
4 changes: 3 additions & 1 deletion OpenAI-DotNet/Common/ContentType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public enum ContentType
[EnumMember(Value = "text")]
Text,
[EnumMember(Value = "image_url")]
ImageUrl
ImageUrl,
[EnumMember(Value = "image_file")]
ImageFile
}
}
12 changes: 12 additions & 0 deletions OpenAI-DotNet/Common/ImageFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace OpenAI
{
public sealed class ImageFile
{
[JsonInclude]
[JsonPropertyName("file_id")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string FileId { get; private set; }
}
}
4 changes: 3 additions & 1 deletion OpenAI-DotNet/Completions/Choice.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;

namespace OpenAI.Completions
{
/// <summary>
/// Represents a completion choice returned by the <see cref="CompletionsEndpoint"/>.
/// </summary>
[Obsolete("Deprecated")]
public sealed class Choice
{
/// <summary>
Expand Down
1 change: 1 addition & 0 deletions OpenAI-DotNet/Completions/CompletionRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace OpenAI.Completions
/// <see href="https://platform.openai.com/docs/api-reference/completions">the OpenAI docs</see>,
/// although some have been renames or expanded into single/multiple properties for ease of use.
/// </summary>
[Obsolete("Deprecated")]
public sealed class CompletionRequest
{
[JsonPropertyName("model")]
Expand Down
1 change: 1 addition & 0 deletions OpenAI-DotNet/Completions/CompletionResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace OpenAI.Completions
/// <summary>
/// Represents a result from calling the <see cref="CompletionsEndpoint"/>.
/// </summary>
[Obsolete("Deprecated")]
public sealed class CompletionResponse : BaseResponse
{
public CompletionResponse() { }
Expand Down
1 change: 1 addition & 0 deletions OpenAI-DotNet/Completions/CompletionsEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace OpenAI.Completions
/// (see the prompt library for inspiration).<br/>
/// <see href="https://platform.openai.com/docs/api-reference/completions"/>
/// </summary>
[Obsolete("Deprecated")]
public sealed class CompletionsEndpoint : BaseEndPoint
{
/// <inheritdoc />
Expand Down
4 changes: 3 additions & 1 deletion OpenAI-DotNet/Completions/LogProbabilities.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace OpenAI.Completions
{
/// <summary>
/// Object belonging to a <see cref="Choice"/>
/// </summary>
[Obsolete("Deprecated")]
public sealed class LogProbabilities
{
[JsonInclude]
Expand Down
5 changes: 4 additions & 1 deletion OpenAI-DotNet/OpenAI-DotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ More context [on Roger Pincombe's blog](https://rogerpincombe.com/openai-dotnet-
<RepositoryUrl>https://github.com/RageAgainstThePixel/OpenAI-DotNet</RepositoryUrl>
<PackageTags>OpenAI, AI, ML, API, gpt-4, gpt-3.5-tubo, gpt-3, chatGPT, chat-gpt, gpt-2, gpt, dall-e-2, dall-e-3</PackageTags>
<Title>OpenAI-DotNet</Title>
<Version>7.4.1</Version>
<Version>7.4.2</Version>
<PackageReleaseNotes>
Version 7.4.2
- Fixed missing Threads.Message.Content.ImageFile property.
- Marked OpenAI.Completions Obsolete
Version 7.4.1
- Fixed AssistantExtension.UploadFileAsync spelling error with file purpose.
Version 7.4.0
Expand Down
43 changes: 22 additions & 21 deletions OpenAI-DotNet/OpenAIClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ public OpenAIClient(OpenAIAuthentication openAIAuthentication = null, OpenAIClie

Client = SetupClient(client);
ModelsEndpoint = new ModelsEndpoint(this);
CompletionsEndpoint = new CompletionsEndpoint(this);
ChatEndpoint = new ChatEndpoint(this);
#pragma warning disable CS0618 // Type or member is obsolete
EditsEndpoint = new EditsEndpoint(this);
#pragma warning restore CS0618 // Type or member is obsolete
ImagesEndPoint = new ImagesEndpoint(this);
EmbeddingsEndpoint = new EmbeddingsEndpoint(this);
AudioEndpoint = new AudioEndpoint(this);
Expand All @@ -63,6 +59,10 @@ public OpenAIClient(OpenAIAuthentication openAIAuthentication = null, OpenAIClie
ModerationsEndpoint = new ModerationsEndpoint(this);
ThreadsEndpoint = new ThreadsEndpoint(this);
AssistantsEndpoint = new AssistantsEndpoint(this);
#pragma warning disable CS0618 // Type or member is obsolete
CompletionsEndpoint = new CompletionsEndpoint(this);
EditsEndpoint = new EditsEndpoint(this);
#pragma warning restore CS0618 // Type or member is obsolete
}

private HttpClient SetupClient(HttpClient client = null)
Expand Down Expand Up @@ -135,29 +135,12 @@ private HttpClient SetupClient(HttpClient client = null)
/// </summary>
public ModelsEndpoint ModelsEndpoint { get; }

/// <summary>
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion.
/// The way you “program” the API to do a task is by simply describing the task in plain english or providing
/// a few written examples. This simple approach works for a wide range of use cases, including summarization,
/// translation, grammar correction, question answering, chatbots, composing emails, and much more
/// (see the prompt library for inspiration).<br/>
/// <see href="https://platform.openai.com/docs/api-reference/completions"/>
/// </summary>
public CompletionsEndpoint CompletionsEndpoint { get; }

/// <summary>
/// Given a chat conversation, the model will return a chat completion response.<br/>
/// <see href="https://platform.openai.com/docs/api-reference/chat"/>
/// </summary>
public ChatEndpoint ChatEndpoint { get; }

/// <summary>
/// Given a prompt and an instruction, the model will return an edited version of the prompt.<br/>
/// <see href="https://platform.openai.com/docs/api-reference/edits"/>
/// </summary>
[Obsolete("Deprecated")]
public EditsEndpoint EditsEndpoint { get; }

/// <summary>
/// Given a prompt and/or an input image, the model will generate a new image.<br/>
/// <see href="https://platform.openai.com/docs/api-reference/images"/>
Expand Down Expand Up @@ -207,5 +190,23 @@ private HttpClient SetupClient(HttpClient client = null)
/// <see href="https://platform.openai.com/docs/api-reference/threads"/>
/// </summary>
public ThreadsEndpoint ThreadsEndpoint { get; }

/// <summary>
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion.
/// The way you “program” the API to do a task is by simply describing the task in plain english or providing
/// a few written examples. This simple approach works for a wide range of use cases, including summarization,
/// translation, grammar correction, question answering, chatbots, composing emails, and much more
/// (see the prompt library for inspiration).<br/>
/// <see href="https://platform.openai.com/docs/api-reference/completions"/>
/// </summary>
[Obsolete("Deprecated")]
public CompletionsEndpoint CompletionsEndpoint { get; }

/// <summary>
/// Given a prompt and an instruction, the model will return an edited version of the prompt.<br/>
/// <see href="https://platform.openai.com/docs/api-reference/edits"/>
/// </summary>
[Obsolete("Deprecated")]
public EditsEndpoint EditsEndpoint { get; }
}
}
6 changes: 3 additions & 3 deletions OpenAI-DotNet/Threads/Content.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public sealed class Content
public TextContent Text { get; private set; }

[JsonInclude]
[JsonPropertyName("image_url")]
[JsonPropertyName("image_file")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public ImageUrl ImageUrl { get; private set; }
public ImageFile ImageFile { get; private set; }

public override string ToString()
=> Type switch
{
ContentType.Text => Text.Value,
ContentType.ImageUrl => ImageUrl.Url,
ContentType.ImageFile => ImageFile.FileId,
_ => throw new ArgumentOutOfRangeException()
};
}
Expand Down
10 changes: 10 additions & 0 deletions OpenAI-DotNet/Threads/ThreadExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ public static async Task<ListResponse<RunResponse>> ListRunsAsync(this ThreadRes
public static async Task<RunResponse> UpdateAsync(this RunResponse run, CancellationToken cancellationToken = default)
=> await run.Client.ThreadsEndpoint.RetrieveRunAsync(run.ThreadId, run.Id, cancellationToken).ConfigureAwait(false);

/// <summary>
/// Retrieves a run.
/// </summary>
/// <param name="thread">The thread that was run.</param>
/// <param name="runId">The id of the run to retrieve.</param>
/// <param name="cancellationToken">Optional, <see cref="CancellationToken"/>.</param>
/// <returns><see cref="RunResponse"/>.</returns>
public static async Task<RunResponse> RetrieveRunAsync(this ThreadResponse thread, string runId, CancellationToken cancellationToken = default)
=> await thread.Client.ThreadsEndpoint.RetrieveRunAsync(thread.Id, runId, cancellationToken).ConfigureAwait(false);

/// <summary>
/// Modifies a run.
/// </summary>
Expand Down
Loading