DeutschLernen/GermanApp/Infrastructure/Configuration/MistralConfig.cs
Lasse Rune Hansen aa3db295ce fix(backend): Fix Mistral story generation with proper chat completion format
- Update MistralChatRequest to remove unused properties (User, Stop, FrequencyPenalty, PresencePenalty) causing 422 errors
- Add explicit JsonPropertyName attributes to ensure correct JSON serialization
- Update MistralService to send minimal requests matching Mistral API expectations
- Pass SegmentCount and CustomPrompt through StoryGenerationService to build proper prompts
- Add request logging in MistralConnector to debug API calls
- Update default model to mistral-small-latest
- Enhance error handling to log raw JSON responses

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-18 15:21:04 +02:00

119 lines
3.4 KiB
C#

namespace GermanApp.Infrastructure.Configuration;
/// <summary>
/// Configuration settings for Mistral API connector.
/// This is part of the Infrastructure layer.
/// </summary>
public class MistralConfig
{
/// <summary>
/// The Mistral API key for authentication.
/// </summary>
public string ApiKey { get; set; } = string.Empty;
/// <summary>
/// The base URL for the Mistral API.
/// Default: https://api.mistral.ai/v1/
/// </summary>
public string BaseUrl { get; set; } = "https://api.mistral.ai/v1/";
/// <summary>
/// The default model to use for completions.
/// Default: mistral-small-latest
/// </summary>
public string DefaultModel { get; set; } = "mistral-small-latest";
/// <summary>
/// Timeout in seconds for HTTP requests.
/// Default: 30 seconds
/// </summary>
public int TimeoutSeconds { get; set; } = 30;
/// <summary>
/// Maximum number of retry attempts for failed requests.
/// Default: 3
/// </summary>
public int MaxRetries { get; set; } = 3;
/// <summary>
/// Maximum requests per minute rate limit.
/// Default: 10 requests/minute
/// </summary>
public int RateLimitPerMinute { get; set; } = 10;
/// <summary>
/// Whether to enable response caching.
/// Default: true
/// </summary>
public bool EnableCaching { get; set; } = true;
/// <summary>
/// Cache time-to-live in minutes.
/// Default: 60 minutes
/// </summary>
public int CacheTTLMinutes { get; set; } = 60;
/// <summary>
/// Circuit breaker failure threshold (number of consecutive failures before opening).
/// Default: 5
/// </summary>
public int CircuitBreakerFailureThreshold { get; set; } = 5;
/// <summary>
/// Circuit breaker reset timeout in minutes.
/// Default: 1 minute
/// </summary>
public int CircuitBreakerResetMinutes { get; set; } = 1;
/// <summary>
/// Validates the configuration.
/// </summary>
/// <exception cref="ArgumentException">Thrown when configuration is invalid</exception>
public void Validate()
{
if (string.IsNullOrWhiteSpace(ApiKey))
{
throw new ArgumentException("Mistral API key is required");
}
if (string.IsNullOrWhiteSpace(BaseUrl))
{
throw new ArgumentException("Mistral BaseUrl is required");
}
if (!Uri.TryCreate(BaseUrl, UriKind.Absolute, out _))
{
throw new ArgumentException("Mistral BaseUrl must be a valid URL");
}
if (TimeoutSeconds <= 0)
{
throw new ArgumentException("TimeoutSeconds must be greater than 0");
}
if (MaxRetries < 0)
{
throw new ArgumentException("MaxRetries must be non-negative");
}
if (RateLimitPerMinute <= 0)
{
throw new ArgumentException("RateLimitPerMinute must be greater than 0");
}
if (CacheTTLMinutes < 0)
{
throw new ArgumentException("CacheTTLMinutes must be non-negative");
}
if (CircuitBreakerFailureThreshold <= 0)
{
throw new ArgumentException("CircuitBreakerFailureThreshold must be greater than 0");
}
if (CircuitBreakerResetMinutes <= 0)
{
throw new ArgumentException("CircuitBreakerResetMinutes must be greater than 0");
}
}
}