Added the possibility to send an assistant's result to another assistant

This commit is contained in:
Thorsten Sommer 2024-08-18 12:31:46 +02:00
parent 44ccac8127
commit 423388e18f
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
14 changed files with 214 additions and 18 deletions

View File

@ -1,4 +1,6 @@
@using AIStudio.Chat @using AIStudio.Chat
@using AIStudio.Components.Pages
@using AIStudio.Tools
<MudText Typo="Typo.h3" Class="mb-2 mr-3"> <MudText Typo="Typo.h3" Class="mb-2 mr-3">
@this.Title @this.Title
</MudText> </MudText>
@ -51,6 +53,20 @@
@buttonData.Text @buttonData.Text
</MudButton> </MudButton>
break; break;
case SendToButton sendToButton:
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Color="Color.Info">
@foreach (var assistant in Enum.GetValues<SendToAssistant>().OrderBy(n => n.Name().Length))
{
if(assistant is Pages.SendToAssistant.NONE || sendToButton.Self == assistant)
continue;
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)">
@assistant.Name()
</MudMenuItem>
}
</MudMenu>
break;
} }
} }
</MudStack> </MudStack>

View File

@ -1,10 +1,13 @@
using AIStudio.Chat; using AIStudio.Chat;
using AIStudio.Components.Pages;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Tools; using AIStudio.Tools;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Path = AIStudio.Components.Pages.Path;
namespace AIStudio.Components; namespace AIStudio.Components;
public abstract partial class AssistantBase : ComponentBase public abstract partial class AssistantBase : ComponentBase
@ -160,4 +163,34 @@ public abstract partial class AssistantBase : ComponentBase
return icon; return icon;
} }
private Task SendToAssistant(SendToAssistant assistant, SendToButton sendToButton)
{
var contentToSend = sendToButton.UseResultingContentBlockData switch
{
false => sendToButton.GetData(),
true => this.resultingContentBlock?.Content switch
{
ContentText textBlock => textBlock.Text,
_ => string.Empty,
},
};
var (eventItem, path) = assistant switch
{
Pages.SendToAssistant.AGENDA_ASSISTANT => (Event.SEND_TO_AGENDA_ASSISTANT, Path.ASSISTANT_AGENDA),
Pages.SendToAssistant.CODING_ASSISTANT => (Event.SEND_TO_CODING_ASSISTANT, Path.ASSISTANT_CODING),
Pages.SendToAssistant.REWRITE_ASSISTANT => (Event.SEND_TO_REWRITE_ASSISTANT, Path.ASSISTANT_REWRITE),
Pages.SendToAssistant.TRANSLATION_ASSISTANT => (Event.SEND_TO_TRANSLATION_ASSISTANT, Path.ASSISTANT_TRANSLATION),
Pages.SendToAssistant.ICON_FINDER_ASSISTANT => (Event.SEND_TO_ICON_FINDER_ASSISTANT, Path.ASSISTANT_ICON_FINDER),
Pages.SendToAssistant.GRAMMAR_SPELLING_ASSISTANT => (Event.SEND_TO_GRAMMAR_SPELLING_ASSISTANT, Path.ASSISTANT_GRAMMAR_SPELLING),
Pages.SendToAssistant.TEXT_SUMMARIZER_ASSISTANT => (Event.SEND_TO_TEXT_SUMMARIZER_ASSISTANT, Path.ASSISTANT_SUMMARIZER),
_ => (Event.NONE, Path.ASSISTANTS),
};
MessageBus.INSTANCE.DeferMessage(this, eventItem, contentToSend);
this.NavigationManager.NavigateTo(path);
return Task.CompletedTask;
}
} }

View File

@ -93,6 +93,14 @@ public partial class AssistantAgenda : AssistantBaseCore
- Mary Jane: Work package 3 - Mary Jane: Work package 3
"""; """;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = SendToAssistant.AGENDA_ASSISTANT,
},
];
private string inputTopic = string.Empty; private string inputTopic = string.Empty;
private string inputName = string.Empty; private string inputName = string.Empty;
private string inputContent = string.Empty; private string inputContent = string.Empty;
@ -145,6 +153,10 @@ public partial class AssistantAgenda : AssistantBaseCore
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider); this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider);
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_AGENDA_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputContent = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -1,5 +1,7 @@
using System.Text; using System.Text;
using AIStudio.Tools;
namespace AIStudio.Components.Pages.Coding; namespace AIStudio.Components.Pages.Coding;
public partial class AssistantCoding : AssistantBaseCore public partial class AssistantCoding : AssistantBaseCore
@ -24,6 +26,14 @@ public partial class AssistantCoding : AssistantBaseCore
When the user asks in a different language than English, you answer in the same language! When the user asks in a different language than English, you answer in the same language!
"""; """;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = SendToAssistant.CODING_ASSISTANT,
},
];
private readonly List<CodingContext> codingContexts = new(); private readonly List<CodingContext> codingContexts = new();
private bool provideCompilerMessages; private bool provideCompilerMessages;
private string compilerMessages = string.Empty; private string compilerMessages = string.Empty;
@ -39,6 +49,10 @@ public partial class AssistantCoding : AssistantBaseCore
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Coding.PreselectedProvider); this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Coding.PreselectedProvider);
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_CODING_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.questions = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -28,7 +28,13 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore
protected override IReadOnlyList<IButtonData> FooterButtons => protected override IReadOnlyList<IButtonData> FooterButtons =>
[ [
new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.correctedText)), new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.correctedText)),
}; new SendToButton
{
Self = SendToAssistant.GRAMMAR_SPELLING_ASSISTANT,
UseResultingContentBlockData = false,
GetData = () => string.IsNullOrWhiteSpace(this.correctedText) ? this.inputText : this.correctedText
},
];
#region Overrides of ComponentBase #region Overrides of ComponentBase
@ -41,6 +47,10 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider); this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider);
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_GRAMMAR_SPELLING_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputText = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -1,3 +1,5 @@
using AIStudio.Tools;
namespace AIStudio.Components.Pages.IconFinder; namespace AIStudio.Components.Pages.IconFinder;
public partial class AssistantIconFinder : AssistantBaseCore public partial class AssistantIconFinder : AssistantBaseCore
@ -5,21 +7,6 @@ public partial class AssistantIconFinder : AssistantBaseCore
private string inputContext = string.Empty; private string inputContext = string.Empty;
private IconSources selectedIconSource; private IconSources selectedIconSource;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if (this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)
{
this.selectedIconSource = this.SettingsManager.ConfigurationData.IconFinder.PreselectedSource;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider);
}
await base.OnInitializedAsync();
}
#endregion
protected override string Title => "Icon Finder"; protected override string Title => "Icon Finder";
protected override string Description => protected override string Description =>
@ -41,6 +28,33 @@ public partial class AssistantIconFinder : AssistantBaseCore
quotation marks. quotation marks.
"""; """;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = SendToAssistant.ICON_FINDER_ASSISTANT,
},
];
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if (this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)
{
this.selectedIconSource = this.SettingsManager.ConfigurationData.IconFinder.PreselectedSource;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider);
}
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_ICON_FINDER_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputContext = deferredContent;
await base.OnInitializedAsync();
}
#endregion
private string? ValidatingContext(string context) private string? ValidatingContext(string context)
{ {
if(string.IsNullOrWhiteSpace(context)) if(string.IsNullOrWhiteSpace(context))

View File

@ -28,7 +28,13 @@ public partial class AssistantRewriteImprove : AssistantBaseCore
protected override IReadOnlyList<IButtonData> FooterButtons => protected override IReadOnlyList<IButtonData> FooterButtons =>
[ [
new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.rewrittenText)) new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.rewrittenText)),
new SendToButton
{
Self = SendToAssistant.REWRITE_ASSISTANT,
UseResultingContentBlockData = false,
GetData = () => string.IsNullOrWhiteSpace(this.rewrittenText) ? this.inputText : this.rewrittenText,
},
]; ];
#region Overrides of ComponentBase #region Overrides of ComponentBase
@ -43,6 +49,10 @@ public partial class AssistantRewriteImprove : AssistantBaseCore
this.selectedWritingStyle = this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedWritingStyle; this.selectedWritingStyle = this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedWritingStyle;
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_REWRITE_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputText = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -0,0 +1,14 @@
namespace AIStudio.Components.Pages;
public enum SendToAssistant
{
NONE = 0,
GRAMMAR_SPELLING_ASSISTANT,
ICON_FINDER_ASSISTANT,
REWRITE_ASSISTANT,
TRANSLATION_ASSISTANT,
AGENDA_ASSISTANT,
CODING_ASSISTANT,
TEXT_SUMMARIZER_ASSISTANT,
}

View File

@ -0,0 +1,20 @@
namespace AIStudio.Components.Pages;
public static class SendToAssistantExtensions
{
public static string Name(this SendToAssistant assistant)
{
return assistant switch
{
SendToAssistant.GRAMMAR_SPELLING_ASSISTANT => "Grammar & Spelling Assistant",
SendToAssistant.TEXT_SUMMARIZER_ASSISTANT => "Text Summarizer Assistant",
SendToAssistant.ICON_FINDER_ASSISTANT => "Icon Finder Assistant",
SendToAssistant.TRANSLATION_ASSISTANT => "Translation Assistant",
SendToAssistant.REWRITE_ASSISTANT => "Rewrite Assistant",
SendToAssistant.AGENDA_ASSISTANT => "Agenda Assistant",
SendToAssistant.CODING_ASSISTANT => "Coding Assistant",
_ => "Send to ...",
};
}
}

View File

@ -23,6 +23,14 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
a summary with the requested complexity. In any case, do not add any information. a summary with the requested complexity. In any case, do not add any information.
"""; """;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = SendToAssistant.TEXT_SUMMARIZER_ASSISTANT,
},
];
private string inputText = string.Empty; private string inputText = string.Empty;
private bool isAgentRunning; private bool isAgentRunning;
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;
@ -43,6 +51,10 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider); this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider);
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_TEXT_SUMMARIZER_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputText = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -19,6 +19,14 @@ public partial class AssistantTranslation : AssistantBaseCore
language requires, e.g., shorter sentences, you should split the text into shorter sentences. language requires, e.g., shorter sentences, you should split the text into shorter sentences.
"""; """;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = SendToAssistant.TRANSLATION_ASSISTANT,
},
];
private bool liveTranslation; private bool liveTranslation;
private bool isAgentRunning; private bool isAgentRunning;
private string inputText = string.Empty; private string inputText = string.Empty;
@ -38,6 +46,10 @@ public partial class AssistantTranslation : AssistantBaseCore
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Translation.PreselectedProvider); this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.Translation.PreselectedProvider);
} }
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_TRANSLATION_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputText = deferredContent;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }

View File

@ -15,4 +15,13 @@ public enum Event
// Chat events: // Chat events:
HAS_CHAT_UNSAVED_CHANGES, HAS_CHAT_UNSAVED_CHANGES,
RESET_CHAT_STATE, RESET_CHAT_STATE,
// Send assistant events:
SEND_TO_GRAMMAR_SPELLING_ASSISTANT,
SEND_TO_ICON_FINDER_ASSISTANT,
SEND_TO_REWRITE_ASSISTANT,
SEND_TO_TRANSLATION_ASSISTANT,
SEND_TO_AGENDA_ASSISTANT,
SEND_TO_CODING_ASSISTANT,
SEND_TO_TEXT_SUMMARIZER_ASSISTANT,
} }

View File

@ -0,0 +1,15 @@
using AIStudio.Components.Pages;
namespace AIStudio.Tools;
public readonly record struct SendToButton() : IButtonData
{
public ButtonTypes Type => ButtonTypes.SEND_TO;
public Func<string> GetData { get; init; } = () => string.Empty;
public bool UseResultingContentBlockData { get; init; } = true;
public SendToAssistant Self { get; init; } = SendToAssistant.NONE;
}

View File

@ -0,0 +1,5 @@
# v0.8.9, build 171
- Added the possibility to send an assistant's result to another assistant
- Refactored page paths
- Refactored assistant footer buttons
- Refactored message bus to support deferred messages