Get started

Conversation Recall

One vector per conversation, org and user scoped, so agents can find a past conversation from a paraphrase rather than a keyword match.

Memory System covers facts, preferences and entities extracted from a conversation. Conversation recall (internally QM-LTM) is narrower: it stores the conversation itself, as a single searchable summary, so an agent can later be reminded that a given topic came up before, even if the current question is worded differently to the original one.

What it does

services/collector/lib/conversationRecall.js runs two operations:

  • Capture. After a conversation, the module builds a bounded extractive summary (the agent name, the last six history turns, the latest prompt, the final response, each truncated, the whole thing capped at 4,000 characters), embeds it, and upserts a single point into a conversation-history Qdrant collection (768-dimension vectors), scoped by org_id and user_id.
  • Recall. Given a query, the module embeds it and runs a vector search against the same collection, filtered to the caller's org (and user, when supplied), returning the closest past conversations with a similarity score.

Bounded by design

Three deliberate limits keep this a small, predictable surface rather than a growing archive:

  • One vector per conversation. The point id is derived deterministically from org_id and conversation_id (a SHA-256 hash, not a random UUID), so a re-capture of the same conversation overwrites the existing point rather than adding a duplicate. There is no history of past summaries for a single conversation, only the latest.
  • Per-conversation throttle. A capture is skipped if the same conversation was captured inside the last QM_LTM_MIN_INTERVAL_MS (default 120,000ms, two minutes). The throttle state is an in-process map, capped at 500 entries with FIFO eviction, so a long-running collector process cannot grow it unbounded.
  • No full-history scans. Both capture and recall work from a bounded summary and a capped, filtered vector search (recall is capped at 10 results), never a scan across a user's entire conversation history.

Every failure path in the module is non-fatal: a missing vector, a failed embed, or a declined upsert logs a warning and returns { captured: false, reason } rather than throwing, so recall can never break the chat path it sits next to.

Provider keys: a real bug, fixed 2026-08-05

Until 2026-08-05, both capture and recall called the embedding function with no provider keys. On any org resolving its embedding key through the vault-backed, org-scoped resolver, rather than a bare environment variable, every capture silently failed: no vector was written, and recall always came back empty, with nothing visible to the user or in the response.

The fix wires a configure() hook at server boot so conversationRecall.js resolves keys through the same org-scoped provider-key resolver the rest of the chat stack uses, instead of maintaining a second implementation of its own.

Verified live, 2026-08-05 (local verification, not a benchmark): three conversations were captured, then three paraphrased queries were run against them. Each query returned the correct conversation first, with a clear score margin over the next-best result: 0.742 against 0.503, 0.756 against 0.529, and 0.714 against 0.509.

The env flag

QM_LTM_ENABLED is the master switch. The module is entirely inert unless it is exactly 'true'; the default is false. No Qdrant writes, no embeds, no queries happen with the flag off.

Per the platform's no-env-only-config rule, this flag is no longer visible only in an environment file. The dashboard's Platform Capabilities view (/platform-capabilities) lists it, alongside every other behaviour flag in the platform, showing its current state, its default, and which service reads it. This documentation page is the second required surface (docs); a dedicated Settings override is not built.

Maturity

CapabilityStatusNotes
Capture (captureConversation)BetaDeterministic point id, per-conversation throttle, capped summary. Non-fatal on every failure path.
Recall (recallConversations)BetaOrg and user scoped filter, capped at 10 results, 3-second timeout.
Provider-key resolutionBetaFixed 2026-08-05 to use the shared org-scoped resolver; previously silently broken for vault-resolved keys.
Live verificationBetaThree conversations, three paraphrased queries, all correct with a clear score margin. No live soak beyond that single verification pass.
Dashboard visibility of QM_LTM_ENABLEDStableListed in Platform Capabilities with state, default and reading service.
Default stateOffQM_LTM_ENABLED=false by default; an org must explicitly turn this on.
  • Memory System: facts, preferences and entities extracted from conversations, the broader store this sits alongside.
  • QuoxDream: the separate consolidation pass that turns Brain2 notes into weighted beliefs in QuoxMemory.
  • Quox Memory: the product overview this technical detail sits underneath. </content>