using ChatApi.Models; using ChatRAG.Contracts.VectorSearch; using ChatRAG.Models; using ChatRAG.Services.Contracts; using Microsoft.SemanticKernel.Embeddings; #pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. namespace ChatRAG.Services.ResponseService { public class MongoResponseService : IResponseService { private readonly ResponseRAGService _originalService; // Sua classe atual! private readonly IVectorSearchService _vectorSearchService; private readonly ITextEmbeddingGenerationService _embeddingService; private readonly TextFilter _textFilter; public MongoResponseService( ResponseRAGService originalService, IVectorSearchService vectorSearchService, ITextEmbeddingGenerationService embeddingService, TextFilter textFilter) { _originalService = originalService; _vectorSearchService = vectorSearchService; _embeddingService = embeddingService; _textFilter = textFilter; } public string ProviderName => "MongoDB"; // ======================================== // MÉTODO ORIGINAL - Delega para ResponseRAGService // ======================================== public async Task GetResponse(UserData userData, string projectId, string sessionId, string question) { return await _originalService.GetResponse(userData, projectId, sessionId, question); } // ======================================== // MÉTODO ESTENDIDO COM MAIS DETALHES // ======================================== public async Task GetResponseDetailed( UserData userData, string projectId, string sessionId, string question, ResponseOptions? options = null) { options ??= new ResponseOptions(); var stopwatch = System.Diagnostics.Stopwatch.StartNew(); // Gera embedding da pergunta var embeddingPergunta = await _embeddingService.GenerateEmbeddingAsync( _textFilter.ToLowerAndWithoutAccents(question)); var embeddingArray = embeddingPergunta.ToArray().Select(e => (double)e).ToArray(); var searchStart = stopwatch.ElapsedMilliseconds; // Busca documentos similares usando a interface var documentos = await _vectorSearchService.SearchSimilarDynamicAsync( embeddingArray, projectId, options.SimilarityThreshold, options.MaxContextDocuments); var searchTime = stopwatch.ElapsedMilliseconds - searchStart; var llmStart = stopwatch.ElapsedMilliseconds; // Chama o método original para gerar resposta var response = await _originalService.GetResponse(userData, projectId, sessionId, question); var llmTime = stopwatch.ElapsedMilliseconds - llmStart; stopwatch.Stop(); // Monta resultado detalhado return new ResponseResult { Content = response, Provider = "MongoDB", Sources = documentos.Select(d => new SourceDocument { Id = d.Id, Title = d.Title, Content = d.Content, Similarity = d.Score, Metadata = d.Metadata }).ToList(), Metrics = new ResponseMetrics { TotalTimeMs = stopwatch.ElapsedMilliseconds, SearchTimeMs = searchTime, LlmTimeMs = llmTime, DocumentsFound = documentos.Count, DocumentsUsed = documentos.Count, AverageSimilarity = documentos.Any() ? documentos.Average(d => d.Score) : 0 } }; } public async Task GetStatsAsync() { // Implementação básica - pode ser expandida return new ResponseStats { TotalRequests = 0, AverageResponseTime = 0, RequestsByProject = new Dictionary(), LastRequest = DateTime.UtcNow }; } } } #pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.