diff --git a/app/MindWork AI Studio/Chat/ListContentBlockExtensions.cs b/app/MindWork AI Studio/Chat/ListContentBlockExtensions.cs
index 5c9883e7..5776ce51 100644
--- a/app/MindWork AI Studio/Chat/ListContentBlockExtensions.cs
+++ b/app/MindWork AI Studio/Chat/ListContentBlockExtensions.cs
@@ -1,4 +1,5 @@
using AIStudio.Provider;
+using AIStudio.Provider.OpenAI;
namespace AIStudio.Chat;
@@ -8,19 +9,44 @@ public static class ListContentBlockExtensions
/// Processes a list of content blocks by transforming them into a collection of message results asynchronously.
///
/// The list of content blocks to process.
- /// A function that transforms each content block into a message result asynchronously.
+ /// A function that transforms each content block into a message result asynchronously.
/// An asynchronous task that resolves to a list of transformed results.
- public static async Task> BuildMessages(this List blocks, Func> transformer)
+ public static async Task> BuildMessages(this List blocks, Func roleTransformer)
{
var messages = blocks
.Where(n => n.ContentType is ContentType.TEXT && !string.IsNullOrWhiteSpace((n.Content as ContentText)?.Text))
- .Select(transformer)
+ .Select(async n => new TextMessage
+ {
+ Role = roleTransformer(n.Role),
+ Content = n.Content switch
+ {
+ ContentText text => await text.PrepareTextContentForAI(),
+ _ => string.Empty,
+ }
+ })
.ToList();
// Await all messages:
await Task.WhenAll(messages);
// Select all results:
- return messages.Select(n => n.Result).ToList();
+ return messages.Select(n => n.Result).Cast().ToList();
}
+
+ ///
+ /// Processes a list of content blocks using standard role transformations to create message results asynchronously.
+ ///
+ /// The list of content blocks to process.
+ /// >An asynchronous task that resolves to a list of transformed message results.
+ public static async Task> BuildMessagesUsingStandardRoles(this List blocks) => await blocks.BuildMessages(StandardRoleTransformer);
+
+ private static string StandardRoleTransformer(ChatRole role) => role switch
+ {
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => "system",
+
+ _ => "user",
+ };
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs b/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
index 258fb309..92a13689 100644
--- a/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
+++ b/app/MindWork AI Studio/Provider/AlibabaCloud/ProviderAlibabaCloud.cs
@@ -40,24 +40,7 @@ public sealed class ProviderAlibabaCloud() : BaseProvider(LLMProviders.ALIBABA_C
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the AlibabaCloud HTTP chat request:
var alibabaCloudChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/Anthropic/ChatRequest.cs b/app/MindWork AI Studio/Provider/Anthropic/ChatRequest.cs
index d6df3990..7489c503 100644
--- a/app/MindWork AI Studio/Provider/Anthropic/ChatRequest.cs
+++ b/app/MindWork AI Studio/Provider/Anthropic/ChatRequest.cs
@@ -9,14 +9,11 @@ namespace AIStudio.Provider.Anthropic;
/// The chat messages.
/// The maximum number of tokens to generate.
/// Whether to stream the chat completion.
-/// The system prompt for the chat completion.
public readonly record struct ChatRequest(
string Model,
IList Messages,
int MaxTokens,
- bool Stream,
- string System
-)
+ bool Stream)
{
// Attention: The "required" modifier is not supported for [JsonExtensionData].
[JsonExtensionData]
diff --git a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
index 632609b0..d5fd9e15 100644
--- a/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
+++ b/app/MindWork AI Studio/Provider/Anthropic/ProviderAnthropic.cs
@@ -27,27 +27,18 @@ public sealed class ProviderAnthropic() : BaseProvider(LLMProviders.ANTHROPIC, "
if(!requestedSecret.Success)
yield break;
+ // Prepare the system prompt:
+ var systemPrompt = new TextMessage
+ {
+ Role = "system",
+ Content = chatThread.PrepareSystemPrompt(settingsManager, chatThread),
+ };
+
// Parse the API parameters:
var apiParameters = this.ParseAdditionalApiParameters("system");
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
-
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => await text.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Anthropic HTTP chat request:
var chatRequest = JsonSerializer.Serialize(new ChatRequest
@@ -55,9 +46,8 @@ public sealed class ProviderAnthropic() : BaseProvider(LLMProviders.ANTHROPIC, "
Model = chatModel.Id,
// Build the messages:
- Messages = [..messages],
+ Messages = [systemPrompt, ..messages],
- System = chatThread.PrepareSystemPrompt(settingsManager, chatThread),
MaxTokens = apiParameters.TryGetValue("max_tokens", out var value) && value is int intValue ? intValue : 4_096,
// Right now, we only support streaming completions:
diff --git a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
index 77c32867..697d4045 100644
--- a/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
+++ b/app/MindWork AI Studio/Provider/DeepSeek/ProviderDeepSeek.cs
@@ -40,24 +40,7 @@ public sealed class ProviderDeepSeek() : BaseProvider(LLMProviders.DEEP_SEEK, "h
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the DeepSeek HTTP chat request:
var deepSeekChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
index 2dc724d7..e423f009 100644
--- a/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
+++ b/app/MindWork AI Studio/Provider/Fireworks/ProviderFireworks.cs
@@ -40,24 +40,7 @@ public class ProviderFireworks() : BaseProvider(LLMProviders.FIREWORKS, "https:/
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Fireworks HTTP chat request:
var fireworksChatRequest = JsonSerializer.Serialize(new ChatRequest
diff --git a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
index da390e05..9d822f8c 100644
--- a/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
+++ b/app/MindWork AI Studio/Provider/GWDG/ProviderGWDG.cs
@@ -40,24 +40,7 @@ public sealed class ProviderGWDG() : BaseProvider(LLMProviders.GWDG, "https://ch
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the GWDG HTTP chat request:
var gwdgChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
index 1954af00..7a8f64b9 100644
--- a/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
+++ b/app/MindWork AI Studio/Provider/Google/ProviderGoogle.cs
@@ -40,24 +40,7 @@ public class ProviderGoogle() : BaseProvider(LLMProviders.GOOGLE, "https://gener
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Google HTTP chat request:
var geminiChatRequest = JsonSerializer.Serialize(new ChatRequest
diff --git a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
index 08bdd53b..e04de535 100644
--- a/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
+++ b/app/MindWork AI Studio/Provider/Groq/ProviderGroq.cs
@@ -40,24 +40,7 @@ public class ProviderGroq() : BaseProvider(LLMProviders.GROQ, "https://api.groq.
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the OpenAI HTTP chat request:
var groqChatRequest = JsonSerializer.Serialize(new ChatRequest
diff --git a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
index e5d0414e..d22abbd2 100644
--- a/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
+++ b/app/MindWork AI Studio/Provider/Helmholtz/ProviderHelmholtz.cs
@@ -40,24 +40,7 @@ public sealed class ProviderHelmholtz() : BaseProvider(LLMProviders.HELMHOLTZ, "
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Helmholtz HTTP chat request:
var helmholtzChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs b/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
index 3883b775..1ce7609f 100644
--- a/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
+++ b/app/MindWork AI Studio/Provider/HuggingFace/ProviderHuggingFace.cs
@@ -45,24 +45,7 @@ public sealed class ProviderHuggingFace : BaseProvider
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var message = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var message = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the HuggingFace HTTP chat request:
var huggingfaceChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
index 165a35a5..28562719 100644
--- a/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
+++ b/app/MindWork AI Studio/Provider/Mistral/ProviderMistral.cs
@@ -38,24 +38,7 @@ public sealed class ProviderMistral() : BaseProvider(LLMProviders.MISTRAL, "http
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Mistral HTTP chat request:
var mistralChatRequest = JsonSerializer.Serialize(new ChatRequest
diff --git a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
index ebdf4bb0..44480d3f 100644
--- a/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
+++ b/app/MindWork AI Studio/Provider/OpenAI/ProviderOpenAI.cs
@@ -90,23 +90,14 @@ public sealed class ProviderOpenAI() : BaseProvider(LLMProviders.OPEN_AI, "https
var apiParameters = this.ParseAdditionalApiParameters("input", "store", "tools");
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
+ var messages = await chatThread.Blocks.BuildMessages(role => role switch
{
- Role = n.Role switch
- {
- ChatRole.USER => "user",
- ChatRole.AI => "assistant",
- ChatRole.AGENT => "assistant",
- ChatRole.SYSTEM => systemPromptRole,
+ ChatRole.USER => "user",
+ ChatRole.AI => "assistant",
+ ChatRole.AGENT => "assistant",
+ ChatRole.SYSTEM => systemPromptRole,
- _ => "user",
- },
-
- Content = n.Content switch
- {
- ContentText text => await text.PrepareTextContentForAI(),
- _ => string.Empty,
- }
+ _ => "user",
});
//
diff --git a/app/MindWork AI Studio/Provider/OpenRouter/ProviderOpenRouter.cs b/app/MindWork AI Studio/Provider/OpenRouter/ProviderOpenRouter.cs
index 0f919b37..38267b6c 100644
--- a/app/MindWork AI Studio/Provider/OpenRouter/ProviderOpenRouter.cs
+++ b/app/MindWork AI Studio/Provider/OpenRouter/ProviderOpenRouter.cs
@@ -43,24 +43,7 @@ public sealed class ProviderOpenRouter() : BaseProvider(LLMProviders.OPEN_ROUTER
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the OpenRouter HTTP chat request:
var openRouterChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs b/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
index a4ab35c6..92a19cb1 100644
--- a/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
+++ b/app/MindWork AI Studio/Provider/Perplexity/ProviderPerplexity.cs
@@ -49,24 +49,7 @@ public sealed class ProviderPerplexity() : BaseProvider(LLMProviders.PERPLEXITY,
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage()
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the Perplexity HTTP chat request:
var perplexityChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest
diff --git a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
index 5a142090..b4849978 100644
--- a/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
+++ b/app/MindWork AI Studio/Provider/SelfHosted/ProviderSelfHosted.cs
@@ -36,24 +36,7 @@ public sealed class ProviderSelfHosted(Host host, string hostname) : BaseProvide
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the OpenAI HTTP chat request:
var providerChatRequest = JsonSerializer.Serialize(new ChatRequest
diff --git a/app/MindWork AI Studio/Provider/X/ProviderX.cs b/app/MindWork AI Studio/Provider/X/ProviderX.cs
index 67ea9f01..d1cc4544 100644
--- a/app/MindWork AI Studio/Provider/X/ProviderX.cs
+++ b/app/MindWork AI Studio/Provider/X/ProviderX.cs
@@ -40,24 +40,7 @@ public sealed class ProviderX() : BaseProvider(LLMProviders.X, "https://api.x.ai
var apiParameters = this.ParseAdditionalApiParameters();
// Build the list of messages:
- var messages = await chatThread.Blocks.BuildMessages(async n => new TextMessage
- {
- 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.PrepareTextContentForAI(),
- _ => string.Empty,
- }
- });
+ var messages = await chatThread.Blocks.BuildMessagesUsingStandardRoles();
// Prepare the xAI HTTP chat request:
var xChatRequest = JsonSerializer.Serialize(new ChatCompletionAPIRequest