UPDATE 24-sept
This commit is contained in:
@@ -2,24 +2,28 @@
|
||||
* 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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Service to classify message entries (user text input from DetectIntent) into predefined categories
|
||||
* like "CONVERSATION" or "NOTIFICATION" using Gemini model.
|
||||
* Classifies a user's text input into a predefined category using a Gemini
|
||||
* model.
|
||||
* It analyzes the user's query in the context of a conversation history and any
|
||||
* relevant notifications to determine if the message is part of the ongoing
|
||||
* dialogue
|
||||
* or an interruption. The classification is used to route the request to the
|
||||
* appropriate handler (e.g., a standard conversational flow or a specific
|
||||
* notification processor).
|
||||
*/
|
||||
@Service
|
||||
public class MessageEntryFilter {
|
||||
@@ -46,27 +50,29 @@ public class MessageEntryFilter {
|
||||
public static final String CATEGORY_NOTIFICATION = "NOTIFICATION";
|
||||
public static final String CATEGORY_UNKNOWN = "UNKNOWN";
|
||||
public static final String CATEGORY_ERROR = "ERROR";
|
||||
|
||||
|
||||
private String promptTemplate;
|
||||
|
||||
public MessageEntryFilter(GeminiClientService geminiService) {
|
||||
this.geminiService = Objects.requireNonNull(geminiService, "GeminiClientService cannot be null for MessageEntryFilter.");
|
||||
this.geminiService = Objects.requireNonNull(geminiService,
|
||||
"GeminiClientService cannot be null for MessageEntryFilter.");
|
||||
}
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void loadPromptTemplate() {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(promptFilePath);
|
||||
try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
|
||||
this.promptTemplate = FileCopyUtils.copyToString(reader);
|
||||
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(promptFilePath)) {
|
||||
if (inputStream == null) {
|
||||
throw new IOException("Resource not found: " + promptFilePath);
|
||||
}
|
||||
logger.info("Successfully loaded prompt template from '{}'.", promptFilePath);
|
||||
byte[] fileBytes = inputStream.readAllBytes();
|
||||
this.promptTemplate = new String(fileBytes, StandardCharsets.UTF_8);
|
||||
logger.info("Successfully loaded prompt template from '" + promptFilePath + "'.");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load prompt template from '{}'. Please ensure the file exists.", promptFilePath, e);
|
||||
logger.error("Failed to load prompt template from '" + promptFilePath
|
||||
+ "'. Please ensure the file exists. Error: " + e.getMessage());
|
||||
throw new IllegalStateException("Could not load prompt template.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String classifyMessage(String queryInputText, String notificationsJson, String conversationJson) {
|
||||
if (queryInputText == null || queryInputText.isBlank()) {
|
||||
logger.warn("Query input text for classification is null or blank. Returning {}.", CATEGORY_UNKNOWN);
|
||||
|
||||
@@ -8,16 +8,24 @@ import com.example.service.notification.MemoryStoreNotificationService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Resolves the conversational context of a user query by leveraging a large
|
||||
* language model (LLM). This service evaluates a user's question in the context
|
||||
* of a specific notification and conversation history, then decides if the
|
||||
* query
|
||||
* can be answered by the LLM or if it should be handled by a standard
|
||||
* Dialogflow agent.
|
||||
* The class loads an LLM prompt from an external file and dynamically
|
||||
* formats it with a user's query and other context to drive its decision-making
|
||||
* process.
|
||||
*/
|
||||
@Service
|
||||
public class NotificationContextResolver {
|
||||
|
||||
@@ -43,21 +51,24 @@ public class NotificationContextResolver {
|
||||
|
||||
private String promptTemplate;
|
||||
|
||||
public NotificationContextResolver(GeminiClientService geminiService, MemoryStoreNotificationService memoryStoreNotificationService) {
|
||||
public NotificationContextResolver(GeminiClientService geminiService,
|
||||
MemoryStoreNotificationService memoryStoreNotificationService) {
|
||||
this.geminiService = Objects.requireNonNull(geminiService,
|
||||
"GeminiClientService cannot be null for NotificationContextResolver.");
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void loadPromptTemplate() {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(promptFilePath);
|
||||
try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
|
||||
this.promptTemplate = FileCopyUtils.copyToString(reader);
|
||||
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(promptFilePath)) {
|
||||
if (inputStream == null) {
|
||||
throw new IOException("Resource not found: " + promptFilePath);
|
||||
}
|
||||
logger.info("Successfully loaded prompt template from '{}'.", promptFilePath);
|
||||
byte[] fileBytes = inputStream.readAllBytes();
|
||||
this.promptTemplate = new String(fileBytes, StandardCharsets.UTF_8);
|
||||
logger.info("Successfully loaded prompt template from '" + promptFilePath + "'.");
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load prompt template from '{}'. Please ensure the file exists.", promptFilePath, e);
|
||||
logger.error("Failed to load prompt template from '" + promptFilePath
|
||||
+ "'. Please ensure the file exists. Error: " + e.getMessage());
|
||||
throw new IllegalStateException("Could not load prompt template.", e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user