mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-10-08 21:20:20 +00:00
Merge branch 'main' into summarize_assistent_extension
This commit is contained in:
commit
baf32b5d00
@ -54,7 +54,7 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
|
|||||||
|
|
||||||
#region Implementation of IAgent
|
#region Implementation of IAgent
|
||||||
|
|
||||||
public abstract AIStudio.Settings.Provider? ProviderSettings { get; set; }
|
public abstract AIStudio.Settings.Provider ProviderSettings { get; set; }
|
||||||
|
|
||||||
public abstract Task<ChatThread> ProcessContext(ChatThread chatThread, IDictionary<string, string> additionalData);
|
public abstract Task<ChatThread> ProcessContext(ChatThread chatThread, IDictionary<string, string> additionalData);
|
||||||
|
|
||||||
@ -103,10 +103,9 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
|
|||||||
|
|
||||||
protected async Task AddAIResponseAsync(ChatThread thread, IContent lastUserPrompt, DateTimeOffset time)
|
protected async Task AddAIResponseAsync(ChatThread thread, IContent lastUserPrompt, DateTimeOffset time)
|
||||||
{
|
{
|
||||||
if(this.ProviderSettings is null)
|
if(this.ProviderSettings == Settings.Provider.NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var providerSettings = this.ProviderSettings.Value;
|
|
||||||
var aiText = new ContentText
|
var aiText = new ContentText
|
||||||
{
|
{
|
||||||
// We have to wait for the remote
|
// We have to wait for the remote
|
||||||
@ -127,6 +126,6 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
|
|||||||
// Use the selected provider to get the AI response.
|
// Use the selected provider to get the AI response.
|
||||||
// By awaiting this line, we wait for the entire
|
// By awaiting this line, we wait for the entire
|
||||||
// content to be streamed.
|
// content to be streamed.
|
||||||
await aiText.CreateFromProviderAsync(providerSettings.CreateProvider(this.Logger), providerSettings.Model, lastUserPrompt, thread);
|
await aiText.CreateFromProviderAsync(this.ProviderSettings.CreateProvider(this.Logger), this.ProviderSettings.Model, lastUserPrompt, thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -86,7 +86,7 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
|
|||||||
""";
|
""";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Settings.Provider? ProviderSettings { get; set; }
|
public override Settings.Provider ProviderSettings { get; set; } = Settings.Provider.NONE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data source selection agent does not work with context. Use
|
/// The data source selection agent does not work with context. Use
|
||||||
@ -141,6 +141,11 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
|
|||||||
|
|
||||||
// We start with the provider currently selected by the user:
|
// We start with the provider currently selected by the user:
|
||||||
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true);
|
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true);
|
||||||
|
if (agentProvider == Settings.Provider.NONE)
|
||||||
|
{
|
||||||
|
logger.LogWarning("No provider is selected for the agent. The agent cannot select data sources.");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// Assign the provider settings to the agent:
|
// Assign the provider settings to the agent:
|
||||||
logger.LogInformation($"The agent for the data source selection uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
logger.LogInformation($"The agent for the data source selection uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
||||||
|
@ -71,7 +71,7 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
|
|||||||
""";
|
""";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Settings.Provider? ProviderSettings { get; set; }
|
public override Settings.Provider ProviderSettings { get; set; } = Settings.Provider.NONE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieval context validation agent does not work with context. Use
|
/// The retrieval context validation agent does not work with context. Use
|
||||||
@ -133,6 +133,11 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
|
|||||||
{
|
{
|
||||||
// We start with the provider currently selected by the user:
|
// We start with the provider currently selected by the user:
|
||||||
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true);
|
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true);
|
||||||
|
if (agentProvider == Settings.Provider.NONE)
|
||||||
|
{
|
||||||
|
logger.LogWarning("No provider is selected for the agent.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Assign the provider settings to the agent:
|
// Assign the provider settings to the agent:
|
||||||
logger.LogInformation($"The agent for the retrieval context validation uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
logger.LogInformation($"The agent for the retrieval context validation uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
|
||||||
|
@ -11,7 +11,7 @@ public sealed class AgentTextContentCleaner(ILogger<AgentBase> logger, SettingsM
|
|||||||
|
|
||||||
#region Overrides of AgentBase
|
#region Overrides of AgentBase
|
||||||
|
|
||||||
public override AIStudio.Settings.Provider? ProviderSettings { get; set; }
|
public override AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
|
||||||
|
|
||||||
protected override Type Type => Type.SYSTEM;
|
protected override Type Type => Type.SYSTEM;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ public interface IAgent
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The provider to use for this agent.
|
/// The provider to use for this agent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public AIStudio.Settings.Provider? ProviderSettings { get; set; }
|
public Settings.Provider ProviderSettings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes a chat thread (i.e., context) and returns the updated thread.
|
/// Processes a chat thread (i.e., context) and returns the updated thread.
|
||||||
|
@ -85,7 +85,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
|
|
||||||
protected virtual IReadOnlyList<IButtonData> FooterButtons => [];
|
protected virtual IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
protected AIStudio.Settings.Provider providerSettings;
|
protected AIStudio.Settings.Provider providerSettings = Settings.Provider.NONE;
|
||||||
protected MudForm? form;
|
protected MudForm? form;
|
||||||
protected bool inputIsValid;
|
protected bool inputIsValid;
|
||||||
protected Profile currentProfile = Profile.NO_PROFILE;
|
protected Profile currentProfile = Profile.NO_PROFILE;
|
||||||
@ -352,7 +352,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
private async Task InnerResetForm()
|
private async Task InnerResetForm()
|
||||||
{
|
{
|
||||||
this.resultingContentBlock = null;
|
this.resultingContentBlock = null;
|
||||||
this.providerSettings = default;
|
this.providerSettings = Settings.Provider.NONE;
|
||||||
|
|
||||||
await this.JsRuntime.ClearDiv(RESULT_DIV_ID);
|
await this.JsRuntime.ClearDiv(RESULT_DIV_ID);
|
||||||
await this.JsRuntime.ClearDiv(AFTER_RESULT_DIV_ID);
|
await this.JsRuntime.ClearDiv(AFTER_RESULT_DIV_ID);
|
||||||
|
@ -473,9 +473,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
if(this.selectedERIServer is null)
|
if(this.selectedERIServer is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the ERI server preset '{0}'?"), this.selectedERIServer.ServerName) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the ERI server preset '{0}'?"), this.selectedERIServer.ServerName) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete ERI server preset"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete ERI server preset"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -827,9 +827,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
? string.Format(T("The embedding '{0}' is used in one or more retrieval processes. Are you sure you want to delete it?"), embeddingInfo.EmbeddingName)
|
? string.Format(T("The embedding '{0}' is used in one or more retrieval processes. Are you sure you want to delete it?"), embeddingInfo.EmbeddingName)
|
||||||
: string.Format(T("Are you sure you want to delete the embedding '{0}'?"), embeddingInfo.EmbeddingName);
|
: string.Format(T("Are you sure you want to delete the embedding '{0}'?"), embeddingInfo.EmbeddingName);
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", message },
|
{ x => x.Message, message },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -890,9 +890,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
|
|
||||||
private async Task DeleteRetrievalProcess(RetrievalInfo retrievalInfo)
|
private async Task DeleteRetrievalProcess(RetrievalInfo retrievalInfo)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the retrieval process '{0}'?"), retrievalInfo.Name) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the retrieval process '{0}'?"), retrievalInfo.Name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -1834,6 +1834,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"]
|
|||||||
-- Language behavior
|
-- Language behavior
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
|
||||||
|
|
||||||
|
-- Update installation method
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Update installation method"
|
||||||
|
|
||||||
-- Language
|
-- Language
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
||||||
|
|
||||||
@ -1864,6 +1867,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T602293588"]
|
|||||||
-- Choose the color theme that best suits for you.
|
-- Choose the color theme that best suits for you.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you."
|
||||||
|
|
||||||
|
-- Should updates be installed automatically or manually?
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T707880477"] = "Should updates be installed automatically or manually?"
|
||||||
|
|
||||||
-- Energy saving is enabled
|
-- Energy saving is enabled
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled"
|
||||||
|
|
||||||
@ -2119,6 +2125,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1016188706"] = "Are you sure
|
|||||||
-- Move chat
|
-- Move chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat"
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1307384014"] = "Unnamed workspace"
|
||||||
|
|
||||||
-- Delete
|
-- Delete
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete"
|
||||||
|
|
||||||
@ -2152,6 +2161,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Are you sure
|
|||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
|
||||||
|
|
||||||
|
-- Please enter a chat name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Please enter a chat name."
|
||||||
|
|
||||||
|
-- Workspace Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2446263209"] = "Workspace Name"
|
||||||
|
|
||||||
-- Move to workspace
|
-- Move to workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
|
||||||
|
|
||||||
@ -2164,6 +2179,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Move Chat to
|
|||||||
-- Please enter a new or edit the name for your workspace '{0}':
|
-- Please enter a new or edit the name for your workspace '{0}':
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
|
||||||
|
|
||||||
|
-- Please enter a workspace name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Please enter a workspace name."
|
||||||
|
|
||||||
|
-- Unnamed chat
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat"
|
||||||
|
|
||||||
-- Rename
|
-- Rename
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename"
|
||||||
|
|
||||||
@ -2176,6 +2197,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3555709365"] = "Load Chat"
|
|||||||
-- Add Workspace
|
-- Add Workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace"
|
||||||
|
|
||||||
|
-- Chat Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3891063690"] = "Chat Name"
|
||||||
|
|
||||||
-- Empty chat
|
-- Empty chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat"
|
||||||
|
|
||||||
@ -4132,8 +4156,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832
|
|||||||
-- Preselect one of your profiles?
|
-- Preselect one of your profiles?
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?"
|
||||||
|
|
||||||
-- Chat name
|
-- Please enter a value.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Please enter a value."
|
||||||
|
|
||||||
|
-- Your Input
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T4030229154"] = "Your Input"
|
||||||
|
|
||||||
-- Cancel
|
-- Cancel
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"
|
||||||
@ -4882,6 +4909,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2128088682
|
|||||||
-- Navigation expands on mouse hover
|
-- Navigation expands on mouse hover
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover"
|
||||||
|
|
||||||
|
-- Install updates manually
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T220653235"] = "Install updates manually"
|
||||||
|
|
||||||
-- Also show features ready for release; these should be stable
|
-- Also show features ready for release; these should be stable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable"
|
||||||
|
|
||||||
@ -4921,6 +4951,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3137986690
|
|||||||
-- Delete disappearing chats older than 180 days
|
-- Delete disappearing chats older than 180 days
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Delete disappearing chats older than 180 days"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Delete disappearing chats older than 180 days"
|
||||||
|
|
||||||
|
-- Install updates automatically
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3569059463"] = "Install updates automatically"
|
||||||
|
|
||||||
-- Disable workspaces
|
-- Disable workspaces
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces"
|
||||||
|
|
||||||
@ -5452,11 +5485,14 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCATEGORYEXTENSIONS::T91464
|
|||||||
-- The SETTINGS table does not exist or is not a valid table.
|
-- The SETTINGS table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "The SETTINGS table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "The SETTINGS table does not exist or is not a valid table."
|
||||||
|
|
||||||
|
-- At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3262676428"] = "At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist."
|
||||||
|
|
||||||
-- The CONFIG table does not exist or is not a valid table.
|
-- The CONFIG table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
|
||||||
|
|
||||||
-- The LLM_PROVIDERS table does not exist or is not a valid table.
|
-- At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "The LLM_PROVIDERS table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T445358428"] = "At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist."
|
||||||
|
|
||||||
-- The field IETF_TAG does not exist or is not a valid string.
|
-- The field IETF_TAG does not exist or is not a valid string.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
|
||||||
@ -5584,6 +5620,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::SECRETS::T4007657575"]
|
|||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
||||||
|
|
||||||
|
-- Failed to install update automatically. Please try again manually.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T3709709946"] = "Failed to install update automatically. Please try again manually."
|
||||||
|
|
||||||
-- The hostname is not a valid HTTP(S) URL.
|
-- The hostname is not a valid HTTP(S) URL.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL."
|
||||||
|
|
||||||
@ -5686,5 +5725,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T497939286"] =
|
|||||||
-- Please select a model.
|
-- Please select a model.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model."
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T1307384014"] = "Unnamed workspace"
|
||||||
|
|
||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat"
|
||||||
|
@ -18,9 +18,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<ChatThread?> ChatThreadChanged { get; set; }
|
public EventCallback<ChatThread?> ChatThreadChanged { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public AIStudio.Settings.Provider Provider { get; set; }
|
public AIStudio.Settings.Provider Provider { get; set; } = AIStudio.Settings.Provider.NONE;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<AIStudio.Settings.Provider> ProviderChanged { get; set; }
|
public EventCallback<AIStudio.Settings.Provider> ProviderChanged { get; set; }
|
||||||
@ -587,9 +587,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
//
|
//
|
||||||
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
|
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", "Are you sure you want to start a new chat? All unsaved changes will be lost." },
|
{ x => x.Message, "Are you sure you want to start a new chat? All unsaved changes will be lost." },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -634,7 +634,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
case AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER:
|
case AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER:
|
||||||
if(this.Provider == default)
|
if(this.Provider == AIStudio.Settings.Provider.NONE)
|
||||||
{
|
{
|
||||||
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
await this.ProviderChanged.InvokeAsync(this.Provider);
|
await this.ProviderChanged.InvokeAsync(this.Provider);
|
||||||
@ -695,9 +695,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
|
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
|
||||||
{
|
{
|
||||||
var confirmationDialogParameters = new DialogParameters
|
var confirmationDialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Are you sure you want to move this chat? All unsaved changes will be lost.") },
|
{ x => x.Message, T("Are you sure you want to move this chat? All unsaved changes will be lost.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var confirmationDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Unsaved Changes", confirmationDialogParameters, DialogOptions.FULLSCREEN);
|
var confirmationDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Unsaved Changes", confirmationDialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -706,11 +706,11 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<WorkspaceSelectionDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Please select the workspace where you want to move the chat to.") },
|
{ x => x.Message, T("Please select the workspace where you want to move the chat to.") },
|
||||||
{ "SelectedWorkspace", this.ChatThread?.WorkspaceId },
|
{ x => x.SelectedWorkspace, this.ChatThread?.WorkspaceId },
|
||||||
{ "ConfirmText", T("Move chat") },
|
{ x => x.ConfirmText, T("Move chat") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -797,7 +797,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER:
|
case LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER:
|
||||||
if(this.Provider == default)
|
if(this.Provider == AIStudio.Settings.Provider.NONE)
|
||||||
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,9 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
|
|||||||
foreach (var providerId in this.Data)
|
foreach (var providerId in this.Data)
|
||||||
{
|
{
|
||||||
var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value);
|
var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value);
|
||||||
|
if (provider is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
||||||
yield return providerId;
|
yield return providerId;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ public partial class ProviderSelection : MSGComponentBase
|
|||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
public AssistantBase<NoComponent>? AssistantBase { get; set; }
|
public AssistantBase<NoComponent>? AssistantBase { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public AIStudio.Settings.Provider ProviderSettings { get; set; }
|
public AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<AIStudio.Settings.Provider> ProviderSettingsChanged { get; set; }
|
public EventCallback<AIStudio.Settings.Provider> ProviderSettingsChanged { get; set; }
|
||||||
@ -32,7 +32,8 @@ public partial class ProviderSelection : MSGComponentBase
|
|||||||
{
|
{
|
||||||
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE);
|
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE);
|
||||||
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
|
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
|
||||||
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
if (provider.UsedLLMProvider != LLMProviders.NONE)
|
||||||
yield return provider;
|
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
||||||
|
yield return provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,7 @@ public partial class ReadWebContent : MSGComponentBase
|
|||||||
public EventCallback<string> ContentChanged { get; set; }
|
public EventCallback<string> ContentChanged { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public AIStudio.Settings.Provider ProviderSettings { get; set; }
|
public AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public bool AgentIsRunning { get; set; }
|
public bool AgentIsRunning { get; set; }
|
||||||
@ -34,7 +34,7 @@ public partial class ReadWebContent : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool PreselectContentCleanerAgent { get; set; }
|
public bool PreselectContentCleanerAgent { get; set; }
|
||||||
|
|
||||||
private Process<ReadWebContentSteps> process = Process<ReadWebContentSteps>.INSTANCE;
|
private readonly Process<ReadWebContentSteps> process = Process<ReadWebContentSteps>.INSTANCE;
|
||||||
private ProcessStepValue processStep;
|
private ProcessStepValue processStep;
|
||||||
|
|
||||||
private bool showWebContentReader;
|
private bool showWebContentReader;
|
||||||
@ -43,7 +43,7 @@ public partial class ReadWebContent : MSGComponentBase
|
|||||||
private bool urlIsValid;
|
private bool urlIsValid;
|
||||||
private bool isProviderValid;
|
private bool isProviderValid;
|
||||||
|
|
||||||
private AIStudio.Settings.Provider providerSettings;
|
private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ public partial class ReadWebContent : MSGComponentBase
|
|||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
markdown = this.HTMLParser.ParseToMarkdown(html);
|
markdown = this.HTMLParser.ParseToMarkdown(html);
|
||||||
|
|
||||||
if (this.useContentCleanerAgent)
|
if (this.useContentCleanerAgent && this.providerSettings != AIStudio.Settings.Provider.NONE)
|
||||||
{
|
{
|
||||||
this.AgentTextContentCleaner.ProviderSettings = this.providerSettings;
|
this.AgentTextContentCleaner.ProviderSettings = this.providerSettings;
|
||||||
var additionalData = new Dictionary<string, string>
|
var additionalData = new Dictionary<string, string>
|
||||||
@ -149,7 +149,7 @@ public partial class ReadWebContent : MSGComponentBase
|
|||||||
|
|
||||||
private string? ValidateProvider(bool shouldUseAgent)
|
private string? ValidateProvider(bool shouldUseAgent)
|
||||||
{
|
{
|
||||||
if(shouldUseAgent && this.providerSettings == default)
|
if(shouldUseAgent && this.providerSettings == AIStudio.Settings.Provider.NONE)
|
||||||
{
|
{
|
||||||
this.isProviderValid = false;
|
this.isProviderValid = false;
|
||||||
return T("Please select a provider to use the cleanup agent.");
|
return T("Please select a provider to use the cleanup agent.");
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
|
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
|
||||||
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.")"/>
|
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.")"/>
|
||||||
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/>
|
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateBehavior, out var meta) && meta.IsLocked"/>
|
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInterval)" Data="@ConfigurationSelectDataFactory.GetUpdateIntervalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInterval = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInterval, out var meta) && meta.IsLocked"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Update installation method")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInstallation)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviourData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInstallation = selectedValue)" OptionHelp="@T("Should updates be installed automatically or manually?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInstallation, out var meta) && meta.IsLocked"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
|
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
|
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
|
|||||||
|
|
||||||
private async Task DeleteEmbeddingProvider(EmbeddingProvider provider)
|
private async Task DeleteEmbeddingProvider(EmbeddingProvider provider)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -54,6 +54,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
|||||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||||
private async Task EditLLMProvider(AIStudio.Settings.Provider provider)
|
private async Task EditLLMProvider(AIStudio.Settings.Provider provider)
|
||||||
{
|
{
|
||||||
|
if(provider == AIStudio.Settings.Provider.NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
if (provider.IsEnterpriseConfiguration)
|
if (provider.IsEnterpriseConfiguration)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -93,9 +96,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
|||||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||||
private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider)
|
private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the provider '{0}'?"), provider.InstanceName) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the provider '{0}'?"), provider.InstanceName) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -111,9 +114,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var issueDialogParameters = new DialogParameters
|
var issueDialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Couldn't delete the provider '{0}'. The issue: {1}. We can ignore this issue and delete the provider anyway. Do you want to ignore it and delete this provider?"), provider.InstanceName, deleteSecretResponse.Issue) },
|
{ x => x.Message, string.Format(T("Couldn't delete the provider '{0}'. The issue: {1}. We can ignore this issue and delete the provider anyway. Do you want to ignore it and delete this provider?"), provider.InstanceName, deleteSecretResponse.Issue) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var issueDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), issueDialogParameters, DialogOptions.FULLSCREEN);
|
var issueDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), issueDialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -112,9 +112,30 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Enumerate the chat directories:
|
// Enumerate the chat directories:
|
||||||
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
|
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
|
||||||
{
|
{
|
||||||
// Read the `name` file:
|
// Read or create the `name` file (self-heal):
|
||||||
var chatNamePath = Path.Join(tempChatDirPath, "name");
|
var chatNamePath = Path.Join(tempChatDirPath, "name");
|
||||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
string chatName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(chatNamePath))
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||||
|
if (string.IsNullOrWhiteSpace(chatName))
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
}
|
||||||
|
|
||||||
// Read the last change time of the chat:
|
// Read the last change time of the chat:
|
||||||
var chatThreadPath = Path.Join(tempChatDirPath, "thread.json");
|
var chatThreadPath = Path.Join(tempChatDirPath, "thread.json");
|
||||||
@ -158,9 +179,30 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Enumerate the workspace directories:
|
// Enumerate the workspace directories:
|
||||||
foreach (var workspaceDirPath in Directory.EnumerateDirectories(workspaceDirectories))
|
foreach (var workspaceDirPath in Directory.EnumerateDirectories(workspaceDirectories))
|
||||||
{
|
{
|
||||||
// Read the `name` file:
|
// Read or create the `name` file (self-heal):
|
||||||
var workspaceNamePath = Path.Join(workspaceDirPath, "name");
|
var workspaceNamePath = Path.Join(workspaceDirPath, "name");
|
||||||
var workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
string workspaceName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(workspaceNamePath))
|
||||||
|
{
|
||||||
|
workspaceName = T("Unnamed workspace");
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||||
|
if (string.IsNullOrWhiteSpace(workspaceName))
|
||||||
|
{
|
||||||
|
workspaceName = T("Unnamed workspace");
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
workspaceName = T("Unnamed workspace");
|
||||||
|
}
|
||||||
|
|
||||||
workspaces.Add(new TreeItemData<ITreeItem>
|
workspaces.Add(new TreeItemData<ITreeItem>
|
||||||
{
|
{
|
||||||
@ -194,9 +236,30 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Enumerate the workspace directory:
|
// Enumerate the workspace directory:
|
||||||
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
|
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
|
||||||
{
|
{
|
||||||
// Read the `name` file:
|
// Read or create the `name` file (self-heal):
|
||||||
var chatNamePath = Path.Join(chatPath, "name");
|
var chatNamePath = Path.Join(chatPath, "name");
|
||||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
string chatName;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(chatNamePath))
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||||
|
if (string.IsNullOrWhiteSpace(chatName))
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
chatName = T("Unnamed chat");
|
||||||
|
}
|
||||||
|
|
||||||
// Read the last change time of the chat:
|
// Read the last change time of the chat:
|
||||||
var chatThreadPath = Path.Join(chatPath, "thread.json");
|
var chatThreadPath = Path.Join(chatPath, "thread.json");
|
||||||
@ -252,9 +315,9 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Check if the chat has unsaved changes:
|
// Check if the chat has unsaved changes:
|
||||||
if (switchToChat && await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
if (switchToChat && await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Are you sure you want to load another chat? All unsaved changes will be lost.") },
|
{ x => x.Message, T("Are you sure you want to load another chat? All unsaved changes will be lost.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Load Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Load Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -293,10 +356,10 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
if (askForConfirmation)
|
if (askForConfirmation)
|
||||||
{
|
{
|
||||||
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(chat.WorkspaceId);
|
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(chat.WorkspaceId);
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"Message", (chat.WorkspaceId == Guid.Empty) switch
|
x => x.Message, (chat.WorkspaceId == Guid.Empty) switch
|
||||||
{
|
{
|
||||||
true => string.Format(T("Are you sure you want to delete the temporary chat '{0}'?"), chat.Name),
|
true => string.Format(T("Are you sure you want to delete the temporary chat '{0}'?"), chat.Name),
|
||||||
false => string.Format(T("Are you sure you want to delete the chat '{0}' in the workspace '{1}'?"), chat.Name, workspaceName),
|
false => string.Format(T("Are you sure you want to delete the chat '{0}' in the workspace '{1}'?"), chat.Name, workspaceName),
|
||||||
@ -333,12 +396,15 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
if (chat is null)
|
if (chat is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<SingleInputDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) },
|
{ x => x.Message, string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) },
|
||||||
{ "UserInput", chat.Name },
|
{ x => x.InputHeaderText, T("Chat Name") },
|
||||||
{ "ConfirmText", T("Rename") },
|
{ x => x.UserInput, chat.Name },
|
||||||
{ "ConfirmColor", Color.Info },
|
{ x => x.ConfirmText, T("Rename") },
|
||||||
|
{ x => x.ConfirmColor, Color.Info },
|
||||||
|
{ x => x.AllowEmptyInput, false },
|
||||||
|
{ x => x.EmptyInputErrorMessage, T("Please enter a chat name.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -365,12 +431,15 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
|
|
||||||
var workspaceId = Guid.Parse(Path.GetFileName(workspacePath));
|
var workspaceId = Guid.Parse(Path.GetFileName(workspacePath));
|
||||||
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId);
|
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId);
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<SingleInputDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) },
|
{ x => x.Message, string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) },
|
||||||
{ "UserInput", workspaceName },
|
{ x => x.InputHeaderText, T("Workspace Name") },
|
||||||
{ "ConfirmText", T("Rename") },
|
{ x => x.UserInput, workspaceName },
|
||||||
{ "ConfirmColor", Color.Info },
|
{ x => x.ConfirmText, T("Rename") },
|
||||||
|
{ x => x.ConfirmColor, Color.Info },
|
||||||
|
{ x => x.AllowEmptyInput, false },
|
||||||
|
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -386,12 +455,15 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
|
|
||||||
private async Task AddWorkspace()
|
private async Task AddWorkspace()
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<SingleInputDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Please name your workspace:") },
|
{ x => x.Message, T("Please name your workspace:") },
|
||||||
{ "UserInput", string.Empty },
|
{ x => x.InputHeaderText, T("Workspace Name") },
|
||||||
{ "ConfirmText", T("Add workspace") },
|
{ x => x.UserInput, string.Empty },
|
||||||
{ "ConfirmColor", Color.Info },
|
{ x => x.ConfirmText, T("Add workspace") },
|
||||||
|
{ x => x.ConfirmColor, Color.Info },
|
||||||
|
{ x => x.AllowEmptyInput, false },
|
||||||
|
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -420,9 +492,9 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Determine how many chats are in the workspace:
|
// Determine how many chats are in the workspace:
|
||||||
var chatCount = Directory.EnumerateDirectories(workspacePath).Count();
|
var chatCount = Directory.EnumerateDirectories(workspacePath).Count();
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the workspace '{0}'? This will also delete {1} chat(s) in this workspace."), workspaceName, chatCount) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the workspace '{0}'? This will also delete {1} chat(s) in this workspace."), workspaceName, chatCount) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -440,11 +512,11 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
if (chat is null)
|
if (chat is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<WorkspaceSelectionDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Please select the workspace where you want to move the chat to.") },
|
{ x => x.Message, T("Please select the workspace where you want to move the chat to.") },
|
||||||
{ "SelectedWorkspace", chat.WorkspaceId },
|
{ x => x.SelectedWorkspace, chat.WorkspaceId },
|
||||||
{ "ConfirmText", T("Move chat") },
|
{ x => x.ConfirmText, T("Move chat") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
@ -487,9 +559,9 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
// Check if the chat has unsaved changes:
|
// Check if the chat has unsaved changes:
|
||||||
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Are you sure you want to create a another chat? All unsaved changes will be lost.") },
|
{ x => x.Message, T("Are you sure you want to create a another chat? All unsaved changes will be lost.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Create Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Create Chat"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -83,9 +83,9 @@ public partial class PandocDialog : MSGComponentBase
|
|||||||
private async Task RejectLicense()
|
private async Task RejectLicense()
|
||||||
{
|
{
|
||||||
var message = T("Pandoc is open-source and free, but if you reject its license, you can't install it and some MindWork AI Studio features will be limited (like the integration of Office files) or unavailable (like the generation of Office files). You can change your decision anytime. Are you sure you want to reject the license?");
|
var message = T("Pandoc is open-source and free, but if you reject its license, you can't install it and some MindWork AI Studio features will be limited (like the integration of Office files) or unavailable (like the generation of Office files). You can change your decision anytime. Are you sure you want to reject the license?");
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", message },
|
{ x => x.Message, message },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reject Pandoc's Licence"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reject Pandoc's Licence"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -8,9 +8,9 @@ public partial class SettingsDialogAssistantBias : SettingsDialogBase
|
|||||||
|
|
||||||
private async Task ResetBiasOfTheDayHistory()
|
private async Task ResetBiasOfTheDayHistory()
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again.") },
|
{ x => x.Message, T("Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reset your bias-of-the-day statistics"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reset your bias-of-the-day statistics"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -82,9 +82,9 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
|
|||||||
|
|
||||||
private async Task DeleteChatTemplate(ChatTemplate chatTemplate)
|
private async Task DeleteChatTemplate(ChatTemplate chatTemplate)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the chat template '{0}'?"), chatTemplate.Name) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the chat template '{0}'?"), chatTemplate.Name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -151,9 +151,9 @@ public partial class SettingsDialogDataSources : SettingsDialogBase
|
|||||||
|
|
||||||
private async Task DeleteDataSource(IDataSource dataSource)
|
private async Task DeleteDataSource(IDataSource dataSource)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the data source '{0}' of type {1}?"), dataSource.Name, dataSource.Type.GetDisplayName()) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the data source '{0}' of type {1}?"), dataSource.Name, dataSource.Type.GetDisplayName()) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Data Source"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Data Source"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -51,9 +51,9 @@ public partial class SettingsDialogProfiles : SettingsDialogBase
|
|||||||
|
|
||||||
private async Task DeleteProfile(Profile profile)
|
private async Task DeleteProfile(Profile profile)
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the profile '{0}'?"), profile.Name) },
|
{ x => x.Message, string.Format(T("Are you sure you want to delete the profile '{0}'?"), profile.Name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Profile"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Profile"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
<MudText Typo="Typo.body1">
|
<MudText Typo="Typo.body1">
|
||||||
@this.Message
|
@this.Message
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@T("Chat name")" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudForm @ref="this.form" Class="mt-4">
|
||||||
|
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@this.GetInputHeaderText" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES" Validation="@this.ValidateUserInput" />
|
||||||
|
</MudForm>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@ -20,9 +20,20 @@ public partial class SingleInputDialog : MSGComponentBase
|
|||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Color ConfirmColor { get; set; } = Color.Error;
|
public Color ConfirmColor { get; set; } = Color.Error;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool AllowEmptyInput { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string InputHeaderText { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string EmptyInputErrorMessage { get; set; } = string.Empty;
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
||||||
|
|
||||||
|
private MudForm form = null!;
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@ -34,7 +45,24 @@ public partial class SingleInputDialog : MSGComponentBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private string GetInputHeaderText => string.IsNullOrWhiteSpace(this.InputHeaderText) ? T("Your Input") : this.InputHeaderText;
|
||||||
|
|
||||||
|
private string? ValidateUserInput(string? value)
|
||||||
|
{
|
||||||
|
if (!this.AllowEmptyInput && string.IsNullOrWhiteSpace(value))
|
||||||
|
return string.IsNullOrWhiteSpace(this.EmptyInputErrorMessage) ? T("Please enter a value.") : this.EmptyInputErrorMessage;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void Cancel() => this.MudDialog.Cancel();
|
private void Cancel() => this.MudDialog.Cancel();
|
||||||
|
|
||||||
private void Confirm() => this.MudDialog.Close(DialogResult.Ok(this.UserInput));
|
private async Task Confirm()
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
if(!this.form.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.MudDialog.Close(DialogResult.Ok(this.UserInput));
|
||||||
|
}
|
||||||
}
|
}
|
@ -92,7 +92,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
|||||||
[
|
[
|
||||||
Event.UPDATE_AVAILABLE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED, Event.SHOW_ERROR,
|
Event.UPDATE_AVAILABLE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED, Event.SHOW_ERROR,
|
||||||
Event.SHOW_ERROR, Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.STARTUP_PLUGIN_SYSTEM,
|
Event.SHOW_ERROR, Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.STARTUP_PLUGIN_SYSTEM,
|
||||||
Event.PLUGINS_RELOADED
|
Event.PLUGINS_RELOADED, Event.INSTALL_UPDATE,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Set the snackbar for the update service:
|
// Set the snackbar for the update service:
|
||||||
@ -143,6 +143,11 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
|||||||
{
|
{
|
||||||
switch (triggeredEvent)
|
switch (triggeredEvent)
|
||||||
{
|
{
|
||||||
|
case Event.INSTALL_UPDATE:
|
||||||
|
this.performingUpdate = true;
|
||||||
|
this.StateHasChanged();
|
||||||
|
break;
|
||||||
|
|
||||||
case Event.UPDATE_AVAILABLE:
|
case Event.UPDATE_AVAILABLE:
|
||||||
if (data is UpdateResponse updateResponse)
|
if (data is UpdateResponse updateResponse)
|
||||||
{
|
{
|
||||||
@ -301,9 +306,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
|||||||
{
|
{
|
||||||
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
|
||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{ "Message", T("Are you sure you want to leave the chat page? All unsaved changes will be lost.") },
|
{ x => x.Message, T("Are you sure you want to leave the chat page? All unsaved changes will be lost.") },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Leave Chat Page"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Leave Chat Page"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
@ -21,7 +21,7 @@ public partial class Chat : MSGComponentBase
|
|||||||
private IDialogService DialogService { get; init; } = null!;
|
private IDialogService DialogService { get; init; } = null!;
|
||||||
|
|
||||||
private ChatThread? chatThread;
|
private ChatThread? chatThread;
|
||||||
private AIStudio.Settings.Provider providerSettings;
|
private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
|
||||||
private bool workspaceOverlayVisible;
|
private bool workspaceOverlayVisible;
|
||||||
private string currentWorkspaceName = string.Empty;
|
private string currentWorkspaceName = string.Empty;
|
||||||
private Workspaces? workspaces;
|
private Workspaces? workspaces;
|
||||||
|
@ -18,7 +18,7 @@ public partial class Writer : MSGComponentBase
|
|||||||
private readonly Timer typeTimer = new(TimeSpan.FromMilliseconds(1_500));
|
private readonly Timer typeTimer = new(TimeSpan.FromMilliseconds(1_500));
|
||||||
|
|
||||||
private MudTextField<string> textField = null!;
|
private MudTextField<string> textField = null!;
|
||||||
private AIStudio.Settings.Provider providerSettings;
|
private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
|
||||||
private ChatThread? chatThread;
|
private ChatThread? chatThread;
|
||||||
private bool isStreaming;
|
private bool isStreaming;
|
||||||
private string userInput = string.Empty;
|
private string userInput = string.Empty;
|
||||||
|
@ -62,9 +62,13 @@ CONFIG["LLM_PROVIDERS"][#CONFIG["LLM_PROVIDERS"]+1] = {
|
|||||||
|
|
||||||
CONFIG["SETTINGS"] = {}
|
CONFIG["SETTINGS"] = {}
|
||||||
|
|
||||||
-- Configure the update behavior:
|
-- Configure the update check interval:
|
||||||
-- Allowed values are: NO_CHECK, ONCE_STARTUP, HOURLY, DAILY, WEEKLY
|
-- Allowed values are: NO_CHECK, ONCE_STARTUP, HOURLY, DAILY, WEEKLY
|
||||||
-- CONFIG["SETTINGS"]["DataApp.UpdateBehavior"] = "NO_CHECK"
|
-- CONFIG["SETTINGS"]["DataApp.UpdateInterval"] = "NO_CHECK"
|
||||||
|
|
||||||
|
-- Configure how updates are installed:
|
||||||
|
-- Allowed values are: MANUAL, AUTOMATIC
|
||||||
|
-- CONFIG["SETTINGS"]["DataApp.UpdateInstallation"] = "MANUAL"
|
||||||
|
|
||||||
-- Configure the user permission to add providers:
|
-- Configure the user permission to add providers:
|
||||||
-- Allowed values are: true, false
|
-- Allowed values are: true, false
|
||||||
|
@ -1836,6 +1836,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"]
|
|||||||
-- Language behavior
|
-- Language behavior
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Sprachverhalten"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Sprachverhalten"
|
||||||
|
|
||||||
|
-- Update installation method
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Installationsmethode für Updates"
|
||||||
|
|
||||||
-- Language
|
-- Language
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Sprache"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Sprache"
|
||||||
|
|
||||||
@ -1866,6 +1869,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T602293588"]
|
|||||||
-- Choose the color theme that best suits for you.
|
-- Choose the color theme that best suits for you.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Wählen Sie das Farbschema, das am besten zu Ihnen passt."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Wählen Sie das Farbschema, das am besten zu Ihnen passt."
|
||||||
|
|
||||||
|
-- Should updates be installed automatically or manually?
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T707880477"] = "Sollen Updates automatisch oder manuell installiert werden?"
|
||||||
|
|
||||||
-- Energy saving is enabled
|
-- Energy saving is enabled
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energiesparmodus ist aktiviert"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energiesparmodus ist aktiviert"
|
||||||
|
|
||||||
@ -2121,6 +2127,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1016188706"] = "Möchten Sie
|
|||||||
-- Move chat
|
-- Move chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Chat verschieben"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Chat verschieben"
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1307384014"] = "Unbenannter Arbeitsbereich"
|
||||||
|
|
||||||
-- Delete
|
-- Delete
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Löschen"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Löschen"
|
||||||
|
|
||||||
@ -2154,6 +2163,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Möchten Sie
|
|||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen"
|
||||||
|
|
||||||
|
-- Please enter a chat name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Bitte geben Sie einen Namen für diesen Chat ein."
|
||||||
|
|
||||||
|
-- Workspace Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2446263209"] = "Name des Arbeitsbereichs"
|
||||||
|
|
||||||
-- Move to workspace
|
-- Move to workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben"
|
||||||
|
|
||||||
@ -2166,6 +2181,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Chat in den
|
|||||||
-- Please enter a new or edit the name for your workspace '{0}':
|
-- Please enter a new or edit the name for your workspace '{0}':
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:"
|
||||||
|
|
||||||
|
-- Please enter a workspace name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Bitte geben Sie einen Namen für diesen Arbeitsbereich ein."
|
||||||
|
|
||||||
|
-- Unnamed chat
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unbenannter Chat"
|
||||||
|
|
||||||
-- Rename
|
-- Rename
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Umbenennen"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Umbenennen"
|
||||||
|
|
||||||
@ -2178,6 +2199,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3555709365"] = "Chat laden"
|
|||||||
-- Add Workspace
|
-- Add Workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Arbeitsbereich hinzufügen"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Arbeitsbereich hinzufügen"
|
||||||
|
|
||||||
|
-- Chat Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3891063690"] = "Name des Chat"
|
||||||
|
|
||||||
-- Empty chat
|
-- Empty chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Leerer Chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Leerer Chat"
|
||||||
|
|
||||||
@ -4134,8 +4158,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832
|
|||||||
-- Preselect one of your profiles?
|
-- Preselect one of your profiles?
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Eines ihrer Profile vorauswählen?"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Eines ihrer Profile vorauswählen?"
|
||||||
|
|
||||||
-- Chat name
|
-- Please enter a value.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat-Name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Bitte geben Sie einen Wert ein."
|
||||||
|
|
||||||
|
-- Your Input
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T4030229154"] = "Ihre Eingabe"
|
||||||
|
|
||||||
-- Cancel
|
-- Cancel
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen"
|
||||||
@ -4884,6 +4911,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2128088682
|
|||||||
-- Navigation expands on mouse hover
|
-- Navigation expands on mouse hover
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigationsleiste erweitert sich, wenn sich die Maus darüber befindet"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigationsleiste erweitert sich, wenn sich die Maus darüber befindet"
|
||||||
|
|
||||||
|
-- Install updates manually
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T220653235"] = "Updates manuell installieren"
|
||||||
|
|
||||||
-- Also show features ready for release; these should be stable
|
-- Also show features ready for release; these should be stable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Auch Funktionen anzeigen, die bereit für die Veröffentlichung sind; diese sollten stabil sein."
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Auch Funktionen anzeigen, die bereit für die Veröffentlichung sind; diese sollten stabil sein."
|
||||||
|
|
||||||
@ -4923,6 +4953,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3137986690
|
|||||||
-- Disappearing chats: delete chats older than 180 days
|
-- Disappearing chats: delete chats older than 180 days
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Selbstlöschende Chats: lösche Chats die älter als 180 Tage sind"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Selbstlöschende Chats: lösche Chats die älter als 180 Tage sind"
|
||||||
|
|
||||||
|
-- Install updates automatically
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3569059463"] = "Updates automatisch installieren"
|
||||||
|
|
||||||
-- Disable workspaces
|
-- Disable workspaces
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Arbeitsbereiche deaktivieren"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Arbeitsbereiche deaktivieren"
|
||||||
|
|
||||||
@ -5454,11 +5487,14 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCATEGORYEXTENSIONS::T91464
|
|||||||
-- The SETTINGS table does not exist or is not a valid table.
|
-- The SETTINGS table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "Die Tabelle SETTINGS existiert nicht oder ist keine gültige Tabelle."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "Die Tabelle SETTINGS existiert nicht oder ist keine gültige Tabelle."
|
||||||
|
|
||||||
|
-- At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3262676428"] = "Mindestens ein konfigurierter LLM-Anbieter ist ungültig oder konnte nicht verarbeitet werden, oder die Tabelle LLM_PROVIDERS existiert nicht."
|
||||||
|
|
||||||
-- The CONFIG table does not exist or is not a valid table.
|
-- The CONFIG table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "Die Tabelle CONFIG existiert nicht oder ist keine gültige Tabelle."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "Die Tabelle CONFIG existiert nicht oder ist keine gültige Tabelle."
|
||||||
|
|
||||||
-- The LLM_PROVIDERS table does not exist or is not a valid table.
|
-- At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "Die Tabelle LLM_PROVIDERS existiert nicht oder ist keine gültige Tabelle."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T445358428"] = "Mindestens eine konfigurierte Chat-Vorlage ist ungültig oder konnte nicht verarbeitet werden, oder die Tabelle CHAT_TEMPLATES existiert nicht."
|
||||||
|
|
||||||
-- The field IETF_TAG does not exist or is not a valid string.
|
-- The field IETF_TAG does not exist or is not a valid string.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "Das Feld IETF_TAG existiert nicht oder ist keine gültige Zeichenkette."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "Das Feld IETF_TAG existiert nicht oder ist keine gültige Zeichenkette."
|
||||||
@ -5586,6 +5622,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::SECRETS::T4007657575"]
|
|||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden."
|
||||||
|
|
||||||
|
-- Failed to install update automatically. Please try again manually.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T3709709946"] = "Fehler bei der automatischen Installation des Updates. Bitte versuchen Sie es manuell erneut."
|
||||||
|
|
||||||
-- The hostname is not a valid HTTP(S) URL.
|
-- The hostname is not a valid HTTP(S) URL.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "Der Hostname ist keine gültige HTTP(S)-URL."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "Der Hostname ist keine gültige HTTP(S)-URL."
|
||||||
|
|
||||||
@ -5688,5 +5727,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T497939286"] =
|
|||||||
-- Please select a model.
|
-- Please select a model.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Bitte wählen Sie ein Modell aus."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Bitte wählen Sie ein Modell aus."
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T1307384014"] = "Unbenannter Arbeitsbereich"
|
||||||
|
|
||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Chat löschen"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Chat löschen"
|
||||||
|
@ -1836,6 +1836,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"]
|
|||||||
-- Language behavior
|
-- Language behavior
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
|
||||||
|
|
||||||
|
-- Update installation method
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Update installation method"
|
||||||
|
|
||||||
-- Language
|
-- Language
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
|
||||||
|
|
||||||
@ -1866,6 +1869,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T602293588"]
|
|||||||
-- Choose the color theme that best suits for you.
|
-- Choose the color theme that best suits for you.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you."
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you."
|
||||||
|
|
||||||
|
-- Should updates be installed automatically or manually?
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T707880477"] = "Should updates be installed automatically or manually?"
|
||||||
|
|
||||||
-- Energy saving is enabled
|
-- Energy saving is enabled
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled"
|
||||||
|
|
||||||
@ -2121,6 +2127,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1016188706"] = "Are you sure
|
|||||||
-- Move chat
|
-- Move chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat"
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1307384014"] = "Unnamed workspace"
|
||||||
|
|
||||||
-- Delete
|
-- Delete
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete"
|
||||||
|
|
||||||
@ -2154,6 +2163,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Are you sure
|
|||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
|
||||||
|
|
||||||
|
-- Please enter a chat name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Please enter a chat name."
|
||||||
|
|
||||||
|
-- Workspace Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2446263209"] = "Workspace Name"
|
||||||
|
|
||||||
-- Move to workspace
|
-- Move to workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
|
||||||
|
|
||||||
@ -2166,6 +2181,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Move Chat to
|
|||||||
-- Please enter a new or edit the name for your workspace '{0}':
|
-- Please enter a new or edit the name for your workspace '{0}':
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
|
||||||
|
|
||||||
|
-- Please enter a workspace name.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Please enter a workspace name."
|
||||||
|
|
||||||
|
-- Unnamed chat
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat"
|
||||||
|
|
||||||
-- Rename
|
-- Rename
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename"
|
||||||
|
|
||||||
@ -2178,6 +2199,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3555709365"] = "Load Chat"
|
|||||||
-- Add Workspace
|
-- Add Workspace
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace"
|
||||||
|
|
||||||
|
-- Chat Name
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3891063690"] = "Chat Name"
|
||||||
|
|
||||||
-- Empty chat
|
-- Empty chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat"
|
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat"
|
||||||
|
|
||||||
@ -4134,8 +4158,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832
|
|||||||
-- Preselect one of your profiles?
|
-- Preselect one of your profiles?
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?"
|
||||||
|
|
||||||
-- Chat name
|
-- Please enter a value.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Please enter a value."
|
||||||
|
|
||||||
|
-- Your Input
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T4030229154"] = "Your Input"
|
||||||
|
|
||||||
-- Cancel
|
-- Cancel
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"
|
||||||
@ -4884,6 +4911,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2128088682
|
|||||||
-- Navigation expands on mouse hover
|
-- Navigation expands on mouse hover
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover"
|
||||||
|
|
||||||
|
-- Install updates manually
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T220653235"] = "Install updates manually"
|
||||||
|
|
||||||
-- Also show features ready for release; these should be stable
|
-- Also show features ready for release; these should be stable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable"
|
||||||
|
|
||||||
@ -4923,6 +4953,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3137986690
|
|||||||
-- Disappearing chats: delete chats older than 180 days
|
-- Disappearing chats: delete chats older than 180 days
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Disappearing chats: delete chats older than 180 days"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Disappearing chats: delete chats older than 180 days"
|
||||||
|
|
||||||
|
-- Install updates automatically
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3569059463"] = "Install updates automatically"
|
||||||
|
|
||||||
-- Disable workspaces
|
-- Disable workspaces
|
||||||
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces"
|
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces"
|
||||||
|
|
||||||
@ -5454,11 +5487,14 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCATEGORYEXTENSIONS::T91464
|
|||||||
-- The SETTINGS table does not exist or is not a valid table.
|
-- The SETTINGS table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "The SETTINGS table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "The SETTINGS table does not exist or is not a valid table."
|
||||||
|
|
||||||
|
-- At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3262676428"] = "At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist."
|
||||||
|
|
||||||
-- The CONFIG table does not exist or is not a valid table.
|
-- The CONFIG table does not exist or is not a valid table.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
|
||||||
|
|
||||||
-- The LLM_PROVIDERS table does not exist or is not a valid table.
|
-- At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "The LLM_PROVIDERS table does not exist or is not a valid table."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T445358428"] = "At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist."
|
||||||
|
|
||||||
-- The field IETF_TAG does not exist or is not a valid string.
|
-- The field IETF_TAG does not exist or is not a valid string.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
|
||||||
@ -5586,6 +5622,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::SECRETS::T4007657575"]
|
|||||||
-- No update found.
|
-- No update found.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
|
||||||
|
|
||||||
|
-- Failed to install update automatically. Please try again manually.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T3709709946"] = "Failed to install update automatically. Please try again manually."
|
||||||
|
|
||||||
-- The hostname is not a valid HTTP(S) URL.
|
-- The hostname is not a valid HTTP(S) URL.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL."
|
||||||
|
|
||||||
@ -5688,5 +5727,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T497939286"] =
|
|||||||
-- Please select a model.
|
-- Please select a model.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model."
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model."
|
||||||
|
|
||||||
|
-- Unnamed workspace
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T1307384014"] = "Unnamed workspace"
|
||||||
|
|
||||||
-- Delete Chat
|
-- Delete Chat
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat"
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
using Lua;
|
||||||
|
|
||||||
namespace AIStudio.Settings;
|
namespace AIStudio.Settings;
|
||||||
|
|
||||||
public record ChatTemplate(uint Num, string Id, string Name, string SystemPrompt, string PredefinedUserPrompt, List<ContentBlock> ExampleConversation, bool AllowProfileUsage, bool IsEnterpriseConfiguration = false, Guid EnterpriseConfigurationPluginId = default)
|
public record ChatTemplate(
|
||||||
|
uint Num,
|
||||||
|
string Id,
|
||||||
|
string Name,
|
||||||
|
string SystemPrompt,
|
||||||
|
string PredefinedUserPrompt,
|
||||||
|
List<ContentBlock> ExampleConversation,
|
||||||
|
bool AllowProfileUsage,
|
||||||
|
bool IsEnterpriseConfiguration = false,
|
||||||
|
Guid EnterpriseConfigurationPluginId = default) : ConfigurationBaseObject
|
||||||
{
|
{
|
||||||
public ChatTemplate() : this(0, Guid.Empty.ToString(), string.Empty, string.Empty, string.Empty, [], false)
|
public ChatTemplate() : this(0, Guid.Empty.ToString(), string.Empty, string.Empty, string.Empty, [], false)
|
||||||
{
|
{
|
||||||
@ -11,6 +22,8 @@ public record ChatTemplate(uint Num, string Id, string Name, string SystemPrompt
|
|||||||
|
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ChatTemplate).Namespace, nameof(ChatTemplate));
|
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ChatTemplate).Namespace, nameof(ChatTemplate));
|
||||||
|
|
||||||
|
private static readonly ILogger<ChatTemplate> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ChatTemplate>();
|
||||||
|
|
||||||
public static readonly ChatTemplate NO_CHAT_TEMPLATE = new()
|
public static readonly ChatTemplate NO_CHAT_TEMPLATE = new()
|
||||||
{
|
{
|
||||||
Name = TB("Use no chat template"),
|
Name = TB("Use no chat template"),
|
||||||
@ -41,4 +54,96 @@ public record ChatTemplate(uint Num, string Id, string Name, string SystemPrompt
|
|||||||
|
|
||||||
return this.SystemPrompt;
|
return this.SystemPrompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryParseChatTemplateTable(int idx, LuaTable table, Guid configPluginId, out ConfigurationBaseObject template)
|
||||||
|
{
|
||||||
|
template = NO_CHAT_TEMPLATE;
|
||||||
|
if (!table.TryGetValue("Id", out var idValue) || !idValue.TryRead<string>(out var idText) || !Guid.TryParse(idText, out var id))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid ID. The ID must be a valid GUID.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("Name", out var nameValue) || !nameValue.TryRead<string>(out var name))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.TryGetValue("SystemPrompt", out var sysPromptValue) || !sysPromptValue.TryRead<string>(out var systemPrompt))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid system prompt.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var predefinedUserPrompt = string.Empty;
|
||||||
|
if (table.TryGetValue("PredefinedUserPrompt", out var preUserValue) && preUserValue.TryRead<string>(out var preUser))
|
||||||
|
predefinedUserPrompt = preUser;
|
||||||
|
|
||||||
|
var allowProfileUsage = false;
|
||||||
|
if (table.TryGetValue("AllowProfileUsage", out var allowProfileValue) && allowProfileValue.TryRead<bool>(out var allow))
|
||||||
|
allowProfileUsage = allow;
|
||||||
|
|
||||||
|
template = new ChatTemplate
|
||||||
|
{
|
||||||
|
Num = 0,
|
||||||
|
Id = id.ToString(),
|
||||||
|
Name = name,
|
||||||
|
SystemPrompt = systemPrompt,
|
||||||
|
PredefinedUserPrompt = predefinedUserPrompt,
|
||||||
|
ExampleConversation = ParseExampleConversation(idx, table),
|
||||||
|
AllowProfileUsage = allowProfileUsage,
|
||||||
|
IsEnterpriseConfiguration = true,
|
||||||
|
EnterpriseConfigurationPluginId = configPluginId,
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<ContentBlock> ParseExampleConversation(int idx, LuaTable table)
|
||||||
|
{
|
||||||
|
var exampleConversation = new List<ContentBlock>();
|
||||||
|
if (!table.TryGetValue("ExampleConversation", out var exConvValue) || !exConvValue.TryRead<LuaTable>(out var exConvTable))
|
||||||
|
return exampleConversation;
|
||||||
|
|
||||||
|
var numBlocks = exConvTable.ArrayLength;
|
||||||
|
for (var j = 1; j <= numBlocks; j++)
|
||||||
|
{
|
||||||
|
var blockValue = exConvTable[j];
|
||||||
|
if (!blockValue.TryRead<LuaTable>(out var blockTable))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} is not a valid table.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blockTable.TryGetValue("Role", out var roleValue) || !roleValue.TryRead<string>(out var roleText) || !Enum.TryParse<ChatRole>(roleText, true, out var parsedRole))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} does not contain a valid role.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blockTable.TryGetValue("Content", out var contentValue) || !contentValue.TryRead<string>(out var content))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} does not contain a valid content message.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(content))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} contains an empty content message.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
exampleConversation.Add(new ContentBlock
|
||||||
|
{
|
||||||
|
Time = DateTimeOffset.UtcNow,
|
||||||
|
Role = parsedRole,
|
||||||
|
Content = new ContentText { Text = content },
|
||||||
|
ContentType = ContentType.TEXT,
|
||||||
|
HideFromUser = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return exampleConversation;
|
||||||
|
}
|
||||||
}
|
}
|
@ -63,13 +63,19 @@ public static class ConfigurationSelectDataFactory
|
|||||||
yield return new(TB("Enter is sending the input"), SendBehavior.ENTER_IS_SENDING);
|
yield return new(TB("Enter is sending the input"), SendBehavior.ENTER_IS_SENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<ConfigurationSelectData<UpdateBehavior>> GetUpdateBehaviorData()
|
public static IEnumerable<ConfigurationSelectData<UpdateInterval>> GetUpdateIntervalData()
|
||||||
{
|
{
|
||||||
yield return new(TB("No automatic update checks"), UpdateBehavior.NO_CHECK);
|
yield return new(TB("No automatic update checks"), UpdateInterval.NO_CHECK);
|
||||||
yield return new(TB("Once at startup"), UpdateBehavior.ONCE_STARTUP);
|
yield return new(TB("Once at startup"), UpdateInterval.ONCE_STARTUP);
|
||||||
yield return new(TB("Check every hour"), UpdateBehavior.HOURLY);
|
yield return new(TB("Check every hour"), UpdateInterval.HOURLY);
|
||||||
yield return new(TB("Check every day"), UpdateBehavior.DAILY);
|
yield return new(TB("Check every day"), UpdateInterval.DAILY);
|
||||||
yield return new (TB("Check every week"), UpdateBehavior.WEEKLY);
|
yield return new (TB("Check every week"), UpdateInterval.WEEKLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ConfigurationSelectData<UpdateInstallation>> GetUpdateBehaviourData()
|
||||||
|
{
|
||||||
|
yield return new(TB("Install updates manually"), UpdateInstallation.MANUAL);
|
||||||
|
yield return new(TB("Install updates automatically"), UpdateInstallation.AUTOMATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<ConfigurationSelectData<WorkspaceStorageBehavior>> GetWorkspaceStorageBehaviorData()
|
public static IEnumerable<ConfigurationSelectData<WorkspaceStorageBehavior>> GetWorkspaceStorageBehaviorData()
|
||||||
|
@ -40,7 +40,12 @@ public sealed class DataApp(Expression<Func<Data, DataApp>>? configSelection = n
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If and when we should look for updates.
|
/// If and when we should look for updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UpdateBehavior UpdateBehavior { get; set; } = ManagedConfiguration.Register(configSelection, n => n.UpdateBehavior, UpdateBehavior.HOURLY);
|
public UpdateInterval UpdateInterval { get; set; } = ManagedConfiguration.Register(configSelection, n => n.UpdateInterval, UpdateInterval.HOURLY);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How updates should be installed.
|
||||||
|
/// </summary>
|
||||||
|
public UpdateInstallation UpdateInstallation { get; set; } = ManagedConfiguration.Register(configSelection, n => n.UpdateInstallation, UpdateInstallation.MANUAL);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The navigation behavior.
|
/// The navigation behavior.
|
||||||
|
@ -41,7 +41,7 @@ public sealed class DataV1V3
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If and when we should look for updates.
|
/// If and when we should look for updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP;
|
public UpdateInterval UpdateInterval { get; set; } = UpdateInterval.ONCE_STARTUP;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The navigation behavior.
|
/// The navigation behavior.
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum UpdateInstallation
|
||||||
|
{
|
||||||
|
MANUAL,
|
||||||
|
AUTOMATIC,
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
namespace AIStudio.Settings.DataModel;
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
public enum UpdateBehavior
|
public enum UpdateInterval
|
||||||
{
|
{
|
||||||
NO_CHECK,
|
NO_CHECK,
|
||||||
ONCE_STARTUP,
|
ONCE_STARTUP,
|
@ -1,26 +0,0 @@
|
|||||||
using System.Linq.Expressions;
|
|
||||||
|
|
||||||
namespace AIStudio.Settings;
|
|
||||||
|
|
||||||
public static class ExpressionExtensions
|
|
||||||
{
|
|
||||||
private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(typeof(ExpressionExtensions));
|
|
||||||
|
|
||||||
public static MemberExpression GetMemberExpression<TIn, TOut>(this Expression<Func<TIn, TOut>> expression)
|
|
||||||
{
|
|
||||||
switch (expression.Body)
|
|
||||||
{
|
|
||||||
// Case for value types, which are wrapped in UnaryExpression:
|
|
||||||
case UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression:
|
|
||||||
return (MemberExpression)unaryExpression.Operand;
|
|
||||||
|
|
||||||
// Case for reference types, which are directly MemberExpressions:
|
|
||||||
case MemberExpression memberExpression:
|
|
||||||
return memberExpression;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOGGER.LogError($"Expression '{expression}' is not a valid property expression.");
|
|
||||||
throw new ArgumentException($"Expression '{expression}' is not a valid property expression.", nameof(expression));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,10 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
using AIStudio.Provider.HuggingFace;
|
using AIStudio.Provider.HuggingFace;
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
using Lua;
|
||||||
|
|
||||||
using Host = AIStudio.Provider.SelfHosted.Host;
|
using Host = AIStudio.Provider.SelfHosted.Host;
|
||||||
|
|
||||||
namespace AIStudio.Settings;
|
namespace AIStudio.Settings;
|
||||||
@ -16,7 +20,7 @@ namespace AIStudio.Settings;
|
|||||||
/// <param name="IsSelfHosted">Whether the provider is self-hosted.</param>
|
/// <param name="IsSelfHosted">Whether the provider is self-hosted.</param>
|
||||||
/// <param name="Hostname">The hostname of the provider. Useful for self-hosted providers.</param>
|
/// <param name="Hostname">The hostname of the provider. Useful for self-hosted providers.</param>
|
||||||
/// <param name="Model">The LLM model to use for chat.</param>
|
/// <param name="Model">The LLM model to use for chat.</param>
|
||||||
public readonly record struct Provider(
|
public sealed record Provider(
|
||||||
uint Num,
|
uint Num,
|
||||||
string Id,
|
string Id,
|
||||||
string InstanceName,
|
string InstanceName,
|
||||||
@ -27,8 +31,24 @@ public readonly record struct Provider(
|
|||||||
Guid EnterpriseConfigurationPluginId = default,
|
Guid EnterpriseConfigurationPluginId = default,
|
||||||
string Hostname = "http://localhost:1234",
|
string Hostname = "http://localhost:1234",
|
||||||
Host Host = Host.NONE,
|
Host Host = Host.NONE,
|
||||||
HFInferenceProvider HFInferenceProvider = HFInferenceProvider.NONE) : ISecretId
|
HFInferenceProvider HFInferenceProvider = HFInferenceProvider.NONE) : ConfigurationBaseObject, ISecretId
|
||||||
{
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#region Overrides of ValueType
|
#region Overrides of ValueType
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -57,4 +77,95 @@ public readonly record struct Provider(
|
|||||||
public string SecretName => this.InstanceName;
|
public string SecretName => this.InstanceName;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -215,18 +215,18 @@ public sealed class SettingsManager
|
|||||||
return this.ConfigurationData.Providers[0];
|
return this.ConfigurationData.Providers[0];
|
||||||
|
|
||||||
// Is there a current provider with a sufficiently high confidence level?
|
// Is there a current provider with a sufficiently high confidence level?
|
||||||
Provider currentProvider = default;
|
var currentProvider = Provider.NONE;
|
||||||
if (currentProviderId is not null && !string.IsNullOrWhiteSpace(currentProviderId))
|
if (currentProviderId is not null && !string.IsNullOrWhiteSpace(currentProviderId))
|
||||||
{
|
{
|
||||||
var currentProviderProbe = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == currentProviderId);
|
var currentProviderProbe = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == currentProviderId);
|
||||||
if (currentProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
if (currentProviderProbe is not null && currentProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||||
currentProvider = currentProviderProbe;
|
currentProvider = currentProviderProbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there a component-preselected provider with a sufficiently high confidence level?
|
// Is there a component-preselected provider with a sufficiently high confidence level?
|
||||||
Provider preselectedProvider = default;
|
var preselectedProvider = Provider.NONE;
|
||||||
var preselectedProviderProbe = component.PreselectedProvider(this);
|
var preselectedProviderProbe = component.PreselectedProvider(this);
|
||||||
if(preselectedProviderProbe != default && preselectedProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
if(preselectedProviderProbe != Provider.NONE && preselectedProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||||
preselectedProvider = preselectedProviderProbe;
|
preselectedProvider = preselectedProviderProbe;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -234,14 +234,14 @@ public sealed class SettingsManager
|
|||||||
// and the preselected provider is available and has a confidence level
|
// and the preselected provider is available and has a confidence level
|
||||||
// that is high enough.
|
// that is high enough.
|
||||||
//
|
//
|
||||||
if(usePreselectionBeforeCurrentProvider && preselectedProvider != default)
|
if(usePreselectionBeforeCurrentProvider && preselectedProvider != Provider.NONE)
|
||||||
return preselectedProvider;
|
return preselectedProvider;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Case: The current provider is available and has a confidence level that is
|
// Case: The current provider is available and has a confidence level that is
|
||||||
// high enough.
|
// high enough.
|
||||||
//
|
//
|
||||||
if(currentProvider != default)
|
if(currentProvider != Provider.NONE)
|
||||||
return currentProvider;
|
return currentProvider;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -250,11 +250,11 @@ public sealed class SettingsManager
|
|||||||
// level that is high enough. The preselected provider is available and
|
// level that is high enough. The preselected provider is available and
|
||||||
// has a confidence level that is high enough.
|
// has a confidence level that is high enough.
|
||||||
//
|
//
|
||||||
if(preselectedProvider != default)
|
if(preselectedProvider != Provider.NONE)
|
||||||
return preselectedProvider;
|
return preselectedProvider;
|
||||||
|
|
||||||
// When there is an app-wide preselected provider, and it has a confidence level that is high enough, we return it:
|
// When there is an app-wide preselected provider, and it has a confidence level that is high enough, we return it:
|
||||||
return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider && x.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel);
|
return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider && x.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel) ?? Provider.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Profile GetPreselectedProfile(Tools.Components component)
|
public Profile GetPreselectedProfile(Tools.Components component)
|
||||||
|
@ -90,7 +90,7 @@ public static class SettingsMigrations
|
|||||||
IsSavingEnergy = previousData.IsSavingEnergy,
|
IsSavingEnergy = previousData.IsSavingEnergy,
|
||||||
NextProviderNum = previousData.NextProviderNum,
|
NextProviderNum = previousData.NextProviderNum,
|
||||||
ShortcutSendBehavior = previousData.ShortcutSendBehavior,
|
ShortcutSendBehavior = previousData.ShortcutSendBehavior,
|
||||||
UpdateBehavior = previousData.UpdateBehavior,
|
UpdateInterval = previousData.UpdateInterval,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public static class SettingsMigrations
|
|||||||
IsSavingEnergy = previousData.IsSavingEnergy,
|
IsSavingEnergy = previousData.IsSavingEnergy,
|
||||||
NextProviderNum = previousData.NextProviderNum,
|
NextProviderNum = previousData.NextProviderNum,
|
||||||
ShortcutSendBehavior = previousData.ShortcutSendBehavior,
|
ShortcutSendBehavior = previousData.ShortcutSendBehavior,
|
||||||
UpdateBehavior = previousData.UpdateBehavior,
|
UpdateInterval = previousData.UpdateInterval,
|
||||||
WorkspaceStorageBehavior = previousData.WorkspaceStorageBehavior,
|
WorkspaceStorageBehavior = previousData.WorkspaceStorageBehavior,
|
||||||
WorkspaceStorageTemporaryMaintenancePolicy = previousData.WorkspaceStorageTemporaryMaintenancePolicy,
|
WorkspaceStorageTemporaryMaintenancePolicy = previousData.WorkspaceStorageTemporaryMaintenancePolicy,
|
||||||
};
|
};
|
||||||
@ -141,7 +141,7 @@ public static class SettingsMigrations
|
|||||||
{
|
{
|
||||||
EnableSpellchecking = previousConfig.EnableSpellchecking,
|
EnableSpellchecking = previousConfig.EnableSpellchecking,
|
||||||
IsSavingEnergy = previousConfig.IsSavingEnergy,
|
IsSavingEnergy = previousConfig.IsSavingEnergy,
|
||||||
UpdateBehavior = previousConfig.UpdateBehavior,
|
UpdateInterval = previousConfig.UpdateInterval,
|
||||||
NavigationBehavior = previousConfig.NavigationBehavior,
|
NavigationBehavior = previousConfig.NavigationBehavior,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -89,32 +89,37 @@ public static class ComponentsExtensions
|
|||||||
};
|
};
|
||||||
|
|
||||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||||
public static AIStudio.Settings.Provider PreselectedProvider(this Components component, SettingsManager settingsManager) => component switch
|
public static AIStudio.Settings.Provider PreselectedProvider(this Components component, SettingsManager settingsManager)
|
||||||
{
|
{
|
||||||
Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider) : default,
|
var preselectedProvider = component switch
|
||||||
Components.ICON_FINDER_ASSISTANT => settingsManager.ConfigurationData.IconFinder.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.IconFinder.PreselectedProvider) : default,
|
{
|
||||||
Components.REWRITE_ASSISTANT => settingsManager.ConfigurationData.RewriteImprove.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.RewriteImprove.PreselectedProvider) : default,
|
Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider) : null,
|
||||||
Components.TRANSLATION_ASSISTANT => settingsManager.ConfigurationData.Translation.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Translation.PreselectedProvider) : default,
|
Components.ICON_FINDER_ASSISTANT => settingsManager.ConfigurationData.IconFinder.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.IconFinder.PreselectedProvider) : null,
|
||||||
Components.AGENDA_ASSISTANT => settingsManager.ConfigurationData.Agenda.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Agenda.PreselectedProvider) : default,
|
Components.REWRITE_ASSISTANT => settingsManager.ConfigurationData.RewriteImprove.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.RewriteImprove.PreselectedProvider) : null,
|
||||||
Components.CODING_ASSISTANT => settingsManager.ConfigurationData.Coding.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Coding.PreselectedProvider) : default,
|
Components.TRANSLATION_ASSISTANT => settingsManager.ConfigurationData.Translation.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Translation.PreselectedProvider) : null,
|
||||||
Components.TEXT_SUMMARIZER_ASSISTANT => settingsManager.ConfigurationData.TextSummarizer.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.TextSummarizer.PreselectedProvider) : default,
|
Components.AGENDA_ASSISTANT => settingsManager.ConfigurationData.Agenda.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Agenda.PreselectedProvider) : null,
|
||||||
Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.EMail.PreselectedProvider) : default,
|
Components.CODING_ASSISTANT => settingsManager.ConfigurationData.Coding.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Coding.PreselectedProvider) : null,
|
||||||
Components.LEGAL_CHECK_ASSISTANT => settingsManager.ConfigurationData.LegalCheck.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.LegalCheck.PreselectedProvider) : default,
|
Components.TEXT_SUMMARIZER_ASSISTANT => settingsManager.ConfigurationData.TextSummarizer.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.TextSummarizer.PreselectedProvider) : null,
|
||||||
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Synonyms.PreselectedProvider) : default,
|
Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.EMail.PreselectedProvider) : null,
|
||||||
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProvider) : default,
|
Components.LEGAL_CHECK_ASSISTANT => settingsManager.ConfigurationData.LegalCheck.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.LegalCheck.PreselectedProvider) : null,
|
||||||
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.JobPostings.PreselectedProvider) : default,
|
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Synonyms.PreselectedProvider) : null,
|
||||||
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider) : default,
|
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.MyTasks.PreselectedProvider) : null,
|
||||||
Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.ERI.PreselectedProvider) : default,
|
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.JobPostings.PreselectedProvider) : null,
|
||||||
Components.I18N_ASSISTANT => settingsManager.ConfigurationData.I18N.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.I18N.PreselectedProvider) : default,
|
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider) : null,
|
||||||
|
Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.ERI.PreselectedProvider) : null,
|
||||||
|
Components.I18N_ASSISTANT => settingsManager.ConfigurationData.I18N.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.I18N.PreselectedProvider) : null,
|
||||||
|
|
||||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : default,
|
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedProvider) : null,
|
||||||
|
|
||||||
|
Components.AGENT_TEXT_CONTENT_CLEANER => settingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider) : null,
|
||||||
|
Components.AGENT_DATA_SOURCE_SELECTION => settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider) : null,
|
||||||
|
Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION => settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider) : null,
|
||||||
|
|
||||||
|
_ => Settings.Provider.NONE,
|
||||||
|
};
|
||||||
|
|
||||||
Components.AGENT_TEXT_CONTENT_CLEANER => settingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider) : default,
|
return preselectedProvider ?? Settings.Provider.NONE;
|
||||||
Components.AGENT_DATA_SOURCE_SELECTION => settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider) : default,
|
}
|
||||||
Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION => settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider) : default,
|
|
||||||
|
|
||||||
_ => default,
|
|
||||||
};
|
|
||||||
|
|
||||||
public static Profile PreselectedProfile(this Components component, SettingsManager settingsManager) => component switch
|
public static Profile PreselectedProfile(this Components component, SettingsManager settingsManager) => component switch
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ public enum Event
|
|||||||
// Update events:
|
// Update events:
|
||||||
USER_SEARCH_FOR_UPDATE,
|
USER_SEARCH_FOR_UPDATE,
|
||||||
UPDATE_AVAILABLE,
|
UPDATE_AVAILABLE,
|
||||||
|
INSTALL_UPDATE,
|
||||||
|
|
||||||
// Chat events:
|
// Chat events:
|
||||||
HAS_CHAT_UNSAVED_CHANGES,
|
HAS_CHAT_UNSAVED_CHANGES,
|
||||||
|
96
app/MindWork AI Studio/Tools/ExpressionExtensions.cs
Normal file
96
app/MindWork AI Studio/Tools/ExpressionExtensions.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public static class ExpressionExtensions
|
||||||
|
{
|
||||||
|
private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(typeof(ExpressionExtensions));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts the member expression from a given lambda expression representing a property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="expression">A lambda expression specifying the property for which the member expression is to be extracted.
|
||||||
|
/// The lambda expression body must represent member access.</param>
|
||||||
|
/// <typeparam name="TIn">The type of the object containing the property referenced in the lambda expression.</typeparam>
|
||||||
|
/// <typeparam name="TOut">The type of the property being accessed in the lambda expression.</typeparam>
|
||||||
|
/// <returns>The member expression that represents the property access.</returns>
|
||||||
|
/// <exception cref="ArgumentException">Thrown if the provided lambda expression does not represent a valid property expression.</exception>
|
||||||
|
public static MemberExpression GetMemberExpression<TIn, TOut>(this Expression<Func<TIn, TOut>> expression)
|
||||||
|
{
|
||||||
|
switch (expression.Body)
|
||||||
|
{
|
||||||
|
// Case for value types, which are wrapped in UnaryExpression:
|
||||||
|
case UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression:
|
||||||
|
return (MemberExpression)unaryExpression.Operand;
|
||||||
|
|
||||||
|
// Case for reference types, which are directly MemberExpressions:
|
||||||
|
case MemberExpression memberExpression:
|
||||||
|
return memberExpression;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOGGER.LogError($"Expression '{expression}' is not a valid property expression.");
|
||||||
|
throw new ArgumentException($"Expression '{expression}' is not a valid property expression.", nameof(expression));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to increment the value of an uint property for a specified object using a
|
||||||
|
/// provided expression.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="expression">An expression representing the property to be incremented. The property
|
||||||
|
/// must be of type uint and belong to the provided object.</param>
|
||||||
|
/// <param name="data">The object that contains the property referenced by the expression.</param>
|
||||||
|
/// <param name="type">The type of increment operation to perform (e.g., prefix or postfix).</param>
|
||||||
|
/// <typeparam name="TIn">The type of the object that contains the property to be incremented.</typeparam>
|
||||||
|
/// <typeparam name="TOut">The type of the property to be incremented.</typeparam>
|
||||||
|
/// <returns>An IncrementResult object containing the result of the increment operation.</returns>
|
||||||
|
public static IncrementResult<TOut> TryIncrement<TIn, TOut>(this Expression<Func<TIn, TOut>> expression, TIn data, IncrementType type) where TOut : IBinaryInteger<TOut>
|
||||||
|
{
|
||||||
|
// Ensure that the expression body is a member expression:
|
||||||
|
if (expression.Body is not MemberExpression memberExpression)
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
|
||||||
|
// Ensure that the member expression is a property:
|
||||||
|
if (memberExpression.Member is not PropertyInfo propertyInfo)
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
|
||||||
|
// Ensure that the member expression has a target object:
|
||||||
|
if (memberExpression.Expression is null)
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
|
||||||
|
// Get the target object for the expression, which is the object containing the property to increment:
|
||||||
|
var targetObjectExpression = Expression.Lambda(memberExpression.Expression, expression.Parameters);
|
||||||
|
|
||||||
|
// Compile the lambda expression to get the target object
|
||||||
|
// (which is the object containing the property to increment):
|
||||||
|
var targetObject = targetObjectExpression.Compile().DynamicInvoke(data);
|
||||||
|
|
||||||
|
// Was the compilation successful?
|
||||||
|
if (targetObject is null)
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
|
||||||
|
// Read the current value of the property:
|
||||||
|
if (propertyInfo.GetValue(targetObject) is not TOut value)
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
|
||||||
|
// Increment the value:
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IncrementType.PRE:
|
||||||
|
var nextValue = value + TOut.CreateChecked(1);
|
||||||
|
propertyInfo.SetValue(targetObject, nextValue);
|
||||||
|
return new(true, nextValue);
|
||||||
|
|
||||||
|
case IncrementType.POST:
|
||||||
|
var currentValue = value;
|
||||||
|
var incrementedValue = value + TOut.CreateChecked(1);
|
||||||
|
propertyInfo.SetValue(targetObject, incrementedValue);
|
||||||
|
return new(true, currentValue);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return new(false, TOut.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
app/MindWork AI Studio/Tools/IncrementResult.cs
Normal file
10
app/MindWork AI Studio/Tools/IncrementResult.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the result of an increment operation. It encapsulates whether the operation
|
||||||
|
/// was successful and the increased value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TOut">The type of the incremented value, constrained to implement the IBinaryInteger interface.</typeparam>
|
||||||
|
public sealed record IncrementResult<TOut>(bool Success, TOut UpdatedValue) where TOut : IBinaryInteger<TOut>;
|
14
app/MindWork AI Studio/Tools/IncrementType.cs
Normal file
14
app/MindWork AI Studio/Tools/IncrementType.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
|
public enum IncrementType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the value before returning it. So, the incremented value is returned.
|
||||||
|
/// </summary>
|
||||||
|
PRE,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the value after returning it. So, the original value is returned.
|
||||||
|
/// </summary>
|
||||||
|
POST,
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
namespace AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
public abstract record ConfigurationBaseObject : IConfigurationObject
|
||||||
|
{
|
||||||
|
#region Implementation of IConfigurationObject
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract string Id { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract uint Num { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract string Name { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract Guid EnterpriseConfigurationPluginId { get; init; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
namespace AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a configuration object, such as a chat template or a LLM provider.
|
||||||
|
/// </summary>
|
||||||
|
public interface IConfigurationObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The unique ID of the configuration object.
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The continuous number of the configuration object.
|
||||||
|
/// </summary>
|
||||||
|
public uint Num { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the configuration object.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this configuration object an enterprise configuration?
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEnterpriseConfiguration { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the enterprise configuration plugin.
|
||||||
|
/// </summary>
|
||||||
|
public Guid EnterpriseConfigurationPluginId { get; }
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
namespace AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
|
public sealed record NoConfigurationObject : ConfigurationBaseObject
|
||||||
|
{
|
||||||
|
public static readonly NoConfigurationObject INSTANCE = new();
|
||||||
|
|
||||||
|
private NoConfigurationObject()
|
||||||
|
{
|
||||||
|
this.Id = Guid.Empty.ToString();
|
||||||
|
this.Name = "No Configuration";
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of ConfigurationBaseObject
|
||||||
|
|
||||||
|
public override string Id { get; init; }
|
||||||
|
|
||||||
|
public override uint Num { get; init; }
|
||||||
|
|
||||||
|
public override string Name { get; init; }
|
||||||
|
|
||||||
|
public override bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
|
public override Guid EnterpriseConfigurationPluginId { get; init; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -1,21 +1,15 @@
|
|||||||
using AIStudio.Provider;
|
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Chat;
|
|
||||||
|
|
||||||
using Lua;
|
using Lua;
|
||||||
|
|
||||||
using Host = AIStudio.Provider.SelfHosted.Host;
|
|
||||||
using Model = AIStudio.Provider.Model;
|
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem;
|
namespace AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginType type) : PluginBase(isInternal, state, type)
|
public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginType type) : PluginBase(isInternal, state, type)
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PluginConfiguration).Namespace, nameof(PluginConfiguration));
|
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PluginConfiguration).Namespace, nameof(PluginConfiguration));
|
||||||
private static readonly ILogger<PluginConfiguration> LOGGER = Program.LOGGER_FACTORY.CreateLogger<PluginConfiguration>();
|
|
||||||
private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
|
private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
|
||||||
|
|
||||||
private readonly List<PluginConfigurationObject> configObjects = [];
|
private List<PluginConfigurationObject> configObjects = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of configuration objects. Configuration objects are, e.g., providers or chat templates.
|
/// The list of configuration objects. Configuration objects are, e.g., providers or chat templates.
|
||||||
@ -51,317 +45,37 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Check for the main SETTINGS table:
|
||||||
// ===========================================
|
|
||||||
// Configured settings
|
|
||||||
// ===========================================
|
|
||||||
//
|
|
||||||
if (!mainTable.TryGetValue("SETTINGS", out var settingsValue) || !settingsValue.TryRead<LuaTable>(out var settingsTable))
|
if (!mainTable.TryGetValue("SETTINGS", out var settingsValue) || !settingsValue.TryRead<LuaTable>(out var settingsTable))
|
||||||
{
|
{
|
||||||
message = TB("The SETTINGS table does not exist or is not a valid table.");
|
message = TB("The SETTINGS table does not exist or is not a valid table.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for updates, and if so, how often?
|
// Config: check for updates, and if so, how often?
|
||||||
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.UpdateBehavior, this.Id, settingsTable, dryRun);
|
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.UpdateInterval, this.Id, settingsTable, dryRun);
|
||||||
|
|
||||||
// Allow the user to add providers?
|
// Config: how should updates be installed?
|
||||||
|
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.UpdateInstallation, this.Id, settingsTable, dryRun);
|
||||||
|
|
||||||
|
// Config: allow the user to add providers?
|
||||||
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.AllowUserToAddProvider, this.Id, settingsTable, dryRun);
|
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.AllowUserToAddProvider, this.Id, settingsTable, dryRun);
|
||||||
|
|
||||||
//
|
// Handle configured LLM providers:
|
||||||
// Configured providers:
|
if (!PluginConfigurationObject.TryParse(PluginConfigurationObjectType.LLM_PROVIDER, x => x.Providers, x => x.NextProviderNum, mainTable, this.Id, ref this.configObjects, dryRun))
|
||||||
//
|
|
||||||
if (!mainTable.TryGetValue("LLM_PROVIDERS", out var providersValue) || !providersValue.TryRead<LuaTable>(out var providersTable))
|
|
||||||
{
|
{
|
||||||
message = TB("The LLM_PROVIDERS table does not exist or is not a valid table.");
|
message = TB("At least one configured LLM provider is not valid or could not be parsed, or the LLM_PROVIDERS table does not exist.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle configured chat templates:
|
||||||
|
if (!PluginConfigurationObject.TryParse(PluginConfigurationObjectType.CHAT_TEMPLATE, x => x.ChatTemplates, x => x.NextChatTemplateNum, mainTable, this.Id, ref this.configObjects, dryRun))
|
||||||
|
{
|
||||||
|
message = TB("At least one configured chat template is not valid or could not be parsed, or the CHAT_TEMPLATES table does not exist.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
message = string.Empty;
|
message = string.Empty;
|
||||||
var numberProviders = providersTable.ArrayLength;
|
|
||||||
var configuredProviders = new List<Settings.Provider>(numberProviders);
|
|
||||||
for (var i = 1; i <= numberProviders; i++)
|
|
||||||
{
|
|
||||||
var providerLuaTableValue = providersTable[i];
|
|
||||||
if (!providerLuaTableValue.TryRead<LuaTable>(out var providerLuaTable))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The LLM_PROVIDERS table at index {i} is not a valid table.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.TryReadProviderTable(i, providerLuaTable, out var provider))
|
|
||||||
configuredProviders.Add(provider);
|
|
||||||
else
|
|
||||||
LOGGER.LogWarning($"The LLM_PROVIDERS table at index {i} does not contain a valid provider configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Apply the configured providers to the system settings:
|
|
||||||
//
|
|
||||||
#pragma warning disable MWAIS0001
|
|
||||||
foreach (var configuredProvider in configuredProviders)
|
|
||||||
{
|
|
||||||
// The iterating variable is immutable, so we need to create a local copy:
|
|
||||||
var provider = configuredProvider;
|
|
||||||
|
|
||||||
// Store this provider in the config object list:
|
|
||||||
this.configObjects.Add(new()
|
|
||||||
{
|
|
||||||
ConfigPluginId = this.Id,
|
|
||||||
Id = Guid.Parse(provider.Id),
|
|
||||||
Type = PluginConfigurationObjectType.LLM_PROVIDER,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (dryRun)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var providerIndex = SETTINGS_MANAGER.ConfigurationData.Providers.FindIndex(p => p.Id == provider.Id);
|
|
||||||
if (providerIndex > -1)
|
|
||||||
{
|
|
||||||
// Case: The provider already exists, we update it:
|
|
||||||
var existingProvider = SETTINGS_MANAGER.ConfigurationData.Providers[providerIndex];
|
|
||||||
provider = provider with { Num = existingProvider.Num }; // Keep the original number
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.Providers[providerIndex] = provider;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Case: The provider does not exist, we add it:
|
|
||||||
provider = provider with { Num = SETTINGS_MANAGER.ConfigurationData.NextProviderNum++ };
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.Providers.Add(provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning restore MWAIS0001
|
|
||||||
|
|
||||||
//
|
|
||||||
// Configured chat templates:
|
|
||||||
//
|
|
||||||
if (mainTable.TryGetValue("CHAT_TEMPLATES", out var templatesValue) && templatesValue.TryRead<LuaTable>(out var templatesTable))
|
|
||||||
{
|
|
||||||
var numberTemplates = templatesTable.ArrayLength;
|
|
||||||
var configuredTemplates = new List<ChatTemplate>(numberTemplates);
|
|
||||||
for (var i = 1; i <= numberTemplates; i++)
|
|
||||||
{
|
|
||||||
var templateLuaTableValue = templatesTable[i];
|
|
||||||
if (!templateLuaTableValue.TryRead<LuaTable>(out var templateLuaTable))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The CHAT_TEMPLATES table at index {i} is not a valid table.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.TryReadChatTemplateTable(i, templateLuaTable, out var template) && template != ChatTemplate.NO_CHAT_TEMPLATE)
|
|
||||||
configuredTemplates.Add(template);
|
|
||||||
else
|
|
||||||
LOGGER.LogWarning($"The CHAT_TEMPLATES table at index {i} does not contain a valid chat template configuration.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply configured chat templates to the system settings:
|
|
||||||
foreach (var configuredTemplate in configuredTemplates)
|
|
||||||
{
|
|
||||||
// The iterating variable is immutable, so we need to create a local copy:
|
|
||||||
var template = configuredTemplate;
|
|
||||||
|
|
||||||
// Store this provider in the config object list:
|
|
||||||
this.configObjects.Add(new()
|
|
||||||
{
|
|
||||||
ConfigPluginId = this.Id,
|
|
||||||
Id = Guid.Parse(template.Id),
|
|
||||||
Type = PluginConfigurationObjectType.CHAT_TEMPLATE,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (dryRun)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var tplIndex = SETTINGS_MANAGER.ConfigurationData.ChatTemplates.FindIndex(t => t.Id == template.Id);
|
|
||||||
if (tplIndex > -1)
|
|
||||||
{
|
|
||||||
// Case: The template already exists, we update it:
|
|
||||||
var existingTemplate = SETTINGS_MANAGER.ConfigurationData.ChatTemplates[tplIndex];
|
|
||||||
template = template with { Num = existingTemplate.Num };
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates[tplIndex] = template;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Case: The template does not exist, we add it:
|
|
||||||
template = template with { Num = SETTINGS_MANAGER.ConfigurationData.NextChatTemplateNum++ };
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates.Add(template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryReadProviderTable(int idx, LuaTable table, out Settings.Provider provider)
|
|
||||||
{
|
|
||||||
provider = default;
|
|
||||||
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 (!this.TryReadModelTable(idx, modelTable, out var model))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The configured provider {idx} does not contain a valid model configuration.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
provider = new()
|
|
||||||
{
|
|
||||||
Num = 0,
|
|
||||||
Id = id.ToString(),
|
|
||||||
InstanceName = instanceName,
|
|
||||||
UsedLLMProvider = usedLLMProvider,
|
|
||||||
Model = model,
|
|
||||||
IsSelfHosted = usedLLMProvider is LLMProviders.SELF_HOSTED,
|
|
||||||
IsEnterpriseConfiguration = true,
|
|
||||||
EnterpriseConfigurationPluginId = this.Id,
|
|
||||||
Hostname = hostname,
|
|
||||||
Host = host
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryReadChatTemplateTable(int idx, LuaTable table, out ChatTemplate template)
|
|
||||||
{
|
|
||||||
template = ChatTemplate.NO_CHAT_TEMPLATE;
|
|
||||||
if (!table.TryGetValue("Id", out var idValue) || !idValue.TryRead<string>(out var idText) || !Guid.TryParse(idText, out var id))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid ID. The ID must be a valid GUID.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!table.TryGetValue("Name", out var nameValue) || !nameValue.TryRead<string>(out var name))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid name.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!table.TryGetValue("SystemPrompt", out var sysPromptValue) || !sysPromptValue.TryRead<string>(out var systemPrompt))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The configured chat template {idx} does not contain a valid system prompt.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var predefinedUserPrompt = string.Empty;
|
|
||||||
if (table.TryGetValue("PredefinedUserPrompt", out var preUserValue) && preUserValue.TryRead<string>(out var preUser))
|
|
||||||
predefinedUserPrompt = preUser;
|
|
||||||
|
|
||||||
var allowProfileUsage = false;
|
|
||||||
if (table.TryGetValue("AllowProfileUsage", out var allowProfileValue) && allowProfileValue.TryRead<bool>(out var allow))
|
|
||||||
allowProfileUsage = allow;
|
|
||||||
|
|
||||||
template = new()
|
|
||||||
{
|
|
||||||
Num = 0,
|
|
||||||
Id = id.ToString(),
|
|
||||||
Name = name,
|
|
||||||
SystemPrompt = systemPrompt,
|
|
||||||
PredefinedUserPrompt = predefinedUserPrompt,
|
|
||||||
ExampleConversation = ParseExampleConversation(idx, table),
|
|
||||||
AllowProfileUsage = allowProfileUsage,
|
|
||||||
IsEnterpriseConfiguration = true,
|
|
||||||
EnterpriseConfigurationPluginId = this.Id
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<ContentBlock> ParseExampleConversation(int idx, LuaTable table)
|
|
||||||
{
|
|
||||||
var exampleConversation = new List<ContentBlock>();
|
|
||||||
if (!table.TryGetValue("ExampleConversation", out var exConvValue) || !exConvValue.TryRead<LuaTable>(out var exConvTable))
|
|
||||||
return exampleConversation;
|
|
||||||
|
|
||||||
var numBlocks = exConvTable.ArrayLength;
|
|
||||||
for (var j = 1; j <= numBlocks; j++)
|
|
||||||
{
|
|
||||||
var blockValue = exConvTable[j];
|
|
||||||
if (!blockValue.TryRead<LuaTable>(out var blockTable))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} is not a valid table.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blockTable.TryGetValue("Role", out var roleValue) || !roleValue.TryRead<string>(out var roleText) || !Enum.TryParse<ChatRole>(roleText, true, out var parsedRole))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} does not contain a valid role.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blockTable.TryGetValue("Content", out var contentValue) || !contentValue.TryRead<string>(out var content))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} does not contain a valid content message.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(content))
|
|
||||||
{
|
|
||||||
LOGGER.LogWarning($"The ExampleConversation entry {j} in chat template {idx} contains an empty content message.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
exampleConversation.Add(new ContentBlock
|
|
||||||
{
|
|
||||||
Time = DateTimeOffset.UtcNow,
|
|
||||||
Role = parsedRole,
|
|
||||||
Content = new ContentText { Text = content },
|
|
||||||
ContentType = ContentType.TEXT,
|
|
||||||
HideFromUser = true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return exampleConversation;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,3 +1,10 @@
|
|||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
using AIStudio.Settings;
|
||||||
|
using AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
using Lua;
|
||||||
|
|
||||||
namespace AIStudio.Tools.PluginSystem;
|
namespace AIStudio.Tools.PluginSystem;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -6,6 +13,9 @@ namespace AIStudio.Tools.PluginSystem;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed record PluginConfigurationObject
|
public sealed record PluginConfigurationObject
|
||||||
{
|
{
|
||||||
|
private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
|
||||||
|
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger<PluginConfigurationObject>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The id of the configuration plugin to which this configuration object belongs.
|
/// The id of the configuration plugin to which this configuration object belongs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -20,4 +30,178 @@ public sealed record PluginConfigurationObject
|
|||||||
/// The type of the configuration object.
|
/// The type of the configuration object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required PluginConfigurationObjectType Type { get; init; } = PluginConfigurationObjectType.NONE;
|
public required PluginConfigurationObjectType Type { get; init; } = PluginConfigurationObjectType.NONE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses Lua table entries into configuration objects of the specified type, populating the
|
||||||
|
/// provided list with results.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TClass">The type of configuration object to parse, which must
|
||||||
|
/// inherit from <see cref="ConfigurationBaseObject"/>.</typeparam>
|
||||||
|
/// <param name="configObjectType">The type of configuration object to process, as specified
|
||||||
|
/// in <see cref="PluginConfigurationObjectType"/>.</param>
|
||||||
|
/// <param name="configObjectSelection">An expression to retrieve existing configuration objects from
|
||||||
|
/// the main configuration data.</param>
|
||||||
|
/// <param name="nextConfigObjectNumSelection">An expression to retrieve the next available configuration
|
||||||
|
/// object number from the main configuration data.</param>
|
||||||
|
/// <param name="mainTable">The Lua table containing entries to parse into configuration objects.</param>
|
||||||
|
/// <param name="configPluginId">The unique identifier of the plugin associated with the configuration
|
||||||
|
/// objects being parsed.</param>
|
||||||
|
/// <param name="configObjects">The list to populate with the parsed configuration objects.
|
||||||
|
/// This parameter is passed by reference.</param>
|
||||||
|
/// <param name="dryRun">Specifies whether to perform the operation as a dry run, where changes
|
||||||
|
/// are not persisted.</param>
|
||||||
|
/// <returns>Returns true if parsing succeeds and configuration objects are added
|
||||||
|
/// to the list; otherwise, false.</returns>
|
||||||
|
public static bool TryParse<TClass>(
|
||||||
|
PluginConfigurationObjectType configObjectType,
|
||||||
|
Expression<Func<Data, List<TClass>>> configObjectSelection,
|
||||||
|
Expression<Func<Data, uint>> nextConfigObjectNumSelection,
|
||||||
|
LuaTable mainTable,
|
||||||
|
Guid configPluginId,
|
||||||
|
ref List<PluginConfigurationObject> configObjects,
|
||||||
|
bool dryRun
|
||||||
|
) where TClass : ConfigurationBaseObject
|
||||||
|
{
|
||||||
|
var luaTableName = configObjectType switch
|
||||||
|
{
|
||||||
|
PluginConfigurationObjectType.LLM_PROVIDER => "LLM_PROVIDERS",
|
||||||
|
PluginConfigurationObjectType.CHAT_TEMPLATE => "CHAT_TEMPLATES",
|
||||||
|
PluginConfigurationObjectType.DATA_SOURCE => "DATA_SOURCES",
|
||||||
|
PluginConfigurationObjectType.EMBEDDING_PROVIDER => "EMBEDDING_PROVIDERS",
|
||||||
|
PluginConfigurationObjectType.PROFILE => "PROFILES",
|
||||||
|
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (luaTableName is null)
|
||||||
|
{
|
||||||
|
LOG.LogError($"The configuration object type '{configObjectType}' is not supported yet.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mainTable.TryGetValue(luaTableName, out var luaValue) || !luaValue.TryRead<LuaTable>(out var luaTable))
|
||||||
|
{
|
||||||
|
LOG.LogWarning($"The {luaTableName} table does not exist or is not a valid table.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var storedObjects = configObjectSelection.Compile()(SETTINGS_MANAGER.ConfigurationData);
|
||||||
|
var numberObjects = luaTable.ArrayLength;
|
||||||
|
ThreadSafeRandom? random = null;
|
||||||
|
for (var i = 1; i <= numberObjects; i++)
|
||||||
|
{
|
||||||
|
var luaObjectTableValue = luaTable[i];
|
||||||
|
if (!luaObjectTableValue.TryRead<LuaTable>(out var luaObjectTable))
|
||||||
|
{
|
||||||
|
LOG.LogWarning($"The {luaObjectTable} table at index {i} is not a valid table.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var (wasParsingSuccessful, configObject) = configObjectType switch
|
||||||
|
{
|
||||||
|
PluginConfigurationObjectType.LLM_PROVIDER => (Settings.Provider.TryParseProviderTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != Settings.Provider.NONE, configurationObject),
|
||||||
|
PluginConfigurationObjectType.CHAT_TEMPLATE => (ChatTemplate.TryParseChatTemplateTable(i, luaObjectTable, configPluginId, out var configurationObject) && configurationObject != ChatTemplate.NO_CHAT_TEMPLATE, configurationObject),
|
||||||
|
|
||||||
|
_ => (false, NoConfigurationObject.INSTANCE)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (wasParsingSuccessful)
|
||||||
|
{
|
||||||
|
// Store it in the config object list:
|
||||||
|
configObjects.Add(new()
|
||||||
|
{
|
||||||
|
ConfigPluginId = configPluginId,
|
||||||
|
Id = Guid.Parse(configObject.Id),
|
||||||
|
Type = configObjectType,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dryRun)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var objectIndex = storedObjects.FindIndex(t => t.Id == configObject.Id);
|
||||||
|
|
||||||
|
// Case: The object already exists, we update it:
|
||||||
|
if (objectIndex > -1)
|
||||||
|
{
|
||||||
|
var existingObject = storedObjects[objectIndex];
|
||||||
|
configObject = configObject with { Num = existingObject.Num };
|
||||||
|
storedObjects[objectIndex] = (TClass)configObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case: The object does not exist, we have to add it
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nextConfigObjectNumSelection.TryIncrement(SETTINGS_MANAGER.ConfigurationData, IncrementType.POST) is { Success: true, UpdatedValue: var nextNum })
|
||||||
|
{
|
||||||
|
// Case: Increment the next number was successful
|
||||||
|
configObject = configObject with { Num = nextNum };
|
||||||
|
storedObjects.Add((TClass)configObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Case: The next number could not be incremented, we use a random number
|
||||||
|
random ??= new ThreadSafeRandom();
|
||||||
|
configObject = configObject with { Num = (uint)random.Next(500_000, 1_000_000) };
|
||||||
|
storedObjects.Add((TClass)configObject);
|
||||||
|
LOG.LogWarning($"The next number for the configuration object '{configObject.Name}' (id={configObject.Id}) could not be incremented. Using a random number instead.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG.LogWarning($"The {luaObjectTable} table at index {i} does not contain a valid chat template configuration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleans up configuration objects of a specified type that are no longer associated with any available plugin.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TClass">The type of configuration object to clean up.</typeparam>
|
||||||
|
/// <param name="configObjectType">The type of configuration object to process.</param>
|
||||||
|
/// <param name="configObjectSelection">A selection expression to retrieve the configuration objects from the main configuration.</param>
|
||||||
|
/// <param name="availablePlugins">A list of currently available plugins.</param>
|
||||||
|
/// <param name="configObjectList">A list of all existing configuration objects.</param>
|
||||||
|
/// <returns>Returns true if the configuration was altered during cleanup; otherwise, false.</returns>
|
||||||
|
public static bool CleanLeftOverConfigurationObjects<TClass>(
|
||||||
|
PluginConfigurationObjectType configObjectType,
|
||||||
|
Expression<Func<Data, List<TClass>>> configObjectSelection,
|
||||||
|
IList<IAvailablePlugin> availablePlugins,
|
||||||
|
IList<PluginConfigurationObject> configObjectList) where TClass : IConfigurationObject
|
||||||
|
{
|
||||||
|
var configuredObjects = configObjectSelection.Compile()(SETTINGS_MANAGER.ConfigurationData);
|
||||||
|
var leftOverObjects = new List<TClass>();
|
||||||
|
foreach (var configuredObject in configuredObjects)
|
||||||
|
{
|
||||||
|
if(!configuredObject.IsEnterpriseConfiguration)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var configObjectSourcePluginId = configuredObject.EnterpriseConfigurationPluginId;
|
||||||
|
if(configObjectSourcePluginId == Guid.Empty)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var templateSourcePlugin = availablePlugins.FirstOrDefault(plugin => plugin.Id == configObjectSourcePluginId);
|
||||||
|
if(templateSourcePlugin is null)
|
||||||
|
{
|
||||||
|
LOG.LogWarning($"The configured object '{configuredObject.Name}' (id={configuredObject.Id}) is based on a plugin that is not available anymore. Removing the chat template from the settings.");
|
||||||
|
leftOverObjects.Add(configuredObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!configObjectList.Any(configObject =>
|
||||||
|
configObject.Type == configObjectType &&
|
||||||
|
configObject.ConfigPluginId == configObjectSourcePluginId &&
|
||||||
|
configObject.Id.ToString() == configuredObject.Id))
|
||||||
|
{
|
||||||
|
LOG.LogWarning($"The configured object '{configuredObject.Name}' (id={configuredObject.Id}) is not present in the configuration plugin anymore. Removing the chat template from the settings.");
|
||||||
|
leftOverObjects.Add(configuredObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove collected items after enumeration to avoid modifying the collection during iteration:
|
||||||
|
var wasConfigurationChanged = leftOverObjects.Count > 0;
|
||||||
|
foreach (var item in leftOverObjects.Distinct())
|
||||||
|
configuredObjects.Remove(item);
|
||||||
|
|
||||||
|
return wasConfigurationChanged;
|
||||||
|
}
|
||||||
}
|
}
|
@ -92,10 +92,10 @@ public static partial class PluginFactory
|
|||||||
|
|
||||||
case { IsValid: false }:
|
case { IsValid: false }:
|
||||||
LOG.LogError($"Was not able to load plugin '{pluginMainFile}', because the Lua code is not a valid AI Studio plugin. There are {plugin.Issues.Count()} issues to fix. First issue is: {plugin.Issues.FirstOrDefault()}");
|
LOG.LogError($"Was not able to load plugin '{pluginMainFile}', because the Lua code is not a valid AI Studio plugin. There are {plugin.Issues.Count()} issues to fix. First issue is: {plugin.Issues.FirstOrDefault()}");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
foreach (var pluginIssue in plugin.Issues)
|
foreach (var pluginIssue in plugin.Issues)
|
||||||
LOG.LogError($"Plugin issue: {pluginIssue}");
|
LOG.LogError($"Plugin issue: {pluginIssue}");
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case { IsMaintained: false }:
|
case { IsMaintained: false }:
|
||||||
@ -125,89 +125,28 @@ public static partial class PluginFactory
|
|||||||
|
|
||||||
//
|
//
|
||||||
// =========================================================
|
// =========================================================
|
||||||
// Next, we have to clean up our settings. It is possible that a configuration plugin was removed.
|
// Next, we have to clean up our settings. It is possible
|
||||||
// We have to remove the related settings as well:
|
// that a configuration plugin was removed. We have to
|
||||||
|
// remove the related settings as well:
|
||||||
// =========================================================
|
// =========================================================
|
||||||
//
|
//
|
||||||
var wasConfigurationChanged = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check LLM providers:
|
// Check LLM providers:
|
||||||
//
|
var wasConfigurationChanged = PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.LLM_PROVIDER, x => x.Providers, AVAILABLE_PLUGINS, configObjectList);
|
||||||
#pragma warning disable MWAIS0001
|
|
||||||
var configuredProviders = SETTINGS_MANAGER.ConfigurationData.Providers.ToList();
|
|
||||||
foreach (var configuredProvider in configuredProviders)
|
|
||||||
{
|
|
||||||
if(!configuredProvider.IsEnterpriseConfiguration)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var providerSourcePluginId = configuredProvider.EnterpriseConfigurationPluginId;
|
|
||||||
if(providerSourcePluginId == Guid.Empty)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var providerSourcePlugin = AVAILABLE_PLUGINS.FirstOrDefault(plugin => plugin.Id == providerSourcePluginId);
|
|
||||||
if(providerSourcePlugin is null)
|
|
||||||
{
|
|
||||||
LOG.LogWarning($"The configured LLM provider '{configuredProvider.InstanceName}' (id={configuredProvider.Id}) is based on a plugin that is not available anymore. Removing the provider from the settings.");
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.Providers.Remove(configuredProvider);
|
|
||||||
wasConfigurationChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!configObjectList.Any(configObject =>
|
|
||||||
configObject.Type is PluginConfigurationObjectType.LLM_PROVIDER &&
|
|
||||||
configObject.ConfigPluginId == providerSourcePluginId &&
|
|
||||||
configObject.Id.ToString() == configuredProvider.Id))
|
|
||||||
{
|
|
||||||
LOG.LogWarning($"The configured LLM provider '{configuredProvider.InstanceName}' (id={configuredProvider.Id}) is not present in the configuration plugin anymore. Removing the provider from the settings.");
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.Providers.Remove(configuredProvider);
|
|
||||||
wasConfigurationChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#pragma warning restore MWAIS0001
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check chat templates:
|
// Check chat templates:
|
||||||
//
|
if(PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.CHAT_TEMPLATE, x => x.ChatTemplates, AVAILABLE_PLUGINS, configObjectList))
|
||||||
var configuredTemplates = SETTINGS_MANAGER.ConfigurationData.ChatTemplates.ToList();
|
|
||||||
foreach (var configuredTemplate in configuredTemplates)
|
|
||||||
{
|
|
||||||
if(!configuredTemplate.IsEnterpriseConfiguration)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var templateSourcePluginId = configuredTemplate.EnterpriseConfigurationPluginId;
|
|
||||||
if(templateSourcePluginId == Guid.Empty)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var templateSourcePlugin = AVAILABLE_PLUGINS.FirstOrDefault(plugin => plugin.Id == templateSourcePluginId);
|
|
||||||
if(templateSourcePlugin is null)
|
|
||||||
{
|
|
||||||
LOG.LogWarning($"The configured chat template '{configuredTemplate.Name}' (id={configuredTemplate.Id}) is based on a plugin that is not available anymore. Removing the chat template from the settings.");
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates.Remove(configuredTemplate);
|
|
||||||
wasConfigurationChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!configObjectList.Any(configObject =>
|
|
||||||
configObject.Type is PluginConfigurationObjectType.CHAT_TEMPLATE &&
|
|
||||||
configObject.ConfigPluginId == templateSourcePluginId &&
|
|
||||||
configObject.Id.ToString() == configuredTemplate.Id))
|
|
||||||
{
|
|
||||||
LOG.LogWarning($"The configured chat template '{configuredTemplate.Name}' (id={configuredTemplate.Id}) is not present in the configuration plugin anymore. Removing the chat template from the settings.");
|
|
||||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates.Remove(configuredTemplate);
|
|
||||||
wasConfigurationChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ==========================================================
|
|
||||||
// Check all possible settings:
|
|
||||||
// ==========================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
// Check for updates, and if so, how often?
|
|
||||||
if(ManagedConfiguration.IsConfigurationLeftOver<DataApp, UpdateBehavior>(x => x.App, x => x.UpdateBehavior, AVAILABLE_PLUGINS))
|
|
||||||
wasConfigurationChanged = true;
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
// Allow the user to add providers?
|
// Check for update behavior:
|
||||||
|
if(ManagedConfiguration.IsConfigurationLeftOver<DataApp, UpdateInterval>(x => x.App, x => x.UpdateInterval, AVAILABLE_PLUGINS))
|
||||||
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
|
// Check for update installation behavior:
|
||||||
|
if(ManagedConfiguration.IsConfigurationLeftOver<DataApp, UpdateInstallation>(x => x.App, x => x.UpdateInstallation, AVAILABLE_PLUGINS))
|
||||||
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
|
// Check for users allowed to added providers:
|
||||||
if(ManagedConfiguration.IsConfigurationLeftOver<DataApp, bool>(x => x.App, x => x.AllowUserToAddProvider, AVAILABLE_PLUGINS))
|
if(ManagedConfiguration.IsConfigurationLeftOver<DataApp, bool>(x => x.App, x => x.AllowUserToAddProvider, AVAILABLE_PLUGINS))
|
||||||
wasConfigurationChanged = true;
|
wasConfigurationChanged = true;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public sealed class DataSourceService
|
|||||||
// does not mean anything. We cannot filter the data sources by any means.
|
// does not mean anything. We cannot filter the data sources by any means.
|
||||||
// We return an empty list. Better safe than sorry.
|
// We return an empty list. Better safe than sorry.
|
||||||
//
|
//
|
||||||
if (selectedLLMProvider == default)
|
if (selectedLLMProvider == Settings.Provider.NONE)
|
||||||
{
|
{
|
||||||
this.logger.LogWarning("The selected LLM provider is not set. We cannot filter the data sources by any means.");
|
this.logger.LogWarning("The selected LLM provider is not set. We cannot filter the data sources by any means.");
|
||||||
return new([], []);
|
return new([], []);
|
||||||
|
@ -42,14 +42,14 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
|||||||
//
|
//
|
||||||
// Set the update interval based on the user's settings.
|
// Set the update interval based on the user's settings.
|
||||||
//
|
//
|
||||||
this.updateInterval = this.settingsManager.ConfigurationData.App.UpdateBehavior switch
|
this.updateInterval = this.settingsManager.ConfigurationData.App.UpdateInterval switch
|
||||||
{
|
{
|
||||||
UpdateBehavior.NO_CHECK => Timeout.InfiniteTimeSpan,
|
UpdateInterval.NO_CHECK => Timeout.InfiniteTimeSpan,
|
||||||
UpdateBehavior.ONCE_STARTUP => Timeout.InfiniteTimeSpan,
|
UpdateInterval.ONCE_STARTUP => Timeout.InfiniteTimeSpan,
|
||||||
|
|
||||||
UpdateBehavior.HOURLY => TimeSpan.FromHours(1),
|
UpdateInterval.HOURLY => TimeSpan.FromHours(1),
|
||||||
UpdateBehavior.DAILY => TimeSpan.FromDays(1),
|
UpdateInterval.DAILY => TimeSpan.FromDays(1),
|
||||||
UpdateBehavior.WEEKLY => TimeSpan.FromDays(7),
|
UpdateInterval.WEEKLY => TimeSpan.FromDays(7),
|
||||||
|
|
||||||
_ => TimeSpan.FromHours(1)
|
_ => TimeSpan.FromHours(1)
|
||||||
};
|
};
|
||||||
@ -58,7 +58,7 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
|||||||
// When the user doesn't want to check for updates, we can
|
// When the user doesn't want to check for updates, we can
|
||||||
// return early.
|
// return early.
|
||||||
//
|
//
|
||||||
if(this.settingsManager.ConfigurationData.App.UpdateBehavior is UpdateBehavior.NO_CHECK)
|
if(this.settingsManager.ConfigurationData.App.UpdateInterval is UpdateInterval.NO_CHECK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -115,7 +115,25 @@ public sealed class UpdateService : BackgroundService, IMessageBusReceiver
|
|||||||
var response = await this.rust.CheckForUpdate();
|
var response = await this.rust.CheckForUpdate();
|
||||||
if (response.UpdateIsAvailable)
|
if (response.UpdateIsAvailable)
|
||||||
{
|
{
|
||||||
await this.messageBus.SendMessage(null, Event.UPDATE_AVAILABLE, response);
|
if (this.settingsManager.ConfigurationData.App.UpdateInstallation is UpdateInstallation.AUTOMATIC)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.messageBus.SendMessage<bool>(null, Event.INSTALL_UPDATE);
|
||||||
|
await this.rust.InstallUpdate();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
SNACKBAR!.Add(TB("Failed to install update automatically. Please try again manually."), Severity.Error, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.Error;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
config.IconColor = Color.Error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
await this.messageBus.SendMessage(null, Event.UPDATE_AVAILABLE, response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,33 @@ public static class WorkspaceBehaviour
|
|||||||
|
|
||||||
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", workspaceId.ToString());
|
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", workspaceId.ToString());
|
||||||
var workspaceNamePath = Path.Join(workspacePath, "name");
|
var workspaceNamePath = Path.Join(workspacePath, "name");
|
||||||
return await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If the name file does not exist or is empty, self-heal with a default name.
|
||||||
|
if (!File.Exists(workspaceNamePath))
|
||||||
|
{
|
||||||
|
var defaultName = TB("Unnamed workspace");
|
||||||
|
Directory.CreateDirectory(workspacePath);
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, defaultName, Encoding.UTF8);
|
||||||
|
return defaultName;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
var defaultName = TB("Unnamed workspace");
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, defaultName, Encoding.UTF8);
|
||||||
|
return defaultName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// On any error, return a localized default without throwing.
|
||||||
|
return TB("Unnamed workspace");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task DeleteChat(IDialogService dialogService, Guid workspaceId, Guid chatId, bool askForConfirmation = true)
|
public static async Task DeleteChat(IDialogService dialogService, Guid workspaceId, Guid chatId, bool askForConfirmation = true)
|
||||||
@ -95,10 +121,10 @@ public static class WorkspaceBehaviour
|
|||||||
if (askForConfirmation)
|
if (askForConfirmation)
|
||||||
{
|
{
|
||||||
var workspaceName = await LoadWorkspaceName(chat.WorkspaceId);
|
var workspaceName = await LoadWorkspaceName(chat.WorkspaceId);
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"Message", (chat.WorkspaceId == Guid.Empty) switch
|
x => x.Message, (chat.WorkspaceId == Guid.Empty) switch
|
||||||
{
|
{
|
||||||
true => TB($"Are you sure you want to delete the temporary chat '{chat.Name}'?"),
|
true => TB($"Are you sure you want to delete the temporary chat '{chat.Name}'?"),
|
||||||
false => TB($"Are you sure you want to delete the chat '{chat.Name}' in the workspace '{workspaceName}'?"),
|
false => TB($"Are you sure you want to delete the chat '{chat.Name}' in the workspace '{workspaceName}'?"),
|
||||||
@ -124,13 +150,30 @@ public static class WorkspaceBehaviour
|
|||||||
private static async Task EnsureWorkspace(Guid workspaceId, string workspaceName)
|
private static async Task EnsureWorkspace(Guid workspaceId, string workspaceName)
|
||||||
{
|
{
|
||||||
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", workspaceId.ToString());
|
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", workspaceId.ToString());
|
||||||
|
|
||||||
if(Path.Exists(workspacePath))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Directory.CreateDirectory(workspacePath);
|
|
||||||
var workspaceNamePath = Path.Join(workspacePath, "name");
|
var workspaceNamePath = Path.Join(workspacePath, "name");
|
||||||
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
|
|
||||||
|
if(!Path.Exists(workspacePath))
|
||||||
|
Directory.CreateDirectory(workspacePath);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// When the name file is missing or empty, write it (self-heal).
|
||||||
|
// Otherwise, keep the existing name:
|
||||||
|
if (!File.Exists(workspaceNamePath))
|
||||||
|
{
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var existing = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||||
|
if (string.IsNullOrWhiteSpace(existing))
|
||||||
|
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore IO issues to avoid interrupting background initialization.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task EnsureBiasWorkspace() => await EnsureWorkspace(KnownWorkspaces.BIAS_WORKSPACE_ID, "Bias of the Day");
|
public static async Task EnsureBiasWorkspace() => await EnsureWorkspace(KnownWorkspaces.BIAS_WORKSPACE_ID, "Bias of the Day");
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
# v0.9.51, build 226 (2025-08-xx xx:xx UTC)
|
# v0.9.51, build 226 (2025-08-xx xx:xx UTC)
|
||||||
- Added support for predefined chat templates in configuration plugins to help enterprises roll out consistent templates across the organization.
|
- Added support for predefined chat templates in configuration plugins to help enterprises roll out consistent templates across the organization.
|
||||||
|
- Added the ability to choose between automatic and manual update installation to the app settings (default is manual).
|
||||||
|
- Added the ability to control the update installation behavior by configuration plugins.
|
||||||
- Improved memory usage in several areas of the app.
|
- Improved memory usage in several areas of the app.
|
||||||
- Improved plugin management for configuration plugins so that hot reload detects when a provider or chat template has been removed.
|
- Improved plugin management for configuration plugins so that hot reload detects when a provider or chat template has been removed.
|
||||||
|
- Improved the dialog for naming chats and workspaces to ensure valid inputs are entered.
|
||||||
|
- Improved the dialog invocation by making parameter provision more robust.
|
||||||
|
- Changed the configuration plugin setting name for how often to check for updates from `UpdateBehavior` to `UpdateInterval`.
|
||||||
- Fixed a bug in various assistants where some text fields were not reset when resetting.
|
- Fixed a bug in various assistants where some text fields were not reset when resetting.
|
||||||
- Added a new text field to the text summarizer assistant to allow users to specify important aspects that the assistant should focus on.
|
- Added a new text field to the text summarizer assistant to allow users to specify important aspects that the assistant should focus on.
|
||||||
|
- Fixed the input field header in the dialog for naming chats and workspaces.
|
||||||
|
- Fixed a rare chat-related bug that could occur when a workspace was not created correctly. Thank you, Naomi, for reporting this issue.
|
||||||
|
Loading…
Reference in New Issue
Block a user