feat(agent): MRAgent reconstructive memory (Cue–Tag–Content graph + active reconstruction)#82
Merged
Conversation
…ctive reconstruction) Implements "Memory is Reconstructed, Not Retrieved: Graph Memory for LLM Agents" (Ji, Li & Hooi, ICML 2026) as a new src/agent/reconstruction/ module. Replaces the static "retrieve-then-reason" paradigm with an associative memory graph and an active, multi-step reconstruction loop that integrates reasoning directly into memory access. - CueTagContentGraph: heterogeneous M = (C, V, R) associative graph where associative tags bridge fine-grained cues to memory contents, organised into episodic / semantic / topic layers. O(1) mapping operators (paper Eq. 5/8/9): tagsForCue, contentsForCueTag, cueTagsForContent (reverse), episodesForTopic; snapshot round-trip. - MemoryToolkit: the seven typed traversal operators from Table 4 (query_tag_events, query_conversation_time, query_event_keywords, query_event_context, query_personal_information, query_personal_aspect, query_topic_events). - MemoryDistiller: construction pipeline (§3.3 / App. B.1) — rewrite (pronoun resolution, temporal normalisation, episodic segmentation) → tag + cue extraction → semantic-fact extraction → topic abstraction. Optional LLMProvider with the paper's App. E prompts; deterministic heuristic fallback for zero-config use (mirrors LLMQueryPlanner). - MemoryReconstructor: active reconstruction (Algorithm 1) — reconstruction state S(t) = (Z(t), H(t)), f_select action selection, controlled forward/reverse/topic traversal, f_route pruning, stopping. LLM answer synthesis with extractive fallback. - ReconstructiveMemory facade + ctx.reconstructiveMemory() lazy getter. Wired through agent + types barrels and the package root. Tagged @experimental. 28 unit tests; typecheck, lint, and full build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZSDcmAkuVaQgb9gUyqinW
Wires the Cue–Tag–Content multi-granular layers to the existing memory
modules they correspond to, so reconstructed memory is durable and visible
to the rest of the stack rather than an in-memory island.
- MemoryGraphBridge persists each layer into its module:
* episodic → memoryType:'episodic' entities stamped with the conversation
timestamp (land on the EpisodicMemoryManager timeline, temporally linked
precedes/follows)
* semantic → memoryType:'semantic' fact entities anchored to their person
entity via a has_<aspect> relation, indexed for SemanticSearch
* topic → topic entities linked to constituent episodes via `summarizes`
Driven through the structural ReconstructiveBacking interface (real managers
or test fakes).
- MemoryReconstructor routing/answer reuse SemanticSearch.calculateSimilarity
when the backing provides it (embedding similarity captures paraphrase),
with lexical overlap as fallback.
- ReconstructiveMemory.ingest persists via the bridge when a backing is set;
exposes lastPersistResult. ctx.reconstructiveMemory() defaults the backing
to the context's entityManager/relationManager/semanticSearch (agent
entities appended via storage to bypass the plain-Entity schema, with
name-dedup); pass backing:undefined to opt out.
- ContentNode gains entityName, set when bridged.
5 new bridge/integration tests (incl. end-to-end via ManagerContext verifying
entities, relations, and timeline ordering). Full suite green; typecheck,
lint, build clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZSDcmAkuVaQgb9gUyqinW
There was a problem hiding this comment.
Pull request overview
This PR adds a new reconstructive memory subsystem (MRAgent-style) to MemoryJS, shifting from one-shot “retrieve-then-reason” toward a Cue–Tag–Content (CTC) associative graph plus an active multi-step reconstruction loop, and wires it into ManagerContext with optional live-store persistence.
Changes:
- Introduces new reconstructive memory types (
src/types/reconstruction.ts) and re-exports them through existing type/agent barrels. - Adds the reconstructive memory implementation (distillation, graph traversal toolkit, active reconstructor, live-store bridge, facade API).
- Adds unit tests covering graph operators, toolkit operators, reconstruction behavior, snapshot round-trips, and live-store bridging.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/agent/reconstruction/ReconstructiveMemory.test.ts | Tests heuristic + LLM-assisted reconstruction, step budgeting, snapshot round-trip, and extractJson. |
| tests/unit/agent/reconstruction/MemoryToolkit.test.ts | Tests the 7 typed traversal operators against a small fixture graph. |
| tests/unit/agent/reconstruction/MemoryGraphBridge.test.ts | Tests persistence into fake backing + end-to-end persistence via ManagerContext backing. |
| tests/unit/agent/reconstruction/CueTagContentGraph.test.ts | Tests core CTC graph operators (forward/reverse/topic traversal) and snapshot round-trip. |
| src/types/reconstruction.ts | Adds the public type model for CTC nodes/edges, distillation output, and reconstruction trajectory/result shapes. |
| src/types/index.ts | Re-exports reconstructive memory types from the main types barrel. |
| src/core/ManagerContext.ts | Adds ctx.reconstructiveMemory() lazy getter and a default backing that bridges to live managers/storage. |
| src/agent/reconstruction/ReconstructiveMemory.ts | Facade API for ingest + reconstruct, plus snapshot, stats, and toolkit accessors. |
| src/agent/reconstruction/MemoryToolkit.ts | Implements the seven traversal operators over the CTC graph. |
| src/agent/reconstruction/MemoryReconstructor.ts | Implements the active multi-step reconstruction loop (action selection → traversal → routing → stopping → answer). |
| src/agent/reconstruction/MemoryGraphBridge.ts | Persists episodic/semantic/topic layers into the live store and annotates graph nodes with backing entity names. |
| src/agent/reconstruction/MemoryDistiller.ts | Distills dialogue into episodes/cues/tags/personal facts/topics with optional LLM path and heuristic fallback. |
| src/agent/reconstruction/index.ts | Barrel export for the reconstruction module. |
| src/agent/index.ts | Re-exports reconstructive memory API from the main agent barrel. |
| CLAUDE.md | Updates project documentation to mention the reconstructive memory module and ctx.reconstructiveMemory(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+216
to
+227
| function dedupeTags(tags: string[]): string[] { | ||
| const seen = new Set<string>(); | ||
| const out: string[] = []; | ||
| for (const t of tags) { | ||
| const key = normalizeKey(t); | ||
| if (key && !seen.has(key)) { | ||
| seen.add(key); | ||
| out.push(t); | ||
| } | ||
| } | ||
| return out; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements "Memory is Reconstructed, Not Retrieved: Graph Memory for LLM
Agents" (Ji, Li & Hooi, ICML 2026) as a new src/agent/reconstruction/ module.
Replaces the static "retrieve-then-reason" paradigm with an associative
memory graph and an active, multi-step reconstruction loop that integrates
reasoning directly into memory access.
associative tags bridge fine-grained cues to memory contents, organised into
episodic / semantic / topic layers. O(1) mapping operators (paper Eq. 5/8/9):
tagsForCue, contentsForCueTag, cueTagsForContent (reverse), episodesForTopic;
snapshot round-trip.
(query_tag_events, query_conversation_time, query_event_keywords,
query_event_context, query_personal_information, query_personal_aspect,
query_topic_events).
resolution, temporal normalisation, episodic segmentation) → tag + cue
extraction → semantic-fact extraction → topic abstraction. Optional
LLMProvider with the paper's App. E prompts; deterministic heuristic fallback
for zero-config use (mirrors LLMQueryPlanner).
state S(t) = (Z(t), H(t)), f_select action selection, controlled
forward/reverse/topic traversal, f_route pruning, stopping. LLM answer
synthesis with extractive fallback.
Wired through agent + types barrels and the package root. Tagged @experimental.
28 unit tests; typecheck, lint, and full build clean.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01GZSDcmAkuVaQgb9gUyqinW