Skip to content

Commit

Permalink
Merge pull request #20 from betalgo/dev
Browse files Browse the repository at this point in the history
Version 6.3.0
  • Loading branch information
kayhantolga authored Sep 20, 2022
2 parents 8b02a8b + a078445 commit e5a6424
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 24 deletions.
1 change: 1 addition & 0 deletions OpenAI.Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

await ModelTestHelper.FetchModelsTest(sdk);
//await CompletionTestHelper.RunSimpleCompletionTest(sdk);
//await EmbeddingTestHelper.RunSimpleEmbeddingTest(sdk);
//await FileTestHelper.RunSimpleFileTest(sdk);
////await FineTuningTestHelper.CleanUpAllFineTunings(sdk); //!!!!! will delete all fine-tunings
//await FineTuningTestHelper.RunCaseStudyIsTheModelMakingUntrueStatements(sdk);
Expand Down
47 changes: 47 additions & 0 deletions OpenAI.Playground/TestHelpers/EmbeddingTestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using OpenAI.GPT3.Interfaces;
using OpenAI.GPT3.ObjectModels;
using OpenAI.GPT3.ObjectModels.RequestModels;
using System.ComponentModel.DataAnnotations;
using System.Numerics;

namespace OpenAI.Playground.TestHelpers
{
internal static class EmbeddingTestHelper
{
public static async Task RunSimpleEmbeddingTest(IOpenAIService sdk)
{
ConsoleExtensions.WriteLine("Simple Embedding test is starting:", ConsoleColor.Cyan);

try
{
ConsoleExtensions.WriteLine("Embedding Test:", ConsoleColor.DarkCyan);
var embeddingResult = await sdk.Embeddings.Create(new EmbeddingCreateRequest()
{
Input = new List<string> { "The quick brown fox jumped over the lazy dog." },
Model = Models.TextSearchAdaDocV1
});

if (embeddingResult.Successful)
{
Console.WriteLine(embeddingResult.Data.FirstOrDefault());
}
else
{
if (embeddingResult.Error == null)
{
throw new Exception("Unknown Error");
}

Console.WriteLine($"{embeddingResult.Error.Code}: {embeddingResult.Error.Message}");
}

Console.WriteLine(embeddingResult.Data.FirstOrDefault());
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
}
17 changes: 17 additions & 0 deletions OpenAI.SDK/Interfaces/IEmbedding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using OpenAI.GPT3.ObjectModels.RequestModels;
using OpenAI.GPT3.ObjectModels.ResponseModels;

namespace OpenAI.GPT3.Interfaces;

/// <summary>
/// Creates an embedding vector representing the input text.
/// </summary>
public interface IEmbedding
{
/// <summary>
/// Creates a new embedding for the provided input and parameters.
/// </summary>
/// <param name="createEmbeddingModel"></param>
/// <returns></returns>
Task<EmbeddingCreateResponse> Create(EmbeddingCreateRequest createEmbeddingModel);
}
3 changes: 2 additions & 1 deletion OpenAI.SDK/Interfaces/IFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public interface IFile
/// <param name="fileName">Name of file</param>
/// <param name="purpose">
/// The intended purpose of the uploaded documents.
/// Use "fine-tune" for <a href="https://beta.openai.com/docs/api-reference/fine-tunes">Fine-tuning</a>. This allows us to validate the format of the uploaded file.
/// Use "fine-tune" for <a href="https://beta.openai.com/docs/api-reference/fine-tunes">Fine-tuning</a>. This allows us
/// to validate the format of the uploaded file.
/// </param>
/// <returns></returns>
Task<FileUploadResponse> FileUpload(string purpose, byte[] file, string fileName);
Expand Down
5 changes: 5 additions & 0 deletions OpenAI.SDK/Interfaces/IOpenAISdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public interface IOpenAIService
/// </summary>
public ICompletion Completions { get; }

/// <summary>
/// Creates an embedding vector representing the input text.
/// </summary>
public IEmbedding Embeddings { get; }

/// <summary>
/// Files are used to upload documents that can be used across features like <see cref="FineTunes" />
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions OpenAI.SDK/Managers/OpenAIEmbedding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using OpenAI.GPT3.Extensions;
using OpenAI.GPT3.Interfaces;
using OpenAI.GPT3.ObjectModels.RequestModels;
using OpenAI.GPT3.ObjectModels.ResponseModels;

namespace OpenAI.GPT3.Managers;

public partial class OpenAIService : IEmbedding
{
public async Task<EmbeddingCreateResponse> Create(EmbeddingCreateRequest createEmbeddingRequest)
{
return await _httpClient.PostAndReadAsAsync<EmbeddingCreateResponse>(_endpointProvider.CreateEmbedding(), createEmbeddingRequest);
}
}
1 change: 1 addition & 0 deletions OpenAI.SDK/Managers/OpenAIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public OpenAIService(OpenAiOptions settings, HttpClient? httpClient = null)

public IModel Models => this;
public ICompletion Completions => this;
public IEmbedding Embeddings => this;
public IFile Files => this;
public IFineTune FineTunes => this;

Expand Down
97 changes: 77 additions & 20 deletions OpenAI.SDK/ObjectModels/Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ public enum Model

CurieSimilarityFast,

TextSimilarityAdaV1,
TextSimilarityBabbageV1,
TextSimilarityCurieV1,
TextSimilarityDavinciV1,

TextSearchAdaDocV1,
TextSearchBabbageDocV1,
TextSearchCurieDocV1,
TextSearchDavinciDocV1,

TextSearchAdaQueryV1,
TextSearchBabbageQueryV1,
TextSearchCurieQueryV1,
TextSearchDavinciQueryV1,

CodeSearchAdaCodeV1,
CodeSearchBabbageCodeV1,

CodeSearchAdaTextV1,
CodeSearchBabbageTextV1,

CodeDavinciV1,
CodeCushmanV1,

Expand All @@ -41,6 +62,11 @@ public enum Subject
Text,
InstructBeta,
SimilarityFast,
TextSimilarity,
TextSearchDocument,
TextSearchQuery,
CodeSearchCode,
CodeSearchText,
Code
}

Expand All @@ -64,6 +90,26 @@ public enum Subject
public static string CodeCushmanV1 => ModelNameBuilder(BaseEngine.Cushman, Subject.Code, "001");
public static string CodeDavinciV2 => ModelNameBuilder(BaseEngine.Davinci, Subject.Code, "002");

public static string TextSimilarityAdaV1 => ModelNameBuilder(BaseEngine.Ada, Subject.TextSimilarity, "001");
public static string TextSimilarityBabbageV1 => ModelNameBuilder(BaseEngine.Babbage, Subject.TextSimilarity, "001");
public static string TextSimilarityCurieV1 => ModelNameBuilder(BaseEngine.Curie, Subject.TextSimilarity, "001");
public static string TextSimilarityDavinciV1 => ModelNameBuilder(BaseEngine.Davinci, Subject.TextSimilarity, "001");

public static string TextSearchAdaDocV1 => ModelNameBuilder(BaseEngine.Ada, Subject.TextSearchDocument, "001");
public static string TextSearchBabbageDocV1 => ModelNameBuilder(BaseEngine.Babbage, Subject.TextSearchDocument, "001");
public static string TextSearchCurieDocV1 => ModelNameBuilder(BaseEngine.Curie, Subject.TextSearchDocument, "001");
public static string TextSearchDavinciDocV1 => ModelNameBuilder(BaseEngine.Davinci, Subject.TextSearchDocument, "001");
public static string TextSearchAdaQueryV1 => ModelNameBuilder(BaseEngine.Ada, Subject.TextSearchQuery, "001");
public static string TextSearchBabbageQueryV1 => ModelNameBuilder(BaseEngine.Babbage, Subject.TextSearchQuery, "001");
public static string TextSearchCurieQueryV1 => ModelNameBuilder(BaseEngine.Curie, Subject.TextSearchQuery, "001");
public static string TextSearchDavinciQueryV1 => ModelNameBuilder(BaseEngine.Davinci, Subject.TextSearchQuery, "001");

public static string CodeSearchAdaCodeV1 => ModelNameBuilder(BaseEngine.Ada, Subject.CodeSearchCode, "001");
public static string CodeSearchBabbageCodeV1 => ModelNameBuilder(BaseEngine.Babbage, Subject.CodeSearchCode, "001");
public static string CodeSearchAdaTextV1 => ModelNameBuilder(BaseEngine.Ada, Subject.CodeSearchText, "001");
public static string CodeSearchBabbageTextV1 => ModelNameBuilder(BaseEngine.Babbage, Subject.CodeSearchText, "001");


/// <summary>
/// This method does not guarantee returned model exists.
/// </summary>
Expand All @@ -73,23 +119,12 @@ public enum Subject
/// <returns></returns>
public static string ModelNameBuilder(this BaseEngine baseEngine, Subject? subject = null, string? version = null)
{
return ModelNameBuilder(baseEngine.EnumToString(), subject?.EnumToString(), version);
return ModelNameBuilder(baseEngine.EnumToString(), subject?.EnumToString(baseEngine.EnumToString()), version);
}

public static string ModelNameBuilder(string baseEngine, string? subject, string? version)
{
var response = baseEngine;
if (!string.IsNullOrEmpty(subject))
{
if (subject == Subject.InstructBeta.EnumToString() || subject == Subject.SimilarityFast.EnumToString())
{
response = $"{baseEngine}-{subject}";
}
else
{
response = $"{subject}-{baseEngine}";
}
}
var response = subject ?? $"{baseEngine}";

if (!string.IsNullOrEmpty(version))
{
Expand Down Expand Up @@ -119,6 +154,22 @@ public static string EnumToString(this Model engine)
Model.CodeDavinciV1 => CodeDavinciV1,
Model.CodeCushmanV1 => CodeCushmanV1,
Model.CodeDavinciV2 => CodeDavinciV2,
Model.TextSimilarityAdaV1 => TextSimilarityAdaV1,
Model.TextSimilarityBabbageV1 => TextSimilarityBabbageV1,
Model.TextSimilarityCurieV1 => TextSimilarityCurieV1,
Model.TextSimilarityDavinciV1 => TextSimilarityDavinciV1,
Model.TextSearchAdaDocV1 => TextSearchAdaDocV1,
Model.TextSearchBabbageDocV1 => TextSearchBabbageDocV1,
Model.TextSearchCurieDocV1 => TextSearchCurieDocV1,
Model.TextSearchDavinciDocV1 => TextSearchDavinciDocV1,
Model.TextSearchAdaQueryV1 => TextSearchAdaQueryV1,
Model.TextSearchBabbageQueryV1 => TextSearchBabbageQueryV1,
Model.TextSearchCurieQueryV1 => TextSearchCurieQueryV1,
Model.TextSearchDavinciQueryV1 => TextSearchDavinciQueryV1,
Model.CodeSearchAdaCodeV1 => CodeSearchAdaCodeV1,
Model.CodeSearchBabbageCodeV1 => CodeSearchBabbageCodeV1,
Model.CodeSearchAdaTextV1 => CodeSearchAdaTextV1,
Model.CodeSearchBabbageTextV1 => CodeSearchBabbageTextV1,
_ => throw new ArgumentOutOfRangeException(nameof(engine), engine, null)
};
}
Expand All @@ -136,16 +187,22 @@ private static string EnumToString(this BaseEngine baseEngine)
};
}

private static string EnumToString(this Subject subject)
public static string EnumToString(this Subject subject, string baseEngine)
{
return subject switch
return string.Format(subject switch
{
Subject.Text => "text",
Subject.InstructBeta => "instruct-beta",
Subject.SimilarityFast => "similarity-fast",
Subject.Code => "code",
//{0}-{1}
Subject.Text => "text-{0}",
Subject.InstructBeta => "{0}-instruct-beta",
Subject.SimilarityFast => "{0}-similarity-fast",
Subject.TextSimilarity => "text-similarity-{0}",
Subject.TextSearchDocument => "text-search-{0}-doc",
Subject.TextSearchQuery => "text-search-{0}-query",
Subject.CodeSearchCode => "code-search-{0}-code",
Subject.CodeSearchText => "code-search-{0}-text",
Subject.Code => "code-{0}",
_ => throw new ArgumentOutOfRangeException(nameof(subject), subject, null)
};
}, baseEngine);
}
}
}
37 changes: 37 additions & 0 deletions OpenAI.SDK/ObjectModels/RequestModels/EmbeddingCreateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using OpenAI.GPT3.Interfaces;

namespace OpenAI.GPT3.ObjectModels.RequestModels
{
//TODO Update Usage of link (see cref)
//TODO add model validation
//TODO check what is string or array for prompt,..
public record EmbeddingCreateRequest : IModelValidate
{
/// <summary>
/// Input text to get embeddings for, encoded as a string or array of tokens. To get embeddings for multiple inputs
/// in a single request, pass an array of strings or array of token arrays. Each input must not exceed 2048 tokens in
/// length.
/// Unless your are embedding code, we suggest replacing newlines (`\n`) in your input with a single space, as we have
/// observed inferior results when newlines are present.
/// </summary>
/// <see cref="https://beta.openai.com/docs/api-reference/embeddings/create#embeddings/create-input" />
[JsonPropertyName("input")]
public List<string>? Input { get; set; }


/// <summary>
/// ID of the model to use. You can use the [List models](/docs/api-reference/models/list) API to see all of your
/// available models, or see our [Model overview](/docs/models/overview) for descriptions of them.
/// </summary>
/// <see cref="https://beta.openai.com/docs/api-reference/embeddings/create#embeddings/create-model" />
[JsonPropertyName("model")]
public string? Model { get; set; }

public IEnumerable<ValidationResult> Validate()
{
throw new NotImplementedException();
}
}
}
18 changes: 18 additions & 0 deletions OpenAI.SDK/ObjectModels/ResponseModels/EmbeddingCreateResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json.Serialization;

namespace OpenAI.GPT3.ObjectModels.ResponseModels
{
public record EmbeddingCreateResponse : BaseResponse
{
[JsonPropertyName("model")] public string Model { get; set; }

[JsonPropertyName("data")] public List<EmbeddingResponse> Data { get; set; }
}

public record EmbeddingResponse
{
[JsonPropertyName("index")] public int? Index { get; set; }

[JsonPropertyName("embedding")] public List<double> Embedding { get; set; }
}
}
2 changes: 1 addition & 1 deletion OpenAI.SDK/OpenAI.GPT3.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<PackageProjectUrl>https://openai.com/</PackageProjectUrl>
<PackageIcon>OpenAI-Logo.png</PackageIcon>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>6.2.0</Version>
<Version>6.3.0</Version>
<Authors>Tolga Kayhan, Betalgo</Authors>
<Company>Betalgo Up Ltd.</Company>
<Product>OpenAI GPT-3 dotnet SDK</Product>
Expand Down
6 changes: 6 additions & 0 deletions OpenAI.SDK/OpenAiEndpointProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal interface IOpenAiEndpointProvider
string FineTuneListEvents(string fineTuneId);
string FineTuneDelete(string fineTuneId);
string FineTuneCompletions();
string CreateEmbedding();
}

internal class OpenAiEndpointProvider : IOpenAiEndpointProvider
Expand Down Expand Up @@ -97,6 +98,11 @@ public string FineTuneCompletions()
return $"/{_apiVersion}/completions";
}

public string CreateEmbedding()
{
return $"/{_apiVersion}/embeddings";
}

private string Files()
{
return $"/{_apiVersion}/files";
Expand Down
20 changes: 18 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,29 @@
```
Install-Package Betalgo.OpenAI.GPT3
```
For changelogs please go end of the document.
For changelogs please go to end of the document.

Unofficial - Dotnet SDK for OpenAI GTP-3.
GPT-3 doesn't have any official .Net SDK.

## Features
- [x] Models
- [x] Completions
- [ ] Edit
- [x] Mars
- [x] Embeddings
- [x] Files
- [x] Fine-tunes
- [ ] Moderation


*I was building an SDK for myself then I decide to share it, I hope it will be useful for you. I haven't maintained any open source projects before. Any help would be much appreciated. I am open to suggestions If you would like to contribute somehow.*

I will be using the latest libraries all the time. Also, next releasing will include breaking changes frequently *(as I mentioned before I was building the SDK for myself. Unfortunately I do not have time to plan these changes and support lower version apps)*. So please be aware of that before starting to use the library.

As you can guess I do not accept any damage caused by use of the library. You are always free to use other libraries or OpenAI Web-API.

Visit https://openai.com/ to get your API key.
Visit https://openai.com/ to get your API key. Also documentation with more detail is avaliable there.

## Sample Usages
The repository includes one sample project already **"OpenAI.Playground"** You can check playground project to see how I was testing it while I was developing the library. Be carefull while playing with it. Some test methods will delete your files or fine tunings. **I would suggest to use different account than your main account while you use playground.**
Expand Down Expand Up @@ -94,4 +105,9 @@ I couldn't find enough time to test all the methods or improve the documentation
* To support fast engine name changing I have created a new Method, `Models.ModelNameBuilder()` you may consider using it.
### 6.2.0
* Removed deprecated Answers, Classifications, and Search endpoints https://community.openai.com/t/answers-classification-search-endpoint-deprecation/18532. They will be still avaliable until December at web-API. If you still need them please do not update to this version.
* Code clean-up
### 6.3.0
* Thanks to @c-d and @sarilouis for contributions on this version.
* Now we support Embedding endpoint. Thanks to @sarilouis
* Bug fixes and updates for Models
* Code clean-up

0 comments on commit e5a6424

Please sign in to comment.