From 864263d9a058e151014ecbeb5837e8e9d7baf0b5 Mon Sep 17 00:00:00 2001 From: Matej Samler Date: Wed, 1 Feb 2023 11:16:13 +0100 Subject: [PATCH 1/3] Added embedding endpoint and tests --- OpenAI_API/Embedding/EmbeddingEndpoint.cs | 77 +++++++++++++++++++++ OpenAI_API/Embedding/EmbeddingRequest.cs | 50 ++++++++++++++ OpenAI_API/Embedding/EmbeddingResult.cs | 84 +++++++++++++++++++++++ OpenAI_API/OpenAIAPI.cs | 61 ++++++++-------- OpenAI_Tests/EmbeddingEndpointTests.cs | 48 +++++++++++++ 5 files changed, 293 insertions(+), 27 deletions(-) create mode 100644 OpenAI_API/Embedding/EmbeddingEndpoint.cs create mode 100644 OpenAI_API/Embedding/EmbeddingRequest.cs create mode 100644 OpenAI_API/Embedding/EmbeddingResult.cs create mode 100644 OpenAI_Tests/EmbeddingEndpointTests.cs 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); + } + } +} From 13fe061e36a403da2312f6d7f659a6469cab8219 Mon Sep 17 00:00:00 2001 From: Roger Date: Thu, 2 Feb 2023 19:33:11 -0800 Subject: [PATCH 2/3] Updated embedding endpoint and result to match new composition style --- OpenAI_API/Embedding/EmbeddingEndpoint.cs | 128 +++++++++------------ OpenAI_API/Embedding/EmbeddingRequest.cs | 81 +++++++------- OpenAI_API/Embedding/EmbeddingResult.cs | 130 +++++++++++----------- OpenAI_API/OpenAIAPI.cs | 7 +- OpenAI_Tests/EmbeddingEndpointTests.cs | 9 +- 5 files changed, 166 insertions(+), 189 deletions(-) diff --git a/OpenAI_API/Embedding/EmbeddingEndpoint.cs b/OpenAI_API/Embedding/EmbeddingEndpoint.cs index 6796b07..617af78 100644 --- a/OpenAI_API/Embedding/EmbeddingEndpoint.cs +++ b/OpenAI_API/Embedding/EmbeddingEndpoint.cs @@ -1,77 +1,59 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Security.Authentication; -using System.Text; -using System.Threading.Tasks; +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); - } - } - - } + /// + /// 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 : EndpointBase + { + /// + /// 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 }; + + /// + /// The name of the endpoint, which is the final path segment in the API URL. For example, "embeddings". + /// + protected override string Endpoint { get { return "embeddings"; } } + + /// + /// Constructor of the api endpoint. Rather than instantiating this yourself, access it through an instance of as . + /// + /// + internal EmbeddingEndpoint(OpenAIAPI api) : base(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) + { + EmbeddingRequest req = new EmbeddingRequest(DefaultEmbeddingRequestArgs.Model, input); + return await CreateEmbeddingAsync(req); + } + + /// + /// 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) + { + return await HttpPost(postData: request); + } + + /// + /// Ask the API to embedd text using the default embedding model + /// + /// Text to be embedded + /// Asynchronously returns the first embedding result as an array of floats. + public async Task GetEmbeddingsAsync(string input) + { + EmbeddingRequest req = new EmbeddingRequest(DefaultEmbeddingRequestArgs.Model, input); + var embeddingResult = await CreateEmbeddingAsync(req); + return embeddingResult?.Data?[0]?.Embedding; + } + } } diff --git a/OpenAI_API/Embedding/EmbeddingRequest.cs b/OpenAI_API/Embedding/EmbeddingRequest.cs index a08b738..0ffb12f 100644 --- a/OpenAI_API/Embedding/EmbeddingRequest.cs +++ b/OpenAI_API/Embedding/EmbeddingRequest.cs @@ -1,50 +1,51 @@ 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; } + /// + /// 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 . + /// + [JsonProperty("model")] + public string 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; } - /// - /// Main text to be embedded - /// - [JsonProperty("input")] - public string Input { get; set; } + /// + /// Cretes a new, empty + /// + public EmbeddingRequest() + { - /// - /// 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; + } - /// - /// 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; - } - } + /// + /// Creates a new with the specified input and the model. + /// + /// The prompt to transform + public EmbeddingRequest(string input) + { + Model = OpenAI_API.Model.AdaTextEmbedding; + this.Input = input; + } + } } diff --git a/OpenAI_API/Embedding/EmbeddingResult.cs b/OpenAI_API/Embedding/EmbeddingResult.cs index 7dcceb6..2801ef2 100644 --- a/OpenAI_API/Embedding/EmbeddingResult.cs +++ b/OpenAI_API/Embedding/EmbeddingResult.cs @@ -1,84 +1,78 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Text; +using System.Linq; 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")] + /// + /// Represents an embedding result returned by the Embedding API. + /// + public class EmbeddingResult : ApiResultBase + { + /// + /// List of results of the embedding + /// + [JsonProperty("data")] + public Data[] Data { get; set; } - public string Object { get; set; } + /// + /// Usage statistics of how many tokens have been used for this request + /// + [JsonProperty("usage")] + public Usage Usage { get; set; } - /// - /// List of results of the embedding - /// - [JsonProperty("data")] - public Data[] Data { get; set; } + /// + /// Allows an EmbeddingResult to be implicitly cast to the array of floats repsresenting the first ebmedding result + /// + /// The to cast to an array of floats. + public static implicit operator float[](EmbeddingResult embeddingResult) + { + return embeddingResult.Data.FirstOrDefault()?.Embedding; + } + } - /// - /// Name of the model used to generate this embedding - /// - [JsonProperty("model")] - public string Model { 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")] - /// - /// Usage statistics of how many tokens have been used for this request - /// - [JsonProperty("usage")] - public Usage Usage { get; set; } - } + public string Object { 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")] + /// + /// The input text represented as a vector (list) of floating point numbers + /// + [JsonProperty("embedding")] + public float[] Embedding { get; set; } - public string Object { get; set; } + /// + /// Index + /// + [JsonProperty("index")] + public int Index { 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; } - /// - /// 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 d764408..93f21e0 100644 --- a/OpenAI_API/OpenAIAPI.cs +++ b/OpenAI_API/OpenAIAPI.cs @@ -10,6 +10,11 @@ namespace OpenAI_API /// public class OpenAIAPI { + /// + /// Base url for OpenAI + /// + public string ApiUrlBase = "https://api.openai.com/v1/"; + /// /// The API authentication information to use for API calls /// @@ -24,7 +29,7 @@ public OpenAIAPI(APIAuthentication apiKeys = null) this.Auth = apiKeys.ThisOrDefault(); Completions = new CompletionEndpoint(this); Models = new ModelsEndpoint(this); - Search = new SearchEndpoint(this); + //Search = new SearchEndpoint(this); Embeddings = new EmbeddingEndpoint(this); } diff --git a/OpenAI_Tests/EmbeddingEndpointTests.cs b/OpenAI_Tests/EmbeddingEndpointTests.cs index 93eb110..982a91b 100644 --- a/OpenAI_Tests/EmbeddingEndpointTests.cs +++ b/OpenAI_Tests/EmbeddingEndpointTests.cs @@ -2,9 +2,7 @@ using OpenAI_API; using OpenAI_API.Embedding; using System; -using System.Collections.Generic; using System.Linq; -using System.Text; namespace OpenAI_Tests { @@ -30,7 +28,6 @@ public void GetBasicEmbedding() Assert.That(results.Data.First().Embedding.Length == 1536); } - [Test] public void GetSimpleEmbedding() { @@ -38,11 +35,9 @@ public void GetSimpleEmbedding() Assert.IsNotNull(api.Embeddings); - var results = api.Embeddings.CreateEmbeddingAsync("A test text for embedding").Result; + var results = api.Embeddings.GetEmbeddingsAsync("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); + Assert.That(results.Length == 1536); } } } From 0788505677795c46aa417b711f75f4c22c7c1bc7 Mon Sep 17 00:00:00 2001 From: Roger Date: Thu, 2 Feb 2023 19:38:10 -0800 Subject: [PATCH 3/3] Updated EmbeddingResult.Data to be a List rather than an array --- OpenAI_API/Embedding/EmbeddingResult.cs | 3 ++- OpenAI_Tests/EmbeddingEndpointTests.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenAI_API/Embedding/EmbeddingResult.cs b/OpenAI_API/Embedding/EmbeddingResult.cs index 2801ef2..611b172 100644 --- a/OpenAI_API/Embedding/EmbeddingResult.cs +++ b/OpenAI_API/Embedding/EmbeddingResult.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Collections.Generic; using System.Linq; namespace OpenAI_API.Embedding @@ -12,7 +13,7 @@ public class EmbeddingResult : ApiResultBase /// List of results of the embedding /// [JsonProperty("data")] - public Data[] Data { get; set; } + public List Data { get; set; } /// /// Usage statistics of how many tokens have been used for this request diff --git a/OpenAI_Tests/EmbeddingEndpointTests.cs b/OpenAI_Tests/EmbeddingEndpointTests.cs index 982a91b..5ecfaa5 100644 --- a/OpenAI_Tests/EmbeddingEndpointTests.cs +++ b/OpenAI_Tests/EmbeddingEndpointTests.cs @@ -24,7 +24,7 @@ public void GetBasicEmbedding() 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.NotZero(results.Data.Count); Assert.That(results.Data.First().Embedding.Length == 1536); }