mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-23 16:54:59 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c08881784d | ||
|
|
05544eca15 | ||
|
|
baa80beb92 | ||
|
|
801179e835 | ||
|
|
e3110820d2 | ||
|
|
e11c15dbab | ||
|
|
fc7a4391cb | ||
|
|
d2f85f31ea | ||
|
|
9e207974e9 | ||
|
|
df062ae6e6 | ||
|
|
35eebc08a5 | ||
|
|
206706f77a | ||
|
|
d87df5b044 | ||
|
|
b9b850b2c1 | ||
|
|
9aa0a91465 | ||
|
|
217d31bc44 | ||
|
|
038ddec46b | ||
|
|
d02efce689 | ||
|
|
2e58ecb97d | ||
|
|
a548cabe24 | ||
|
|
4b2da61a90 | ||
|
|
2ae292009d | ||
|
|
03e196b66f | ||
|
|
4ca1fd54d9 | ||
|
|
c0cf620fe3 | ||
|
|
47a0598e8f | ||
|
|
85a867459e | ||
|
|
ba236c4012 | ||
|
|
9fa0f95611 | ||
|
|
f10d9a5d88 | ||
|
|
1a4e4781cd | ||
|
|
99b4d616c7 | ||
|
|
ace125d7cb | ||
|
|
d6af5a3afd | ||
|
|
07b858fd72 | ||
|
|
5d7949211f | ||
|
|
c23f0f49f9 | ||
|
|
7a08baf99b | ||
|
|
cfc2103b43 | ||
|
|
f8dbc186fb | ||
|
|
6041b42510 | ||
|
|
10dc03f33b | ||
|
|
437ea2c243 | ||
|
|
b0d4615506 | ||
|
|
c4d9af18cd | ||
|
|
9996b810e2 | ||
|
|
53ec4c2162 | ||
|
|
38facf3e04 | ||
|
|
68404199ba | ||
|
|
08b8f42c25 | ||
|
|
3c41fe2771 |
No files matched your search
@@ -167,6 +167,12 @@ jobs:
|
|||||||
sed -i '' "10s/.*/${{ matrix.dotnet_runtime }}/" metadata.txt
|
sed -i '' "10s/.*/${{ matrix.dotnet_runtime }}/" metadata.txt
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Next line is the necessary PDFium version.
|
||||||
|
# The format is '137.0.7123.0'. What we need
|
||||||
|
# is the '7123' part:
|
||||||
|
pdfium_version=$(sed -n '11p' metadata.txt)
|
||||||
|
pdfium_version=$(echo $pdfium_version | cut -d'.' -f3)
|
||||||
|
|
||||||
# Write the metadata to the environment:
|
# Write the metadata to the environment:
|
||||||
echo "APP_VERSION=${app_version}" >> $GITHUB_ENV
|
echo "APP_VERSION=${app_version}" >> $GITHUB_ENV
|
||||||
echo "FORMATTED_APP_VERSION=${formatted_app_version}" >> $GITHUB_ENV
|
echo "FORMATTED_APP_VERSION=${formatted_app_version}" >> $GITHUB_ENV
|
||||||
@@ -178,6 +184,7 @@ jobs:
|
|||||||
echo "MUD_BLAZOR_VERSION=${mud_blazor_version}" >> $GITHUB_ENV
|
echo "MUD_BLAZOR_VERSION=${mud_blazor_version}" >> $GITHUB_ENV
|
||||||
echo "TAURI_VERSION=${tauri_version}" >> $GITHUB_ENV
|
echo "TAURI_VERSION=${tauri_version}" >> $GITHUB_ENV
|
||||||
echo "ARCHITECTURE=${{ matrix.dotnet_runtime }}" >> $GITHUB_ENV
|
echo "ARCHITECTURE=${{ matrix.dotnet_runtime }}" >> $GITHUB_ENV
|
||||||
|
echo "PDFIUM_VERSION=${pdfium_version}" >> $GITHUB_ENV
|
||||||
|
|
||||||
# Log the metadata:
|
# Log the metadata:
|
||||||
echo "App version: '${formatted_app_version}'"
|
echo "App version: '${formatted_app_version}'"
|
||||||
@@ -189,6 +196,7 @@ jobs:
|
|||||||
echo "MudBlazor version: '${mud_blazor_version}'"
|
echo "MudBlazor version: '${mud_blazor_version}'"
|
||||||
echo "Tauri version: '${tauri_version}'"
|
echo "Tauri version: '${tauri_version}'"
|
||||||
echo "Architecture: '${{ matrix.dotnet_runtime }}'"
|
echo "Architecture: '${{ matrix.dotnet_runtime }}'"
|
||||||
|
echo "PDFium version: '${pdfium_version}'"
|
||||||
|
|
||||||
- name: Read and format metadata (Windows)
|
- name: Read and format metadata (Windows)
|
||||||
if: matrix.platform == 'windows-latest'
|
if: matrix.platform == 'windows-latest'
|
||||||
@@ -227,6 +235,12 @@ jobs:
|
|||||||
# Write the changed metadata back to the file:
|
# Write the changed metadata back to the file:
|
||||||
Set-Content -Path metadata.txt -Value $metadata
|
Set-Content -Path metadata.txt -Value $metadata
|
||||||
|
|
||||||
|
# Next line is the necessary PDFium version.
|
||||||
|
# The format is '137.0.7123.0'. What we need
|
||||||
|
# is the '7123' part:
|
||||||
|
$pdfium_version = $metadata[10]
|
||||||
|
$pdfium_version = $pdfium_version.Split('.')[2]
|
||||||
|
|
||||||
# Write the metadata to the environment:
|
# Write the metadata to the environment:
|
||||||
Write-Output "APP_VERSION=${app_version}" >> $env:GITHUB_ENV
|
Write-Output "APP_VERSION=${app_version}" >> $env:GITHUB_ENV
|
||||||
Write-Output "FORMATTED_APP_VERSION=${formatted_app_version}" >> $env:GITHUB_ENV
|
Write-Output "FORMATTED_APP_VERSION=${formatted_app_version}" >> $env:GITHUB_ENV
|
||||||
@@ -237,6 +251,7 @@ jobs:
|
|||||||
Write-Output "RUST_VERSION=${rust_version}" >> $env:GITHUB_ENV
|
Write-Output "RUST_VERSION=${rust_version}" >> $env:GITHUB_ENV
|
||||||
Write-Output "MUD_BLAZOR_VERSION=${mud_blazor_version}" >> $env:GITHUB_ENV
|
Write-Output "MUD_BLAZOR_VERSION=${mud_blazor_version}" >> $env:GITHUB_ENV
|
||||||
Write-Output "ARCHITECTURE=${{ matrix.dotnet_runtime }}" >> $env:GITHUB_ENV
|
Write-Output "ARCHITECTURE=${{ matrix.dotnet_runtime }}" >> $env:GITHUB_ENV
|
||||||
|
Write-Output "PDFIUM_VERSION=${pdfium_version}" >> $env:GITHUB_ENV
|
||||||
|
|
||||||
# Log the metadata:
|
# Log the metadata:
|
||||||
Write-Output "App version: '${formatted_app_version}'"
|
Write-Output "App version: '${formatted_app_version}'"
|
||||||
@@ -248,6 +263,7 @@ jobs:
|
|||||||
Write-Output "MudBlazor version: '${mud_blazor_version}'"
|
Write-Output "MudBlazor version: '${mud_blazor_version}'"
|
||||||
Write-Output "Tauri version: '${tauri_version}'"
|
Write-Output "Tauri version: '${tauri_version}'"
|
||||||
Write-Output "Architecture: '${{ matrix.dotnet_runtime }}'"
|
Write-Output "Architecture: '${{ matrix.dotnet_runtime }}'"
|
||||||
|
Write-Output "PDFium version: '${pdfium_version}'"
|
||||||
|
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v4
|
||||||
@@ -256,6 +272,117 @@ jobs:
|
|||||||
cache: true
|
cache: true
|
||||||
cache-dependency-path: 'app/MindWork AI Studio/packages.lock.json'
|
cache-dependency-path: 'app/MindWork AI Studio/packages.lock.json'
|
||||||
|
|
||||||
|
- name: Deploy PDFium (Unix)
|
||||||
|
if: matrix.platform != 'windows-latest'
|
||||||
|
env:
|
||||||
|
PDFIUM_VERSION: ${{ env.PDFIUM_VERSION }}
|
||||||
|
DOTNET_RUNTIME: ${{ matrix.dotnet_runtime }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Target directory:
|
||||||
|
TLIB_DIR="runtime/resources/libraries"
|
||||||
|
mkdir -p "$TLIB_DIR"
|
||||||
|
|
||||||
|
case "${DOTNET_RUNTIME}" in
|
||||||
|
linux-x64)
|
||||||
|
PDFIUM_FILE="linux-x64.tgz"
|
||||||
|
LIB_SOURCE="lib/libpdfium.so"
|
||||||
|
LIB_TARGET="libpdfium.so"
|
||||||
|
;;
|
||||||
|
linux-arm64)
|
||||||
|
PDFIUM_FILE="linux-arm64.tgz"
|
||||||
|
LIB_SOURCE="lib/libpdfium.so"
|
||||||
|
LIB_TARGET="libpdfium.so"
|
||||||
|
;;
|
||||||
|
osx-x64)
|
||||||
|
PDFIUM_FILE="mac-x64.tgz"
|
||||||
|
LIB_SOURCE="lib/libpdfium.dylib"
|
||||||
|
LIB_TARGET="libpdfium.dylib"
|
||||||
|
;;
|
||||||
|
osx-arm64)
|
||||||
|
PDFIUM_FILE="mac-arm64.tgz"
|
||||||
|
LIB_SOURCE="lib/libpdfium.dylib"
|
||||||
|
LIB_TARGET="libpdfium.dylib"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown platform: ${DOTNET_RUNTIME}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
PDFIUM_URL="https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F${PDFIUM_VERSION}/pdfium-${PDFIUM_FILE}"
|
||||||
|
|
||||||
|
echo "Download PDFium $PDFIUM_URL ..."
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
ARCHIVE="${TMP}/pdfium.tgz"
|
||||||
|
|
||||||
|
curl -fsSL -o "$ARCHIVE" "$PDFIUM_URL"
|
||||||
|
|
||||||
|
echo "Extracting PDFium ..."
|
||||||
|
tar xzf "$ARCHIVE" -C "$TMP"
|
||||||
|
SRC="${TMP}/${LIB_SOURCE}"
|
||||||
|
|
||||||
|
if [ ! -f "$SRC" ]; then
|
||||||
|
echo "Was not able to find PDFium source: $SRC"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Copy PDFium from ${LIB_TARGET} to ${TLIB_DIR}/"
|
||||||
|
cp -f "$SRC" "$TLIB_DIR/$LIB_TARGET"
|
||||||
|
|
||||||
|
echo "Cleaning up ..."
|
||||||
|
rm -fr "$TMP"
|
||||||
|
|
||||||
|
- name: Install PDFium (Windows)
|
||||||
|
if: matrix.platform == 'windows-latest'
|
||||||
|
env:
|
||||||
|
PDFIUM_VERSION: ${{ env.PDFIUM_VERSION }}
|
||||||
|
DOTNET_RUNTIME: ${{ matrix.dotnet_runtime }}
|
||||||
|
run: |
|
||||||
|
$TLIB_DIR = "runtime\resources\libraries"
|
||||||
|
New-Item -ItemType Directory -Force -Path $TLIB_DIR | Out-Null
|
||||||
|
|
||||||
|
switch ($env:DOTNET_RUNTIME) {
|
||||||
|
"win-x64" {
|
||||||
|
$PDFIUM_FILE = "win-x64.tgz"
|
||||||
|
$LIB_SOURCE = "bin\pdfium.dll"
|
||||||
|
$LIB_TARGET = "pdfium.dll"
|
||||||
|
}
|
||||||
|
"win-arm64" {
|
||||||
|
$PDFIUM_FILE = "win-arm64.tgz"
|
||||||
|
$LIB_SOURCE = "bin\pdfium.dll"
|
||||||
|
$LIB_TARGET = "pdfium.dll"
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Error "Unknown platform: $($env:DOTNET_RUNTIME)"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$PDFIUM_URL = "https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$($env:PDFIUM_VERSION)/pdfium-$PDFIUM_FILE"
|
||||||
|
Write-Host "Download $PDFIUM_URL ..."
|
||||||
|
$TMP = New-TemporaryFile | Split-Path
|
||||||
|
$ARCHIVE = Join-Path $TMP "pdfium.tgz"
|
||||||
|
|
||||||
|
Invoke-WebRequest -Uri $PDFIUM_URL -OutFile $ARCHIVE
|
||||||
|
|
||||||
|
Write-Host "Extracting PDFium ..."
|
||||||
|
tar -xzf $ARCHIVE -C $TMP
|
||||||
|
|
||||||
|
$SRC = Join-Path $TMP $LIB_SOURCE
|
||||||
|
if (!(Test-Path $SRC)) {
|
||||||
|
Write-Error "Cannot find PDFium source: $SRC"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$DEST = Join-Path $TLIB_DIR $LIB_TARGET
|
||||||
|
Copy-Item -Path $SRC -Destination $DEST -Force
|
||||||
|
|
||||||
|
Write-Host "Cleaning up ..."
|
||||||
|
Remove-Item $ARCHIVE -Force
|
||||||
|
Remove-Item $TMP -Recurse -Force
|
||||||
|
|
||||||
- name: Build .NET project
|
- name: Build .NET project
|
||||||
run: |
|
run: |
|
||||||
cd "app/MindWork AI Studio"
|
cd "app/MindWork AI Studio"
|
||||||
@@ -298,13 +425,13 @@ jobs:
|
|||||||
if: matrix.platform == 'ubuntu-22.04' && contains(matrix.rust_target, 'x86_64')
|
if: matrix.platform == 'ubuntu-22.04' && contains(matrix.rust_target, 'x86_64')
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
sudo apt-get install -y libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libfuse2
|
||||||
|
|
||||||
- name: Setup dependencies (Ubuntu-specific, ARM)
|
- name: Setup dependencies (Ubuntu-specific, ARM)
|
||||||
if: matrix.platform == 'ubuntu-22.04-arm' && contains(matrix.rust_target, 'aarch64')
|
if: matrix.platform == 'ubuntu-22.04-arm' && contains(matrix.rust_target, 'aarch64')
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
sudo apt-get install -y libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libfuse2
|
||||||
|
|
||||||
- name: Setup Tauri (Unix)
|
- name: Setup Tauri (Unix)
|
||||||
if: matrix.platform != 'windows-latest'
|
if: matrix.platform != 'windows-latest'
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
# Ignore any startup.env file:
|
||||||
|
startup.env
|
||||||
|
|
||||||
|
# Ignore pdfium library:
|
||||||
|
libpdfium.dylib
|
||||||
|
libpdfium.so
|
||||||
|
libpdfium.dll
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ 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))~~
|
||||||
- [ ] 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))~~
|
- [ ] 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))~~
|
||||||
- [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))~~
|
||||||
- [ ] Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430))
|
- [ ] 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)~~)
|
||||||
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations
|
- [ ] 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,6 +47,7 @@ Other News:
|
|||||||
|
|
||||||
Features we have recently released:
|
Features we have recently released:
|
||||||
|
|
||||||
|
- 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.
|
||||||
@@ -55,7 +56,6 @@ Features we have recently released:
|
|||||||
- 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.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?
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Tauri Dev" type="ShConfigurationType">
|
<configuration default="false" name="[1] Start Tauri" type="ShConfigurationType">
|
||||||
<option name="SCRIPT_TEXT" value="cargo tauri dev --no-watch" />
|
<option name="SCRIPT_TEXT" value="cargo tauri dev --no-watch" />
|
||||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||||
<option name="SCRIPT_PATH" value="" />
|
<option name="SCRIPT_PATH" value="" />
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="[2] Start .NET Server" type="DotNetProject" factoryName=".NET Project">
|
||||||
|
<option name="EXE_PATH" value="$PROJECT_DIR$/MindWork AI Studio/bin/Debug/net9.0/osx-arm64/mindworkAIStudio" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/MindWork AI Studio" />
|
||||||
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="ENV_FILE_PATHS" value="" />
|
||||||
|
<option name="REDIRECT_INPUT_PATH" value="" />
|
||||||
|
<option name="PTY_MODE" value="Auto" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
|
<option name="AUTO_ATTACH_CHILDREN" value="0" />
|
||||||
|
<option name="MIXED_MODE_DEBUG" value="0" />
|
||||||
|
<option name="RUNTIME_TYPE" value="coreclr" />
|
||||||
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/MindWork AI Studio/MindWork AI Studio.csproj" />
|
||||||
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
|
<option name="PROJECT_TFM" value="net9.0" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Build" />
|
||||||
|
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Collect I18N content" run_configuration_type="ShConfigurationType" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -17,5 +17,10 @@ public sealed class CheckRidsCommand
|
|||||||
{
|
{
|
||||||
Console.WriteLine($"- {rid}");
|
Console.WriteLine($"- {rid}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
Console.WriteLine("The RID for the current OS and CPU is:");
|
||||||
|
var currentRid = Environment.GetCurrentRid();
|
||||||
|
Console.WriteLine($"- {currentRid}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,29 @@ namespace Build.Commands;
|
|||||||
|
|
||||||
public sealed partial class CollectI18NKeysCommand
|
public sealed partial class CollectI18NKeysCommand
|
||||||
{
|
{
|
||||||
|
private const string START_TAG1 = """
|
||||||
|
T("
|
||||||
|
""";
|
||||||
|
|
||||||
|
private const string START_TAG2 = """
|
||||||
|
TB("
|
||||||
|
""";
|
||||||
|
|
||||||
|
private const string START_TAG3 = """
|
||||||
|
T(@"
|
||||||
|
""";
|
||||||
|
|
||||||
|
private const string END_TAG = """
|
||||||
|
")
|
||||||
|
""";
|
||||||
|
|
||||||
|
private static readonly (string Tag, int Length)[] START_TAGS =
|
||||||
|
[
|
||||||
|
(START_TAG1, START_TAG1.Length),
|
||||||
|
(START_TAG2, START_TAG2.Length),
|
||||||
|
(START_TAG3, START_TAG3.Length)
|
||||||
|
];
|
||||||
|
|
||||||
[Command("collect-i18n", Description = "Collect I18N keys")]
|
[Command("collect-i18n", Description = "Collect I18N keys")]
|
||||||
public async Task CollectI18NKeys()
|
public async Task CollectI18NKeys()
|
||||||
{
|
{
|
||||||
@@ -133,36 +156,22 @@ public sealed partial class CollectI18NKeysCommand
|
|||||||
|
|
||||||
private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)
|
private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)
|
||||||
{
|
{
|
||||||
const string START_TAG1 = """
|
|
||||||
T("
|
|
||||||
""";
|
|
||||||
|
|
||||||
const string START_TAG2 = """
|
|
||||||
TB("
|
|
||||||
""";
|
|
||||||
|
|
||||||
const string END_TAG = """
|
|
||||||
")
|
|
||||||
""";
|
|
||||||
|
|
||||||
(int Index, int Len) FindNextStart(ReadOnlySpan<char> content)
|
(int Index, int Len) FindNextStart(ReadOnlySpan<char> content)
|
||||||
{
|
{
|
||||||
var startIdx1 = content.IndexOf(START_TAG1);
|
var bestIndex = -1;
|
||||||
var startIdx2 = content.IndexOf(START_TAG2);
|
var bestLength = 0;
|
||||||
|
|
||||||
if (startIdx1 == -1 && startIdx2 == -1)
|
foreach (var (tag, length) in START_TAGS)
|
||||||
return (-1, 0);
|
{
|
||||||
|
var index = content.IndexOf(tag);
|
||||||
|
if (index != -1 && (bestIndex == -1 || index < bestIndex))
|
||||||
|
{
|
||||||
|
bestIndex = index;
|
||||||
|
bestLength = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (startIdx1 == -1)
|
return (bestIndex, bestLength);
|
||||||
return (startIdx2, START_TAG2.Length);
|
|
||||||
|
|
||||||
if (startIdx2 == -1)
|
|
||||||
return (startIdx1, START_TAG1.Length);
|
|
||||||
|
|
||||||
if (startIdx1 < startIdx2)
|
|
||||||
return (startIdx1, START_TAG1.Length);
|
|
||||||
|
|
||||||
return (startIdx2, START_TAG2.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches = new List<string>();
|
var matches = new List<string>();
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Build.Commands;
|
||||||
|
|
||||||
|
public record Library(string Path, string Filename);
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
using System.Formats.Tar;
|
||||||
|
using System.IO.Compression;
|
||||||
|
|
||||||
|
using SharedTools;
|
||||||
|
|
||||||
|
namespace Build.Commands;
|
||||||
|
|
||||||
|
public static class Pdfium
|
||||||
|
{
|
||||||
|
public static async Task InstallAsync(RID rid, string version)
|
||||||
|
{
|
||||||
|
Console.Write($"- Installing Pdfium {version} for {rid.ToUserFriendlyName()} ...");
|
||||||
|
|
||||||
|
var cwd = Environment.GetRustRuntimeDirectory();
|
||||||
|
var pdfiumTmpDownloadPath = Path.GetTempFileName();
|
||||||
|
var pdfiumTmpExtractPath = Directory.CreateTempSubdirectory();
|
||||||
|
var pdfiumUrl = GetPdfiumDownloadUrl(rid, version);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Download the file:
|
||||||
|
//
|
||||||
|
Console.Write(" downloading ...");
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var response = await client.GetAsync(pdfiumUrl);
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Console.WriteLine($" failed to download Pdfium {version} for {rid.ToUserFriendlyName()} from {pdfiumUrl}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var fileStream = File.Create(pdfiumTmpDownloadPath);
|
||||||
|
await response.Content.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extract the downloaded file:
|
||||||
|
//
|
||||||
|
Console.Write(" extracting ...");
|
||||||
|
await using(var tgzStream = File.Open(pdfiumTmpDownloadPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
|
{
|
||||||
|
await using var uncompressedStream = new GZipStream(tgzStream, CompressionMode.Decompress);
|
||||||
|
await TarFile.ExtractToDirectoryAsync(uncompressedStream, pdfiumTmpExtractPath.FullName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the library to the target directory:
|
||||||
|
//
|
||||||
|
Console.Write(" deploying ...");
|
||||||
|
var library = GetLibraryPath(rid);
|
||||||
|
if (string.IsNullOrEmpty(library.Path))
|
||||||
|
{
|
||||||
|
Console.WriteLine($" failed to find the library path for {rid.ToUserFriendlyName()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pdfiumLibSourcePath = Path.Join(pdfiumTmpExtractPath.FullName, library.Path);
|
||||||
|
var pdfiumLibTargetPath = Path.Join(cwd, "resources", "libraries", library.Filename);
|
||||||
|
if (!File.Exists(pdfiumLibSourcePath))
|
||||||
|
{
|
||||||
|
Console.WriteLine($" failed to find the library file '{pdfiumLibSourcePath}'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.CreateDirectory(Path.Join(cwd, "resources", "libraries"));
|
||||||
|
if (File.Exists(pdfiumLibTargetPath))
|
||||||
|
File.Delete(pdfiumLibTargetPath);
|
||||||
|
|
||||||
|
File.Copy(pdfiumLibSourcePath, pdfiumLibTargetPath);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup:
|
||||||
|
//
|
||||||
|
Console.Write(" cleaning up ...");
|
||||||
|
File.Delete(pdfiumTmpDownloadPath);
|
||||||
|
Directory.Delete(pdfiumTmpExtractPath.FullName, true);
|
||||||
|
|
||||||
|
Console.WriteLine(" done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Library GetLibraryPath(RID rid) => rid switch
|
||||||
|
{
|
||||||
|
RID.LINUX_ARM64 or RID.LINUX_X64 => new(Path.Join("lib", "libpdfium.so"), "libpdfium.so"),
|
||||||
|
RID.OSX_ARM64 or RID.OSX_X64 => new(Path.Join("lib", "libpdfium.dylib"), "libpdfium.dylib"),
|
||||||
|
RID.WIN_ARM64 or RID.WIN_X64 => new(Path.Join("bin", "pdfium.dll"), "pdfium.dll"),
|
||||||
|
|
||||||
|
_ => new(string.Empty, string.Empty),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string GetPdfiumDownloadUrl(RID rid, string version)
|
||||||
|
{
|
||||||
|
var baseUrl = $"https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F{version}/pdfium-";
|
||||||
|
return rid switch
|
||||||
|
{
|
||||||
|
RID.LINUX_ARM64 => $"{baseUrl}linux-arm64.tgz",
|
||||||
|
RID.LINUX_X64 => $"{baseUrl}linux-x64.tgz",
|
||||||
|
|
||||||
|
RID.OSX_ARM64 => $"{baseUrl}mac-arm64.tgz",
|
||||||
|
RID.OSX_X64 => $"{baseUrl}mac-x64.tgz",
|
||||||
|
|
||||||
|
RID.WIN_ARM64 => $"{baseUrl}win-arm64.tgz",
|
||||||
|
RID.WIN_X64 => $"{baseUrl}win-x64.tgz",
|
||||||
|
|
||||||
|
_ => string.Empty,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,13 +105,15 @@ public sealed partial class UpdateMetadataCommands
|
|||||||
// Build the .NET project:
|
// Build the .NET project:
|
||||||
//
|
//
|
||||||
var pathApp = Environment.GetAIStudioDirectory();
|
var pathApp = Environment.GetAIStudioDirectory();
|
||||||
var rids = Environment.GetRidsForCurrentOS();
|
var rid = Environment.GetCurrentRid();
|
||||||
foreach (var rid in rids)
|
|
||||||
{
|
|
||||||
Console.WriteLine("==============================");
|
Console.WriteLine("==============================");
|
||||||
await this.UpdateArchitecture(rid);
|
await this.UpdateArchitecture(rid);
|
||||||
|
|
||||||
Console.Write($"- Start .NET build for '{rid.AsMicrosoftRid()}' ...");
|
var pdfiumVersion = await this.ReadPdfiumVersion();
|
||||||
|
await Pdfium.InstallAsync(rid, pdfiumVersion);
|
||||||
|
|
||||||
|
Console.Write($"- Start .NET build for {rid.ToUserFriendlyName()} ...");
|
||||||
await this.ReadCommandOutput(pathApp, "dotnet", $"clean --configuration release --runtime {rid.AsMicrosoftRid()}");
|
await this.ReadCommandOutput(pathApp, "dotnet", $"clean --configuration release --runtime {rid.AsMicrosoftRid()}");
|
||||||
var dotnetBuildOutput = await this.ReadCommandOutput(pathApp, "dotnet", $"publish --configuration release --runtime {rid.AsMicrosoftRid()} --disable-build-servers --force");
|
var dotnetBuildOutput = await this.ReadCommandOutput(pathApp, "dotnet", $"publish --configuration release --runtime {rid.AsMicrosoftRid()} --disable-build-servers --force");
|
||||||
var dotnetBuildOutputLines = dotnetBuildOutput.Split([global::System.Environment.NewLine], StringSplitOptions.RemoveEmptyEntries);
|
var dotnetBuildOutputLines = dotnetBuildOutput.Split([global::System.Environment.NewLine], StringSplitOptions.RemoveEmptyEntries);
|
||||||
@@ -196,14 +198,9 @@ public sealed partial class UpdateMetadataCommands
|
|||||||
Console.WriteLine($" - Error: {e.Message}");
|
Console.WriteLine($" - Error: {e.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build the Rust project / runtime:
|
// Build the Rust project / runtime:
|
||||||
//
|
//
|
||||||
|
|
||||||
Console.WriteLine("==============================");
|
|
||||||
Console.WriteLine("- Start building the Rust runtime ...");
|
Console.WriteLine("- Start building the Rust runtime ...");
|
||||||
|
|
||||||
var pathRuntime = Environment.GetRustRuntimeDirectory();
|
var pathRuntime = Environment.GetRustRuntimeDirectory();
|
||||||
@@ -315,13 +312,25 @@ public sealed partial class UpdateMetadataCommands
|
|||||||
Console.WriteLine(" done.");
|
Console.WriteLine(" done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<string> ReadPdfiumVersion()
|
||||||
|
{
|
||||||
|
const int PDFIUM_VERSION_INDEX = 10;
|
||||||
|
|
||||||
|
var pathMetadata = Environment.GetMetadataPath();
|
||||||
|
var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8);
|
||||||
|
var currentPdfiumVersion = lines[PDFIUM_VERSION_INDEX].Trim();
|
||||||
|
var shortVersion = currentPdfiumVersion.Split('.')[2];
|
||||||
|
|
||||||
|
return shortVersion;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UpdateArchitecture(RID rid)
|
private async Task UpdateArchitecture(RID rid)
|
||||||
{
|
{
|
||||||
const int ARCHITECTURE_INDEX = 9;
|
const int ARCHITECTURE_INDEX = 9;
|
||||||
|
|
||||||
var pathMetadata = Environment.GetMetadataPath();
|
var pathMetadata = Environment.GetMetadataPath();
|
||||||
var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8);
|
var lines = await File.ReadAllLinesAsync(pathMetadata, Encoding.UTF8);
|
||||||
Console.Write("- Updating architecture ...");
|
Console.Write($"- Updating architecture to {rid.ToUserFriendlyName()} ...");
|
||||||
lines[ARCHITECTURE_INDEX] = rid.AsMicrosoftRid();
|
lines[ARCHITECTURE_INDEX] = rid.AsMicrosoftRid();
|
||||||
|
|
||||||
await File.WriteAllLinesAsync(pathMetadata, lines, Environment.UTF8_NO_BOM);
|
await File.WriteAllLinesAsync(pathMetadata, lines, Environment.UTF8_NO_BOM);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public sealed class UpdateWebAssetsCommand
|
|||||||
Console.WriteLine("=========================");
|
Console.WriteLine("=========================");
|
||||||
Console.Write("- Updating web assets ...");
|
Console.Write("- Updating web assets ...");
|
||||||
|
|
||||||
var rid = Environment.GetRidsForCurrentOS().First();
|
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"));
|
||||||
|
|||||||
@@ -76,4 +76,38 @@ public static class Environment
|
|||||||
Console.WriteLine($"Error: Unsupported OS '{RuntimeInformation.OSDescription}'");
|
Console.WriteLine($"Error: Unsupported OS '{RuntimeInformation.OSDescription}'");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RID GetCurrentRid()
|
||||||
|
{
|
||||||
|
var arch = RuntimeInformation.ProcessArchitecture;
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
|
return arch switch
|
||||||
|
{
|
||||||
|
Architecture.X64 => RID.WIN_X64,
|
||||||
|
Architecture.Arm64 => RID.WIN_ARM64,
|
||||||
|
|
||||||
|
_ => RID.NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||||
|
return arch switch
|
||||||
|
{
|
||||||
|
Architecture.X64 => RID.OSX_X64,
|
||||||
|
Architecture.Arm64 => RID.OSX_ARM64,
|
||||||
|
|
||||||
|
_ => RID.NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||||
|
return arch switch
|
||||||
|
{
|
||||||
|
Architecture.X64 => RID.LINUX_X64,
|
||||||
|
Architecture.Arm64 => RID.LINUX_ARM64,
|
||||||
|
|
||||||
|
_ => RID.NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
Console.WriteLine($"Error: Unsupported OS '{RuntimeInformation.OSDescription}'");
|
||||||
|
return RID.NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<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>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PDF/@EntryIndexedValue">PDF</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAG/@EntryIndexedValue">RAG</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAG/@EntryIndexedValue">RAG</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RID/@EntryIndexedValue">RID</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RID/@EntryIndexedValue">RID</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TB/@EntryIndexedValue">TB</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TB/@EntryIndexedValue">TB</s:String>
|
||||||
|
|||||||
@@ -1,51 +1,55 @@
|
|||||||
@attribute [Route(Routes.ASSISTANT_AGENDA)]
|
@attribute [Route(Routes.ASSISTANT_AGENDA)]
|
||||||
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogAgenda>
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogAgenda>
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.inputName" Validation="@this.ValidateName" Label="Meeting Name" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Tag" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Name the meeting, seminar, etc." Placeholder="Weekly jour fixe" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputName" Validation="@this.ValidateName" Label="@T("Meeting Name")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Tag" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Name the meeting, seminar, etc.")" Placeholder="@T("Weekly jour fixe")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputTopic" Validation="@this.ValidateTopic" Label="Topic" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.EventNote" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Describe the topic of the meeting, seminar, etc. Is it about quantum computing, software engineering, or is it a general business meeting?" Placeholder="Project meeting" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputTopic" Validation="@this.ValidateTopic" Label="@T("Topic")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.EventNote" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the topic of the meeting, seminar, etc. Is it about quantum computing, software engineering, or is it a general business meeting?")" Placeholder="@T("Project meeting")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputContent" Validation="@this.ValidateContent" Label="Content list" Variant="Variant.Outlined" Lines="6" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Bullet list the content of the meeting, seminar, etc. roughly. Use dashes (-) to separate the items." Placeholder="@PLACEHOLDER_CONTENT" Class="mb-3" Immediate="@false" DebounceInterval="1_000" OnDebounceIntervalElapsed="@this.OnContentChanged" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt"/>
|
<DebouncedTextField @bind-Text="@this.inputContent" ValidationFunc="@this.ValidateContent" DebounceTime="TimeSpan.FromSeconds(1)" Label="@T("Content list")" Lines="6" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the meeting, seminar, etc. roughly. Use dashes (-) to separate the items.")" Placeholder="@PLACEHOLDER_CONTENT" WhenTextCanged="@this.OnContentChanged" Icon="@Icons.Material.Filled.ListAlt"/>
|
||||||
<MudSelect T="string" Label="(Optional) What topics should be the focus?" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
<MudSelect T="string" Label="@T("(Optional) What topics should be the focus?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
||||||
@foreach (var contentLine in this.contentLines)
|
@foreach (var contentLine in this.contentLines)
|
||||||
{
|
{
|
||||||
@if(!this.justBriefly.Contains(contentLine))
|
@if(!this.justBriefly.Contains(contentLine))
|
||||||
{
|
{
|
||||||
<MudSelectItem T="string" Value="@contentLine">@contentLine</MudSelectItem>
|
<MudSelectItem T="string" Value="@contentLine">
|
||||||
|
@contentLine
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
<MudSelect T="string" Label="(Optional) What topics should only be briefly addressed?" MultiSelection="@true" @bind-SelectedValues="@this.justBriefly" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
<MudSelect T="string" Label="@T("(Optional) What topics should only be briefly addressed?")" MultiSelection="@true" @bind-SelectedValues="@this.justBriefly" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
||||||
@foreach (var contentLine in this.contentLines)
|
@foreach (var contentLine in this.contentLines)
|
||||||
{
|
{
|
||||||
@if(!this.selectedFoci.Contains(contentLine))
|
@if(!this.selectedFoci.Contains(contentLine))
|
||||||
{
|
{
|
||||||
<MudSelectItem T="string" Value="@contentLine">@contentLine</MudSelectItem>
|
<MudSelectItem T="string" Value="@contentLine">
|
||||||
|
@contentLine
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.inputObjective" Validation="@this.ValidateObjective" Label="Objective" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Flag" Variant="Variant.Outlined" Lines="3" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Describe the objective(s) of the meeting, seminar, etc. What should be achieved?" Placeholder="Discuss the current project status and plan the next steps." Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputObjective" Validation="@this.ValidateObjective" Label="@T("Objective")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Flag" Variant="Variant.Outlined" Lines="3" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the objective(s) of the meeting, seminar, etc. What should be achieved?")" Placeholder="@T("Discuss the current project status and plan the next steps.")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputModerator" Validation="@this.ValidateModerator" Label="Moderator" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person3" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Who will moderate the meeting, seminar, etc.?" Placeholder="Jane Doe" Class="mb-3" />
|
<MudTextField T="string" @bind-Text="@this.inputModerator" Validation="@this.ValidateModerator" Label="@T("Moderator")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person3" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Who will moderate the meeting, seminar, etc.?")" Placeholder="Jane Doe" Class="mb-3" />
|
||||||
<MudTextField T="string" @bind-Text="@this.inputDuration" Validation="@this.ValidateDuration" Label="Duration" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="How long will the meeting, seminar, etc. last? E.g., '2 hours', or '2 days (first day 8 hours, then 4 hours)', etc." Placeholder="2 hours" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputDuration" Validation="@this.ValidateDuration" Label="@T("Duration")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("How long will the meeting, seminar, etc. last? E.g., '2 hours', or '2 days (first day 8 hours, then 4 hours)', etc.")" Placeholder="@T("2 hours")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputStartTime" Validation="@this.ValidateStartTime" Label="Start time" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="When will the meeting, seminar, etc. start? E.g., '9:00 AM', or '9:00 AM (CET)', etc. When the meeting is a multi-day event, specify the start time for each day." Placeholder="9:00 AM" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputStartTime" Validation="@this.ValidateStartTime" Label="Start time" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("When will the meeting, seminar, etc. start? E.g., '9:00 AM', or '9:00 AM (CET)', etc. When the meeting is a multi-day event, specify the start time for each day.")" Placeholder="@T("9:00 AM")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputWhoIsPresenting" Label="(Optional) Who is presenting?" Variant="Variant.Outlined" Lines="6" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="(Optional) List the persons who will present at the meeting, seminar, etc. Use dashes (-) to separate the items." Placeholder="@PLACEHOLDER_WHO_IS_PRESENTING" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputWhoIsPresenting" Label="@T("(Optional) Who is presenting?")" Variant="Variant.Outlined" Lines="6" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("(Optional) List the persons who will present at the meeting, seminar, etc. Use dashes (-) to separate the items.")" Placeholder="@PLACEHOLDER_WHO_IS_PRESENTING" Class="mb-3"/>
|
||||||
<MudTextSwitch Label="Do the participants need to get to know each other first?" @bind-Value="@this.introduceParticipants" LabelOn="Yes, introduce participants" LabelOff="No, participants know each other" />
|
<MudTextSwitch Label="@T("Do the participants need to get to know each other first?")" @bind-Value="@this.introduceParticipants" LabelOn="@T("Yes, introduce participants")" LabelOff="@T("No, participants know each other")" />
|
||||||
<EnumSelection T="NumberParticipants" @bind-Value="@this.numberParticipants" NameFunc="@(participants => participants.Name())" Icon="@Icons.Material.Filled.Group" Label="Number of participants" ValidateSelection="@this.ValidateNumberParticipants"/>
|
<EnumSelection T="NumberParticipants" @bind-Value="@this.numberParticipants" NameFunc="@(participants => participants.Name())" Icon="@Icons.Material.Filled.Group" Label="@T("Number of participants")" ValidateSelection="@this.ValidateNumberParticipants"/>
|
||||||
<MudTextSwitch Label="Should the participants be involved passively or actively?" @bind-Value="@this.activeParticipation" LabelOn="Active participation, like world café, discussions, etc." LabelOff="Passive participation, like presentations, lectures, etc." />
|
<MudTextSwitch Label="@T("Should the participants be involved passively or actively?")" @bind-Value="@this.activeParticipation" LabelOn="@T("Active participation, like world café, discussions, etc.")" LabelOff="@T("Passive participation, like presentations, lectures, etc.")" />
|
||||||
<MudTextSwitch Label="Is this a virtual event, e.g., a call or webinar?" @bind-Value="@this.isMeetingVirtual" LabelOn="Yes, this is a virtual event" LabelOff="No, this is a physical event" />
|
<MudTextSwitch Label="@T("Is this a virtual event, e.g., a call or webinar?")" @bind-Value="@this.isMeetingVirtual" LabelOn="@T("Yes, this is a virtual event")" LabelOff="@T("No, this is a physical event")" />
|
||||||
@if (!this.isMeetingVirtual)
|
@if (!this.isMeetingVirtual)
|
||||||
{
|
{
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<MudTextField T="string" @bind-Text="@this.inputLocation" Validation="@this.ValidateLocation" Label="Location" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.MyLocation" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Where will the meeting, seminar, etc. take place?" Placeholder="Hamburg, Germany" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputLocation" Validation="@this.ValidateLocation" Label="@T("Location")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.MyLocation" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Where will the meeting, seminar, etc. take place?")" Placeholder="@T("Hamburg, Germany")" Class="mb-3"/>
|
||||||
<MudTextSwitch Label="Should there be a joint dinner?" @bind-Value="@this.goingToDinner" LabelOn="Yes, there should be a joint dinner" LabelOff="No, there should be no joint dinner" />
|
<MudTextSwitch Label="@T("Should there be a joint dinner?")" @bind-Value="@this.goingToDinner" LabelOn="@T("Yes, there should be a joint dinner")" LabelOff="@T("No, there should be no joint dinner")" />
|
||||||
<MudTextSwitch Label="Should there be a social activity?" @bind-Value="@this.doingSocialActivity" LabelOn="Yes, there should be a social activity" LabelOff="No, there should be no social activity" />
|
<MudTextSwitch Label="@T("Should there be a social activity?")" @bind-Value="@this.doingSocialActivity" LabelOn="@T("Yes, there should be a social activity")" LabelOff="@T("No, there should be no social activity")" />
|
||||||
<MudTextSwitch Label="Do participants need to arrive and depart?" @bind-Value="@this.needToArriveAndDepart" LabelOn="Yes, participants need to arrive and depart" LabelOff="No, participants do not need to arrive and depart" />
|
<MudTextSwitch Label="@T("Do participants need to arrive and depart?")" @bind-Value="@this.needToArriveAndDepart" LabelOn="@T("Yes, participants need to arrive and depart")" LabelOff="@T("No, participants do not need to arrive and depart")" />
|
||||||
<MudStack Row="@true" Wrap="Wrap.Wrap">
|
<MudStack Row="@true" Wrap="Wrap.Wrap">
|
||||||
<MudTextSlider T="int" Label="Approx. duration of the lunch break" @bind-Value="@this.durationLunchBreak" Min="30" Max="120" Step="5" Unit="minutes"/>
|
<MudTextSlider T="int" Label="@T("Approx. duration of the lunch break")" @bind-Value="@this.durationLunchBreak" Min="30" Max="120" Step="5" Unit="@T("minutes")"/>
|
||||||
<MudTextSlider T="int" Label="Approx. duration of the coffee or tea breaks" @bind-Value="@this.durationBreaks" Min="10" Max="60" Step="5" Unit="minutes"/>
|
<MudTextSlider T="int" Label="@T("Approx. duration of the coffee or tea breaks")" @bind-Value="@this.durationBreaks" Min="10" Max="60" Step="5" Unit="@T("minutes")"/>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
}
|
}
|
||||||
|
|
||||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom target language" />
|
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" 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")" />
|
||||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||||
@@ -9,14 +9,9 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
{
|
{
|
||||||
public override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.AGENDA_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => "Agenda Planner";
|
protected override string Title => T("Agenda Planner");
|
||||||
|
|
||||||
protected override string Description =>
|
protected override string Description => T("This agenda planner helps you create a structured agenda for your meeting or seminar. Just provide some basic information about the event, and the assistant will generate an agenda for you. You can also specify the duration, the start time, the location, the target language, and other details.");
|
||||||
"""
|
|
||||||
This agenda planner helps you create a structured agenda for your meeting or seminar. Just provide some basic
|
|
||||||
information about the event, and the assistant will generate an agenda for you. You can also specify the
|
|
||||||
duration, the start time, the location, the target language, and other details.
|
|
||||||
""";
|
|
||||||
|
|
||||||
protected override string SystemPrompt =>
|
protected override string SystemPrompt =>
|
||||||
$"""
|
$"""
|
||||||
@@ -98,7 +93,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
|
|
||||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
protected override string SubmitText => "Create Agenda";
|
protected override string SubmitText => T("Create Agenda");
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.CreateAgenda;
|
protected override Func<Task> SubmitAction => this.CreateAgenda;
|
||||||
|
|
||||||
@@ -235,7 +230,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateLocation(string location)
|
private string? ValidateLocation(string location)
|
||||||
{
|
{
|
||||||
if(!this.isMeetingVirtual && string.IsNullOrWhiteSpace(location))
|
if(!this.isMeetingVirtual && string.IsNullOrWhiteSpace(location))
|
||||||
return "Please provide a location for the meeting or the seminar.";
|
return T("Please provide a location for the meeting or the seminar.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -243,7 +238,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateNumberParticipants(NumberParticipants selectedSize)
|
private string? ValidateNumberParticipants(NumberParticipants selectedSize)
|
||||||
{
|
{
|
||||||
if(selectedSize is NumberParticipants.NOT_SPECIFIED)
|
if(selectedSize is NumberParticipants.NOT_SPECIFIED)
|
||||||
return "Please select the number of participants.";
|
return T("Please select the number of participants.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -251,7 +246,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateTargetLanguage(CommonLanguages language)
|
private string? ValidateTargetLanguage(CommonLanguages language)
|
||||||
{
|
{
|
||||||
if(language is CommonLanguages.AS_IS)
|
if(language is CommonLanguages.AS_IS)
|
||||||
return "Please select a target language for the agenda.";
|
return T("Please select a target language for the agenda.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -259,7 +254,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateDuration(string duration)
|
private string? ValidateDuration(string duration)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(duration))
|
if(string.IsNullOrWhiteSpace(duration))
|
||||||
return "Please provide a duration for the meeting or the seminar, e.g. '2 hours', or '2 days (8 hours and 4 hours)', etc.";
|
return T("Please provide a duration for the meeting or the seminar, e.g. '2 hours', or '2 days (8 hours and 4 hours)', etc.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -267,7 +262,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateStartTime(string startTime)
|
private string? ValidateStartTime(string startTime)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(startTime))
|
if(string.IsNullOrWhiteSpace(startTime))
|
||||||
return "Please provide a start time for the meeting or the seminar. When the meeting is a multi-day event, specify the start time for each day, e.g. '9:00 AM, 10:00 AM', etc.";
|
return T("Please provide a start time for the meeting or the seminar. When the meeting is a multi-day event, specify the start time for each day, e.g. '9:00 AM, 10:00 AM', etc.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -275,7 +270,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
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 "Please provide a custom language.";
|
return T("Please provide a custom language.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -283,7 +278,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateTopic(string topic)
|
private string? ValidateTopic(string topic)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(topic))
|
if(string.IsNullOrWhiteSpace(topic))
|
||||||
return "Please provide a topic for the agenda. What is the meeting or the seminar about?";
|
return T("Please provide a topic for the agenda. What is the meeting or the seminar about?");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -291,7 +286,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateName(string name)
|
private string? ValidateName(string name)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(name))
|
if(string.IsNullOrWhiteSpace(name))
|
||||||
return "Please provide a name for the meeting or the seminar.";
|
return T("Please provide a name for the meeting or the seminar.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -299,12 +294,12 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateContent(string content)
|
private string? ValidateContent(string content)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(content))
|
if(string.IsNullOrWhiteSpace(content))
|
||||||
return "Please provide some content for the agenda. What are the main points of the meeting or the seminar?";
|
return T("Please provide some content for the agenda. What are the main points of the meeting or the seminar?");
|
||||||
|
|
||||||
var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||||
foreach (var line in lines)
|
foreach (var line in lines)
|
||||||
if(!line.TrimStart().StartsWith('-'))
|
if(!line.TrimStart().StartsWith('-'))
|
||||||
return "Please start each line of your content list with a dash (-) to create a bullet point list.";
|
return T("Please start each line of your content list with a dash (-) to create a bullet point list.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -312,7 +307,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateObjective(string objective)
|
private string? ValidateObjective(string objective)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(objective))
|
if(string.IsNullOrWhiteSpace(objective))
|
||||||
return "Please provide an objective for the meeting or the seminar. What do you want to achieve?";
|
return T("Please provide an objective for the meeting or the seminar. What do you want to achieve?");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -320,7 +315,7 @@ public partial class AssistantAgenda : AssistantBaseCore<SettingsDialogAgenda>
|
|||||||
private string? ValidateModerator(string moderator)
|
private string? ValidateModerator(string moderator)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(moderator))
|
if(string.IsNullOrWhiteSpace(moderator))
|
||||||
return "Please provide a moderator for the meeting or the seminar. Who will lead the discussion?";
|
return T("Please provide a moderator for the meeting or the seminar. Who will lead the discussion?");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,20 @@
|
|||||||
|
|
||||||
<div class="inner-scrolling-context">
|
<div class="inner-scrolling-context">
|
||||||
|
|
||||||
<MudText Typo="Typo.h3" Class="mb-2 mr-3">
|
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2 mr-3" StretchItems="StretchItems.Start">
|
||||||
|
<MudText Typo="Typo.h3">
|
||||||
@(this.Title)
|
@(this.Title)
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
|
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="() => 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">
|
||||||
<MudGrid Class="mb-2">
|
<MudText Typo="Typo.body1" Align="Align.Justify" 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ 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;
|
||||||
@@ -115,6 +116,7 @@ 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()
|
||||||
@@ -144,7 +146,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
protected string? ValidatingProvider(AIStudio.Settings.Provider provider)
|
protected string? ValidatingProvider(AIStudio.Settings.Provider provider)
|
||||||
{
|
{
|
||||||
if(provider.UsedLLMProvider == LLMProviders.NONE)
|
if(provider.UsedLLMProvider == LLMProviders.NONE)
|
||||||
return "Please select a provider.";
|
return this.TB("Please select a provider.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
SystemPrompt = this.SystemPrompt,
|
SystemPrompt = this.SystemPrompt,
|
||||||
WorkspaceId = Guid.Empty,
|
WorkspaceId = Guid.Empty,
|
||||||
ChatId = Guid.NewGuid(),
|
ChatId = Guid.NewGuid(),
|
||||||
Name = string.Format(T("Assistant - {0}"), this.Title),
|
Name = string.Format(this.TB("Assistant - {0}"), this.Title),
|
||||||
Seed = this.RNG.Next(),
|
Seed = this.RNG.Next(),
|
||||||
Blocks = [],
|
Blocks = [],
|
||||||
};
|
};
|
||||||
@@ -242,6 +244,9 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
|
|
||||||
protected async Task<string> AddAIResponseAsync(DateTimeOffset time, bool hideContentFromUser = false)
|
protected async Task<string> AddAIResponseAsync(DateTimeOffset time, bool hideContentFromUser = false)
|
||||||
{
|
{
|
||||||
|
var manageCancellationLocally = this.cancellationTokenSource is null;
|
||||||
|
this.cancellationTokenSource ??= new CancellationTokenSource();
|
||||||
|
|
||||||
var aiText = new ContentText
|
var aiText = new ContentText
|
||||||
{
|
{
|
||||||
// We have to wait for the remote
|
// We have to wait for the remote
|
||||||
@@ -275,6 +280,12 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
|
|||||||
this.isProcessing = false;
|
this.isProcessing = false;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
|
||||||
|
if(manageCancellationLocally)
|
||||||
|
{
|
||||||
|
this.cancellationTokenSource.Dispose();
|
||||||
|
this.cancellationTokenSource = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the AI response:
|
// Return the AI response:
|
||||||
return aiText.Text;
|
return aiText.Text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
<b>Links:</b>
|
<b>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://en.wikipedia.org/wiki/List_of_cognitive_biases">Wikipedia list of cognitive biases</MudListItem>
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://en.wikipedia.org/wiki/List_of_cognitive_biases">@T("Wikipedia list of cognitive biases")</MudListItem>
|
||||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">Extended bias poster</MudListItem>
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">@T("Extended bias poster")</MudListItem>
|
||||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">Blog post of Buster Benson: "Cognitive bias cheat sheet"</MudListItem>
|
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">@T("Blog post of Buster Benson:") "Cognitive bias cheat sheet"</MudListItem>
|
||||||
</MudList>
|
</MudList>
|
||||||
|
|
||||||
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom target language" />
|
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" 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")" />
|
||||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
|
||||||
@@ -10,18 +10,9 @@ public partial class BiasOfTheDayAssistant : AssistantBaseCore<SettingsDialogAss
|
|||||||
{
|
{
|
||||||
public override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT;
|
public override Tools.Components Component => Tools.Components.BIAS_DAY_ASSISTANT;
|
||||||
|
|
||||||
protected override string Title => "Bias of the Day";
|
protected override string Title => T("Bias of the Day");
|
||||||
|
|
||||||
protected override string Description =>
|
protected override string Description => T("""Learn about a different cognitive bias every day. You can also ask the LLM your questions. The idea behind "Bias of the Day" is based on work by Buster Benson, John Manoogian III, and Brian Rene Morrissette. Buster Benson grouped the biases, and the original texts come from Wikipedia. Brian Rene Morrissette condensed them into a shorter version. Finally, John Manoogian III created the original poster based on Benson's work and Morrissette's texts. Thorsten Sommer compared all texts for integration into AI Studio with the current Wikipedia versions, updated them, and added source references. The idea of learning about one bias each day based on John's poster comes from Drew Nelson.""");
|
||||||
"""
|
|
||||||
Learn about a different cognitive bias every day. You can also ask the LLM your questions. The idea behind
|
|
||||||
"Bias of the Day" is based on work by Buster Benson, John Manoogian III, and Brian Rene Morrissette. Buster
|
|
||||||
Benson grouped the biases, and the original texts come from Wikipedia. Brian Rene Morrissette condensed them
|
|
||||||
into a shorter version. Finally, John Manoogian III created the original poster based on Benson's work and
|
|
||||||
Morrissette's texts. Thorsten Sommer compared all texts for integration into AI Studio with the current Wikipedia
|
|
||||||
versions, updated them, and added source references. The idea of learning about one bias each day based on John's
|
|
||||||
poster comes from Drew Nelson.
|
|
||||||
""";
|
|
||||||
|
|
||||||
protected override string SystemPrompt => $"""
|
protected override string SystemPrompt => $"""
|
||||||
You are a friendly, helpful expert on cognitive bias. You studied psychology and
|
You are a friendly, helpful expert on cognitive bias. You studied psychology and
|
||||||
@@ -41,7 +32,7 @@ public partial class BiasOfTheDayAssistant : AssistantBaseCore<SettingsDialogAss
|
|||||||
|
|
||||||
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
protected override IReadOnlyList<IButtonData> FooterButtons => [];
|
||||||
|
|
||||||
protected override string SubmitText => "Show me the bias of the day";
|
protected override string SubmitText => T("Show me the bias of the day");
|
||||||
|
|
||||||
protected override Func<Task> SubmitAction => this.TellBias;
|
protected override Func<Task> SubmitAction => this.TellBias;
|
||||||
|
|
||||||
@@ -79,7 +70,7 @@ public partial class BiasOfTheDayAssistant : AssistantBaseCore<SettingsDialogAss
|
|||||||
private string? ValidateTargetLanguage(CommonLanguages language)
|
private string? ValidateTargetLanguage(CommonLanguages language)
|
||||||
{
|
{
|
||||||
if(language is CommonLanguages.AS_IS)
|
if(language is CommonLanguages.AS_IS)
|
||||||
return "Please select a target language for the bias.";
|
return T("Please select a target language for the bias.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -87,7 +78,7 @@ public partial class BiasOfTheDayAssistant : AssistantBaseCore<SettingsDialogAss
|
|||||||
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 "Please provide a custom language.";
|
return T("Please provide a custom language.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="@T("(Optional) The greeting phrase to use")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="@T("Dear Colleagues")" Class="mb-3"/>
|
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="@T("(Optional) The greeting phrase to use")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="@T("Dear Colleagues")" Class="mb-3"/>
|
||||||
<MudTextField T="string" @bind-Text="@this.inputBulletPoints" Validation="@this.ValidateBulletPoints" AdornmentIcon="@Icons.Material.Filled.ListAlt" Adornment="Adornment.Start" Label="@T("Your bullet points")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items.")" Immediate="@false" DebounceInterval="1_000" OnDebounceIntervalElapsed="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
|
<DebouncedTextField @bind-Text="@this.inputBulletPoints" ValidationFunc="@this.ValidateBulletPoints" Icon="@Icons.Material.Filled.ListAlt" Label="@T("Your bullet points")" Lines="6" MaxLines="12" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items.")" DebounceTime="TimeSpan.FromSeconds(1)" WhenTextCanged="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
|
||||||
<MudSelect T="string" Label="@T("(Optional) Are any of your points particularly important?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
<MudSelect T="string" Label="@T("(Optional) Are any of your points particularly important?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
|
||||||
@foreach (var contentLine in this.bulletPointsLines)
|
@foreach (var contentLine in this.bulletPointsLines)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,14 +2,16 @@ namespace AIStudio.Assistants.EMail;
|
|||||||
|
|
||||||
public static class WritingStylesExtensions
|
public static class WritingStylesExtensions
|
||||||
{
|
{
|
||||||
|
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(WritingStylesExtensions).Namespace, nameof(WritingStylesExtensions));
|
||||||
|
|
||||||
public static string Name(this WritingStyles style) => style switch
|
public static string Name(this WritingStyles style) => style switch
|
||||||
{
|
{
|
||||||
WritingStyles.ACADEMIC => "Academic",
|
WritingStyles.ACADEMIC => TB("Academic"),
|
||||||
WritingStyles.PERSONAL => "Personal",
|
WritingStyles.PERSONAL => TB("Personal"),
|
||||||
WritingStyles.BUSINESS_FORMAL => "Business formal",
|
WritingStyles.BUSINESS_FORMAL => TB("Business formal"),
|
||||||
WritingStyles.BUSINESS_INFORMAL => "Business informal",
|
WritingStyles.BUSINESS_INFORMAL => TB("Business informal"),
|
||||||
|
|
||||||
_ => "Not specified",
|
_ => TB("Not specified"),
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Prompt(this WritingStyles style) => style switch
|
public static string Prompt(this WritingStyles style) => style switch
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
|||||||
var filePath = Path.Join(Environment.CurrentDirectory, "Assistants", "I18N");
|
var filePath = Path.Join(Environment.CurrentDirectory, "Assistants", "I18N");
|
||||||
var resourceFileProvider = new PhysicalFileProvider(filePath);
|
var resourceFileProvider = new PhysicalFileProvider(filePath);
|
||||||
#else
|
#else
|
||||||
var resourceFileProvider = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "Assistants.I18N");
|
var resourceFileProvider = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "Assistants/I18N");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var file = resourceFileProvider.GetFileInfo("allTexts.lua");
|
var file = resourceFileProvider.GetFileInfo("allTexts.lua");
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -6,6 +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)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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"/>
|
||||||
@@ -2,12 +2,14 @@ namespace AIStudio.Assistants.RewriteImprove;
|
|||||||
|
|
||||||
public static class SentenceStructureExtensions
|
public static class SentenceStructureExtensions
|
||||||
{
|
{
|
||||||
|
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(SentenceStructureExtensions).Namespace, nameof(SentenceStructureExtensions));
|
||||||
|
|
||||||
public static string Name(this SentenceStructure sentenceStructure) => sentenceStructure switch
|
public static string Name(this SentenceStructure sentenceStructure) => sentenceStructure switch
|
||||||
{
|
{
|
||||||
SentenceStructure.ACTIVE => "Active voice",
|
SentenceStructure.ACTIVE => TB("Active voice"),
|
||||||
SentenceStructure.PASSIVE => "Passive voice",
|
SentenceStructure.PASSIVE => TB("Passive voice"),
|
||||||
|
|
||||||
_ => "Not Specified",
|
_ => TB("Not Specified"),
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Prompt(this SentenceStructure sentenceStructure) => sentenceStructure switch
|
public static string Prompt(this SentenceStructure sentenceStructure) => sentenceStructure switch
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ public enum WritingStyles
|
|||||||
MARKETING,
|
MARKETING,
|
||||||
ACADEMIC,
|
ACADEMIC,
|
||||||
LEGAL,
|
LEGAL,
|
||||||
|
CHANGELOG,
|
||||||
}
|
}
|
||||||
@@ -2,19 +2,22 @@ namespace AIStudio.Assistants.RewriteImprove;
|
|||||||
|
|
||||||
public static class WritingStylesExtensions
|
public static class WritingStylesExtensions
|
||||||
{
|
{
|
||||||
|
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(WritingStylesExtensions).Namespace, nameof(WritingStylesExtensions));
|
||||||
|
|
||||||
public static string Name(this WritingStyles style) => style switch
|
public static string Name(this WritingStyles style) => style switch
|
||||||
{
|
{
|
||||||
WritingStyles.EVERYDAY => "Everyday (personal texts, social media)",
|
WritingStyles.EVERYDAY => TB("Everyday (personal texts, social media)"),
|
||||||
WritingStyles.BUSINESS => "Business (business emails, reports, presentations)",
|
WritingStyles.BUSINESS => TB("Business (business emails, reports, presentations)"),
|
||||||
WritingStyles.SCIENTIFIC => "Scientific (scientific papers, research reports)",
|
WritingStyles.SCIENTIFIC => TB("Scientific (scientific papers, research reports)"),
|
||||||
WritingStyles.JOURNALISTIC => "Journalistic (magazines, newspapers, news)",
|
WritingStyles.JOURNALISTIC => TB("Journalistic (magazines, newspapers, news)"),
|
||||||
WritingStyles.LITERARY => "Literary (fiction, poetry)",
|
WritingStyles.LITERARY => TB("Literary (fiction, poetry)"),
|
||||||
WritingStyles.TECHNICAL => "Technical (manuals, documentation)",
|
WritingStyles.TECHNICAL => TB("Technical (manuals, documentation)"),
|
||||||
WritingStyles.MARKETING => "Marketing (advertisements, sales texts)",
|
WritingStyles.MARKETING => TB("Marketing (advertisements, sales texts)"),
|
||||||
WritingStyles.ACADEMIC => "Academic (essays, seminar papers)",
|
WritingStyles.ACADEMIC => TB("Academic (essays, seminar papers)"),
|
||||||
WritingStyles.LEGAL => "Legal (legal texts, contracts)",
|
WritingStyles.LEGAL => TB("Legal (legal texts, contracts)"),
|
||||||
|
WritingStyles.CHANGELOG => TB("Changelog (release notes, version history)"),
|
||||||
|
|
||||||
_ => "Not specified",
|
_ => TB("Not specified"),
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Prompt(this WritingStyles style) => style switch
|
public static string Prompt(this WritingStyles style) => style switch
|
||||||
@@ -28,6 +31,7 @@ public static class WritingStylesExtensions
|
|||||||
WritingStyles.MARKETING => "Use a marketing style like for advertisements, sales texts, and promotional content. Most important is persuasiveness and engagement.",
|
WritingStyles.MARKETING => "Use a marketing style like for advertisements, sales texts, and promotional content. Most important is persuasiveness and engagement.",
|
||||||
WritingStyles.ACADEMIC => "Use a academic style like for essays, seminar papers, and academic writing. Most important is clarity and objectivity.",
|
WritingStyles.ACADEMIC => "Use a academic style like for essays, seminar papers, and academic writing. Most important is clarity and objectivity.",
|
||||||
WritingStyles.LEGAL => "Use a legal style like for legal texts, contracts, and official documents. Most important is precision and legal correctness. Use formal legal language.",
|
WritingStyles.LEGAL => "Use a legal style like for legal texts, contracts, and official documents. Most important is precision and legal correctness. Use formal legal language.",
|
||||||
|
WritingStyles.CHANGELOG => "Use a changelog style like for release notes, version history, and software updates. Most important is clarity and conciseness. The changelog is structured as a Markdown list. Most list items start with one of the following verbs: Added, Changed, Deprecated, Removed, Fixed, Refactored, Improved, or Upgraded -- these verbs should also translated to the target language. Also, changelogs use past tense.",
|
||||||
|
|
||||||
_ => "Keep the style of the text as it is.",
|
_ => "Keep the style of the text as it is.",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +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)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
|||||||
@@ -2,18 +2,20 @@ namespace AIStudio.Assistants.TextSummarizer;
|
|||||||
|
|
||||||
public static class ComplexityExtensions
|
public static class ComplexityExtensions
|
||||||
{
|
{
|
||||||
|
private static string TB(string fallbackEN) => Tools.PluginSystem.I18N.I.T(fallbackEN, typeof(ComplexityExtensions).Namespace, nameof(ComplexityExtensions));
|
||||||
|
|
||||||
public static string Name(this Complexity complexity) => complexity switch
|
public static string Name(this Complexity complexity) => complexity switch
|
||||||
{
|
{
|
||||||
Complexity.NO_CHANGE => "No change in complexity",
|
Complexity.NO_CHANGE => TB("No change in complexity"),
|
||||||
|
|
||||||
Complexity.SIMPLE_LANGUAGE => "Simple language, e.g., for children",
|
Complexity.SIMPLE_LANGUAGE => TB("Simple language, e.g., for children"),
|
||||||
Complexity.TEEN_LANGUAGE => "Teen language, e.g., for teenagers",
|
Complexity.TEEN_LANGUAGE => TB("Teen language, e.g., for teenagers"),
|
||||||
Complexity.EVERYDAY_LANGUAGE => "Everyday language, e.g., for adults",
|
Complexity.EVERYDAY_LANGUAGE => TB("Everyday language, e.g., for adults"),
|
||||||
Complexity.POPULAR_SCIENCE_LANGUAGE => "Popular science language, e.g., for people interested in science",
|
Complexity.POPULAR_SCIENCE_LANGUAGE => TB("Popular science language, e.g., for people interested in science"),
|
||||||
Complexity.SCIENTIFIC_LANGUAGE_FIELD_EXPERTS => "Scientific language for experts in this field",
|
Complexity.SCIENTIFIC_LANGUAGE_FIELD_EXPERTS => TB("Scientific language for experts in this field"),
|
||||||
Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS => "Scientific language for experts from other fields (interdisciplinary)",
|
Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS => TB("Scientific language for experts from other fields (interdisciplinary)"),
|
||||||
|
|
||||||
_ => "No change in complexity",
|
_ => TB("No change in complexity"),
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Prompt(this Complexity complexity, string expertInField) => complexity switch
|
public static string Prompt(this Complexity complexity, string expertInField) => complexity switch
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
<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)"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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)
|
||||||
{
|
{
|
||||||
<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" Immediate="@true" DebounceInterval="@this.SettingsManager.ConfigurationData.Translation.DebounceIntervalMilliseconds" OnDebounceIntervalElapsed="() => this.TranslateText(force: false)" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
|
<DebouncedTextField Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" ValidationFunc="@this.ValidatingText" Icon="@Icons.Material.Filled.DocumentScanner" Label="@T("Your input")" Lines="6" MaxLines="12" DebounceTime="@TimeSpan.FromMilliseconds(this.SettingsManager.ConfigurationData.Translation.DebounceIntervalMilliseconds)" WhenTextChangedAsync="async _ => await this.TranslateText(force: false)" Attributes="@USER_INPUT_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,51 +13,3 @@ 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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace AIStudio.Chat;
|
||||||
|
|
||||||
|
public static class ChatRoles
|
||||||
|
{
|
||||||
|
public static IEnumerable<ChatRole> ChatTemplateRoles()
|
||||||
|
{
|
||||||
|
yield return ChatRole.USER;
|
||||||
|
yield return ChatRole.AI;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,11 @@ 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>
|
||||||
@@ -70,6 +75,8 @@ 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>
|
||||||
@@ -84,16 +91,51 @@ 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 chatTeamplateId))
|
||||||
|
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(chatThread.SelectedChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE.Id || chatTeamplateId == Guid.Empty)
|
||||||
|
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var chatTemplate = settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatThread.SelectedChatTemplate);
|
||||||
|
if(chatTemplate == default)
|
||||||
|
systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logMessage = $"Using chat template '{chatTemplate.Name}' for chat thread '{chatThread.Name}'.";
|
||||||
|
this.allowProfile = chatTemplate.AllowProfileUsage;
|
||||||
|
systemPromptTextWithChatTemplate = chatTemplate.ToSystemPrompt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 => $"""
|
||||||
{chatThread.SystemPrompt}
|
{systemPromptTextWithChatTemplate}
|
||||||
|
|
||||||
{chatThread.AugmentedData}
|
{chatThread.AugmentedData}
|
||||||
""",
|
""",
|
||||||
|
|
||||||
false => chatThread.SystemPrompt,
|
false => systemPromptTextWithChatTemplate,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(isAugmentedDataAvailable)
|
if(isAugmentedDataAvailable)
|
||||||
@@ -101,12 +143,13 @@ 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.");
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare the system prompt:
|
// Add information from the profile if available and allowed:
|
||||||
//
|
//
|
||||||
string systemPromptText;
|
string systemPromptText;
|
||||||
var logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
||||||
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile))
|
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile) || this.allowProfile is false)
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = systemPromptWithAugmentedData;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,15 +18,24 @@ public class ContentBlock
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The content of the block.
|
/// The content of the block.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IContent? Content { get; init; }
|
public IContent? Content { get; set; }
|
||||||
|
|
||||||
/// <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; init; } = ChatRole.NONE;
|
public ChatRole Role { get; set; } = 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; set; }
|
public bool HideFromUser { get; init; }
|
||||||
|
|
||||||
|
public ContentBlock DeepClone() => new()
|
||||||
|
{
|
||||||
|
Time = this.Time,
|
||||||
|
ContentType = this.ContentType,
|
||||||
|
Content = this.Content?.DeepClone(),
|
||||||
|
Role = this.Role,
|
||||||
|
HideFromUser = this.HideFromUser,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -13,11 +13,11 @@ public sealed class ContentImage : IContent, IImageSource
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool InitialRemoteWait { get; set; } = false;
|
public bool InitialRemoteWait { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsStreaming { get; set; } = false;
|
public bool IsStreaming { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@@ -33,6 +33,15 @@ 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>
|
||||||
|
|||||||
@@ -125,6 +125,14 @@ public sealed class ContentText : IContent
|
|||||||
return chatThread;
|
return chatThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IContent DeepClone() => new ContentText
|
||||||
|
{
|
||||||
|
Text = this.Text,
|
||||||
|
InitialRemoteWait = this.InitialRemoteWait,
|
||||||
|
IsStreaming = this.IsStreaming,
|
||||||
|
};
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ 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>
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ public partial class Changelog
|
|||||||
|
|
||||||
public static readonly Log[] LOGS =
|
public static readonly Log[] LOGS =
|
||||||
[
|
[
|
||||||
|
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 (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 (216, "v0.9.41, build 216 (2025-04-27 14:18 UTC)", "v0.9.41.md"),
|
new (216, "v0.9.41, build 216 (2025-04-27 14:18 UTC)", "v0.9.41.md"),
|
||||||
new (215, "v0.9.40, build 215 (2025-04-20 13:30 UTC)", "v0.9.40.md"),
|
new (215, "v0.9.40, build 215 (2025-04-20 13:30 UTC)", "v0.9.40.md"),
|
||||||
new (214, "v0.9.39, build 214 (2025-04-07 17:39 UTC)", "v0.9.39.md"),
|
new (214, "v0.9.39, build 214 (2025-04-07 17:39 UTC)", "v0.9.39.md"),
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<ChatTemplateSelection 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">
|
||||||
@@ -107,7 +108,7 @@
|
|||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged"/>
|
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" Disabled="@(!this.currentChatTemplate.AllowProfileUsage)" DisabledText="@T("Profile usage is disabled according to your chat template settings.")"/>
|
||||||
|
|
||||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ 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!;
|
||||||
@@ -77,6 +78,9 @@ 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);
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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:
|
||||||
@@ -270,7 +274,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
|
|
||||||
private bool CanThreadBeSaved => this.ChatThread is not null && this.ChatThread.Blocks.Count > 0;
|
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);
|
||||||
|
|
||||||
private string UserInputStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.Provider.UsedLLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager) : string.Empty;
|
private string UserInputStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.Provider.UsedLLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager) : string.Empty;
|
||||||
|
|
||||||
@@ -291,6 +295,12 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
// We select the first 10 words of the user input:
|
// We select the first 10 words of the user input:
|
||||||
var words = firstUserInput.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
var words = firstUserInput.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||||
var threadName = string.Join(' ', words.Take(10));
|
var threadName = string.Join(' ', words.Take(10));
|
||||||
|
threadName = threadName.Trim();
|
||||||
|
|
||||||
|
// Remove all line breaks:
|
||||||
|
threadName = threadName.Replace("\r", string.Empty);
|
||||||
|
threadName = threadName.Replace("\n", " ");
|
||||||
|
threadName = threadName.Replace("\t", " ");
|
||||||
|
|
||||||
// If the thread name is empty, we use a default name:
|
// If the thread name is empty, we use a default name:
|
||||||
if (string.IsNullOrWhiteSpace(threadName))
|
if (string.IsNullOrWhiteSpace(threadName))
|
||||||
@@ -313,6 +323,15 @@ 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(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)
|
||||||
@@ -407,13 +426,14 @@ 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 = [],
|
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
|
||||||
@@ -424,9 +444,15 @@ 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 and profile:
|
// Update provider, profile and chat template:
|
||||||
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;
|
||||||
@@ -637,12 +663,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(),
|
||||||
Name = string.Empty,
|
Name = string.Empty,
|
||||||
Seed = this.RNG.Next(),
|
Seed = this.RNG.Next(),
|
||||||
Blocks = [],
|
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,6 +775,7 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -775,6 +803,14 @@ 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))
|
||||||
|
{
|
||||||
|
this.currentChatTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate);
|
||||||
|
if(this.currentChatTemplate == default)
|
||||||
|
this.currentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ToggleWorkspaceOverlay()
|
private async Task ToggleWorkspaceOverlay()
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@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/>
|
||||||
|
@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>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,15 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
|
|
||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class ConfigurationProviderSelection : MSGComponentBase
|
public partial class ConfigurationProviderSelection : MSGComponentBase
|
||||||
{
|
{
|
||||||
|
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ConfigurationProviderSelection).Namespace, nameof(ConfigurationProviderSelection));
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string> SelectedValue { get; set; } = () => string.Empty;
|
public Func<string> SelectedValue { get; set; } = () => string.Empty;
|
||||||
|
|
||||||
@@ -25,7 +27,7 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
|
|||||||
public Func<bool> Disabled { get; set; } = () => false;
|
public Func<bool> Disabled { get; set; } = () => false;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string> HelpText { get; set; } = () => "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;
|
||||||
|
|||||||
@@ -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 Variant="Variant.Filled" Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialog"/>
|
<MudIconButton Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialog"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</CardHeaderContent>
|
</CardHeaderContent>
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@inherits MudComponentBase
|
||||||
|
|
||||||
|
<MudTextField T="string" Disabled="@this.Disabled" Text="@this.text" TextChanged="@this.OnTextChanged" Validation="@this.ValidationFunc" Label="@this.Label" Variant="Variant.Outlined" Lines="@this.Lines" MaxLines="@this.MaxLines" AutoGrow="@(this.MaxLines > this.Lines)" Margin="Margin.Dense" UserAttributes="@this.Attributes" HelperText="@this.HelpText" Placeholder="@this.Placeholder" Class="mb-3" Immediate="true" Adornment="Adornment.Start" AdornmentIcon="@this.Icon"/>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public partial class DebouncedTextField : MudComponentBase
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string Label { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> TextChanged { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Func<string, Task> WhenTextChangedAsync { get; set; } = _ => Task.CompletedTask;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Action<string> WhenTextCanged { get; set; } = _ => { };
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public int Lines { get; set; } = 1;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public int MaxLines { get; set; } = 1;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Dictionary<string, object?> Attributes { get; set; } = [];
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Func<string, string?> ValidationFunc { get; set; } = _ => null;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string HelpText { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Placeholder { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Icon { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public TimeSpan DebounceTime { get; set; } = TimeSpan.FromMilliseconds(800);
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool Disabled { get; set; }
|
||||||
|
|
||||||
|
private readonly Timer debounceTimer = new();
|
||||||
|
private string text = string.Empty;
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
this.text = this.Text;
|
||||||
|
this.debounceTimer.AutoReset = false;
|
||||||
|
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
|
||||||
|
this.debounceTimer.Elapsed += (_, _) =>
|
||||||
|
{
|
||||||
|
this.debounceTimer.Stop();
|
||||||
|
this.InvokeAsync(async () => await this.TextChanged.InvokeAsync(this.text));
|
||||||
|
this.InvokeAsync(async () => await this.WhenTextChangedAsync(this.text));
|
||||||
|
this.InvokeAsync(() => this.WhenTextCanged(this.text));
|
||||||
|
};
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void OnTextChanged(string value)
|
||||||
|
{
|
||||||
|
this.text = value;
|
||||||
|
this.debounceTimer.Stop();
|
||||||
|
this.debounceTimer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
@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,7 +1,10 @@
|
|||||||
|
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
|
||||||
@@ -15,9 +18,18 @@ 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,11 +1,28 @@
|
|||||||
|
@using AIStudio.Settings
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<MudTooltip Text="@T("You can switch between your profiles here")" Placement="Placement.Top">
|
<MudTooltip Text="@this.ToolTipText" 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">
|
<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">
|
||||||
|
<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 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 OnClick="() => this.SelectionChanged(profile)">
|
<MudMenuItem Icon="@Icons.Material.Filled.Person4" OnClick="() => this.SelectionChanged(profile)">
|
||||||
@profile.Name
|
@profile.Name
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
}
|
}
|
||||||
|
</ChildContent>
|
||||||
</MudMenu>
|
</MudMenu>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
@@ -1,11 +1,16 @@
|
|||||||
|
using AIStudio.Dialogs.Settings;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -18,6 +23,19 @@ 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)
|
||||||
@@ -25,4 +43,10 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@inherits MSGComponentBase
|
||||||
|
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="async () => await this.SelectFile()" Variant="Variant.Filled" Class="mb-3">
|
||||||
|
@T("Use PDF content as input")
|
||||||
|
</MudButton>
|
||||||
@@ -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,5 +1,5 @@
|
|||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-3 border-dashed border rounded-lg">
|
||||||
<MudTextSwitch Label="@T("Read content from web?")" Disabled="@this.AgentIsRunning" @bind-Value="@this.showWebContentReader" LabelOn="@T("Show web content options")" LabelOff="@T("Hide web content options")" />
|
<MudTextSwitch Label="@T("Read content from web?")" Disabled="@this.AgentIsRunning" @bind-Value="@this.showWebContentReader" LabelOn="@T("Show web content options")" LabelOff="@T("Hide web content options")" />
|
||||||
@if (this.showWebContentReader)
|
@if (this.showWebContentReader)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
@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>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
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,4 +1,5 @@
|
|||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
using AIStudio.Tools.Rust;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
@@ -22,6 +23,9 @@ public partial class SelectFile : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string FileDialogTitle { get; set; } = "Select File";
|
public string FileDialogTitle { get; set; } = "Select File";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public FileTypeFilter? Filter { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string, string?> Validation { get; set; } = _ => null;
|
public Func<string, string?> Validation { get; set; } = _ => null;
|
||||||
|
|
||||||
@@ -55,7 +59,7 @@ public partial class SelectFile : ComponentBase
|
|||||||
|
|
||||||
private async Task OpenFileDialog()
|
private async Task OpenFileDialog()
|
||||||
{
|
{
|
||||||
var response = await this.RustService.SelectFile(this.FileDialogTitle, string.IsNullOrWhiteSpace(this.File) ? null : this.File);
|
var response = await this.RustService.SelectFile(this.FileDialogTitle, this.Filter, string.IsNullOrWhiteSpace(this.File) ? null : this.File);
|
||||||
this.Logger.LogInformation($"The user selected the file '{response.SelectedFilePath}'.");
|
this.Logger.LogInformation($"The user selected the file '{response.SelectedFilePath}'.");
|
||||||
|
|
||||||
if (!response.UserCancelled)
|
if (!response.UserCancelled)
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
@if (PreviewFeatures.PRE_PLUGINS_2025.IsEnabled(this.SettingsManager))
|
@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.SettingsManager.ConfigurationData.App.LanguageBehavior = 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.SettingsManager.ConfigurationData.App.LanguagePluginId = 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.")"/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
var availablePreviewFeatures = ConfigurationSelectDataFactory.GetPreviewFeaturesData(this.SettingsManager).ToList();
|
var availablePreviewFeatures = ConfigurationSelectDataFactory.GetPreviewFeaturesData(this.SettingsManager).ToList();
|
||||||
if (availablePreviewFeatures.Count > 0)
|
if (availablePreviewFeatures.Count > 0)
|
||||||
{
|
{
|
||||||
<ConfigurationMultiSelect OptionDescription="@T("Select preview features")" SelectedValues="@(() => this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures)" Data="@availablePreviewFeatures" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures = selectedValue)" OptionHelp="@T("Which preview features would you like to enable?")"/>
|
<ConfigurationMultiSelect OptionDescription="@T("Select preview features")" SelectedValues="@(() => this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures.Where(x => !x.IsReleased()).ToHashSet())" Data="@availablePreviewFeatures" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures = selectedValue)" OptionHelp="@T("Which preview features would you like to enable?")"/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,16 @@ public partial class SettingsPanelApp : SettingsPanelBase
|
|||||||
this.SettingsManager.ConfigurationData.App.PreviewVisibility = previewVisibility;
|
this.SettingsManager.ConfigurationData.App.PreviewVisibility = previewVisibility;
|
||||||
this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures = previewVisibility.FilterPreviewFeatures(this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures);
|
this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures = previewVisibility.FilterPreviewFeatures(this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task UpdateLangBehaviour(LangBehavior behavior)
|
||||||
|
{
|
||||||
|
this.SettingsManager.ConfigurationData.App.LanguageBehavior = behavior;
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.PLUGINS_RELOADED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateManuallySelectedLanguage(Guid pluginId)
|
||||||
|
{
|
||||||
|
this.SettingsManager.ConfigurationData.App.LanguagePluginId = pluginId;
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.PLUGINS_RELOADED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
@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>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace AIStudio.Components.Settings;
|
|
||||||
|
|
||||||
public partial class SettingsPanelChat : SettingsPanelBase;
|
|
||||||
@@ -4,24 +4,17 @@
|
|||||||
|
|
||||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||||
{
|
{
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.IntegrationInstructions" HeaderText="Configure Embeddings">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.IntegrationInstructions" HeaderText="@T("Configure Embeddings")">
|
||||||
<PreviewPrototype/>
|
<PreviewPrototype/>
|
||||||
<MudText Typo="Typo.h4" Class="mb-3">
|
<MudText Typo="Typo.h4" Class="mb-3">
|
||||||
Configured Embeddings
|
@T("Configured Embeddings")
|
||||||
</MudText>
|
</MudText>
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
Embeddings are a way to represent words, sentences, entire documents, or even images and videos as digital
|
@T("Embeddings are a way to represent words, sentences, entire documents, or even images and videos as digital fingerprints. Just like each person has a unique fingerprint, embedding models create unique digital patterns that capture the meaning and characteristics of the content they analyze. When two things are similar in meaning or content, their digital fingerprints will look very similar. For example, the fingerprints for 'happy' and 'joyful' would be more alike than those for 'happy' and 'sad'.")
|
||||||
fingerprints. Just like each person has a unique fingerprint, embedding models create unique digital patterns
|
|
||||||
that capture the meaning and characteristics of the content they analyze. When two things are similar in meaning
|
|
||||||
or content, their digital fingerprints will look very similar. For example, the fingerprints for 'happy' and
|
|
||||||
'joyful' would be more alike than those for 'happy' and 'sad'.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
This helps AI Studio understand and compare things in a way that's similar to how humans do. When you're working on
|
@T("This helps AI Studio understand and compare things in a way that's similar to how humans do. When you're working on something, AI Studio can automatically identify related documents and data by comparing their digital fingerprints. For instance, if you're writing about customer service, AI Studio can instantly find other documents in your data that discuss similar topics or experiences, even if they use different words.")
|
||||||
something, AI Studio can automatically identify related documents and data by comparing their digital fingerprints.
|
|
||||||
For instance, if you're writing about customer service, AI Studio can instantly find other documents in your data that
|
|
||||||
discuss similar topics or experiences, even if they use different words.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<MudTable Items="@this.SettingsManager.ConfigurationData.EmbeddingProviders" Hover="@true" Class="border-dashed border rounded-lg">
|
<MudTable Items="@this.SettingsManager.ConfigurationData.EmbeddingProviders" Hover="@true" Class="border-dashed border rounded-lg">
|
||||||
<ColGroup>
|
<ColGroup>
|
||||||
@@ -29,14 +22,14 @@
|
|||||||
<col style="width: 12em;"/>
|
<col style="width: 12em;"/>
|
||||||
<col style="width: 12em;"/>
|
<col style="width: 12em;"/>
|
||||||
<col/>
|
<col/>
|
||||||
<col style="width: 40em;"/>
|
<col style="width: 16em;"/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>#</MudTh>
|
<MudTh>#</MudTh>
|
||||||
<MudTh>Name</MudTh>
|
<MudTh>@T("Name")</MudTh>
|
||||||
<MudTh>Provider</MudTh>
|
<MudTh>@T("Provider")</MudTh>
|
||||||
<MudTh>Model</MudTh>
|
<MudTh>@T("Model")</MudTh>
|
||||||
<MudTh>Actions</MudTh>
|
<MudTh>@T("Actions")</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>@context.Num</MudTd>
|
<MudTd>@context.Num</MudTd>
|
||||||
@@ -46,15 +39,15 @@
|
|||||||
|
|
||||||
<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.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())">
|
<MudTooltip Text="@T("Open Dashboard")">
|
||||||
Open Dashboard
|
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbeddingProvider(context)">
|
<MudTooltip Text="@T("Edit")">
|
||||||
Edit
|
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbeddingProvider(context)"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbeddingProvider(context)">
|
<MudTooltip Text="@T("Delete")">
|
||||||
Delete
|
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbeddingProvider(context)"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
@@ -62,11 +55,13 @@
|
|||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.EmbeddingProviders.Count == 0)
|
@if (this.SettingsManager.ConfigurationData.EmbeddingProviders.Count == 0)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.h6" Class="mt-3">No embeddings configured yet.</MudText>
|
<MudText Typo="Typo.h6" Class="mt-3">
|
||||||
|
@T("No embeddings configured yet.")
|
||||||
|
</MudText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbeddingProvider">
|
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbeddingProvider">
|
||||||
Add Embedding
|
@T("Add Embedding")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
|
|||||||
{ x => x.IsEditing, false },
|
{ x => x.IsEditing, false },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>("Add Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Add Embedding Provider"), 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;
|
||||||
@@ -69,7 +69,7 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
|
|||||||
{ x => x.DataHost, embeddingProvider.Host },
|
{ x => x.DataHost, embeddingProvider.Host },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>("Edit Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Edit Embedding Provider"), 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;
|
||||||
@@ -92,10 +92,10 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
|
|||||||
{
|
{
|
||||||
var dialogParameters = new DialogParameters
|
var dialogParameters = new DialogParameters
|
||||||
{
|
{
|
||||||
{ "Message", $"Are you sure you want to delete the embedding provider '{provider.Name}'?" },
|
{ "Message", string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), 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;
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
@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: 40em;"/>
|
|
||||||
</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">
|
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditProfile(context)">
|
|
||||||
@T("Edit")
|
|
||||||
</MudButton>
|
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteProfile(context)">
|
|
||||||
@T("Delete")
|
|
||||||
</MudButton>
|
|
||||||
</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>
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<col style="width: 12em;"/>
|
<col style="width: 12em;"/>
|
||||||
<col style="width: 12em;"/>
|
<col style="width: 12em;"/>
|
||||||
<col/>
|
<col/>
|
||||||
<col style="width: 34em;"/>
|
<col style="width: 16em;"/>
|
||||||
</ColGroup>
|
</ColGroup>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
<MudTh>#</MudTh>
|
<MudTh>#</MudTh>
|
||||||
@@ -44,16 +44,16 @@
|
|||||||
}
|
}
|
||||||
</MudTd>
|
</MudTd>
|
||||||
<MudTd>
|
<MudTd>
|
||||||
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
<MudStack Row="true" Class="mb-2 mt-2" Spacing="1" Wrap="Wrap.Wrap">
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())">
|
<MudTooltip Text="@T("Open Dashboard")">
|
||||||
@T("Open Dashboard")
|
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditLLMProvider(context)">
|
<MudTooltip Text="@T("Edit")">
|
||||||
@T("Edit")
|
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditLLMProvider(context)"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteLLMProvider(context)">
|
<MudTooltip Text="@T("Delete")">
|
||||||
@T("Delete")
|
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteLLMProvider(context)"/>
|
||||||
</MudButton>
|
</MudTooltip>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
@using AIStudio.Settings
|
|
||||||
@using AIStudio.Settings.DataModel
|
|
||||||
@inherits SettingsPanelBase
|
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Work" HeaderText="@T("Workspace Options")">
|
|
||||||
<ConfigurationSelect OptionDescription="@T("Workspace behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageBehavior = selectedValue)" OptionHelp="@T("Should we store your chats?")"/>
|
|
||||||
|
|
||||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
|
|
||||||
{
|
|
||||||
<ConfigurationSelect OptionDescription="@T("Workspace maintenance")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.StorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="@T("If and when should we delete your temporary chats?")"/>
|
|
||||||
<ConfigurationSelect OptionDescription="@T("Workspace display behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceDisplayBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior = selectedValue)" OptionHelp="@T("How should we display your workspaces?")"/>
|
|
||||||
}
|
|
||||||
</ExpansionPanel>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace AIStudio.Components.Settings;
|
|
||||||
|
|
||||||
public partial class SettingsPanelWorkspaces : SettingsPanelBase;
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<MudListItem T="string" Href="@this.URL" Target="_blank">
|
||||||
|
<AvatarContent>
|
||||||
|
<MudAvatar Variant="Variant.Filled" Size="Size.Large" Style="background-color: white;" Class="mr-6">
|
||||||
|
<MudImage Src="@this.ImageSrc"/>
|
||||||
|
</MudAvatar>
|
||||||
|
</AvatarContent>
|
||||||
|
<ChildContent>
|
||||||
|
<MudText Typo="Typo.h6" Inline="@true">
|
||||||
|
@this.Name
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Class="ml-3" Inline="@true">
|
||||||
|
@this.Acknowledgment
|
||||||
|
</MudText>
|
||||||
|
</ChildContent>
|
||||||
|
</MudListItem>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
public partial class Titan : ComponentBase
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Acknowledgment { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? URL { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public SupporterType Type { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string? ImageSrc { get; set; }
|
||||||
|
}
|
||||||
@@ -344,6 +344,13 @@ public partial class Workspaces : MSGComponentBase
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
chat.Name = (dialogResult.Data as string)!;
|
chat.Name = (dialogResult.Data as string)!;
|
||||||
|
if(this.CurrentChatThread?.ChatId == chat.ChatId)
|
||||||
|
{
|
||||||
|
this.CurrentChatThread.Name = chat.Name;
|
||||||
|
await this.CurrentChatThreadChanged.InvokeAsync(this.CurrentChatThread);
|
||||||
|
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.WORKSPACE_LOADED_CHAT_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
await this.StoreChat(chat);
|
await this.StoreChat(chat);
|
||||||
await this.LoadTreeItems();
|
await this.LoadTreeItems();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
@using AIStudio.Chat
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<DialogContent>
|
||||||
|
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
|
||||||
|
@T("Create your custom chat template to tailor the LLM's behavior for specific tasks or domains. Define a custom system prompt and provide an example conversation to design an AI experience perfectly suited to your requirements.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
|
||||||
|
@T("The name of the chat template is mandatory. Each chat template must have a unique name.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataName"
|
||||||
|
Label="@T("Chat Template Name")"
|
||||||
|
Class="mb-3"
|
||||||
|
Immediate="@true"
|
||||||
|
MaxLength="40"
|
||||||
|
Counter="40"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Badge"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Validation="@this.ValidateName"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h6" Class="mb-3 mt-3">
|
||||||
|
@T("System Prompt")
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataSystemPrompt"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.ListAlt"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
Immediate="@true"
|
||||||
|
Label="@T("What system prompt do you want to use?")"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Lines="6"
|
||||||
|
MaxLines="12"
|
||||||
|
AutoGrow="@true"
|
||||||
|
Class="mb-3"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
HelperText="@T("Tell the AI your system prompt.")"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
|
||||||
|
@T("Are you unsure which system prompt to use? You might start with the default system prompt that AI Studio uses for all chats.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
<MudButton Class="mb-3" Color="Color.Default" OnClick="@this.UseDefaultSystemPrompt" StartIcon="@Icons.Material.Filled.ListAlt" Variant="Variant.Filled">
|
||||||
|
@T("Use the default system prompt")
|
||||||
|
</MudButton>
|
||||||
|
|
||||||
|
<MudJustifiedText Class="mt-6" Typo="Typo.body1">
|
||||||
|
@T("Using some chat templates in tandem with profiles might cause issues. Therefore, you might prohibit the usage of profiles here.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
<MudTextSwitch @bind-Value="@this.AllowProfileUsage" Color="Color.Primary" Label="@T("Allow the use of profiles together with this chat template?")" LabelOn="@T("Yes, allow profiles when using this template")" LabelOff="@T("No, prohibit profile use for this template")" />
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h6" Class="mb-3 mt-6">
|
||||||
|
@T("Example Conversation")
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
@T("Add messages of an example conversation (user prompt followed by assistant prompt) to demonstrate the desired interaction pattern. These examples help the AI understand your expectations by showing it the correct format, style, and content of responses before it receives actual user inputs.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudTable Items="@this.dataExampleConversation" FixedHeader="true" Hover="true" Class="mt-3 mb-3" CanCancelEdit="true" CancelEditTooltip="@T("Cancel")" CommitEditTooltip="@T("Commit Changes")" Outlined="true" RowEditCancel="@this.ResetItem" RowEditPreview="@this.BackupItem" EditTrigger="TableEditTrigger.RowClick" IsEditRowSwitchingBlocked="false" RowEditCommit="@this.CommitInlineEdit">
|
||||||
|
<ColGroup>
|
||||||
|
<col style="width: 10em;" />
|
||||||
|
<col/>
|
||||||
|
<col style="width: 10em;" />
|
||||||
|
</ColGroup>
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>@T("Role")</MudTh>
|
||||||
|
<MudTh>@T("Entry")</MudTh>
|
||||||
|
<MudTh>@T("Actions")</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd>
|
||||||
|
@context.Role.ToChatTemplateName()
|
||||||
|
</MudTd>
|
||||||
|
<MudTd>
|
||||||
|
@switch(context.Content)
|
||||||
|
{
|
||||||
|
case ContentText textContent:
|
||||||
|
<MudTextField AutoGrow="true" Value="@textContent.Text" Placeholder="@T("Enter a message")" ReadOnly="true" Variant="Variant.Text" Validation="@this.ValidateExampleTextMessage"/>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ContentImage { SourceType: ContentImageSource.URL or ContentImageSource.LOCAL_PATH } imageContent:
|
||||||
|
<MudImage Src="@imageContent.Source" Alt="@T("Image content")" Fluid="true" />
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
@T("Unsupported content type")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
</MudTd>
|
||||||
|
<MudTd>
|
||||||
|
@if (!this.isInlineEditOnGoing)
|
||||||
|
{
|
||||||
|
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
|
||||||
|
<MudTooltip Text="@T("Add a new message below")">
|
||||||
|
<MudIconButton Color="Color.Primary" Icon="@Icons.Material.Filled.Add" OnClick="@(() => this.AddMessageBelow(context))"/>
|
||||||
|
</MudTooltip>
|
||||||
|
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => this.RemoveMessage(context))"/>
|
||||||
|
</MudStack>
|
||||||
|
}
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
<RowEditingTemplate>
|
||||||
|
<MudTd>
|
||||||
|
<MudSelect Label="@T("Role")" @bind-Value="@context.Role" Required="true">
|
||||||
|
@foreach (var role in ChatRoles.ChatTemplateRoles())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@role">
|
||||||
|
@role.ToChatTemplateName()
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
</MudTd>
|
||||||
|
<MudTd>
|
||||||
|
@switch(context.Content)
|
||||||
|
{
|
||||||
|
case ContentText textContent:
|
||||||
|
<MudTextField AutoGrow="true" @bind-Value="@textContent.Text" Label="@T("The message")" Required="true" Immediate="true" Placeholder="@T("Enter a message")"/>
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
<MudText Typo="Typo.body2">
|
||||||
|
@T("Only text content is supported in the editing mode yet.")
|
||||||
|
</MudText>
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
</MudTd>
|
||||||
|
</RowEditingTemplate>
|
||||||
|
<PagerContent>
|
||||||
|
<MudTablePager PageSizeOptions="[10,20,50,100]" RowsPerPageString="@T("Messages per page")" />
|
||||||
|
</PagerContent>
|
||||||
|
</MudTable>
|
||||||
|
</MudForm>
|
||||||
|
|
||||||
|
@if (!this.isInlineEditOnGoing)
|
||||||
|
{
|
||||||
|
<MudButton Class="mb-6" Color="Color.Primary" OnClick="@this.AddMessageToEnd" StartIcon="@Icons.Material.Filled.Add" Variant="Variant.Filled">
|
||||||
|
@T("Add a message")
|
||||||
|
</MudButton>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
|
|
||||||
|
@if (!this.isInlineEditOnGoing)
|
||||||
|
{
|
||||||
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
|
@if (this.IsEditing)
|
||||||
|
{
|
||||||
|
@T("Update")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@T("Add")
|
||||||
|
}
|
||||||
|
</MudButton>
|
||||||
|
}
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Settings;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
|
public partial class ChatTemplateDialog : MSGComponentBase
|
||||||
|
{
|
||||||
|
[CascadingParameter]
|
||||||
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The chat template's number in the list.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public uint DataNum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The chat template's ID.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataId { get; set; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The chat template name chosen by the user.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What is the system prompt?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataSystemPrompt { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the dialog be in editing mode?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public IReadOnlyCollection<ContentBlock> ExampleConversation { get; init; } = [];
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool AllowProfileUsage { get; set; } = true;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private ILogger<ChatTemplateDialog> Logger { get; init; } = null!;
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of used chat template names. We need this to check for uniqueness.
|
||||||
|
/// </summary>
|
||||||
|
private List<string> UsedNames { get; set; } = [];
|
||||||
|
|
||||||
|
private bool dataIsValid;
|
||||||
|
private List<ContentBlock> dataExampleConversation = [];
|
||||||
|
private string[] dataIssues = [];
|
||||||
|
private string dataEditingPreviousName = string.Empty;
|
||||||
|
private bool isInlineEditOnGoing;
|
||||||
|
|
||||||
|
private ContentBlock? messageEntryBeforeEdit;
|
||||||
|
|
||||||
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
|
private MudForm form = null!;
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
// Configure the spellchecking for the instance name input:
|
||||||
|
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
||||||
|
|
||||||
|
// Load the used instance names:
|
||||||
|
this.UsedNames = this.SettingsManager.ConfigurationData.ChatTemplates.Select(x => x.Name.ToLowerInvariant()).ToList();
|
||||||
|
|
||||||
|
// When editing, we need to load the data:
|
||||||
|
if(this.IsEditing)
|
||||||
|
{
|
||||||
|
this.dataEditingPreviousName = this.DataName.ToLowerInvariant();
|
||||||
|
this.dataExampleConversation = this.ExampleConversation.Select(n => n.DeepClone()).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
// Reset the validation when not editing and on the first render.
|
||||||
|
// We don't want to show validation errors when the user opens the dialog.
|
||||||
|
if(!this.IsEditing && firstRender)
|
||||||
|
this.form.ResetValidation();
|
||||||
|
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private ChatTemplate CreateChatTemplateSettings() => new()
|
||||||
|
{
|
||||||
|
Num = this.DataNum,
|
||||||
|
Id = this.DataId,
|
||||||
|
|
||||||
|
Name = this.DataName,
|
||||||
|
SystemPrompt = this.DataSystemPrompt,
|
||||||
|
ExampleConversation = this.dataExampleConversation,
|
||||||
|
AllowProfileUsage = this.AllowProfileUsage,
|
||||||
|
};
|
||||||
|
|
||||||
|
private void RemoveMessage(ContentBlock item)
|
||||||
|
{
|
||||||
|
this.dataExampleConversation.Remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddMessageToEnd()
|
||||||
|
{
|
||||||
|
var newEntry = new ContentBlock
|
||||||
|
{
|
||||||
|
Role = this.dataExampleConversation.Count is 0 ? ChatRole.USER : this.dataExampleConversation.Last().Role.SelectNextRoleForTemplate(),
|
||||||
|
Content = new ContentText(),
|
||||||
|
ContentType = ContentType.TEXT,
|
||||||
|
HideFromUser = true,
|
||||||
|
Time = DateTimeOffset.Now,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dataExampleConversation.Add(newEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddMessageBelow(ContentBlock currentItem)
|
||||||
|
{
|
||||||
|
var insertedEntry = new ContentBlock
|
||||||
|
{
|
||||||
|
Role = this.dataExampleConversation.Count is 0 ? ChatRole.USER : this.dataExampleConversation.Last().Role.SelectNextRoleForTemplate(),
|
||||||
|
Content = new ContentText(),
|
||||||
|
ContentType = ContentType.TEXT,
|
||||||
|
HideFromUser = true,
|
||||||
|
Time = DateTimeOffset.Now,
|
||||||
|
};
|
||||||
|
|
||||||
|
// The rest of the method remains the same:
|
||||||
|
var index = this.dataExampleConversation.IndexOf(currentItem);
|
||||||
|
if (index >= 0)
|
||||||
|
this.dataExampleConversation.Insert(index + 1, insertedEntry);
|
||||||
|
else
|
||||||
|
this.dataExampleConversation.Add(insertedEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BackupItem(object? element)
|
||||||
|
{
|
||||||
|
this.isInlineEditOnGoing = true;
|
||||||
|
this.messageEntryBeforeEdit = element switch
|
||||||
|
{
|
||||||
|
ContentBlock block => block.DeepClone(),
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetItem(object? element)
|
||||||
|
{
|
||||||
|
this.isInlineEditOnGoing = false;
|
||||||
|
switch (element)
|
||||||
|
{
|
||||||
|
case ContentBlock block:
|
||||||
|
if (this.messageEntryBeforeEdit is null)
|
||||||
|
return; // No backup to restore from
|
||||||
|
|
||||||
|
block.Content = this.messageEntryBeforeEdit.Content?.DeepClone();
|
||||||
|
block.Role = this.messageEntryBeforeEdit.Role;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CommitInlineEdit(object? element)
|
||||||
|
{
|
||||||
|
this.isInlineEditOnGoing = false;
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Store()
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
|
||||||
|
// When the data is not valid, we don't store it:
|
||||||
|
if (!this.dataIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// When an inline edit is ongoing, we cannot store the data:
|
||||||
|
if (this.isInlineEditOnGoing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Use the data model to store the chat template.
|
||||||
|
// We just return this data to the parent component:
|
||||||
|
var addedChatTemplateSettings = this.CreateChatTemplateSettings();
|
||||||
|
|
||||||
|
if(this.IsEditing)
|
||||||
|
this.Logger.LogInformation($"Edited chat template '{addedChatTemplateSettings.Name}'.");
|
||||||
|
else
|
||||||
|
this.Logger.LogInformation($"Created chat template '{addedChatTemplateSettings.Name}'.");
|
||||||
|
|
||||||
|
this.MudDialog.Close(DialogResult.Ok(addedChatTemplateSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateExampleTextMessage(string message)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
return T("Please enter a message for the example conversation.");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateName(string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
return T("Please enter a name for the chat template.");
|
||||||
|
|
||||||
|
if (name.Length > 40)
|
||||||
|
return T("The chat template name must not exceed 40 characters.");
|
||||||
|
|
||||||
|
// The instance name must be unique:
|
||||||
|
var lowerName = name.ToLowerInvariant();
|
||||||
|
if (lowerName != this.dataEditingPreviousName && this.UsedNames.Contains(lowerName))
|
||||||
|
return T("The chat template name must be unique; the chosen name is already in use.");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UseDefaultSystemPrompt()
|
||||||
|
{
|
||||||
|
this.DataSystemPrompt = SystemPrompts.DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel() => this.MudDialog.Cancel();
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
@@ -7,7 +9,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataName"
|
@bind-Text="@this.dataName"
|
||||||
Label="Data Source Name"
|
Label="@T("Data Source Name")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
MaxLength="40"
|
MaxLength="40"
|
||||||
Counter="40"
|
Counter="40"
|
||||||
@@ -24,7 +26,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataHostname"
|
@bind-Text="@this.dataHostname"
|
||||||
Label="ERI v1 Server Hostname"
|
Label="@T("ERI v1 Server Hostname")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
Immediate="@true"
|
Immediate="@true"
|
||||||
Validation="@this.dataSourceValidation.ValidatingHostname"
|
Validation="@this.dataSourceValidation.ValidatingHostname"
|
||||||
@@ -35,7 +37,7 @@
|
|||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
|
|
||||||
<MudNumericField
|
<MudNumericField
|
||||||
Label="Port"
|
Label="@T("Port")"
|
||||||
Immediate="@true"
|
Immediate="@true"
|
||||||
Min="1" Max="65535"
|
Min="1" Max="65535"
|
||||||
Validation="@this.dataSourceValidation.ValidatePort"
|
Validation="@this.dataSourceValidation.ValidatePort"
|
||||||
@@ -47,9 +49,7 @@
|
|||||||
@if (!this.IsConnectionEncrypted())
|
@if (!this.IsConnectionEncrypted())
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
Please note: the connection to the ERI v1 server is not encrypted. This means that all
|
@T("Please note: the connection to the ERI v1 server is not encrypted. This means that all data sent to the server is transmitted in plain text. Please ask the ERI server administrator to enable encryption.")
|
||||||
data sent to the server is transmitted in plain text. Please ask the ERI server administrator
|
|
||||||
to enable encryption.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
{
|
{
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
||||||
<MudButton Variant="Variant.Filled" Color="@this.GetTestResultColor()" StartIcon="@this.GetTestResultIcon()" Class="mb-3" OnClick="@this.TestConnection">
|
<MudButton Variant="Variant.Filled" Color="@this.GetTestResultColor()" StartIcon="@this.GetTestResultIcon()" Class="mb-3" OnClick="@this.TestConnection">
|
||||||
Test connection & read available metadata
|
@T("Test connection & read available metadata")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
@this.GetTestResultText()
|
@this.GetTestResultText()
|
||||||
@@ -70,7 +70,9 @@
|
|||||||
<MudSelect @bind-Value="@this.dataAuthMethod" Text="@this.dataAuthMethod.DisplayName()" Label="Authentication Method" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateAuthMethod">
|
<MudSelect @bind-Value="@this.dataAuthMethod" Text="@this.dataAuthMethod.DisplayName()" Label="Authentication Method" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateAuthMethod">
|
||||||
@foreach (var authMethod in this.availableAuthMethods)
|
@foreach (var authMethod in this.availableAuthMethods)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@authMethod">@authMethod.DisplayName()</MudSelectItem>
|
<MudSelectItem Value="@authMethod">
|
||||||
|
@authMethod.DisplayName()
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
}
|
}
|
||||||
@@ -83,7 +85,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataUsername"
|
@bind-Text="@this.dataUsername"
|
||||||
Label="Username"
|
Label="@T("Username")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
Immediate="@true"
|
Immediate="@true"
|
||||||
Validation="@this.dataSourceValidation.ValidateUsername"
|
Validation="@this.dataSourceValidation.ValidateUsername"
|
||||||
@@ -94,25 +96,12 @@
|
|||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
<SecretInputField @bind-Secret="@this.dataSecret" Label="@this.GetSecretLabel()" Validation="@this.dataSourceValidation.ValidatingSecret" Class="mb-6"/>
|
||||||
<MudTextField
|
|
||||||
T="string"
|
|
||||||
@bind-Text="@this.dataSecret"
|
|
||||||
Label="@this.GetSecretLabel()"
|
|
||||||
Class="mb-6"
|
|
||||||
Immediate="@true"
|
|
||||||
Validation="@this.dataSourceValidation.ValidatingSecret"
|
|
||||||
Adornment="Adornment.Start"
|
|
||||||
AdornmentIcon="@Icons.Material.Filled.Security"
|
|
||||||
AdornmentColor="Color.Info"
|
|
||||||
Variant="Variant.Text"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.availableRetrievalProcesses.Count > 0)
|
@if (this.availableRetrievalProcesses.Count > 0)
|
||||||
{
|
{
|
||||||
<MudSelect @bind-Value="@this.dataSelectedRetrievalProcess" Text="@this.dataSelectedRetrievalProcess.Name" Label="Select one retrieval process" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateRetrievalProcess">
|
<MudSelect @bind-Value="@this.dataSelectedRetrievalProcess" Text="@this.dataSelectedRetrievalProcess.Name" Label="@T("Select one retrieval process")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateRetrievalProcess">
|
||||||
@foreach (var retrievalProcess in this.availableRetrievalProcesses)
|
@foreach (var retrievalProcess in this.availableRetrievalProcesses)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@retrievalProcess">
|
<MudSelectItem Value="@retrievalProcess">
|
||||||
@@ -122,7 +111,7 @@
|
|||||||
</MudSelect>
|
</MudSelect>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="Your security policy" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="@T("Your security policy")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
||||||
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@policy">
|
<MudSelectItem Value="@policy">
|
||||||
@@ -135,15 +124,17 @@
|
|||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.ERIClient;
|
using AIStudio.Tools.ERIClient;
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
@@ -13,7 +13,7 @@ using RetrievalInfo = AIStudio.Tools.ERIClient.DataModel.RetrievalInfo;
|
|||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -24,9 +24,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public DataSourceERI_V1 DataSource { get; set; }
|
public DataSourceERI_V1 DataSource { get; set; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private ILogger<ProviderDialog> Logger { get; init; } = null!;
|
private ILogger<ProviderDialog> Logger { get; init; } = null!;
|
||||||
|
|
||||||
@@ -195,7 +192,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
|
|
||||||
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
||||||
this.dataIssues[^1] = "Failed to connect to the ERI v1 server. The server is not supported.";
|
this.dataIssues[^1] = T("Failed to connect to the ERI v1 server. The server is not supported.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +251,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
|
|
||||||
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
||||||
this.dataIssues[^1] = $"Failed to connect to the ERI v1 server. The message was: {e.Message}";
|
this.dataIssues[^1] = string.Format(T("Failed to connect to the ERI v1 server. The message was: {0}"), e.Message);
|
||||||
this.Logger.LogError($"Failed to connect to the ERI v1 server. Message: {e.Message}");
|
this.Logger.LogError($"Failed to connect to the ERI v1 server. Message: {e.Message}");
|
||||||
|
|
||||||
this.connectionTested = true;
|
this.connectionTested = true;
|
||||||
@@ -265,9 +262,9 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
private string GetTestResultText()
|
private string GetTestResultText()
|
||||||
{
|
{
|
||||||
if(!this.connectionTested)
|
if(!this.connectionTested)
|
||||||
return "Not tested yet.";
|
return T("Not tested yet.");
|
||||||
|
|
||||||
return this.connectionSuccessfulTested ? "Connection successful." : "Connection failed.";
|
return this.connectionSuccessfulTested ? T("Connection successful.") : T("Connection failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color GetTestResultColor()
|
private Color GetTestResultColor()
|
||||||
@@ -290,9 +287,9 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
|
|
||||||
private string GetSecretLabel() => this.dataAuthMethod switch
|
private string GetSecretLabel() => this.dataAuthMethod switch
|
||||||
{
|
{
|
||||||
AuthMethod.TOKEN => "Access Token",
|
AuthMethod.TOKEN => T("Access Token"),
|
||||||
AuthMethod.USERNAME_PASSWORD => "Password",
|
AuthMethod.USERNAME_PASSWORD => T("Password"),
|
||||||
_ => "Secret",
|
_ => T("Secret"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private async Task Store()
|
private async Task Store()
|
||||||
@@ -320,7 +317,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
var storeResponse = await this.RustService.SetSecret(this, this.dataSecret);
|
var storeResponse = await this.RustService.SetSecret(this, this.dataSecret);
|
||||||
if (!storeResponse.Success)
|
if (!storeResponse.Success)
|
||||||
{
|
{
|
||||||
this.dataSecretStorageIssue = $"Failed to store the auth. secret in the operating system. The message was: {storeResponse.Issue}. Please try again.";
|
this.dataSecretStorageIssue = string.Format(T("Failed to store the auth. secret in the operating system. The message was: {0}. Please try again."), storeResponse.Issue);
|
||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-25
@@ -1,66 +1,64 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5">
|
<MudText Typo="Typo.h5">
|
||||||
Common data source information
|
@T("Common data source information")
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="@T("Data source name")" Value="@this.DataSource.Name" ClipboardTooltipSubject="@T("the data source name")"/>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.NetworkCheck" Label="ERI server hostname" Value="@this.DataSource.Hostname" ClipboardTooltipSubject="the ERI server hostname"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.NetworkCheck" Label="@T("ERI server hostname")" Value="@this.DataSource.Hostname" ClipboardTooltipSubject="@T("the ERI server hostname")"/>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="ERI server port" Value="@this.Port" ClipboardTooltipSubject="the ERI server port"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="@T("ERI server port")" Value="@this.Port" ClipboardTooltipSubject="@T("the ERI server port")"/>
|
||||||
|
|
||||||
@if (!this.IsConnectionEncrypted())
|
@if (!this.IsConnectionEncrypted())
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
Please note: the connection to the ERI v1 server is not encrypted. This means that all
|
@T("Please note: the connection to the ERI v1 server is not encrypted. This means that all data sent to the server is transmitted in plain text. Please ask the ERI server administrator to enable encryption.")
|
||||||
data sent to the server is transmitted in plain text. Please ask the ERI server administrator
|
|
||||||
to enable encryption.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.DataSource.AuthMethod is AuthMethod.USERNAME_PASSWORD)
|
@if (this.DataSource.AuthMethod is AuthMethod.USERNAME_PASSWORD)
|
||||||
{
|
{
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Person2" Label="Username" Value="@this.DataSource.Username" ClipboardTooltipSubject="the username"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Person2" Label="@T("Username")" Value="@this.DataSource.Username" ClipboardTooltipSubject="@T("the username")"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="Server description" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="the server description"/>
|
<TextInfoLines Label="@T("Server description")" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="@T("the server description")"/>
|
||||||
<TextInfoLines Label="Security requirements of the data provider" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="the security requirements of the data provider"/>
|
<TextInfoLines Label="@T("Security requirements of the data provider")" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="@T("the security requirements of the data provider")"/>
|
||||||
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mt-6">
|
<MudText Typo="Typo.h5" Class="mt-6">
|
||||||
Retrieval information
|
@T("Retrieval information")
|
||||||
</MudText>
|
</MudText>
|
||||||
@if (!this.retrievalInfoformation.Any())
|
@if (!this.retrievalInfoformation.Any())
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
||||||
The data source does not provide any retrieval information.
|
@T("The data source does not provide any retrieval information.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudExpansionPanels Class="mb-3">
|
<MudExpansionPanels Class="mb-3">
|
||||||
<ExpansionPanel HeaderText="@this.RetrievalName(this.selectedRetrievalInfo)" HeaderIcon="@Icons.Material.Filled.Info">
|
<ExpansionPanel HeaderText="@this.RetrievalName(this.selectedRetrievalInfo)" HeaderIcon="@Icons.Material.Filled.Info">
|
||||||
<TextInfoLines Label="Description" MaxLines="14" Value="@this.selectedRetrievalInfo.Description" ClipboardTooltipSubject="the retrieval description"/>
|
<TextInfoLines Label="Description" MaxLines="14" Value="@this.selectedRetrievalInfo.Description" ClipboardTooltipSubject="@T("the retrieval description")"/>
|
||||||
<TextInfoLines Label="Parameters" MaxLines="14" Value="@this.RetrievalParameters(this.selectedRetrievalInfo)" ClipboardTooltipSubject="the retrieval parameters"/>
|
<TextInfoLines Label="Parameters" MaxLines="14" Value="@this.RetrievalParameters(this.selectedRetrievalInfo)" ClipboardTooltipSubject="@T("the retrieval parameters")"/>
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(this.selectedRetrievalInfo.Link))
|
@if (!string.IsNullOrWhiteSpace(this.selectedRetrievalInfo.Link))
|
||||||
{
|
{
|
||||||
<MudButton Href="@this.selectedRetrievalInfo.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
<MudButton Href="@this.selectedRetrievalInfo.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
||||||
Open web link, show more information
|
@T("Open web link, show more information")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudText Typo="Typo.h6" Class="mt-3">
|
<MudText Typo="Typo.h6" Class="mt-3">
|
||||||
Embeddings
|
@T("Embeddings")
|
||||||
</MudText>
|
</MudText>
|
||||||
@* ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract *@
|
@* ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract *@
|
||||||
@if (this.selectedRetrievalInfo.Embeddings is null || !this.selectedRetrievalInfo.Embeddings.Any())
|
@if (this.selectedRetrievalInfo.Embeddings is null || !this.selectedRetrievalInfo.Embeddings.Any())
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
||||||
The data source does not provide any embedding information.
|
@T("The data source does not provide any embedding information.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -70,14 +68,14 @@
|
|||||||
{
|
{
|
||||||
var embedding = this.selectedRetrievalInfo.Embeddings[embeddingIndex];
|
var embedding = this.selectedRetrievalInfo.Embeddings[embeddingIndex];
|
||||||
<ExpansionPanel HeaderText="@embedding.EmbeddingName" HeaderIcon="@Icons.Material.Filled.Info" IsExpanded="embeddingIndex == 0">
|
<ExpansionPanel HeaderText="@embedding.EmbeddingName" HeaderIcon="@Icons.Material.Filled.Info" IsExpanded="embeddingIndex == 0">
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.FormatShapes" Label="Type" Value="@embedding.EmbeddingType" ClipboardTooltipSubject="the embedding type"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.FormatShapes" Label="Type" Value="@embedding.EmbeddingType" ClipboardTooltipSubject="@T("the embedding type")"/>
|
||||||
<TextInfoLines Label="Description" MaxLines="14" Value="@embedding.Description" ClipboardTooltipSubject="the embedding description"/>
|
<TextInfoLines Label="@T("Description")" MaxLines="14" Value="@embedding.Description" ClipboardTooltipSubject="@T("the embedding description")"/>
|
||||||
<TextInfoLines Label="When to use" MaxLines="3" Value="@embedding.UsedWhen" ClipboardTooltipSubject="when is the embedding used"/>
|
<TextInfoLines Label="@T("When to use")" MaxLines="3" Value="@embedding.UsedWhen" ClipboardTooltipSubject="@T("when is the embedding used")"/>
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(embedding.Link))
|
@if (!string.IsNullOrWhiteSpace(embedding.Link))
|
||||||
{
|
{
|
||||||
<MudButton Href="@embedding.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
<MudButton Href="@embedding.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
||||||
Open web link, show more information
|
@T("Open web link, show more information")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
@@ -95,7 +93,11 @@
|
|||||||
{
|
{
|
||||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="ml-5 mr-5"/>
|
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="ml-5 mr-5"/>
|
||||||
}
|
}
|
||||||
<MudButton OnClick="@this.GetERIMetadata" Variant="Variant.Filled" Color="Color.Info">Reload</MudButton>
|
<MudButton OnClick="@this.GetERIMetadata" Variant="Variant.Filled" Color="Color.Info">
|
||||||
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
|
@T("Reload")
|
||||||
|
</MudButton>
|
||||||
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
+9
-8
@@ -3,6 +3,7 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.ERIClient;
|
using AIStudio.Tools.ERIClient;
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
@@ -14,7 +15,7 @@ using RetrievalInfo = AIStudio.Tools.ERIClient.DataModel.RetrievalInfo;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposable, ISecretId
|
public partial class DataSourceERI_V1InfoDialog : MSGComponentBase, IAsyncDisposable, ISecretId
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -29,8 +30,8 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
this.eriServerTasks.Add(this.GetERIMetadata());
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
|
this.eriServerTasks.Add(this.GetERIMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -59,21 +60,21 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
return $"[{retrievalInfo.Id}] {retrievalInfo.Name}";
|
return $"[{retrievalInfo.Id}] {retrievalInfo.Name}";
|
||||||
|
|
||||||
if (hasId)
|
if (hasId)
|
||||||
return $"[{retrievalInfo.Id}] Unnamed retrieval process";
|
return string.Format(T("[{0}] Unnamed retrieval process"), retrievalInfo.Id);
|
||||||
|
|
||||||
return hasName ? retrievalInfo.Name : "Unnamed retrieval process";
|
return hasName ? retrievalInfo.Name : T("Unnamed retrieval process");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string RetrievalParameters(RetrievalInfo retrievalInfo)
|
private string RetrievalParameters(RetrievalInfo retrievalInfo)
|
||||||
{
|
{
|
||||||
var parameters = retrievalInfo.ParametersDescription;
|
var parameters = retrievalInfo.ParametersDescription;
|
||||||
if (parameters is null || parameters.Count == 0)
|
if (parameters is null || parameters.Count == 0)
|
||||||
return "This retrieval process has no parameters.";
|
return T("This retrieval process has no parameters.");
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var (paramName, description) in parameters)
|
foreach (var (paramName, description) in parameters)
|
||||||
{
|
{
|
||||||
sb.Append("Parameter: ");
|
sb.Append(T("Parameter: "));
|
||||||
sb.AppendLine(paramName);
|
sb.AppendLine(paramName);
|
||||||
sb.AppendLine(description);
|
sb.AppendLine(description);
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
@@ -94,7 +95,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
using var client = ERIClientFactory.Get(ERIVersion.V1, this.DataSource);
|
using var client = ERIClientFactory.Get(ERIVersion.V1, this.DataSource);
|
||||||
if(client is null)
|
if(client is null)
|
||||||
{
|
{
|
||||||
this.dataIssues.Add("Failed to connect to the ERI v1 server. The server is not supported.");
|
this.dataIssues.Add(T("Failed to connect to the ERI v1 server. The server is not supported."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
this.dataIssues.Add($"Failed to connect to the ERI v1 server. The message was: {e.Message}");
|
this.dataIssues.Add(string.Format(T("Failed to connect to the ERI v1 server. The message was: {0}"), e.Message));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
@@ -7,7 +8,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataName"
|
@bind-Text="@this.dataName"
|
||||||
Label="Data Source Name"
|
Label="@T("Data Source Name")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
MaxLength="40"
|
MaxLength="40"
|
||||||
Counter="40"
|
Counter="40"
|
||||||
@@ -20,19 +21,19 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
Select a root directory for this data source. All data in this directory and all
|
@T("Select a root directory for this data source. All data in this directory and all its subdirectories will be processed for this data source.")
|
||||||
its subdirectories will be processed for this data source.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<SelectDirectory @bind-Directory="@this.dataPath" Label="Selected base directory for this data source" DirectoryDialogTitle="Select the base directory" Validation="@this.dataSourceValidation.ValidatePath" />
|
<SelectDirectory @bind-Directory="@this.dataPath" Label="@T("Selected base directory for this data source")" DirectoryDialogTitle="@T("Select the base directory")" Validation="@this.dataSourceValidation.ValidatePath" />
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
In order for the AI to be able to determine the appropriate data at any time, you must
|
@T("In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.")
|
||||||
choose an embedding method.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<MudSelect @bind-Value="@this.dataEmbeddingId" Label="Embedding" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateEmbeddingId">
|
<MudSelect @bind-Value="@this.dataEmbeddingId" Label="@T("Embedding")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateEmbeddingId">
|
||||||
@foreach (var embedding in this.AvailableEmbeddings)
|
@foreach (var embedding in this.AvailableEmbeddings)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@embedding.Value">@embedding.Name</MudSelectItem>
|
<MudSelectItem Value="@embedding.Value">
|
||||||
|
@embedding.Name
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
@@ -43,45 +44,46 @@
|
|||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
@if (string.IsNullOrWhiteSpace(this.dataPath))
|
@if (string.IsNullOrWhiteSpace(this.dataPath))
|
||||||
{
|
{
|
||||||
@: Please note: the embedding you selected runs in the cloud. All your data will be sent to the cloud.
|
@T("Please note: the embedding you selected runs in the cloud. All your data will be sent to the cloud. Please confirm that you have read and understood this.")
|
||||||
@: Please confirm that you have read and understood this.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@: Please note: the embedding you selected runs in the cloud. All your data from the
|
@string.Format(T("Please note: the embedding you selected runs in the cloud. All your data from the folder '{0}' and all its subdirectories will be sent to the cloud. Please confirm that you have read and understood this."), this.dataPath)
|
||||||
@: folder '@this.dataPath' and all its subdirectories will be sent to the cloud. Please
|
|
||||||
@: confirm that you have read and understood this.
|
|
||||||
}
|
}
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<MudTextSwitch @bind-Value="@this.dataUserAcknowledgedCloudEmbedding" Label="I confirm that I have read and understood the above" LabelOn="Yes, please send my data to the cloud" LabelOff="No, I will chose another embedding" Validation="@this.dataSourceValidation.ValidateUserAcknowledgedCloudEmbedding"/>
|
<MudTextSwitch @bind-Value="@this.dataUserAcknowledgedCloudEmbedding" Label="@T("I confirm that I have read and understood the above")" LabelOn="@T("Yes, please send my data to the cloud")" LabelOff="@T("No, I will chose another embedding")" Validation="@this.dataSourceValidation.ValidateUserAcknowledgedCloudEmbedding"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
@T("The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="Your security policy" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="@T("Your security policy")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
||||||
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
<MudSelectItem Value="@policy">
|
||||||
|
@policy.ToSelectionText()
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
</MudForm>
|
</MudForm>
|
||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.Validation;
|
using AIStudio.Tools.Validation;
|
||||||
@@ -6,7 +7,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceLocalDirectoryDialog : ComponentBase
|
public partial class DataSourceLocalDirectoryDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -20,9 +21,6 @@ public partial class DataSourceLocalDirectoryDialog : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public IReadOnlyList<ConfigurationSelectData<string>> AvailableEmbeddings { get; set; } = [];
|
public IReadOnlyList<ConfigurationSelectData<string>> AvailableEmbeddings { get; set; } = [];
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
private readonly DataSourceValidation dataSourceValidation;
|
private readonly DataSourceValidation dataSourceValidation;
|
||||||
|
|||||||
@@ -1,56 +1,58 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="@T("Data source name")" Value="@this.DataSource.Name" ClipboardTooltipSubject="@T("the data source name")"/>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.FolderOpen" Label="Path" Value="@this.DataSource.Path" ClipboardTooltipSubject="this path"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.FolderOpen" Label="@T("Path")" Value="@this.DataSource.Path" ClipboardTooltipSubject="@T("this path")"/>
|
||||||
@if (!this.IsDirectoryAvailable)
|
@if (!this.IsDirectoryAvailable)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
The directory chosen for the data source does not exist anymore. Please edit the data source and correct the path.
|
@T("The directory chosen for the data source does not exist anymore. Please edit the data source and correct the path.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The directory chosen for the data source exists.
|
@T("The directory chosen for the data source exists.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Layers" Label="Embedding name" Value="@this.embeddingProvider.Name" ClipboardTooltipSubject="the embedding name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Layers" Label="@T("Embedding name")" Value="@this.embeddingProvider.Name" ClipboardTooltipSubject="@T("the embedding name")"/>
|
||||||
@if (this.IsCloudEmbedding)
|
@if (this.IsCloudEmbedding)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
The embedding runs in the cloud. All your data from the folder '@this.DataSource.Path' and all its subdirectories
|
@string.Format(T("The embedding runs in the cloud. All your data from the folder '{0}' and all its subdirectories will be sent to the cloud."), this.DataSource.Path)
|
||||||
will be sent to the cloud.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The embedding runs locally or in your organization. Your data is not sent to the cloud.
|
@T("The embedding runs locally or in your organization. Your data is not sent to the cloud.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Number of files" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="the number of files in the directory"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("Number of files")" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="@T("the number of files in the directory")"/>
|
||||||
<TextInfoLines Label="Files list" MaxLines="14" Value="@this.directoryFiles.ToString()" ClipboardTooltipSubject="the files list"/>
|
<TextInfoLines Label="@T("Files list")" MaxLines="14" Value="@this.directoryFiles.ToString()" ClipboardTooltipSubject="@T("the files list")"/>
|
||||||
@if (this.directorySizeNumFiles > 100)
|
@if (this.directorySizeNumFiles > 100)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Warning" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Warning" Class="mb-3">
|
||||||
For performance reasons, only the first 100 files are shown. The directory contains @this.NumberFilesInDirectory files in total.
|
@string.Format(T("For performance reasons, only the first 100 files are shown. The directory contains {0} files in total."), this.NumberFilesInDirectory)
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Total directory size" Value="@this.directorySizeBytes.FileSize()" ClipboardTooltipSubject="the total directory size"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("Total directory size")" Value="@this.directorySizeBytes.FileSize()" ClipboardTooltipSubject="@T("the total directory size")"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
@if (this.IsOperationInProgress)
|
@if (this.IsOperationInProgress)
|
||||||
{
|
{
|
||||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="ml-5 mr-5"/>
|
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="ml-5 mr-5"/>
|
||||||
}
|
}
|
||||||
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ using Timer = System.Timers.Timer;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceLocalDirectoryInfoDialog : ComponentBase, IAsyncDisposable
|
public partial class DataSourceLocalDirectoryInfoDialog : MSGComponentBase, IAsyncDisposable
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -17,9 +18,6 @@ public partial class DataSourceLocalDirectoryInfoDialog : ComponentBase, IAsyncD
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public DataSourceLocalDirectory DataSource { get; set; }
|
public DataSourceLocalDirectory DataSource { get; set; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
private readonly Timer refreshTimer = new(TimeSpan.FromSeconds(1.6))
|
private readonly Timer refreshTimer = new(TimeSpan.FromSeconds(1.6))
|
||||||
{
|
{
|
||||||
AutoReset = true,
|
AutoReset = true,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
@@ -6,7 +8,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataName"
|
@bind-Text="@this.dataName"
|
||||||
Label="Data Source Name"
|
Label="@T("Data Source Name")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
MaxLength="40"
|
MaxLength="40"
|
||||||
Counter="40"
|
Counter="40"
|
||||||
@@ -19,18 +21,19 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
Select a file for this data source. The content of this file will be processed for the data source.
|
@T("Select a file for this data source. The content of this file will be processed for the data source.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<SelectFile @bind-File="@this.dataFilePath" Label="Selected file path for this data source" FileDialogTitle="Select the file" Validation="@this.dataSourceValidation.ValidateFilePath" />
|
<SelectFile @bind-File="@this.dataFilePath" Label="@T("Selected file path for this data source")" FileDialogTitle="@T("Select the file")" Validation="@this.dataSourceValidation.ValidateFilePath" />
|
||||||
|
|
||||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
In order for the AI to be able to determine the appropriate data at any time, you must
|
@T("In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.")
|
||||||
choose an embedding method.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<MudSelect @bind-Value="@this.dataEmbeddingId" Label="Embedding" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.GetSelectedCloudEmbedding">
|
<MudSelect @bind-Value="@this.dataEmbeddingId" Label="@T("Embedding")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.GetSelectedCloudEmbedding">
|
||||||
@foreach (var embedding in this.AvailableEmbeddings)
|
@foreach (var embedding in this.AvailableEmbeddings)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@embedding.Value">@embedding.Name</MudSelectItem>
|
<MudSelectItem Value="@embedding.Value">
|
||||||
|
@embedding.Name
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
@@ -41,45 +44,46 @@
|
|||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
@if (string.IsNullOrWhiteSpace(this.dataFilePath))
|
@if (string.IsNullOrWhiteSpace(this.dataFilePath))
|
||||||
{
|
{
|
||||||
@: Please note: the embedding you selected runs in the cloud. All your data will be sent to the cloud.
|
@T("Please note: the embedding you selected runs in the cloud. All your data will be sent to the cloud. Please confirm that you have read and understood this.")
|
||||||
@: Please confirm that you have read and understood this.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@: Please note: the embedding you selected runs in the cloud. All your data within the
|
@string.Format(T("Please note: the embedding you selected runs in the cloud. All your data within the file '{0}' will be sent to the cloud. Please confirm that you have read and understood this."), this.dataFilePath)
|
||||||
@: file '@this.dataFilePath' will be sent to the cloud. Please confirm that you have read
|
|
||||||
@: and understood this.
|
|
||||||
}
|
}
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
<MudTextSwitch @bind-Value="@this.dataUserAcknowledgedCloudEmbedding" Label="I confirm that I have read and understood the above" LabelOn="Yes, please send my data to the cloud" LabelOff="No, I will chose another embedding" Validation="@this.dataSourceValidation.ValidateUserAcknowledgedCloudEmbedding"/>
|
<MudTextSwitch @bind-Value="@this.dataUserAcknowledgedCloudEmbedding" Label="@T("I confirm that I have read and understood the above")" LabelOn="@T("Yes, please send my data to the cloud")" LabelOff="@T("No, I will chose another embedding")" Validation="@this.dataSourceValidation.ValidateUserAcknowledgedCloudEmbedding"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
@T("The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="Your security policy" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="@T("Your security policy")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
||||||
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
<MudSelectItem Value="@policy">
|
||||||
|
@policy.ToSelectionText()
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
</MudForm>
|
</MudForm>
|
||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.Validation;
|
using AIStudio.Tools.Validation;
|
||||||
@@ -6,7 +7,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceLocalFileDialog : ComponentBase
|
public partial class DataSourceLocalFileDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -20,9 +21,6 @@ public partial class DataSourceLocalFileDialog : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public IReadOnlyList<ConfigurationSelectData<string>> AvailableEmbeddings { get; set; } = [];
|
public IReadOnlyList<ConfigurationSelectData<string>> AvailableEmbeddings { get; set; } = [];
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
private readonly DataSourceValidation dataSourceValidation;
|
private readonly DataSourceValidation dataSourceValidation;
|
||||||
|
|||||||
@@ -1,42 +1,44 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="@T("Data source name")" Value="@this.DataSource.Name" ClipboardTooltipSubject="@T("the data source name")"/>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.FolderOpen" Label="File path" Value="@this.DataSource.FilePath" ClipboardTooltipSubject="this path"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.FolderOpen" Label="@T("File path")" Value="@this.DataSource.FilePath" ClipboardTooltipSubject="@T("this path")"/>
|
||||||
@if (!this.IsFileAvailable)
|
@if (!this.IsFileAvailable)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
The file chosen for the data source does not exist anymore. Please edit the data source and choose another file or correct the path.
|
@T("The file chosen for the data source does not exist anymore. Please edit the data source and choose another file or correct the path.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The file chosen for the data source exists.
|
@T("The file chosen for the data source exists.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Layers" Label="Embedding name" Value="@this.embeddingProvider.Name" ClipboardTooltipSubject="the embedding name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Layers" Label="@T("Embedding name")" Value="@this.embeddingProvider.Name" ClipboardTooltipSubject="@T("the embedding name")"/>
|
||||||
@if (this.IsCloudEmbedding)
|
@if (this.IsCloudEmbedding)
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
|
||||||
The embedding runs in the cloud. All your data within the
|
@string.Format(T("The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud."), this.DataSource.FilePath)
|
||||||
file '@this.DataSource.FilePath' will be sent to the cloud.
|
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Tertiary" Class="mb-3">
|
||||||
The embedding runs locally or in your organization. Your data is not sent to the cloud.
|
@T("The embedding runs locally or in your organization. Your data is not sent to the cloud.")
|
||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="File size" Value="@this.FileSize" ClipboardTooltipSubject="the file size"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("File size")" Value="@this.FileSize" ClipboardTooltipSubject="@T("the file size")"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
@@ -5,7 +6,7 @@ using Microsoft.AspNetCore.Components;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class DataSourceLocalFileInfoDialog : ComponentBase
|
public partial class DataSourceLocalFileInfoDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -13,9 +14,6 @@ public partial class DataSourceLocalFileInfoDialog : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public DataSourceLocalFile DataSource { get; set; }
|
public DataSourceLocalFile DataSource { get; set; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
@@ -5,8 +7,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataEmbeddingName"
|
@bind-Text="@this.DataEmbeddingName"
|
||||||
Label="Embedding Name"
|
Label="@T("Embedding Name")"
|
||||||
HelperText="The name of the embedding method."
|
HelperText="@T("The name of the embedding method.")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Label"
|
AdornmentIcon="@Icons.Material.Filled.Label"
|
||||||
@@ -22,8 +24,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataEmbeddingType"
|
@bind-Text="@this.DataEmbeddingType"
|
||||||
Label="Embedding Type"
|
Label="@T("Embedding Type")"
|
||||||
HelperText="What kind of embedding is used. For example, Transformer Embedding, Contextual Word Embedding, Graph Embedding, etc."
|
HelperText="@T("What kind of embedding is used. For example, Transformer Embedding, Contextual Word Embedding, Graph Embedding, etc.")"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Extension"
|
AdornmentIcon="@Icons.Material.Filled.Extension"
|
||||||
AdornmentColor="Color.Info"
|
AdornmentColor="Color.Info"
|
||||||
@@ -35,16 +37,16 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudList T="@string" Class="mb-3">
|
<MudList T="@string" Class="mb-3">
|
||||||
<MudListItem Icon="@Icons.Material.Filled.Link" Href="https://en.wikipedia.org/wiki/Word_embedding" Target="_blank" Text="See Wikipedia for more information about word embeddings"/>
|
<MudListItem Icon="@Icons.Material.Filled.Link" Href="https://en.wikipedia.org/wiki/Word_embedding" Target="_blank" Text="@T("See Wikipedia for more information about word embeddings")"/>
|
||||||
<MudListItem Icon="@Icons.Material.Filled.Link" Href="https://en.wikipedia.org/wiki/Knowledge_graph_embedding" Target="_blank" Text="See Wikipedia for more information about knowledge graph embeddings"/>
|
<MudListItem Icon="@Icons.Material.Filled.Link" Href="https://en.wikipedia.org/wiki/Knowledge_graph_embedding" Target="_blank" Text="@T("See Wikipedia for more information about knowledge graph embeddings")"/>
|
||||||
</MudList>
|
</MudList>
|
||||||
|
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataDescription"
|
@bind-Text="@this.DataDescription"
|
||||||
Label="Embedding Description"
|
Label="@T("Embedding Description")"
|
||||||
HelperText="A short description of the embedding method."
|
HelperText="@T("A short description of the embedding method.")"
|
||||||
Lines="3"
|
Lines="3"
|
||||||
AutoGrow="@true"
|
AutoGrow="@true"
|
||||||
MaxLines="6"
|
MaxLines="6"
|
||||||
@@ -62,8 +64,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataUsedWhen"
|
@bind-Text="@this.DataUsedWhen"
|
||||||
Label="Used when"
|
Label="@T("Used when")"
|
||||||
HelperText="When is this embedding used? When you define multiple embeddings, it is helpful to know when to use which one."
|
HelperText="@T("When is this embedding used? When you define multiple embeddings, it is helpful to know when to use which one.")"
|
||||||
Lines="3"
|
Lines="3"
|
||||||
AutoGrow="@true"
|
AutoGrow="@true"
|
||||||
MaxLines="6"
|
MaxLines="6"
|
||||||
@@ -81,8 +83,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataLink"
|
@bind-Text="@this.DataLink"
|
||||||
Label="Embedding Link"
|
Label="@T("Embedding Link")"
|
||||||
HelperText="A link to the embedding, e.g., to the model, the source code, the paper, it's Wikipedia page, etc."
|
HelperText="@T("A link to the embedding, e.g., to the model, the source code, the paper, it's Wikipedia page, etc.")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Link"
|
AdornmentIcon="@Icons.Material.Filled.Link"
|
||||||
@@ -94,15 +96,17 @@
|
|||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Components;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class EmbeddingMethodDialog : ComponentBase
|
public partial class EmbeddingMethodDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -52,9 +52,6 @@ public partial class EmbeddingMethodDialog : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool IsEditing { get; init; }
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
private bool dataIsValid;
|
private bool dataIsValid;
|
||||||
@@ -90,13 +87,13 @@ public partial class EmbeddingMethodDialog : ComponentBase
|
|||||||
private string? ValidateName(string name)
|
private string? ValidateName(string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
return "The embedding name must not be empty. Please name the embedding.";
|
return T("The embedding name must not be empty. Please name the embedding.");
|
||||||
|
|
||||||
if (name.Length > 26)
|
if (name.Length > 26)
|
||||||
return "The embedding name must not be longer than 26 characters.";
|
return T("The embedding name must not be longer than 26 characters.");
|
||||||
|
|
||||||
if (this.UsedEmbeddingMethodNames.Contains(name))
|
if (this.UsedEmbeddingMethodNames.Contains(name))
|
||||||
return $"The embedding method name '{name}' is already used. Please choose a unique name.";
|
return string.Format(T("The embedding method name '{0}' is already used. Please choose a unique name."), name);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -104,10 +101,10 @@ public partial class EmbeddingMethodDialog : ComponentBase
|
|||||||
private string? ValidateType(string type)
|
private string? ValidateType(string type)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(type))
|
if (string.IsNullOrWhiteSpace(type))
|
||||||
return "The embedding type must not be empty. Please specify the embedding type.";
|
return T("The embedding type must not be empty. Please specify the embedding type.");
|
||||||
|
|
||||||
if (type.Length > 56)
|
if (type.Length > 56)
|
||||||
return "The embedding type must not be longer than 56 characters.";
|
return T("The embedding type must not be longer than 56 characters.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -115,7 +112,7 @@ public partial class EmbeddingMethodDialog : ComponentBase
|
|||||||
private string? ValidateDescription(string description)
|
private string? ValidateDescription(string description)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(description))
|
if (string.IsNullOrWhiteSpace(description))
|
||||||
return "The description must not be empty. Please describe the embedding method.";
|
return T("The description must not be empty. Please describe the embedding method.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -123,7 +120,7 @@ public partial class EmbeddingMethodDialog : ComponentBase
|
|||||||
private string? ValidateUsedWhen(string usedWhen)
|
private string? ValidateUsedWhen(string usedWhen)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(usedWhen))
|
if (string.IsNullOrWhiteSpace(usedWhen))
|
||||||
return "Please describe when the embedding is used. Might be anytime or when certain keywords are present, etc.";
|
return T("Please describe when the embedding is used. Might be anytime or when certain keywords are present, etc.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
@using AIStudio.Provider
|
@using AIStudio.Provider
|
||||||
@using AIStudio.Provider.SelfHosted
|
@using AIStudio.Provider.SelfHosted
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
<MudSelect @bind-Value="@this.DataLLMProvider" Label="Provider" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingProvider">
|
<MudSelect @bind-Value="@this.DataLLMProvider" Label="@T("Provider")" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingProvider">
|
||||||
@foreach (LLMProviders provider in Enum.GetValues(typeof(LLMProviders)))
|
@foreach (LLMProviders provider in Enum.GetValues(typeof(LLMProviders)))
|
||||||
{
|
{
|
||||||
if (provider.ProvideEmbeddings())
|
if (provider.ProvideEmbeddings() || provider is LLMProviders.NONE)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@provider">
|
<MudSelectItem Value="@provider">
|
||||||
@provider.ToName()
|
@provider.ToName()
|
||||||
@@ -17,22 +18,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
<MudButton Disabled="@(!this.DataLLMProvider.ShowRegisterButton())" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@this.DataLLMProvider.GetCreationURL()" Target="_blank">Create account</MudButton>
|
<MudButton Disabled="@(!this.DataLLMProvider.ShowRegisterButton())" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@this.DataLLMProvider.GetCreationURL()" Target="_blank">
|
||||||
|
@T("Create account")
|
||||||
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost))
|
@if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost))
|
||||||
{
|
{
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
<SecretInputField @bind-Secret="@this.dataAPIKey" Label="@this.APIKeyText" Validation="@this.providerValidation.ValidatingAPIKey"/>
|
||||||
<MudTextField
|
|
||||||
T="string"
|
|
||||||
@bind-Text="@this.dataAPIKey"
|
|
||||||
Label="@this.APIKeyText"
|
|
||||||
Class="mb-3"
|
|
||||||
Adornment="Adornment.Start"
|
|
||||||
AdornmentIcon="@Icons.Material.Filled.VpnKey"
|
|
||||||
AdornmentColor="Color.Info"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
Validation="@this.providerValidation.ValidatingAPIKey"/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.DataLLMProvider.IsHostnameNeeded())
|
@if (this.DataLLMProvider.IsHostnameNeeded())
|
||||||
@@ -40,7 +33,7 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataHostname"
|
@bind-Text="@this.DataHostname"
|
||||||
Label="Hostname"
|
Label="@T("Hostname")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Dns"
|
AdornmentIcon="@Icons.Material.Filled.Dns"
|
||||||
@@ -51,7 +44,7 @@
|
|||||||
|
|
||||||
@if (this.DataLLMProvider.IsHostNeeded())
|
@if (this.DataLLMProvider.IsHostNeeded())
|
||||||
{
|
{
|
||||||
<MudSelect @bind-Value="@this.DataHost" Label="Host" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingHost">
|
<MudSelect @bind-Value="@this.DataHost" Label="@T("Host")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingHost">
|
||||||
@foreach (Host host in Enum.GetValues(typeof(Host)))
|
@foreach (Host host in Enum.GetValues(typeof(Host)))
|
||||||
{
|
{
|
||||||
if (host.AreEmbeddingsSupported())
|
if (host.AreEmbeddingsSupported())
|
||||||
@@ -64,39 +57,57 @@
|
|||||||
</MudSelect>
|
</MudSelect>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center">
|
<MudField FullWidth="true" Label="@T("Model selection")" Variant="Variant.Outlined" Class="mb-3">
|
||||||
|
<MudStack Row="@true" AlignItems="AlignItems.Center" StretchItems="StretchItems.End">
|
||||||
@if (this.DataLLMProvider.IsEmbeddingModelProvidedManually(this.DataHost))
|
@if (this.DataLLMProvider.IsEmbeddingModelProvidedManually(this.DataHost))
|
||||||
{
|
{
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.dataManuallyModel"
|
@bind-Text="@this.dataManuallyModel"
|
||||||
Label="Model"
|
Label="@T("Model")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Dns"
|
AdornmentIcon="@Icons.Material.Filled.Dns"
|
||||||
AdornmentColor="Color.Info"
|
AdornmentColor="Color.Info"
|
||||||
Validation="@this.ValidateManuallyModel"
|
Validation="@this.ValidateManuallyModel"
|
||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
HelperText="Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually."
|
HelperText="@T("Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually.")"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudButton Disabled="@(!this.DataLLMProvider.CanLoadModels(this.DataHost, this.dataAPIKey))" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.Refresh" OnClick="this.ReloadModels">Load</MudButton>
|
<MudButton Disabled="@(!this.DataLLMProvider.CanLoadModels(this.DataHost, this.dataAPIKey))" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.Refresh" OnClick="this.ReloadModels">
|
||||||
<MudSelect Disabled="@this.IsNoneProvider" @bind-Value="@this.DataModel" Label="Model" Class="mb-3" OpenIcon="@Icons.Material.Filled.FaceRetouchingNatural" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingModel">
|
@T("Load")
|
||||||
|
</MudButton>
|
||||||
|
@if(this.availableModels.Count is 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.body1">
|
||||||
|
@T("No models loaded or available.")
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudSelect Disabled="@this.IsNoneProvider" @bind-Value="@this.DataModel" Label="@T("Model")"
|
||||||
|
OpenIcon="@Icons.Material.Filled.FaceRetouchingNatural"
|
||||||
|
AdornmentColor="Color.Info" Adornment="Adornment.Start"
|
||||||
|
Validation="@this.providerValidation.ValidatingModel">
|
||||||
@foreach (var model in this.availableModels)
|
@foreach (var model in this.availableModels)
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@model">@model</MudSelectItem>
|
<MudSelectItem Value="@model">
|
||||||
|
@model
|
||||||
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
</MudField>
|
||||||
|
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataName"
|
@bind-Text="@this.DataName"
|
||||||
Label="Instance Name"
|
Label="@T("Instance Name")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
MaxLength="40"
|
MaxLength="40"
|
||||||
Counter="40"
|
Counter="40"
|
||||||
@@ -112,15 +123,17 @@
|
|||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Components;
|
||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
@@ -9,7 +10,7 @@ using Host = AIStudio.Provider.SelfHosted.Host;
|
|||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
public partial class EmbeddingProviderDialog : MSGComponentBase, ISecretId
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -68,9 +69,6 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool IsEditing { get; init; }
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private ILogger<ProviderDialog> Logger { get; init; } = null!;
|
private ILogger<ProviderDialog> Logger { get; init; } = null!;
|
||||||
|
|
||||||
@@ -175,7 +173,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
|||||||
this.dataAPIKey = string.Empty;
|
this.dataAPIKey = string.Empty;
|
||||||
if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
|
if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
|
||||||
{
|
{
|
||||||
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again.";
|
this.dataAPIKeyStorageIssue = string.Format(T("Failed to load the API key from the operating system. The message was: {0}. You might ignore this message and provide the API key again."), requestedSecret.Issue);
|
||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +222,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
|||||||
var storeResponse = await this.RustService.SetAPIKey(this, this.dataAPIKey);
|
var storeResponse = await this.RustService.SetAPIKey(this, this.dataAPIKey);
|
||||||
if (!storeResponse.Success)
|
if (!storeResponse.Success)
|
||||||
{
|
{
|
||||||
this.dataAPIKeyStorageIssue = $"Failed to store the API key in the operating system. The message was: {storeResponse.Issue}. Please try again.";
|
this.dataAPIKeyStorageIssue = string.Format(T("Failed to store the API key in the operating system. The message was: {0}. Please try again."), storeResponse.Issue);
|
||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -236,7 +234,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
|||||||
private string? ValidateManuallyModel(string manuallyModel)
|
private string? ValidateManuallyModel(string manuallyModel)
|
||||||
{
|
{
|
||||||
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && string.IsNullOrWhiteSpace(manuallyModel))
|
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && string.IsNullOrWhiteSpace(manuallyModel))
|
||||||
return "Please enter an embedding model name.";
|
return T("Please enter an embedding model name.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -261,8 +259,8 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
|
|||||||
|
|
||||||
private string APIKeyText => this.DataLLMProvider switch
|
private string APIKeyText => this.DataLLMProvider switch
|
||||||
{
|
{
|
||||||
LLMProviders.SELF_HOSTED => "(Optional) API Key",
|
LLMProviders.SELF_HOSTED => T("(Optional) API Key"),
|
||||||
_ => "API Key",
|
_ => T("API Key"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool IsNoneProvider => this.DataLLMProvider is LLMProviders.NONE;
|
private bool IsNoneProvider => this.DataLLMProvider is LLMProviders.NONE;
|
||||||
|
|||||||
@@ -22,18 +22,7 @@
|
|||||||
|
|
||||||
@if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost))
|
@if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost))
|
||||||
{
|
{
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
<SecretInputField @bind-Secret="@this.dataAPIKey" Label="@this.APIKeyText" Validation="@this.providerValidation.ValidatingAPIKey"/>
|
||||||
<MudTextField
|
|
||||||
T="string"
|
|
||||||
@bind-Text="@this.dataAPIKey"
|
|
||||||
Label="@this.APIKeyText"
|
|
||||||
Class="mb-3"
|
|
||||||
Adornment="Adornment.Start"
|
|
||||||
AdornmentIcon="@Icons.Material.Filled.VpnKey"
|
|
||||||
AdornmentColor="Color.Info"
|
|
||||||
InputType="InputType.Password"
|
|
||||||
Immediate="true"
|
|
||||||
Validation="@this.providerValidation.ValidatingAPIKey"/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.DataLLMProvider.IsHostnameNeeded())
|
@if (this.DataLLMProvider.IsHostnameNeeded())
|
||||||
@@ -79,7 +68,7 @@
|
|||||||
@* ReSharper restore Asp.Entity *@
|
@* ReSharper restore Asp.Entity *@
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudField FullWidth="true" Label="Model selection" Variant="Variant.Outlined" Class="mb-3">
|
<MudField FullWidth="true" Label="@T("Model selection")" Variant="Variant.Outlined" Class="mb-3">
|
||||||
<MudStack Row="@true" AlignItems="AlignItems.Center" StretchItems="StretchItems.End">
|
<MudStack Row="@true" AlignItems="AlignItems.Center" StretchItems="StretchItems.End">
|
||||||
@if (this.DataLLMProvider.IsLLMModelProvidedManually())
|
@if (this.DataLLMProvider.IsLLMModelProvidedManually())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
@using AIStudio.Assistants.ERI
|
@using AIStudio.Assistants.ERI
|
||||||
@using MudExtensions
|
@using MudExtensions
|
||||||
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mb-3">
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
General Information
|
@T("General Information")
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
Please provide some general information about your retrieval process first. This data may be
|
@T("Please provide some general information about your retrieval process first. This data may be displayed to the users.")
|
||||||
displayed to the users.
|
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataName"
|
@bind-Text="@this.DataName"
|
||||||
Label="Retrieval Process Name"
|
Label="@T("Retrieval Process Name")"
|
||||||
HelperText="The name of your retrieval process."
|
HelperText="@T("The name of your retrieval process.")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Label"
|
AdornmentIcon="@Icons.Material.Filled.Label"
|
||||||
@@ -34,8 +35,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataDescription"
|
@bind-Text="@this.DataDescription"
|
||||||
Label="Retrieval Process Description"
|
Label="@T("Retrieval Process Description")"
|
||||||
HelperText="A short description of the retrieval process."
|
HelperText="@T("A short description of the retrieval process.")"
|
||||||
Lines="3"
|
Lines="3"
|
||||||
AutoGrow="@true"
|
AutoGrow="@true"
|
||||||
MaxLines="6"
|
MaxLines="6"
|
||||||
@@ -53,8 +54,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.DataLink"
|
@bind-Text="@this.DataLink"
|
||||||
Label="Retrieval Process Link"
|
Label="@T("Retrieval Process Link")"
|
||||||
HelperText="A link to the retrieval process, e.g., the source code, the paper, it's Wikipedia page, etc. Make sense for common retrieval processes. Leave empty if not applicable."
|
HelperText="@T("A link to the retrieval process, e.g., the source code, the paper, it's Wikipedia page, etc. Make sense for common retrieval processes. Leave empty if not applicable.")"
|
||||||
Class="mb-6"
|
Class="mb-6"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Link"
|
AdornmentIcon="@Icons.Material.Filled.Link"
|
||||||
@@ -63,13 +64,11 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mb-3">
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
Retrieval Process Parameters
|
@T("Retrieval Process Parameters")
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
You may want to parameterize your retrieval process. However, this is optional. You can specify any
|
@T("You may want to parameterize your retrieval process. However, this is optional. You can specify any parameters that can be set by the user or the system during the call. Nevertheless, you should use sensible default values in your code so that users are not forced to set the parameters manually.")
|
||||||
parameters that can be set by the user or the system during the call. Nevertheless, you should use
|
|
||||||
sensible default values in your code so that users are not forced to set the parameters manually.
|
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudStack Row="@true" Spacing="6" AlignItems="AlignItems.Start" StretchItems="StretchItems.None">
|
<MudStack Row="@true" Spacing="6" AlignItems="AlignItems.Start" StretchItems="StretchItems.None">
|
||||||
@@ -87,7 +86,7 @@
|
|||||||
</MudList>
|
</MudList>
|
||||||
}
|
}
|
||||||
<MudButton OnClick="@this.AddRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Primary" Class="mt-1">
|
<MudButton OnClick="@this.AddRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Primary" Class="mt-1">
|
||||||
Add Parameter
|
@T("Add Parameter")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@@ -98,13 +97,13 @@
|
|||||||
@if(this.retrievalParameters.Count == 0)
|
@if(this.retrievalParameters.Count == 0)
|
||||||
{
|
{
|
||||||
<MudText>
|
<MudText>
|
||||||
Add a parameter first, then select it to edit.
|
@T("Add a parameter first, then select it to edit.")
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudText>
|
<MudText>
|
||||||
Select a parameter to show and edit it.
|
@T("Select a parameter to show and edit it.")
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,8 +113,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.selectedParameter.Name"
|
@bind-Text="@this.selectedParameter.Name"
|
||||||
Label="Parameter Name"
|
Label="@T("Parameter Name")"
|
||||||
HelperText="The parameter name. It must be unique within the retrieval process."
|
HelperText="@T("The parameter name. It must be unique within the retrieval process.")"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Adornment="Adornment.Start"
|
Adornment="Adornment.Start"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Label"
|
AdornmentIcon="@Icons.Material.Filled.Label"
|
||||||
@@ -130,8 +129,8 @@
|
|||||||
<MudTextField
|
<MudTextField
|
||||||
T="string"
|
T="string"
|
||||||
@bind-Text="@this.selectedParameter.Description"
|
@bind-Text="@this.selectedParameter.Description"
|
||||||
Label="Parameter Description"
|
Label="@T("Parameter Description")"
|
||||||
HelperText="A short description of the parameter. What data type is it? What is it used for? What are the possible values?"
|
HelperText="@T("A short description of the parameter. What data type is it? What is it used for? What are the possible values?")"
|
||||||
Lines="3"
|
Lines="3"
|
||||||
AutoGrow="@true"
|
AutoGrow="@true"
|
||||||
MaxLines="6"
|
MaxLines="6"
|
||||||
@@ -146,7 +145,7 @@
|
|||||||
|
|
||||||
<MudStack Row="@true">
|
<MudStack Row="@true">
|
||||||
<MudButton OnClick="@this.RemoveRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Secondary">
|
<MudButton OnClick="@this.RemoveRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Secondary">
|
||||||
Delete this parameter
|
@T("Delete this parameter")
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
@@ -155,22 +154,19 @@
|
|||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mb-3">
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
Embeddings
|
@T("Embeddings")
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
@if(this.AvailableEmbeddings.Count == 0)
|
@if(this.AvailableEmbeddings.Count == 0)
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
Currently, you have not defined any embedding methods. If your retrieval process does not require embedding, you can ignore this part.
|
@T("Currently, you have not defined any embedding methods. If your retrieval process does not require embedding, you can ignore this part. Otherwise, you can define one or more embedding methods in the previous view to assign them to your retrieval process here.")
|
||||||
Otherwise, you can define one or more embedding methods in the previous view to assign them to your retrieval process here.
|
|
||||||
</MudText>
|
</MudText>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudText Typo="Typo.body1" Class="mb-3">
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
Here you can select which embedding methods are used for this retrieval process. Embeddings are optional;
|
@T("Here you can select which embedding methods are used for this retrieval process. Embeddings are optional; if your retrieval process works without embedding, you can ignore this part. You can only choose the embedding methods you have previously defined.")
|
||||||
if your retrieval process works without embedding, you can ignore this part. You can only choose the embedding
|
|
||||||
methods you have previously defined.
|
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
<MudSelectExtended
|
<MudSelectExtended
|
||||||
@@ -181,11 +177,11 @@
|
|||||||
SelectedValuesChanged="@this.EmbeddingsChanged"
|
SelectedValuesChanged="@this.EmbeddingsChanged"
|
||||||
Strict="@true"
|
Strict="@true"
|
||||||
Margin="Margin.Dense"
|
Margin="Margin.Dense"
|
||||||
Label="Embeddings methods"
|
Label="@T("Embeddings methods")"
|
||||||
ShrinkLabel="@true"
|
ShrinkLabel="@true"
|
||||||
Class="mb-3"
|
Class="mb-3"
|
||||||
Variant="Variant.Outlined"
|
Variant="Variant.Outlined"
|
||||||
HelperText="Optional. Select the embedding methods that are used for this retrieval process.">
|
HelperText="@T("Optional. Select the embedding methods that are used for this retrieval process.")">
|
||||||
@foreach (var embedding in this.AvailableEmbeddings)
|
@foreach (var embedding in this.AvailableEmbeddings)
|
||||||
{
|
{
|
||||||
<MudSelectItemExtended Value="@embedding">
|
<MudSelectItemExtended Value="@embedding">
|
||||||
@@ -198,15 +194,17 @@
|
|||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
|
||||||
|
@T("Cancel")
|
||||||
|
</MudButton>
|
||||||
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
@if(this.IsEditing)
|
@if(this.IsEditing)
|
||||||
{
|
{
|
||||||
@:Update
|
@T("Update")
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@:Add
|
@T("Add")
|
||||||
}
|
}
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Components;
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
public partial class RetrievalProcessDialog : ComponentBase
|
public partial class RetrievalProcessDialog : MSGComponentBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private IMudDialogInstance MudDialog { get; set; } = null!;
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
@@ -60,9 +60,6 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool IsEditing { get; init; }
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
[Inject]
|
|
||||||
private SettingsManager SettingsManager { get; init; } = null!;
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
private bool dataIsValid;
|
private bool dataIsValid;
|
||||||
@@ -80,13 +77,13 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
// Configure the spellchecking for the instance name input:
|
// Configure the spellchecking for the instance name input:
|
||||||
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
||||||
|
|
||||||
// Convert the parameters:
|
// Convert the parameters:
|
||||||
this.retrievalParameters = this.DataParametersDescription.Select(pair => new RetrievalParameter { Name = pair.Key, Description = pair.Value }).ToList();
|
this.retrievalParameters = this.DataParametersDescription.Select(pair => new RetrievalParameter { Name = pair.Key, Description = pair.Value }).ToList();
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
@@ -104,13 +101,13 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
private string? ValidateName(string name)
|
private string? ValidateName(string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
return "The retrieval process name must not be empty. Please name your retrieval process.";
|
return T("The retrieval process name must not be empty. Please name your retrieval process.");
|
||||||
|
|
||||||
if (name.Length > 26)
|
if (name.Length > 26)
|
||||||
return "The retrieval process name must not be longer than 26 characters.";
|
return T("The retrieval process name must not be longer than 26 characters.");
|
||||||
|
|
||||||
if (this.UsedRetrievalProcessNames.Contains(name))
|
if (this.UsedRetrievalProcessNames.Contains(name))
|
||||||
return $"The retrieval process name '{name}' must be unique. Please choose a different name.";
|
return string.Format(T("The retrieval process name '{0}' must be unique. Please choose a different name."), name);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -118,26 +115,26 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
private string? ValidateDescription(string description)
|
private string? ValidateDescription(string description)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(description))
|
if (string.IsNullOrWhiteSpace(description))
|
||||||
return "The description must not be empty. Please describe the retrieval process.";
|
return T("The description must not be empty. Please describe the retrieval process.");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddRetrievalProcessParameter()
|
private void AddRetrievalProcessParameter()
|
||||||
{
|
{
|
||||||
this.retrievalParameters.Add(new() { Name = $"New Parameter {this.nextParameterId++}", Description = string.Empty });
|
this.retrievalParameters.Add(new() { Name = string.Format(T("New Parameter {0}"), this.nextParameterId++), Description = string.Empty });
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? ValidateParameterName(string name)
|
private string? ValidateParameterName(string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
return "The parameter name must not be empty. Please name the parameter.";
|
return T("The parameter name must not be empty. Please name the parameter.");
|
||||||
|
|
||||||
if(name.Length > 26)
|
if(name.Length > 26)
|
||||||
return "The parameter name must not be longer than 26 characters.";
|
return T("The parameter name must not be longer than 26 characters.");
|
||||||
|
|
||||||
if (this.retrievalParameters.Count(parameter => parameter.Name == name) > 1)
|
if (this.retrievalParameters.Count(parameter => parameter.Name == name) > 1)
|
||||||
return $"The parameter name '{name}' must be unique. Please choose a different name.";
|
return string.Format(T("The parameter name '{0}' must be unique. Please choose a different name."), name);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -145,7 +142,7 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
private string? ValidateParameterDescription(string description)
|
private string? ValidateParameterDescription(string description)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(description))
|
if (string.IsNullOrWhiteSpace(description))
|
||||||
return $"The parameter description must not be empty. Please describe the parameter '{this.selectedParameter?.Name}'. What data type is it? What is it used for? What are the possible values?";
|
return string.Format(T("The parameter description must not be empty. Please describe the parameter '{0}'. What data type is it? What is it used for? What are the possible values?"), this.selectedParameter?.Name);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -156,7 +153,7 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
return nameIssue;
|
return nameIssue;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(parameter.Description))
|
if (string.IsNullOrWhiteSpace(parameter.Description))
|
||||||
return $"The parameter description must not be empty. Please describe the parameter '{parameter.Name}'. What data type is it? What is it used for? What are the possible values?";
|
return string.Format(T("The parameter description must not be empty. Please describe the parameter '{0}'. What data type is it? What is it used for? What are the possible values?"), parameter.Name);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -172,12 +169,12 @@ public partial class RetrievalProcessDialog : ComponentBase
|
|||||||
private string GetMultiSelectionText(List<EmbeddingInfo> selectedEmbeddings)
|
private string GetMultiSelectionText(List<EmbeddingInfo> selectedEmbeddings)
|
||||||
{
|
{
|
||||||
if(selectedEmbeddings.Count == 0)
|
if(selectedEmbeddings.Count == 0)
|
||||||
return "No embedding methods selected.";
|
return T("No embedding methods selected.");
|
||||||
|
|
||||||
if(selectedEmbeddings.Count == 1)
|
if(selectedEmbeddings.Count == 1)
|
||||||
return "You have selected 1 embedding method.";
|
return T("You have selected 1 embedding method.");
|
||||||
|
|
||||||
return $"You have selected {selectedEmbeddings.Count} embedding methods.";
|
return string.Format(T("You have selected {0} embedding methods."), selectedEmbeddings.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmbeddingsChanged(IEnumerable<EmbeddingInfo>? updatedEmbeddings)
|
private void EmbeddingsChanged(IEnumerable<EmbeddingInfo>? updatedEmbeddings)
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
</MudPaper>
|
</MudPaper>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</MudDialog>
|
</MudDialog>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
@using AIStudio.Settings
|
||||||
|
@using AIStudio.Settings.DataModel
|
||||||
|
@inherits SettingsDialogBase
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6" Class="d-flex align-center">
|
||||||
|
<MudIcon Icon="@Icons.Material.Filled.Chat" Class="mr-2" />
|
||||||
|
@T("Chat Options")
|
||||||
|
</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
<DialogContent>
|
||||||
|
<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.availableLLMProviders" 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?")"/>
|
||||||
|
<ConfigurationSelect OptionDescription="@T("Preselect one of your chat templates?")" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedChatTemplate)" Data="@ConfigurationSelectDataFactory.GetChatTemplatesData(this.SettingsManager.ConfigurationData.ChatTemplates)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedChatTemplate = selectedValue)" OptionHelp="@T("Would you like to set one of your chat templates 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?")"/>
|
||||||
|
}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace AIStudio.Dialogs.Settings;
|
||||||
|
|
||||||
|
public partial class SettingsDialogChat : SettingsDialogBase;
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
@inherits SettingsDialogBase
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6" Class="d-flex align-center">
|
||||||
|
<MudIcon Icon="@Icons.Material.Filled.RateReview" Class="mr-2" />
|
||||||
|
@T("Your Chat Templates")
|
||||||
|
</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
<DialogContent>
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
@T("Customize your AI experience with chat templates. Whether you want to experiment with prompt engineering, simply use a custom system prompt in the standard chat interface, or create a specialized assistant, our templates give you full control. Similar to common AI companies' playgrounds, you can define your own system prompts and leverage assistant prompts for providers that support them.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
@T("Note: This advanced feature is designed for users familiar with prompt engineering concepts. Furthermore, you have to make sure yourself that your chosen provider supports the use of assistant prompts.")
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudTable Items="@this.SettingsManager.ConfigurationData.ChatTemplates" Hover="@true" Class="border-dashed border rounded-lg">
|
||||||
|
<ColGroup>
|
||||||
|
<col style="width: 3em;"/>
|
||||||
|
<col/>
|
||||||
|
<col style="width: 16em;"/>
|
||||||
|
</ColGroup>
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>#</MudTh>
|
||||||
|
<MudTh>@T("Chat Template 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.EditChatTemplate(context)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
<MudTooltip Text="@T("Delete")">
|
||||||
|
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteChatTemplate(context)"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
|
||||||
|
@if(this.SettingsManager.ConfigurationData.ChatTemplates.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h6" Class="mt-3">
|
||||||
|
@T("No chat templates configured yet.")
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddChatTemplate">
|
||||||
|
@T("Add Chat Template")
|
||||||
|
</MudButton>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using AIStudio.Settings;
|
||||||
|
|
||||||
|
namespace AIStudio.Dialogs.Settings;
|
||||||
|
|
||||||
|
public partial class SettingsDialogChatTemplate : SettingsDialogBase
|
||||||
|
{
|
||||||
|
private async Task AddChatTemplate()
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<ChatTemplateDialog>
|
||||||
|
{
|
||||||
|
{ x => x.IsEditing, false },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ChatTemplateDialog>(T("Add Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var addedChatTemplate = (ChatTemplate)dialogResult.Data!;
|
||||||
|
addedChatTemplate = addedChatTemplate with { Num = this.SettingsManager.ConfigurationData.NextChatTemplateNum++ };
|
||||||
|
|
||||||
|
this.SettingsManager.ConfigurationData.ChatTemplates.Add(addedChatTemplate);
|
||||||
|
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EditChatTemplate(ChatTemplate chatTemplate)
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<ChatTemplateDialog>
|
||||||
|
{
|
||||||
|
{ x => x.DataNum, chatTemplate.Num },
|
||||||
|
{ x => x.DataId, chatTemplate.Id },
|
||||||
|
{ x => x.DataName, chatTemplate.Name },
|
||||||
|
{ x => x.DataSystemPrompt, chatTemplate.SystemPrompt },
|
||||||
|
{ x => x.IsEditing, true },
|
||||||
|
{ x => x.ExampleConversation, chatTemplate.ExampleConversation },
|
||||||
|
{ x => x.AllowProfileUsage, chatTemplate.AllowProfileUsage },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ChatTemplateDialog>(T("Edit Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var editedChatTemplate = (ChatTemplate)dialogResult.Data!;
|
||||||
|
this.SettingsManager.ConfigurationData.ChatTemplates[this.SettingsManager.ConfigurationData.ChatTemplates.IndexOf(chatTemplate)] = editedChatTemplate;
|
||||||
|
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteChatTemplate(ChatTemplate chatTemplate)
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Message", string.Format(T("Are you sure you want to delete the chat template '{0}'?"), chatTemplate.Name) },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.SettingsManager.ConfigurationData.ChatTemplates.Remove(chatTemplate);
|
||||||
|
await this.SettingsManager.StoreSettings();
|
||||||
|
|
||||||
|
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</TitleContent>
|
</TitleContent>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<ConfigurationOption OptionDescription="Preselect grammar & spell checker options?" LabelOn="Grammar & spell checker options are preselected" LabelOff="No grammar & spell checker options are preselected" State="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect the grammar & spell checker options. This is might be useful when you prefer a specific language or LLM model."/>
|
<ConfigurationOption OptionDescription="@T("Preselect grammar & spell checker options?")" LabelOn="@T("Grammar & spell checker options are preselected")" LabelOff="@T("No grammar & spell checker options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect the grammar & spell checker options. This is might be useful when you prefer a specific language or LLM model.")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Preselect the target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage = selectedValue)" OptionHelp="@T("Which target language should be preselected?")"/>
|
<ConfigurationSelect OptionDescription="@T("Preselect the target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage = selectedValue)" OptionHelp="@T("Which target language should be preselected?")"/>
|
||||||
@if (this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
@if (this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
</TitleContent>
|
</TitleContent>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
|
||||||
<ConfigurationOption OptionDescription="Preselect localization options?" LabelOn="Localization options are preselected" LabelOff="No localization options are preselected" State="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.I18N.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect the localization options. This is might be useful when you prefer a specific language or LLM model."/>
|
<ConfigurationOption OptionDescription="@T("Preselect localization options?")" LabelOn="@T("Localization options are preselected")" LabelOff="@T("No localization options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.I18N.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect the localization options. This is might be useful when you prefer a specific language or LLM model.")"/>
|
||||||
<ConfigurationSelect OptionDescription="@T("Preselect the target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage = selectedValue)" OptionHelp="@T("Which target language should be preselected?")"/>
|
<ConfigurationSelect OptionDescription="@T("Preselect the target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesOptionalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage = selectedValue)" OptionHelp="@T("Which target language should be preselected?")"/>
|
||||||
@if (this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
@if (this.SettingsManager.ConfigurationData.I18N.PreselectedTargetLanguage is CommonLanguages.OTHER)
|
||||||
{
|
{
|
||||||
<ConfigurationText OptionDescription="@T("Preselect another target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.I18N.PreselectOtherLanguage = updatedText)"/>
|
<ConfigurationText OptionDescription="@T("Preselect another target language")" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.I18N.PreselectOtherLanguage = updatedText)"/>
|
||||||
}
|
}
|
||||||
<ConfigurationSelect OptionDescription="Language plugin used for comparision" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedLanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedLanguagePluginId = selectedValue)" OptionHelp="Select the language plugin used for comparision."/>
|
<ConfigurationSelect OptionDescription="@T("Language plugin used for comparision")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedLanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedLanguagePluginId = selectedValue)" OptionHelp="@T("Select the language plugin used for comparision.")"/>
|
||||||
<ConfigurationProviderSelection Component="Components.I18N_ASSISTANT" Data="@this.availableLLMProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedProvider = selectedValue)"/>
|
<ConfigurationProviderSelection Component="Components.I18N_ASSISTANT" Data="@this.availableLLMProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.I18N.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.I18N.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.I18N.PreselectedProvider = selectedValue)"/>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
@inherits SettingsDialogBase
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6" Class="d-flex align-center">
|
||||||
|
<MudIcon Icon="@Icons.Material.Filled.Person4" Class="mr-2" />
|
||||||
|
@T("Your Profiles")
|
||||||
|
</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
<DialogContent>
|
||||||
|
<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>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
|
||||||
|
@T("Close")
|
||||||
|
</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
+2
-5
@@ -1,11 +1,8 @@
|
|||||||
using AIStudio.Dialogs;
|
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
namespace AIStudio.Dialogs.Settings;
|
||||||
|
|
||||||
namespace AIStudio.Components.Settings;
|
public partial class SettingsDialogProfiles : SettingsDialogBase
|
||||||
|
|
||||||
public partial class SettingsPanelProfiles : SettingsPanelBase
|
|
||||||
{
|
{
|
||||||
private async Task AddProfile()
|
private async Task AddProfile()
|
||||||
{
|
{
|
||||||
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user