Added the possibility to attach files to the chat (#585)
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions

Co-authored-by: Thorsten Sommer
This commit is contained in:
Sabrina-devopsandThorsten Sommer authored and GitHub committed 2025-12-10 13:48:13 +01:00
1 parent 0aff45eca3
commit f521c11a60
33 files changed
+579 -280

No files matched your search

@@ -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);
@@ -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,
@@ -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);
@@ -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,
@@ -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);
@@ -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,
@@ -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,
@@ -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);
@@ -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);
@@ -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<HttpRequestMessage> RequestBuilder()
{
// Build the HTTP post request:
@@ -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,
@@ -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);
@@ -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,
+21 -18
View File
@@ -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,