Problem
When a sub-agent (e.g. via /new command or delegate) runs, its before_prompt_build hooks execute synchronously inside the same Node.js process as the gateway, blocking the event loop. User sessions waiting on the gateway's IPC response are starved.
This manifests as:
The root cause is that memory-lancedb-pro registers multiple before_prompt_build hooks (priority 12 and 15) that call await loadAgentReflectionSlices() which does store.list() -- a blocking DB operation during prompt build. The agent:bootstrap hook has subagent skip logic but before_prompt_build hooks do not.
Proposed Solution
A per-agent exclusion mechanism via the existing autoRecallExcludeAgents config field, extended to also protect the memoryReflection hooks.
Changes
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: #492
Problem
When a sub-agent (e.g. via
/newcommand or delegate) runs, itsbefore_prompt_buildhooks execute synchronously inside the same Node.js process as the gateway, blocking the event loop. User sessions waiting on the gateway's IPC response are starved.This manifests as:
/newsessions fail to produce a response (Issue memoryReflection hook in before_prompt_build starves user session (beta.10) #492)doneinsessions.jsonbut no JSONL file writtenThe root cause is that
memory-lancedb-proregisters multiplebefore_prompt_buildhooks (priority 12 and 15) that callawait loadAgentReflectionSlices()which doesstore.list()-- a blocking DB operation during prompt build. Theagent:bootstraphook has subagent skip logic butbefore_prompt_buildhooks do not.Proposed Solution
A per-agent exclusion mechanism via the existing
autoRecallExcludeAgentsconfig field, extended to also protect the memoryReflection hooks.Changes
1. New helper function
isAgentOrSessionExcludedSupports three pattern types:
memory-distillerpi-(matchespi-agent,pi-coder)temp:*for internal reflection sessions2. Fixed auto-recall
before_prompt_buildexclusion checkRemoved the ineffective
agentId !== undefinedcheck (always true due to|| "main"fallback).3. Added exclusion checks to both reflection
before_prompt_buildhooks (priority 12 & 15)Both hooks now have
isInternalReflectionSessionKeyguard first, followed byisAgentOrSessionExcludedcheck.4. Three-layer guard on
runMemoryReflectioncommand hookSymbol.for+globalThis)5. Added internal session guard to
appendSelfImprovementNoteConsistent with
agent:bootstraphook behavior.6. Enhanced early-return logging
All early returns now include
sessionKey/sessionIdfor observability.Protection Matrix
before_prompt_build(auto-recall)before_prompt_build(priority 12)before_prompt_build(priority 15)command:new/reset -> runMemoryRefl.appendSelfImprovementNoteUsage
{ "memory-lancedb-pro": { "autoRecallExcludeAgents": ["memory-distiller", "pi-", "temp:*"] } }Questions for Maintainers
autoRecallExcludeAgentsnow serves both auto-recall and reflection exclusion purposes.reflectionExcludeAgentsfor clarity?SERIAL_GUARD_COOLDOWN_MS) reasonable, or should it be configurable?globalThiswithSymbol.forfor the lock maps?Related: #492