mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-02-05 14:49:06 +00:00
Implemented the "my tasks" assistant (#137)
This commit is contained in:
parent
7a5f2d4aec
commit
09f5b83e66
@ -94,7 +94,7 @@
|
||||
Reset
|
||||
</MudButton>
|
||||
|
||||
@if (this.AllowProfiles)
|
||||
@if (this.AllowProfiles && this.ShowProfileSelection)
|
||||
{
|
||||
<ProfileSelection MarginLeft="" @bind-CurrentProfile="@this.currentProfile"/>
|
||||
}
|
||||
|
@ -57,6 +57,8 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
protected virtual bool ShowResult => true;
|
||||
|
||||
protected virtual bool AllowProfiles => true;
|
||||
|
||||
protected virtual bool ShowProfileSelection => true;
|
||||
|
||||
protected virtual bool ShowDedicatedProgress => false;
|
||||
|
||||
@ -69,12 +71,12 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
protected AIStudio.Settings.Provider providerSettings;
|
||||
protected MudForm? form;
|
||||
protected bool inputIsValid;
|
||||
protected Profile currentProfile = Profile.NO_PROFILE;
|
||||
|
||||
protected ChatThread? chatThread;
|
||||
private ContentBlock? resultingContentBlock;
|
||||
private string[] inputIssues = [];
|
||||
private bool isProcessing;
|
||||
private Profile currentProfile = Profile.NO_PROFILE;
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
@attribute [Route(Routes.ASSISTANT_MY_TASKS)]
|
||||
@inherits AssistantBaseCore
|
||||
|
||||
<ProfileFormSelection Validation="@this.ValidateProfile" @bind-Profile="@this.currentProfile"/>
|
||||
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Text or email" Variant="Variant.Outlined" Lines="12" AutoGrow="@true" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom target language" />
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.AnalyzeText()">
|
||||
Analyze text
|
||||
</MudButton>
|
@ -0,0 +1,119 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Assistants.MyTasks;
|
||||
|
||||
public partial class AssistantMyTasks : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.MY_TASKS_ASSISTANT;
|
||||
|
||||
protected override string Title => "My Tasks";
|
||||
|
||||
protected override string Description =>
|
||||
"""
|
||||
You received a cryptic email that was sent to many recipients and you are now wondering
|
||||
if you need to do something? Copy the email into the input field. You also need to select
|
||||
a personal profile. In this profile, you should describe your role in the organization.
|
||||
The AI will then try to give you hints on what your tasks might be.
|
||||
""";
|
||||
|
||||
protected override string SystemPrompt =>
|
||||
$"""
|
||||
You are a friendly and professional business expert. You receive business emails, protocols,
|
||||
reports, etc. as input. Additionally, you know the user's role in the organization. The user
|
||||
wonders if any tasks arise for them in their role based on the text. You now try to give hints
|
||||
and advice on whether and what the user should do. When you believe there are no tasks for the
|
||||
user, you tell them this. You consider typical business etiquette in your advice.
|
||||
|
||||
You write your advice in the following language: {this.SystemPromptLanguage()}.
|
||||
""";
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override bool ShowProfileSelection => false;
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
this.inputText = string.Empty;
|
||||
if (!this.MightPreselectValues())
|
||||
{
|
||||
this.selectedTargetLanguage = CommonLanguages.AS_IS;
|
||||
this.customTargetLanguage = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool MightPreselectValues()
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)
|
||||
{
|
||||
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.MyTasks.PreselectedTargetLanguage;
|
||||
this.customTargetLanguage = this.SettingsManager.ConfigurationData.MyTasks.PreselectOtherLanguage;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string inputText = string.Empty;
|
||||
private CommonLanguages selectedTargetLanguage = CommonLanguages.AS_IS;
|
||||
private string customTargetLanguage = string.Empty;
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_MY_TASKS_ASSISTANT).FirstOrDefault();
|
||||
if (deferredContent is not null)
|
||||
this.inputText = deferredContent;
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string? ValidatingText(string text)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(text))
|
||||
return "Please provide some text as input. For example, an email.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string? ValidateProfile(Profile profile)
|
||||
{
|
||||
if(profile == default || profile == Profile.NO_PROFILE)
|
||||
return "Please select one of your profiles.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string? ValidateCustomLanguage(string language)
|
||||
{
|
||||
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
||||
return "Please provide a custom language.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string SystemPromptLanguage()
|
||||
{
|
||||
if(this.selectedTargetLanguage is CommonLanguages.AS_IS)
|
||||
return "Use the same language as the input";
|
||||
|
||||
if(this.selectedTargetLanguage is CommonLanguages.OTHER)
|
||||
return this.customTargetLanguage;
|
||||
|
||||
return this.selectedTargetLanguage.Name();
|
||||
}
|
||||
|
||||
private async Task AnalyzeText()
|
||||
{
|
||||
await this.form!.Validate();
|
||||
if (!this.inputIsValid)
|
||||
return;
|
||||
|
||||
this.CreateChatThread();
|
||||
var time = this.AddUserRequest(this.inputText);
|
||||
|
||||
await this.AddAIResponseAsync(time);
|
||||
}
|
||||
}
|
10
app/MindWork AI Studio/Components/ProfileFormSelection.razor
Normal file
10
app/MindWork AI Studio/Components/ProfileFormSelection.razor
Normal file
@ -0,0 +1,10 @@
|
||||
@using AIStudio.Settings
|
||||
|
||||
<MudSelect T="Profile" Strict="@true" Value="@this.Profile" ValueChanged="@this.SelectionChanged" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person4" Margin="Margin.Dense" Label="Select one of your profiles" Variant="Variant.Outlined" Class="mb-3" Validation="@this.Validation">
|
||||
@foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles())
|
||||
{
|
||||
<MudSelectItem Value="profile">
|
||||
@profile.Name
|
||||
</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
@ -0,0 +1,26 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public partial class ProfileFormSelection : ComponentBase
|
||||
{
|
||||
[Parameter]
|
||||
public Profile Profile { get; set; } = Profile.NO_PROFILE;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<Profile> ProfileChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Func<Profile, string?> Validation { get; set; } = _ => null;
|
||||
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
private async Task SelectionChanged(Profile profile)
|
||||
{
|
||||
this.Profile = profile;
|
||||
await this.ProfileChanged.InvokeAsync(profile);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
</MudText>
|
||||
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
|
||||
<AssistantBlock Name="E-Mail" Description="Generate an e-mail for a given context." Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
|
||||
<AssistantBlock Name="My Tasks" Description="Analyze a text or an email for tasks you need to complete." Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
|
||||
<AssistantBlock Name="Agenda Planner" Description="Generate an agenda for a given meeting, seminar, etc." Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
|
||||
<AssistantBlock Name="Legal Check" Description="Ask a question about a legal document." Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
|
||||
<AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
|
||||
|
@ -299,6 +299,19 @@
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Synonyms.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Synonyms.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Synonyms.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Task" HeaderText="Assistant: My Tasks">
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
<ConfigurationOption OptionDescription="Preselect options?" LabelOn="Options are preselected" LabelOff="No options are preselected" State="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect options. This is might be useful when you prefer a specific language or LLM model."/>
|
||||
<ConfigurationSelect OptionDescription="Preselect the language" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.PreselectedTargetLanguage = selectedValue)" OptionHelp="Which language should be preselected?"/>
|
||||
@if (this.SettingsManager.ConfigurationData.MyTasks.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another language" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.MyTasks.PreselectOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="Agent: Text Content Cleaner Options">
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
|
@ -20,5 +20,6 @@ public sealed partial class Routes
|
||||
public const string ASSISTANT_EMAIL = "/assistant/email";
|
||||
public const string ASSISTANT_LEGAL_CHECK = "/assistant/legal-check";
|
||||
public const string ASSISTANT_SYNONYMS = "/assistant/synonyms";
|
||||
public const string ASSISTANT_MY_TASKS = "/assistant/my-tasks";
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
@ -58,4 +58,6 @@ public sealed class Data
|
||||
public DataLegalCheck LegalCheck { get; set; } = new();
|
||||
|
||||
public DataSynonyms Synonyms { get; set; } = new();
|
||||
|
||||
public DataMyTasks MyTasks { get; set; } = new();
|
||||
}
|
29
app/MindWork AI Studio/Settings/DataModel/DataMyTasks.cs
Normal file
29
app/MindWork AI Studio/Settings/DataModel/DataMyTasks.cs
Normal file
@ -0,0 +1,29 @@
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataMyTasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Do you want to preselect any options?
|
||||
/// </summary>
|
||||
public bool PreselectOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preselect the target language?
|
||||
/// </summary>
|
||||
public CommonLanguages PreselectedTargetLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preselect any other language?
|
||||
/// </summary>
|
||||
public string PreselectOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected provider.
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a profile?
|
||||
/// </summary>
|
||||
public string PreselectedProfile { get; set; } = string.Empty;
|
||||
}
|
@ -129,6 +129,7 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
||||
Tools.Components.EMAIL_ASSISTANT => this.ConfigurationData.EMail.PreselectOptions ? this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.EMail.PreselectedProvider) : default,
|
||||
Tools.Components.LEGAL_CHECK_ASSISTANT => this.ConfigurationData.LegalCheck.PreselectOptions ? this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.LegalCheck.PreselectedProvider) : default,
|
||||
Tools.Components.SYNONYMS_ASSISTANT => this.ConfigurationData.Synonyms.PreselectOptions ? this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.Synonyms.PreselectedProvider) : default,
|
||||
Tools.Components.MY_TASKS_ASSISTANT => this.ConfigurationData.MyTasks.PreselectOptions ? this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.MyTasks.PreselectedProvider) : default,
|
||||
|
||||
_ => default,
|
||||
};
|
||||
@ -148,6 +149,7 @@ public sealed class SettingsManager(ILogger<SettingsManager> logger)
|
||||
Tools.Components.CODING_ASSISTANT => this.ConfigurationData.Coding.PreselectOptions ? this.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == this.ConfigurationData.Coding.PreselectedProfile) : default,
|
||||
Tools.Components.EMAIL_ASSISTANT => this.ConfigurationData.EMail.PreselectOptions ? this.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == this.ConfigurationData.EMail.PreselectedProfile) : default,
|
||||
Tools.Components.LEGAL_CHECK_ASSISTANT => this.ConfigurationData.LegalCheck.PreselectOptions ? this.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == this.ConfigurationData.LegalCheck.PreselectedProfile) : default,
|
||||
Tools.Components.MY_TASKS_ASSISTANT => this.ConfigurationData.MyTasks.PreselectOptions ? this.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == this.ConfigurationData.MyTasks.PreselectedProfile) : default,
|
||||
|
||||
_ => default,
|
||||
};
|
||||
|
@ -14,6 +14,7 @@ public enum Components
|
||||
EMAIL_ASSISTANT,
|
||||
LEGAL_CHECK_ASSISTANT,
|
||||
SYNONYMS_ASSISTANT,
|
||||
MY_TASKS_ASSISTANT,
|
||||
|
||||
CHAT,
|
||||
}
|
@ -28,4 +28,5 @@ public enum Event
|
||||
SEND_TO_EMAIL_ASSISTANT,
|
||||
SEND_TO_LEGAL_CHECK_ASSISTANT,
|
||||
SEND_TO_SYNONYMS_ASSISTANT,
|
||||
SEND_TO_MY_TASKS_ASSISTANT,
|
||||
}
|
@ -14,6 +14,7 @@ public static class SendToExtensions
|
||||
Components.EMAIL_ASSISTANT => "E-Mail Assistant",
|
||||
Components.LEGAL_CHECK_ASSISTANT => "Legal Check Assistant",
|
||||
Components.SYNONYMS_ASSISTANT => "Synonym Assistant",
|
||||
Components.MY_TASKS_ASSISTANT => "My Tasks Assistant",
|
||||
|
||||
Components.CHAT => "New Chat",
|
||||
|
||||
@ -32,6 +33,7 @@ public static class SendToExtensions
|
||||
Components.TEXT_SUMMARIZER_ASSISTANT => new(Event.SEND_TO_TEXT_SUMMARIZER_ASSISTANT, Routes.ASSISTANT_SUMMARIZER),
|
||||
Components.LEGAL_CHECK_ASSISTANT => new(Event.SEND_TO_LEGAL_CHECK_ASSISTANT, Routes.ASSISTANT_LEGAL_CHECK),
|
||||
Components.SYNONYMS_ASSISTANT => new(Event.SEND_TO_SYNONYMS_ASSISTANT, Routes.ASSISTANT_SYNONYMS),
|
||||
Components.MY_TASKS_ASSISTANT => new(Event.SEND_TO_MY_TASKS_ASSISTANT, Routes.ASSISTANT_MY_TASKS),
|
||||
|
||||
Components.CHAT => new(Event.SEND_TO_CHAT, Routes.CHAT),
|
||||
|
||||
|
2
app/MindWork AI Studio/wwwroot/changelog/v0.9.8.md
Normal file
2
app/MindWork AI Studio/wwwroot/changelog/v0.9.8.md
Normal file
@ -0,0 +1,2 @@
|
||||
# v0.9.8, build 183 (2024-09-09 13:00 UTC)
|
||||
- Added the "my tasks" assistant to analyze, e.g., business emails and extract related tasks for your role.
|
Loading…
Reference in New Issue
Block a user