diff --git a/OpenAI_API/Embedding/EmbeddingEndpoint.cs b/OpenAI_API/Embedding/EmbeddingEndpoint.cs
new file mode 100644
index 0000000..6796b07
--- /dev/null
+++ b/OpenAI_API/Embedding/EmbeddingEndpoint.cs
@@ -0,0 +1,77 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Security.Authentication;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OpenAI_API.Embedding
+{
+ ///
+ /// OpenAI’s text embeddings measure the relatedness of text strings by generating an embedding, which is a vector (list) of floating point numbers. The distance between two vectors measures their relatedness. Small distances suggest high relatedness and large distances suggest low relatedness.
+ ///
+ public class EmbeddingEndpoint
+ {
+ OpenAIAPI Api;
+ ///
+ /// This allows you to send request to the recommended model without needing to specify. Every request uses the model
+ ///
+ public EmbeddingRequest DefaultEmbeddingRequestArgs { get; set; } = new EmbeddingRequest() { Model = Model.AdaTextEmbedding };
+
+ ///
+ /// Constructor of the api endpoint. Rather than instantiating this yourself, access it through an instance of as .
+ ///
+ ///
+ internal EmbeddingEndpoint(OpenAIAPI api)
+ {
+ this.Api = api;
+ }
+
+ ///
+ /// Ask the API to embedd text using the default embedding model
+ ///
+ /// Text to be embedded
+ /// Asynchronously returns the embedding result. Look in its property of to find the vector of floating point numbers
+ public async Task CreateEmbeddingAsync(string input)
+ {
+ DefaultEmbeddingRequestArgs.Input = input;
+ return await CreateEmbeddingAsync(DefaultEmbeddingRequestArgs);
+ }
+
+ ///
+ /// Ask the API to embedd text using a custom request
+ ///
+ /// Request to be send
+ /// Asynchronously returns the embedding result. Look in its property of to find the vector of floating point numbers
+ public async Task CreateEmbeddingAsync(EmbeddingRequest request)
+ {
+ if (Api.Auth?.ApiKey is null)
+ {
+ throw new AuthenticationException("You must provide API authentication. Please refer to https://github.com/OkGoDoIt/OpenAI-API-dotnet#authentication for details.");
+ }
+
+ HttpClient client = new HttpClient();
+ client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Api.Auth.ApiKey);
+ client.DefaultRequestHeaders.Add("User-Agent", "okgodoit/dotnet_openai_api");
+
+ string jsonContent = JsonConvert.SerializeObject(request, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
+ var stringContent = new StringContent(jsonContent, Encoding.UTF8, "application/json");
+
+ var response = await client.PostAsync($"https://api.openai.com/v1/embeddings", stringContent);
+ if (response.IsSuccessStatusCode)
+ {
+ string resultAsString = await response.Content.ReadAsStringAsync();
+
+ var res = JsonConvert.DeserializeObject(resultAsString);
+
+ return res;
+ }
+ else
+ {
+ throw new HttpRequestException("Error calling OpenAi API to get completion. HTTP status code: " + response.StatusCode.ToString() + ". Request body: " + jsonContent);
+ }
+ }
+
+ }
+}
diff --git a/OpenAI_API/Embedding/EmbeddingRequest.cs b/OpenAI_API/Embedding/EmbeddingRequest.cs
new file mode 100644
index 0000000..a08b738
--- /dev/null
+++ b/OpenAI_API/Embedding/EmbeddingRequest.cs
@@ -0,0 +1,50 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenAI_API.Embedding
+{
+ ///
+ /// Represents a request to the Completions API. Matches with the docs at the OpenAI docs
+ ///
+ public class EmbeddingRequest
+ {
+ ///
+ /// ID of the model to use. You can use to see all of your available models, or use a standard model like .
+ ///
+ [JsonIgnore]
+ public Model Model { get; set; }
+
+ ///
+ /// The id/name of the model
+ ///
+ [JsonProperty("model")]
+ public string ModelName => Model.ModelID;
+
+ ///
+ /// Main text to be embedded
+ ///
+ [JsonProperty("input")]
+ public string Input { get; set; }
+
+ ///
+ /// Cretes a new, empty
+ ///
+ public EmbeddingRequest()
+ {
+
+ }
+
+ ///
+ /// Creates a new with the specified parameters
+ ///
+ /// The model to use. You can use to see all of your available models, or use a standard model like .
+ /// The prompt to transform
+ public EmbeddingRequest(Model model, string input)
+ {
+ Model = model;
+ this.Input = input;
+ }
+ }
+}
diff --git a/OpenAI_API/Embedding/EmbeddingResult.cs b/OpenAI_API/Embedding/EmbeddingResult.cs
new file mode 100644
index 0000000..7dcceb6
--- /dev/null
+++ b/OpenAI_API/Embedding/EmbeddingResult.cs
@@ -0,0 +1,84 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenAI_API.Embedding
+{
+ ///
+ /// Represents an embedding result returned by the Embedding API.
+ ///
+ public class EmbeddingResult
+ {
+ ///
+ /// Type of the response. In case of embeddings, this will be "list"
+ ///
+ [JsonProperty("object")]
+
+ public string Object { get; set; }
+
+ ///
+ /// List of results of the embedding
+ ///
+ [JsonProperty("data")]
+ public Data[] Data { get; set; }
+
+ ///
+ /// Name of the model used to generate this embedding
+ ///
+ [JsonProperty("model")]
+ public string Model { get; set; }
+
+ ///
+ /// Usage statistics of how many tokens have been used for this request
+ ///
+ [JsonProperty("usage")]
+ public Usage Usage { get; set; }
+ }
+
+ ///
+ /// Data returned from the Embedding API.
+ ///
+ public class Data
+ {
+ ///
+ /// Type of the response. In case of Data, this will be "embedding"
+ ///
+ [JsonProperty("object")]
+
+ public string Object { get; set; }
+
+ ///
+ /// The input text represented as a vector (list) of floating point numbers
+ ///
+ [JsonProperty("embedding")]
+ public float[] Embedding { get; set; }
+
+ ///
+ /// Index
+ ///
+ [JsonProperty("index")]
+ public int Index { get; set; }
+
+ }
+
+ ///
+ /// Usage statistics of how many tokens have been used for this request.
+ ///
+ public class Usage
+ {
+ ///
+ /// How many tokens did the prompt consist of
+ ///
+ [JsonProperty("prompt_tokens")]
+ public int PromptTokens { get; set; }
+
+ ///
+ /// How many tokens did the request consume total
+ ///
+ [JsonProperty("total_tokens")]
+ public int TotalTokens { get; set; }
+
+ }
+
+}
diff --git a/OpenAI_API/OpenAIAPI.cs b/OpenAI_API/OpenAIAPI.cs
index 74c5f55..3bc3ad8 100644
--- a/OpenAI_API/OpenAIAPI.cs
+++ b/OpenAI_API/OpenAIAPI.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
+using OpenAI_API.Embedding;
using System;
using System.Collections.Generic;
using System.IO;
@@ -9,32 +10,38 @@
namespace OpenAI_API
{
- ///
- /// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
- ///
- public class OpenAIAPI
- {
- ///
- /// The API authentication information to use for API calls
- ///
- public APIAuthentication Auth { get; set; }
-
- ///
- /// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
- ///
- /// The API authentication information to use for API calls, or to attempt to use the , potentially loading from environment vars or from a config file.
- public OpenAIAPI(APIAuthentication apiKeys = null)
- {
- this.Auth = apiKeys.ThisOrDefault();
- Completions = new CompletionEndpoint(this);
- Models = new ModelsEndpoint(this);
- Search = new SearchEndpoint(this);
- }
-
- ///
- /// 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).
- ///
- public CompletionEndpoint Completions { get; }
+ ///
+ /// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
+ ///
+ public class OpenAIAPI
+ {
+ ///
+ /// The API authentication information to use for API calls
+ ///
+ public APIAuthentication Auth { get; set; }
+
+ ///
+ /// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
+ ///
+ /// The API authentication information to use for API calls, or to attempt to use the , potentially loading from environment vars or from a config file.
+ public OpenAIAPI(APIAuthentication apiKeys = null)
+ {
+ this.Auth = apiKeys.ThisOrDefault();
+ Completions = new CompletionEndpoint(this);
+ Models = new ModelsEndpoint(this);
+ Search = new SearchEndpoint(this);
+ Embeddings = new EmbeddingEndpoint(this);
+ }
+
+ ///
+ /// 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).
+ ///
+ public CompletionEndpoint Completions { get; }
+
+ ///
+ /// The API lets you transform text into a vector (list) of floating point numbers. The distance between two vectors measures their relatedness. Small distances suggest high relatedness and large distances suggest low relatedness.
+ ///
+ public EmbeddingEndpoint Embeddings { get; }
///
/// The API endpoint for querying available Engines/models
@@ -51,5 +58,5 @@ public OpenAIAPI(APIAuthentication apiKeys = null)
- }
+ }
}
diff --git a/OpenAI_Tests/EmbeddingEndpointTests.cs b/OpenAI_Tests/EmbeddingEndpointTests.cs
new file mode 100644
index 0000000..93eb110
--- /dev/null
+++ b/OpenAI_Tests/EmbeddingEndpointTests.cs
@@ -0,0 +1,48 @@
+using NUnit.Framework;
+using OpenAI_API;
+using OpenAI_API.Embedding;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OpenAI_Tests
+{
+ public class EmbeddingEndpointTests
+ {
+ [SetUp]
+ public void Setup()
+ {
+ OpenAI_API.APIAuthentication.Default = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY"));
+ }
+
+ [Test]
+ public void GetBasicEmbedding()
+ {
+ var api = new OpenAI_API.OpenAIAPI();
+
+ Assert.IsNotNull(api.Embeddings);
+
+ var results = api.Embeddings.CreateEmbeddingAsync(new EmbeddingRequest(Model.AdaTextEmbedding, "A test text for embedding")).Result;
+ Assert.IsNotNull(results);
+ Assert.NotNull(results.Object);
+ Assert.NotZero(results.Data.Length);
+ Assert.That(results.Data.First().Embedding.Length == 1536);
+ }
+
+
+ [Test]
+ public void GetSimpleEmbedding()
+ {
+ var api = new OpenAI_API.OpenAIAPI();
+
+ Assert.IsNotNull(api.Embeddings);
+
+ var results = api.Embeddings.CreateEmbeddingAsync("A test text for embedding").Result;
+ Assert.IsNotNull(results);
+ Assert.NotNull(results.Object);
+ Assert.NotZero(results.Data.Length);
+ Assert.That(results.Data.First().Embedding.Length == 1536);
+ }
+ }
+}