)messages.Select(n => n.Result);
+ }
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Components/AttachDocuments.razor b/app/MindWork AI Studio/Components/AttachDocuments.razor
index aa89ebe3..d0cf8d6b 100644
--- a/app/MindWork AI Studio/Components/AttachDocuments.razor
+++ b/app/MindWork AI Studio/Components/AttachDocuments.razor
@@ -1,20 +1,52 @@
@inherits MSGComponentBase
-
-
-
-
- @T("Drag and drop files here or click to attach documents.")
-
- @foreach (var fileInfo in this.DocumentPaths.Select(file => new FileInfo(file)))
+@if (this.UseSmallForm)
+{
+
+ @{
+ var fileInfos = this.DocumentPaths.Select(file => new FileInfo(file)).ToList();
+ }
+ @if (fileInfos.Any())
{
-
-
+
+
}
-
-
-
- @T("Clear file list")
-
-
\ No newline at end of file
+ else
+ {
+
+
+
+ }
+
+}
+else
+{
+
+
+
+
+ @T("Drag and drop files here or click to attach documents.")
+
+ @foreach (var fileInfo in this.DocumentPaths.Select(file => new FileInfo(file)))
+ {
+
+
+
+ }
+
+
+
+ @T("Clear file list")
+
+
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Components/AttachDocuments.razor.cs b/app/MindWork AI Studio/Components/AttachDocuments.razor.cs
index 7b885842..d7e65aba 100644
--- a/app/MindWork AI Studio/Components/AttachDocuments.razor.cs
+++ b/app/MindWork AI Studio/Components/AttachDocuments.razor.cs
@@ -28,6 +28,9 @@ public partial class AttachDocuments : MSGComponentBase
[Parameter]
public bool CatchAllDocuments { get; set; }
+ [Parameter]
+ public bool UseSmallForm { get; set; }
+
[Inject]
private ILogger Logger { get; set; } = null!;
@@ -36,6 +39,7 @@ public partial class AttachDocuments : MSGComponentBase
[Inject]
private IDialogService DialogService { get; init; } = null!;
+ private const Placement TOOLBAR_TOOLTIP_PLACEMENT = Placement.Top;
#region Overrides of MSGComponentBase
diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor b/app/MindWork AI Studio/Components/ChatComponent.razor
index 48420522..b68ef369 100644
--- a/app/MindWork AI Studio/Components/ChatComponent.razor
+++ b/app/MindWork AI Studio/Components/ChatComponent.razor
@@ -83,6 +83,8 @@
+
+
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
{
diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor.cs b/app/MindWork AI Studio/Components/ChatComponent.razor.cs
index 94ee2385..4d192f4f 100644
--- a/app/MindWork AI Studio/Components/ChatComponent.razor.cs
+++ b/app/MindWork AI Studio/Components/ChatComponent.razor.cs
@@ -57,6 +57,8 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
private string currentWorkspaceName = string.Empty;
private Guid currentWorkspaceId = Guid.Empty;
private CancellationTokenSource? cancellationTokenSource;
+ private List fileAttachments = new();
+ private HashSet chatDocumentPaths = [];
// Unfortunately, we need the input field reference to blur the focus away. Without
// this, we cannot clear the input field.
@@ -462,6 +464,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
lastUserPrompt = new ContentText
{
Text = this.userInput,
+ FileAttachments = this.fileAttachments.ToList(), // Create a copy
};
//
@@ -507,6 +510,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
// Clear the input field:
await this.inputField.FocusAsync();
this.userInput = string.Empty;
+ this.fileAttachments.Clear();
await this.inputField.BlurAsync();
// Enable the stream state for the chat component:
@@ -575,6 +579,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
this.hasUnsavedChanges = false;
}
+
private async Task StartNewChat(bool useSameWorkspace = false, bool deletePreviousChat = false)
{
//
diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs
index 1dd94c1c..0dd1af1b 100644
--- a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs
+++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs
@@ -23,7 +23,7 @@ public abstract class SettingsDialogBase : MSGComponentBase
protected readonly List> availableEmbeddingProviders = new();
#region Overrides of ComponentBase
-
+
///
protected override async Task OnInitializedAsync()
{
diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs
index 93084866..2708ab4f 100644
--- a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs
+++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs
@@ -13,7 +13,7 @@ public partial class SettingsDialogChatTemplate : SettingsDialogBase
public ChatThread? ExistingChatThread { get; set; }
#region Overrides of ComponentBase
-
+
///
protected override async Task OnInitializedAsync()
{
diff --git a/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs b/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
index e7d3e523..78618db2 100644
--- a/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
+++ b/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
@@ -39,6 +39,26 @@ public sealed class ProviderAlibabaCloud() : BaseProvider("https://dashscope-int
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the AlibabaCloud HTTP chat request:
var alibabaCloudChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -47,24 +67,8 @@ public sealed class ProviderAlibabaCloud() : BaseProvider("https://dashscope-int
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
+
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
index f2c88f52..4ea73e77 100644
--- a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
+++ b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
@@ -30,29 +30,32 @@ public sealed class ProviderAnthropic() : BaseProvider("https://api.anthropic.co
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters("system");
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the Anthropic HTTP chat request:
var chatRequest = JsonSerializer.Serialize(new ChatRequest
{
Model = chatModel.Id,
// Build the messages:
- Messages = [..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [..messages],
System = chatThread.PrepareSystemPrompt(settingsManager, chatThread),
MaxTokens = apiParameters.TryGetValue("max_tokens", out var value) && value is int intValue ? intValue : 4_096,
diff --git a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
index 1063262c..991d6a2e 100644
--- a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
+++ b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
@@ -39,6 +39,26 @@ public sealed class ProviderDeepSeek() : BaseProvider("https://api.deepseek.com/
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the DeepSeek HTTP chat request:
var deepSeekChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -47,24 +67,8 @@ public sealed class ProviderDeepSeek() : BaseProvider("https://api.deepseek.com/
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
+
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
index a02c692c..20c79188 100644
--- a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
+++ b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
@@ -39,6 +39,26 @@ public class ProviderFireworks() : BaseProvider("https://api.fireworks.ai/infere
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the Fireworks HTTP chat request:
var fireworksChatRequest = JsonSerializer.Serialize(new ChatRequest
{
@@ -47,24 +67,7 @@ public class ProviderFireworks() : BaseProvider("https://api.fireworks.ai/infere
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
diff --git a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
index 2a56bfd4..b1cb291c 100644
--- a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
+++ b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
@@ -39,6 +39,26 @@ public sealed class ProviderGWDG() : BaseProvider("https://chat-ai.academiccloud
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the GWDG HTTP chat request:
var gwdgChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -47,24 +67,8 @@ public sealed class ProviderGWDG() : BaseProvider("https://chat-ai.academiccloud
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
+
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
index 8dcf0c96..7ce3f24e 100644
--- a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
+++ b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
@@ -39,6 +39,26 @@ public class ProviderGoogle() : BaseProvider("https://generativelanguage.googlea
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the Google HTTP chat request:
var geminiChatRequest = JsonSerializer.Serialize(new ChatRequest
{
@@ -47,24 +67,7 @@ public class ProviderGoogle() : BaseProvider("https://generativelanguage.googlea
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
diff --git a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
index 5cc7b3df..45473d82 100644
--- a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
+++ b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
@@ -39,6 +39,26 @@ public class ProviderGroq() : BaseProvider("https://api.groq.com/openai/v1/", LO
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the OpenAI HTTP chat request:
var groqChatRequest = JsonSerializer.Serialize(new ChatRequest
{
@@ -47,24 +67,7 @@ public class ProviderGroq() : BaseProvider("https://api.groq.com/openai/v1/", LO
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
diff --git a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
index f0b69bb4..3f7b405b 100644
--- a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
+++ b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
@@ -38,6 +38,26 @@ public sealed class ProviderHelmholtz() : BaseProvider("https://api.helmholtz-bl
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
// Prepare the Helmholtz HTTP chat request:
var helmholtzChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
@@ -47,24 +67,8 @@ public sealed class ProviderHelmholtz() : BaseProvider("https://api.helmholtz-bl
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
+
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs b/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
index 6cfb8027..31522b5c 100644
--- a/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
+++ b/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
@@ -44,6 +44,26 @@ public sealed class ProviderHuggingFace : BaseProvider
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var message = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the HuggingFace HTTP chat request:
var huggingfaceChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -52,24 +72,8 @@ public sealed class ProviderHuggingFace : BaseProvider
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..message],
+
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
index 01b0db11..bd999b92 100644
--- a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
+++ b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
@@ -36,6 +36,26 @@ public sealed class ProviderMistral() : BaseProvider("https://api.mistral.ai/v1/
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new RegularMessage
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
// Prepare the Mistral HTTP chat request:
var mistralChatRequest = JsonSerializer.Serialize(new ChatRequest
@@ -45,24 +65,7 @@ public sealed class ProviderMistral() : BaseProvider("https://api.mistral.ai/v1/
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new RegularMessage
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
@@ -70,6 +73,7 @@ public sealed class ProviderMistral() : BaseProvider("https://api.mistral.ai/v1/
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
+
async Task RequestBuilder()
{
// Build the HTTP post request:
diff --git a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
index be38cedc..89da7b7d 100644
--- a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
+++ b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
@@ -88,6 +88,26 @@ public sealed class ProviderOpenAI() : BaseProvider("https://api.openai.com/v1/"
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters("input", "store", "tools");
+
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => systemPromptRole,
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
//
// Create the request: either for the Responses API or the Chat Completion API
@@ -102,24 +122,7 @@ public sealed class ProviderOpenAI() : BaseProvider("https://api.openai.com/v1/"
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => systemPromptRole,
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
diff --git a/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs b/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
index a15a7e3a..3687ad7b 100644
--- a/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
+++ b/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
@@ -48,6 +48,26 @@ public sealed class ProviderPerplexity() : BaseProvider("https://api.perplexity.
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message()
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the Perplexity HTTP chat request:
var perplexityChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -56,24 +76,7 @@ public sealed class ProviderPerplexity() : BaseProvider("https://api.perplexity.
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
Stream = true,
AdditionalApiParameters = apiParameters
}, JSON_SERIALIZER_OPTIONS);
diff --git a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
index abb15532..4389099e 100644
--- a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
+++ b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
@@ -35,6 +35,26 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the OpenAI HTTP chat request:
var providerChatRequest = JsonSerializer.Serialize(new ChatRequest
{
@@ -43,24 +63,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,
diff --git a/app/MindWork AI Studio/Provider/X/ProviderX.cs b/app/MindWork AI Studio/Provider/X/ProviderX.cs
index b1743c53..e8a0b2e7 100644
--- a/app/MindWork AI Studio/Provider/X/ProviderX.cs
+++ b/app/MindWork AI Studio/Provider/X/ProviderX.cs
@@ -39,6 +39,26 @@ public sealed class ProviderX() : BaseProvider("https://api.x.ai/v1/", LOGGER)
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters();
+ // Build the list of messages:
+ var messages = await chatThread.Blocks.BuildMessages(async n => new Message()
+ {
+ Role = n.Role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ },
+
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareContentForAI(),
+ _ => string.Empty,
+ }
+ });
+
// Prepare the xAI HTTP chat request:
var xChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
{
@@ -47,24 +67,7 @@ public sealed class ProviderX() : BaseProvider("https://api.x.ai/v1/", LOGGER)
// Build the messages:
// - First of all the system prompt
// - Then none-empty user and AI messages
- Messages = [systemPrompt, ..chatThread.Blocks.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text)).Select(n => new Message
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => "system",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => text.Text,
- _ => string.Empty,
- }
- }).ToList()],
+ Messages = [systemPrompt, ..messages],
// Right now, we only support streaming completions:
Stream = true,