mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-08-21 15:12:56 +00:00
Compare commits
No commits in common. "main" and "v0.9.44" have entirely different histories.
16
.github/workflows/build-and-release.yml
vendored
16
.github/workflows/build-and-release.yml
vendored
@ -362,10 +362,7 @@ jobs:
|
|||||||
|
|
||||||
$PDFIUM_URL = "https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$($env:PDFIUM_VERSION)/pdfium-$PDFIUM_FILE"
|
$PDFIUM_URL = "https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$($env:PDFIUM_VERSION)/pdfium-$PDFIUM_FILE"
|
||||||
Write-Host "Download $PDFIUM_URL ..."
|
Write-Host "Download $PDFIUM_URL ..."
|
||||||
|
$TMP = New-TemporaryFile | Split-Path
|
||||||
# Create a unique temporary directory (not just a file)
|
|
||||||
$TMP = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
|
|
||||||
New-Item -ItemType Directory -Path $TMP -Force | Out-Null
|
|
||||||
$ARCHIVE = Join-Path $TMP "pdfium.tgz"
|
$ARCHIVE = Join-Path $TMP "pdfium.tgz"
|
||||||
|
|
||||||
Invoke-WebRequest -Uri $PDFIUM_URL -OutFile $ARCHIVE
|
Invoke-WebRequest -Uri $PDFIUM_URL -OutFile $ARCHIVE
|
||||||
@ -383,15 +380,8 @@ jobs:
|
|||||||
Copy-Item -Path $SRC -Destination $DEST -Force
|
Copy-Item -Path $SRC -Destination $DEST -Force
|
||||||
|
|
||||||
Write-Host "Cleaning up ..."
|
Write-Host "Cleaning up ..."
|
||||||
Remove-Item $ARCHIVE -Force -ErrorAction SilentlyContinue
|
Remove-Item $ARCHIVE -Force
|
||||||
|
Remove-Item $TMP -Recurse -Force
|
||||||
# Try to remove the temporary directory, but ignore errors if files are still in use
|
|
||||||
try {
|
|
||||||
Remove-Item $TMP -Recurse -Force -ErrorAction Stop
|
|
||||||
Write-Host "Successfully cleaned up temporary directory: $TMP"
|
|
||||||
} catch {
|
|
||||||
Write-Warning "Could not fully clean up temporary directory: $TMP. This is usually harmless as Windows will clean it up later. Error: $($_.Exception.Message)"
|
|
||||||
}
|
|
||||||
|
|
||||||
- name: Build .NET project
|
- name: Build .NET project
|
||||||
run: |
|
run: |
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -156,6 +156,3 @@ orleans.codegen.cs
|
|||||||
**/.idea/**/uiDesigner.xml
|
**/.idea/**/uiDesigner.xml
|
||||||
**/.idea/**/dbnavigator.xml
|
**/.idea/**/dbnavigator.xml
|
||||||
**/.vs
|
**/.vs
|
||||||
|
|
||||||
# Ignore AI plugin config files:
|
|
||||||
/app/.idea/.idea.MindWork AI Studio/.idea/AugmentWebviewStateStore.xml
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
# Project Guidelines
|
|
||||||
|
|
||||||
## Repository Structure
|
|
||||||
- The repository and the app consist of a Rust project in the `runtime` folder and a .NET solution in the `app` folder.
|
|
||||||
- The .NET solution then contains 4 .NET projects:
|
|
||||||
- `Build Script` is not required for running the app; instead, it contains the build script for creating new releases, for example.
|
|
||||||
- `MindWork AI Studio` contains the actual app code.
|
|
||||||
- `SharedTools` contains types that are needed in the build script and in the app, for example.
|
|
||||||
- `SourceCodeRules` is a Roslyn analyzer project. It contains analyzers and code fixes that we use to enforce code style rules within the team.
|
|
||||||
|
|
||||||
## Changelogs
|
|
||||||
- There is a changelog in Markdown format for each version.
|
|
||||||
- All changelogs are located in the folder `app/MindWork AI Studio/wwwroot/changelog`.
|
|
||||||
- These changelogs are intended for end users, not for developers.
|
|
||||||
- Therefore, we don't mention all changes in the changelog: changes that end users wouldn't understand remain unmentioned. For complex refactorings, for example, we mention a generic point that the code quality has been improved to enhance future maintenance.
|
|
||||||
- The changelog is always written in US English.
|
|
||||||
- The changelog doesn't mention bug fixes if the bug was never shipped and users don't know about it.
|
|
21
README.md
21
README.md
@ -15,7 +15,7 @@ Things we are currently working on:
|
|||||||
- [x] ~~App: Management of data sources (local & external data via [ERI](https://github.com/MindWorkAI/ERI)) (PR [#259](https://github.com/MindWorkAI/AI-Studio/pull/259), [#273](https://github.com/MindWorkAI/AI-Studio/pull/273))~~
|
- [x] ~~App: Management of data sources (local & external data via [ERI](https://github.com/MindWorkAI/ERI)) (PR [#259](https://github.com/MindWorkAI/AI-Studio/pull/259), [#273](https://github.com/MindWorkAI/AI-Studio/pull/273))~~
|
||||||
- [x] ~~Runtime: Extract data from txt / md / pdf / docx / xlsx files (PR [#374](https://github.com/MindWorkAI/AI-Studio/pull/374))~~
|
- [x] ~~Runtime: Extract data from txt / md / pdf / docx / xlsx files (PR [#374](https://github.com/MindWorkAI/AI-Studio/pull/374))~~
|
||||||
- [ ] (*Optional*) Runtime: Implement internal embedding provider through [fastembed-rs](https://github.com/Anush008/fastembed-rs)
|
- [ ] (*Optional*) Runtime: Implement internal embedding provider through [fastembed-rs](https://github.com/Anush008/fastembed-rs)
|
||||||
- [x] ~~App: Implement dialog for checking & handling [pandoc](https://pandoc.org/) installation ([PR #393](https://github.com/MindWorkAI/AI-Studio/pull/393), [PR #487](https://github.com/MindWorkAI/AI-Studio/pull/487))~~
|
- [ ] App: Implement dialog for checking & handling [pandoc](https://pandoc.org/) installation ([PR #393](https://github.com/MindWorkAI/AI-Studio/pull/393))
|
||||||
- [ ] App: Implement external embedding providers
|
- [ ] App: Implement external embedding providers
|
||||||
- [ ] App: Implement the process to vectorize one local file using embeddings
|
- [ ] App: Implement the process to vectorize one local file using embeddings
|
||||||
- [ ] Runtime: Integration of the vector database [LanceDB](https://github.com/lancedb/lancedb)
|
- [ ] Runtime: Integration of the vector database [LanceDB](https://github.com/lancedb/lancedb)
|
||||||
@ -31,10 +31,10 @@ Things we are currently working on:
|
|||||||
- [x] ~~Plan & implement the base plugin system ([PR #322](https://github.com/MindWorkAI/AI-Studio/pull/322))~~
|
- [x] ~~Plan & implement the base plugin system ([PR #322](https://github.com/MindWorkAI/AI-Studio/pull/322))~~
|
||||||
- [x] ~~Start the plugin system ([PR #372](https://github.com/MindWorkAI/AI-Studio/pull/372))~~
|
- [x] ~~Start the plugin system ([PR #372](https://github.com/MindWorkAI/AI-Studio/pull/372))~~
|
||||||
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
|
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
|
||||||
- [x] ~~Add support for other languages (I18N) to AI Studio ([PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
|
- [ ] Add support for other languages (I18N) to AI Studio (~~[PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446))~~
|
||||||
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
|
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
|
||||||
- [x] ~~Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
|
- [ ] Provide MindWork AI Studio in German (~~[PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446)~~)
|
||||||
- [x] ~~Add configuration plugins, which allow pre-defining some LLM providers in organizations ([PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491), [PR #493](https://github.com/MindWorkAI/AI-Studio/pull/493), [PR #494](https://github.com/MindWorkAI/AI-Studio/pull/494), [PR #497](https://github.com/MindWorkAI/AI-Studio/pull/497))~~
|
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations
|
||||||
- [ ] Add an app store for plugins, showcasing community-contributed plugins from public GitHub and GitLab repositories. This will enable AI Studio users to discover, install, and update plugins directly within the platform.
|
- [ ] Add an app store for plugins, showcasing community-contributed plugins from public GitHub and GitLab repositories. This will enable AI Studio users to discover, install, and update plugins directly within the platform.
|
||||||
- [ ] Add assistant plugins
|
- [ ] Add assistant plugins
|
||||||
|
|
||||||
@ -47,10 +47,6 @@ Other News:
|
|||||||
|
|
||||||
Features we have recently released:
|
Features we have recently released:
|
||||||
|
|
||||||
- v0.9.50: Added support for self-hosted LLMs using [vLLM](https://blog.vllm.ai/2023/06/20/vllm.html).
|
|
||||||
- v0.9.46: Released our plugin system, a German language plugin, early support for enterprise environments, and configuration plugins. Additionally, we added the Pandoc integration for future data processing and file generation.
|
|
||||||
- v0.9.45: Added chat templates to AI Studio, allowing you to create and use a library of system prompts for your chats.
|
|
||||||
- v0.9.44: Added PDF import to the text summarizer, translation, and legal check assistants, allowing you to import PDF files and use them as input for the assistants.
|
|
||||||
- v0.9.40: Added support for the `o4` models from OpenAI. Also, we added Alibaba Cloud & Hugging Face as LLM providers.
|
- v0.9.40: Added support for the `o4` models from OpenAI. Also, we added Alibaba Cloud & Hugging Face as LLM providers.
|
||||||
- v0.9.39: Added the plugin system as a preview feature.
|
- v0.9.39: Added the plugin system as a preview feature.
|
||||||
- v0.9.31: Added Helmholtz & GWDG as LLM providers. This is a huge improvement for many researchers out there who can use these providers for free. We added DeepSeek as a provider as well.
|
- v0.9.31: Added Helmholtz & GWDG as LLM providers. This is a huge improvement for many researchers out there who can use these providers for free. We added DeepSeek as a provider as well.
|
||||||
@ -58,6 +54,8 @@ Features we have recently released:
|
|||||||
- v0.9.26+: Added RAG for external data sources using our [ERI interface](https://mindworkai.org/#eri---external-retrieval-interface) as a preview feature.
|
- v0.9.26+: Added RAG for external data sources using our [ERI interface](https://mindworkai.org/#eri---external-retrieval-interface) as a preview feature.
|
||||||
- v0.9.25: Added [xAI](https://x.ai/) as a new provider. xAI provides their Grok models for generating content.
|
- v0.9.25: Added [xAI](https://x.ai/) as a new provider. xAI provides their Grok models for generating content.
|
||||||
- v0.9.23: Added support for OpenAI `o` models (`o1`, `o1-mini`, `o3`, etc.); added also an [ERI](https://github.com/MindWorkAI/ERI) server coding assistant as a preview feature behind the RAG feature flag. Your own ERI server can be used to gain access to, e.g., your enterprise data from within AI Studio.
|
- v0.9.23: Added support for OpenAI `o` models (`o1`, `o1-mini`, `o3`, etc.); added also an [ERI](https://github.com/MindWorkAI/ERI) server coding assistant as a preview feature behind the RAG feature flag. Your own ERI server can be used to gain access to, e.g., your enterprise data from within AI Studio.
|
||||||
|
- v0.9.22: Added options for preview features; added embedding provider configuration for RAG (preview) and writer mode (experimental preview).
|
||||||
|
- v0.9.18: Added the new Anthropic Heiku model; added Groq and Google Gemini as provider options.
|
||||||
|
|
||||||
## What is AI Studio?
|
## What is AI Studio?
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ MindWork AI Studio is a free desktop app for macOS, Windows, and Linux. It provi
|
|||||||
**Key advantages:**
|
**Key advantages:**
|
||||||
- **Free of charge**: The app is free to use, both for personal and commercial purposes.
|
- **Free of charge**: The app is free to use, both for personal and commercial purposes.
|
||||||
- **Independence**: You are not tied to any single provider. Instead, you can choose the providers that best suit your needs. Right now, we support:
|
- **Independence**: You are not tied to any single provider. Instead, you can choose the providers that best suit your needs. Right now, we support:
|
||||||
- [OpenAI](https://openai.com/) (GPT5, GPT4.1, o1, o3, o4, etc.)
|
- [OpenAI](https://openai.com/) (GPT4o, GPT4.1, o1, o3, o4, etc.)
|
||||||
- [Mistral](https://mistral.ai/)
|
- [Mistral](https://mistral.ai/)
|
||||||
- [Anthropic](https://www.anthropic.com/) (Claude)
|
- [Anthropic](https://www.anthropic.com/) (Claude)
|
||||||
- [Google Gemini](https://gemini.google.com)
|
- [Google Gemini](https://gemini.google.com)
|
||||||
@ -79,7 +77,7 @@ MindWork AI Studio is a free desktop app for macOS, Windows, and Linux. It provi
|
|||||||
- [DeepSeek](https://www.deepseek.com/en)
|
- [DeepSeek](https://www.deepseek.com/en)
|
||||||
- [Alibaba Cloud](https://www.alibabacloud.com) (Qwen)
|
- [Alibaba Cloud](https://www.alibabacloud.com) (Qwen)
|
||||||
- [Hugging Face](https://huggingface.co/) using their [inference providers](https://huggingface.co/docs/inference-providers/index) such as Cerebras, Nebius, Sambanova, Novita, Hyperbolic, Together AI, Fireworks, Hugging Face
|
- [Hugging Face](https://huggingface.co/) using their [inference providers](https://huggingface.co/docs/inference-providers/index) such as Cerebras, Nebius, Sambanova, Novita, Hyperbolic, Together AI, Fireworks, Hugging Face
|
||||||
- Self-hosted models using [llama.cpp](https://github.com/ggerganov/llama.cpp), [ollama](https://github.com/ollama/ollama), [LM Studio](https://lmstudio.ai/), and [vLLM](https://github.com/vllm-project/vllm)
|
- Self-hosted models using [llama.cpp](https://github.com/ggerganov/llama.cpp), [ollama](https://github.com/ollama/ollama), [LM Studio](https://lmstudio.ai/)
|
||||||
- [Groq](https://groq.com/)
|
- [Groq](https://groq.com/)
|
||||||
- [Fireworks](https://fireworks.ai/)
|
- [Fireworks](https://fireworks.ai/)
|
||||||
- For scientists and employees of research institutions, we also support [Helmholtz](https://helmholtz.cloud/services/?serviceID=d7d5c597-a2f6-4bd1-b71e-4d6499d98570) and [GWDG](https://gwdg.de/services/application-services/ai-services/) AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.
|
- For scientists and employees of research institutions, we also support [Helmholtz](https://helmholtz.cloud/services/?serviceID=d7d5c597-a2f6-4bd1-b71e-4d6499d98570) and [GWDG](https://gwdg.de/services/application-services/ai-services/) AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.
|
||||||
@ -123,9 +121,6 @@ Stay tuned for more updates and enhancements to make MindWork AI Studio even mor
|
|||||||
## Building
|
## Building
|
||||||
You want to know how to build MindWork AI Studio from source? [Check out the instructions here](documentation/Build.md).
|
You want to know how to build MindWork AI Studio from source? [Check out the instructions here](documentation/Build.md).
|
||||||
|
|
||||||
## Enterprise IT
|
|
||||||
Do you want to manage AI Studio centrally from your IT department? Yes, that’s possible. [Here’s how it works.](documentation/Enterprise%20IT.md)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
MindWork AI Studio is licensed under the `FSL-1.1-MIT` license (functional source license). Here’s a simple rundown of what that means for you:
|
MindWork AI Studio is licensed under the `FSL-1.1-MIT` license (functional source license). Here’s a simple rundown of what that means for you:
|
||||||
- **Permitted Use**: Feel free to use, copy, modify, and share the software for your own projects, educational purposes, research, or even in professional services. The key is to use it in a way that doesn't compete with our offerings.
|
- **Permitted Use**: Feel free to use, copy, modify, and share the software for your own projects, educational purposes, research, or even in professional services. The key is to use it in a way that doesn't compete with our offerings.
|
||||||
|
@ -48,7 +48,7 @@ public static class Pdfium
|
|||||||
//
|
//
|
||||||
Console.Write(" deploying ...");
|
Console.Write(" deploying ...");
|
||||||
var library = GetLibraryPath(rid);
|
var library = GetLibraryPath(rid);
|
||||||
if (string.IsNullOrWhiteSpace(library.Path))
|
if (string.IsNullOrEmpty(library.Path))
|
||||||
{
|
{
|
||||||
Console.WriteLine($" failed to find the library path for {rid.ToUserFriendlyName()}");
|
Console.WriteLine($" failed to find the library path for {rid.ToUserFriendlyName()}");
|
||||||
return;
|
return;
|
||||||
|
@ -20,7 +20,6 @@ public sealed class UpdateWebAssetsCommand
|
|||||||
var rid = Environment.GetCurrentRid();
|
var rid = Environment.GetCurrentRid();
|
||||||
var cwd = Environment.GetAIStudioDirectory();
|
var cwd = Environment.GetAIStudioDirectory();
|
||||||
var contentPath = Path.Join(cwd, "bin", "release", Environment.DOTNET_VERSION, rid.AsMicrosoftRid(), "publish", "wwwroot", "_content");
|
var contentPath = Path.Join(cwd, "bin", "release", Environment.DOTNET_VERSION, rid.AsMicrosoftRid(), "publish", "wwwroot", "_content");
|
||||||
|
|
||||||
var isMudBlazorDirectoryPresent = Directory.Exists(Path.Join(contentPath, "MudBlazor"));
|
var isMudBlazorDirectoryPresent = Directory.Exists(Path.Join(contentPath, "MudBlazor"));
|
||||||
if (!isMudBlazorDirectoryPresent)
|
if (!isMudBlazorDirectoryPresent)
|
||||||
{
|
{
|
||||||
@ -29,21 +28,14 @@ public sealed class UpdateWebAssetsCommand
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var destinationPath = Path.Join(cwd, "wwwroot", "system");
|
Directory.CreateDirectory(Path.Join(cwd, "wwwroot", "system"));
|
||||||
if(Directory.Exists(destinationPath))
|
|
||||||
Directory.Delete(destinationPath, true);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(destinationPath);
|
|
||||||
|
|
||||||
var sourcePaths = Directory.EnumerateFiles(contentPath, "*", SearchOption.AllDirectories);
|
var sourcePaths = Directory.EnumerateFiles(contentPath, "*", SearchOption.AllDirectories);
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
foreach(var sourcePath in sourcePaths)
|
foreach(var sourcePath in sourcePaths)
|
||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
var relativePath = sourcePath
|
var relativePath = Path.GetRelativePath(cwd, sourcePath);
|
||||||
.Replace(contentPath, "")
|
var targetPath = Path.Join(cwd, "wwwroot", relativePath);
|
||||||
.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
|
||||||
var targetPath = Path.Join(cwd, "wwwroot", "system", relativePath);
|
|
||||||
var targetDirectory = Path.GetDirectoryName(targetPath);
|
var targetDirectory = Path.GetDirectoryName(targetPath);
|
||||||
if (targetDirectory != null)
|
if (targetDirectory != null)
|
||||||
Directory.CreateDirectory(targetDirectory);
|
Directory.CreateDirectory(targetDirectory);
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FNV/@EntryIndexedValue">FNV</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FNV/@EntryIndexedValue">FNV</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GWDG/@EntryIndexedValue">GWDG</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GWDG/@EntryIndexedValue">GWDG</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HF/@EntryIndexedValue">HF</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HF/@EntryIndexedValue">HF</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IERI/@EntryIndexedValue">IERI</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/=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/=LM/@EntryIndexedValue">LM</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSG/@EntryIndexedValue">MSG</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSG/@EntryIndexedValue">MSG</s:String>
|
||||||
@ -21,7 +20,6 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=groq/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=groq/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=gwdg/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=gwdg/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=huggingface/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=huggingface/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ieri/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=mwais/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=mwais/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tauri_0027s/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tauri_0027s/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
@ -2,24 +2,22 @@ namespace AIStudio.Assistants.Agenda;
|
|||||||
|
|
||||||
public static class NumberParticipantsExtensions
|
public static class NumberParticipantsExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(NumberParticipantsExtensions).Namespace, nameof(NumberParticipantsExtensions));
|
|
||||||
|
|
||||||
public static string Name(this NumberParticipants numberParticipants) => numberParticipants switch
|
public static string Name(this NumberParticipants numberParticipants) => numberParticipants switch
|
||||||
{
|
{
|
||||||
NumberParticipants.NOT_SPECIFIED => TB("Please select how many participants are expected"),
|
NumberParticipants.NOT_SPECIFIED => "Please select how many participants are expected",
|
||||||
|
|
||||||
NumberParticipants.PEER_TO_PEER => TB("2 (peer to peer)"),
|
NumberParticipants.PEER_TO_PEER => "2 (peer to peer)",
|
||||||
|
|
||||||
NumberParticipants.SMALL_GROUP => TB("3 - 5 (small group)"),
|
NumberParticipants.SMALL_GROUP => "3 - 5 (small group)",
|
||||||
NumberParticipants.LARGE_GROUP => TB("6 - 12 (large group)"),
|
NumberParticipants.LARGE_GROUP => "6 - 12 (large group)",
|
||||||
NumberParticipants.MULTIPLE_SMALL_GROUPS => TB("13 - 20 (multiple small groups)"),
|
NumberParticipants.MULTIPLE_SMALL_GROUPS => "13 - 20 (multiple small groups)",
|
||||||
NumberParticipants.MULTIPLE_LARGE_GROUPS => TB("21 - 30 (multiple large groups)"),
|
NumberParticipants.MULTIPLE_LARGE_GROUPS => "21 - 30 (multiple large groups)",
|
||||||
|
|
||||||
NumberParticipants.SYMPOSIUM => TB("31 - 100 (symposium)"),
|
NumberParticipants.SYMPOSIUM => "31 - 100 (symposium)",
|
||||||
NumberParticipants.CONFERENCE => TB("101 - 200 (conference)"),
|
NumberParticipants.CONFERENCE => "101 - 200 (conference)",
|
||||||
NumberParticipants.CONGRESS => TB("201 - 1,000 (congress)"),
|
NumberParticipants.CONGRESS => "201 - 1,000 (congress)",
|
||||||
|
|
||||||
NumberParticipants.LARGE_EVENT => TB("1,000+ (large event)"),
|
NumberParticipants.LARGE_EVENT => "1,000+ (large event)",
|
||||||
|
|
||||||
_ => "Unknown"
|
_ => "Unknown"
|
||||||
};
|
};
|
||||||
|
@ -4,20 +4,23 @@
|
|||||||
|
|
||||||
<div class="inner-scrolling-context">
|
<div class="inner-scrolling-context">
|
||||||
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2 mr-3" StretchItems="StretchItems.Start">
|
<MudText Typo="Typo.h3" Class="mb-2 mr-3">
|
||||||
<MudText Typo="Typo.h3">
|
@(this.Title)
|
||||||
@this.Title
|
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="@(async () => await this.OpenSettingsDialog())"/>
|
|
||||||
</MudStack>
|
|
||||||
|
|
||||||
<InnerScrolling>
|
<InnerScrolling>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
<MudForm @ref="@(this.form)" @bind-IsValid="@(this.inputIsValid)" @bind-Errors="@(this.inputIssues)" FieldChanged="@this.TriggerFormChange" Class="pr-2">
|
<MudForm @ref="@(this.form)" @bind-IsValid="@(this.inputIsValid)" @bind-Errors="@(this.inputIssues)" FieldChanged="@this.TriggerFormChange" Class="pr-2">
|
||||||
<MudText Typo="Typo.body1" Align="Align.Justify" Class="mb-2">
|
<MudGrid Class="mb-2">
|
||||||
|
<MudItem xs="10">
|
||||||
|
<MudText Typo="Typo.body1" Align="Align.Justify">
|
||||||
@this.Description
|
@this.Description
|
||||||
</MudText>
|
</MudText>
|
||||||
|
</MudItem>
|
||||||
|
<MudItem xs="2" Class="d-flex justify-end align-start">
|
||||||
|
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Settings" OnClick="() => this.OpenSettingsDialog()"/>
|
||||||
|
</MudItem>
|
||||||
|
</MudGrid>
|
||||||
|
|
||||||
@if (this.Body is not null)
|
@if (this.Body is not null)
|
||||||
{
|
{
|
||||||
@ -26,13 +29,13 @@
|
|||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" StretchItems="StretchItems.Start" Class="mb-3">
|
<MudStack Row="true" AlignItems="AlignItems.Center" StretchItems="StretchItems.Start" Class="mb-3">
|
||||||
<MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" OnClick="@(async () => await this.Start())" Style="@this.SubmitButtonStyle">
|
<MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" OnClick="async () => await this.Start()" Style="@this.SubmitButtonStyle">
|
||||||
@this.SubmitText
|
@this.SubmitText
|
||||||
</MudButton>
|
</MudButton>
|
||||||
@if (this.isProcessing && this.cancellationTokenSource is not null)
|
@if (this.isProcessing && this.cancellationTokenSource is not null)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="@TB("Stop generation")">
|
<MudTooltip Text="@TB("Stop generation")">
|
||||||
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="@(async () => await this.CancelStreaming())"/>
|
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="() => this.CancelStreaming()"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
@ -71,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
<FooterContent>
|
<FooterContent>
|
||||||
<MudStack Row="@true" Wrap="Wrap.Wrap" AlignItems="AlignItems.Center" StretchItems="StretchItems.None" Class="ma-1">
|
<MudStack Row="@true" Wrap="Wrap.Wrap" Class="ma-1">
|
||||||
|
|
||||||
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
|
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
|
||||||
{
|
{
|
||||||
@ -80,7 +83,7 @@
|
|||||||
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
||||||
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
||||||
{
|
{
|
||||||
<MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, new()))">
|
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())">
|
||||||
@assistant.Name()
|
@assistant.Name()
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
}
|
}
|
||||||
@ -94,14 +97,14 @@
|
|||||||
{
|
{
|
||||||
case ButtonData buttonData when !string.IsNullOrWhiteSpace(buttonData.Tooltip):
|
case ButtonData buttonData when !string.IsNullOrWhiteSpace(buttonData.Tooltip):
|
||||||
<MudTooltip Text="@buttonData.Tooltip">
|
<MudTooltip Text="@buttonData.Tooltip">
|
||||||
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="@(async () => await buttonData.AsyncAction())">
|
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()">
|
||||||
@buttonData.Text
|
@buttonData.Text
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonData buttonData:
|
case ButtonData buttonData:
|
||||||
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="@(async () => await buttonData.AsyncAction())">
|
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()">
|
||||||
@buttonData.Text
|
@buttonData.Text
|
||||||
</MudButton>
|
</MudButton>
|
||||||
break;
|
break;
|
||||||
@ -110,7 +113,7 @@
|
|||||||
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
|
||||||
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
|
||||||
{
|
{
|
||||||
<MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, sendToButton))">
|
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)">
|
||||||
@assistant.Name()
|
@assistant.Name()
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
}
|
}
|
||||||
@ -121,14 +124,14 @@
|
|||||||
|
|
||||||
@if (this.ShowCopyResult)
|
@if (this.ShowCopyResult)
|
||||||
{
|
{
|
||||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="@(async () => await this.CopyToClipboard())">
|
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()">
|
||||||
@TB("Copy result")
|
@TB("Copy result")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.ShowReset)
|
@if (this.ShowReset)
|
||||||
{
|
{
|
||||||
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="@(async () => await this.InnerResetForm())">
|
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
|
||||||
@TB("Reset")
|
@TB("Reset")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
protected MudForm? form;
|
protected MudForm? form;
|
||||||
protected bool inputIsValid;
|
protected bool inputIsValid;
|
||||||
protected Profile currentProfile = Profile.NO_PROFILE;
|
protected Profile currentProfile = Profile.NO_PROFILE;
|
||||||
protected ChatTemplate currentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
|
|
||||||
protected ChatThread? chatThread;
|
protected ChatThread? chatThread;
|
||||||
protected IContent? lastUserPrompt;
|
protected IContent? lastUserPrompt;
|
||||||
protected CancellationTokenSource? cancellationTokenSource;
|
protected CancellationTokenSource? cancellationTokenSource;
|
||||||
@ -116,7 +115,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
this.MightPreselectValues();
|
this.MightPreselectValues();
|
||||||
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
|
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
|
||||||
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
|
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
|
||||||
this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
@ -384,18 +382,8 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
|
|
||||||
protected override void DisposeResources()
|
protected override void DisposeResources()
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
this.formChangeTimer.Stop();
|
|
||||||
this.formChangeTimer.Dispose();
|
this.formChangeTimer.Dispose();
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
base.DisposeResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
@ -6,22 +6,22 @@
|
|||||||
{
|
{
|
||||||
var codingContext = this.codingContexts[contextIndex];
|
var codingContext = this.codingContexts[contextIndex];
|
||||||
var index = contextIndex;
|
var index = contextIndex;
|
||||||
<ExpansionPanel HeaderText="@codingContext.Id" HeaderIcon="@Icons.Material.Filled.Code" ShowEndButton="@true" EndButtonColor="Color.Error" EndButtonIcon="@Icons.Material.Filled.Delete" EndButtonTooltip="@T("Delete context")" EndButtonClickAsync="@(() => this.DeleteContext(index))">
|
<ExpansionPanel HeaderText="@codingContext.Id" HeaderIcon="@Icons.Material.Filled.Code" ShowEndButton="@true" EndButtonColor="Color.Error" EndButtonIcon="@Icons.Material.Filled.Delete" EndButtonTooltip="Delete context" EndButtonClickAsync="@(() => this.DeleteContext(index))">
|
||||||
<CodingContextItem @bind-CodingContext="@codingContext"/>
|
<CodingContextItem @bind-CodingContext="@codingContext"/>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
}
|
}
|
||||||
</MudExpansionPanels>
|
</MudExpansionPanels>
|
||||||
<MudButton Variant="Variant.Filled" OnClick="() => this.AddCodingContext()" Class="mb-3">
|
<MudButton Variant="Variant.Filled" OnClick="() => this.AddCodingContext()" Class="mb-3">
|
||||||
@T("Add context")
|
Add context
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
|
||||||
<MudStack Row="@false" Class="mb-3">
|
<MudStack Row="@false" Class="mb-3">
|
||||||
<MudTextSwitch Label="@T("Do you want to provide compiler messages?")" @bind-Value="@this.provideCompilerMessages" LabelOn="@T("Yes, provide compiler messages")" LabelOff="@T("No, there are no compiler messages")" />
|
<MudTextSwitch Label="Do you want to provide compiler messages?" @bind-Value="@this.provideCompilerMessages" LabelOn="Yes, provide compiler messages" LabelOff="No, there are no compiler messages" />
|
||||||
@if (this.provideCompilerMessages)
|
@if (this.provideCompilerMessages)
|
||||||
{
|
{
|
||||||
<MudTextField T="string" @bind-Text="@this.compilerMessages" Validation="@this.ValidatingCompilerMessages" AdornmentIcon="@Icons.Material.Filled.Error" Adornment="Adornment.Start" Label="@T("Compiler messages")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField T="string" @bind-Text="@this.compilerMessages" Validation="@this.ValidatingCompilerMessages" AdornmentIcon="@Icons.Material.Filled.Error" Adornment="Adornment.Start" Label="Compiler messages" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.questions" Validation="@this.ValidateQuestions" AdornmentIcon="@Icons.Material.Filled.QuestionMark" Adornment="Adornment.Start" Label="@T("Your question(s)")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<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"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
@ -8,9 +8,14 @@ public partial class AssistantCoding : AssistantBaseCore<SettingsDialogCoding>
|
|||||||
{
|
{
|
||||||
public override Tools.Components Component => Tools.Components.CODING_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.CODING_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => T("Coding Assistant");
|
protected override string Title => "Coding Assistant";
|
||||||
|
|
||||||
protected override string Description => T("This coding assistant supports you in writing code. Provide some coding context by copying and pasting your code into the input fields. You might assign an ID to your code snippet to easily reference it later. When you have compiler messages, you can paste them into the input fields to get help with debugging as well.");
|
protected override string Description =>
|
||||||
|
"""
|
||||||
|
This coding assistant supports you in writing code. Provide some coding context by copying and pasting
|
||||||
|
your code into the input fields. You might assign an ID to your code snippet to easily reference it later.
|
||||||
|
When you have compiler messages, you can paste them into the input fields to get help with debugging as well.
|
||||||
|
""";
|
||||||
|
|
||||||
protected override string SystemPrompt =>
|
protected override string SystemPrompt =>
|
||||||
"""
|
"""
|
||||||
@ -25,7 +30,7 @@ public partial class AssistantCoding : AssistantBaseCore<SettingsDialogCoding>
|
|||||||
|
|
||||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
protected override string SubmitText => T("Get Support");
|
protected override string SubmitText => "Get Support";
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.GetSupport;
|
protected override Func<Task> SubmitAction => this.GetSupport;
|
||||||
|
|
||||||
@ -75,7 +80,7 @@ public partial class AssistantCoding : AssistantBaseCore<SettingsDialogCoding>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(checkCompilerMessages))
|
if(string.IsNullOrWhiteSpace(checkCompilerMessages))
|
||||||
return T("Please provide the compiler messages.");
|
return "Please provide the compiler messages.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -83,7 +88,7 @@ public partial class AssistantCoding : AssistantBaseCore<SettingsDialogCoding>
|
|||||||
private string? ValidateQuestions(string checkQuestions)
|
private string? ValidateQuestions(string checkQuestions)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(checkQuestions))
|
if(string.IsNullOrWhiteSpace(checkQuestions))
|
||||||
return T("Please provide your questions.");
|
return "Please provide your questions.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -92,7 +97,7 @@ public partial class AssistantCoding : AssistantBaseCore<SettingsDialogCoding>
|
|||||||
{
|
{
|
||||||
this.codingContexts.Add(new()
|
this.codingContexts.Add(new()
|
||||||
{
|
{
|
||||||
Id = string.Format(T("Context {0}"), this.codingContexts.Count + 1),
|
Id = $"Context {this.codingContexts.Count + 1}",
|
||||||
Language = this.SettingsManager.ConfigurationData.Coding.PreselectOptions ? this.SettingsManager.ConfigurationData.Coding.PreselectedProgrammingLanguage : default,
|
Language = this.SettingsManager.ConfigurationData.Coding.PreselectOptions ? this.SettingsManager.ConfigurationData.Coding.PreselectedProgrammingLanguage : default,
|
||||||
OtherLanguage = this.SettingsManager.ConfigurationData.Coding.PreselectOptions ? this.SettingsManager.ConfigurationData.Coding.PreselectedOtherProgrammingLanguage : string.Empty,
|
OtherLanguage = this.SettingsManager.ConfigurationData.Coding.PreselectOptions ? this.SettingsManager.ConfigurationData.Coding.PreselectedOtherProgrammingLanguage : string.Empty,
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
@inherits MSGComponentBase
|
<MudTextField T="string" @bind-Text="@this.CodingContext.Id" AdornmentIcon="@Icons.Material.Filled.Numbers" Adornment="Adornment.Start" Label="(Optional) Identifier" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.CodingContext.Id" AdornmentIcon="@Icons.Material.Filled.Numbers" Adornment="Adornment.Start" Label="@T("(Optional) Identifier")" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
|
||||||
<MudStack Row="@true" Class="mb-3">
|
<MudStack Row="@true" Class="mb-3">
|
||||||
<MudSelect T="CommonCodingLanguages" @bind-Value="@this.CodingContext.Language" AdornmentIcon="@Icons.Material.Filled.Code" Adornment="Adornment.Start" Label="@T("Language")" Variant="Variant.Outlined" Margin="Margin.Dense">
|
<MudSelect T="CommonCodingLanguages" @bind-Value="@this.CodingContext.Language" AdornmentIcon="@Icons.Material.Filled.Code" Adornment="Adornment.Start" Label="Language" Variant="Variant.Outlined" Margin="Margin.Dense">
|
||||||
@foreach (var language in Enum.GetValues<CommonCodingLanguages>())
|
@foreach (var language in Enum.GetValues<CommonCodingLanguages>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@language">
|
<MudSelectItem Value="@language">@language.Name()</MudSelectItem>
|
||||||
@language.Name()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
@if (this.CodingContext.Language is CommonCodingLanguages.OTHER)
|
@if (this.CodingContext.Language is CommonCodingLanguages.OTHER)
|
||||||
{
|
{
|
||||||
<MudTextField T="string" @bind-Text="@this.CodingContext.OtherLanguage" Validation="@this.ValidatingOtherLanguage" Label="@T("Other language")" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField T="string" @bind-Text="@this.CodingContext.OtherLanguage" Validation="@this.ValidatingOtherLanguage" Label="Other language" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
<MudTextField T="string" @bind-Text="@this.CodingContext.Code" Validation="@this.ValidatingCode" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your code")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" />
|
<MudTextField T="string" @bind-Text="@this.CodingContext.Code" Validation="@this.ValidatingCode" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your code" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" />
|
@ -1,10 +1,10 @@
|
|||||||
using AIStudio.Components;
|
using AIStudio.Settings;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Assistants.Coding;
|
namespace AIStudio.Assistants.Coding;
|
||||||
|
|
||||||
public partial class CodingContextItem : MSGComponentBase
|
public partial class CodingContextItem : ComponentBase
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public CodingContext CodingContext { get; set; } = new();
|
public CodingContext CodingContext { get; set; } = new();
|
||||||
@ -12,6 +12,9 @@ public partial class CodingContextItem : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<CodingContext> CodingContextChanged { get; set; }
|
public EventCallback<CodingContext> CodingContextChanged { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
protected SettingsManager SettingsManager { get; set; } = null!;
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
@ -29,7 +32,7 @@ public partial class CodingContextItem : MSGComponentBase
|
|||||||
private string? ValidatingCode(string code)
|
private string? ValidatingCode(string code)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(code))
|
if(string.IsNullOrWhiteSpace(code))
|
||||||
return string.Format(T("{0}: Please provide your input."), this.CodingContext.Id);
|
return $"{this.CodingContext.Id}: Please provide your input.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -40,7 +43,7 @@ public partial class CodingContextItem : MSGComponentBase
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(language))
|
if(string.IsNullOrWhiteSpace(language))
|
||||||
return T("Please specify the language.");
|
return "Please specify the language.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
public static class CommonCodingLanguageExtensions
|
public static class CommonCodingLanguageExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(CommonCodingLanguageExtensions).Namespace, nameof(CommonCodingLanguageExtensions));
|
|
||||||
|
|
||||||
public static string Name(this CommonCodingLanguages language) => language switch
|
public static string Name(this CommonCodingLanguages language) => language switch
|
||||||
{
|
{
|
||||||
CommonCodingLanguages.NONE => TB("None"),
|
CommonCodingLanguages.NONE => "None",
|
||||||
|
|
||||||
CommonCodingLanguages.BASH => "Bash",
|
CommonCodingLanguages.BASH => "Bash",
|
||||||
CommonCodingLanguages.BLAZOR => ".NET Blazor",
|
CommonCodingLanguages.BLAZOR => ".NET Blazor",
|
||||||
@ -39,7 +37,7 @@ public static class CommonCodingLanguageExtensions
|
|||||||
CommonCodingLanguages.TYPESCRIPT => "TypeScript",
|
CommonCodingLanguages.TYPESCRIPT => "TypeScript",
|
||||||
CommonCodingLanguages.XML => "XML",
|
CommonCodingLanguages.XML => "XML",
|
||||||
|
|
||||||
CommonCodingLanguages.OTHER => TB("Other"),
|
CommonCodingLanguages.OTHER => "Other",
|
||||||
_ => TB("Unknown")
|
_ => "Unknown"
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,14 +2,12 @@ namespace AIStudio.Assistants.ERI;
|
|||||||
|
|
||||||
public static class AllowedLLMProvidersExtensions
|
public static class AllowedLLMProvidersExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(AllowedLLMProvidersExtensions).Namespace, nameof(AllowedLLMProvidersExtensions));
|
|
||||||
|
|
||||||
public static string Description(this AllowedLLMProviders provider) => provider switch
|
public static string Description(this AllowedLLMProviders provider) => provider switch
|
||||||
{
|
{
|
||||||
AllowedLLMProviders.NONE => TB("Please select what kind of LLM provider are allowed for this data source"),
|
AllowedLLMProviders.NONE => "Please select what kind of LLM provider are allowed for this data source",
|
||||||
AllowedLLMProviders.ANY => TB("Any LLM provider is allowed: users might choose a cloud-based or a self-hosted provider"),
|
AllowedLLMProviders.ANY => "Any LLM provider is allowed: users might choose a cloud-based or a self-hosted provider",
|
||||||
AllowedLLMProviders.SELF_HOSTED => TB("Self-hosted LLM providers are allowed: users cannot choose any cloud-based provider"),
|
AllowedLLMProviders.SELF_HOSTED => "Self-hosted LLM providers are allowed: users cannot choose any cloud-based provider",
|
||||||
|
|
||||||
_ => TB("Unknown option was selected")
|
_ => "Unknown option was selected"
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,38 +4,36 @@
|
|||||||
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogERIServer>
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogERIServer>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("You can imagine it like this: Hypothetically, when Wikipedia implemented the ERI, it would vectorize all pages using an embedding method. All of Wikipedia’s data would remain with Wikipedia, including the vector database (decentralized approach). Then, any AI Studio user could add Wikipedia as a data source to significantly reduce the hallucination of the LLM in knowledge questions.")
|
You can imagine it like this: Hypothetically, when Wikipedia implemented the ERI, it would vectorize
|
||||||
|
all pages using an embedding method. All of Wikipedia’s data would remain with Wikipedia, including the
|
||||||
|
vector database (decentralized approach). Then, any AI Studio user could add Wikipedia as a data source to
|
||||||
|
significantly reduce the hallucination of the LLM in knowledge questions.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudText Typo="Typo.body1">
|
<MudText Typo="Typo.body1">
|
||||||
<b>
|
<b>Related links:</b>
|
||||||
@T("Related links:")
|
|
||||||
</b>
|
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudList T="string" Class="mb-6">
|
<MudList T="string" Class="mb-6">
|
||||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://github.com/MindWorkAI/ERI">
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://github.com/MindWorkAI/ERI">ERI repository with example implementation in .NET and C#</MudListItem>
|
||||||
@T("ERI repository with example implementation in .NET and C#")
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://mindworkai.org/swagger-ui.html">Interactive documentation aka Swagger UI</MudListItem>
|
||||||
</MudListItem>
|
|
||||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://mindworkai.org/swagger-ui.html">
|
|
||||||
@T("Interactive documentation aka Swagger UI")
|
|
||||||
</MudListItem>
|
|
||||||
</MudList>
|
</MudList>
|
||||||
|
|
||||||
<PreviewPrototype/>
|
<PreviewPrototype/>
|
||||||
<div class="mb-6"></div>
|
<div class="mb-6"></div>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mb-3">
|
<MudText Typo="Typo.h4" Class="mb-3">
|
||||||
@T("ERI server presets")
|
ERI server presets
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("Here you have the option to save different configurations for various ERI servers and switch between them. This is useful if you are responsible for multiple ERI servers.")
|
Here you have the option to save different configurations for various ERI servers and switch between them. This is useful if
|
||||||
|
you are responsible for multiple ERI servers.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
@if(this.SettingsManager.ConfigurationData.ERI.ERIServers.Count is 0)
|
@if(this.SettingsManager.ConfigurationData.ERI.ERIServers.Count is 0)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("You have not yet added any ERI server presets.")
|
You have not yet added any ERI server presets.
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -52,116 +50,112 @@ else
|
|||||||
|
|
||||||
<MudStack Row="@true" Class="mt-1">
|
<MudStack Row="@true" Class="mt-1">
|
||||||
<MudButton Disabled="@this.AreServerPresetsBlocked" OnClick="@this.AddERIServer" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton Disabled="@this.AreServerPresetsBlocked" OnClick="@this.AddERIServer" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@T("Add ERI server preset")
|
Add ERI server preset
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudButton OnClick="@this.RemoveERIServer" Disabled="@(this.AreServerPresetsBlocked || this.IsNoneERIServerSelected)" Variant="Variant.Filled" Color="Color.Error">
|
<MudButton OnClick="@this.RemoveERIServer" Disabled="@(this.AreServerPresetsBlocked || this.IsNoneERIServerSelected)" Variant="Variant.Filled" Color="Color.Error">
|
||||||
@T("Delete this server preset")
|
Delete this server preset
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@if(this.AreServerPresetsBlocked)
|
@if(this.AreServerPresetsBlocked)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3 mt-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3 mt-3">
|
||||||
@T("Hint: to allow this assistant to manage multiple presets, you must enable the preselection of values in the settings.")
|
Hint: to allow this assistant to manage multiple presets, you must enable the preselection of values in the settings.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mb-3 mt-6">
|
<MudText Typo="Typo.h4" Class="mb-3 mt-6">
|
||||||
@T("Auto save")
|
Auto save
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("The ERI specification will change over time. You probably want to keep your ERI server up to date. This means you might want to regenerate the code for your ERI server. To avoid having to make all inputs each time, all your inputs and decisions can be automatically saved. Would you like this?")
|
The ERI specification will change over time. You probably want to keep your ERI server up to date. This means you might want to
|
||||||
|
regenerate the code for your ERI server. To avoid having to make all inputs each time, all your inputs and decisions can be
|
||||||
|
automatically saved. Would you like this?
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
@if(this.AreServerPresetsBlocked)
|
@if(this.AreServerPresetsBlocked)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("Hint: to allow this assistant to automatically save your changes, you must enable the preselection of values in the settings.")
|
Hint: to allow this assistant to automatically save your changes, you must enable the preselection of values in the settings.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudTextSwitch Label="@T("Should we automatically save any input made?")" Disabled="@this.AreServerPresetsBlocked" @bind-Value="@this.autoSave" LabelOn="@T("Yes, please save my inputs")" LabelOff="@T("No, I will enter everything again or configure it manually in the settings")" />
|
<MudTextSwitch Label="Should we automatically save any input made?" Disabled="@this.AreServerPresetsBlocked" @bind-Value="@this.autoSave" LabelOn="Yes, please save my inputs" LabelOff="No, I will enter everything again or configure it manually in the settings" />
|
||||||
|
|
||||||
<hr style="width: 100%; border-width: 0.25ch;" class="mt-6"/>
|
<hr style="width: 100%; border-width: 0.25ch;" class="mt-6"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-6 mb-1">
|
<MudText Typo="Typo.h4" Class="mt-6 mb-1">
|
||||||
@T("Common ERI server settings")
|
Common ERI server settings
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudTextField T="string" Disabled="@this.IsNoneERIServerSelected" @bind-Text="@this.serverName" Validation="@this.ValidateServerName" Immediate="@true" Label="@T("ERI server name")" HelperText="@T("Please give your ERI server a name that provides information about the data source and/or its intended purpose. The name will be displayed to users in AI Studio.")" Counter="60" MaxLength="60" Variant="Variant.Outlined" Margin="Margin.Normal" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" OnKeyUp="() => this.ServerNameWasChanged()"/>
|
<MudTextField T="string" Disabled="@this.IsNoneERIServerSelected" @bind-Text="@this.serverName" Validation="@this.ValidateServerName" Immediate="@true" Label="ERI server name" HelperText="Please give your ERI server a name that provides information about the data source and/or its intended purpose. The name will be displayed to users in AI Studio." Counter="60" MaxLength="60" Variant="Variant.Outlined" Margin="Margin.Normal" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" OnKeyUp="() => this.ServerNameWasChanged()"/>
|
||||||
<MudTextField T="string" Disabled="@this.IsNoneERIServerSelected" @bind-Text="@this.serverDescription" Validation="@this.ValidateServerDescription" Immediate="@true" Label="@T("ERI server description")" HelperText="@T("Please provide a brief description of your ERI server. Describe or explain what your ERI server does and what data it uses for this purpose. This description will be shown to users in AI Studio.")" Counter="512" MaxLength="512" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
<MudTextField T="string" Disabled="@this.IsNoneERIServerSelected" @bind-Text="@this.serverDescription" Validation="@this.ValidateServerDescription" Immediate="@true" Label="ERI server description" HelperText="Please provide a brief description of your ERI server. Describe or explain what your ERI server does and what data it uses for this purpose. This description will be shown to users in AI Studio." Counter="512" MaxLength="512" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||||
|
|
||||||
<MudStack Row="@true" Class="mb-3">
|
<MudStack Row="@true" Class="mb-3">
|
||||||
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="ProgrammingLanguages" @bind-Value="@this.selectedProgrammingLanguage" AdornmentIcon="@Icons.Material.Filled.Code" Adornment="Adornment.Start" Label="@T("Programming language")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateProgrammingLanguage">
|
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="ProgrammingLanguages" @bind-Value="@this.selectedProgrammingLanguage" AdornmentIcon="@Icons.Material.Filled.Code" Adornment="Adornment.Start" Label="Programming language" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateProgrammingLanguage">
|
||||||
@foreach (var language in Enum.GetValues<ProgrammingLanguages>())
|
@foreach (var language in Enum.GetValues<ProgrammingLanguages>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@language">
|
<MudSelectItem Value="@language">@language.Name()</MudSelectItem>
|
||||||
@language.Name()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
@if (this.selectedProgrammingLanguage is ProgrammingLanguages.OTHER)
|
@if (this.selectedProgrammingLanguage is ProgrammingLanguages.OTHER)
|
||||||
{
|
{
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.otherProgrammingLanguage" Validation="@this.ValidateOtherLanguage" Label="@T("Other language")" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.otherProgrammingLanguage" Validation="@this.ValidateOtherLanguage" Label="Other language" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3">
|
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3">
|
||||||
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="ERIVersion" @bind-Value="@this.selectedERIVersion" Label="@T("ERI specification version")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateERIVersion">
|
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="ERIVersion" @bind-Value="@this.selectedERIVersion" Label="ERI specification version" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateERIVersion">
|
||||||
@foreach (var version in Enum.GetValues<ERIVersion>())
|
@foreach (var version in Enum.GetValues<ERIVersion>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@version">
|
<MudSelectItem Value="@version">@version</MudSelectItem>
|
||||||
@version
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
<MudButton Variant="Variant.Outlined" Size="Size.Small" Disabled="@(!this.selectedERIVersion.WasSpecificationSelected() || this.IsNoneERIServerSelected)" Href="@this.selectedERIVersion.SpecificationURL()" Target="_blank">
|
<MudButton Variant="Variant.Outlined" Size="Size.Small" Disabled="@(!this.selectedERIVersion.WasSpecificationSelected() || this.IsNoneERIServerSelected)" Href="@this.selectedERIVersion.SpecificationURL()" Target="_blank">
|
||||||
<MudIcon Icon="@Icons.Material.Filled.Link" Class="mr-2"/> @T("Download specification")
|
<MudIcon Icon="@Icons.Material.Filled.Link" Class="mr-2"/> Download specification
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-9 mb-3">
|
<MudText Typo="Typo.h4" Class="mt-9 mb-3">
|
||||||
@T("Data source settings")
|
Data source settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudStack Row="@false" Spacing="1" Class="mb-3">
|
<MudStack Row="@false" Spacing="1" Class="mb-3">
|
||||||
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="DataSources" @bind-Value="@this.selectedDataSource" AdornmentIcon="@Icons.Material.Filled.Dataset" Adornment="Adornment.Start" Label="@T("Data source")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateDataSource" SelectedValuesChanged="@this.DataSourceWasChanged">
|
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="DataSources" @bind-Value="@this.selectedDataSource" AdornmentIcon="@Icons.Material.Filled.Dataset" Adornment="Adornment.Start" Label="Data source" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateDataSource" SelectedValuesChanged="@this.DataSourceWasChanged">
|
||||||
@foreach (var dataSource in Enum.GetValues<DataSources>())
|
@foreach (var dataSource in Enum.GetValues<DataSources>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@dataSource">
|
<MudSelectItem Value="@dataSource">@dataSource.Name()</MudSelectItem>
|
||||||
@dataSource.Name()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
@if (this.selectedDataSource is DataSources.CUSTOM)
|
@if (this.selectedDataSource is DataSources.CUSTOM)
|
||||||
{
|
{
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.otherDataSource" Validation="@this.ValidateOtherDataSource" Label="@T("Describe your data source")" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.otherDataSource" Validation="@this.ValidateOtherDataSource" Label="Describe your data source" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@if(this.selectedDataSource > DataSources.FILE_SYSTEM)
|
@if(this.selectedDataSource > DataSources.FILE_SYSTEM)
|
||||||
{
|
{
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.dataSourceProductName" Label="@T("Data source: product name")" Validation="@this.ValidateDataSourceProductName" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.dataSourceProductName" Label="Data source: product name" Validation="@this.ValidateDataSourceProductName" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.NeedHostnamePort())
|
@if (this.NeedHostnamePort())
|
||||||
{
|
{
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<MudStack Row="@true">
|
<MudStack Row="@true">
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.dataSourceHostname" Label="@T("Data source: hostname")" Validation="@this.ValidateHostname" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.dataSourceHostname" Label="Data source: hostname" Validation="@this.ValidateHostname" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
<MudNumericField Disabled="@this.IsNoneERIServerSelected" Label="@T("Data source: port")" Immediate="@true" Min="1" Max="65535" Validation="@this.ValidatePort" @bind-Value="@this.dataSourcePort" Variant="Variant.Outlined" Margin="Margin.Dense" OnKeyUp="() => this.DataSourcePortWasTyped()"/>
|
<MudNumericField Disabled="@this.IsNoneERIServerSelected" Label="Data source: port" Immediate="@true" Min="1" Max="65535" Validation="@this.ValidatePort" @bind-Value="@this.dataSourcePort" Variant="Variant.Outlined" Margin="Margin.Dense" OnKeyUp="() => this.DataSourcePortWasTyped()"/>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
@if (this.dataSourcePort < 1024)
|
@if (this.dataSourcePort < 1024)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body2">
|
<MudText Typo="Typo.body2">
|
||||||
<b>@T("Warning:")</b> @T("Ports below 1024 are reserved for system services. Your ERI server need to run with elevated permissions (root user).")
|
<b>Warning:</b> Ports below 1024 are reserved for system services. Your ERI server need to run with elevated permissions (root user).
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-9 mb-3">
|
<MudText Typo="Typo.h4" Class="mt-9 mb-3">
|
||||||
@T("Authentication settings")
|
Authentication settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudStack Row="@false" Spacing="1" Class="mb-1">
|
<MudStack Row="@false" Spacing="1" Class="mb-1">
|
||||||
@ -174,14 +168,12 @@ else
|
|||||||
SelectedValues="@this.selectedAuthenticationMethods"
|
SelectedValues="@this.selectedAuthenticationMethods"
|
||||||
Validation="@this.ValidateAuthenticationMethods"
|
Validation="@this.ValidateAuthenticationMethods"
|
||||||
SelectedValuesChanged="@this.AuthenticationMethodWasChanged"
|
SelectedValuesChanged="@this.AuthenticationMethodWasChanged"
|
||||||
Label="@T("Authentication method(s)")"
|
Label="Authentication method(s)"
|
||||||
Variant="Variant.Outlined"
|
Variant="Variant.Outlined"
|
||||||
Margin="Margin.Dense">
|
Margin="Margin.Dense">
|
||||||
@foreach (var authMethod in Enum.GetValues<Auth>())
|
@foreach (var authMethod in Enum.GetValues<Auth>())
|
||||||
{
|
{
|
||||||
<MudSelectItemExtended Value="@authMethod">
|
<MudSelectItemExtended Value="@authMethod">@authMethod.Name()</MudSelectItemExtended>
|
||||||
@authMethod.Name()
|
|
||||||
</MudSelectItemExtended>
|
|
||||||
}
|
}
|
||||||
</MudSelectExtended>
|
</MudSelectExtended>
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.authDescription" Label="@this.AuthDescriptionTitle()" Validation="@this.ValidateAuthDescription" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.authDescription" Label="@this.AuthDescriptionTitle()" Validation="@this.ValidateAuthDescription" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
@ -189,39 +181,40 @@ else
|
|||||||
|
|
||||||
@if (this.selectedAuthenticationMethods.Contains(Auth.KERBEROS))
|
@if (this.selectedAuthenticationMethods.Contains(Auth.KERBEROS))
|
||||||
{
|
{
|
||||||
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="OperatingSystem" @bind-Value="@this.selectedOperatingSystem" Label="@T("Operating system on which your ERI will run")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateOperatingSystem" Class="mb-1">
|
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="OperatingSystem" @bind-Value="@this.selectedOperatingSystem" Label="Operating system on which your ERI will run" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateOperatingSystem" Class="mb-1">
|
||||||
@foreach (var os in Enum.GetValues<OperatingSystem>())
|
@foreach (var os in Enum.GetValues<OperatingSystem>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@os">
|
<MudSelectItem Value="@os">@os.Name()</MudSelectItem>
|
||||||
@os.Name()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-11 mb-3">
|
<MudText Typo="Typo.h4" Class="mt-11 mb-3">
|
||||||
@T("Data protection settings")
|
Data protection settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="AllowedLLMProviders" @bind-Value="@this.allowedLLMProviders" Label="@T("Allowed LLM providers for this data source")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateAllowedLLMProviders" Class="mb-1">
|
<MudSelect Disabled="@this.IsNoneERIServerSelected" T="AllowedLLMProviders" @bind-Value="@this.allowedLLMProviders" Label="Allowed LLM providers for this data source" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateAllowedLLMProviders" Class="mb-1">
|
||||||
@foreach (var option in Enum.GetValues<AllowedLLMProviders>())
|
@foreach (var option in Enum.GetValues<AllowedLLMProviders>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@option">
|
<MudSelectItem Value="@option">@option.Description()</MudSelectItem>
|
||||||
@option.Description()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-11 mb-3">
|
<MudText Typo="Typo.h4" Class="mt-11 mb-3">
|
||||||
@T("Embedding settings")
|
Embedding settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
@T("You will likely use one or more embedding methods to encode the meaning of your data into a typically high-dimensional vector space. In this case, you will use a vector database to store and search these vectors (called embeddings). However, you don't have to use embedding methods. When your retrieval method works without any embedding, you can ignore this section. An example: You store files on a file server, and your retrieval method works exclusively with file names in the file system, so you don't need embeddings.")
|
You will likely use one or more embedding methods to encode the meaning of your data into a typically high-dimensional vector
|
||||||
|
space. In this case, you will use a vector database to store and search these vectors (called embeddings). However, you don't
|
||||||
|
have to use embedding methods. When your retrieval method works without any embedding, you can ignore this section. An example: You
|
||||||
|
store files on a file server, and your retrieval method works exclusively with file names in the file system, so you don't
|
||||||
|
need embeddings.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("You can specify more than one embedding method. This can be useful when you want to use different embeddings for different queries or data types. For example, one embedding for texts, another for images, and a third for videos, etc.")
|
You can specify more than one embedding method. This can be useful when you want to use different embeddings for different queries
|
||||||
|
or data types. For example, one embedding for texts, another for images, and a third for videos, etc.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
@if (!this.IsNoneERIServerSelected)
|
@if (!this.IsNoneERIServerSelected)
|
||||||
@ -233,9 +226,9 @@ else
|
|||||||
<col style="width: 34em;"/>
|
<col style="width: 34em;"/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>@T("Name")</MudTh>
|
<MudTh>Name</MudTh>
|
||||||
<MudTh>@T("Type")</MudTh>
|
<MudTh>Type</MudTh>
|
||||||
<MudTh>@T("Actions")</MudTh>
|
<MudTh>Actions</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>@context.EmbeddingName</MudTd>
|
<MudTd>@context.EmbeddingName</MudTd>
|
||||||
@ -243,10 +236,10 @@ else
|
|||||||
<MudTd>
|
<MudTd>
|
||||||
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbedding(context)">
|
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbedding(context)">
|
||||||
@T("Edit")
|
Edit
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbedding(context)">
|
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbedding(context)">
|
||||||
@T("Delete")
|
Delete
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
@ -255,22 +248,23 @@ else
|
|||||||
|
|
||||||
@if (this.embeddings.Count == 0)
|
@if (this.embeddings.Count == 0)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.h6" Class="mt-3">
|
<MudText Typo="Typo.h6" Class="mt-3">No embedding methods configured yet.</MudText>
|
||||||
@T("No embedding methods configured yet.")
|
|
||||||
</MudText>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudButton Disabled="@this.IsNoneERIServerSelected" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbedding">
|
<MudButton Disabled="@this.IsNoneERIServerSelected" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbedding">
|
||||||
@T("Add Embedding Method")
|
Add Embedding Method
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-6 mb-1">
|
<MudText Typo="Typo.h4" Class="mt-6 mb-1">
|
||||||
@T("Data retrieval settings")
|
Data retrieval settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
@T("For your ERI server, you need to retrieve data that matches a chat or prompt in some way. We call this the retrieval process. You must describe at least one such process. You may offer several retrieval processes from which users can choose. This allows you to test with beta users which process works better. Or you might generally want to give users the choice so they can select the process that best suits their circumstances.")
|
For your ERI server, you need to retrieve data that matches a chat or prompt in some way. We call this the retrieval process.
|
||||||
|
You must describe at least one such process. You may offer several retrieval processes from which users can choose. This allows
|
||||||
|
you to test with beta users which process works better. Or you might generally want to give users the choice so they can select
|
||||||
|
the process that best suits their circumstances.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
@if (!this.IsNoneERIServerSelected)
|
@if (!this.IsNoneERIServerSelected)
|
||||||
@ -281,18 +275,18 @@ else
|
|||||||
<col style="width: 34em;"/>
|
<col style="width: 34em;"/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>@T("Name")</MudTh>
|
<MudTh>Name</MudTh>
|
||||||
<MudTh>@T("Actions")</MudTh>
|
<MudTh>Actions</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>@context.Name</MudTd>
|
<MudTd>@context.Name</MudTd>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditRetrievalProcess(context)">
|
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditRetrievalProcess(context)">
|
||||||
@T("Edit")
|
Edit
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteRetrievalProcess(context)">
|
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteRetrievalProcess(context)">
|
||||||
@T("Delete")
|
Delete
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
@ -301,47 +295,59 @@ else
|
|||||||
|
|
||||||
@if (this.retrievalProcesses.Count == 0)
|
@if (this.retrievalProcesses.Count == 0)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.h6" Class="mt-3">
|
<MudText Typo="Typo.h6" Class="mt-3">No retrieval process configured yet.</MudText>
|
||||||
@T("No retrieval process configured yet.")
|
|
||||||
</MudText>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudButton Disabled="@this.IsNoneERIServerSelected" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddRetrievalProcess">
|
<MudButton Disabled="@this.IsNoneERIServerSelected" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddRetrievalProcess">
|
||||||
@T("Add Retrieval Process")
|
Add Retrieval Process
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-1">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-1">
|
||||||
@T("You can integrate additional libraries. Perhaps you want to evaluate the prompts in advance using a machine learning method or analyze them with a text mining approach? Or maybe you want to preprocess images in the prompts? For such advanced scenarios, you can specify which libraries you want to use here. It's best to describe which library you want to integrate for which purpose. This way, the LLM that writes the ERI server for you can try to use these libraries effectively. This should result in less rework being necessary. If you don't know the necessary libraries, you can instead attempt to describe the intended use. The LLM can then attempt to choose suitable libraries. However, hallucinations can occur, and fictional libraries might be selected.")
|
You can integrate additional libraries. Perhaps you want to evaluate the prompts in advance using a machine learning method or analyze them with a text
|
||||||
|
mining approach? Or maybe you want to preprocess images in the prompts? For such advanced scenarios, you can specify which libraries you want to use here.
|
||||||
|
It's best to describe which library you want to integrate for which purpose. This way, the LLM that writes the ERI server for you can try to use these
|
||||||
|
libraries effectively. This should result in less rework being necessary. If you don't know the necessary libraries, you can instead attempt to describe
|
||||||
|
the intended use. The LLM can then attempt to choose suitable libraries. However, hallucinations can occur, and fictional libraries might be selected.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.additionalLibraries" Label="@T("(Optional) Additional libraries")" HelperText="@T("Do you want to include additional libraries? Then name them and briefly describe what you want to achieve with them.")" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="12" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
<MudTextField Disabled="@this.IsNoneERIServerSelected" T="string" @bind-Text="@this.additionalLibraries" Label="(Optional) Additional libraries" HelperText="Do you want to include additional libraries? Then name them and briefly describe what you want to achieve with them." Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="12" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-9 mb-1">
|
<MudText Typo="Typo.h4" Class="mt-9 mb-1">
|
||||||
@T("Provider selection for generation")
|
Provider selection for generation
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
@T("The task of writing the ERI server for you is very complex. Therefore, a very powerful LLM is needed to successfully accomplish this task. Small local models will probably not be sufficient. Instead, try using a large cloud-based or a large self-hosted model.")
|
The task of writing the ERI server for you is very complex. Therefore, a very powerful LLM is needed to successfully accomplish this task.
|
||||||
|
Small local models will probably not be sufficient. Instead, try using a large cloud-based or a large self-hosted model.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
<b>@T("Important:")</b> @T("The LLM may need to generate many files. This reaches the request limit of most providers. Typically, only a certain number of requests can be made per minute, and only a maximum number of tokens can be generated per minute. AI Studio automatically considers this.") <b>@T("However, generating all the files takes a certain amount of time.")</b> @T("Local or self-hosted models may work without these limitations and can generate responses faster. AI Studio dynamically adapts its behavior and always tries to achieve the fastest possible data processing.")
|
<b>Important:</b> The LLM may need to generate many files. This reaches the request limit of most providers. Typically, only a certain number
|
||||||
|
of requests can be made per minute, and only a maximum number of tokens can be generated per minute. AI Studio automatically considers this.
|
||||||
|
<b>However, generating all the files takes a certain amount of time.</b> Local or self-hosted models may work without these limitations
|
||||||
|
and can generate responses faster. AI Studio dynamically adapts its behavior and always tries to achieve the fastest possible data processing.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h4" Class="mt-9 mb-1">
|
<MudText Typo="Typo.h4" Class="mt-9 mb-1">
|
||||||
@T("Write code to file system")
|
Write code to file system
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
@T("AI Studio can save the generated code to the file system. You can select a base folder for this. AI Studio ensures that no files are created outside of this base folder. Furthermore, we recommend that you create a Git repository in this folder. This way, you can see what changes the AI has made in which files.")
|
AI Studio can save the generated code to the file system. You can select a base folder for this. AI Studio ensures that no files are created
|
||||||
|
outside of this base folder. Furthermore, we recommend that you create a Git repository in this folder. This way, you can see what changes the
|
||||||
|
AI has made in which files.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
|
||||||
@T("When you rebuild / re-generate the ERI server code, AI Studio proceeds as follows: All files generated last time will be deleted. All other files you have created remain. Then, the AI generates the new files.") <b>@T("But beware:")</b> @T("It may happen that the AI generates a file this time that you manually created last time. In this case, your manually created file will then be overwritten. Therefore, you should always create a Git repository and commit or revert all changes before using this assistant. With a diff visualization, you can immediately see where the AI has made changes. It is best to use an IDE suitable for your selected language for this purpose.")
|
When you rebuild / re-generate the ERI server code, AI Studio proceeds as follows: All files generated last time will be deleted. All
|
||||||
|
other files you have created remain. Then, the AI generates the new files. <b>But beware:</b> It may happen that the AI generates a
|
||||||
|
file this time that you manually created last time. In this case, your manually created file will then be overwritten. Therefore,
|
||||||
|
you should always create a Git repository and commit or revert all changes before using this assistant. With a diff visualization,
|
||||||
|
you can immediately see where the AI has made changes. It is best to use an IDE suitable for your selected language for this purpose.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudTextSwitch Label="@T("Should we write the generated code to the file system?")" Disabled="@this.IsNoneERIServerSelected" @bind-Value="@this.writeToFilesystem" LabelOn="@T("Yes, please write or update all generated code to the file system")" LabelOff="@T("No, just show me the code")" />
|
<MudTextSwitch Label="Should we write the generated code to the file system?" Disabled="@this.IsNoneERIServerSelected" @bind-Value="@this.writeToFilesystem" LabelOn="Yes, please write or update all generated code to the file system" LabelOff="No, just show me the code" />
|
||||||
<SelectDirectory Label="@T("Base directory where to write the code")" @bind-Directory="@this.baseDirectory" Disabled="@(this.IsNoneERIServerSelected || !this.writeToFilesystem)" DirectoryDialogTitle="@T("Select the target directory for the ERI server")" Validation="@this.ValidateDirectory" />
|
<SelectDirectory Label="Base directory where to write the code" @bind-Directory="@this.baseDirectory" Disabled="@(this.IsNoneERIServerSelected || !this.writeToFilesystem)" DirectoryDialogTitle="Select the target directory for the ERI server" Validation="@this.ValidateDirectory" />
|
||||||
|
@ -22,9 +22,16 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
|
|
||||||
public override Tools.Components Component => Tools.Components.ERI_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.ERI_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => T("ERI Server");
|
protected override string Title => "ERI Server";
|
||||||
|
|
||||||
protected override string Description => T("The ERI is the External Retrieval Interface for AI Studio and other tools. The ERI acts as a contract between decentralized data sources and, e.g., AI Studio. The ERI is implemented by the data sources, allowing them to be integrated into AI Studio later. This means that the data sources assume the server role and AI Studio (or any other LLM tool) assumes the client role of the API. This approach serves to realize a Retrieval-Augmented Generation (RAG) process with external data.");
|
protected override string Description =>
|
||||||
|
"""
|
||||||
|
The ERI is the External Retrieval Interface for AI Studio and other tools. The ERI acts as a contract
|
||||||
|
between decentralized data sources and, e.g., AI Studio. The ERI is implemented by the data sources,
|
||||||
|
allowing them to be integrated into AI Studio later. This means that the data sources assume the server
|
||||||
|
role and AI Studio (or any other LLM tool) assumes the client role of the API. This approach serves to
|
||||||
|
realize a Retrieval-Augmented Generation (RAG) process with external data.
|
||||||
|
""";
|
||||||
|
|
||||||
protected override string SystemPrompt
|
protected override string SystemPrompt
|
||||||
{
|
{
|
||||||
@ -37,7 +44,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
// Introduction
|
// Introduction
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
//
|
//
|
||||||
var programmingLanguage = this.selectedProgrammingLanguage is ProgrammingLanguages.OTHER ? this.otherProgrammingLanguage : this.selectedProgrammingLanguage.ToPrompt();
|
var programmingLanguage = this.selectedProgrammingLanguage is ProgrammingLanguages.OTHER ? this.otherProgrammingLanguage : this.selectedProgrammingLanguage.Name();
|
||||||
sb.Append($"""
|
sb.Append($"""
|
||||||
# Introduction
|
# Introduction
|
||||||
You are an experienced {programmingLanguage} developer. Your task is to implement an API server in
|
You are an experienced {programmingLanguage} developer. Your task is to implement an API server in
|
||||||
@ -152,7 +159,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{
|
{
|
||||||
sb.Append($"""
|
sb.Append($"""
|
||||||
|
|
||||||
The server will run on {this.selectedOperatingSystem.ToPrompt()} operating systems. Keep
|
The server will run on {this.selectedOperatingSystem.Name()} operating systems. Keep
|
||||||
this in mind when implementing the SSO with Kerberos.
|
this in mind when implementing the SSO with Kerberos.
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@ -297,7 +304,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
|
|
||||||
protected override bool ShowSendTo => false;
|
protected override bool ShowSendTo => false;
|
||||||
|
|
||||||
protected override string SubmitText => T("Create the ERI server");
|
protected override string SubmitText => "Create the ERI server";
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.GenerateServer;
|
protected override Func<Task> SubmitAction => this.GenerateServer;
|
||||||
|
|
||||||
@ -462,7 +469,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{
|
{
|
||||||
this.SettingsManager.ConfigurationData.ERI.ERIServers.Add(new ()
|
this.SettingsManager.ConfigurationData.ERI.ERIServers.Add(new ()
|
||||||
{
|
{
|
||||||
ServerName = string.Format(T("ERI Server {0}"), DateTimeOffset.UtcNow),
|
ServerName = $"ERI Server {DateTimeOffset.UtcNow}",
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.SettingsManager.StoreSettings();
|
await this.SettingsManager.StoreSettings();
|
||||||
@ -475,10 +482,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the ERI server preset '{0}'?"), this.selectedERIServer.ServerName) },
|
{ "Message", $"Are you sure you want to delete the ERI server preset '{this.selectedERIServer.ServerName}'?" },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete ERI server preset"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete ERI server preset", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -511,13 +518,13 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private string? ValidateServerName(string name)
|
private string? ValidateServerName(string name)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(name))
|
if(string.IsNullOrWhiteSpace(name))
|
||||||
return T("Please provide a name for your ERI server. This name will be used to identify the server in AI Studio.");
|
return "Please provide a name for your ERI server. This name will be used to identify the server in AI Studio.";
|
||||||
|
|
||||||
if(name.Length is > 60 or < 6)
|
if(name.Length is > 60 or < 6)
|
||||||
return T("The name of your ERI server must be between 6 and 60 characters long.");
|
return "The name of your ERI server must be between 6 and 60 characters long.";
|
||||||
|
|
||||||
if(this.SettingsManager.ConfigurationData.ERI.ERIServers.Where(n => n != this.selectedERIServer).Any(n => n.ServerName == name))
|
if(this.SettingsManager.ConfigurationData.ERI.ERIServers.Where(n => n != this.selectedERIServer).Any(n => n.ServerName == name))
|
||||||
return T("An ERI server preset with this name already exists. Please choose a different name.");
|
return "An ERI server preset with this name already exists. Please choose a different name.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -525,10 +532,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private string? ValidateServerDescription(string description)
|
private string? ValidateServerDescription(string description)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(description))
|
if(string.IsNullOrWhiteSpace(description))
|
||||||
return T("Please provide a description for your ERI server. What data will the server retrieve? This description will be used to inform users about the purpose of your ERI server.");
|
return "Please provide a description for your ERI server. What data will the server retrieve? This description will be used to inform users about the purpose of your ERI server.";
|
||||||
|
|
||||||
if(description.Length is < 32 or > 512)
|
if(description.Length is < 32 or > 512)
|
||||||
return T("The description of your ERI server must be between 32 and 512 characters long.");
|
return "The description of your ERI server must be between 32 and 512 characters long.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -536,7 +543,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private string? ValidateERIVersion(ERIVersion version)
|
private string? ValidateERIVersion(ERIVersion version)
|
||||||
{
|
{
|
||||||
if (version == ERIVersion.NONE)
|
if (version == ERIVersion.NONE)
|
||||||
return T("Please select an ERI specification version for the ERI server.");
|
return "Please select an ERI specification version for the ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -547,7 +554,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (language == ProgrammingLanguages.NONE)
|
if (language == ProgrammingLanguages.NONE)
|
||||||
return T("Please select a programming language for the ERI server.");
|
return "Please select a programming language for the ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -558,7 +565,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(language))
|
if(string.IsNullOrWhiteSpace(language))
|
||||||
return T("Please specify the custom programming language for the ERI server.");
|
return "Please specify the custom programming language for the ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -569,7 +576,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (dataSource == DataSources.NONE)
|
if (dataSource == DataSources.NONE)
|
||||||
return T("Please select a data source for the ERI server.");
|
return "Please select a data source for the ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -580,7 +587,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(productName))
|
if(string.IsNullOrWhiteSpace(productName))
|
||||||
return T("Please specify the product name of the data source, e.g., 'MongoDB', 'Redis', 'PostgreSQL', 'Neo4j', or 'MinIO', etc.");
|
return "Please specify the product name of the data source, e.g., 'MongoDB', 'Redis', 'PostgreSQL', 'Neo4j', or 'MinIO', etc.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -591,7 +598,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(dataSource))
|
if(string.IsNullOrWhiteSpace(dataSource))
|
||||||
return T("Please describe the data source of your ERI server.");
|
return "Please describe the data source of your ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -606,10 +613,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(hostname))
|
if(string.IsNullOrWhiteSpace(hostname))
|
||||||
return T("Please provide the hostname of the data source. Use 'localhost' if the data source is on the same machine as the ERI server.");
|
return "Please provide the hostname of the data source. Use 'localhost' if the data source is on the same machine as the ERI server.";
|
||||||
|
|
||||||
if(hostname.Length > 255)
|
if(hostname.Length > 255)
|
||||||
return T("The hostname of the data source must not exceed 255 characters.");
|
return "The hostname of the data source must not exceed 255 characters.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -624,10 +631,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(port is null)
|
if(port is null)
|
||||||
return T("Please provide the port of the data source.");
|
return "Please provide the port of the data source.";
|
||||||
|
|
||||||
if(port is < 1 or > 65535)
|
if(port is < 1 or > 65535)
|
||||||
return T("The port of the data source must be between 1 and 65535.");
|
return "The port of the data source must be between 1 and 65535.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -672,7 +679,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{
|
{
|
||||||
var authenticationMethods = (this.selectedAuthenticationMethods as HashSet<Auth>)!;
|
var authenticationMethods = (this.selectedAuthenticationMethods as HashSet<Auth>)!;
|
||||||
if(authenticationMethods.Count == 0)
|
if(authenticationMethods.Count == 0)
|
||||||
return T("Please select at least one authentication method for the ERI server.");
|
return "Please select at least one authentication method for the ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -702,7 +709,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(os is OperatingSystem.NONE)
|
if(os is OperatingSystem.NONE)
|
||||||
return T("Please select the operating system on which the ERI server will run. This is necessary when using SSO with Kerberos.");
|
return "Please select the operating system on which the ERI server will run. This is necessary when using SSO with Kerberos.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -710,12 +717,16 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private string? ValidateAllowedLLMProviders(AllowedLLMProviders provider)
|
private string? ValidateAllowedLLMProviders(AllowedLLMProviders provider)
|
||||||
{
|
{
|
||||||
if(provider == AllowedLLMProviders.NONE)
|
if(provider == AllowedLLMProviders.NONE)
|
||||||
return T("Please select which types of LLMs users are allowed to use with the data from this ERI server.");
|
return "Please select which types of LLMs users are allowed to use with the data from this ERI server.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string AuthDescriptionTitle() => this.IsAuthDescriptionOptional() ? T("(Optional) Describe how you planned the authentication process") : T("Describe how you planned the authentication process");
|
private string AuthDescriptionTitle()
|
||||||
|
{
|
||||||
|
const string TITLE = "Describe how you planned the authentication process";
|
||||||
|
return this.IsAuthDescriptionOptional() ? $"(Optional) {TITLE}" : TITLE;
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsAuthDescriptionOptional()
|
private bool IsAuthDescriptionOptional()
|
||||||
{
|
{
|
||||||
@ -735,10 +746,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{
|
{
|
||||||
var authenticationMethods = (this.selectedAuthenticationMethods as HashSet<Auth>)!;
|
var authenticationMethods = (this.selectedAuthenticationMethods as HashSet<Auth>)!;
|
||||||
if(authenticationMethods.Any(n => n == Auth.NONE) && authenticationMethods.Count > 1 && string.IsNullOrWhiteSpace(this.authDescription))
|
if(authenticationMethods.Any(n => n == Auth.NONE) && authenticationMethods.Count > 1 && string.IsNullOrWhiteSpace(this.authDescription))
|
||||||
return T("Please describe how the selected authentication methods should be used. Especially, explain for what data the NONE method (public access) is used.");
|
return "Please describe how the selected authentication methods should be used. Especially, explain for what data the NONE method (public access) is used.";
|
||||||
|
|
||||||
if(authenticationMethods.Count > 1 && string.IsNullOrWhiteSpace(this.authDescription))
|
if(authenticationMethods.Count > 1 && string.IsNullOrWhiteSpace(this.authDescription))
|
||||||
return T("Please describe how the selected authentication methods should be used.");
|
return "Please describe how the selected authentication methods should be used.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -749,7 +760,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(path))
|
if(string.IsNullOrWhiteSpace(path))
|
||||||
return T("Please provide a base directory for the ERI server to write files to.");
|
return "Please provide a base directory for the ERI server to write files to.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -757,12 +768,12 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private string GetMultiSelectionAuthText(List<Auth> selectedValues)
|
private string GetMultiSelectionAuthText(List<Auth> selectedValues)
|
||||||
{
|
{
|
||||||
if(selectedValues.Count == 0)
|
if(selectedValues.Count == 0)
|
||||||
return T("Please select at least one authentication method");
|
return "Please select at least one authentication method";
|
||||||
|
|
||||||
if(selectedValues.Count == 1)
|
if(selectedValues.Count == 1)
|
||||||
return T("You have selected 1 authentication method");
|
return $"You have selected 1 authentication method";
|
||||||
|
|
||||||
return string.Format(T("You have selected {0} authentication methods"), selectedValues.Count);
|
return $"You have selected {selectedValues.Count} authentication methods";
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool NeedHostnamePort()
|
private bool NeedHostnamePort()
|
||||||
@ -786,7 +797,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{ x => x.UsedEmbeddingMethodNames, this.embeddings.Select(n => n.EmbeddingName).ToList() },
|
{ x => x.UsedEmbeddingMethodNames, this.embeddings.Select(n => n.EmbeddingName).ToList() },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingMethodDialog>(T("Add Embedding Method"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<EmbeddingMethodDialog>("Add Embedding Method", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -810,7 +821,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{ x => x.IsEditing, true },
|
{ x => x.IsEditing, true },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingMethodDialog>(T("Edit Embedding Method"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<EmbeddingMethodDialog>("Edit Embedding Method", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -824,15 +835,15 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
private async Task DeleteEmbedding(EmbeddingInfo embeddingInfo)
|
private async Task DeleteEmbedding(EmbeddingInfo embeddingInfo)
|
||||||
{
|
{
|
||||||
var message = this.retrievalProcesses.Any(n => n.Embeddings?.Contains(embeddingInfo) is true)
|
var message = this.retrievalProcesses.Any(n => n.Embeddings?.Contains(embeddingInfo) is true)
|
||||||
? string.Format(T("The embedding '{0}' is used in one or more retrieval processes. Are you sure you want to delete it?"), embeddingInfo.EmbeddingName)
|
? $"The embedding '{embeddingInfo.EmbeddingName}' is used in one or more retrieval processes. Are you sure you want to delete it?"
|
||||||
: string.Format(T("Are you sure you want to delete the embedding '{0}'?"), embeddingInfo.EmbeddingName);
|
: $"Are you sure you want to delete the embedding '{embeddingInfo.EmbeddingName}'?";
|
||||||
|
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters
|
||||||
{
|
{
|
||||||
{ "Message", message },
|
{ "Message", message },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Embedding", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -852,7 +863,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{ x => x.UsedRetrievalProcessNames, this.retrievalProcesses.Select(n => n.Name).ToList() },
|
{ x => x.UsedRetrievalProcessNames, this.retrievalProcesses.Select(n => n.Name).ToList() },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<RetrievalProcessDialog>(T("Add Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<RetrievalProcessDialog>("Add Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -877,7 +888,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{ x => x.UsedRetrievalProcessNames, this.retrievalProcesses.Where(n => n != retrievalInfo).Select(n => n.Name).ToList() },
|
{ x => x.UsedRetrievalProcessNames, this.retrievalProcesses.Where(n => n != retrievalInfo).Select(n => n.Name).ToList() },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<RetrievalProcessDialog>(T("Edit Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<RetrievalProcessDialog>("Edit Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -892,10 +903,10 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters
|
||||||
{
|
{
|
||||||
{ "Message", string.Format(T("Are you sure you want to delete the retrieval process '{0}'?"), retrievalInfo.Name) },
|
{ "Message", $"Are you sure you want to delete the retrieval process '{retrievalInfo.Name}'?" },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
var dialogResult = await dialogReference.Result;
|
var dialogResult = await dialogReference.Result;
|
||||||
if (dialogResult is null || dialogResult.Canceled)
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
return;
|
return;
|
||||||
@ -946,14 +957,14 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
|
|
||||||
if(this.retrievalProcesses.Count == 0)
|
if(this.retrievalProcesses.Count == 0)
|
||||||
{
|
{
|
||||||
this.AddInputIssue(T("Please describe at least one retrieval process."));
|
this.AddInputIssue("Please describe at least one retrieval process.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.eriSpecification = await this.selectedERIVersion.ReadSpecification(this.HttpClient);
|
this.eriSpecification = await this.selectedERIVersion.ReadSpecification(this.HttpClient);
|
||||||
if (string.IsNullOrWhiteSpace(this.eriSpecification))
|
if (string.IsNullOrWhiteSpace(this.eriSpecification))
|
||||||
{
|
{
|
||||||
this.AddInputIssue(T("The ERI specification could not be loaded. Please try again later."));
|
this.AddInputIssue("The ERI specification could not be loaded. Please try again later.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,17 +2,15 @@ namespace AIStudio.Assistants.ERI;
|
|||||||
|
|
||||||
public static class AuthExtensions
|
public static class AuthExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(AuthExtensions).Namespace, nameof(AuthExtensions));
|
|
||||||
|
|
||||||
public static string Name(this Auth auth) => auth switch
|
public static string Name(this Auth auth) => auth switch
|
||||||
{
|
{
|
||||||
Auth.NONE => TB("No login necessary: useful for public data sources"),
|
Auth.NONE => "No login necessary: useful for public data sources",
|
||||||
|
|
||||||
Auth.KERBEROS => TB("Login by single-sign-on (SSO) using Kerberos: very complex to implement and to operate, useful for many users"),
|
Auth.KERBEROS => "Login by single-sign-on (SSO) using Kerberos: very complex to implement and to operate, useful for many users",
|
||||||
Auth.USERNAME_PASSWORD => TB("Login by username and password: simple to implement and to operate, useful for few users; easy to use for users"),
|
Auth.USERNAME_PASSWORD => "Login by username and password: simple to implement and to operate, useful for few users; easy to use for users",
|
||||||
Auth.TOKEN => TB("Login by token: simple to implement and to operate, useful for few users; unusual for many users"),
|
Auth.TOKEN => "Login by token: simple to implement and to operate, useful for few users; unusual for many users",
|
||||||
|
|
||||||
_ => TB("Unknown login method")
|
_ => "Unknown login method"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string ToPrompt(this Auth auth) => auth switch
|
public static string ToPrompt(this Auth auth) => auth switch
|
||||||
|
@ -2,20 +2,18 @@ namespace AIStudio.Assistants.ERI;
|
|||||||
|
|
||||||
public static class DataSourcesExtensions
|
public static class DataSourcesExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(DataSourcesExtensions).Namespace, nameof(DataSourcesExtensions));
|
|
||||||
|
|
||||||
public static string Name(this DataSources dataSource) => dataSource switch
|
public static string Name(this DataSources dataSource) => dataSource switch
|
||||||
{
|
{
|
||||||
DataSources.NONE => TB("No data source selected"),
|
DataSources.NONE => "No data source selected",
|
||||||
DataSources.CUSTOM => TB("Custom description"),
|
DataSources.CUSTOM => "Custom description",
|
||||||
|
|
||||||
DataSources.FILE_SYSTEM => TB("File system (local or network share)"),
|
DataSources.FILE_SYSTEM => "File system (local or network share)",
|
||||||
DataSources.OBJECT_STORAGE => TB("Object storage, like Amazon S3, MinIO, etc."),
|
DataSources.OBJECT_STORAGE => "Object storage, like Amazon S3, MinIO, etc.",
|
||||||
DataSources.KEY_VALUE_STORE => TB("Key-Value store, like Redis, etc."),
|
DataSources.KEY_VALUE_STORE => "Key-Value store, like Redis, etc.",
|
||||||
DataSources.DOCUMENT_STORE => TB("Document store, like MongoDB, etc."),
|
DataSources.DOCUMENT_STORE => "Document store, like MongoDB, etc.",
|
||||||
DataSources.RELATIONAL_DATABASE => TB("Relational database, like MySQL, PostgreSQL, etc."),
|
DataSources.RELATIONAL_DATABASE => "Relational database, like MySQL, PostgreSQL, etc.",
|
||||||
DataSources.GRAPH_DATABASE => TB("Graph database, like Neo4j, ArangoDB, etc."),
|
DataSources.GRAPH_DATABASE => "Graph database, like Neo4j, ArangoDB, etc.",
|
||||||
|
|
||||||
_ => TB("Unknown data source")
|
_ => "Unknown data source"
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,19 +2,7 @@ namespace AIStudio.Assistants.ERI;
|
|||||||
|
|
||||||
public static class OperatingSystemExtensions
|
public static class OperatingSystemExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(OperatingSystemExtensions).Namespace, nameof(OperatingSystemExtensions));
|
|
||||||
|
|
||||||
public static string Name(this OperatingSystem os) => os switch
|
public static string Name(this OperatingSystem os) => os switch
|
||||||
{
|
|
||||||
OperatingSystem.NONE => TB("No operating system specified"),
|
|
||||||
|
|
||||||
OperatingSystem.WINDOWS => TB("Windows"),
|
|
||||||
OperatingSystem.LINUX => TB("Linux"),
|
|
||||||
|
|
||||||
_ => TB("Unknown operating system")
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string ToPrompt(this OperatingSystem os) => os switch
|
|
||||||
{
|
{
|
||||||
OperatingSystem.NONE => "No operating system specified",
|
OperatingSystem.NONE => "No operating system specified",
|
||||||
|
|
||||||
|
@ -2,29 +2,7 @@ namespace AIStudio.Assistants.ERI;
|
|||||||
|
|
||||||
public static class ProgrammingLanguagesExtensions
|
public static class ProgrammingLanguagesExtensions
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(ProgrammingLanguagesExtensions).Namespace, nameof(ProgrammingLanguagesExtensions));
|
|
||||||
|
|
||||||
public static string Name(this ProgrammingLanguages language) => language switch
|
public static string Name(this ProgrammingLanguages language) => language switch
|
||||||
{
|
|
||||||
ProgrammingLanguages.NONE => TB("No programming language selected"),
|
|
||||||
|
|
||||||
ProgrammingLanguages.C => "C",
|
|
||||||
ProgrammingLanguages.CPP => "C++",
|
|
||||||
ProgrammingLanguages.CSHARP => "C#",
|
|
||||||
ProgrammingLanguages.GO => "Go",
|
|
||||||
ProgrammingLanguages.JAVA => "Java",
|
|
||||||
ProgrammingLanguages.JAVASCRIPT => "JavaScript",
|
|
||||||
ProgrammingLanguages.JULIA => "Julia",
|
|
||||||
ProgrammingLanguages.MATLAB => "MATLAB",
|
|
||||||
ProgrammingLanguages.PHP => "PHP",
|
|
||||||
ProgrammingLanguages.PYTHON => "Python",
|
|
||||||
ProgrammingLanguages.RUST => "Rust",
|
|
||||||
|
|
||||||
ProgrammingLanguages.OTHER => TB("Other"),
|
|
||||||
_ => TB("Unknown")
|
|
||||||
};
|
|
||||||
|
|
||||||
public static string ToPrompt(this ProgrammingLanguages language) => language switch
|
|
||||||
{
|
{
|
||||||
ProgrammingLanguages.NONE => "No programming language selected",
|
ProgrammingLanguages.NONE => "No programming language selected",
|
||||||
|
|
||||||
|
@ -2,35 +2,35 @@
|
|||||||
@using AIStudio.Settings
|
@using AIStudio.Settings
|
||||||
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogI18N>
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogI18N>
|
||||||
|
|
||||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" SelectionUpdated="_ => this.OnChangedLanguage()" />
|
<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" SelectionUpdated="_ => this.OnChangedLanguage()" />
|
||||||
<ConfigurationSelect OptionDescription="@T("Language plugin used for comparision")" SelectedValue="@(() => this.selectedLanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(async void (id) => await this.OnLanguagePluginChanged(id))" OptionHelp="@T("Select the language plugin used for comparision.")"/>
|
<ConfigurationSelect OptionDescription="Language plugin used for comparision" SelectedValue="@(() => this.selectedLanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(async void (id) => await this.OnLanguagePluginChanged(id))" OptionHelp="Select the language plugin used for comparision."/>
|
||||||
@if (this.isLoading)
|
@if (this.isLoading)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Class="mb-6">
|
<MudText Typo="Typo.body1" Class="mb-6">
|
||||||
@T("The data is being loaded, please wait...")
|
The data is being loaded, please wait...
|
||||||
</MudText>
|
</MudText>
|
||||||
} else if (!this.isLoading && !string.IsNullOrWhiteSpace(this.loadingIssue))
|
} else if (!this.isLoading && !string.IsNullOrWhiteSpace(this.loadingIssue))
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Class="mb-6">
|
<MudText Typo="Typo.body1" Class="mb-6">
|
||||||
@T("While loading the I18N data, an issue occurred:") @this.loadingIssue
|
While loading the I18N data, an issue occurred: @this.loadingIssue
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
|
else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.h6">
|
<MudText Typo="Typo.h6">
|
||||||
@this.AddedContentText
|
Added Content (@this.addedContent.Count entries)
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudTable Items="@this.addedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
<MudTable Items="@this.addedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
||||||
<ToolBarContent>
|
<ToolBarContent>
|
||||||
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<ColGroup>
|
<ColGroup>
|
||||||
<col/>
|
<col/>
|
||||||
<col/>
|
<col/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>@T("Key")</MudTh>
|
<MudTh>Key</MudTh>
|
||||||
<MudTh>@T("Text")</MudTh>
|
<MudTh>Text</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
@ -48,19 +48,19 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
|
|||||||
</MudTable>
|
</MudTable>
|
||||||
|
|
||||||
<MudText Typo="Typo.h6">
|
<MudText Typo="Typo.h6">
|
||||||
@this.RemovedContentText
|
Removed Content (@this.removedContent.Count entries)
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudTable Items="@this.removedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
<MudTable Items="@this.removedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
||||||
<ToolBarContent>
|
<ToolBarContent>
|
||||||
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<ColGroup>
|
<ColGroup>
|
||||||
<col/>
|
<col/>
|
||||||
<col/>
|
<col/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>@T("Key")</MudTh>
|
<MudTh>Key</MudTh>
|
||||||
<MudTh>@T("Text")</MudTh>
|
<MudTh>Text</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
@ -80,7 +80,7 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
|
|||||||
@if (this.selectedTargetLanguage is CommonLanguages.EN_US)
|
@if (this.selectedTargetLanguage is CommonLanguages.EN_US)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-6">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-6">
|
||||||
@T("Please note: neither is a translation needed nor performed for English (USA). Anyway, you might want to generate the related Lua code.")
|
Please note: neither is a translation needed nor performed for English (USA). Anyway, you might want to generate the related Lua code.
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -92,19 +92,19 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
|
|||||||
{
|
{
|
||||||
<hr style="width: 100%; border-width: 0.25ch;" class="mt-6 mb-6"/>
|
<hr style="width: 100%; border-width: 0.25ch;" class="mt-6 mb-6"/>
|
||||||
<MudText Typo="Typo.h6">
|
<MudText Typo="Typo.h6">
|
||||||
@this.LocalizedContentText
|
Localized Content (@this.localizedContent.Count entries of @this.NumTotalItems)
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudTable Items="@this.localizedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
<MudTable Items="@this.localizedContent" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
|
||||||
<ToolBarContent>
|
<ToolBarContent>
|
||||||
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<ColGroup>
|
<ColGroup>
|
||||||
<col/>
|
<col/>
|
||||||
<col/>
|
<col/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>@T("Key")</MudTh>
|
<MudTh>Key</MudTh>
|
||||||
<MudTh>@T("Text")</MudTh>
|
<MudTh>Text</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
|
@ -18,9 +18,12 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
{
|
{
|
||||||
public override Tools.Components Component => Tools.Components.I18N_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.I18N_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => T("Localization");
|
protected override string Title => "Localization";
|
||||||
|
|
||||||
protected override string Description => T("Translate MindWork AI Studio text content into another language.");
|
protected override string Description =>
|
||||||
|
"""
|
||||||
|
Translate MindWork AI Studio text content into another language.
|
||||||
|
""";
|
||||||
|
|
||||||
protected override string SystemPrompt =>
|
protected override string SystemPrompt =>
|
||||||
$"""
|
$"""
|
||||||
@ -56,7 +59,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
[
|
[
|
||||||
new ButtonData
|
new ButtonData
|
||||||
{
|
{
|
||||||
Text = T("Copy Lua code to clipboard"),
|
Text = "Copy Lua code to clipboard",
|
||||||
Icon = Icons.Material.Filled.Extension,
|
Icon = Icons.Material.Filled.Extension,
|
||||||
Color = Color.Default,
|
Color = Color.Default,
|
||||||
AsyncAction = async () => await this.RustService.CopyText2Clipboard(this.Snackbar, this.finalLuaCode.ToString()),
|
AsyncAction = async () => await this.RustService.CopyText2Clipboard(this.Snackbar, this.finalLuaCode.ToString()),
|
||||||
@ -64,7 +67,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
protected override string SubmitText => T("Localize AI Studio & generate the Lua code");
|
protected override string SubmitText => "Localize AI Studio & generate the Lua code";
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.LocalizeTextContent;
|
protected override Func<Task> SubmitAction => this.LocalizeTextContent;
|
||||||
|
|
||||||
@ -140,12 +143,12 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
this.localizationPossible = false;
|
this.localizationPossible = false;
|
||||||
if (PluginFactory.RunningPlugins.FirstOrDefault(n => n is PluginLanguage && n.Id == this.selectedLanguagePluginId) is not PluginLanguage comparisonPlugin)
|
if (PluginFactory.RunningPlugins.FirstOrDefault(n => n is PluginLanguage && n.Id == this.selectedLanguagePluginId) is not PluginLanguage comparisonPlugin)
|
||||||
{
|
{
|
||||||
this.loadingIssue = string.Format(T("Was not able to load the language plugin for comparison ({0}). Please select a valid, loaded & running language plugin."), this.selectedLanguagePluginId);
|
this.loadingIssue = $"Was not able to load the language plugin for comparison ({this.selectedLanguagePluginId}). Please select a valid, loaded & running language plugin.";
|
||||||
this.selectedLanguagePlugin = null;
|
this.selectedLanguagePlugin = null;
|
||||||
}
|
}
|
||||||
else if (comparisonPlugin.IETFTag != this.selectedTargetLanguage.ToIETFTag())
|
else if (comparisonPlugin.IETFTag != this.selectedTargetLanguage.ToIETFTag())
|
||||||
{
|
{
|
||||||
this.loadingIssue = string.Format(T("The selected language plugin for comparison uses the IETF tag '{0}' which does not match the selected target language '{1}'. Please select a valid, loaded & running language plugin which matches the target language."), comparisonPlugin.IETFTag, this.selectedTargetLanguage.ToIETFTag());
|
this.loadingIssue = $"The selected language plugin for comparison uses the IETF tag '{comparisonPlugin.IETFTag}' which does not match the selected target language '{this.selectedTargetLanguage.ToIETFTag()}'. Please select a valid, loaded & running language plugin which matches the target language.";
|
||||||
this.selectedLanguagePlugin = null;
|
this.selectedLanguagePlugin = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -162,7 +165,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
{
|
{
|
||||||
if (this.selectedLanguagePlugin is null)
|
if (this.selectedLanguagePlugin is null)
|
||||||
{
|
{
|
||||||
this.loadingIssue = T("Please select a language plugin for comparison.");
|
this.loadingIssue = "Please select a language plugin for comparison.";
|
||||||
this.localizationPossible = false;
|
this.localizationPossible = false;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
@ -199,7 +202,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NoPlugin:
|
case NoPlugin:
|
||||||
this.loadingIssue = T("Was not able to load the I18N plugin. Please check the plugin code.");
|
this.loadingIssue = "Was not able to load the I18N plugin. Please check the plugin code.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case { IsValid: false } plugin when plugin.Issues.Any():
|
case { IsValid: false } plugin when plugin.Issues.Any():
|
||||||
@ -238,7 +241,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
private string? ValidatingTargetLanguage(CommonLanguages language)
|
private string? ValidatingTargetLanguage(CommonLanguages language)
|
||||||
{
|
{
|
||||||
if(language == CommonLanguages.AS_IS)
|
if(language == CommonLanguages.AS_IS)
|
||||||
return T("Please select a target language.");
|
return "Please select a target language.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -246,19 +249,13 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
private string? ValidateCustomLanguage(string language)
|
private string? ValidateCustomLanguage(string language)
|
||||||
{
|
{
|
||||||
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
||||||
return T("Please provide a custom language.");
|
return "Please provide a custom language.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int NumTotalItems => (this.selectedLanguagePlugin?.Content.Count ?? 0) + this.addedContent.Count - this.removedContent.Count;
|
private int NumTotalItems => (this.selectedLanguagePlugin?.Content.Count ?? 0) + this.addedContent.Count - this.removedContent.Count;
|
||||||
|
|
||||||
private string AddedContentText => string.Format(T("Added Content ({0} entries)"), this.addedContent.Count);
|
|
||||||
|
|
||||||
private string RemovedContentText => string.Format(T("Removed Content ({0} entries)"), this.removedContent.Count);
|
|
||||||
|
|
||||||
private string LocalizedContentText => string.Format(T("Localized Content ({0} entries of {1})"), this.localizedContent.Count, this.NumTotalItems);
|
|
||||||
|
|
||||||
private async Task LocalizeTextContent()
|
private async Task LocalizeTextContent()
|
||||||
{
|
{
|
||||||
await this.form!.Validate();
|
await this.form!.Validate();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,15 @@
|
|||||||
@attribute [Route(Routes.ASSISTANT_JOB_POSTING)]
|
@attribute [Route(Routes.ASSISTANT_JOB_POSTING)]
|
||||||
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogJobPostings>
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogJobPostings>
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.inputCompanyName" Label="@T("(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.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="@T("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="@T("This is important to consider the legal framework of the country.")"/>
|
<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="@T("(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="@T("Mandatory information that your company requires for all job postings. This can include the company description, etc.")" />
|
<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="@T("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="@T("Describe what the person is supposed to do in the company. This might be just short bullet points.")" />
|
<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="@T("(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="@T("Describe what the person should bring to the table. 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="@T("(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="@T("Describe the responsibilities the person should take on in the company.")" />
|
<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="@T("(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.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="@T("(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.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="@T("(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"/>
|
<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="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
|
<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"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
@ -7,9 +7,13 @@ public partial class AssistantJobPostings : AssistantBaseCore<SettingsDialogJobP
|
|||||||
{
|
{
|
||||||
public override Tools.Components Component => Tools.Components.JOB_POSTING_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.JOB_POSTING_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => T("Job Posting");
|
protected override string Title => "Job Posting";
|
||||||
|
|
||||||
protected override string Description => T("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 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 =>
|
protected override string SystemPrompt =>
|
||||||
$"""
|
$"""
|
||||||
@ -43,7 +47,7 @@ public partial class AssistantJobPostings : AssistantBaseCore<SettingsDialogJobP
|
|||||||
|
|
||||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
protected override string SubmitText => T("Create the job posting");
|
protected override string SubmitText => "Create the job posting";
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.CreateJobPosting;
|
protected override Func<Task> SubmitAction => this.CreateJobPosting;
|
||||||
|
|
||||||
@ -122,7 +126,7 @@ public partial class AssistantJobPostings : AssistantBaseCore<SettingsDialogJobP
|
|||||||
private string? ValidateCustomLanguage(string language)
|
private string? ValidateCustomLanguage(string language)
|
||||||
{
|
{
|
||||||
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
|
||||||
return T("Please provide a custom target language.");
|
return "Please provide a custom target language.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -130,7 +134,7 @@ public partial class AssistantJobPostings : AssistantBaseCore<SettingsDialogJobP
|
|||||||
private string? ValidateJobDescription(string jobDescription)
|
private string? ValidateJobDescription(string jobDescription)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(jobDescription))
|
if(string.IsNullOrWhiteSpace(jobDescription))
|
||||||
return T("Please provide a job description.");
|
return "Please provide a job description.";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -138,7 +142,7 @@ public partial class AssistantJobPostings : AssistantBaseCore<SettingsDialogJobP
|
|||||||
private string? ValidateCountryLegalFramework(string countryLegalFramework)
|
private string? ValidateCountryLegalFramework(string countryLegalFramework)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(countryLegalFramework))
|
if(string.IsNullOrWhiteSpace(countryLegalFramework))
|
||||||
return T("Please provide the country where the job is posted (legal framework).");
|
return "Please provide the country where the job is posted (legal framework).";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<ReadWebContent @bind-Content="@this.inputLegalDocument" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions && this.SettingsManager.ConfigurationData.LegalCheck.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions && this.SettingsManager.ConfigurationData.LegalCheck.PreselectContentCleanerAgent)"/>
|
<ReadWebContent @bind-Content="@this.inputLegalDocument" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions && this.SettingsManager.ConfigurationData.LegalCheck.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions && this.SettingsManager.ConfigurationData.LegalCheck.PreselectContentCleanerAgent)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ReadFileContent @bind-FileContent="@this.inputLegalDocument"/>
|
<ReadPDFContent @bind-PDFContent="@this.inputLegalDocument"/>
|
||||||
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputLegalDocument" Validation="@this.ValidatingLegalDocument" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("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.inputLegalDocument" Validation="@this.ValidatingLegalDocument" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("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="@T("Your questions")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" 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="@T("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"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
@ -6,7 +6,7 @@
|
|||||||
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions && this.SettingsManager.ConfigurationData.TextSummarizer.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions && this.SettingsManager.ConfigurationData.TextSummarizer.PreselectContentCleanerAgent)"/>
|
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions && this.SettingsManager.ConfigurationData.TextSummarizer.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions && this.SettingsManager.ConfigurationData.TextSummarizer.PreselectContentCleanerAgent)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ReadFileContent @bind-FileContent="@this.inputText"/>
|
<ReadPDFContent @bind-PDFContent="@this.inputText"/>
|
||||||
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("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="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
|
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
|
||||||
<EnumSelection T="Complexity" NameFunc="@(complexity => complexity.Name())" @bind-Value="@this.selectedComplexity" Icon="@Icons.Material.Filled.Layers" Label="@T("Target complexity")" AllowOther="@true" @bind-OtherInput="@this.expertInField" OtherValue="Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS" LabelOther="@T("Your expertise")" ValidateOther="@this.ValidateExpertInField" />
|
<EnumSelection T="Complexity" NameFunc="@(complexity => complexity.Name())" @bind-Value="@this.selectedComplexity" Icon="@Icons.Material.Filled.Layers" Label="@T("Target complexity")" AllowOther="@true" @bind-OtherInput="@this.expertInField" OtherValue="Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS" LabelOther="@T("Your expertise")" ValidateOther="@this.ValidateExpertInField" />
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.Translation.PreselectOptions && this.SettingsManager.ConfigurationData.Translation.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.Translation.PreselectOptions && this.SettingsManager.ConfigurationData.Translation.PreselectContentCleanerAgent)"/>
|
<ReadWebContent @bind-Content="@this.inputText" ProviderSettings="@this.providerSettings" @bind-AgentIsRunning="@this.isAgentRunning" Preselect="@(this.SettingsManager.ConfigurationData.Translation.PreselectOptions && this.SettingsManager.ConfigurationData.Translation.PreselectWebContentReader)" PreselectContentCleanerAgent="@(this.SettingsManager.ConfigurationData.Translation.PreselectOptions && this.SettingsManager.ConfigurationData.Translation.PreselectContentCleanerAgent)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ReadFileContent @bind-FileContent="@this.inputText"/>
|
<ReadPDFContent @bind-PDFContent="@this.inputText"/>
|
||||||
|
|
||||||
<MudTextSwitch Label="@T("Live translation")" @bind-Value="@this.liveTranslation" LabelOn="@T("Live translation")" LabelOff="@T("No live translation")"/>
|
<MudTextSwitch Label="@T("Live translation")" @bind-Value="@this.liveTranslation" LabelOn="@T("Live translation")" LabelOff="@T("No live translation")"/>
|
||||||
@if (this.liveTranslation)
|
@if (this.liveTranslation)
|
||||||
{
|
{
|
||||||
|
@ -13,3 +13,51 @@ public enum ChatRole
|
|||||||
AI,
|
AI,
|
||||||
AGENT,
|
AGENT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extensions for the ChatRole enum.
|
||||||
|
/// </summary>
|
||||||
|
public static class ExtensionsChatRole
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the name of the role.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="role">The role.</param>
|
||||||
|
/// <returns>The name of the role.</returns>
|
||||||
|
public static string ToName(this ChatRole role) => role switch
|
||||||
|
{
|
||||||
|
ChatRole.SYSTEM => "System",
|
||||||
|
ChatRole.USER => "You",
|
||||||
|
ChatRole.AI => "AI",
|
||||||
|
|
||||||
|
_ => "Unknown",
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the color of the role.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="role">The role.</param>
|
||||||
|
/// <returns>The color of the role.</returns>
|
||||||
|
public static Color ToColor(this ChatRole role) => role switch
|
||||||
|
{
|
||||||
|
ChatRole.SYSTEM => Color.Info,
|
||||||
|
ChatRole.USER => Color.Primary,
|
||||||
|
ChatRole.AI => Color.Tertiary,
|
||||||
|
|
||||||
|
_ => Color.Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the icon of the role.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="role">The role.</param>
|
||||||
|
/// <returns>The icon of the role.</returns>
|
||||||
|
public static string ToIcon(this ChatRole role) => role switch
|
||||||
|
{
|
||||||
|
ChatRole.SYSTEM => Icons.Material.Filled.Settings,
|
||||||
|
ChatRole.USER => Icons.Material.Filled.Person,
|
||||||
|
ChatRole.AI => Icons.Material.Filled.AutoAwesome,
|
||||||
|
|
||||||
|
_ => Icons.Material.Filled.Help,
|
||||||
|
};
|
||||||
|
}
|
@ -1,75 +0,0 @@
|
|||||||
using AIStudio.Tools.PluginSystem;
|
|
||||||
|
|
||||||
namespace AIStudio.Chat;
|
|
||||||
|
|
||||||
public static class ChatRoleExtensions
|
|
||||||
{
|
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ChatRoleExtensions).Namespace, nameof(ChatRoleExtensions));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the name of the role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role.</param>
|
|
||||||
/// <returns>The name of the role.</returns>
|
|
||||||
public static string ToName(this ChatRole role) => role switch
|
|
||||||
{
|
|
||||||
ChatRole.SYSTEM => TB("System"),
|
|
||||||
ChatRole.USER => TB("You"),
|
|
||||||
ChatRole.AI => TB("AI"),
|
|
||||||
|
|
||||||
_ => TB("Unknown"),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the color of the role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role.</param>
|
|
||||||
/// <returns>The color of the role.</returns>
|
|
||||||
public static Color ToColor(this ChatRole role) => role switch
|
|
||||||
{
|
|
||||||
ChatRole.SYSTEM => Color.Info,
|
|
||||||
ChatRole.USER => Color.Primary,
|
|
||||||
ChatRole.AI => Color.Tertiary,
|
|
||||||
|
|
||||||
_ => Color.Error,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the icon of the role.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role.</param>
|
|
||||||
/// <returns>The icon of the role.</returns>
|
|
||||||
public static string ToIcon(this ChatRole role) => role switch
|
|
||||||
{
|
|
||||||
ChatRole.SYSTEM => Icons.Material.Filled.Settings,
|
|
||||||
ChatRole.USER => Icons.Material.Filled.Person,
|
|
||||||
ChatRole.AI => Icons.Material.Filled.AutoAwesome,
|
|
||||||
|
|
||||||
_ => Icons.Material.Filled.Help,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the specific name of the role for the chat template.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="role">The role.</param>
|
|
||||||
/// <returns>The name of the role.</returns>
|
|
||||||
public static string ToChatTemplateName(this ChatRole role) => role switch
|
|
||||||
{
|
|
||||||
ChatRole.SYSTEM => TB("System"),
|
|
||||||
ChatRole.USER => TB("User"),
|
|
||||||
ChatRole.AI => TB("Assistant"),
|
|
||||||
|
|
||||||
_ => TB("Unknown"),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Selects the next role for a chat template.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="currentRole">The current role.</param>
|
|
||||||
/// <returns>The next role for the chat template.</returns>
|
|
||||||
public static ChatRole SelectNextRoleForTemplate(this ChatRole currentRole) => currentRole switch
|
|
||||||
{
|
|
||||||
ChatRole.USER => ChatRole.AI,
|
|
||||||
_ => ChatRole.USER,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace AIStudio.Chat;
|
|
||||||
|
|
||||||
public static class ChatRoles
|
|
||||||
{
|
|
||||||
public static IEnumerable<ChatRole> ChatTemplateRoles()
|
|
||||||
{
|
|
||||||
yield return ChatRole.USER;
|
|
||||||
yield return ChatRole.AI;
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,11 +30,6 @@ public sealed record ChatThread
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SelectedProfile { get; set; } = string.Empty;
|
public string SelectedProfile { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the profile selected for the chat thread.
|
|
||||||
/// </summary>
|
|
||||||
public string SelectedChatTemplate { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data source options for this chat thread.
|
/// The data source options for this chat thread.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -75,8 +70,6 @@ public sealed record ChatThread
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ContentBlock> Blocks { get; init; } = [];
|
public List<ContentBlock> Blocks { get; init; } = [];
|
||||||
|
|
||||||
private bool allowProfile = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prepares the system prompt for the chat thread.
|
/// Prepares the system prompt for the chat thread.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,56 +84,16 @@ public sealed record ChatThread
|
|||||||
/// <returns>The prepared system prompt.</returns>
|
/// <returns>The prepared system prompt.</returns>
|
||||||
public string PrepareSystemPrompt(SettingsManager settingsManager, ChatThread chatThread, ILogger logger)
|
public string PrepareSystemPrompt(SettingsManager settingsManager, ChatThread chatThread, ILogger logger)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Use the information from the chat template, if provided. Otherwise, use the default system prompt
|
|
||||||
//
|
|
||||||
string systemPromptTextWithChatTemplate;
|
|
||||||
var logMessage = $"Using no chat template for chat thread '{chatThread.Name}'.";
|
|
||||||
if (string.IsNullOrWhiteSpace(chatThread.SelectedChatTemplate))
|
|
||||||
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!Guid.TryParse(chatThread.SelectedChatTemplate, out var chatTemplateId))
|
|
||||||
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(chatThread.SelectedChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE.Id || chatTemplateId == Guid.Empty)
|
|
||||||
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var chatTemplate = settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatThread.SelectedChatTemplate);
|
|
||||||
if(chatTemplate == null)
|
|
||||||
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logMessage = $"Using chat template '{chatTemplate.Name}' for chat thread '{chatThread.Name}'.";
|
|
||||||
this.allowProfile = chatTemplate.AllowProfileUsage;
|
|
||||||
systemPromptTextWithChatTemplate = chatTemplate.ToSystemPrompt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need a way to save the changed system prompt in our chat thread.
|
|
||||||
// Otherwise, the chat thread will always tell us that it is using the
|
|
||||||
// default system prompt:
|
|
||||||
chatThread = chatThread with { SystemPrompt = systemPromptTextWithChatTemplate };
|
|
||||||
|
|
||||||
logger.LogInformation(logMessage);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add augmented data, if available:
|
|
||||||
//
|
|
||||||
var isAugmentedDataAvailable = !string.IsNullOrWhiteSpace(chatThread.AugmentedData);
|
var isAugmentedDataAvailable = !string.IsNullOrWhiteSpace(chatThread.AugmentedData);
|
||||||
var systemPromptWithAugmentedData = isAugmentedDataAvailable switch
|
var systemPromptWithAugmentedData = isAugmentedDataAvailable switch
|
||||||
{
|
{
|
||||||
true => $"""
|
true => $"""
|
||||||
{systemPromptTextWithChatTemplate}
|
{chatThread.SystemPrompt}
|
||||||
|
|
||||||
{chatThread.AugmentedData}
|
{chatThread.AugmentedData}
|
||||||
""",
|
""",
|
||||||
|
|
||||||
false => systemPromptTextWithChatTemplate,
|
false => chatThread.SystemPrompt,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(isAugmentedDataAvailable)
|
if(isAugmentedDataAvailable)
|
||||||
@ -148,13 +101,12 @@ public sealed record ChatThread
|
|||||||
else
|
else
|
||||||
logger.LogInformation("No augmented data is available for the chat thread.");
|
logger.LogInformation("No augmented data is available for the chat thread.");
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add information from the profile if available and allowed:
|
// Prepare the system prompt:
|
||||||
//
|
//
|
||||||
string systemPromptText;
|
string systemPromptText;
|
||||||
logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
var logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
||||||
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile) || this.allowProfile is false)
|
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile))
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = systemPromptWithAugmentedData;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -18,24 +18,15 @@ public class ContentBlock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The content of the block.
|
/// The content of the block.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IContent? Content { get; set; }
|
public IContent? Content { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The role of the content block in the chat thread, e.g., user, AI, etc.
|
/// The role of the content block in the chat thread, e.g., user, AI, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ChatRole Role { get; set; } = ChatRole.NONE;
|
public ChatRole Role { get; init; } = ChatRole.NONE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should the content block be hidden from the user?
|
/// Should the content block be hidden from the user?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HideFromUser { get; init; }
|
public bool HideFromUser { get; set; }
|
||||||
|
|
||||||
public ContentBlock DeepClone(bool changeHideState = false, bool hideFromUser = true) => new()
|
|
||||||
{
|
|
||||||
Time = this.Time,
|
|
||||||
ContentType = this.ContentType,
|
|
||||||
Content = this.Content?.DeepClone(),
|
|
||||||
Role = this.Role,
|
|
||||||
HideFromUser = changeHideState ? hideFromUser : this.HideFromUser,
|
|
||||||
};
|
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
@using AIStudio.Tools
|
@using AIStudio.Tools
|
||||||
@using MudBlazor
|
@using MudBlazor
|
||||||
@using AIStudio.Components
|
|
||||||
@inherits AIStudio.Components.MSGComponentBase
|
@inherits AIStudio.Components.MSGComponentBase
|
||||||
<MudCard Class="@this.CardClasses" Outlined="@true">
|
<MudCard Class="@this.CardClasses" Outlined="@true">
|
||||||
<MudCardHeader>
|
<MudCardHeader>
|
||||||
@ -11,7 +10,7 @@
|
|||||||
</CardHeaderAvatar>
|
</CardHeaderAvatar>
|
||||||
<CardHeaderContent>
|
<CardHeaderContent>
|
||||||
<MudText Typo="Typo.body1">
|
<MudText Typo="Typo.body1">
|
||||||
@this.Role.ToName() (@this.Time.LocalDateTime)
|
@this.Role.ToName() (@this.Time)
|
||||||
</MudText>
|
</MudText>
|
||||||
</CardHeaderContent>
|
</CardHeaderContent>
|
||||||
<CardHeaderActions>
|
<CardHeaderActions>
|
||||||
@ -39,7 +38,9 @@
|
|||||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/>
|
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
<MudCopyClipboardButton Content="@this.Content" Type="@this.Type" Size="Size.Medium"/>
|
<MudTooltip Text="@T("Copies the content to the clipboard")" Placement="Placement.Bottom">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Color="Color.Default" OnClick="@this.CopyToClipboard"/>
|
||||||
|
</MudTooltip>
|
||||||
</CardHeaderActions>
|
</CardHeaderActions>
|
||||||
</MudCardHeader>
|
</MudCardHeader>
|
||||||
<MudCardContent>
|
<MudCardContent>
|
||||||
@ -66,12 +67,12 @@
|
|||||||
@if (this.Content.IsStreaming)
|
@if (this.Content.IsStreaming)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Style="white-space: pre-wrap;">
|
<MudText Typo="Typo.body1" Style="white-space: pre-wrap;">
|
||||||
@textContent.Text.RemoveThinkTags()
|
@textContent.Text
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudMarkdown Value="@textContent.Text.RemoveThinkTags().Trim()" Props="Markdown.DefaultConfig" Styling="@this.MarkdownStyling" />
|
<MudMarkdown Value="@textContent.Text" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo" CodeBlockTheme="@this.CodeColorPalette"/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
@ -60,6 +61,12 @@ public partial class ContentBlockComponent : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<bool> RegenerateEnabled { get; set; } = () => false;
|
public Func<bool> RegenerateEnabled { get; set; } = () => false;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private RustService RustService { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private ISnackbar Snackbar { get; init; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private IDialogService DialogService { get; init; } = null!;
|
private IDialogService DialogService { get; init; } = null!;
|
||||||
|
|
||||||
@ -109,15 +116,33 @@ public partial class ContentBlockComponent : MSGComponentBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copy this block's content to the clipboard.
|
||||||
|
/// </summary>
|
||||||
|
private async Task CopyToClipboard()
|
||||||
|
{
|
||||||
|
switch (this.Type)
|
||||||
|
{
|
||||||
|
case ContentType.TEXT:
|
||||||
|
var textContent = (ContentText) this.Content;
|
||||||
|
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.Snackbar.Add(T("Cannot copy this content type to clipboard!"), Severity.Error, config =>
|
||||||
|
{
|
||||||
|
config.Icon = Icons.Material.Filled.ContentCopy;
|
||||||
|
config.IconSize = Size.Large;
|
||||||
|
config.IconColor = Color.Error;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string CardClasses => $"my-2 rounded-lg {this.Class}";
|
private string CardClasses => $"my-2 rounded-lg {this.Class}";
|
||||||
|
|
||||||
private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default;
|
private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default;
|
||||||
|
|
||||||
private MudMarkdownStyling MarkdownStyling => new()
|
|
||||||
{
|
|
||||||
CodeBlock = { Theme = this.CodeColorPalette },
|
|
||||||
};
|
|
||||||
|
|
||||||
private async Task RemoveBlock()
|
private async Task RemoveBlock()
|
||||||
{
|
{
|
||||||
if (this.RemoveBlockFunc is null)
|
if (this.RemoveBlockFunc is null)
|
||||||
|
@ -13,11 +13,11 @@ public sealed class ContentImage : IContent, IImageSource
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool InitialRemoteWait { get; set; }
|
public bool InitialRemoteWait { get; set; } = false;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsStreaming { get; set; }
|
public bool IsStreaming { get; set; } = false;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@ -33,15 +33,6 @@ public sealed class ContentImage : IContent, IImageSource
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IContent DeepClone() => new ContentImage
|
|
||||||
{
|
|
||||||
Source = this.Source,
|
|
||||||
InitialRemoteWait = this.InitialRemoteWait,
|
|
||||||
IsStreaming = this.IsStreaming,
|
|
||||||
SourceType = this.SourceType,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -120,21 +120,11 @@ public sealed class ContentText : IContent
|
|||||||
this.IsStreaming = false;
|
this.IsStreaming = false;
|
||||||
}, token);
|
}, token);
|
||||||
|
|
||||||
this.Text = this.Text.RemoveThinkTags().Trim();
|
|
||||||
|
|
||||||
// Inform the UI that the streaming is done:
|
// Inform the UI that the streaming is done:
|
||||||
await this.StreamingDone();
|
await this.StreamingDone();
|
||||||
return chatThread;
|
return chatThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IContent DeepClone() => new ContentText
|
|
||||||
{
|
|
||||||
Text = this.Text,
|
|
||||||
InitialRemoteWait = this.InitialRemoteWait,
|
|
||||||
IsStreaming = this.IsStreaming,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -43,12 +43,6 @@ public interface IContent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
|
public Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a deep copy
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The copy</returns>
|
|
||||||
public IContent DeepClone();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the corresponding ERI content type.
|
/// Returns the corresponding ERI content type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
namespace AIStudio.Chat;
|
|
||||||
|
|
||||||
public static class StringExtensions
|
|
||||||
{
|
|
||||||
public static string RemoveThinkTags(this string input)
|
|
||||||
{
|
|
||||||
const string OPEN_TAG = "<think>";
|
|
||||||
const string CLOSE_TAG = "</think>";
|
|
||||||
if (string.IsNullOrWhiteSpace(input) || !input.StartsWith(OPEN_TAG, StringComparison.Ordinal))
|
|
||||||
return input;
|
|
||||||
|
|
||||||
var endIndex = input.IndexOf(CLOSE_TAG, StringComparison.Ordinal);
|
|
||||||
if (endIndex == -1)
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
return input[(endIndex + CLOSE_TAG.Length)..];
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,12 +13,6 @@ public partial class Changelog
|
|||||||
|
|
||||||
public static readonly Log[] LOGS =
|
public static readonly Log[] LOGS =
|
||||||
[
|
[
|
||||||
new (225, "v0.9.50, build 225 (2025-08-10 16:40 UTC)", "v0.9.50.md"),
|
|
||||||
new (224, "v0.9.49, build 224 (2025-07-02 12:12 UTC)", "v0.9.49.md"),
|
|
||||||
new (223, "v0.9.48, build 223 (2025-06-10 13:15 UTC)", "v0.9.48.md"),
|
|
||||||
new (222, "v0.9.47, build 222 (2025-06-02 18:25 UTC)", "v0.9.47.md"),
|
|
||||||
new (221, "v0.9.46, build 221 (2025-06-01 19:19 UTC)", "v0.9.46.md"),
|
|
||||||
new (220, "v0.9.45, build 220 (2025-05-25 13:56 UTC)", "v0.9.45.md"),
|
|
||||||
new (219, "v0.9.44, build 219 (2025-05-18 19:33 UTC)", "v0.9.44.md"),
|
new (219, "v0.9.44, build 219 (2025-05-18 19:33 UTC)", "v0.9.44.md"),
|
||||||
new (218, "v0.9.43, build 218 (2025-05-11 17:22 UTC)", "v0.9.43.md"),
|
new (218, "v0.9.43, build 218 (2025-05-11 17:22 UTC)", "v0.9.43.md"),
|
||||||
new (217, "v0.9.42, build 217 (2025-05-04 13:03 UTC)", "v0.9.42.md"),
|
new (217, "v0.9.42, build 217 (2025-05-04 13:03 UTC)", "v0.9.42.md"),
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
<MudMarkdown Value="@this.LogContent" Props="Markdown.DefaultConfig"/>
|
<MudMarkdown Value="@this.LogContent" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/>
|
@ -81,8 +81,6 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ChatTemplateSelection CanChatThreadBeUsedForTemplate="@this.CanThreadBeSaved" CurrentChatThread="@this.ChatThread" CurrentChatTemplate="@this.currentChatTemplate" CurrentChatTemplateChanged="@this.ChatTemplateWasChanged"/>
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="@T("Delete this chat & start a new one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
<MudTooltip Text="@T("Delete this chat & start a new one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||||
@ -109,7 +107,7 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" Disabled="@(!this.currentChatTemplate.AllowProfileUsage)" DisabledText="@T("Profile usage is disabled according to your chat template settings.")"/>
|
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged"/>
|
||||||
|
|
||||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
private DataSourceSelection? dataSourceSelectionComponent;
|
private DataSourceSelection? dataSourceSelectionComponent;
|
||||||
private DataSourceOptions earlyDataSourceOptions = new();
|
private DataSourceOptions earlyDataSourceOptions = new();
|
||||||
private Profile currentProfile = Profile.NO_PROFILE;
|
private Profile currentProfile = Profile.NO_PROFILE;
|
||||||
private ChatTemplate currentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
|
|
||||||
private bool hasUnsavedChanges;
|
private bool hasUnsavedChanges;
|
||||||
private bool mustScrollToBottomAfterRender;
|
private bool mustScrollToBottomAfterRender;
|
||||||
private InnerScrolling scrollingArea = null!;
|
private InnerScrolling scrollingArea = null!;
|
||||||
@ -78,10 +77,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
// Get the preselected profile:
|
// Get the preselected profile:
|
||||||
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
|
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
|
||||||
|
|
||||||
// Get the preselected chat template:
|
|
||||||
this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(Tools.Components.CHAT);
|
|
||||||
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for deferred messages of the kind 'SEND_TO_CHAT',
|
// Check for deferred messages of the kind 'SEND_TO_CHAT',
|
||||||
// aka the user sends an assistant result to the chat:
|
// aka the user sends an assistant result to the chat:
|
||||||
@ -273,7 +268,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanThreadBeSaved => this.ChatThread is not null && this.ChatThread.Blocks.Any(b => !b.HideFromUser);
|
private bool CanThreadBeSaved => this.ChatThread is not null && this.ChatThread.Blocks.Count > 0;
|
||||||
|
|
||||||
private string TooltipAddChatToWorkspace => string.Format(T("Start new chat in workspace '{0}'"), this.currentWorkspaceName);
|
private string TooltipAddChatToWorkspace => string.Format(T("Start new chat in workspace '{0}'"), this.currentWorkspaceName);
|
||||||
|
|
||||||
@ -324,18 +319,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ChatTemplateWasChanged(ChatTemplate chatTemplate)
|
|
||||||
{
|
|
||||||
this.currentChatTemplate = chatTemplate;
|
|
||||||
if(!string.IsNullOrWhiteSpace(this.currentChatTemplate.PredefinedUserPrompt))
|
|
||||||
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
|
|
||||||
|
|
||||||
if(this.ChatThread is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await this.StartNewChat(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IReadOnlyList<DataSourceAgentSelected> GetAgentSelectedDataSources()
|
private IReadOnlyList<DataSourceAgentSelected> GetAgentSelectedDataSources()
|
||||||
{
|
{
|
||||||
if (this.ChatThread is null)
|
if (this.ChatThread is null)
|
||||||
@ -430,14 +413,13 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
SelectedProvider = this.Provider.Id,
|
SelectedProvider = this.Provider.Id,
|
||||||
SelectedProfile = this.currentProfile.Id,
|
SelectedProfile = this.currentProfile.Id,
|
||||||
SelectedChatTemplate = this.currentChatTemplate.Id,
|
|
||||||
SystemPrompt = SystemPrompts.DEFAULT,
|
SystemPrompt = SystemPrompts.DEFAULT,
|
||||||
WorkspaceId = this.currentWorkspaceId,
|
WorkspaceId = this.currentWorkspaceId,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
DataSourceOptions = this.earlyDataSourceOptions,
|
DataSourceOptions = this.earlyDataSourceOptions,
|
||||||
Name = this.ExtractThreadName(this.userInput),
|
Name = this.ExtractThreadName(this.userInput),
|
||||||
Seed = this.RNG.Next(),
|
Seed = this.RNG.Next(),
|
||||||
Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
Blocks = [],
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
||||||
@ -448,15 +430,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
if (string.IsNullOrWhiteSpace(this.ChatThread.Name))
|
if (string.IsNullOrWhiteSpace(this.ChatThread.Name))
|
||||||
this.ChatThread.Name = this.ExtractThreadName(this.userInput);
|
this.ChatThread.Name = this.ExtractThreadName(this.userInput);
|
||||||
|
|
||||||
// Update provider, profile and chat template:
|
// Update provider and profile:
|
||||||
this.ChatThread.SelectedProvider = this.Provider.Id;
|
this.ChatThread.SelectedProvider = this.Provider.Id;
|
||||||
this.ChatThread.SelectedProfile = this.currentProfile.Id;
|
this.ChatThread.SelectedProfile = this.currentProfile.Id;
|
||||||
|
|
||||||
//
|
|
||||||
// Remark: We do not update the chat template here
|
|
||||||
// because the chat template is only used when starting a new chat.
|
|
||||||
// Updating the chat template afterward is not supported.
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var time = DateTimeOffset.Now;
|
var time = DateTimeOffset.Now;
|
||||||
@ -509,9 +485,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Clear the input field:
|
// Clear the input field:
|
||||||
await this.inputField.FocusAsync();
|
|
||||||
this.userInput = string.Empty;
|
this.userInput = string.Empty;
|
||||||
await this.inputField.BlurAsync();
|
|
||||||
|
|
||||||
// Enable the stream state for the chat component:
|
// Enable the stream state for the chat component:
|
||||||
this.isStreaming = true;
|
this.isStreaming = true;
|
||||||
@ -669,18 +643,15 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
SelectedProvider = this.Provider.Id,
|
SelectedProvider = this.Provider.Id,
|
||||||
SelectedProfile = this.currentProfile.Id,
|
SelectedProfile = this.currentProfile.Id,
|
||||||
SelectedChatTemplate = this.currentChatTemplate.Id,
|
|
||||||
SystemPrompt = SystemPrompts.DEFAULT,
|
SystemPrompt = SystemPrompts.DEFAULT,
|
||||||
WorkspaceId = this.currentWorkspaceId,
|
WorkspaceId = this.currentWorkspaceId,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
Name = string.Empty,
|
Name = string.Empty,
|
||||||
Seed = this.RNG.Next(),
|
Seed = this.RNG.Next(),
|
||||||
Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
Blocks = [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
|
|
||||||
|
|
||||||
// Now, we have to reset the data source options as well:
|
// Now, we have to reset the data source options as well:
|
||||||
this.ApplyStandardDataSourceOptions();
|
this.ApplyStandardDataSourceOptions();
|
||||||
|
|
||||||
@ -783,7 +754,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
var chatProvider = this.ChatThread?.SelectedProvider;
|
var chatProvider = this.ChatThread?.SelectedProvider;
|
||||||
var chatProfile = this.ChatThread?.SelectedProfile;
|
var chatProfile = this.ChatThread?.SelectedProfile;
|
||||||
var chatChatTemplate = this.ChatThread?.SelectedChatTemplate;
|
|
||||||
|
|
||||||
switch (this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior)
|
switch (this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior)
|
||||||
{
|
{
|
||||||
@ -811,13 +781,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
if(this.currentProfile == default)
|
if(this.currentProfile == default)
|
||||||
this.currentProfile = Profile.NO_PROFILE;
|
this.currentProfile = Profile.NO_PROFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to select the chat template:
|
|
||||||
if (!string.IsNullOrWhiteSpace(chatChatTemplate))
|
|
||||||
{
|
|
||||||
var selectedTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate);
|
|
||||||
this.currentChatTemplate = selectedTemplate ?? ChatTemplate.NO_CHAT_TEMPLATE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ToggleWorkspaceOverlay()
|
private async Task ToggleWorkspaceOverlay()
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
@using AIStudio.Settings
|
|
||||||
@inherits MSGComponentBase
|
|
||||||
|
|
||||||
<MudTooltip Placement="Placement.Top" Text="@T("Start a new chat with a chat template")">
|
|
||||||
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="@Origin.BottomLeft" Class="@this.MarginClass">
|
|
||||||
<ActivatorContent>
|
|
||||||
@if (this.CurrentChatTemplate != ChatTemplate.NO_CHAT_TEMPLATE)
|
|
||||||
{
|
|
||||||
<MudButton IconSize="Size.Large" StartIcon="@Icons.Material.Filled.RateReview" IconColor="Color.Default">
|
|
||||||
@this.CurrentChatTemplate.Name
|
|
||||||
</MudButton>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.RateReview" />
|
|
||||||
}
|
|
||||||
</ActivatorContent>
|
|
||||||
<ChildContent>
|
|
||||||
<MudMenuItem Icon="@Icons.Material.Filled.Settings" Label="@T("Manage your templates")" OnClick="async () => await this.OpenSettingsDialog()" />
|
|
||||||
<MudDivider/>
|
|
||||||
<MudMenuItem Icon="@Icons.Material.Filled.AddComment" Label="@T("Create template from current chat")" OnClick="async () => await this.CreateNewChatTemplateFromChat()" Disabled="@(!this.CanChatThreadBeUsedForTemplate)"/>
|
|
||||||
<MudDivider/>
|
|
||||||
@foreach (var chatTemplate in this.SettingsManager.ConfigurationData.ChatTemplates.GetAllChatTemplates())
|
|
||||||
{
|
|
||||||
<MudMenuItem Icon="@Icons.Material.Filled.RateReview" OnClick="async () => await this.SelectionChanged(chatTemplate)">
|
|
||||||
@chatTemplate.Name
|
|
||||||
</MudMenuItem>
|
|
||||||
}
|
|
||||||
</ChildContent>
|
|
||||||
</MudMenu>
|
|
||||||
</MudTooltip>
|
|
@ -1,56 +0,0 @@
|
|||||||
using AIStudio.Chat;
|
|
||||||
using AIStudio.Dialogs.Settings;
|
|
||||||
using AIStudio.Settings;
|
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class ChatTemplateSelection : MSGComponentBase
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public ChatTemplate CurrentChatTemplate { get; set; } = ChatTemplate.NO_CHAT_TEMPLATE;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public bool CanChatThreadBeUsedForTemplate { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public ChatThread? CurrentChatThread { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<ChatTemplate> CurrentChatTemplateChanged { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string MarginLeft { get; set; } = "ml-1";
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string MarginRight { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private IDialogService DialogService { get; init; } = null!;
|
|
||||||
|
|
||||||
private string MarginClass => $"{this.MarginLeft} {this.MarginRight}";
|
|
||||||
|
|
||||||
private async Task SelectionChanged(ChatTemplate chatTemplate)
|
|
||||||
{
|
|
||||||
this.CurrentChatTemplate = chatTemplate;
|
|
||||||
await this.CurrentChatTemplateChanged.InvokeAsync(chatTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task OpenSettingsDialog()
|
|
||||||
{
|
|
||||||
var dialogParameters = new DialogParameters();
|
|
||||||
await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CreateNewChatTemplateFromChat()
|
|
||||||
{
|
|
||||||
var dialogParameters = new DialogParameters<SettingsDialogChatTemplate>
|
|
||||||
{
|
|
||||||
{ x => x.CreateTemplateFromExistingChatThread, true },
|
|
||||||
{ x => x.ExistingChatThread, this.CurrentChatThread }
|
|
||||||
};
|
|
||||||
await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
@if (!this.IsInline)
|
|
||||||
{
|
|
||||||
@if (this.ParentTabs is null)
|
|
||||||
{
|
|
||||||
<MudPaper Class="code-block no-elevation" Style="@this.BlockPadding">
|
|
||||||
<pre>
|
|
||||||
<code>
|
|
||||||
@this.ChildContent
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</MudPaper>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<span class="inline-code-block">
|
|
||||||
<kbd>
|
|
||||||
@this.ChildContent
|
|
||||||
</kbd>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class CodeBlock : ComponentBase
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public RenderFragment? ChildContent { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string? Title { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public bool IsInline { get; set; }
|
|
||||||
|
|
||||||
[CascadingParameter]
|
|
||||||
public CodeTabs? ParentTabs { get; set; }
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
if (this.ParentTabs is not null && this.Title is not null)
|
|
||||||
{
|
|
||||||
void BlockSelf(RenderTreeBuilder builder)
|
|
||||||
{
|
|
||||||
builder.OpenComponent<CodeBlock>(0);
|
|
||||||
builder.AddAttribute(1, "Title", this.Title);
|
|
||||||
builder.AddAttribute(2, "ChildContent", this.ChildContent);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ParentTabs.RegisterBlock(this.Title, BlockSelf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string BlockPadding => this.ParentTabs is null ? "padding: 16px !important;" : "padding: 8px !important";
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
<MudTabs ActivePanelIndex="this.SelectedIndex" ActivePanelIndexChanged="async idx => await this.TabChanged(idx)" PanelClass="code-block mt-1" MinimumTabWidth="30px" Class="mt-2">
|
|
||||||
@foreach (var block in this.blocks)
|
|
||||||
{
|
|
||||||
<MudTabPanel Text="@block.Title">
|
|
||||||
@block.Fragment
|
|
||||||
</MudTabPanel>
|
|
||||||
}
|
|
||||||
</MudTabs>
|
|
||||||
<CascadingValue Value="this">
|
|
||||||
@this.ChildContent
|
|
||||||
</CascadingValue>
|
|
@ -1,42 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class CodeTabs : ComponentBase
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public RenderFragment? ChildContent { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public int SelectedIndex { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<int> SelectedIndexChanged { get; set; }
|
|
||||||
|
|
||||||
private readonly List<CodeTabItem> blocks = new();
|
|
||||||
|
|
||||||
internal void RegisterBlock(string title, RenderFragment fragment)
|
|
||||||
{
|
|
||||||
this.blocks.Add(new CodeTabItem
|
|
||||||
{
|
|
||||||
Title = title,
|
|
||||||
Fragment = fragment,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CodeTabItem
|
|
||||||
{
|
|
||||||
public string Title { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
public RenderFragment Fragment { get; init; } = null!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task TabChanged(int index)
|
|
||||||
{
|
|
||||||
this.SelectedIndex = index;
|
|
||||||
await this.SelectedIndexChanged.InvokeAsync(index);
|
|
||||||
await this.InvokeAsync(this.StateHasChanged);
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,7 +44,7 @@ public partial class ConfidenceInfo : MSGComponentBase
|
|||||||
{
|
{
|
||||||
var index = 0;
|
var index = 0;
|
||||||
foreach (var source in this.currentConfidence.Sources)
|
foreach (var source in this.currentConfidence.Sources)
|
||||||
yield return (string.Format(T("Source {0}"), ++index), source);
|
yield return ($"Source {++index}", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetCurrentConfidenceColor() => $"color: {this.currentConfidence.Level.GetColor(this.SettingsManager)};";
|
private string GetCurrentConfidenceColor() => $"color: {this.currentConfidence.Level.GetColor(this.SettingsManager)};";
|
||||||
|
@ -1,23 +1 @@
|
|||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
@if (this.Body is not null)
|
|
||||||
{
|
|
||||||
@if (!this.Disabled() && this.IsLocked())
|
|
||||||
{
|
|
||||||
<MudField Label="@this.Label" Variant="@this.Variant" Underline="false" HelperText="@this.OptionHelp" Class="@this.Classes" InnerPadding="false">
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.FlexStart" Wrap="Wrap.NoWrap" StretchItems="this.StretchItems">
|
|
||||||
@* MudTooltip.RootStyle is set as a workaround for issue -> https://github.com/MudBlazor/MudBlazor/issues/10882 *@
|
|
||||||
<MudTooltip Text="@TB("This feature is managed by your organization and has therefore been disabled.")" Arrow="true" Placement="Placement.Right" RootStyle="display:inline-flex;">
|
|
||||||
<MudIcon Icon="@Icons.Material.Filled.Lock" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
|
|
||||||
</MudTooltip>
|
|
||||||
@this.Body
|
|
||||||
</MudStack>
|
|
||||||
</MudField>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<MudField Label="@this.Label" Variant="@this.Variant" Underline="false" HelperText="@this.OptionHelp" Class="@this.Classes" InnerPadding="false">
|
|
||||||
@this.Body
|
|
||||||
</MudField>
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ namespace AIStudio.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A base class for configuration options.
|
/// A base class for configuration options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract partial class ConfigurationBase : MSGComponentBase
|
public partial class ConfigurationBase : MSGComponentBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The description of the option, i.e., the name. Should be
|
/// The description of the option, i.e., the name. Should be
|
||||||
@ -26,42 +26,7 @@ public abstract partial class ConfigurationBase : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<bool> Disabled { get; set; } = () => false;
|
public Func<bool> Disabled { get; set; } = () => false;
|
||||||
|
|
||||||
/// <summary>
|
protected const string MARGIN_CLASS = "mb-6";
|
||||||
/// Is the option locked by a configuration plugin?
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public Func<bool> IsLocked { get; set; } = () => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should the option be stretched to fill the available space?
|
|
||||||
/// </summary>
|
|
||||||
protected abstract bool Stretch { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The CSS class to apply to the component.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual string GetClassForBase => string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The visual variant of the option.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual Variant Variant => Variant.Text;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The label to display for the option.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual string Label => string.Empty;
|
|
||||||
|
|
||||||
private StretchItems StretchItems => this.Stretch ? StretchItems.End : StretchItems.None;
|
|
||||||
|
|
||||||
protected bool IsDisabled => this.Disabled() || this.IsLocked();
|
|
||||||
|
|
||||||
private string Classes => $"{this.GetClassForBase} {MARGIN_CLASS}";
|
|
||||||
|
|
||||||
private protected virtual RenderFragment? Body => null;
|
|
||||||
|
|
||||||
private const string MARGIN_CLASS = "mb-6";
|
|
||||||
|
|
||||||
protected static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
protected static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
@ -75,8 +40,6 @@ public abstract partial class ConfigurationBase : MSGComponentBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private string TB(string fallbackEN) => this.T(fallbackEN, typeof(ConfigurationBase).Namespace, nameof(ConfigurationBase));
|
|
||||||
|
|
||||||
protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
#region Overrides of MSGComponentBase
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public abstract class ConfigurationBaseCore : ConfigurationBase
|
|
||||||
{
|
|
||||||
private protected sealed override RenderFragment Body => this.BuildRenderTree;
|
|
||||||
|
|
||||||
// Allow content to be provided by a .razor file but without
|
|
||||||
// overriding the content of the base class
|
|
||||||
protected new virtual void BuildRenderTree(RenderTreeBuilder builder)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
@using AIStudio.Settings
|
@using AIStudio.Settings
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<ConfigurationSelect IsLocked="this.IsLocked" Disabled="this.Disabled" OptionDescription="@T("Select a minimum confidence level")" SelectedValue="@this.FilteredSelectedValue" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData(this.SettingsManager, this.RestrictToGlobalMinimumConfidence)" SelectionUpdate="@this.SelectionUpdate" OptionHelp="@T("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.")"/>
|
<ConfigurationSelect Disabled="@this.Disabled" OptionDescription="@T("Select a minimum confidence level")" SelectedValue="@this.FilteredSelectedValue" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData(this.SettingsManager, this.RestrictToGlobalMinimumConfidence)" SelectionUpdate="@this.SelectionUpdate" OptionHelp="@T("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.")"/>
|
@ -18,18 +18,18 @@ public partial class ConfigurationMinConfidenceSelection : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<ConfidenceLevel> SelectionUpdate { get; set; } = _ => { };
|
public Action<ConfidenceLevel> SelectionUpdate { get; set; } = _ => { };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the selection component disabled?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Func<bool> Disabled { get; set; } = () => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Boolean value indicating whether the selection is restricted to a global minimum confidence level.
|
/// Boolean value indicating whether the selection is restricted to a global minimum confidence level.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public bool RestrictToGlobalMinimumConfidence { get; set; }
|
public bool RestrictToGlobalMinimumConfidence { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<bool> Disabled { get; set; } = () => false;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<bool> IsLocked { get; set; } = () => false;
|
|
||||||
|
|
||||||
private ConfidenceLevel FilteredSelectedValue()
|
private ConfidenceLevel FilteredSelectedValue()
|
||||||
{
|
{
|
||||||
if (this.SelectedValue() is ConfidenceLevel.NONE)
|
if (this.SelectedValue() is ConfidenceLevel.NONE)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@inherits ConfigurationBaseCore
|
@inherits ConfigurationBase
|
||||||
@typeparam TData
|
@typeparam TData
|
||||||
|
|
||||||
<MudSelectExtended
|
<MudSelectExtended
|
||||||
@ -7,10 +7,12 @@
|
|||||||
MultiSelectionTextFunc="@this.GetMultiSelectionText"
|
MultiSelectionTextFunc="@this.GetMultiSelectionText"
|
||||||
SelectedValues="@this.SelectedValues()"
|
SelectedValues="@this.SelectedValues()"
|
||||||
Strict="@true"
|
Strict="@true"
|
||||||
Disabled="@this.IsDisabled"
|
Disabled="@this.Disabled()"
|
||||||
Margin="Margin.Dense"
|
Margin="Margin.Dense"
|
||||||
Class="rounded-lg"
|
Label="@this.OptionDescription"
|
||||||
Underline="false"
|
Class="@GetClass"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
HelperText="@this.OptionHelp"
|
||||||
SelectedValuesChanged="@this.OptionChanged">
|
SelectedValuesChanged="@this.OptionChanged">
|
||||||
@foreach (var data in this.Data)
|
@foreach (var data in this.Data)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ namespace AIStudio.Components;
|
|||||||
/// Configuration component for selecting many values from a list.
|
/// Configuration component for selecting many values from a list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TData">The type of the value to select.</typeparam>
|
/// <typeparam name="TData">The type of the value to select.</typeparam>
|
||||||
public partial class ConfigurationMultiSelect<TData> : ConfigurationBaseCore
|
public partial class ConfigurationMultiSelect<TData> : ConfigurationBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data to select from.
|
/// The data to select from.
|
||||||
@ -28,17 +28,6 @@ public partial class ConfigurationMultiSelect<TData> : ConfigurationBaseCore
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<HashSet<TData>> SelectionUpdate { get; set; } = _ => { };
|
public Action<HashSet<TData>> SelectionUpdate { get; set; } = _ => { };
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => true;
|
|
||||||
|
|
||||||
protected override Variant Variant => Variant.Outlined;
|
|
||||||
|
|
||||||
protected override string Label => this.OptionDescription;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private async Task OptionChanged(IEnumerable<TData?>? updatedValues)
|
private async Task OptionChanged(IEnumerable<TData?>? updatedValues)
|
||||||
{
|
{
|
||||||
if(updatedValues is null)
|
if(updatedValues is null)
|
||||||
@ -50,6 +39,8 @@ public partial class ConfigurationMultiSelect<TData> : ConfigurationBaseCore
|
|||||||
await this.InformAboutChange();
|
await this.InformAboutChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetClass => $"{MARGIN_CLASS} rounded-lg";
|
||||||
|
|
||||||
private string GetMultiSelectionText(List<TData?>? selectedValues)
|
private string GetMultiSelectionText(List<TData?>? selectedValues)
|
||||||
{
|
{
|
||||||
if(selectedValues is null || selectedValues.Count == 0)
|
if(selectedValues is null || selectedValues.Count == 0)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
@inherits ConfigurationBaseCore
|
@inherits ConfigurationBase
|
||||||
|
|
||||||
<MudSwitch T="bool" Disabled="@this.IsDisabled" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
|
<MudField Disabled="@this.Disabled()" Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
|
||||||
|
<MudSwitch T="bool" Disabled="@this.Disabled()" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
|
||||||
@(this.State() ? this.LabelOn : this.LabelOff)
|
@(this.State() ? this.LabelOn : this.LabelOff)
|
||||||
</MudSwitch>
|
</MudSwitch>
|
||||||
|
</MudField>
|
@ -5,7 +5,7 @@ namespace AIStudio.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration component for any boolean option.
|
/// Configuration component for any boolean option.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ConfigurationOption : ConfigurationBaseCore
|
public partial class ConfigurationOption : ConfigurationBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Text to display when the option is true.
|
/// Text to display when the option is true.
|
||||||
@ -31,19 +31,6 @@ public partial class ConfigurationOption : ConfigurationBaseCore
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<bool> StateUpdate { get; set; } = _ => { };
|
public Action<bool> StateUpdate { get; set; } = _ => { };
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override Variant Variant => Variant.Outlined;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override string Label => this.OptionDescription;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private async Task OptionChanged(bool updatedState)
|
private async Task OptionChanged(bool updatedState)
|
||||||
{
|
{
|
||||||
this.StateUpdate(updatedState);
|
this.StateUpdate(updatedState);
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<ConfigurationSelect IsLocked="@this.IsLocked" OptionDescription="@T("Preselected provider")" Disabled="@(() => this.Disabled())" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
|
<ConfigurationSelect OptionDescription="@T("Preselected provider")" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
|
@ -20,17 +20,27 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>();
|
public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the selection component disabled?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Func<bool> Disabled { get; set; } = () => false;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string> HelpText { get; set; } = () => TB("Select a provider that is preselected.");
|
public Func<string> HelpText { get; set; } = () => TB("Select a provider that is preselected.");
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Tools.Components Component { get; set; } = Tools.Components.NONE;
|
public Tools.Components Component { get; set; } = Tools.Components.NONE;
|
||||||
|
|
||||||
[Parameter]
|
#region Overrides of ComponentBase
|
||||||
public Func<bool> Disabled { get; set; } = () => false;
|
|
||||||
|
|
||||||
[Parameter]
|
protected override async Task OnParametersSetAsync()
|
||||||
public Func<bool> IsLocked { get; set; } = () => false;
|
{
|
||||||
|
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
|
||||||
|
await base.OnParametersSetAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
|
||||||
private IEnumerable<ConfigurationSelectData<string>> FilteredData()
|
private IEnumerable<ConfigurationSelectData<string>> FilteredData()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
@inherits ConfigurationBaseCore
|
@inherits ConfigurationBase
|
||||||
@typeparam TConfig
|
@typeparam T
|
||||||
|
|
||||||
<MudSelect T="TConfig" Value="@this.SelectedValue()" Strict="@true" ShrinkLabel="@true" Disabled="@this.IsDisabled" Margin="Margin.Dense" Class="rounded-lg mb-0" Underline="false" ValueChanged="@this.OptionChanged">
|
<MudSelect T="T" Value="@this.SelectedValue()" Strict="@true" ShrinkLabel="@true" Disabled="@this.Disabled()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="@this.OptionChanged">
|
||||||
@foreach (var data in this.Data)
|
@foreach (var data in this.Data)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@data.Value">
|
<MudSelectItem Value="@data.Value">
|
||||||
|
@ -7,43 +7,33 @@ namespace AIStudio.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration component for selecting a value from a list.
|
/// Configuration component for selecting a value from a list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TConfig">The type of the value to select.</typeparam>
|
/// <typeparam name="T">The type of the value to select.</typeparam>
|
||||||
public partial class ConfigurationSelect<TConfig> : ConfigurationBaseCore
|
public partial class ConfigurationSelect<T> : ConfigurationBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data to select from.
|
/// The data to select from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<ConfigurationSelectData<TConfig>> Data { get; set; } = [];
|
public IEnumerable<ConfigurationSelectData<T>> Data { get; set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The selected value.
|
/// The selected value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<TConfig> SelectedValue { get; set; } = () => default!;
|
public Func<T> SelectedValue { get; set; } = () => default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An action that is called when the selection changes.
|
/// An action that is called when the selection changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<TConfig> SelectionUpdate { get; set; } = _ => { };
|
public Action<T> SelectionUpdate { get; set; } = _ => { };
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
private async Task OptionChanged(T updatedValue)
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override string Label => this.OptionDescription;
|
|
||||||
|
|
||||||
protected override Variant Variant => Variant.Outlined;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private async Task OptionChanged(TConfig updatedValue)
|
|
||||||
{
|
{
|
||||||
this.SelectionUpdate(updatedValue);
|
this.SelectionUpdate(updatedValue);
|
||||||
await this.SettingsManager.StoreSettings();
|
await this.SettingsManager.StoreSettings();
|
||||||
await this.InformAboutChange();
|
await this.InformAboutChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetClass => $"{MARGIN_CLASS} rounded-lg";
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
@typeparam T
|
@typeparam T
|
||||||
@inherits ConfigurationBaseCore
|
@inherits ConfigurationBase
|
||||||
|
|
||||||
<MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.IsDisabled" Class="mb-1">
|
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" Class="mb-3" Disabled="@this.Disabled()">
|
||||||
|
<MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.Disabled()">
|
||||||
@this.Value() @this.Unit
|
@this.Value() @this.Unit
|
||||||
</MudSlider>
|
</MudSlider>
|
||||||
|
</MudField>
|
@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class ConfigurationSlider<T> : ConfigurationBaseCore where T : struct, INumber<T>
|
public partial class ConfigurationSlider<T> : ConfigurationBase where T : struct, INumber<T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The minimum value for the slider.
|
/// The minimum value for the slider.
|
||||||
@ -42,18 +42,6 @@ public partial class ConfigurationSlider<T> : ConfigurationBaseCore where T : st
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<T> ValueUpdate { get; set; } = _ => { };
|
public Action<T> ValueUpdate { get; set; } = _ => { };
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => true;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override Variant Variant => Variant.Outlined;
|
|
||||||
|
|
||||||
protected override string Label => this.OptionDescription;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
@inherits ConfigurationBaseCore
|
@inherits ConfigurationBase
|
||||||
|
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
Text="@this.Text()"
|
Text="@this.Text()"
|
||||||
TextChanged="@this.InternalUpdate"
|
TextChanged="@this.InternalUpdate"
|
||||||
Disabled="@this.IsDisabled"
|
Label="@this.OptionDescription"
|
||||||
|
Disabled="@this.Disabled()"
|
||||||
|
Class="@MARGIN_CLASS"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@this.Icon"
|
AdornmentIcon="@this.Icon"
|
||||||
AdornmentColor="@this.IconColor"
|
AdornmentColor="@this.IconColor"
|
||||||
@ -13,5 +15,5 @@
|
|||||||
AutoGrow="@this.AutoGrow"
|
AutoGrow="@this.AutoGrow"
|
||||||
MaxLines="@this.GetMaxLines"
|
MaxLines="@this.GetMaxLines"
|
||||||
Immediate="@true"
|
Immediate="@true"
|
||||||
Underline="false"
|
Variant="Variant.Outlined"
|
||||||
/>
|
/>
|
@ -4,7 +4,7 @@ using Timer = System.Timers.Timer;
|
|||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class ConfigurationText : ConfigurationBaseCore
|
public partial class ConfigurationText : ConfigurationBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The text used for the textfield.
|
/// The text used for the textfield.
|
||||||
@ -43,30 +43,21 @@ public partial class ConfigurationText : ConfigurationBaseCore
|
|||||||
public int MaxLines { get; set; } = 12;
|
public int MaxLines { get; set; } = 12;
|
||||||
|
|
||||||
private string internalText = string.Empty;
|
private string internalText = string.Empty;
|
||||||
private readonly Timer timer = new(TimeSpan.FromMilliseconds(500))
|
private Timer timer = new(TimeSpan.FromMilliseconds(500))
|
||||||
{
|
{
|
||||||
AutoReset = false
|
AutoReset = false
|
||||||
};
|
};
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
#region Overrides of ConfigurationBase
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => true;
|
|
||||||
|
|
||||||
protected override Variant Variant => Variant.Outlined;
|
|
||||||
|
|
||||||
protected override string Label => this.OptionDescription;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText));
|
this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText));
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
this.internalText = this.Text();
|
this.internalText = this.Text();
|
||||||
@ -75,6 +66,8 @@ public partial class ConfigurationText : ConfigurationBaseCore
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
private bool AutoGrow => this.NumLines > 1;
|
private bool AutoGrow => this.NumLines > 1;
|
||||||
|
|
||||||
private int GetMaxLines => this.AutoGrow ? this.MaxLines : 1;
|
private int GetMaxLines => this.AutoGrow ? this.MaxLines : 1;
|
||||||
@ -92,23 +85,4 @@ public partial class ConfigurationText : ConfigurationBaseCore
|
|||||||
await this.SettingsManager.StoreSettings();
|
await this.SettingsManager.StoreSettings();
|
||||||
await this.InformAboutChange();
|
await this.InformAboutChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
|
||||||
|
|
||||||
protected override void DisposeResources()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.timer.Stop();
|
|
||||||
this.timer.Dispose();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
base.DisposeResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
@ -27,7 +27,7 @@
|
|||||||
</MudText>
|
</MudText>
|
||||||
<MudSpacer/>
|
<MudSpacer/>
|
||||||
<MudTooltip Text="@T("Manage your data sources")" Placement="Placement.Top">
|
<MudTooltip Text="@T("Manage your data sources")" Placement="Placement.Top">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialog"/>
|
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialog"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</CardHeaderContent>
|
</CardHeaderContent>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
}
|
}
|
||||||
else if (this.showDataSourceSelection)
|
else if (this.showDataSourceSelection)
|
||||||
{
|
{
|
||||||
<MudTextSwitch Label="@T("Are data sources enabled?")" Value="@this.areDataSourcesEnabled" LabelOn="@T("Yes, I want to use data sources.")" LabelOff="@T("No, I don't want to use data sources.")" ValueChanged="@this.EnabledChanged"/>
|
<MudTextSwitch Label="Are data sources enabled?" Value="@this.areDataSourcesEnabled" LabelOn="@T("Yes, I want to use data sources.")" LabelOff="@T("No, I don't want to use data sources.")" ValueChanged="@this.EnabledChanged"/>
|
||||||
@if (this.areDataSourcesEnabled)
|
@if (this.areDataSourcesEnabled)
|
||||||
{
|
{
|
||||||
<MudTextSwitch Label="@T("AI-based data source selection")" Value="@this.aiBasedSourceSelection" LabelOn="@T("Yes, let the AI decide which data sources are needed.")" LabelOff="@T("No, I manually decide which data source to use.")" ValueChanged="@this.AutoModeChanged"/>
|
<MudTextSwitch Label="@T("AI-based data source selection")" Value="@this.aiBasedSourceSelection" LabelOn="@T("Yes, let the AI decide which data sources are needed.")" LabelOff="@T("No, I manually decide which data source to use.")" ValueChanged="@this.AutoModeChanged"/>
|
||||||
|
@ -4,7 +4,7 @@ using Timer = System.Timers.Timer;
|
|||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class DebouncedTextField : MudComponentBase, IDisposable
|
public partial class DebouncedTextField : MudComponentBase
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Label { get; set; } = string.Empty;
|
public string Label { get; set; } = string.Empty;
|
||||||
@ -50,15 +50,12 @@ public partial class DebouncedTextField : MudComponentBase, IDisposable
|
|||||||
|
|
||||||
private readonly Timer debounceTimer = new();
|
private readonly Timer debounceTimer = new();
|
||||||
private string text = string.Empty;
|
private string text = string.Empty;
|
||||||
private string lastParameterText = string.Empty;
|
|
||||||
private bool isInitialized;
|
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
this.text = this.Text;
|
this.text = this.Text;
|
||||||
this.lastParameterText = this.Text;
|
|
||||||
this.debounceTimer.AutoReset = false;
|
this.debounceTimer.AutoReset = false;
|
||||||
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
|
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
|
||||||
this.debounceTimer.Elapsed += (_, _) =>
|
this.debounceTimer.Elapsed += (_, _) =>
|
||||||
@ -69,32 +66,9 @@ public partial class DebouncedTextField : MudComponentBase, IDisposable
|
|||||||
this.InvokeAsync(() => this.WhenTextCanged(this.text));
|
this.InvokeAsync(() => this.WhenTextCanged(this.text));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isInitialized = true;
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
// Ensure the timer uses the latest debouncing interval:
|
|
||||||
if (!this.isInitialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(Math.Abs(this.debounceTimer.Interval - this.DebounceTime.TotalMilliseconds) > 1)
|
|
||||||
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
|
|
||||||
|
|
||||||
// Only sync when the parent's parameter actually changed since the last change:
|
|
||||||
if (this.Text != this.lastParameterText)
|
|
||||||
{
|
|
||||||
this.text = this.Text;
|
|
||||||
this.lastParameterText = this.Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.debounceTimer.Stop();
|
|
||||||
this.debounceTimer.Start();
|
|
||||||
|
|
||||||
await base.OnParametersSetAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnTextChanged(string value)
|
private void OnTextChanged(string value)
|
||||||
@ -103,21 +77,4 @@ public partial class DebouncedTextField : MudComponentBase, IDisposable
|
|||||||
this.debounceTimer.Stop();
|
this.debounceTimer.Stop();
|
||||||
this.debounceTimer.Start();
|
this.debounceTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.debounceTimer.Stop();
|
|
||||||
this.debounceTimer.Dispose();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
<MudExpansionPanel Class="border-solid border rounded-lg" Expanded="@this.IsExpanded" MaxHeight="@this.MaxHeight" ExpandedChanged="async s => await this.ExpandedChanged(s)">
|
<MudExpansionPanel Class="border-solid border rounded-lg" Expanded="@this.IsExpanded">
|
||||||
<TitleContent>
|
<TitleContent>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
<MudIcon Icon="@this.HeaderIcon" Size="@this.IconSize" Color="@this.IconColor" class="mr-3"/>
|
<MudIcon Icon="@this.HeaderIcon" Size="@this.IconSize" Color="@this.IconColor" class="mr-3"/>
|
||||||
|
@ -16,12 +16,6 @@ public partial class ExpansionPanel : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string HeaderText { get; set; } = "n/a";
|
public string HeaderText { get; set; } = "n/a";
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public int? MaxHeight { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<bool, Task> ExpandedChanged { get; set; } = _ => Task.CompletedTask;
|
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment? ChildContent { get; set; }
|
public RenderFragment? ChildContent { get; set; }
|
||||||
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
@inherits ConfigurationBaseCore
|
|
||||||
|
|
||||||
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@this.Icon" Disabled="@this.IsDisabled" OnClick="@(async () => await this.ClickAsync())">
|
|
||||||
@this.Text
|
|
||||||
</MudButton>
|
|
@ -1,39 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class LockableButton : ConfigurationBaseCore
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public string Icon { get; set; } = Icons.Material.Filled.Info;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<Task> OnClickAsync { get; set; } = () => Task.CompletedTask;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Action OnClick { get; set; } = () => { };
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Text { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Class { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
#region Overrides of ConfigurationBase
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override bool Stretch => false;
|
|
||||||
|
|
||||||
protected override string GetClassForBase => this.Class;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private async Task ClickAsync()
|
|
||||||
{
|
|
||||||
if (this.IsLocked() || this.Disabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
await this.OnClickAsync();
|
|
||||||
this.OnClick();
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,6 +13,10 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
|||||||
[Inject]
|
[Inject]
|
||||||
protected MessageBus MessageBus { get; init; } = null!;
|
protected MessageBus MessageBus { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||||
|
private ILogger<MSGComponentBase> Logger { get; init; } = null!;
|
||||||
|
|
||||||
private ILanguagePlugin Lang { get; set; } = PluginFactory.BaseLanguage;
|
private ILanguagePlugin Lang { get; set; } = PluginFactory.BaseLanguage;
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
@ -40,8 +44,6 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
|||||||
#region Implementation of IMessageBusReceiver
|
#region Implementation of IMessageBusReceiver
|
||||||
|
|
||||||
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
|
||||||
{
|
|
||||||
await this.InvokeAsync(async () =>
|
|
||||||
{
|
{
|
||||||
switch (triggeredEvent)
|
switch (triggeredEvent)
|
||||||
{
|
{
|
||||||
@ -56,7 +58,6 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
await this.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
public async Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
@inherits MSGComponentBase
|
|
||||||
|
|
||||||
<MudStack Row="false" Class="mb-3 pa-3 border-dashed border rounded-lg">
|
|
||||||
<MudJustifiedText Typo="Typo.body1">
|
|
||||||
@this.DetermineIntroText()
|
|
||||||
</MudJustifiedText>
|
|
||||||
<MudButton Color="@this.DetermineButtonColor()" Variant="Variant.Filled" OnClick="() => this.ShowPandocDialogAsync()">
|
|
||||||
@this.DetermineButtonText()
|
|
||||||
</MudButton>
|
|
||||||
</MudStack>
|
|
@ -1,97 +0,0 @@
|
|||||||
using AIStudio.Dialogs;
|
|
||||||
using AIStudio.Tools.Services;
|
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class ManagePandocDependency : MSGComponentBase
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public string IntroText { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private IDialogService DialogService { get; init; } = null!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private RustService RustService { get; init; } = null!;
|
|
||||||
|
|
||||||
private PandocInstallation pandocInstallation;
|
|
||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
await base.OnInitializedAsync();
|
|
||||||
this.pandocInstallation = await Pandoc.CheckAvailabilityAsync(this.RustService, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private Color DetermineButtonColor()
|
|
||||||
{
|
|
||||||
if (this.pandocInstallation == default)
|
|
||||||
return Color.Default;
|
|
||||||
|
|
||||||
switch (this.pandocInstallation)
|
|
||||||
{
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: true }:
|
|
||||||
return Color.Default;
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: false }:
|
|
||||||
return Color.Warning;
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: false }:
|
|
||||||
return Color.Error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string DetermineButtonText()
|
|
||||||
{
|
|
||||||
if(this.pandocInstallation == default)
|
|
||||||
return T("Please wait while we check the availability of Pandoc.");
|
|
||||||
|
|
||||||
switch (this.pandocInstallation)
|
|
||||||
{
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: true }:
|
|
||||||
return T("Check your Pandoc installation");
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: false }:
|
|
||||||
return T("Update Pandoc");
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: false }:
|
|
||||||
return T("Install Pandoc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string DetermineIntroText()
|
|
||||||
{
|
|
||||||
if (this.pandocInstallation == default)
|
|
||||||
return $"{this.IntroText} {T("Please wait while we check the availability of Pandoc.")}";
|
|
||||||
|
|
||||||
switch (this.pandocInstallation)
|
|
||||||
{
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: true }:
|
|
||||||
return $"{this.IntroText} {T("Your Pandoc installation meets the requirements.")}";
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: true, IsAvailable: false }:
|
|
||||||
return $"{this.IntroText} {T("Your Pandoc installation is outdated. Please update it to the latest version to ensure compatibility with all features.")}";
|
|
||||||
|
|
||||||
case { CheckWasSuccessful: false }:
|
|
||||||
return $"{this.IntroText} {T("Pandoc is not installed or not available. Please install it to use the features that require Pandoc.")}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ShowPandocDialogAsync()
|
|
||||||
{
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<PandocDialog>(T("Pandoc Installation"), DialogOptions.FULLSCREEN);
|
|
||||||
await dialogReference.Result;
|
|
||||||
|
|
||||||
// Refresh the availability of Pandoc after the dialog is closed:
|
|
||||||
this.pandocInstallation = await Pandoc.CheckAvailabilityAsync(this.RustService, false);
|
|
||||||
|
|
||||||
await this.InvokeAsync(this.StateHasChanged);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
<MudTooltip Text="@this.TooltipMessage" Placement="Placement.Bottom">
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Size="@this.Size" OnClick="@(() => this.HandleCopyClick())"/>
|
|
||||||
</MudTooltip>
|
|
@ -1,90 +0,0 @@
|
|||||||
using AIStudio.Chat;
|
|
||||||
using AIStudio.Tools.PluginSystem;
|
|
||||||
using AIStudio.Tools.Services;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class MudCopyClipboardButton : ComponentBase
|
|
||||||
{
|
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(MudCopyClipboardButton).Namespace, nameof(MudCopyClipboardButton));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The string, if you want to copy a string.
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public string StringContent { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The content, if you want to copy content.
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public IContent? Content { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The content type, if you want to copy Content.
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public ContentType Type { get; init; } = ContentType.NONE;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The tooltip that should be shown to the user.
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public string TooltipMessage { get; set; } = TB("Copies the content to the clipboard");
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The size of the button. The default size is small.
|
|
||||||
/// </summary>
|
|
||||||
[Parameter]
|
|
||||||
public Size Size { get; set; } = Size.Small;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private ISnackbar Snackbar { get; init; } = null!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private RustService RustService { get; init; } = null!;
|
|
||||||
|
|
||||||
private async Task HandleCopyClick()
|
|
||||||
{
|
|
||||||
if (this.Type is ContentType.NONE)
|
|
||||||
await this.CopyToClipboard(this.StringContent);
|
|
||||||
else
|
|
||||||
await this.CopyToClipboard(this.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copy this the string to the clipboard.
|
|
||||||
/// </summary>
|
|
||||||
private async Task CopyToClipboard(string textContent)
|
|
||||||
{
|
|
||||||
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copy this block's content to the clipboard.
|
|
||||||
/// </summary>
|
|
||||||
private async Task CopyToClipboard(IContent? contentToCopy)
|
|
||||||
{
|
|
||||||
if (contentToCopy is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (this.Type)
|
|
||||||
{
|
|
||||||
case ContentType.TEXT:
|
|
||||||
var textContent = (ContentText) contentToCopy;
|
|
||||||
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
this.Snackbar.Add(TB("Cannot copy this content type to clipboard."), Severity.Error, config =>
|
|
||||||
{
|
|
||||||
config.Icon = Icons.Material.Filled.ContentCopy;
|
|
||||||
config.IconSize = Size.Large;
|
|
||||||
config.IconColor = Color.Error;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +1,10 @@
|
|||||||
@using AIStudio.Settings
|
@using AIStudio.Settings
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
<MudSelect T="Profile" Strict="@true" Value="@this.Profile" ValueChanged="@this.SelectionChanged" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person4" Margin="Margin.Dense" Label="@T("Select one of your profiles")" Variant="Variant.Outlined" Class="mb-3" Validation="@this.Validation">
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Baseline" StretchItems="StretchItems.Start" Class="mb-3" Wrap="Wrap.NoWrap">
|
|
||||||
<MudSelect T="Profile" Strict="@true" Value="@this.Profile" ValueChanged="@this.SelectionChanged" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person4" Margin="Margin.Dense" Label="@T("Select one of your profiles")" Variant="Variant.Outlined" Class="mb-3" Validation="@this.Validation">
|
|
||||||
@foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles())
|
@foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="profile">
|
<MudSelectItem Value="profile">
|
||||||
@profile.Name
|
@profile.Name
|
||||||
</MudSelectItem>
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Settings" OnClick="() => this.OpenSettingsDialog()"/>
|
|
||||||
</MudStack>
|
|
@ -1,10 +1,7 @@
|
|||||||
using AIStudio.Dialogs.Settings;
|
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class ProfileFormSelection : MSGComponentBase
|
public partial class ProfileFormSelection : MSGComponentBase
|
||||||
@ -18,18 +15,9 @@ public partial class ProfileFormSelection : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<Profile, string?> Validation { get; set; } = _ => null;
|
public Func<Profile, string?> Validation { get; set; } = _ => null;
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IDialogService DialogService { get; init; } = null!;
|
|
||||||
|
|
||||||
private async Task SelectionChanged(Profile profile)
|
private async Task SelectionChanged(Profile profile)
|
||||||
{
|
{
|
||||||
this.Profile = profile;
|
this.Profile = profile;
|
||||||
await this.ProfileChanged.InvokeAsync(profile);
|
await this.ProfileChanged.InvokeAsync(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OpenSettingsDialog()
|
|
||||||
{
|
|
||||||
var dialogParameters = new DialogParameters();
|
|
||||||
await this.DialogService.ShowAsync<SettingsDialogProfiles>(T("Open Profile Options"), dialogParameters, DialogOptions.FULLSCREEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,28 +1,11 @@
|
|||||||
@using AIStudio.Settings
|
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<MudTooltip Text="@this.ToolTipText" Placement="Placement.Top">
|
<MudTooltip Text="@T("You can switch between your profiles here")" Placement="Placement.Top">
|
||||||
<MudMenu TransformOrigin="@Origin.BottomLeft" AnchorOrigin="Origin.TopLeft" StartIcon="@Icons.Material.Filled.Person4" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@this.CurrentProfile.Name" Variant="Variant.Filled" Color="Color.Default" Class="@this.MarginClass" Disabled="@this.Disabled">
|
<MudMenu TransformOrigin="@Origin.BottomLeft" AnchorOrigin="Origin.TopLeft" StartIcon="@Icons.Material.Filled.Person4" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@this.CurrentProfile.Name" Variant="Variant.Filled" Color="Color.Default" Class="@this.MarginClass">
|
||||||
<ActivatorContent>
|
|
||||||
@if (this.CurrentProfile != Profile.NO_PROFILE)
|
|
||||||
{
|
|
||||||
<MudButton IconSize="Size.Large" StartIcon="@Icons.Material.Filled.Person4" IconColor="Color.Default">
|
|
||||||
@this.CurrentProfile.Name
|
|
||||||
</MudButton>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Person4" />
|
|
||||||
}
|
|
||||||
</ActivatorContent>
|
|
||||||
<ChildContent>
|
|
||||||
<MudMenuItem Icon="@Icons.Material.Filled.Settings" Label="@T("Manage your profiles")" OnClick="async () => await this.OpenSettingsDialog()" />
|
|
||||||
<MudDivider/>
|
|
||||||
@foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles())
|
@foreach (var profile in this.SettingsManager.ConfigurationData.Profiles.GetAllProfiles())
|
||||||
{
|
{
|
||||||
<MudMenuItem Icon="@Icons.Material.Filled.Person4" OnClick="() => this.SelectionChanged(profile)">
|
<MudMenuItem OnClick="() => this.SelectionChanged(profile)">
|
||||||
@profile.Name
|
@profile.Name
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
}
|
}
|
||||||
</ChildContent>
|
|
||||||
</MudMenu>
|
</MudMenu>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
@ -1,16 +1,11 @@
|
|||||||
using AIStudio.Dialogs.Settings;
|
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Tools.PluginSystem;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class ProfileSelection : MSGComponentBase
|
public partial class ProfileSelection : MSGComponentBase
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ProfileSelection).Namespace, nameof(ProfileSelection));
|
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Profile CurrentProfile { get; set; } = Profile.NO_PROFILE;
|
public Profile CurrentProfile { get; set; } = Profile.NO_PROFILE;
|
||||||
|
|
||||||
@ -23,19 +18,6 @@ public partial class ProfileSelection : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string MarginRight { get; set; } = string.Empty;
|
public string MarginRight { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public bool Disabled { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string DisabledText { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private IDialogService DialogService { get; init; } = null!;
|
|
||||||
|
|
||||||
private readonly string defaultToolTipText = TB("You can switch between your profiles here");
|
|
||||||
|
|
||||||
private string ToolTipText => this.Disabled ? this.DisabledText : this.defaultToolTipText;
|
|
||||||
|
|
||||||
private string MarginClass => $"{this.MarginLeft} {this.MarginRight}";
|
private string MarginClass => $"{this.MarginLeft} {this.MarginRight}";
|
||||||
|
|
||||||
private async Task SelectionChanged(Profile profile)
|
private async Task SelectionChanged(Profile profile)
|
||||||
@ -43,10 +25,4 @@ public partial class ProfileSelection : MSGComponentBase
|
|||||||
this.CurrentProfile = profile;
|
this.CurrentProfile = profile;
|
||||||
await this.CurrentProfileChanged.InvokeAsync(profile);
|
await this.CurrentProfileChanged.InvokeAsync(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OpenSettingsDialog()
|
|
||||||
{
|
|
||||||
var dialogParameters = new DialogParameters();
|
|
||||||
await this.DialogService.ShowAsync<SettingsDialogProfiles>(T("Open Profile Options"), dialogParameters, DialogOptions.FULLSCREEN);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,44 +0,0 @@
|
|||||||
using AIStudio.Tools.Rust;
|
|
||||||
using AIStudio.Tools.Services;
|
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class ReadFileContent : MSGComponentBase
|
|
||||||
{
|
|
||||||
[Parameter]
|
|
||||||
public string FileContent { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<string> FileContentChanged { get; set; }
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private RustService RustService { get; init; } = null!;
|
|
||||||
|
|
||||||
private async Task SelectFile()
|
|
||||||
{
|
|
||||||
var selectedFile = await this.RustService.SelectFile(T("Select file to read its content"));
|
|
||||||
if (selectedFile.UserCancelled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!File.Exists(selectedFile.SelectedFilePath))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ext = Path.GetExtension(selectedFile.SelectedFilePath).TrimStart('.');
|
|
||||||
if (Array.Exists(FileTypeFilter.Executables.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.AppBlocking, T("Executables are not allowed")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.Exists(FileTypeFilter.AllImages.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.ImageNotSupported, T("Images are not supported yet")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileContent = await this.RustService.ReadArbitraryFileData(selectedFile.SelectedFilePath, int.MaxValue);
|
|
||||||
await this.FileContentChanged.InvokeAsync(fileContent);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="async () => await this.SelectFile()" Variant="Variant.Filled" Class="mb-3">
|
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="async () => await this.SelectFile()" Variant="Variant.Filled" Class="mb-3">
|
||||||
@T("Use file content as input")
|
@T("Use PDF content as input")
|
||||||
</MudButton>
|
</MudButton>
|
31
app/MindWork AI Studio/Components/ReadPDFContent.razor.cs
Normal file
31
app/MindWork AI Studio/Components/ReadPDFContent.razor.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using AIStudio.Tools.Rust;
|
||||||
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public partial class ReadPDFContent : MSGComponentBase
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string PDFContent { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> PDFContentChanged { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private RustService RustService { get; init; } = null!;
|
||||||
|
|
||||||
|
private async Task SelectFile()
|
||||||
|
{
|
||||||
|
var pdfFile = await this.RustService.SelectFile(T("Select PDF file"), FileTypeFilter.PDF);
|
||||||
|
if (pdfFile.UserCancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!File.Exists(pdfFile.SelectedFilePath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var pdfText = await this.RustService.GetPDFText(pdfFile.SelectedFilePath);
|
||||||
|
await this.PDFContentChanged.InvokeAsync(pdfText);
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
@inherits MSGComponentBase
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" Class="@this.Class" StretchItems="StretchItems.Start" Wrap="Wrap.NoWrap">
|
|
||||||
<MudTextField
|
|
||||||
T="string"
|
|
||||||
Text="@this.Secret"
|
|
||||||
TextChanged="@this.OnSecretChanged"
|
|
||||||
Label="@this.Label"
|
|
||||||
Placeholder="@this.Placeholder"
|
|
||||||
Adornment="Adornment.Start"
|
|
||||||
AdornmentIcon="@Icons.Material.Filled.VpnKey"
|
|
||||||
AdornmentColor="Color.Info"
|
|
||||||
InputType="@this.InputType"
|
|
||||||
Immediate="true"
|
|
||||||
Validation="@this.Validation"
|
|
||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
|
||||||
|
|
||||||
<MudTooltip Text="@this.ToggleVisibilityTooltip">
|
|
||||||
<MudIconButton Icon="@this.InputTypeIcon" OnClick="() => this.ToggleVisibility()"/>
|
|
||||||
</MudTooltip>
|
|
||||||
</MudStack>
|
|
@ -1,54 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
|
||||||
|
|
||||||
public partial class SecretInputField : MSGComponentBase
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Secret { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<string> SecretChanged { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Label { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Placeholder { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public Func<string, string?> Validation { get; set; } = _ => null;
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string Class { get; set; } = "mb-3";
|
|
||||||
|
|
||||||
#region Overrides of MSGComponentBase
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
await base.OnInitializedAsync();
|
|
||||||
|
|
||||||
// Configure the spellchecking for the instance name input:
|
|
||||||
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private bool isSecretVisible;
|
|
||||||
|
|
||||||
private InputType InputType => this.isSecretVisible ? InputType.Text : InputType.Password;
|
|
||||||
|
|
||||||
private string InputTypeIcon => this.isSecretVisible ? Icons.Material.Filled.Visibility : Icons.Material.Filled.VisibilityOff;
|
|
||||||
|
|
||||||
private string ToggleVisibilityTooltip => this.isSecretVisible ? T("Hide content") : T("Show content");
|
|
||||||
|
|
||||||
private Task OnSecretChanged(string arg)
|
|
||||||
{
|
|
||||||
this.Secret = arg;
|
|
||||||
return this.SecretChanged.InvokeAsync(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ToggleVisibility() => this.isSecretVisible = !this.isSecretVisible;
|
|
||||||
}
|
|
@ -1,5 +1,3 @@
|
|||||||
@inherits MSGComponentBase
|
|
||||||
|
|
||||||
<MudStack Row="@true" Spacing="3" Class="mb-3" StretchItems="StretchItems.None" AlignItems="AlignItems.Center">
|
<MudStack Row="@true" Spacing="3" Class="mb-3" StretchItems="StretchItems.None" AlignItems="AlignItems.Center">
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@ -14,6 +12,6 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="this.Disabled" OnClick="@this.OpenDirectoryDialog">
|
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="this.Disabled" OnClick="@this.OpenDirectoryDialog">
|
||||||
@T("Choose Directory")
|
Choose Directory
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
@ -1,10 +1,11 @@
|
|||||||
|
using AIStudio.Settings;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class SelectDirectory : MSGComponentBase
|
public partial class SelectDirectory : ComponentBase
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Directory { get; set; } = string.Empty;
|
public string Directory { get; set; } = string.Empty;
|
||||||
@ -24,6 +25,9 @@ public partial class SelectDirectory : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string, string?> Validation { get; set; } = _ => null;
|
public Func<string, string?> Validation { get; set; } = _ => null;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private SettingsManager SettingsManager { get; init; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public RustService RustService { get; set; } = null!;
|
public RustService RustService { get; set; } = null!;
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
@inherits MSGComponentBase
|
|
||||||
|
|
||||||
<MudStack Row="@true" Spacing="3" Class="mb-3" StretchItems="StretchItems.None" AlignItems="AlignItems.Center">
|
<MudStack Row="@true" Spacing="3" Class="mb-3" StretchItems="StretchItems.None" AlignItems="AlignItems.Center">
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@ -14,6 +12,6 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="this.Disabled" OnClick="@this.OpenFileDialog">
|
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen" Variant="Variant.Outlined" Color="Color.Primary" Disabled="this.Disabled" OnClick="@this.OpenFileDialog">
|
||||||
@T("Choose File")
|
Choose File
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Settings;
|
||||||
using AIStudio.Tools.Rust;
|
using AIStudio.Tools.Rust;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
@ -5,7 +6,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class SelectFile : MSGComponentBase
|
public partial class SelectFile : ComponentBase
|
||||||
{
|
{
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string File { get; set; } = string.Empty;
|
public string File { get; set; } = string.Empty;
|
||||||
@ -28,6 +29,9 @@ public partial class SelectFile : MSGComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string, string?> Validation { get; set; } = _ => null;
|
public Func<string, string?> Validation { get; set; } = _ => null;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private SettingsManager SettingsManager { get; init; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public RustService RustService { get; set; } = null!;
|
public RustService RustService { get; set; } = null!;
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
@inherits SettingsPanelBase
|
@inherits SettingsPanelBase
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="@T("Agent: Text Content Cleaner Options")">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="Agent: Text Content Cleaner Options">
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used.")
|
Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things,
|
||||||
|
and attempts to convert relative links into absolute links so that they can be used.
|
||||||
</MudText>
|
</MudText>
|
||||||
<ConfigurationOption OptionDescription="@T("Preselect text content cleaner options?")" LabelOn="@T("Options are preselected")" LabelOff="@T("No options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM.")"/>
|
<ConfigurationOption OptionDescription="Preselect text content cleaner options?" LabelOn="Options are preselected" LabelOff="No options are preselected" State="@(() => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions = updatedState)" OptionHelp="When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM."/>
|
||||||
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectedAgentProvider = selectedValue)"/>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
@ -1,11 +1,11 @@
|
|||||||
@inherits SettingsPanelBase
|
@inherits SettingsPanelBase
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.SelectAll" HeaderText="@T("Agent: Data Source Selection Options")">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.SelectAll" HeaderText="Agent: Data Source Selection Options">
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("Use Case: this agent is used to select the appropriate data sources for the current prompt.")
|
Use Case: this agent is used to select the appropriate data sources for the current prompt.
|
||||||
</MudText>
|
</MudText>
|
||||||
<ConfigurationOption OptionDescription="@T("Preselect data source selection options?")" LabelOn="@T("Options are preselected")" LabelOff="@T("No options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM.")"/>
|
<ConfigurationOption OptionDescription="Preselect data source selection options?" LabelOn="Options are preselected" LabelOff="No options are preselected" State="@(() => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions = updatedState)" OptionHelp="When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM."/>
|
||||||
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.AgentDataSourceSelection.PreselectedAgentProvider = selectedValue)"/>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
@ -1,15 +1,17 @@
|
|||||||
@inherits SettingsPanelBase
|
@inherits SettingsPanelBase
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Assessment" HeaderText="@T("Agent: Retrieval Context Validation Options")">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Assessment" HeaderText="Agent: Retrieval Context Validation Options">
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
@T("Use Case: this agent is used to validate any retrieval context of any retrieval process. Perhaps there are many of these retrieval contexts and you want to validate them all. Therefore, you might want to use a cheap and fast LLM for this job. When using a local or self-hosted LLM, look for a small (e.g. 3B) and fast model.")
|
Use Case: this agent is used to validate any retrieval context of any retrieval process. Perhaps there are many of these
|
||||||
|
retrieval contexts and you want to validate them all. Therefore, you might want to use a cheap and fast LLM for this
|
||||||
|
job. When using a local or self-hosted LLM, look for a small (e.g. 3B) and fast model.
|
||||||
</MudText>
|
</MudText>
|
||||||
<ConfigurationOption OptionDescription="@T("Enable the retrieval context validation agent?")" LabelOn="@T("The validation agent is enabled")" LabelOff="@T("No validation is performed")" State="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation = updatedState)" OptionHelp="@T("When enabled, the retrieval context validation agent will check each retrieval context of any retrieval process, whether a context makes sense for the given prompt.")"/>
|
<ConfigurationOption OptionDescription="Enable the retrieval context validation agent?" LabelOn="The validation agent is enabled" LabelOff="No validation is performed" State="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation = updatedState)" OptionHelp="When enabled, the retrieval context validation agent will check each retrieval context of any retrieval process, whether a context makes sense for the given prompt."/>
|
||||||
@if (this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)
|
@if (this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation)
|
||||||
{
|
{
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<ConfigurationOption OptionDescription="@T("Preselect retrieval context validation options?")" LabelOn="@T("Options are preselected")" LabelOff="@T("No options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM.")"/>
|
<ConfigurationOption OptionDescription="Preselect retrieval context validation options?" LabelOn="Options are preselected" LabelOff="No options are preselected" State="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions = updatedState)" OptionHelp="When enabled, you can preselect some agent options. This is might be useful when you prefer an LLM."/>
|
||||||
<ConfigurationSlider T="int" OptionDescription="@T("How many validation agents should work simultaneously?")" Min="1" Max="100" Step="1" Unit="@T("agents")" Value="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations)" ValueUpdate="@(updatedValue => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations = updatedValue)" OptionHelp="@T("More active agents also mean that a corresponding number of requests are made simultaneously. Some providers limit the number of requests per minute. When you are unsure, choose a low setting between 1 to 6 agents.")"/>
|
<ConfigurationSlider T="int" OptionDescription="How many validation agents should work simultaneously?" Min="1" Max="100" Step="1" Unit="agents" Value="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations)" ValueUpdate="@(updatedValue => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.NumParallelValidations = updatedValue)" OptionHelp="More active agents also mean that a corresponding number of requests are made simultaneously. Some providers limit the number of requests per minute. When you are unsure, choose a low setting between 1 to 6 agents."/>
|
||||||
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectAgentOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.PreselectedAgentProvider = selectedValue)"/>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,20 @@
|
|||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="@T("App Options")">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="@T("App Options")">
|
||||||
|
|
||||||
|
@if (PreviewFeatures.PRE_PLUGINS_2025.IsEnabled(this.SettingsManager))
|
||||||
|
{
|
||||||
<ConfigurationSelect OptionDescription="@T("Language behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.LanguageBehavior)" Data="@ConfigurationSelectDataFactory.GetLangBehaviorData()" SelectionUpdate="@(selectedValue => _ = this.UpdateLangBehaviour(selectedValue))" OptionHelp="@T("Select the language behavior for the app. The default is to use the system language. You might want to choose a language manually?")"/>
|
<ConfigurationSelect OptionDescription="@T("Language behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.LanguageBehavior)" Data="@ConfigurationSelectDataFactory.GetLangBehaviorData()" SelectionUpdate="@(selectedValue => _ = this.UpdateLangBehaviour(selectedValue))" OptionHelp="@T("Select the language behavior for the app. The default is to use the system language. You might want to choose a language manually?")"/>
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.App.LanguageBehavior is LangBehavior.MANUAL)
|
@if (this.SettingsManager.ConfigurationData.App.LanguageBehavior is LangBehavior.MANUAL)
|
||||||
{
|
{
|
||||||
<ConfigurationSelect OptionDescription="@T("Language")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.LanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(selectedValue => _ = this.UpdateManuallySelectedLanguage(selectedValue))" OptionHelp="@T("Select the language for the app.")"/>
|
<ConfigurationSelect OptionDescription="@T("Language")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.LanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(selectedValue => _ = this.UpdateManuallySelectedLanguage(selectedValue))" OptionHelp="@T("Select the language for the app.")"/>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
|
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
|
||||||
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("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="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("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="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("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.")"/>
|
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("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="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateBehavior, out var meta) && meta.IsLocked"/>
|
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
|
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
|
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
|
||||||
|
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
@using AIStudio.Settings
|
||||||
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits SettingsPanelBase
|
||||||
|
|
||||||
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Chat" HeaderText="@T("Chat Options")">
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Shortcut to send input")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior = selectedValue)" OptionHelp="@T("Do you want to use any shortcut to send your input?")"/>
|
||||||
|
<ConfigurationOption OptionDescription="@T("Show the latest message after loading?")" LabelOn="@T("Latest message is shown, after loading a chat")" LabelOff="@T("First (oldest) message is shown, after loading a chat")" State="@(() => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading = updatedState)" OptionHelp="@T("When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown.")"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Provider selection when creating new chats")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.AddChatProviderBehavior)" Data="@ConfigurationSelectDataFactory.GetAddChatProviderBehavior()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.AddChatProviderBehavior = selectedValue)" OptionHelp="@T("Control how the LLM provider for added chats is selected.")"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Provider selection when loading a chat and sending assistant results to chat")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior)" Data="@ConfigurationSelectDataFactory.GetLoadingChatProviderBehavior()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.LoadingProviderBehavior = selectedValue)" OptionHelp="@T("Control how the LLM provider for loaded chats is selected and when assistant results are sent to chat.")"/>
|
||||||
|
|
||||||
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
|
<ConfigurationOption OptionDescription="@T("Preselect chat options?")" LabelOn="@T("Chat options are preselected")" LabelOff="@T("No chat options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect chat options. This is might be useful when you prefer a specific provider.")"/>
|
||||||
|
<ConfigurationProviderSelection Component="Components.CHAT" Data="@this.AvailableLLMProvidersFunc()" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider = selectedValue)"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Preselect one of your profiles?")" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedProfile = selectedValue)" OptionHelp="@T("Would you like to set one of your profiles as the default for chats?")"/>
|
||||||
|
</MudPaper>
|
||||||
|
|
||||||
|
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||||
|
{
|
||||||
|
<DataSourceSelection SelectionMode="DataSourceSelectionMode.CONFIGURATION_MODE" AutoSaveAppSettings="@true" @bind-DataSourceOptions="@this.SettingsManager.ConfigurationData.Chat.PreselectedDataSourceOptions" ConfigurationHeaderMessage="@T("You can set default data sources and options for new chats. You can change these settings later for each individual chat.")"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Apply default data source option when sending assistant results to chat")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.SendToChatDataSourceBehavior)" Data="@ConfigurationSelectDataFactory.GetSendToChatDataSourceBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.SendToChatDataSourceBehavior = selectedValue)" OptionHelp="@T("Do you want to apply the default data source options when sending assistant results to chat?")"/>
|
||||||
|
}
|
||||||
|
</ExpansionPanel>
|
@ -0,0 +1,3 @@
|
|||||||
|
namespace AIStudio.Components.Settings;
|
||||||
|
|
||||||
|
public partial class SettingsPanelChat : SettingsPanelBase;
|
@ -0,0 +1,51 @@
|
|||||||
|
@inherits SettingsPanelBase
|
||||||
|
|
||||||
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Person4" HeaderText="@T("Configure Profiles")">
|
||||||
|
<MudText Typo="Typo.h4" Class="mb-3">
|
||||||
|
@T("Your Profiles")
|
||||||
|
</MudText>
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
@T("Store personal data about yourself in various profiles so that the AIs know your personal context. This saves you from having to explain your context each time, for example, in every chat. When you have different roles, you can create a profile for each role.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
@T("Are you a project manager in a research facility? You might want to create a profile for your project management activities, one for your scientific work, and a profile for when you need to write program 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" Hover="@true" Class="border-dashed border rounded-lg">
|
||||||
|
<ColGroup>
|
||||||
|
<col style="width: 3em;"/>
|
||||||
|
<col/>
|
||||||
|
<col style="width: 16em;"/>
|
||||||
|
</ColGroup>
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>#</MudTh>
|
||||||
|
<MudTh>@T("Profile Name")</MudTh>
|
||||||
|
<MudTh>@T("Actions")</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd>@context.Num</MudTd>
|
||||||
|
<MudTd>@context.Name</MudTd>
|
||||||
|
<MudTd>
|
||||||
|
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
||||||
|
<MudTooltip Text="@T("Edit")">
|
||||||
|
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditProfile(context)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
<MudTooltip Text="@T("Delete")">
|
||||||
|
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteProfile(context)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
|
||||||
|
@if(this.SettingsManager.ConfigurationData.Profiles.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h6" Class="mt-3">
|
||||||
|
@T("No profiles configured yet.")
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddProfile">
|
||||||
|
@T("Add Profile")
|
||||||
|
</MudButton>
|
||||||
|
</ExpansionPanel>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user