Skip to content

Proposal: Per-agent exclusion mechanism for before_prompt_build hooks (related to #492) #514

@jlin53882

Description

@jlin53882

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

  1. Is this approach acceptable? autoRecallExcludeAgents now serves both auto-recall
    and reflection exclusion purposes.
  2. Should we split into reflectionExcludeAgents for clarity?
  3. Is the 120s cooldown (SERIAL_GUARD_COOLDOWN_MS) reasonable, or should it be
    configurable?
  4. Any concerns about using globalThis with Symbol.for for the lock maps?

Related to: #492
See also: PR #516

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions