Bug Description
When both StaticLongTermMemoryHook and GenericRAGHook are attached to the same agent, they interfere with each other's message extraction logic. Each hook searches for "the last user message" to use as its query, but since both hooks inject their results as USER role messages at the end of the message list, one hook may pick up the other hook's injected message instead of the original user input.
Root Cause
This is a side effect of previous fixes:
Both hooks use "find the last USER role message" to extract the user's query:
StaticLongTermMemoryHook#extractLastUserMessageIndex — scans from end to start, returns the first USER role message
GenericRAGHook#extractQueryFromMessages — scans from end to start, returns the first USER role message's text
Since hooks execute in a chain, when the second hook runs, the first hook has already appended its USER message. The second hook then picks up that injected message as the "user query", not the actual user input.
Example flow (hooks execute by priority; both have priority 50):
- User sends:
USER: "What is the refund policy?"
StaticLongTermMemoryHook runs first:
extractLastUserMessageIndex finds "What is the refund policy?" ✓
- Appends
USER (name="long_term_memory"): <long_term_memory>...</long_term_memory>
GenericRAGHook runs next:
extractQueryFromMessages finds <long_term_memory>...</long_term_memory> ✗ — this is the memory hook's output, not the user's query!
- Uses this as the RAG retrieval query, producing irrelevant or incorrect results
The reverse scenario is equally problematic if the RAG hook runs first.
Steps to Reproduce
- Configure a
ReActAgent with both StaticLongTermMemoryHook and GenericRAGHook
- Send a user query
- Observe that the second-executing hook uses the first hook's injected message as its retrieval query
Expected Behavior
Each hook should extract the original user input message, not the other hook's injected context.
Suggested Fix
Give injected messages distinct name identifiers so that each hook can skip them when extracting the user query:
StaticLongTermMemoryHook already uses name="long_term_memory" — update extractLastUserMessageIndex to skip messages where name is "retrieved_knowledge"
GenericRAGHook should use name="retrieved_knowledge" (instead of the default "user") — update extractQueryFromMessages to skip messages where name is "long_term_memory"
This way each hook only considers genuine user input messages, regardless of execution order.
Related Issues
Bug Description
When both
StaticLongTermMemoryHookandGenericRAGHookare attached to the same agent, they interfere with each other's message extraction logic. Each hook searches for "the last user message" to use as its query, but since both hooks inject their results asUSERrole messages at the end of the message list, one hook may pick up the other hook's injected message instead of the original user input.Root Cause
This is a side effect of previous fixes:
StaticLongTermMemoryHookto inject memory as aUSERmessage at the end of the message list (previously it wasSYSTEMat the end)GenericRAGHookto inject retrieved knowledge as aUSERmessage (previously it wasSYSTEM)Both hooks use "find the last
USERrole message" to extract the user's query:StaticLongTermMemoryHook#extractLastUserMessageIndex— scans from end to start, returns the firstUSERrole messageGenericRAGHook#extractQueryFromMessages— scans from end to start, returns the firstUSERrole message's textSince hooks execute in a chain, when the second hook runs, the first hook has already appended its
USERmessage. The second hook then picks up that injected message as the "user query", not the actual user input.Example flow (hooks execute by priority; both have priority 50):
USER: "What is the refund policy?"StaticLongTermMemoryHookruns first:extractLastUserMessageIndexfinds"What is the refund policy?"✓USER (name="long_term_memory"): <long_term_memory>...</long_term_memory>GenericRAGHookruns next:extractQueryFromMessagesfinds<long_term_memory>...</long_term_memory>✗ — this is the memory hook's output, not the user's query!The reverse scenario is equally problematic if the RAG hook runs first.
Steps to Reproduce
ReActAgentwith bothStaticLongTermMemoryHookandGenericRAGHookExpected Behavior
Each hook should extract the original user input message, not the other hook's injected context.
Suggested Fix
Give injected messages distinct
nameidentifiers so that each hook can skip them when extracting the user query:StaticLongTermMemoryHookalready usesname="long_term_memory"— updateextractLastUserMessageIndexto skip messages wherenameis"retrieved_knowledge"GenericRAGHookshould usename="retrieved_knowledge"(instead of the default"user") — updateextractQueryFromMessagesto skip messages wherenameis"long_term_memory"This way each hook only considers genuine user input messages, regardless of execution order.
Related Issues
USERrole injection)USERrole injection at end)