diff --git a/pom.xml b/pom.xml
index 9b199f9..dad285d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.3.0
+ 3.3.11
@@ -21,6 +21,7 @@
5.4.0
2023.0.0
6.4.0.RELEASE
+ 6.1.20
@@ -46,6 +47,13 @@
pom
import
+
+ io.projectreactor
+ reactor-bom
+ 2024.0.8
+ pom
+ import
+
@@ -91,7 +99,7 @@
com.google.genai
google-genai
- 1.13.0
+ 1.14.0
com.google.protobuf
@@ -126,13 +134,49 @@
io.netty
netty-codec-http2
- 4.1.124.Final
+ 4.1.125.Final
+
+
+ io.netty
+ netty-handler
+ 4.1.125.Final
+
+
+ io.netty
+ netty-common
+ 4.1.125.Final
+
+
+ io.netty
+ netty-codec-http
+ 4.1.125.Final
+
+
+ io.netty
+ netty-codec
+ 4.1.125.Final
com.google.protobuf
protobuf-java
3.25.5
+
+ net.minidev
+ json-smart
+ 2.5.2
+
+
+ org.xmlunit
+ xmlunit-core
+ 2.10.0
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ 3.18.0
+
diff --git a/src/main/java/com/example/controller/ConversationSummaryController.java b/src/main/java/com/example/controller/ConversationSummaryController.java
deleted file mode 100644
index e73e1b5..0000000
--- a/src/main/java/com/example/controller/ConversationSummaryController.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.controller;
-
-import com.example.dto.gemini.ConversationSummaryRequest;
-import com.example.dto.gemini.ConversationSummaryResponse;
-import com.example.service.summary.ConversationSummaryService;
-
-import jakarta.validation.Valid;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@RestController
-@RequestMapping("/api/v1/summary")
-public class ConversationSummaryController {
-
- private static final Logger logger = LoggerFactory.getLogger(ConversationSummaryController.class);
- private final ConversationSummaryService conversationSummaryService;
-
- public ConversationSummaryController(ConversationSummaryService conversationSummaryService) {
- this.conversationSummaryService = conversationSummaryService;
- }
-
-
- @PostMapping("/conversation")
- public ResponseEntity summarizeConversation(
- @Valid @RequestBody ConversationSummaryRequest request) {
-
- logger.info("Received request to summarize conversation for session ID: {}",
- request.sessionId());
-
- ConversationSummaryResponse response = conversationSummaryService.summarizeConversation(request);
-
- if (response.summaryText() != null &&
- (response.summaryText().contains("Error:") ||
- response.summaryText().contains("Failed:") ||
- response.summaryText().contains("not found") ||
- response.summaryText().contains("No conversation provided"))) {
- logger.error("Summarization failed for session ID {}: {}", request.sessionId(), response.summaryText());
- return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
- } else {
- logger.info("Successfully processed summarization request for session ID: {}", request.sessionId());
- return ResponseEntity.ok(response);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java b/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java
deleted file mode 100644
index a98acec..0000000
--- a/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.dto.gemini;
-
-import com.example.dto.dialogflow.conversation.ConversationEntryEntity;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.cloud.Timestamp;
-import java.util.Map;
-import java.util.Optional;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record ConversationEntrySummaryDTO(
- @JsonProperty("text") String text,
- @JsonProperty("timestamp") Timestamp timestamp,
- Optional type,
- @JsonProperty("intentDisplayName") String intentDisplayName,
- @JsonProperty("parameters") Map parameters,
- @JsonProperty("webhookStatus") String webhookStatus,
- @JsonProperty("canal") String canal
-) {
- @JsonCreator
- public ConversationEntrySummaryDTO(
- @JsonProperty("text") String text,
- @JsonProperty("timestamp") Timestamp timestamp,
- @JsonProperty("type") String typeString,
- @JsonProperty("intentDisplayName") String intentDisplayName,
- @JsonProperty("parameters") Map parameters,
- @JsonProperty("webhookStatus") String webhookStatus,
- @JsonProperty("canal") String canal
- ) {
- this(
- text,
- timestamp,
- Optional.ofNullable(typeString).map(t -> {
- try {
- return ConversationEntryEntity.valueOf(t);
- } catch (IllegalArgumentException e) {
- System.err.println("Warning: Invalid ConversationEntryType string during deserialization: " + t);
- return null;
- }
- }),
- intentDisplayName,
- parameters,
- webhookStatus,
- canal
- );
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java b/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java
deleted file mode 100644
index 5168cba..0000000
--- a/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.dto.gemini;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.cloud.Timestamp;
-import java.util.Collections;
-import java.util.List;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record ConversationSessionSummaryDTO(
- @JsonProperty("sessionId") String sessionId,
- @JsonProperty("userId") String userId,
- @JsonProperty("startTime") Timestamp startTime,
- @JsonProperty("lastUpdated") Timestamp lastUpdated,
- @JsonProperty("entries") List entries
-) {
- @JsonCreator
- public ConversationSessionSummaryDTO(
- @JsonProperty("sessionId") String sessionId,
- @JsonProperty("userId") String userId,
- @JsonProperty("startTime") Timestamp startTime,
- @JsonProperty("lastUpdated") Timestamp lastUpdated,
- @JsonProperty("entries") List entries
- ) {
- this.sessionId = sessionId;
- this.userId = userId;
- this.startTime = startTime;
- this.lastUpdated = lastUpdated;
- this.entries = entries != null ? entries : Collections.emptyList();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java b/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java
deleted file mode 100644
index 7e71f5f..0000000
--- a/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.dto.gemini;
-
-import jakarta.validation.constraints.DecimalMax;
-import jakarta.validation.constraints.DecimalMin;
-import jakarta.validation.constraints.NotBlank;
-
-public record ConversationSummaryRequest(
- @NotBlank(message = "Session ID is required.")
- String sessionId,
- @NotBlank(message = "Prompt for summarization is required.")
- String prompt,
- @DecimalMin(value = "0.0", message = "Temperature must be between 0.0 and 1.0.")
- @DecimalMax(value = "0.1", message = "Temperature must be between 0.0 and 1.0.")
- Float temperature,
- @DecimalMin(value = "0.1", message = "Max Output Tokens must be at least 1.")
- Integer maxOutputTokens,
- @NotBlank(message = "model is required.")
- String modelName,
- @NotBlank(message = "topP is required.")
- @DecimalMin(value = "0.0", message = "topP must be between 0.0 and 1.0.")
- Float top_P
-
-
-) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java b/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java
deleted file mode 100644
index b7d0a2f..0000000
--- a/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.dto.gemini;
-
-import jakarta.validation.constraints.NotBlank;
-
-public record ConversationSummaryResponse(
- @NotBlank
- String summaryText
-) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/mapper/conversation/ExternalConvRequestMapper.java b/src/main/java/com/example/mapper/conversation/ExternalConvRequestMapper.java
index 5cd0876..730e2c1 100644
--- a/src/main/java/com/example/mapper/conversation/ExternalConvRequestMapper.java
+++ b/src/main/java/com/example/mapper/conversation/ExternalConvRequestMapper.java
@@ -48,12 +48,11 @@ public class ExternalConvRequestMapper {
&& !externalRequest.user().telefono().isBlank()) {
primaryPhoneNumber = externalRequest.user().telefono();
parameters.put("telefono", primaryPhoneNumber);
- logger.debug("Mapped 'telefono' from external request: {}", primaryPhoneNumber);
}
if (primaryPhoneNumber == null || primaryPhoneNumber.isBlank()) {
throw new IllegalArgumentException(
- "Phone number (telefono) is required in the 'usuario' field for conversation management.");
+ "Phone number is required in the 'usuario' field for conversation management.");
}
String resolvedUserId = null;
diff --git a/src/main/java/com/example/mapper/notification/ExternalNotRequestMapper.java b/src/main/java/com/example/mapper/notification/ExternalNotRequestMapper.java
index 39077b6..1f42f87 100644
--- a/src/main/java/com/example/mapper/notification/ExternalNotRequestMapper.java
+++ b/src/main/java/com/example/mapper/notification/ExternalNotRequestMapper.java
@@ -39,7 +39,7 @@ public class ExternalNotRequestMapper {
Objects.requireNonNull(request, "NotificationRequestDTO cannot be null for mapping.");
if (request.phoneNumber() == null || request.phoneNumber().isEmpty()) {
- throw new IllegalArgumentException("List of 'telefonos' (phone numbers) is required and cannot be empty in NotificationRequestDTO.");
+ throw new IllegalArgumentException("Phone numbers is required and cannot be empty in NotificationRequestDTO.");
}
String phoneNumber = request.phoneNumber();
diff --git a/src/main/java/com/example/service/base/MessageEntryFilter.java b/src/main/java/com/example/service/base/MessageEntryFilter.java
index 3fd25ad..d55bc49 100644
--- a/src/main/java/com/example/service/base/MessageEntryFilter.java
+++ b/src/main/java/com/example/service/base/MessageEntryFilter.java
@@ -104,7 +104,7 @@ public class MessageEntryFilter {
String resultCategory = switch (geminiResponse != null ? geminiResponse.trim().toUpperCase() : "") {
case CATEGORY_CONVERSATION -> {
logger.info("Classified as {}. Input: '{}'", CATEGORY_CONVERSATION);
- logger.debug("Classified as {}. Input: '{}'", CATEGORY_CONVERSATION, queryInputText);
+ logger.debug("Classified as {}. Input: '{}'", CATEGORY_CONVERSATION, queryInputText);
yield CATEGORY_CONVERSATION;
}
case CATEGORY_NOTIFICATION -> {
diff --git a/src/main/java/com/example/service/conversation/FirestoreConversationService.java b/src/main/java/com/example/service/conversation/FirestoreConversationService.java
index 89c6f03..7c09ebf 100644
--- a/src/main/java/com/example/service/conversation/FirestoreConversationService.java
+++ b/src/main/java/com/example/service/conversation/FirestoreConversationService.java
@@ -104,7 +104,6 @@ public class FirestoreConversationService {
}
public Mono getSessionByTelefono(String userPhoneNumber) {
- logger.info("Attempting to retrieve conversation session for phone number {}.", userPhoneNumber);
return firestoreBaseRepository.getDocumentsByField(getConversationCollectionPath(), "userPhoneNumber", userPhoneNumber)
.map(documentSnapshot -> {
if (documentSnapshot != null && documentSnapshot.exists()) {
@@ -112,7 +111,6 @@ public class FirestoreConversationService {
logger.info("Successfully retrieved and mapped conversation session for session {}.", sessionDTO.sessionId());
return sessionDTO;
}
- logger.info("Conversation session not found for phone number {}.", userPhoneNumber);
return null;
});
}
diff --git a/src/main/java/com/example/service/conversation/MemoryStoreConversationService.java b/src/main/java/com/example/service/conversation/MemoryStoreConversationService.java
index 4a989fd..6410f50 100644
--- a/src/main/java/com/example/service/conversation/MemoryStoreConversationService.java
+++ b/src/main/java/com/example/service/conversation/MemoryStoreConversationService.java
@@ -88,20 +88,18 @@ public class MemoryStoreConversationService {
return Mono.empty();
}
String phoneToSessionKey = PHONE_TO_SESSION_KEY_PREFIX + telefono;
- logger.debug("Attempting to retrieve session ID for phone number {} from Memorystore.", telefono);
return stringRedisTemplate.opsForValue().get(phoneToSessionKey)
.flatMap(sessionId -> {
- logger.debug("Found session ID {} for phone number {}. Retrieving session data.", sessionId, telefono);
return redisTemplate.opsForValue().get(SESSION_KEY_PREFIX + sessionId);
})
.doOnSuccess(session -> {
if (session != null) {
- logger.info("Successfully retrieved session {} by phone number {}.", session.sessionId(), telefono);
+ logger.info("Successfully retrieved session by phone number");
} else {
- logger.info("No session found in Redis for phone number {}.", telefono);
+ logger.info("No session found in Redis for phone number.");
}
})
- .doOnError(e -> logger.error("Error retrieving session by phone number {}: {}", telefono, e.getMessage(), e));
+ .doOnError(e -> logger.error("Error retrieving session by phone number: {}", e));
}
public Mono updateSession(ConversationSessionDTO session) {
diff --git a/src/main/java/com/example/service/notification/FirestoreNotificationService.java b/src/main/java/com/example/service/notification/FirestoreNotificationService.java
index 3d53760..b741521 100644
--- a/src/main/java/com/example/service/notification/FirestoreNotificationService.java
+++ b/src/main/java/com/example/service/notification/FirestoreNotificationService.java
@@ -95,12 +95,11 @@ public class FirestoreNotificationService {
}
} catch (ExecutionException e) {
logger.error(
- "Error saving notification to Firestore for phone {}: {}",
- phoneNumber,
+ "Error saving notification to Firestore for phone: {}",
e.getMessage(),
e);
throw new FirestorePersistenceException(
- "Failed to save notification to Firestore for phone " + phoneNumber, e);
+ "Failed to save notification to Firestore for phone ", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
logger.error(
@@ -109,7 +108,7 @@ public class FirestoreNotificationService {
e.getMessage(),
e);
throw new FirestorePersistenceException(
- "Saving notification was interrupted for phone " + phoneNumber, e);
+ "Saving notification was interrupted for phone ", e);
}
}
})
diff --git a/src/main/java/com/example/service/notification/MemoryStoreNotificationService.java b/src/main/java/com/example/service/notification/MemoryStoreNotificationService.java
index 29e6fe1..4475a0f 100644
--- a/src/main/java/com/example/service/notification/MemoryStoreNotificationService.java
+++ b/src/main/java/com/example/service/notification/MemoryStoreNotificationService.java
@@ -111,12 +111,12 @@ public class MemoryStoreNotificationService {
return stringRedisTemplate.opsForValue().get(key)
.doOnSuccess(sessionId -> {
if (sessionId != null) {
- logger.info("Session ID {} found for phone {}.", sessionId, phone);
+ logger.info("Session ID {} found for phone.", sessionId);
} else {
- logger.debug("Session ID not found for phone {}.", phone);
+ logger.debug("Session ID not found for phone.");
}
})
- .doOnError(e -> logger.error("Error retrieving session ID for phone {} from MemoryStore: {}", phone,
+ .doOnError(e -> logger.error("Error retrieving session ID for phone from MemoryStore: {}",
e.getMessage(), e));
}
@@ -144,19 +144,18 @@ public class MemoryStoreNotificationService {
return Mono.empty();
}
String phoneToSessionKey = PHONE_TO_CONVERSATION_SESSION_KEY_PREFIX + telefono;
- logger.debug("Attempting to retrieve session ID for phone number {} from Redis.", telefono);
return stringRedisTemplate.opsForValue().get(phoneToSessionKey)
.flatMap(sessionId -> {
- logger.debug("Found session ID {} for phone number {}. Retrieving session data.", sessionId, telefono);
+ logger.debug("Found session ID {} for phone number. Retrieving session data.", sessionId);
return conversationRedisTemplate.opsForValue().get(CONVERSATION_SESSION_KEY_PREFIX + sessionId);
})
.doOnSuccess(session -> {
if (session != null) {
- logger.info("Successfully retrieved session {} by phone number {}.", session.sessionId(), telefono);
+ logger.info("Successfully retrieved session {} by phone number.", session.sessionId());
} else {
- logger.info("No session found in Redis for phone number {}.", telefono);
+ logger.info("No session found in Redis for phone number.");
}
})
- .doOnError(e -> logger.error("Error retrieving session by phone number {}: {}", telefono, e.getMessage(), e));
+ .doOnError(e -> logger.error("Error retrieving session by phone number: {}",e.getMessage(), e));
}
}
\ No newline at end of file
diff --git a/src/main/java/com/example/service/notification/NotificationManagerService.java b/src/main/java/com/example/service/notification/NotificationManagerService.java
index 80ae260..efe192c 100644
--- a/src/main/java/com/example/service/notification/NotificationManagerService.java
+++ b/src/main/java/com/example/service/notification/NotificationManagerService.java
@@ -93,11 +93,9 @@ public class NotificationManagerService {
firestoreNotificationService.saveOrAppendNotificationEntry(newNotificationEntry)
.subscribe(
ignored -> logger.debug(
- "Background: Notification entry persistence initiated for phone {} in Firestore.",
- telefono),
+ "Background: Notification entry persistence initiated for phone in Firestore."),
e -> logger.error(
- "Background: Error during notification entry persistence for phone {} in Firestore: {}",
- telefono, e.getMessage(), e));
+ "Background: Error during notification entry persistence for phone in Firestore: {}", e.getMessage(), e));
});
// 2. Resolve or create a conversation session
@@ -117,8 +115,7 @@ public class NotificationManagerService {
})
.switchIfEmpty(Mono.defer(() -> {
String newSessionId = SessionIdGenerator.generateStandardSessionId();
- logger.info("No existing conversation session found for phone number {}. Creating new session: {}",
- telefono, newSessionId);
+ logger.info("No existing conversation session found for phone number. Creating new session: {}", newSessionId);
String userId = "user_by_phone_" + telefono;
Map prefixedParameters = new HashMap<>();
if (obfuscatedRequest.hiddenParameters() != null) {
@@ -143,7 +140,7 @@ public class NotificationManagerService {
return dialogflowClientService.detectIntent(sessionId, detectIntentRequest);
})
.doOnSuccess(response -> logger
- .info("Finished processing notification. Dialogflow response received for phone {}.", telefono))
+ .info("Finished processing notification. Dialogflow response received for phone"))
.doOnError(e -> logger.error("Overall error in NotificationManagerService: {}", e.getMessage(), e));
});
}
diff --git a/src/main/java/com/example/service/quickreplies/MemoryStoreQRService.java b/src/main/java/com/example/service/quickreplies/MemoryStoreQRService.java
index fbb0abb..49836ab 100644
--- a/src/main/java/com/example/service/quickreplies/MemoryStoreQRService.java
+++ b/src/main/java/com/example/service/quickreplies/MemoryStoreQRService.java
@@ -68,7 +68,6 @@ public class MemoryStoreQRService {
return Mono.empty();
}
String phoneToSessionKey = PHONE_TO_SESSION_KEY_PREFIX + telefono;
- logger.debug("Attempting to retrieve quick reply session ID for phone number {} from Redis.", telefono);
return stringRedisTemplate.opsForValue().get(phoneToSessionKey)
.flatMap(sessionId -> {
logger.debug("Found quick reply session ID {} for phone number {}. Retrieving session data.",
@@ -77,13 +76,12 @@ public class MemoryStoreQRService {
})
.doOnSuccess(session -> {
if (session != null) {
- logger.info("Successfully retrieved quick reply session {} by phone number {}.",
- session.sessionId(), telefono);
+ logger.info("Successfully retrieved quick reply session {} by phone number",
+ session.sessionId());
} else {
- logger.info("No quick reply session found in Redis for phone number {}.", telefono);
+ logger.info("No quick reply session found in Redis for phone number");
}
})
- .doOnError(e -> logger.error("Error retrieving quick reply session by phone number {}: {}", telefono,
- e.getMessage(), e));
+ .doOnError(e -> logger.error("Error retrieving quick reply session by phone numbe: {}",e.getMessage(), e));
}
}
\ No newline at end of file
diff --git a/src/main/java/com/example/service/quickreplies/QuickRepliesManagerService.java b/src/main/java/com/example/service/quickreplies/QuickRepliesManagerService.java
index db7b773..890e14c 100644
--- a/src/main/java/com/example/service/quickreplies/QuickRepliesManagerService.java
+++ b/src/main/java/com/example/service/quickreplies/QuickRepliesManagerService.java
@@ -84,7 +84,7 @@ public class QuickRepliesManagerService {
return memoryStoreConversationService.getSessionByTelefono(userPhoneNumber)
.switchIfEmpty(Mono.error(
- new IllegalStateException("No quick reply session found for phone number: " + userPhoneNumber)))
+ new IllegalStateException("No quick reply session found for phone number" )))
.flatMap(session -> {
String userId = session.userId();
String sessionId = session.sessionId();
@@ -93,13 +93,14 @@ public class QuickRepliesManagerService {
List entries = session.entries();
int lastInitIndex = IntStream.range(0, entries.size())
- .map(i -> entries.size() - 1 - i)
- .filter(i -> {
- ConversationEntryDTO entry = entries.get(i);
- return entry.entity() == ConversationEntryEntity.SISTEMA && entry.type() == ConversationEntryType.INICIO;
- })
- .findFirst()
- .orElse(-1);
+ .map(i -> entries.size() - 1 - i)
+ .filter(i -> {
+ ConversationEntryDTO entry = entries.get(i);
+ return entry.entity() == ConversationEntryEntity.SISTEMA
+ && entry.type() == ConversationEntryType.INICIO;
+ })
+ .findFirst()
+ .orElse(-1);
long userMessagesCount;
if (lastInitIndex != -1) {
@@ -136,19 +137,20 @@ public class QuickRepliesManagerService {
// Matched question, return the answer
String respuesta = matchedPreguntas.get(0).respuesta();
QueryResultDTO queryResult = new QueryResultDTO(respuesta, null);
- DetectIntentResponseDTO response = new DetectIntentResponseDTO(sessionId, queryResult, null);
+ DetectIntentResponseDTO response = new DetectIntentResponseDTO(sessionId,
+ queryResult, null);
return memoryStoreConversationService
- .updateSession(session.withPantallaContexto(null))
- .then(persistConversationTurn(userId, sessionId,
- ConversationEntryDTO.forAgentWithMessage(respuesta),
- userPhoneNumber, null))
- .thenReturn(response);
+ .updateSession(session.withPantallaContexto(null))
+ .then(persistConversationTurn(userId, sessionId,
+ ConversationEntryDTO.forAgentWithMessage(respuesta),
+ userPhoneNumber, null))
+ .thenReturn(response);
} else {
// No match, delegate to Dialogflow
return memoryStoreConversationService
- .updateSession(session.withPantallaContexto(null))
- .then(conversationManagerService.manageConversation(externalRequest));
+ .updateSession(session.withPantallaContexto(null))
+ .then(conversationManagerService.manageConversation(externalRequest));
}
});
} else {
diff --git a/src/main/java/com/example/service/summary/ConversationSummaryService.java b/src/main/java/com/example/service/summary/ConversationSummaryService.java
deleted file mode 100644
index ed853c1..0000000
--- a/src/main/java/com/example/service/summary/ConversationSummaryService.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
- * Your use of it is subject to your agreement with Google.
- */
-
-package com.example.service.summary;
-
-import com.example.dto.gemini.ConversationSummaryRequest;
-import com.example.dto.gemini.ConversationSummaryResponse;
-import com.example.dto.gemini.ConversationSessionSummaryDTO;
-import com.example.dto.gemini.ConversationEntrySummaryDTO;
-import com.example.repository.FirestoreBaseRepository;
-import com.example.service.base.GeminiClientService;
-import com.google.cloud.firestore.DocumentReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
-
-@Service
-public class ConversationSummaryService {
-
- private static final Logger logger = LoggerFactory.getLogger(ConversationSummaryService.class);
- private final GeminiClientService geminiService;
- private final FirestoreBaseRepository firestoreBaseRepository;
-
- private static final String CONVERSATION_COLLECTION_PATH_FORMAT = "artifacts/%s/conversations";
-
- private static final String DEFAULT_GEMINI_MODEL_NAME = "gemini-2.0-flash-001";
- private static final Float DEFAULT_TEMPERATURE = 0.7f;
- private static final Integer DEFAULT_MAX_OUTPUT_TOKENS = 800;
- private static final Float DEFAULT_tOPP = 0.1f;
-
-
- public ConversationSummaryService(GeminiClientService geminiService, FirestoreBaseRepository firestoreBaseRepository) {
- this.geminiService = geminiService;
- this.firestoreBaseRepository = firestoreBaseRepository;
- }
-
- public ConversationSummaryResponse summarizeConversation(ConversationSummaryRequest request) {
- if (request == null) {
- logger.warn("Summarization request is null.");
- return new ConversationSummaryResponse("Request cannot be null.");
- }
- if (request.sessionId() == null || request.sessionId().isBlank()) {
- logger.warn("Session ID is missing in the summarization request.");
- return new ConversationSummaryResponse("Session ID is required.");
- }
- if (request.prompt() == null || request.prompt().isBlank()) {
- logger.warn("Prompt for summarization is missing in the request.");
- return new ConversationSummaryResponse("Prompt for summarization is required.");
- }
-
- String sessionId = request.sessionId();
- String summarizationPromptInstruction = request.prompt();
-
- String actualModelName = (request.modelName() != null && !request.modelName().isBlank())
- ? request.modelName() : DEFAULT_GEMINI_MODEL_NAME;
- Float actualTemperature = (request.temperature() != null)
- ? request.temperature() : DEFAULT_TEMPERATURE;
- Integer actualMaxOutputTokens = (request.maxOutputTokens() != null)
- ? request.maxOutputTokens() : DEFAULT_MAX_OUTPUT_TOKENS;
- Float actualTopP = (request.top_P() != null)
- ? request.top_P() : DEFAULT_tOPP;
-
- String collectionPath = String.format(CONVERSATION_COLLECTION_PATH_FORMAT, firestoreBaseRepository.getAppId());
- String documentId = sessionId;
- logger.info("Fetching conversation from Firestore: Collection='{}', Document='{}'", collectionPath, documentId);
-
- ConversationSessionSummaryDTO sessionSummary;
- try {
- DocumentReference docRef = firestoreBaseRepository.getDocumentReference(collectionPath, documentId);
- sessionSummary = firestoreBaseRepository.getDocument(docRef, ConversationSessionSummaryDTO.class);
-
- logger.debug("Retrieved ConversationSessionSummaryDTO after Firestore fetch: sessionId={}, entries size={}",
- sessionSummary != null ? sessionSummary.sessionId() : "null",
- sessionSummary != null && sessionSummary.entries() != null ? sessionSummary.entries().size() : "N/A (entries list is null)");
-
- if (sessionSummary == null) {
- logger.warn("Firestore document not found or could not be mapped: {}/{}", collectionPath, documentId);
- return new ConversationSummaryResponse("Conversation document not found for session ID: " + sessionId);
- }
-
- List entries = sessionSummary.entries();
- if (entries == null || entries.isEmpty()) {
- logger.warn("No conversation entries found in document {}/{} for session ID: {}",
- collectionPath, documentId, sessionId);
- return new ConversationSummaryResponse("No conversation messages found in the document for session ID: " + sessionId);
- }
-
- List conversationMessages = entries.stream()
- .map(entry -> {
- String type = entry.type().map(t -> t.name()).orElse("UNKNOWN_TYPE");
- String timestampString = entry.timestamp() != null ? entry.timestamp().toDate().toInstant().toString() : "UNKNOWN_TIMESTAMP";
- return String.format("[%s - %s] %s", type, timestampString, entry.text());
- })
- .collect(Collectors.toList());
-
- String formattedConversation = String.join("\n", conversationMessages);
- String fullPromptForGemini = summarizationPromptInstruction + "\n\n" + formattedConversation;
-
- logger.info("Sending summarization request to Gemini with custom prompt (first 200 chars): \n{}",
- fullPromptForGemini.substring(0, Math.min(fullPromptForGemini.length(), 200)) + "...");
-
- String summaryText = geminiService.generateContent(
- fullPromptForGemini,
- actualTemperature,
- actualMaxOutputTokens,
- actualModelName,
- actualTopP
- );
-
- if (summaryText == null || summaryText.trim().isEmpty()) {
- logger.warn("Gemini returned an empty or null summary for the conversation.");
- return new ConversationSummaryResponse("Could not generate a summary. The model returned no text.");
- }
- logger.info("Successfully generated summary for session ID: {}", sessionId);
- return new ConversationSummaryResponse(summaryText);
-
- } catch (InterruptedException | ExecutionException e) {
- logger.error("Error accessing Firestore for session ID {}: {}", sessionId, e.getMessage(), e);
- Thread.currentThread().interrupt();
- return new ConversationSummaryResponse("Error accessing conversation data: " + e.getMessage());
- } catch (Exception e) {
- logger.error("An unexpected error occurred during summarization for session ID {}: {}", sessionId, e.getMessage(), e);
- return new ConversationSummaryResponse("An unexpected error occurred during summarization: " + e.getMessage());
- }
- }
-}
\ No newline at end of file