Package org.codelibs.fess.llm
Class AbstractLlmClient
java.lang.Object
org.codelibs.fess.llm.AbstractLlmClient
- All Implemented Interfaces:
LlmClient
Abstract base class for LLM client implementations.
Provides shared infrastructure (HTTP client, availability checking) and
default implementations of RAG workflow methods with injectable prompt templates.
Subclasses implement provider-specific chat/streamChat and checkAvailabilityNow.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected StringThe system prompt for answer generation.protected org.codelibs.core.timer.TimeoutTaskThe scheduled task for periodic availability checks.protected BooleanCached availability status of the LLM provider.protected SemaphoreSemaphore for limiting concurrent LLM requests.protected static final intBuffer size reserved when truncating context to fit within max chars limit.protected StringThe system prompt for direct answer generation.protected StringThe system prompt for handling document not found.protected StringThe prompt for evaluating responses.protected StringThe system prompt for FAQ answer generation.protected org.apache.hc.client5.http.impl.classic.CloseableHttpClientThe HTTP client used for API communication.protected StringThe prompt for detecting user intent.protected static final intMaximum length of an LLM response prefix surfaced in WARN-level operator logs.protected StringThe system prompt for handling no results.protected static final com.fasterxml.jackson.databind.ObjectMapperShared ObjectMapper instance for JSON processing.protected StringThe prompt for query regeneration.protected StringThe system prompt for summary generation.protected StringThe system prompt for LLM interactions.Provider-specific finish-reason values that indicate the LLM stopped because it ran out of output token budget (truncated response).protected StringThe system prompt for handling unclear intents. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected voidaddHistory(LlmChatRequest request, List<LlmMessage> history) Adds conversation history to the request.protected voidaddHistoryWithBudget(LlmChatRequest request, List<LlmMessage> history, int budgetChars) Adds conversation history to the request, truncating from oldest to fit within the character budget.protected voidaddIntentHistory(LlmChatRequest request, List<LlmMessage> history) Adds conversation history as structured messages for intent detection.protected voidapplyPromptTypeParams(LlmChatRequest request, String promptType) Applies per-prompt-type parameters to the request from configuration.protected StringBuilds context from document content for the LLM prompt.protected StringBuilds the evaluation prompt for relevance checking.protected StringBuilds the system prompt for intent detection by removing the user-specific placeholders.protected LlmChatRequestbuildStreamingRequest(String userMessage, String context, List<LlmMessage> history) Builds a streaming LLM chat request with conversation history.protected LlmChatResponsechatWithConcurrencyControl(LlmChatRequest request) Executes a chat request with concurrency control via Semaphore.protected abstract booleanPerforms the actual availability check against the LLM provider.protected voidconfigureProxy(org.apache.hc.client5.http.impl.classic.HttpClientBuilder builder) Configures proxy settings on the HTTP client builder if a proxy is configured.voiddestroy()Cleans up resources.detectIntent(String userMessage) Detects the intent of a user message.detectIntent(String userMessage, List<LlmMessage> history) Detects the intent of a user message with conversation history context.Evaluates search results for relevance to the user's question.extractJsonArray(String json, String key) Extracts a string array from JSON response.protected booleanextractJsonBoolean(String json, String key) Extracts a boolean value from JSON response.extractJsonIntArray(String json, String key) Extracts an integer array from JSON response.protected StringextractJsonString(String json, String key) Extracts a string value from JSON response using Jackson parser.protected StringextractJsonStringFallback(String json, String key) Fallback regex-based extraction for string values.generateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history) Generates an answer using document content (synchronous version for non-enhanced flow).voidgenerateDirectAnswer(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Generates a direct answer without document search.voidgenerateDocumentNotFoundResponse(String userMessage, String documentUrl, List<LlmMessage> history, LlmStreamCallback callback) Generates a response when the specified document URL is not found.voidgenerateFaqAnswerResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Generates an FAQ answer using document content (streaming).voidgenerateNoResultsResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Generates a response when no relevant documents are found.voidgenerateSummaryResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Generates a summary of the specified documents.voidgenerateUnclearIntentResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Generates a response asking user for clarification when intent is unclear.protected StringGets the system prompt for answer generation.protected abstract intGets the availability check interval in seconds.protected longGets the timeout for waiting to acquire a concurrency permit (ms).protected intgetConfigInt(String keySuffix, int defaultValue) Gets an integer configuration value using the config prefix and key suffix.protected abstract StringGets the configuration prefix for this provider.protected abstract intgetContextMaxChars(String promptType) Gets the maximum characters for context building for a specific prompt type.protected StringGets the system prompt for direct answer generation.protected StringGets the system prompt for document-not-found responses.protected abstract intGets the maximum number of characters for evaluation description.protected abstract intGets the maximum number of relevant documents for evaluation.protected StringGets the evaluation prompt for relevance checking.protected StringGets the system prompt for FAQ answer generation.intGets the maximum characters for assistant message content in history.intGets the maximum characters for assistant summary content in history.protected intGets the maximum characters for conversation history in LLM requests.org.apache.hc.client5.http.impl.classic.CloseableHttpClientGets the HTTP client, initializing it if necessary.protected StringGets the intent detection prompt template.protected intGets the maximum characters for intent detection history.protected intGets the maximum number of history messages for intent detection.protected StringGets the language instruction based on the user's locale.protected abstract StringGets the configured LLM type.protected intGets the maximum number of concurrent requests to the LLM provider.protected abstract StringgetModel()Gets the model name.protected StringGets the system prompt for no-results responses.protected StringGets the HTTP proxy host.protected StringGets the HTTP proxy password.protected IntegerGets the HTTP proxy port.protected StringGets the HTTP proxy username.protected StringGets the query regeneration prompt template.protected StringgetStringValue(Map<String, Object> map, String key) Gets a string value from a map.protected StringGets the system prompt for summary generation.protected StringGets the base system prompt for RAG chat responses.protected abstract intGets the request timeout in milliseconds.protected StringGets the system prompt for unclear intent responses.protected LocaleGets the user's locale from the current request context.voidinit()Initializes the HTTP client and starts availability checking.booleanChecks if this LLM client is available and properly configured.protected booleanChecks if the LLM response has empty/blank content combined with a truncation finish reason.protected abstract booleanChecks if RAG chat feature is enabled.protected booleanisTruncatedFinish(String finishReason) Checks if a finish reason indicates that the LLM response was truncated by the output token limit (provider-agnostic).protected RelevanceEvaluationResultParses the evaluation response from LLM.protected IntentDetectionResultparseIntentResponse(String response, String userMessage) Parses the LLM response and extracts intent detection result.regenerateQuery(String userMessage, String failedQuery, String failureReason, List<LlmMessage> history) Regenerates a search query when the previous query failed to produce relevant results.voidregister()Registers this client with the LlmClientManager.protected StringresolveErrorCode(int statusCode) Resolves an HTTP status code to an LlmException error code.protected StringresolveLanguageInstruction(String prompt) Resolves the {{languageInstruction}} placeholder in a prompt.protected StringSanitizes document content by escaping delimiter-like sequences to prevent boundary spoofing in LLM prompts.voidsetAnswerGenerationSystemPrompt(String answerGenerationSystemPrompt) Sets the system prompt for answer generation.voidsetDirectAnswerSystemPrompt(String directAnswerSystemPrompt) Sets the system prompt for direct answer generation.voidsetDocumentNotFoundSystemPrompt(String documentNotFoundSystemPrompt) Sets the system prompt for handling document not found.voidsetEvaluationPrompt(String evaluationPrompt) Sets the prompt for evaluating responses.voidsetFaqAnswerSystemPrompt(String faqAnswerSystemPrompt) Sets the system prompt for FAQ answer generation.voidsetIntentDetectionPrompt(String intentDetectionPrompt) Sets the prompt for detecting user intent.voidsetNoResultsSystemPrompt(String noResultsSystemPrompt) Sets the system prompt for handling no results.voidsetQueryRegenerationPrompt(String queryRegenerationPrompt) Sets the prompt for query regeneration.voidsetSummarySystemPrompt(String summarySystemPrompt) Sets the system prompt for summary generation.voidsetSystemPrompt(String systemPrompt) Sets the system prompt for LLM interactions.voidsetUnclearIntentSystemPrompt(String unclearIntentSystemPrompt) Sets the system prompt for handling unclear intents.protected voidStarts periodic availability checking if RAG chat is enabled.protected voidstreamChatWithConcurrencyControl(LlmChatRequest request, LlmStreamCallback callback) Executes a streaming chat request with concurrency control via Semaphore.voidstreamGenerateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Generates an answer using document content (streaming version for enhanced flow).protected StringstripCodeFences(String response) Strips code fence markers from JSON response.protected StringstripHtmlTags(String text) Strips HTML tags from the given text.protected StringtruncateForLog(String response) Returns a bounded prefix of an LLM response suitable for WARN-level logging.protected voidUpdates the cached availability state.protected StringwrapUserInput(String userMessage) Wraps user input with delimiters, escaping any closing tags in the content.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.codelibs.fess.llm.LlmClient
chat, getName, streamChat
-
Field Details
-
objectMapper
protected static final com.fasterxml.jackson.databind.ObjectMapper objectMapperShared ObjectMapper instance for JSON processing. -
CONTEXT_TRUNCATION_BUFFER
protected static final int CONTEXT_TRUNCATION_BUFFERBuffer size reserved when truncating context to fit within max chars limit.- See Also:
-
httpClient
protected org.apache.hc.client5.http.impl.classic.CloseableHttpClient httpClientThe HTTP client used for API communication. -
cachedAvailability
Cached availability status of the LLM provider. -
availabilityCheckTask
protected org.codelibs.core.timer.TimeoutTask availabilityCheckTaskThe scheduled task for periodic availability checks. -
concurrencyLimiter
Semaphore for limiting concurrent LLM requests. Initialized lazily in init(). -
systemPrompt
The system prompt for LLM interactions. -
intentDetectionPrompt
The prompt for detecting user intent. -
unclearIntentSystemPrompt
The system prompt for handling unclear intents. -
noResultsSystemPrompt
The system prompt for handling no results. -
documentNotFoundSystemPrompt
The system prompt for handling document not found. -
evaluationPrompt
The prompt for evaluating responses. -
answerGenerationSystemPrompt
The system prompt for answer generation. -
summarySystemPrompt
The system prompt for summary generation. -
faqAnswerSystemPrompt
The system prompt for FAQ answer generation. -
directAnswerSystemPrompt
The system prompt for direct answer generation. -
queryRegenerationPrompt
The prompt for query regeneration. -
LOG_RESPONSE_HEAD_MAX_CHARS
protected static final int LOG_RESPONSE_HEAD_MAX_CHARSMaximum length of an LLM response prefix surfaced in WARN-level operator logs.- See Also:
-
TRUNCATION_FINISH_REASONS
Provider-specific finish-reason values that indicate the LLM stopped because it ran out of output token budget (truncated response). Includes:length- OpenAI / OllamaMAX_TOKENS- Geminimax_tokens- Anthropicmodel_length- some self-hosted endpoints
-
-
Constructor Details
-
AbstractLlmClient
public AbstractLlmClient()Default constructor.
-
-
Method Details
-
register
public void register()Registers this client with the LlmClientManager. Called via postConstruct before init(). -
init
public void init()Initializes the HTTP client and starts availability checking. Should be called from subclass init() methods. -
configureProxy
protected void configureProxy(org.apache.hc.client5.http.impl.classic.HttpClientBuilder builder) Configures proxy settings on the HTTP client builder if a proxy is configured. Reads proxy configuration viagetProxyHost(),getProxyPort(),getProxyUsername(), andgetProxyPassword(). When username is provided, registers aBasicCredentialsProviderfor proxy authentication.- Parameters:
builder- the HTTP client builder to configure
-
getProxyHost
Gets the HTTP proxy host. Defaults tohttp.proxy.hostfrom FessConfig.- Returns:
- the proxy host, or null/blank if no proxy is configured
-
getProxyPort
Gets the HTTP proxy port. Defaults tohttp.proxy.portfrom FessConfig.- Returns:
- the proxy port, or null if no proxy is configured
-
getProxyUsername
Gets the HTTP proxy username. Defaults tohttp.proxy.usernamefrom FessConfig.- Returns:
- the proxy username, or null/blank if no proxy authentication is required
-
getProxyPassword
Gets the HTTP proxy password. Defaults tohttp.proxy.passwordfrom FessConfig.- Returns:
- the proxy password, or null if no proxy authentication is required
-
destroy
public void destroy()Cleans up resources. -
startAvailabilityCheck
protected void startAvailabilityCheck()Starts periodic availability checking if RAG chat is enabled. -
updateAvailability
protected void updateAvailability()Updates the cached availability state. -
isAvailable
public boolean isAvailable()Description copied from interface:LlmClientChecks if this LLM client is available and properly configured.- Specified by:
isAvailablein interfaceLlmClient- Returns:
- true if the client is available, false otherwise
-
getHttpClient
public org.apache.hc.client5.http.impl.classic.CloseableHttpClient getHttpClient()Gets the HTTP client, initializing it if necessary.- Returns:
- the HTTP client
-
checkAvailabilityNow
protected abstract boolean checkAvailabilityNow()Performs the actual availability check against the LLM provider.- Returns:
- true if the provider is available
-
getTimeout
protected abstract int getTimeout()Gets the request timeout in milliseconds.- Returns:
- the timeout in milliseconds
-
getModel
Gets the model name.- Returns:
- the model name
-
getAvailabilityCheckInterval
protected abstract int getAvailabilityCheckInterval()Gets the availability check interval in seconds.- Returns:
- the interval in seconds
-
isRagChatEnabled
protected abstract boolean isRagChatEnabled()Checks if RAG chat feature is enabled.- Returns:
- true if RAG chat is enabled
-
getLlmType
Gets the configured LLM type.- Returns:
- the LLM type from configuration
-
getConfigPrefix
Gets the configuration prefix for this provider. Used to look up per-prompt-type parameters from FessConfig.- Returns:
- the config prefix (e.g. "rag.llm.openai")
-
getSystemPrompt
Gets the base system prompt for RAG chat responses.- Returns:
- the system prompt
-
getIntentDetectionPrompt
Gets the intent detection prompt template.- Returns:
- the intent detection prompt
-
getUnclearIntentSystemPrompt
Gets the system prompt for unclear intent responses.- Returns:
- the unclear intent system prompt
-
getNoResultsSystemPrompt
Gets the system prompt for no-results responses.- Returns:
- the no-results system prompt
-
getDocumentNotFoundSystemPrompt
Gets the system prompt for document-not-found responses.- Returns:
- the document-not-found system prompt
-
getEvaluationPrompt
Gets the evaluation prompt for relevance checking.- Returns:
- the evaluation prompt
-
getAnswerGenerationSystemPrompt
Gets the system prompt for answer generation.- Returns:
- the answer generation system prompt
-
getSummarySystemPrompt
Gets the system prompt for summary generation.- Returns:
- the summary system prompt
-
getFaqAnswerSystemPrompt
Gets the system prompt for FAQ answer generation.- Returns:
- the FAQ answer system prompt
-
getDirectAnswerSystemPrompt
Gets the system prompt for direct answer generation.- Returns:
- the direct answer system prompt
-
getQueryRegenerationPrompt
Gets the query regeneration prompt template.- Returns:
- the query regeneration prompt
-
setSystemPrompt
Sets the system prompt for LLM interactions.- Parameters:
systemPrompt- the system prompt
-
setIntentDetectionPrompt
Sets the prompt for detecting user intent.- Parameters:
intentDetectionPrompt- the intent detection prompt
-
setUnclearIntentSystemPrompt
Sets the system prompt for handling unclear intents.- Parameters:
unclearIntentSystemPrompt- the unclear intent system prompt
-
setNoResultsSystemPrompt
Sets the system prompt for handling no results.- Parameters:
noResultsSystemPrompt- the no results system prompt
-
setDocumentNotFoundSystemPrompt
Sets the system prompt for handling document not found.- Parameters:
documentNotFoundSystemPrompt- the document not found system prompt
-
setEvaluationPrompt
Sets the prompt for evaluating responses.- Parameters:
evaluationPrompt- the evaluation prompt
-
setAnswerGenerationSystemPrompt
Sets the system prompt for answer generation.- Parameters:
answerGenerationSystemPrompt- the answer generation system prompt
-
setSummarySystemPrompt
Sets the system prompt for summary generation.- Parameters:
summarySystemPrompt- the summary system prompt
-
setFaqAnswerSystemPrompt
Sets the system prompt for FAQ answer generation.- Parameters:
faqAnswerSystemPrompt- the FAQ answer system prompt
-
setDirectAnswerSystemPrompt
Sets the system prompt for direct answer generation.- Parameters:
directAnswerSystemPrompt- the direct answer system prompt
-
setQueryRegenerationPrompt
Sets the prompt for query regeneration.- Parameters:
queryRegenerationPrompt- the query regeneration prompt
-
getConfigInt
Gets an integer configuration value using the config prefix and key suffix. Returns the configured value if it is a positive integer, otherwise returns the default.- Parameters:
keySuffix- the key suffix (appended to getConfigPrefix() + ".")defaultValue- the default value- Returns:
- the configured or default value
-
getContextMaxChars
Gets the maximum characters for context building for a specific prompt type. Each LlmClient implementation defines per-prompt-type defaults appropriate for its target model.- Parameters:
promptType- the prompt type (e.g., "answer", "summary", "faq")- Returns:
- the maximum characters
-
getEvaluationMaxRelevantDocs
protected abstract int getEvaluationMaxRelevantDocs()Gets the maximum number of relevant documents for evaluation.- Returns:
- the maximum number of relevant documents
-
getEvaluationDescriptionMaxChars
protected abstract int getEvaluationDescriptionMaxChars()Gets the maximum number of characters for evaluation description.- Returns:
- the maximum number of characters
-
getHistoryMaxChars
protected int getHistoryMaxChars()Gets the maximum characters for conversation history in LLM requests. Each LlmClient implementation should override to define defaults appropriate for its target model. The default returns 4000 for backward compatibility.- Returns:
- the maximum history characters
-
getIntentHistoryMaxMessages
protected int getIntentHistoryMaxMessages()Gets the maximum number of history messages for intent detection. The default returns 6. Override in subclasses for provider-specific tuning.- Returns:
- the maximum number of messages
-
getIntentHistoryMaxChars
protected int getIntentHistoryMaxChars()Gets the maximum characters for intent detection history. The default returns 3000. Override in subclasses for provider-specific tuning.- Returns:
- the maximum characters
-
getHistoryAssistantMaxChars
public int getHistoryAssistantMaxChars()Gets the maximum characters for assistant message content in history. The default returns 800. Override in subclasses for provider-specific tuning.- Specified by:
getHistoryAssistantMaxCharsin interfaceLlmClient- Returns:
- the maximum characters
-
getHistoryAssistantSummaryMaxChars
public int getHistoryAssistantSummaryMaxChars()Gets the maximum characters for assistant summary content in history. The default returns 800. Override in subclasses for provider-specific tuning.- Specified by:
getHistoryAssistantSummaryMaxCharsin interfaceLlmClient- Returns:
- the maximum characters
-
getMaxConcurrentRequests
protected int getMaxConcurrentRequests()Gets the maximum number of concurrent requests to the LLM provider. Default is 5. Override or configure via rag.llm.{provider}.max.concurrent.requests.- Returns:
- the maximum concurrent requests
-
getConcurrencyWaitTimeoutMs
protected long getConcurrencyWaitTimeoutMs()Gets the timeout for waiting to acquire a concurrency permit (ms). Default is 30000ms. Override or configure via rag.llm.{provider}.concurrency.wait.timeout.- Returns:
- the wait timeout in milliseconds
-
chatWithConcurrencyControl
Executes a chat request with concurrency control via Semaphore.- Parameters:
request- the chat request- Returns:
- the chat response
- Throws:
LlmException- if too many concurrent requests or interrupted
-
streamChatWithConcurrencyControl
Executes a streaming chat request with concurrency control via Semaphore.- Parameters:
request- the chat requestcallback- the streaming callback- Throws:
LlmException- if too many concurrent requests or interrupted
-
applyPromptTypeParams
Applies per-prompt-type parameters to the request from configuration. Reads temperature, max.tokens, and thinking.budget from config using the pattern: {configPrefix}.{promptType}.{paramName} Subclasses can override to add provider-specific parameters (e.g. reasoning_effort, top_p).- Parameters:
request- the LLM chat requestpromptType- the prompt type (e.g. "intent", "evaluation", "answer")
-
getUserLocale
Gets the user's locale from the current request context.- Returns:
- the user's locale, or default locale if not in request context
-
getLanguageInstruction
Gets the language instruction based on the user's locale.- Returns:
- the language instruction string, or empty string if locale is English
-
resolveLanguageInstruction
Resolves the {{languageInstruction}} placeholder in a prompt.- Parameters:
prompt- the prompt template- Returns:
- the prompt with language instruction resolved
-
detectIntent
Description copied from interface:LlmClientDetects the intent of a user message.- Specified by:
detectIntentin interfaceLlmClient- Parameters:
userMessage- the user's message- Returns:
- the detected intent with extracted keywords
-
detectIntent
Description copied from interface:LlmClientDetects the intent of a user message with conversation history context.- Specified by:
detectIntentin interfaceLlmClient- Parameters:
userMessage- the user's messagehistory- the conversation history for context- Returns:
- the detected intent with extracted keywords
-
evaluateResults
public RelevanceEvaluationResult evaluateResults(String userMessage, String query, List<Map<String, Object>> searchResults) Description copied from interface:LlmClientEvaluates search results for relevance to the user's question.- Specified by:
evaluateResultsin interfaceLlmClient- Parameters:
userMessage- the original user messagequery- the search query usedsearchResults- the search results to evaluate- Returns:
- evaluation result with relevant document IDs
-
generateAnswer
public LlmChatResponse generateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history) Description copied from interface:LlmClientGenerates an answer using document content (synchronous version for non-enhanced flow).- Specified by:
generateAnswerin interfaceLlmClient- Parameters:
userMessage- the user's messagedocuments- the documents with contenthistory- the conversation history- Returns:
- the chat response
-
regenerateQuery
public String regenerateQuery(String userMessage, String failedQuery, String failureReason, List<LlmMessage> history) Description copied from interface:LlmClientRegenerates a search query when the previous query failed to produce relevant results.- Specified by:
regenerateQueryin interfaceLlmClient- Parameters:
userMessage- the user's original messagefailedQuery- the query that failedfailureReason- the reason for failure ("no_results" or "no_relevant_results")history- the conversation history- Returns:
- a new query string, or the userMessage if regeneration fails
-
streamGenerateAnswer
public void streamGenerateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates an answer using document content (streaming version for enhanced flow).- Specified by:
streamGenerateAnswerin interfaceLlmClient- Parameters:
userMessage- the user's messagedocuments- the documents with contenthistory- the conversation historycallback- the streaming callback
-
generateUnclearIntentResponse
public void generateUnclearIntentResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates a response asking user for clarification when intent is unclear.- Specified by:
generateUnclearIntentResponsein interfaceLlmClient- Parameters:
userMessage- the user's messagehistory- the conversation historycallback- the streaming callback
-
generateNoResultsResponse
public void generateNoResultsResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates a response when no relevant documents are found.- Specified by:
generateNoResultsResponsein interfaceLlmClient- Parameters:
userMessage- the user's messagehistory- the conversation historycallback- the streaming callback
-
generateDocumentNotFoundResponse
public void generateDocumentNotFoundResponse(String userMessage, String documentUrl, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates a response when the specified document URL is not found.- Specified by:
generateDocumentNotFoundResponsein interfaceLlmClient- Parameters:
userMessage- the user's messagedocumentUrl- the URL that was not foundhistory- the conversation historycallback- the streaming callback
-
generateSummaryResponse
public void generateSummaryResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates a summary of the specified documents.- Specified by:
generateSummaryResponsein interfaceLlmClient- Parameters:
userMessage- the user's messagedocuments- the documents to summarizehistory- the conversation historycallback- the streaming callback
-
generateFaqAnswerResponse
public void generateFaqAnswerResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history, LlmStreamCallback callback) Description copied from interface:LlmClientGenerates an FAQ answer using document content (streaming). Uses a prompt optimized for direct, concise FAQ-style answers.- Specified by:
generateFaqAnswerResponsein interfaceLlmClient- Parameters:
userMessage- the user's messagedocuments- the documents with contenthistory- the conversation historycallback- the streaming callback
-
generateDirectAnswer
public void generateDirectAnswer(String userMessage, List<LlmMessage> history, LlmStreamCallback callback) Generates a direct answer without document search. This method is currently not called from the streamChatEnhanced() flow, but is provided as an extension point for future DIRECT_ANSWER intent support.- Specified by:
generateDirectAnswerin interfaceLlmClient- Parameters:
userMessage- the user's messagehistory- the conversation historycallback- the streaming callback
-
wrapUserInput
Wraps user input with delimiters, escaping any closing tags in the content.- Parameters:
userMessage- the user's message to wrap- Returns:
- the wrapped user input
-
buildIntentDetectionSystemPrompt
Builds the system prompt for intent detection by removing the user-specific placeholders.- Returns:
- the system prompt for intent detection
-
addIntentHistory
Adds conversation history as structured messages for intent detection.- Parameters:
request- the LLM chat requesthistory- the conversation history
-
buildEvaluationPrompt
protected String buildEvaluationPrompt(String userMessage, String query, List<Map<String, Object>> searchResults) Builds the evaluation prompt for relevance checking.- Parameters:
userMessage- the user's messagequery- the search querysearchResults- the search results to evaluate- Returns:
- the evaluation prompt
-
stripHtmlTags
Strips HTML tags from the given text.- Parameters:
text- the text to strip HTML tags from- Returns:
- the text without HTML tags
-
sanitizeDocumentContent
Sanitizes document content by escaping delimiter-like sequences to prevent boundary spoofing in LLM prompts.- Parameters:
text- the text to sanitize- Returns:
- the sanitized text with delimiter sequences escaped
-
buildContext
Builds context from document content for the LLM prompt.- Parameters:
documents- the search result documentspromptType- the prompt type (e.g., "answer", "summary", "faq")- Returns:
- the context string
-
buildStreamingRequest
protected LlmChatRequest buildStreamingRequest(String userMessage, String context, List<LlmMessage> history) Builds a streaming LLM chat request with conversation history.- Parameters:
userMessage- the user's messagecontext- the context from search resultshistory- the conversation history- Returns:
- the LLM chat request
-
addHistoryWithBudget
protected void addHistoryWithBudget(LlmChatRequest request, List<LlmMessage> history, int budgetChars) Adds conversation history to the request, truncating from oldest to fit within the character budget.- Parameters:
request- the LLM chat requesthistory- the conversation history (oldest first)budgetChars- the maximum total characters for history messages
-
parseIntentResponse
Parses the LLM response and extracts intent detection result.- Parameters:
response- the JSON response from LLMuserMessage- the original user message- Returns:
- the parsed intent detection result
-
parseEvaluationResponse
protected RelevanceEvaluationResult parseEvaluationResponse(String response, List<Map<String, Object>> searchResults) Parses the evaluation response from LLM.- Parameters:
response- the LLM responsesearchResults- the search results- Returns:
- the parsed evaluation result
-
stripCodeFences
Strips code fence markers from JSON response.- Parameters:
response- the response that may contain code fences- Returns:
- the response with code fences removed
-
extractJsonString
Extracts a string value from JSON response using Jackson parser.- Parameters:
json- the JSON responsekey- the key to extract- Returns:
- the extracted string value
-
extractJsonStringFallback
Fallback regex-based extraction for string values.- Parameters:
json- the JSON responsekey- the key to extract- Returns:
- the extracted string value
-
extractJsonBoolean
Extracts a boolean value from JSON response.- Parameters:
json- the JSON responsekey- the key to extract- Returns:
- the extracted boolean value
-
extractJsonArray
Extracts a string array from JSON response.- Parameters:
json- the JSON responsekey- the key to extract- Returns:
- the extracted string array
-
extractJsonIntArray
Extracts an integer array from JSON response.- Parameters:
json- the JSON responsekey- the key to extract- Returns:
- the extracted integer array
-
resolveErrorCode
Resolves an HTTP status code to an LlmException error code.- Parameters:
statusCode- the HTTP status code- Returns:
- the corresponding error code
-
truncateForLog
Returns a bounded prefix of an LLM response suitable for WARN-level logging. Limits operator log volume and reduces accidental exposure of user-supplied text or retrieved context that may appear inside a malformed response. The full payload remains available at DEBUG via the surrounding callers.- Parameters:
response- the raw LLM response (may be null)- Returns:
- a truncated, log-safe prefix; "null" when response is null
-
isTruncatedFinish
Checks if a finish reason indicates that the LLM response was truncated by the output token limit (provider-agnostic).- Parameters:
finishReason- the finish reason reported by the LLM provider- Returns:
- true if the reason indicates truncation
-
isEmptyContentWithLengthFinish
Checks if the LLM response has empty/blank content combined with a truncation finish reason. This typically indicates that a reasoning model consumed all tokens for internal reasoning, leaving no tokens for actual output content.- Parameters:
response- the LLM chat response- Returns:
- true if content is empty/blank and finish reason indicates truncation
-
getStringValue
Gets a string value from a map.- Parameters:
map- the map to get the value fromkey- the key to look up- Returns:
- the string value, or an empty string if not found
-
addHistory
Adds conversation history to the request.- Parameters:
request- the LLM chat requesthistory- the conversation history
-