diff --git a/OpenAI-DotNet-Proxy/OpenAI-DotNet-Proxy.csproj b/OpenAI-DotNet-Proxy/OpenAI-DotNet-Proxy.csproj
index 9d8223af..5cccc098 100644
--- a/OpenAI-DotNet-Proxy/OpenAI-DotNet-Proxy.csproj
+++ b/OpenAI-DotNet-Proxy/OpenAI-DotNet-Proxy.csproj
@@ -1,24 +1,32 @@
-
- net6.0
- false
- disable
- false
- Stephen Hodgson
- 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.
- 2024
- CC0-1.0
- https://github.com/RageAgainstThePixel/OpenAI-DotNet
- https://github.com/RageAgainstThePixel/OpenAI-DotNet
- OpenAI, AI, ML, API, gpt, gpt-4, gpt-3.5-turbo, gpt-3, chatGPT, api-proxy, proxy, gateway
- OpenAI API Proxy
- OpenAI-DotNet-Proxy
- 7.7.10
- RageAgainstThePixel
- OpenAI.Proxy
- OpenAI-DotNet-Icon.png
- Version 7.7.10
+
+ net6.0
+ latest
+ disable
+ OpenAI API Proxy
+ OpenAI-DotNet-Proxy
+ OpenAI-DotNet-Proxy
+ OpenAI.Proxy
+ Stephen Hodgson
+ RageAgainstThePixel
+ A simple Proxy API gateway for OpenAI-DotNet to make authenticated requests from a front end application without exposing your API keys.
+ 2024
+ CC0-1.0
+ https://github.com/RageAgainstThePixel/OpenAI-DotNet
+ https://github.com/RageAgainstThePixel/OpenAI-DotNet
+ OpenAI, AI, ML, API, gpt, gpt-4, gpt-3.5-turbo, gpt-3, chatGPT, api-proxy, proxy, gateway
+ Readme.md
+ OpenAI-DotNet-Icon.png
+ true
+ false
+ true
+ false
+ false
+ 8.1.1
+
+Version 8.1.1
+- Renamed OpenAIProxyStartup to OpenAIProxy
+Version 7.7.10
- Updated EndpointRouteBuilder with optional route prefix parameter
Version 7.7.9
- Slight refactor of OpenAIProxyStartup to remove duplicate code
@@ -28,26 +36,22 @@ Version 7.7.8
- Updated OpenAI-DotNet-Test-Proxy to use WebApplication implementation
Version 7.7.7
- Added ValidateAuthenticationAsync
-
- True
- false
- Readme.md
- True
-
-
-
-
-
-
-
- True
- \
-
-
-
-
- True
- \
-
-
+
+
+
+
+
+
+
+
+ true
+ \
+
+
+
+
+ true
+ \
+
+
diff --git a/OpenAI-DotNet-Proxy/Proxy/OpenAIProxy.cs b/OpenAI-DotNet-Proxy/Proxy/OpenAIProxy.cs
new file mode 100644
index 00000000..4513a8bb
--- /dev/null
+++ b/OpenAI-DotNet-Proxy/Proxy/OpenAIProxy.cs
@@ -0,0 +1,114 @@
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using System;
+using System.Threading.Tasks;
+
+namespace OpenAI.Proxy
+{
+ ///
+ /// Used in ASP.NET Core WebApps to start your own OpenAI web api proxy.
+ ///
+ public class OpenAIProxy
+ {
+ private OpenAIClient openAIClient;
+ private IAuthenticationFilter authenticationFilter;
+
+ ///
+ /// Configures the and services.
+ ///
+ /// Services collection.
+ public void ConfigureServices(IServiceCollection services)
+ => SetupServices(services.BuildServiceProvider());
+
+ ///
+ /// Configures the to handle requests and forward them to OpenAI API.
+ ///
+ /// .
+ /// .
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ SetupServices(app.ApplicationServices);
+
+ app.UseHttpsRedirection();
+ app.UseRouting();
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapGet("/health", HealthEndpoint);
+ endpoints.MapOpenAIEndpoints(openAIClient, authenticationFilter);
+ });
+ }
+
+ ///
+ /// Creates a new that acts as a proxy web api for OpenAI.
+ ///
+ /// type to use to validate your custom issued tokens.
+ /// Startup args.
+ /// with configured and .
+ public static IHost CreateDefaultHost(string[] args, OpenAIClient openAIClient) where T : class, IAuthenticationFilter
+ => Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ webBuilder.ConfigureKestrel(ConfigureKestrel);
+ })
+ .ConfigureServices(services =>
+ {
+ services.AddSingleton(openAIClient);
+ services.AddSingleton();
+ }).Build();
+
+ ///
+ /// Creates a new that acts as a proxy web api for OpenAI.
+ ///
+ /// type to use to validate your custom issued tokens.
+ /// Startup args.
+ /// with configured and .
+ public static WebApplication CreateWebApplication(string[] args, OpenAIClient openAIClient) where T : class, IAuthenticationFilter
+ {
+ var builder = WebApplication.CreateBuilder(args);
+ builder.WebHost.ConfigureKestrel(ConfigureKestrel);
+ builder.Services.AddSingleton(openAIClient);
+ builder.Services.AddSingleton();
+ var app = builder.Build();
+ var startup = new OpenAIProxy();
+ startup.Configure(app, app.Environment);
+ return app;
+ }
+
+ private static void ConfigureKestrel(KestrelServerOptions options)
+ {
+ options.AllowSynchronousIO = false;
+ options.Limits.MinRequestBodyDataRate = null;
+ options.Limits.MinResponseDataRate = null;
+ options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);
+ options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(2);
+ }
+
+ private void SetupServices(IServiceProvider serviceProvider)
+ {
+ openAIClient ??= serviceProvider.GetRequiredService();
+ authenticationFilter ??= serviceProvider.GetRequiredService();
+ }
+
+ private static async Task HealthEndpoint(HttpContext context)
+ {
+ // Respond with a 200 OK status code and a plain text message
+ context.Response.StatusCode = StatusCodes.Status200OK;
+ const string contentType = "text/plain";
+ context.Response.ContentType = contentType;
+ const string content = "OK";
+ await context.Response.WriteAsync(content);
+ }
+ }
+}
diff --git a/OpenAI-DotNet-Proxy/Proxy/OpenAIProxyStartup.cs b/OpenAI-DotNet-Proxy/Proxy/OpenAIProxyStartup.cs
index 1023e239..55a4e927 100644
--- a/OpenAI-DotNet-Proxy/Proxy/OpenAIProxyStartup.cs
+++ b/OpenAI-DotNet-Proxy/Proxy/OpenAIProxyStartup.cs
@@ -2,113 +2,29 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
-using System.Threading.Tasks;
namespace OpenAI.Proxy
{
- ///
- /// Used in ASP.NET Core WebApps to start your own OpenAI web api proxy.
- ///
+ [Obsolete("Use OpenAIProxy")]
public class OpenAIProxyStartup
{
- private OpenAIClient openAIClient;
- private IAuthenticationFilter authenticationFilter;
+ private OpenAIProxy openAIProxy;
+
+ private OpenAIProxy OpenAIProxy => openAIProxy ??= new OpenAIProxy();
- ///
- /// Configures the and services.
- ///
- /// Services collection.
public void ConfigureServices(IServiceCollection services)
- => SetupServices(services.BuildServiceProvider());
+ => OpenAIProxy.ConfigureServices(services);
- ///
- /// Configures the to handle requests and forward them to OpenAI API.
- ///
- /// .
- /// .
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
-
- SetupServices(app.ApplicationServices);
-
- app.UseHttpsRedirection();
- app.UseRouting();
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapGet("/health", HealthEndpoint);
- endpoints.MapOpenAIEndpoints(openAIClient, authenticationFilter);
- });
- }
-
- ///
- /// Creates a new that acts as a proxy web api for OpenAI.
- ///
- /// type to use to validate your custom issued tokens.
- /// Startup args.
- /// with configured and .
- public static IHost CreateDefaultHost(string[] args, OpenAIClient openAIClient) where T : class, IAuthenticationFilter
- => Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup();
- webBuilder.ConfigureKestrel(ConfigureKestrel);
- })
- .ConfigureServices(services =>
- {
- services.AddSingleton(openAIClient);
- services.AddSingleton();
- }).Build();
-
- ///
- /// Creates a new that acts as a proxy web api for OpenAI.
- ///
- /// type to use to validate your custom issued tokens.
- /// Startup args.
- /// with configured and .
- public static WebApplication CreateWebApplication(string[] args, OpenAIClient openAIClient) where T : class, IAuthenticationFilter
- {
- var builder = WebApplication.CreateBuilder(args);
- builder.WebHost.ConfigureKestrel(ConfigureKestrel);
- builder.Services.AddSingleton(openAIClient);
- builder.Services.AddSingleton();
- var app = builder.Build();
- var startup = new OpenAIProxyStartup();
- startup.Configure(app, app.Environment);
- return app;
- }
-
- private static void ConfigureKestrel(KestrelServerOptions options)
- {
- options.AllowSynchronousIO = false;
- options.Limits.MinRequestBodyDataRate = null;
- options.Limits.MinResponseDataRate = null;
- options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);
- options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(2);
- }
+ => OpenAIProxy.Configure(app, env);
- private void SetupServices(IServiceProvider serviceProvider)
- {
- openAIClient ??= serviceProvider.GetRequiredService();
- authenticationFilter ??= serviceProvider.GetRequiredService();
- }
+ public static IHost CreateDefaultHost(string[] args, OpenAIClient openAIClient)
+ where T : class, IAuthenticationFilter => OpenAIProxy.CreateDefaultHost(args, openAIClient);
- private static async Task HealthEndpoint(HttpContext context)
- {
- // Respond with a 200 OK status code and a plain text message
- context.Response.StatusCode = StatusCodes.Status200OK;
- const string contentType = "text/plain";
- context.Response.ContentType = contentType;
- const string content = "OK";
- await context.Response.WriteAsync(content);
- }
+ public static WebApplication CreateWebApplication(string[] args, OpenAIClient openAIClient)
+ where T : class, IAuthenticationFilter => OpenAIProxy.CreateWebApplication(args, openAIClient);
}
}
diff --git a/OpenAI-DotNet-Proxy/Readme.md b/OpenAI-DotNet-Proxy/Readme.md
index fa20c4ff..40c45c1c 100644
--- a/OpenAI-DotNet-Proxy/Readme.md
+++ b/OpenAI-DotNet-Proxy/Readme.md
@@ -44,14 +44,14 @@ This setup allows your front end application to securely communicate with your b
### 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.
+In this example, we demonstrate how to set up and use `OpenAIProxy` 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](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-6.0) project.
2. Add the OpenAI-DotNet nuget package to your project.
- Powershell install: `Install-Package OpenAI-DotNet-Proxy`
- Manually editing .csproj: ``
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.CreateWebApplication` method, passing your custom `AuthenticationFilter` as a type argument.
+4. In `Program.cs`, create a new proxy web application by calling `OpenAIProxy.CreateWebApplication` 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.
```csharp
@@ -87,7 +87,7 @@ public partial class Program
var auth = OpenAIAuthentication.LoadFromEnv();
var settings = new OpenAIClientSettings(/* your custom settings if using Azure OpenAI */);
using var openAIClient = new OpenAIClient(auth, settings);
- OpenAIProxyStartup.CreateWebApplication(args, openAIClient).Run();
+ OpenAIProxy.CreateWebApplication(args, openAIClient).Run();
}
}
```
diff --git a/OpenAI-DotNet-Tests-Proxy/Program.cs b/OpenAI-DotNet-Tests-Proxy/Program.cs
index b85c6587..ed20e322 100644
--- a/OpenAI-DotNet-Tests-Proxy/Program.cs
+++ b/OpenAI-DotNet-Tests-Proxy/Program.cs
@@ -45,7 +45,7 @@ public static void Main(string[] args)
var auth = OpenAIAuthentication.LoadFromEnv();
var settings = new OpenAIClientSettings(/* your custom settings if using Azure OpenAI */);
using var openAIClient = new OpenAIClient(auth, settings);
- OpenAIProxyStartup.CreateWebApplication(args, openAIClient).Run();
+ OpenAIProxy.CreateWebApplication(args, openAIClient).Run();
}
}
}
diff --git a/OpenAI-DotNet-Tests/OpenAI-DotNet-Tests.csproj b/OpenAI-DotNet-Tests/OpenAI-DotNet-Tests.csproj
index 0ae86c67..0343d83b 100644
--- a/OpenAI-DotNet-Tests/OpenAI-DotNet-Tests.csproj
+++ b/OpenAI-DotNet-Tests/OpenAI-DotNet-Tests.csproj
@@ -4,7 +4,7 @@
false
false
latest
- True
+ true
diff --git a/OpenAI-DotNet-Tests/TestFixture_00_01_Authentication.cs b/OpenAI-DotNet-Tests/TestFixture_00_01_Authentication.cs
index 345c101a..7a889744 100644
--- a/OpenAI-DotNet-Tests/TestFixture_00_01_Authentication.cs
+++ b/OpenAI-DotNet-Tests/TestFixture_00_01_Authentication.cs
@@ -71,7 +71,7 @@ public void Test_05_Authentication()
{
var defaultAuth = OpenAIAuthentication.Default;
var manualAuth = new OpenAIAuthentication("sk-testAA", "org-testAA", "proj_testProject");
- var api = new OpenAIClient();
+ using var api = new OpenAIClient();
var shouldBeDefaultAuth = api.OpenAIAuthentication;
Assert.IsNotNull(shouldBeDefaultAuth);
Assert.IsNotNull(shouldBeDefaultAuth.ApiKey);
@@ -81,8 +81,8 @@ public void Test_05_Authentication()
Assert.AreEqual(defaultAuth.ProjectId, shouldBeDefaultAuth.ProjectId);
OpenAIAuthentication.Default = new OpenAIAuthentication("sk-testAA", "org-testAA", "proj_testProject");
- api = new OpenAIClient();
- var shouldBeManualAuth = api.OpenAIAuthentication;
+ using var api2 = new OpenAIClient();
+ var shouldBeManualAuth = api2.OpenAIAuthentication;
Assert.IsNotNull(shouldBeManualAuth);
Assert.IsNotNull(shouldBeManualAuth.ApiKey);
Assert.IsNotNull(shouldBeManualAuth.OrganizationId);
diff --git a/OpenAI-DotNet-Tests/TestFixture_11_VectorStores.cs b/OpenAI-DotNet-Tests/TestFixture_11_VectorStores.cs
index 874a6a7a..5e88259d 100644
--- a/OpenAI-DotNet-Tests/TestFixture_11_VectorStores.cs
+++ b/OpenAI-DotNet-Tests/TestFixture_11_VectorStores.cs
@@ -1,6 +1,5 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.
-using NuGet.Frameworks;
using NUnit.Framework;
using OpenAI.Files;
using OpenAI.VectorStores;
diff --git a/OpenAI-DotNet/OpenAI-DotNet.csproj b/OpenAI-DotNet/OpenAI-DotNet.csproj
index 3d43b967..cab9dfda 100644
--- a/OpenAI-DotNet/OpenAI-DotNet.csproj
+++ b/OpenAI-DotNet/OpenAI-DotNet.csproj
@@ -2,12 +2,12 @@
net6.0
latest
- OpenAI-DotNet
OpenAI-DotNet
+ OpenAI-DotNet
OpenAI-DotNet
+ OpenAI
RageAgainstThePixel
Stephen Hodgson, Roger Pincombe
- 2024
A simple C# .NET client library for OpenAI to use though their RESTful API.
Independently developed, this is not an official library and I am not affiliated with OpenAI.
An OpenAI API account is required.
@@ -15,6 +15,7 @@ An OpenAI API account is required.
Forked from [OpenAI-API-dotnet](https://github.com/OkGoDoIt/OpenAI-API-dotnet).
More context [on Roger Pincombe's blog](https://rogerpincombe.com/openai-dotnet-api).
+ 2024
true
https://github.com/RageAgainstThePixel/OpenAI-DotNet
https://github.com/RageAgainstThePixel/OpenAI-DotNet
@@ -26,10 +27,12 @@ More context [on Roger Pincombe's blog](https://rogerpincombe.com/openai-dotnet-
true
false
OpenAI-DotNet.pfx
- True
- True
- 8.1.0
+ true
+ true
+ 8.1.1
+Version 8.1.1
+- Added overloads to Assistant streaming event callbacks to include event name: Func<String, IServerSentEvent, Task>
Version 8.1.0
- Fixed streaming event race conditions where the subscriber to the stream would finish before steam events were executed
- Refactored streaming events callbacks from Action<IServerSentEvent> to Func<IServerSentEvent, Task>
@@ -362,19 +365,19 @@ Version 4.4.0
- True
+ true
\
- True
+ true
\
- True
+ true
\
diff --git a/OpenAI-DotNet/OpenAIClient.cs b/OpenAI-DotNet/OpenAIClient.cs
index a875c0dd..467debae 100644
--- a/OpenAI-DotNet/OpenAIClient.cs
+++ b/OpenAI-DotNet/OpenAIClient.cs
@@ -114,7 +114,7 @@ private void Dispose(bool disposing)
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { new JsonStringEnumConverterFactory() },
- ReferenceHandler = ReferenceHandler.IgnoreCycles,
+ ReferenceHandler = ReferenceHandler.IgnoreCycles
};
///
diff --git a/OpenAI-DotNet/Threads/ThreadsEndpoint.cs b/OpenAI-DotNet/Threads/ThreadsEndpoint.cs
index c6223fc9..479e50f2 100644
--- a/OpenAI-DotNet/Threads/ThreadsEndpoint.cs
+++ b/OpenAI-DotNet/Threads/ThreadsEndpoint.cs
@@ -208,6 +208,20 @@ public async Task CreateRunAsync(string threadId, CreateRunRequest
/// Optional, .
/// .
public async Task CreateRunAsync(string threadId, CreateRunRequest request = null, Func streamEventHandler = null, CancellationToken cancellationToken = default)
+ => await CreateRunAsync(threadId, request, streamEventHandler == null ? null : async (_, serverSentEvent) =>
+ {
+ await streamEventHandler.Invoke(serverSentEvent);
+ }, cancellationToken);
+
+ ///
+ /// Create a run.
+ ///
+ /// The id of the thread to run.
+ /// .
+ /// Optional, stream callback handler.
+ /// Optional, .
+ /// .
+ public async Task CreateRunAsync(string threadId, CreateRunRequest request = null, Func streamEventHandler = null, CancellationToken cancellationToken = default)
{
if (request == null || string.IsNullOrWhiteSpace(request.AssistantId))
{
@@ -245,6 +259,19 @@ public async Task CreateThreadAndRunAsync(CreateThreadAndRunRequest
/// Optional, .
/// .
public async Task CreateThreadAndRunAsync(CreateThreadAndRunRequest request = null, Func streamEventHandler = null, CancellationToken cancellationToken = default)
+ => await CreateThreadAndRunAsync(request, streamEventHandler == null ? null : async (_, serverSentEvent) =>
+ {
+ await streamEventHandler.Invoke(serverSentEvent);
+ }, cancellationToken);
+
+ ///
+ /// Create a thread and run it in one request.
+ ///
+ /// .
+ /// Optional, stream callback handler.
+ /// Optional, .
+ /// .
+ public async Task CreateThreadAndRunAsync(CreateThreadAndRunRequest request = null, Func streamEventHandler = null, CancellationToken cancellationToken = default)
{
if (request == null || string.IsNullOrWhiteSpace(request.AssistantId))
{
@@ -321,6 +348,23 @@ public async Task SubmitToolOutputsAsync(string threadId, string ru
/// Optional, .
/// .
public async Task SubmitToolOutputsAsync(string threadId, string runId, SubmitToolOutputsRequest request, Func streamEventHandler = null, CancellationToken cancellationToken = default)
+ => await SubmitToolOutputsAsync(threadId, runId, request, streamEventHandler == null ? null : async (_, serverSentEvent) =>
+ {
+ await streamEventHandler.Invoke(serverSentEvent);
+ }, cancellationToken);
+
+ ///
+ /// When a run has the status: "requires_action" and required_action.type is submit_tool_outputs,
+ /// this endpoint can be used to submit the outputs from the tool calls once they're all completed.
+ /// All outputs must be submitted in a single request.
+ ///
+ /// The id of the thread to which this run belongs.
+ /// The id of the run that requires the tool output submission.
+ /// .
+ /// Optional, stream callback handler.
+ /// Optional, .
+ /// .
+ public async Task SubmitToolOutputsAsync(string threadId, string runId, SubmitToolOutputsRequest request, Func streamEventHandler = null, CancellationToken cancellationToken = default)
{
request.Stream = streamEventHandler != null;
using var payload = JsonSerializer.Serialize(request, OpenAIClient.JsonSerializationOptions).ToJsonStringContent();
@@ -432,7 +476,7 @@ public async Task RetrieveFileAsync(string threadId, string
#endregion Files (Obsolete)
- private async Task StreamRunAsync(string endpoint, StringContent payload, Func streamEventHandler, CancellationToken cancellationToken = default)
+ private async Task StreamRunAsync(string endpoint, StringContent payload, Func streamEventHandler, CancellationToken cancellationToken = default)
{
RunResponse run = null;
RunStepResponse runStep = null;
@@ -440,13 +484,16 @@ private async Task StreamRunAsync(string endpoint, StringContent pa
using var response = await this.StreamEventsAsync(endpoint, payload, async (sseResponse, ssEvent) =>
{
+ IServerSentEvent serverSentEvent = default;
+ var @event = ssEvent.Value.GetValue();
+
try
{
- switch (ssEvent.Value.GetValue())
+ switch (@event)
{
case "thread.created":
- await streamEventHandler.Invoke(sseResponse.Deserialize(ssEvent, client));
- return;
+ serverSentEvent = sseResponse.Deserialize(ssEvent, client);
+ break;
case "thread.run.created":
case "thread.run.queued":
case "thread.run.in_progress":
@@ -468,8 +515,8 @@ private async Task StreamRunAsync(string endpoint, StringContent pa
run.AppendFrom(partialRun);
}
- await streamEventHandler.Invoke(run);
- return;
+ serverSentEvent = run;
+ break;
case "thread.run.step.created":
case "thread.run.step.in_progress":
case "thread.run.step.delta":
@@ -489,8 +536,8 @@ private async Task StreamRunAsync(string endpoint, StringContent pa
runStep.AppendFrom(partialRunStep);
}
- await streamEventHandler.Invoke(runStep);
- return;
+ serverSentEvent = runStep;
+ break;
case "thread.message.created":
case "thread.message.in_progress":
case "thread.message.delta":
@@ -508,20 +555,25 @@ private async Task StreamRunAsync(string endpoint, StringContent pa
message.AppendFrom(partialMessage);
}
- await streamEventHandler.Invoke(message);
- return;
+ serverSentEvent = message;
+ break;
case "error":
- await streamEventHandler.Invoke(sseResponse.Deserialize(ssEvent, client));
- return;
+ serverSentEvent = sseResponse.Deserialize(ssEvent, client);
+ break;
default:
// if not properly handled raise it up to caller to deal with it themselves.
- await streamEventHandler.Invoke(ssEvent);
- return;
+ serverSentEvent = ssEvent;
+ break;
}
}
catch (Exception e)
{
- await streamEventHandler.Invoke(new Error(e));
+ @event = "error";
+ serverSentEvent = new Error(e);
+ }
+ finally
+ {
+ await streamEventHandler.Invoke(@event, serverSentEvent);
}
}, cancellationToken);
diff --git a/README.md b/README.md
index afcff31a..71d94491 100644
--- a/README.md
+++ b/README.md
@@ -103,7 +103,6 @@ Install-Package OpenAI-DotNet
- [Json Mode](#chat-json-mode)
- [Audio](#audio)
- [Create Speech](#create-speech)
- - [Stream Speech](#stream-speech)
- [Create Transcription](#create-transcription)
- [Create Translation](#create-translation)
- [Images](#images) :warning: :construction:
@@ -143,8 +142,6 @@ There are 3 ways to provide your API keys, in order of precedence:
2. [Load key from configuration file](#load-key-from-configuration-file)
3. [Use System Environment Variables](#use-system-environment-variables)
-You use the `OpenAIAuthentication` when you initialize the API as shown:
-
#### Pass keys directly with constructor
> [!WARNING]
@@ -303,14 +300,14 @@ This setup allows your front end application to securely communicate with your b
#### 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.
+In this example, we demonstrate how to set up and use `OpenAIProxy` 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](https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-6.0) project.
2. Add the OpenAI-DotNet nuget package to your project.
- Powershell install: `Install-Package OpenAI-DotNet-Proxy`
- Manually editing .csproj: ``
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.CreateWebApplication` method, passing your custom `AuthenticationFilter` as a type argument.
+4. In `Program.cs`, create a new proxy web application by calling `OpenAIProxy.CreateWebApplication` 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.
```csharp
@@ -346,7 +343,7 @@ public partial class Program
var auth = OpenAIAuthentication.LoadFromEnv();
var settings = new OpenAIClientSettings(/* your custom settings if using Azure OpenAI */);
using var openAIClient = new OpenAIClient(auth, settings);
- OpenAIProxyStartup.CreateWebApplication(args, openAIClient).Run();
+ OpenAIProxy.CreateWebApplication(args, openAIClient).Run();
}
}
```