Skip to content

Commit

Permalink
OpenAI-DotNet 7.4.2 (#202)
Browse files Browse the repository at this point in the history
- Fixed missing Threads.Message.Content.ImageFile property. 
- Marked OpenAI.Completions Obsolete

---------

Co-authored-by: Chad <[email protected]>
  • Loading branch information
StephenHodgson and chadcts authored Dec 7, 2023
1 parent 93177b0 commit 0138115
Show file tree
Hide file tree
Showing 16 changed files with 138 additions and 83 deletions.
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

0 comments on commit 0138115

Please sign in to comment.