From abb1e3f52d147bf527d34e02a7a19fd82f972a52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peer=20Sch=C3=BCtt?=
<20603780+peerschuett@users.noreply.github.com>
Date: Mon, 10 Mar 2025 13:32:02 +0100
Subject: [PATCH] Merge
---
.../Assistants/AssistantBase.razor.cs | 2 +-
.../Assistants/ERI/AssistantERI.razor.cs | 1 +
app/MindWork AI Studio/Chat/ChatRole.cs | 1 -
app/MindWork AI Studio/Chat/ChatThread.cs | 37 ++++++--
.../Chat/ChatThreadExtensions.cs | 58 +++++++++++++
.../Chat/ContentBlockComponent.razor | 2 +-
app/MindWork AI Studio/Chat/ContentImage.cs | 2 +-
app/MindWork AI Studio/Chat/ContentText.cs | 24 ++++-
app/MindWork AI Studio/Chat/IContent.cs | 2 +-
.../Components/Changelog.Logs.cs | 1 +
.../Components/ChatComponent.razor | 12 ++-
.../Components/ChatComponent.razor.cs | 25 +++++-
.../Dialogs/DataSourceERI-V1InfoDialog.razor | 87 +++++++++----------
.../DataSourceERI-V1InfoDialog.razor.cs | 3 +-
.../Dialogs/DataSourceERI_V1Dialog.razor | 16 +++-
.../Dialogs/DataSourceERI_V1Dialog.razor.cs | 26 ++++++
.../MindWork AI Studio.csproj | 2 +-
app/MindWork AI Studio/Pages/Supporters.razor | 1 +
app/MindWork AI Studio/Pages/Writer.razor.cs | 2 +-
.../Provider/Anthropic/ProviderAnthropic.cs | 1 -
.../Provider/DeepSeek/ProviderDeepSeek.cs | 1 -
.../Provider/Fireworks/ProviderFireworks.cs | 1 -
.../Provider/GWDG/ProviderGWDG.cs | 1 -
.../Provider/Google/ProviderGoogle.cs | 1 -
.../Provider/Groq/ProviderGroq.cs | 1 -
.../Provider/Helmholtz/ProviderHelmholtz.cs | 1 -
.../Provider/Mistral/ProviderMistral.cs | 1 -
.../Provider/OpenAI/ProviderOpenAI.cs | 1 -
.../Provider/SelfHosted/ProviderSelfHosted.cs | 1 -
.../Provider/X/ProviderX.cs | 1 -
.../Settings/DataModel/DataSourceERI_V1.cs | 9 +-
.../Settings/IERIDataSource.cs | 5 ++
.../Tools/ERIClient/ERIClientBase.cs | 5 +-
.../AugmentationProcesses/AugmentationOne.cs | 18 +---
.../RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs | 77 +++++++++++++++-
.../Tools/Validation/DataSourceValidation.cs | 8 ++
app/MindWork AI Studio/packages.lock.json | 8 +-
.../wwwroot/changelog/v0.9.32.md | 18 +++-
.../wwwroot/changelog/v0.9.33.md | 1 +
metadata.txt | 8 +-
runtime/Cargo.lock | 53 ++++++-----
runtime/Cargo.toml | 13 +--
runtime/tauri.conf.json | 2 +-
43 files changed, 402 insertions(+), 138 deletions(-)
create mode 100644 app/MindWork AI Studio/Chat/ChatThreadExtensions.cs
create mode 100644 app/MindWork AI Studio/wwwroot/changelog/v0.9.33.md
diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs
index 9e1fc363..bec2e7b1 100644
--- a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs
+++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs
@@ -298,7 +298,7 @@ public abstract partial class AssistantBase : ComponentBase, IMessageBusReceiver
// Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire
// content to be streamed.
- await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, this.lastUserPrompt, this.chatThread);
+ this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, this.lastUserPrompt, this.chatThread);
this.isProcessing = false;
this.StateHasChanged();
diff --git a/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs b/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs
index 413bc017..46d011f2 100644
--- a/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs
+++ b/app/MindWork AI Studio/Assistants/ERI/AssistantERI.razor.cs
@@ -291,6 +291,7 @@ public partial class AssistantERI : AssistantBaseCore
- You consider the security of the implementation by applying the Security by Design principle.
- Your output is formatted as Markdown. Code is formatted as code blocks. For every file, you
create a separate code block with its file path and name as chapter title.
+ - Important: The JSON objects of the API messages use camel case for the data field names.
""");
return sb.ToString();
diff --git a/app/MindWork AI Studio/Chat/ChatRole.cs b/app/MindWork AI Studio/Chat/ChatRole.cs
index d4e61e4b..339be971 100644
--- a/app/MindWork AI Studio/Chat/ChatRole.cs
+++ b/app/MindWork AI Studio/Chat/ChatRole.cs
@@ -12,7 +12,6 @@ public enum ChatRole
USER,
AI,
AGENT,
- RAG,
}
///
diff --git a/app/MindWork AI Studio/Chat/ChatThread.cs b/app/MindWork AI Studio/Chat/ChatThread.cs
index d7dbf9a4..d6c870aa 100644
--- a/app/MindWork AI Studio/Chat/ChatThread.cs
+++ b/app/MindWork AI Studio/Chat/ChatThread.cs
@@ -40,6 +40,16 @@ public sealed record ChatThread
///
public IReadOnlyList AISelectedDataSources { get; set; } = [];
+ ///
+ /// The augmented data for this chat thread. Will be inserted into the system prompt.
+ ///
+ public string AugmentedData { get; set; } = string.Empty;
+
+ ///
+ /// The data security to use, derived from the data sources used so far.
+ ///
+ public DataSourceSecurity DataSecurity { get; set; } = DataSourceSecurity.NOT_SPECIFIED;
+
///
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
///
@@ -74,31 +84,48 @@ public sealed record ChatThread
/// The prepared system prompt.
public string PrepareSystemPrompt(SettingsManager settingsManager, ChatThread chatThread, ILogger logger)
{
+ var isAugmentedDataAvailable = !string.IsNullOrWhiteSpace(chatThread.AugmentedData);
+ var systemPromptWithAugmentedData = isAugmentedDataAvailable switch
+ {
+ true => $"""
+ {chatThread.SystemPrompt}
+
+ {chatThread.AugmentedData}
+ """,
+
+ false => chatThread.SystemPrompt,
+ };
+
+ if(isAugmentedDataAvailable)
+ logger.LogInformation("Augmented data is available for the chat thread.");
+ else
+ logger.LogInformation("No augmented data is available for the chat thread.");
+
//
// Prepare the system prompt:
//
string systemPromptText;
var logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile))
- systemPromptText = chatThread.SystemPrompt;
+ systemPromptText = systemPromptWithAugmentedData;
else
{
if(!Guid.TryParse(chatThread.SelectedProfile, out var profileId))
- systemPromptText = chatThread.SystemPrompt;
+ systemPromptText = systemPromptWithAugmentedData;
else
{
if(chatThread.SelectedProfile == Profile.NO_PROFILE.Id || profileId == Guid.Empty)
- systemPromptText = chatThread.SystemPrompt;
+ systemPromptText = systemPromptWithAugmentedData;
else
{
var profile = settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == chatThread.SelectedProfile);
if(profile == default)
- systemPromptText = chatThread.SystemPrompt;
+ systemPromptText = systemPromptWithAugmentedData;
else
{
logMessage = $"Using profile '{profile.Name}' for chat thread '{chatThread.Name}'.";
systemPromptText = $"""
- {chatThread.SystemPrompt}
+ {systemPromptWithAugmentedData}
{profile.ToSystemPrompt()}
""";
diff --git a/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs b/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs
new file mode 100644
index 00000000..f2d553d2
--- /dev/null
+++ b/app/MindWork AI Studio/Chat/ChatThreadExtensions.cs
@@ -0,0 +1,58 @@
+using AIStudio.Provider.SelfHosted;
+using AIStudio.Settings.DataModel;
+
+namespace AIStudio.Chat;
+
+public static class ChatThreadExtensions
+{
+ ///
+ /// Checks if the specified provider is allowed for the chat thread.
+ ///
+ ///
+ /// We don't check if the provider is allowed to use the data sources of the chat thread.
+ /// That kind of check is done in the RAG process itself.
+ ///
+ /// One thing which is not so obvious: after RAG was used on this thread, the entire chat
+ /// thread is kind of a data source by itself. Why? Because the augmentation data collected
+ /// from the data sources is stored in the chat thread. This means we must check if the
+ /// selected provider is allowed to use this thread's data.
+ ///
+ /// The chat thread to check.
+ /// The provider to check.
+ /// True, when the provider is allowed for the chat thread. False, otherwise.
+ public static bool IsLLMProviderAllowed(this ChatThread? chatThread, T provider)
+ {
+ // No chat thread available means we have a new chat. That's fine:
+ if (chatThread is null)
+ return true;
+
+ // The chat thread is available, but the data security is not specified.
+ // Means, we never used RAG or RAG was enabled, but no data sources were selected.
+ // That's fine as well:
+ if (chatThread.DataSecurity is DataSourceSecurity.NOT_SPECIFIED)
+ return true;
+
+ //
+ // Is the provider self-hosted?
+ //
+ var isSelfHostedProvider = provider switch
+ {
+ ProviderSelfHosted => true,
+ AIStudio.Settings.Provider p => p.IsSelfHosted,
+
+ _ => false,
+ };
+
+ //
+ // Check the chat data security against the selected provider:
+ //
+ return isSelfHostedProvider switch
+ {
+ // The provider is self-hosted -- we can use any data source:
+ true => true,
+
+ // The provider is not self-hosted -- it depends on the data security of the chat thread:
+ false => chatThread.DataSecurity is not DataSourceSecurity.SELF_HOSTED,
+ };
+ }
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor
index 826cfdc0..f1c93b65 100644
--- a/app/MindWork AI Studio/Chat/ContentBlockComponent.razor
+++ b/app/MindWork AI Studio/Chat/ContentBlockComponent.razor
@@ -27,7 +27,7 @@
@if (this.IsLastContentBlock && this.Role is ChatRole.AI && this.RegenerateFunc is not null)
{
-
+
}
@if (this.RemoveBlockFunc is not null)
diff --git a/app/MindWork AI Studio/Chat/ContentImage.cs b/app/MindWork AI Studio/Chat/ContentImage.cs
index 9f09e87c..c7e785eb 100644
--- a/app/MindWork AI Studio/Chat/ContentImage.cs
+++ b/app/MindWork AI Studio/Chat/ContentImage.cs
@@ -28,7 +28,7 @@ public sealed class ContentImage : IContent, IImageSource
public Func StreamingEvent { get; set; } = () => Task.CompletedTask;
///
- public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default)
+ public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default)
{
throw new NotImplementedException();
}
diff --git a/app/MindWork AI Studio/Chat/ContentText.cs b/app/MindWork AI Studio/Chat/ContentText.cs
index 9f511752..38872edf 100644
--- a/app/MindWork AI Studio/Chat/ContentText.cs
+++ b/app/MindWork AI Studio/Chat/ContentText.cs
@@ -36,16 +36,31 @@ public sealed class ContentText : IContent
public Func StreamingEvent { get; set; } = () => Task.CompletedTask;
///
- public async Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default)
+ public async Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default)
{
if(chatThread is null)
- return;
+ return new();
+ if(!chatThread.IsLLMProviderAllowed(provider))
+ {
+ var logger = Program.SERVICE_PROVIDER.GetService>()!;
+ logger.LogError("The provider is not allowed for this chat thread due to data security reasons. Skipping the AI process.");
+ return chatThread;
+ }
+
// Call the RAG process. Right now, we only have one RAG process:
if (lastPrompt is not null)
{
- var rag = new AISrcSelWithRetCtxVal();
- chatThread = await rag.ProcessAsync(provider, lastPrompt, chatThread, token);
+ try
+ {
+ var rag = new AISrcSelWithRetCtxVal();
+ chatThread = await rag.ProcessAsync(provider, lastPrompt, chatThread, token);
+ }
+ catch (Exception e)
+ {
+ var logger = Program.SERVICE_PROVIDER.GetService>()!;
+ logger.LogError(e, "Skipping the RAG process due to an error.");
+ }
}
// Store the last time we got a response. We use this later
@@ -107,6 +122,7 @@ public sealed class ContentText : IContent
// Inform the UI that the streaming is done:
await this.StreamingDone();
+ return chatThread;
}
#endregion
diff --git a/app/MindWork AI Studio/Chat/IContent.cs b/app/MindWork AI Studio/Chat/IContent.cs
index 8ca94025..be3bf097 100644
--- a/app/MindWork AI Studio/Chat/IContent.cs
+++ b/app/MindWork AI Studio/Chat/IContent.cs
@@ -41,7 +41,7 @@ public interface IContent
///
/// Uses the provider to create the content.
///
- public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
+ public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
///
/// Returns the corresponding ERI content type.
diff --git a/app/MindWork AI Studio/Components/Changelog.Logs.cs b/app/MindWork AI Studio/Components/Changelog.Logs.cs
index 6981386c..c0f7db9a 100644
--- a/app/MindWork AI Studio/Components/Changelog.Logs.cs
+++ b/app/MindWork AI Studio/Components/Changelog.Logs.cs
@@ -13,6 +13,7 @@ public partial class Changelog
public static readonly Log[] LOGS =
[
+ new (207, "v0.9.32, build 207 (2025-03-08 20:15 UTC)", "v0.9.32.md"),
new (206, "v0.9.31, build 206 (2025-03-03 15:33 UTC)", "v0.9.31.md"),
new (205, "v0.9.30, build 205 (2025-02-24 19:55 UTC)", "v0.9.30.md"),
new (204, "v0.9.29, build 204 (2025-02-24 13:48 UTC)", "v0.9.29.md"),
diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor b/app/MindWork AI Studio/Components/ChatComponent.razor
index 06dd07b2..703d9175 100644
--- a/app/MindWork AI Studio/Components/ChatComponent.razor
+++ b/app/MindWork AI Studio/Components/ChatComponent.razor
@@ -24,7 +24,7 @@
IsLastContentBlock="@isLastBlock"
IsSecondToLastBlock="@isSecondLastBlock"
RegenerateFunc="@this.RegenerateBlock"
- RegenerateEnabled="@(() => this.IsProviderSelected)"
+ RegenerateEnabled="@(() => this.IsProviderSelected && this.ChatThread.IsLLMProviderAllowed(this.Provider))"
EditLastBlockFunc="@this.EditLastBlock"
EditLastUserBlockFunc="@this.EditLastUserBlock"/>
}
@@ -46,7 +46,7 @@
Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Send"
OnAdornmentClick="() => this.SendMessage()"
- ReadOnly="!this.IsProviderSelected || this.isStreaming"
+ Disabled="@this.IsInputForbidden()"
Immediate="@true"
OnKeyUp="this.InputKeyEvent"
UserAttributes="@USER_INPUT_ATTRIBUTES"
@@ -113,6 +113,14 @@
{
}
+
+ @if (!this.ChatThread.IsLLMProviderAllowed(this.Provider))
+ {
+
+
+
+ }
+
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor.cs b/app/MindWork AI Studio/Components/ChatComponent.razor.cs
index 67d805d2..f3b6b742 100644
--- a/app/MindWork AI Studio/Components/ChatComponent.razor.cs
+++ b/app/MindWork AI Studio/Components/ChatComponent.razor.cs
@@ -275,6 +275,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
{
var chatDefaultOptions = this.SettingsManager.ConfigurationData.Chat.PreselectedDataSourceOptions.CreateCopy();
this.earlyDataSourceOptions = chatDefaultOptions;
+ if(this.ChatThread is not null)
+ this.ChatThread.DataSourceOptions = chatDefaultOptions;
+
this.dataSourceSelectionComponent?.ChangeOptionWithoutSaving(chatDefaultOptions);
}
@@ -337,6 +340,20 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
this.earlyDataSourceOptions = updatedOptions;
}
+ private bool IsInputForbidden()
+ {
+ if (!this.IsProviderSelected)
+ return true;
+
+ if(this.isStreaming)
+ return true;
+
+ if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
+ return true;
+
+ return false;
+ }
+
private async Task InputKeyEvent(KeyboardEventArgs keyEvent)
{
if(this.dataSourceSelectionComponent?.IsVisible ?? false)
@@ -371,6 +388,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
if (!this.IsProviderSelected)
return;
+ if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
+ return;
+
// We need to blur the focus away from the input field
// to be able to clear the field:
await this.inputField.BlurAsync();
@@ -475,7 +495,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire
// content to be streamed.
- 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.Logger), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token);
}
this.cancellationTokenSource = null;
@@ -773,6 +793,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
if(this.ChatThread is null)
return;
+ if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
+ return;
+
this.ChatThread.Remove(aiBlock, removeForRegenerate: true);
this.hasUnsavedChanges = true;
this.StateHasChanged();
diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor
index 984d2e40..dd6d2773 100644
--- a/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor
+++ b/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor
@@ -42,52 +42,49 @@
else
{
- @for (var index = 0; index < this.retrievalInfoformation.Count; index++)
- {
- var info = this.retrievalInfoformation[index];
-
-
-
-
- @if (!string.IsNullOrWhiteSpace(info.Link))
- {
-
- Open web link, show more information
-
- }
+
+
+
-
- Embeddings
-
- @if (!info.Embeddings.Any())
- {
-
- The data source does not provide any embedding information.
-
- }
- else
- {
-
- @for (var embeddingIndex = 0; embeddingIndex < info.Embeddings.Count; embeddingIndex++)
- {
- var embedding = info.Embeddings[embeddingIndex];
-
-
-
-
-
- @if (!string.IsNullOrWhiteSpace(embedding.Link))
- {
-
- Open web link, show more information
-
- }
-
- }
-
- }
-
- }
+ @if (!string.IsNullOrWhiteSpace(this.selectedRetrievalInfo.Link))
+ {
+
+ Open web link, show more information
+
+ }
+
+
+ Embeddings
+
+ @* ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract *@
+ @if (this.selectedRetrievalInfo.Embeddings is null || !this.selectedRetrievalInfo.Embeddings.Any())
+ {
+
+ The data source does not provide any embedding information.
+
+ }
+ else
+ {
+
+ @for (var embeddingIndex = 0; embeddingIndex < this.selectedRetrievalInfo.Embeddings.Count; embeddingIndex++)
+ {
+ var embedding = this.selectedRetrievalInfo.Embeddings[embeddingIndex];
+
+
+
+
+
+ @if (!string.IsNullOrWhiteSpace(embedding.Link))
+ {
+
+ Open web link, show more information
+
+ }
+
+ }
+
+ }
+
}
diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor.cs
index 192347d0..af173516 100644
--- a/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor.cs
+++ b/app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor.cs
@@ -42,6 +42,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
private string serverDescription = string.Empty;
private ProviderType securityRequirements = ProviderType.NONE;
private IReadOnlyList retrievalInfoformation = [];
+ private RetrievalInfo selectedRetrievalInfo;
private bool IsOperationInProgress { get; set; } = true;
@@ -130,7 +131,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
}
this.retrievalInfoformation = retrievalInfoResult.Data ?? [];
-
+ this.selectedRetrievalInfo = this.retrievalInfoformation.FirstOrDefault(x => x.Id == this.DataSource.SelectedRetrievalId);
this.StateHasChanged();
}
catch (Exception e)
diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor
index fcc9fff0..a37a2d4d 100644
--- a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor
+++ b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor
@@ -109,11 +109,25 @@
InputType="InputType.Password"
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
}
+
+ @if (this.availableRetrievalProcesses.Count > 0)
+ {
+
+ @foreach (var retrievalProcess in this.availableRetrievalProcesses)
+ {
+
+ @retrievalProcess.Name
+
+ }
+
+ }
@foreach (var policy in Enum.GetValues())
{
- @policy.ToSelectionText()
+
+ @policy.ToSelectionText()
+
}
diff --git a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs
index e042f92a..dd0f9cea 100644
--- a/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs
+++ b/app/MindWork AI Studio/Dialogs/DataSourceERI_V1Dialog.razor.cs
@@ -8,6 +8,8 @@ using AIStudio.Tools.Validation;
using Microsoft.AspNetCore.Components;
+using RetrievalInfo = AIStudio.Tools.ERIClient.DataModel.RetrievalInfo;
+
// ReSharper disable InconsistentNaming
namespace AIStudio.Dialogs;
@@ -59,6 +61,8 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
private int dataPort;
private AuthMethod dataAuthMethod;
private string dataUsername = string.Empty;
+ private List availableRetrievalProcesses = [];
+ private RetrievalInfo dataSelectedRetrievalProcess;
// We get the form reference from Blazor code to validate it manually:
private MudForm form = null!;
@@ -91,6 +95,9 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
// When editing, we need to load the data:
if(this.IsEditing)
{
+ //
+ // Assign the data to the form fields:
+ //
this.dataEditingPreviousInstanceName = this.DataSource.Name.ToLowerInvariant();
this.dataNum = this.DataSource.Num;
this.dataId = this.DataSource.Id;
@@ -114,6 +121,12 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
await this.form.Validate();
}
}
+
+ // Load the data:
+ await this.TestConnection();
+
+ // Select the retrieval process:
+ this.dataSelectedRetrievalProcess = this.availableRetrievalProcesses.FirstOrDefault(n => n.Id == this.DataSource.SelectedRetrievalId);
}
await base.OnInitializedAsync();
@@ -153,6 +166,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
Username = this.dataUsername,
Type = DataSourceType.ERI_V1,
SecurityPolicy = this.dataSecurityPolicy,
+ SelectedRetrievalId = this.dataSelectedRetrievalProcess.Id,
};
}
@@ -224,6 +238,18 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
this.dataSourceSecurityRequirements = securityRequirementsRequest.Data;
+ var retrievalInfoRequest = await client.GetRetrievalInfoAsync(cts.Token);
+ if (!retrievalInfoRequest.Successful)
+ {
+ await this.form.Validate();
+
+ Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
+ this.dataIssues[^1] = retrievalInfoRequest.Message;
+ return;
+ }
+
+ this.availableRetrievalProcesses = retrievalInfoRequest.Data ?? [];
+
this.connectionTested = true;
this.connectionSuccessfulTested = true;
this.Logger.LogInformation("Connection to the ERI v1 server was successful tested.");
diff --git a/app/MindWork AI Studio/MindWork AI Studio.csproj b/app/MindWork AI Studio/MindWork AI Studio.csproj
index 7160b815..21c02959 100644
--- a/app/MindWork AI Studio/MindWork AI Studio.csproj
+++ b/app/MindWork AI Studio/MindWork AI Studio.csproj
@@ -46,7 +46,7 @@
-
+
diff --git a/app/MindWork AI Studio/Pages/Supporters.razor b/app/MindWork AI Studio/Pages/Supporters.razor
index d1fc2d3d..91a744a3 100644
--- a/app/MindWork AI Studio/Pages/Supporters.razor
+++ b/app/MindWork AI Studio/Pages/Supporters.razor
@@ -78,6 +78,7 @@
+
diff --git a/app/MindWork AI Studio/Pages/Writer.razor.cs b/app/MindWork AI Studio/Pages/Writer.razor.cs
index 76409c32..42b23abc 100644
--- a/app/MindWork AI Studio/Pages/Writer.razor.cs
+++ b/app/MindWork AI Studio/Pages/Writer.razor.cs
@@ -139,7 +139,7 @@ public partial class Writer : MSGComponentBase, IAsyncDisposable
this.isStreaming = true;
this.StateHasChanged();
- await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, lastUserPrompt, this.chatThread);
+ this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, lastUserPrompt, this.chatThread);
this.suggestion = aiText.Text;
this.isStreaming = false;
diff --git a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
index a900095d..7693d21f 100644
--- a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
+++ b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
@@ -38,7 +38,6 @@ public sealed class ProviderAnthropic(ILogger logger) : BaseProvider("https://ap
ChatRole.USER => "user",
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
index c58e914b..b4ce57a0 100644
--- a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
+++ b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
@@ -49,7 +49,6 @@ public sealed class ProviderDeepSeek(ILogger logger) : BaseProvider("https://api
ChatRole.USER => "user",
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
- ChatRole.RAG => "assistant",
ChatRole.SYSTEM => "system",
_ => "user",
diff --git a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
index 88801a1f..66817fc2 100644
--- a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
+++ b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
@@ -49,7 +49,6 @@ public class ProviderFireworks(ILogger logger) : BaseProvider("https://api.firew
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
index 40054cf8..c0562a69 100644
--- a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
+++ b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
@@ -49,7 +49,6 @@ public sealed class ProviderGWDG(ILogger logger) : BaseProvider("https://chat-ai
ChatRole.USER => "user",
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
- ChatRole.RAG => "assistant",
ChatRole.SYSTEM => "system",
_ => "user",
diff --git a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
index 4fd12ab6..942cb245 100644
--- a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
+++ b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
@@ -50,7 +50,6 @@ public class ProviderGoogle(ILogger logger) : BaseProvider("https://generativela
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
index 10e8899b..f32a31b5 100644
--- a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
+++ b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
@@ -50,7 +50,6 @@ public class ProviderGroq(ILogger logger) : BaseProvider("https://api.groq.com/o
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
index 005475e8..b8450503 100644
--- a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
+++ b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
@@ -49,7 +49,6 @@ public sealed class ProviderHelmholtz(ILogger logger) : BaseProvider("https://ap
ChatRole.USER => "user",
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
- ChatRole.RAG => "assistant",
ChatRole.SYSTEM => "system",
_ => "user",
diff --git a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
index 4395920a..024f60d3 100644
--- a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
+++ b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
@@ -48,7 +48,6 @@ public sealed class ProviderMistral(ILogger logger) : BaseProvider("https://api.
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
index f9019259..ed092174 100644
--- a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
+++ b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
@@ -76,7 +76,6 @@ public sealed class ProviderOpenAI(ILogger logger) : BaseProvider("https://api.o
ChatRole.USER => "user",
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
- ChatRole.RAG => "assistant",
ChatRole.SYSTEM => systemPromptRole,
_ => "user",
diff --git a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
index 73c101a6..4ba45c6b 100644
--- a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
+++ b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
@@ -46,7 +46,6 @@ public sealed class ProviderSelfHosted(ILogger logger, Host host, string hostnam
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Provider/X/ProviderX.cs b/app/MindWork AI Studio/Provider/X/ProviderX.cs
index df927d73..a8334c8d 100644
--- a/app/MindWork AI Studio/Provider/X/ProviderX.cs
+++ b/app/MindWork AI Studio/Provider/X/ProviderX.cs
@@ -50,7 +50,6 @@ public sealed class ProviderX(ILogger logger) : BaseProvider("https://api.x.ai/v
ChatRole.AI => "assistant",
ChatRole.AGENT => "assistant",
ChatRole.SYSTEM => "system",
- ChatRole.RAG => "assistant",
_ => "user",
},
diff --git a/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs b/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs
index a9e40231..305c1f09 100644
--- a/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs
+++ b/app/MindWork AI Studio/Settings/DataModel/DataSourceERI_V1.cs
@@ -51,6 +51,9 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
///
public ERIVersion Version { get; init; } = ERIVersion.V1;
+ ///
+ public string SelectedRetrievalId { get; init; } = string.Empty;
+
///
public async Task> RetrieveDataAsync(IContent lastPrompt, ChatThread thread, CancellationToken token = default)
{
@@ -74,7 +77,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
Thread = await thread.ToERIChatThread(token),
MaxMatches = 10,
- RetrievalProcessId = null, // The ERI server selects the retrieval process when multiple processes are available
+ RetrievalProcessId = string.IsNullOrWhiteSpace(this.SelectedRetrievalId) ? null : this.SelectedRetrievalId,
Parameters = null, // The ERI server selects useful default parameters
};
@@ -97,7 +100,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
Links = eriContext.Links,
Category = eriContext.Type.ToRetrievalContentCategory(),
MatchedText = eriContext.MatchedContent,
- DataSourceName = eriContext.Name,
+ DataSourceName = this.Name,
SurroundingContent = eriContext.SurroundingContent,
});
break;
@@ -111,7 +114,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
Source = eriContext.MatchedContent,
Category = eriContext.Type.ToRetrievalContentCategory(),
SourceType = ContentImageSource.BASE64,
- DataSourceName = eriContext.Name,
+ DataSourceName = this.Name,
});
break;
diff --git a/app/MindWork AI Studio/Settings/IERIDataSource.cs b/app/MindWork AI Studio/Settings/IERIDataSource.cs
index 35e37791..55138978 100644
--- a/app/MindWork AI Studio/Settings/IERIDataSource.cs
+++ b/app/MindWork AI Studio/Settings/IERIDataSource.cs
@@ -29,4 +29,9 @@ public interface IERIDataSource : IExternalDataSource
/// The ERI specification to use.
///
public ERIVersion Version { get; init; }
+
+ ///
+ /// The ID of the selected retrieval process.
+ ///
+ public string SelectedRetrievalId { get; init; }
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs b/app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs
index 1906a0d5..58811b07 100644
--- a/app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs
+++ b/app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs
@@ -9,9 +9,10 @@ public abstract class ERIClientBase(string baseAddress) : IDisposable
{
WriteIndented = true,
AllowTrailingCommas = true,
- PropertyNamingPolicy = null,
- DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
+ UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow,
Converters =
{
new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper),
diff --git a/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs b/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs
index fd6e30af..fff91251 100644
--- a/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs
+++ b/app/MindWork AI Studio/Tools/RAG/AugmentationProcesses/AugmentationOne.cs
@@ -66,22 +66,8 @@ public sealed class AugmentationOne : IAugmentationProcess
// Let's convert all retrieval contexts to Markdown:
await retrievalContexts.AsMarkdown(sb, token);
- //
- // Append the entire augmentation to the chat thread,
- // just before the user prompt:
- //
- chatThread.Blocks.Insert(chatThread.Blocks.Count - 1, new()
- {
- Role = ChatRole.RAG,
- Time = DateTimeOffset.UtcNow,
- ContentType = ContentType.TEXT,
- HideFromUser = true,
- Content = new ContentText
- {
- Text = sb.ToString(),
- }
- });
-
+ // Add the augmented data to the chat thread:
+ chatThread.AugmentedData = sb.ToString();
return chatThread;
}
diff --git a/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs b/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs
index 13e32500..2736f7b0 100644
--- a/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs
+++ b/app/MindWork AI Studio/Tools/RAG/RAGProcesses/AISrcSelWithRetCtxVal.cs
@@ -1,6 +1,7 @@
using AIStudio.Chat;
using AIStudio.Provider;
using AIStudio.Settings;
+using AIStudio.Settings.DataModel;
using AIStudio.Tools.RAG.AugmentationProcesses;
using AIStudio.Tools.RAG.DataSourceSelectionProcesses;
using AIStudio.Tools.Services;
@@ -38,6 +39,30 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
// makes sense to proceed with the RAG process:
var proceedWithRAG = true;
+ //
+ // We read the last block in the chat thread. We need to re-arrange
+ // the order of blocks later, after the augmentation process takes
+ // place:
+ //
+ if(chatThread.Blocks.Count == 0)
+ {
+ logger.LogError("The chat thread is empty. Skipping the RAG process.");
+ return chatThread;
+ }
+
+ if (chatThread.Blocks.Last().Role != ChatRole.AI)
+ {
+ logger.LogError("The last block in the chat thread is not the AI block. There is something wrong with the chat thread. Skipping the RAG process.");
+ return chatThread;
+ }
+
+ //
+ // At this point in time, the chat thread contains already the
+ // last block, which is the waiting AI block. We need to remove
+ // this block before we call some parts of the RAG process:
+ //
+ var chatThreadWithoutWaitingAIBlock = chatThread with { Blocks = chatThread.Blocks[..^1] };
+
//
// When the user wants to bind data sources to the chat, we
// have to check if the data sources are available for the
@@ -72,6 +97,56 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
logger.LogWarning("No data sources are selected. The RAG process is skipped.");
proceedWithRAG = false;
}
+ else
+ {
+ var previousDataSecurity = chatThread.DataSecurity;
+
+ //
+ // Update the data security of the chat thread. We consider the current data security
+ // of the chat thread and the data security of the selected data sources:
+ //
+ var dataSecurityRestrictedToSelfHosted = selectedDataSources.Any(x => x.SecurityPolicy is DataSourceSecurity.SELF_HOSTED);
+ chatThread.DataSecurity = dataSecurityRestrictedToSelfHosted switch
+ {
+ //
+ //
+ // Case: the data sources which are selected have a security policy
+ // of SELF_HOSTED (at least one data source).
+ //
+ // When the policy was already set to ALLOW_ANY, we restrict it
+ // to SELF_HOSTED.
+ //
+ true => DataSourceSecurity.SELF_HOSTED,
+
+ //
+ // Case: the data sources which are selected have a security policy
+ // of ALLOW_ANY (none of the data sources has a SELF_HOSTED policy).
+ //
+ // When the policy was already set to SELF_HOSTED, we must keep that.
+ //
+ false => chatThread.DataSecurity switch
+ {
+ //
+ // When the policy was not specified yet, we set it to ALLOW_ANY.
+ //
+ DataSourceSecurity.NOT_SPECIFIED => DataSourceSecurity.ALLOW_ANY,
+ DataSourceSecurity.ALLOW_ANY => DataSourceSecurity.ALLOW_ANY,
+
+ //
+ // When the policy was already set to SELF_HOSTED, we must keep that.
+ // This is important since the thread might already contain data
+ // from a data source with a SELF_HOSTED policy.
+ //
+ DataSourceSecurity.SELF_HOSTED => DataSourceSecurity.SELF_HOSTED,
+
+ // Default case: we use the current data security of the chat thread.
+ _ => chatThread.DataSecurity,
+ }
+ };
+
+ if (previousDataSecurity != chatThread.DataSecurity)
+ logger.LogInformation($"The data security of the chat thread was updated from '{previousDataSecurity}' to '{chatThread.DataSecurity}'.");
+ }
//
// Trigger the retrieval part of the (R)AG process:
@@ -84,7 +159,7 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
//
var retrievalTasks = new List>>(selectedDataSources.Count);
foreach (var dataSource in selectedDataSources)
- retrievalTasks.Add(dataSource.RetrieveDataAsync(lastPrompt, chatThread, token));
+ retrievalTasks.Add(dataSource.RetrieveDataAsync(lastPrompt, chatThreadWithoutWaitingAIBlock, token));
//
// Wait for all retrieval tasks to finish:
diff --git a/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs b/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs
index b3f85426..d97edb31 100644
--- a/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs
+++ b/app/MindWork AI Studio/Tools/Validation/DataSourceValidation.cs
@@ -92,6 +92,14 @@ public sealed class DataSourceValidation
return null;
}
+
+ public string? ValidateRetrievalProcess(RetrievalInfo retrievalInfo)
+ {
+ if(retrievalInfo == default)
+ return "Please select one retrieval process.";
+
+ return null;
+ }
public string? ValidatingName(string dataSourceName)
{
diff --git a/app/MindWork AI Studio/packages.lock.json b/app/MindWork AI Studio/packages.lock.json
index 5d302021..e31392c5 100644
--- a/app/MindWork AI Studio/packages.lock.json
+++ b/app/MindWork AI Studio/packages.lock.json
@@ -18,9 +18,9 @@
},
"HtmlAgilityPack": {
"type": "Direct",
- "requested": "[1.11.72, )",
- "resolved": "1.11.72",
- "contentHash": "RNLgXxTFdIGFI+o5l8c2aJ2L5StIRn9Uv8HKR76p7QP4ZUL26wzpWUCWh08xWUdkL2kocl+Xhv6VUu0rA1npVg=="
+ "requested": "[1.11.74, )",
+ "resolved": "1.11.74",
+ "contentHash": "q0wRGbegtr4sZXjCNoV3OeRLTOcTNJQKiO9etNVSKPoTo33unmSK8Ahg36C4jIg/Hd3aw8YnTQjtKpBy+wlOpg=="
},
"Microsoft.Extensions.FileProviders.Embedded": {
"type": "Direct",
@@ -207,6 +207,6 @@
"contentHash": "7WaVMHklpT3Ye2ragqRIwlFRsb6kOk63BOGADV0fan3ulVfGLUYkDi5yNUsZS/7FVNkWbtHAlDLmu4WnHGfqvQ=="
}
},
- "net8.0/osx-x64": {}
+ "net8.0/win-x64": {}
}
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/wwwroot/changelog/v0.9.32.md b/app/MindWork AI Studio/wwwroot/changelog/v0.9.32.md
index 9863080f..62a9a86c 100644
--- a/app/MindWork AI Studio/wwwroot/changelog/v0.9.32.md
+++ b/app/MindWork AI Studio/wwwroot/changelog/v0.9.32.md
@@ -1,2 +1,16 @@
-# v0.9.32, build 207 (2025-03-xx xx:xx UTC)
-- Added the Community & Code section to the About page. It includes links to the GitHub repositories and the project homepage.
\ No newline at end of file
+# v0.9.32, build 207 (2025-03-08 20:15 UTC)
+- Added the "Community & Code" section to the about page. It includes links to the GitHub repositories and the project website.
+- Added the retrieval process section for ERI data sources in the configuration dialog. Like all RAG functions, this is hidden behind the RAG feature flag in the app settings due to its preview status.
+- Improved data security by preventing the use of cloud LLMs after confidential data has been retrieved previously.
+- Improved the ERI client to expect JSON responses and send JSON requests using camel case.
+- Improved the ERI client to raise an error when the server responds with additional JSON data that is not expected.
+- Improved the error handling in the ERI data source info dialog in cases where servers respond with an invalid message.
+- Improved the error handling for the entire RAG process.
+- Improved chat thread persistence after modifications through the RAG process.
+- Improved the augmentation and generation part of RAG by passing the augmented data into the system prompt.
+- Fixed the chat thread we use for the data retrieval by removing the last block, which is meant to be for the final AI answer.
+- Fixed the data source name for ERI data sources when performing data retrieval.
+- Fixed the default data source selection when replacing the current chat with a new one.
+- Fixed the state of the re-generate button in the chat thread, when no provider is selected or the data security is preventing the use of cloud LLMs.
+- Updated the code contributions section in the supporter page. Thanks `peerschuett` for being our next contributor.
+- Upgraded code dependencies.
\ No newline at end of file
diff --git a/app/MindWork AI Studio/wwwroot/changelog/v0.9.33.md b/app/MindWork AI Studio/wwwroot/changelog/v0.9.33.md
new file mode 100644
index 00000000..6b27d3ea
--- /dev/null
+++ b/app/MindWork AI Studio/wwwroot/changelog/v0.9.33.md
@@ -0,0 +1 @@
+# v0.9.33, build 208 (2025-03-xx xx:xx UTC)
diff --git a/metadata.txt b/metadata.txt
index e53de536..7f7339d9 100644
--- a/metadata.txt
+++ b/metadata.txt
@@ -1,9 +1,9 @@
-0.9.31
-2025-03-03 15:33:03 UTC
-206
+0.9.32
+2025-03-08 20:15:02 UTC
+207
8.0.113 (commit 8f216348dc)
8.0.13 (commit eba546b0f0)
1.85.0 (commit 4d91de4e4)
7.16.0
1.8.1
-2e84f10a977, release
+5a726577ca2, release
diff --git a/runtime/Cargo.lock b/runtime/Cargo.lock
index a6422bf5..a0600468 100644
--- a/runtime/Cargo.lock
+++ b/runtime/Cargo.lock
@@ -377,9 +377,12 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.1.6"
+version = "1.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
+checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
+dependencies = [
+ "shlex",
+]
[[package]]
name = "cesu8"
@@ -2181,9 +2184,9 @@ dependencies = [
[[package]]
name = "keyring"
-version = "3.6.1"
+version = "3.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f8fe839464d4e4b37d756d7e910063696af79a7e877282cb1825e4ec5f10833"
+checksum = "1961983669d57bdfe6c0f3ef8e4c229b5ef751afcc7d87e4271d2f71f6ccfa8b"
dependencies = [
"byteorder",
"dbus-secret-service",
@@ -2214,9 +2217,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
-version = "0.2.155"
+version = "0.2.170"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
[[package]]
name = "libdbus-sys"
@@ -2261,9 +2264,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
name = "loom"
@@ -2347,7 +2350,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mindwork-ai-studio"
-version = "0.9.31"
+version = "0.9.32"
dependencies = [
"aes",
"arboard",
@@ -2365,6 +2368,7 @@ dependencies = [
"rand_chacha 0.9.0",
"rcgen",
"reqwest 0.12.12",
+ "ring",
"rocket",
"serde",
"serde_json",
@@ -2758,9 +2762,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.20.2"
+version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "open"
@@ -3557,15 +3561,14 @@ dependencies = [
[[package]]
name = "ring"
-version = "0.17.8"
+version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.15",
"libc",
- "spin",
"untrusted",
"windows-sys 0.52.0",
]
@@ -3873,18 +3876,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.217"
+version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.217"
+version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
dependencies = [
"proc-macro2",
"quote",
@@ -4028,6 +4031,12 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
@@ -4719,9 +4728,9 @@ dependencies = [
[[package]]
name = "tokio"
-version = "1.42.0"
+version = "1.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
+checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
dependencies = [
"backtrace",
"bytes",
@@ -4736,9 +4745,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 0293056e..a14c4e2b 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mindwork-ai-studio"
-version = "0.9.31"
+version = "0.9.32"
edition = "2021"
description = "MindWork AI Studio"
authors = ["Thorsten Sommer"]
@@ -11,14 +11,14 @@ tauri-build = { version = "1.5", features = [] }
[dependencies]
tauri = { version = "1.8", features = [ "http-all", "updater", "shell-sidecar", "shell-open", "dialog"] }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
-serde = { version = "1.0.217", features = ["derive"] }
+serde = { version = "1.0.218", features = ["derive"] }
serde_json = "1.0.134"
-keyring = { version = "3.6.1", features = ["apple-native", "windows-native", "sync-secret-service"] }
+keyring = { version = "3.6.2", features = ["apple-native", "windows-native", "sync-secret-service"] }
arboard = "3.4.1"
-tokio = { version = "1.42", features = ["rt", "rt-multi-thread", "macros"] }
+tokio = { version = "1.44", features = ["rt", "rt-multi-thread", "macros"] }
flexi_logger = "0.29.8"
-log = { version = "0.4", features = ["kv"] }
-once_cell = "1.20"
+log = { version = "0.4.26", features = ["kv"] }
+once_cell = "1.20.3"
rocket = { version = "0.5.1", features = ["json", "tls"] }
rand = "0.9"
rand_chacha = "0.9"
@@ -33,6 +33,7 @@ rcgen = { version = "0.13.2", features = ["pem"] }
# Fixes security vulnerability downstream, where the upstream is not fixed yet:
url = "2.5"
+ring = "0.17.13"
[target.'cfg(target_os = "linux")'.dependencies]
# See issue https://github.com/tauri-apps/tauri/issues/4470
diff --git a/runtime/tauri.conf.json b/runtime/tauri.conf.json
index cfbe3b3a..09dcf8ff 100644
--- a/runtime/tauri.conf.json
+++ b/runtime/tauri.conf.json
@@ -6,7 +6,7 @@
},
"package": {
"productName": "MindWork AI Studio",
- "version": "0.9.31"
+ "version": "0.9.32"
},
"tauri": {
"allowlist": {