diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 847e689..715d717 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -20,7 +20,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
@@ -28,4 +28,7 @@ jobs:
- name: Test
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
+ AZURE_OPENAI_ENDPOINT_URL: ${{ secrets.AZURE_OPENAI_ENDPOINT_URL }}
+ AZURE_OPENAI_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_DEPLOYMENT_NAME }}
run: dotnet test --no-build --verbosity normal
diff --git a/.github/workflows/publish_to_nuget.yml b/.github/workflows/publish_to_nuget.yml
index 5206589..ac86405 100644
--- a/.github/workflows/publish_to_nuget.yml
+++ b/.github/workflows/publish_to_nuget.yml
@@ -2,7 +2,7 @@ name: Publish NuGet Package
on:
release:
- types: [ ]
+ types: [ created ]
push:
branches: [ release ]
@@ -17,7 +17,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..dad2db5
--- /dev/null
+++ b/global.json
@@ -0,0 +1,7 @@
+{
+ "sdk": {
+ "version": "8.0.0",
+ "rollForward": "latestMajor",
+ "allowPrerelease": true
+ }
+}
\ No newline at end of file
diff --git a/samples/ChatGpt.BlazorExample/ChatGpt.BlazorExample.csproj b/samples/ChatGpt.BlazorExample/ChatGpt.BlazorExample.csproj
index 4be33d7..41b5579 100644
--- a/samples/ChatGpt.BlazorExample/ChatGpt.BlazorExample.csproj
+++ b/samples/ChatGpt.BlazorExample/ChatGpt.BlazorExample.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
enable
enable
e883db38-8c66-433b-a1cf-301b5b3b2171
@@ -9,7 +9,7 @@
-
+
diff --git a/samples/ChatGpt.BlazorExample/Program.cs b/samples/ChatGpt.BlazorExample/Program.cs
index bac98a6..12ce7af 100644
--- a/samples/ChatGpt.BlazorExample/Program.cs
+++ b/samples/ChatGpt.BlazorExample/Program.cs
@@ -10,8 +10,7 @@
// make sure that you have added the OpenAICredentials:ApiKey to your secrets.json
// or environment variables
builder.Services.AddChatGptEntityFrameworkIntegration(
- options => options.UseSqlite("Data Source=chats.db"))
- .AddServerSideBlazor();
+ options => options.UseSqlite("Data Source=chats.db"));
var app = builder.Build();
diff --git a/samples/ChatGpt.ConsoleExample/ChatGpt.ConsoleExample.csproj b/samples/ChatGpt.ConsoleExample/ChatGpt.ConsoleExample.csproj
index 8296b06..e360dbf 100644
--- a/samples/ChatGpt.ConsoleExample/ChatGpt.ConsoleExample.csproj
+++ b/samples/ChatGpt.ConsoleExample/ChatGpt.ConsoleExample.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net8.0
enable
enable
diff --git a/samples/ChatGpt.SpectreConsoleExample/ChatGpt.SpectreConsoleExample.csproj b/samples/ChatGpt.SpectreConsoleExample/ChatGpt.SpectreConsoleExample.csproj
index 3db0558..b440ce0 100644
--- a/samples/ChatGpt.SpectreConsoleExample/ChatGpt.SpectreConsoleExample.csproj
+++ b/samples/ChatGpt.SpectreConsoleExample/ChatGpt.SpectreConsoleExample.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net8.0
enable
enable
diff --git a/samples/ChatGpt.TelegramBotExample/ChatGpt.TelegramBotExample.csproj b/samples/ChatGpt.TelegramBotExample/ChatGpt.TelegramBotExample.csproj
index d32a0d2..7c0cc3f 100644
--- a/samples/ChatGpt.TelegramBotExample/ChatGpt.TelegramBotExample.csproj
+++ b/samples/ChatGpt.TelegramBotExample/ChatGpt.TelegramBotExample.csproj
@@ -2,14 +2,14 @@
Exe
- net7.0
+ net8.0
enable
enable
-
+
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index bd2ad62..975e26e 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,6 +1,7 @@
- 3.1.1
+ 3.2.0
+ net6.0;net7.0;net8.0
enable
enable
12
diff --git a/src/OpenAI.ChatGpt.AspNetCore/OpenAI.ChatGpt.AspNetCore.csproj b/src/OpenAI.ChatGpt.AspNetCore/OpenAI.ChatGpt.AspNetCore.csproj
index 17057b0..8449459 100644
--- a/src/OpenAI.ChatGpt.AspNetCore/OpenAI.ChatGpt.AspNetCore.csproj
+++ b/src/OpenAI.ChatGpt.AspNetCore/OpenAI.ChatGpt.AspNetCore.csproj
@@ -2,7 +2,6 @@
enable
enable
- 11
Rodion Mostovoi
true
OpenAI.ChatGPT.AspNetCore
@@ -10,7 +9,6 @@
OpenAI ChatGPT integration for .NET with DI
OpenAI Chat Completions API (ChatGPT) integration with easy DI supporting (Microsoft.Extensions.DependencyInjection). It allows you to use the API in your .NET applications. Also, the client supports streaming responses (like ChatGPT) via async streams.
https://github.com/rodion-m/ChatGPT_API_dotnet
- net6.0;net7.0
chatgpt, openai, sdk, api, chatcompletions, gpt3, gpt4, aspnetcore
MIT
ChatGPT easy DI for ASP.NET Core
@@ -36,11 +34,11 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
+
+
+
+
+
diff --git a/src/OpenAI.ChatGpt.EntityFrameworkCore/OpenAI.ChatGpt.EntityFrameworkCore.csproj b/src/OpenAI.ChatGpt.EntityFrameworkCore/OpenAI.ChatGpt.EntityFrameworkCore.csproj
index 284a7b3..3d713e9 100644
--- a/src/OpenAI.ChatGpt.EntityFrameworkCore/OpenAI.ChatGpt.EntityFrameworkCore.csproj
+++ b/src/OpenAI.ChatGpt.EntityFrameworkCore/OpenAI.ChatGpt.EntityFrameworkCore.csproj
@@ -3,7 +3,6 @@
enable
enable
- 11
Rodion Mostovoi
true
OpenAI.ChatGPT.EntityFrameworkCore
@@ -11,7 +10,6 @@
OpenAI ChatGPT integration for .NET with EF Core storage
OpenAI Chat Completions API (ChatGPT) integration with DI and EF Core supporting. It allows you to use the API in your .NET applications. Also, the client supports streaming responses (like ChatGPT) via async streams.
https://github.com/rodion-m/ChatGPT_API_dotnet
- net6.0;net7.0
chatgpt, openai, sdk, api, chatcompletions, gpt3, gpt4, di, entityframework, ef
MIT
ChatGPT easy DI with EF Core storage
@@ -31,8 +29,8 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/OpenAI.ChatGpt/AzureOpenAiClient.cs b/src/OpenAI.ChatGpt/AzureOpenAiClient.cs
new file mode 100644
index 0000000..6a8e3c1
--- /dev/null
+++ b/src/OpenAI.ChatGpt/AzureOpenAiClient.cs
@@ -0,0 +1,57 @@
+namespace OpenAI.ChatGpt;
+
+///
+/// Azure OpenAI services client
+///
+///
+/// Docs: https://learn.microsoft.com/en-us/azure/ai-services/openai/reference
+/// Models availability by zones: https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models
+///
+public class AzureOpenAiClient : OpenAiClient
+{
+ private readonly string _apiVersion;
+ private const string DefaultApiVersion = "2023-12-01-preview";
+
+ //https://github.com/Azure/azure-rest-api-specs/tree/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference
+
+ ///
+ /// Creates Azure OpenAI services client
+ ///
+ /// Endpoint URL like https://{your-resource-name}.openai.azure.com/
+ /// Deployment name from the page https://oai.azure.com/deployment
+ /// Azure OpenAI API Key
+ /// Azure OpenAI API version
+ ///
+ /// See currently available API versions: https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#completions
+ ///
+ public AzureOpenAiClient(
+ string endpointUrl,
+ string deploymentName,
+ string azureKey,
+ string apiVersion = DefaultApiVersion)
+ {
+ if (string.IsNullOrWhiteSpace(azureKey))
+ throw new ArgumentException("Value cannot be null or whitespace.", nameof(azureKey));
+
+ _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion));
+ HttpClient = new HttpClient()
+ {
+ BaseAddress = new Uri($"{endpointUrl}/openai/deployments/{deploymentName}/"),
+ DefaultRequestHeaders =
+ {
+ { "api-key", azureKey }
+ }
+ };
+ IsHttpClientInjected = false;
+ }
+
+ public AzureOpenAiClient(HttpClient httpClient, string apiVersion) : base(httpClient)
+ {
+ _apiVersion = apiVersion ?? throw new ArgumentNullException(nameof(apiVersion));
+ }
+
+ protected override string GetChatCompletionsEndpoint()
+ {
+ return $"chat/completions?api-version={_apiVersion}";
+ }
+}
\ No newline at end of file
diff --git a/src/OpenAI.ChatGpt/Models/ChatCompletion/ChatCompletionRequest.cs b/src/OpenAI.ChatGpt/Models/ChatCompletion/ChatCompletionRequest.cs
index 9834361..d73bd67 100644
--- a/src/OpenAI.ChatGpt/Models/ChatCompletion/ChatCompletionRequest.cs
+++ b/src/OpenAI.ChatGpt/Models/ChatCompletion/ChatCompletionRequest.cs
@@ -144,8 +144,8 @@ public int MaxTokens
///
/// An object specifying the format that the model must output.
///
- [JsonPropertyName("response_format")]
- public ChatCompletionResponseFormat ResponseFormat { get; set; } = new(false);
+ [JsonPropertyName("response_format"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
+ public ChatCompletionResponseFormat? ResponseFormat { get; set; }
///
/// This feature is in Beta.
diff --git a/src/OpenAI.ChatGpt/OpenAI.ChatGpt.csproj b/src/OpenAI.ChatGpt/OpenAI.ChatGpt.csproj
index 9ec483e..89cd06f 100644
--- a/src/OpenAI.ChatGpt/OpenAI.ChatGpt.csproj
+++ b/src/OpenAI.ChatGpt/OpenAI.ChatGpt.csproj
@@ -3,7 +3,6 @@
enable
enable
- 11
Rodion Mostovoi
OpenAI ChatGPT integration for .NET
true
@@ -13,7 +12,6 @@
.NET integration for ChatGPT with streaming responses supporting (like ChatGPT) via async streams.
https://github.com/rodion-m/ChatGPT_API_dotnet
MIT
- net6.0;net7.0
OpenAI.ChatGpt
Rodion Mostovoi
chatgpt, openai, sdk, api, chatcompletions, gpt3, gpt4
diff --git a/src/OpenAI.ChatGpt/OpenAiClient.cs b/src/OpenAI.ChatGpt/OpenAiClient.cs
index 1ae2ac5..b430fbe 100644
--- a/src/OpenAI.ChatGpt/OpenAiClient.cs
+++ b/src/OpenAI.ChatGpt/OpenAiClient.cs
@@ -19,8 +19,8 @@ public class OpenAiClient : IOpenAiClient, IDisposable
private static readonly Uri DefaultHostUri = new(DefaultHost);
- private readonly HttpClient _httpClient;
- private readonly bool _isHttpClientInjected;
+ protected HttpClient HttpClient;
+ protected bool IsHttpClientInjected;
private bool _disposed;
private readonly JsonSerializerOptions _nullIgnoreSerializerOptions = new()
@@ -28,6 +28,12 @@ public class OpenAiClient : IOpenAiClient, IDisposable
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
+#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+ protected OpenAiClient()
+#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+ {
+ }
+
///
/// Creates a new OpenAI client with given .
///
@@ -39,19 +45,19 @@ public OpenAiClient(string apiKey, string? host = DefaultHost)
throw new ArgumentException("API key cannot be null or whitespace.", nameof(apiKey));
var uri = ValidateHost(host);
- _httpClient = new HttpClient()
+ HttpClient = new HttpClient()
{
BaseAddress = uri
};
var header = new AuthenticationHeaderValue("Bearer", apiKey);
- _httpClient.DefaultRequestHeaders.Authorization = header;
+ HttpClient.DefaultRequestHeaders.Authorization = header;
}
///
/// Creates a new OpenAI client from DI with given .
///
///
- /// from DI. It should have an Authorization header set with OpenAI API key.
+ /// from DI. It should have an Authorization header set with OpenAI API key.
///
///
/// Indicates that OpenAI API key is not set in
@@ -59,18 +65,18 @@ public OpenAiClient(string apiKey, string? host = DefaultHost)
///
public OpenAiClient(HttpClient httpClient)
{
- _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+ HttpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
ValidateHttpClient(httpClient);
- _isHttpClientInjected = true;
+ IsHttpClientInjected = true;
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
- if (!_isHttpClientInjected)
+ if (!IsHttpClientInjected)
{
- _httpClient.Dispose();
+ HttpClient.Dispose();
}
GC.SuppressFinalize(this);
}
@@ -89,8 +95,9 @@ private static Uri ValidateHost(string? host)
if (host is null) return DefaultHostUri;
if (!Uri.TryCreate(host, UriKind.Absolute, out var uri))
{
- throw new ArgumentException("Host must be a valid absolute URI and end with a slash." +
- $"For example: {DefaultHost}", nameof(host));
+ throw new ArgumentException(
+ $"Host must be a valid absolute URI and end with a slash. Provided: {host}" +
+ $"\nCorrect example: {DefaultHost}", nameof(host));
}
if(!host.EndsWith("/")) uri = new Uri(host + "/");
@@ -230,8 +237,8 @@ internal async Task GetChatCompletionsRaw(
{
ArgumentNullException.ThrowIfNull(request);
ThrowIfDisposed();
- var response = await _httpClient.PostAsJsonAsync(
- ChatCompletionsEndpoint,
+ var response = await HttpClient.PostAsJsonAsync(
+ GetChatCompletionsEndpoint(),
request,
cancellationToken: cancellationToken,
options: _nullIgnoreSerializerOptions
@@ -247,6 +254,11 @@ internal async Task GetChatCompletionsRaw(
return jsonResponse;
}
+ protected virtual string GetChatCompletionsEndpoint()
+ {
+ return ChatCompletionsEndpoint;
+ }
+
///
public IAsyncEnumerable StreamChatCompletions(
IEnumerable messages,
@@ -296,7 +308,7 @@ private static ChatCompletionRequest CreateChatCompletionRequest(
Stream = stream,
User = user,
Temperature = temperature,
- ResponseFormat = new ChatCompletionRequest.ChatCompletionResponseFormat(jsonMode),
+ ResponseFormat = jsonMode ? new ChatCompletionRequest.ChatCompletionResponseFormat(jsonMode) : null,
Seed = seed,
};
requestModifier?.Invoke(request);
@@ -339,7 +351,7 @@ public async IAsyncEnumerable StreamChatCompletions(
{
ArgumentNullException.ThrowIfNull(request);
if (request == null) throw new ArgumentNullException(nameof(request));
- EnsureJsonModeIsSupported(request.Model, request.ResponseFormat.Type == ChatCompletionRequest.ResponseTypes.JsonObject);
+ EnsureJsonModeIsSupported(request.Model, request.ResponseFormat?.Type == ChatCompletionRequest.ResponseTypes.JsonObject);
ThrowIfDisposed();
request.Stream = true;
await foreach (var response in StreamChatCompletionsRaw(request, cancellationToken))
@@ -355,10 +367,10 @@ public IAsyncEnumerable StreamChatCompletionsRaw(
ChatCompletionRequest request, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(request);
- EnsureJsonModeIsSupported(request.Model, request.ResponseFormat.Type == ChatCompletionRequest.ResponseTypes.JsonObject);
+ EnsureJsonModeIsSupported(request.Model, request.ResponseFormat?.Type == ChatCompletionRequest.ResponseTypes.JsonObject);
ThrowIfDisposed();
request.Stream = true;
- return _httpClient.StreamUsingServerSentEvents
+ return HttpClient.StreamUsingServerSentEvents
(
ChatCompletionsEndpoint,
request,
diff --git a/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAI.ChatGpt.Modules.StructuredResponse.csproj b/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAI.ChatGpt.Modules.StructuredResponse.csproj
index a094b97..d0d5098 100644
--- a/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAI.ChatGpt.Modules.StructuredResponse.csproj
+++ b/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAI.ChatGpt.Modules.StructuredResponse.csproj
@@ -2,7 +2,6 @@
enable
enable
- 11
Rodion Mostovoi
true
OpenAI.ChatGPT.Modules.StructuredResponse
@@ -10,7 +9,6 @@
OpenAI ChatGPT structured response module
The module for OpenAI ChatGPT that allows to retrive a structured response from ChatGPT.
https://github.com/rodion-m/ChatGPT_API_dotnet
- net6.0;net7.0
chatgpt, openai, sdk, api, chatcompletions, gpt3, gpt4, json, structured
MIT
OpenAI ChatGPT structured response
@@ -31,7 +29,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAiClientExtensions.GetStructuredResponse.cs b/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAiClientExtensions.GetStructuredResponse.cs
index 73c623c..eeeb954 100644
--- a/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAiClientExtensions.GetStructuredResponse.cs
+++ b/src/modules/OpenAI.ChatGpt.Modules.StructuredResponse/OpenAiClientExtensions.GetStructuredResponse.cs
@@ -15,7 +15,7 @@ public static class OpenAiClientExtensions
{
Nullability = Nullability.Disabled,
PropertyOrder = PropertyOrder.AsDeclared,
- PropertyNamingMethod = PropertyNamingMethods.AsDeclared
+ PropertyNameResolver = PropertyNameResolvers.AsDeclared
};
private static readonly JsonSerializerOptions JsonSchemaSerializerOptions = new()
{
diff --git a/src/modules/OpenAI.ChatGpt.Modules.Translator/OpenAI.ChatGpt.Modules.Translator.csproj b/src/modules/OpenAI.ChatGpt.Modules.Translator/OpenAI.ChatGpt.Modules.Translator.csproj
index 782d198..69eb558 100644
--- a/src/modules/OpenAI.ChatGpt.Modules.Translator/OpenAI.ChatGpt.Modules.Translator.csproj
+++ b/src/modules/OpenAI.ChatGpt.Modules.Translator/OpenAI.ChatGpt.Modules.Translator.csproj
@@ -3,7 +3,6 @@
enable
enable
- 11
Rodion Mostovoi
true
OpenAI.ChatGPT.Modules.Translator
@@ -11,7 +10,6 @@
OpenAI ChatGPT based language translator
OpenAI ChatGPT based language translator.
https://github.com/rodion-m/ChatGPT_API_dotnet
- net6.0;net7.0
chatgpt, openai, sdk, api, chatcompletions, gpt3, gpt4, translator
MIT
OpenAI ChatGPT based language translator
diff --git a/tests/OpenAI.ChatGpt.IntegrationTests/ChatGptTests.cs b/tests/OpenAI.ChatGpt.IntegrationTests/ChatGptTests.cs
index cb897ec..2333cf0 100644
--- a/tests/OpenAI.ChatGpt.IntegrationTests/ChatGptTests.cs
+++ b/tests/OpenAI.ChatGpt.IntegrationTests/ChatGptTests.cs
@@ -1,6 +1,4 @@
-using OpenAI.Tests.Shared;
-
-namespace OpenAI.ChatGpt.IntegrationTests;
+namespace OpenAI.ChatGpt.IntegrationTests;
public class ChatGptTests
{
diff --git a/tests/OpenAI.ChatGpt.IntegrationTests/OpenAI.ChatGpt.IntegrationTests.csproj b/tests/OpenAI.ChatGpt.IntegrationTests/OpenAI.ChatGpt.IntegrationTests.csproj
index c348426..9544647 100644
--- a/tests/OpenAI.ChatGpt.IntegrationTests/OpenAI.ChatGpt.IntegrationTests.csproj
+++ b/tests/OpenAI.ChatGpt.IntegrationTests/OpenAI.ChatGpt.IntegrationTests.csproj
@@ -1,23 +1,22 @@
- net7.0
+ net8.0
enable
enable
-
false
true
-
-
-
-
-
+
+
+
+
+
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/tests/OpenAI.ChatGpt.IntegrationTests/OpenAiClientTests/AzureOpenAiClientTests.cs b/tests/OpenAI.ChatGpt.IntegrationTests/OpenAiClientTests/AzureOpenAiClientTests.cs
new file mode 100644
index 0000000..52b686a
--- /dev/null
+++ b/tests/OpenAI.ChatGpt.IntegrationTests/OpenAiClientTests/AzureOpenAiClientTests.cs
@@ -0,0 +1,25 @@
+namespace OpenAI.ChatGpt.IntegrationTests.OpenAiClientTests;
+
+public class AzureOpenAiClientTests
+{
+ private readonly ITestOutputHelper _outputHelper;
+ private readonly IOpenAiClient _client;
+
+ public AzureOpenAiClientTests(ITestOutputHelper outputHelper)
+ {
+ _outputHelper = outputHelper;
+ var endpointUrl = Helpers.GetValueFromConfiguration("AZURE_OPENAI_ENDPOINT_URL");
+ var azureKey = Helpers.GetValueFromConfiguration("AZURE_OPENAI_API_KEY");
+ var deploymentName = Helpers.GetValueFromConfiguration("AZURE_OPENAI_DEPLOYMENT_NAME");
+ _client = new AzureOpenAiClient(endpointUrl, deploymentName, azureKey, "2023-12-01-preview");
+ }
+
+ [Fact]
+ public async void Get_chatgpt_response_for_one_message_works()
+ {
+ string text = "Who are you? In two words.";
+ string response = await _client.GetChatCompletions(new UserMessage(text), 64);
+ _outputHelper.WriteLine(response);
+ response.Should().NotBeNullOrEmpty();
+ }
+}
\ No newline at end of file
diff --git a/tests/OpenAI.ChatGpt.UnitTests/ChatGptTranslatorServiceTests.cs b/tests/OpenAI.ChatGpt.UnitTests/ChatGptTranslatorServiceTests.cs
index 8efda52..dfc723f 100644
--- a/tests/OpenAI.ChatGpt.UnitTests/ChatGptTranslatorServiceTests.cs
+++ b/tests/OpenAI.ChatGpt.UnitTests/ChatGptTranslatorServiceTests.cs
@@ -52,7 +52,7 @@ public async Task Translate_without_source_and_target_languages_uses_default_lan
(IOpenAiClient) clientMock.Object,
expectedSourceLanguage,
expectedTargetLanguage,
- null);
+ (string) null!);
translatorServiceMock.Setup(service => service.CreateTextTranslationPrompt(
It.IsAny(), It.IsAny()))
diff --git a/tests/OpenAI.ChatGpt.UnitTests/OpenAI.ChatGpt.UnitTests.csproj b/tests/OpenAI.ChatGpt.UnitTests/OpenAI.ChatGpt.UnitTests.csproj
index 415d312..e367160 100644
--- a/tests/OpenAI.ChatGpt.UnitTests/OpenAI.ChatGpt.UnitTests.csproj
+++ b/tests/OpenAI.ChatGpt.UnitTests/OpenAI.ChatGpt.UnitTests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
enable
enable
@@ -10,14 +10,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/tests/OpenAI.Tests.Shared/Helpers.cs b/tests/OpenAI.Tests.Shared/Helpers.cs
index 1c1d6b3..cd3aec4 100644
--- a/tests/OpenAI.Tests.Shared/Helpers.cs
+++ b/tests/OpenAI.Tests.Shared/Helpers.cs
@@ -1,23 +1,36 @@
-namespace OpenAI.Tests.Shared;
+using Microsoft.Extensions.Configuration;
-public static class Helpers
+namespace OpenAI.Tests.Shared
{
- public static string GetOpenAiKey() => GetKeyFromEnvironment("OPENAI_API_KEY");
-
- public static string? NullIfEmpty(this string? str)
+ public static class Helpers
{
- return string.IsNullOrEmpty(str) ? null : str;
- }
-
- public static string GetKeyFromEnvironment(string keyName)
- {
- if (keyName == null) throw new ArgumentNullException(nameof(keyName));
- var value = Environment.GetEnvironmentVariable(keyName);
- if (value is null)
+ private static IConfiguration Configuration { get; set; }
+
+ static Helpers()
+ {
+ Configuration = new ConfigurationBuilder()
+ .AddEnvironmentVariables()
+ .AddUserSecrets(typeof(Helpers).Assembly)
+ .Build();
+ }
+
+ public static string GetOpenAiKey() => GetValueFromConfiguration("OPENAI_API_KEY");
+
+ public static string? NullIfEmpty(this string? str)
{
- throw new InvalidOperationException($"{keyName} is not set as environment variable");
+ return string.IsNullOrEmpty(str) ? null : str;
}
- return value;
+ public static string GetValueFromConfiguration(string key)
+ {
+ ArgumentNullException.ThrowIfNull(key);
+ var value = Configuration[key];
+ if (value is null)
+ {
+ throw new InvalidOperationException($"{key} is not set in configuration");
+ }
+
+ return value;
+ }
}
}
\ No newline at end of file
diff --git a/tests/OpenAI.Tests.Shared/OpenAI.Tests.Shared.csproj b/tests/OpenAI.Tests.Shared/OpenAI.Tests.Shared.csproj
index e8c6a11..18979f4 100644
--- a/tests/OpenAI.Tests.Shared/OpenAI.Tests.Shared.csproj
+++ b/tests/OpenAI.Tests.Shared/OpenAI.Tests.Shared.csproj
@@ -1,11 +1,17 @@
- net7.0
+ net8.0
enable
enable
-
false
+ c1a19734-c162-40ca-8a60-a21b29a396cd
+
+
+
+
+
+