memo-grafter 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +73 -187
  2. package/USER_GUIDE.md +158 -40
  3. package/dist/MemoGrafter.d.ts +2 -0
  4. package/dist/MemoGrafter.d.ts.map +1 -1
  5. package/dist/MemoGrafter.js +15 -0
  6. package/dist/MemoGrafter.js.map +1 -1
  7. package/dist/MemoGrafterAgent.d.ts +4 -1
  8. package/dist/MemoGrafterAgent.d.ts.map +1 -1
  9. package/dist/MemoGrafterAgent.js +42 -12
  10. package/dist/MemoGrafterAgent.js.map +1 -1
  11. package/dist/index.d.ts +4 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +3 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/pipeline/GrafterPipeline.d.ts +7 -1
  16. package/dist/pipeline/GrafterPipeline.d.ts.map +1 -1
  17. package/dist/pipeline/GrafterPipeline.js +5 -1
  18. package/dist/pipeline/GrafterPipeline.js.map +1 -1
  19. package/dist/pipeline/IngestPipeline.d.ts +12 -1
  20. package/dist/pipeline/IngestPipeline.d.ts.map +1 -1
  21. package/dist/pipeline/IngestPipeline.js +9 -1
  22. package/dist/pipeline/IngestPipeline.js.map +1 -1
  23. package/dist/pipeline/RetrieverPipeline.d.ts +14 -1
  24. package/dist/pipeline/RetrieverPipeline.d.ts.map +1 -1
  25. package/dist/pipeline/RetrieverPipeline.js +35 -2
  26. package/dist/pipeline/RetrieverPipeline.js.map +1 -1
  27. package/dist/store/GraphStore.d.ts +2 -0
  28. package/dist/store/GraphStore.d.ts.map +1 -1
  29. package/dist/store/postgres-pgvector/GraphStore.d.ts +2 -0
  30. package/dist/store/postgres-pgvector/GraphStore.d.ts.map +1 -1
  31. package/dist/store/postgres-pgvector/GraphStore.js +26 -0
  32. package/dist/store/postgres-pgvector/GraphStore.js.map +1 -1
  33. package/dist/types.d.ts +17 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/utils/drift/driftScore.d.ts.map +1 -1
  36. package/dist/utils/drift/driftScore.js +2 -1
  37. package/dist/utils/drift/driftScore.js.map +1 -1
  38. package/dist/utils/reentry/reentryText.d.ts.map +1 -1
  39. package/dist/utils/reentry/reentryText.js +2 -2
  40. package/dist/utils/reentry/reentryText.js.map +1 -1
  41. package/dist/utils/text/tokenCount.d.ts +1 -0
  42. package/dist/utils/text/tokenCount.d.ts.map +1 -1
  43. package/dist/utils/text/tokenCount.js +3 -0
  44. package/dist/utils/text/tokenCount.js.map +1 -1
  45. package/package.json +1 -1
package/README.md CHANGED
@@ -1,187 +1,73 @@
1
- # MemoGrafter
2
- [![npm version](https://img.shields.io/npm/v/memo-grafter.svg)](https://www.npmjs.com/package/memo-grafter)
3
-
4
- Structured memory for TypeScript chatbots.
5
-
6
- MemoGrafter helps chatbot applications remember conversations without stuffing every old message back into the prompt. It turns conversations into topic-based memory, retrieves the relevant parts later, and can copy useful memory from one chatbot or session into another.
7
-
8
- It is a memory framework, not an autonomous agent runtime. It does not run tools, schedule tasks, or decide goals for an agent.
9
-
10
- ## What You Can Build
11
-
12
- - Chatbots that remember user preferences across long conversations.
13
- - Support or tutoring assistants that recall prior topics without replaying full history.
14
- - Multi-chatbot demos where one bot can absorb selected memory from another.
15
- - Prototypes for graph-based conversational memory, retrieval, and memory transfer.
16
- - Server-side TypeScript apps that need reusable LLM memory primitives.
17
-
18
- ## How It Works
19
-
20
- At a high level:
21
-
22
- ```text
23
- chat messages
24
- -> topic segments
25
- -> memory nodes
26
- -> graph links
27
- -> relevant memory injection
28
- -> optional memory grafting
29
- ```
30
-
31
- MemoGrafter stores conversation turns, detects topic shifts, summarizes segments into memory nodes, links related nodes, and injects relevant memory into future LLM calls. Drift detection uses embedding distance, sharp message pivots, short-message dampening, and structural phrases like "by the way" or "going back to" to split conversations into useful topic segments. Memory grafting lets one chatbot or session copy selected memory from another.
32
-
33
- ## Install
34
-
35
- ```bash
36
- npm install memo-grafter
37
- ```
38
-
39
- MemoGrafter runs server-side on Node.js. The built-in storage implementation is `PostgresGraphStore`, which requires PostgreSQL with `pgvector`. Included provider adapters require their matching API keys.
40
-
41
- ```bash
42
- DATABASE_URL=postgres://postgres:postgres@localhost:5432/memo_grafter
43
- ANTHROPIC_API_KEY=sk-ant-...
44
- GEMINI_API_KEY=...
45
- OPENAI_API_KEY=sk-...
46
- ```
47
-
48
- ## Minimal Example
49
-
50
- ```ts
51
- import "dotenv/config";
52
-
53
- import {
54
- MemoGrafterAgent,
55
- OpenAIEmbedAdapter,
56
- OpenAILLMAdapter,
57
- } from "memo-grafter";
58
-
59
- const agent = new MemoGrafterAgent({
60
- db: { connectionString: process.env.DATABASE_URL! },
61
- llm: new OpenAILLMAdapter("gpt-4o"),
62
- embedder: new OpenAIEmbedAdapter("text-embedding-3-small"),
63
- });
64
-
65
- await agent.initialize();
66
-
67
- console.log(await agent.invoke("I am planning a Japan trip."));
68
- console.log(await agent.invoke("I like quiet towns, bookstores, and local cafes."));
69
- console.log(await agent.invoke("What do you remember about my travel preferences?"));
70
-
71
- const recall = await agent.recall("travel preferences", {
72
- limit: 5,
73
- minSimilarity: 0.6,
74
- });
75
-
76
- console.log(recall.facts);
77
- console.log(recall.systemPrompt);
78
-
79
- await agent.close();
80
- ```
81
-
82
- ## Adapters
83
-
84
- MemoGrafter includes provider adapters such as `OpenAILLMAdapter`, `OpenAIEmbedAdapter`, `AnthropicLLMAdapter`, `GeminiLLMAdapter`, and `GeminiEmbedAdapter`. You can also bring any provider by implementing the public adapter interfaces:
85
-
86
- ```ts
87
- import {
88
- type EmbedAdapter,
89
- type LLMAdapter,
90
- type Message,
91
- } from "memo-grafter";
92
-
93
- class MyLLMAdapter implements LLMAdapter {
94
- async complete(messages: Message[], system?: string): Promise<string> {
95
- // Call your model provider here.
96
- return "Assistant response";
97
- }
98
- }
99
-
100
- class MyEmbedAdapter implements EmbedAdapter {
101
- async embed(text: string): Promise<number[]> {
102
- // Return an embedding vector matching your storage schema.
103
- return [];
104
- }
105
- }
106
- ```
107
-
108
- ## Storage
109
-
110
- MemoGrafter uses a public `GraphStore` interface internally. The default implementation is `PostgresGraphStore`, backed by PostgreSQL and `pgvector`, and this is what `MemoGrafter` and `MemoGrafterAgent` construct from the `db.connectionString` config today.
111
-
112
- ```ts
113
- import {
114
- PostgresGraphStore,
115
- type GraphStore,
116
- } from "memo-grafter";
117
-
118
- const store: GraphStore = new PostgresGraphStore(process.env.DATABASE_URL!);
119
- ```
120
-
121
- The interface boundary keeps the Postgres implementation isolated and gives future storage backends a clear contract to implement.
122
-
123
- ## Targeted Recall
124
-
125
- Use `agent.recall()` when you want structured memory back without asking the LLM to answer yet. It searches atomic memory nodes by meaning, filters stale memories, groups them with their parent topic summaries, and returns a prompt block you can inspect or pass to your own model call.
126
-
127
- ```ts
128
- const result = await agent.recall("deployment config", {
129
- limit: 8,
130
- minSimilarity: 0.55,
131
- tokenBudget: 1000,
132
- });
133
-
134
- console.log(result.facts);
135
- console.log(result.nodes);
136
- console.log(result.systemPrompt);
137
- console.log(result.tokenCount);
138
- ```
139
-
140
- `recall()` is side-effect free. It does not call `invoke()`, does not mutate chat history, and does not inject anything automatically.
141
-
142
- ## Memory Grafting
143
-
144
- Memory grafting is the core idea behind the name: one chatbot can build memory, and another chatbot can absorb only the useful parts.
145
-
146
- ```ts
147
- await writingBot.absorbFromAgent(travelBot, {
148
- prompt: "Japan travel preferences",
149
- limit: 3,
150
- });
151
- ```
152
-
153
- ## Drift And Reentry
154
-
155
- Use `driftSensitivity` for developer-friendly topic segmentation:
156
-
157
- ```ts
158
- const agent = new MemoGrafterAgent({
159
- db: { connectionString: process.env.DATABASE_URL! },
160
- llm,
161
- embedder,
162
- drift: {
163
- mode: "intent",
164
- driftSensitivity: "medium",
165
- minSegmentMessages: 3,
166
- reentryDetection: true,
167
- },
168
- });
169
- ```
170
-
171
- Sensitivity presets are `"low"`, `"medium"`, and `"high"`. The older numeric `threshold` option is still accepted for compatibility, but `driftSensitivity` is preferred.
172
-
173
- When a conversation returns to an earlier topic, MemoGrafter can create a `reentry` edge between the new topic node and the earlier related topic node. For example, a chat can move from database decisions to authentication, then back to database pooling; the later database segment is linked back to the original database topic instead of becoming an isolated duplicate.
174
-
175
- ## Learn More
176
-
177
- Read [USER_GUIDE.md](https://github.com/mayhemking007/memo-grafter/blob/main/USER_GUIDE.md) for setup, configuration, queue mode, custom adapters, fleet APIs, examples, and troubleshooting.
178
-
179
- This repository also includes a runnable demo:
180
-
181
- ```text
182
- examples/chatbot-memory-demo
183
- ```
184
-
185
- ## License
186
-
187
- MIT
1
+ # MemoGrafter
2
+ [![npm version](https://img.shields.io/npm/v/memo-grafter.svg)](https://www.npmjs.com/package/memo-grafter)
3
+
4
+ Structured memory for TypeScript chatbots.
5
+
6
+ MemoGrafter helps chatbot applications remember conversations without stuffing every old message back into the prompt. It turns conversation history into topic-based memory, recalls relevant details later, and can copy useful memory from one chatbot or session into another.
7
+
8
+ It is a memory framework, not an autonomous agent runtime. It does not run tools, schedule work, or decide goals for an agent.
9
+
10
+ ## What It Is For
11
+
12
+ - Chatbots that need long-running memory.
13
+ - Assistants that should recall user preferences, prior context, and open questions.
14
+ - Multi-chatbot or multi-session flows where selected memory can be grafted into another conversation.
15
+ - TypeScript apps that need reusable memory, retrieval, and graph-backed conversation primitives.
16
+
17
+ ## How It Works
18
+
19
+ ```text
20
+ chat messages
21
+ -> topic-based memory
22
+ -> graph links
23
+ -> relevant recall
24
+ -> optional memory grafting
25
+ ```
26
+
27
+ MemoGrafter stores conversation turns, detects topic changes, summarizes useful context, links related memories, and retrieves or grafts memory when needed.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ npm install memo-grafter
33
+ ```
34
+
35
+ MemoGrafter runs server-side on Node.js. The built-in storage backend uses PostgreSQL with `pgvector`.
36
+
37
+ ## Minimal Example
38
+
39
+ ```ts
40
+ import "dotenv/config";
41
+
42
+ import {
43
+ MemoGrafterAgent,
44
+ OpenAIEmbedAdapter,
45
+ OpenAILLMAdapter,
46
+ } from "memo-grafter";
47
+
48
+ const agent = new MemoGrafterAgent({
49
+ db: { connectionString: process.env.DATABASE_URL! },
50
+ llm: new OpenAILLMAdapter("gpt-4o"),
51
+ embedder: new OpenAIEmbedAdapter("text-embedding-3-small"),
52
+ });
53
+
54
+ await agent.initialize();
55
+
56
+ await agent.invoke("I am planning a Japan trip.");
57
+ await agent.invoke("I like quiet towns, bookstores, and local cafes.");
58
+
59
+ const recall = await agent.recall("travel preferences");
60
+ console.log(recall.facts);
61
+
62
+ await agent.close();
63
+ ```
64
+
65
+ ## Learn More
66
+
67
+ - [USER_GUIDE.md](https://github.com/mayhemking007/memo-grafter/blob/main/USER_GUIDE.md) covers setup, configuration, adapters, queue mode, fleet APIs, examples, and troubleshooting.
68
+ - [ARCHITECTURE.md](https://github.com/mayhemking007/memo-grafter/blob/main/ARCHITECTURE.md) explains the current high-level implementation.
69
+ - `examples` contains runnable demo.
70
+
71
+ ## License
72
+
73
+ MIT
package/USER_GUIDE.md CHANGED
@@ -18,7 +18,7 @@ The most important idea is memory grafting. A chatbot can build useful memory du
18
18
  - An OpenAI API key only if using the included OpenAI adapters.
19
19
  - An Anthropic API key only if using the included Anthropic LLM adapter.
20
20
  - A Gemini API key only if using the included Gemini adapters.
21
- - Redis only if enabling queue mode.
21
+ - Redis only if enabling queue mode or the optional recall cache.
22
22
 
23
23
  MemoGrafter is server-side only. Do not run it in browser code.
24
24
 
@@ -65,7 +65,7 @@ REDIS_URL=redis://localhost:6379
65
65
 
66
66
  `GEMINI_API_KEY` is required only when using `GeminiLLMAdapter` or `GeminiEmbedAdapter`.
67
67
 
68
- `REDIS_URL` is optional and only needed when you pass `queue` config.
68
+ `REDIS_URL` is optional and only needed when you pass `queue` or `cache` config.
69
69
 
70
70
  Enable `pgvector` in PostgreSQL:
71
71
 
@@ -135,12 +135,12 @@ A message is one user or assistant turn:
135
135
 
136
136
  ```ts
137
137
  export interface Message {
138
- role: "user" | "assistant";
138
+ role: "system" | "user" | "assistant";
139
139
  content: string;
140
140
  }
141
141
  ```
142
142
 
143
- `MemoGrafterAgent` keeps an in-memory history for the current session and stores messages in PostgreSQL during ingestion.
143
+ `MemoGrafterAgent` keeps an in-memory user/assistant history for the current session and stores messages in PostgreSQL during ingestion. System messages can be added to LLM calls internally when memory recall is pinned into an overflowing context window.
144
144
 
145
145
  ### Segments
146
146
 
@@ -252,13 +252,15 @@ await agent.close();
252
252
  On every call, `invoke()`:
253
253
 
254
254
  1. Adds the user message to local history.
255
- 2. Loads existing topic nodes for the session.
256
- 3. Builds a memory injection prompt from those nodes.
257
- 4. Sends history plus memory prompt to the LLM.
255
+ 2. Builds the message list for the LLM.
256
+ 3. If history is under the configured budget, sends the raw local history.
257
+ 4. If history crosses the overflow threshold, calls targeted recall using recent conversation context, prepends the recall result as one pinned system message, and keeps only the recent raw message window.
258
258
  5. Adds the assistant response to history.
259
- 6. Ingests the updated conversation into the memory graph.
259
+ 6. Queues ingestion of the updated conversation into the memory graph.
260
260
 
261
- On the first turn there may be no memory to inject. Later turns can use memory created from earlier turns.
261
+ The overflow threshold is 80% of `inject.tokenBudget`. Recall failures are logged as warnings and fall back to the recent raw message window, so a retrieval or embedder problem should not crash the foreground chatbot turn.
262
+
263
+ On the first turn there may be no memory to recall. Later turns can use memory created from earlier turns once ingestion has completed.
262
264
 
263
265
  ### Targeted Recall
264
266
 
@@ -269,6 +271,9 @@ const result = await agent.recall("deployment config", {
269
271
  limit: 8,
270
272
  minSimilarity: 0.55,
271
273
  tokenBudget: 1000,
274
+ cache: {
275
+ ttlSeconds: 90,
276
+ },
272
277
  });
273
278
 
274
279
  console.log(result.facts);
@@ -289,17 +294,42 @@ Options:
289
294
  - `limit`: max memory nodes to fetch before filtering. Defaults to `10`.
290
295
  - `minSimilarity`: cosine similarity floor. Defaults to `0.6`.
291
296
  - `tokenBudget`: max approximate tokens for included fact blocks. Defaults to `1200`.
292
-
293
- `recall()` is side-effect free. It does not call `invoke()`, does not trigger a new LLM completion, does not mutate local history, and does not inject the result automatically. Your application decides whether to display the memories, add `result.systemPrompt` to a model call, or ignore the result.
294
-
295
- If you call `recall()` immediately after `invoke()`, it only sees memory that has already been ingested into storage. In queue mode, wait for your background worker to finish before expecting newly created memories to appear.
296
-
297
- ## Inspecting Memory
298
-
299
- Read active topic nodes:
300
-
301
- ```ts
302
- const nodes = await agent.getActiveNodes();
297
+ - `cache.ttlSeconds`: per-call recall cache TTL override when `MemoGrafterConfig.cache` is enabled. Values are clamped to 60-120 seconds.
298
+
299
+ `recall()` is side-effect free. It does not call `invoke()`, does not trigger a new LLM completion, and does not mutate local history. Your application can call it directly to display memories, add `result.systemPrompt` to a model call, or ignore the result.
300
+
301
+ `MemoGrafterAgent.invoke()` also calls `recall()` internally when local history overflows the configured history budget. In that automatic path, the returned `systemPrompt` is pinned as a single system message before the recent raw chat window.
302
+
303
+ If you call `recall()` immediately after `invoke()`, it only sees memory that has already been ingested into storage. In queue mode, wait for your background worker to finish before expecting newly created memories to appear.
304
+
305
+ ## Inspecting Memory
306
+
307
+ Read a complete session graph snapshot:
308
+
309
+ ```ts
310
+ const snapshot = await agent.getGraphSnapshot();
311
+
312
+ console.log(snapshot.sessionId);
313
+ console.log(snapshot.nodes);
314
+ console.log(snapshot.edges);
315
+ console.log(snapshot.memories);
316
+ console.log(snapshot.capturedAt);
317
+ ```
318
+
319
+ `getGraphSnapshot()` returns a `GraphSnapshot`:
320
+
321
+ - `sessionId`: current agent session ID.
322
+ - `nodes`: active topic nodes for the session.
323
+ - `edges`: topic edges where either endpoint belongs to a session topic node.
324
+ - `memories`: all memory nodes for the session, including decayed or superseded rows.
325
+ - `capturedAt`: ISO timestamp for when the snapshot was produced.
326
+
327
+ This method is read-only. It does not include raw `mg_message_buffer` content and does not add rendering, layout, or color decisions. Like `getActiveNodes()` and `getActiveSegments()`, it waits for the agent's pending ingest work before reading. If called immediately after `invoke()` in queue mode, it waits for the current ingest job to settle before returning.
328
+
329
+ Read active topic nodes:
330
+
331
+ ```ts
332
+ const nodes = await agent.getActiveNodes();
303
333
 
304
334
  for (const node of nodes) {
305
335
  console.log({
@@ -449,6 +479,11 @@ const agent = new MemoGrafterAgent({
449
479
  inject: {
450
480
  bufferSize: 4,
451
481
  tokenBudget: 1500,
482
+ recentWindowSize: 20,
483
+ },
484
+ cache: {
485
+ connectionString: process.env.REDIS_URL!,
486
+ ttlSeconds: 90,
452
487
  },
453
488
  });
454
489
  ```
@@ -476,12 +511,14 @@ const store: GraphStore = new PostgresGraphStore(process.env.DATABASE_URL!);
476
511
 
477
512
  `GraphStore` is the public storage interface. `PostgresGraphStore` is the default PostgreSQL and pgvector implementation.
478
513
 
479
- Useful store inspection methods include:
480
-
481
- - `getNodesBySession(sessionId)`: read topic nodes for a session.
482
- - `getTopicNode(topicNodeId, sessionId?)`: read one topic node by ID.
483
- - `getSegmentsBySession(sessionId)`: read topic segments for a session.
484
- - `getEdgesByType(sessionId, type)`: inspect graph edges such as `"reentry"`, `"semantic"`, `"temporal"`, or `"grafted"`.
514
+ Useful store inspection methods include:
515
+
516
+ - `getNodesBySession(sessionId)`: read topic nodes for a session.
517
+ - `getTopicNode(topicNodeId, sessionId?)`: read one topic node by ID.
518
+ - `getSegmentsBySession(sessionId)`: read topic segments for a session.
519
+ - `getEdgesByType(sessionId, type)`: inspect graph edges such as `"reentry"`, `"semantic"`, `"temporal"`, or `"grafted"`.
520
+ - `getEdgesBySession(sessionId)`: read all topic edges where either endpoint belongs to the session's topic nodes.
521
+ - `getMemoriesBySession(sessionId)`: read all memory nodes for a session, including decayed and superseded rows.
485
522
 
486
523
  ### `llm`
487
524
 
@@ -592,13 +629,33 @@ Controls graph retrieval and traversal.
592
629
  inject: {
593
630
  bufferSize: 4,
594
631
  tokenBudget: 1500,
632
+ recentWindowSize: 20,
595
633
  }
596
634
  ```
597
635
 
598
- Controls how much memory is inserted into the prompt.
636
+ Controls memory prompt sizing and the raw history window kept when chat history overflows.
599
637
 
600
638
  - `bufferSize`: nearby raw messages to include.
601
- - `tokenBudget`: approximate memory prompt budget.
639
+ - `tokenBudget`: approximate token budget used for memory prompts and agent history overflow checks. `MemoGrafterAgent` starts overflow handling at 80% of this value.
640
+ - `recentWindowSize`: number of newest raw chat messages to keep after the pinned recall block during overflow. Defaults to `20`.
641
+
642
+ When `MemoGrafterAgent` detects overflow, it builds a recall query from the last six message contents, calls recall with `{ limit: 5, minSimilarity: 0.65 }`, prepends the returned memory prompt as a system message, and keeps the last `recentWindowSize` raw messages. If recall fails, it uses only that recent raw window.
643
+
644
+ ### `cache`
645
+
646
+ ```ts
647
+ cache: {
648
+ connectionString: process.env.REDIS_URL!,
649
+ ttlSeconds: 90,
650
+ }
651
+ ```
652
+
653
+ Enables an opt-in Redis cache for targeted recall. MemoGrafter creates one shared Redis client and uses it to cache only the raw `searchMemories()` result. It does not cache final prompts, filtered blocks, or `RetrievalResult`, so different `tokenBudget` values still assemble fresh output.
654
+
655
+ - `connectionString`: Redis URL.
656
+ - `ttlSeconds`: cache TTL in seconds. Defaults to `90` and is clamped between `60` and `120`.
657
+
658
+ Recall cache keys include the session ID, `limit`, `minSimilarity`, and a deterministic hash of the query embedding. Redis failures are logged as warnings and recall falls back to PostgreSQL search. The cache is disabled unless this section is present.
602
659
 
603
660
  ## Queue Mode
604
661
 
@@ -695,6 +752,60 @@ class MyGraphStore implements GraphStore {
695
752
 
696
753
  Future storage implementations can use the same interface without changing pipeline or fleet code. For example, a SQLite plus vector-database implementation would implement `GraphStore` while preserving the same behavior expected by ingestion, grafting, and fleet APIs.
697
754
 
755
+ ## Using Pipelines Directly
756
+
757
+ `MemoGrafterAgent` is the recommended starting point, but the underlying
758
+ pipeline classes are also exported for developers who want to build custom
759
+ agent loops or integrate MemoGrafter memory primitives into an existing
760
+ orchestration framework.
761
+
762
+ Pipeline classes are exported for composability. Their constructors and
763
+ internal behavior are not covered by semver stability guarantees until v1.0.
764
+ Breaking changes to pipeline internals may occur in minor versions.
765
+
766
+ Available pipeline exports:
767
+
768
+ - `IngestPipeline`: segments messages, builds topic nodes, extracts memory nodes, and writes graph edges.
769
+ - `RetrieverPipeline`: embeds a query, searches memory nodes, and returns a structured `RetrievalResult`.
770
+ - `GrafterPipeline`: traverses the topic graph and assembles a token-budget-fitted system prompt.
771
+
772
+ Example using `RetrieverPipeline` directly:
773
+
774
+ ```ts
775
+ import {
776
+ PostgresGraphStore,
777
+ RetrieverPipeline,
778
+ OpenAIEmbedAdapter,
779
+ } from "memo-grafter";
780
+
781
+ const store = new PostgresGraphStore(process.env.DATABASE_URL!);
782
+ await store.initialize();
783
+
784
+ const embedder = new OpenAIEmbedAdapter("text-embedding-3-small");
785
+
786
+ const retriever = new RetrieverPipeline(store, embedder, {
787
+ limit: 8,
788
+ minSimilarity: 0.55,
789
+ tokenBudget: 1000,
790
+ });
791
+
792
+ const result = await retriever.run(
793
+ "deployment config and Kubernetes namespace",
794
+ sessionId,
795
+ );
796
+
797
+ console.log(result.facts);
798
+ console.log(result.systemPrompt);
799
+
800
+ await store.close();
801
+ ```
802
+
803
+ When using pipelines directly you are responsible for managing the store
804
+ connection lifecycle. Call `store.close()` during graceful shutdown.
805
+
806
+ `MemoGrafterAgent` remains the batteries-included default. Existing code
807
+ that uses `MemoGrafterAgent` does not need to change.
808
+
698
809
  ## Fleet API
699
810
 
700
811
  Fleets let you group color-scoped worker chatbots and use a conductor to graft memory across workers.
@@ -868,7 +979,7 @@ const result = await agent.recall("Japan travel preferences", {
868
979
 
869
980
  ### Redis Warnings
870
981
 
871
- Redis is only required when you pass `queue` config. If you do not need background ingestion, remove the `queue` section.
982
+ Redis is only required when you pass `queue` or `cache` config. If you do not need background ingestion or recall caching, remove those sections.
872
983
 
873
984
  ### Browser Runtime Error
874
985
 
@@ -884,6 +995,7 @@ Practical notes:
884
995
  - Use PostgreSQL with `pgvector` enabled.
885
996
  - Tune `tokenBudget` to control prompt size and cost.
886
997
  - Use queue mode if ingestion becomes slow.
998
+ - Use the optional recall cache for long sessions with repeated or automatic overflow recall.
887
999
  - Store your own user/session mapping outside MemoGrafter.
888
1000
  - Call `close()` during graceful shutdown.
889
1001
  - Do not expose database credentials or OpenAI keys to browser code.
@@ -904,27 +1016,33 @@ Main exports:
904
1016
  - `OpenAILLMAdapter`
905
1017
  - `OpenAIEmbedAdapter`
906
1018
  - `PostgresGraphStore`
1019
+ - `GrafterPipeline`
1020
+ - `IngestPipeline`
1021
+ - `RetrieverPipeline`
907
1022
  - `GraphStore`
908
1023
  - `FleetAgentRecord`
909
1024
  - `RetrievalResult`
910
1025
  - `RetrieverConfig`
911
1026
  - public shared and fleet types
912
1027
 
913
- Useful `GraphStore` inspection methods:
914
-
915
- - `getTopicNode(topicNodeId, sessionId?)`
916
- - `getNodesBySession(sessionId)`
917
- - `getSegmentsBySession(sessionId)`
918
- - `getEdgesByType(sessionId, type)`
919
-
920
- Common `MemoGrafterAgent` methods:
1028
+ Useful `GraphStore` inspection methods:
1029
+
1030
+ - `getTopicNode(topicNodeId, sessionId?)`
1031
+ - `getNodesBySession(sessionId)`
1032
+ - `getSegmentsBySession(sessionId)`
1033
+ - `getEdgesByType(sessionId, type)`
1034
+ - `getEdgesBySession(sessionId)`
1035
+ - `getMemoriesBySession(sessionId)`
1036
+
1037
+ Common `MemoGrafterAgent` methods:
921
1038
 
922
1039
  - `initialize()`: initialize storage.
923
1040
  - `invoke(message)`: send a user message and receive an assistant response.
924
1041
  - `getHistory()`: read local chat history.
925
- - `getSessionId()`: read the current session ID.
926
- - `getActiveNodes()`: inspect topic nodes.
927
- - `getActiveSegments()`: inspect topic segments.
1042
+ - `getSessionId()`: read the current session ID.
1043
+ - `getGraphSnapshot()`: read nodes, edges, memories, session ID, and capture timestamp for visualization or inspection.
1044
+ - `getActiveNodes()`: inspect topic nodes.
1045
+ - `getActiveSegments()`: inspect topic segments.
928
1046
  - `recall(query, options?)`: retrieve structured memory by semantic query.
929
1047
  - `graft(topicIds?)`: preview memory injection.
930
1048
  - `ingestGraftedNodes(nodes)`: copy provided nodes into this agent.
@@ -1,3 +1,4 @@
1
+ import { Redis } from "ioredis";
1
2
  import { MemoGrafterFleet } from "./fleet/MemoGrafterFleet.js";
2
3
  import type { MemoGrafterFleetOptions } from "./fleet/types.js";
3
4
  import type { GraphStore } from "./store/index.js";
@@ -6,6 +7,7 @@ export declare class MemoGrafter {
6
7
  readonly llm: LLMAdapter;
7
8
  readonly embedder: EmbedAdapter;
8
9
  readonly store: GraphStore;
10
+ readonly recallCache: Redis | null;
9
11
  private readonly ingestPipeline;
10
12
  private readonly grafterPipeline;
11
13
  private readonly ingestQueue;
@@ -1 +1 @@
1
- {"version":3,"file":"MemoGrafter.d.ts","sourceRoot":"","sources":["../src/MemoGrafter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EACV,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,OAAO,EACP,SAAS,EACT,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAErC,MAAM,EAAE,iBAAiB;IA0CrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQpE,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIjE,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IAM7F,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAIjE,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMrF,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBpG,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMpF,WAAW,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB;IAI9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,OAAO,CAAC,uBAAuB;CAUhC"}
1
+ {"version":3,"file":"MemoGrafter.d.ts","sourceRoot":"","sources":["../src/MemoGrafter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAKhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EACV,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,OAAO,EACP,SAAS,EACT,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAErC,MAAM,EAAE,iBAAiB;IAmDrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQpE,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAIjE,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IAM7F,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAIjE,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMrF,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBpG,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMpF,WAAW,CAAC,OAAO,GAAE,uBAA4B,GAAG,gBAAgB;IAI9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,OAAO,CAAC,uBAAuB;CAUhC"}
@@ -1,3 +1,4 @@
1
+ import { Redis } from "ioredis";
1
2
  import { GrafterPipeline } from "./pipeline/GrafterPipeline.js";
2
3
  import { IngestPipeline } from "./pipeline/IngestPipeline.js";
3
4
  import { IngestQueue } from "./queue/IngestQueue.js";
@@ -7,6 +8,7 @@ export class MemoGrafter {
7
8
  llm;
8
9
  embedder;
9
10
  store;
11
+ recallCache;
10
12
  ingestPipeline;
11
13
  grafterPipeline;
12
14
  ingestQueue;
@@ -27,6 +29,15 @@ export class MemoGrafter {
27
29
  this.llm = config.llm;
28
30
  this.embedder = config.embedder;
29
31
  this.store = new PostgresGraphStore(config.db.connectionString);
32
+ this.recallCache = config.cache
33
+ ? new Redis(config.cache.connectionString, {
34
+ enableOfflineQueue: false,
35
+ maxRetriesPerRequest: 1,
36
+ })
37
+ : null;
38
+ this.recallCache?.on("error", (error) => {
39
+ console.warn("MemoGrafter recall cache Redis warning:", error.message);
40
+ });
30
41
  const ingestConfig = {
31
42
  windowSize,
32
43
  topK,
@@ -105,6 +116,10 @@ export class MemoGrafter {
105
116
  }
106
117
  async close() {
107
118
  await this.ingestQueue?.close();
119
+ await this.recallCache?.quit().catch((error) => {
120
+ console.warn("MemoGrafter recall cache close warning:", error);
121
+ this.recallCache?.disconnect();
122
+ });
108
123
  await this.store.close();
109
124
  }
110
125
  assertServerEnvironment() {
@@ -1 +1 @@
1
- {"version":3,"file":"MemoGrafter.js","sourceRoot":"","sources":["../src/MemoGrafter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemoGrafter.js","sourceRoot":"","sources":["../src/MemoGrafter.ts"],"names":[],"mappings":"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"}