memo-grafter 0.1.0 → 0.2.0

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 (136) hide show
  1. package/.env.example +5 -3
  2. package/README.md +187 -182
  3. package/USER_GUIDE.md +932 -702
  4. package/dist/MemoGrafter.d.ts +1 -1
  5. package/dist/MemoGrafter.d.ts.map +1 -1
  6. package/dist/MemoGrafter.js +16 -5
  7. package/dist/MemoGrafter.js.map +1 -1
  8. package/dist/MemoGrafterAgent.d.ts +7 -1
  9. package/dist/MemoGrafterAgent.d.ts.map +1 -1
  10. package/dist/MemoGrafterAgent.js +45 -8
  11. package/dist/MemoGrafterAgent.js.map +1 -1
  12. package/dist/adapters/AnthropicAdapter.d.ts +9 -0
  13. package/dist/adapters/AnthropicAdapter.d.ts.map +1 -0
  14. package/dist/adapters/AnthropicAdapter.js +33 -0
  15. package/dist/adapters/AnthropicAdapter.js.map +1 -0
  16. package/dist/adapters/GeminiAdapter.d.ts +15 -0
  17. package/dist/adapters/GeminiAdapter.d.ts.map +1 -0
  18. package/dist/adapters/GeminiAdapter.js +48 -0
  19. package/dist/adapters/GeminiAdapter.js.map +1 -0
  20. package/dist/fleet/FleetStore.d.ts +1 -1
  21. package/dist/fleet/FleetStore.d.ts.map +1 -1
  22. package/dist/index.d.ts +5 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/pipeline/GrafterPipeline.d.ts +1 -3
  27. package/dist/pipeline/GrafterPipeline.d.ts.map +1 -1
  28. package/dist/pipeline/GrafterPipeline.js +6 -19
  29. package/dist/pipeline/GrafterPipeline.js.map +1 -1
  30. package/dist/pipeline/IngestPipeline.d.ts +7 -3
  31. package/dist/pipeline/IngestPipeline.d.ts.map +1 -1
  32. package/dist/pipeline/IngestPipeline.js +31 -5
  33. package/dist/pipeline/IngestPipeline.js.map +1 -1
  34. package/dist/pipeline/RetrieverPipeline.d.ts +11 -0
  35. package/dist/pipeline/RetrieverPipeline.d.ts.map +1 -0
  36. package/dist/pipeline/RetrieverPipeline.js +73 -0
  37. package/dist/pipeline/RetrieverPipeline.js.map +1 -0
  38. package/dist/pipeline/SegmentProcessor.d.ts +3 -2
  39. package/dist/pipeline/SegmentProcessor.d.ts.map +1 -1
  40. package/dist/pipeline/SegmentProcessor.js +52 -40
  41. package/dist/pipeline/SegmentProcessor.js.map +1 -1
  42. package/dist/pipeline/TopicDriftDetector.d.ts +21 -3
  43. package/dist/pipeline/TopicDriftDetector.d.ts.map +1 -1
  44. package/dist/pipeline/TopicDriftDetector.js +143 -17
  45. package/dist/pipeline/TopicDriftDetector.js.map +1 -1
  46. package/dist/prompts/factRetrievalPrompt.d.ts +4 -0
  47. package/dist/prompts/factRetrievalPrompt.d.ts.map +1 -0
  48. package/dist/prompts/factRetrievalPrompt.js +25 -0
  49. package/dist/prompts/factRetrievalPrompt.js.map +1 -0
  50. package/dist/prompts/historyCompressionPrompt.d.ts +3 -0
  51. package/dist/prompts/historyCompressionPrompt.d.ts.map +1 -0
  52. package/dist/prompts/historyCompressionPrompt.js +4 -0
  53. package/dist/prompts/historyCompressionPrompt.js.map +1 -0
  54. package/dist/prompts/intentShiftPrompt.d.ts +3 -0
  55. package/dist/prompts/intentShiftPrompt.d.ts.map +1 -0
  56. package/dist/prompts/intentShiftPrompt.js +11 -0
  57. package/dist/prompts/intentShiftPrompt.js.map +1 -0
  58. package/dist/prompts/memoryInjectionPrompt.d.ts +4 -0
  59. package/dist/prompts/memoryInjectionPrompt.d.ts.map +1 -0
  60. package/dist/prompts/memoryInjectionPrompt.js +16 -0
  61. package/dist/prompts/memoryInjectionPrompt.js.map +1 -0
  62. package/dist/prompts/segmentExtractionPrompt.d.ts +3 -0
  63. package/dist/prompts/segmentExtractionPrompt.d.ts.map +1 -0
  64. package/dist/prompts/segmentExtractionPrompt.js +81 -0
  65. package/dist/prompts/segmentExtractionPrompt.js.map +1 -0
  66. package/dist/store/GraphStore.d.ts +16 -19
  67. package/dist/store/GraphStore.d.ts.map +1 -1
  68. package/dist/store/GraphStore.js +1 -576
  69. package/dist/store/GraphStore.js.map +1 -1
  70. package/dist/store/index.d.ts +3 -0
  71. package/dist/store/index.d.ts.map +1 -0
  72. package/dist/store/index.js +2 -0
  73. package/dist/store/index.js.map +1 -0
  74. package/dist/store/postgres-pgvector/GraphStore.d.ts +75 -0
  75. package/dist/store/postgres-pgvector/GraphStore.d.ts.map +1 -0
  76. package/dist/store/postgres-pgvector/GraphStore.js +782 -0
  77. package/dist/store/postgres-pgvector/GraphStore.js.map +1 -0
  78. package/dist/types.d.ts +69 -1
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/utils/drift/driftMarkers.d.ts +4 -0
  81. package/dist/utils/drift/driftMarkers.d.ts.map +1 -0
  82. package/dist/utils/drift/driftMarkers.js +31 -0
  83. package/dist/utils/drift/driftMarkers.js.map +1 -0
  84. package/dist/utils/drift/driftScore.d.ts +3 -0
  85. package/dist/utils/drift/driftScore.d.ts.map +1 -0
  86. package/dist/utils/drift/driftScore.js +11 -0
  87. package/dist/utils/drift/driftScore.js.map +1 -0
  88. package/dist/utils/drift/driftThreshold.d.ts +7 -0
  89. package/dist/utils/drift/driftThreshold.d.ts.map +1 -0
  90. package/dist/utils/drift/driftThreshold.js +21 -0
  91. package/dist/utils/drift/driftThreshold.js.map +1 -0
  92. package/dist/utils/drift/reentryMatch.d.ts +3 -0
  93. package/dist/utils/drift/reentryMatch.d.ts.map +1 -0
  94. package/dist/utils/drift/reentryMatch.js +10 -0
  95. package/dist/utils/drift/reentryMatch.js.map +1 -0
  96. package/dist/utils/extraction/segmentExtraction.d.ts +5 -0
  97. package/dist/utils/extraction/segmentExtraction.d.ts.map +1 -0
  98. package/dist/utils/extraction/segmentExtraction.js +82 -0
  99. package/dist/utils/extraction/segmentExtraction.js.map +1 -0
  100. package/dist/utils/reentry/reentryCues.d.ts +3 -0
  101. package/dist/utils/reentry/reentryCues.d.ts.map +1 -0
  102. package/dist/utils/reentry/reentryCues.js +14 -0
  103. package/dist/utils/reentry/reentryCues.js.map +1 -0
  104. package/dist/utils/reentry/reentryEdges.d.ts +16 -0
  105. package/dist/utils/reentry/reentryEdges.d.ts.map +1 -0
  106. package/dist/utils/reentry/reentryEdges.js +80 -0
  107. package/dist/utils/reentry/reentryEdges.js.map +1 -0
  108. package/dist/utils/reentry/reentrySimilarity.d.ts +5 -0
  109. package/dist/utils/reentry/reentrySimilarity.d.ts.map +1 -0
  110. package/dist/utils/reentry/reentrySimilarity.js +26 -0
  111. package/dist/utils/reentry/reentrySimilarity.js.map +1 -0
  112. package/dist/utils/reentry/reentryText.d.ts +6 -0
  113. package/dist/utils/reentry/reentryText.d.ts.map +1 -0
  114. package/dist/utils/reentry/reentryText.js +29 -0
  115. package/dist/utils/reentry/reentryText.js.map +1 -0
  116. package/dist/utils/reentry/types.d.ts +6 -0
  117. package/dist/utils/reentry/types.d.ts.map +1 -0
  118. package/dist/utils/reentry/types.js +2 -0
  119. package/dist/utils/reentry/types.js.map +1 -0
  120. package/dist/utils/text/normalizeText.d.ts +2 -0
  121. package/dist/utils/text/normalizeText.d.ts.map +1 -0
  122. package/dist/utils/text/normalizeText.js +5 -0
  123. package/dist/utils/text/normalizeText.js.map +1 -0
  124. package/dist/utils/text/terms.d.ts +3 -0
  125. package/dist/utils/text/terms.d.ts.map +1 -0
  126. package/dist/utils/text/terms.js +51 -0
  127. package/dist/utils/text/terms.js.map +1 -0
  128. package/dist/utils/text/tokenCount.d.ts +2 -0
  129. package/dist/utils/text/tokenCount.d.ts.map +1 -0
  130. package/dist/utils/text/tokenCount.js +4 -0
  131. package/dist/utils/text/tokenCount.js.map +1 -0
  132. package/dist/utils/vector/vectorLiteral.d.ts +3 -0
  133. package/dist/utils/vector/vectorLiteral.d.ts.map +1 -0
  134. package/dist/utils/vector/vectorLiteral.js +19 -0
  135. package/dist/utils/vector/vectorLiteral.js.map +1 -0
  136. package/package.json +84 -55
package/.env.example CHANGED
@@ -1,3 +1,5 @@
1
- DATABASE_URL=postgres://postgres:postgres@localhost:5432/memograffer
2
- OPENAI_API_KEY=
3
- REDIS_URL=redis://localhost:6379
1
+ DATABASE_URL=postgres://postgres:postgres@localhost:5432/memograffer
2
+ ANTHROPIC_API_KEY=
3
+ GEMINI_API_KEY=
4
+ OPENAI_API_KEY=
5
+ REDIS_URL=redis://localhost:6379
package/README.md CHANGED
@@ -1,182 +1,187 @@
1
- # MemoGrafter
2
-
3
- Experimental structured memory for TypeScript chatbots.
4
-
5
- MemoGrafter turns chatbot conversations into topic segments, topic nodes, and graph edges, then injects relevant memory into future turns. Its core idea is memory grafting: copying useful conversational memory from one chatbot or session into another.
6
-
7
- MemoGrafter is a chatbot memory framework. It is not an autonomous agent runtime.
8
-
9
- ## Why MemoGrafter?
10
-
11
- Most chatbots either forget old context or keep stuffing long chat history back into the prompt. MemoGrafter explores a different shape:
12
-
13
- - store conversations as structured memory
14
- - detect topic shifts
15
- - summarize topic segments into memory nodes
16
- - connect related nodes in a graph
17
- - inject only relevant memory into later calls
18
- - graft selected memory into another chatbot/session
19
-
20
- The project is early-stage and experimental, but it is useful for demos, prototypes, and exploring memory workflows beyond plain chat history.
21
-
22
- ## How It Works
23
-
24
- ```text
25
- chat messages
26
- -> topic segments
27
- -> topic nodes
28
- -> graph edges
29
- -> memory injection
30
- -> selective grafting into another chatbot
31
- ```
32
-
33
- On each chatbot call, MemoGrafter can retrieve existing topic memory and pass it to the LLM as a system prompt. After the response, it ingests the updated conversation so future turns have better memory.
34
-
35
- ## Installation
36
-
37
- ```bash
38
- npm install memo-grafter
39
- ```
40
-
41
- For local development from this repository:
42
-
43
- ```bash
44
- git clone <repo-url> project-memoGrafter
45
- cd project-memoGrafter
46
- npm install
47
- npm run build
48
- ```
49
-
50
- Then install it from a local app:
51
-
52
- ```bash
53
- npm install D:/cohort/projects/project-memoGrafter
54
- ```
55
-
56
- ## Environment
57
-
58
- ```bash
59
- DATABASE_URL=postgres://postgres:postgres@localhost:5432/memo_grafter
60
- OPENAI_API_KEY=sk-...
61
- REDIS_URL=redis://localhost:6379
62
- ```
63
-
64
- `DATABASE_URL` is required. PostgreSQL must have `pgvector` enabled.
65
-
66
- `OPENAI_API_KEY` is only needed when using the included OpenAI adapters.
67
-
68
- `REDIS_URL` is optional and only needed for queue mode.
69
-
70
- ## Minimal Usage
71
-
72
- ```ts
73
- import "dotenv/config";
74
-
75
- import {
76
- MemoGrafterAgent,
77
- OpenAIEmbedAdapter,
78
- OpenAILLMAdapter,
79
- } from "memo-grafter";
80
-
81
- const agent = new MemoGrafterAgent({
82
- db: {
83
- connectionString: process.env.DATABASE_URL!,
84
- },
85
- llm: new OpenAILLMAdapter("gpt-4o"),
86
- embedder: new OpenAIEmbedAdapter("text-embedding-3-small"),
87
- });
88
-
89
- await agent.initialize();
90
-
91
- console.log(await agent.invoke("I am planning a Japan trip."));
92
- console.log(await agent.invoke("I like quiet towns, bookstores, and local cafes."));
93
-
94
- const nodes = await agent.getActiveNodes();
95
- console.log(nodes.map((node) => ({ label: node.label, summary: node.summary })));
96
-
97
- await agent.close();
98
- ```
99
-
100
- Run with:
101
-
102
- ```bash
103
- npx tsx --env-file=.env src/index.ts
104
- ```
105
-
106
- ## Memory Grafting
107
-
108
- Memory grafting copies selected memory from one chatbot/session into another.
109
-
110
- ```ts
111
- const travelBot = new MemoGrafterAgent(config);
112
- const writingBot = new MemoGrafterAgent(config);
113
-
114
- await travelBot.initialize();
115
- await writingBot.initialize();
116
-
117
- await travelBot.invoke("I am planning a Japan trip.");
118
- await travelBot.invoke("I like quiet towns, bookstores, and local cafes.");
119
- await travelBot.invoke("My budget is around 2500 dollars.");
120
-
121
- await writingBot.absorbFromAgent(travelBot, {
122
- prompt: "Japan travel preferences",
123
- minSimilarity: 0.6,
124
- limit: 3,
125
- });
126
-
127
- const intro = await writingBot.invoke(
128
- "Suggest a reflective blog intro for my Japan trip."
129
- );
130
-
131
- console.log(intro);
132
-
133
- await travelBot.close();
134
- await writingBot.close();
135
- ```
136
-
137
- You can also preview a graft before copying it:
138
-
139
- ```ts
140
- const graft = await travelBot.graft();
141
-
142
- console.log(graft.systemPrompt);
143
- console.log(graft.nodes);
144
- console.log(graft.tokenCount);
145
- ```
146
-
147
- ## Key Features
148
-
149
- - Structured chatbot memory over PostgreSQL and pgvector.
150
- - Topic drift detection for splitting conversations into segments.
151
- - Topic nodes with summaries, embeddings, message ranges, and graph edges.
152
- - Automatic memory injection during chatbot calls.
153
- - Selective memory grafting by topic ID or semantic prompt.
154
- - Optional BullMQ/Redis queue mode for background ingestion.
155
- - OpenAI adapters included.
156
- - Custom LLM and embedding adapters supported.
157
- - Minimal fleet API for color-scoped worker chatbots and conductor grafting.
158
-
159
- ## Requirements
160
-
161
- - Node.js 18 or newer.
162
- - Server-side Node.js runtime.
163
- - PostgreSQL with `pgvector`.
164
- - An LLM adapter and embedding adapter.
165
- - OpenAI API key if using `OpenAILLMAdapter` or `OpenAIEmbedAdapter`.
166
- - Redis only if using queue mode.
167
-
168
- MemoGrafter does not run in browser code.
169
-
170
- ## Learn More
171
-
172
- Read the full [USER_GUIDE.md](./USER_GUIDE.md) for setup, concepts, configuration, queue mode, custom adapters, fleet usage, examples, and troubleshooting.
173
-
174
- This repository also includes a runnable demo:
175
-
176
- ```text
177
- examples/chatbot-memory-demo
178
- ```
179
-
180
- ## License
181
-
182
- 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 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