mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-08-20 11:12:55 +00:00
Allow chat templates coming from a config plugin
This commit is contained in:
parent
afefc651a5
commit
26e597b159
@ -109,7 +109,7 @@ public sealed record ChatThread
|
||||
else
|
||||
{
|
||||
var chatTemplate = settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatThread.SelectedChatTemplate);
|
||||
if(chatTemplate == default)
|
||||
if(chatTemplate == null)
|
||||
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
||||
else
|
||||
{
|
||||
|
@ -327,7 +327,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
private async Task ChatTemplateWasChanged(ChatTemplate chatTemplate)
|
||||
{
|
||||
this.currentChatTemplate = chatTemplate;
|
||||
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
|
||||
if(!string.IsNullOrWhiteSpace(this.currentChatTemplate.PredefinedUserPrompt))
|
||||
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
|
||||
|
||||
if(this.ChatThread is null)
|
||||
return;
|
||||
|
||||
@ -435,7 +437,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
DataSourceOptions = this.earlyDataSourceOptions,
|
||||
Name = this.ExtractThreadName(this.userInput),
|
||||
Seed = this.RNG.Next(),
|
||||
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||
Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||
};
|
||||
|
||||
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
||||
@ -673,7 +675,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
ChatId = Guid.NewGuid(),
|
||||
Name = string.Empty,
|
||||
Seed = this.RNG.Next(),
|
||||
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||
Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -813,9 +815,8 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
// Try to select the chat template:
|
||||
if (!string.IsNullOrWhiteSpace(chatChatTemplate))
|
||||
{
|
||||
this.currentChatTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate);
|
||||
if(this.currentChatTemplate == default)
|
||||
this.currentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
|
||||
var selectedTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate);
|
||||
this.currentChatTemplate = selectedTemplate ?? ChatTemplate.NO_CHAT_TEMPLATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||
private async Task EditLLMProvider(AIStudio.Settings.Provider provider)
|
||||
{
|
||||
if (provider.IsEnterpriseConfiguration)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<ProviderDialog>
|
||||
{
|
||||
{ x => x.DataNum, provider.Num },
|
||||
|
@ -129,6 +129,9 @@ public partial class ChatTemplateDialog : MSGComponentBase
|
||||
PredefinedUserPrompt = this.PredefinedUserPrompt,
|
||||
ExampleConversation = this.dataExampleConversation,
|
||||
AllowProfileUsage = this.AllowProfileUsage,
|
||||
|
||||
EnterpriseConfigurationPluginId = Guid.Empty,
|
||||
IsEnterpriseConfiguration = false,
|
||||
};
|
||||
|
||||
private void RemoveMessage(ContentBlock item)
|
||||
|
@ -53,6 +53,9 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
|
||||
|
||||
private async Task EditChatTemplate(ChatTemplate chatTemplate)
|
||||
{
|
||||
if (chatTemplate == ChatTemplate.NO_CHAT_TEMPLATE || chatTemplate.IsEnterpriseConfiguration)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<ChatTemplateDialog>
|
||||
{
|
||||
{ x => x.DataNum, chatTemplate.Num },
|
||||
|
@ -3,7 +3,7 @@ using AIStudio.Tools.PluginSystem;
|
||||
|
||||
namespace AIStudio.Settings;
|
||||
|
||||
public record ChatTemplate(uint Num, string Id, string Name, string SystemPrompt, string PredefinedUserPrompt, List<ContentBlock> ExampleConversation, bool AllowProfileUsage)
|
||||
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 ChatTemplate() : this(0, Guid.Empty.ToString(), string.Empty, string.Empty, string.Empty, [], false)
|
||||
{
|
||||
@ -20,6 +20,8 @@ public record ChatTemplate(uint Num, string Id, string Name, string SystemPrompt
|
||||
Num = uint.MaxValue,
|
||||
ExampleConversation = [],
|
||||
AllowProfileUsage = true,
|
||||
EnterpriseConfigurationPluginId = Guid.Empty,
|
||||
IsEnterpriseConfiguration = false,
|
||||
};
|
||||
|
||||
#region Overrides of ValueType
|
||||
|
@ -270,11 +270,11 @@ public sealed class SettingsManager
|
||||
public ChatTemplate GetPreselectedChatTemplate(Tools.Components component)
|
||||
{
|
||||
var preselection = component.PreselectedChatTemplate(this);
|
||||
if (preselection != default)
|
||||
if (preselection != ChatTemplate.NO_CHAT_TEMPLATE)
|
||||
return preselection;
|
||||
|
||||
preselection = this.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedChatTemplate);
|
||||
return preselection != default ? preselection : ChatTemplate.NO_CHAT_TEMPLATE;
|
||||
return preselection ?? ChatTemplate.NO_CHAT_TEMPLATE;
|
||||
}
|
||||
|
||||
public ConfidenceLevel GetConfiguredConfidenceLevel(LLMProviders llmProvider)
|
||||
|
@ -133,8 +133,8 @@ public static class ComponentsExtensions
|
||||
|
||||
public static ChatTemplate PreselectedChatTemplate(this Components component, SettingsManager settingsManager) => component switch
|
||||
{
|
||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedChatTemplate) : default,
|
||||
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.Chat.PreselectedChatTemplate) ?? ChatTemplate.NO_CHAT_TEMPLATE : ChatTemplate.NO_CHAT_TEMPLATE,
|
||||
|
||||
_ => default,
|
||||
_ => ChatTemplate.NO_CHAT_TEMPLATE,
|
||||
};
|
||||
}
|
@ -111,6 +111,47 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
|
||||
}
|
||||
#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)
|
||||
{
|
||||
var template = configuredTemplate;
|
||||
var tplIndex = SETTINGS_MANAGER.ConfigurationData.ChatTemplates.FindIndex(t => t.Id == template.Id);
|
||||
if (tplIndex > -1)
|
||||
{
|
||||
var existingTemplate = SETTINGS_MANAGER.ConfigurationData.ChatTemplates[tplIndex];
|
||||
template = template with { Num = existingTemplate.Num };
|
||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates[tplIndex] = template;
|
||||
}
|
||||
else
|
||||
{
|
||||
template = template with { Num = SETTINGS_MANAGER.ConfigurationData.NextChatTemplateNum++ };
|
||||
SETTINGS_MANAGER.ConfigurationData.ChatTemplates.Add(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -194,4 +235,51 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
|
||||
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;
|
||||
|
||||
#warning Need to add support for ExampleConversation
|
||||
|
||||
template = new()
|
||||
{
|
||||
Num = 0,
|
||||
Id = id.ToString(),
|
||||
Name = name,
|
||||
SystemPrompt = systemPrompt,
|
||||
PredefinedUserPrompt = predefinedUserPrompt,
|
||||
ExampleConversation = [],
|
||||
AllowProfileUsage = allowProfileUsage,
|
||||
IsEnterpriseConfiguration = true,
|
||||
EnterpriseConfigurationPluginId = this.Id
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -151,7 +151,29 @@ public static partial class PluginFactory
|
||||
}
|
||||
}
|
||||
#pragma warning restore MWAIS0001
|
||||
|
||||
//
|
||||
// Check Chat Templates:
|
||||
//
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ==========================================================
|
||||
// Check all possible settings:
|
||||
|
Loading…
Reference in New Issue
Block a user