DeutschLernen/GermanApp/Domain/Interfaces/IMistralConnector.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

102 lines
3.8 KiB
C#

using GermanApp.Application.Models;
namespace GermanApp.Domain.Interfaces;
/// <summary>
/// Interface for Mistral API connector.
/// This is part of the Domain layer - defines the contract for communicating with Mistral API.
/// </summary>
public interface IMistralConnector
{
/// <summary>
/// Sends a completion request to Mistral API.
/// </summary>
/// <param name="request">The completion request containing prompt and parameters</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Mistral API response containing generated text</returns>
/// <exception cref="AiServiceException">Thrown when Mistral API request fails</exception>
Task<MistralResponse> CompleteAsync(MistralRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// Sends a chat completion request to Mistral API.
/// </summary>
/// <param name="request">The chat completion request containing messages and parameters</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Mistral API chat response containing generated message</returns>
/// <exception cref="AiServiceException">Thrown when Mistral API request fails</exception>
Task<MistralResponse> ChatAsync(MistralChatRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// Lists available models from Mistral API.
/// </summary>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>List of available Mistral models</returns>
/// <exception cref="AiServiceException">Thrown when Mistral API request fails</exception>
Task<IReadOnlyList<MistralModel>> ListModelsAsync(
CancellationToken cancellationToken = default);
/// <summary>
/// Gets information about a specific model.
/// </summary>
/// <param name="modelId">The model identifier</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Information about the specified model</returns>
/// <exception cref="AiServiceException">Thrown when Mistral API request fails</exception>
Task<MistralModel> GetModelAsync(string modelId,
CancellationToken cancellationToken = default);
}
/// <summary>
/// Custom exception for AI service errors.
/// </summary>
public class AiServiceException : Exception
{
/// <summary>
/// Error code for categorizing AI service errors.
/// </summary>
public AiErrorCode ErrorCode { get; }
/// <summary>
/// Creates a new AI service exception.
/// </summary>
public AiServiceException(string message, AiErrorCode errorCode = AiErrorCode.Unknown)
: base(message)
{
ErrorCode = errorCode;
}
/// <summary>
/// Creates a new AI service exception with inner exception.
/// </summary>
public AiServiceException(string message, Exception innerException,
AiErrorCode errorCode = AiErrorCode.Unknown)
: base(message, innerException)
{
ErrorCode = errorCode;
}
}
/// <summary>
/// Error codes for AI service exceptions.
/// </summary>
public enum AiErrorCode
{
/// <summary>Unknown or unspecified error</summary>
Unknown = 0,
/// <summary>API rate limit exceeded</summary>
RateLimited = 1,
/// <summary>Temporary API failure, may succeed on retry</summary>
Temporary = 2,
/// <summary>Request timeout</summary>
Timeout = 3,
/// <summary>Invalid API key or authentication error</summary>
AuthenticationError = 4,
/// <summary>Invalid request parameters</summary>
InvalidRequest = 5,
/// <summary>API returned invalid/empty response</summary>
InvalidResponse = 6,
/// <summary>Service is temporarily unavailable (circuit breaker open)</summary>
ServiceUnavailable = 7
}