Add RAG client

This commit is contained in:
2026-02-22 22:45:47 +00:00
parent 3c1c1a246a
commit 10520012d4
189 changed files with 10690 additions and 31 deletions

View File

@@ -0,0 +1,58 @@
/*
* 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.config;
import com.example.service.base.IntentDetectionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* Configuration class for selecting the intent detection implementation.
* Allows switching between Dialogflow and RAG based on configuration property.
*
* Usage:
* - Set intent.detection.client=dialogflow to use Dialogflow CX
* - Set intent.detection.client=rag to use RAG server
*/
@Configuration
public class IntentDetectionConfig {
private static final Logger logger = LoggerFactory.getLogger(IntentDetectionConfig.class);
@Value("${intent.detection.client:dialogflow}")
private String clientType;
/**
* Creates the primary IntentDetectionService bean based on configuration.
* This bean will be injected into ConversationManagerService and NotificationManagerService.
*
* @param dialogflowService The Dialogflow implementation
* @param ragService The RAG implementation
* @return The selected IntentDetectionService implementation
*/
@Bean
@Primary
public IntentDetectionService intentDetectionService(
@Qualifier("dialogflowClientService") IntentDetectionService dialogflowService,
@Qualifier("ragClientService") IntentDetectionService ragService) {
if ("rag".equalsIgnoreCase(clientType)) {
logger.info("✓ Intent detection configured to use RAG client");
return ragService;
} else if ("dialogflow".equalsIgnoreCase(clientType)) {
logger.info("✓ Intent detection configured to use Dialogflow CX client");
return dialogflowService;
} else {
logger.warn("Unknown intent.detection.client value: '{}'. Defaulting to Dialogflow.", clientType);
return dialogflowService;
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* 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.rag;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
/**
* Internal DTO representing a request to the RAG server.
* This is used only within the RAG client adapter and is not exposed to other services.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record RagQueryRequest(
@JsonProperty("phone_number") String phoneNumber,
@JsonProperty("text") String text,
@JsonProperty("type") String type,
@JsonProperty("notification") NotificationContext notification,
@JsonProperty("language_code") String languageCode
) {
/**
* Nested record for notification context
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public record NotificationContext(
@JsonProperty("text") String text,
@JsonProperty("parameters") Map<String, Object> parameters
) {}
}

View File

@@ -0,0 +1,23 @@
/*
* 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.rag;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
/**
* Internal DTO representing a response from the RAG server.
* This is used only within the RAG client adapter and is not exposed to other services.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record RagQueryResponse(
@JsonProperty("response_id") String responseId,
@JsonProperty("response_text") String responseText,
@JsonProperty("parameters") Map<String, Object> parameters,
@JsonProperty("confidence") Double confidence
) {}

View File

@@ -0,0 +1,21 @@
/*
* 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.exception;
/**
* Exception thrown when the RAG client encounters an error communicating with the RAG server.
* This mirrors the structure of DialogflowClientException for consistency.
*/
public class RagClientException extends RuntimeException {
public RagClientException(String message) {
super(message);
}
public RagClientException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,154 @@
/*
* 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.mapper.rag;
import com.example.dto.dialogflow.base.DetectIntentRequestDTO;
import com.example.dto.dialogflow.conversation.QueryInputDTO;
import com.example.dto.rag.RagQueryRequest;
import com.example.dto.rag.RagQueryRequest.NotificationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Mapper component responsible for converting DetectIntentRequestDTO to RAG API format.
* This adapter preserves the existing DTO structure while translating to the simpler RAG API.
*/
@Component
public class RagRequestMapper {
private static final Logger logger = LoggerFactory.getLogger(RagRequestMapper.class);
private static final String NOTIFICATION_PREFIX = "notification_po_";
private static final String NOTIFICATION_TEXT_PARAM = "notification_text";
/**
* Maps a DetectIntentRequestDTO to a RagQueryRequest.
* Extracts the phone number, text/event, and notification data from the existing structure.
*
* @param requestDto The existing DetectIntentRequestDTO
* @param sessionId The session ID (not used by RAG but kept for logging)
* @return A RagQueryRequest ready to send to the RAG server
*/
public RagQueryRequest mapToRagRequest(DetectIntentRequestDTO requestDto, String sessionId) {
Objects.requireNonNull(requestDto, "DetectIntentRequestDTO cannot be null");
logger.debug("Mapping DetectIntentRequestDTO to RagQueryRequest for session: {}", sessionId);
// Extract phone number from parameters
Map<String, Object> parameters = requestDto.queryParams() != null
? requestDto.queryParams().parameters()
: Map.of();
String phoneNumber = extractPhoneNumber(parameters);
if (phoneNumber == null || phoneNumber.isBlank()) {
logger.error("Phone number is required but not found in request parameters");
throw new IllegalArgumentException("Phone number is required in request parameters");
}
// Extract text or event from QueryInputDTO
QueryInputDTO queryInput = requestDto.queryInput();
String text = extractText(queryInput);
String languageCode = queryInput.languageCode();
// Determine request type and notification context
String type = determineRequestType(queryInput, parameters);
NotificationContext notificationContext = extractNotificationContext(parameters);
RagQueryRequest ragRequest = new RagQueryRequest(
phoneNumber,
text,
type,
notificationContext,
languageCode
);
logger.debug("Mapped RAG request: type={}, phoneNumber={}, hasNotification={}",
type, phoneNumber, notificationContext != null);
return ragRequest;
}
/**
* Extracts the phone number from request parameters.
*/
private String extractPhoneNumber(Map<String, Object> parameters) {
Object telefono = parameters.get("telefono");
if (telefono instanceof String) {
return (String) telefono;
}
logger.warn("Phone number (telefono) not found or not a string in parameters");
return null;
}
/**
* Extracts text from QueryInputDTO (either text input or event).
* For events, we use the event name as the text.
*/
private String extractText(QueryInputDTO queryInput) {
if (queryInput.text() != null && queryInput.text().text() != null
&& !queryInput.text().text().trim().isEmpty()) {
return queryInput.text().text();
} else if (queryInput.event() != null && queryInput.event().event() != null
&& !queryInput.event().event().trim().isEmpty()) {
// For events (like "LLM_RESPONSE_PROCESSED"), use the event name
return queryInput.event().event();
} else {
logger.error("Query input must contain either text or event");
throw new IllegalArgumentException("Query input must contain either text or event");
}
}
/**
* Determines if this is a conversation or notification request.
* If notification parameters are present, it's a notification request.
*/
private String determineRequestType(QueryInputDTO queryInput, Map<String, Object> parameters) {
// Check if there are notification-prefixed parameters
boolean hasNotificationParams = parameters.keySet().stream()
.anyMatch(key -> key.startsWith(NOTIFICATION_PREFIX));
// Check if there's a notification_text parameter
boolean hasNotificationText = parameters.containsKey(NOTIFICATION_TEXT_PARAM);
// Check if the input is an event (notifications use events)
boolean isEvent = queryInput.event() != null && queryInput.event().event() != null;
if (hasNotificationParams || hasNotificationText ||
(isEvent && "notificacion".equals(queryInput.event().event()))) {
return "notification";
}
return "conversation";
}
/**
* Extracts notification context from parameters.
* Looks for notification_text and notification_po_* parameters.
*/
private NotificationContext extractNotificationContext(Map<String, Object> parameters) {
String notificationText = (String) parameters.get(NOTIFICATION_TEXT_PARAM);
// Extract all notification_po_* parameters and remove the prefix
Map<String, Object> notificationParams = new HashMap<>();
parameters.forEach((key, value) -> {
if (key.startsWith(NOTIFICATION_PREFIX)) {
String cleanKey = key.substring(NOTIFICATION_PREFIX.length());
notificationParams.put(cleanKey, value);
}
});
// Only create NotificationContext if we have notification data
if (notificationText != null || !notificationParams.isEmpty()) {
return new NotificationContext(notificationText, notificationParams);
}
return null;
}
}

View File

@@ -0,0 +1,73 @@
/*
* 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.mapper.rag;
import com.example.dto.dialogflow.base.DetectIntentResponseDTO;
import com.example.dto.dialogflow.conversation.QueryResultDTO;
import com.example.dto.rag.RagQueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
/**
* Mapper component responsible for converting RAG API responses to DetectIntentResponseDTO.
* This adapter ensures the response structure matches what the rest of the application expects.
*/
@Component
public class RagResponseMapper {
private static final Logger logger = LoggerFactory.getLogger(RagResponseMapper.class);
/**
* Maps a RagQueryResponse to a DetectIntentResponseDTO.
* Preserves the existing response structure expected by the rest of the application.
*
* @param ragResponse The response from the RAG server
* @param sessionId The session ID (for logging purposes)
* @return A DetectIntentResponseDTO matching the expected structure
*/
public DetectIntentResponseDTO mapFromRagResponse(RagQueryResponse ragResponse, String sessionId) {
logger.info("Mapping RAG response to DetectIntentResponseDTO for session: {}", sessionId);
// Use RAG's response_id if available, otherwise generate one
String responseId = ragResponse.responseId() != null && !ragResponse.responseId().isBlank()
? ragResponse.responseId()
: "rag-" + UUID.randomUUID().toString();
// Extract response text
String responseText = ragResponse.responseText() != null
? ragResponse.responseText()
: "";
if (responseText.isBlank()) {
logger.warn("RAG returned empty response text for session: {}", sessionId);
}
// Extract parameters (can be null or empty)
Map<String, Object> parameters = ragResponse.parameters() != null
? ragResponse.parameters()
: Collections.emptyMap();
// Log confidence if available
if (ragResponse.confidence() != null) {
logger.debug("RAG response confidence: {} for session: {}", ragResponse.confidence(), sessionId);
}
// Create QueryResultDTO with response text and parameters
QueryResultDTO queryResult = new QueryResultDTO(responseText, parameters);
// Create DetectIntentResponseDTO (quickReplies is null for now)
DetectIntentResponseDTO response = new DetectIntentResponseDTO(responseId, queryResult, null);
logger.info("Successfully mapped RAG response for session: {}. Response ID: {}", sessionId, responseId);
return response;
}
}

View File

@@ -18,6 +18,7 @@ import com.google.cloud.dialogflow.cx.v3.SessionName;
import com.google.cloud.dialogflow.cx.v3.SessionsSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import javax.annotation.PreDestroy;
@@ -32,7 +33,8 @@ import reactor.util.retry.Retry;
* all within a reactive programming context.
*/
@Service
public class DialogflowClientService {
@Qualifier("dialogflowClientService")
public class DialogflowClientService implements IntentDetectionService {
private static final Logger logger = LoggerFactory.getLogger(DialogflowClientService.class);
@@ -81,6 +83,7 @@ public class DialogflowClientService {
}
}
@Override
public Mono<DetectIntentResponseDTO> detectIntent(
String sessionId,
DetectIntentRequestDTO request) {

View File

@@ -0,0 +1,27 @@
/*
* 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.base;
import com.example.dto.dialogflow.base.DetectIntentRequestDTO;
import com.example.dto.dialogflow.base.DetectIntentResponseDTO;
import reactor.core.publisher.Mono;
/**
* Common interface for intent detection services.
* This abstraction allows switching between different intent detection implementations
* (e.g., Dialogflow, RAG) without changing dependent services.
*/
public interface IntentDetectionService {
/**
* Detects user intent and generates a response.
*
* @param sessionId The session identifier for this conversation
* @param request The request containing user input and context parameters
* @return A Mono of DetectIntentResponseDTO with the generated response
*/
Mono<DetectIntentResponseDTO> detectIntent(String sessionId, DetectIntentRequestDTO request);
}

View File

@@ -0,0 +1,183 @@
/*
* 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.base;
import com.example.dto.dialogflow.base.DetectIntentRequestDTO;
import com.example.dto.dialogflow.base.DetectIntentResponseDTO;
import com.example.dto.rag.RagQueryRequest;
import com.example.dto.rag.RagQueryResponse;
import com.example.exception.RagClientException;
import com.example.mapper.rag.RagRequestMapper;
import com.example.mapper.rag.RagResponseMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
import reactor.util.retry.Retry;
import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.TimeoutException;
/**
* Service for interacting with the RAG server to detect user intent and generate responses.
* This service mirrors the structure of DialogflowClientService but calls a RAG API instead.
* It maintains the same method signatures and reactive patterns for seamless integration.
*/
@Service
@Qualifier("ragClientService")
public class RagClientService implements IntentDetectionService {
private static final Logger logger = LoggerFactory.getLogger(RagClientService.class);
private final WebClient webClient;
private final RagRequestMapper ragRequestMapper;
private final RagResponseMapper ragResponseMapper;
private final int maxRetries;
private final Duration retryBackoff;
private final Duration timeout;
public RagClientService(
@Value("${rag.server.url}") String ragServerUrl,
@Value("${rag.server.timeout:30s}") Duration timeout,
@Value("${rag.server.retry.max-attempts:3}") int maxRetries,
@Value("${rag.server.retry.backoff:1s}") Duration retryBackoff,
@Value("${rag.server.api-key:}") String apiKey,
RagRequestMapper ragRequestMapper,
RagResponseMapper ragResponseMapper) {
this.ragRequestMapper = ragRequestMapper;
this.ragResponseMapper = ragResponseMapper;
this.maxRetries = maxRetries;
this.retryBackoff = retryBackoff;
this.timeout = timeout;
// Build WebClient with base URL and optional API key
WebClient.Builder builder = WebClient.builder()
.baseUrl(ragServerUrl)
.defaultHeader("Content-Type", "application/json");
// Add API key header if provided
if (apiKey != null && !apiKey.isBlank()) {
builder.defaultHeader("X-API-Key", apiKey);
logger.info("RAG Client initialized with API key authentication");
}
this.webClient = builder.build();
logger.info("RAG Client initialized successfully with endpoint: {}", ragServerUrl);
logger.info("RAG Client configuration - timeout: {}, max retries: {}, backoff: {}",
timeout, maxRetries, retryBackoff);
}
/**
* Detects user intent by calling the RAG server.
* This method signature matches DialogflowClientService.detectIntent() for compatibility.
*
* @param sessionId The session identifier (used for logging, not sent to RAG)
* @param request The DetectIntentRequestDTO containing user input and parameters
* @return A Mono of DetectIntentResponseDTO with the RAG-generated response
*/
@Override
public Mono<DetectIntentResponseDTO> detectIntent(
String sessionId,
DetectIntentRequestDTO request) {
Objects.requireNonNull(sessionId, "Session ID cannot be null.");
Objects.requireNonNull(request, "Request DTO cannot be null.");
logger.info("Initiating RAG query for session: {}", sessionId);
// Map DetectIntentRequestDTO to RAG format
RagQueryRequest ragRequest;
try {
ragRequest = ragRequestMapper.mapToRagRequest(request, sessionId);
logger.debug("Successfully mapped request to RAG format for session: {}", sessionId);
} catch (IllegalArgumentException e) {
logger.error("Failed to map DTO to RAG request for session {}: {}", sessionId, e.getMessage());
return Mono.error(new IllegalArgumentException("Invalid RAG request input: " + e.getMessage()));
}
// Call RAG API
return Mono.defer(() ->
webClient.post()
.uri("/api/v1/query")
.header("X-Session-Id", sessionId) // Optional: for RAG server logging
.bodyValue(ragRequest)
.retrieve()
.onStatus(
HttpStatusCode::is4xxClientError,
response -> response.bodyToMono(String.class)
.flatMap(body -> {
logger.error("RAG client error for session {}: status={}, body={}",
sessionId, response.statusCode(), body);
return Mono.error(new RagClientException(
"Invalid RAG request: " + response.statusCode() + " - " + body));
})
)
.bodyToMono(RagQueryResponse.class)
.timeout(timeout) // Timeout per attempt
)
.retryWhen(Retry.backoff(maxRetries, retryBackoff)
.filter(throwable -> {
// Retry on server errors and timeouts
if (throwable instanceof WebClientResponseException wce) {
int statusCode = wce.getStatusCode().value();
boolean isRetryable = statusCode == 500 || statusCode == 503 || statusCode == 504;
if (isRetryable) {
logger.warn("Retrying RAG call for session {} due to status code: {}",
sessionId, statusCode);
}
return isRetryable;
}
if (throwable instanceof TimeoutException) {
logger.warn("Retrying RAG call for session {} due to timeout", sessionId);
return true;
}
return false;
})
.doBeforeRetry(retrySignal ->
logger.debug("Retry attempt #{} for session {}: {}",
retrySignal.totalRetries() + 1, sessionId, retrySignal.failure().getMessage()))
.onRetryExhaustedThrow((retrySpec, retrySignal) -> {
logger.error("RAG retries exhausted for session {}", sessionId);
return retrySignal.failure();
})
)
.onErrorMap(WebClientResponseException.class, e -> {
int statusCode = e.getStatusCode().value();
logger.error("RAG server error for session {}: status={}, body={}",
sessionId, statusCode, e.getResponseBodyAsString());
return new RagClientException(
"RAG server error: " + statusCode + " - " + e.getResponseBodyAsString(), e);
})
.onErrorMap(WebClientRequestException.class, e -> {
logger.error("RAG connection error for session {}: {}", sessionId, e.getMessage());
return new RagClientException("RAG connection failed: " + e.getMessage(), e);
})
.onErrorMap(TimeoutException.class, e -> {
logger.error("RAG timeout for session {}: {}", sessionId, e.getMessage());
return new RagClientException("RAG request timeout after " + timeout.getSeconds() + "s", e);
})
.onErrorMap(RagClientException.class, e -> e) // Pass through RagClientException
.onErrorMap(throwable -> !(throwable instanceof RagClientException), throwable -> {
logger.error("Unexpected error during RAG call for session {}: {}", sessionId, throwable.getMessage(), throwable);
return new RagClientException("Unexpected RAG error: " + throwable.getMessage(), throwable);
})
.map(ragResponse -> ragResponseMapper.mapFromRagResponse(ragResponse, sessionId))
.doOnSuccess(response ->
logger.info("RAG query successful for session: {}, response ID: {}",
sessionId, response.responseId()))
.doOnError(error ->
logger.error("RAG query failed for session {}: {}", sessionId, error.getMessage()));
}
}

View File

@@ -14,7 +14,7 @@ import com.example.mapper.conversation.ConversationEntryMapper;
import com.example.mapper.conversation.ExternalConvRequestMapper;
import com.example.mapper.messagefilter.ConversationContextMapper;
import com.example.mapper.messagefilter.NotificationContextMapper;
import com.example.service.base.DialogflowClientService;
import com.example.service.base.IntentDetectionService;
import com.example.service.base.MessageEntryFilter;
import com.example.service.base.NotificationContextResolver;
import com.example.service.notification.MemoryStoreNotificationService;
@@ -67,7 +67,7 @@ public class ConversationManagerService {
private static final String CONV_HISTORY_PARAM = "conversation_history";
private static final String HISTORY_PARAM = "historial";
private final ExternalConvRequestMapper externalRequestToDialogflowMapper;
private final DialogflowClientService dialogflowServiceClient;
private final IntentDetectionService intentDetectionService;
private final FirestoreConversationService firestoreConversationService;
private final MemoryStoreConversationService memoryStoreConversationService;
private final QuickRepliesManagerService quickRepliesManagerService;
@@ -83,7 +83,7 @@ public class ConversationManagerService {
private final ConversationEntryMapper conversationEntryMapper;
public ConversationManagerService(
DialogflowClientService dialogflowServiceClient,
IntentDetectionService intentDetectionService,
FirestoreConversationService firestoreConversationService,
MemoryStoreConversationService memoryStoreConversationService,
ExternalConvRequestMapper externalRequestToDialogflowMapper,
@@ -97,7 +97,7 @@ public class ConversationManagerService {
LlmResponseTunerService llmResponseTunerService,
ConversationEntryMapper conversationEntryMapper,
@Value("${google.cloud.dlp.dlpTemplateCompleteFlow}") String dlpTemplateCompleteFlow) {
this.dialogflowServiceClient = dialogflowServiceClient;
this.intentDetectionService = intentDetectionService;
this.firestoreConversationService = firestoreConversationService;
this.memoryStoreConversationService = memoryStoreConversationService;
this.externalRequestToDialogflowMapper = externalRequestToDialogflowMapper;
@@ -305,7 +305,7 @@ public class ConversationManagerService {
finalSessionId))
.doOnError(e -> logger.error("Error during user entry persistence for session {}: {}", finalSessionId,
e.getMessage(), e))
.then(Mono.defer(() -> dialogflowServiceClient.detectIntent(finalSessionId, request)
.then(Mono.defer(() -> intentDetectionService.detectIntent(finalSessionId, request)
.flatMap(response -> {
logger.debug(
"RTest eceived Dialogflow CX response for session {}. Initiating agent response persistence.",
@@ -366,7 +366,7 @@ public class ConversationManagerService {
request.queryParams())
.withParameter("llm_reponse_uuid", uuid);
return dialogflowServiceClient.detectIntent(sessionId, newRequest)
return intentDetectionService.detectIntent(sessionId, newRequest)
.flatMap(response -> {
ConversationEntryDTO agentEntry = ConversationEntryDTO
.forAgent(response.queryResult());
@@ -387,7 +387,7 @@ public class ConversationManagerService {
.withParameters(notification.parametros());
}
return persistConversationTurn(session, conversationEntryMapper.toConversationMessageDTO(userEntry))
.then(dialogflowServiceClient.detectIntent(sessionId, finalRequest)
.then(intentDetectionService.detectIntent(sessionId, finalRequest)
.flatMap(response -> {
ConversationEntryDTO agentEntry = ConversationEntryDTO
.forAgent(response.queryResult());

View File

@@ -14,7 +14,7 @@ import com.example.dto.dialogflow.conversation.ConversationSessionDTO;
import com.example.dto.dialogflow.notification.NotificationDTO;
import com.example.mapper.conversation.ConversationEntryMapper;
import com.example.mapper.notification.ExternalNotRequestMapper;
import com.example.service.base.DialogflowClientService;
import com.example.service.base.IntentDetectionService;
import com.example.service.conversation.DataLossPrevention;
import com.example.service.conversation.FirestoreConversationService;
import com.example.service.conversation.MemoryStoreConversationService;
@@ -36,7 +36,7 @@ public class NotificationManagerService {
private static final String eventName = "notificacion";
private static final String PREFIX_PO_PARAM = "notification_po_";
private final DialogflowClientService dialogflowClientService;
private final IntentDetectionService intentDetectionService;
private final FirestoreNotificationService firestoreNotificationService;
private final MemoryStoreNotificationService memoryStoreNotificationService;
private final ExternalNotRequestMapper externalNotRequestMapper;
@@ -50,7 +50,7 @@ public class NotificationManagerService {
private String defaultLanguageCode;
public NotificationManagerService(
DialogflowClientService dialogflowClientService,
IntentDetectionService intentDetectionService,
FirestoreNotificationService firestoreNotificationService,
MemoryStoreNotificationService memoryStoreNotificationService,
MemoryStoreConversationService memoryStoreConversationService,
@@ -60,8 +60,8 @@ public class NotificationManagerService {
DataLossPrevention dataLossPrevention,
ConversationEntryMapper conversationEntryMapper,
@Value("${google.cloud.dlp.dlpTemplateCompleteFlow}") String dlpTemplateCompleteFlow) {
this.dialogflowClientService = dialogflowClientService;
this.intentDetectionService = intentDetectionService;
this.firestoreNotificationService = firestoreNotificationService;
this.memoryStoreNotificationService = memoryStoreNotificationService;
this.externalNotRequestMapper = externalNotRequestMapper;
@@ -147,7 +147,7 @@ public class NotificationManagerService {
DetectIntentRequestDTO detectIntentRequest = externalNotRequestMapper.map(obfuscatedRequest);
return dialogflowClientService.detectIntent(sessionId, detectIntentRequest);
return intentDetectionService.detectIntent(sessionId, detectIntentRequest);
})
.doOnSuccess(response -> logger
.info("Finished processing notification. Dialogflow response received for phone {}.", telefono))

View File

@@ -38,12 +38,27 @@ spring.data.redis.port=${REDIS_PORT}
# spring.data.redis.ssl.key-store=classpath:keystore.p12
# spring.data.redis.ssl.key-store-password=${REDIS_KEY_PWD}
# =========================================================
# Google Conversational Agents Configuration
# Intent Detection Client Selection
# =========================================================
# Options: 'dialogflow' or 'rag'
# Set to 'dialogflow' to use Dialogflow CX (default)
# Set to 'rag' to use RAG server
intent.detection.client=${INTENT_DETECTION_CLIENT:dialogflow}
# =========================================================
# Google Conversational Agents Configuration (Dialogflow)
# =========================================================
dialogflow.cx.project-id=${DIALOGFLOW_CX_PROJECT_ID}
dialogflow.cx.location=${DIALOGFLOW_CX_LOCATION}
dialogflow.cx.agent-id=${DIALOGFLOW_CX_AGENT_ID}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE:es}
# =========================================================
# RAG Server Configuration
# =========================================================
rag.server.url=${RAG_SERVER_URL:http://localhost:8080}
rag.server.timeout=${RAG_SERVER_TIMEOUT:30s}
rag.server.retry.max-attempts=${RAG_SERVER_RETRY_MAX_ATTEMPTS:3}
rag.server.retry.backoff=${RAG_SERVER_RETRY_BACKOFF:1s}
rag.server.api-key=${RAG_SERVER_API_KEY:}
# =========================================================
# Google Generative AI (Gemini) Configuration
# =========================================================

View File

@@ -38,12 +38,27 @@ spring.data.redis.port=${REDIS_PORT}
# spring.data.redis.ssl.key-store=classpath:keystore.p12
# spring.data.redis.ssl.key-store-password=${REDIS_KEY_PWD}
# =========================================================
# Google Conversational Agents Configuration
# Intent Detection Client Selection
# =========================================================
# Options: 'dialogflow' or 'rag'
# Set to 'dialogflow' to use Dialogflow CX (default)
# Set to 'rag' to use RAG server
intent.detection.client=${INTENT_DETECTION_CLIENT:dialogflow}
# =========================================================
# Google Conversational Agents Configuration (Dialogflow)
# =========================================================
dialogflow.cx.project-id=${DIALOGFLOW_CX_PROJECT_ID}
dialogflow.cx.location=${DIALOGFLOW_CX_LOCATION}
dialogflow.cx.agent-id=${DIALOGFLOW_CX_AGENT_ID}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE:es}
# =========================================================
# RAG Server Configuration
# =========================================================
rag.server.url=${RAG_SERVER_URL:http://localhost:8080}
rag.server.timeout=${RAG_SERVER_TIMEOUT:30s}
rag.server.retry.max-attempts=${RAG_SERVER_RETRY_MAX_ATTEMPTS:3}
rag.server.retry.backoff=${RAG_SERVER_RETRY_BACKOFF:1s}
rag.server.api-key=${RAG_SERVER_API_KEY:}
# =========================================================
# Google Generative AI (Gemini) Configuration
# =========================================================

View File

@@ -38,12 +38,27 @@ spring.data.redis.port=${REDIS_PORT}
# spring.data.redis.ssl.key-store=classpath:keystore.p12
# spring.data.redis.ssl.key-store-password=${REDIS_KEY_PWD}
# =========================================================
# Google Conversational Agents Configuration
# Intent Detection Client Selection
# =========================================================
# Options: 'dialogflow' or 'rag'
# Set to 'dialogflow' to use Dialogflow CX (default)
# Set to 'rag' to use RAG server
intent.detection.client=${INTENT_DETECTION_CLIENT:dialogflow}
# =========================================================
# Google Conversational Agents Configuration (Dialogflow)
# =========================================================
dialogflow.cx.project-id=${DIALOGFLOW_CX_PROJECT_ID}
dialogflow.cx.location=${DIALOGFLOW_CX_LOCATION}
dialogflow.cx.agent-id=${DIALOGFLOW_CX_AGENT_ID}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE}
dialogflow.default-language-code=${DIALOGFLOW_DEFAULT_LANGUAGE_CODE:es}
# =========================================================
# RAG Server Configuration
# =========================================================
rag.server.url=${RAG_SERVER_URL:http://localhost:8080}
rag.server.timeout=${RAG_SERVER_TIMEOUT:30s}
rag.server.retry.max-attempts=${RAG_SERVER_RETRY_MAX_ATTEMPTS:3}
rag.server.retry.backoff=${RAG_SERVER_RETRY_BACKOFF:1s}
rag.server.api-key=${RAG_SERVER_API_KEY:}
# =========================================================
# Google Generative AI (Gemini) Configuration
# =========================================================