2024-12-03 14:24:40 +00:00
using System.Text.Json.Serialization ;
2024-04-19 19:25:44 +00:00
using AIStudio.Provider ;
2025-04-11 12:31:10 +00:00
using AIStudio.Provider.HuggingFace ;
2025-08-26 08:59:56 +00:00
using AIStudio.Tools.PluginSystem ;
using Lua ;
2024-07-16 08:28:13 +00:00
using Host = AIStudio . Provider . SelfHosted . Host ;
2024-04-19 19:25:44 +00:00
namespace AIStudio.Settings ;
2024-05-04 08:55:00 +00:00
/// <summary>
/// Data model for configured providers.
/// </summary>
2024-05-19 18:28:25 +00:00
/// <param name="Num">The provider's number.</param>
2024-05-04 08:55:00 +00:00
/// <param name="Id">The provider's ID.</param>
/// <param name="InstanceName">The provider's instance name. Useful for multiple instances of the same provider, e.g., to distinguish between different OpenAI API keys.</param>
2024-09-13 19:50:00 +00:00
/// <param name="UsedLLMProvider">The provider used.</param>
2024-07-03 18:31:04 +00:00
/// <param name="IsSelfHosted">Whether the provider is self-hosted.</param>
/// <param name="Hostname">The hostname of the provider. Useful for self-hosted providers.</param>
2024-05-19 14:10:37 +00:00
/// <param name="Model">The LLM model to use for chat.</param>
2025-08-26 08:59:56 +00:00
public sealed record Provider (
2024-07-16 08:28:13 +00:00
uint Num ,
string Id ,
string InstanceName ,
2024-09-13 19:50:00 +00:00
LLMProviders UsedLLMProvider ,
2024-07-16 08:28:13 +00:00
Model Model ,
bool IsSelfHosted = false ,
2025-06-01 19:14:21 +00:00
bool IsEnterpriseConfiguration = false ,
Guid EnterpriseConfigurationPluginId = default ,
2024-07-16 08:28:13 +00:00
string Hostname = "http://localhost:1234" ,
2025-04-11 12:31:10 +00:00
Host Host = Host . NONE ,
2025-08-26 08:59:56 +00:00
HFInferenceProvider HFInferenceProvider = HFInferenceProvider . NONE ) : ConfigurationBaseObject , ISecretId
2024-05-04 08:55:00 +00:00
{
2025-08-26 08:59:56 +00:00
private static readonly ILogger < Provider > LOGGER = Program . LOGGER_FACTORY . CreateLogger < Provider > ( ) ;
public static readonly Provider NONE = new ( ) ;
public Provider ( ) : this (
0 ,
Guid . Empty . ToString ( ) ,
string . Empty ,
LLMProviders . NONE ,
default ,
false ,
false ,
Guid . Empty )
{
}
2024-05-04 08:55:00 +00:00
#region Overrides of ValueType
/// <summary>
/// Returns a string that represents the current provider in a human-readable format.
/// We use this to display the provider in the chat UI.
/// </summary>
/// <returns>A string that represents the current provider in a human-readable format.</returns>
public override string ToString ( )
{
2024-07-03 18:31:04 +00:00
if ( this . IsSelfHosted )
2024-09-13 19:50:00 +00:00
return $"{this.InstanceName} ({this.UsedLLMProvider.ToName()}, {this.Host}, {this.Hostname}, {this.Model})" ;
2024-07-03 18:31:04 +00:00
2024-09-13 19:50:00 +00:00
return $"{this.InstanceName} ({this.UsedLLMProvider.ToName()}, {this.Model})" ;
2024-05-04 08:55:00 +00:00
}
#endregion
2024-12-03 14:24:40 +00:00
#region Implementation of ISecretId
/// <inheritdoc />
[JsonIgnore]
public string SecretId = > this . Id ;
/// <inheritdoc />
[JsonIgnore]
public string SecretName = > this . InstanceName ;
#endregion
2025-08-26 08:59:56 +00:00
#region Implementation of IConfigurationObject
public override string Name
{
get = > this . InstanceName ;
init = > this . InstanceName = value ;
}
#endregion
public static bool TryParseProviderTable ( int idx , LuaTable table , Guid configPluginId , out ConfigurationBaseObject provider )
{
provider = NONE ;
if ( ! table . TryGetValue ( "Id" , out var idValue ) | | ! idValue . TryRead < string > ( out var idText ) | | ! Guid . TryParse ( idText , out var id ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid ID. The ID must be a valid GUID." ) ;
return false ;
}
if ( ! table . TryGetValue ( "InstanceName" , out var instanceNameValue ) | | ! instanceNameValue . TryRead < string > ( out var instanceName ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid instance name." ) ;
return false ;
}
if ( ! table . TryGetValue ( "UsedLLMProvider" , out var usedLLMProviderValue ) | | ! usedLLMProviderValue . TryRead < string > ( out var usedLLMProviderText ) | | ! Enum . TryParse < LLMProviders > ( usedLLMProviderText , true , out var usedLLMProvider ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid LLM provider enum value." ) ;
return false ;
}
if ( ! table . TryGetValue ( "Host" , out var hostValue ) | | ! hostValue . TryRead < string > ( out var hostText ) | | ! Enum . TryParse < Host > ( hostText , true , out var host ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid host enum value." ) ;
return false ;
}
if ( ! table . TryGetValue ( "Hostname" , out var hostnameValue ) | | ! hostnameValue . TryRead < string > ( out var hostname ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid hostname." ) ;
return false ;
}
if ( ! table . TryGetValue ( "Model" , out var modelValue ) | | ! modelValue . TryRead < LuaTable > ( out var modelTable ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid model table." ) ;
return false ;
}
if ( ! TryReadModelTable ( idx , modelTable , out var model ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid model configuration." ) ;
return false ;
}
provider = new Provider
{
Num = 0 ,
Id = id . ToString ( ) ,
InstanceName = instanceName ,
UsedLLMProvider = usedLLMProvider ,
Model = model ,
IsSelfHosted = usedLLMProvider is LLMProviders . SELF_HOSTED ,
IsEnterpriseConfiguration = true ,
EnterpriseConfigurationPluginId = configPluginId ,
Hostname = hostname ,
Host = host
} ;
return true ;
}
private static bool TryReadModelTable ( int idx , LuaTable table , out Model model )
{
model = default ;
if ( ! table . TryGetValue ( "Id" , out var idValue ) | | ! idValue . TryRead < string > ( out var id ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid model ID." ) ;
return false ;
}
if ( ! table . TryGetValue ( "DisplayName" , out var displayNameValue ) | | ! displayNameValue . TryRead < string > ( out var displayName ) )
{
LOGGER . LogWarning ( $"The configured provider {idx} does not contain a valid model display name." ) ;
return false ;
}
model = new ( id , displayName ) ;
return true ;
}
2024-05-04 08:55:00 +00:00
}