From fce110d3b21c136c46e30613bf191f3e24c85f9d Mon Sep 17 00:00:00 2001 From: Stephen Hodgson Date: Fri, 27 Jan 2023 22:37:06 -0500 Subject: [PATCH] OpenAI-DotNet 4.2.0 (#16) - Fixed missing completions namespace - Fixed missing image edit response disposal - misc formatting --- OpenAI-DotNet-Tests/TestFixture_01_Models.cs | 11 ++++++----- OpenAI-DotNet-Tests/TestFixture_02_Completions.cs | 1 + OpenAI-DotNet-Tests/TestFixture_03_Edits.cs | 5 +++-- OpenAI-DotNet-Tests/TestFixture_04_Images.cs | 13 +++++++------ OpenAI-DotNet-Tests/TestFixture_05_Embeddings.cs | 7 ++++--- OpenAI-DotNet/AuthInfo.cs | 11 +++++------ OpenAI-DotNet/BaseEndPoint.cs | 2 +- OpenAI-DotNet/BaseResponse.cs | 2 +- OpenAI-DotNet/Completions/Choice.cs | 6 +++--- OpenAI-DotNet/Completions/CompletionRequest.cs | 4 ++-- OpenAI-DotNet/Completions/CompletionResult.cs | 2 +- OpenAI-DotNet/Completions/CompletionsEndpoint.cs | 9 ++++----- OpenAI-DotNet/Completions/Logprobs.cs | 4 ++-- OpenAI-DotNet/Edits/Choice.cs | 2 +- OpenAI-DotNet/Edits/EditRequest.cs | 2 +- OpenAI-DotNet/Edits/EditResponse.cs | 2 +- OpenAI-DotNet/Edits/EditsEndpoint.cs | 1 + OpenAI-DotNet/Embeddings/Datum.cs | 2 +- OpenAI-DotNet/Embeddings/EmbeddingsRequest.cs | 6 +++--- OpenAI-DotNet/Embeddings/EmbeddingsResponse.cs | 2 +- OpenAI-DotNet/Event.cs | 2 +- OpenAI-DotNet/Files/FileData.cs | 2 +- OpenAI-DotNet/Files/FileUploadRequest.cs | 2 +- OpenAI-DotNet/Files/FilesEndpoint.cs | 2 +- .../FineTuning/CreateFineTuneJobRequest.cs | 2 +- OpenAI-DotNet/FineTuning/FineTuneJob.cs | 2 +- OpenAI-DotNet/FineTuning/FineTuneJobResponse.cs | 2 +- OpenAI-DotNet/FineTuning/FineTuningEndpoint.cs | 4 ++-- OpenAI-DotNet/FineTuning/FineTuningTrainingData.cs | 2 +- OpenAI-DotNet/FineTuning/HyperParams.cs | 2 +- OpenAI-DotNet/Images/ImageEditRequest.cs | 7 ++----- OpenAI-DotNet/Images/ImageGenerationRequest.cs | 2 +- OpenAI-DotNet/Images/ImageResult.cs | 2 +- OpenAI-DotNet/Images/ImageSize.cs | 2 +- OpenAI-DotNet/Images/ImageVariationRequest.cs | 7 ++----- OpenAI-DotNet/Images/ImagesEndpoint.cs | 3 +++ OpenAI-DotNet/Images/ImagesResponse.cs | 2 +- OpenAI-DotNet/Models/ModelsEndpoint.cs | 8 ++++---- OpenAI-DotNet/Models/Permission.cs | 2 +- OpenAI-DotNet/Moderations/Categories.cs | 2 +- OpenAI-DotNet/Moderations/ModerationResult.cs | 2 +- OpenAI-DotNet/Moderations/ModerationsResponse.cs | 2 +- OpenAI-DotNet/Moderations/Scores.cs | 2 +- OpenAI-DotNet/OpenAI-DotNet.csproj | 13 +++++++------ OpenAI-DotNet/OpenAIAuthentication.cs | 4 ++-- OpenAI-DotNet/OpenAIClient.cs | 3 ++- OpenAI-DotNet/ResponseExtensions.cs | 4 ++-- OpenAI-DotNet/StringExtensions.cs | 4 ++-- OpenAI-DotNet/Usage.cs | 2 +- README.md | 10 +++++----- 50 files changed, 101 insertions(+), 98 deletions(-) diff --git a/OpenAI-DotNet-Tests/TestFixture_01_Models.cs b/OpenAI-DotNet-Tests/TestFixture_01_Models.cs index 0a0e77a6..c04a4b91 100644 --- a/OpenAI-DotNet-Tests/TestFixture_01_Models.cs +++ b/OpenAI-DotNet-Tests/TestFixture_01_Models.cs @@ -1,24 +1,25 @@ using NUnit.Framework; using System; +using System.Threading.Tasks; namespace OpenAI.Tests { internal class TestFixture_01_Models { [Test] - public void Test_1_GetModels() + public async Task Test_1_GetModels() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); - var results = api.ModelsEndpoint.GetModelsAsync().Result; + var results = await api.ModelsEndpoint.GetModelsAsync(); Assert.IsNotNull(results); Assert.NotZero(results.Count); } [Test] - public void Test_2_RetrieveModelDetails() + public async Task Test_2_RetrieveModelDetails() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); - var models = api.ModelsEndpoint.GetModelsAsync().Result; + var models = await api.ModelsEndpoint.GetModelsAsync(); Console.WriteLine($"Found {models.Count} models!"); @@ -28,7 +29,7 @@ public void Test_2_RetrieveModelDetails() try { - var result = api.ModelsEndpoint.GetModelDetailsAsync(model.Id).Result; + var result = await api.ModelsEndpoint.GetModelDetailsAsync(model.Id); Assert.IsNotNull(result); } catch (Exception e) diff --git a/OpenAI-DotNet-Tests/TestFixture_02_Completions.cs b/OpenAI-DotNet-Tests/TestFixture_02_Completions.cs index 1c1b0dfc..ae870384 100644 --- a/OpenAI-DotNet-Tests/TestFixture_02_Completions.cs +++ b/OpenAI-DotNet-Tests/TestFixture_02_Completions.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using OpenAI.Completions; using OpenAI.Models; using System; using System.Collections.Generic; diff --git a/OpenAI-DotNet-Tests/TestFixture_03_Edits.cs b/OpenAI-DotNet-Tests/TestFixture_03_Edits.cs index 644d63e5..5eba8e79 100644 --- a/OpenAI-DotNet-Tests/TestFixture_03_Edits.cs +++ b/OpenAI-DotNet-Tests/TestFixture_03_Edits.cs @@ -1,18 +1,19 @@ using NUnit.Framework; using OpenAI.Edits; using System; +using System.Threading.Tasks; namespace OpenAI.Tests { internal class TestFixture_03_Edits { [Test] - public void Test_1_GetBasicEdit() + public async Task Test_1_GetBasicEdit() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); Assert.IsNotNull(api.EditsEndpoint); var request = new EditRequest("What day of the wek is it?", "Fix the spelling mistakes"); - var result = api.EditsEndpoint.CreateEditAsync(request).Result; + var result = await api.EditsEndpoint.CreateEditAsync(request); Assert.IsNotNull(result); Assert.NotNull(result.Choices); Assert.NotZero(result.Choices.Count); diff --git a/OpenAI-DotNet-Tests/TestFixture_04_Images.cs b/OpenAI-DotNet-Tests/TestFixture_04_Images.cs index 2b9f8fd4..2eec6eab 100644 --- a/OpenAI-DotNet-Tests/TestFixture_04_Images.cs +++ b/OpenAI-DotNet-Tests/TestFixture_04_Images.cs @@ -2,18 +2,19 @@ using OpenAI.Images; using System; using System.IO; +using System.Threading.Tasks; namespace OpenAI.Tests { internal class TestFixture_04_Images { [Test] - public void Test_1_GenerateImages() + public async Task Test_1_GenerateImages() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); Assert.IsNotNull(api.ImagesEndPoint); - var results = api.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small).Result; + var results = await api.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small); Assert.IsNotNull(results); Assert.NotZero(results.Count); @@ -25,7 +26,7 @@ public void Test_1_GenerateImages() } [Test] - public void Test_2_GenerateImageEdits() + public async Task Test_2_GenerateImageEdits() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); Assert.IsNotNull(api.ImagesEndPoint); @@ -33,7 +34,7 @@ public void Test_2_GenerateImageEdits() var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png"); var maskAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_mask.png"); - var results = api.ImagesEndPoint.CreateImageEditAsync(Path.GetFullPath(imageAssetPath), Path.GetFullPath(maskAssetPath), "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small).Result; + var results = await api.ImagesEndPoint.CreateImageEditAsync(Path.GetFullPath(imageAssetPath), Path.GetFullPath(maskAssetPath), "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small); Assert.IsNotNull(results); Assert.NotZero(results.Count); @@ -45,14 +46,14 @@ public void Test_2_GenerateImageEdits() } [Test] - public void Test_3_GenerateImageVariations() + public async Task Test_3_GenerateImageVariations() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); Assert.IsNotNull(api.ImagesEndPoint); var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png"); - var results = api.ImagesEndPoint.CreateImageVariationAsync(imageAssetPath, 1, ImageSize.Small).Result; + var results = await api.ImagesEndPoint.CreateImageVariationAsync(imageAssetPath, 1, ImageSize.Small); Assert.IsNotNull(results); Assert.NotZero(results.Count); diff --git a/OpenAI-DotNet-Tests/TestFixture_05_Embeddings.cs b/OpenAI-DotNet-Tests/TestFixture_05_Embeddings.cs index 6707ba33..5a84d178 100644 --- a/OpenAI-DotNet-Tests/TestFixture_05_Embeddings.cs +++ b/OpenAI-DotNet-Tests/TestFixture_05_Embeddings.cs @@ -1,15 +1,16 @@ -using NUnit.Framework; +using System.Threading.Tasks; +using NUnit.Framework; namespace OpenAI.Tests { internal class TestFixture_05_Embeddings { [Test] - public void Test_1_CreateEmbedding() + public async Task Test_1_CreateEmbedding() { var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); Assert.IsNotNull(api.EmbeddingsEndpoint); - var result = api.EmbeddingsEndpoint.CreateEmbeddingAsync("The food was delicious and the waiter...").Result; + var result = await api.EmbeddingsEndpoint.CreateEmbeddingAsync("The food was delicious and the waiter..."); Assert.IsNotNull(result); Assert.IsNotEmpty(result.Data); } diff --git a/OpenAI-DotNet/AuthInfo.cs b/OpenAI-DotNet/AuthInfo.cs index 44a3054c..561e31b9 100644 --- a/OpenAI-DotNet/AuthInfo.cs +++ b/OpenAI-DotNet/AuthInfo.cs @@ -1,12 +1,11 @@ -using System; -using System.Security.Authentication; +using System.Security.Authentication; using System.Text.Json.Serialization; namespace OpenAI { - [Serializable] internal class AuthInfo { + [JsonConstructor] public AuthInfo(string apiKey, string organization = null) { if (!apiKey.Contains("sk-")) @@ -28,9 +27,9 @@ public AuthInfo(string apiKey, string organization = null) } [JsonPropertyName("apiKey")] - public string ApiKey { get; set; } + public string ApiKey { get; } [JsonPropertyName("organization")] - public string Organization { get; set; } + public string Organization { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/BaseEndPoint.cs b/OpenAI-DotNet/BaseEndPoint.cs index a63c5dc0..32d93325 100644 --- a/OpenAI-DotNet/BaseEndPoint.cs +++ b/OpenAI-DotNet/BaseEndPoint.cs @@ -16,4 +16,4 @@ public abstract class BaseEndPoint /// The completed basic url for the endpoint. protected abstract string GetEndpoint(); } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/BaseResponse.cs b/OpenAI-DotNet/BaseResponse.cs index be4ca952..a551d278 100644 --- a/OpenAI-DotNet/BaseResponse.cs +++ b/OpenAI-DotNet/BaseResponse.cs @@ -23,4 +23,4 @@ public abstract class BaseResponse [JsonIgnore] public string RequestId { get; internal set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Completions/Choice.cs b/OpenAI-DotNet/Completions/Choice.cs index 1a6ebe44..252caef6 100644 --- a/OpenAI-DotNet/Completions/Choice.cs +++ b/OpenAI-DotNet/Completions/Choice.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace OpenAI +namespace OpenAI.Completions { /// /// Represents a completion choice returned by the . @@ -34,8 +34,8 @@ public sealed class Choice /// /// Gets the main text of this completion /// - public override string ToString() => $"{Index}|{FinishReason}|{Text}"; + public override string ToString() => Text; public static implicit operator string(Choice choice) => choice.Text; } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Completions/CompletionRequest.cs b/OpenAI-DotNet/Completions/CompletionRequest.cs index 60b4dd9f..7d85e832 100644 --- a/OpenAI-DotNet/Completions/CompletionRequest.cs +++ b/OpenAI-DotNet/Completions/CompletionRequest.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text.Json.Serialization; -namespace OpenAI +namespace OpenAI.Completions { /// /// Represents a request to the . Mostly matches the parameters in @@ -20,7 +20,7 @@ public sealed class CompletionRequest /// If you are requesting more than one prompt, specify them as an array of strings. /// [JsonPropertyName("prompt")] - public string[] Prompts { get; set; } = new string[0]; + public string[] Prompts { get; set; } = Array.Empty(); /// /// For convenience, if you are only requesting a single prompt, set it here diff --git a/OpenAI-DotNet/Completions/CompletionResult.cs b/OpenAI-DotNet/Completions/CompletionResult.cs index 767e2c3a..1a02972f 100644 --- a/OpenAI-DotNet/Completions/CompletionResult.cs +++ b/OpenAI-DotNet/Completions/CompletionResult.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace OpenAI +namespace OpenAI.Completions { /// /// Represents a result from calling the . diff --git a/OpenAI-DotNet/Completions/CompletionsEndpoint.cs b/OpenAI-DotNet/Completions/CompletionsEndpoint.cs index d809fc63..c181a7b0 100644 --- a/OpenAI-DotNet/Completions/CompletionsEndpoint.cs +++ b/OpenAI-DotNet/Completions/CompletionsEndpoint.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Threading.Tasks; -namespace OpenAI +namespace OpenAI.Completions { /// /// Text generation is the core function of the API. You give the API a prompt, and it generates a completion. @@ -16,7 +16,7 @@ namespace OpenAI /// (see the prompt library for inspiration). /// /// - public class CompletionsEndpoint : BaseEndPoint + public sealed class CompletionsEndpoint : BaseEndPoint { /// internal CompletionsEndpoint(OpenAIClient api) : base(api) { } @@ -71,8 +71,7 @@ public async Task CreateCompletionAsync( int? logProbabilities = null, bool? echo = null, string[] stopSequences = null, - Model model = null - ) + Model model = null) { var request = new CompletionRequest( model ?? Api.DefaultModel, @@ -354,7 +353,7 @@ public async IAsyncEnumerable StreamCompletionEnumerableAsync( private CompletionResult DeserializeResult(HttpResponseMessage response, string result) { - var completionResult = JsonSerializer.Deserialize(result); + var completionResult = JsonSerializer.Deserialize(result, Api.JsonSerializationOptions); if (completionResult?.Completions == null || completionResult.Completions.Count == 0) { diff --git a/OpenAI-DotNet/Completions/Logprobs.cs b/OpenAI-DotNet/Completions/Logprobs.cs index 27bd83f8..dd5a2dde 100644 --- a/OpenAI-DotNet/Completions/Logprobs.cs +++ b/OpenAI-DotNet/Completions/Logprobs.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace OpenAI +namespace OpenAI.Completions { /// /// Object belonging to a @@ -20,4 +20,4 @@ public sealed class Logprobs [JsonPropertyName("text_offset")] public List TextOffsets { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Edits/Choice.cs b/OpenAI-DotNet/Edits/Choice.cs index b0fe5b69..ea95ae7a 100644 --- a/OpenAI-DotNet/Edits/Choice.cs +++ b/OpenAI-DotNet/Edits/Choice.cs @@ -17,4 +17,4 @@ public sealed class Choice public static implicit operator string(Choice choice) => choice.Text; } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Edits/EditRequest.cs b/OpenAI-DotNet/Edits/EditRequest.cs index 0aea66fc..35763dd9 100644 --- a/OpenAI-DotNet/Edits/EditRequest.cs +++ b/OpenAI-DotNet/Edits/EditRequest.cs @@ -80,4 +80,4 @@ public EditRequest( [JsonPropertyName("top_p")] public double? TopP { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Edits/EditResponse.cs b/OpenAI-DotNet/Edits/EditResponse.cs index 394bb5d2..43403d0b 100644 --- a/OpenAI-DotNet/Edits/EditResponse.cs +++ b/OpenAI-DotNet/Edits/EditResponse.cs @@ -35,4 +35,4 @@ public override string ToString() : "Edit result has no valid output"; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Edits/EditsEndpoint.cs b/OpenAI-DotNet/Edits/EditsEndpoint.cs index f1ae8f52..28ac0e1c 100644 --- a/OpenAI-DotNet/Edits/EditsEndpoint.cs +++ b/OpenAI-DotNet/Edits/EditsEndpoint.cs @@ -2,6 +2,7 @@ using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; +using OpenAI.Models; namespace OpenAI.Edits { diff --git a/OpenAI-DotNet/Embeddings/Datum.cs b/OpenAI-DotNet/Embeddings/Datum.cs index 40bf36b0..8088361e 100644 --- a/OpenAI-DotNet/Embeddings/Datum.cs +++ b/OpenAI-DotNet/Embeddings/Datum.cs @@ -14,4 +14,4 @@ public sealed class Datum [JsonPropertyName("index")] public int Index { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Embeddings/EmbeddingsRequest.cs b/OpenAI-DotNet/Embeddings/EmbeddingsRequest.cs index ba3af30b..a7bac497 100644 --- a/OpenAI-DotNet/Embeddings/EmbeddingsRequest.cs +++ b/OpenAI-DotNet/Embeddings/EmbeddingsRequest.cs @@ -1,6 +1,6 @@ -using System; +using OpenAI.Models; +using System; using System.Text.Json.Serialization; -using OpenAI.Models; namespace OpenAI.Embeddings { @@ -43,4 +43,4 @@ public EmbeddingsRequest(string input, Model model = null, string user = null) [JsonPropertyName("user")] public string User { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Embeddings/EmbeddingsResponse.cs b/OpenAI-DotNet/Embeddings/EmbeddingsResponse.cs index 471aa50f..3191d148 100644 --- a/OpenAI-DotNet/Embeddings/EmbeddingsResponse.cs +++ b/OpenAI-DotNet/Embeddings/EmbeddingsResponse.cs @@ -17,4 +17,4 @@ public sealed class EmbeddingsResponse : BaseResponse [JsonPropertyName("usage")] public Usage Usage { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Event.cs b/OpenAI-DotNet/Event.cs index fa3d57e0..8454e36a 100644 --- a/OpenAI-DotNet/Event.cs +++ b/OpenAI-DotNet/Event.cs @@ -34,4 +34,4 @@ string message [JsonPropertyName("message")] public string Message { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Files/FileData.cs b/OpenAI-DotNet/Files/FileData.cs index 9440718d..1ac136aa 100644 --- a/OpenAI-DotNet/Files/FileData.cs +++ b/OpenAI-DotNet/Files/FileData.cs @@ -31,4 +31,4 @@ public sealed class FileData public static implicit operator string(FileData fileData) => fileData.Id; } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Files/FileUploadRequest.cs b/OpenAI-DotNet/Files/FileUploadRequest.cs index e324ec1b..e3c39933 100644 --- a/OpenAI-DotNet/Files/FileUploadRequest.cs +++ b/OpenAI-DotNet/Files/FileUploadRequest.cs @@ -56,4 +56,4 @@ public void Dispose() GC.SuppressFinalize(this); } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Files/FilesEndpoint.cs b/OpenAI-DotNet/Files/FilesEndpoint.cs index dcf539a1..3e58c89d 100644 --- a/OpenAI-DotNet/Files/FilesEndpoint.cs +++ b/OpenAI-DotNet/Files/FilesEndpoint.cs @@ -46,7 +46,7 @@ public async Task> ListFilesAsync() if (response.IsSuccessStatusCode) { - return JsonSerializer.Deserialize(resultAsString)?.Data; + return JsonSerializer.Deserialize(resultAsString, Api.JsonSerializationOptions)?.Data; } throw new HttpRequestException($"{nameof(ListFilesAsync)} Failed! HTTP status code: {response.StatusCode}."); diff --git a/OpenAI-DotNet/FineTuning/CreateFineTuneJobRequest.cs b/OpenAI-DotNet/FineTuning/CreateFineTuneJobRequest.cs index d379d478..f80e8b11 100644 --- a/OpenAI-DotNet/FineTuning/CreateFineTuneJobRequest.cs +++ b/OpenAI-DotNet/FineTuning/CreateFineTuneJobRequest.cs @@ -69,4 +69,4 @@ public CreateFineTuneJobRequest( [JsonPropertyName("suffix")] public string Suffix { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/FineTuning/FineTuneJob.cs b/OpenAI-DotNet/FineTuning/FineTuneJob.cs index a186fbbc..9cc724e8 100644 --- a/OpenAI-DotNet/FineTuning/FineTuneJob.cs +++ b/OpenAI-DotNet/FineTuning/FineTuneJob.cs @@ -52,4 +52,4 @@ public sealed class FineTuneJob [JsonIgnore] public DateTime UpdatedAt => DateTimeOffset.FromUnixTimeSeconds(UpdatedAtUnixTime).DateTime; } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/FineTuning/FineTuneJobResponse.cs b/OpenAI-DotNet/FineTuning/FineTuneJobResponse.cs index d18f0755..0f3f5d78 100644 --- a/OpenAI-DotNet/FineTuning/FineTuneJobResponse.cs +++ b/OpenAI-DotNet/FineTuning/FineTuneJobResponse.cs @@ -71,4 +71,4 @@ public static implicit operator FineTuneJob(FineTuneJobResponse jobResponse) [JsonIgnore] public DateTime UpdatedAt => DateTimeOffset.FromUnixTimeSeconds(UpdatedAtUnixTime).DateTime; } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/FineTuning/FineTuningEndpoint.cs b/OpenAI-DotNet/FineTuning/FineTuningEndpoint.cs index 60959718..7925b9df 100644 --- a/OpenAI-DotNet/FineTuning/FineTuningEndpoint.cs +++ b/OpenAI-DotNet/FineTuning/FineTuningEndpoint.cs @@ -173,7 +173,7 @@ public async Task StreamFineTuneEventsAsync(FineTuneJob fineTuneJob, Action(line.Trim())); + fineTuneEventCallback(JsonSerializer.Deserialize(line.Trim(), Api.JsonSerializationOptions)); } } @@ -225,7 +225,7 @@ public async IAsyncEnumerable StreamFineTuneEventsEnumerableAsync(FineTun if (!string.IsNullOrWhiteSpace(line)) { - yield return JsonSerializer.Deserialize(line.Trim()); + yield return JsonSerializer.Deserialize(line.Trim(), Api.JsonSerializationOptions); } } diff --git a/OpenAI-DotNet/FineTuning/FineTuningTrainingData.cs b/OpenAI-DotNet/FineTuning/FineTuningTrainingData.cs index b88cde5f..c33297d3 100644 --- a/OpenAI-DotNet/FineTuning/FineTuningTrainingData.cs +++ b/OpenAI-DotNet/FineTuning/FineTuningTrainingData.cs @@ -36,4 +36,4 @@ public FineTuningTrainingData(string prompt, string completion) [JsonPropertyName("completion")] public string Completion { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/FineTuning/HyperParams.cs b/OpenAI-DotNet/FineTuning/HyperParams.cs index 79a4e9e6..adcd5570 100644 --- a/OpenAI-DotNet/FineTuning/HyperParams.cs +++ b/OpenAI-DotNet/FineTuning/HyperParams.cs @@ -16,4 +16,4 @@ public sealed class HyperParams [JsonPropertyName("prompt_loss_weight")] public double PromptLossWeight { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImageEditRequest.cs b/OpenAI-DotNet/Images/ImageEditRequest.cs index f1954deb..982b0720 100644 --- a/OpenAI-DotNet/Images/ImageEditRequest.cs +++ b/OpenAI-DotNet/Images/ImageEditRequest.cs @@ -128,10 +128,7 @@ public ImageEditRequest(Stream image, string imageName, Stream mask, string mask User = user; } - ~ImageEditRequest() - { - Dispose(false); - } + ~ImageEditRequest() => Dispose(false); /// /// The image to edit. Must be a valid PNG file, less than 4MB, and square. @@ -186,4 +183,4 @@ public void Dispose() GC.SuppressFinalize(this); } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImageGenerationRequest.cs b/OpenAI-DotNet/Images/ImageGenerationRequest.cs index ed08e1b7..9f103f9a 100644 --- a/OpenAI-DotNet/Images/ImageGenerationRequest.cs +++ b/OpenAI-DotNet/Images/ImageGenerationRequest.cs @@ -67,4 +67,4 @@ public ImageGenerationRequest(string prompt, int numberOfResults = 1, ImageSize [JsonPropertyName("user")] public string User { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImageResult.cs b/OpenAI-DotNet/Images/ImageResult.cs index a05dbc0c..8c212873 100644 --- a/OpenAI-DotNet/Images/ImageResult.cs +++ b/OpenAI-DotNet/Images/ImageResult.cs @@ -7,4 +7,4 @@ internal class ImageResult [JsonPropertyName("url")] public string Url { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImageSize.cs b/OpenAI-DotNet/Images/ImageSize.cs index 70846f1a..6087f895 100644 --- a/OpenAI-DotNet/Images/ImageSize.cs +++ b/OpenAI-DotNet/Images/ImageSize.cs @@ -15,4 +15,4 @@ public enum ImageSize /// Large, } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImageVariationRequest.cs b/OpenAI-DotNet/Images/ImageVariationRequest.cs index 6e0763d5..b8acb886 100644 --- a/OpenAI-DotNet/Images/ImageVariationRequest.cs +++ b/OpenAI-DotNet/Images/ImageVariationRequest.cs @@ -49,10 +49,7 @@ public ImageVariationRequest(string imagePath, int numberOfResults = 1, ImageSiz User = user; } - ~ImageVariationRequest() - { - Dispose(false); - } + ~ImageVariationRequest() => Dispose(false); /// /// The image to use as the basis for the variation(s). Must be a valid PNG file, less than 4MB, and square. @@ -91,4 +88,4 @@ public void Dispose() GC.SuppressFinalize(this); } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Images/ImagesEndpoint.cs b/OpenAI-DotNet/Images/ImagesEndpoint.cs index a6dce8cd..e95709ec 100644 --- a/OpenAI-DotNet/Images/ImagesEndpoint.cs +++ b/OpenAI-DotNet/Images/ImagesEndpoint.cs @@ -96,6 +96,7 @@ public async Task> CreateImageEditAsync(ImageEditRequest r { content.Add(new StringContent(request.User), "user"); } + request.Dispose(); var response = await Api.Client.PostAsync($"{GetEndpoint()}edits", content); @@ -147,6 +148,8 @@ public async Task> CreateImageVariationAsync(ImageVariatio content.Add(new StringContent(request.User), "user"); } + request.Dispose(); + var response = await Api.Client.PostAsync($"{GetEndpoint()}variations", content); var responseAsString = await response.Content.ReadAsStringAsync(); diff --git a/OpenAI-DotNet/Images/ImagesResponse.cs b/OpenAI-DotNet/Images/ImagesResponse.cs index 0d33ac80..6d9ef2be 100644 --- a/OpenAI-DotNet/Images/ImagesResponse.cs +++ b/OpenAI-DotNet/Images/ImagesResponse.cs @@ -11,4 +11,4 @@ internal class ImagesResponse : BaseResponse [JsonPropertyName("data")] public List Data { get; set; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Models/ModelsEndpoint.cs b/OpenAI-DotNet/Models/ModelsEndpoint.cs index 3c945cda..22782c3b 100644 --- a/OpenAI-DotNet/Models/ModelsEndpoint.cs +++ b/OpenAI-DotNet/Models/ModelsEndpoint.cs @@ -59,7 +59,7 @@ public async Task> GetModelsAsync() if (response.IsSuccessStatusCode) { - return JsonSerializer.Deserialize(responseAsString)?.Data; + return JsonSerializer.Deserialize(responseAsString, Api.JsonSerializationOptions)?.Data; } throw new HttpRequestException($"{nameof(GetModelsAsync)} Failed! HTTP status code: {response.StatusCode}| response body: {responseAsString}."); @@ -78,7 +78,7 @@ public async Task GetModelDetailsAsync(string id) if (response.IsSuccessStatusCode) { - return JsonSerializer.Deserialize(responseAsString); + return JsonSerializer.Deserialize(responseAsString, Api.JsonSerializationOptions); } throw new HttpRequestException($"{nameof(GetModelDetailsAsync)} Failed! HTTP status code: {response.StatusCode} | response body: {responseAsString}."); @@ -109,10 +109,10 @@ public async Task DeleteFineTuneModelAsync(string modelId) if (response.IsSuccessStatusCode) { - return JsonSerializer.Deserialize(responseAsString)?.Deleted ?? false; + return JsonSerializer.Deserialize(responseAsString, Api.JsonSerializationOptions)?.Deleted ?? false; } throw new HttpRequestException($"{nameof(DeleteFineTuneModelAsync)} Failed! HTTP status code: {response.StatusCode} | response body: {responseAsString}."); } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Models/Permission.cs b/OpenAI-DotNet/Models/Permission.cs index 648a304a..ee735a83 100644 --- a/OpenAI-DotNet/Models/Permission.cs +++ b/OpenAI-DotNet/Models/Permission.cs @@ -57,4 +57,4 @@ public Permission(string id, string @object, int created, bool allowCreateEngine [JsonPropertyName("is_blocking")] public bool IsBlocking { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Moderations/Categories.cs b/OpenAI-DotNet/Moderations/Categories.cs index c29b66ed..04a6fdc2 100644 --- a/OpenAI-DotNet/Moderations/Categories.cs +++ b/OpenAI-DotNet/Moderations/Categories.cs @@ -37,4 +37,4 @@ public Categories(bool hate, bool hateThreatening, bool selfHarm, bool sexual, b [JsonPropertyName("violence/graphic")] public bool ViolenceGraphic { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Moderations/ModerationResult.cs b/OpenAI-DotNet/Moderations/ModerationResult.cs index f3fe3b64..f9aea10c 100644 --- a/OpenAI-DotNet/Moderations/ModerationResult.cs +++ b/OpenAI-DotNet/Moderations/ModerationResult.cs @@ -21,4 +21,4 @@ public ModerationResult(Categories categories, Scores scores, bool flagged) [JsonPropertyName("flagged")] public bool Flagged { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Moderations/ModerationsResponse.cs b/OpenAI-DotNet/Moderations/ModerationsResponse.cs index 9720b3a0..9ad7fbd0 100644 --- a/OpenAI-DotNet/Moderations/ModerationsResponse.cs +++ b/OpenAI-DotNet/Moderations/ModerationsResponse.cs @@ -22,4 +22,4 @@ public ModerationsResponse(string id, string model, List resul [JsonPropertyName("results")] public List Results { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/Moderations/Scores.cs b/OpenAI-DotNet/Moderations/Scores.cs index c08595f8..5f810c8f 100644 --- a/OpenAI-DotNet/Moderations/Scores.cs +++ b/OpenAI-DotNet/Moderations/Scores.cs @@ -37,4 +37,4 @@ public Scores(double hate, double hateThreatening, double selfHarm, double sexua [JsonPropertyName("violence/graphic")] public double ViolenceGraphic { get; } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/OpenAI-DotNet.csproj b/OpenAI-DotNet/OpenAI-DotNet.csproj index 3427323a..8f9c66fa 100644 --- a/OpenAI-DotNet/OpenAI-DotNet.csproj +++ b/OpenAI-DotNet/OpenAI-DotNet.csproj @@ -15,17 +15,18 @@ OpenAI, AI, ML, API OpenAI API -Bump version to 4.1.0 -Added Files and Fine Tunes Endpoints. -Refactored some responses to be immutable. +Bump version to 4.2.0 +Added missing Completions namespace. +Alignment with com.openai.unity library. +Misc formatting and bug fixes. false OpenAI-DotNet.pfx true OpenAI-DotNet - 4.1.0 - 4.1.0.0 - 4.1.0.0 + 4.2.0 + 4.2.0.0 + 4.2.0.0 RageAgainstThePixel diff --git a/OpenAI-DotNet/OpenAIAuthentication.cs b/OpenAI-DotNet/OpenAIAuthentication.cs index 95fcd409..29ceb67f 100644 --- a/OpenAI-DotNet/OpenAIAuthentication.cs +++ b/OpenAI-DotNet/OpenAIAuthentication.cs @@ -7,7 +7,7 @@ namespace OpenAI /// /// Represents authentication to the OpenAPI API endpoint /// - public class OpenAIAuthentication + public sealed class OpenAIAuthentication { private const string OPENAI_KEY = "OPENAI_KEY"; private const string OPENAI_API_KEY = "OPENAI_API_KEY"; @@ -29,7 +29,7 @@ public class OpenAIAuthentication public string Organization => authInfo.Organization; /// - /// Allows implicit casting from a string, so that a simple string API key can be provided in place of an instance of + /// Allows implicit casting from a string, so that a simple string API key can be provided in place of an instance of . /// /// The API key to convert into a . public static implicit operator OpenAIAuthentication(string key) => new OpenAIAuthentication(key); diff --git a/OpenAI-DotNet/OpenAIClient.cs b/OpenAI-DotNet/OpenAIClient.cs index 53b8d610..dcb91459 100644 --- a/OpenAI-DotNet/OpenAIClient.cs +++ b/OpenAI-DotNet/OpenAIClient.cs @@ -1,4 +1,5 @@ -using OpenAI.Edits; +using OpenAI.Completions; +using OpenAI.Edits; using OpenAI.Embeddings; using OpenAI.Files; using OpenAI.FineTuning; diff --git a/OpenAI-DotNet/ResponseExtensions.cs b/OpenAI-DotNet/ResponseExtensions.cs index de18b9aa..7d03b0b9 100644 --- a/OpenAI-DotNet/ResponseExtensions.cs +++ b/OpenAI-DotNet/ResponseExtensions.cs @@ -4,7 +4,7 @@ namespace OpenAI { - public static class ResponseExtensions + internal static class ResponseExtensions { private const string Organization = "Openai-Organization"; private const string RequestId = "X-Request-ID"; @@ -17,4 +17,4 @@ internal static void SetResponseData(this BaseResponse response, HttpResponseHea response.ProcessingTime = TimeSpan.FromMilliseconds(int.Parse(headers.GetValues(ProcessingTime).First())); } } -} \ No newline at end of file +} diff --git a/OpenAI-DotNet/StringExtensions.cs b/OpenAI-DotNet/StringExtensions.cs index 62042986..f3ad7d16 100644 --- a/OpenAI-DotNet/StringExtensions.cs +++ b/OpenAI-DotNet/StringExtensions.cs @@ -5,7 +5,7 @@ namespace OpenAI { internal static class StringExtensions { - public static StringContent ToJsonStringContent(this string s) - => new StringContent(s, Encoding.UTF8, "application/json"); + public static StringContent ToJsonStringContent(this string json) + => new StringContent(json, Encoding.UTF8, "application/json"); } } diff --git a/OpenAI-DotNet/Usage.cs b/OpenAI-DotNet/Usage.cs index 40e43102..d0196f7f 100644 --- a/OpenAI-DotNet/Usage.cs +++ b/OpenAI-DotNet/Usage.cs @@ -25,4 +25,4 @@ int totalTokens [JsonPropertyName("total_tokens")] public int TotalTokens { get; } } -} \ No newline at end of file +} diff --git a/README.md b/README.md index bdf7811d..ce0382ba 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); ### [Models](https://beta.openai.com/docs/api-reference/models) -List and describe the various models available in the API. You can refer to the Models documentation to understand what models are available and the differences between them. +List and describe the various models available in the API. You can refer to the [Models documentation](https://beta.openai.com/docs/models) to understand what models are available and the differences between them. The Models API is accessed via `OpenAIClient.ModelsEndpoint`. @@ -165,11 +165,11 @@ var result = await api.ModelsEndpoint.DeleteFineTuneModelAsync("your-fine-tuned- ### [Completions](https://beta.openai.com/docs/api-reference/completions) -The Completion API is accessed via `OpenAIClient.CompletionEndpoint`: +The Completion API is accessed via `OpenAIClient.CompletionsEndpoint`: ```csharp var api = new OpenAIClient(); -var result = await api.CompletionEndpoint.CreateCompletionAsync("One Two Three One Two", temperature: 0.1, model: Model.Davinci); +var result = await api.CompletionsEndpoint.CreateCompletionAsync("One Two Three One Two", temperature: 0.1, model: Model.Davinci); Console.WriteLine(result); ``` @@ -182,7 +182,7 @@ Streaming allows you to get results are they are generated, which can help your ```csharp var api = new OpenAIClient(); -await api.CompletionEndpoint.StreamCompletionAsync(result => +await api.CompletionsEndpoint.StreamCompletionAsync(result => { foreach (var choice in result.Completions) { @@ -195,7 +195,7 @@ Or if using [`IAsyncEnumerable{T}`](https://docs.microsoft.com/en-us/dotnet/api/ ```csharp var api = new OpenAIClient(); -await foreach (var token in api.CompletionEndpoint.StreamCompletionEnumerableAsync("My name is Roger and I am a principal software engineer at Salesforce. This is my resume:", max_tokens: 200, temperature: 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1, model: Model.Davinci)) +await foreach (var token in api.CompletionsEndpoint.StreamCompletionEnumerableAsync("My name is Roger and I am a principal software engineer at Salesforce. This is my resume:", max_tokens: 200, temperature: 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1, model: Model.Davinci)) { Console.WriteLine(token); }