mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-17 14:18:00 +00:00
Added embedding configurations (#224)
This commit is contained in:
1 parent
f806ee28c5
commit
799112eb9d
39 files changed
+1359
-439
No files matched your search
@@ -0,0 +1,17 @@
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an interface defining a secret identifier.
|
||||
/// </summary>
|
||||
public interface ISecretId
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique ID of the secret.
|
||||
/// </summary>
|
||||
public string SecretId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The instance name of the secret.
|
||||
/// </summary>
|
||||
public string SecretName { get; }
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Tools.Rust;
|
||||
|
||||
// ReSharper disable NotAccessedPositionalProperty.Local
|
||||
@@ -255,71 +254,71 @@ public sealed class RustService : IDisposable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the API key for the given provider.
|
||||
/// Try to get the API key for the given secret ID.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider to get the API key for.</param>
|
||||
/// <param name="secretId">The secret ID to get the API key for.</param>
|
||||
/// <param name="isTrying">Indicates if we are trying to get the API key. In that case, we don't log errors.</param>
|
||||
/// <returns>The requested secret.</returns>
|
||||
public async Task<RequestedSecret> GetAPIKey(IProvider provider, bool isTrying = false)
|
||||
public async Task<RequestedSecret> GetAPIKey(ISecretId secretId, bool isTrying = false)
|
||||
{
|
||||
var secretRequest = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName, isTrying);
|
||||
var secretRequest = new SelectSecretRequest($"provider::{secretId.SecretId}::{secretId.SecretName}::api_key", Environment.UserName, isTrying);
|
||||
var result = await this.http.PostAsJsonAsync("/secrets/get", secretRequest, this.jsonRustSerializerOptions);
|
||||
if (!result.IsSuccessStatusCode)
|
||||
{
|
||||
if(!isTrying)
|
||||
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}' due to an API issue: '{result.StatusCode}'");
|
||||
this.logger!.LogError($"Failed to get the API key for secret ID '{secretId.SecretId}' due to an API issue: '{result.StatusCode}'");
|
||||
return new RequestedSecret(false, new EncryptedText(string.Empty), "Failed to get the API key due to an API issue.");
|
||||
}
|
||||
|
||||
var secret = await result.Content.ReadFromJsonAsync<RequestedSecret>(this.jsonRustSerializerOptions);
|
||||
if (!secret.Success && !isTrying)
|
||||
this.logger!.LogError($"Failed to get the API key for provider '{provider.Id}': '{secret.Issue}'");
|
||||
this.logger!.LogError($"Failed to get the API key for secret ID '{secretId.SecretId}': '{secret.Issue}'");
|
||||
|
||||
return secret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to store the API key for the given provider.
|
||||
/// Try to store the API key for the given secret ID.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider to store the API key for.</param>
|
||||
/// <param name="secretId">The secret ID to store the API key for.</param>
|
||||
/// <param name="key">The API key to store.</param>
|
||||
/// <returns>The store secret response.</returns>
|
||||
public async Task<StoreSecretResponse> SetAPIKey(IProvider provider, string key)
|
||||
public async Task<StoreSecretResponse> SetAPIKey(ISecretId secretId, string key)
|
||||
{
|
||||
var encryptedKey = await this.encryptor!.Encrypt(key);
|
||||
var request = new StoreSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName, encryptedKey);
|
||||
var request = new StoreSecretRequest($"provider::{secretId.SecretId}::{secretId.SecretName}::api_key", Environment.UserName, encryptedKey);
|
||||
var result = await this.http.PostAsJsonAsync("/secrets/store", request, this.jsonRustSerializerOptions);
|
||||
if (!result.IsSuccessStatusCode)
|
||||
{
|
||||
this.logger!.LogError($"Failed to store the API key for provider '{provider.Id}' due to an API issue: '{result.StatusCode}'");
|
||||
this.logger!.LogError($"Failed to store the API key for secret ID '{secretId.SecretId}' due to an API issue: '{result.StatusCode}'");
|
||||
return new StoreSecretResponse(false, "Failed to get the API key due to an API issue.");
|
||||
}
|
||||
|
||||
var state = await result.Content.ReadFromJsonAsync<StoreSecretResponse>(this.jsonRustSerializerOptions);
|
||||
if (!state.Success)
|
||||
this.logger!.LogError($"Failed to store the API key for provider '{provider.Id}': '{state.Issue}'");
|
||||
this.logger!.LogError($"Failed to store the API key for secret ID '{secretId.SecretId}': '{state.Issue}'");
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to delete the API key for the given provider.
|
||||
/// Tries to delete the API key for the given secret ID.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider to delete the API key for.</param>
|
||||
/// <param name="secretId">The secret ID to delete the API key for.</param>
|
||||
/// <returns>The delete secret response.</returns>
|
||||
public async Task<DeleteSecretResponse> DeleteAPIKey(IProvider provider)
|
||||
public async Task<DeleteSecretResponse> DeleteAPIKey(ISecretId secretId)
|
||||
{
|
||||
var request = new SelectSecretRequest($"provider::{provider.Id}::{provider.InstanceName}::api_key", Environment.UserName, false);
|
||||
var request = new SelectSecretRequest($"provider::{secretId.SecretId}::{secretId.SecretName}::api_key", Environment.UserName, false);
|
||||
var result = await this.http.PostAsJsonAsync("/secrets/delete", request, this.jsonRustSerializerOptions);
|
||||
if (!result.IsSuccessStatusCode)
|
||||
{
|
||||
this.logger!.LogError($"Failed to delete the API key for provider '{provider.Id}' due to an API issue: '{result.StatusCode}'");
|
||||
this.logger!.LogError($"Failed to delete the API key for secret ID '{secretId.SecretId}' due to an API issue: '{result.StatusCode}'");
|
||||
return new DeleteSecretResponse{Success = false, WasEntryFound = false, Issue = "Failed to delete the API key due to an API issue."};
|
||||
}
|
||||
|
||||
var state = await result.Content.ReadFromJsonAsync<DeleteSecretResponse>(this.jsonRustSerializerOptions);
|
||||
if (!state.Success)
|
||||
this.logger!.LogError($"Failed to delete the API key for provider '{provider.Id}': '{state.Issue}'");
|
||||
this.logger!.LogError($"Failed to delete the API key for secret ID '{secretId.SecretId}': '{state.Issue}'");
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
using Host = AIStudio.Provider.SelfHosted.Host;
|
||||
|
||||
namespace AIStudio.Tools.Validation;
|
||||
|
||||
public sealed class ProviderValidation
|
||||
{
|
||||
public Func<LLMProviders> GetProvider { get; init; } = () => LLMProviders.NONE;
|
||||
|
||||
public Func<string> GetAPIKeyStorageIssue { get; init; } = () => string.Empty;
|
||||
|
||||
public Func<string> GetPreviousInstanceName { get; init; } = () => string.Empty;
|
||||
|
||||
public Func<IEnumerable<string>> GetUsedInstanceNames { get; init; } = () => [];
|
||||
|
||||
public Func<Host> GetHost { get; init; } = () => Host.NONE;
|
||||
|
||||
public string? ValidatingHostname(string hostname)
|
||||
{
|
||||
if(this.GetProvider() != LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(hostname))
|
||||
return "Please enter a hostname, e.g., http://localhost:1234";
|
||||
|
||||
if(!hostname.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase) && !hostname.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
|
||||
return "The hostname must start with either http:// or https://";
|
||||
|
||||
if(!Uri.TryCreate(hostname, UriKind.Absolute, out _))
|
||||
return "The hostname is not a valid HTTP(S) URL.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string? ValidatingAPIKey(string apiKey)
|
||||
{
|
||||
if(this.GetProvider() is LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
var apiKeyStorageIssue = this.GetAPIKeyStorageIssue();
|
||||
if(!string.IsNullOrWhiteSpace(apiKeyStorageIssue))
|
||||
return apiKeyStorageIssue;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(apiKey))
|
||||
return "Please enter an API key.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string? ValidatingInstanceName(string instanceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(instanceName))
|
||||
return "Please enter an instance name.";
|
||||
|
||||
if (instanceName.Length > 40)
|
||||
return "The instance name must not exceed 40 characters.";
|
||||
|
||||
// The instance name must be unique:
|
||||
var lowerInstanceName = instanceName.ToLowerInvariant();
|
||||
if (lowerInstanceName != this.GetPreviousInstanceName() && this.GetUsedInstanceNames().Contains(lowerInstanceName))
|
||||
return "The instance name must be unique; the chosen name is already in use.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string? ValidatingModel(Model model)
|
||||
{
|
||||
if(this.GetProvider() is LLMProviders.SELF_HOSTED && this.GetHost() == Host.LLAMACPP)
|
||||
return null;
|
||||
|
||||
if (model == default)
|
||||
return "Please select a model.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string? ValidatingProvider(LLMProviders llmProvider)
|
||||
{
|
||||
if (llmProvider == LLMProviders.NONE)
|
||||
return "Please select a provider.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string? ValidatingHost(Host host)
|
||||
{
|
||||
if(this.GetProvider() is not LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
if (host == Host.NONE)
|
||||
return "Please select a host.";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user