Conversation
…t/LLM - Add session ownership verification in ChatSessionManager.clearSession() to prevent cross-user session clearing; validate userId on session reuse - Add semaphore-based concurrency control in AbstractLlmClient to limit concurrent LLM requests (configurable via rag.llm.*.max.concurrent.requests) - Prevent prompt injection in intent detection system prompt and evaluation prompts by adding delimiter markers around user/search inputs - Wrap document URLs in [URL: ...] format to prevent injection in generateDocumentNotFoundResponse - Refactor LlmClientManager to use getAvailableClient() consolidating duplicate availability checks across all delegation methods - Move user message addition and trimHistory to finally block in ChatClient for session integrity under concurrent access and error conditions - Simplify history budget calculation to use getHistoryMaxChars() directly - Add truncation fallback when newest history message exceeds budget - Rename escapeLuceneValue to escapeQueryValue; skip NULL characters in escaping - Add new config properties for history max chars and highlight settings - Update Javadoc terminology from "Lucene query" to "Fess query" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n, and RAG config keys - Make getContextMaxChars prompt-type aware to allow per-type defaults - Preserve search score order when fetching full document content - Tighten relevance evaluator system prompt for stricter filtering - Add config keys: intent history max messages, message max length, highlight fragment size/count, history assistant content/chars, and history max chars Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove the initial "session" SSE event from ChatApiManager and its client-side handler in chat.js (sessionId is already set before SSE starts) - Extract private findSession() to separate lookup from touch, preventing unintended session lifetime extension during internal lookups - Add explicit session.touch() calls in getOrCreateSession and clearSession for correct session lifetime tracking - Pass userId to clearSession in ChatAction for proper ownership validation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LlmClientManagerto consolidate availability checks intogetAvailableClient()ChatClientChanges Made
Security
ChatSessionManager.clearSession(sessionId, userId): New overload validates userId ownership before clearing; rejects mismatched user IDs with 404ChatApiManager: Session clear now passes userId for ownership verificationAbstractLlmClient.buildIntentDetectionSystemPrompt(): Added anti-injection instruction appended to system prompt--- USER QUERY START ---etc.) to prevent injectiongenerateDocumentNotFoundResponse: Document URL wrapped as[URL: ...]to prevent injectionescapeQueryValue(renamed fromescapeLuceneValue): Skip NULL characters in query value escapingContext & Relevance
getContextMaxChars(): Now prompt-type aware, allowing per-type default context sizesConcurrency Control
AbstractLlmClient: AddedSemaphore-based concurrency limiter initialized ininit()chatWithConcurrencyControl()/streamChatWithConcurrencyControl(): All LLM calls now go through concurrency limitingrag.llm.{provider}.max.concurrent.requests(default: 5) andrag.llm.{provider}.concurrency.wait.timeout(default: 30000ms)LlmException(ERROR_RATE_LIMIT)when too many concurrent requestsReliability
ChatClient: User message added to session immediately (before LLM call) for session integrity under concurrency;trimHistory()moved tofinallyblockAbstractLlmClient.addHistoryWithBudget(): Truncation fallback when newest history message exceeds budgetbuildStreamingRequest(): Simplified history budget — usesgetHistoryMaxChars()directly instead of complex fixed-size calculationaddHistoryWithBudget()withgetHistoryMaxChars()Refactoring
LlmClientManager.getAvailableClient(): Consolidated duplicate!available()checks across all 10+ delegation methodsIntentDetectionResult,ChatClientConfiguration
Added to
fess_config.properties:Plus config keys for intent history max messages, message max length, and per-provider concurrency settings.
Testing
ChatClientTest: Updated to reflect new session message ordering (user message added before LLM call)AbstractLlmClientTest: Updated for method renameIntentDetectionResultTest: Updated accordinglyBreaking Changes
ChatSessionManager.clearSession(String sessionId)(no-arg userId) still exists for admin/internal use, but the API-facing path now requires userId ownership matchescapeLuceneValuerenamed toescapeQueryValueinChatClient(internal method)🤖 Generated with Claude Code