Compare commits

..
57 Commits
Author SHA1 Message Date
Thorsten Sommer f00722e0a6 Prepared release v0.9.51 (#557)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
2025-09-04 20:17:55 +02:00
Thorsten Sommer ce243913ed Fixed resetting profiles and chat templates on assistant reset (#556)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-09-04 11:26:06 +02:00
Thorsten Sommer fc37882773 Fixed bottom margin for code blocks in chat (#555)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
2025-09-04 11:11:49 +02:00
Thorsten Sommer 864bda1213 Fixed #546: made Lua tables for config objects optional (#554)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-09-03 22:41:28 +02:00
Thorsten Sommer 73b2f1fa6a Upgraded MudBlazor (#553) 2025-09-03 22:28:51 +02:00
Thorsten Sommer d966929dca Improved the I18N & the German translation (#552)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-09-03 22:14:31 +02:00
Thorsten Sommer 6a37ce6d25 Improved provider logging (#551)
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
2025-09-03 21:25:17 +02:00
Thorsten Sommer 70e64f2d14 Fixed Dependabot security alert regarding tracing-subscriber crate (#550)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-09-03 20:52:54 +02:00
Thorsten Sommer 38ec098430 Improved the OpenAI provider (#548)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
2025-09-03 10:08:04 +02:00
Peer Schüttandtsommer 4e167d58ea Fixed bugs in & related to the web content reader (#549)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Co-authored-by: Thorsten Sommer <mail@tsommer.org>
2025-09-01 19:13:02 +02:00
Thorsten Sommer f61fe87181 Fixed calling the workspace selection dialog (#547)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
2025-08-31 14:45:03 +02:00
Peer Schüttandtsommer 2a01d3bb6e Added support for Perplexity (#545)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Publish release (push) Blocked by required conditions
Co-authored-by: Thorsten Sommer <mail@tsommer.org>
2025-08-31 14:27:35 +02:00
Peer SchüttandThorsten Sommer adf61a1384 Improving the text summarizer assistant (#544)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
2025-08-30 10:35:40 +02:00
Thorsten Sommer f1c2a65450 Made dialog parameter usage explicit with generic types (#543)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
2025-08-28 18:51:44 +02:00
Thorsten Sommer e03289b680 Fixed input field header for single input dialog (#542)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
2025-08-28 18:31:50 +02:00
Thorsten Sommer 99dc2606aa Improved input validation for the single input dialog (#541) 2025-08-28 18:16:30 +02:00
Thorsten Sommer e931e28ab1 Improved workspace handling (#540)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
2025-08-28 16:44:32 +02:00
Thorsten Sommer 5d17dcc29b Added option for update installation behavior (#539)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
2025-08-26 20:06:13 +02:00
Thorsten Sommer c1826426d9 Refactored configuration objects (#538)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
2025-08-26 10:59:56 +02:00
Thorsten Sommer be11efed67 Allow chat templates in config plugins (#537)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
2025-08-18 20:40:52 +02:00
Thorsten Sommer 7d10bb00f7 Applied several small fixes (#536)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
2025-08-15 21:16:51 +02:00
Thorsten Sommer 9ca2860079 Fixed resetting bug in assistants (#535)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-08-15 20:07:05 +02:00
Thorsten Sommer 28b470f40b Prepared release v0.9.50 (#534)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
2025-08-10 18:47:06 +02:00
Thorsten Sommer 6b61f34fff Upgraded dependencies (#533)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
2025-08-10 18:32:38 +02:00
Thorsten Sommer 4197d5a0ee Fixed a profile selection visual bug in assistants (#532)
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
2025-08-10 17:59:49 +02:00
Thorsten Sommer 22aacff717 Improved the German translation (#531)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-08-10 16:39:07 +02:00
Peer SchüttandThorsten Sommer b75d90b13f Added vLLM support (#524)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
2025-08-10 16:26:25 +02:00
Peer SchüttandThorsten Sommer fe2baa8c00 Hide the enterprise configuration details by default (#523)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
2025-08-10 15:59:44 +02:00
Thorsten Sommer 7d22b77d47 Updated Git ignore (#530)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
2025-08-09 20:28:40 +02:00
Thorsten Sommer 96c1c0653d Fixed Windows pipeline (#529)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
2025-08-09 20:04:50 +02:00
Peer Schüttandtsommer 035412f7ff Adding providers can now be disabled using config plugins (#522)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Co-authored-by: Thorsten Sommer <mail@tsommer.org>
2025-08-09 19:29:43 +02:00
6116c03f7c Extension of the chat template (#521)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Co-authored-by: Thorsten Sommer <mail@tsommer.org>
Co-authored-by: Thorsten Sommer <thorsten.sommer@dlr.de>
2025-07-11 09:57:46 +02:00
Thorsten Sommer 9c52812c09 Prepared release v0.9.49 (#520)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
2025-07-02 14:15:35 +02:00
Thorsten Sommer be27fd84b8 Fixed chat bug causing the input box to occupy too much space (#519)
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
2025-07-02 14:01:10 +02:00
Thorsten Sommer 61ffddf1ec Improved the loading of the about page (#518)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
2025-07-02 13:34:21 +02:00
Thorsten Sommer 6d1ecb7678 Improved PowerPoint implementation for reading slide data (#517)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
2025-07-01 18:34:14 +02:00
Thorsten Sommer 68f5bb1512 Finished the function for importing arbitrary documents (#516) 2025-06-30 21:51:02 +02:00
aaedf667fe Allow loading any document in some assistants (#508)
Co-authored-by: krut_ni <nils.kruthoff@dlr.de>
Co-authored-by: Thorsten Sommer <mail@tsommer.org>
2025-06-30 18:56:48 +02:00
Thorsten Sommer 7df0b3e6e0 Refactored plugin settings handling for maintainability (#515) 2025-06-27 22:52:34 +02:00
Thorsten Sommer 1b8ed286e7 Fixed a bug with ERI data source retrieval process loading (#514) 2025-06-27 22:03:51 +02:00
Thorsten Sommer 87bb04e3c0 Improved text content phrasing in German and English (#513) 2025-06-27 21:40:39 +02:00
Thorsten Sommer 181ba07d2d Improved the loading of some components that require data fetching (#512) 2025-06-27 20:52:33 +02:00
Thorsten Sommer 3587f547b5 Refactored theme provider to replace obsolete calls (#511) 2025-06-27 20:03:28 +02:00
Thorsten Sommer cf17c643a0 Upgraded dependencies (#510) 2025-06-27 10:31:36 +02:00
Thorsten Sommer 7843426057 Fixed the web asset update logic in the build script (#509) 2025-06-27 10:02:32 +02:00
Thorsten Sommer 4db31fd9cf Added acknowledgment, docs, & final things for PowerPoint lib (#507) 2025-06-23 15:19:21 +02:00
nilskruthoffandkrut_ni 18b2e22725 Added support for reading PowerPoint files (#506)
Co-authored-by: krut_ni <nils.kruthoff@dlr.de>
2025-06-23 14:49:36 +02:00
Peer Schütt b6169e5bfb Changed chat time to local time format (#502) 2025-06-11 19:04:04 +02:00
Thorsten Sommer 4aeb51c9f1 Prepared release v0.9.48 (#501) 2025-06-11 10:20:49 +02:00
Peer Schütt 7c4ddf1164 Prepared release v0.9.48 (#500) 2025-06-10 15:40:25 +02:00
Peer Schütt 793a9cae0a Dont display <think> tags (#496) 2025-06-10 14:32:24 +02:00
Thorsten Sommer 368fc9ce39 Improved the German translation within the "send to" menu (#499) 2025-06-09 14:21:58 +02:00
Thorsten Sommer 2ef563e9ab Improved the confirmation dialog for longer texts (#498) 2025-06-09 14:13:31 +02:00
Thorsten Sommer 32e1ab977d Improved enterprise IT (#497) 2025-06-09 14:06:54 +02:00
Thorsten Sommer 7a498d524e Prepared release v0.9.47 (#495) 2025-06-02 20:29:09 +02:00
Thorsten Sommer ce915292dc Improved enterprise IT checks when run without such an environment (#494) 2025-06-02 20:22:15 +02:00
Thorsten Sommer 6979a73e5c Improved enterprise service (#493) 2025-06-02 20:08:25 +02:00
261 changed files with 6299 additions and 1973 deletions

No files matched your search

+13 -3
View File
@@ -362,7 +362,10 @@ jobs:
$PDFIUM_URL = "https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$($env:PDFIUM_VERSION)/pdfium-$PDFIUM_FILE" $PDFIUM_URL = "https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F$($env:PDFIUM_VERSION)/pdfium-$PDFIUM_FILE"
Write-Host "Download $PDFIUM_URL ..." Write-Host "Download $PDFIUM_URL ..."
$TMP = New-TemporaryFile | Split-Path
# Create a unique temporary directory (not just a file)
$TMP = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Path $TMP -Force | Out-Null
$ARCHIVE = Join-Path $TMP "pdfium.tgz" $ARCHIVE = Join-Path $TMP "pdfium.tgz"
Invoke-WebRequest -Uri $PDFIUM_URL -OutFile $ARCHIVE Invoke-WebRequest -Uri $PDFIUM_URL -OutFile $ARCHIVE
@@ -380,8 +383,15 @@ jobs:
Copy-Item -Path $SRC -Destination $DEST -Force Copy-Item -Path $SRC -Destination $DEST -Force
Write-Host "Cleaning up ..." Write-Host "Cleaning up ..."
Remove-Item $ARCHIVE -Force Remove-Item $ARCHIVE -Force -ErrorAction SilentlyContinue
Remove-Item $TMP -Recurse -Force
# Try to remove the temporary directory, but ignore errors if files are still in use
try {
Remove-Item $TMP -Recurse -Force -ErrorAction Stop
Write-Host "Successfully cleaned up temporary directory: $TMP"
} catch {
Write-Warning "Could not fully clean up temporary directory: $TMP. This is usually harmless as Windows will clean it up later. Error: $($_.Exception.Message)"
}
- name: Build .NET project - name: Build .NET project
run: | run: |
+3
View File
@@ -156,3 +156,6 @@ orleans.codegen.cs
**/.idea/**/uiDesigner.xml **/.idea/**/uiDesigner.xml
**/.idea/**/dbnavigator.xml **/.idea/**/dbnavigator.xml
**/.vs **/.vs
# Ignore AI plugin config files:
/app/.idea/.idea.MindWork AI Studio/.idea/AugmentWebviewStateStore.xml
+17
View File
@@ -0,0 +1,17 @@
# Project Guidelines
## Repository Structure
- The repository and the app consist of a Rust project in the `runtime` folder and a .NET solution in the `app` folder.
- The .NET solution then contains 4 .NET projects:
- `Build Script` is not required for running the app; instead, it contains the build script for creating new releases, for example.
- `MindWork AI Studio` contains the actual app code.
- `SharedTools` contains types that are needed in the build script and in the app, for example.
- `SourceCodeRules` is a Roslyn analyzer project. It contains analyzers and code fixes that we use to enforce code style rules within the team.
## Changelogs
- There is a changelog in Markdown format for each version.
- All changelogs are located in the folder `app/MindWork AI Studio/wwwroot/changelog`.
- These changelogs are intended for end users, not for developers.
- Therefore, we don't mention all changes in the changelog: changes that end users wouldn't understand remain unmentioned. For complex refactorings, for example, we mention a generic point that the code quality has been improved to enhance future maintenance.
- The changelog is always written in US English.
- The changelog doesn't mention bug fixes if the bug was never shipped and users don't know about it.
+8 -5
View File
@@ -33,8 +33,8 @@ Things we are currently working on:
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~ - [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
- [x] ~~Add support for other languages (I18N) to AI Studio ([PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~ - [x] ~~Add support for other languages (I18N) to AI Studio ([PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~ - [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
- [x] ~~Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486)~~) - [x] ~~Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations (~~[PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491)~~) - [x] ~~Add configuration plugins, which allow pre-defining some LLM providers in organizations ([PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491), [PR #493](https://github.com/MindWorkAI/AI-Studio/pull/493), [PR #494](https://github.com/MindWorkAI/AI-Studio/pull/494), [PR #497](https://github.com/MindWorkAI/AI-Studio/pull/497))~~
- [ ] Add 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.50: Added support for self-hosted LLMs using [vLLM](https://blog.vllm.ai/2023/06/20/vllm.html).
- v0.9.46: Released our plugin system, a German language plugin, early support for enterprise environments, and configuration plugins. Additionally, we added the Pandoc integration for future data processing and file generation. - v0.9.46: Released our plugin system, a German language plugin, early support for enterprise environments, and configuration plugins. Additionally, we added the Pandoc integration for future data processing and file generation.
- v0.9.45: Added chat templates to AI Studio, allowing you to create and use a library of system prompts for your chats. - v0.9.45: Added chat templates to AI Studio, allowing you to create and use a library of system prompts for your chats.
- v0.9.44: Added PDF import to the text summarizer, translation, and legal check assistants, allowing you to import PDF files and use them as input for the assistants. - v0.9.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.
@@ -57,7 +58,6 @@ Features we have recently released:
- v0.9.26+: Added RAG for external data sources using our [ERI interface](https://mindworkai.org/#eri---external-retrieval-interface) as a preview feature. - v0.9.26+: Added RAG for external data sources using our [ERI interface](https://mindworkai.org/#eri---external-retrieval-interface) as a preview feature.
- v0.9.25: Added [xAI](https://x.ai/) as a new provider. xAI provides their Grok models for generating content. - v0.9.25: Added [xAI](https://x.ai/) as a new provider. xAI provides their Grok models for generating content.
- v0.9.23: Added support for OpenAI `o` models (`o1`, `o1-mini`, `o3`, etc.); added also an [ERI](https://github.com/MindWorkAI/ERI) server coding assistant as a preview feature behind the RAG feature flag. Your own ERI server can be used to gain access to, e.g., your enterprise data from within AI Studio. - v0.9.23: Added support for OpenAI `o` models (`o1`, `o1-mini`, `o3`, etc.); added also an [ERI](https://github.com/MindWorkAI/ERI) server coding assistant as a preview feature behind the RAG feature flag. Your own ERI server can be used to gain access to, e.g., your enterprise data from within AI Studio.
- v0.9.22: Added options for preview features; added embedding provider configuration for RAG (preview) and writer mode (experimental preview).
## What is AI Studio? ## What is AI Studio?
@@ -71,7 +71,7 @@ MindWork AI Studio is a free desktop app for macOS, Windows, and Linux. It provi
**Key advantages:** **Key advantages:**
- **Free of charge**: The app is free to use, both for personal and commercial purposes. - **Free of charge**: The app is free to use, both for personal and commercial purposes.
- **Independence**: You are not tied to any single provider. Instead, you can choose the providers that best suit your needs. Right now, we support: - **Independence**: You are not tied to any single provider. Instead, you can choose the providers that best suit your needs. Right now, we support:
- [OpenAI](https://openai.com/) (GPT4o, GPT4.1, o1, o3, o4, etc.) - [OpenAI](https://openai.com/) (GPT5, GPT4.1, o1, o3, o4, etc.)
- [Mistral](https://mistral.ai/) - [Mistral](https://mistral.ai/)
- [Anthropic](https://www.anthropic.com/) (Claude) - [Anthropic](https://www.anthropic.com/) (Claude)
- [Google Gemini](https://gemini.google.com) - [Google Gemini](https://gemini.google.com)
@@ -79,7 +79,7 @@ MindWork AI Studio is a free desktop app for macOS, Windows, and Linux. It provi
- [DeepSeek](https://www.deepseek.com/en) - [DeepSeek](https://www.deepseek.com/en)
- [Alibaba Cloud](https://www.alibabacloud.com) (Qwen) - [Alibaba Cloud](https://www.alibabacloud.com) (Qwen)
- [Hugging Face](https://huggingface.co/) using their [inference providers](https://huggingface.co/docs/inference-providers/index) such as Cerebras, Nebius, Sambanova, Novita, Hyperbolic, Together AI, Fireworks, Hugging Face - [Hugging Face](https://huggingface.co/) using their [inference providers](https://huggingface.co/docs/inference-providers/index) such as Cerebras, Nebius, Sambanova, Novita, Hyperbolic, Together AI, Fireworks, Hugging Face
- Self-hosted models using [llama.cpp](https://github.com/ggerganov/llama.cpp), [ollama](https://github.com/ollama/ollama), [LM Studio](https://lmstudio.ai/) - Self-hosted models using [llama.cpp](https://github.com/ggerganov/llama.cpp), [ollama](https://github.com/ollama/ollama), [LM Studio](https://lmstudio.ai/), and [vLLM](https://github.com/vllm-project/vllm)
- [Groq](https://groq.com/) - [Groq](https://groq.com/)
- [Fireworks](https://fireworks.ai/) - [Fireworks](https://fireworks.ai/)
- For scientists and employees of research institutions, we also support [Helmholtz](https://helmholtz.cloud/services/?serviceID=d7d5c597-a2f6-4bd1-b71e-4d6499d98570) and [GWDG](https://gwdg.de/services/application-services/ai-services/) AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities. - For scientists and employees of research institutions, we also support [Helmholtz](https://helmholtz.cloud/services/?serviceID=d7d5c597-a2f6-4bd1-b71e-4d6499d98570) and [GWDG](https://gwdg.de/services/application-services/ai-services/) AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.
@@ -123,6 +123,9 @@ Stay tuned for more updates and enhancements to make MindWork AI Studio even mor
## Building ## Building
You want to know how to build MindWork AI Studio from source? [Check out the instructions here](documentation/Build.md). You want to know how to build MindWork AI Studio from source? [Check out the instructions here](documentation/Build.md).
## Enterprise IT
Do you want to manage AI Studio centrally from your IT department? Yes, that’s possible. [Here’s how it works.](documentation/Enterprise%20IT.md)
## License ## License
MindWork AI Studio is licensed under the `FSL-1.1-MIT` license (functional source license). Here’s a simple rundown of what that means for you: MindWork AI Studio is licensed under the `FSL-1.1-MIT` license (functional source license). Here’s a simple rundown of what that means for you:
- **Permitted Use**: Feel free to use, copy, modify, and share the software for your own projects, educational purposes, research, or even in professional services. The key is to use it in a way that doesn't compete with our offerings. - **Permitted Use**: Feel free to use, copy, modify, and share the software for your own projects, educational purposes, research, or even in professional services. The key is to use it in a way that doesn't compete with our offerings.
+11 -3
View File
@@ -20,6 +20,7 @@ public sealed class UpdateWebAssetsCommand
var rid = Environment.GetCurrentRid(); var rid = Environment.GetCurrentRid();
var cwd = Environment.GetAIStudioDirectory(); var cwd = Environment.GetAIStudioDirectory();
var contentPath = Path.Join(cwd, "bin", "release", Environment.DOTNET_VERSION, rid.AsMicrosoftRid(), "publish", "wwwroot", "_content"); var contentPath = Path.Join(cwd, "bin", "release", Environment.DOTNET_VERSION, rid.AsMicrosoftRid(), "publish", "wwwroot", "_content");
var isMudBlazorDirectoryPresent = Directory.Exists(Path.Join(contentPath, "MudBlazor")); var isMudBlazorDirectoryPresent = Directory.Exists(Path.Join(contentPath, "MudBlazor"));
if (!isMudBlazorDirectoryPresent) if (!isMudBlazorDirectoryPresent)
{ {
@@ -28,14 +29,21 @@ public sealed class UpdateWebAssetsCommand
return; return;
} }
Directory.CreateDirectory(Path.Join(cwd, "wwwroot", "system")); var destinationPath = Path.Join(cwd, "wwwroot", "system");
if(Directory.Exists(destinationPath))
Directory.Delete(destinationPath, true);
Directory.CreateDirectory(destinationPath);
var sourcePaths = Directory.EnumerateFiles(contentPath, "*", SearchOption.AllDirectories); var sourcePaths = Directory.EnumerateFiles(contentPath, "*", SearchOption.AllDirectories);
var counter = 0; var counter = 0;
foreach(var sourcePath in sourcePaths) foreach(var sourcePath in sourcePaths)
{ {
counter++; counter++;
var relativePath = Path.GetRelativePath(cwd, sourcePath); var relativePath = sourcePath
var targetPath = Path.Join(cwd, "wwwroot", relativePath); .Replace(contentPath, "")
.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var targetPath = Path.Join(cwd, "wwwroot", "system", relativePath);
var targetDirectory = Path.GetDirectoryName(targetPath); var targetDirectory = Path.GetDirectoryName(targetPath);
if (targetDirectory != null) if (targetDirectory != null)
Directory.CreateDirectory(targetDirectory); Directory.CreateDirectory(targetDirectory);
+2
View File
@@ -5,6 +5,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FNV/@EntryIndexedValue">FNV</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FNV/@EntryIndexedValue">FNV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GWDG/@EntryIndexedValue">GWDG</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GWDG/@EntryIndexedValue">GWDG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HF/@EntryIndexedValue">HF</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HF/@EntryIndexedValue">HF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IERI/@EntryIndexedValue">IERI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LLM/@EntryIndexedValue">LLM</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LLM/@EntryIndexedValue">LLM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LM/@EntryIndexedValue">LM</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LM/@EntryIndexedValue">LM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSG/@EntryIndexedValue">MSG</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSG/@EntryIndexedValue">MSG</s:String>
@@ -20,6 +21,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=groq/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=groq/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=gwdg/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=gwdg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=huggingface/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=huggingface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ieri/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mwais/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=mwais/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=ollama/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=tauri_0027s/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/UserDictionary/Words/=tauri_0027s/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+3 -5
View File
@@ -54,7 +54,7 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
#region Implementation of IAgent #region Implementation of IAgent
public abstract AIStudio.Settings.Provider? ProviderSettings { get; set; } public abstract AIStudio.Settings.Provider ProviderSettings { get; set; }
public abstract Task<ChatThread> ProcessContext(ChatThread chatThread, IDictionary<string, string> additionalData); public abstract Task<ChatThread> ProcessContext(ChatThread chatThread, IDictionary<string, string> additionalData);
@@ -73,7 +73,6 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
WorkspaceId = Guid.Empty, WorkspaceId = Guid.Empty,
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = this.RNG.Next(),
SystemPrompt = systemPrompt, SystemPrompt = systemPrompt,
Blocks = [], Blocks = [],
}; };
@@ -103,10 +102,9 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
protected async Task AddAIResponseAsync(ChatThread thread, IContent lastUserPrompt, DateTimeOffset time) protected async Task AddAIResponseAsync(ChatThread thread, IContent lastUserPrompt, DateTimeOffset time)
{ {
if(this.ProviderSettings is null) if(this.ProviderSettings == Settings.Provider.NONE)
return; return;
var providerSettings = this.ProviderSettings.Value;
var aiText = new ContentText var aiText = new ContentText
{ {
// We have to wait for the remote // We have to wait for the remote
@@ -127,6 +125,6 @@ public abstract class AgentBase(ILogger<AgentBase> logger, SettingsManager setti
// Use the selected provider to get the AI response. // Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire // By awaiting this line, we wait for the entire
// content to be streamed. // content to be streamed.
await aiText.CreateFromProviderAsync(providerSettings.CreateProvider(this.Logger), providerSettings.Model, lastUserPrompt, thread); await aiText.CreateFromProviderAsync(this.ProviderSettings.CreateProvider(), this.ProviderSettings.Model, lastUserPrompt, thread);
} }
} }
@@ -86,7 +86,7 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
"""; """;
/// <inheritdoc /> /// <inheritdoc />
public override Settings.Provider? ProviderSettings { get; set; } public override Settings.Provider ProviderSettings { get; set; } = Settings.Provider.NONE;
/// <summary> /// <summary>
/// The data source selection agent does not work with context. Use /// The data source selection agent does not work with context. Use
@@ -141,6 +141,11 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
// We start with the provider currently selected by the user: // We start with the provider currently selected by the user:
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true); var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_DATA_SOURCE_SELECTION, provider.Id, true);
if (agentProvider == Settings.Provider.NONE)
{
logger.LogWarning("No provider is selected for the agent. The agent cannot select data sources.");
return [];
}
// Assign the provider settings to the agent: // Assign the provider settings to the agent:
logger.LogInformation($"The agent for the data source selection uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()})."); logger.LogInformation($"The agent for the data source selection uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
@@ -71,7 +71,7 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
"""; """;
/// <inheritdoc /> /// <inheritdoc />
public override Settings.Provider? ProviderSettings { get; set; } public override Settings.Provider ProviderSettings { get; set; } = Settings.Provider.NONE;
/// <summary> /// <summary>
/// The retrieval context validation agent does not work with context. Use /// The retrieval context validation agent does not work with context. Use
@@ -133,6 +133,11 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
{ {
// We start with the provider currently selected by the user: // We start with the provider currently selected by the user:
var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true); var agentProvider = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION, provider.Id, true);
if (agentProvider == Settings.Provider.NONE)
{
logger.LogWarning("No provider is selected for the agent.");
return;
}
// Assign the provider settings to the agent: // Assign the provider settings to the agent:
logger.LogInformation($"The agent for the retrieval context validation uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()})."); logger.LogInformation($"The agent for the retrieval context validation uses the provider '{agentProvider.InstanceName}' ({agentProvider.UsedLLMProvider.ToName()}, confidence={agentProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level.GetName()}).");
@@ -11,7 +11,7 @@ public sealed class AgentTextContentCleaner(ILogger<AgentBase> logger, SettingsM
#region Overrides of AgentBase #region Overrides of AgentBase
public override AIStudio.Settings.Provider? ProviderSettings { get; set; } public override AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
protected override Type Type => Type.SYSTEM; protected override Type Type => Type.SYSTEM;
+1 -1
View File
@@ -12,7 +12,7 @@ public interface IAgent
/// <summary> /// <summary>
/// The provider to use for this agent. /// The provider to use for this agent.
/// </summary> /// </summary>
public AIStudio.Settings.Provider? ProviderSettings { get; set; } public Settings.Provider ProviderSettings { get; set; }
/// <summary> /// <summary>
/// Processes a chat thread (i.e., context) and returns the updated thread. /// Processes a chat thread (i.e., context) and returns the updated thread.
@@ -6,10 +6,10 @@
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2 mr-3" StretchItems="StretchItems.Start"> <MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2 mr-3" StretchItems="StretchItems.Start">
<MudText Typo="Typo.h3"> <MudText Typo="Typo.h3">
@(this.Title) @this.Title
</MudText> </MudText>
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="() => this.OpenSettingsDialog()"/> <MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="@(async () => await this.OpenSettingsDialog())"/>
</MudStack> </MudStack>
<InnerScrolling> <InnerScrolling>
@@ -26,13 +26,13 @@
</CascadingValue> </CascadingValue>
<MudStack Row="true" AlignItems="AlignItems.Center" StretchItems="StretchItems.Start" Class="mb-3"> <MudStack Row="true" AlignItems="AlignItems.Center" StretchItems="StretchItems.Start" Class="mb-3">
<MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" OnClick="async () => await this.Start()" Style="@this.SubmitButtonStyle"> <MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" OnClick="@(async () => await this.Start())" Style="@this.SubmitButtonStyle">
@this.SubmitText @this.SubmitText
</MudButton> </MudButton>
@if (this.isProcessing && this.cancellationTokenSource is not null) @if (this.isProcessing && this.cancellationTokenSource is not null)
{ {
<MudTooltip Text="@TB("Stop generation")"> <MudTooltip Text="@TB("Stop generation")">
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="() => this.CancelStreaming()"/> <MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="@(async () => await this.CancelStreaming())"/>
</MudTooltip> </MudTooltip>
} }
</MudStack> </MudStack>
@@ -71,7 +71,7 @@
</div> </div>
</ChildContent> </ChildContent>
<FooterContent> <FooterContent>
<MudStack Row="@true" Wrap="Wrap.Wrap" Class="ma-1"> <MudStack Row="@true" Wrap="Wrap.Wrap" AlignItems="AlignItems.Center" StretchItems="StretchItems.None" Class="ma-1">
@if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO)) @if (!this.FooterButtons.Any(x => x.Type is ButtonTypes.SEND_TO))
{ {
@@ -80,7 +80,7 @@
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded"> <MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length)) @foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
{ {
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, new())"> <MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, new()))">
@assistant.Name() @assistant.Name()
</MudMenuItem> </MudMenuItem>
} }
@@ -94,14 +94,14 @@
{ {
case ButtonData buttonData when !string.IsNullOrWhiteSpace(buttonData.Tooltip): case ButtonData buttonData when !string.IsNullOrWhiteSpace(buttonData.Tooltip):
<MudTooltip Text="@buttonData.Tooltip"> <MudTooltip Text="@buttonData.Tooltip">
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> <MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="@(async () => await buttonData.AsyncAction())">
@buttonData.Text @buttonData.Text
</MudButton> </MudButton>
</MudTooltip> </MudTooltip>
break; break;
case ButtonData buttonData: case ButtonData buttonData:
<MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="async () => await buttonData.AsyncAction()"> <MudButton Variant="Variant.Filled" Color="@buttonData.Color" Disabled="@buttonData.DisabledAction()" StartIcon="@GetButtonIcon(buttonData.Icon)" OnClick="@(async () => await buttonData.AsyncAction())">
@buttonData.Text @buttonData.Text
</MudButton> </MudButton>
break; break;
@@ -110,7 +110,7 @@
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded"> <MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded">
@foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length)) @foreach (var assistant in Enum.GetValues<Components>().Where(n => n.AllowSendTo()).OrderBy(n => n.Name().Length))
{ {
<MudMenuItem OnClick="() => this.SendToAssistant(assistant, sendToButton)"> <MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, sendToButton))">
@assistant.Name() @assistant.Name()
</MudMenuItem> </MudMenuItem>
} }
@@ -121,14 +121,14 @@
@if (this.ShowCopyResult) @if (this.ShowCopyResult)
{ {
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="() => this.CopyToClipboard()"> <MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="@(async () => await this.CopyToClipboard())">
@TB("Copy result") @TB("Copy result")
</MudButton> </MudButton>
} }
@if (this.ShowReset) @if (this.ShowReset)
{ {
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()"> <MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" OnClick="@(async () => await this.InnerResetForm())">
@TB("Reset") @TB("Reset")
</MudButton> </MudButton>
} }
@@ -21,9 +21,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
[Inject] [Inject]
protected IJSRuntime JsRuntime { get; init; } = null!; protected IJSRuntime JsRuntime { get; init; } = null!;
[Inject]
protected ThreadSafeRandom RNG { get; init; } = null!;
[Inject] [Inject]
protected ISnackbar Snackbar { get; init; } = null!; protected ISnackbar Snackbar { get; init; } = null!;
@@ -85,7 +82,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
protected virtual IReadOnlyList<IButtonData> FooterButtons => []; protected virtual IReadOnlyList<IButtonData> FooterButtons => [];
protected AIStudio.Settings.Provider providerSettings; protected AIStudio.Settings.Provider providerSettings = Settings.Provider.NONE;
protected MudForm? form; protected MudForm? form;
protected bool inputIsValid; protected bool inputIsValid;
protected Profile currentProfile = Profile.NO_PROFILE; protected Profile currentProfile = Profile.NO_PROFILE;
@@ -199,7 +196,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
WorkspaceId = Guid.Empty, WorkspaceId = Guid.Empty,
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Format(this.TB("Assistant - {0}"), this.Title), Name = string.Format(this.TB("Assistant - {0}"), this.Title),
Seed = this.RNG.Next(),
Blocks = [], Blocks = [],
}; };
} }
@@ -215,7 +211,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
WorkspaceId = workspaceId, WorkspaceId = workspaceId,
ChatId = chatId, ChatId = chatId,
Name = name, Name = name,
Seed = this.RNG.Next(),
Blocks = [], Blocks = [],
}; };
@@ -275,7 +270,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
// Use the selected provider to get the AI response. // Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire // By awaiting this line, we wait for the entire
// content to be streamed. // content to be streamed.
this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, this.lastUserPrompt, this.chatThread, this.cancellationTokenSource!.Token); this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(), this.providerSettings.Model, this.lastUserPrompt, this.chatThread, this.cancellationTokenSource!.Token);
this.isProcessing = false; this.isProcessing = false;
this.StateHasChanged(); this.StateHasChanged();
@@ -352,13 +347,15 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
private async Task InnerResetForm() private async Task InnerResetForm()
{ {
this.resultingContentBlock = null; this.resultingContentBlock = null;
this.providerSettings = default; this.providerSettings = Settings.Provider.NONE;
await this.JsRuntime.ClearDiv(RESULT_DIV_ID); await this.JsRuntime.ClearDiv(RESULT_DIV_ID);
await this.JsRuntime.ClearDiv(AFTER_RESULT_DIV_ID); await this.JsRuntime.ClearDiv(AFTER_RESULT_DIV_ID);
this.ResetForm(); this.ResetForm();
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component); this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(this.Component);
this.inputIsValid = false; this.inputIsValid = false;
this.inputIssues = []; this.inputIssues = [];
@@ -384,8 +381,18 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
protected override void DisposeResources() protected override void DisposeResources()
{ {
try
{
this.formChangeTimer.Stop();
this.formChangeTimer.Dispose(); this.formChangeTimer.Dispose();
} }
catch
{
// ignore
}
base.DisposeResources();
}
#endregion #endregion
} }
@@ -473,9 +473,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
if(this.selectedERIServer is null) if(this.selectedERIServer is null)
return; return;
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the ERI server preset '{0}'?"), this.selectedERIServer.ServerName) }, { x => x.Message, string.Format(T("Are you sure you want to delete the ERI server preset '{0}'?"), this.selectedERIServer.ServerName) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete ERI server preset"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete ERI server preset"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -827,9 +827,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
? string.Format(T("The embedding '{0}' is used in one or more retrieval processes. Are you sure you want to delete it?"), embeddingInfo.EmbeddingName) ? string.Format(T("The embedding '{0}' is used in one or more retrieval processes. Are you sure you want to delete it?"), embeddingInfo.EmbeddingName)
: string.Format(T("Are you sure you want to delete the embedding '{0}'?"), embeddingInfo.EmbeddingName); : string.Format(T("Are you sure you want to delete the embedding '{0}'?"), embeddingInfo.EmbeddingName);
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", message }, { x => x.Message, message },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -890,9 +890,9 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
private async Task DeleteRetrievalProcess(RetrievalInfo retrievalInfo) private async Task DeleteRetrievalProcess(RetrievalInfo retrievalInfo)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the retrieval process '{0}'?"), retrievalInfo.Name) }, { x => x.Message, string.Format(T("Are you sure you want to delete the retrieval process '{0}'?"), retrievalInfo.Name) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Retrieval Process"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -1222,12 +1222,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::
-- Target language -- Target language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T237828418"] = "Target language" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T237828418"] = "Target language"
-- (Optional) Important Aspects
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T24391765"] = "(Optional) Important Aspects"
-- Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand. -- Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T359929871"] = "Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand." UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T359929871"] = "Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand."
-- Please provide your field of expertise. -- Please provide your field of expertise.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3610378685"] = "Please provide your field of expertise." UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3610378685"] = "Please provide your field of expertise."
-- (Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3830285347"] = "(Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize."
-- Custom target language -- Custom target language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3848935911"] = "Custom target language" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3848935911"] = "Custom target language"
@@ -1315,9 +1321,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CHATROLEEXTENSIONS::T601166687"] = "AI"
-- Edit Message -- Edit Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message"
-- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T12948066"] = "Copies the content to the clipboard"
-- Do you really want to remove this message? -- Do you really want to remove this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?"
@@ -1330,6 +1333,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1603883875"] = "Yes, re
-- Yes, remove it -- Yes, remove it
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Yes, remove it" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Yes, remove it"
-- Number of sources
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1848978959"] = "Number of sources"
-- Do you really want to edit this message? In order to edit this message, the AI response will be deleted. -- Do you really want to edit this message? In order to edit this message, the AI response will be deleted.
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Do you really want to edit this message? In order to edit this message, the AI response will be deleted." UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Do you really want to edit this message? In order to edit this message, the AI response will be deleted."
@@ -1351,9 +1357,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3587744975"] = "Regener
-- Do you really want to regenerate this message? -- Do you really want to regenerate this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Do you really want to regenerate this message?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Do you really want to regenerate this message?"
-- Cannot copy this content type to clipboard!
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4021525742"] = "Cannot copy this content type to clipboard!"
-- Remove Message -- Remove Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove Message" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove Message"
@@ -1414,6 +1417,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T636393754"] = "Move the c
-- Show your workspaces -- Show your workspaces
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T733672375"] = "Show your workspaces" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T733672375"] = "Show your workspaces"
-- Create template from current chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1112722156"] = "Create template from current chat"
-- Start a new chat with a chat template -- Start a new chat with a chat template
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1333844707"] = "Start a new chat with a chat template" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1333844707"] = "Start a new chat with a chat template"
@@ -1447,6 +1453,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T3243388657"] = "Confiden
-- Shows and hides the confidence card with information about the selected LLM provider. -- Shows and hides the confidence card with information about the selected LLM provider.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T847071819"] = "Shows and hides the confidence card with information about the selected LLM provider." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T847071819"] = "Shows and hides the confidence card with information about the selected LLM provider."
-- This feature is managed by your organization and has therefore been disabled.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONBASE::T1416426626"] = "This feature is managed by your organization and has therefore been disabled."
-- Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level. -- Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T2526727283"] = "Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T2526727283"] = "Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level."
@@ -1585,6 +1594,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T372007989"] = "Relying on we
-- Cross-Platform and Modern Development -- Cross-Platform and Modern Development
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T843057510"] = "Cross-Platform and Modern Development" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T843057510"] = "Cross-Platform and Modern Development"
-- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T12948066"] = "Copies the content to the clipboard"
-- Cannot copy this content type to clipboard.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T3937637647"] = "Cannot copy this content type to clipboard."
-- Alpha phase means that we are working on the last details before the beta phase. -- Alpha phase means that we are working on the last details before the beta phase.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha phase means that we are working on the last details before the beta phase." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha phase means that we are working on the last details before the beta phase."
@@ -1648,11 +1663,17 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROFILESELECTION::T918741365"] = "You can
-- Provider -- Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Provider" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Provider"
-- Use PDF content as input -- Images are not supported yet
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READPDFCONTENT::T2849276709"] = "Use PDF content as input" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T298062956"] = "Images are not supported yet"
-- Select PDF file -- Use file content as input
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READPDFCONTENT::T63272795"] = "Select PDF file" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T3499386973"] = "Use file content as input"
-- Select file to read its content
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T354817589"] = "Select file to read its content"
-- Executables are not allowed
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T4167762413"] = "Executables are not allowed"
-- The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used. -- The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T1164201762"] = "The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T1164201762"] = "The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used."
@@ -1693,6 +1714,24 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3825586228"] = "Please p
-- Show web content options -- Show web content options
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T4249712357"] = "Show web content options" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T4249712357"] = "Show web content options"
-- Loading
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T1404011351"] = "Loading"
-- Start
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T182978943"] = "Start"
-- Done
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T2379421585"] = "Done"
-- Parsing
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T3151033983"] = "Parsing"
-- Cleaning
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T3420573362"] = "Cleaning"
-- n/a
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T907272257"] = "n/a"
-- Hide content -- Hide content
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SECRETINPUTFIELD::T1273315904"] = "Hide content" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SECRETINPUTFIELD::T1273315904"] = "Hide content"
@@ -1711,6 +1750,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANE
-- Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used. -- Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T1299550589"] = "Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T1299550589"] = "Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used."
-- Agent: Text Content Cleaner Options
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T3517268866"] = "Agent: Text Content Cleaner Options"
-- No options are preselected -- No options are preselected
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T354528094"] = "No options are preselected" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T354528094"] = "No options are preselected"
@@ -1813,6 +1855,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"]
-- Language behavior -- Language behavior
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Language behavior"
-- Update installation method
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Update installation method"
-- Language -- Language
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Language"
@@ -1843,6 +1888,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T602293588"]
-- Choose the color theme that best suits for you. -- Choose the color theme that best suits for you.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Choose the color theme that best suits for you."
-- Should updates be installed automatically or manually?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T707880477"] = "Should updates be installed automatically or manually?"
-- Energy saving is enabled -- Energy saving is enabled
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energy saving is enabled"
@@ -2098,6 +2146,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1016188706"] = "Are you sure
-- Move chat -- Move chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Move chat"
-- Unnamed workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1307384014"] = "Unnamed workspace"
-- Delete -- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Delete"
@@ -2131,6 +2182,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Are you sure
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
-- Please enter a chat name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Please enter a chat name."
-- Workspace Name
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2446263209"] = "Workspace Name"
-- Move to workspace -- Move to workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
@@ -2143,6 +2200,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Move Chat to
-- Please enter a new or edit the name for your workspace '{0}': -- Please enter a new or edit the name for your workspace '{0}':
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Please enter a workspace name."
-- Unnamed chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat"
-- Rename -- Rename
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Rename"
@@ -2155,6 +2218,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3555709365"] = "Load Chat"
-- Add Workspace -- Add Workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Add Workspace"
-- Chat Name
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3891063690"] = "Chat Name"
-- Empty chat -- Empty chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Empty chat"
@@ -2188,18 +2254,30 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T1847791252"] = "Update"
-- The chat template name must not exceed 40 characters. -- The chat template name must not exceed 40 characters.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T204496403"] = "The chat template name must not exceed 40 characters." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T204496403"] = "The chat template name must not exceed 40 characters."
-- Profile Usage
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2147062613"] = "Profile Usage"
-- 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. -- 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.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2292424657"] = "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." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2292424657"] = "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."
-- Role -- Role
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2418769465"] = "Role" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2418769465"] = "Role"
-- What predefined user input do you want to use?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2501284417"] = "What predefined user input do you want to use?"
-- Tell the AI your system prompt. -- Tell the AI your system prompt.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2552381261"] = "Tell the AI your system prompt." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2552381261"] = "Tell the AI your system prompt."
-- No, prohibit profile use for this template -- No, prohibit profile use for this template
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579080722"] = "No, prohibit profile use for this template" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579080722"] = "No, prohibit profile use for this template"
-- You might want to predefine a first message that will be copied into the user prompt, when you use this chat template. This message could for example be a blueprint for a structured message that this chat template is defined to work with.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579208700"] = "You might want to predefine a first message that will be copied into the user prompt, when you use this chat template. This message could for example be a blueprint for a structured message that this chat template is defined to work with."
-- Predefined User Input
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2607897066"] = "Predefined User Input"
-- Entry -- Entry
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2629823795"] = "Entry" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2629823795"] = "Entry"
@@ -2254,6 +2332,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T3893704289"] = "Message
-- Use the default system prompt -- Use the default system prompt
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4051106111"] = "Use the default system prompt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4051106111"] = "Use the default system prompt"
-- Tell the AI your predefined user input.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4052406705"] = "Tell the AI your predefined user input."
-- 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. -- 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.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4199560726"] = "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." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4199560726"] = "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."
@@ -3385,6 +3466,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T32678
-- Close -- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3448155331"] = "Close" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3448155331"] = "Close"
-- This template is managed by your organization.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3576775249"] = "This template is managed by your organization."
-- Edit Chat Template -- Edit Chat Template
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3596030597"] = "Edit Chat Template" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3596030597"] = "Edit Chat Template"
@@ -3928,12 +4012,18 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T364
-- When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it. -- When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3660434400"] = "When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3660434400"] = "When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it."
-- Preselect important aspects
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3705987833"] = "Preselect important aspects"
-- When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM. -- When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3820844575"] = "When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3820844575"] = "When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM."
-- Which summarizer complexity should be preselected? -- Which summarizer complexity should be preselected?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T408530182"] = "Which summarizer complexity should be preselected?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T408530182"] = "Which summarizer complexity should be preselected?"
-- Preselect aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T414420518"] = "Preselect aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize."
-- Preselect your expertise -- Preselect your expertise
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T51139714"] = "Preselect your expertise" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T51139714"] = "Preselect your expertise"
@@ -4087,8 +4177,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832
-- Preselect one of your profiles? -- Preselect one of your profiles?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Preselect one of your profiles?"
-- Chat name -- Please enter a value.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Please enter a value."
-- Your Input
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T4030229154"] = "Your Input"
-- Cancel -- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"
@@ -4156,8 +4249,11 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1020427799"] = "About MindWork AI Stud
-- Browse AI Studio's source code on GitHub — we welcome your contributions. -- Browse AI Studio's source code on GitHub — we welcome your contributions.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1107156991"] = "Browse AI Studio's source code on GitHub — we welcome your contributions." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1107156991"] = "Browse AI Studio's source code on GitHub — we welcome your contributions."
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available. -- This is a private AI Studio installation. It runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1297057566"] = "AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1209549230"] = "This is a private AI Studio installation. It runs without an enterprise configuration."
-- AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1282228996"] = "AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available."
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat. -- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat."
@@ -4165,12 +4261,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "This library is used t
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library. -- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1421513382"] = "This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1421513382"] = "This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library."
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1454889560"] = "AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active."
-- AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1530477579"] = "AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management."
-- We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library. -- We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T162898512"] = "We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T162898512"] = "We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library."
@@ -4189,6 +4279,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1806897624"] = "By clicking on the res
-- Pandoc Installation -- Pandoc Installation
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T185447014"] = "Pandoc Installation" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T185447014"] = "Pandoc Installation"
-- Copies the configuration plugin ID to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1859295819"] = "Copies the configuration plugin ID to the clipboard"
-- Check for updates -- Check for updates
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1890416390"] = "Check for updates" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1890416390"] = "Check for updates"
@@ -4204,21 +4297,30 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1924365263"] = "This library is used t
-- We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust. -- We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1943216839"] = "We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1943216839"] = "We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust."
-- Copies the server URL to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2037899437"] = "Copies the server URL to the clipboard"
-- This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file. -- This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file."
-- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose. -- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose."
-- AI Studio runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio runs without an enterprise configuration."
-- OK -- OK
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
-- Configuration server:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2272122662"] = "Configuration server:"
-- We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose. -- We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2273492381"] = "We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2273492381"] = "We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose."
-- AI Studio runs with an enterprise configuration using a configuration plugin, without central configuration management.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2280402765"] = "AI Studio runs with an enterprise configuration using a configuration plugin, without central configuration management."
-- Configuration plugin ID:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2301484629"] = "Configuration plugin ID:"
-- The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK. -- The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2329884315"] = "The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2329884315"] = "The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK."
@@ -4258,6 +4360,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2765814390"] = "Determine Pandoc versi
-- Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor. -- Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2777988282"] = "Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2777988282"] = "Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor."
-- Show Details
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T27924674"] = "Show Details"
-- View our project roadmap and help shape AI Studio's future development. -- View our project roadmap and help shape AI Studio's future development.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2829971158"] = "View our project roadmap and help shape AI Studio's future development." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2829971158"] = "View our project roadmap and help shape AI Studio's future development."
@@ -4273,12 +4378,18 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2868174483"] = "The .NET backend canno
-- Changelog -- Changelog
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3017574265"] = "Changelog" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3017574265"] = "Changelog"
-- Enterprise configuration ID:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3092349641"] = "Enterprise configuration ID:"
-- Connect AI Studio to your organization's data with our External Retrieval Interface (ERI). -- Connect AI Studio to your organization's data with our External Retrieval Interface (ERI).
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T313276297"] = "Connect AI Studio to your organization's data with our External Retrieval Interface (ERI)." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T313276297"] = "Connect AI Studio to your organization's data with our External Retrieval Interface (ERI)."
-- Have feature ideas? Submit suggestions for future AI Studio enhancements. -- Have feature ideas? Submit suggestions for future AI Studio enhancements.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3178730036"] = "Have feature ideas? Submit suggestions for future AI Studio enhancements." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3178730036"] = "Have feature ideas? Submit suggestions for future AI Studio enhancements."
-- Hide Details
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3183837919"] = "Hide Details"
-- Update Pandoc -- Update Pandoc
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3249965383"] = "Update Pandoc" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3249965383"] = "Update Pandoc"
@@ -4303,6 +4414,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3563271893"] = "Motivation"
-- This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat. -- This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3722989559"] = "This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3722989559"] = "This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat."
-- AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3741877842"] = "AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active."
-- this version does not met the requirements -- this version does not met the requirements
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3813932670"] = "this version does not met the requirements" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3813932670"] = "this version does not met the requirements"
@@ -4345,9 +4459,15 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T639371534"] = "Did you find a bug or a
-- This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible. -- This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T64689067"] = "This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T64689067"] = "This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible."
-- Copies the config ID to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T788846912"] = "Copies the config ID to the clipboard"
-- installed by AI Studio -- installed by AI Studio
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T833849470"] = "installed by AI Studio" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T833849470"] = "installed by AI Studio"
-- We use this library to be able to read PowerPoint files. This allows us to insert content from slides into prompts and take PowerPoint files into account in RAG processes. We thank Nils Kruthoff for his work on this Rust crate.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T855925638"] = "We use this library to be able to read PowerPoint files. This allows us to insert content from slides into prompts and take PowerPoint files into account in RAG processes. We thank Nils Kruthoff for his work on this Rust crate."
-- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose. -- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T870640199"] = "For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T870640199"] = "For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose."
@@ -4516,8 +4636,8 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1702902297"] = "Introduction"
-- Vision -- Vision
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1892426825"] = "Vision" UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1892426825"] = "Vision"
-- You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT4o, o1, etc.), Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities. -- You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT5, o1, etc.), Perplexity, Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using vLLM, llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2217921237"] = "You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT4o, o1, etc.), Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities." UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2183503084"] = "You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT5, o1, etc.), Perplexity, Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using vLLM, llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities."
-- Let's get started -- Let's get started
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2331588413"] = "Let's get started" UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2331588413"] = "Let's get started"
@@ -4762,6 +4882,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T3424652889"] = "Un
-- no model selected -- no model selected
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "no model selected" UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "no model selected"
-- Sources
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::SOURCEEXTENSIONS::T2730980305"] = "Sources"
-- Use no chat template -- Use no chat template
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CHATTEMPLATE::T4258819635"] = "Use no chat template" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CHATTEMPLATE::T4258819635"] = "Use no chat template"
@@ -4810,6 +4933,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2128088682
-- Navigation expands on mouse hover -- Navigation expands on mouse hover
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigation expands on mouse hover"
-- Install updates manually
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T220653235"] = "Install updates manually"
-- Also show features ready for release; these should be stable -- Also show features ready for release; these should be stable
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Also show features ready for release; these should be stable"
@@ -4849,6 +4975,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3137986690
-- Delete disappearing chats older than 180 days -- Delete disappearing chats older than 180 days
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Delete disappearing chats older than 180 days" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Delete disappearing chats older than 180 days"
-- Install updates automatically
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3569059463"] = "Install updates automatically"
-- Disable workspaces -- Disable workspaces
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Disable workspaces"
@@ -5383,9 +5512,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011
-- The CONFIG table does not exist or is not a valid table. -- The CONFIG table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table." UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
-- The LLM_PROVIDERS table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "The LLM_PROVIDERS table does not exist or is not a valid table."
-- The field IETF_TAG does not exist or is not a valid string. -- The field IETF_TAG does not exist or is not a valid string.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string." UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
@@ -5476,6 +5602,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T304
-- AI source selection with AI retrieval context validation -- AI source selection with AI retrieval context validation
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI source selection with AI retrieval context validation" UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI source selection with AI retrieval context validation"
-- Executable Files
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2217313358"] = "Executable Files"
-- PDF Files -- PDF Files
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF Files" UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF Files"
@@ -5509,6 +5638,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::SECRETS::T4007657575"]
-- No update found. -- No update found.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found." UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "No update found."
-- Failed to install update automatically. Please try again manually.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T3709709946"] = "Failed to install update automatically. Please try again manually."
-- The hostname is not a valid HTTP(S) URL. -- The hostname is not a valid HTTP(S) URL.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL." UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "The hostname is not a valid HTTP(S) URL."
@@ -5611,5 +5743,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T497939286"] =
-- Please select a model. -- Please select a model.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model." UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Please select a model."
-- Unnamed workspace
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T1307384014"] = "Unnamed workspace"
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat" UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Delete Chat"
@@ -3,10 +3,10 @@
@if (!this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader) @if (!this.SettingsManager.ConfigurationData.LegalCheck.HideWebContentReader)
{ {
<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" @bind-Preselect="@this.showWebContentReader" @bind-PreselectContentCleanerAgent="@this.useContentCleanerAgent"/>
} }
<ReadPDFContent @bind-PDFContent="@this.inputLegalDocument"/> <ReadFileContent @bind-FileContent="@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"/>
@@ -37,11 +37,27 @@ public partial class AssistantLegalCheck : AssistantBaseCore<SettingsDialogLegal
{ {
this.inputLegalDocument = string.Empty; this.inputLegalDocument = string.Empty;
this.inputQuestions = string.Empty; this.inputQuestions = string.Empty;
this.MightPreselectValues(); if (!this.MightPreselectValues())
{
this.showWebContentReader = false;
this.useContentCleanerAgent = false;
}
} }
protected override bool MightPreselectValues() => false; protected override bool MightPreselectValues()
{
if (this.SettingsManager.ConfigurationData.LegalCheck.PreselectOptions)
{
this.showWebContentReader = this.SettingsManager.ConfigurationData.LegalCheck.PreselectWebContentReader;
this.useContentCleanerAgent = this.SettingsManager.ConfigurationData.LegalCheck.PreselectContentCleanerAgent;
return true;
}
return false;
}
private bool showWebContentReader;
private bool useContentCleanerAgent;
private bool isAgentRunning; private bool isAgentRunning;
private string inputLegalDocument = string.Empty; private string inputLegalDocument = string.Empty;
private string inputQuestions = string.Empty; private string inputQuestions = string.Empty;
@@ -3,11 +3,12 @@
@if (!this.SettingsManager.ConfigurationData.TextSummarizer.HideWebContentReader) @if (!this.SettingsManager.ConfigurationData.TextSummarizer.HideWebContentReader)
{ {
<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" @bind-Preselect="@this.showWebContentReader" @bind-PreselectContentCleanerAgent="@this.useContentCleanerAgent"/>
} }
<ReadPDFContent @bind-PDFContent="@this.inputText"/> <ReadFileContent @bind-FileContent="@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" />
<MudTextField T="string" AutoGrow="true" Lines="2" @bind-Text="@this.importantAspects" class="mb-3" Label="@T("(Optional) Important Aspects")" HelperText="@T("(Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start"/>
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/> <ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -12,12 +12,12 @@ public partial class AssistantTextSummarizer : AssistantBaseCore<SettingsDialogT
protected override string Description => T("Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand."); protected override string Description => T("Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand.");
protected override string SystemPrompt => protected override string SystemPrompt =>
""" $"""
You get a long text as input. The user wants to get a summary of the text. You get a long text as input. The text is marked with ```. The user wants to get a summary of the text.
The user might want to change the language of the summary. In this case, {this.selectedTargetLanguage.PromptSummarizing(this.customTargetLanguage)}
you should provide a summary in the requested language. Eventually, the user {this.selectedComplexity.Prompt(this.expertInField)}
want to change the complexity of the text. In this case, you should provide {this.PromptImportantAspects()}
a summary with the requested complexity. In any case, do not add any information. In any case, only use information that is provided in the text for the summary.
"""; """;
protected override bool AllowProfiles => false; protected override bool AllowProfiles => false;
@@ -40,10 +40,13 @@ public partial class AssistantTextSummarizer : AssistantBaseCore<SettingsDialogT
this.inputText = string.Empty; this.inputText = string.Empty;
if(!this.MightPreselectValues()) if(!this.MightPreselectValues())
{ {
this.showWebContentReader = false;
this.useContentCleanerAgent = false;
this.selectedTargetLanguage = CommonLanguages.AS_IS; this.selectedTargetLanguage = CommonLanguages.AS_IS;
this.customTargetLanguage = string.Empty; this.customTargetLanguage = string.Empty;
this.selectedComplexity = Complexity.NO_CHANGE; this.selectedComplexity = Complexity.NO_CHANGE;
this.expertInField = string.Empty; this.expertInField = string.Empty;
this.importantAspects = string.Empty;
} }
} }
@@ -51,22 +54,28 @@ public partial class AssistantTextSummarizer : AssistantBaseCore<SettingsDialogT
{ {
if (this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions) if (this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)
{ {
this.showWebContentReader = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectWebContentReader;
this.useContentCleanerAgent = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectContentCleanerAgent;
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedTargetLanguage; this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedOtherLanguage; this.customTargetLanguage = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedOtherLanguage;
this.selectedComplexity = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedComplexity; this.selectedComplexity = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedComplexity;
this.expertInField = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField; this.expertInField = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField;
this.importantAspects = this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedImportantAspects;
return true; return true;
} }
return false; return false;
} }
private bool showWebContentReader;
private bool useContentCleanerAgent;
private string inputText = string.Empty; private string inputText = string.Empty;
private bool isAgentRunning; private bool isAgentRunning;
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;
private string customTargetLanguage = string.Empty; private string customTargetLanguage = string.Empty;
private Complexity selectedComplexity; private Complexity selectedComplexity;
private string expertInField = string.Empty; private string expertInField = string.Empty;
private string importantAspects = string.Empty;
#region Overrides of ComponentBase #region Overrides of ComponentBase
@@ -105,6 +114,17 @@ public partial class AssistantTextSummarizer : AssistantBaseCore<SettingsDialogT
return null; return null;
} }
private string PromptImportantAspects()
{
if (string.IsNullOrWhiteSpace(this.importantAspects))
return string.Empty;
return $"""
Emphasize the following aspects in your summary:
{this.importantAspects}
""";
}
private async Task SummarizeText() private async Task SummarizeText()
{ {
await this.form!.Validate(); await this.form!.Validate();
@@ -114,11 +134,7 @@ public partial class AssistantTextSummarizer : AssistantBaseCore<SettingsDialogT
this.CreateChatThread(); this.CreateChatThread();
var time = this.AddUserRequest( var time = this.AddUserRequest(
$""" $"""
{this.selectedTargetLanguage.PromptSummarizing(this.customTargetLanguage)}
{this.selectedComplexity.Prompt(this.expertInField)}
Please summarize the following text: Please summarize the following text:
``` ```
{this.inputText} {this.inputText}
``` ```
@@ -3,10 +3,11 @@
@if (!this.SettingsManager.ConfigurationData.Translation.HideWebContentReader) @if (!this.SettingsManager.ConfigurationData.Translation.HideWebContentReader)
{ {
<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" @bind-Preselect="@this.showWebContentReader" @bind-PreselectContentCleanerAgent="@this.useContentCleanerAgent"/>
} }
<ReadPDFContent @bind-PDFContent="@this.inputText"/> <ReadFileContent @bind-FileContent="@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)
{ {
@@ -40,6 +40,8 @@ public partial class AssistantTranslation : AssistantBaseCore<SettingsDialogTran
this.inputTextLastTranslation = string.Empty; this.inputTextLastTranslation = string.Empty;
if (!this.MightPreselectValues()) if (!this.MightPreselectValues())
{ {
this.showWebContentReader = false;
this.useContentCleanerAgent = false;
this.liveTranslation = false; this.liveTranslation = false;
this.selectedTargetLanguage = CommonLanguages.AS_IS; this.selectedTargetLanguage = CommonLanguages.AS_IS;
this.customTargetLanguage = string.Empty; this.customTargetLanguage = string.Empty;
@@ -50,6 +52,8 @@ public partial class AssistantTranslation : AssistantBaseCore<SettingsDialogTran
{ {
if (this.SettingsManager.ConfigurationData.Translation.PreselectOptions) if (this.SettingsManager.ConfigurationData.Translation.PreselectOptions)
{ {
this.showWebContentReader = this.SettingsManager.ConfigurationData.Translation.PreselectWebContentReader;
this.useContentCleanerAgent = this.SettingsManager.ConfigurationData.Translation.PreselectContentCleanerAgent;
this.liveTranslation = this.SettingsManager.ConfigurationData.Translation.PreselectLiveTranslation; this.liveTranslation = this.SettingsManager.ConfigurationData.Translation.PreselectLiveTranslation;
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.Translation.PreselectedTargetLanguage; this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.Translation.PreselectedTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.Translation.PreselectOtherLanguage; this.customTargetLanguage = this.SettingsManager.ConfigurationData.Translation.PreselectOtherLanguage;
@@ -59,6 +63,8 @@ public partial class AssistantTranslation : AssistantBaseCore<SettingsDialogTran
return false; return false;
} }
private bool showWebContentReader;
private bool useContentCleanerAgent;
private bool liveTranslation; private bool liveTranslation;
private bool isAgentRunning; private bool isAgentRunning;
private string inputText = string.Empty; private string inputText = string.Empty;
+15 -14
View File
@@ -10,6 +10,8 @@ namespace AIStudio.Chat;
/// </summary> /// </summary>
public sealed record ChatThread public sealed record ChatThread
{ {
private static readonly ILogger<ChatThread> LOGGER = Program.LOGGER_FACTORY.CreateLogger<ChatThread>();
/// <summary> /// <summary>
/// The unique identifier of the chat thread. /// The unique identifier of the chat thread.
/// </summary> /// </summary>
@@ -60,11 +62,6 @@ public sealed record ChatThread
/// </summary> /// </summary>
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
/// <summary>
/// The seed for the chat thread. Some providers use this to generate deterministic results.
/// </summary>
public int Seed { get; init; }
/// <summary> /// <summary>
/// The current system prompt for the chat thread. /// The current system prompt for the chat thread.
/// </summary> /// </summary>
@@ -87,9 +84,8 @@ public sealed record ChatThread
/// </remarks> /// </remarks>
/// <param name="settingsManager">The settings manager instance to use.</param> /// <param name="settingsManager">The settings manager instance to use.</param>
/// <param name="chatThread">The chat thread to prepare the system prompt for.</param> /// <param name="chatThread">The chat thread to prepare the system prompt for.</param>
/// <param name="logger">The logger instance to use.</param>
/// <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)
{ {
// //
// Use the information from the chat template, if provided. Otherwise, use the default system prompt // Use the information from the chat template, if provided. Otherwise, use the default system prompt
@@ -100,16 +96,16 @@ public sealed record ChatThread
systemPromptTextWithChatTemplate = chatThread.SystemPrompt; systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
else else
{ {
if(!Guid.TryParse(chatThread.SelectedChatTemplate, out var chatTeamplateId)) if(!Guid.TryParse(chatThread.SelectedChatTemplate, out var chatTemplateId))
systemPromptTextWithChatTemplate = chatThread.SystemPrompt; systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
else else
{ {
if(chatThread.SelectedChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE.Id || chatTeamplateId == Guid.Empty) if(chatThread.SelectedChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE.Id || chatTemplateId == Guid.Empty)
systemPromptTextWithChatTemplate = chatThread.SystemPrompt; systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
else else
{ {
var chatTemplate = settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatThread.SelectedChatTemplate); var chatTemplate = settingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatThread.SelectedChatTemplate);
if(chatTemplate == default) if(chatTemplate == null)
systemPromptTextWithChatTemplate = chatThread.SystemPrompt; systemPromptTextWithChatTemplate = chatThread.SystemPrompt;
else else
{ {
@@ -121,7 +117,12 @@ public sealed record ChatThread
} }
} }
logger.LogInformation(logMessage); // We need a way to save the changed system prompt in our chat thread.
// Otherwise, the chat thread will always tell us that it is using the
// default system prompt:
chatThread = chatThread with { SystemPrompt = systemPromptTextWithChatTemplate };
LOGGER.LogInformation(logMessage);
// //
// Add augmented data, if available: // Add augmented data, if available:
@@ -139,9 +140,9 @@ public sealed record ChatThread
}; };
if(isAugmentedDataAvailable) if(isAugmentedDataAvailable)
logger.LogInformation("Augmented data is available for the chat thread."); LOGGER.LogInformation("Augmented data is available for the chat thread.");
else else
logger.LogInformation("No augmented data is available for the chat thread."); LOGGER.LogInformation("No augmented data is available for the chat thread.");
// //
@@ -177,7 +178,7 @@ public sealed record ChatThread
} }
} }
logger.LogInformation(logMessage); LOGGER.LogInformation(logMessage);
return systemPromptText; return systemPromptText;
} }
+2 -2
View File
@@ -30,12 +30,12 @@ public class ContentBlock
/// </summary> /// </summary>
public bool HideFromUser { get; init; } public bool HideFromUser { get; init; }
public ContentBlock DeepClone() => new() public ContentBlock DeepClone(bool changeHideState = false, bool hideFromUser = true) => new()
{ {
Time = this.Time, Time = this.Time,
ContentType = this.ContentType, ContentType = this.ContentType,
Content = this.Content?.DeepClone(), Content = this.Content?.DeepClone(),
Role = this.Role, Role = this.Role,
HideFromUser = this.HideFromUser, HideFromUser = changeHideState ? hideFromUser : this.HideFromUser,
}; };
} }
@@ -1,5 +1,7 @@
@using AIStudio.Tools @using AIStudio.Tools
@using MudBlazor @using MudBlazor
@using AIStudio.Components
@using AIStudio.Provider
@inherits AIStudio.Components.MSGComponentBase @inherits AIStudio.Components.MSGComponentBase
<MudCard Class="@this.CardClasses" Outlined="@true"> <MudCard Class="@this.CardClasses" Outlined="@true">
<MudCardHeader> <MudCardHeader>
@@ -10,10 +12,18 @@
</CardHeaderAvatar> </CardHeaderAvatar>
<CardHeaderContent> <CardHeaderContent>
<MudText Typo="Typo.body1"> <MudText Typo="Typo.body1">
@this.Role.ToName() (@this.Time) @this.Role.ToName() (@this.Time.LocalDateTime)
</MudText> </MudText>
</CardHeaderContent> </CardHeaderContent>
<CardHeaderActions> <CardHeaderActions>
@if (this.Content.Sources.Count > 0)
{
<MudTooltip Text="@T("Number of sources")" Placement="Placement.Bottom">
<MudBadge Content="@this.Content.Sources.Count" Color="Color.Primary" Overlap="true" BadgeClass="sources-card-header">
<MudIconButton Icon="@Icons.Material.Filled.Link" />
</MudBadge>
</MudTooltip>
}
@if (this.IsSecondToLastBlock && this.Role is ChatRole.USER && this.EditLastUserBlockFunc is not null) @if (this.IsSecondToLastBlock && this.Role is ChatRole.USER && this.EditLastUserBlockFunc is not null)
{ {
<MudTooltip Text="@T("Edit")" Placement="Placement.Bottom"> <MudTooltip Text="@T("Edit")" Placement="Placement.Bottom">
@@ -38,9 +48,7 @@
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/> <MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/>
</MudTooltip> </MudTooltip>
} }
<MudTooltip Text="@T("Copies the content to the clipboard")" Placement="Placement.Bottom"> <MudCopyClipboardButton Content="@this.Content" Type="@this.Type" Size="Size.Medium"/>
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Color="Color.Default" OnClick="@this.CopyToClipboard"/>
</MudTooltip>
</CardHeaderActions> </CardHeaderActions>
</MudCardHeader> </MudCardHeader>
<MudCardContent> <MudCardContent>
@@ -67,12 +75,16 @@
@if (this.Content.IsStreaming) @if (this.Content.IsStreaming)
{ {
<MudText Typo="Typo.body1" Style="white-space: pre-wrap;"> <MudText Typo="Typo.body1" Style="white-space: pre-wrap;">
@textContent.Text @textContent.Text.RemoveThinkTags()
</MudText> </MudText>
} }
else else
{ {
<MudMarkdown Value="@textContent.Text" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo" CodeBlockTheme="@this.CodeColorPalette"/> <MudMarkdown Value="@textContent.Text.RemoveThinkTags().Trim()" Props="Markdown.DefaultConfig" Styling="@this.MarkdownStyling" />
@if (textContent.Sources.Count > 0)
{
<MudMarkdown Value="@textContent.Sources.ToMarkdown()" Props="Markdown.DefaultConfig" Styling="@this.MarkdownStyling" />
}
} }
} }
} }
@@ -1,5 +1,4 @@
using AIStudio.Components; using AIStudio.Components;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -61,12 +60,6 @@ public partial class ContentBlockComponent : MSGComponentBase
[Parameter] [Parameter]
public Func<bool> RegenerateEnabled { get; set; } = () => false; public Func<bool> RegenerateEnabled { get; set; } = () => false;
[Inject]
private RustService RustService { get; init; } = null!;
[Inject]
private ISnackbar Snackbar { get; init; } = null!;
[Inject] [Inject]
private IDialogService DialogService { get; init; } = null!; private IDialogService DialogService { get; init; } = null!;
@@ -116,33 +109,15 @@ public partial class ContentBlockComponent : MSGComponentBase
#endregion #endregion
/// <summary>
/// Copy this block's content to the clipboard.
/// </summary>
private async Task CopyToClipboard()
{
switch (this.Type)
{
case ContentType.TEXT:
var textContent = (ContentText) this.Content;
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
break;
default:
this.Snackbar.Add(T("Cannot copy this content type to clipboard!"), Severity.Error, config =>
{
config.Icon = Icons.Material.Filled.ContentCopy;
config.IconSize = Size.Large;
config.IconColor = Color.Error;
});
break;
}
}
private string CardClasses => $"my-2 rounded-lg {this.Class}"; private string CardClasses => $"my-2 rounded-lg {this.Class}";
private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default; private CodeBlockTheme CodeColorPalette => this.SettingsManager.IsDarkMode ? CodeBlockTheme.Dark : CodeBlockTheme.Default;
private MudMarkdownStyling MarkdownStyling => new()
{
CodeBlock = { Theme = this.CodeColorPalette },
};
private async Task RemoveBlock() private async Task RemoveBlock()
{ {
if (this.RemoveBlockFunc is null) if (this.RemoveBlockFunc is null)
@@ -27,6 +27,9 @@ public sealed class ContentImage : IContent, IImageSource
[JsonIgnore] [JsonIgnore]
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask; public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
/// <inheritdoc />
public List<Source> Sources { get; set; } = [];
/// <inheritdoc /> /// <inheritdoc />
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)
{ {
+11 -3
View File
@@ -24,7 +24,7 @@ public sealed class ContentText : IContent
public bool InitialRemoteWait { get; set; } public bool InitialRemoteWait { get; set; }
/// <inheritdoc /> /// <inheritdoc />
// [JsonIgnore] [JsonIgnore]
public bool IsStreaming { get; set; } public bool IsStreaming { get; set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -35,6 +35,9 @@ public sealed class ContentText : IContent
[JsonIgnore] [JsonIgnore]
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask; public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
/// <inheritdoc />
public List<Source> Sources { get; set; } = [];
/// <inheritdoc /> /// <inheritdoc />
public async Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default) public async Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default)
{ {
@@ -80,7 +83,7 @@ public sealed class ContentText : IContent
this.InitialRemoteWait = true; this.InitialRemoteWait = true;
// Iterate over the responses from the AI: // Iterate over the responses from the AI:
await foreach (var deltaText in provider.StreamChatCompletion(chatModel, chatThread, settings, token)) await foreach (var contentStreamChunk in provider.StreamChatCompletion(chatModel, chatThread, settings, token))
{ {
// When the user cancels the request, we stop the loop: // When the user cancels the request, we stop the loop:
if (token.IsCancellationRequested) if (token.IsCancellationRequested)
@@ -91,7 +94,10 @@ public sealed class ContentText : IContent
this.IsStreaming = true; this.IsStreaming = true;
// Add the response to the text: // Add the response to the text:
this.Text += deltaText; this.Text += contentStreamChunk;
// Merge the sources:
this.Sources.MergeSources(contentStreamChunk.Sources);
// Notify the UI that the content has changed, // Notify the UI that the content has changed,
// depending on the energy saving mode: // depending on the energy saving mode:
@@ -120,6 +126,8 @@ public sealed class ContentText : IContent
this.IsStreaming = false; this.IsStreaming = false;
}, token); }, token);
this.Text = this.Text.RemoveThinkTags().Trim();
// Inform the UI that the streaming is done: // Inform the UI that the streaming is done:
await this.StreamingDone(); await this.StreamingDone();
return chatThread; return chatThread;
+6
View File
@@ -38,6 +38,12 @@ public interface IContent
[JsonIgnore] [JsonIgnore]
public Func<Task> StreamingDone { get; set; } public Func<Task> StreamingDone { get; set; }
/// <summary>
/// The provided sources, if any.
/// </summary>
[JsonIgnore]
public List<Source> Sources { get; set; }
/// <summary> /// <summary>
/// Uses the provider to create the content. /// Uses the provider to create the content.
/// </summary> /// </summary>
@@ -0,0 +1,18 @@
namespace AIStudio.Chat;
public static class StringExtensions
{
public static string RemoveThinkTags(this string input)
{
const string OPEN_TAG = "<think>";
const string CLOSE_TAG = "</think>";
if (string.IsNullOrWhiteSpace(input) || !input.StartsWith(OPEN_TAG, StringComparison.Ordinal))
return input;
var endIndex = input.IndexOf(CLOSE_TAG, StringComparison.Ordinal);
if (endIndex == -1)
return string.Empty;
return input[(endIndex + CLOSE_TAG.Length)..];
}
}
@@ -13,6 +13,11 @@ public partial class Changelog
public static readonly Log[] LOGS = public static readonly Log[] LOGS =
[ [
new (226, "v0.9.51, build 226 (2025-09-04 18:02 UTC)", "v0.9.51.md"),
new (225, "v0.9.50, build 225 (2025-08-10 16:40 UTC)", "v0.9.50.md"),
new (224, "v0.9.49, build 224 (2025-07-02 12:12 UTC)", "v0.9.49.md"),
new (223, "v0.9.48, build 223 (2025-06-10 13:15 UTC)", "v0.9.48.md"),
new (222, "v0.9.47, build 222 (2025-06-02 18:25 UTC)", "v0.9.47.md"),
new (221, "v0.9.46, build 221 (2025-06-01 19:19 UTC)", "v0.9.46.md"), new (221, "v0.9.46, build 221 (2025-06-01 19:19 UTC)", "v0.9.46.md"),
new (220, "v0.9.45, build 220 (2025-05-25 13:56 UTC)", "v0.9.45.md"), new (220, "v0.9.45, build 220 (2025-05-25 13:56 UTC)", "v0.9.45.md"),
new (219, "v0.9.44, build 219 (2025-05-18 19:33 UTC)", "v0.9.44.md"), new (219, "v0.9.44, build 219 (2025-05-18 19:33 UTC)", "v0.9.44.md"),
@@ -6,4 +6,4 @@
} }
</MudSelect> </MudSelect>
<MudMarkdown Value="@this.LogContent" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/> <MudMarkdown Value="@this.LogContent" Props="Markdown.DefaultConfig"/>
@@ -81,7 +81,8 @@
</MudTooltip> </MudTooltip>
} }
<ChatTemplateSelection CurrentChatTemplate="@this.currentChatTemplate" CurrentChatTemplateChanged="@this.ChatTemplateWasChanged"/> <ChatTemplateSelection CanChatThreadBeUsedForTemplate="@this.CanThreadBeSaved" CurrentChatThread="@this.ChatThread" CurrentChatTemplate="@this.currentChatTemplate" CurrentChatTemplateChanged="@this.ChatTemplateWasChanged"/>
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY) @if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
{ {
<MudTooltip Text="@T("Delete this chat & start a new one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT"> <MudTooltip Text="@T("Delete this chat & start a new one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
@@ -20,7 +20,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
public EventCallback<ChatThread?> ChatThreadChanged { get; set; } public EventCallback<ChatThread?> ChatThreadChanged { get; set; }
[Parameter] [Parameter]
public AIStudio.Settings.Provider Provider { get; set; } public AIStudio.Settings.Provider Provider { get; set; } = AIStudio.Settings.Provider.NONE;
[Parameter] [Parameter]
public EventCallback<AIStudio.Settings.Provider> ProviderChanged { get; set; } public EventCallback<AIStudio.Settings.Provider> ProviderChanged { get; set; }
@@ -34,9 +34,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
[Inject] [Inject]
private ILogger<ChatComponent> Logger { get; set; } = null!; private ILogger<ChatComponent> Logger { get; set; } = null!;
[Inject]
private ThreadSafeRandom RNG { get; init; } = null!;
[Inject] [Inject]
private IDialogService DialogService { get; init; } = null!; private IDialogService DialogService { get; init; } = null!;
@@ -80,6 +77,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// Get the preselected chat template: // Get the preselected chat template:
this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(Tools.Components.CHAT); this.currentChatTemplate = this.SettingsManager.GetPreselectedChatTemplate(Tools.Components.CHAT);
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
// //
// Check for deferred messages of the kind 'SEND_TO_CHAT', // Check for deferred messages of the kind 'SEND_TO_CHAT',
@@ -272,7 +270,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.Any(b => !b.HideFromUser);
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);
@@ -326,6 +324,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
private async Task ChatTemplateWasChanged(ChatTemplate chatTemplate) private async Task ChatTemplateWasChanged(ChatTemplate chatTemplate)
{ {
this.currentChatTemplate = chatTemplate; this.currentChatTemplate = chatTemplate;
if(!string.IsNullOrWhiteSpace(this.currentChatTemplate.PredefinedUserPrompt))
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
if(this.ChatThread is null) if(this.ChatThread is null)
return; return;
@@ -432,8 +433,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
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(), Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
}; };
await this.ChatThreadChanged.InvokeAsync(this.ChatThread); await this.ChatThreadChanged.InvokeAsync(this.ChatThread);
@@ -505,7 +505,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
}); });
// Clear the input field: // Clear the input field:
await this.inputField.FocusAsync();
this.userInput = string.Empty; this.userInput = string.Empty;
await this.inputField.BlurAsync();
// Enable the stream state for the chat component: // Enable the stream state for the chat component:
this.isStreaming = true; this.isStreaming = true;
@@ -526,7 +528,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// Use the selected provider to get the AI response. // Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire // By awaiting this line, we wait for the entire
// content to be streamed. // content to be streamed.
this.ChatThread = await aiText.CreateFromProviderAsync(this.Provider.CreateProvider(this.Logger), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token); this.ChatThread = await aiText.CreateFromProviderAsync(this.Provider.CreateProvider(), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token);
} }
this.cancellationTokenSource = null; this.cancellationTokenSource = null;
@@ -581,9 +583,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// //
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges) if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", "Are you sure you want to start a new chat? All unsaved changes will be lost." }, { x => x.Message, "Are you sure you want to start a new chat? All unsaved changes will be lost." },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN);
@@ -628,7 +630,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
default: default:
case AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER: case AddChatProviderBehavior.ADDED_CHATS_USE_LATEST_PROVIDER:
if(this.Provider == default) if(this.Provider == AIStudio.Settings.Provider.NONE)
{ {
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT); this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
await this.ProviderChanged.InvokeAsync(this.Provider); await this.ProviderChanged.InvokeAsync(this.Provider);
@@ -668,11 +670,12 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
WorkspaceId = this.currentWorkspaceId, WorkspaceId = this.currentWorkspaceId,
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = this.RNG.Next(), Blocks = this.currentChatTemplate == ChatTemplate.NO_CHAT_TEMPLATE ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
Blocks = this.currentChatTemplate == default ? [] : this.currentChatTemplate.ExampleConversation.Select(x => x.DeepClone()).ToList(),
}; };
} }
this.userInput = this.currentChatTemplate.PredefinedUserPrompt;
// Now, we have to reset the data source options as well: // Now, we have to reset the data source options as well:
this.ApplyStandardDataSourceOptions(); this.ApplyStandardDataSourceOptions();
@@ -687,9 +690,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges) if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY && this.hasUnsavedChanges)
{ {
var confirmationDialogParameters = new DialogParameters var confirmationDialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", T("Are you sure you want to move this chat? All unsaved changes will be lost.") }, { x => x.Message, T("Are you sure you want to move this chat? All unsaved changes will be lost.") },
}; };
var confirmationDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Unsaved Changes", confirmationDialogParameters, DialogOptions.FULLSCREEN); var confirmationDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Unsaved Changes", confirmationDialogParameters, DialogOptions.FULLSCREEN);
@@ -698,11 +701,11 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
return; return;
} }
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<WorkspaceSelectionDialog>
{ {
{ "Message", T("Please select the workspace where you want to move the chat to.") }, { x => x.Message, T("Please select the workspace where you want to move the chat to.") },
{ "SelectedWorkspace", this.ChatThread?.WorkspaceId }, { x => x.SelectedWorkspace, this.ChatThread?.WorkspaceId ?? Guid.Empty },
{ "ConfirmText", T("Move chat") }, { x => x.ConfirmText, T("Move chat") },
}; };
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -789,7 +792,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
break; break;
case LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER: case LoadingChatProviderBehavior.ALWAYS_USE_LATEST_CHAT_PROVIDER:
if(this.Provider == default) if(this.Provider == AIStudio.Settings.Provider.NONE)
this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT); this.Provider = this.SettingsManager.GetPreselectedProvider(Tools.Components.CHAT);
break; break;
} }
@@ -807,9 +810,8 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// Try to select the chat template: // Try to select the chat template:
if (!string.IsNullOrWhiteSpace(chatChatTemplate)) if (!string.IsNullOrWhiteSpace(chatChatTemplate))
{ {
this.currentChatTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate); var selectedTemplate = this.SettingsManager.ConfigurationData.ChatTemplates.FirstOrDefault(x => x.Id == chatChatTemplate);
if(this.currentChatTemplate == default) this.currentChatTemplate = selectedTemplate ?? ChatTemplate.NO_CHAT_TEMPLATE;
this.currentChatTemplate = ChatTemplate.NO_CHAT_TEMPLATE;
} }
} }
@@ -18,6 +18,8 @@
<ChildContent> <ChildContent>
<MudMenuItem Icon="@Icons.Material.Filled.Settings" Label="@T("Manage your templates")" OnClick="async () => await this.OpenSettingsDialog()" /> <MudMenuItem Icon="@Icons.Material.Filled.Settings" Label="@T("Manage your templates")" OnClick="async () => await this.OpenSettingsDialog()" />
<MudDivider/> <MudDivider/>
<MudMenuItem Icon="@Icons.Material.Filled.AddComment" Label="@T("Create template from current chat")" OnClick="async () => await this.CreateNewChatTemplateFromChat()" Disabled="@(!this.CanChatThreadBeUsedForTemplate)"/>
<MudDivider/>
@foreach (var chatTemplate in this.SettingsManager.ConfigurationData.ChatTemplates.GetAllChatTemplates()) @foreach (var chatTemplate in this.SettingsManager.ConfigurationData.ChatTemplates.GetAllChatTemplates())
{ {
<MudMenuItem Icon="@Icons.Material.Filled.RateReview" OnClick="async () => await this.SelectionChanged(chatTemplate)"> <MudMenuItem Icon="@Icons.Material.Filled.RateReview" OnClick="async () => await this.SelectionChanged(chatTemplate)">
@@ -1,3 +1,4 @@
using AIStudio.Chat;
using AIStudio.Dialogs.Settings; using AIStudio.Dialogs.Settings;
using AIStudio.Settings; using AIStudio.Settings;
@@ -11,6 +12,12 @@ public partial class ChatTemplateSelection : MSGComponentBase
[Parameter] [Parameter]
public ChatTemplate CurrentChatTemplate { get; set; } = ChatTemplate.NO_CHAT_TEMPLATE; public ChatTemplate CurrentChatTemplate { get; set; } = ChatTemplate.NO_CHAT_TEMPLATE;
[Parameter]
public bool CanChatThreadBeUsedForTemplate { get; set; }
[Parameter]
public ChatThread? CurrentChatThread { get; set; }
[Parameter] [Parameter]
public EventCallback<ChatTemplate> CurrentChatTemplateChanged { get; set; } public EventCallback<ChatTemplate> CurrentChatTemplateChanged { get; set; }
@@ -36,4 +43,14 @@ public partial class ChatTemplateSelection : MSGComponentBase
var dialogParameters = new DialogParameters(); var dialogParameters = new DialogParameters();
await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN); await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN);
} }
private async Task CreateNewChatTemplateFromChat()
{
var dialogParameters = new DialogParameters<SettingsDialogChatTemplate>
{
{ x => x.CreateTemplateFromExistingChatThread, true },
{ x => x.ExistingChatThread, this.CurrentChatThread }
};
await this.DialogService.ShowAsync<SettingsDialogChatTemplate>(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN);
}
} }
@@ -1 +1,23 @@
@inherits MSGComponentBase @inherits MSGComponentBase
@if (this.Body is not null)
{
@if (!this.Disabled() && this.IsLocked())
{
<MudField Label="@this.Label" Variant="@this.Variant" Underline="false" HelperText="@this.OptionHelp" Class="@this.Classes" InnerPadding="false">
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.FlexStart" Wrap="Wrap.NoWrap" StretchItems="this.StretchItems">
@* MudTooltip.RootStyle is set as a workaround for issue -> https://github.com/MudBlazor/MudBlazor/issues/10882 *@
<MudTooltip Text="@TB("This feature is managed by your organization and has therefore been disabled.")" Arrow="true" Placement="Placement.Right" RootStyle="display:inline-flex;">
<MudIcon Icon="@Icons.Material.Filled.Lock" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
</MudTooltip>
@this.Body
</MudStack>
</MudField>
}
else
{
<MudField Label="@this.Label" Variant="@this.Variant" Underline="false" HelperText="@this.OptionHelp" Class="@this.Classes" InnerPadding="false">
@this.Body
</MudField>
}
}
@@ -5,7 +5,7 @@ namespace AIStudio.Components;
/// <summary> /// <summary>
/// A base class for configuration options. /// A base class for configuration options.
/// </summary> /// </summary>
public partial class ConfigurationBase : MSGComponentBase public abstract partial class ConfigurationBase : MSGComponentBase
{ {
/// <summary> /// <summary>
/// The description of the option, i.e., the name. Should be /// The description of the option, i.e., the name. Should be
@@ -26,7 +26,42 @@ public partial class ConfigurationBase : MSGComponentBase
[Parameter] [Parameter]
public Func<bool> Disabled { get; set; } = () => false; public Func<bool> Disabled { get; set; } = () => false;
protected const string MARGIN_CLASS = "mb-6"; /// <summary>
/// Is the option locked by a configuration plugin?
/// </summary>
[Parameter]
public Func<bool> IsLocked { get; set; } = () => false;
/// <summary>
/// Should the option be stretched to fill the available space?
/// </summary>
protected abstract bool Stretch { get; }
/// <summary>
/// The CSS class to apply to the component.
/// </summary>
protected virtual string GetClassForBase => string.Empty;
/// <summary>
/// The visual variant of the option.
/// </summary>
protected virtual Variant Variant => Variant.Text;
/// <summary>
/// The label to display for the option.
/// </summary>
protected virtual string Label => string.Empty;
private StretchItems StretchItems => this.Stretch ? StretchItems.End : StretchItems.None;
protected bool IsDisabled => this.Disabled() || this.IsLocked();
private string Classes => $"{this.GetClassForBase} {MARGIN_CLASS}";
private protected virtual RenderFragment? Body => null;
private const string MARGIN_CLASS = "mb-6";
protected static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new(); protected static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
#region Overrides of ComponentBase #region Overrides of ComponentBase
@@ -40,6 +75,8 @@ public partial class ConfigurationBase : MSGComponentBase
#endregion #endregion
private string TB(string fallbackEN) => this.T(fallbackEN, typeof(ConfigurationBase).Namespace, nameof(ConfigurationBase));
protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
#region Overrides of MSGComponentBase #region Overrides of MSGComponentBase
@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
namespace AIStudio.Components;
public abstract class ConfigurationBaseCore : ConfigurationBase
{
private protected sealed override RenderFragment Body => this.BuildRenderTree;
// Allow content to be provided by a .razor file but without
// overriding the content of the base class
protected new virtual void BuildRenderTree(RenderTreeBuilder builder)
{
}
}
@@ -1,3 +1,3 @@
@using AIStudio.Settings @using AIStudio.Settings
@inherits MSGComponentBase @inherits MSGComponentBase
<ConfigurationSelect Disabled="@this.Disabled" OptionDescription="@T("Select a minimum confidence level")" SelectedValue="@this.FilteredSelectedValue" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData(this.SettingsManager, this.RestrictToGlobalMinimumConfidence)" SelectionUpdate="@this.SelectionUpdate" OptionHelp="@T("Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level.")"/> <ConfigurationSelect IsLocked="this.IsLocked" Disabled="this.Disabled" OptionDescription="@T("Select a minimum confidence level")" SelectedValue="@this.FilteredSelectedValue" Data="@ConfigurationSelectDataFactory.GetConfidenceLevelsData(this.SettingsManager, this.RestrictToGlobalMinimumConfidence)" SelectionUpdate="@this.SelectionUpdate" OptionHelp="@T("Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level.")"/>
@@ -18,18 +18,18 @@ public partial class ConfigurationMinConfidenceSelection : MSGComponentBase
[Parameter] [Parameter]
public Action<ConfidenceLevel> SelectionUpdate { get; set; } = _ => { }; public Action<ConfidenceLevel> SelectionUpdate { get; set; } = _ => { };
/// <summary>
/// Is the selection component disabled?
/// </summary>
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
/// <summary> /// <summary>
/// Boolean value indicating whether the selection is restricted to a global minimum confidence level. /// Boolean value indicating whether the selection is restricted to a global minimum confidence level.
/// </summary> /// </summary>
[Parameter] [Parameter]
public bool RestrictToGlobalMinimumConfidence { get; set; } public bool RestrictToGlobalMinimumConfidence { get; set; }
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
[Parameter]
public Func<bool> IsLocked { get; set; } = () => false;
private ConfidenceLevel FilteredSelectedValue() private ConfidenceLevel FilteredSelectedValue()
{ {
if (this.SelectedValue() is ConfidenceLevel.NONE) if (this.SelectedValue() is ConfidenceLevel.NONE)
@@ -1,4 +1,4 @@
@inherits ConfigurationBase @inherits ConfigurationBaseCore
@typeparam TData @typeparam TData
<MudSelectExtended <MudSelectExtended
@@ -7,12 +7,10 @@
MultiSelectionTextFunc="@this.GetMultiSelectionText" MultiSelectionTextFunc="@this.GetMultiSelectionText"
SelectedValues="@this.SelectedValues()" SelectedValues="@this.SelectedValues()"
Strict="@true" Strict="@true"
Disabled="@this.Disabled()" Disabled="@this.IsDisabled"
Margin="Margin.Dense" Margin="Margin.Dense"
Label="@this.OptionDescription" Class="rounded-lg"
Class="@GetClass" Underline="false"
Variant="Variant.Outlined"
HelperText="@this.OptionHelp"
SelectedValuesChanged="@this.OptionChanged"> SelectedValuesChanged="@this.OptionChanged">
@foreach (var data in this.Data) @foreach (var data in this.Data)
{ {
@@ -8,7 +8,7 @@ namespace AIStudio.Components;
/// Configuration component for selecting many values from a list. /// Configuration component for selecting many values from a list.
/// </summary> /// </summary>
/// <typeparam name="TData">The type of the value to select.</typeparam> /// <typeparam name="TData">The type of the value to select.</typeparam>
public partial class ConfigurationMultiSelect<TData> : ConfigurationBase public partial class ConfigurationMultiSelect<TData> : ConfigurationBaseCore
{ {
/// <summary> /// <summary>
/// The data to select from. /// The data to select from.
@@ -28,6 +28,17 @@ public partial class ConfigurationMultiSelect<TData> : ConfigurationBase
[Parameter] [Parameter]
public Action<HashSet<TData>> SelectionUpdate { get; set; } = _ => { }; public Action<HashSet<TData>> SelectionUpdate { get; set; } = _ => { };
#region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => true;
protected override Variant Variant => Variant.Outlined;
protected override string Label => this.OptionDescription;
#endregion
private async Task OptionChanged(IEnumerable<TData?>? updatedValues) private async Task OptionChanged(IEnumerable<TData?>? updatedValues)
{ {
if(updatedValues is null) if(updatedValues is null)
@@ -39,8 +50,6 @@ public partial class ConfigurationMultiSelect<TData> : ConfigurationBase
await this.InformAboutChange(); await this.InformAboutChange();
} }
private static string GetClass => $"{MARGIN_CLASS} rounded-lg";
private string GetMultiSelectionText(List<TData?>? selectedValues) private string GetMultiSelectionText(List<TData?>? selectedValues)
{ {
if(selectedValues is null || selectedValues.Count == 0) if(selectedValues is null || selectedValues.Count == 0)
@@ -1,7 +1,5 @@
@inherits ConfigurationBase @inherits ConfigurationBaseCore
<MudField Disabled="@this.Disabled()" Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS"> <MudSwitch T="bool" Disabled="@this.IsDisabled" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
<MudSwitch T="bool" Disabled="@this.Disabled()" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
@(this.State() ? this.LabelOn : this.LabelOff) @(this.State() ? this.LabelOn : this.LabelOff)
</MudSwitch> </MudSwitch>
</MudField>
@@ -5,7 +5,7 @@ namespace AIStudio.Components;
/// <summary> /// <summary>
/// Configuration component for any boolean option. /// Configuration component for any boolean option.
/// </summary> /// </summary>
public partial class ConfigurationOption : ConfigurationBase public partial class ConfigurationOption : ConfigurationBaseCore
{ {
/// <summary> /// <summary>
/// Text to display when the option is true. /// Text to display when the option is true.
@@ -31,6 +31,19 @@ public partial class ConfigurationOption : ConfigurationBase
[Parameter] [Parameter]
public Action<bool> StateUpdate { get; set; } = _ => { }; public Action<bool> StateUpdate { get; set; } = _ => { };
#region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => true;
/// <inheritdoc />
protected override Variant Variant => Variant.Outlined;
/// <inheritdoc />
protected override string Label => this.OptionDescription;
#endregion
private async Task OptionChanged(bool updatedState) private async Task OptionChanged(bool updatedState)
{ {
this.StateUpdate(updatedState); this.StateUpdate(updatedState);
@@ -1,2 +1,2 @@
@inherits MSGComponentBase @inherits MSGComponentBase
<ConfigurationSelect OptionDescription="@T("Preselected provider")" Disabled="@this.Disabled" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/> <ConfigurationSelect IsLocked="@this.IsLocked" OptionDescription="@T("Preselected provider")" Disabled="@(() => this.Disabled())" OptionHelp="@this.HelpText()" Data="@this.FilteredData()" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
@@ -20,27 +20,17 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
[Parameter] [Parameter]
public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>(); public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>();
/// <summary>
/// Is the selection component disabled?
/// </summary>
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
[Parameter] [Parameter]
public Func<string> HelpText { get; set; } = () => TB("Select a provider that is preselected."); public Func<string> HelpText { get; set; } = () => TB("Select a provider that is preselected.");
[Parameter] [Parameter]
public Tools.Components Component { get; set; } = Tools.Components.NONE; public Tools.Components Component { get; set; } = Tools.Components.NONE;
#region Overrides of ComponentBase [Parameter]
public Func<bool> Disabled { get; set; } = () => false;
protected override async Task OnParametersSetAsync() [Parameter]
{ public Func<bool> IsLocked { get; set; } = () => false;
this.ApplyFilters([], [ Event.CONFIGURATION_CHANGED ]);
await base.OnParametersSetAsync();
}
#endregion
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
private IEnumerable<ConfigurationSelectData<string>> FilteredData() private IEnumerable<ConfigurationSelectData<string>> FilteredData()
@@ -52,6 +42,9 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
foreach (var providerId in this.Data) foreach (var providerId in this.Data)
{ {
var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value); var provider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == providerId.Value);
if (provider is null)
continue;
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel) if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
yield return providerId; yield return providerId;
} }
@@ -1,7 +1,7 @@
@inherits ConfigurationBase @inherits ConfigurationBaseCore
@typeparam T @typeparam TConfig
<MudSelect T="T" Value="@this.SelectedValue()" Strict="@true" ShrinkLabel="@true" Disabled="@this.Disabled()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="@this.OptionChanged"> <MudSelect T="TConfig" Value="@this.SelectedValue()" Strict="@true" ShrinkLabel="@true" Disabled="@this.IsDisabled" Margin="Margin.Dense" Class="rounded-lg mb-0" Underline="false" ValueChanged="@this.OptionChanged">
@foreach (var data in this.Data) @foreach (var data in this.Data)
{ {
<MudSelectItem Value="@data.Value"> <MudSelectItem Value="@data.Value">
@@ -7,33 +7,43 @@ namespace AIStudio.Components;
/// <summary> /// <summary>
/// Configuration component for selecting a value from a list. /// Configuration component for selecting a value from a list.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the value to select.</typeparam> /// <typeparam name="TConfig">The type of the value to select.</typeparam>
public partial class ConfigurationSelect<T> : ConfigurationBase public partial class ConfigurationSelect<TConfig> : ConfigurationBaseCore
{ {
/// <summary> /// <summary>
/// The data to select from. /// The data to select from.
/// </summary> /// </summary>
[Parameter] [Parameter]
public IEnumerable<ConfigurationSelectData<T>> Data { get; set; } = []; public IEnumerable<ConfigurationSelectData<TConfig>> Data { get; set; } = [];
/// <summary> /// <summary>
/// The selected value. /// The selected value.
/// </summary> /// </summary>
[Parameter] [Parameter]
public Func<T> SelectedValue { get; set; } = () => default!; public Func<TConfig> SelectedValue { get; set; } = () => default!;
/// <summary> /// <summary>
/// An action that is called when the selection changes. /// An action that is called when the selection changes.
/// </summary> /// </summary>
[Parameter] [Parameter]
public Action<T> SelectionUpdate { get; set; } = _ => { }; public Action<TConfig> SelectionUpdate { get; set; } = _ => { };
private async Task OptionChanged(T updatedValue) #region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => true;
/// <inheritdoc />
protected override string Label => this.OptionDescription;
protected override Variant Variant => Variant.Outlined;
#endregion
private async Task OptionChanged(TConfig updatedValue)
{ {
this.SelectionUpdate(updatedValue); this.SelectionUpdate(updatedValue);
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.InformAboutChange(); await this.InformAboutChange();
} }
private static string GetClass => $"{MARGIN_CLASS} rounded-lg";
} }
@@ -1,8 +1,6 @@
@typeparam T @typeparam T
@inherits ConfigurationBase @inherits ConfigurationBaseCore
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" Class="mb-3" Disabled="@this.Disabled()"> <MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.IsDisabled" Class="mb-1">
<MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.Disabled()">
@this.Value() @this.Unit @this.Value() @this.Unit
</MudSlider> </MudSlider>
</MudField>
@@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components;
public partial class ConfigurationSlider<T> : ConfigurationBase where T : struct, INumber<T> public partial class ConfigurationSlider<T> : ConfigurationBaseCore where T : struct, INumber<T>
{ {
/// <summary> /// <summary>
/// The minimum value for the slider. /// The minimum value for the slider.
@@ -42,6 +42,18 @@ public partial class ConfigurationSlider<T> : ConfigurationBase where T : struct
[Parameter] [Parameter]
public Action<T> ValueUpdate { get; set; } = _ => { }; public Action<T> ValueUpdate { get; set; } = _ => { };
#region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => true;
/// <inheritdoc />
protected override Variant Variant => Variant.Outlined;
protected override string Label => this.OptionDescription;
#endregion
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@@ -1,12 +1,10 @@
@inherits ConfigurationBase @inherits ConfigurationBaseCore
<MudTextField <MudTextField
T="string" T="string"
Text="@this.Text()" Text="@this.Text()"
TextChanged="@this.InternalUpdate" TextChanged="@this.InternalUpdate"
Label="@this.OptionDescription" Disabled="@this.IsDisabled"
Disabled="@this.Disabled()"
Class="@MARGIN_CLASS"
Adornment="Adornment.Start" Adornment="Adornment.Start"
AdornmentIcon="@this.Icon" AdornmentIcon="@this.Icon"
AdornmentColor="@this.IconColor" AdornmentColor="@this.IconColor"
@@ -15,5 +13,5 @@
AutoGrow="@this.AutoGrow" AutoGrow="@this.AutoGrow"
MaxLines="@this.GetMaxLines" MaxLines="@this.GetMaxLines"
Immediate="@true" Immediate="@true"
Variant="Variant.Outlined" Underline="false"
/> />
@@ -4,7 +4,7 @@ using Timer = System.Timers.Timer;
namespace AIStudio.Components; namespace AIStudio.Components;
public partial class ConfigurationText : ConfigurationBase public partial class ConfigurationText : ConfigurationBaseCore
{ {
/// <summary> /// <summary>
/// The text used for the textfield. /// The text used for the textfield.
@@ -43,21 +43,30 @@ public partial class ConfigurationText : ConfigurationBase
public int MaxLines { get; set; } = 12; public int MaxLines { get; set; } = 12;
private string internalText = string.Empty; private string internalText = string.Empty;
private Timer timer = new(TimeSpan.FromMilliseconds(500)) private readonly Timer timer = new(TimeSpan.FromMilliseconds(500))
{ {
AutoReset = false AutoReset = false
}; };
#region Overrides of ConfigurationBase #region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => true;
protected override Variant Variant => Variant.Outlined;
protected override string Label => this.OptionDescription;
#endregion
#region Overrides of ConfigurationBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText)); this.timer.Elapsed += async (_, _) => await this.InvokeAsync(async () => await this.OptionChanged(this.internalText));
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
#region Overrides of ComponentBase
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
this.internalText = this.Text(); this.internalText = this.Text();
@@ -66,8 +75,6 @@ public partial class ConfigurationText : ConfigurationBase
#endregion #endregion
#endregion
private bool AutoGrow => this.NumLines > 1; private bool AutoGrow => this.NumLines > 1;
private int GetMaxLines => this.AutoGrow ? this.MaxLines : 1; private int GetMaxLines => this.AutoGrow ? this.MaxLines : 1;
@@ -85,4 +92,23 @@ public partial class ConfigurationText : ConfigurationBase
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.InformAboutChange(); await this.InformAboutChange();
} }
#region Overrides of MSGComponentBase
protected override void DisposeResources()
{
try
{
this.timer.Stop();
this.timer.Dispose();
}
catch
{
// ignore
}
base.DisposeResources();
}
#endregion
} }
@@ -4,7 +4,7 @@ using Timer = System.Timers.Timer;
namespace AIStudio.Components; namespace AIStudio.Components;
public partial class DebouncedTextField : MudComponentBase public partial class DebouncedTextField : MudComponentBase, IDisposable
{ {
[Parameter] [Parameter]
public string Label { get; set; } = string.Empty; public string Label { get; set; } = string.Empty;
@@ -50,12 +50,15 @@ public partial class DebouncedTextField : MudComponentBase
private readonly Timer debounceTimer = new(); private readonly Timer debounceTimer = new();
private string text = string.Empty; private string text = string.Empty;
private string lastParameterText = string.Empty;
private bool isInitialized;
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
this.text = this.Text; this.text = this.Text;
this.lastParameterText = this.Text;
this.debounceTimer.AutoReset = false; this.debounceTimer.AutoReset = false;
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds; this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
this.debounceTimer.Elapsed += (_, _) => this.debounceTimer.Elapsed += (_, _) =>
@@ -66,9 +69,32 @@ public partial class DebouncedTextField : MudComponentBase
this.InvokeAsync(() => this.WhenTextCanged(this.text)); this.InvokeAsync(() => this.WhenTextCanged(this.text));
}; };
this.isInitialized = true;
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
protected override async Task OnParametersSetAsync()
{
// Ensure the timer uses the latest debouncing interval:
if (!this.isInitialized)
return;
if(Math.Abs(this.debounceTimer.Interval - this.DebounceTime.TotalMilliseconds) > 1)
this.debounceTimer.Interval = this.DebounceTime.TotalMilliseconds;
// Only sync when the parent's parameter actually changed since the last change:
if (this.Text != this.lastParameterText)
{
this.text = this.Text;
this.lastParameterText = this.Text;
}
this.debounceTimer.Stop();
this.debounceTimer.Start();
await base.OnParametersSetAsync();
}
#endregion #endregion
private void OnTextChanged(string value) private void OnTextChanged(string value)
@@ -77,4 +103,21 @@ public partial class DebouncedTextField : MudComponentBase
this.debounceTimer.Stop(); this.debounceTimer.Stop();
this.debounceTimer.Start(); this.debounceTimer.Start();
} }
#region IDisposable
public void Dispose()
{
try
{
this.debounceTimer.Stop();
this.debounceTimer.Dispose();
}
catch
{
// ignore
}
}
#endregion
} }
@@ -0,0 +1,5 @@
@inherits ConfigurationBaseCore
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@this.Icon" Disabled="@this.IsDisabled" OnClick="@(async () => await this.ClickAsync())">
@this.Text
</MudButton>
@@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class LockableButton : ConfigurationBaseCore
{
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.Info;
[Parameter]
public Func<Task> OnClickAsync { get; set; } = () => Task.CompletedTask;
[Parameter]
public Action OnClick { get; set; } = () => { };
[Parameter]
public string Text { get; set; } = string.Empty;
[Parameter]
public string Class { get; set; } = string.Empty;
#region Overrides of ConfigurationBase
/// <inheritdoc />
protected override bool Stretch => false;
protected override string GetClassForBase => this.Class;
#endregion
private async Task ClickAsync()
{
if (this.IsLocked() || this.Disabled())
return;
await this.OnClickAsync();
this.OnClick();
}
}
@@ -13,10 +13,6 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
[Inject] [Inject]
protected MessageBus MessageBus { get; init; } = null!; protected MessageBus MessageBus { get; init; } = null!;
[Inject]
// ReSharper disable once UnusedAutoPropertyAccessor.Local
private ILogger<MSGComponentBase> Logger { get; init; } = null!;
private ILanguagePlugin Lang { get; set; } = PluginFactory.BaseLanguage; private ILanguagePlugin Lang { get; set; } = PluginFactory.BaseLanguage;
#region Overrides of ComponentBase #region Overrides of ComponentBase
@@ -44,6 +40,8 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
#region Implementation of IMessageBusReceiver #region Implementation of IMessageBusReceiver
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
{
await this.InvokeAsync(async () =>
{ {
switch (triggeredEvent) switch (triggeredEvent)
{ {
@@ -58,6 +56,7 @@ public abstract class MSGComponentBase : ComponentBase, IDisposable, IMessageBus
} }
await this.ProcessIncomingMessage(sendingComponent, triggeredEvent, data); await this.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
});
} }
public async Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) public async Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
@@ -0,0 +1,3 @@
<MudTooltip Text="@this.TooltipMessage" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Size="@this.Size" OnClick="@(() => this.HandleCopyClick())"/>
</MudTooltip>
@@ -0,0 +1,90 @@
using AIStudio.Chat;
using AIStudio.Tools.PluginSystem;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class MudCopyClipboardButton : ComponentBase
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(MudCopyClipboardButton).Namespace, nameof(MudCopyClipboardButton));
/// <summary>
/// The string, if you want to copy a string.
/// </summary>
[Parameter]
public string StringContent { get; set; } = string.Empty;
/// <summary>
/// The content, if you want to copy content.
/// </summary>
[Parameter]
public IContent? Content { get; init; }
/// <summary>
/// The content type, if you want to copy Content.
/// </summary>
[Parameter]
public ContentType Type { get; init; } = ContentType.NONE;
/// <summary>
/// The tooltip that should be shown to the user.
/// </summary>
[Parameter]
public string TooltipMessage { get; set; } = TB("Copies the content to the clipboard");
/// <summary>
/// The size of the button. The default size is small.
/// </summary>
[Parameter]
public Size Size { get; set; } = Size.Small;
[Inject]
private ISnackbar Snackbar { get; init; } = null!;
[Inject]
private RustService RustService { get; init; } = null!;
private async Task HandleCopyClick()
{
if (this.Type is ContentType.NONE)
await this.CopyToClipboard(this.StringContent);
else
await this.CopyToClipboard(this.Content);
}
/// <summary>
/// Copy this the string to the clipboard.
/// </summary>
private async Task CopyToClipboard(string textContent)
{
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent);
}
/// <summary>
/// Copy this block's content to the clipboard.
/// </summary>
private async Task CopyToClipboard(IContent? contentToCopy)
{
if (contentToCopy is null)
return;
switch (this.Type)
{
case ContentType.TEXT:
var textContent = (ContentText) contentToCopy;
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
break;
default:
this.Snackbar.Add(TB("Cannot copy this content type to clipboard."), Severity.Error, config =>
{
config.Icon = Icons.Material.Filled.ContentCopy;
config.IconSize = Size.Large;
config.IconColor = Color.Error;
});
break;
}
}
}
@@ -11,7 +11,7 @@
} }
else else
{ {
<MudIconButton Icon="@Icons.Material.Filled.Person4" /> <MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Person4" />
} }
</ActivatorContent> </ActivatorContent>
<ChildContent> <ChildContent>
@@ -13,7 +13,7 @@ public partial class ProviderSelection : MSGComponentBase
public AssistantBase<NoComponent>? AssistantBase { get; set; } public AssistantBase<NoComponent>? AssistantBase { get; set; }
[Parameter] [Parameter]
public AIStudio.Settings.Provider ProviderSettings { get; set; } public AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
[Parameter] [Parameter]
public EventCallback<AIStudio.Settings.Provider> ProviderSettingsChanged { get; set; } public EventCallback<AIStudio.Settings.Provider> ProviderSettingsChanged { get; set; }
@@ -32,6 +32,7 @@ public partial class ProviderSelection : MSGComponentBase
{ {
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE); var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.AssistantBase?.Component ?? Tools.Components.NONE);
foreach (var provider in this.SettingsManager.ConfigurationData.Providers) foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
if (provider.UsedLLMProvider != LLMProviders.NONE)
if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel) if (provider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
yield return provider; yield return provider;
} }
@@ -1,4 +1,4 @@
@inherits MSGComponentBase @inherits MSGComponentBase
<MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="async () => await this.SelectFile()" Variant="Variant.Filled" Class="mb-3"> <MudButton StartIcon="@Icons.Material.Filled.Description" OnClick="async () => await this.SelectFile()" Variant="Variant.Filled" Class="mb-3">
@T("Use PDF content as input") @T("Use file content as input")
</MudButton> </MudButton>
@@ -0,0 +1,44 @@
using AIStudio.Tools.Rust;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class ReadFileContent : MSGComponentBase
{
[Parameter]
public string FileContent { get; set; } = string.Empty;
[Parameter]
public EventCallback<string> FileContentChanged { get; set; }
[Inject]
private RustService RustService { get; init; } = null!;
private async Task SelectFile()
{
var selectedFile = await this.RustService.SelectFile(T("Select file to read its content"));
if (selectedFile.UserCancelled)
return;
if(!File.Exists(selectedFile.SelectedFilePath))
return;
var ext = Path.GetExtension(selectedFile.SelectedFilePath).TrimStart('.');
if (Array.Exists(FileTypeFilter.Executables.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase)))
{
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.AppBlocking, T("Executables are not allowed")));
return;
}
if (Array.Exists(FileTypeFilter.AllImages.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase)))
{
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.ImageNotSupported, T("Images are not supported yet")));
return;
}
var fileContent = await this.RustService.ReadArbitraryFileData(selectedFile.SelectedFilePath, int.MaxValue);
await this.FileContentChanged.InvokeAsync(fileContent);
}
}
@@ -1,31 +0,0 @@
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,9 +1,9 @@
@inherits MSGComponentBase @inherits MSGComponentBase
<MudPaper Class="pa-3 mb-3 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" Value="@this.Preselect" ValueChanged="@this.ShowWebContentReaderChanged" LabelOn="@T("Show web content options")" LabelOff="@T("Hide web content options")" />
@if (this.showWebContentReader) @if (this.Preselect)
{ {
<MudTextSwitch Label="@T("Cleanup content by using an LLM agent?")" @bind-Value="@this.useContentCleanerAgent" Validation="@this.ValidateProvider" Disabled="@this.AgentIsRunning" LabelOn="@T("The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used.")" LabelOff="@T("No content cleaning")" /> <MudTextSwitch Label="@T("Cleanup content by using an LLM agent?")" Value="@this.PreselectContentCleanerAgent" ValueChanged="@this.UseContentCleanerAgentChanged" Validation="@this.ValidateProvider" Disabled="@this.AgentIsRunning" LabelOn="@T("The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used.")" LabelOff="@T("No content cleaning")" />
<MudStack Row="@true" AlignItems="@AlignItems.Baseline" Class="mb-3"> <MudStack Row="@true" AlignItems="@AlignItems.Baseline" Class="mb-3">
<MudTextField T="string" Label="@T("URL from which to load the content")" @bind-Value="@this.providedURL" Validation="@this.ValidateURL" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Link" Placeholder="https://..." HelperText="@T("Loads the content from your URL. Does not work when the content is hidden behind a paywall.")" Variant="Variant.Outlined" Immediate="@true" Disabled="@this.AgentIsRunning"/> <MudTextField T="string" Label="@T("URL from which to load the content")" @bind-Value="@this.providedURL" Validation="@this.ValidateURL" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Link" Placeholder="https://..." HelperText="@T("Loads the content from your URL. Does not work when the content is hidden behind a paywall.")" Variant="Variant.Outlined" Immediate="@true" Disabled="@this.AgentIsRunning"/>
<MudButton Disabled="@(!this.IsReady || this.AgentIsRunning)" Variant="Variant.Filled" Size="Size.Large" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Download" OnClick="() => this.LoadFromWeb()"> <MudButton Disabled="@(!this.IsReady || this.AgentIsRunning)" Variant="Variant.Filled" Size="Size.Large" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Download" OnClick="() => this.LoadFromWeb()">
@@ -20,7 +20,7 @@ public partial class ReadWebContent : MSGComponentBase
public EventCallback<string> ContentChanged { get; set; } public EventCallback<string> ContentChanged { get; set; }
[Parameter] [Parameter]
public AIStudio.Settings.Provider ProviderSettings { get; set; } public AIStudio.Settings.Provider ProviderSettings { get; set; } = AIStudio.Settings.Provider.NONE;
[Parameter] [Parameter]
public bool AgentIsRunning { get; set; } public bool AgentIsRunning { get; set; }
@@ -31,31 +31,32 @@ public partial class ReadWebContent : MSGComponentBase
[Parameter] [Parameter]
public bool Preselect { get; set; } public bool Preselect { get; set; }
[Parameter]
public EventCallback<bool> PreselectChanged { get; set; }
[Parameter] [Parameter]
public bool PreselectContentCleanerAgent { get; set; } public bool PreselectContentCleanerAgent { get; set; }
private Process<ReadWebContentSteps> process = Process<ReadWebContentSteps>.INSTANCE; [Parameter]
public EventCallback<bool> PreselectContentCleanerAgentChanged { get; set; }
private readonly Process<ReadWebContentSteps> process = Process<ReadWebContentSteps>.INSTANCE;
private ProcessStepValue processStep; private ProcessStepValue processStep;
private bool showWebContentReader;
private bool useContentCleanerAgent;
private string providedURL = string.Empty; private string providedURL = string.Empty;
private bool urlIsValid; private bool urlIsValid;
private bool isProviderValid; private bool isProviderValid;
private AIStudio.Settings.Provider providerSettings; private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
if(this.Preselect)
this.showWebContentReader = true;
if(this.PreselectContentCleanerAgent)
this.useContentCleanerAgent = true;
this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_TEXT_CONTENT_CLEANER, this.ProviderSettings.Id, true); this.ProviderSettings = this.SettingsManager.GetPreselectedProvider(Tools.Components.AGENT_TEXT_CONTENT_CLEANER, this.ProviderSettings.Id, true);
this.providerSettings = this.ProviderSettings;
this.ValidateProvider(this.PreselectContentCleanerAgent);
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
@@ -64,6 +65,7 @@ public partial class ReadWebContent : MSGComponentBase
if (!this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions) if (!this.SettingsManager.ConfigurationData.TextContentCleaner.PreselectAgentOptions)
this.providerSettings = this.ProviderSettings; this.providerSettings = this.ProviderSettings;
this.ValidateProvider(this.PreselectContentCleanerAgent);
await base.OnParametersSetAsync(); await base.OnParametersSetAsync();
} }
@@ -86,7 +88,7 @@ public partial class ReadWebContent : MSGComponentBase
this.StateHasChanged(); this.StateHasChanged();
markdown = this.HTMLParser.ParseToMarkdown(html); markdown = this.HTMLParser.ParseToMarkdown(html);
if (this.useContentCleanerAgent) if (this.PreselectContentCleanerAgent && this.providerSettings != AIStudio.Settings.Provider.NONE)
{ {
this.AgentTextContentCleaner.ProviderSettings = this.providerSettings; this.AgentTextContentCleaner.ProviderSettings = this.providerSettings;
var additionalData = new Dictionary<string, string> var additionalData = new Dictionary<string, string>
@@ -140,16 +142,26 @@ public partial class ReadWebContent : MSGComponentBase
if(!this.urlIsValid) if(!this.urlIsValid)
return false; return false;
if(this.useContentCleanerAgent && !this.isProviderValid) if(this.PreselectContentCleanerAgent && !this.isProviderValid)
return false; return false;
return true; return true;
} }
} }
private async Task ShowWebContentReaderChanged(bool state)
{
await this.PreselectChanged.InvokeAsync(state);
}
private async Task UseContentCleanerAgentChanged(bool state)
{
await this.PreselectContentCleanerAgentChanged.InvokeAsync(state);
}
private string? ValidateProvider(bool shouldUseAgent) private string? ValidateProvider(bool shouldUseAgent)
{ {
if(shouldUseAgent && this.providerSettings == default) if(shouldUseAgent && this.providerSettings == AIStudio.Settings.Provider.NONE)
{ {
this.isProviderValid = false; this.isProviderValid = false;
return T("Please select a provider to use the cleanup agent."); return T("Please select a provider to use the cleanup agent.");
@@ -0,0 +1,24 @@
using AIStudio.Tools.PluginSystem;
namespace AIStudio.Components;
public static class ReadWebContentStepsExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ReadWebContentStepsExtensions).Namespace, nameof(ReadWebContentStepsExtensions));
/// <summary>
/// Gets the text representation of a given ReadWebContentSteps enum value.
/// </summary>
/// <param name="step">The ReadWebContentSteps enum value.</param>
/// <returns>>The text representation of the process step.</returns>
public static string GetText(this ReadWebContentSteps step) => step switch
{
ReadWebContentSteps.START => TB("Start"),
ReadWebContentSteps.LOADING => TB("Loading"),
ReadWebContentSteps.PARSING => TB("Parsing"),
ReadWebContentSteps.CLEANING => TB("Cleaning"),
ReadWebContentSteps.DONE => TB("Done"),
_ => TB("n/a")
};
}
@@ -1,6 +1,6 @@
@inherits SettingsPanelBase @inherits SettingsPanelBase
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="Agent: Text Content Cleaner Options"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.TextFields" HeaderText="@T("Agent: Text Content Cleaner Options")">
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg"> <MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<MudText Typo="Typo.body1" Class="mb-3"> <MudText Typo="Typo.body1" Class="mb-3">
@T("Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used.") @T("Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used.")
@@ -13,7 +13,8 @@
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/> <ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.")"/> <ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.")"/>
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/> <ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/>
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" Disabled="() => this.SettingsLocker.IsLocked<DataApp>(x => x.UpdateBehavior)"/> <ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInterval)" Data="@ConfigurationSelectDataFactory.GetUpdateIntervalData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInterval = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInterval, out var meta) && meta.IsLocked"/>
<ConfigurationSelect OptionDescription="@T("Update installation method")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateInstallation)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviourData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateInstallation = selectedValue)" OptionHelp="@T("Should updates be installed automatically or manually?")" IsLocked="() => ManagedConfiguration.TryGet(x => x.App, x => x.UpdateInstallation, out var meta) && meta.IsLocked"/>
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/> <ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/> <ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
@@ -15,7 +15,4 @@ public abstract class SettingsPanelBase : MSGComponentBase
[Inject] [Inject]
protected RustService RustService { get; init; } = null!; protected RustService RustService { get; init; } = null!;
[Inject]
protected SettingsLocker SettingsLocker { get; init; } = null!;
} }
@@ -90,9 +90,9 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
private async Task DeleteEmbeddingProvider(EmbeddingProvider provider) private async Task DeleteEmbeddingProvider(EmbeddingProvider provider)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) }, { x => x.Message, string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -75,9 +75,7 @@
</MudText> </MudText>
} }
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddLLMProvider"> <LockableButton Text="@T("Add Provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddLLMProvider" Class="mt-3" />
@T("Add Provider")
</MudButton>
<MudText Typo="Typo.h4" Class="mb-3"> <MudText Typo="Typo.h4" Class="mb-3">
@T("LLM Provider Confidence") @T("LLM Provider Confidence")
@@ -54,6 +54,12 @@ public partial class SettingsPanelProviders : SettingsPanelBase
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
private async Task EditLLMProvider(AIStudio.Settings.Provider provider) private async Task EditLLMProvider(AIStudio.Settings.Provider provider)
{ {
if(provider == AIStudio.Settings.Provider.NONE)
return;
if (provider.IsEnterpriseConfiguration)
return;
var dialogParameters = new DialogParameters<ProviderDialog> var dialogParameters = new DialogParameters<ProviderDialog>
{ {
{ x => x.DataNum, provider.Num }, { x => x.DataNum, provider.Num },
@@ -90,9 +96,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider) private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the provider '{0}'?"), provider.InstanceName) }, { x => x.Message, string.Format(T("Are you sure you want to delete the provider '{0}'?"), provider.InstanceName) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -108,9 +114,9 @@ public partial class SettingsPanelProviders : SettingsPanelBase
} }
else else
{ {
var issueDialogParameters = new DialogParameters var issueDialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Couldn't delete the provider '{0}'. The issue: {1}. We can ignore this issue and delete the provider anyway. Do you want to ignore it and delete this provider?"), provider.InstanceName, deleteSecretResponse.Issue) }, { x => x.Message, string.Format(T("Couldn't delete the provider '{0}'. The issue: {1}. We can ignore this issue and delete the provider anyway. Do you want to ignore it and delete this provider?"), provider.InstanceName, deleteSecretResponse.Issue) },
}; };
var issueDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), issueDialogParameters, DialogOptions.FULLSCREEN); var issueDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete LLM Provider"), issueDialogParameters, DialogOptions.FULLSCREEN);
@@ -16,9 +16,6 @@ public partial class Workspaces : MSGComponentBase
[Inject] [Inject]
private IDialogService DialogService { get; init; } = null!; private IDialogService DialogService { get; init; } = null!;
[Inject]
private ThreadSafeRandom RNG { get; init; } = null!;
[Inject] [Inject]
private ILogger<Workspaces> Logger { get; init; } = null!; private ILogger<Workspaces> Logger { get; init; } = null!;
@@ -47,14 +44,17 @@ public partial class Workspaces : MSGComponentBase
// - Those initial tree items cannot have children // - Those initial tree items cannot have children
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item // - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
// //
await this.LoadTreeItems(); // We won't await the loading of the tree items here,
// to avoid blocking the UI thread:
_ = this.LoadTreeItems();
} }
#endregion #endregion
private async Task LoadTreeItems() private async Task LoadTreeItems()
{ {
var workspacesNode = new TreeItemData<ITreeItem> this.treeItems.Clear();
this.treeItems.Add(new TreeItemData<ITreeItem>
{ {
Expanded = this.ExpandRootNodes, Expanded = this.ExpandRootNodes,
Expandable = true, Expandable = true,
@@ -68,9 +68,16 @@ public partial class Workspaces : MSGComponentBase
Path = "root", Path = "root",
Children = await this.LoadWorkspaces(), Children = await this.LoadWorkspaces(),
}, },
}; });
var tempChatNode = new TreeItemData<ITreeItem> this.treeItems.Add(new TreeItemData<ITreeItem>
{
Expandable = false,
Value = new TreeDivider(),
});
await this.InvokeAsync(this.StateHasChanged);
this.treeItems.Add(new TreeItemData<ITreeItem>
{ {
Expanded = this.ExpandRootNodes, Expanded = this.ExpandRootNodes,
Expandable = true, Expandable = true,
@@ -84,16 +91,9 @@ public partial class Workspaces : MSGComponentBase
Path = "temp", Path = "temp",
Children = await this.LoadTemporaryChats(), Children = await this.LoadTemporaryChats(),
}, },
};
this.treeItems.Clear();
this.treeItems.Add(workspacesNode);
this.treeItems.Add(new TreeItemData<ITreeItem>
{
Expandable = false,
Value = new TreeDivider(),
}); });
this.treeItems.Add(tempChatNode);
await this.InvokeAsync(this.StateHasChanged);
} }
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadTemporaryChats() private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadTemporaryChats()
@@ -109,9 +109,30 @@ public partial class Workspaces : MSGComponentBase
// Enumerate the chat directories: // Enumerate the chat directories:
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories)) foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
{ {
// Read the `name` file: // Read or create the `name` file (self-heal):
var chatNamePath = Path.Join(tempChatDirPath, "name"); var chatNamePath = Path.Join(tempChatDirPath, "name");
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8); string chatName;
try
{
if (!File.Exists(chatNamePath))
{
chatName = T("Unnamed chat");
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
}
else
{
chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
if (string.IsNullOrWhiteSpace(chatName))
{
chatName = T("Unnamed chat");
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
}
}
}
catch
{
chatName = T("Unnamed chat");
}
// Read the last change time of the chat: // Read the last change time of the chat:
var chatThreadPath = Path.Join(tempChatDirPath, "thread.json"); var chatThreadPath = Path.Join(tempChatDirPath, "thread.json");
@@ -155,9 +176,30 @@ public partial class Workspaces : MSGComponentBase
// Enumerate the workspace directories: // Enumerate the workspace directories:
foreach (var workspaceDirPath in Directory.EnumerateDirectories(workspaceDirectories)) foreach (var workspaceDirPath in Directory.EnumerateDirectories(workspaceDirectories))
{ {
// Read the `name` file: // Read or create the `name` file (self-heal):
var workspaceNamePath = Path.Join(workspaceDirPath, "name"); var workspaceNamePath = Path.Join(workspaceDirPath, "name");
var workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8); string workspaceName;
try
{
if (!File.Exists(workspaceNamePath))
{
workspaceName = T("Unnamed workspace");
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
}
else
{
workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
if (string.IsNullOrWhiteSpace(workspaceName))
{
workspaceName = T("Unnamed workspace");
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
}
}
}
catch
{
workspaceName = T("Unnamed workspace");
}
workspaces.Add(new TreeItemData<ITreeItem> workspaces.Add(new TreeItemData<ITreeItem>
{ {
@@ -191,9 +233,30 @@ public partial class Workspaces : MSGComponentBase
// Enumerate the workspace directory: // Enumerate the workspace directory:
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath)) foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
{ {
// Read the `name` file: // Read or create the `name` file (self-heal):
var chatNamePath = Path.Join(chatPath, "name"); var chatNamePath = Path.Join(chatPath, "name");
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8); string chatName;
try
{
if (!File.Exists(chatNamePath))
{
chatName = T("Unnamed chat");
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
}
else
{
chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
if (string.IsNullOrWhiteSpace(chatName))
{
chatName = T("Unnamed chat");
await File.WriteAllTextAsync(chatNamePath, chatName, Encoding.UTF8);
}
}
}
catch
{
chatName = T("Unnamed chat");
}
// Read the last change time of the chat: // Read the last change time of the chat:
var chatThreadPath = Path.Join(chatPath, "thread.json"); var chatThreadPath = Path.Join(chatPath, "thread.json");
@@ -249,9 +312,9 @@ public partial class Workspaces : MSGComponentBase
// Check if the chat has unsaved changes: // Check if the chat has unsaved changes:
if (switchToChat && await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES)) if (switchToChat && await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", T("Are you sure you want to load another chat? All unsaved changes will be lost.") }, { x => x.Message, T("Are you sure you want to load another chat? All unsaved changes will be lost.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Load Chat"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Load Chat"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -290,10 +353,10 @@ public partial class Workspaces : MSGComponentBase
if (askForConfirmation) if (askForConfirmation)
{ {
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(chat.WorkspaceId); var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(chat.WorkspaceId);
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ {
"Message", (chat.WorkspaceId == Guid.Empty) switch x => x.Message, (chat.WorkspaceId == Guid.Empty) switch
{ {
true => string.Format(T("Are you sure you want to delete the temporary chat '{0}'?"), chat.Name), true => string.Format(T("Are you sure you want to delete the temporary chat '{0}'?"), chat.Name),
false => string.Format(T("Are you sure you want to delete the chat '{0}' in the workspace '{1}'?"), chat.Name, workspaceName), false => string.Format(T("Are you sure you want to delete the chat '{0}' in the workspace '{1}'?"), chat.Name, workspaceName),
@@ -330,12 +393,15 @@ public partial class Workspaces : MSGComponentBase
if (chat is null) if (chat is null)
return; return;
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) }, { x => x.Message, string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) },
{ "UserInput", chat.Name }, { x => x.InputHeaderText, T("Chat Name") },
{ "ConfirmText", T("Rename") }, { x => x.UserInput, chat.Name },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmText, T("Rename") },
{ x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a chat name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -362,12 +428,15 @@ public partial class Workspaces : MSGComponentBase
var workspaceId = Guid.Parse(Path.GetFileName(workspacePath)); var workspaceId = Guid.Parse(Path.GetFileName(workspacePath));
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId); var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId);
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) }, { x => x.Message, string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) },
{ "UserInput", workspaceName }, { x => x.InputHeaderText, T("Workspace Name") },
{ "ConfirmText", T("Rename") }, { x => x.UserInput, workspaceName },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmText, T("Rename") },
{ x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -383,12 +452,15 @@ public partial class Workspaces : MSGComponentBase
private async Task AddWorkspace() private async Task AddWorkspace()
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", T("Please name your workspace:") }, { x => x.Message, T("Please name your workspace:") },
{ "UserInput", string.Empty }, { x => x.InputHeaderText, T("Workspace Name") },
{ "ConfirmText", T("Add workspace") }, { x => x.UserInput, string.Empty },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmText, T("Add workspace") },
{ x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -417,9 +489,9 @@ public partial class Workspaces : MSGComponentBase
// Determine how many chats are in the workspace: // Determine how many chats are in the workspace:
var chatCount = Directory.EnumerateDirectories(workspacePath).Count(); var chatCount = Directory.EnumerateDirectories(workspacePath).Count();
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the workspace '{0}'? This will also delete {1} chat(s) in this workspace."), workspaceName, chatCount) }, { x => x.Message, string.Format(T("Are you sure you want to delete the workspace '{0}'? This will also delete {1} chat(s) in this workspace."), workspaceName, chatCount) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -437,11 +509,11 @@ public partial class Workspaces : MSGComponentBase
if (chat is null) if (chat is null)
return; return;
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<WorkspaceSelectionDialog>
{ {
{ "Message", T("Please select the workspace where you want to move the chat to.") }, { x => x.Message, T("Please select the workspace where you want to move the chat to.") },
{ "SelectedWorkspace", chat.WorkspaceId }, { x => x.SelectedWorkspace, chat.WorkspaceId },
{ "ConfirmText", T("Move chat") }, { x => x.ConfirmText, T("Move chat") },
}; };
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -484,9 +556,9 @@ public partial class Workspaces : MSGComponentBase
// Check if the chat has unsaved changes: // Check if the chat has unsaved changes:
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES)) if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", T("Are you sure you want to create a another chat? All unsaved changes will be lost.") }, { x => x.Message, T("Are you sure you want to create a another chat? All unsaved changes will be lost.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Create Chat"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Create Chat"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -501,7 +573,6 @@ public partial class Workspaces : MSGComponentBase
WorkspaceId = workspaceId, WorkspaceId = workspaceId,
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = this.RNG.Next(),
SystemPrompt = SystemPrompts.DEFAULT, SystemPrompt = SystemPrompts.DEFAULT,
Blocks = [], Blocks = [],
}; };
@@ -56,7 +56,32 @@
@T("Use the default system prompt") @T("Use the default system prompt")
</MudButton> </MudButton>
<MudJustifiedText Class="mt-6" Typo="Typo.body1"> <MudText Typo="Typo.h6" Class="mb-3 mt-6">
@T("Predefined User Input")
</MudText>
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
@T("You might want to predefine a first message that will be copied into the user prompt, when you use this chat template. This message could for example be a blueprint for a structured message that this chat template is defined to work with.")
</MudJustifiedText>
<MudTextField
T="string"
@bind-Text="@this.PredefinedUserPrompt"
AdornmentIcon="@Icons.Material.Filled.ListAlt"
Adornment="Adornment.Start"
Immediate="@true"
Label="@T("What predefined user input do you want to use?")"
Variant="Variant.Outlined"
Lines="4"
MaxLines="12"
AutoGrow="@true"
Class="mb-3"
UserAttributes="@SPELLCHECK_ATTRIBUTES"
HelperText="@T("Tell the AI your predefined user input.")"
/>
<MudText Typo="Typo.h6" Class="mb-3 mt-6">
@T("Profile Usage")
</MudText>
<MudJustifiedText Class="mb-3" Typo="Typo.body1">
@T("Using some chat templates in tandem with profiles might cause issues. Therefore, you might prohibit the usage of profiles here.") @T("Using some chat templates in tandem with profiles might cause issues. Therefore, you might prohibit the usage of profiles here.")
</MudJustifiedText> </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")" /> <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")" />
@@ -64,11 +89,9 @@
<MudText Typo="Typo.h6" Class="mb-3 mt-6"> <MudText Typo="Typo.h6" Class="mb-3 mt-6">
@T("Example Conversation") @T("Example Conversation")
</MudText> </MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-3"> <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.") @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> </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"> <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> <ColGroup>
<col style="width: 10em;" /> <col style="width: 10em;" />
@@ -35,6 +35,12 @@ public partial class ChatTemplateDialog : MSGComponentBase
[Parameter] [Parameter]
public string DataSystemPrompt { get; set; } = string.Empty; public string DataSystemPrompt { get; set; } = string.Empty;
/// <summary>
/// What is the predefined user prompt?
/// </summary>
[Parameter]
public string PredefinedUserPrompt { get; set; } = string.Empty;
/// <summary> /// <summary>
/// Should the dialog be in editing mode? /// Should the dialog be in editing mode?
/// </summary> /// </summary>
@@ -47,6 +53,12 @@ public partial class ChatTemplateDialog : MSGComponentBase
[Parameter] [Parameter]
public bool AllowProfileUsage { get; set; } = true; public bool AllowProfileUsage { get; set; } = true;
[Parameter]
public bool CreateFromExistingChatThread { get; set; }
[Parameter]
public ChatThread? ExistingChatThread { get; set; }
[Inject] [Inject]
private ILogger<ChatTemplateDialog> Logger { get; init; } = null!; private ILogger<ChatTemplateDialog> Logger { get; init; } = null!;
@@ -85,6 +97,13 @@ public partial class ChatTemplateDialog : MSGComponentBase
this.dataExampleConversation = this.ExampleConversation.Select(n => n.DeepClone()).ToList(); this.dataExampleConversation = this.ExampleConversation.Select(n => n.DeepClone()).ToList();
} }
if (this.CreateFromExistingChatThread && this.ExistingChatThread is not null)
{
this.DataSystemPrompt = this.ExistingChatThread.SystemPrompt;
this.dataExampleConversation = this.ExistingChatThread.Blocks.Select(n => n.DeepClone(true)).ToList();
this.DataName = this.ExistingChatThread.Name;
}
await base.OnInitializedAsync(); await base.OnInitializedAsync();
} }
@@ -107,8 +126,12 @@ public partial class ChatTemplateDialog : MSGComponentBase
Name = this.DataName, Name = this.DataName,
SystemPrompt = this.DataSystemPrompt, SystemPrompt = this.DataSystemPrompt,
PredefinedUserPrompt = this.PredefinedUserPrompt,
ExampleConversation = this.dataExampleConversation, ExampleConversation = this.dataExampleConversation,
AllowProfileUsage = this.AllowProfileUsage, AllowProfileUsage = this.AllowProfileUsage,
EnterpriseConfigurationPluginId = Guid.Empty,
IsEnterpriseConfiguration = false,
}; };
private void RemoveMessage(ContentBlock item) private void RemoveMessage(ContentBlock item)
@@ -1,9 +1,9 @@
@inherits MSGComponentBase @inherits MSGComponentBase
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
<MudText Typo="Typo.body1"> <MudJustifiedText Typo="Typo.body1">
@this.Message @this.Message
</MudText> </MudJustifiedText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled"> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
@@ -107,6 +107,12 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
this.dataSecurityPolicy = this.DataSource.SecurityPolicy; this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
this.dataMaxMatches = this.DataSource.MaxMatches; this.dataMaxMatches = this.DataSource.MaxMatches;
// We cannot load the retrieval processes now, since we have
// to load the data first. But while doing so, we can need to
// restore the selected retrieval process id. That's why we
// assign the selected retrieval id to the default retrieval process:
this.dataSelectedRetrievalProcess = this.dataSelectedRetrievalProcess with { Id = this.DataSource.SelectedRetrievalId };
if (this.dataAuthMethod is AuthMethod.TOKEN or AuthMethod.USERNAME_PASSWORD) if (this.dataAuthMethod is AuthMethod.TOKEN or AuthMethod.USERNAME_PASSWORD)
{ {
// Load the secret: // Load the secret:
@@ -69,9 +69,6 @@ public partial class EmbeddingProviderDialog : MSGComponentBase, ISecretId
[Parameter] [Parameter]
public bool IsEditing { get; init; } public bool IsEditing { get; init; }
[Inject]
private ILogger<ProviderDialog> Logger { get; init; } = null!;
[Inject] [Inject]
private RustService RustService { get; init; } = null!; private RustService RustService { get; init; } = null!;
@@ -244,7 +241,7 @@ public partial class EmbeddingProviderDialog : MSGComponentBase, ISecretId
private async Task ReloadModels() private async Task ReloadModels()
{ {
var currentEmbeddingProviderSettings = this.CreateEmbeddingProviderSettings(); var currentEmbeddingProviderSettings = this.CreateEmbeddingProviderSettings();
var provider = currentEmbeddingProviderSettings.CreateProvider(this.Logger); var provider = currentEmbeddingProviderSettings.CreateProvider();
if(provider is NoProvider) if(provider is NoProvider)
return; return;
@@ -30,7 +30,7 @@
} }
else if (!string.IsNullOrWhiteSpace(this.licenseText)) else if (!string.IsNullOrWhiteSpace(this.licenseText))
{ {
<MudMarkdown Value="@this.licenseText" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/> <MudMarkdown Value="@this.licenseText" Props="Markdown.DefaultConfig"/>
} }
</ExpansionPanel> </ExpansionPanel>
@@ -33,7 +33,7 @@ public partial class PandocDialog : MSGComponentBase
[CascadingParameter] [CascadingParameter]
private IMudDialogInstance MudDialog { get; set; } = null!; private IMudDialogInstance MudDialog { get; set; } = null!;
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger("PandocDialog"); private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(PandocDialog));
private static readonly string LICENCE_URI = "https://raw.githubusercontent.com/jgm/pandoc/refs/heads/main/COPYING.md"; private static readonly string LICENCE_URI = "https://raw.githubusercontent.com/jgm/pandoc/refs/heads/main/COPYING.md";
private static string LATEST_PANDOC_VERSION = string.Empty; private static string LATEST_PANDOC_VERSION = string.Empty;
@@ -83,9 +83,9 @@ public partial class PandocDialog : MSGComponentBase
private async Task RejectLicense() private async Task RejectLicense()
{ {
var message = T("Pandoc is open-source and free, but if you reject its license, you can't install it and some MindWork AI Studio features will be limited (like the integration of Office files) or unavailable (like the generation of Office files). You can change your decision anytime. Are you sure you want to reject the license?"); var message = T("Pandoc is open-source and free, but if you reject its license, you can't install it and some MindWork AI Studio features will be limited (like the integration of Office files) or unavailable (like the generation of Office files). You can change your decision anytime. Are you sure you want to reject the license?");
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", message }, { x => x.Message, message },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reject Pandoc's Licence"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reject Pandoc's Licence"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -78,9 +78,6 @@ public partial class ProviderDialog : MSGComponentBase, ISecretId
[Parameter] [Parameter]
public bool IsEditing { get; init; } public bool IsEditing { get; init; }
[Inject]
private ILogger<ProviderDialog> Logger { get; init; } = null!;
[Inject] [Inject]
private RustService RustService { get; init; } = null!; private RustService RustService { get; init; } = null!;
@@ -126,12 +123,13 @@ public partial class ProviderDialog : MSGComponentBase, ISecretId
Id = this.DataId, Id = this.DataId,
InstanceName = this.DataInstanceName, InstanceName = this.DataInstanceName,
UsedLLMProvider = this.DataLLMProvider, UsedLLMProvider = this.DataLLMProvider,
Model = this.DataLLMProvider switch Model = this.DataLLMProvider switch
{ {
LLMProviders.FIREWORKS => new Model(this.dataManuallyModel, null), LLMProviders.FIREWORKS or LLMProviders.HUGGINGFACE => new Model(this.dataManuallyModel, null),
LLMProviders.HUGGINGFACE => new Model(this.dataManuallyModel, null),
_ => this.DataModel _ => this.DataModel
}, },
IsSelfHosted = this.DataLLMProvider is LLMProviders.SELF_HOSTED, IsSelfHosted = this.DataLLMProvider is LLMProviders.SELF_HOSTED,
IsEnterpriseConfiguration = false, IsEnterpriseConfiguration = false,
Hostname = cleanedHostname.EndsWith('/') ? cleanedHostname[..^1] : cleanedHostname, Hostname = cleanedHostname.EndsWith('/') ? cleanedHostname[..^1] : cleanedHostname,
@@ -158,13 +156,13 @@ public partial class ProviderDialog : MSGComponentBase, ISecretId
this.dataEditingPreviousInstanceName = this.DataInstanceName.ToLowerInvariant(); this.dataEditingPreviousInstanceName = this.DataInstanceName.ToLowerInvariant();
// When using Fireworks or Hugging Face, we must copy the model name: // When using Fireworks or Hugging Face, we must copy the model name:
if (this.DataLLMProvider is LLMProviders.FIREWORKS or LLMProviders.HUGGINGFACE) if (this.DataLLMProvider.IsLLMModelProvidedManually())
this.dataManuallyModel = this.DataModel.Id; this.dataManuallyModel = this.DataModel.Id;
// //
// We cannot load the API key for self-hosted providers: // We cannot load the API key for self-hosted providers:
// //
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && this.DataHost is not Host.OLLAMA) if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && this.DataHost is not Host.OLLAMA && this.DataHost is not Host.VLLM)
{ {
await this.ReloadModels(); await this.ReloadModels();
await base.OnInitializedAsync(); await base.OnInitializedAsync();
@@ -241,7 +239,7 @@ public partial class ProviderDialog : MSGComponentBase, ISecretId
private string? ValidateManuallyModel(string manuallyModel) private string? ValidateManuallyModel(string manuallyModel)
{ {
if ((this.DataLLMProvider is LLMProviders.FIREWORKS or LLMProviders.HUGGINGFACE) && string.IsNullOrWhiteSpace(manuallyModel)) if (this.DataLLMProvider.IsLLMModelProvidedManually() && string.IsNullOrWhiteSpace(manuallyModel))
return T("Please enter a model name."); return T("Please enter a model name.");
return null; return null;
@@ -252,7 +250,7 @@ public partial class ProviderDialog : MSGComponentBase, ISecretId
private async Task ReloadModels() private async Task ReloadModels()
{ {
var currentProviderSettings = this.CreateProviderSettings(); var currentProviderSettings = this.CreateProviderSettings();
var provider = currentProviderSettings.CreateProvider(this.Logger); var provider = currentProviderSettings.CreateProvider();
if(provider is NoProvider) if(provider is NoProvider)
return; return;
@@ -8,9 +8,9 @@ public partial class SettingsDialogAssistantBias : SettingsDialogBase
private async Task ResetBiasOfTheDayHistory() private async Task ResetBiasOfTheDayHistory()
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", T("Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again.") }, { x => x.Message, T("Are you sure you want to reset your bias-of-the-day statistics? The system will no longer remember which biases you already know. As a result, biases you are already familiar with may be addressed again.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reset your bias-of-the-day statistics"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Reset your bias-of-the-day statistics"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -31,6 +31,14 @@
<MudTd>@context.Num</MudTd> <MudTd>@context.Num</MudTd>
<MudTd>@context.Name</MudTd> <MudTd>@context.Name</MudTd>
<MudTd> <MudTd>
@if (context.IsEnterpriseConfiguration)
{
<MudTooltip Text="@T("This template is managed by your organization.")">
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Business" Disabled="true"/>
</MudTooltip>
}
else
{
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap"> <MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
<MudTooltip Text="@T("Edit")"> <MudTooltip Text="@T("Edit")">
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditChatTemplate(context)"/> <MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditChatTemplate(context)"/>
@@ -39,6 +47,7 @@
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteChatTemplate(context)"/> <MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteChatTemplate(context)"/>
</MudTooltip> </MudTooltip>
</MudStack> </MudStack>
}
</MudTd> </MudTd>
</RowTemplate> </RowTemplate>
</MudTable> </MudTable>
@@ -1,9 +1,29 @@
using AIStudio.Chat;
using AIStudio.Settings; using AIStudio.Settings;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Dialogs.Settings; namespace AIStudio.Dialogs.Settings;
public partial class SettingsDialogChatTemplate : SettingsDialogBase public partial class SettingsDialogChatTemplate : SettingsDialogBase
{ {
[Parameter]
public bool CreateTemplateFromExistingChatThread { get; set; }
[Parameter]
public ChatThread? ExistingChatThread { get; set; }
#region Overrides of ComponentBase
/// <inheritdoc />
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
if (this.CreateTemplateFromExistingChatThread)
await this.AddChatTemplate();
}
#endregion
private async Task AddChatTemplate() private async Task AddChatTemplate()
{ {
var dialogParameters = new DialogParameters<ChatTemplateDialog> var dialogParameters = new DialogParameters<ChatTemplateDialog>
@@ -11,6 +31,12 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
{ x => x.IsEditing, false }, { x => x.IsEditing, false },
}; };
if (this.CreateTemplateFromExistingChatThread)
{
dialogParameters.Add(x => x.CreateFromExistingChatThread, this.CreateTemplateFromExistingChatThread);
dialogParameters.Add(x => x.ExistingChatThread, this.ExistingChatThread);
}
var dialogReference = await this.DialogService.ShowAsync<ChatTemplateDialog>(T("Add Chat Template"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ChatTemplateDialog>(T("Add Chat Template"), 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)
@@ -27,12 +53,16 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
private async Task EditChatTemplate(ChatTemplate chatTemplate) private async Task EditChatTemplate(ChatTemplate chatTemplate)
{ {
if (chatTemplate == ChatTemplate.NO_CHAT_TEMPLATE || chatTemplate.IsEnterpriseConfiguration)
return;
var dialogParameters = new DialogParameters<ChatTemplateDialog> var dialogParameters = new DialogParameters<ChatTemplateDialog>
{ {
{ x => x.DataNum, chatTemplate.Num }, { x => x.DataNum, chatTemplate.Num },
{ x => x.DataId, chatTemplate.Id }, { x => x.DataId, chatTemplate.Id },
{ x => x.DataName, chatTemplate.Name }, { x => x.DataName, chatTemplate.Name },
{ x => x.DataSystemPrompt, chatTemplate.SystemPrompt }, { x => x.DataSystemPrompt, chatTemplate.SystemPrompt },
{ x => x.PredefinedUserPrompt, chatTemplate.PredefinedUserPrompt },
{ x => x.IsEditing, true }, { x => x.IsEditing, true },
{ x => x.ExampleConversation, chatTemplate.ExampleConversation }, { x => x.ExampleConversation, chatTemplate.ExampleConversation },
{ x => x.AllowProfileUsage, chatTemplate.AllowProfileUsage }, { x => x.AllowProfileUsage, chatTemplate.AllowProfileUsage },
@@ -52,9 +82,9 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
private async Task DeleteChatTemplate(ChatTemplate chatTemplate) private async Task DeleteChatTemplate(ChatTemplate chatTemplate)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the chat template '{0}'?"), chatTemplate.Name) }, { x => x.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 dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Chat Template"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -151,9 +151,9 @@ public partial class SettingsDialogDataSources : SettingsDialogBase
private async Task DeleteDataSource(IDataSource dataSource) private async Task DeleteDataSource(IDataSource dataSource)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the data source '{0}' of type {1}?"), dataSource.Name, dataSource.Type.GetDisplayName()) }, { x => x.Message, string.Format(T("Are you sure you want to delete the data source '{0}' of type {1}?"), dataSource.Name, dataSource.Type.GetDisplayName()) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Data Source"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Data Source"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -51,9 +51,9 @@ public partial class SettingsDialogProfiles : SettingsDialogBase
private async Task DeleteProfile(Profile profile) private async Task DeleteProfile(Profile profile)
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", string.Format(T("Are you sure you want to delete the profile '{0}'?"), profile.Name) }, { x => x.Message, string.Format(T("Are you sure you want to delete the profile '{0}'?"), profile.Name) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Profile"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Profile"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -25,6 +25,7 @@
{ {
<ConfigurationText OptionDescription="@T("Preselect your expertise")" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" Icon="@Icons.Material.Filled.Person" Text="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField = updatedText)"/> <ConfigurationText OptionDescription="@T("Preselect your expertise")" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" Icon="@Icons.Material.Filled.Person" Text="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedExpertInField = updatedText)"/>
} }
<ConfigurationText OptionDescription="@T("Preselect important aspects")" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" Text="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedImportantAspects)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedImportantAspects = updatedText)" NumLines="2" OptionHelp="@T("Preselect aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.")" Icon="@Icons.Material.Filled.List"/>
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence = selectedValue)"/> <ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.MinimumProviderConfidence = selectedValue)"/>
<ConfigurationProviderSelection Component="Components.TEXT_SUMMARIZER_ASSISTANT" Data="@this.availableLLMProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider = selectedValue)"/> <ConfigurationProviderSelection Component="Components.TEXT_SUMMARIZER_ASSISTANT" Data="@this.availableLLMProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.TextSummarizer.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.TextSummarizer.PreselectedProvider = selectedValue)"/>
</MudPaper> </MudPaper>
@@ -4,7 +4,9 @@
<MudText Typo="Typo.body1"> <MudText Typo="Typo.body1">
@this.Message @this.Message
</MudText> </MudText>
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@T("Chat name")" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES"/> <MudForm @ref="this.form" Class="mt-4">
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@this.GetInputHeaderText" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES" Validation="@this.ValidateUserInput" />
</MudForm>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled"> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
@@ -21,8 +21,19 @@ public partial class SingleInputDialog : MSGComponentBase
[Parameter] [Parameter]
public Color ConfirmColor { get; set; } = Color.Error; public Color ConfirmColor { get; set; } = Color.Error;
[Parameter]
public bool AllowEmptyInput { get; set; }
[Parameter]
public string InputHeaderText { get; set; } = string.Empty;
[Parameter]
public string EmptyInputErrorMessage { get; set; } = string.Empty;
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
private MudForm form = null!;
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@@ -34,7 +45,24 @@ public partial class SingleInputDialog : MSGComponentBase
#endregion #endregion
private string GetInputHeaderText => string.IsNullOrWhiteSpace(this.InputHeaderText) ? T("Your Input") : this.InputHeaderText;
private string? ValidateUserInput(string? value)
{
if (!this.AllowEmptyInput && string.IsNullOrWhiteSpace(value))
return string.IsNullOrWhiteSpace(this.EmptyInputErrorMessage) ? T("Please enter a value.") : this.EmptyInputErrorMessage;
return null;
}
private void Cancel() => this.MudDialog.Cancel(); private void Cancel() => this.MudDialog.Cancel();
private void Confirm() => this.MudDialog.Close(DialogResult.Ok(this.UserInput)); private async Task Confirm()
{
await this.form.Validate();
if(!this.form.IsValid)
return;
this.MudDialog.Close(DialogResult.Ok(this.UserInput));
}
} }
@@ -5,7 +5,7 @@
<MudIcon Icon="@Icons.Material.Filled.Update" Size="Size.Large" Class="mr-3"/> <MudIcon Icon="@Icons.Material.Filled.Update" Size="Size.Large" Class="mr-3"/>
@this.HeaderText @this.HeaderText
</MudText> </MudText>
<MudMarkdown Value="@this.UpdateResponse.Changelog" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/> <MudMarkdown Value="@this.UpdateResponse.Changelog" Props="Markdown.DefaultConfig"/>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled"> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
@@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Components.Routing;
using DialogOptions = AIStudio.Dialogs.DialogOptions; using DialogOptions = AIStudio.Dialogs.DialogOptions;
using EnterpriseEnvironment = AIStudio.Tools.EnterpriseEnvironment;
namespace AIStudio.Layout; namespace AIStudio.Layout;
@@ -91,7 +92,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
[ [
Event.UPDATE_AVAILABLE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED, Event.SHOW_ERROR, Event.UPDATE_AVAILABLE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED, Event.SHOW_ERROR,
Event.SHOW_ERROR, Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.STARTUP_PLUGIN_SYSTEM, Event.SHOW_ERROR, Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.STARTUP_PLUGIN_SYSTEM,
Event.PLUGINS_RELOADED Event.PLUGINS_RELOADED, Event.INSTALL_UPDATE,
]); ]);
// Set the snackbar for the update service: // Set the snackbar for the update service:
@@ -108,7 +109,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
// Send a message to start the plugin system: // Send a message to start the plugin system:
await this.MessageBus.SendMessage<bool>(this, Event.STARTUP_PLUGIN_SYSTEM); await this.MessageBus.SendMessage<bool>(this, Event.STARTUP_PLUGIN_SYSTEM);
await this.themeProvider.WatchSystemPreference(this.SystemeThemeChanged); await this.themeProvider.WatchSystemDarkModeAsync(this.SystemeThemeChanged);
await this.UpdateThemeConfiguration(); await this.UpdateThemeConfiguration();
this.LoadNavItems(); this.LoadNavItems();
@@ -137,9 +138,16 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
public string ComponentName => nameof(MainLayout); public string ComponentName => nameof(MainLayout);
public async Task ProcessMessage<TMessage>(ComponentBase? sendingComponent, Event triggeredEvent, TMessage? data) public async Task ProcessMessage<TMessage>(ComponentBase? sendingComponent, Event triggeredEvent, TMessage? data)
{
await this.InvokeAsync(async () =>
{ {
switch (triggeredEvent) switch (triggeredEvent)
{ {
case Event.INSTALL_UPDATE:
this.performingUpdate = true;
this.StateHasChanged();
break;
case Event.UPDATE_AVAILABLE: case Event.UPDATE_AVAILABLE:
if (data is UpdateResponse updateResponse) if (data is UpdateResponse updateResponse)
{ {
@@ -204,8 +212,19 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
// Ensure that all internal plugins are present: // Ensure that all internal plugins are present:
await PluginFactory.EnsureInternalPlugins(); await PluginFactory.EnsureInternalPlugins();
// Load (but not start) all plugins, without waiting for them: //
// Check if there is an enterprise configuration plugin to download:
//
var enterpriseEnvironment = this.MessageBus.CheckDeferredMessages<EnterpriseEnvironment>(Event.STARTUP_ENTERPRISE_ENVIRONMENT).FirstOrDefault();
if (enterpriseEnvironment != default)
await PluginFactory.TryDownloadingConfigPluginAsync(enterpriseEnvironment.ConfigurationId, enterpriseEnvironment.ConfigurationServerUrl);
// Load (but not start) all plugins without waiting for them:
#if DEBUG
var pluginLoadingTimeout = new CancellationTokenSource();
#else
var pluginLoadingTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var pluginLoadingTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
#endif
await PluginFactory.LoadAll(pluginLoadingTimeout.Token); await PluginFactory.LoadAll(pluginLoadingTimeout.Token);
// Set up hot reloading for plugins: // Set up hot reloading for plugins:
@@ -222,6 +241,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
await this.InvokeAsync(this.StateHasChanged); await this.InvokeAsync(this.StateHasChanged);
break; break;
} }
});
} }
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data) public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
@@ -286,9 +306,9 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
{ {
if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES)) if (await MessageBus.INSTANCE.SendMessageUseFirstResult<bool, bool>(this, Event.HAS_CHAT_UNSAVED_CHANGES))
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<ConfirmDialog>
{ {
{ "Message", T("Are you sure you want to leave the chat page? All unsaved changes will be lost.") }, { x => x.Message, T("Are you sure you want to leave the chat page? All unsaved changes will be lost.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Leave Chat Page"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Leave Chat Page"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -313,7 +333,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
private async Task UpdateThemeConfiguration() private async Task UpdateThemeConfiguration()
{ {
if (this.SettingsManager.ConfigurationData.App.PreferredTheme is Themes.SYSTEM) if (this.SettingsManager.ConfigurationData.App.PreferredTheme is Themes.SYSTEM)
this.useDarkMode = await this.themeProvider.GetSystemPreference(); this.useDarkMode = await this.themeProvider.GetSystemDarkModeAsync();
else else
this.useDarkMode = this.SettingsManager.ConfigurationData.App.PreferredTheme == Themes.DARK; this.useDarkMode = this.SettingsManager.ConfigurationData.App.PreferredTheme == Themes.DARK;
@@ -47,12 +47,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.2.1" /> <PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.2.4" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" /> <PackageReference Include="HtmlAgilityPack" Version="1.12.2" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.5" /> <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.8" />
<PackageReference Include="MudBlazor" Version="8.6.0" /> <PackageReference Include="MudBlazor" Version="8.12.0" />
<PackageReference Include="MudBlazor.Markdown" Version="8.6.0" /> <PackageReference Include="MudBlazor.Markdown" Version="8.11.0" />
<PackageReference Include="ReverseMarkdown" Version="4.6.0" /> <PackageReference Include="ReverseMarkdown" Version="4.7.0" />
<PackageReference Include="LuaCSharp" Version="0.4.2" /> <PackageReference Include="LuaCSharp" Version="0.4.2" />
</ItemGroup> </ItemGroup>
+97 -7
View File
@@ -1,4 +1,5 @@
@attribute [Route(Routes.ABOUT)] @attribute [Route(Routes.ABOUT)]
@using AIStudio.Tools.Services
@inherits MSGComponentBase @inherits MSGComponentBase
<div class="inner-scrolling-context"> <div class="inner-scrolling-context">
@@ -14,16 +15,104 @@
</MudText> </MudText>
<MudList T="string" Class="mb-3"> <MudList T="string" Class="mb-3">
<MudListItem T="string" Icon="@Icons.Material.Outlined.Chat" Text="@VersionApp"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Chat" Text="@VersionApp"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Timer" Text="@BuildTime"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Timer" Text="@this.BuildTime"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@VersionDotnetSdk"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@this.VersionDotnetSdk"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@VersionDotnetRuntime"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@this.VersionDotnetRuntime"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@VersionRust"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@this.VersionRust"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.DocumentScanner" Text="@VersionPdfium"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.DocumentScanner" Text="@this.VersionPdfium"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Article" Text="@this.versionPandoc"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Article" Text="@this.versionPandoc"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Widgets" Text="@MudBlazorVersion"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Widgets" Text="@MudBlazorVersion"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Translate" Text="@this.OSLanguage"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Translate" Text="@this.OSLanguage"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Business" Text="@this.GetEnterpriseEnvironment()"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Business">
@switch (EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.IsActive)
{
case false when this.configPlug is null:
<MudText Typo="Typo.body1">
@T("This is a private AI Studio installation. It runs without an enterprise configuration.")
</MudText>
break;
case false:
<MudText Typo="Typo.body1">
@T("AI Studio runs with an enterprise configuration using a configuration plugin, without central configuration management.")
</MudText>
<MudCollapse Expanded="@this.showEnterpriseConfigDetails">
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Configuration plugin ID:") @this.configPlug!.Id</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the configuration plugin ID to the clipboard")" StringContent=@this.configPlug!.Id.ToString()/>
</div>
</MudText>
</MudCollapse>
break;
case true when this.configPlug is null:
<MudText Typo="Typo.body1">
@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.")
</MudText>
<MudCollapse Expanded="@this.showEnterpriseConfigDetails">
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Enterprise configuration ID:") @EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationId</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the config ID to the clipboard")" StringContent=@EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationId.ToString()/>
</div>
</MudText>
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Configuration server:") @EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationServerUrl</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the server URL to the clipboard")" StringContent=@EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationServerUrl/>
</div>
</MudText>
</MudCollapse>
break;
case true:
<MudText Typo="Typo.body1">
@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.")
</MudText>
<MudCollapse Expanded="@this.showEnterpriseConfigDetails">
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Enterprise configuration ID:") @EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationId</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the config ID to the clipboard")" StringContent=@EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationId.ToString()/>
</div>
</MudText>
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Configuration server:") @EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationServerUrl</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the server URL to the clipboard")" StringContent=@EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.ConfigurationServerUrl/>
</div>
</MudText>
<MudText Typo="Typo.body1" Class="mt-2 mb-2">
<div style="display: flex; align-items: center; gap: 8px;">
<MudIcon Icon="@Icons.Material.Filled.ArrowRightAlt"/>
<span>@T("Configuration plugin ID:") @this.configPlug!.Id</span>
<MudCopyClipboardButton TooltipMessage="@T("Copies the configuration plugin ID to the clipboard")" StringContent=@this.configPlug!.Id.ToString()/>
</div>
</MudText>
</MudCollapse>
break;
}
@if (this.HasEnterpriseConfigurationDetails)
{
<MudButton StartIcon="@(this.showEnterpriseConfigDetails ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)"
Size="Size.Small"
Variant="Variant.Text"
OnClick="@this.ToggleEnterpriseConfigDetails">
@(this.showEnterpriseConfigDetails ? T("Hide Details") : T("Show Details"))
</MudButton>
}
</MudListItem>
</MudList> </MudList>
<MudStack Row="true"> <MudStack Row="true">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Update" OnClick="() => this.CheckForUpdate()"> <MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Update" OnClick="() => this.CheckForUpdate()">
@@ -114,6 +203,7 @@
<ThirdPartyComponent Name="async-stream" Developer="Carl Lerche, Taiki Endo & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/tokio-rs/async-stream/blob/master/LICENSE" RepositoryUrl="https://github.com/tokio-rs/async-stream" UseCase="@T("This library is used to create asynchronous streams in Rust. It allows us to work with streams of data that can be produced asynchronously, making it easier to handle events or data that arrive over time. We use this, e.g., to stream arbitrary data from the file system to the embedding system.")"/> <ThirdPartyComponent Name="async-stream" Developer="Carl Lerche, Taiki Endo & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/tokio-rs/async-stream/blob/master/LICENSE" RepositoryUrl="https://github.com/tokio-rs/async-stream" UseCase="@T("This library is used to create asynchronous streams in Rust. It allows us to work with streams of data that can be produced asynchronously, making it easier to handle events or data that arrive over time. We use this, e.g., to stream arbitrary data from the file system to the embedding system.")"/>
<ThirdPartyComponent Name="flexi_logger" Developer="emabee & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/emabee/flexi_logger/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/emabee/flexi_logger" UseCase="@T("This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible.")"/> <ThirdPartyComponent Name="flexi_logger" Developer="emabee & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/emabee/flexi_logger/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/emabee/flexi_logger" UseCase="@T("This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible.")"/>
<ThirdPartyComponent Name="rand" Developer="Rust developers & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rust-random/rand/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/rust-random/rand" UseCase="@T("We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.")"/> <ThirdPartyComponent Name="rand" Developer="Rust developers & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rust-random/rand/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/rust-random/rand" UseCase="@T("We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.")"/>
<ThirdPartyComponent Name="pptx-to-md" Developer="Nils Kruthoff & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/nilskruthoff/pptx-parser/blob/master/LICENCE-MIT" RepositoryUrl="https://github.com/nilskruthoff/pptx-parser" UseCase="@T("We use this library to be able to read PowerPoint files. This allows us to insert content from slides into prompts and take PowerPoint files into account in RAG processes. We thank Nils Kruthoff for his work on this Rust crate.")"/>
<ThirdPartyComponent Name="base64" Developer="Marshall Pierce, Alice Maz & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/marshallpierce/rust-base64/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/marshallpierce/rust-base64" UseCase="@T("For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.")"/> <ThirdPartyComponent Name="base64" Developer="Marshall Pierce, Alice Maz & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/marshallpierce/rust-base64/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/marshallpierce/rust-base64" UseCase="@T("For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.")"/>
<ThirdPartyComponent Name="Rust Crypto" Developer="Artyom Pavlov, Tony Arcieri, Brian Warner, Arthur Gautier, Vlad Filippov, Friedel Ziegelmayer, Nicolas Stalder & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/RustCrypto/traits/blob/master/cipher/LICENSE-MIT" RepositoryUrl="https://github.com/RustCrypto" UseCase="@T("When transferring sensitive data between Rust runtime and .NET app, we encrypt the data. We use some libraries from the Rust Crypto project for this purpose: cipher, aes, cbc, pbkdf2, hmac, and sha2. We are thankful for the great work of the Rust Crypto project.")"/> <ThirdPartyComponent Name="Rust Crypto" Developer="Artyom Pavlov, Tony Arcieri, Brian Warner, Arthur Gautier, Vlad Filippov, Friedel Ziegelmayer, Nicolas Stalder & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/RustCrypto/traits/blob/master/cipher/LICENSE-MIT" RepositoryUrl="https://github.com/RustCrypto" UseCase="@T("When transferring sensitive data between Rust runtime and .NET app, we encrypt the data. We use some libraries from the Rust Crypto project for this purpose: cipher, aes, cbc, pbkdf2, hmac, and sha2. We are thankful for the great work of the Rust Crypto project.")"/>
<ThirdPartyComponent Name="rcgen" Developer="RustTLS developers, est31 & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rustls/rcgen/blob/main/LICENSE" RepositoryUrl="https://github.com/rustls/rcgen" UseCase="@T("For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.")"/> <ThirdPartyComponent Name="rcgen" Developer="RustTLS developers, est31 & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rustls/rcgen/blob/main/LICENSE" RepositoryUrl="https://github.com/rustls/rcgen" UseCase="@T("For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.")"/>
@@ -130,7 +220,7 @@
</MudGrid> </MudGrid>
</ExpansionPanel> </ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Verified" HeaderText="License: FSL-1.1-MIT"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.Verified" HeaderText="License: FSL-1.1-MIT">
<MudMarkdown Value="@LICENSE" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/> <MudMarkdown Value="@LICENSE" Props="Markdown.DefaultConfig"/>
</ExpansionPanel> </ExpansionPanel>
</MudExpansionPanels> </MudExpansionPanels>
</InnerScrolling> </InnerScrolling>
+53 -20
View File
@@ -58,15 +58,64 @@ public partial class About : MSGComponentBase
private GetLogPathsResponse logPaths; private GetLogPathsResponse logPaths;
private bool showEnterpriseConfigDetails;
private IPluginMetadata? configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
/// <summary>
/// Determines whether the enterprise configuration has details that can be shown/hidden.
/// Returns true if there are details available, false otherwise.
/// </summary>
private bool HasEnterpriseConfigurationDetails
{
get
{
return EnterpriseEnvironmentService.CURRENT_ENVIRONMENT.IsActive switch
{
// Case 1: No enterprise config and no plugin - no details available
false when this.configPlug is null => false,
// Case 2: Enterprise config with plugin but no central management - has details
false => true,
// Case 3: Enterprise config active but no plugin - has details
true when this.configPlug is null => true,
// Case 4: Enterprise config active with plugin - has details
true => true
};
}
}
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
await base.OnInitializedAsync();
this.osLanguage = await this.RustService.ReadUserLanguage(); this.osLanguage = await this.RustService.ReadUserLanguage();
this.logPaths = await this.RustService.GetLogPaths(); this.logPaths = await this.RustService.GetLogPaths();
await base.OnInitializedAsync(); // Determine the Pandoc version may take some time, so we start it here
await this.DeterminePandocVersion(); // without waiting for the result:
_ = this.DeterminePandocVersion();
}
#endregion
#region Overrides of MSGComponentBase
protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
switch (triggeredEvent)
{
case Event.PLUGINS_RELOADED:
this.configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
await this.InvokeAsync(this.StateHasChanged);
break;
}
await base.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
} }
#endregion #endregion
@@ -117,25 +166,9 @@ public partial class About : MSGComponentBase
await this.DeterminePandocVersion(); await this.DeterminePandocVersion();
} }
private string GetEnterpriseEnvironment() private void ToggleEnterpriseConfigDetails()
{ {
var configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION); this.showEnterpriseConfigDetails = !this.showEnterpriseConfigDetails;
var currentEnvironment = EnterpriseEnvironmentService.CURRENT_ENVIRONMENT;
switch (currentEnvironment)
{
case { IsActive: false } when configPlug is null:
return T("AI Studio runs without an enterprise configuration.");
case { IsActive: false }:
return string.Format(T("AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management."), configPlug.Id);
case { IsActive: true } when configPlug is null:
return string.Format(T("AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available."), currentEnvironment.ConfigurationId, currentEnvironment.ConfigurationServerUrl);
case { IsActive: true }:
return string.Format(T("AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active."), currentEnvironment.ConfigurationId, currentEnvironment.ConfigurationServerUrl);
}
} }
private async Task CopyStartupLogPath() private async Task CopyStartupLogPath()
+18 -3
View File
@@ -21,7 +21,7 @@ public partial class Chat : MSGComponentBase
private IDialogService DialogService { get; init; } = null!; private IDialogService DialogService { get; init; } = null!;
private ChatThread? chatThread; private ChatThread? chatThread;
private AIStudio.Settings.Provider providerSettings; private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
private bool workspaceOverlayVisible; private bool workspaceOverlayVisible;
private string currentWorkspaceName = string.Empty; private string currentWorkspaceName = string.Empty;
private Workspaces? workspaces; private Workspaces? workspaces;
@@ -100,6 +100,23 @@ public partial class Chat : MSGComponentBase
#region Overrides of MSGComponentBase #region Overrides of MSGComponentBase
protected override void DisposeResources()
{
try
{
this.splitterSaveTimer.Stop();
this.splitterSaveTimer.Dispose();
}
catch
{
// ignore
}
base.DisposeResources();
}
#endregion
protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default protected override Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{ {
switch (triggeredEvent) switch (triggeredEvent)
@@ -111,6 +128,4 @@ public partial class Chat : MSGComponentBase
return Task.CompletedTask; return Task.CompletedTask;
} }
#endregion
} }
+2 -2
View File
@@ -27,7 +27,7 @@
</ExpansionPanel> </ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.EventNote" HeaderText="@T("Last Changelog")"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.EventNote" HeaderText="@T("Last Changelog")">
<MudMarkdown Value="@this.LastChangeContent" OverrideHeaderTypo="@Markdown.OverrideHeaderTypo"/> <MudMarkdown Value="@this.LastChangeContent" Props="Markdown.DefaultConfig"/>
</ExpansionPanel> </ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Lightbulb" HeaderText="@T("Vision")"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.Lightbulb" HeaderText="@T("Vision")">
@@ -35,7 +35,7 @@
</ExpansionPanel> </ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.RocketLaunch" HeaderText="@T("Quick Start Guide")"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.RocketLaunch" HeaderText="@T("Quick Start Guide")">
<MudMarkdown OverrideHeaderTypo="@Markdown.OverrideHeaderTypo" Value="@QUICK_START_GUIDE"/> <MudMarkdown Props="Markdown.DefaultConfig" Value="@QUICK_START_GUIDE"/>
</ExpansionPanel> </ExpansionPanel>
</MudExpansionPanels> </MudExpansionPanels>
+7 -3
View File
@@ -19,17 +19,19 @@ public partial class Home : MSGComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
await this.ReadLastChangeAsync();
await base.OnInitializedAsync(); await base.OnInitializedAsync();
this.InitializeAdvantagesItems(); this.InitializeAdvantagesItems();
// Read the last change content asynchronously
// without blocking the UI thread:
_ = this.ReadLastChangeAsync();
} }
private void InitializeAdvantagesItems() private void InitializeAdvantagesItems()
{ {
this.itemsAdvantages = [ this.itemsAdvantages = [
new(this.T("Free of charge"), this.T("The app is free to use, both for personal and commercial purposes.")), new(this.T("Free of charge"), this.T("The app is free to use, both for personal and commercial purposes.")),
new(this.T("Independence"), this.T("You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT4o, o1, etc.), Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.")), new(this.T("Independence"), this.T("You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT5, o1, etc.), Perplexity, Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using vLLM, llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.")),
new(this.T("Assistants"), this.T("You just want to quickly translate a text? AI Studio has so-called assistants for such and other tasks. No prompting is necessary when working with these assistants.")), new(this.T("Assistants"), this.T("You just want to quickly translate a text? AI Studio has so-called assistants for such and other tasks. No prompting is necessary when working with these assistants.")),
new(this.T("Unrestricted usage"), this.T("Unlike services like ChatGPT, which impose limits after intensive use, MindWork AI Studio offers unlimited usage through the providers API.")), new(this.T("Unrestricted usage"), this.T("Unlike services like ChatGPT, which impose limits after intensive use, MindWork AI Studio offers unlimited usage through the providers API.")),
new(this.T("Cost-effective"), this.T("You only pay for what you use, which can be cheaper than monthly subscription services like ChatGPT Plus, especially if used infrequently. But beware, here be dragons: For extremely intensive usage, the API costs can be significantly higher. Unfortunately, providers currently do not offer a way to display current costs in the app. Therefore, check your account with the respective provider to see how your costs are developing. When available, use prepaid and set a cost limit.")), new(this.T("Cost-effective"), this.T("You only pay for what you use, which can be cheaper than monthly subscription services like ChatGPT Plus, especially if used infrequently. But beware, here be dragons: For extremely intensive usage, the API costs can be significantly higher. Unfortunately, providers currently do not offer a way to display current costs in the app. Therefore, check your account with the respective provider to see how your costs are developing. When available, use prepaid and set a cost limit.")),
@@ -61,6 +63,8 @@ public partial class Home : MSGComponentBase
var latest = Changelog.LOGS.MaxBy(n => n.Build); var latest = Changelog.LOGS.MaxBy(n => n.Build);
using var response = await this.HttpClient.GetAsync($"changelog/{latest.Filename}"); using var response = await this.HttpClient.GetAsync($"changelog/{latest.Filename}");
this.LastChangeContent = await response.Content.ReadAsStringAsync(); this.LastChangeContent = await response.Content.ReadAsStringAsync();
await this.InvokeAsync(this.StateHasChanged);
} }
private const string QUICK_START_GUIDE = private const string QUICK_START_GUIDE =
+21 -7
View File
@@ -2,7 +2,6 @@ using AIStudio.Chat;
using AIStudio.Components; using AIStudio.Components;
using AIStudio.Provider; using AIStudio.Provider;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
@@ -11,14 +10,11 @@ namespace AIStudio.Pages;
public partial class Writer : MSGComponentBase public partial class Writer : MSGComponentBase
{ {
[Inject]
private ILogger<Chat> Logger { get; init; } = null!;
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
private readonly Timer typeTimer = new(TimeSpan.FromMilliseconds(1_500)); private readonly Timer typeTimer = new(TimeSpan.FromMilliseconds(1_500));
private MudTextField<string> textField = null!; private MudTextField<string> textField = null!;
private AIStudio.Settings.Provider providerSettings; private AIStudio.Settings.Provider providerSettings = AIStudio.Settings.Provider.NONE;
private ChatThread? chatThread; private ChatThread? chatThread;
private bool isStreaming; private bool isStreaming;
private string userInput = string.Empty; private string userInput = string.Empty;
@@ -77,7 +73,6 @@ public partial class Writer : MSGComponentBase
WorkspaceId = Guid.Empty, WorkspaceId = Guid.Empty,
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = 798798,
SystemPrompt = """ SystemPrompt = """
You are an assistant who helps with writing documents. You receive a sample You are an assistant who helps with writing documents. You receive a sample
from a document as input. As output, you provide how the begun sentence could from a document as input. As output, you provide how the begun sentence could
@@ -122,7 +117,7 @@ public partial class Writer : MSGComponentBase
this.isStreaming = true; this.isStreaming = true;
this.StateHasChanged(); this.StateHasChanged();
this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, lastUserPrompt, this.chatThread); this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(), this.providerSettings.Model, lastUserPrompt, this.chatThread);
this.suggestion = aiText.Text; this.suggestion = aiText.Text;
this.isStreaming = false; this.isStreaming = false;
@@ -152,4 +147,23 @@ public partial class Writer : MSGComponentBase
this.suggestion = string.Join(' ', words.Skip(1)); this.suggestion = string.Join(' ', words.Skip(1));
this.StateHasChanged(); this.StateHasChanged();
} }
#region Overrides of MSGComponentBase
protected override void DisposeResources()
{
try
{
this.typeTimer.Stop();
this.typeTimer.Dispose();
}
catch
{
// ignore
}
base.DisposeResources();
}
#endregion
} }
@@ -62,6 +62,38 @@ CONFIG["LLM_PROVIDERS"][#CONFIG["LLM_PROVIDERS"]+1] = {
CONFIG["SETTINGS"] = {} CONFIG["SETTINGS"] = {}
-- Configure the update behavior: -- Configure the update check interval:
-- Allowed values are: NO_CHECK, ONCE_STARTUP, HOURLY, DAILY, WEEKLY -- Allowed values are: NO_CHECK, ONCE_STARTUP, HOURLY, DAILY, WEEKLY
-- CONFIG["SETTINGS"]["DataApp.UpdateBehavior"] = "NO_CHECK" -- CONFIG["SETTINGS"]["DataApp.UpdateInterval"] = "NO_CHECK"
-- Configure how updates are installed:
-- Allowed values are: MANUAL, AUTOMATIC
-- CONFIG["SETTINGS"]["DataApp.UpdateInstallation"] = "MANUAL"
-- Configure the user permission to add providers:
-- Allowed values are: true, false
-- CONFIG["SETTINGS"]["DataApp.AllowUserToAddProvider"] = false
-- Example chat templates for this configuration:
CONFIG["CHAT_TEMPLATES"] = {}
-- A simple example chat template:
CONFIG["CHAT_TEMPLATES"][#CONFIG["CHAT_TEMPLATES"]+1] = {
["Id"] = "00000000-0000-0000-0000-000000000000",
["Name"] = "<user-friendly name of the chat template>",
["SystemPrompt"] = "You are <Company Name>'s helpful AI assistant for <Department Name>. Your task is ...",
["PredefinedUserPrompt"] = "Please help me with ...",
["AllowProfileUsage"] = true,
["ExampleConversation"] = {
{
-- Allowed values are: USER, AI, SYSTEM
["Role"] = "USER",
["Content"] = "Hello! Can you help me with a quick task?"
},
{
-- Allowed values are: USER, AI, SYSTEM
["Role"] = "AI",
["Content"] = "Of course. What do you need?"
}
}
}
@@ -1129,7 +1129,7 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3032662264"] = "Benutzerdefinierte Sprache" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3032662264"] = "Benutzerdefinierte Sprache"
-- Your input to improve -- Your input to improve
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Vorschlag zur Verbesserung" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Text, der verbessert werden soll"
-- Writing style -- Writing style
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3754048862"] = "Schreibstil" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3754048862"] = "Schreibstil"
@@ -1224,12 +1224,18 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::
-- Target language -- Target language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T237828418"] = "Zielsprache" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T237828418"] = "Zielsprache"
-- (Optional) Important Aspects
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T24391765"] = "(Optional) Wichtige Aspekte"
-- Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand. -- Summarize long text into a shorter version while retaining the main points. You might want to change the language of the summary to make it more readable. It is also possible to change the complexity of the summary to make it easy to understand.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T359929871"] = "Fasse einen langen Text zu einer kürzeren Version zusammen und behalte dabei die wichtigsten Punkte bei. Sie können die Sprache des Textes anpassen, um die Zusammenfassung verständlicher zu machen. Außerdem ist es möglich, die Zusammenfassung einfacher zu formulieren, damit sie leichter zu verstehen ist." UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T359929871"] = "Fasse einen langen Text zu einer kürzeren Version zusammen und behalte dabei die wichtigsten Punkte bei. Sie können die Sprache des Textes anpassen, um die Zusammenfassung verständlicher zu machen. Außerdem ist es möglich, die Zusammenfassung einfacher zu formulieren, damit sie leichter zu verstehen ist."
-- Please provide your field of expertise. -- Please provide your field of expertise.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3610378685"] = "Bitte geben Sie Ihr Fachgebiet an." UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3610378685"] = "Bitte geben Sie Ihr Fachgebiet an."
-- (Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3830285347"] = "(Optional) Spezifizieren Sie Aspekte, auf die das LLM bei der Erstellung einer Zusammenfassung den Fokus legen soll, wie z.B. die Länge der Zusammenfassung oder bestimmte Themen, die hervorgehoben werden sollen."
-- Custom target language -- Custom target language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3848935911"] = "Benutzerdefinierte Zielsprache" UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::TEXTSUMMARIZER::ASSISTANTTEXTSUMMARIZER::T3848935911"] = "Benutzerdefinierte Zielsprache"
@@ -1317,9 +1323,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CHATROLEEXTENSIONS::T601166687"] = "KI"
-- Edit Message -- Edit Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Nachricht bearbeiten" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Nachricht bearbeiten"
-- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T12948066"] = "Kopiert den Inhalt in die Zwischenablage"
-- Do you really want to remove this message? -- Do you really want to remove this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Möchten Sie diese Nachricht wirklich löschen?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Möchten Sie diese Nachricht wirklich löschen?"
@@ -1332,6 +1335,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1603883875"] = "Ja, neu
-- Yes, remove it -- Yes, remove it
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Ja, entferne es" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1820166585"] = "Ja, entferne es"
-- Number of sources
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1848978959"] = "Anzahl der Quellen"
-- Do you really want to edit this message? In order to edit this message, the AI response will be deleted. -- Do you really want to edit this message? In order to edit this message, the AI response will be deleted.
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Möchten Sie diese Nachricht wirklich bearbeiten? Um die Nachricht zu bearbeiten, wird die Antwort der KI gelöscht." UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2018431076"] = "Möchten Sie diese Nachricht wirklich bearbeiten? Um die Nachricht zu bearbeiten, wird die Antwort der KI gelöscht."
@@ -1353,9 +1359,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3587744975"] = "Neu gen
-- Do you really want to regenerate this message? -- Do you really want to regenerate this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Möchten Sie diese Nachricht wirklich neu generieren?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Möchten Sie diese Nachricht wirklich neu generieren?"
-- Cannot copy this content type to clipboard!
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4021525742"] = "Dieser Inhaltstyp kann nicht in die Zwischenablage kopiert werden!"
-- Remove Message -- Remove Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Nachricht entfernen" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Nachricht entfernen"
@@ -1416,6 +1419,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T636393754"] = "Verschiebe
-- Show your workspaces -- Show your workspaces
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T733672375"] = "Ihre Arbeitsbereiche anzeigen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T733672375"] = "Ihre Arbeitsbereiche anzeigen"
-- Create template from current chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1112722156"] = "Vorlage aus aktuellem Chat erstellen"
-- Start a new chat with a chat template -- Start a new chat with a chat template
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1333844707"] = "Neuen Chat mit einer Chat-Vorlage starten" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATTEMPLATESELECTION::T1333844707"] = "Neuen Chat mit einer Chat-Vorlage starten"
@@ -1449,6 +1455,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T3243388657"] = "Vertraue
-- Shows and hides the confidence card with information about the selected LLM provider. -- Shows and hides the confidence card with information about the selected LLM provider.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T847071819"] = "Zeigt oder verbirgt die Vertrauenskarte mit Informationen über den ausgewählten LLM-Anbieter." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIDENCEINFO::T847071819"] = "Zeigt oder verbirgt die Vertrauenskarte mit Informationen über den ausgewählten LLM-Anbieter."
-- This feature is managed by your organization and has therefore been disabled.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONBASE::T1416426626"] = "Diese Funktion wird von Ihrer Organisation verwaltet und wurde daher deaktiviert."
-- Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level. -- Choose the minimum confidence level that all LLM providers must meet. This way, you can ensure that only trustworthy providers are used. You cannot use any provider that falls below this level.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T2526727283"] = "Wählen Sie das minimale Vertrauensniveau, das alle LLM-Anbieter erfüllen müssen. So stellen Sie sicher, dass nur vertrauenswürdige Anbieter verwendet werden. Anbieter, die dieses Niveau unterschreiten, können nicht verwendet werden." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONMINCONFIDENCESELECTION::T2526727283"] = "Wählen Sie das minimale Vertrauensniveau, das alle LLM-Anbieter erfüllen müssen. So stellen Sie sicher, dass nur vertrauenswürdige Anbieter verwendet werden. Anbieter, die dieses Niveau unterschreiten, können nicht verwendet werden."
@@ -1474,7 +1483,7 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T20906218
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "App-Standard verwenden" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "App-Standard verwenden"
-- Yes, let the AI decide which data sources are needed. -- Yes, let the AI decide which data sources are needed.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T1031370894"] = "Ja, lassen Sie die KI entscheiden, welche Datenquellen benötigt werden." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T1031370894"] = "Ja, die KI soll entscheiden, welche Datenquellen benötigt werden."
-- Yes, let the AI validate & filter the retrieved data. -- Yes, let the AI validate & filter the retrieved data.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T1309929755"] = "Ja, die KI soll die abgerufenen Daten überprüfen und filtern." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::DATASOURCESELECTION::T1309929755"] = "Ja, die KI soll die abgerufenen Daten überprüfen und filtern."
@@ -1587,6 +1596,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T372007989"] = "Sich auf Webd
-- Cross-Platform and Modern Development -- Cross-Platform and Modern Development
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T843057510"] = "Plattformübergreifende und moderne Entwicklung" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T843057510"] = "Plattformübergreifende und moderne Entwicklung"
-- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T12948066"] = "Kopiert den Inhalt in die Zwischenablage"
-- Cannot copy this content type to clipboard.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T3937637647"] = "Dieser Inhaltstyp kann nicht in die Zwischenablage kopiert werden."
-- Alpha phase means that we are working on the last details before the beta phase. -- Alpha phase means that we are working on the last details before the beta phase.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha-Phase bedeutet, dass wir an den letzten Details arbeiten, bevor die Beta-Phase beginnt." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha-Phase bedeutet, dass wir an den letzten Details arbeiten, bevor die Beta-Phase beginnt."
@@ -1650,11 +1665,17 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROFILESELECTION::T918741365"] = "Hier k
-- Provider -- Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Anbieter" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PROVIDERSELECTION::T900237532"] = "Anbieter"
-- Use PDF content as input -- Images are not supported yet
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READPDFCONTENT::T2849276709"] = "PDF-Inhalt als Eingabe verwenden" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T298062956"] = "Bilder werden derzeit nicht unterstützt"
-- Select PDF file -- Use file content as input
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READPDFCONTENT::T63272795"] = "PDF-Datei auswählen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T3499386973"] = "Dokumenteninhalt als Eingabe verwenden"
-- Select file to read its content
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T354817589"] = "Datei auswählen, um den Inhalt zu lesen"
-- Executables are not allowed
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READFILECONTENT::T4167762413"] = "Ausführbare Dateien sind nicht erlaubt"
-- The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used. -- The content is cleaned using an LLM agent: the main content is extracted, advertisements and other irrelevant things are attempted to be removed; relative links are attempted to be converted into absolute links so that they can be used.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T1164201762"] = "Der Inhalt wird mithilfe eines LLM-Agents bereinigt: Der Hauptinhalt wird extrahiert, Werbung und andere irrelevante Elemente werden nach Möglichkeit entfernt. Relative Links werden nach Möglichkeit in absolute Links umgewandelt, damit sie verwendet werden können." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T1164201762"] = "Der Inhalt wird mithilfe eines LLM-Agents bereinigt: Der Hauptinhalt wird extrahiert, Werbung und andere irrelevante Elemente werden nach Möglichkeit entfernt. Relative Links werden nach Möglichkeit in absolute Links umgewandelt, damit sie verwendet werden können."
@@ -1681,7 +1702,7 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T2927391091"] = "Inhalte
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T2939928117"] = "Inhalte mit einem LLM-Agenten bereinigen?" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T2939928117"] = "Inhalte mit einem LLM-Agenten bereinigen?"
-- Hide web content options -- Hide web content options
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3031774728"] = "Web-Inhaltsoptionen ausblenden" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3031774728"] = "Optionen für Webinhalte ausblenden"
-- Please provide a valid HTTP or HTTPS URL. -- Please provide a valid HTTP or HTTPS URL.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T307442288"] = "Bitte geben Sie eine gültige HTTP- oder HTTPS-URL ein." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T307442288"] = "Bitte geben Sie eine gültige HTTP- oder HTTPS-URL ein."
@@ -1693,7 +1714,25 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3588401674"] = "Keine In
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3825586228"] = "Bitte geben Sie eine gültige URL ein." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T3825586228"] = "Bitte geben Sie eine gültige URL ein."
-- Show web content options -- Show web content options
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T4249712357"] = "Web-Inhalte anzeigen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENT::T4249712357"] = "Optionen für Webinhalte anzeigen"
-- Loading
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T1404011351"] = "Laden"
-- Start
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T182978943"] = "Start"
-- Done
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T2379421585"] = "Fertig"
-- Parsing
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T3151033983"] = "Zerlegen"
-- Cleaning
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T3420573362"] = "Bereinigen"
-- n/a
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::READWEBCONTENTSTEPSEXTENSIONS::T907272257"] = "n/a"
-- Hide content -- Hide content
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SECRETINPUTFIELD::T1273315904"] = "Inhalt ausblenden" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SECRETINPUTFIELD::T1273315904"] = "Inhalt ausblenden"
@@ -1713,6 +1752,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANE
-- Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used. -- Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, and attempts to convert relative links into absolute links so that they can be used.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T1299550589"] = "Anwendungsfall: Dieser Agent wird verwendet, um Textinhalte zu bereinigen. Er extrahiert den Hauptinhalt, entfernt Werbung und andere irrelevante Elemente und versucht, relative Links in absolute Links umzuwandeln, damit diese verwendet werden können." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T1299550589"] = "Anwendungsfall: Dieser Agent wird verwendet, um Textinhalte zu bereinigen. Er extrahiert den Hauptinhalt, entfernt Werbung und andere irrelevante Elemente und versucht, relative Links in absolute Links umzuwandeln, damit diese verwendet werden können."
-- Agent: Text Content Cleaner
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T3517268866"] = "Agent: Inhaltsbereinigung"
-- No options are preselected -- No options are preselected
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T354528094"] = "Keine Optionen sind vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTCONTENTCLEANER::T354528094"] = "Keine Optionen sind vorausgewählt"
@@ -1728,8 +1770,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESEL
-- Use Case: this agent is used to select the appropriate data sources for the current prompt. -- Use Case: this agent is used to select the appropriate data sources for the current prompt.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T2208143316"] = "Anwendungsfall: Dieser Assistent wird verwendet, um die passenden Datenquellen für die aktuelle Eingabe auszuwählen." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T2208143316"] = "Anwendungsfall: Dieser Assistent wird verwendet, um die passenden Datenquellen für die aktuelle Eingabe auszuwählen."
-- Agent: Data Source Selection Options -- Agent: Data Source Selection
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T2258031949"] = "Agent: Auswahlmöglichkeiten für Datenquellen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T2258031949"] = "Agent: Wahl der Datenquellen"
-- No options are preselected -- No options are preselected
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T354528094"] = "Keine Optionen sind vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTDATASOURCESELECTION::T354528094"] = "Keine Optionen sind vorausgewählt"
@@ -1773,11 +1815,11 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONT
-- Options are preselected -- Options are preselected
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T3875604319"] = "Optionen sind vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T3875604319"] = "Optionen sind vorausgewählt"
-- Agent: Retrieval Context Validation Options -- Agent: Retrieval Context Validation
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T928989804"] = "Agent: Optionen zur Überprüfung des Abruf-Kontexts" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T928989804"] = "Agent: Validierung der Abruf-Kontexte"
-- No validation is performed -- No validation is performed
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T95175095"] = "Es findet keine Überprüfung statt" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAGENTRETRIEVALCONTEXTVALIDATION::T95175095"] = "Es findet keine Validierung statt"
-- Spellchecking is disabled -- Spellchecking is disabled
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1059411425"] = "Rechtschreibprüfung ist deaktiviert" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1059411425"] = "Rechtschreibprüfung ist deaktiviert"
@@ -1815,6 +1857,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T1907446663"]
-- Language behavior -- Language behavior
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Sprachverhalten" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2341504363"] = "Sprachverhalten"
-- Update installation method
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T237706157"] = "Installationsmethode für Updates"
-- Language -- Language
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Sprache" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T2591284123"] = "Sprache"
@@ -1845,6 +1890,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T602293588"]
-- Choose the color theme that best suits for you. -- Choose the color theme that best suits for you.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Wählen Sie das Farbschema, das am besten zu Ihnen passt." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T654667432"] = "Wählen Sie das Farbschema, das am besten zu Ihnen passt."
-- Should updates be installed automatically or manually?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T707880477"] = "Sollen Updates automatisch oder manuell installiert werden?"
-- Energy saving is enabled -- Energy saving is enabled
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energiesparmodus ist aktiviert" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELAPP::T71162186"] = "Energiesparmodus ist aktiviert"
@@ -2100,6 +2148,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1016188706"] = "Möchten Sie
-- Move chat -- Move chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Chat verschieben" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1133040906"] = "Chat verschieben"
-- Unnamed workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1307384014"] = "Unbenannter Arbeitsbereich"
-- Delete -- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Löschen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T1469573738"] = "Löschen"
@@ -2133,6 +2184,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Möchten Sie
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen"
-- Please enter a chat name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Bitte geben Sie einen Namen für diesen Chat ein."
-- Workspace Name
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2446263209"] = "Name des Arbeitsbereichs"
-- Move to workspace -- Move to workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben"
@@ -2145,6 +2202,12 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Chat in den
-- Please enter a new or edit the name for your workspace '{0}': -- Please enter a new or edit the name for your workspace '{0}':
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:"
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Bitte geben Sie einen Namen für diesen Arbeitsbereich ein."
-- Unnamed chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unbenannter Chat"
-- Rename -- Rename
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Umbenennen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3355849203"] = "Umbenennen"
@@ -2157,6 +2220,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3555709365"] = "Chat laden"
-- Add Workspace -- Add Workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Arbeitsbereich hinzufügen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3672981145"] = "Arbeitsbereich hinzufügen"
-- Chat Name
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3891063690"] = "Name des Chat"
-- Empty chat -- Empty chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Leerer Chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T4019509364"] = "Leerer Chat"
@@ -2190,18 +2256,30 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T1847791252"] = "Aktuali
-- The chat template name must not exceed 40 characters. -- The chat template name must not exceed 40 characters.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T204496403"] = "Der Name der Chat-Vorlage darf maximal 40 Zeichen lang sein." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T204496403"] = "Der Name der Chat-Vorlage darf maximal 40 Zeichen lang sein."
-- Profile Usage
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2147062613"] = "Profilnutzung"
-- 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. -- 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.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2292424657"] = "Fügen Sie Nachrichten einer Beispiel-Konversation hinzu (Nutzereingabe, gefolgt von einer Antwort des Assistenten), um das gewünschte Interaktionsmuster zu demonstrieren. Diese Beispiele helfen der KI, ihre Erwartungen zu verstehen, indem Sie das korrekte Format, den Stil und den Inhalt von Antworten zeigen, bevor tatsächliche Nutzereingaben erfolgen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2292424657"] = "Fügen Sie Nachrichten einer Beispiel-Konversation hinzu (Nutzereingabe, gefolgt von einer Antwort des Assistenten), um das gewünschte Interaktionsmuster zu demonstrieren. Diese Beispiele helfen der KI, ihre Erwartungen zu verstehen, indem Sie das korrekte Format, den Stil und den Inhalt von Antworten zeigen, bevor tatsächliche Nutzereingaben erfolgen."
-- Role -- Role
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2418769465"] = "Rolle" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2418769465"] = "Rolle"
-- What predefined user input do you want to use?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2501284417"] = "Welche vordefinierte Benutzereingabe möchten Sie verwenden?"
-- Tell the AI your system prompt. -- Tell the AI your system prompt.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2552381261"] = "Teilen Sie der KI einen System-Prompt mit." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2552381261"] = "Teilen Sie der KI einen System-Prompt mit."
-- No, prohibit profile use for this template -- No, prohibit profile use for this template
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579080722"] = "Nein, die Profilnutzung für diese Vorlage verbieten" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579080722"] = "Nein, die Profilnutzung für diese Vorlage verbieten"
-- You might want to predefine a first message that will be copied into the user prompt, when you use this chat template. This message could for example be a blueprint for a structured message that this chat template is defined to work with.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2579208700"] = "Sie können eine Nachricht vordefinieren, die als Benutzereingabe verwendet wird, wenn Sie diese Chat-Vorlage verwenden. Diese Nachricht könnte beispielsweise eine Vorlage für eine strukturierte Nachricht sein, für die diese Chat-Vorlage entwickelt wurde."
-- Predefined User Input
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2607897066"] = "Vordefinierte Benutzereingabe"
-- Entry -- Entry
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2629823795"] = "Eintrag" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T2629823795"] = "Eintrag"
@@ -2256,6 +2334,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T3893704289"] = "Nachric
-- Use the default system prompt -- Use the default system prompt
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4051106111"] = "Verwenden Sie den Standard-System-Prompt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4051106111"] = "Verwenden Sie den Standard-System-Prompt"
-- Tell the AI your predefined user input.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4052406705"] = "Teilen Sie der KI ihre vordefinierte Benutzereingabe mit."
-- 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. -- 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.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4199560726"] = "Erstellen Sie ihre eigene Chat-Vorlage, um das Verhalten des LLMs für bestimmte Aufgaben oder Bereiche anzupassen. Definieren Sie einen individuellen System-Prompt und geben Sie eine Beispiel-Konversation vor, um eine KI-Erfahrung zu gestalten, die genau auf ihre Anforderungen zugeschnitten ist." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CHATTEMPLATEDIALOG::T4199560726"] = "Erstellen Sie ihre eigene Chat-Vorlage, um das Verhalten des LLMs für bestimmte Aufgaben oder Bereiche anzupassen. Definieren Sie einen individuellen System-Prompt und geben Sie eine Beispiel-Konversation vor, um eine KI-Erfahrung zu gestalten, die genau auf ihre Anforderungen zugeschnitten ist."
@@ -3387,6 +3468,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T32678
-- Close -- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3448155331"] = "Schließen" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3448155331"] = "Schließen"
-- This template is managed by your organization.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3576775249"] = "Diesee Vorlage wird von Ihrer Organisation verwaltet."
-- Edit Chat Template -- Edit Chat Template
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3596030597"] = "Chat-Vorlage bearbeiten" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGCHATTEMPLATE::T3596030597"] = "Chat-Vorlage bearbeiten"
@@ -3691,7 +3775,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1591931
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1633101895"] = "Wenn diese Option aktiviert ist, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1633101895"] = "Wenn diese Option aktiviert ist, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen."
-- Web content reader is not preselected -- Web content reader is not preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1701127912"] = "Tool zum Lesen von Webinhalten ist nicht vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1701127912"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist nicht vorausgewählt"
-- Content cleaner agent is not preselected -- Content cleaner agent is not preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1969816694"] = "Agent zur Inhaltsbereinigung ist nicht vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T1969816694"] = "Agent zur Inhaltsbereinigung ist nicht vorausgewählt"
@@ -3712,13 +3796,13 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T2529161
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T2746583995"] = "Wenn aktiviert, ist der Content Cleaner Agent vorausgewählt. Das kann nützlich sein, wenn Sie den rechtlichen Inhalt bereinigen möchten, bevor Sie ihn übersetzen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T2746583995"] = "Wenn aktiviert, ist der Content Cleaner Agent vorausgewählt. Das kann nützlich sein, wenn Sie den rechtlichen Inhalt bereinigen möchten, bevor Sie ihn übersetzen."
-- Web content reader is hidden -- Web content reader is hidden
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T2799795311"] = "Tool zum Lesen von Webinhalten ist ausgeblendet" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T2799795311"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist ausgeblendet"
-- Close -- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3448155331"] = "Schließen" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3448155331"] = "Schließen"
-- Web content reader is preselected -- Web content reader is preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3641773985"] = "Tool zum Lesen von Webinhalten ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3641773985"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist vorausgewählt"
-- Preselect the content cleaner agent? -- Preselect the content cleaner agent?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3649428096"] = "Assistent zur Inhaltsbereinigungs vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T3649428096"] = "Assistent zur Inhaltsbereinigungs vorauswählen?"
@@ -3730,7 +3814,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T4004501
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T4033382756"] = "Assistent: Optionen für rechtliche Prüfung" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T4033382756"] = "Assistent: Optionen für rechtliche Prüfung"
-- Preselect the web content reader? -- Preselect the web content reader?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T629158142"] = "Tool zum Lesen von Webinhalten vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGLEGALCHECK::T629158142"] = "Den Web-Content-Reader zum Lesen von Webinhalten vorauswählen?"
-- Would you like to preselect one of your profiles? -- Would you like to preselect one of your profiles?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGMYTASKS::T2221665527"] = "Möchten Sie eines ihrer Profile vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGMYTASKS::T2221665527"] = "Möchten Sie eines ihrer Profile vorauswählen?"
@@ -3874,7 +3958,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGSYNONYMS::T417092184
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1013787967"] = "Agent zur Inhaltsbereinigung ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1013787967"] = "Agent zur Inhaltsbereinigung ist vorausgewählt"
-- Web content reader is shown -- Web content reader is shown
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1030372436"] = "Tool zum Lesen von Webinhalten wird angezeigt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1030372436"] = "Der Web-Content-Reader zum Lesen von Webinhalten wird angezeigt"
-- Preselect the summarizer complexity -- Preselect the summarizer complexity
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T104409170"] = "Wähle die Sprachkomplexität der Zusammenfassungs aus" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T104409170"] = "Wähle die Sprachkomplexität der Zusammenfassungs aus"
@@ -3892,7 +3976,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T146
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1633101895"] = "Wenn aktiviert, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1633101895"] = "Wenn aktiviert, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen."
-- Web content reader is not preselected -- Web content reader is not preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1701127912"] = "Das Tool zum Lesen von Webinhalten ist nicht vorab selektiert" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1701127912"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist nicht vorab selektiert"
-- Assistant: Text Summarizer Options -- Assistant: Text Summarizer Options
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1767527569"] = "Assistent: Optionen zur Textzusammenfassung" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T1767527569"] = "Assistent: Optionen zur Textzusammenfassung"
@@ -3922,7 +4006,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T344
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3547337928"] = "Welche Zielsprache soll vorausgewählt werden?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3547337928"] = "Welche Zielsprache soll vorausgewählt werden?"
-- Web content reader is preselected -- Web content reader is preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3641773985"] = "Tool zum Lesen von Webinhalten ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3641773985"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist vorausgewählt"
-- Preselect the content cleaner agent? -- Preselect the content cleaner agent?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3649428096"] = "Den Agenten zur Inhaltsbereinigungs vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3649428096"] = "Den Agenten zur Inhaltsbereinigungs vorauswählen?"
@@ -3930,17 +4014,23 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T364
-- When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it. -- When enabled, the content cleaner agent is preselected. This is might be useful when you prefer to clean up the content before summarize it.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3660434400"] = "Wenn diese Option aktiviert ist, wird der Content Cleaner-Agent automatisch vorausgewählt. Das kann nützlich sein, wenn Sie den Inhalt bereinigen möchten, bevor Sie ihn zusammenfassen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3660434400"] = "Wenn diese Option aktiviert ist, wird der Content Cleaner-Agent automatisch vorausgewählt. Das kann nützlich sein, wenn Sie den Inhalt bereinigen möchten, bevor Sie ihn zusammenfassen."
-- Preselect important aspects
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3705987833"] = "Vorauswahl der Aspekte"
-- When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM. -- When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3820844575"] = "Wenn aktiviert, können Sie die Optionen für die Textzusammenfassung im Voraus auswählen. Das kann hilfreich sein, wenn Sie eine bestimmte Sprache, einen bestimmten Schwierigkeitsgrad oder ein bestimmtes LLM bevorzugen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T3820844575"] = "Wenn aktiviert, können Sie die Optionen für die Textzusammenfassung im Voraus auswählen. Das kann hilfreich sein, wenn Sie eine bestimmte Sprache, einen bestimmten Schwierigkeitsgrad oder ein bestimmtes LLM bevorzugen."
-- Which summarizer complexity should be preselected? -- Which summarizer complexity should be preselected?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T408530182"] = "Welche Komplexität der Zusammenfassung soll vorausgewählt werden?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T408530182"] = "Welche Komplexität der Zusammenfassung soll vorausgewählt werden?"
-- Preselect aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T414420518"] = "Vorausgewählte Aspekte, auf die sich das LLM beim Erstellen einer Zusammenfassung fokussieren soll, wie z.B. die Länge der Zusammenfassung oder bestimmte zu betonende Themen."
-- Preselect your expertise -- Preselect your expertise
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T51139714"] = "Wählen Sie Ihr Fachgebiet aus" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T51139714"] = "Wählen Sie Ihr Fachgebiet aus"
-- Preselect the web content reader? -- Preselect the web content reader?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T629158142"] = "Tool zum Lesen von Webinhalten vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTEXTSUMMARIZER::T629158142"] = "Den Web-Content-Reader zum Lesen von Webinhalten vorauswählen?"
-- Content cleaner agent is preselected -- Content cleaner agent is preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1013787967"] = "Agent zur Inhaltsbereinigung ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1013787967"] = "Agent zur Inhaltsbereinigung ist vorausgewählt"
@@ -3949,7 +4039,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T101378
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1016384269"] = "Assistent: Übersetzer-Optionen" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1016384269"] = "Assistent: Übersetzer-Optionen"
-- Web content reader is shown -- Web content reader is shown
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1030372436"] = "Tool zum Lesen von Webinhalten wird angezeigt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1030372436"] = "Der Web-Content-Reader zum Lesen von Webinhalten wird angezeigt"
-- When enabled, you can preselect the translator options. This is might be useful when you prefer a specific target language or LLM model. -- When enabled, you can preselect the translator options. This is might be useful when you prefer a specific target language or LLM model.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1111006275"] = "Wenn diese Option aktiviert ist, können Sie die Übersetzungsoptionen im Voraus auswählen. Das ist nützlich, wenn Sie eine bestimmte Zielsprache oder ein bestimmtes LLM-Modell bevorzugen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1111006275"] = "Wenn diese Option aktiviert ist, können Sie die Übersetzungsoptionen im Voraus auswählen. Das ist nützlich, wenn Sie eine bestimmte Zielsprache oder ein bestimmtes LLM-Modell bevorzugen."
@@ -3967,7 +4057,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T146229
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1633101895"] = "Wenn aktiviert, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1633101895"] = "Wenn aktiviert, wird der Web-Content-Reader ausgeblendet und kann nicht verwendet werden. Dadurch wird die Benutzeroberfläche etwas einfacher zu bedienen."
-- Web content reader is not preselected -- Web content reader is not preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1701127912"] = "Tool zum Lesen von Webinhalten ist nicht vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1701127912"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist nicht vorausgewählt"
-- Live translation is not preselected -- Live translation is not preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1825690873"] = "Live-Übersetzung ist nicht vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T1825690873"] = "Live-Übersetzung ist nicht vorausgewählt"
@@ -3988,7 +4078,7 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T223453
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2435743076"] = "Live-Übersetzung ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2435743076"] = "Live-Übersetzung ist vorausgewählt"
-- Web content reader is hidden -- Web content reader is hidden
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2799795311"] = "Tool zum Lesen von Webinhalten ist ausgeblendet" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2799795311"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist ausgeblendet"
-- No translator options are preselected -- No translator options are preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2866358796"] = "Keine Übersetzungseinstellungen sind vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T2866358796"] = "Keine Übersetzungseinstellungen sind vorausgewählt"
@@ -4003,13 +4093,13 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T344815
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3547337928"] = "Welche Zielsprache soll vorausgewählt werden?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3547337928"] = "Welche Zielsprache soll vorausgewählt werden?"
-- Web content reader is preselected -- Web content reader is preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3641773985"] = "Tool zum Lesen von Webinhalten ist vorausgewählt" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3641773985"] = "Der Web-Content-Reader zum Lesen von Webinhalten ist vorausgewählt"
-- Preselect the content cleaner agent? -- Preselect the content cleaner agent?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3649428096"] = "Agent zur Inhaltsbereinigung vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T3649428096"] = "Agent zur Inhaltsbereinigung vorauswählen?"
-- Preselect the web content reader? -- Preselect the web content reader?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T629158142"] = "Tool zum Lesen von Webinhalten vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T629158142"] = "Den Web-Content-Reader zum Lesen von Webinhalten vorauswählen?"
-- How fast should the live translation react? -- How fast should the live translation react?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T884246296"] = "Wie schnell soll die Live-Übersetzung reagieren?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGTRANSLATION::T884246296"] = "Wie schnell soll die Live-Übersetzung reagieren?"
@@ -4089,8 +4179,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T3832
-- Preselect one of your profiles? -- Preselect one of your profiles?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Eines ihrer Profile vorauswählen?" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004501229"] = "Eines ihrer Profile vorauswählen?"
-- Chat name -- Please enter a value.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat-Name" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Bitte geben Sie einen Wert ein."
-- Your Input
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T4030229154"] = "Ihre Eingabe"
-- Cancel -- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen"
@@ -4158,8 +4251,11 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1020427799"] = "Über MindWork AI Stud
-- Browse AI Studio's source code on GitHub — we welcome your contributions. -- Browse AI Studio's source code on GitHub — we welcome your contributions.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1107156991"] = "Sehen Sie sich den Quellcode von AI Studio auf GitHub an – wir freuen uns über ihre Beiträge." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1107156991"] = "Sehen Sie sich den Quellcode von AI Studio auf GitHub an – wir freuen uns über ihre Beiträge."
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available. -- This is a private AI Studio installation. It runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1297057566"] = "AI Studio läuft mit der Konfigurations-ID '{0}' ihrer Organisation und dem Konfigurationsserver '{1}'. Das Konfigurations-Plugin ist noch nicht verfügbar." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1209549230"] = "Dies ist eine private AI Studio-Installation. Sie läuft ohne Unternehmenskonfiguration."
-- AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1282228996"] = "AI Studio läuft mit einer Unternehmenskonfiguration und einem Konfigurationsserver. Das Konfigurations-Plugin ist noch nicht verfügbar."
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat. -- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "Diese Bibliothek wird verwendet, um PDF-Dateien zu lesen. Das ist zum Beispiel notwendig, um PDFs als Datenquelle für einen Chat zu nutzen." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "Diese Bibliothek wird verwendet, um PDF-Dateien zu lesen. Das ist zum Beispiel notwendig, um PDFs als Datenquelle für einen Chat zu nutzen."
@@ -4167,12 +4263,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "Diese Bibliothek wird
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library. -- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1421513382"] = "Diese Bibliothek wird verwendet, um die MudBlazor-Bibliothek zu erweitern. Sie stellt zusätzliche Komponenten bereit, die nicht Teil der MudBlazor-Bibliothek sind." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1421513382"] = "Diese Bibliothek wird verwendet, um die MudBlazor-Bibliothek zu erweitern. Sie stellt zusätzliche Komponenten bereit, die nicht Teil der MudBlazor-Bibliothek sind."
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1454889560"] = "AI Studio läuft mit der Konfigurations-ID '{0}' ihrer Organisation und dem Konfigurationsserver '{1}'. Das Konfigurations-Plugin ist aktiv."
-- AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1530477579"] = "AI Studio läuft mit einer Unternehmenseinstellung und verwendet das Konfigurations-Plugin '{0}', jedoch ohne zentrale Konfigurationsverwaltung."
-- We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library. -- We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T162898512"] = "Wir verwenden Lua als Sprache für Plugins. Lua-CSharp ermöglicht die Kommunikation zwischen Lua-Skripten und AI Studio in beide Richtungen. Vielen Dank an Yusuke Nakada für diese großartige Bibliothek." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T162898512"] = "Wir verwenden Lua als Sprache für Plugins. Lua-CSharp ermöglicht die Kommunikation zwischen Lua-Skripten und AI Studio in beide Richtungen. Vielen Dank an Yusuke Nakada für diese großartige Bibliothek."
@@ -4191,6 +4281,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1806897624"] = "Wenn Sie auf den jewei
-- Pandoc Installation -- Pandoc Installation
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T185447014"] = "Pandoc-Installation" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T185447014"] = "Pandoc-Installation"
-- Copies the configuration plugin ID to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1859295819"] = "Kopiert die Konfigurations-Plugin-ID in die Zwischenablage"
-- Check for updates -- Check for updates
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1890416390"] = "Nach Updates suchen" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1890416390"] = "Nach Updates suchen"
@@ -4206,21 +4299,30 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1924365263"] = "Diese Bibliothek wird
-- We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust. -- We use Rocket to implement the runtime API. This is necessary because the runtime must be able to communicate with the user interface (IPC). Rocket is a great framework for implementing web APIs in Rust.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1943216839"] = "Wir verwenden Rocket zur Implementierung der Runtime-API. Dies ist notwendig, da die Runtime mit der Benutzeroberfläche (IPC) kommunizieren muss. Rocket ist ein ausgezeichnetes Framework zur Umsetzung von Web-APIs in Rust." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1943216839"] = "Wir verwenden Rocket zur Implementierung der Runtime-API. Dies ist notwendig, da die Runtime mit der Benutzeroberfläche (IPC) kommunizieren muss. Rocket ist ein ausgezeichnetes Framework zur Umsetzung von Web-APIs in Rust."
-- Copies the server URL to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2037899437"] = "Kopiert die Server-URL in die Zwischenablage"
-- This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file. -- This library is used to determine the file type of a file. This is necessary, e.g., when we want to stream a file.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "Diese Bibliothek wird verwendet, um den Dateityp einer Datei zu bestimmen. Das ist zum Beispiel notwendig, wenn wir eine Datei streamen möchten." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "Diese Bibliothek wird verwendet, um den Dateityp einer Datei zu bestimmen. Das ist zum Beispiel notwendig, wenn wir eine Datei streamen möchten."
-- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose. -- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "Für die sichere Kommunikation zwischen der Benutzeroberfläche und der Laufzeit müssen wir Zertifikate erstellen. Diese Rust-Bibliothek eignet sich hervorragend dafür." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "Für die sichere Kommunikation zwischen der Benutzeroberfläche und der Laufzeit müssen wir Zertifikate erstellen. Diese Rust-Bibliothek eignet sich hervorragend dafür."
-- AI Studio runs without an enterprise configuration.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio läuft ohne eine Konfiguration ihrer Organisation."
-- OK -- OK
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
-- Configuration server:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2272122662"] = "Konfigurationsserver:"
-- We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose. -- We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2273492381"] = "Wir müssen Zufallszahlen erzeugen, z. B. um die Kommunikation zwischen der Benutzeroberfläche und der Laufzeitumgebung abzusichern. Die rand-Bibliothek eignet sich dafür hervorragend." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2273492381"] = "Wir müssen Zufallszahlen erzeugen, z. B. um die Kommunikation zwischen der Benutzeroberfläche und der Laufzeitumgebung abzusichern. Die rand-Bibliothek eignet sich dafür hervorragend."
-- AI Studio runs with an enterprise configuration using a configuration plugin, without central configuration management.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2280402765"] = "AI Studio läuft mit einer Unternehmenskonfiguration über ein Konfigurations-Plugin, ohne zentrale Konfigurationsverwaltung."
-- Configuration plugin ID:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2301484629"] = "Konfigurations-Plugin-ID:"
-- The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK. -- The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2329884315"] = "Die Programmiersprache C# wird für die Umsetzung der Benutzeroberfläche und des Backends verwendet. Für die Entwicklung der Benutzeroberfläche mit C# kommt die Blazor-Technologie aus ASP.NET Core zum Einsatz. Alle diese Technologien sind im .NET SDK integriert." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2329884315"] = "Die Programmiersprache C# wird für die Umsetzung der Benutzeroberfläche und des Backends verwendet. Für die Entwicklung der Benutzeroberfläche mit C# kommt die Blazor-Technologie aus ASP.NET Core zum Einsatz. Alle diese Technologien sind im .NET SDK integriert."
@@ -4260,6 +4362,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2765814390"] = "Pandoc-Version wird er
-- Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor. -- Code in the Rust language can be specified as synchronous or asynchronous. Unlike .NET and the C# language, Rust cannot execute asynchronous code by itself. Rust requires support in the form of an executor for this. Tokio is one such executor.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2777988282"] = "Code in der Programmiersprache Rust kann als synchron oder asynchron spezifiziert werden. Im Gegensatz zu .NET und der Sprache C# kann Rust asynchronen Code jedoch nicht von selbst ausführen. Dafür benötigt Rust Unterstützung in Form eines Executors. Tokio ist ein solcher Executor." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2777988282"] = "Code in der Programmiersprache Rust kann als synchron oder asynchron spezifiziert werden. Im Gegensatz zu .NET und der Sprache C# kann Rust asynchronen Code jedoch nicht von selbst ausführen. Dafür benötigt Rust Unterstützung in Form eines Executors. Tokio ist ein solcher Executor."
-- Show Details
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T27924674"] = "Details anzeigen"
-- View our project roadmap and help shape AI Studio's future development. -- View our project roadmap and help shape AI Studio's future development.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2829971158"] = "Sehen Sie sich unsere Roadmap an und helfen Sie mit, die zukünftige Entwicklung von AI Studio mitzugestalten." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2829971158"] = "Sehen Sie sich unsere Roadmap an und helfen Sie mit, die zukünftige Entwicklung von AI Studio mitzugestalten."
@@ -4275,12 +4380,18 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2868174483"] = "Das .NET-Backend kann
-- Changelog -- Changelog
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3017574265"] = "Änderungsprotokoll" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3017574265"] = "Änderungsprotokoll"
-- Enterprise configuration ID:
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3092349641"] = "Unternehmenskonfigurations-ID:"
-- Connect AI Studio to your organization's data with our External Retrieval Interface (ERI). -- Connect AI Studio to your organization's data with our External Retrieval Interface (ERI).
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T313276297"] = "Verbinden Sie AI Studio mit den Daten ihrer Organisation über unsere Schnittstelle für externe Datenabfrage (ERI)." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T313276297"] = "Verbinden Sie AI Studio mit den Daten ihrer Organisation über unsere Schnittstelle für externe Datenabfrage (ERI)."
-- Have feature ideas? Submit suggestions for future AI Studio enhancements. -- Have feature ideas? Submit suggestions for future AI Studio enhancements.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3178730036"] = "Haben Sie Ideen für neue Funktionen? Senden Sie uns Vorschläge für zukünftige Verbesserungen von AI Studio." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3178730036"] = "Haben Sie Ideen für neue Funktionen? Senden Sie uns Vorschläge für zukünftige Verbesserungen von AI Studio."
-- Hide Details
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3183837919"] = "Details ausblenden"
-- Update Pandoc -- Update Pandoc
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3249965383"] = "Pandoc aktualisieren" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3249965383"] = "Pandoc aktualisieren"
@@ -4305,6 +4416,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3563271893"] = "Motivation"
-- This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat. -- This library is used to read Excel and OpenDocument spreadsheet files. This is necessary, e.g., for using spreadsheets as a data source for a chat.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3722989559"] = "Diese Bibliothek wird verwendet, um Excel- und OpenDocument-Tabellendateien zu lesen. Dies ist zum Beispiel notwendig, wenn Tabellen als Datenquelle für einen Chat verwendet werden sollen." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3722989559"] = "Diese Bibliothek wird verwendet, um Excel- und OpenDocument-Tabellendateien zu lesen. Dies ist zum Beispiel notwendig, wenn Tabellen als Datenquelle für einen Chat verwendet werden sollen."
-- AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3741877842"] = "AI Studio läuft mit einer Unternehmenskonfiguration und einem Konfigurationsserver. Das Konfigurations-Plugin ist aktiv."
-- this version does not met the requirements -- this version does not met the requirements
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3813932670"] = "diese Version erfüllt die Anforderungen nicht" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3813932670"] = "diese Version erfüllt die Anforderungen nicht"
@@ -4347,9 +4461,15 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T639371534"] = "Haben Sie einen Fehler
-- This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible. -- This Rust library is used to output the app's messages to the terminal. This is helpful during development and troubleshooting. This feature is initially invisible; when the app is started via the terminal, the messages become visible.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T64689067"] = "Diese Rust-Bibliothek wird verwendet, um die Nachrichten der App im Terminal auszugeben. Das ist während der Entwicklung und Fehlersuche hilfreich. Diese Funktion ist zunächst unsichtbar; werden App über das Terminal gestartet, werden die Nachrichten sichtbar." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T64689067"] = "Diese Rust-Bibliothek wird verwendet, um die Nachrichten der App im Terminal auszugeben. Das ist während der Entwicklung und Fehlersuche hilfreich. Diese Funktion ist zunächst unsichtbar; werden App über das Terminal gestartet, werden die Nachrichten sichtbar."
-- Copies the config ID to the clipboard
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T788846912"] = "Kopiert die Konfigurations-ID in die Zwischenablage"
-- installed by AI Studio -- installed by AI Studio
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T833849470"] = "installiert von AI Studio" UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T833849470"] = "installiert von AI Studio"
-- We use this library to be able to read PowerPoint files. This allows us to insert content from slides into prompts and take PowerPoint files into account in RAG processes. We thank Nils Kruthoff for his work on this Rust crate.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T855925638"] = "Wir verwenden diese Bibliothek, um PowerPoint-Dateien lesen zu können. So ist es möglich, Inhalte aus Folien in Prompts einzufügen und PowerPoint-Dateien in RAG-Prozessen zu berücksichtigen. Wir danken Nils Kruthoff für seine Arbeit an diesem Rust-Crate."
-- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose. -- For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T870640199"] = "Für einige Datenübertragungen müssen wir die Daten in Base64 kodieren. Diese Rust-Bibliothek eignet sich dafür hervorragend." UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T870640199"] = "Für einige Datenübertragungen müssen wir die Daten in Base64 kodieren. Diese Rust-Bibliothek eignet sich dafür hervorragend."
@@ -4518,8 +4638,8 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1702902297"] = "Einführung"
-- Vision -- Vision
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1892426825"] = "Vision" UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T1892426825"] = "Vision"
-- You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT4o, o1, etc.), Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities. -- You are not tied to any single provider. Instead, you might choose the provider that best suits your needs. Right now, we support OpenAI (GPT5, o1, etc.), Perplexity, Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face, and self-hosted models using vLLM, llama.cpp, ollama, LM Studio, Groq, or Fireworks. For scientists and employees of research institutions, we also support Helmholtz and GWDG AI services. These are available through federated logins like eduGAIN to all 18 Helmholtz Centers, the Max Planck Society, most German, and many international universities.
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2217921237"] = "Sie sind nicht an einen einzelnen Anbieter gebunden. Stattdessen können Sie den Anbieter wählen, der am besten zu ihren Bedürfnissen passt. Aktuell unterstützen wir OpenAI (GPT4o, o1 usw.), Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face sowie selbst gehostete Modelle mit llama.cpp, ollama, LM Studio, Groq oder Fireworks. Für Wissenschaftler und Beschäftigte von Forschungseinrichtungen unterstützen wir außerdem die KI-Dienste von Helmholtz und GWDG. Diese sind über föderierte Logins wie eduGAIN für alle 18 Helmholtz-Zentren, die Max-Planck-Gesellschaft, die meisten deutschen sowie viele internationale Universitäten verfügbar." UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2183503084"] = "Sie sind an keinen einzelnen Anbieter gebunden. Stattdessen können Sie den Anbieter wählen, der am besten zu ihren Bedürfnissen passt. Derzeit unterstützen wir OpenAI (GPT5, o1, etc.), Perplexity, Mistral, Anthropic (Claude), Google Gemini, xAI (Grok), DeepSeek, Alibaba Cloud (Qwen), Hugging Face und selbst gehostete Modelle mit vLLM, llama.cpp, ollama, LM Studio, Groq oder Fireworks. Für Wissenschaftler und Mitarbeiter von Forschungseinrichtungen unterstützen wir auch die KI-Dienste von Helmholtz und GWDG. Diese sind über föderierte Anmeldungen wie eduGAIN für alle 18 Helmholtz-Zentren, die Max-Planck-Gesellschaft, die meisten deutschen und viele internationale Universitäten verfügbar."
-- Let's get started -- Let's get started
UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2331588413"] = "Los geht's" UI_TEXT_CONTENT["AISTUDIO::PAGES::HOME::T2331588413"] = "Los geht's"
@@ -4720,7 +4840,7 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3010553924"] = "Der Anbieter h
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3368531176"] = "Kein Anbieter ausgewählt. Bitte wählen Sie einen Anbieter aus, um dessen Vertrauensniveau zu sehen." UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3368531176"] = "Kein Anbieter ausgewählt. Bitte wählen Sie einen Anbieter aus, um dessen Vertrauensniveau zu sehen."
-- The provider operates its service from the USA and is subject to **US jurisdiction**. In case of suspicion, authorities in the USA can access your data. However, **your data is not used for training** purposes. -- The provider operates its service from the USA and is subject to **US jurisdiction**. In case of suspicion, authorities in the USA can access your data. However, **your data is not used for training** purposes.
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3528165925"] = "Der Anbieter betreibt seinen Dienst aus den USA und unterliegt der **US-amerikanischen Gerichtsbarkeit**. Bei Verdacht können US-Behörden auf ihre Daten zugreifen. **ihre Daten werden jedoch nicht für Trainingszwecke** verwendet." UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3528165925"] = "Der Anbieter betreibt seinen Dienst aus den USA und unterliegt der **US-amerikanischen Gerichtsbarkeit**. Bei Verdacht können US-Behörden auf ihre Daten zugreifen. **Ihre Daten werden jedoch nicht für Trainingszwecke** verwendet."
-- The provider operates its service from the USA and is subject to **U.S. jurisdiction**. In case of suspicion, authorities in the USA can access your data. Please inform yourself about the use of your data. We do not know if your data is safe. -- The provider operates its service from the USA and is subject to **U.S. jurisdiction**. In case of suspicion, authorities in the USA can access your data. Please inform yourself about the use of your data. We do not know if your data is safe.
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3788466789"] = "Der Anbieter betreibt seinen Service in den USA und unterliegt der **US-amerikanischen Gerichtsbarkeit**. Im Verdachtsfall können US-Behörden auf ihre Daten zugreifen. Bitte informieren Sie sich über die Verwendung ihrer Daten. Wir wissen nicht, ob ihre Daten sicher sind." UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCE::T3788466789"] = "Der Anbieter betreibt seinen Service in den USA und unterliegt der **US-amerikanischen Gerichtsbarkeit**. Im Verdachtsfall können US-Behörden auf ihre Daten zugreifen. Bitte informieren Sie sich über die Verwendung ihrer Daten. Wir wissen nicht, ob ihre Daten sicher sind."
@@ -4764,6 +4884,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T3424652889"] = "Un
-- no model selected -- no model selected
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "Kein Modell ausgewählt" UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "Kein Modell ausgewählt"
-- Sources
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::SOURCEEXTENSIONS::T2730980305"] = "Quellen"
-- Use no chat template -- Use no chat template
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CHATTEMPLATE::T4258819635"] = "Keine Chat-Vorlage verwenden" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CHATTEMPLATE::T4258819635"] = "Keine Chat-Vorlage verwenden"
@@ -4812,6 +4935,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2128088682
-- Navigation expands on mouse hover -- Navigation expands on mouse hover
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigationsleiste erweitert sich, wenn sich die Maus darüber befindet" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2195945406"] = "Navigationsleiste erweitert sich, wenn sich die Maus darüber befindet"
-- Install updates manually
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T220653235"] = "Updates manuell installieren"
-- Also show features ready for release; these should be stable -- Also show features ready for release; these should be stable
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Auch Funktionen anzeigen, die bereit für die Veröffentlichung sind; diese sollten stabil sein." UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T2301448762"] = "Auch Funktionen anzeigen, die bereit für die Veröffentlichung sind; diese sollten stabil sein."
@@ -4851,6 +4977,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3137986690
-- Disappearing chats: delete chats older than 180 days -- Disappearing chats: delete chats older than 180 days
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Selbstlöschende Chats: lösche Chats die älter als 180 Tage sind" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3491430707"] = "Selbstlöschende Chats: lösche Chats die älter als 180 Tage sind"
-- Install updates automatically
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3569059463"] = "Updates automatisch installieren"
-- Disable workspaces -- Disable workspaces
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Arbeitsbereiche deaktivieren" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T3612390107"] = "Arbeitsbereiche deaktivieren"
@@ -5014,7 +5143,7 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMMONLANGUAGEEXTENSIONS::T4187368718"] = "Rus
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMMONLANGUAGEEXTENSIONS::T658789330"] = "Sprache nicht ändern" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMMONLANGUAGEEXTENSIONS::T658789330"] = "Sprache nicht ändern"
-- Coding Assistant -- Coding Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1082499335"] = "Programmierassistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1082499335"] = "Programmier-Assistent"
-- E-Mail Assistant -- E-Mail Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1185802704"] = "E-Mail-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1185802704"] = "E-Mail-Assistent"
@@ -5023,25 +5152,25 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1185802704"] = "E-Mail-
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1546040625"] = "Meine Aufgaben-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1546040625"] = "Meine Aufgaben-Assistent"
-- Grammar & Spelling Assistant -- Grammar & Spelling Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T166453786"] = "Grammatik- & Rechtschreibassistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T166453786"] = "Grammatik- & Rechtschreib-Assistent"
-- Legal Check Assistant -- Legal Check Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1886447798"] = "Assistent für rechtliche Prüfungen" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1886447798"] = "Rechtlichen Prüfungs-Assistent"
-- Job Posting Assistant -- Job Posting Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2212811874"] = "Assistent für Stellenanzeigen" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2212811874"] = "Stellenanzeigen-Assistent"
-- Icon Finder Assistant -- Icon Finder Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2457005512"] = "Icon Finder-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2457005512"] = "Icon Finder-Assistent"
-- Text Summarizer Assistant -- Text Summarizer Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2684676843"] = "Assistent zur Textzusammenfassung" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2684676843"] = "Texte zusammenfassen-Assistent"
-- Synonym Assistant -- Synonym Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2921123194"] = "Synonym-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2921123194"] = "Synonym-Assistent"
-- Translation Assistant -- Translation Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T3887962308"] = "Übersetzungsassistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T3887962308"] = "Übersetzungs-Assistent"
-- Agenda Assistant -- Agenda Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4034795997"] = "Agenda-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4034795997"] = "Agenda-Assistent"
@@ -5050,7 +5179,7 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4034795997"] = "Agenda-
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4204533420"] = "ERI-Server" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4204533420"] = "ERI-Server"
-- Rewrite Assistant -- Rewrite Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4262148639"] = "Assistent zum Umformulieren & Verbessern" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T4262148639"] = "Umformulieren & Verbessern-Assistent"
-- Localization Assistant -- Localization Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T446674624"] = "Lokalisierungs-Assistent" UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T446674624"] = "Lokalisierungs-Assistent"
@@ -5385,9 +5514,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011
-- The CONFIG table does not exist or is not a valid table. -- The CONFIG table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "Die Tabelle CONFIG existiert nicht oder ist keine gültige Tabelle." UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "Die Tabelle CONFIG existiert nicht oder ist keine gültige Tabelle."
-- The LLM_PROVIDERS table does not exist or is not a valid table.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "Die Tabelle LLM_PROVIDERS existiert nicht oder ist keine gültige Tabelle."
-- The field IETF_TAG does not exist or is not a valid string. -- The field IETF_TAG does not exist or is not a valid string.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "Das Feld IETF_TAG existiert nicht oder ist keine gültige Zeichenkette." UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "Das Feld IETF_TAG existiert nicht oder ist keine gültige Zeichenkette."
@@ -5478,6 +5604,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T304
-- AI-based data source selection with AI retrieval context validation -- AI-based data source selection with AI retrieval context validation
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "KI-basierte Datenquellen-Auswahl mit Validierung des Abrufkontexts" UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "KI-basierte Datenquellen-Auswahl mit Validierung des Abrufkontexts"
-- Executable Files
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2217313358"] = "Ausführbare Dateien"
-- PDF Files -- PDF Files
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF-Dateien" UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF-Dateien"
@@ -5511,6 +5640,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::RUSTSERVICE::SECRETS::T4007657575"]
-- No update found. -- No update found.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden." UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T1015418291"] = "Kein Update gefunden."
-- Failed to install update automatically. Please try again manually.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::UPDATESERVICE::T3709709946"] = "Fehler bei der automatischen Installation des Updates. Bitte versuchen Sie es manuell erneut."
-- The hostname is not a valid HTTP(S) URL. -- The hostname is not a valid HTTP(S) URL.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "Der Hostname ist keine gültige HTTP(S)-URL." UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::DATASOURCEVALIDATION::T1013354736"] = "Der Hostname ist keine gültige HTTP(S)-URL."
@@ -5613,5 +5745,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T497939286"] =
-- Please select a model. -- Please select a model.
UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Bitte wählen Sie ein Modell aus." UI_TEXT_CONTENT["AISTUDIO::TOOLS::VALIDATION::PROVIDERVALIDATION::T818893091"] = "Bitte wählen Sie ein Modell aus."
-- Unnamed workspace
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T1307384014"] = "Unbenannter Arbeitsbereich"
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Chat löschen" UI_TEXT_CONTENT["AISTUDIO::TOOLS::WORKSPACEBEHAVIOUR::T2244038752"] = "Chat löschen"
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff. Show more