mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-06-27 14:36:27 +00:00
146 lines
5.2 KiB
C#
146 lines
5.2 KiB
C#
using System.Text;
|
|
using AIStudio.Dialogs.Settings;
|
|
|
|
namespace AIStudio.Assistants.Meta;
|
|
|
|
public partial class AssistantMetaAssistant : AssistantBaseCore<NoSettingsPanel>
|
|
{
|
|
private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(AssistantMetaAssistant));
|
|
|
|
protected override Tools.Components Component => Tools.Components.META_ASSISTANT;
|
|
protected override string Title => T("Assistant Builder");
|
|
protected override string Description => string.Empty;
|
|
protected override string SystemPrompt => this.AssembleSystemPrompt();
|
|
protected override string SubmitText => T("Build your assistant");
|
|
protected override Func<Task> SubmitAction => this.GenerateLuaAssistant;
|
|
protected override bool SubmitDisabled => this.isAgentRunning;
|
|
protected override bool ShowResult { get; }
|
|
protected override bool AllowProfiles { get; }
|
|
protected override bool ShowProfileSelection { get; }
|
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
|
protected override bool HasSettingsPanel { get; }
|
|
|
|
private bool isAgentRunning;
|
|
private AssistantCategory selectedCategory;
|
|
private string customCategory = string.Empty;
|
|
private static readonly AssistantContextFile[] ASSISTANT_CONTEXT_FILES =
|
|
[
|
|
new("Assistant plugin schema", "Plugins/assistants/README.md", IsRequired: true),
|
|
new("Lua manifest template", "Plugins/assistants/plugin.lua", IsRequired: true),
|
|
new("Translation example", "Plugins/assistants/examples/translation/plugin.lua", IsRequired: false),
|
|
];
|
|
private readonly record struct AssistantContextFile(
|
|
string Title,
|
|
string RelativePath,
|
|
bool IsRequired);
|
|
|
|
#region Overrides of ComponentBase
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await base.OnInitializedAsync();
|
|
}
|
|
|
|
#endregion
|
|
|
|
protected override void ResetForm()
|
|
{
|
|
this.selectedCategory = AssistantCategory.AS_IS;
|
|
this.customCategory = string.Empty;
|
|
}
|
|
|
|
protected override bool MightPreselectValues()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private string AssembleSystemPrompt() => string.Empty;
|
|
|
|
private string? ValidatingCategory(AssistantCategory category)
|
|
{
|
|
if(category is AssistantCategory.AS_IS)
|
|
return T("Please select an assistant category.");
|
|
|
|
return null;
|
|
}
|
|
|
|
private string? ValidateCustomCategory(string category)
|
|
{
|
|
if(this.selectedCategory is AssistantCategory.OTHER && string.IsNullOrWhiteSpace(category))
|
|
return T("Please provide a custom category.");
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task GenerateLuaAssistant()
|
|
{
|
|
await this.Form!.Validate();
|
|
if (!this.InputIsValid)
|
|
return;
|
|
|
|
this.CreateChatThread();
|
|
var time = this.AddUserRequest(
|
|
$"""
|
|
Assistant category: {this.GetSelectedCategoryName()}
|
|
|
|
Remind me to replace this placeholder with the real lua plugin context
|
|
""");
|
|
|
|
await this.AddAIResponseAsync(time);
|
|
}
|
|
|
|
private string GetSelectedCategoryName() => this.selectedCategory is AssistantCategory.OTHER
|
|
? this.customCategory
|
|
: this.selectedCategory.Name();
|
|
|
|
private static async Task<string> ReadAppResourceTextAsync(string relativePath)
|
|
{
|
|
relativePath = relativePath.Replace('\\', '/');
|
|
#if DEBUG
|
|
var filePath = Path.Join(Environment.CurrentDirectory, relativePath);
|
|
return File.Exists(filePath)
|
|
? await File.ReadAllTextAsync(filePath)
|
|
: string.Empty;
|
|
#else
|
|
var provider = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!);
|
|
var file = provider.GetFileInfo(relativePath);
|
|
if (!file.Exists)
|
|
return string.Empty;
|
|
|
|
await using var stream = file.CreateReadStream();
|
|
using var reader = new StreamReader(stream, Encoding.UTF8);
|
|
return await reader.ReadToEndAsync();
|
|
#endif
|
|
}
|
|
|
|
private async Task<string> LoadAssistantBuilderContextAsync()
|
|
{
|
|
var builder = new StringBuilder();
|
|
|
|
foreach (var contextFile in ASSISTANT_CONTEXT_FILES)
|
|
{
|
|
var content = await ReadAppResourceTextAsync(contextFile.RelativePath);
|
|
if (string.IsNullOrWhiteSpace(content))
|
|
{
|
|
LOGGER.LogError($"The context for \"{contextFile.Title}\" could not be read from the assembly. Path: {contextFile.RelativePath}");
|
|
if (contextFile.IsRequired)
|
|
{
|
|
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.SettingsSuggest, string.Format(T("The Assistant-Builder was not able to read the plugin manifest and therefore cannot safely generate your assistant right now."))));
|
|
this.isAgentRunning = true;
|
|
return string.Empty;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
builder.AppendLine($"# {contextFile.Title}");
|
|
builder.AppendLine($"Source: {contextFile.RelativePath}");
|
|
builder.AppendLine("<context>");
|
|
builder.AppendLine(content.Trim());
|
|
builder.AppendLine("</context>");
|
|
builder.AppendLine();
|
|
}
|
|
|
|
return builder.ToString().Trim();
|
|
}
|
|
}
|