OpenAI-DotNet 6.4.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package OpenAI-DotNet --version 6.4.3
NuGet\Install-Package OpenAI-DotNet -Version 6.4.3
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenAI-DotNet" Version="6.4.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add OpenAI-DotNet --version 6.4.3
#r "nuget: OpenAI-DotNet, 6.4.3"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install OpenAI-DotNet as a Cake Addin
#addin nuget:?package=OpenAI-DotNet&version=6.4.3

// Install OpenAI-DotNet as a Cake Tool
#tool nuget:?package=OpenAI-DotNet&version=6.4.3

OpenAI-DotNet

Discord NuGet version (OpenAI-DotNet) NuGet version (OpenAI-DotNet-Proxy) Nuget Publish

A simple C# .NET client library for OpenAI to use use chat-gpt, GPT-4, GPT-3.5-Turbo and Dall-E though their RESTful API (currently in beta). Independently developed, this is not an official library and I am not affiliated with OpenAI. An OpenAI API account is required.

Forked from OpenAI-API-dotnet.

More context on Roger Pincombe's blog.

This repository is available to transfer to the OpenAI organization if they so choose to accept it.

Requirements

  • This library targets .NET 6.0 and above.
  • It should work across console apps, winforms, wpf, asp.net, etc.
  • It should also work across Windows, Linux, and Mac.

Getting started

Install from NuGet

Install package OpenAI-DotNet from Nuget. Here's how via command line:

Install-Package OpenAI-DotNet

Looking to use OpenAI-DotNet in the Unity Game Engine? Check out our unity package on OpenUPM:

openupm

Documentation

Table of Contents

Authentication

There are 3 ways to provide your API keys, in order of precedence:

  1. Pass keys directly with constructor
  2. Load key from configuration file
  3. Use System Environment Variables

You use the OpenAIAuthentication when you initialize the API as shown:

Pass keys directly with constructor
var api = new OpenAIClient("sk-apiKey");

Or create a OpenAIAuthentication object manually

var api = new OpenAIClient(new OpenAIAuthentication("sk-apiKey", "org-yourOrganizationId"));
Load key from configuration file

Attempts to load api keys from a configuration file, by default .openai in the current directory, optionally traversing up the directory tree or in the user's home directory.

To create a configuration file, create a new text file named .openai and containing the line:

Organization entry is optional.

Json format
{
  "apiKey": "sk-aaaabbbbbccccddddd",
  "organization": "org-yourOrganizationId"
}
Deprecated format
OPENAI_KEY=sk-aaaabbbbbccccddddd
ORGANIZATION=org-yourOrganizationId

You can also load the file directly with known path by calling a static method in Authentication:

var api = new OpenAIClient(OpenAIAuthentication.LoadFromDirectory("your/path/to/.openai"));;
Use System Environment Variables

Use your system's environment variables specify an api key and organization to use.

  • Use OPENAI_API_KEY for your api key.
  • Use OPENAI_ORGANIZATION_ID to specify an organization.
var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv());

Azure OpenAI

You can also choose to use Microsoft's Azure OpenAI deployments as well. To setup the client to use your deployment, you'll need to pass in OpenAIClientSettings into the client constructor.

var auth = new OpenAIAuthentication("sk-apiKey");
var settings = new OpenAIClientSettings(resourceName: "your-resource", deploymentId: "your-deployment-id");
var api = new OpenAIClient(auth, settings);
Azure Active Directory Authentication

Authenticate with MSAL as usual and get access token, then use the access token when creating your OpenAIAuthentication. Then be sure to set useAzureActiveDirectory to true when creating your OpenAIClientSettings.

Tutorial: Desktop app that calls web APIs: Acquire a token

// get your access token using any of the MSAL methods
var accessToken = result.AccessToken;
var auth = new OpenAIAuthentication(accessToken);
var settings = new OpenAIClientSettings(resourceName: "your-resource", deploymentId: "your-deployment-id", useActiveDirectoryAuthentication: true);
var api = new OpenAIClient(auth, settings);

OpenAI API Proxy

NuGet version (OpenAI-DotNet-Proxy)

Using either the OpenAI-DotNet or com.openai.unity packages directly in your front-end app may expose your API keys and other sensitive information. To mitigate this risk, it is recommended to set up an intermediate API that makes requests to OpenAI on behalf of your front-end app. This library can be utilized for both front-end and intermediary host configurations, ensuring secure communication with the OpenAI API.

Front End Example

In the front end example, you will need to securely authenticate your users using your preferred OAuth provider. Once the user is authenticated, exchange your custom auth token with your API key on the backend.

Follow these steps:

  1. Setup a new project using either the OpenAI-DotNet or com.openai.unity packages.
  2. Authenticate users with your OAuth provider.
  3. After successful authentication, create a new OpenAIAuthentication object and pass in the custom token with the prefix sess-.
  4. Create a new OpenAIClientSettings object and specify the domain where your intermediate API is located.
  5. Pass your new auth and settings objects to the OpenAIClient constructor when you create the client instance.

Here's an example of how to set up the front end:

var authToken = await LoginAsync();
var auth = new OpenAIAuthentication($"sess-{authToken}");
var settings = new OpenAIClientSettings(domain: "api.your-custom-domain.com");
var api = new OpenAIClient(auth, settings);

This setup allows your front end application to securely communicate with your backend that will be using the OpenAI-DotNet-Proxy, which then forwards requests to the OpenAI API. This ensures that your OpenAI API keys and other sensitive information remain secure throughout the process.

Back End Example

In this example, we demonstrate how to set up and use OpenAIProxyStartup in a new ASP.NET Core web app. The proxy server will handle authentication and forward requests to the OpenAI API, ensuring that your API keys and other sensitive information remain secure.

  1. Create a new ASP.NET Core minimal web API project.
  2. Add the OpenAI-DotNet nuget package to your project.
    • Powershell install: Install-Package OpenAI-DotNet-Proxy
    • Manually editing .csproj: <PackageReference Include="OpenAI-DotNet-Proxy" />
  3. Create a new class that inherits from AbstractAuthenticationFilter and override the ValidateAuthentication method. This will implement the IAuthenticationFilter that you will use to check user session token against your internal server.
  4. In Program.cs, create a new proxy web application by calling OpenAIProxyStartup.CreateDefaultHost method, passing your custom AuthenticationFilter as a type argument.
  5. Create OpenAIAuthentication and OpenAIClientSettings as you would normally with your API keys, org id, or Azure settings.
public partial class Program
{
    private class AuthenticationFilter : AbstractAuthenticationFilter
    {
        public override void ValidateAuthentication(IHeaderDictionary request)
        {
            // You will need to implement your own class to properly test
            // custom issued tokens you've setup for your end users.
            if (!request.Authorization.ToString().Contains(userToken))
            {
                throw new AuthenticationException("User is not authorized");
            }
        }
    }

    public static void Main(string[] args)
    {
        var auth = OpenAIAuthentication.LoadFromEnv();
        var settings = new OpenAIClientSettings(/* your custom settings if using Azure OpenAI */);
        var openAIClient = new OpenAIClient(auth, settings);
        var proxy = OpenAIProxyStartup.CreateDefaultHost<AuthenticationFilter>(args, openAIClient);
        proxy.Run();
    }
}

Once you have set up your proxy server, your end users can now make authenticated requests to your proxy api instead of directly to the OpenAI API. The proxy server will handle authentication and forward requests to the OpenAI API, ensuring that your API keys and other sensitive information remain secure.

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.

Also checkout model endpoint compatibility to understand which models work with which endpoints.

The Models API is accessed via OpenAIClient.ModelsEndpoint

List models

Lists the currently available models, and provides basic information about each one such as the owner and availability.

var api = new OpenAIClient();
var models = await api.ModelsEndpoint.GetModelsAsync();

foreach (var model in models)
{
    Console.WriteLine(model.ToString());
}
Retrieve model

Retrieves a model instance, providing basic information about the model such as the owner and permissions.

var api = new OpenAIClient();
var model = await api.ModelsEndpoint.GetModelDetailsAsync("text-davinci-003");
Console.WriteLine(model.ToString());
Delete Fine Tuned Model

Delete a fine-tuned model. You must have the Owner role in your organization.

var api = new OpenAIClient();
var result = await api.ModelsEndpoint.DeleteFineTuneModelAsync("your-fine-tuned-model");
Assert.IsTrue(result);

Completions

Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.

The Completions API is accessed via OpenAIClient.CompletionsEndpoint

var api = new OpenAIClient();
var result = await api.CompletionsEndpoint.CreateCompletionAsync("One Two Three One Two", temperature: 0.1, model: Model.Davinci);
Console.WriteLine(result);

To get the CompletionResult (which is mostly metadata), use its implicit string operator to get the text if all you want is the completion choice.

Completion Streaming

Streaming allows you to get results are they are generated, which can help your application feel more responsive, especially on slow models like Davinci.

var api = new OpenAIClient();

await api.CompletionsEndpoint.StreamCompletionAsync(result =>
{
    foreach (var choice in result.Completions)
    {
        Console.WriteLine(choice);
    }
}, "My name is Roger and I am a principal software engineer at Salesforce.  This is my resume:", maxTokens: 200, temperature: 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1, model: Model.Davinci);

Or if using IAsyncEnumerable{T} (C# 8.0+)

var api = new OpenAIClient();
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:", maxTokens: 200, temperature: 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1, model: Model.Davinci))
{
  Console.WriteLine(token);
}

Chat

Given a chat conversation, the model will return a chat completion response.

The Chat API is accessed via OpenAIClient.ChatEndpoint

Chat Completions

Creates a completion for the chat message

var api = new OpenAIClient();
var chatPrompts = new List<ChatPrompt>
{
    new ChatPrompt("system", "You are a helpful assistant."),
    new ChatPrompt("user", "Who won the world series in 2020?"),
    new ChatPrompt("assistant", "The Los Angeles Dodgers won the World Series in 2020."),
    new ChatPrompt("user", "Where was it played?"),
};
var chatRequest = new ChatRequest(chatPrompts);
var result = await api.ChatEndpoint.GetCompletionAsync(chatRequest);
Console.WriteLine(result.FirstChoice);
Chat Streaming
var api = new OpenAIClient();
var chatPrompts = new List<ChatPrompt>
{
    new ChatPrompt("system", "You are a helpful assistant."),
    new ChatPrompt("user", "Who won the world series in 2020?"),
    new ChatPrompt("assistant", "The Los Angeles Dodgers won the World Series in 2020."),
    new ChatPrompt("user", "Where was it played?"),
};
var chatRequest = new ChatRequest(chatPrompts, Model.GPT3_5_Turbo);

await api.ChatEndpoint.StreamCompletionAsync(chatRequest, result =>
{
    Console.WriteLine(result.FirstChoice);
});

Or if using IAsyncEnumerable{T} (C# 8.0+)

var api = new OpenAIClient();
var chatPrompts = new List<ChatPrompt>
{
    new ChatPrompt("system", "You are a helpful assistant."),
    new ChatPrompt("user", "Who won the world series in 2020?"),
    new ChatPrompt("assistant", "The Los Angeles Dodgers won the World Series in 2020."),
    new ChatPrompt("user", "Where was it played?"),
};
var chatRequest = new ChatRequest(chatPrompts, Model.GPT3_5_Turbo);

await foreach (var result in api.ChatEndpoint.StreamCompletionEnumerableAsync(chatRequest))
{
    Console.WriteLine(result.FirstChoice);
}

Edits

Given a prompt and an instruction, the model will return an edited version of the prompt.

The Edits API is accessed via OpenAIClient.EditsEndpoint

Create Edit

Creates a new edit for the provided input, instruction, and parameters using the provided input and instruction.

var api = new OpenAIClient();
var request = new EditRequest("What day of the wek is it?", "Fix the spelling mistakes");
var result = await api.EditsEndpoint.CreateEditAsync(request);
Console.WriteLine(result);

Embeddings

Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms.

Related guide: Embeddings

The Edits API is accessed via OpenAIClient.EmbeddingsEndpoint

Create Embeddings

Creates an embedding vector representing the input text.

var api = new OpenAIClient();
var model = await api.ModelsEndpoint.GetModelDetailsAsync("text-embedding-ada-002");
var result = await api.EmbeddingsEndpoint.CreateEmbeddingAsync("The food was delicious and the waiter...", model);
Console.WriteLine(result);

Audio

Converts audio into text.

The Audio API is accessed via OpenAIClient.AudioEndpoint

Create Transcription

Transcribes audio into the input language.

var api = new OpenAIClient();
var request = new AudioTranscriptionRequest(Path.GetFullPath(audioAssetPath), language: "en");
var result = await api.AudioEndpoint.CreateTranscriptionAsync(request);
Console.WriteLine(result);
Create Translation

Translates audio into into English.

var api = new OpenAIClient();
var request = new AudioTranslationRequest(Path.GetFullPath(audioAssetPath));
var result = await api.AudioEndpoint.CreateTranslationAsync(request);
Console.WriteLine(result);

Images

Given a prompt and/or an input image, the model will generate a new image.

The Images API is accessed via OpenAIClient.ImagesEndpoint

Create Image

Creates an image given a prompt.

var api = new OpenAIClient();
var results = await api.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small);

foreach (var result in results)
{
    Console.WriteLine(result);
    // result == file://path/to/image.png
}
Edit Image

Creates an edited or extended image given an original image and a prompt.

var api = new OpenAIClient();
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);

foreach (var result in results)
{
    Console.WriteLine(result);
    // result == file://path/to/image.png
}
Create Image Variation

Creates a variation of a given image.

var api = new OpenAIClient();
var results = await api.ImagesEndPoint.CreateImageVariationAsync(Path.GetFullPath(imageAssetPath), 1, ImageSize.Small);

foreach (var result in results)
{
    Console.WriteLine(result);
    // result == file://path/to/image.png
}

Files

Files are used to upload documents that can be used with features like Fine-tuning.

The Files API is accessed via OpenAIClient.FilesEndpoint

List Files

Returns a list of files that belong to the user's organization.

var api = new OpenAIClient();
var files = await api.FilesEndpoint.ListFilesAsync();

foreach (var file in files)
{
    Console.WriteLine($"{file.Id} -> {file.Object}: {file.FileName} | {file.Size} bytes");
}
Upload File

Upload a file that contains document(s) to be used across various endpoints/features. Currently, the size of all the files uploaded by one organization can be up to 1 GB. Please contact us if you need to increase the storage limit.

var api = new OpenAIClient();
var fileData = await api.FilesEndpoint.UploadFileAsync("path/to/your/file.jsonl", "fine-tune");
Console.WriteLine(fileData.Id);
Delete File

Delete a file.

var api = new OpenAIClient();
var result = await api.FilesEndpoint.DeleteFileAsync(fileData);
Assert.IsTrue(result);
Retrieve File Info

Returns information about a specific file.

var api = new OpenAIClient();
var fileData = await GetFileInfoAsync(fileId);
Console.WriteLine($"{fileData.Id} -> {fileData.Object}: {fileData.FileName} | {fileData.Size} bytes");
Download File Content

Downloads the specified file.

var api = new OpenAIClient();
var downloadedFilePath = await api.FilesEndpoint.DownloadFileAsync(fileId, "path/to/your/save/directory");
Console.WriteLine(downloadedFilePath);
Assert.IsTrue(File.Exists(downloadedFilePath));

Fine Tuning

Manage fine-tuning jobs to tailor a model to your specific training data.

Related guide: Fine-tune models

The Files API is accessed via OpenAIClient.FineTuningEndpoint

Create Fine Tune Job

Creates a job that fine-tunes a specified model from a given dataset.

Response includes details of the enqueued job including job status and the name of the fine-tuned models once complete.

var api = new OpenAIClient();
var request = new CreateFineTuneRequest(fileData);
var fineTuneJob = await api.FineTuningEndpoint.CreateFineTuneJobAsync(request);
Console.WriteLine(fineTuneJob.Id);
List Fine Tune Jobs

List your organization's fine-tuning jobs.

var api = new OpenAIClient();
var fineTuneJobs = await api.FineTuningEndpoint.ListFineTuneJobsAsync();

foreach (var job in fineTuneJobs)
{
    Console.WriteLine($"{job.Id} -> {job.Status}");
}
Retrieve Fine Tune Job Info

Gets info about the fine-tune job.

var api = new OpenAIClient();
var result = await api.FineTuningEndpoint.RetrieveFineTuneJobInfoAsync(fineTuneJob);
Console.WriteLine($"{result.Id} -> {result.Status}");
Cancel Fine Tune Job

Immediately cancel a fine-tune job.

var api = new OpenAIClient();
var result = await api.FineTuningEndpoint.CancelFineTuneJobAsync(fineTuneJob);
Assert.IsTrue(result);
List Fine Tune Events

Get fine-grained status updates for a fine-tune job.

var api = new OpenAIClient();
var fineTuneEvents = await api.FineTuningEndpoint.ListFineTuneEventsAsync(fineTuneJob);
Console.WriteLine($"{fineTuneJob.Id} -> status: {fineTuneJob.Status} | event count: {fineTuneEvents.Count}");
Stream Fine Tune Events
var api = new OpenAIClient();
await api.FineTuningEndpoint.StreamFineTuneEventsAsync(fineTuneJob, fineTuneEvent =>
{
    Console.WriteLine($"  {fineTuneEvent.CreatedAt} [{fineTuneEvent.Level}] {fineTuneEvent.Message}");
});

Or if using IAsyncEnumerable{T} (C# 8.0+)

var api = new OpenAIClient();
await foreach (var fineTuneEvent in api.FineTuningEndpoint.StreamFineTuneEventsEnumerableAsync(fineTuneJob))
{
    Console.WriteLine($"  {fineTuneEvent.CreatedAt} [{fineTuneEvent.Level}] {fineTuneEvent.Message}");
}

Moderations

Given a input text, outputs if the model classifies it as violating OpenAI's content policy.

Related guide: Moderations

The Moderations API can be accessed via OpenAIClient.ModerationsEndpoint

Create Moderation

Classifies if text violates OpenAI's Content Policy.

var api = new OpenAIClient();
var response = await api.ModerationsEndpoint.GetModerationAsync("I want to kill them.");
Assert.IsTrue(response);

License

CC-0 Public Domain

This library is licensed CC-0, in the public domain. You can use it for whatever you want, publicly or privately, without worrying about permission or licensing or whatever. It's just a wrapper around the OpenAI API, so you still need to get access to OpenAI from them directly. I am not affiliated with OpenAI and this library is not endorsed by them, I just have beta access and wanted to make a C# library to access it more easily. Hopefully others find this useful as well. Feel free to open a PR if there's anything you want to contribute.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages (9)

Showing the top 5 NuGet packages that depend on OpenAI-DotNet:

Package Downloads
OpenAI-DotNet-Proxy

A simple Proxy API gateway for OpenAI-DotNet to make authenticated requests from a front end application without exposing your API keys.

GptInvoke

GptInvoke is a NuGet package that simplifies the integration of ChatGPT with your own service invocation. This allows you to easily combine AI with custom service execution, such as calling a webhook or performing an action in your application.

ModelMindAI

Library for building and running Model Mind AI Flows.

AICore.Core

Package Description

Universal.Tools.Core.Definitions.Extensions.OpenAI

Package Description

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on OpenAI-DotNet:

Repository Stars
dkgv/pinpoint
Keystroke launcher and personal command central. Alternative to Spotlight and Alfred for Windows. Alternative to Wox, PowerToys.
SlimeNull/OpenGptChat
An OpenAI Chat completion Client. Support for the six major universal languages in the world and some other languages. Support for dark mode.
Version Downloads Last updated
7.7.6 3,558 3/19/2024
7.7.5 5,236 3/3/2024
7.7.4 1,206 2/29/2024
7.7.3 832 2/27/2024
7.7.2 797 2/27/2024
7.7.1 588 2/25/2024
7.7.0 1,254 2/22/2024
7.6.5 3,236 2/6/2024
7.6.4 1,760 1/29/2024
7.6.3 546 1/26/2024
7.6.2 5,025 1/14/2024
7.6.1 2,371 1/6/2024
7.6.0 1,857 1/2/2024
7.5.0 2,219 12/22/2023
7.4.4 8,462 12/10/2023
7.4.3 1,039 12/7/2023
7.4.2 798 12/7/2023
7.4.1 3,903 12/3/2023
7.4.0 1,126 11/30/2023
7.3.8 584 11/29/2023
7.3.7 741 11/28/2023
7.3.6 414 11/28/2023
7.3.5 645 11/27/2023
7.3.4 3,516 11/24/2023
7.3.3 1,109 11/23/2023
7.3.2 814 11/22/2023
7.3.1 3,126 11/21/2023
7.3.0 434 11/21/2023
7.2.3 3,753 11/12/2023
7.2.2 1,538 11/10/2023
7.2.1 453 11/9/2023
7.2.0 3,222 11/9/2023
7.1.0 639 11/7/2023
7.0.10 4,434 10/7/2023
7.0.9 10,901 8/27/2023
7.0.8 2,313 8/25/2023
7.0.5 5,355 8/10/2023
7.0.4 4,038 7/27/2023
7.0.3 9,994 6/21/2023
7.0.2 895 6/19/2023
7.0.1 1,911 6/17/2023
7.0.0 828 6/17/2023
6.8.7 7,661 5/21/2023
6.8.6 645 5/19/2023
6.8.5 628 5/19/2023
6.8.3 1,333 5/16/2023
6.8.2 704 5/15/2023
6.8.1 2,673 5/7/2023
6.8.0 3,835 4/30/2023
6.7.4 1,043 4/27/2023
6.7.3 1,168 4/26/2023
6.7.2 1,274 4/23/2023
6.7.1 6,580 4/13/2023
6.7.0 1,888 4/10/2023
6.6.0 39,448 4/4/2023
6.5.3 2,519 3/29/2023
6.5.2 766 3/29/2023
6.5.1 1,272 3/27/2023
6.5.0 2,480 3/26/2023
6.4.3 678 3/26/2023
6.4.2 1,135 3/26/2023
6.4.1 2,549 3/24/2023
6.4.0 825 3/23/2023
6.3.2 1,662 3/22/2023
6.3.1 5,698 3/17/2023
6.3.0 1,632 3/17/2023
6.2.0 735 3/16/2023
6.1.0 3,007 3/14/2023
6.0.1 1,754 3/12/2023
6.0.0 790 3/11/2023
5.1.2 751 3/10/2023
5.1.1 773 3/9/2023
5.1.0 1,090 3/8/2023
5.0.2 1,586 3/6/2023
5.0.1 1,314 3/2/2023
5.0.0 924 3/2/2023
4.4.4 2,356 2/18/2023
4.4.3 1,795 2/10/2023
4.4.2 1,273 2/7/2023
4.4.1 933 2/4/2023
4.4.0 715 2/4/2023
4.3.0 957 1/31/2023
4.2.0 902 1/28/2023
4.1.0 814 1/27/2023
4.0.2 1,153 1/20/2023
4.0.1 983 1/17/2023
4.0.0 2,266 1/9/2023
3.0.1 8,192 4/14/2022
3.0.0 2,204 6/20/2021
2.0.1 919 5/29/2021
2.0.0 943 5/29/2021
1.0.1 929 5/2/2021
1.0.0 1,046 5/1/2021

Bump version to 6.4.3
- Fixed support for Azure Active Directory authentication for Azure OpenAI
Bump version to 6.4.2
- Misc fixes and added validation for OpenAICLientSettings
- Updated docs
- Decoupled proxy version from main package
Bump version to 6.4.1
- Added ImageEditRequest overloads for optional mask parameter
Bump version to 6.4.0
- Moved OpenAI-DotNet-Proxy back into its own project and package
- Make a few classes sealed that are not meant to be extended
Bump version to 6.3.2
- Attempt to fix dependency requirement for dotnet/runtime docker base images
- Made internal OpenAIClient constructor with HttpClient public
- Make sure we only copy the appropriate headers in the proxy
Bump version to 6.3.1
- Fixed apikey requiring sk- prefix with Azure OpenAI
Bump version to 6.3.0
- Removed OpenAI-DotNet-Proxy and put it directly in package on its own
Bump version to 6.2.0
- Added OpenAI-DotNet-Proxy project and package.
- Added support for custom domains
- Updated unit tests
- Updated docs
Bump version to 6.1.0
- Added support for gpt-4 models
Bump version to 6.0.1
- Updated package info
- Updated docs
Bump version to 6.0.0
- Added support for Azure OpenAI
Bump version to 5.1.2
- Fixed an issue when deleting personal account fine tuned models
Bump version to 5.1.1
- Refactored Model validation
- Added additional default models
- Deprecate OpenAIClient.DefaultModel
- Implemented chat completion streaming
- Refactored immutable types
Bump version to 5.1.0
- Add support for Audio endpoint and Whisper models
 - Audio Speech to text
 - Audio translation
Bump version to 5.0.2
- Support multiple inputs in embedding
- Added better model validation in all endpoints
Bump version to 5.0.1
- Fixed chat parameters
Bump version to 5.0.0
- Added Chat endpoint
Bump version to 4.4.4
- ImageEditRequest mask is now optional so long as texture has alpha transparency
- ImageVariationRequest added constructor overload for memory stream image
- Updated AuthInfo parameter validation
- Renamed OPEN_AI_ORGANIZATION_ID -> OPENAI_ORGANIZATION_ID
Bump version to 4.4.3
- added OPEN_AI_ORGANIZATION_ID environment variable
- deprecated Organization use OrganizationId instead
Bump version to 4.4.2
- Removed a useless assert
- Updated docs
Bump version to 4.4.1
- hotfix to CompletionsEndpoint to use IEnumerable<string>
- hotfix to cleanup Images endpoints
Bump version to 4.4.0
- Renamed Choice.Logprobs -> Choice.LogProbabilities
- Renamed OpenAI.Completions.Logprobs -> OpenAI.Completions.OpenAI.Completions
- Renamed CompletionRequest parameter names:
 - max_tokens -> maxTokens
 - top_p -> topP
- Updated CompletionRequest to accept IEnumerable<string> values for prompts and stopSequences
- Refactored all endpoints to use new response validation extension
- Added CancellationToken to most endpoints that had long running operations