Skip to content

[bug] Concurrent memory recalls silently lose the vector path (query-embedding dedupe is per agent/model, not per query) #1887

Description

@yyhhyyyyyy

Summary

startQueryEmbedding (src/main/presenter/memoryPresenter/services/retrievalService.ts:90-112) dedupes in-flight query embeddings by agentId::embeddingFingerprint — the query text is not part of the key — and returns null for any caller while a fresh entry exists, making that caller skip vector recall for the turn.

Consequences:

  • Memory injection and a memory_recall tool call in the same turn collide; the second silently degrades to FTS-only.
  • After an 800 ms soft timeout (RECALL_QUERY_EMBEDDING_TIMEOUT_MS), the timed-out promise stays in flight, so subsequent recalls keep skipping the vector path until the provider call settles or the 30 s staleness window (RECALL_QUERY_EMBEDDING_STALE_MS) expires.
  • Background consolidation retrieves occupy the same key and starve foreground recalls (tracked separately in [bug] Memory consolidation near-duplicate pass makes unbounded embedding calls and starves foreground vector recall #1883).

The single-entry skip was an accepted AC of docs/issues/memory-recall-hot-path-keyword-recall/spec.md; this issue revisits that tradeoff: share identical-query embeddings and allow a small bounded number of concurrent distinct-query embeddings instead of skipping outright.

Severity

P2 — silent recall-quality degradation under normal concurrency; only a warn log distinguishes it.

SDD doc: docs/issues/memory-audit-hardening/ (spec.md + plan.md + tasks.md)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions