mirror of
				https://github.com/MindWorkAI/AI-Studio.git
				synced 2025-10-31 15:40:21 +00:00 
			
		
		
		
	Assistant send result (#75)
This commit is contained in:
		
							parent
							
								
									ea0ead58f8
								
							
						
					
					
						commit
						909fbe89bb
					
				| @ -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> | ||||||
| @ -34,11 +36,11 @@ | |||||||
|         @if (this.FooterButtons.Count > 0) |         @if (this.FooterButtons.Count > 0) | ||||||
|         { |         { | ||||||
|             <MudStack Row="@true" Wrap="Wrap.Wrap" Class="mt-3 mr-2"> |             <MudStack Row="@true" Wrap="Wrap.Wrap" Class="mt-3 mr-2"> | ||||||
|                 @foreach (var buttonData in this.FooterButtons) |                 @foreach (var button in this.FooterButtons) | ||||||
|                 { |                 { | ||||||
|                     switch (buttonData) |                     switch (button) | ||||||
|                     { |                     { | ||||||
|                         case var _ when !string.IsNullOrWhiteSpace(buttonData.Tooltip): |                         case ButtonData buttonData when !string.IsNullOrWhiteSpace(buttonData.Tooltip): | ||||||
|                             <MudTooltip Text="@buttonData.Tooltip"> |                             <MudTooltip Text="@buttonData.Tooltip"> | ||||||
|                                 <MudButton Variant="Variant.Filled" Color="@buttonData.Color" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> |                                 <MudButton Variant="Variant.Filled" Color="@buttonData.Color" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> | ||||||
|                                     @buttonData.Text |                                     @buttonData.Text | ||||||
| @ -46,11 +48,25 @@ | |||||||
|                             </MudTooltip> |                             </MudTooltip> | ||||||
|                             break; |                             break; | ||||||
| 
 | 
 | ||||||
|                         default: |                         case ButtonData buttonData: | ||||||
|                             <MudButton Variant="Variant.Filled" Color="@buttonData.Color" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> |                             <MudButton Variant="Variant.Filled" Color="@buttonData.Color" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> | ||||||
|                                 @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> | ||||||
|  | |||||||
| @ -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 | ||||||
| @ -24,6 +27,9 @@ public abstract partial class AssistantBase : ComponentBase | |||||||
|     [Inject] |     [Inject] | ||||||
|     protected Rust Rust { get; init; } = null!; |     protected Rust Rust { get; init; } = null!; | ||||||
|      |      | ||||||
|  |     [Inject] | ||||||
|  |     protected NavigationManager NavigationManager { get; init; } = null!; | ||||||
|  |      | ||||||
|     internal const string AFTER_RESULT_DIV_ID = "afterAssistantResult"; |     internal const string AFTER_RESULT_DIV_ID = "afterAssistantResult"; | ||||||
|     internal const string ASSISTANT_RESULT_DIV_ID = "assistantResult"; |     internal const string ASSISTANT_RESULT_DIV_ID = "assistantResult"; | ||||||
|      |      | ||||||
| @ -39,7 +45,7 @@ public abstract partial class AssistantBase : ComponentBase | |||||||
|      |      | ||||||
|     protected virtual bool ShowDedicatedProgress => false; |     protected virtual bool ShowDedicatedProgress => false; | ||||||
| 
 | 
 | ||||||
|     protected virtual IReadOnlyList<ButtonData> FooterButtons => []; |     protected virtual IReadOnlyList<IButtonData> FooterButtons => []; | ||||||
| 
 | 
 | ||||||
|     protected static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); |     protected static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); | ||||||
|      |      | ||||||
| @ -157,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; | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										24
									
								
								app/MindWork AI Studio/Components/Blocks/SplitButton.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/MindWork AI Studio/Components/Blocks/SplitButton.razor
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | @typeparam T | ||||||
|  | 
 | ||||||
|  | <MudButtonGroup Color="@this.Color" Variant="Variant.Filled"> | ||||||
|  |     @if (string.IsNullOrWhiteSpace(this.Icon)) | ||||||
|  |     { | ||||||
|  |         <MudButton OnClick="() => this.OnClick(this.selectedValue)"> | ||||||
|  |             @this.SelectedValueName() | ||||||
|  |         </MudButton> | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         <MudButton StartIcon="@this.Icon" OnClick="() => this.OnClick(this.selectedValue)"> | ||||||
|  |             @this.SelectedValueName() | ||||||
|  |         </MudButton> | ||||||
|  |     } | ||||||
|  |     <MudMenu Icon="@Icons.Material.Filled.ArrowDropDown" Style="align-self: auto;"> | ||||||
|  |         @foreach(var item in this.Items) | ||||||
|  |         { | ||||||
|  |             <MudMenuItem OnClick="() => this.SelectItem(item)"> | ||||||
|  |                 @this.NameFunc(item) | ||||||
|  |             </MudMenuItem> | ||||||
|  |         } | ||||||
|  |     </MudMenu> | ||||||
|  | </MudButtonGroup> | ||||||
| @ -0,0 +1,64 @@ | |||||||
|  | using Microsoft.AspNetCore.Components; | ||||||
|  | 
 | ||||||
|  | namespace AIStudio.Components.Blocks; | ||||||
|  | 
 | ||||||
|  | public partial class SplitButton<T> : ComponentBase | ||||||
|  | { | ||||||
|  |     [Parameter] | ||||||
|  |     public Color Color { get; set; } = Color.Default; | ||||||
|  |      | ||||||
|  |     [Parameter] | ||||||
|  |     public string Icon { get; set; } = string.Empty; | ||||||
|  | 
 | ||||||
|  |     [Parameter] | ||||||
|  |     public IReadOnlyCollection<T> Items { get; set; } = []; | ||||||
|  |      | ||||||
|  |     [Parameter] | ||||||
|  |     public Func<T, string> NameFunc { get; set; } = _ => string.Empty; | ||||||
|  |      | ||||||
|  |     [Parameter] | ||||||
|  |     public T? PreselectedValue { get; set; } | ||||||
|  |      | ||||||
|  |     [Parameter] | ||||||
|  |     public Func<T?, Task> OnClick { get; set; } = _ => Task.CompletedTask; | ||||||
|  |      | ||||||
|  |     /// <summary> | ||||||
|  |     /// What happens when the user selects an item by the dropdown? | ||||||
|  |     /// Immediate = true means that the OnClick event is triggered immediately | ||||||
|  |     /// after the user selects an item. Immediate = false means that the OnClick | ||||||
|  |     /// event is triggered only when the user clicks the button. | ||||||
|  |     /// </summary> | ||||||
|  |     [Parameter] | ||||||
|  |     public bool Immediate { get; set; } | ||||||
|  | 
 | ||||||
|  |     #region Overrides of ComponentBase | ||||||
|  | 
 | ||||||
|  |     protected override async Task OnInitializedAsync() | ||||||
|  |     { | ||||||
|  |         if(this.PreselectedValue is not null) | ||||||
|  |             this.selectedValue = this.PreselectedValue; | ||||||
|  |         else | ||||||
|  |             this.selectedValue = this.Items.FirstOrDefault(); | ||||||
|  |          | ||||||
|  |         await base.OnInitializedAsync(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #endregion | ||||||
|  | 
 | ||||||
|  |     private T? selectedValue; | ||||||
|  |      | ||||||
|  |     private string SelectedValueName() | ||||||
|  |     { | ||||||
|  |         if(this.selectedValue is null) | ||||||
|  |             return "Select..."; | ||||||
|  |          | ||||||
|  |         return this.NameFunc(this.selectedValue!); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private void SelectItem(T item) | ||||||
|  |     { | ||||||
|  |         this.selectedValue = item; | ||||||
|  |         if(this.Immediate) | ||||||
|  |             this.OnClick(this.selectedValue); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -51,12 +51,12 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis | |||||||
|      |      | ||||||
|     private static readonly IReadOnlyCollection<NavBarItem> NAV_ITEMS = new List<NavBarItem> |     private static readonly IReadOnlyCollection<NavBarItem> NAV_ITEMS = new List<NavBarItem> | ||||||
|     { |     { | ||||||
|         new("Home", Icons.Material.Filled.Home, Color.Default, "/", true), |         new("Home", Icons.Material.Filled.Home, Color.Default, Pages.Path.HOME, true), | ||||||
|         new("Chat", Icons.Material.Filled.Chat, Color.Default, "/chat", false), |         new("Chat", Icons.Material.Filled.Chat, Color.Default, Pages.Path.CHAT, false), | ||||||
|         new("Assistants", Icons.Material.Filled.Apps, Color.Default ,"/assistants", false), |         new("Assistants", Icons.Material.Filled.Apps, Color.Default, Pages.Path.ASSISTANTS, false), | ||||||
|         new("Supporters", Icons.Material.Filled.Favorite, Color.Error ,"/supporters", false), |         new("Supporters", Icons.Material.Filled.Favorite, Color.Error, Pages.Path.SUPPORTERS, false), | ||||||
|         new("About", Icons.Material.Filled.Info, Color.Default ,"/about", false), |         new("About", Icons.Material.Filled.Info, Color.Default, Pages.Path.ABOUT, false), | ||||||
|         new("Settings", Icons.Material.Filled.Settings, Color.Default ,"/settings", false), |         new("Settings", Icons.Material.Filled.Settings, Color.Default, Pages.Path.SETTINGS, false), | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|     #region Overrides of ComponentBase |     #region Overrides of ComponentBase | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/about" | @attribute [Route(Path.ABOUT)] | ||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| 
 | 
 | ||||||
| <MudText Typo="Typo.h3" Class="mb-2">About MindWork AI Studio</MudText> | <MudText Typo="Typo.h3" Class="mb-2">About MindWork AI Studio</MudText> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistant/agenda" | @attribute [Route(Path.ASSISTANT_AGENDA)] | ||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistants" | @attribute [Route(Path.ASSISTANTS)] | ||||||
| 
 | 
 | ||||||
| <MudText Typo="Typo.h3" Class="mb-2 mr-3"> | <MudText Typo="Typo.h3" Class="mb-2 mr-3"> | ||||||
|     Assistants |     Assistants | ||||||
| @ -10,25 +10,25 @@ | |||||||
|         General |         General | ||||||
|     </MudText> |     </MudText> | ||||||
|     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> |     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> | ||||||
|         <AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/> |         <AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="@Path.ASSISTANT_SUMMARIZER"/> | ||||||
|         <AssistantBlock Name="Translation" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translation"/> |         <AssistantBlock Name="Translation" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="@Path.ASSISTANT_TRANSLATION"/> | ||||||
|         <AssistantBlock Name="Grammar & Spelling" Description="Check grammar and spelling of a given text." Icon="@Icons.Material.Filled.Edit" Link="/assistant/grammar-spelling"/> |         <AssistantBlock Name="Grammar & Spelling" Description="Check grammar and spelling of a given text." Icon="@Icons.Material.Filled.Edit" Link="@Path.ASSISTANT_GRAMMAR_SPELLING"/> | ||||||
|         <AssistantBlock Name="Rewrite & Improve" Description="Rewrite and improve a given text for a chosen style." Icon="@Icons.Material.Filled.Edit" Link="/assistant/rewrite-improve"/> |         <AssistantBlock Name="Rewrite & Improve" Description="Rewrite and improve a given text for a chosen style." Icon="@Icons.Material.Filled.Edit" Link="@Path.ASSISTANT_REWRITE"/> | ||||||
|     </MudStack> |     </MudStack> | ||||||
| 
 | 
 | ||||||
|     <MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6"> |     <MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6"> | ||||||
|         Business |         Business | ||||||
|     </MudText> |     </MudText> | ||||||
|     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> |     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> | ||||||
|         <AssistantBlock Name="Agenda Planner" Description="Generate an agenda for a given meeting, seminar, etc." Icon="@Icons.Material.Filled.CalendarToday" Link="/assistant/agenda"/> |         <AssistantBlock Name="Agenda Planner" Description="Generate an agenda for a given meeting, seminar, etc." Icon="@Icons.Material.Filled.CalendarToday" Link="@Path.ASSISTANT_AGENDA"/> | ||||||
|         <AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="/assistant/icons"/> |         <AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="@Path.ASSISTANT_ICON_FINDER"/> | ||||||
|     </MudStack> |     </MudStack> | ||||||
| 
 | 
 | ||||||
|     <MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6"> |     <MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6"> | ||||||
|         Software Engineering |         Software Engineering | ||||||
|     </MudText> |     </MudText> | ||||||
|     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> |     <MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3"> | ||||||
|         <AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="/assistant/coding"/> |         <AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="@Path.ASSISTANT_CODING"/> | ||||||
|     </MudStack> |     </MudStack> | ||||||
|      |      | ||||||
| </InnerScrolling> | </InnerScrolling> | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/chat" | @attribute [Route(Path.CHAT)] | ||||||
| @using AIStudio.Chat | @using AIStudio.Chat | ||||||
| @using AIStudio.Settings.DataModel | @using AIStudio.Settings.DataModel | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -250,11 +250,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable | |||||||
|             string chatPath; |             string chatPath; | ||||||
|             if (this.chatThread.WorkspaceId == Guid.Empty) |             if (this.chatThread.WorkspaceId == Guid.Empty) | ||||||
|             { |             { | ||||||
|                 chatPath = Path.Join(SettingsManager.DataDirectory, "tempChats", this.chatThread.ChatId.ToString()); |                 chatPath = System.IO.Path.Join(SettingsManager.DataDirectory, "tempChats", this.chatThread.ChatId.ToString()); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 chatPath = Path.Join(SettingsManager.DataDirectory, "workspaces", this.chatThread.WorkspaceId.ToString(), this.chatThread.ChatId.ToString()); |                 chatPath = System.IO.Path.Join(SettingsManager.DataDirectory, "workspaces", this.chatThread.WorkspaceId.ToString(), this.chatThread.ChatId.ToString()); | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             await this.workspaces.DeleteChat(chatPath, askForConfirmation: false, unloadChat: true); |             await this.workspaces.DeleteChat(chatPath, askForConfirmation: false, unloadChat: true); | ||||||
| @ -327,12 +327,12 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable | |||||||
|         if (this.chatThread!.WorkspaceId == Guid.Empty) |         if (this.chatThread!.WorkspaceId == Guid.Empty) | ||||||
|         { |         { | ||||||
|             // Case: The chat is stored in the temporary storage: |             // Case: The chat is stored in the temporary storage: | ||||||
|             await this.workspaces.DeleteChat(Path.Join(SettingsManager.DataDirectory, "tempChats", this.chatThread.ChatId.ToString()), askForConfirmation: false, unloadChat: false); |             await this.workspaces.DeleteChat(System.IO.Path.Join(SettingsManager.DataDirectory, "tempChats", this.chatThread.ChatId.ToString()), askForConfirmation: false, unloadChat: false); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             // Case: The chat is stored in a workspace. |             // Case: The chat is stored in a workspace. | ||||||
|             await this.workspaces.DeleteChat(Path.Join(SettingsManager.DataDirectory, "workspaces", this.chatThread.WorkspaceId.ToString(), this.chatThread.ChatId.ToString()), askForConfirmation: false, unloadChat: false); |             await this.workspaces.DeleteChat(System.IO.Path.Join(SettingsManager.DataDirectory, "workspaces", this.chatThread.WorkspaceId.ToString(), this.chatThread.ChatId.ToString()), askForConfirmation: false, unloadChat: false); | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         this.chatThread!.WorkspaceId = workspaceId; |         this.chatThread!.WorkspaceId = workspaceId; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistant/coding" | @attribute [Route(Path.ASSISTANT_CODING)] | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
| <MudExpansionPanels Class="mb-3"> | <MudExpansionPanels Class="mb-3"> | ||||||
|  | |||||||
| @ -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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| @page "/assistant/grammar-spelling" | @attribute [Route(Path.ASSISTANT_GRAMMAR_SPELLING)] | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
| <MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to check" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | <MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to check" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | ||||||
|  | |||||||
| @ -25,11 +25,17 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore | |||||||
|      |      | ||||||
|     protected override bool ShowDedicatedProgress => true; |     protected override bool ShowDedicatedProgress => true; | ||||||
|      |      | ||||||
|     protected override IReadOnlyList<ButtonData> FooterButtons => new[] |     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 | ||||||
| 
 | 
 | ||||||
|     protected override async Task OnInitializedAsync() |     protected override async Task OnInitializedAsync() | ||||||
| @ -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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/" | @attribute [Route(Path.HOME)] | ||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| 
 | 
 | ||||||
| <MudImage Src="svg/banner.svg" /> | <MudImage Src="svg/banner.svg" /> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistant/icons" | @attribute [Route(Path.ASSISTANT_ICON_FINDER)] | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
| <MudTextField T="string" @bind-Text="@this.inputContext" Validation="@this.ValidatingContext" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Label="Your context" Variant="Variant.Outlined" Lines="3" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | <MudTextField T="string" @bind-Text="@this.inputContext" Validation="@this.ValidatingContext" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Label="Your context" Variant="Variant.Outlined" Lines="3" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | ||||||
|  | |||||||
| @ -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 => | ||||||
| @ -40,7 +27,34 @@ public partial class AssistantIconFinder : AssistantBaseCore | |||||||
|         related to the keyword "buildings" might be the best match. Provide your keywords in a Markdown list without |         related to the keyword "buildings" might be the best match. Provide your keywords in a Markdown list without | ||||||
|         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)) | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								app/MindWork AI Studio/Components/Pages/Path.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/MindWork AI Studio/Components/Pages/Path.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | namespace AIStudio.Components.Pages; | ||||||
|  | 
 | ||||||
|  | public static class Path | ||||||
|  | { | ||||||
|  |     public const string HOME = "/"; | ||||||
|  |     public const string CHAT = "/chat"; | ||||||
|  |     public const string ABOUT = "/about"; | ||||||
|  |     public const string ASSISTANTS = "/assistants"; | ||||||
|  |     public const string SETTINGS = "/settings"; | ||||||
|  |     public const string SUPPORTERS = "/supporters"; | ||||||
|  |      | ||||||
|  |     public const string ASSISTANT_TRANSLATION = "/assistant/translation"; | ||||||
|  |     public const string ASSISTANT_REWRITE = "/assistant/rewrite-improve"; | ||||||
|  |     public const string ASSISTANT_ICON_FINDER = "/assistant/icons"; | ||||||
|  |     public const string ASSISTANT_GRAMMAR_SPELLING = "/assistant/grammar-spelling"; | ||||||
|  |     public const string ASSISTANT_SUMMARIZER = "/assistant/summarizer"; | ||||||
|  |     public const string ASSISTANT_CODING = "/assistant/coding"; | ||||||
|  |     public const string ASSISTANT_AGENDA = "/assistant/agenda"; | ||||||
|  | } | ||||||
| @ -1,5 +1,5 @@ | |||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| @page "/assistant/rewrite-improve" | @attribute [Route(Path.ASSISTANT_REWRITE)] | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
| <MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to improve" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | <MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to improve" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/> | ||||||
|  | |||||||
| @ -24,17 +24,19 @@ public partial class AssistantRewriteImprove : AssistantBaseCore | |||||||
|      |      | ||||||
|     protected override bool ShowResult => false; |     protected override bool ShowResult => false; | ||||||
| 
 | 
 | ||||||
|     #region Overrides of AssistantBase |  | ||||||
| 
 |  | ||||||
|     protected override bool ShowDedicatedProgress => true; |     protected override bool ShowDedicatedProgress => true; | ||||||
| 
 | 
 | ||||||
|     #endregion |     protected override IReadOnlyList<IButtonData> FooterButtons => | ||||||
| 
 |     [ | ||||||
|     protected override IReadOnlyList<ButtonData> FooterButtons => new[] |  | ||||||
|     { |  | ||||||
|         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 | ||||||
| 
 | 
 | ||||||
|     protected override async Task OnInitializedAsync() |     protected override async Task OnInitializedAsync() | ||||||
| @ -47,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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								app/MindWork AI Studio/Components/Pages/SendToAssistant.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/MindWork AI Studio/Components/Pages/SendToAssistant.cs
									
									
									
									
									
										Normal 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, | ||||||
|  | } | ||||||
| @ -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 ...", | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/settings" | @attribute [Route(Path.SETTINGS)] | ||||||
| @using AIStudio.Components.Pages.Coding | @using AIStudio.Components.Pages.Coding | ||||||
| @using AIStudio.Components.Pages.TextSummarizer | @using AIStudio.Components.Pages.TextSummarizer | ||||||
| @using AIStudio.Provider | @using AIStudio.Provider | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/Supporters" | @attribute [Route(Path.SUPPORTERS)] | ||||||
| 
 | 
 | ||||||
| <MudText Typo="Typo.h3" Class="mb-2">Supporters</MudText> | <MudText Typo="Typo.h3" Class="mb-2">Supporters</MudText> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistant/summarizer" | @attribute [Route(Path.ASSISTANT_SUMMARIZER)] | ||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @page "/assistant/translation" | @attribute [Route(Path.ASSISTANT_TRANSLATION)] | ||||||
| @using AIStudio.Tools | @using AIStudio.Tools | ||||||
| @inherits AssistantBaseCore | @inherits AssistantBaseCore | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,3 +1,6 @@ | |||||||
| namespace AIStudio.Tools; | namespace AIStudio.Tools; | ||||||
| 
 | 
 | ||||||
| public readonly record struct ButtonData(string Text, string Icon, Color Color, string Tooltip, Func<Task> AsyncAction); | public readonly record struct ButtonData(string Text, string Icon, Color Color, string Tooltip, Func<Task> AsyncAction) : IButtonData | ||||||
|  | { | ||||||
|  |     public ButtonTypes Type => ButtonTypes.BUTTON; | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								app/MindWork AI Studio/Tools/ButtonTypes.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/MindWork AI Studio/Tools/ButtonTypes.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | namespace AIStudio.Tools; | ||||||
|  | 
 | ||||||
|  | public enum ButtonTypes | ||||||
|  | { | ||||||
|  |     BUTTON = 0, | ||||||
|  |     SEND_TO, | ||||||
|  | } | ||||||
| @ -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, | ||||||
| } | } | ||||||
							
								
								
									
										6
									
								
								app/MindWork AI Studio/Tools/IButtonData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/MindWork AI Studio/Tools/IButtonData.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | namespace AIStudio.Tools; | ||||||
|  | 
 | ||||||
|  | public interface IButtonData | ||||||
|  | { | ||||||
|  |     public ButtonTypes Type { get; } | ||||||
|  | } | ||||||
| @ -11,6 +11,7 @@ public sealed class MessageBus | |||||||
|      |      | ||||||
|     private readonly ConcurrentDictionary<IMessageBusReceiver, ComponentBase[]> componentFilters = new(); |     private readonly ConcurrentDictionary<IMessageBusReceiver, ComponentBase[]> componentFilters = new(); | ||||||
|     private readonly ConcurrentDictionary<IMessageBusReceiver, Event[]> componentEvents = new(); |     private readonly ConcurrentDictionary<IMessageBusReceiver, Event[]> componentEvents = new(); | ||||||
|  |     private readonly ConcurrentDictionary<Event, ConcurrentQueue<Message>> deferredMessages = new(); | ||||||
|     private readonly ConcurrentQueue<Message> messageQueue = new(); |     private readonly ConcurrentQueue<Message> messageQueue = new(); | ||||||
|     private readonly SemaphoreSlim sendingSemaphore = new(1, 1); |     private readonly SemaphoreSlim sendingSemaphore = new(1, 1); | ||||||
| 
 | 
 | ||||||
| @ -65,6 +66,24 @@ public sealed class MessageBus | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     public void DeferMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data = default) | ||||||
|  |     { | ||||||
|  |         if (this.deferredMessages.TryGetValue(triggeredEvent, out var queue)) | ||||||
|  |             queue.Enqueue(new Message(sendingComponent, triggeredEvent, data)); | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             this.deferredMessages[triggeredEvent] = new(); | ||||||
|  |             this.deferredMessages[triggeredEvent].Enqueue(new Message(sendingComponent, triggeredEvent, data)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public IEnumerable<T?> CheckDeferredMessages<T>(Event triggeredEvent) | ||||||
|  |     { | ||||||
|  |         if (this.deferredMessages.TryGetValue(triggeredEvent, out var queue)) | ||||||
|  |             while (queue.TryDequeue(out var message)) | ||||||
|  |                 yield return message.Data is T data ? data : default; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     public async Task<TResult?> SendMessageUseFirstResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data = default) |     public async Task<TResult?> SendMessageUseFirstResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data = default) | ||||||
|     { |     { | ||||||
|         foreach (var (receiver, componentFilter) in this.componentFilters) |         foreach (var (receiver, componentFilter) in this.componentFilters) | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								app/MindWork AI Studio/Tools/SendToButton.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/MindWork AI Studio/Tools/SendToButton.cs
									
									
									
									
									
										Normal 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; | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								app/MindWork AI Studio/wwwroot/changelog/v0.8.9.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/MindWork AI Studio/wwwroot/changelog/v0.8.9.md
									
									
									
									
									
										Normal 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 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user