using GermanApp.Domain.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace GermanApp.Presentation.Controllers;
///
/// API controller for Mistral AI text generation.
/// This is part of the Presentation layer.
///
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class MistralController : ControllerBase
{
private readonly IMistralService _mistralService;
public MistralController(IMistralService mistralService)
{
_mistralService = mistralService;
}
///
/// Generates text from a prompt.
///
/// Text generation request
/// Cancellation token
/// Generated text
[HttpPost("generate")]
public async Task GenerateText(
[FromBody] TextGenerationRequest request,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(request.Prompt))
return BadRequest("Prompt is required");
try
{
var result = await _mistralService.GenerateTextAsync(
request.Prompt,
request.Model,
request.Temperature,
request.MaxTokens,
cancellationToken);
return Ok(new TextGenerationResponse(result));
}
catch (Exception ex)
{
return StatusCode(500, new { Error = ex.Message });
}
}
///
/// Generates text from chat messages.
///
/// Chat generation request
/// Cancellation token
/// Generated text
[HttpPost("chat")]
public async Task GenerateChat(
[FromBody] ChatGenerationRequest request,
CancellationToken cancellationToken = default)
{
if (request.Messages == null || request.Messages.Count == 0)
return BadRequest("Messages are required");
try
{
var result = await _mistralService.GenerateChatAsync(
request.Messages,
request.Model,
request.Temperature,
request.MaxTokens,
cancellationToken);
return Ok(new TextGenerationResponse(result));
}
catch (Exception ex)
{
return StatusCode(500, new { Error = ex.Message });
}
}
///
/// Generates a story based on lesson context.
///
/// Story generation request
/// Cancellation token
/// Generated story
[HttpPost("story")]
public async Task GenerateStory(
[FromBody] StoryGenerationRequest request,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(request.Level))
return BadRequest("Level is required");
try
{
var result = await _mistralService.GenerateStoryAsync(
request.Level,
request.Topic ?? string.Empty,
request.VocabularyWords ?? new List(),
request.Length,
cancellationToken);
return Ok(new StoryGenerationResponse(result));
}
catch (Exception ex)
{
return StatusCode(500, new { Error = ex.Message });
}
}
///
/// Provides feedback on user writing.
///
/// Writing feedback request
/// Cancellation token
/// Generated feedback
[HttpPost("writing-feedback")]
public async Task GenerateWritingFeedback(
[FromBody] WritingFeedbackRequest request,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(request.UserText))
return BadRequest("User text is required");
if (string.IsNullOrWhiteSpace(request.Level))
return BadRequest("Level is required");
try
{
var result = await _mistralService.GenerateWritingFeedbackAsync(
request.UserText,
request.Level,
request.Prompt,
cancellationToken);
return Ok(new WritingFeedbackResponse(result));
}
catch (Exception ex)
{
return StatusCode(500, new { Error = ex.Message });
}
}
///
/// Tests the Mistral API connection.
///
/// Health check result
[HttpGet("health")]
[AllowAnonymous]
public async Task HealthCheck(CancellationToken cancellationToken = default)
{
try
{
var isHealthy = await _mistralService.TestConnectionAsync(cancellationToken);
return Ok(new { Healthy = isHealthy });
}
catch (Exception ex)
{
return StatusCode(500, new { Error = ex.Message });
}
}
}
///
/// Request DTO for text generation.
///
public record TextGenerationRequest(
string Prompt,
string? Model = null,
float Temperature = 0.7f,
int? MaxTokens = null);
///
/// Request DTO for chat generation.
///
public record ChatGenerationRequest(
IReadOnlyList<(string Role, string Content)> Messages,
string? Model = null,
float Temperature = 0.7f,
int? MaxTokens = null);
///
/// Request DTO for story generation.
///
public record StoryGenerationRequest(
string Level,
string? Topic = null,
IReadOnlyList? VocabularyWords = null,
int Length = 200);
///
/// Request DTO for writing feedback.
///
public record WritingFeedbackRequest(
string UserText,
string Level,
string? Prompt = null);
///
/// Response DTO for text generation.
///
public record TextGenerationResponse(string Text);
///
/// Response DTO for story generation.
///
public record StoryGenerationResponse(string Story);
///
/// Response DTO for writing feedback.
///
public record WritingFeedbackResponse(string Feedback);