Bias of the day (#173)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2024-10-28 15:41:00 +01:00
1 parent e9c805f0df
commit 217b9c4db3
20 files changed
+491 -35

No files matched your search

@@ -48,17 +48,20 @@
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
{
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().OrderBy(n => n.Name().Length))
{
if (assistant is Components.NONE || this.Component == assistant)
continue;
@if (this.ShowSendTo)
{
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().OrderBy(n => n.Name().Length))
{
if (assistant is Components.NONE || this.Component == assistant)
continue;
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
@assistant.Name()
</MudMenuItem>
}
</MudMenu>
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
@assistant.Name()
</MudMenuItem>
}
</MudMenu>
}
}
@foreach (var button in this.FooterButtons)
@@ -95,13 +98,19 @@
}
}
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
Copy result
</MudButton>
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
Reset
</MudButton>
@if (this.ShowCopyResult)
{
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
Copy result
</MudButton>
}
@if (this.ShowReset)
{
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
Reset
</MudButton>
}
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
{
@@ -74,6 +74,12 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
protected virtual bool ShowProfileSelection => true;
protected virtual bool ShowDedicatedProgress => false;
protected virtual bool ShowSendTo => true;
protected virtual bool ShowCopyResult => true;
protected virtual bool ShowReset => true;
protected virtual ChatThread ConvertToChatThread => this.chatThread ?? new();
@@ -173,14 +179,36 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
Blocks = [],
};
}
protected Guid CreateChatThread(Guid workspaceId, string name)
{
var chatId = Guid.NewGuid();
this.chatThread = new()
{
WorkspaceId = workspaceId,
ChatId = chatId,
Name = name,
Seed = this.RNG.Next(),
SystemPrompt = !this.AllowProfiles ? this.SystemPrompt :
$"""
{this.SystemPrompt}
{this.currentProfile.ToSystemPrompt()}
""",
Blocks = [],
};
return chatId;
}
protected DateTimeOffset AddUserRequest(string request)
protected DateTimeOffset AddUserRequest(string request, bool hideContentFromUser = false)
{
var time = DateTimeOffset.Now;
this.chatThread!.Blocks.Add(new ContentBlock
{
Time = time,
ContentType = ContentType.TEXT,
HideFromUser = hideContentFromUser,
Role = ChatRole.USER,
Content = new ContentText
{
@@ -237,9 +265,9 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
return icon;
}
private Task SendToAssistant(Tools.Components destination, SendToButton sendToButton)
protected Task SendToAssistant(Tools.Components destination, SendToButton sendToButton)
{
var contentToSend = sendToButton.UseResultingContentBlockData switch
var contentToSend = sendToButton == default ? string.Empty : sendToButton.UseResultingContentBlockData switch
{
false => sendToButton.GetText(),
true => this.resultingContentBlock?.Content switch
@@ -0,0 +1,14 @@
@attribute [Route(Routes.ASSISTANT_BIAS)]
@inherits AssistantBaseCore
<MudText Typo="Typo.body1">
<b>Links:</b>
</MudText>
<MudList T="string" Class="mb-6">
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://en.wikipedia.org/wiki/List_of_cognitive_biases">Wikipedia list of cognitive biases</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">Extended bias poster</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">Blog post of Buster Benson: "Cognitive bias cheat sheet"</MudListItem>
</MudList>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" 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"/>
@@ -0,0 +1,164 @@
using System.Text;
using AIStudio.Components;
using AIStudio.Settings.DataModel;
namespace AIStudio.Assistants.BiasDay;
public partial class BiasOfTheDayAssistant : AssistantBaseCore
{
public override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT;
protected override string Title => "Bias of the Day";
protected override string Description =>
"""
Learn about a different cognitive bias every day. You can also ask the LLM your questions. The idea behind
"Bias of the Day" is based on work by Buster Benson, John Manoogian III, and Brian Rene Morrissette. Buster
Benson grouped the biases, and the original texts come from Wikipedia. Brian Rene Morrissette condensed them
into a shorter version. Finally, John Manoogian III created the original poster based on Benson's work and
Morrissette's texts. Thorsten Sommer compared all texts for integration into AI Studio with the current Wikipedia
versions, updated them, and added source references. The idea of learning about one bias each day based on John's
poster comes from Drew Nelson.
""";
protected override string SystemPrompt => $"""
You are a friendly, helpful expert on cognitive bias. You studied psychology and
have a lot of experience. You explain a bias every day. Today's bias belongs to
the category: "{this.biasOfTheDay.Category.ToName()}". We have the following
thoughts on this category:
{this.biasOfTheDay.Category.GetThoughts()}
Today's bias is:
{this.biasOfTheDay.Description}
{this.SystemPromptSources()}
Important: you use the following language: {this.SystemPromptLanguage()}. Please
ask the user a personal question at the end to encourage them to think about
this bias.
""";
protected override IReadOnlyList<IButtonData> FooterButtons => [];
protected override string SubmitText => "Show me the bias of the day";
protected override Func<Task> SubmitAction => this.TellBias;
protected override bool ShowSendTo => false;
protected override bool ShowCopyResult => false;
protected override bool ShowReset => false;
protected override void ResetFrom()
{
if (!this.MightPreselectValues())
{
this.selectedTargetLanguage = CommonLanguages.AS_IS;
this.customTargetLanguage = string.Empty;
}
}
protected override bool MightPreselectValues()
{
if (this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)
{
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage;
return true;
}
return false;
}
private Bias biasOfTheDay = BiasCatalog.NONE;
private CommonLanguages selectedTargetLanguage = CommonLanguages.AS_IS;
private string customTargetLanguage = string.Empty;
private string? ValidateTargetLanguage(CommonLanguages language)
{
if(language is CommonLanguages.AS_IS)
return "Please select a target language for the bias.";
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 SystemPromptSources()
{
var sb = new StringBuilder();
if (this.biasOfTheDay.Links.Count > 0)
{
sb.AppendLine();
sb.AppendLine("Please share the following sources with the user as a Markdown list:");
foreach (var link in this.biasOfTheDay.Links)
sb.AppendLine($"- {link}");
sb.AppendLine();
}
return sb.ToString();
}
private string SystemPromptLanguage()
{
if(this.selectedTargetLanguage is CommonLanguages.OTHER)
return this.customTargetLanguage;
return this.selectedTargetLanguage.Name();
}
private async Task TellBias()
{
bool useDrawnBias = false;
if(this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay)
{
if(this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn == DateOnly.FromDateTime(DateTime.Now))
{
var biasChat = new LoadChat
{
WorkspaceId = Workspaces.WORKSPACE_ID_BIAS,
ChatId = this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayChatId,
};
if (Workspaces.IsChatExisting(biasChat))
{
MessageBus.INSTANCE.DeferMessage(this, Event.LOAD_CHAT, biasChat);
this.NavigationManager.NavigateTo(Routes.CHAT);
return;
}
else
useDrawnBias = true;
}
}
await this.form!.Validate();
if (!this.inputIsValid)
return;
this.biasOfTheDay = useDrawnBias ?
BiasCatalog.ALL_BIAS[this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayId] :
BiasCatalog.GetRandomBias(this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias);
var chatId = this.CreateChatThread(Workspaces.WORKSPACE_ID_BIAS, this.biasOfTheDay.Name);
this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayId = this.biasOfTheDay.Id;
this.SettingsManager.ConfigurationData.BiasOfTheDay.BiasOfTheDayChatId = chatId;
this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn = DateOnly.FromDateTime(DateTime.Now);
await this.SettingsManager.StoreSettings();
var time = this.AddUserRequest(
"""
Please tell me about the bias of the day.
""", true);
// Start the AI response without waiting for it to finish:
_ = this.AddAIResponseAsync(time);
await this.SendToAssistant(Tools.Components.CHAT, default);
}
}