-
Notifications
You must be signed in to change notification settings - Fork 433
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated embedding endpoint and result to match new composition style
- Loading branch information
Showing
5 changed files
with
166 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
{ | ||
/// <summary> | ||
/// 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. | ||
/// </summary> | ||
public class EmbeddingEndpoint | ||
{ | ||
OpenAIAPI Api; | ||
/// <summary> | ||
/// This allows you to send request to the recommended model without needing to specify. Every request uses the <see cref="Model.AdaTextEmbedding"/> model | ||
/// </summary> | ||
public EmbeddingRequest DefaultEmbeddingRequestArgs { get; set; } = new EmbeddingRequest() { Model = Model.AdaTextEmbedding }; | ||
|
||
/// <summary> | ||
/// Constructor of the api endpoint. Rather than instantiating this yourself, access it through an instance of <see cref="OpenAIAPI"/> as <see cref="OpenAIAPI.Embeddings"/>. | ||
/// </summary> | ||
/// <param name="api"></param> | ||
internal EmbeddingEndpoint(OpenAIAPI api) | ||
{ | ||
this.Api = api; | ||
} | ||
|
||
/// <summary> | ||
/// Ask the API to embedd text using the default embedding model <see cref="Model.AdaTextEmbedding"/> | ||
/// </summary> | ||
/// <param name="input">Text to be embedded</param> | ||
/// <returns>Asynchronously returns the embedding result. Look in its <see cref="Data.Embedding"/> property of <see cref="EmbeddingResult.Data"/> to find the vector of floating point numbers</returns> | ||
public async Task<EmbeddingResult> CreateEmbeddingAsync(string input) | ||
{ | ||
DefaultEmbeddingRequestArgs.Input = input; | ||
return await CreateEmbeddingAsync(DefaultEmbeddingRequestArgs); | ||
} | ||
|
||
/// <summary> | ||
/// Ask the API to embedd text using a custom request | ||
/// </summary> | ||
/// <param name="request">Request to be send</param> | ||
/// <returns>Asynchronously returns the embedding result. Look in its <see cref="Data.Embedding"/> property of <see cref="EmbeddingResult.Data"/> to find the vector of floating point numbers</returns> | ||
public async Task<EmbeddingResult> 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<EmbeddingResult>(resultAsString); | ||
|
||
return res; | ||
} | ||
else | ||
{ | ||
throw new HttpRequestException("Error calling OpenAi API to get completion. HTTP status code: " + response.StatusCode.ToString() + ". Request body: " + jsonContent); | ||
} | ||
} | ||
|
||
} | ||
/// <summary> | ||
/// 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. | ||
/// </summary> | ||
public class EmbeddingEndpoint : EndpointBase | ||
{ | ||
/// <summary> | ||
/// This allows you to send request to the recommended model without needing to specify. Every request uses the <see cref="Model.AdaTextEmbedding"/> model | ||
/// </summary> | ||
public EmbeddingRequest DefaultEmbeddingRequestArgs { get; set; } = new EmbeddingRequest() { Model = Model.AdaTextEmbedding }; | ||
|
||
/// <summary> | ||
/// The name of the endpoint, which is the final path segment in the API URL. For example, "embeddings". | ||
/// </summary> | ||
protected override string Endpoint { get { return "embeddings"; } } | ||
|
||
/// <summary> | ||
/// Constructor of the api endpoint. Rather than instantiating this yourself, access it through an instance of <see cref="OpenAIAPI"/> as <see cref="OpenAIAPI.Embeddings"/>. | ||
/// </summary> | ||
/// <param name="api"></param> | ||
internal EmbeddingEndpoint(OpenAIAPI api) : base(api) { } | ||
|
||
/// <summary> | ||
/// Ask the API to embedd text using the default embedding model <see cref="Model.AdaTextEmbedding"/> | ||
/// </summary> | ||
/// <param name="input">Text to be embedded</param> | ||
/// <returns>Asynchronously returns the embedding result. Look in its <see cref="Data.Embedding"/> property of <see cref="EmbeddingResult.Data"/> to find the vector of floating point numbers</returns> | ||
public async Task<EmbeddingResult> CreateEmbeddingAsync(string input) | ||
{ | ||
EmbeddingRequest req = new EmbeddingRequest(DefaultEmbeddingRequestArgs.Model, input); | ||
return await CreateEmbeddingAsync(req); | ||
} | ||
|
||
/// <summary> | ||
/// Ask the API to embedd text using a custom request | ||
/// </summary> | ||
/// <param name="request">Request to be send</param> | ||
/// <returns>Asynchronously returns the embedding result. Look in its <see cref="Data.Embedding"/> property of <see cref="EmbeddingResult.Data"/> to find the vector of floating point numbers</returns> | ||
public async Task<EmbeddingResult> CreateEmbeddingAsync(EmbeddingRequest request) | ||
{ | ||
return await HttpPost<EmbeddingResult>(postData: request); | ||
} | ||
|
||
/// <summary> | ||
/// Ask the API to embedd text using the default embedding model <see cref="Model.AdaTextEmbedding"/> | ||
/// </summary> | ||
/// <param name="input">Text to be embedded</param> | ||
/// <returns>Asynchronously returns the first embedding result as an array of floats.</returns> | ||
public async Task<float[]> GetEmbeddingsAsync(string input) | ||
{ | ||
EmbeddingRequest req = new EmbeddingRequest(DefaultEmbeddingRequestArgs.Model, input); | ||
var embeddingResult = await CreateEmbeddingAsync(req); | ||
return embeddingResult?.Data?[0]?.Embedding; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,51 @@ | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace OpenAI_API.Embedding | ||
{ | ||
/// <summary> | ||
/// Represents a request to the Completions API. Matches with the docs at <see href="https://platform.openai.com/docs/api-reference/embeddings">the OpenAI docs</see> | ||
/// </summary> | ||
public class EmbeddingRequest | ||
{ | ||
/// <summary> | ||
/// ID of the model to use. You can use <see cref="ModelsEndpoint.GetModelsAsync()"/> to see all of your available models, or use a standard model like <see cref="Model.AdaTextEmbedding"/>. | ||
/// </summary> | ||
[JsonIgnore] | ||
public Model Model { get; set; } | ||
/// <summary> | ||
/// Represents a request to the Completions API. Matches with the docs at <see href="https://platform.openai.com/docs/api-reference/embeddings">the OpenAI docs</see> | ||
/// </summary> | ||
public class EmbeddingRequest | ||
{ | ||
/// <summary> | ||
/// ID of the model to use. You can use <see cref="ModelsEndpoint.GetModelsAsync()"/> to see all of your available models, or use a standard model like <see cref="Model.AdaTextEmbedding"/>. | ||
/// </summary> | ||
[JsonProperty("model")] | ||
public string Model { get; set; } | ||
|
||
/// <summary> | ||
/// The id/name of the model | ||
/// </summary> | ||
[JsonProperty("model")] | ||
public string ModelName => Model.ModelID; | ||
/// <summary> | ||
/// Main text to be embedded | ||
/// </summary> | ||
[JsonProperty("input")] | ||
public string Input { get; set; } | ||
|
||
/// <summary> | ||
/// Main text to be embedded | ||
/// </summary> | ||
[JsonProperty("input")] | ||
public string Input { get; set; } | ||
/// <summary> | ||
/// Cretes a new, empty <see cref="EmbeddingRequest"/> | ||
/// </summary> | ||
public EmbeddingRequest() | ||
{ | ||
|
||
/// <summary> | ||
/// Cretes a new, empty <see cref="EmbeddingRequest"/> | ||
/// </summary> | ||
public EmbeddingRequest() | ||
{ | ||
} | ||
|
||
} | ||
/// <summary> | ||
/// Creates a new <see cref="EmbeddingRequest"/> with the specified parameters | ||
/// </summary> | ||
/// <param name="model">The model to use. You can use <see cref="ModelsEndpoint.GetModelsAsync()"/> to see all of your available models, or use a standard model like <see cref="Model.AdaTextEmbedding"/>.</param> | ||
/// <param name="input">The prompt to transform</param> | ||
public EmbeddingRequest(Model model, string input) | ||
{ | ||
Model = model; | ||
this.Input = input; | ||
} | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="EmbeddingRequest"/> with the specified parameters | ||
/// </summary> | ||
/// <param name="model">The model to use. You can use <see cref="ModelsEndpoint.GetModelsAsync()"/> to see all of your available models, or use a standard model like <see cref="Model.AdaTextEmbedding"/>.</param> | ||
/// <param name="input">The prompt to transform</param> | ||
public EmbeddingRequest(Model model, string input) | ||
{ | ||
Model = model; | ||
this.Input = input; | ||
} | ||
} | ||
/// <summary> | ||
/// Creates a new <see cref="EmbeddingRequest"/> with the specified input and the <see cref="Model.AdaTextEmbedding"/> model. | ||
/// </summary> | ||
/// <param name="input">The prompt to transform</param> | ||
public EmbeddingRequest(string input) | ||
{ | ||
Model = OpenAI_API.Model.AdaTextEmbedding; | ||
this.Input = input; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,78 @@ | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Linq; | ||
|
||
namespace OpenAI_API.Embedding | ||
{ | ||
/// <summary> | ||
/// Represents an embedding result returned by the Embedding API. | ||
/// </summary> | ||
public class EmbeddingResult | ||
{ | ||
/// <summary> | ||
/// Type of the response. In case of embeddings, this will be "list" | ||
/// </summary> | ||
[JsonProperty("object")] | ||
/// <summary> | ||
/// Represents an embedding result returned by the Embedding API. | ||
/// </summary> | ||
public class EmbeddingResult : ApiResultBase | ||
{ | ||
/// <summary> | ||
/// List of results of the embedding | ||
/// </summary> | ||
[JsonProperty("data")] | ||
public Data[] Data { get; set; } | ||
|
||
public string Object { get; set; } | ||
/// <summary> | ||
/// Usage statistics of how many tokens have been used for this request | ||
/// </summary> | ||
[JsonProperty("usage")] | ||
public Usage Usage { get; set; } | ||
|
||
/// <summary> | ||
/// List of results of the embedding | ||
/// </summary> | ||
[JsonProperty("data")] | ||
public Data[] Data { get; set; } | ||
/// <summary> | ||
/// Allows an EmbeddingResult to be implicitly cast to the array of floats repsresenting the first ebmedding result | ||
/// </summary> | ||
/// <param name="embeddingResult">The <see cref="EmbeddingResult"/> to cast to an array of floats.</param> | ||
public static implicit operator float[](EmbeddingResult embeddingResult) | ||
{ | ||
return embeddingResult.Data.FirstOrDefault()?.Embedding; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Name of the model used to generate this embedding | ||
/// </summary> | ||
[JsonProperty("model")] | ||
public string Model { get; set; } | ||
/// <summary> | ||
/// Data returned from the Embedding API. | ||
/// </summary> | ||
public class Data | ||
{ | ||
/// <summary> | ||
/// Type of the response. In case of Data, this will be "embedding" | ||
/// </summary> | ||
[JsonProperty("object")] | ||
|
||
/// <summary> | ||
/// Usage statistics of how many tokens have been used for this request | ||
/// </summary> | ||
[JsonProperty("usage")] | ||
public Usage Usage { get; set; } | ||
} | ||
public string Object { get; set; } | ||
|
||
/// <summary> | ||
/// Data returned from the Embedding API. | ||
/// </summary> | ||
public class Data | ||
{ | ||
/// <summary> | ||
/// Type of the response. In case of Data, this will be "embedding" | ||
/// </summary> | ||
[JsonProperty("object")] | ||
/// <summary> | ||
/// The input text represented as a vector (list) of floating point numbers | ||
/// </summary> | ||
[JsonProperty("embedding")] | ||
public float[] Embedding { get; set; } | ||
|
||
public string Object { get; set; } | ||
/// <summary> | ||
/// Index | ||
/// </summary> | ||
[JsonProperty("index")] | ||
public int Index { get; set; } | ||
|
||
/// <summary> | ||
/// The input text represented as a vector (list) of floating point numbers | ||
/// </summary> | ||
[JsonProperty("embedding")] | ||
public float[] Embedding { get; set; } | ||
} | ||
|
||
/// <summary> | ||
/// Index | ||
/// </summary> | ||
[JsonProperty("index")] | ||
public int Index { get; set; } | ||
/// <summary> | ||
/// Usage statistics of how many tokens have been used for this request. | ||
/// </summary> | ||
public class Usage | ||
{ | ||
/// <summary> | ||
/// How many tokens did the prompt consist of | ||
/// </summary> | ||
[JsonProperty("prompt_tokens")] | ||
public int PromptTokens { get; set; } | ||
|
||
} | ||
/// <summary> | ||
/// How many tokens did the request consume total | ||
/// </summary> | ||
[JsonProperty("total_tokens")] | ||
public int TotalTokens { get; set; } | ||
|
||
/// <summary> | ||
/// Usage statistics of how many tokens have been used for this request. | ||
/// </summary> | ||
public class Usage | ||
{ | ||
/// <summary> | ||
/// How many tokens did the prompt consist of | ||
/// </summary> | ||
[JsonProperty("prompt_tokens")] | ||
public int PromptTokens { get; set; } | ||
|
||
/// <summary> | ||
/// How many tokens did the request consume total | ||
/// </summary> | ||
[JsonProperty("total_tokens")] | ||
public int TotalTokens { get; set; } | ||
|
||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.