Problem
Issue #492 describes a scenario where memoryReflection hooks in before_prompt_build are
synchronously executing LanceDB queries on every user session, causing 30-50% of user
sessions to fail to produce replies. The root cause is that two before_prompt_build hooks
(priority 12 and 15) call await loadAgentReflectionSlices() which does store.list() --
a blocking DB operation during prompt build.
Proposed Solution
A per-agent exclusion mechanism via the existing autoRecallExcludeAgents config field,
extended to also protect the memoryReflection hooks.
Changes (PR #516)
1. New helper function isAgentOrSessionExcluded
Supports three pattern types:
- Exact match: memory-distiller
- Wildcard prefix: pi- (matches pi-agent, pi-coder)
- Special temp:* for internal reflection sessions
2. Fixed auto-recall before_prompt_build exclusion check
Removed the ineffective agentId !== undefined check (always true due to || "main" fallback).
3. Added exclusion checks to both reflection before_prompt_build hooks (priority 12 & 15)
Both hooks now have isInternalReflectionSessionKey guard first, followed by
isAgentOrSessionExcluded check.
4. Three-layer guard on runMemoryReflection command hook
- Internal session guard
- Re-entrant guard (global lock via Symbol.for + globalThis)
- Serial cooldown guard (120s)
5. Added internal session guard to appendSelfImprovementNote
Consistent with agent:bootstrap hook behavior.
6. Enhanced early-return logging
All early returns now include sessionKey/sessionId for observability.
Protection Matrix
| Hook |
Protection |
| before_prompt_build (auto-recall) |
exclusion check |
| before_prompt_build (priority 12) |
isInternal guard + exclusion |
| before_prompt_build (priority 15) |
isInternal guard + exclusion |
| command:new/reset -> runMemoryRefl. |
three-layer guard |
| appendSelfImprovementNote |
internal session guard |
Usage
{
"memory-lancedb-pro": {
"autoRecallExcludeAgents": ["memory-distiller", "pi-", "temp:*"]
}
}
Questions for Maintainers
- Is this approach acceptable? autoRecallExcludeAgents now serves both auto-recall
and reflection exclusion purposes.
- Should we split into reflectionExcludeAgents for clarity?
- Is the 120s cooldown (SERIAL_GUARD_COOLDOWN_MS) reasonable, or should it be
configurable?
- Any concerns about using globalThis with Symbol.for for the lock maps?
Related to: #492
See also: PR #516
Problem
Issue #492 describes a scenario where memoryReflection hooks in before_prompt_build are
synchronously executing LanceDB queries on every user session, causing 30-50% of user
sessions to fail to produce replies. The root cause is that two before_prompt_build hooks
(priority 12 and 15) call await loadAgentReflectionSlices() which does store.list() --
a blocking DB operation during prompt build.
Proposed Solution
A per-agent exclusion mechanism via the existing autoRecallExcludeAgents config field,
extended to also protect the memoryReflection hooks.
Changes (PR #516)
1. New helper function isAgentOrSessionExcluded
Supports three pattern types:
2. Fixed auto-recall before_prompt_build exclusion check
Removed the ineffective agentId !== undefined check (always true due to || "main" fallback).
3. Added exclusion checks to both reflection before_prompt_build hooks (priority 12 & 15)
Both hooks now have isInternalReflectionSessionKey guard first, followed by
isAgentOrSessionExcluded check.
4. Three-layer guard on runMemoryReflection command hook
5. Added internal session guard to appendSelfImprovementNote
Consistent with agent:bootstrap hook behavior.
6. Enhanced early-return logging
All early returns now include sessionKey/sessionId for observability.
Protection Matrix
Usage
{
"memory-lancedb-pro": {
"autoRecallExcludeAgents": ["memory-distiller", "pi-", "temp:*"]
}
}
Questions for Maintainers
and reflection exclusion purposes.
configurable?
Related to: #492
See also: PR #516