@foreach (var message in messages)
@@ -62,6 +81,12 @@
private string? message;
private bool isAsking;
+ private string azureResource;
+ private string apiKey;
+ private string model;
+
+ private IChatGptClient? chatGptClient = null;
+
private bool CanSendMessage()
=> !string.IsNullOrWhiteSpace(message) && !isAsking;
@@ -73,6 +98,17 @@
}
}
+ private void Connect()
+ {
+ chatGptClient = chatGptClientFactory.CreateClient(options =>
+ {
+ options.UseAzure(azureResource, apiKey, authenticationType: AzureAuthenticationType.ApiKey);
+ options.DefaultModel = model;
+ options.MessageLimit = 16; // Default: 10
+ options.MessageExpiration = TimeSpan.FromMinutes(5); // Default: 1 hour
+ });
+ }
+
private async Task AskAsync()
{
if (!isAsking)
diff --git a/samples/ChatGptBlazor.Wasm/Program.cs b/samples/ChatGptBlazor.Wasm/Program.cs
index 447738a..595caf9 100644
--- a/samples/ChatGptBlazor.Wasm/Program.cs
+++ b/samples/ChatGptBlazor.Wasm/Program.cs
@@ -1,5 +1,6 @@
using ChatGptBlazor.Wasm;
using ChatGptNet;
+using ChatGptNet.ServiceConfigurations;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
@@ -10,27 +11,6 @@
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// Adds ChatGPT service and configure options via code.
-builder.Services.AddChatGpt(options =>
-{
- // OpenAI.
- //options.UseOpenAI(apiKey: "", organization: "");
-
- // Azure OpenAI Service.
- //options.UseAzure(resourceName: "", apiKey: "", authenticationType: AzureAuthenticationType.ApiKey);
-
- options.DefaultModel = "my-model";
- options.MessageLimit = 16; // Default: 10
- options.MessageExpiration = TimeSpan.FromMinutes(5); // Default: 1 hour
-},
-httpClient =>
-{
- // Configures retry policy on the inner HttpClient using Polly.
- httpClient.AddStandardResilienceHandler(options =>
- {
- options.AttemptTimeout.Timeout = TimeSpan.FromMinutes(1);
- options.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(3);
- options.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(3);
- });
-});
+builder.Services.AddChatGptClientFactory();
await builder.Build().RunAsync();
diff --git a/samples/ChatGptBlazor.Wasm/Properties/launchSettings.json b/samples/ChatGptBlazor.Wasm/Properties/launchSettings.json
index f9af232..deec97b 100644
--- a/samples/ChatGptBlazor.Wasm/Properties/launchSettings.json
+++ b/samples/ChatGptBlazor.Wasm/Properties/launchSettings.json
@@ -1,40 +1,32 @@
{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:8206",
- "sslPort": 44385
- }
- },
"profiles": {
"http": {
"commandName": "Project",
- "dotnetRunMessages": true,
"launchBrowser": true,
- "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
- "applicationUrl": "http://localhost:5297",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
- }
+ },
+ "dotnetRunMessages": true,
+ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
+ "applicationUrl": "http://localhost:5297"
},
"https": {
"commandName": "Project",
- "dotnetRunMessages": true,
"launchBrowser": true,
- "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
- "applicationUrl": "https://localhost:7021;http://localhost:5297",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
+ },
+ "dotnetRunMessages": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
+ "applicationUrl": "https://localhost:7021;http://localhost:5297"
+ }
+ },
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:8206",
+ "sslPort": 44385
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ChatGptNet/ChatGptClientFactory.cs b/src/ChatGptNet/ChatGptClientFactory.cs
new file mode 100644
index 0000000..3d0736a
--- /dev/null
+++ b/src/ChatGptNet/ChatGptClientFactory.cs
@@ -0,0 +1,38 @@
+using Microsoft.Extensions.Caching.Memory;
+
+namespace ChatGptNet;
+
+internal class ChatGptClientFactory : IChatGptClientFactory
+{
+ private readonly IServiceProvider services;
+ private readonly IChatGptCache chatGptCache;
+ private readonly ChatGptOptionsBuilder defaultOptions;
+
+ public ChatGptClientFactory(IServiceProvider services, IChatGptCache chatGptCache, ChatGptOptionsBuilder defaultOptions)
+ {
+ this.services = services;
+ this.chatGptCache = chatGptCache;
+ this.defaultOptions = defaultOptions;
+ }
+
+ public IChatGptClient CreateClient(Action
? setupAction)
+ {
+ var options = defaultOptions with { };
+
+ if (setupAction is not null)
+ setupAction(services, options);
+
+ return new ChatGptClient(new HttpClient(), chatGptCache, options.Build());
+ }
+ public IChatGptClient CreateClient(Action? setupAction)
+ {
+ if (setupAction is null)
+ return CreateClient();
+
+ return CreateClient((s, o) => setupAction(o));
+ }
+ public IChatGptClient CreateClient()
+ {
+ return CreateClient((Action?)null);
+ }
+}
diff --git a/src/ChatGptNet/ChatGptFactoryServiceCollectionExtensions.cs b/src/ChatGptNet/ChatGptFactoryServiceCollectionExtensions.cs
new file mode 100644
index 0000000..4523299
--- /dev/null
+++ b/src/ChatGptNet/ChatGptFactoryServiceCollectionExtensions.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using ChatGptNet.Models;
+using ChatGptNet.ServiceConfigurations;
+using Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+
+namespace ChatGptNet;
+///
+/// Provides extension methods for adding ChatGPT Client Factory support in NET applications.
+///
+public static class ChatGptFactoryServiceCollectionExtensions
+{
+ ///
+ /// Registers a instance with the specified options.
+ ///
+ /// The to add services to.
+ /// The to configure the provided .
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddChatGptClientFactory(this IServiceCollection services, Action builder)
+ {
+ ArgumentNullException.ThrowIfNull(services);
+
+ var options = new ChatGptOptionsBuilder();
+ if (builder is not null)
+ builder.Invoke(options);
+
+ return AddChatGptClientFactoryCore(services, options);
+ }
+
+ ///
+ /// Registers a instance.
+ ///
+ /// The to add services to.
+ /// A reference to this instance after the operation has completed.
+ public static IServiceCollection AddChatGptClientFactory(this IServiceCollection services)
+ {
+ return services.AddChatGptClientFactory(null);
+ }
+
+ private static IServiceCollection AddChatGptClientFactoryCore(this IServiceCollection services, ChatGptOptionsBuilder deafultOptions)
+ {
+ services.AddMemoryCache();
+ services.AddSingleton();
+
+ var httpClientBuilder = services.AddHttpClient();
+ services.AddSingleton(
+ s => new ChatGptClientFactory(s, s.GetRequiredService(), deafultOptions)
+ );
+
+ return services;
+ }
+
+ private static void SetMissingDefaults(ChatGptOptions options)
+ {
+ // If the provider is OpenAI and no default model has been specified, uses gpt-3.5-turbo by default.
+ if (options.ServiceConfiguration is OpenAIChatGptServiceConfiguration && string.IsNullOrWhiteSpace(options.DefaultModel))
+ {
+ options.DefaultModel = OpenAIChatGptModels.Gpt35Turbo;
+ }
+ }
+}
+
+///
+/// Represents the default builder for configuring ChatGPT client factory.
+///
+/// "/>
+public class ChatGptClientFactoryBuilder : IChatGptClientFactoryBuilder
+{
+ ///
+ /// Gets the where ChatGPT services are registered.
+ ///
+ public IServiceCollection Services { get; }
+
+ ///
+ ///
+ /// Gets the used to configure the used by ChatGPT.
+ ///
+ public IHttpClientBuilder HttpClientBuilder { get; }
+
+ internal ChatGptClientFactoryBuilder(IServiceCollection services, IHttpClientBuilder httpClientBuilder)
+ {
+ Services = services;
+ HttpClientBuilder = httpClientBuilder;
+ }
+}
+
+///
+/// Represents a builder for configuring ChatGPT client factory.
+///
+public interface IChatGptClientFactoryBuilder
+{
+ ///
+ /// Gets the where ChatGPT services are registered.
+ ///
+ IServiceCollection Services { get; }
+
+ ///
+ /// Gets the used to configure the used by ChatGPT.
+ ///
+ IHttpClientBuilder HttpClientBuilder { get; }
+}
diff --git a/src/ChatGptNet/ChatGptOptions.cs b/src/ChatGptNet/ChatGptOptions.cs
index 7d291c5..77004d8 100644
--- a/src/ChatGptNet/ChatGptOptions.cs
+++ b/src/ChatGptNet/ChatGptOptions.cs
@@ -8,7 +8,7 @@ namespace ChatGptNet;
///
/// Options class that provides settings for configuring ChatGPT.
///
-public class ChatGptOptions
+public record ChatGptOptions
{
///
/// Gets or sets the configuration settings for accessing the service.
diff --git a/src/ChatGptNet/ChatGptOptionsBuilder.cs b/src/ChatGptNet/ChatGptOptionsBuilder.cs
index 721a801..5b13769 100644
--- a/src/ChatGptNet/ChatGptOptionsBuilder.cs
+++ b/src/ChatGptNet/ChatGptOptionsBuilder.cs
@@ -8,7 +8,7 @@ namespace ChatGptNet;
///
/// Builder class to define settings for configuring ChatGPT.
///
-public class ChatGptOptionsBuilder
+public record ChatGptOptionsBuilder
{
///
/// Gets or sets the configuration settings for accessing the service.
diff --git a/src/ChatGptNet/IChatGptClientFactory.cs b/src/ChatGptNet/IChatGptClientFactory.cs
new file mode 100644
index 0000000..ed5f31b
--- /dev/null
+++ b/src/ChatGptNet/IChatGptClientFactory.cs
@@ -0,0 +1,28 @@
+namespace ChatGptNet;
+
+///
+/// Provides methods to create new instances of at runtime
+///
+public interface IChatGptClientFactory
+{
+ ///
+ /// Creates a new instance of a ChatGptClient configured with the supplied action.
+ ///
+ /// The to configure the provided .
+ /// A new
+ IChatGptClient CreateClient(Action? setupAction);
+
+ ///
+ /// Creates a new instance of a ChatGptClient configured with the supplied action.
+ ///
+ /// The to configure the provided .
+ /// A new
+ IChatGptClient CreateClient(Action? setupAction);
+
+ ///
+ /// Creates a new instance of a ChatGptClient.
+ ///
+ /// A new
+ IChatGptClient CreateClient();
+
+}