diff --git a/ChatbotApi/Constrollers/ChatController.cs b/ChatbotApi/Constrollers/ChatController.cs index 2a57e51..42c51d6 100644 --- a/ChatbotApi/Constrollers/ChatController.cs +++ b/ChatbotApi/Constrollers/ChatController.cs @@ -12,7 +12,21 @@ using System.Runtime.CompilerServices; using System.Text.Json; // Clases de Request/Response -public class GeminiRequest { [JsonPropertyName("contents")] public Content[] Contents { get; set; } = default!; } +public class GenerationConfig +{ + [JsonPropertyName("maxOutputTokens")] + public int MaxOutputTokens { get; set; } +} + +public class GeminiRequest +{ + [JsonPropertyName("contents")] + public Content[] Contents { get; set; } = default!; + + [JsonPropertyName("generationConfig")] + public GenerationConfig? GenerationConfig { get; set; } +} + public class Content { [JsonPropertyName("parts")] public Part[] Parts { get; set; } = default!; } public class Part { [JsonPropertyName("text")] public string Text { get; set; } = default!; } public class GeminiResponse { [JsonPropertyName("candidates")] public Candidate[] Candidates { get; set; } = default!; } @@ -36,7 +50,8 @@ namespace ChatbotApi.Controllers private static readonly string _siteUrl = "https://www.eldia.com/"; private static readonly string[] PrefijosAQuitar = { "VIDEO.- ", "VIDEO. ", "FOTOS.- ", "FOTOS. " }; - + const int OutTokens = 8192; + public ChatController(IConfiguration configuration, IMemoryCache memoryCache, IServiceProvider serviceProvider, ILogger logger) { _logger = logger; @@ -96,8 +111,8 @@ namespace ChatbotApi.Controllers [HttpPost("stream-message")] [EnableRateLimiting("fixed")] public async IAsyncEnumerable StreamMessage( - [FromBody] ChatRequest request, - [EnumeratorCancellation] CancellationToken cancellationToken) + [FromBody] ChatRequest request, + [EnumeratorCancellation] CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(request?.Message)) { @@ -110,9 +125,7 @@ namespace ChatbotApi.Controllers string promptInstructions = ""; string? articleContext = null; string? errorMessage = null; - - // --- CORRECCIÓN: Declarar e inicializar 'intent' aquí --- - IntentType intent = IntentType.Homepage; // Default fallback + IntentType intent = IntentType.Homepage; try { @@ -120,8 +133,7 @@ namespace ChatbotApi.Controllers { articleContext = await GetArticleContentAsync(request.ContextUrl); } - - // Ya no se declara con "IntentType intent", solo se le asigna el valor. + intent = await GetIntentAsync(userMessage, articleContext); switch (intent) @@ -151,11 +163,8 @@ namespace ChatbotApi.Controllers { _logger.LogError(ex, "Error al procesar la intención y el contexto."); errorMessage = "Error: Lo siento, estoy teniendo un problema técnico al procesar tu pregunta."; - context = string.Empty; - promptInstructions = string.Empty; } - // Ahora 'intent' es accesible aquí. yield return $"INTENT::{intent}"; if (!string.IsNullOrEmpty(errorMessage)) @@ -169,7 +178,7 @@ namespace ChatbotApi.Controllers { var promptBuilder = new StringBuilder(); promptBuilder.AppendLine("INSTRUCCIONES:"); - promptBuilder.AppendLine("Eres DiaBot, el asistente virtual del periódico El Día. Tu personalidad es profesional, servicial y concisa."); + promptBuilder.AppendLine("Eres DiaBot, el asistente virtual del periódico El Día. Tu personalidad es profesional, servicial y concisa. Responde siempre en español Rioplatense."); promptBuilder.AppendLine(promptInstructions); promptBuilder.AppendLine("NUNCA INVENTES información. Si la respuesta no está en el contexto, indica amablemente que no encontraste la información."); promptBuilder.AppendLine("\nCONTEXTO:\n---"); @@ -180,7 +189,13 @@ namespace ChatbotApi.Controllers string finalPrompt = promptBuilder.ToString(); var streamingApiUrl = _apiUrl; - var requestData = new GeminiRequest { Contents = new[] { new Content { Parts = new[] { new Part { Text = finalPrompt } } } } }; + + var requestData = new GeminiRequest + { + Contents = new[] { new Content { Parts = new[] { new Part { Text = finalPrompt } } } }, + GenerationConfig = new GenerationConfig { MaxOutputTokens = OutTokens } + }; + var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, streamingApiUrl); httpRequestMessage.Content = JsonContent.Create(requestData); @@ -189,17 +204,12 @@ namespace ChatbotApi.Controllers if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); - _logger.LogWarning("La API de Gemini (Streaming) devolvió un error. Status: {StatusCode}, Content: {ErrorContent}", response.StatusCode, errorContent); - throw new HttpRequestException("La API de Gemini devolvió un error."); + _logger.LogWarning("La API (Streaming) devolvió un error. Status: {StatusCode}, Content: {ErrorContent}", response.StatusCode, errorContent); + throw new HttpRequestException("La API devolvió un error."); } responseStream = await response.Content.ReadAsStreamAsync(cancellationToken); } - catch (TaskCanceledException) - { - _logger.LogInformation("La operación fue cancelada por el cliente durante la configuración del stream."); - yield break; - } catch (Exception ex) { _logger.LogError(ex, "Error inesperado durante la configuración del stream.");