View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.llm;
17  
18  import java.util.List;
19  import java.util.Map;
20  
21  /**
22   * Interface for LLM (Large Language Model) clients.
23   * Implementations provide integration with different LLM providers
24   * such as Ollama, OpenAI, and Google Gemini.
25   *
26   * In addition to low-level chat operations, this interface defines
27   * high-level RAG workflow methods that allow each provider to optimize
28   * prompt construction, parameter tuning, and response parsing.
29   */
30  public interface LlmClient {
31  
32      /**
33       * Performs a chat completion request.
34       *
35       * @param request the chat request containing messages and parameters
36       * @return the chat response from the LLM
37       * @throws LlmException if an error occurs during the request
38       */
39      LlmChatResponse chat(LlmChatRequest request);
40  
41      /**
42       * Performs a streaming chat completion request.
43       * The callback is invoked for each chunk of the response.
44       *
45       * @param request the chat request containing messages and parameters
46       * @param callback the callback to receive streaming chunks
47       * @throws LlmException if an error occurs during the request
48       */
49      void streamChat(LlmChatRequest request, LlmStreamCallback callback);
50  
51      /**
52       * Returns the name of this LLM client.
53       *
54       * @return the client name (e.g., "ollama", "openai", "gemini")
55       */
56      String getName();
57  
58      /**
59       * Checks if this LLM client is available and properly configured.
60       *
61       * @return true if the client is available, false otherwise
62       */
63      boolean isAvailable();
64  
65      // RAG workflow methods
66  
67      /**
68       * Detects the intent of a user message.
69       *
70       * @param userMessage the user's message
71       * @return the detected intent with extracted keywords
72       */
73      IntentDetectionResult detectIntent(String userMessage);
74  
75      /**
76       * Detects the intent of a user message with conversation history context.
77       *
78       * @param userMessage the user's message
79       * @param history the conversation history for context
80       * @return the detected intent with extracted keywords
81       */
82      default IntentDetectionResult detectIntent(String userMessage, List<LlmMessage> history) {
83          return detectIntent(userMessage);
84      }
85  
86      /**
87       * Evaluates search results for relevance to the user's question.
88       *
89       * @param userMessage the original user message
90       * @param query the search query used
91       * @param searchResults the search results to evaluate
92       * @return evaluation result with relevant document IDs
93       */
94      RelevanceEvaluationResult evaluateResults(String userMessage, String query, List<Map<String, Object>> searchResults);
95  
96      /**
97       * Generates an answer using document content (synchronous version for non-enhanced flow).
98       *
99       * @param userMessage the user's message
100      * @param documents the documents with content
101      * @param history the conversation history
102      * @return the chat response
103      */
104     LlmChatResponse generateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history);
105 
106     /**
107      * Regenerates a search query when the previous query failed to produce relevant results.
108      *
109      * @param userMessage the user's original message
110      * @param failedQuery the query that failed
111      * @param failureReason the reason for failure ("no_results" or "no_relevant_results")
112      * @param history the conversation history
113      * @return a new query string, or the userMessage if regeneration fails
114      */
115     String regenerateQuery(String userMessage, String failedQuery, String failureReason, List<LlmMessage> history);
116 
117     /**
118      * Generates an answer using document content (streaming version for enhanced flow).
119      *
120      * @param userMessage the user's message
121      * @param documents the documents with content
122      * @param history the conversation history
123      * @param callback the streaming callback
124      */
125     void streamGenerateAnswer(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history,
126             LlmStreamCallback callback);
127 
128     /**
129      * Generates a response asking user for clarification when intent is unclear.
130      *
131      * @param userMessage the user's message
132      * @param history the conversation history
133      * @param callback the streaming callback
134      */
135     void generateUnclearIntentResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback);
136 
137     /**
138      * Generates a response when no relevant documents are found.
139      *
140      * @param userMessage the user's message
141      * @param history the conversation history
142      * @param callback the streaming callback
143      */
144     void generateNoResultsResponse(String userMessage, List<LlmMessage> history, LlmStreamCallback callback);
145 
146     /**
147      * Generates a response when the specified document URL is not found.
148      *
149      * @param userMessage the user's message
150      * @param documentUrl the URL that was not found
151      * @param history the conversation history
152      * @param callback the streaming callback
153      */
154     void generateDocumentNotFoundResponse(String userMessage, String documentUrl, List<LlmMessage> history, LlmStreamCallback callback);
155 
156     /**
157      * Generates a summary of the specified documents.
158      *
159      * @param userMessage the user's message
160      * @param documents the documents to summarize
161      * @param history the conversation history
162      * @param callback the streaming callback
163      */
164     void generateSummaryResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history,
165             LlmStreamCallback callback);
166 
167     /**
168      * Generates an FAQ answer using document content (streaming).
169      * Uses a prompt optimized for direct, concise FAQ-style answers.
170      *
171      * @param userMessage the user's message
172      * @param documents the documents with content
173      * @param history the conversation history
174      * @param callback the streaming callback
175      */
176     void generateFaqAnswerResponse(String userMessage, List<Map<String, Object>> documents, List<LlmMessage> history,
177             LlmStreamCallback callback);
178 
179     /**
180      * Generates a direct answer without document search.
181      *
182      * @param userMessage the user's message
183      * @param history the conversation history
184      * @param callback the streaming callback
185      */
186     void generateDirectAnswer(String userMessage, List<LlmMessage> history, LlmStreamCallback callback);
187 
188     /**
189      * Gets the maximum characters for assistant message in history.
190      *
191      * @return the maximum characters
192      */
193     default int getHistoryAssistantMaxChars() {
194         return 800;
195     }
196 
197     /**
198      * Gets the maximum characters for assistant summary in history.
199      *
200      * @return the maximum characters
201      */
202     default int getHistoryAssistantSummaryMaxChars() {
203         return 800;
204     }
205 }