diff --git a/app/MindWork AI Studio/Provider/IProvider.cs b/app/MindWork AI Studio/Provider/IProvider.cs
index 153ebba..776d981 100644
--- a/app/MindWork AI Studio/Provider/IProvider.cs
+++ b/app/MindWork AI Studio/Provider/IProvider.cs
@@ -48,16 +48,18 @@ public interface IProvider
///
/// The JS runtime to access the Rust code.
/// The settings manager to access the API key.
+ /// The provisional API key to use. Useful when the user is adding a new provider. When null, the stored API key is used.
/// The cancellation token.
/// The list of text models.
- public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default);
-
+ public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default);
+
///
/// Load all possible image models that can be used with this provider.
///
/// The JS runtime to access the Rust code.
/// The settings manager to access the API key.
+ /// The provisional API key to use. Useful when the user is adding a new provider. When null, the stored API key is used.
/// The cancellation token.
/// The list of image models.
- public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default);
+ public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default);
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Provider/NoProvider.cs b/app/MindWork AI Studio/Provider/NoProvider.cs
index 5c0a9e5..b5b9b2f 100644
--- a/app/MindWork AI Studio/Provider/NoProvider.cs
+++ b/app/MindWork AI Studio/Provider/NoProvider.cs
@@ -13,9 +13,9 @@ public class NoProvider : IProvider
public string InstanceName { get; set; } = "None";
- public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default) => Task.FromResult>([]);
+ public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default) => Task.FromResult>([]);
- public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default) => Task.FromResult>([]);
+ public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default) => Task.FromResult>([]);
public async IAsyncEnumerable StreamChatCompletion(IJSRuntime jsRuntime, SettingsManager settings, Model chatModel, ChatThread chatChatThread, [EnumeratorCancellation] CancellationToken token = default)
{
diff --git a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
index f883a6e..33865b3 100644
--- a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
+++ b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
@@ -151,27 +151,36 @@ public sealed class ProviderOpenAI() : BaseProvider("https://api.openai.com/v1/"
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
///
- public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default)
+ public Task> GetTextModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default)
{
- return this.LoadModels(jsRuntime, settings, "gpt-", token);
+ return this.LoadModels(jsRuntime, settings, "gpt-", token, apiKeyProvisional);
}
///
- public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, CancellationToken token = default)
+ public Task> GetImageModels(IJSRuntime jsRuntime, SettingsManager settings, string? apiKeyProvisional = null, CancellationToken token = default)
{
- return this.LoadModels(jsRuntime, settings, "dall-e-", token);
+ return this.LoadModels(jsRuntime, settings, "dall-e-", token, apiKeyProvisional);
}
#endregion
- private async Task> LoadModels(IJSRuntime jsRuntime, SettingsManager settings, string prefix, CancellationToken token)
+ private async Task> LoadModels(IJSRuntime jsRuntime, SettingsManager settings, string prefix, CancellationToken token, string? apiKeyProvisional = null)
{
- var requestedSecret = await settings.GetAPIKey(jsRuntime, this);
- if (!requestedSecret.Success)
+ var secretKey = apiKeyProvisional switch
+ {
+ not null => apiKeyProvisional,
+ _ => await settings.GetAPIKey(jsRuntime, this) switch
+ {
+ { Success: true } result => result.Secret,
+ _ => null,
+ }
+ };
+
+ if (secretKey is null)
return [];
var request = new HttpRequestMessage(HttpMethod.Get, "models");
- request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", requestedSecret.Secret);
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", secretKey);
var response = await this.httpClient.SendAsync(request, token);
if(!response.IsSuccessStatusCode)