DeutschLernen/GermanApp/Application/Models/MistralRequest.cs
Lasse Rune Hansen 2b11367a97
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
feat(backend/infrastructure): implement Mistral API Connector (Phase 0 of AI Services)
- Add Domain/Interfaces/IMistralConnector.cs with AiServiceException and AiErrorCode enum
- Add Infrastructure/Configuration/MistralConfig.cs with validation
- Add Infrastructure/Services/MistralConnector.cs with HTTP client implementation
- Add Infrastructure/Services/MistralRateLimiter.cs for rate limiting
- Add Infrastructure/Services/MistralCircuitBreaker.cs for circuit breaker pattern
- Add Application/Models/MistralRequest.cs with request models
- Add Application/Models/MistralResponse.cs with response models
- Update Program.cs to register IMistralConnector with MemoryCache, HttpClient, and config
- Update GermanApp.csproj with existing dependencies
- Update docs/features/ai-services.md with Phase 0 completion

Phase 0 of AI Services feature is complete. Mistral API Connector is ready for use by MistralService.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-09 18:56:37 +02:00

236 lines
7 KiB
C#

namespace GermanApp.Application.Models;
/// <summary>
/// Request model for Mistral completion API.
/// Used for text generation (stories, feedback, etc.).
/// </summary>
/// <remarks>
/// See: https://docs.mistral.ai/api/#operation/createCompletion
/// </remarks>
public record MistralRequest
{
/// <summary>
/// ID of the model to use.
/// </summary>
public string Model { get; init; } = "mistral-medium";
/// <summary>
/// The prompt(s) to generate completions for.
/// </summary>
public string Prompt { get; init; } = string.Empty;
/// <summary>
/// The maximum number of tokens to generate in the completion.
/// Default: 256, Max: 2048 for mistral-medium
/// </summary>
public int? MaxTokens { get; init; } = 512;
/// <summary>
/// What sampling temperature to use.
/// Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 for ones with a well-defined answer.
/// Default: 0.7
/// </summary>
public double? Temperature { get; init; } = 0.7;
/// <summary>
/// Nucleus sampling, where the model considers the results of the tokens with top_p probability mass.
/// So 0.1 means only the tokens comprising the top 10% probability mass are considered.
/// Default: 1.0
/// </summary>
public double? TopP { get; init; } = 1.0;
/// <summary>
/// How many completions to generate for each prompt.
/// Default: 1
/// </summary>
public int? N { get; init; } = 1;
/// <summary>
/// Whether to stream partial responses.
/// Not supported by this connector (use streaming endpoint separately if needed).
/// </summary>
public bool? Stream { get; init; } = false;
/// <summary>
/// Whether to echo the prompt in the response.
/// Default: false
/// </summary>
public bool? Echo { get; init; } = false;
/// <summary>
/// Up to 4 sequences where the API will stop generating further tokens.
/// </summary>
public IReadOnlyList<string>? Stop { get; init; }
/// <summary>
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on their frequency in the text so far.
/// </summary>
public double? FrequencyPenalty { get; init; }
/// <summary>
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far.
/// </summary>
public double? PresencePenalty { get; init; }
/// <summary>
/// User identifier for tracking usage.
/// </summary>
public string? User { get; init; }
/// <summary>
/// Factory method to create a completion request with default settings.
/// </summary>
public static MistralRequest CreateCompletion(string prompt, string model = "mistral-medium", int maxTokens = 512)
{
return new MistralRequest
{
Model = model,
Prompt = prompt,
MaxTokens = maxTokens,
Temperature = 0.7,
TopP = 1.0,
N = 1,
Stream = false,
Echo = false
};
}
}
/// <summary>
/// Request model for Mistral chat completion API.
/// Used for conversational text generation.
/// </summary>
/// <remarks>
/// See: https://docs.mistral.ai/api/#operation/createChatCompletion
/// </remarks>
public record MistralChatRequest
{
/// <summary>
/// ID of the model to use.
/// </summary>
public string Model { get; init; } = "mistral-medium";
/// <summary>
/// A list of messages comprising the conversation so far.
/// </summary>
public IReadOnlyList<MistralMessage> Messages { get; init; } = new List<MistralMessage>();
/// <summary>
/// The maximum number of tokens to generate in the completion.
/// </summary>
public int? MaxTokens { get; init; } = 512;
/// <summary>
/// What sampling temperature to use.
/// </summary>
public double? Temperature { get; init; } = 0.7;
/// <summary>
/// Nucleus sampling.
/// </summary>
public double? TopP { get; init; } = 1.0;
/// <summary>
/// How many chat completions to generate for each input message.
/// </summary>
public int? N { get; init; } = 1;
/// <summary>
/// Whether to stream partial responses.
/// </summary>
public bool? Stream { get; init; } = false;
/// <summary>
/// Up to 4 sequences where the API will stop generating further tokens.
/// </summary>
public IReadOnlyList<string>? Stop { get; init; }
/// <summary>
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on their frequency.
/// </summary>
public double? FrequencyPenalty { get; init; }
/// <summary>
/// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear.
/// </summary>
public double? PresencePenalty { get; init; }
/// <summary>
/// User identifier for tracking usage.
/// </summary>
public string? User { get; init; }
/// <summary>
/// Factory method to create a chat request.
/// </summary>
public static MistralChatRequest CreateChat(IReadOnlyList<MistralMessage> messages, string model = "mistral-medium", int maxTokens = 512)
{
return new MistralChatRequest
{
Model = model,
Messages = messages,
MaxTokens = maxTokens,
Temperature = 0.7,
TopP = 1.0,
N = 1,
Stream = false
};
}
}
/// <summary>
/// Represents a message in a Mistral chat conversation.
/// </summary>
public record MistralMessage
{
/// <summary>
/// The role of the message author.
/// </summary>
public string Role { get; init; } = string.Empty;
/// <summary>
/// The content of the message.
/// </summary>
public string Content { get; init; } = string.Empty;
/// <summary>
/// Factory method to create a user message.
/// </summary>
public static MistralMessage User(string content) => new() { Role = "user", Content = content };
/// <summary>
/// Factory method to create an assistant message.
/// </summary>
public static MistralMessage Assistant(string content) => new() { Role = "assistant", Content = content };
/// <summary>
/// Factory method to create a system message.
/// </summary>
public static MistralMessage System(string content) => new() { Role = "system", Content = content };
}
/// <summary>
/// Model information from Mistral API.
/// </summary>
public record MistralModel
{
/// <summary>
/// The model identifier.
/// </summary>
public string Id { get; init; } = string.Empty;
/// <summary>
/// The model object type.
/// </summary>
public string Object { get; init; } = string.Empty;
/// <summary>
/// When the model was created.
/// </summary>
public long Created { get; init; }
/// <summary>
/// The model's description.
/// </summary>
public string Description { get; init; } = string.Empty;
}