mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-19 23:18:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1d5be63cc | ||
|
|
5d3ea3d57a | ||
|
|
217b9c4db3 | ||
|
|
e9c805f0df | ||
|
|
11475ea4af | ||
|
|
46a7e98141 | ||
|
|
0d6ccbd237 | ||
|
|
efb30cad87 | ||
|
|
fe33867cb6 | ||
|
|
1b1989e8eb | ||
|
|
afa5df894e | ||
|
|
c8d67b1e4c | ||
|
|
e717b84fb4 | ||
|
|
2463c85b77 | ||
|
|
cbf34580b3 | ||
|
|
e60f815d77 | ||
|
|
a19a6b2188 | ||
|
|
d2dd90d089 | ||
|
|
37e113af0e | ||
|
|
776fa8ac58 | ||
|
|
8715054dda | ||
|
|
95da4c6410 | ||
|
|
92f5b49543 | ||
|
|
e6be9a593e | ||
|
|
375be805a1 | ||
|
|
b99866b8fe | ||
|
|
e9998348c5 | ||
|
|
0ad7b8d4dd | ||
|
|
4175387a93 | ||
|
|
1cac1a7913 | ||
|
|
5fa2f3c822 | ||
|
|
5608b48a2d | ||
|
|
bf01fbd706 | ||
|
|
4722c1baa1 |
No files matched your search
@@ -11,3 +11,7 @@ media/**/*.pptx filter=lfs diff=lfs merge=lfs -text
|
||||
media/**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||
media/**/*.ico filter=lfs diff=lfs merge=lfs -text
|
||||
media/**/*.icns filter=lfs diff=lfs merge=lfs -text
|
||||
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.afpub filter=lfs diff=lfs merge=lfs -text
|
||||
*.afdesign filter=lfs diff=lfs merge=lfs -text
|
||||
*.afphoto filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -278,7 +278,7 @@ jobs:
|
||||
if: matrix.platform != 'windows-latest'
|
||||
run: |
|
||||
if ! cargo tauri --version > /dev/null 2>&1; then
|
||||
cargo install tauri-cli
|
||||
cargo install --version 1.6.2 tauri-cli
|
||||
else
|
||||
echo "Tauri is already installed"
|
||||
fi
|
||||
@@ -287,7 +287,7 @@ jobs:
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: |
|
||||
if (-not (cargo tauri --version 2>$null)) {
|
||||
cargo install tauri-cli
|
||||
cargo install --version 1.6.2 tauri-cli
|
||||
} else {
|
||||
Write-Output "Tauri is already installed"
|
||||
}
|
||||
@@ -500,7 +500,7 @@ jobs:
|
||||
apt-get install --yes libwebkit2gtk-4.0-dev build-essential libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
|
||||
# Setup Tauri:
|
||||
cargo install tauri-cli
|
||||
cargo install --version 1.6.2 tauri-cli
|
||||
|
||||
- name: Add the built runner image to the cache
|
||||
if: ${{ steps.linux_arm_cache.outputs.cache-hit != 'true' && env.SKIP != 'true' }}
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
# MindWork AI Studio
|
||||
|
||||
## News
|
||||
Things we are currently working on:
|
||||
|
||||
- Since September 2024: Work on the first personal assistant. The first personal assistant is a specialist in cognitive bias. It should be able to explain to you what biases exist. We do not want to rely on the training data of the LLM. Instead, AI Studio will bring a large catalog of bias descriptions in the future. This requires a lot of editorial work because we need to collect and revise the information. Related PR: [~~#166~~](https://github.com/MindWorkAI/AI-Studio/pull/166), [#173](https://github.com/MindWorkAI/AI-Studio/pull/173).
|
||||
|
||||
|
||||
- Since September 2024: Experiments have been started on how we can work on long texts with AI Studio. Let's say you want to write a fantasy novel or create a complex project proposal and use LLM for support. The initial experiments were promising, but not yet satisfactory. We are testing further approaches until a satisfactory solution is found. Related PR: [#167](https://github.com/MindWorkAI/AI-Studio/pull/167).
|
||||
|
||||
|
||||
Other News:
|
||||
|
||||
- October 2024: We have our first financial supporter: Thank you @richard-stanton for financially supporting AI Studio. The supporter page in the app will be updated accordingly with the next update.
|
||||
|
||||
|
||||
- October 2024: The [German Aerospace Center (DLR)](https://en.wikipedia.org/wiki/German_Aerospace_Center) ([Website](https://www.dlr.de/en)) will use AI Studio at least within the scope of one project and will also contribute to its further development. This is great news.
|
||||
|
||||
|
||||
## What is AI Studio?
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="AI Studio" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/MindWork AI Studio/bin/Debug/net8.0/osx-arm64/mindworkAIStudio.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/MindWork AI Studio" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="RUNTIME_TYPE" value="coreclr" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/MindWork AI Studio/MindWork AI Studio.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value="net8.0" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,7 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Dev" type="CompoundRunConfigurationType">
|
||||
<toRun name="AI Studio" type="DotNetProject" />
|
||||
<toRun name="Tauri Dev" type="ShConfigurationType" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,5 +1,6 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LLM/@EntryIndexedValue">LLM</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LM/@EntryIndexedValue">LM</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSG/@EntryIndexedValue">MSG</s:String>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -48,8 +48,4 @@
|
||||
}
|
||||
|
||||
<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"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.CreateAgenda()">
|
||||
Create agenda
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -6,7 +6,7 @@ namespace AIStudio.Assistants.Agenda;
|
||||
|
||||
public partial class AssistantAgenda : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT;
|
||||
|
||||
protected override string Title => "Agenda Planner";
|
||||
|
||||
@@ -97,6 +97,10 @@ public partial class AssistantAgenda : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Create Agenda";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.CreateAgenda;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
<ChildContent>
|
||||
<MudForm @ref="@(this.form)" @bind-IsValid="@(this.inputIsValid)" @bind-Errors="@(this.inputIssues)" Class="pr-2">
|
||||
<MudText Typo="Typo.body1" Align="Align.Justify" Class="mb-6">
|
||||
@(this.Description)
|
||||
@this.Description
|
||||
</MudText>
|
||||
|
||||
@if (this.Body is not null)
|
||||
{
|
||||
@(this.Body)
|
||||
<CascadingValue Value="@this">
|
||||
@this.Body
|
||||
</CascadingValue>
|
||||
|
||||
<MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" Class="mb-3" OnClick="() => this.SubmitAction()" Style="@this.SubmitButtonStyle">
|
||||
@this.SubmitText
|
||||
</MudButton>
|
||||
}
|
||||
</MudForm>
|
||||
<Issues IssuesData="@(this.inputIssues)"/>
|
||||
@@ -26,6 +32,9 @@
|
||||
<div id="@RESULT_DIV_ID" class="mr-2 mt-3">
|
||||
</div>
|
||||
|
||||
<div id="@BEFORE_RESULT_DIV_ID" class="mt-3">
|
||||
</div>
|
||||
|
||||
@if (this.ShowResult && this.resultingContentBlock is not null)
|
||||
{
|
||||
<ContentBlockComponent Role="@(this.resultingContentBlock.Role)" Type="@(this.resultingContentBlock.ContentType)" Time="@(this.resultingContentBlock.Time)" Content="@(this.resultingContentBlock.Content)"/>
|
||||
@@ -39,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" Color="Color.Info">
|
||||
@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)
|
||||
@@ -71,7 +83,7 @@
|
||||
break;
|
||||
|
||||
case SendToButton sendToButton:
|
||||
<MudMenu StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="Send to ..." Variant="Variant.Filled" Color="Color.Info">
|
||||
<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 || sendToButton.Self == assistant)
|
||||
@@ -86,14 +98,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
|
||||
Copy result
|
||||
</MudButton>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Warning" 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)
|
||||
{
|
||||
<ConfidenceInfo Mode="ConfidenceInfoMode.BUTTON" LLMProvider="@this.providerSettings.UsedLLMProvider"/>
|
||||
}
|
||||
|
||||
@if (this.AllowProfiles && this.ShowProfileSelection)
|
||||
{
|
||||
<ProfileSelection MarginLeft="" @bind-CurrentProfile="@this.currentProfile"/>
|
||||
|
||||
@@ -8,7 +8,7 @@ using RustService = AIStudio.Tools.RustService;
|
||||
|
||||
namespace AIStudio.Assistants;
|
||||
|
||||
public abstract partial class AssistantBase : ComponentBase
|
||||
public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
{
|
||||
[Inject]
|
||||
protected SettingsManager SettingsManager { get; init; } = null!;
|
||||
@@ -31,8 +31,15 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
[Inject]
|
||||
protected ILogger<AssistantBase> Logger { get; init; } = null!;
|
||||
|
||||
internal const string AFTER_RESULT_DIV_ID = "afterAssistantResult";
|
||||
[Inject]
|
||||
private MudTheme ColorTheme { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
internal const string RESULT_DIV_ID = "assistantResult";
|
||||
internal const string BEFORE_RESULT_DIV_ID = "beforeAssistantResult";
|
||||
internal const string AFTER_RESULT_DIV_ID = "afterAssistantResult";
|
||||
|
||||
protected abstract string Title { get; }
|
||||
|
||||
@@ -40,7 +47,7 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
|
||||
protected abstract string SystemPrompt { get; }
|
||||
|
||||
protected abstract Tools.Components Component { get; }
|
||||
public abstract Tools.Components Component { get; }
|
||||
|
||||
protected virtual Func<string> Result2Copy => () => this.resultingContentBlock is null ? string.Empty : this.resultingContentBlock.Content switch
|
||||
{
|
||||
@@ -52,6 +59,12 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
|
||||
protected abstract bool MightPreselectValues();
|
||||
|
||||
protected abstract string SubmitText { get; }
|
||||
|
||||
protected abstract Func<Task> SubmitAction { get; }
|
||||
|
||||
protected virtual bool SubmitDisabled => false;
|
||||
|
||||
private protected virtual RenderFragment? Body => null;
|
||||
|
||||
protected virtual bool ShowResult => true;
|
||||
@@ -61,6 +74,12 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
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();
|
||||
|
||||
@@ -85,6 +104,10 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
this.MightPreselectValues();
|
||||
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
|
||||
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
|
||||
|
||||
this.MessageBus.RegisterComponent(this);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.COLOR_THEME_CHANGED ]);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
@@ -108,9 +131,32 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.COLOR_THEME_CHANGED:
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
||||
{
|
||||
return Task.FromResult<TResult?>(default);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string SubmitButtonStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).StyleBorder(this.SettingsManager) : string.Empty;
|
||||
|
||||
protected string? ValidatingProvider(AIStudio.Settings.Provider provider)
|
||||
{
|
||||
if(provider.UsedProvider == Providers.NONE)
|
||||
if(provider.UsedLLMProvider == LLMProviders.NONE)
|
||||
return "Please select a provider.";
|
||||
|
||||
return null;
|
||||
@@ -133,14 +179,36 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
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
|
||||
{
|
||||
@@ -197,9 +265,9 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
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
|
||||
@@ -243,4 +311,25 @@ public abstract partial class AssistantBase : ComponentBase
|
||||
this.StateHasChanged();
|
||||
this.form?.ResetValidation();
|
||||
}
|
||||
|
||||
private string GetResetColor() => this.SettingsManager.IsDarkMode switch
|
||||
{
|
||||
true => $"background-color: #804000",
|
||||
false => $"background-color: {this.ColorTheme.GetCurrentPalette(this.SettingsManager).Warning.Value}",
|
||||
};
|
||||
|
||||
private string GetSendToColor() => this.SettingsManager.IsDarkMode switch
|
||||
{
|
||||
true => $"background-color: #004080",
|
||||
false => $"background-color: {this.ColorTheme.GetCurrentPalette(this.SettingsManager).InfoLighten}",
|
||||
};
|
||||
|
||||
#region Implementation of IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.MessageBus.Unregister(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,4 @@
|
||||
</MudStack>
|
||||
|
||||
<MudTextField T="string" @bind-Text="@this.questions" Validation="@this.ValidateQuestions" AdornmentIcon="@Icons.Material.Filled.QuestionMark" Adornment="Adornment.Start" Label="Your question(s)" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" OnClick="() => this.GetSupport()" Class="mb-3">
|
||||
Get support
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.Coding;
|
||||
|
||||
public partial class AssistantCoding : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.CODING_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.CODING_ASSISTANT;
|
||||
|
||||
protected override string Title => "Coding Assistant";
|
||||
|
||||
@@ -28,6 +28,10 @@ public partial class AssistantCoding : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Get Support";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.GetSupport;
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
this.codingContexts.Clear();
|
||||
|
||||
@@ -20,8 +20,4 @@
|
||||
<MudTextField T="string" @bind-Text="@this.inputName" Label="(Optional) Your name for the closing salutation" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Your name for the closing salutation of your e-mail." Class="mb-3"/>
|
||||
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name())" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="Select the writing style" ValidateSelection="@this.ValidateWritingStyle"/>
|
||||
<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"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.CreateMail()">
|
||||
Create e-mail
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -6,7 +6,7 @@ namespace AIStudio.Assistants.EMail;
|
||||
|
||||
public partial class AssistantEMail : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.EMAIL_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.EMAIL_ASSISTANT;
|
||||
|
||||
protected override string Title => "E-Mail";
|
||||
|
||||
@@ -24,6 +24,10 @@ public partial class AssistantEMail : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Create email";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.CreateMail;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -3,8 +3,4 @@
|
||||
|
||||
<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"/>
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom language" />
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.ProofreadText()">
|
||||
Proofread
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.GrammarSpelling;
|
||||
|
||||
public partial class AssistantGrammarSpelling : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.GRAMMAR_SPELLING_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.GRAMMAR_SPELLING_ASSISTANT;
|
||||
|
||||
protected override string Title => "Grammar & Spelling Checker";
|
||||
|
||||
@@ -24,8 +24,6 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore
|
||||
""";
|
||||
|
||||
protected override bool AllowProfiles => false;
|
||||
|
||||
protected override bool ShowResult => false;
|
||||
|
||||
protected override bool ShowDedicatedProgress => true;
|
||||
|
||||
@@ -41,6 +39,10 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore
|
||||
},
|
||||
];
|
||||
|
||||
protected override string SubmitText => "Proofread";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.ProofreadText;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -15,8 +15,4 @@
|
||||
<MudButton Href="@this.selectedIconSource.URL()" Target="_blank" Variant="Variant.Filled" Size="Size.Medium">Open website</MudButton>
|
||||
}
|
||||
</MudStack>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.FindIcon()">
|
||||
Find icon
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -2,7 +2,7 @@ namespace AIStudio.Assistants.IconFinder;
|
||||
|
||||
public partial class AssistantIconFinder : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.ICON_FINDER_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.ICON_FINDER_ASSISTANT;
|
||||
|
||||
protected override string Title => "Icon Finder";
|
||||
|
||||
@@ -29,6 +29,10 @@ public partial class AssistantIconFinder : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Find Icon";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.FindIcon;
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
this.inputContext = string.Empty;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
@attribute [Route(Routes.ASSISTANT_JOB_POSTING)]
|
||||
@inherits AssistantBaseCore
|
||||
|
||||
<MudTextField T="string" @bind-Text="@this.inputCompanyName" Label="(Optional) The company name" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Warehouse" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||
<MudTextField T="string" @bind-Text="@this.inputCountryLegalFramework" Label="Provide the country, where the company is located" Validation="@this.ValidateCountryLegalFramework" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Flag" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" HelperText="This is important to consider the legal framework of the country."/>
|
||||
<MudTextField T="string" @bind-Text="@this.inputMandatoryInformation" Label="(Optional) Provide mandatory information" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.TextSnippet" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Mandatory information that your company requires for all job postings. This can include the company description, etc." />
|
||||
<MudTextField T="string" @bind-Text="@this.inputJobDescription" Label="Job description" Validation="@this.ValidateJobDescription" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Describe what the person is supposed to do in the company. This might be just short bullet points." />
|
||||
<MudTextField T="string" @bind-Text="@this.inputQualifications" Label="(Optional) Provide necessary job qualifications" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Describe what the person should bring to the table. This might be just short bullet points." />
|
||||
<MudTextField T="string" @bind-Text="@this.inputResponsibilities" Label="(Optional) Provide job responsibilities" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Describe the responsibilities the person should take on in the company." />
|
||||
<MudTextField T="string" @bind-Text="@this.inputWorkLocation" Label="(Optional) Provide the work location" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.MyLocation" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||
<MudTextField T="string" @bind-Text="@this.inputEntryDate" Label="(Optional) Provide the entry date" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DateRange" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||
<MudTextField T="string" @bind-Text="@this.inputValidUntil" Label="(Optional) Provide the date until the job posting is valid" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DateRange" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||
|
||||
<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"/>
|
||||
@@ -0,0 +1,290 @@
|
||||
using AIStudio.Chat;
|
||||
|
||||
namespace AIStudio.Assistants.JobPosting;
|
||||
|
||||
public partial class AssistantJobPostings : AssistantBaseCore
|
||||
{
|
||||
public override Tools.Components Component => Tools.Components.JOB_POSTING_ASSISTANT;
|
||||
|
||||
protected override string Title => "Job Posting";
|
||||
|
||||
protected override string Description =>
|
||||
"""
|
||||
Provide some key points about the job you want to post. The AI will then
|
||||
formulate a suggestion that you can finalize.
|
||||
""";
|
||||
|
||||
protected override string SystemPrompt =>
|
||||
$"""
|
||||
You are an experienced specialist in personnel matters. You write job postings.
|
||||
You follow the usual guidelines in the country of the posting. You ensure that
|
||||
no individuals are discriminated against or excluded by the job posting. You do
|
||||
not ask any questions and you do not repeat the task. You provide your response
|
||||
in a Markdown format. Missing information necessary for the job posting, you try
|
||||
to derive from the other details provided.
|
||||
|
||||
Structure of your response:
|
||||
---
|
||||
# <TITLE>
|
||||
<Description of the job and the company>
|
||||
|
||||
# <TASKS>
|
||||
<Describe what takes the job entails>
|
||||
|
||||
# <QUALIFICATIONS>
|
||||
<What qualifications are required>
|
||||
|
||||
# <RESPONSIBILITIES>
|
||||
<What responsibilities are associated with the job>
|
||||
|
||||
<When available, closing details such as the entry date etc.>
|
||||
|
||||
---
|
||||
|
||||
You write the job posting in the following language: {this.SystemPromptLanguage()}.
|
||||
""";
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Create the job posting";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.CreateJobPosting;
|
||||
|
||||
protected override bool SubmitDisabled => false;
|
||||
|
||||
protected override bool AllowProfiles => false;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
};
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
this.inputEntryDate = string.Empty;
|
||||
this.inputValidUntil = string.Empty;
|
||||
if (!this.MightPreselectValues())
|
||||
{
|
||||
this.selectedTargetLanguage = CommonLanguages.AS_IS;
|
||||
this.customTargetLanguage = string.Empty;
|
||||
this.inputMandatoryInformation = string.Empty;
|
||||
this.inputJobDescription = string.Empty;
|
||||
this.inputQualifications = string.Empty;
|
||||
this.inputResponsibilities = string.Empty;
|
||||
this.inputCompanyName = string.Empty;
|
||||
this.inputWorkLocation = string.Empty;
|
||||
this.inputCountryLegalFramework = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool MightPreselectValues()
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)
|
||||
{
|
||||
this.inputMandatoryInformation = this.SettingsManager.ConfigurationData.JobPostings.PreselectedMandatoryInformation;
|
||||
if(string.IsNullOrWhiteSpace(this.inputJobDescription))
|
||||
this.inputJobDescription = this.SettingsManager.ConfigurationData.JobPostings.PreselectedJobDescription;
|
||||
this.inputQualifications = this.SettingsManager.ConfigurationData.JobPostings.PreselectedQualifications;
|
||||
this.inputResponsibilities = this.SettingsManager.ConfigurationData.JobPostings.PreselectedResponsibilities;
|
||||
this.inputCompanyName = this.SettingsManager.ConfigurationData.JobPostings.PreselectedCompanyName;
|
||||
this.inputWorkLocation = this.SettingsManager.ConfigurationData.JobPostings.PreselectedWorkLocation;
|
||||
this.inputCountryLegalFramework = this.SettingsManager.ConfigurationData.JobPostings.PreselectedCountryLegalFramework;
|
||||
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.JobPostings.PreselectedTargetLanguage;
|
||||
this.customTargetLanguage = this.SettingsManager.ConfigurationData.JobPostings.PreselectOtherLanguage;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string inputMandatoryInformation = string.Empty;
|
||||
private string inputJobDescription = string.Empty;
|
||||
private string inputQualifications = string.Empty;
|
||||
private string inputResponsibilities = string.Empty;
|
||||
private string inputCompanyName = string.Empty;
|
||||
private string inputEntryDate = string.Empty;
|
||||
private string inputValidUntil = string.Empty;
|
||||
private string inputWorkLocation = string.Empty;
|
||||
private string inputCountryLegalFramework = 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_JOB_POSTING_ASSISTANT).FirstOrDefault();
|
||||
if (deferredContent is not null)
|
||||
this.inputJobDescription = deferredContent;
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string? ValidateCustomLanguage(string language)
|
||||
{
|
||||
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
||||
return "Please provide a custom target language.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string? ValidateJobDescription(string jobDescription)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(jobDescription))
|
||||
return "Please provide a job description.";
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string? ValidateCountryLegalFramework(string countryLegalFramework)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(countryLegalFramework))
|
||||
return "Please provide the country where the job is posted (legal framework).";
|
||||
|
||||
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 string UserPromptMandatoryInformation()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputMandatoryInformation))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Mandatory Information
|
||||
{this.inputMandatoryInformation}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptJobDescription()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputJobDescription))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Job Description
|
||||
{this.inputJobDescription}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptQualifications()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputQualifications))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Qualifications
|
||||
{this.inputQualifications}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptResponsibilities()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputResponsibilities))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Responsibilities
|
||||
{this.inputResponsibilities}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptCompanyName()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputCompanyName))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Company Name
|
||||
{this.inputCompanyName}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptEntryDate()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputEntryDate))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Entry Date
|
||||
{this.inputEntryDate}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptValidUntil()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputValidUntil))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Job Posting Valid Until
|
||||
{this.inputValidUntil}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptWorkLocation()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputWorkLocation))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Work Location
|
||||
{this.inputWorkLocation}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private string UserPromptCountryLegalFramework()
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(this.inputCountryLegalFramework))
|
||||
return string.Empty;
|
||||
|
||||
return $"""
|
||||
# Country where the job is posted (legal framework)
|
||||
{this.inputCountryLegalFramework}
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
private async Task CreateJobPosting()
|
||||
{
|
||||
await this.form!.Validate();
|
||||
if (!this.inputIsValid)
|
||||
return;
|
||||
|
||||
this.CreateChatThread();
|
||||
var time = this.AddUserRequest(
|
||||
$"""
|
||||
{this.UserPromptCompanyName()}
|
||||
{this.UserPromptCountryLegalFramework()}
|
||||
{this.UserPromptMandatoryInformation()}
|
||||
{this.UserPromptJobDescription()}
|
||||
{this.UserPromptQualifications()}
|
||||
{this.UserPromptResponsibilities()}
|
||||
{this.UserPromptWorkLocation()}
|
||||
{this.UserPromptEntryDate()}
|
||||
{this.UserPromptValidUntil()}
|
||||
""");
|
||||
|
||||
await this.AddAIResponseAsync(time);
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,4 @@
|
||||
|
||||
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputLegalDocument" Validation="@this.ValidatingLegalDocument" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Legal document" Variant="Variant.Outlined" Lines="12" AutoGrow="@true" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputQuestions" Validation="@this.ValidatingQuestions" AdornmentIcon="@Icons.Material.Filled.QuestionAnswer" Adornment="Adornment.Start" Label="Your questions" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Disabled="@this.isAgentRunning" Variant="Variant.Filled" Class="mb-3" OnClick="() => this.AksQuestions()">
|
||||
Ask your questions
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -1,8 +1,10 @@
|
||||
using AIStudio.Chat;
|
||||
|
||||
namespace AIStudio.Assistants.LegalCheck;
|
||||
|
||||
public partial class AssistantLegalCheck : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.LEGAL_CHECK_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.LEGAL_CHECK_ASSISTANT;
|
||||
|
||||
protected override string Title => "Legal Check";
|
||||
|
||||
@@ -24,6 +26,17 @@ public partial class AssistantLegalCheck : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Ask your questions";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.AksQuestions;
|
||||
|
||||
protected override bool SubmitDisabled => this.isAgentRunning;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
};
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
this.inputLegalDocument = string.Empty;
|
||||
|
||||
@@ -4,8 +4,4 @@
|
||||
<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>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -1,10 +1,11 @@
|
||||
using AIStudio.Chat;
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Assistants.MyTasks;
|
||||
|
||||
public partial class AssistantMyTasks : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.MY_TASKS_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.MY_TASKS_ASSISTANT;
|
||||
|
||||
protected override string Title => "My Tasks";
|
||||
|
||||
@@ -28,8 +29,17 @@ public partial class AssistantMyTasks : AssistantBaseCore
|
||||
""";
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Analyze text";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.AnalyzeText;
|
||||
|
||||
protected override bool ShowProfileSelection => false;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
};
|
||||
|
||||
protected override void ResetFrom()
|
||||
{
|
||||
|
||||
@@ -5,8 +5,4 @@
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom language" />
|
||||
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name())" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="Writing style" AllowOther="@false" />
|
||||
<EnumSelection T="SentenceStructure" NameFunc="@(voice => voice.Name())" @bind-Value="@this.selectedSentenceStructure" Icon="@Icons.Material.Filled.Person4" Label="Sentence structure" />
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.RewriteText()">
|
||||
Improve
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.RewriteImprove;
|
||||
|
||||
public partial class AssistantRewriteImprove : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.REWRITE_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.REWRITE_ASSISTANT;
|
||||
|
||||
protected override string Title => "Rewrite & Improve Text";
|
||||
|
||||
@@ -26,8 +26,6 @@ public partial class AssistantRewriteImprove : AssistantBaseCore
|
||||
|
||||
protected override bool AllowProfiles => false;
|
||||
|
||||
protected override bool ShowResult => false;
|
||||
|
||||
protected override bool ShowDedicatedProgress => true;
|
||||
|
||||
protected override Func<string> Result2Copy => () => this.rewrittenText;
|
||||
@@ -42,6 +40,10 @@ public partial class AssistantRewriteImprove : AssistantBaseCore
|
||||
},
|
||||
];
|
||||
|
||||
protected override string SubmitText => "Improve";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.RewriteText;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -6,7 +6,3 @@
|
||||
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedLanguage" Icon="@Icons.Material.Filled.Translate" Label="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.FindSynonyms()">
|
||||
Get synonyms
|
||||
</MudButton>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.Synonym;
|
||||
|
||||
public partial class AssistantSynonyms : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.SYNONYMS_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.SYNONYMS_ASSISTANT;
|
||||
|
||||
protected override string Title => "Synonyms";
|
||||
|
||||
@@ -51,6 +51,10 @@ public partial class AssistantSynonyms : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Find synonyms";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.FindSynonyms;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -9,8 +9,4 @@
|
||||
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="Custom target language" ValidateOther="@this.ValidateCustomLanguage" />
|
||||
<EnumSelection T="Complexity" NameFunc="@(complexity => complexity.Name())" @bind-Value="@this.selectedComplexity" Icon="@Icons.Material.Filled.Layers" Label="Target complexity" AllowOther="@true" @bind-OtherInput="@this.expertInField" OtherValue="Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS" LabelOther="Your expertise" ValidateOther="@this.ValidateExpertInField" />
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
|
||||
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.SummarizeText()" Disabled="@this.isAgentRunning">
|
||||
Summarize
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.TextSummarizer;
|
||||
|
||||
public partial class AssistantTextSummarizer : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.TEXT_SUMMARIZER_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.TEXT_SUMMARIZER_ASSISTANT;
|
||||
|
||||
protected override string Title => "Text Summarizer";
|
||||
|
||||
@@ -29,6 +29,12 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Summarize";
|
||||
|
||||
protected override Func<Task> SubmitAction => this.SummarizeText;
|
||||
|
||||
protected override bool SubmitDisabled => this.isAgentRunning;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -17,8 +17,4 @@ else
|
||||
}
|
||||
|
||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" 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 Disabled="@this.isAgentRunning" Variant="Variant.Filled" Class="mb-3" OnClick="() => this.TranslateText(force: true)">
|
||||
Translate
|
||||
</MudButton>
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||
@@ -4,7 +4,7 @@ namespace AIStudio.Assistants.Translation;
|
||||
|
||||
public partial class AssistantTranslation : AssistantBaseCore
|
||||
{
|
||||
protected override Tools.Components Component => Tools.Components.TRANSLATION_ASSISTANT;
|
||||
public override Tools.Components Component => Tools.Components.TRANSLATION_ASSISTANT;
|
||||
|
||||
protected override string Title => "Translation";
|
||||
|
||||
@@ -25,6 +25,12 @@ public partial class AssistantTranslation : AssistantBaseCore
|
||||
|
||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||
|
||||
protected override string SubmitText => "Translate";
|
||||
|
||||
protected override Func<Task> SubmitAction => () => this.TranslateText(true);
|
||||
|
||||
protected override bool SubmitDisabled => this.isAgentRunning;
|
||||
|
||||
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
|
||||
{
|
||||
SystemPrompt = SystemPrompts.DEFAULT,
|
||||
|
||||
@@ -18,10 +18,15 @@ public class ContentBlock
|
||||
/// <summary>
|
||||
/// The content of the block.
|
||||
/// </summary>
|
||||
public IContent? Content { get; init; } = null;
|
||||
public IContent? Content { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The role of the content block in the chat thread, e.g., user, AI, etc.
|
||||
/// </summary>
|
||||
public ChatRole Role { get; init; } = ChatRole.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Should the content block be hidden from the user?
|
||||
/// </summary>
|
||||
public bool HideFromUser { get; set; }
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public partial class ContentBlockComponent : ComponentBase
|
||||
private async Task AfterStreaming()
|
||||
{
|
||||
// Might be called from a different thread, so we need to invoke the UI thread:
|
||||
await this.InvokeAsync(() =>
|
||||
await this.InvokeAsync(async () =>
|
||||
{
|
||||
//
|
||||
// Issue we try to solve: When the content changes during streaming,
|
||||
@@ -83,6 +83,9 @@ public partial class ContentBlockComponent : ComponentBase
|
||||
|
||||
// Let Blazor update the UI, i.e., to see the render tree diff:
|
||||
this.StateHasChanged();
|
||||
|
||||
// Inform the chat that the streaming is done:
|
||||
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.CHAT_STREAMING_DONE);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<MudCard Outlined="@true" Style="border-width: 2px; border-color: #0d47a1; border-radius: 12px; border-style: solid; max-width: 20em;">
|
||||
<MudCard Outlined="@true" Style="@this.BlockStyle">
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudStack AlignItems="AlignItems.Center" Row="@true">
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public partial class AssistantBlock : ComponentBase
|
||||
public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
{
|
||||
[Parameter]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
@@ -18,4 +20,63 @@ public partial class AssistantBlock : ComponentBase
|
||||
|
||||
[Parameter]
|
||||
public string Link { get; set; } = string.Empty;
|
||||
|
||||
[Inject]
|
||||
private MudTheme ColorTheme { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.MessageBus.RegisterComponent(this);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.COLOR_THEME_CHANGED ]);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.COLOR_THEME_CHANGED:
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
||||
{
|
||||
return Task.FromResult<TResult?>(default);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string BorderColor => this.SettingsManager.IsDarkMode switch
|
||||
{
|
||||
true => this.ColorTheme.GetCurrentPalette(this.SettingsManager).GrayLight,
|
||||
false => this.ColorTheme.GetCurrentPalette(this.SettingsManager).Primary.Value,
|
||||
};
|
||||
|
||||
private string BlockStyle => $"border-width: 2px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;";
|
||||
|
||||
#region Implementation of IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.MessageBus.Unregister(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -13,6 +13,13 @@ public partial class Changelog
|
||||
|
||||
public static readonly Log[] LOGS =
|
||||
[
|
||||
new (190, "v0.9.15, build 190 (2024-10-28 15:04 UTC)", "v0.9.15.md"),
|
||||
new (189, "v0.9.14, build 189 (2024-10-18 08:48 UTC)", "v0.9.14.md"),
|
||||
new (188, "v0.9.13, build 188 (2024-10-07 11:18 UTC)", "v0.9.13.md"),
|
||||
new (187, "v0.9.12, build 187 (2024-09-15 20:49 UTC)", "v0.9.12.md"),
|
||||
new (186, "v0.9.11, build 186 (2024-09-15 10:33 UTC)", "v0.9.11.md"),
|
||||
new (185, "v0.9.10, build 185 (2024-09-12 20:52 UTC)", "v0.9.10.md"),
|
||||
new (184, "v0.9.9, build 184 (2024-09-11 21:10 UTC)", "v0.9.9.md"),
|
||||
new (183, "v0.9.8, build 183 (2024-09-09 13:10 UTC)", "v0.9.8.md"),
|
||||
new (182, "v0.9.7, build 182 (2024-09-08 20:55 UTC)", "v0.9.7.md"),
|
||||
new (181, "v0.9.6, build 181 (2024-09-08 09:30 UTC)", "v0.9.6.md"),
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
@using AIStudio.Provider
|
||||
<div class="d-flex">
|
||||
<MudTooltip Text="Shows and hides the confidence card with information about the selected LLM provider.">
|
||||
@if (this.Mode is ConfidenceInfoMode.ICON)
|
||||
{
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Security" Class="confidence-icon" Style="@this.LLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager)" OnClick="@(() => this.ToggleConfidence())"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Security" IconClass="confidence-icon" Style="@this.LLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager)" OnClick="@(() => this.ToggleConfidence())">
|
||||
Confidence
|
||||
</MudButton>
|
||||
}
|
||||
</MudTooltip>
|
||||
|
||||
<MudPopover Open="@this.showConfidence" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" Style="@this.GetPopoverStyle()" DropShadow="@true" Class="border-solid border-4 rounded-lg">
|
||||
<MudCard>
|
||||
<MudCardHeader>
|
||||
<CardHeaderContent>
|
||||
<MudText Typo="Typo.h5">Confidence Card</MudText>
|
||||
</CardHeaderContent>
|
||||
</MudCardHeader>
|
||||
<MudCardContent>
|
||||
<MudText Typo="Typo.h6">Description</MudText>
|
||||
<MudMarkdown Value="@this.currentConfidence.Description"/>
|
||||
|
||||
@if (this.currentConfidence.Sources.Count > 0)
|
||||
{
|
||||
<MudText Typo="Typo.h6">Sources</MudText>
|
||||
<MudList T="@string">
|
||||
@foreach (var sourceTuple in this.GetConfidenceSources())
|
||||
{
|
||||
<MudListItem Icon="@Icons.Material.Filled.Link" Href="@sourceTuple.Source" Target="_blank" Text="@sourceTuple.Index"/>
|
||||
}
|
||||
</MudList>
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(this.currentConfidence.Region))
|
||||
{
|
||||
<MudText Typo="Typo.h6">Region</MudText>
|
||||
<MudText Typo="Typo.body1" Class="mb-3">
|
||||
<b>@this.currentConfidence.Region</b>
|
||||
</MudText>
|
||||
}
|
||||
|
||||
<MudText Typo="Typo.h6">Confidence Level</MudText>
|
||||
<MudText Typo="Typo.body1" Style="@this.GetCurrentConfidenceColor()">
|
||||
<b>@this.currentConfidence.Level.GetName()</b>
|
||||
</MudText>
|
||||
</MudCardContent>
|
||||
<MudCardActions>
|
||||
<MudButton Variant="Variant.Filled" OnClick="@(() => this.HideConfidence())">
|
||||
Close
|
||||
</MudButton>
|
||||
</MudCardActions>
|
||||
</MudCard>
|
||||
</MudPopover>
|
||||
</div>
|
||||
@@ -0,0 +1,94 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public partial class ConfidenceInfo : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
{
|
||||
[Parameter]
|
||||
public ConfidenceInfoMode Mode { get; set; } = ConfidenceInfoMode.BUTTON;
|
||||
|
||||
[Parameter]
|
||||
public LLMProviders LLMProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
private Confidence currentConfidence;
|
||||
private bool showConfidence;
|
||||
|
||||
public ConfidenceInfo()
|
||||
{
|
||||
this.currentConfidence = LLMProviders.NONE.GetConfidence(this.SettingsManager);
|
||||
}
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
this.MessageBus.RegisterComponent(this);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.COLOR_THEME_CHANGED ]);
|
||||
|
||||
this.currentConfidence = this.LLMProvider.GetConfidence(this.SettingsManager);
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ToggleConfidence()
|
||||
{
|
||||
this.showConfidence = !this.showConfidence;
|
||||
}
|
||||
|
||||
private void HideConfidence()
|
||||
{
|
||||
this.showConfidence = false;
|
||||
}
|
||||
|
||||
private IEnumerable<(string Index, string Source)> GetConfidenceSources()
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var source in this.currentConfidence.Sources)
|
||||
yield return ($"Source {++index}", source);
|
||||
}
|
||||
|
||||
private string GetCurrentConfidenceColor() => $"color: {this.currentConfidence.Level.GetColor(this.SettingsManager)};";
|
||||
|
||||
private string GetPopoverStyle() => $"border-color: {this.currentConfidence.Level.GetColor(this.SettingsManager)}; max-width: calc(35vw);";
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.COLOR_THEME_CHANGED:
|
||||
this.showConfidence = false;
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
||||
{
|
||||
return Task.FromResult<TResult?>(default);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.MessageBus.Unregister(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public enum ConfidenceInfoMode
|
||||
{
|
||||
BUTTON,
|
||||
ICON,
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@using AIStudio.Settings
|
||||
<ConfigurationSelect Disabled="@this.Disabled" OptionDescription="Select a minimum confidence level" SelectedValue="@this.FilteredSelectedValue" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData(this.SettingsManager, this.RestrictToGlobalMinimumConfidence)" SelectionUpdate="@this.SelectionUpdate" OptionHelp="Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level."/>
|
||||
@@ -0,0 +1,51 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public partial class ConfigurationMinConfidenceSelection : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The selected value.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<ConfidenceLevel> SelectedValue { get; set; } = () => default!;
|
||||
|
||||
/// <summary>
|
||||
/// An action that is called when the selection changes.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Action<ConfidenceLevel> SelectionUpdate { get; set; } = _ => { };
|
||||
|
||||
/// <summary>
|
||||
/// Is the selection component disabled?
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<bool> Disabled { get; set; } = () => false;
|
||||
|
||||
/// <summary>
|
||||
/// Boolean value indicating whether the selection is restricted to a global minimum confidence level.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool RestrictToGlobalMinimumConfidence { get; set; }
|
||||
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
private ConfidenceLevel FilteredSelectedValue()
|
||||
{
|
||||
if (this.SelectedValue() is ConfidenceLevel.NONE)
|
||||
return ConfidenceLevel.NONE;
|
||||
|
||||
if(this.RestrictToGlobalMinimumConfidence && this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence)
|
||||
{
|
||||
var minimumLevel = this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence;
|
||||
if(this.SelectedValue() < minimumLevel)
|
||||
return minimumLevel;
|
||||
}
|
||||
|
||||
return this.SelectedValue();
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.Data" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
|
||||
<ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
|
||||
@@ -1,3 +1,4 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@@ -23,6 +24,9 @@ public partial class ConfigurationProviderSelection : ComponentBase, IMessageBus
|
||||
|
||||
[Parameter]
|
||||
public Func<string> HelpText { get; set; } = () => "Select a provider that is preselected.";
|
||||
|
||||
[Parameter]
|
||||
public Tools.Components Component { get; set; } = Tools.Components.NONE;
|
||||
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
@@ -43,6 +47,17 @@ public partial class ConfigurationProviderSelection : ComponentBase, IMessageBus
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<ConfigurationSelectData<string>> FilteredData()
|
||||
{
|
||||
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.Component);
|
||||
foreach (var providerId in this.Data)
|
||||
{
|
||||
var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value);
|
||||
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
||||
yield return providerId;
|
||||
}
|
||||
}
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||
|
||||
@@ -3,16 +3,17 @@
|
||||
<MudTextField
|
||||
T="string"
|
||||
Text="@this.Text()"
|
||||
TextChanged="@this.OptionChanged"
|
||||
TextChanged="@this.InternalUpdate"
|
||||
Label="@this.OptionDescription"
|
||||
Disabled="@this.Disabled()"
|
||||
Class="mb-3"
|
||||
Class="@MARGIN_CLASS"
|
||||
Adornment="Adornment.Start"
|
||||
AdornmentIcon="@this.Icon"
|
||||
AdornmentColor="@this.IconColor"
|
||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||
Lines="1"
|
||||
Immediate="@false"
|
||||
DebounceInterval="500"
|
||||
Lines="@this.NumLines"
|
||||
AutoGrow="@this.AutoGrow"
|
||||
MaxLines="@this.GetMaxLines"
|
||||
Immediate="@true"
|
||||
Variant="Variant.Outlined"
|
||||
/>
|
||||
@@ -1,5 +1,7 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace AIStudio.Components;
|
||||
|
||||
public partial class ConfigurationText : ConfigurationBase
|
||||
@@ -11,7 +13,7 @@ public partial class ConfigurationText : ConfigurationBase
|
||||
public Func<string> Text { get; set; } = () => string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// An action which is called when the option is changed.
|
||||
/// An action which is called when the text was changed.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Action<string> TextUpdate { get; set; } = _ => { };
|
||||
@@ -27,6 +29,55 @@ public partial class ConfigurationText : ConfigurationBase
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color IconColor { get; set; } = Color.Default;
|
||||
|
||||
/// <summary>
|
||||
/// How many lines should the textfield have?
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int NumLines { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// What is the maximum number of lines?
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int MaxLines { get; set; } = 12;
|
||||
|
||||
private string internalText = string.Empty;
|
||||
private Timer timer = new(TimeSpan.FromMilliseconds(500))
|
||||
{
|
||||
AutoReset = false
|
||||
};
|
||||
|
||||
#region Overrides of ConfigurationBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText));
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
this.internalText = this.Text();
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private bool AutoGrow => this.NumLines > 1;
|
||||
|
||||
private int GetMaxLines => this.AutoGrow ? this.MaxLines : 1;
|
||||
|
||||
private void InternalUpdate(string text)
|
||||
{
|
||||
this.timer.Stop();
|
||||
this.internalText = text;
|
||||
this.timer.Start();
|
||||
}
|
||||
|
||||
private async Task OptionChanged(string updatedText)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ public partial class InnerScrolling : MSGComponentBase
|
||||
|
||||
#region Overrides of MSGComponentBase
|
||||
|
||||
public override Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
public override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,22 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
public abstract Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.COLOR_THEME_CHANGED:
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
|
||||
default:
|
||||
return this.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public abstract Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data);
|
||||
|
||||
public abstract Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data);
|
||||
|
||||
@@ -46,6 +61,12 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
||||
|
||||
protected void ApplyFilters(ComponentBase[] components, Event[] events)
|
||||
{
|
||||
this.MessageBus.ApplyFilters(this, components, events);
|
||||
// Append the color theme changed event to the list of events:
|
||||
var eventsList = new List<Event>(events)
|
||||
{
|
||||
Event.COLOR_THEME_CHANGED
|
||||
};
|
||||
|
||||
this.MessageBus.ApplyFilters(this, components, eventsList.ToArray());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
@using AIStudio.Settings
|
||||
|
||||
<MudSelect T="Provider" Value="@this.ProviderSettings" ValueChanged="@this.SelectionChanged" Validation="@this.ValidateProvider" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Apps" Margin="Margin.Dense" Label="Provider" Class="mb-3 rounded-lg" Variant="Variant.Outlined">
|
||||
@foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
|
||||
@foreach (var provider in this.GetAvailableProviders())
|
||||
{
|
||||
<MudSelectItem Value="@provider"/>
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Assistants;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@@ -6,6 +8,9 @@ namespace AIStudio.Components;
|
||||
|
||||
public partial class ProviderSelection : ComponentBase
|
||||
{
|
||||
[CascadingParameter]
|
||||
public AssistantBase? AssistantBase { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Settings.Provider ProviderSettings { get; set; }
|
||||
|
||||
@@ -16,11 +21,19 @@ public partial class ProviderSelection : ComponentBase
|
||||
public Func<Settings.Provider, string?> ValidateProvider { get; set; } = _ => null;
|
||||
|
||||
[Inject]
|
||||
protected SettingsManager SettingsManager { get; set; } = null!;
|
||||
private SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
private async Task SelectionChanged(Settings.Provider provider)
|
||||
{
|
||||
this.ProviderSettings = provider;
|
||||
await this.ProviderSettingsChanged.InvokeAsync(provider);
|
||||
}
|
||||
|
||||
private IEnumerable<Settings.Provider> GetAvailableProviders()
|
||||
{
|
||||
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE);
|
||||
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
|
||||
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
|
||||
yield return provider;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
private const Placement WORKSPACE_ITEM_TOOLTIP_PLACEMENT = Placement.Bottom;
|
||||
|
||||
public static readonly Guid WORKSPACE_ID_BIAS = Guid.Parse("82050a4e-ee92-43d7-8ee5-ab512f847e02");
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
@@ -63,6 +64,7 @@ public partial class Workspaces : ComponentBase
|
||||
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
|
||||
//
|
||||
|
||||
await this.EnsureBiasWorkspace();
|
||||
await this.LoadTreeItems();
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
@@ -250,7 +252,7 @@ public partial class Workspaces : ComponentBase
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task StoreChat(ChatThread chat)
|
||||
public async Task StoreChat(ChatThread chat, bool reloadTreeItems = true)
|
||||
{
|
||||
string chatDirectory;
|
||||
if (chat.WorkspaceId == Guid.Empty)
|
||||
@@ -270,9 +272,29 @@ public partial class Workspaces : ComponentBase
|
||||
await File.WriteAllTextAsync(chatPath, JsonSerializer.Serialize(chat, JSON_OPTIONS), Encoding.UTF8);
|
||||
|
||||
// Reload the tree items:
|
||||
await this.LoadTreeItems();
|
||||
if(reloadTreeItems)
|
||||
await this.LoadTreeItems();
|
||||
|
||||
this.StateHasChanged();
|
||||
}
|
||||
|
||||
public async Task LoadChat(LoadChat loadChat)
|
||||
{
|
||||
var chatPath = loadChat.WorkspaceId == Guid.Empty
|
||||
? Path.Join(SettingsManager.DataDirectory, "tempChats", loadChat.ChatId.ToString())
|
||||
: Path.Join(SettingsManager.DataDirectory, "workspaces", loadChat.WorkspaceId.ToString(), loadChat.ChatId.ToString());
|
||||
|
||||
await this.LoadChat(chatPath, switchToChat: true);
|
||||
}
|
||||
|
||||
public static bool IsChatExisting(LoadChat loadChat)
|
||||
{
|
||||
var chatPath = loadChat.WorkspaceId == Guid.Empty
|
||||
? Path.Join(SettingsManager.DataDirectory, "tempChats", loadChat.ChatId.ToString())
|
||||
: Path.Join(SettingsManager.DataDirectory, "workspaces", loadChat.WorkspaceId.ToString(), loadChat.ChatId.ToString());
|
||||
|
||||
return Directory.Exists(chatPath);
|
||||
}
|
||||
|
||||
private async Task<ChatThread?> LoadChat(string? chatPath, bool switchToChat)
|
||||
{
|
||||
@@ -434,6 +456,18 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
await this.LoadTreeItems();
|
||||
}
|
||||
|
||||
private async Task EnsureBiasWorkspace()
|
||||
{
|
||||
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", WORKSPACE_ID_BIAS.ToString());
|
||||
|
||||
if(Path.Exists(workspacePath))
|
||||
return;
|
||||
|
||||
Directory.CreateDirectory(workspacePath);
|
||||
var workspaceNamePath = Path.Join(workspacePath, "name");
|
||||
await File.WriteAllTextAsync(workspaceNamePath, "Bias of the Day", Encoding.UTF8);
|
||||
}
|
||||
|
||||
private async Task DeleteWorkspace(string? workspacePath)
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||
<MudSelect @bind-Value="@this.DataProvider" Label="Provider" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.ValidatingProvider">
|
||||
@foreach (Providers provider in Enum.GetValues(typeof(Providers)))
|
||||
<MudSelect @bind-Value="@this.DataLLMProvider" Label="Provider" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.ValidatingProvider">
|
||||
@foreach (LLMProviders provider in Enum.GetValues(typeof(LLMProviders)))
|
||||
{
|
||||
<MudSelectItem Value="@provider">@provider</MudSelectItem>
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
<MudTextField
|
||||
T="string"
|
||||
@bind-Text="@this.dataAPIKey"
|
||||
Label="API Key"
|
||||
Label="@this.APIKeyText"
|
||||
Disabled="@(!this.NeedAPIKey)"
|
||||
Class="mb-3"
|
||||
Adornment="Adornment.Start"
|
||||
|
||||
@@ -56,7 +56,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
/// The provider to use.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Providers DataProvider { get; set; } = Providers.NONE;
|
||||
public LLMProviders DataLLMProvider { get; set; } = LLMProviders.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The LLM model to use, e.g., GPT-4o.
|
||||
@@ -104,9 +104,9 @@ public partial class ProviderDialog : ComponentBase
|
||||
Num = this.DataNum,
|
||||
Id = this.DataId,
|
||||
InstanceName = this.DataInstanceName,
|
||||
UsedProvider = this.DataProvider,
|
||||
Model = this.DataProvider is Providers.FIREWORKS ? new Model(this.dataManuallyModel) : this.DataModel,
|
||||
IsSelfHosted = this.DataProvider is Providers.SELF_HOSTED,
|
||||
UsedLLMProvider = this.DataLLMProvider,
|
||||
Model = this.DataLLMProvider is LLMProviders.FIREWORKS ? new Model(this.dataManuallyModel) : this.DataModel,
|
||||
IsSelfHosted = this.DataLLMProvider is LLMProviders.SELF_HOSTED,
|
||||
Hostname = this.DataHostname.EndsWith('/') ? this.DataHostname[..^1] : this.DataHostname,
|
||||
Host = this.DataHost,
|
||||
};
|
||||
@@ -127,13 +127,13 @@ public partial class ProviderDialog : ComponentBase
|
||||
this.dataEditingPreviousInstanceName = this.DataInstanceName.ToLowerInvariant();
|
||||
|
||||
// When using Fireworks, we must copy the model name:
|
||||
if (this.DataProvider is Providers.FIREWORKS)
|
||||
if (this.DataLLMProvider is LLMProviders.FIREWORKS)
|
||||
this.dataManuallyModel = this.DataModel.Id;
|
||||
|
||||
//
|
||||
// We cannot load the API key for self-hosted providers:
|
||||
//
|
||||
if (this.DataProvider is Providers.SELF_HOSTED)
|
||||
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && this.DataHost is not Host.OLLAMA)
|
||||
{
|
||||
await this.ReloadModels();
|
||||
await base.OnInitializedAsync();
|
||||
@@ -149,7 +149,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
}
|
||||
|
||||
// Load the API key:
|
||||
var requestedSecret = await this.RustService.GetAPIKey(provider);
|
||||
var requestedSecret = await this.RustService.GetAPIKey(provider, isTrying: this.DataLLMProvider is LLMProviders.SELF_HOSTED);
|
||||
if(requestedSecret.Success)
|
||||
{
|
||||
this.dataAPIKey = await requestedSecret.Secret.Decrypt(this.encryption);
|
||||
@@ -159,8 +159,15 @@ public partial class ProviderDialog : ComponentBase
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again.";
|
||||
await this.form.Validate();
|
||||
this.dataAPIKey = string.Empty;
|
||||
if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
|
||||
{
|
||||
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again.";
|
||||
await this.form.Validate();
|
||||
}
|
||||
|
||||
// We still try to load the models. Some local hosts don't need an API key:
|
||||
await this.ReloadModels();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +199,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
// Use the data model to store the provider.
|
||||
// We just return this data to the parent component:
|
||||
var addedProviderSettings = this.CreateProviderSettings();
|
||||
if (addedProviderSettings.UsedProvider != Providers.SELF_HOSTED)
|
||||
if (!string.IsNullOrWhiteSpace(this.dataAPIKey))
|
||||
{
|
||||
// We need to instantiate the provider to store the API key:
|
||||
var provider = addedProviderSettings.CreateProvider(this.Logger);
|
||||
@@ -210,9 +217,9 @@ public partial class ProviderDialog : ComponentBase
|
||||
this.MudDialog.Close(DialogResult.Ok(addedProviderSettings));
|
||||
}
|
||||
|
||||
private string? ValidatingProvider(Providers provider)
|
||||
private string? ValidatingProvider(LLMProviders llmProvider)
|
||||
{
|
||||
if (provider == Providers.NONE)
|
||||
if (llmProvider == LLMProviders.NONE)
|
||||
return "Please select a provider.";
|
||||
|
||||
return null;
|
||||
@@ -220,7 +227,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private string? ValidatingHost(Host host)
|
||||
{
|
||||
if(this.DataProvider is not Providers.SELF_HOSTED)
|
||||
if(this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
if (host == Host.NONE)
|
||||
@@ -231,7 +238,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private string? ValidateManuallyModel(string manuallyModel)
|
||||
{
|
||||
if (this.DataProvider is Providers.FIREWORKS && string.IsNullOrWhiteSpace(manuallyModel))
|
||||
if (this.DataLLMProvider is LLMProviders.FIREWORKS && string.IsNullOrWhiteSpace(manuallyModel))
|
||||
return "Please enter a model name.";
|
||||
|
||||
return null;
|
||||
@@ -239,7 +246,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private string? ValidatingModel(Model model)
|
||||
{
|
||||
if(this.DataProvider is Providers.SELF_HOSTED && this.DataHost == Host.LLAMACPP)
|
||||
if(this.DataLLMProvider is LLMProviders.SELF_HOSTED && this.DataHost == Host.LLAMACPP)
|
||||
return null;
|
||||
|
||||
if (model == default)
|
||||
@@ -266,7 +273,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private string? ValidatingAPIKey(string apiKey)
|
||||
{
|
||||
if(this.DataProvider is Providers.SELF_HOSTED)
|
||||
if(this.DataLLMProvider is LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(this.dataAPIKeyStorageIssue))
|
||||
@@ -280,7 +287,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private string? ValidatingHostname(string hostname)
|
||||
{
|
||||
if(this.DataProvider != Providers.SELF_HOSTED)
|
||||
if(this.DataLLMProvider != LLMProviders.SELF_HOSTED)
|
||||
return null;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(hostname))
|
||||
@@ -315,7 +322,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
|
||||
private bool CanLoadModels()
|
||||
{
|
||||
if (this.DataProvider is Providers.SELF_HOSTED)
|
||||
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED)
|
||||
{
|
||||
switch (this.DataHost)
|
||||
{
|
||||
@@ -336,7 +343,7 @@ public partial class ProviderDialog : ComponentBase
|
||||
}
|
||||
}
|
||||
|
||||
if(this.DataProvider is Providers.NONE)
|
||||
if(this.DataLLMProvider is LLMProviders.NONE)
|
||||
return false;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(this.dataAPIKey))
|
||||
@@ -345,63 +352,70 @@ public partial class ProviderDialog : ComponentBase
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ShowRegisterButton => this.DataProvider switch
|
||||
private bool ShowRegisterButton => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => true,
|
||||
Providers.MISTRAL => true,
|
||||
Providers.ANTHROPIC => true,
|
||||
LLMProviders.OPEN_AI => true,
|
||||
LLMProviders.MISTRAL => true,
|
||||
LLMProviders.ANTHROPIC => true,
|
||||
|
||||
Providers.FIREWORKS => true,
|
||||
LLMProviders.FIREWORKS => true,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private bool NeedAPIKey => this.DataProvider switch
|
||||
private bool NeedAPIKey => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => true,
|
||||
Providers.MISTRAL => true,
|
||||
Providers.ANTHROPIC => true,
|
||||
LLMProviders.OPEN_AI => true,
|
||||
LLMProviders.MISTRAL => true,
|
||||
LLMProviders.ANTHROPIC => true,
|
||||
|
||||
Providers.FIREWORKS => true,
|
||||
LLMProviders.FIREWORKS => true,
|
||||
LLMProviders.SELF_HOSTED => this.DataHost is Host.OLLAMA,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private string APIKeyText => this.DataLLMProvider switch
|
||||
{
|
||||
LLMProviders.SELF_HOSTED => "(Optional) API Key",
|
||||
_ => "API Key",
|
||||
};
|
||||
|
||||
private bool NeedHostname => this.DataProvider switch
|
||||
private bool NeedHostname => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.SELF_HOSTED => true,
|
||||
LLMProviders.SELF_HOSTED => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private bool NeedHost => this.DataProvider switch
|
||||
private bool NeedHost => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.SELF_HOSTED => true,
|
||||
LLMProviders.SELF_HOSTED => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private bool ProvideModelManually => this.DataProvider switch
|
||||
private bool ProvideModelManually => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.FIREWORKS => true,
|
||||
LLMProviders.FIREWORKS => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private string GetModelOverviewURL() => this.DataProvider switch
|
||||
private string GetModelOverviewURL() => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.FIREWORKS => "https://fireworks.ai/models?show=Serverless",
|
||||
LLMProviders.FIREWORKS => "https://fireworks.ai/models?show=Serverless",
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
private string GetProviderCreationURL() => this.DataProvider switch
|
||||
private string GetProviderCreationURL() => this.DataLLMProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => "https://platform.openai.com/signup",
|
||||
Providers.MISTRAL => "https://console.mistral.ai/",
|
||||
Providers.ANTHROPIC => "https://console.anthropic.com/dashboard",
|
||||
LLMProviders.OPEN_AI => "https://platform.openai.com/signup",
|
||||
LLMProviders.MISTRAL => "https://console.mistral.ai/",
|
||||
LLMProviders.ANTHROPIC => "https://console.anthropic.com/dashboard",
|
||||
|
||||
Providers.FIREWORKS => "https://fireworks.ai/login",
|
||||
LLMProviders.FIREWORKS => "https://fireworks.ai/login",
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
private bool IsNoneProvider => this.DataProvider is Providers.NONE;
|
||||
private bool IsNoneProvider => this.DataLLMProvider is LLMProviders.NONE;
|
||||
}
|
||||
@@ -11,17 +11,17 @@
|
||||
<MudDrawerContainer Class="mud-height-full absolute">
|
||||
<MudDrawer @bind-Open="@this.navBarOpen" MiniWidth="@NAVBAR_COLLAPSED_WIDTH" Width="@NAVBAR_EXPANDED_WIDTH" Elevation="1" Fixed="@true" Variant="@DrawerVariant.Mini" OpenMiniOnHover="@(this.SettingsManager.ConfigurationData.App.NavigationBehavior is NavBehavior.EXPAND_ON_HOVER)" Color="Color.Default">
|
||||
<MudNavMenu>
|
||||
@foreach (var navBarItem in NAV_ITEMS)
|
||||
@foreach (var navBarItem in this.navItems)
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.App.NavigationBehavior is NavBehavior.NEVER_EXPAND_USE_TOOLTIPS)
|
||||
{
|
||||
<MudTooltip Text="@navBarItem.Name" Placement="Placement.Right">
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" IconColor="@navBarItem.IconColor">@navBarItem.Name</MudNavLink>
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" Style="@navBarItem.SetColorStyle(this.SettingsManager)" Class="custom-icon-color">@navBarItem.Name</MudNavLink>
|
||||
</MudTooltip>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" IconColor="@navBarItem.IconColor">@navBarItem.Name</MudNavLink>
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" Style="@navBarItem.SetColorStyle(this.SettingsManager)" Class="custom-icon-color">@navBarItem.Name</MudNavLink>
|
||||
}
|
||||
}
|
||||
</MudNavMenu>
|
||||
@@ -58,4 +58,6 @@
|
||||
</MudContainer>
|
||||
</MudMainContent>
|
||||
</MudLayout>
|
||||
</MudPaper>
|
||||
</MudPaper>
|
||||
|
||||
<MudThemeProvider @ref="@this.themeProvider" Theme="@this.ColorTheme" IsDarkMode="@this.useDarkMode" />
|
||||
@@ -34,6 +34,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
|
||||
[Inject]
|
||||
private ILogger<MainLayout> Logger { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private MudTheme ColorTheme { get; init; } = null!;
|
||||
|
||||
public string AdditionalHeight { get; private set; } = "0em";
|
||||
|
||||
@@ -50,16 +53,10 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
private bool userDismissedUpdate;
|
||||
private string updateToVersion = string.Empty;
|
||||
private UpdateResponse? currentUpdateResponse;
|
||||
|
||||
private static readonly IReadOnlyCollection<NavBarItem> NAV_ITEMS = new List<NavBarItem>
|
||||
{
|
||||
new("Home", Icons.Material.Filled.Home, Color.Default, Routes.HOME, true),
|
||||
new("Chat", Icons.Material.Filled.Chat, Color.Default, Routes.CHAT, false),
|
||||
new("Assistants", Icons.Material.Filled.Apps, Color.Default, Routes.ASSISTANTS, false),
|
||||
new("Supporters", Icons.Material.Filled.Favorite, Color.Error, Routes.SUPPORTERS, false),
|
||||
new("About", Icons.Material.Filled.Info, Color.Default, Routes.ABOUT, false),
|
||||
new("Settings", Icons.Material.Filled.Settings, Color.Default, Routes.SETTINGS, false),
|
||||
};
|
||||
private MudThemeProvider themeProvider = null!;
|
||||
private bool useDarkMode;
|
||||
|
||||
private IReadOnlyCollection<NavBarItem> navItems = [];
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
@@ -87,7 +84,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
|
||||
// Register this component with the message bus:
|
||||
this.MessageBus.RegisterComponent(this);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.UPDATE_AVAILABLE, Event.USER_SEARCH_FOR_UPDATE, Event.CONFIGURATION_CHANGED ]);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.UPDATE_AVAILABLE, Event.USER_SEARCH_FOR_UPDATE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED ]);
|
||||
|
||||
// Set the snackbar for the update service:
|
||||
UpdateService.SetBlazorDependencies(this.Snackbar);
|
||||
@@ -96,6 +93,20 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
// Should the navigation bar be open by default?
|
||||
if(this.SettingsManager.ConfigurationData.App.NavigationBehavior is NavBehavior.ALWAYS_EXPAND)
|
||||
this.navBarOpen = true;
|
||||
|
||||
await this.themeProvider.WatchSystemPreference(this.SystemeThemeChanged);
|
||||
await this.UpdateThemeConfiguration();
|
||||
|
||||
var palette = this.ColorTheme.GetCurrentPalette(this.SettingsManager);
|
||||
this.navItems = new List<NavBarItem>
|
||||
{
|
||||
new("Home", Icons.Material.Filled.Home, palette.DarkLighten, palette.GrayLight, Routes.HOME, true),
|
||||
new("Chat", Icons.Material.Filled.Chat, palette.DarkLighten, palette.GrayLight, Routes.CHAT, false),
|
||||
new("Assistants", Icons.Material.Filled.Apps, palette.DarkLighten, palette.GrayLight, Routes.ASSISTANTS, false),
|
||||
new("Supporters", Icons.Material.Filled.Favorite, palette.Error.Value, "#801a00", Routes.SUPPORTERS, false),
|
||||
new("About", Icons.Material.Filled.Info, palette.DarkLighten, palette.GrayLight, Routes.ABOUT, false),
|
||||
new("Settings", Icons.Material.Filled.Settings, palette.DarkLighten, palette.GrayLight, Routes.SETTINGS, false),
|
||||
};
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
@@ -131,6 +142,11 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
else
|
||||
this.navBarOpen = false;
|
||||
|
||||
await this.UpdateThemeConfiguration();
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
|
||||
case Event.COLOR_THEME_CHANGED:
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
}
|
||||
@@ -217,6 +233,24 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDis
|
||||
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.RESET_CHAT_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SystemeThemeChanged(bool isDark)
|
||||
{
|
||||
this.Logger.LogInformation($"The system theme changed to {(isDark ? "dark" : "light")}.");
|
||||
await this.UpdateThemeConfiguration();
|
||||
}
|
||||
|
||||
private async Task UpdateThemeConfiguration()
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.App.PreferredTheme is Themes.SYSTEM)
|
||||
this.useDarkMode = await this.themeProvider.GetSystemPreference();
|
||||
else
|
||||
this.useDarkMode = this.SettingsManager.ConfigurationData.App.PreferredTheme == Themes.DARK;
|
||||
|
||||
this.SettingsManager.IsDarkMode = this.useDarkMode;
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.COLOR_THEME_CHANGED);
|
||||
this.StateHasChanged();
|
||||
}
|
||||
|
||||
#region Implementation of IDisposable
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Layout;
|
||||
|
||||
public record NavBarItem(string Name, string Icon, Color IconColor, string Path, bool MatchAll);
|
||||
public record NavBarItem(string Name, string Icon, string IconLightColor, string IconDarkColor, string Path, bool MatchAll)
|
||||
{
|
||||
public string SetColorStyle(SettingsManager settingsManager) => $"--custom-icon-color: {(settingsManager.IsDarkMode ? this.IconDarkColor : this.IconLightColor)};";
|
||||
}
|
||||
@@ -45,10 +45,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.65" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.8" />
|
||||
<PackageReference Include="MudBlazor" Version="7.8.0" />
|
||||
<PackageReference Include="MudBlazor.Markdown" Version="7.8.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.70" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.10" />
|
||||
<PackageReference Include="MudBlazor" Version="7.14.0" />
|
||||
<PackageReference Include="MudBlazor.Markdown" Version="7.14.0" />
|
||||
<PackageReference Include="ReverseMarkdown" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -24,10 +24,18 @@
|
||||
<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="Job Posting" Description="Generate a job posting for a given job description." Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>
|
||||
<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"/>
|
||||
</MudStack>
|
||||
|
||||
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
|
||||
Learning
|
||||
</MudText>
|
||||
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
|
||||
<AssistantBlock Name="Bias of the Day" Description="Learn about one cognitive bias every day." Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
|
||||
</MudStack>
|
||||
|
||||
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
|
||||
Software Engineering
|
||||
</MudText>
|
||||
|
||||
@@ -22,13 +22,16 @@
|
||||
{
|
||||
foreach (var block in this.chatThread.Blocks.OrderBy(n => n.Time))
|
||||
{
|
||||
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content"/>
|
||||
@if (!block.HideFromUser)
|
||||
{
|
||||
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content"/>
|
||||
}
|
||||
}
|
||||
}
|
||||
</ChildContent>
|
||||
<FooterContent>
|
||||
<MudElement Style="flex: 0 0 auto;">
|
||||
<MudTextField T="string" @ref="@this.inputField" @bind-Text="@this.userInput" Variant="Variant.Outlined" AutoGrow="@true" Lines="3" MaxLines="12" Label="@this.InputLabel" Placeholder="@this.ProviderPlaceholder" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Send" OnAdornmentClick="() => this.SendMessage()" ReadOnly="!this.IsProviderSelected || this.isStreaming" Immediate="@true" OnKeyUp="this.InputKeyEvent" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||
<MudTextField T="string" @ref="@this.inputField" @bind-Text="@this.userInput" Variant="Variant.Outlined" AutoGrow="@true" Lines="3" MaxLines="12" Label="@this.InputLabel" Placeholder="@this.ProviderPlaceholder" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Send" OnAdornmentClick="() => this.SendMessage()" ReadOnly="!this.IsProviderSelected || this.isStreaming" Immediate="@true" OnKeyUp="this.InputKeyEvent" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="@this.UserInputClass" Style="@this.UserInputStyle"/>
|
||||
</MudElement>
|
||||
<MudToolBar WrapContent="true" Gutters="@false" Class="border border-solid rounded" Style="border-color: lightgrey;">
|
||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
||||
@@ -70,6 +73,11 @@
|
||||
</MudTooltip>
|
||||
}
|
||||
|
||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
||||
{
|
||||
<ConfidenceInfo Mode="ConfidenceInfoMode.ICON" LLMProvider="@this.providerSettings.UsedLLMProvider"/>
|
||||
}
|
||||
|
||||
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" />
|
||||
</MudToolBar>
|
||||
</FooterContent>
|
||||
|
||||
@@ -45,7 +45,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
private bool workspacesVisible;
|
||||
private Workspaces? workspaces;
|
||||
private bool mustScrollToBottomAfterRender;
|
||||
private bool mustStoreChat;
|
||||
private bool mustLoadChat;
|
||||
private LoadChat loadChat;
|
||||
private byte scrollRenderCountdown;
|
||||
private bool autoSaveEnabled;
|
||||
|
||||
// Unfortunately, we need the input field reference to blur the focus away. Without
|
||||
// this, we cannot clear the input field.
|
||||
@@ -55,7 +59,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE ]);
|
||||
this.ApplyFilters([], [ Event.HAS_CHAT_UNSAVED_CHANGES, Event.RESET_CHAT_STATE, Event.CHAT_STREAMING_DONE ]);
|
||||
|
||||
// Configure the spellchecking for the user input:
|
||||
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
||||
@@ -68,14 +72,23 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
this.chatThread = deferredContent;
|
||||
if (this.chatThread is not null)
|
||||
{
|
||||
var firstUserBlock = this.chatThread.Blocks.FirstOrDefault(x => x.Role == ChatRole.USER);
|
||||
if (firstUserBlock is not null)
|
||||
if (string.IsNullOrWhiteSpace(this.chatThread.Name))
|
||||
{
|
||||
this.chatThread.Name = firstUserBlock.Content switch
|
||||
var firstUserBlock = this.chatThread.Blocks.FirstOrDefault(x => x.Role == ChatRole.USER);
|
||||
if (firstUserBlock is not null)
|
||||
{
|
||||
ContentText textBlock => this.ExtractThreadName(textBlock.Text),
|
||||
_ => "Thread"
|
||||
};
|
||||
this.chatThread.Name = firstUserBlock.Content switch
|
||||
{
|
||||
ContentText textBlock => this.ExtractThreadName(textBlock.Text),
|
||||
_ => "Thread"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if(this.chatThread.WorkspaceId != Guid.Empty)
|
||||
{
|
||||
this.autoSaveEnabled = true;
|
||||
this.mustStoreChat = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +99,33 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
this.StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
var deferredLoading = MessageBus.INSTANCE.CheckDeferredMessages<LoadChat>(Event.LOAD_CHAT).FirstOrDefault();
|
||||
if (deferredLoading != default)
|
||||
{
|
||||
this.loadChat = deferredLoading;
|
||||
this.mustLoadChat = true;
|
||||
}
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender && this.workspaces is not null && this.chatThread is not null && this.mustStoreChat)
|
||||
{
|
||||
this.mustStoreChat = false;
|
||||
await this.workspaces.StoreChat(this.chatThread, false);
|
||||
this.currentWorkspaceId = this.chatThread.WorkspaceId;
|
||||
this.currentWorkspaceName = await this.workspaces.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||
}
|
||||
|
||||
if (firstRender && this.workspaces is not null && this.mustLoadChat)
|
||||
{
|
||||
this.mustLoadChat = false;
|
||||
await this.workspaces.LoadChat(this.loadChat);
|
||||
}
|
||||
|
||||
if(this.mustScrollToBottomAfterRender)
|
||||
{
|
||||
if (--this.scrollRenderCountdown == 0)
|
||||
@@ -110,16 +144,20 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
#endregion
|
||||
|
||||
private bool IsProviderSelected => this.providerSettings.UsedProvider != Providers.NONE;
|
||||
private bool IsProviderSelected => this.providerSettings.UsedLLMProvider != LLMProviders.NONE;
|
||||
|
||||
private string ProviderPlaceholder => this.IsProviderSelected ? "Type your input here..." : "Select a provider first";
|
||||
|
||||
private string InputLabel => this.IsProviderSelected ? $"Your Prompt (use selected instance '{this.providerSettings.InstanceName}', provider '{this.providerSettings.UsedProvider.ToName()}')" : "Select a provider first";
|
||||
private string InputLabel => this.IsProviderSelected ? $"Your Prompt (use selected instance '{this.providerSettings.InstanceName}', provider '{this.providerSettings.UsedLLMProvider.ToName()}')" : "Select a provider first";
|
||||
|
||||
private bool CanThreadBeSaved => this.chatThread is not null && this.chatThread.Blocks.Count > 0;
|
||||
|
||||
private string TooltipAddChatToWorkspace => $"Start new chat in workspace \"{this.currentWorkspaceName}\"";
|
||||
|
||||
private string UserInputStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager) : string.Empty;
|
||||
|
||||
private string UserInputClass => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? "confidence-border" : string.Empty;
|
||||
|
||||
private void ProfileWasChanged(Profile profile)
|
||||
{
|
||||
this.currentProfile = profile;
|
||||
@@ -451,16 +489,19 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
#region Overrides of MSGComponentBase
|
||||
|
||||
public override Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
public override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
|
||||
{
|
||||
switch (triggeredEvent)
|
||||
{
|
||||
case Event.RESET_CHAT_STATE:
|
||||
this.ResetState();
|
||||
break;
|
||||
|
||||
case Event.CHAT_STREAMING_DONE:
|
||||
if(this.autoSaveEnabled)
|
||||
await this.SaveThread();
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) where TResult : default where TPayload : default
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@using AIStudio.Assistants.TextSummarizer
|
||||
@using AIStudio.Provider
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Settings.DataModel
|
||||
@using Host = AIStudio.Provider.SelfHosted.Host
|
||||
|
||||
<MudText Typo="Typo.h3" Class="mb-12">Settings</MudText>
|
||||
@@ -17,7 +18,7 @@
|
||||
task. As an LLM provider, you can also choose local providers. However, to use this app, you must
|
||||
configure at least one provider.
|
||||
</MudJustifiedText>
|
||||
<MudTable Items="@this.SettingsManager.ConfigurationData.Providers" Class="border-dashed border rounded-lg">
|
||||
<MudTable Items="@this.SettingsManager.ConfigurationData.Providers" Hover="@true" Class="border-dashed border rounded-lg">
|
||||
<ColGroup>
|
||||
<col style="width: 3em;"/>
|
||||
<col style="width: 12em;"/>
|
||||
@@ -35,13 +36,13 @@
|
||||
<RowTemplate>
|
||||
<MudTd>@context.Num</MudTd>
|
||||
<MudTd>@context.InstanceName</MudTd>
|
||||
<MudTd>@context.UsedProvider</MudTd>
|
||||
<MudTd>@context.UsedLLMProvider</MudTd>
|
||||
<MudTd>
|
||||
@if (context.UsedProvider is not Providers.SELF_HOSTED)
|
||||
@if (context.UsedLLMProvider is not LLMProviders.SELF_HOSTED)
|
||||
{
|
||||
@this.GetProviderModelName(context)
|
||||
}
|
||||
else if (context.UsedProvider is Providers.SELF_HOSTED && context.Host is not Host.LLAMACPP)
|
||||
else if (context.UsedLLMProvider is LLMProviders.SELF_HOSTED && context.Host is not Host.LLAMACPP)
|
||||
{
|
||||
@this.GetProviderModelName(context)
|
||||
}
|
||||
@@ -51,7 +52,7 @@
|
||||
}
|
||||
</MudTd>
|
||||
<MudTd Style="text-align: left;">
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Class="ma-2" Href="@this.GetProviderDashboardURL(context.UsedProvider)" Target="_blank" Disabled="@(!this.HasDashboard(context.UsedProvider))">
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Class="ma-2" Href="@this.GetProviderDashboardURL(context.UsedLLMProvider)" Target="_blank" Disabled="@(!this.HasDashboard(context.UsedLLMProvider))">
|
||||
Open Dashboard
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" Class="ma-2" OnClick="() => this.EditProvider(context)">
|
||||
@@ -72,6 +73,62 @@
|
||||
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddProvider">
|
||||
Add Provider
|
||||
</MudButton>
|
||||
|
||||
<MudText Typo="Typo.h4" Class="mb-3">LLM Provider Confidence</MudText>
|
||||
<MudJustifiedText Class="mb-3">
|
||||
Do you want to always be able to recognize how trustworthy your LLM providers are? This way,
|
||||
you keep control over which provider you send your data to. You have two options for this:
|
||||
Either you choose a common schema, or you configure the trust levels for each LLM provider yourself.
|
||||
</MudJustifiedText>
|
||||
|
||||
<ConfigurationOption OptionDescription="Do you want to enforce an app-wide minimum confidence level?" LabelOn="Yes, enforce a minimum confidence level" LabelOff="No, do not enforce a minimum confidence level" State="@(() => this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence = updatedState)" OptionHelp="When enabled, you can enforce a minimum confidence level for all LLM providers. This way, you can ensure that only trustworthy providers are used."/>
|
||||
@if(this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence)
|
||||
{
|
||||
<ConfigurationMinConfidenceSelection RestrictToGlobalMinimumConfidence="@false" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence = selectedValue)"/>
|
||||
}
|
||||
|
||||
<ConfigurationOption OptionDescription="Show provider's confidence level?" LabelOn="Yes, show me the confidence level" LabelOff="No, please hide the confidence level" State="@(() => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence = updatedState)" OptionHelp="When enabled, we show you the confidence level for the selected provider in the app. This helps you assess where you are sending your data at any time. Example: are you currently working with sensitive data? Then choose a particularly trustworthy provider, etc."/>
|
||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
||||
{
|
||||
<ConfigurationSelect OptionDescription="Select a confidence scheme" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme)" Data="@ConfigurationSelectDataFactory.GetConfidenceSchemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme = selectedValue)" OptionHelp="Choose the scheme that best suits you and your life. Do you trust any western provider? Or only providers from the USA or exclusively European providers? Then choose the appropriate scheme. Alternatively, you can assign the confidence levels to each provider yourself."/>
|
||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme is ConfidenceSchemes.CUSTOM)
|
||||
{
|
||||
<MudTable Items="@(Enum.GetValues<LLMProviders>().Where(x => x is not LLMProviders.NONE))" Hover="@true" Class="border-dashed border rounded-lg">
|
||||
<ColGroup>
|
||||
<col style="width: 12em;"/>
|
||||
<col/>
|
||||
<col style="width: 22em;"/>
|
||||
</ColGroup>
|
||||
<HeaderContent>
|
||||
<MudTh>LLM Provider</MudTh>
|
||||
<MudTh>Description</MudTh>
|
||||
<MudTh>Confidence Level</MudTh>
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd Style="vertical-align: top;">
|
||||
@context.ToName()
|
||||
</MudTd>
|
||||
<MudTd>
|
||||
<MudMarkdown Value="@context.GetConfidence(this.SettingsManager).Description"/>
|
||||
</MudTd>
|
||||
<MudTd Style="vertical-align: top;">
|
||||
<MudMenu StartIcon="@Icons.Material.Filled.Security" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@this.GetCurrentConfidenceLevelName(context)" Variant="Variant.Filled" Style="@this.SetCurrentConfidenceLevelColorStyle(context)">
|
||||
@foreach (var confidenceLevel in Enum.GetValues<ConfidenceLevel>().OrderBy(n => n))
|
||||
{
|
||||
if(confidenceLevel is ConfidenceLevel.NONE or ConfidenceLevel.UNKNOWN)
|
||||
continue;
|
||||
|
||||
<MudMenuItem OnClick="@(async () => await this.ChangeCustomConfidenceLevel(context, confidenceLevel))">
|
||||
@confidenceLevel.GetName()
|
||||
</MudMenuItem>
|
||||
}
|
||||
</MudMenu>
|
||||
</MudTd>
|
||||
</RowTemplate>
|
||||
</MudTable>
|
||||
}
|
||||
}
|
||||
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Person4" HeaderText="Configure Profiles">
|
||||
@@ -88,7 +145,7 @@
|
||||
code. In these profiles, you can record how much experience you have or which methods you like or
|
||||
dislike using. Later, you can choose when and where you want to use each profile.
|
||||
</MudJustifiedText>
|
||||
<MudTable Items="@this.SettingsManager.ConfigurationData.Profiles" Class="border-dashed border rounded-lg">
|
||||
<MudTable Items="@this.SettingsManager.ConfigurationData.Profiles" Hover="@true" Class="border-dashed border rounded-lg">
|
||||
<ColGroup>
|
||||
<col style="width: 3em;"/>
|
||||
<col/>
|
||||
@@ -124,6 +181,7 @@
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="App Options">
|
||||
<ConfigurationSelect OptionDescription="Color theme" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="Choose the color theme that best suits for you."/>
|
||||
<ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/>
|
||||
<ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." />
|
||||
<ConfigurationSelect OptionDescription="Check for updates" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="How often should we check for app updates?"/>
|
||||
@@ -151,7 +209,8 @@
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
<ConfigurationOption OptionDescription="Preselect icon options?" LabelOn="Icon options are preselected" LabelOff="No icon options are preselected" State="@(() => this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect the icon options. This is might be useful when you prefer a specific icon source or LLM model."/>
|
||||
<ConfigurationSelect OptionDescription="Preselect the icon source" Disabled="@(() => !this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.IconFinder.PreselectedSource)" Data="@ConfigurationSelectDataFactory.GetIconSourcesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.IconFinder.PreselectedSource = selectedValue)" OptionHelp="Which icon source should be preselected?"/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.IconFinder.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.IconFinder.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.ICON_FINDER_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.IconFinder.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.IconFinder.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
@@ -168,7 +227,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.Translation.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.Translation.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.Translation.PreselectOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Translation.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Translation.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Translation.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.Translation.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Translation.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Translation.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.TRANSLATION_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Translation.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Translation.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Translation.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
@@ -181,7 +241,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another programming language" Disabled="@(() => !this.SettingsManager.ConfigurationData.Coding.PreselectOptions)" Icon="@Icons.Material.Filled.Code" Text="@(() => this.SettingsManager.ConfigurationData.Coding.PreselectedOtherProgrammingLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.Coding.PreselectedOtherProgrammingLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Coding.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Coding.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Coding.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.Coding.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Coding.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Coding.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.CODING_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Coding.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Coding.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Coding.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.Coding.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Coding.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Coding.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
@@ -202,7 +263,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect your expertise" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" Icon="@Icons.Material.Filled.Person" Text="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.TEXT_SUMMARIZER_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
@@ -230,7 +292,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another agenda language" Disabled="@(() => !this.SettingsManager.ConfigurationData.Agenda.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.Agenda.PreselectedOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.Agenda.PreselectedOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Agenda.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.Agenda.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Agenda.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Agenda.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.AGENDA_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Agenda.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Agenda.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.Agenda.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Agenda.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Agenda.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
@@ -243,7 +306,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.GrammarSpelling.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.GRAMMAR_SPELLING_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
@@ -257,7 +321,8 @@
|
||||
}
|
||||
<ConfigurationSelect OptionDescription="Preselect a writing style" Disabled="@(() => !this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedWritingStyle)" Data="@ConfigurationSelectDataFactory.GetWritingStyles4RewriteData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedWritingStyle = selectedValue)" OptionHelp="Which writing style should be preselected?"/>
|
||||
<ConfigurationSelect OptionDescription="Preselect a sentence structure" Disabled="@(() => !this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedSentenceStructure)" Data="@ConfigurationSelectDataFactory.GetSentenceStructureData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedSentenceStructure = selectedValue)" OptionHelp="Which voice should be preselected for the sentence structure?"/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.RewriteImprove.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.RewriteImprove.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.REWRITE_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
@@ -272,18 +337,40 @@
|
||||
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.EMail.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.EMail.PreselectOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationSelect OptionDescription="Preselect a writing style" Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.EMail.PreselectedWritingStyle)" Data="@ConfigurationSelectDataFactory.GetWritingStyles4EMailData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.EMail.PreselectedWritingStyle = selectedValue)" OptionHelp="Which writing style should be preselected?"/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.EMail.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.EMail.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.EMail.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.EMail.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.EMAIL_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.EMail.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.EMail.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.EMail.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.EMail.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.EMail.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Work" HeaderText="Assistant: Job Postings">
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
<ConfigurationOption OptionDescription="Preselect job posting options?" LabelOn="Job posting options are preselected" LabelOff="No job posting options are preselected" State="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect some job posting options. This is might be useful when you prefer a specific LLM model."/>
|
||||
<ConfigurationText OptionDescription="Preselect the company name?" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Warehouse" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedCompanyName)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedCompanyName = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect some mandatory information about the job posting?" NumLines="6" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.TextSnippet" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedMandatoryInformation)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedMandatoryInformation = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect the job description?" NumLines="3" MaxLines="6" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Settings" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedJobDescription)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedJobDescription = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect the job qualifications?" NumLines="3" MaxLines="6" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Settings" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedQualifications)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedQualifications = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect the job responsibilities?" NumLines="3" MaxLines="6" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Settings" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedResponsibilities)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedResponsibilities = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect the work location?" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.MyLocation" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedWorkLocation)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedWorkLocation = updatedText)" />
|
||||
<ConfigurationText OptionDescription="Preselect the country (legal framework)?" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Flag" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedCountryLegalFramework)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectedCountryLegalFramework = updatedText)" />
|
||||
<ConfigurationSelect OptionDescription="Preselect the language" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.JobPostings.PreselectedTargetLanguage = selectedValue)" OptionHelp="Which target language should be preselected?"/>
|
||||
@if (this.SettingsManager.ConfigurationData.JobPostings.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.JobPostings.PreselectOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.JobPostings.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.JobPostings.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.JOB_POSTING_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.JobPostings.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.JobPostings.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.JobPostings.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Gavel" HeaderText="Assistant: Legal Check">
|
||||
<ConfigurationOption OptionDescription="Hide the web content reader?" LabelOn="Web content reader is hidden" LabelOff="Web content reader is shown" State="@(() => this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader = updatedState)" OptionHelp="When activated, the web content reader is hidden and cannot be used. As a result, the user interface becomes a bit easier to use."/>
|
||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||
<ConfigurationOption OptionDescription="Preselect legal check options?" LabelOn="Legal check options are preselected" LabelOff="No legal check options are preselected" State="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect some legal check options. This is might be useful when you prefer a specific LLM model."/>
|
||||
<ConfigurationOption OptionDescription="Preselect the web content reader?" Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions || this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader)" LabelOn="Web content reader is preselected" LabelOff="Web content reader is not preselected" State="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectWebContentReader)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LegalCheck.PreselectWebContentReader = updatedState)" OptionHelp="When enabled, the web content reader is preselected. This is might be useful when you prefer to load legal content from the web very often."/>
|
||||
<ConfigurationOption OptionDescription="Preselect the content cleaner agent?" Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions || this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader)" LabelOn="Content cleaner agent is preselected" LabelOff="Content cleaner agent is not preselected" State="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectContentCleanerAgent)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.LegalCheck.PreselectContentCleanerAgent = updatedState)" OptionHelp="When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the legal content before translating it."/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LegalCheck.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LegalCheck.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.LEGAL_CHECK_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.LegalCheck.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
@@ -296,7 +383,8 @@
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another language" Disabled="@(() => !this.SettingsManager.ConfigurationData.Synonyms.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.Synonyms.PreselectedOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.Synonyms.PreselectedOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Synonyms.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Synonyms.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Synonyms.PreselectedProvider = selectedValue)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.Synonyms.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Synonyms.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Synonyms.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.SYNONYMS_ASSISTANT" 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>
|
||||
|
||||
@@ -309,7 +397,34 @@
|
||||
<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)"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.MyTasks.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.MyTasks.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.MyTasks.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.MY_TASKS_ASSISTANT" 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.Psychology" HeaderText="Assistant: Bias of the Day">
|
||||
|
||||
<ConfigurationOption OptionDescription="Restrict to one bias a day?" LabelOn="Yes, you can only retrieve one bias per day" LabelOff="No restriction. You can retrieve as many biases as you want per day." State="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.BiasOfTheDay.RestrictOneBiasPerDay = updatedState)"/>
|
||||
|
||||
<MudField Label="Statistics" Variant="Variant.Outlined" Class="mb-2">
|
||||
<MudText Typo="Typo.body1">
|
||||
You have learned about @this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias.Count out of @BiasCatalog.ALL_BIAS.Count biases.
|
||||
</MudText>
|
||||
<MudButton Size="Size.Small" Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Restore" Color="Color.Error" OnClick="@(() => this.ResetBiasOfTheDayHistory())">
|
||||
Reset
|
||||
</MudButton>
|
||||
</MudField>
|
||||
|
||||
<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.BiasOfTheDay.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.BiasOfTheDay.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.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage = selectedValue)" OptionHelp="Which language should be preselected?"/>
|
||||
@if (this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||
{
|
||||
<ConfigurationText OptionDescription="Preselect another language" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedOtherLanguage = updatedText)"/>
|
||||
}
|
||||
<ConfigurationSelect OptionDescription="Preselect one of your profiles?" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProfile = selectedValue)" OptionHelp="Would you like to preselect one of your profiles?"/>
|
||||
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.MinimumProviderConfidence = selectedValue)"/>
|
||||
<ConfigurationProviderSelection Component="Components.BIAS_DAY_ASSISTANT" Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider = selectedValue)"/>
|
||||
</MudPaper>
|
||||
</ExpansionPanel>
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
{ x => x.DataNum, provider.Num },
|
||||
{ x => x.DataId, provider.Id },
|
||||
{ x => x.DataInstanceName, provider.InstanceName },
|
||||
{ x => x.DataProvider, provider.UsedProvider },
|
||||
{ x => x.DataLLMProvider, provider.UsedLLMProvider },
|
||||
{ x => x.DataModel, provider.Model },
|
||||
{ x => x.DataHostname, provider.Hostname },
|
||||
{ x => x.IsSelfHosted, provider.IsSelfHosted },
|
||||
@@ -126,22 +126,22 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private bool HasDashboard(Providers provider) => provider switch
|
||||
private bool HasDashboard(LLMProviders llmProvider) => llmProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => true,
|
||||
Providers.MISTRAL => true,
|
||||
Providers.ANTHROPIC => true,
|
||||
Providers.FIREWORKS => true,
|
||||
LLMProviders.OPEN_AI => true,
|
||||
LLMProviders.MISTRAL => true,
|
||||
LLMProviders.ANTHROPIC => true,
|
||||
LLMProviders.FIREWORKS => true,
|
||||
|
||||
_ => false,
|
||||
};
|
||||
|
||||
private string GetProviderDashboardURL(Providers provider) => provider switch
|
||||
private string GetProviderDashboardURL(LLMProviders llmProvider) => llmProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => "https://platform.openai.com/usage",
|
||||
Providers.MISTRAL => "https://console.mistral.ai/usage/",
|
||||
Providers.ANTHROPIC => "https://console.anthropic.com/settings/plans",
|
||||
Providers.FIREWORKS => "https://fireworks.ai/account/billing",
|
||||
LLMProviders.OPEN_AI => "https://platform.openai.com/usage",
|
||||
LLMProviders.MISTRAL => "https://console.mistral.ai/usage/",
|
||||
LLMProviders.ANTHROPIC => "https://console.anthropic.com/settings/plans",
|
||||
LLMProviders.FIREWORKS => "https://fireworks.ai/account/billing",
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
@@ -160,6 +160,28 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
this.availableProviders.Add(new (provider.InstanceName, provider.Id));
|
||||
}
|
||||
|
||||
private string GetCurrentConfidenceLevelName(LLMProviders llmProvider)
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level))
|
||||
return level.GetName();
|
||||
|
||||
return "Not yet configured";
|
||||
}
|
||||
|
||||
private string SetCurrentConfidenceLevelColorStyle(LLMProviders llmProvider)
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level))
|
||||
return $"background-color: {level.GetColor(this.SettingsManager)};";
|
||||
|
||||
return $"background-color: {ConfidenceLevel.UNKNOWN.GetColor(this.SettingsManager)};";
|
||||
}
|
||||
|
||||
private async Task ChangeCustomConfidenceLevel(LLMProviders llmProvider, ConfidenceLevel level)
|
||||
{
|
||||
this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme[llmProvider] = level;
|
||||
await this.SettingsManager.StoreSettings();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Profile related
|
||||
@@ -227,6 +249,29 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bias-of-the-day related
|
||||
|
||||
private async Task ResetBiasOfTheDayHistory()
|
||||
{
|
||||
var dialogParameters = new DialogParameters
|
||||
{
|
||||
{ "Message", "Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again." },
|
||||
};
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Reset your bias-of-the-day statistics", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
this.SettingsManager.ConfigurationData.BiasOfTheDay.UsedBias.Clear();
|
||||
this.SettingsManager.ConfigurationData.BiasOfTheDay.DateLastBiasDrawn = DateOnly.MinValue;
|
||||
await this.SettingsManager.StoreSettings();
|
||||
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMessageBusReceiver
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</MudButton>
|
||||
</div>
|
||||
|
||||
<MudGrid Justify="Justify.Center" Spacing="2" Style="width: 100%;" Class="align-center ma-0">
|
||||
<MudGrid Justify="Justify.Center" Spacing="2" Style="width: 100%;" Class="ma-0">
|
||||
<MudItem Class="pa-0 pr-2" xs="6">
|
||||
<MudPaper Elevation="3" Class="border-solid border rounded-lg pa-3">
|
||||
<MudText Typo="Typo.h4" Class="mb-3 d-flex align-center">
|
||||
@@ -28,6 +28,20 @@
|
||||
<MudButton Href="https://github.com/sponsors/MindWorkAI" StartIcon="@Icons.Material.Filled.People" Variant="Variant.Filled" Target="_blank">
|
||||
Become a contributor
|
||||
</MudButton>
|
||||
|
||||
<MudText Typo="Typo.h6" Class="mt-8">
|
||||
The first 10 supporters who make a monthly contribution:
|
||||
</MudText>
|
||||
<MudList T="string">
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Person">
|
||||
<MudLink Href="https://github.com/richard-stanton" Target="_blank">
|
||||
richard-stanton
|
||||
</MudLink>
|
||||
<MudText Typo="Typo.body1" Class="ml-3" Inline="@true">
|
||||
Thank you, Richard, for being the first.
|
||||
</MudText>
|
||||
</MudListItem>
|
||||
</MudList>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ internal sealed class Program
|
||||
});
|
||||
|
||||
builder.Services.AddMudMarkdownServices();
|
||||
builder.Services.AddSingleton(new MudTheme());
|
||||
builder.Services.AddSingleton(MessageBus.INSTANCE);
|
||||
builder.Services.AddSingleton(rust);
|
||||
builder.Services.AddMudMarkdownClipboardService<MarkdownClipboardService>();
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Provider;
|
||||
|
||||
public sealed record Confidence
|
||||
{
|
||||
public ConfidenceLevel Level { get; private init; } = ConfidenceLevel.UNKNOWN;
|
||||
|
||||
public string Region { get; private init; } = string.Empty;
|
||||
|
||||
public string Description { get; private init; } = string.Empty;
|
||||
|
||||
public List<string> Sources { get; private init; } = [];
|
||||
|
||||
private Confidence()
|
||||
{
|
||||
}
|
||||
|
||||
public Confidence WithSources(params string[] sources) => this with { Sources = sources.ToList() };
|
||||
|
||||
public Confidence WithRegion(string region) => this with { Region = region };
|
||||
|
||||
public Confidence WithLevel(ConfidenceLevel level) => this with { Level = level };
|
||||
|
||||
public string StyleBorder(SettingsManager settingsManager) => $"border: 2px solid {this.Level.GetColor(settingsManager)}; border-radius: 6px;";
|
||||
|
||||
public string SetColorStyle(SettingsManager settingsManager) => $"--confidence-color: {this.Level.GetColor(settingsManager)};";
|
||||
|
||||
public static readonly Confidence NONE = new()
|
||||
{
|
||||
Level = ConfidenceLevel.NONE,
|
||||
Description =
|
||||
"""
|
||||
No provider selected. Please select a provider to get see its confidence level.
|
||||
""",
|
||||
};
|
||||
|
||||
public static readonly Confidence USA_NOT_TRUSTED = new()
|
||||
{
|
||||
Level = ConfidenceLevel.UNTRUSTED,
|
||||
Description = "The provider operates its service from the USA and is subject to **U.S. jurisdiction**. In case of suspicion, authorities in the USA can access your data. The provider's terms of service state that **all your data can be used by the provider at will.**",
|
||||
};
|
||||
|
||||
public static readonly Confidence UNKNOWN = new()
|
||||
{
|
||||
Level = ConfidenceLevel.UNKNOWN,
|
||||
Description = "The trust level of this provider **has not yet** been thoroughly **investigated and evaluated**. We do not know if your data is safe.",
|
||||
};
|
||||
|
||||
public static readonly Confidence USA_NO_TRAINING = new()
|
||||
{
|
||||
Level = ConfidenceLevel.MODERATE,
|
||||
Description = "The provider operates its service from the USA and is subject to **US jurisdiction**. In case of suspicion, authorities in the USA can access your data. However, **your data is not used for training** purposes.",
|
||||
};
|
||||
|
||||
public static readonly Confidence GDPR_NO_TRAINING = new()
|
||||
{
|
||||
Level = ConfidenceLevel.MEDIUM,
|
||||
Description = "The provider is located in the EU and is subject to the **GDPR** (General Data Protection Regulation). Additionally, the provider states that **your data is not used for training**.",
|
||||
};
|
||||
|
||||
public static readonly Confidence SELF_HOSTED = new()
|
||||
{
|
||||
Level = ConfidenceLevel.HIGH,
|
||||
Description = "You or your organization operate the LLM locally or within your trusted network. In terms of data processing and security, this is the best possible way.",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace AIStudio.Provider;
|
||||
|
||||
public enum ConfidenceLevel
|
||||
{
|
||||
NONE = 0,
|
||||
UNTRUSTED = 1,
|
||||
|
||||
UNKNOWN = 10,
|
||||
|
||||
VERY_LOW = 90,
|
||||
LOW = 100,
|
||||
|
||||
MODERATE = 150,
|
||||
|
||||
MEDIUM = 200,
|
||||
|
||||
HIGH = 300,
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Provider;
|
||||
|
||||
public static class ConfidenceLevelExtensions
|
||||
{
|
||||
public static string GetName(this ConfidenceLevel level) => level switch
|
||||
{
|
||||
ConfidenceLevel.NONE => "No provider selected",
|
||||
|
||||
ConfidenceLevel.UNTRUSTED => "Untrusted",
|
||||
ConfidenceLevel.VERY_LOW => "Very Low",
|
||||
ConfidenceLevel.LOW => "Low",
|
||||
ConfidenceLevel.MODERATE => "Moderate",
|
||||
ConfidenceLevel.MEDIUM => "Medium",
|
||||
ConfidenceLevel.HIGH => "High",
|
||||
|
||||
_ => "Unknown confidence level",
|
||||
};
|
||||
|
||||
public static string GetColor(this ConfidenceLevel level, SettingsManager settingsManager) => (level, settingsManager.IsDarkMode) switch
|
||||
{
|
||||
(ConfidenceLevel.NONE, _) => "#cccccc",
|
||||
|
||||
(ConfidenceLevel.UNTRUSTED, false) => "#ff0000",
|
||||
(ConfidenceLevel.UNTRUSTED, true) => "#800000",
|
||||
|
||||
(ConfidenceLevel.VERY_LOW, false) => "#ff6600",
|
||||
(ConfidenceLevel.VERY_LOW, true) => "#803300",
|
||||
|
||||
(ConfidenceLevel.LOW, false) => "#ffcc00",
|
||||
(ConfidenceLevel.LOW, true) => "#806600",
|
||||
|
||||
(ConfidenceLevel.MODERATE, false) => "#99cc00",
|
||||
(ConfidenceLevel.MODERATE, true) => "#4d6600",
|
||||
|
||||
(ConfidenceLevel.MEDIUM, false) => "#86b300",
|
||||
(ConfidenceLevel.MEDIUM, true) => "#394d00",
|
||||
|
||||
(ConfidenceLevel.HIGH, false) => "#009933",
|
||||
(ConfidenceLevel.HIGH, true) => "#004d1a",
|
||||
|
||||
(_, false) => "#cc6600",
|
||||
(_, true) => "#663300",
|
||||
};
|
||||
|
||||
public static string SetColorStyle(this ConfidenceLevel level, SettingsManager settingsManager) => $"--confidence-color: {level.GetColor(settingsManager)};";
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ namespace AIStudio.Provider;
|
||||
/// <summary>
|
||||
/// Enum for all available providers.
|
||||
/// </summary>
|
||||
public enum Providers
|
||||
public enum LLMProviders
|
||||
{
|
||||
NONE = 0,
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
using AIStudio.Provider.Anthropic;
|
||||
using AIStudio.Provider.Fireworks;
|
||||
using AIStudio.Provider.Mistral;
|
||||
using AIStudio.Provider.OpenAI;
|
||||
using AIStudio.Provider.SelfHosted;
|
||||
using AIStudio.Settings;
|
||||
|
||||
namespace AIStudio.Provider;
|
||||
|
||||
public static class LLMProvidersExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the human-readable name of the provider.
|
||||
/// </summary>
|
||||
/// <param name="llmProvider">The provider.</param>
|
||||
/// <returns>The human-readable name of the provider.</returns>
|
||||
public static string ToName(this LLMProviders llmProvider) => llmProvider switch
|
||||
{
|
||||
LLMProviders.NONE => "No provider selected",
|
||||
|
||||
LLMProviders.OPEN_AI => "OpenAI",
|
||||
LLMProviders.ANTHROPIC => "Anthropic",
|
||||
LLMProviders.MISTRAL => "Mistral",
|
||||
|
||||
LLMProviders.FIREWORKS => "Fireworks.ai",
|
||||
|
||||
LLMProviders.SELF_HOSTED => "Self-hosted",
|
||||
|
||||
_ => "Unknown",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get a provider's confidence.
|
||||
/// </summary>
|
||||
/// <param name="llmProvider">The provider.</param>
|
||||
/// <param name="settingsManager">The settings manager.</param>
|
||||
/// <returns>The confidence of the provider.</returns>
|
||||
public static Confidence GetConfidence(this LLMProviders llmProvider, SettingsManager settingsManager) => llmProvider switch
|
||||
{
|
||||
LLMProviders.NONE => Confidence.NONE,
|
||||
|
||||
LLMProviders.FIREWORKS => Confidence.USA_NOT_TRUSTED.WithRegion("America, U.S.").WithSources("https://fireworks.ai/terms-of-service").WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
|
||||
LLMProviders.OPEN_AI => Confidence.USA_NO_TRAINING.WithRegion("America, U.S.").WithSources(
|
||||
"https://platform.openai.com/docs/models/default-usage-policies-by-endpoint",
|
||||
"https://openai.com/policies/terms-of-use/",
|
||||
"https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance",
|
||||
"https://openai.com/enterprise-privacy/"
|
||||
).WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
|
||||
LLMProviders.ANTHROPIC => Confidence.USA_NO_TRAINING.WithRegion("America, U.S.").WithSources("https://www.anthropic.com/legal/commercial-terms").WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
|
||||
LLMProviders.MISTRAL => Confidence.GDPR_NO_TRAINING.WithRegion("Europe, France").WithSources("https://mistral.ai/terms/#terms-of-service-la-plateforme").WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
|
||||
LLMProviders.SELF_HOSTED => Confidence.SELF_HOSTED.WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
|
||||
_ => Confidence.UNKNOWN.WithLevel(settingsManager.GetConfiguredConfidenceLevel(llmProvider)),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new provider instance based on the provider value.
|
||||
/// </summary>
|
||||
/// <param name="providerSettings">The provider settings.</param>
|
||||
/// <param name="logger">The logger to use.</param>
|
||||
/// <returns>The provider instance.</returns>
|
||||
public static IProvider CreateProvider(this Settings.Provider providerSettings, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
return providerSettings.UsedLLMProvider switch
|
||||
{
|
||||
LLMProviders.OPEN_AI => new ProviderOpenAI(logger) { InstanceName = providerSettings.InstanceName },
|
||||
LLMProviders.ANTHROPIC => new ProviderAnthropic(logger) { InstanceName = providerSettings.InstanceName },
|
||||
LLMProviders.MISTRAL => new ProviderMistral(logger) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
LLMProviders.FIREWORKS => new ProviderFireworks(logger) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
LLMProviders.SELF_HOSTED => new ProviderSelfHosted(logger, providerSettings) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
_ => new NoProvider(),
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to create provider: {e.Message}");
|
||||
return new NoProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,18 +153,18 @@ public sealed class ProviderOpenAI(ILogger logger) : BaseProvider("https://api.o
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<Model>> GetTextModels(string? apiKeyProvisional = null, CancellationToken token = default)
|
||||
{
|
||||
return this.LoadModels("gpt-", token, apiKeyProvisional);
|
||||
return this.LoadModels(["gpt-", "o1-"], token, apiKeyProvisional);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<Model>> GetImageModels(string? apiKeyProvisional = null, CancellationToken token = default)
|
||||
{
|
||||
return this.LoadModels("dall-e-", token, apiKeyProvisional);
|
||||
return this.LoadModels(["dall-e-"], token, apiKeyProvisional);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private async Task<IEnumerable<Model>> LoadModels(string prefix, CancellationToken token, string? apiKeyProvisional = null)
|
||||
private async Task<IEnumerable<Model>> LoadModels(string[] prefixes, CancellationToken token, string? apiKeyProvisional = null)
|
||||
{
|
||||
var secretKey = apiKeyProvisional switch
|
||||
{
|
||||
@@ -187,6 +187,6 @@ public sealed class ProviderOpenAI(ILogger logger) : BaseProvider("https://api.o
|
||||
return [];
|
||||
|
||||
var modelResponse = await response.Content.ReadFromJsonAsync<ModelsResponse>(token);
|
||||
return modelResponse.Data.Where(n => n.Id.StartsWith(prefix, StringComparison.InvariantCulture));
|
||||
return modelResponse.Data.Where(model => prefixes.Any(prefix => model.Id.StartsWith(prefix, StringComparison.InvariantCulture)));
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using AIStudio.Provider.Anthropic;
|
||||
using AIStudio.Provider.Fireworks;
|
||||
using AIStudio.Provider.Mistral;
|
||||
using AIStudio.Provider.OpenAI;
|
||||
using AIStudio.Provider.SelfHosted;
|
||||
|
||||
namespace AIStudio.Provider;
|
||||
|
||||
public static class ProvidersExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the human-readable name of the provider.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <returns>The human-readable name of the provider.</returns>
|
||||
public static string ToName(this Providers provider) => provider switch
|
||||
{
|
||||
Providers.NONE => "No provider selected",
|
||||
|
||||
Providers.OPEN_AI => "OpenAI",
|
||||
Providers.ANTHROPIC => "Anthropic",
|
||||
Providers.MISTRAL => "Mistral",
|
||||
|
||||
Providers.FIREWORKS => "Fireworks.ai",
|
||||
|
||||
Providers.SELF_HOSTED => "Self-hosted",
|
||||
|
||||
_ => "Unknown",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new provider instance based on the provider value.
|
||||
/// </summary>
|
||||
/// <param name="providerSettings">The provider settings.</param>
|
||||
/// <param name="logger">The logger to use.</param>
|
||||
/// <returns>The provider instance.</returns>
|
||||
public static IProvider CreateProvider(this Settings.Provider providerSettings, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
return providerSettings.UsedProvider switch
|
||||
{
|
||||
Providers.OPEN_AI => new ProviderOpenAI(logger) { InstanceName = providerSettings.InstanceName },
|
||||
Providers.ANTHROPIC => new ProviderAnthropic(logger) { InstanceName = providerSettings.InstanceName },
|
||||
Providers.MISTRAL => new ProviderMistral(logger) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
Providers.FIREWORKS => new ProviderFireworks(logger) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
Providers.SELF_HOSTED => new ProviderSelfHosted(logger, providerSettings) { InstanceName = providerSettings.InstanceName },
|
||||
|
||||
_ => new NoProvider(),
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to create provider: {e.Message}");
|
||||
return new NoProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
@@ -23,6 +24,9 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
||||
/// <inheritdoc />
|
||||
public async IAsyncEnumerable<string> StreamChatCompletion(Provider.Model chatModel, ChatThread chatThread, [EnumeratorCancellation] CancellationToken token = default)
|
||||
{
|
||||
// Get the API key:
|
||||
var requestedSecret = await RUST_SERVICE.GetAPIKey(this, isTrying: true);
|
||||
|
||||
// Prepare the system prompt:
|
||||
var systemPrompt = new Message
|
||||
{
|
||||
@@ -62,68 +66,83 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
||||
MaxTokens = -1,
|
||||
}, JSON_SERIALIZER_OPTIONS);
|
||||
|
||||
// Build the HTTP post request:
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, provider.Host.ChatURL());
|
||||
|
||||
// Set the content:
|
||||
request.Content = new StringContent(providerChatRequest, Encoding.UTF8, "application/json");
|
||||
|
||||
// Send the request with the ResponseHeadersRead option.
|
||||
// This allows us to read the stream as soon as the headers are received.
|
||||
// This is important because we want to stream the responses.
|
||||
var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
|
||||
|
||||
// Open the response stream:
|
||||
var providerStream = await response.Content.ReadAsStreamAsync(token);
|
||||
|
||||
// Add a stream reader to read the stream, line by line:
|
||||
var streamReader = new StreamReader(providerStream);
|
||||
|
||||
// Read the stream, line by line:
|
||||
while(!streamReader.EndOfStream)
|
||||
StreamReader? streamReader = default;
|
||||
try
|
||||
{
|
||||
// Check if the token is canceled:
|
||||
if(token.IsCancellationRequested)
|
||||
yield break;
|
||||
|
||||
// Read the next line:
|
||||
var line = await streamReader.ReadLineAsync(token);
|
||||
|
||||
// Skip empty lines:
|
||||
if(string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
// Skip lines that do not start with "data: ". Regard
|
||||
// to the specification, we only want to read the data lines:
|
||||
if(!line.StartsWith("data: ", StringComparison.InvariantCulture))
|
||||
continue;
|
||||
// Build the HTTP post request:
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, provider.Host.ChatURL());
|
||||
|
||||
// Check if the line is the end of the stream:
|
||||
if (line.StartsWith("data: [DONE]", StringComparison.InvariantCulture))
|
||||
yield break;
|
||||
// Set the authorization header:
|
||||
if (requestedSecret.Success)
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", await requestedSecret.Secret.Decrypt(ENCRYPTION));
|
||||
|
||||
ResponseStreamLine providerResponse;
|
||||
try
|
||||
// Set the content:
|
||||
request.Content = new StringContent(providerChatRequest, Encoding.UTF8, "application/json");
|
||||
|
||||
// Send the request with the ResponseHeadersRead option.
|
||||
// This allows us to read the stream as soon as the headers are received.
|
||||
// This is important because we want to stream the responses.
|
||||
var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
|
||||
|
||||
// Open the response stream:
|
||||
var providerStream = await response.Content.ReadAsStreamAsync(token);
|
||||
|
||||
// Add a stream reader to read the stream, line by line:
|
||||
streamReader = new StreamReader(providerStream);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
this.logger.LogError($"Failed to stream chat completion from self-hosted provider '{this.InstanceName}': {e.Message}");
|
||||
}
|
||||
|
||||
if (streamReader is not null)
|
||||
{
|
||||
// Read the stream, line by line:
|
||||
while (!streamReader.EndOfStream)
|
||||
{
|
||||
// We know that the line starts with "data: ". Hence, we can
|
||||
// skip the first 6 characters to get the JSON data after that.
|
||||
var jsonData = line[6..];
|
||||
|
||||
// Deserialize the JSON data:
|
||||
providerResponse = JsonSerializer.Deserialize<ResponseStreamLine>(jsonData, JSON_SERIALIZER_OPTIONS);
|
||||
// Check if the token is canceled:
|
||||
if (token.IsCancellationRequested)
|
||||
yield break;
|
||||
|
||||
// Read the next line:
|
||||
var line = await streamReader.ReadLineAsync(token);
|
||||
|
||||
// Skip empty lines:
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
// Skip lines that do not start with "data: ". Regard
|
||||
// to the specification, we only want to read the data lines:
|
||||
if (!line.StartsWith("data: ", StringComparison.InvariantCulture))
|
||||
continue;
|
||||
|
||||
// Check if the line is the end of the stream:
|
||||
if (line.StartsWith("data: [DONE]", StringComparison.InvariantCulture))
|
||||
yield break;
|
||||
|
||||
ResponseStreamLine providerResponse;
|
||||
try
|
||||
{
|
||||
// We know that the line starts with "data: ". Hence, we can
|
||||
// skip the first 6 characters to get the JSON data after that.
|
||||
var jsonData = line[6..];
|
||||
|
||||
// Deserialize the JSON data:
|
||||
providerResponse = JsonSerializer.Deserialize<ResponseStreamLine>(jsonData, JSON_SERIALIZER_OPTIONS);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Skip invalid JSON data:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip empty responses:
|
||||
if (providerResponse == default || providerResponse.Choices.Count == 0)
|
||||
continue;
|
||||
|
||||
// Yield the response:
|
||||
yield return providerResponse.Choices[0].Delta.Content;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Skip invalid JSON data:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip empty responses:
|
||||
if(providerResponse == default || providerResponse.Choices.Count == 0)
|
||||
continue;
|
||||
|
||||
// Yield the response:
|
||||
yield return providerResponse.Choices[0].Delta.Content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +168,21 @@ public sealed class ProviderSelfHosted(ILogger logger, Settings.Provider provide
|
||||
|
||||
case Host.LM_STUDIO:
|
||||
case Host.OLLAMA:
|
||||
|
||||
var secretKey = apiKeyProvisional switch
|
||||
{
|
||||
not null => apiKeyProvisional,
|
||||
_ => await RUST_SERVICE.GetAPIKey(this, isTrying: true) switch
|
||||
{
|
||||
{ Success: true } result => await result.Secret.Decrypt(ENCRYPTION),
|
||||
_ => null,
|
||||
}
|
||||
};
|
||||
|
||||
var lmStudioRequest = new HttpRequestMessage(HttpMethod.Get, "models");
|
||||
if(secretKey is not null)
|
||||
lmStudioRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKeyProvisional);
|
||||
|
||||
var lmStudioResponse = await this.httpClient.SendAsync(lmStudioRequest, token);
|
||||
if(!lmStudioResponse.IsSuccessStatusCode)
|
||||
return [];
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
</Found>
|
||||
</Router>
|
||||
|
||||
<MudThemeProvider />
|
||||
<MudDialogProvider />
|
||||
<MudPopoverProvider />
|
||||
<MudSnackbarProvider />
|
||||
@@ -21,5 +21,7 @@ public sealed partial class Routes
|
||||
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";
|
||||
public const string ASSISTANT_JOB_POSTING = "/assistant/job-posting";
|
||||
public const string ASSISTANT_BIAS = "/assistant/bias-of-the-day";
|
||||
// ReSharper restore InconsistentNaming
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using AIStudio.Assistants.IconFinder;
|
||||
using AIStudio.Assistants.RewriteImprove;
|
||||
using AIStudio.Assistants.TextSummarizer;
|
||||
using AIStudio.Assistants.EMail;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings.DataModel;
|
||||
|
||||
using WritingStylesRewrite = AIStudio.Assistants.RewriteImprove.WritingStyles;
|
||||
@@ -136,4 +137,43 @@ public static class ConfigurationSelectDataFactory
|
||||
foreach (var profile in profiles.GetAllProfiles())
|
||||
yield return new(profile.Name, profile.Id);
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<ConfidenceSchemes>> GetConfidenceSchemesData()
|
||||
{
|
||||
foreach (var scheme in Enum.GetValues<ConfidenceSchemes>())
|
||||
yield return new(scheme.GetListDescription(), scheme);
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<ConfidenceLevel>> GetConfidenceLevelsData(SettingsManager settingsManager, bool restrictToGlobalMinimum = false)
|
||||
{
|
||||
var minimumLevel = ConfidenceLevel.NONE;
|
||||
if(restrictToGlobalMinimum && settingsManager.ConfigurationData.LLMProviders is { EnforceGlobalMinimumConfidence: true, GlobalMinimumConfidence: not ConfidenceLevel.NONE and not ConfidenceLevel.UNKNOWN })
|
||||
minimumLevel = settingsManager.ConfigurationData.LLMProviders.GlobalMinimumConfidence;
|
||||
|
||||
foreach (var level in Enum.GetValues<ConfidenceLevel>())
|
||||
{
|
||||
if(level is ConfidenceLevel.NONE)
|
||||
yield return new("No minimum confidence level chosen", level);
|
||||
|
||||
if(level < minimumLevel)
|
||||
continue;
|
||||
|
||||
switch (level)
|
||||
{
|
||||
case ConfidenceLevel.NONE:
|
||||
case ConfidenceLevel.UNKNOWN:
|
||||
continue;
|
||||
|
||||
default:
|
||||
yield return new(level.GetName(), level);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<Themes>> GetThemesData()
|
||||
{
|
||||
foreach (var theme in Enum.GetValues<Themes>())
|
||||
yield return new(theme.GetName(), theme);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class Bias
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the bias.
|
||||
/// </summary>
|
||||
public Guid Id { get; init; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// In which category the bias is located.
|
||||
/// </summary>
|
||||
public BiasCategory Category { get; set; } = BiasCategory.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The bias name.
|
||||
/// </summary>
|
||||
public string Name { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The bias description.
|
||||
/// </summary>
|
||||
public string Description { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Related bias.
|
||||
/// </summary>
|
||||
public IReadOnlyList<Guid> Related { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Related links.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> Links { get; init; } = [];
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,11 @@
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public enum BiasCategory
|
||||
{
|
||||
NONE,
|
||||
|
||||
WHAT_SHOULD_WE_REMEMBER,
|
||||
TOO_MUCH_INFORMATION,
|
||||
NOT_ENOUGH_MEANING,
|
||||
NEED_TO_ACT_FAST,
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public static class BiasCategoryExtensions
|
||||
{
|
||||
public static string ToName(this BiasCategory biasCategory) => biasCategory switch
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER => "What should we remember?",
|
||||
BiasCategory.TOO_MUCH_INFORMATION => "Too much information",
|
||||
BiasCategory.NOT_ENOUGH_MEANING => "Not enough meaning",
|
||||
BiasCategory.NEED_TO_ACT_FAST => "Need to act fast",
|
||||
|
||||
_ => "Unknown category",
|
||||
};
|
||||
|
||||
public static string GetThoughts(this BiasCategory biasCategory) => biasCategory switch
|
||||
{
|
||||
BiasCategory.WHAT_SHOULD_WE_REMEMBER =>
|
||||
"""
|
||||
- We store memories differently based on how they were experienced
|
||||
- We reduce events and lists to their key elements
|
||||
- We discard specifics to form generalities
|
||||
- We edit and reinforce some memories after the fact
|
||||
""",
|
||||
|
||||
BiasCategory.TOO_MUCH_INFORMATION =>
|
||||
"""
|
||||
- We notice things already primed in memory or repeated often
|
||||
- Bizarre, funny, visually-striking, or anthropomorphic things stick out more than non-bizarre/unfunny things
|
||||
- We notice when something has changed
|
||||
- We are drawn to details that confirm our own existing beliefs
|
||||
- We notice flaws in others more easily than we notice flaws in ourselves
|
||||
""",
|
||||
|
||||
BiasCategory.NOT_ENOUGH_MEANING =>
|
||||
"""
|
||||
- We tend to find stories and patterns even when looking at sparse data
|
||||
- We fill in characteristics from stereotypes, generalities, and prior histories
|
||||
- We imagine things and people we’re familiar with or fond of as better
|
||||
- We simplify probabilities and numbers to make them easier to think about
|
||||
- We project our current mindset and assumptions onto the past and future
|
||||
- We think we know what other people are thinking
|
||||
""",
|
||||
|
||||
BiasCategory.NEED_TO_ACT_FAST =>
|
||||
"""
|
||||
- We favor simple-looking options and complete information over complex, ambiguous options
|
||||
- To avoid mistakes, we aim to preserve autonomy and group status, and avoid irreversible decisions
|
||||
- To get things done, we tend to complete things we’ve invested time & energy in
|
||||
- To stay focused, we favor the immediate, relatable thing in front of us
|
||||
- To act, we must be confident we can make an impact and feel what we do is important
|
||||
""",
|
||||
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
@@ -9,13 +9,18 @@ public sealed class Data
|
||||
/// The version of the settings file. Allows us to upgrade the settings
|
||||
/// when a new version is available.
|
||||
/// </summary>
|
||||
public Version Version { get; init; } = Version.V4;
|
||||
public Version Version { get; init; } = Version.V5;
|
||||
|
||||
/// <summary>
|
||||
/// List of configured providers.
|
||||
/// </summary>
|
||||
public List<Provider> Providers { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Settings concerning the LLM providers.
|
||||
/// </summary>
|
||||
public DataLLMProviders LLMProviders { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of configured profiles.
|
||||
/// </summary>
|
||||
@@ -53,11 +58,15 @@ public sealed class Data
|
||||
|
||||
public DataRewriteImprove RewriteImprove { get; init; } = new();
|
||||
|
||||
public DataEMail EMail { get; set; } = new();
|
||||
public DataEMail EMail { get; init; } = new();
|
||||
|
||||
public DataLegalCheck LegalCheck { get; set; } = new();
|
||||
public DataLegalCheck LegalCheck { get; init; } = new();
|
||||
|
||||
public DataSynonyms Synonyms { get; set; } = new();
|
||||
public DataSynonyms Synonyms { get; init; } = new();
|
||||
|
||||
public DataMyTasks MyTasks { get; set; } = new();
|
||||
public DataMyTasks MyTasks { get; init; } = new();
|
||||
|
||||
public DataJobPostings JobPostings { get; init; } = new();
|
||||
|
||||
public DataBiasOfTheDay BiasOfTheDay { get; init; } = new();
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.Agenda;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -51,6 +52,11 @@ public sealed class DataAgenda
|
||||
/// </summary>
|
||||
public string PreselectedOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a agenda provider?
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,11 @@ namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataApp
|
||||
{
|
||||
/// <summary>
|
||||
/// The preferred theme to use.
|
||||
/// </summary>
|
||||
public Themes PreferredTheme { get; set; } = Themes.SYSTEM;
|
||||
|
||||
/// <summary>
|
||||
/// Should we save energy? When true, we will update content streamed
|
||||
/// from the server, i.e., AI, less frequently.
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataBiasOfTheDay
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of bias IDs that have been used.
|
||||
/// </summary>
|
||||
public List<int> UsedBias { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// When was the last bias drawn?
|
||||
/// </summary>
|
||||
public DateOnly DateLastBiasDrawn { get; set; } = DateOnly.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Which bias is the bias of the day? This isn't the bias id, but rather the chat id in the bias workspace.
|
||||
/// </summary>
|
||||
public Guid BiasOfTheDayChatId { get; set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Which bias is the bias of the day?
|
||||
/// </summary>
|
||||
public Guid BiasOfTheDayId { get; set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Restrict to one bias per day?
|
||||
/// </summary>
|
||||
public bool RestrictOneBiasPerDay { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect any rewrite options?
|
||||
/// </summary>
|
||||
public bool PreselectOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preselect the language?
|
||||
/// </summary>
|
||||
public CommonLanguages PreselectedTargetLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preselect any other language?
|
||||
/// </summary>
|
||||
public string PreselectedOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a profile?
|
||||
/// </summary>
|
||||
public string PreselectedProfile { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.Coding;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -24,6 +25,11 @@ public sealed class DataCoding
|
||||
/// </summary>
|
||||
public string PreselectedOtherProgrammingLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Which coding provider should be preselected?
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.EMail;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -23,16 +24,6 @@ public sealed class DataEMail
|
||||
/// Preselect any writing style?
|
||||
/// </summary>
|
||||
public WritingStyles PreselectedWritingStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a profile?
|
||||
/// </summary>
|
||||
public string PreselectedProfile { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a greeting phrase?
|
||||
@@ -43,4 +34,19 @@ public sealed class DataEMail
|
||||
/// Preselect the sender name for the closing salutation?
|
||||
/// </summary>
|
||||
public string SenderName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a profile?
|
||||
/// </summary>
|
||||
public string PreselectedProfile { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataGrammarSpelling
|
||||
@@ -17,6 +19,11 @@ public sealed class DataGrammarSpelling
|
||||
/// </summary>
|
||||
public string PreselectedOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.IconFinder;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -14,6 +15,11 @@ public sealed class DataIconFinder
|
||||
/// </summary>
|
||||
public IconSources PreselectedSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected icon provider.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataJobPostings
|
||||
{
|
||||
/// <summary>
|
||||
/// Do we want to preselect any translator options?
|
||||
/// </summary>
|
||||
public bool PreselectOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The mandatory information for the job posting.
|
||||
/// </summary>
|
||||
public string PreselectedMandatoryInformation { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The job description.
|
||||
/// </summary>
|
||||
public string PreselectedJobDescription { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The qualifications required for the job.
|
||||
/// </summary>
|
||||
public string PreselectedQualifications { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// What are the responsibilities of the job?
|
||||
/// </summary>
|
||||
public string PreselectedResponsibilities { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Which company name should be preselected?
|
||||
/// </summary>
|
||||
public string PreselectedCompanyName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Where should the work be done?
|
||||
/// </summary>
|
||||
public string PreselectedWorkLocation { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected country legal framework.
|
||||
/// </summary>
|
||||
public string PreselectedCountryLegalFramework { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect the target language?
|
||||
/// </summary>
|
||||
public CommonLanguages PreselectedTargetLanguage { get; set; } = CommonLanguages.EN_US;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect any other language?
|
||||
/// </summary>
|
||||
public string PreselectOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected translator provider.
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataLLMProviders
|
||||
{
|
||||
/// <summary>
|
||||
/// Should we enforce a global minimum confidence level?
|
||||
/// </summary>
|
||||
public bool EnforceGlobalMinimumConfidence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The global minimum confidence level to enforce.
|
||||
/// </summary>
|
||||
public ConfidenceLevel GlobalMinimumConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Should we show the provider confidence level?
|
||||
/// </summary>
|
||||
public bool ShowProviderConfidence { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Which confidence scheme to use.
|
||||
/// </summary>
|
||||
public ConfidenceSchemes ConfidenceScheme { get; set; } = ConfidenceSchemes.TRUST_USA_EUROPE;
|
||||
|
||||
/// <summary>
|
||||
/// Provide custom confidence levels for each LLM provider.
|
||||
/// </summary>
|
||||
public Dictionary<LLMProviders, ConfidenceLevel> CustomConfidenceScheme { get; set; } = new();
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public class DataLegalCheck
|
||||
@@ -22,6 +24,11 @@ public class DataLegalCheck
|
||||
/// </summary>
|
||||
public bool PreselectContentCleanerAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected translator provider.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataMyTasks
|
||||
@@ -17,6 +19,11 @@ public sealed class DataMyTasks
|
||||
/// </summary>
|
||||
public string PreselectOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected provider.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.RewriteImprove;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -29,6 +30,11 @@ public sealed class DataRewriteImprove
|
||||
/// </summary>
|
||||
public SentenceStructure PreselectedSentenceStructure { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataSynonyms
|
||||
@@ -17,6 +19,11 @@ public sealed class DataSynonyms
|
||||
/// </summary>
|
||||
public string PreselectedOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a provider?
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AIStudio.Assistants.TextSummarizer;
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
@@ -45,6 +46,11 @@ public sealed class DataTextSummarizer
|
||||
/// </summary>
|
||||
public string PreselectedExpertInField { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// Preselect a text summarizer provider?
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
|
||||
public sealed class DataTranslation
|
||||
@@ -42,6 +44,11 @@ public sealed class DataTranslation
|
||||
/// </summary>
|
||||
public string PreselectOtherLanguage { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum confidence level required for a provider to be considered.
|
||||
/// </summary>
|
||||
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
|
||||
|
||||
/// <summary>
|
||||
/// The preselected translator provider.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
namespace AIStudio.Settings.DataModel.PreviousModels;
|
||||
|
||||
public sealed class DataV4
|
||||
{
|
||||
/// <summary>
|
||||
/// The version of the settings file. Allows us to upgrade the settings
|
||||
/// when a new version is available.
|
||||
/// </summary>
|
||||
public Version Version { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// List of configured providers.
|
||||
/// </summary>
|
||||
public List<Provider> Providers { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Settings concerning the LLM providers.
|
||||
/// </summary>
|
||||
public DataLLMProviders LLMProviders { get; init; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of configured profiles.
|
||||
/// </summary>
|
||||
public List<Profile> Profiles { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// The next provider number to use.
|
||||
/// </summary>
|
||||
public uint NextProviderNum { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The next profile number to use.
|
||||
/// </summary>
|
||||
public uint NextProfileNum { get; set; } = 1;
|
||||
|
||||
public DataApp App { get; init; } = new();
|
||||
|
||||
public DataChat Chat { get; init; } = new();
|
||||
|
||||
public DataWorkspace Workspace { get; init; } = new();
|
||||
|
||||
public DataIconFinder IconFinder { get; init; } = new();
|
||||
|
||||
public DataTranslation Translation { get; init; } = new();
|
||||
|
||||
public DataCoding Coding { get; init; } = new();
|
||||
|
||||
public DataTextSummarizer TextSummarizer { get; init; } = new();
|
||||
|
||||
public DataTextContentCleaner TextContentCleaner { get; init; } = new();
|
||||
|
||||
public DataAgenda Agenda { get; init; } = new();
|
||||
|
||||
public DataGrammarSpelling GrammarSpelling { get; init; } = new();
|
||||
|
||||
public DataRewriteImprove RewriteImprove { get; init; } = new();
|
||||
|
||||
public DataEMail EMail { get; set; } = new();
|
||||
|
||||
public DataLegalCheck LegalCheck { get; set; } = new();
|
||||
|
||||
public DataSynonyms Synonyms { get; set; } = new();
|
||||
|
||||
public DataMyTasks MyTasks { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
using Host = AIStudio.Provider.SelfHosted.Host;
|
||||
|
||||
namespace AIStudio.Settings.DataModel.PreviousModels;
|
||||
|
||||
public readonly record struct Provider(
|
||||
uint Num,
|
||||
string Id,
|
||||
string InstanceName,
|
||||
LLMProviders UsedProvider,
|
||||
Model Model,
|
||||
bool IsSelfHosted = false,
|
||||
string Hostname = "http://localhost:1234",
|
||||
Host Host = Host.NONE);
|
||||
Loaded 100 of 145 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user