memo-grafter 0.2.7 → 0.3.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.
- package/README.md +26 -0
- package/USER_GUIDE.md +262 -17
- package/dist/MemoGrafter.d.ts +11 -5
- package/dist/MemoGrafter.d.ts.map +1 -1
- package/dist/MemoGrafter.js +64 -4
- package/dist/MemoGrafter.js.map +1 -1
- package/dist/MemoGrafterAgent.d.ts +8 -1
- package/dist/MemoGrafterAgent.d.ts.map +1 -1
- package/dist/MemoGrafterAgent.js +31 -2
- package/dist/MemoGrafterAgent.js.map +1 -1
- package/dist/adapters/AnthropicAdapter.d.ts +1 -1
- package/dist/adapters/AnthropicAdapter.d.ts.map +1 -1
- package/dist/adapters/GeminiAdapter.d.ts +1 -1
- package/dist/adapters/GeminiAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenAIAdapter.d.ts +1 -1
- package/dist/adapters/OpenAIAdapter.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +1 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/agents/MemoGrafterAgent.d.ts +45 -0
- package/dist/agents/MemoGrafterAgent.d.ts.map +1 -0
- package/dist/agents/MemoGrafterAgent.js +278 -0
- package/dist/agents/MemoGrafterAgent.js.map +1 -0
- package/dist/agents/fleet/ConductorAgent.d.ts +15 -0
- package/dist/agents/fleet/ConductorAgent.d.ts.map +1 -0
- package/dist/agents/fleet/ConductorAgent.js +41 -0
- package/dist/agents/fleet/ConductorAgent.js.map +1 -0
- package/dist/agents/fleet/FleetStore.d.ts +12 -0
- package/dist/agents/fleet/FleetStore.d.ts.map +1 -0
- package/dist/agents/fleet/FleetStore.js +30 -0
- package/dist/agents/fleet/FleetStore.js.map +1 -0
- package/dist/agents/fleet/MemoGrafterFleet.d.ts +27 -0
- package/dist/agents/fleet/MemoGrafterFleet.d.ts.map +1 -0
- package/dist/agents/fleet/MemoGrafterFleet.js +87 -0
- package/dist/agents/fleet/MemoGrafterFleet.js.map +1 -0
- package/dist/agents/fleet/WorkerAgent.d.ts +36 -0
- package/dist/agents/fleet/WorkerAgent.d.ts.map +1 -0
- package/dist/agents/fleet/WorkerAgent.js +140 -0
- package/dist/agents/fleet/WorkerAgent.js.map +1 -0
- package/dist/agents/fleet/types.d.ts +58 -0
- package/dist/agents/fleet/types.d.ts.map +1 -0
- package/dist/agents/fleet/types.js +2 -0
- package/dist/agents/fleet/types.js.map +1 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +124 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +6 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +34 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +39 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +11 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +92 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/logger.d.ts +7 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/cli/utils/logger.js +15 -0
- package/dist/cli/utils/logger.js.map +1 -0
- package/dist/core/MemoGrafter.d.ts +46 -0
- package/dist/core/MemoGrafter.d.ts.map +1 -0
- package/dist/core/MemoGrafter.js +236 -0
- package/dist/core/MemoGrafter.js.map +1 -0
- package/dist/core/types.d.ts +319 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/crawler/DecayScoringPass.d.ts.map +1 -1
- package/dist/crawler/DecayScoringPass.js +6 -0
- package/dist/crawler/DecayScoringPass.js.map +1 -1
- package/dist/crawler/memoryMaintenance.d.ts +1 -0
- package/dist/crawler/memoryMaintenance.d.ts.map +1 -1
- package/dist/crawler/memoryMaintenance.js +2 -1
- package/dist/crawler/memoryMaintenance.js.map +1 -1
- package/dist/crawler/types.d.ts +1 -0
- package/dist/crawler/types.d.ts.map +1 -1
- package/dist/fleet/MemoGrafterFleet.d.ts +9 -2
- package/dist/fleet/MemoGrafterFleet.d.ts.map +1 -1
- package/dist/fleet/MemoGrafterFleet.js +39 -1
- package/dist/fleet/MemoGrafterFleet.js.map +1 -1
- package/dist/fleet/WorkerAgent.d.ts +9 -4
- package/dist/fleet/WorkerAgent.d.ts.map +1 -1
- package/dist/fleet/WorkerAgent.js +45 -3
- package/dist/fleet/WorkerAgent.js.map +1 -1
- package/dist/fleet/types.d.ts +21 -2
- package/dist/fleet/types.d.ts.map +1 -1
- package/dist/index.d.ts +13 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/ingestion/IngestQueue.d.ts +17 -0
- package/dist/ingestion/IngestQueue.d.ts.map +1 -0
- package/dist/ingestion/IngestQueue.js +123 -0
- package/dist/ingestion/IngestQueue.js.map +1 -0
- package/dist/ingestion/conversation/IngestPipeline.d.ts +41 -0
- package/dist/ingestion/conversation/IngestPipeline.d.ts.map +1 -0
- package/dist/ingestion/conversation/IngestPipeline.js +189 -0
- package/dist/ingestion/conversation/IngestPipeline.js.map +1 -0
- package/dist/ingestion/conversation/SegmentProcessor.d.ts +20 -0
- package/dist/ingestion/conversation/SegmentProcessor.d.ts.map +1 -0
- package/dist/ingestion/conversation/SegmentProcessor.js +110 -0
- package/dist/ingestion/conversation/SegmentProcessor.js.map +1 -0
- package/dist/ingestion/conversation/TopicDriftDetector.d.ts +40 -0
- package/dist/ingestion/conversation/TopicDriftDetector.d.ts.map +1 -0
- package/dist/ingestion/conversation/TopicDriftDetector.js +222 -0
- package/dist/ingestion/conversation/TopicDriftDetector.js.map +1 -0
- package/dist/maintenance/ConflictDetectionPass.d.ts +6 -0
- package/dist/maintenance/ConflictDetectionPass.d.ts.map +1 -0
- package/dist/maintenance/ConflictDetectionPass.js +46 -0
- package/dist/maintenance/ConflictDetectionPass.js.map +1 -0
- package/dist/maintenance/DecayScoringPass.d.ts +17 -0
- package/dist/maintenance/DecayScoringPass.d.ts.map +1 -0
- package/dist/maintenance/DecayScoringPass.js +79 -0
- package/dist/maintenance/DecayScoringPass.js.map +1 -0
- package/dist/maintenance/MemoGrafterCrawler.d.ts +14 -0
- package/dist/maintenance/MemoGrafterCrawler.d.ts.map +1 -0
- package/dist/maintenance/MemoGrafterCrawler.js +108 -0
- package/dist/maintenance/MemoGrafterCrawler.js.map +1 -0
- package/dist/maintenance/VersioningPass.d.ts +6 -0
- package/dist/maintenance/VersioningPass.d.ts.map +1 -0
- package/dist/maintenance/VersioningPass.js +40 -0
- package/dist/maintenance/VersioningPass.js.map +1 -0
- package/dist/maintenance/decayScoring.d.ts +7 -0
- package/dist/maintenance/decayScoring.d.ts.map +1 -0
- package/dist/maintenance/decayScoring.js +9 -0
- package/dist/maintenance/decayScoring.js.map +1 -0
- package/dist/maintenance/index.d.ts +7 -0
- package/dist/maintenance/index.d.ts.map +1 -0
- package/dist/maintenance/index.js +5 -0
- package/dist/maintenance/index.js.map +1 -0
- package/dist/maintenance/memoryMaintenance.d.ts +23 -0
- package/dist/maintenance/memoryMaintenance.d.ts.map +1 -0
- package/dist/maintenance/memoryMaintenance.js +141 -0
- package/dist/maintenance/memoryMaintenance.js.map +1 -0
- package/dist/maintenance/types.d.ts +65 -0
- package/dist/maintenance/types.d.ts.map +1 -0
- package/dist/maintenance/types.js +2 -0
- package/dist/maintenance/types.js.map +1 -0
- package/dist/pipeline/GrafterPipeline.d.ts +2 -0
- package/dist/pipeline/GrafterPipeline.d.ts.map +1 -1
- package/dist/pipeline/GrafterPipeline.js +33 -7
- package/dist/pipeline/GrafterPipeline.js.map +1 -1
- package/dist/pipeline/RetrieverPipeline.d.ts +1 -0
- package/dist/pipeline/RetrieverPipeline.d.ts.map +1 -1
- package/dist/pipeline/RetrieverPipeline.js +16 -5
- package/dist/pipeline/RetrieverPipeline.js.map +1 -1
- package/dist/prompts/factRetrievalPrompt.d.ts +1 -1
- package/dist/prompts/factRetrievalPrompt.d.ts.map +1 -1
- package/dist/prompts/historyCompressionPrompt.d.ts +1 -1
- package/dist/prompts/historyCompressionPrompt.d.ts.map +1 -1
- package/dist/prompts/intentShiftPrompt.d.ts +1 -1
- package/dist/prompts/intentShiftPrompt.d.ts.map +1 -1
- package/dist/prompts/memoryInjectionPrompt.d.ts +1 -1
- package/dist/prompts/memoryInjectionPrompt.d.ts.map +1 -1
- package/dist/prompts/segmentExtractionPrompt.d.ts +1 -1
- package/dist/prompts/segmentExtractionPrompt.d.ts.map +1 -1
- package/dist/retrieval/GrafterPipeline.d.ts +26 -0
- package/dist/retrieval/GrafterPipeline.d.ts.map +1 -0
- package/dist/retrieval/GrafterPipeline.js +117 -0
- package/dist/retrieval/GrafterPipeline.js.map +1 -0
- package/dist/retrieval/RetrieverPipeline.d.ts +28 -0
- package/dist/retrieval/RetrieverPipeline.d.ts.map +1 -0
- package/dist/retrieval/RetrieverPipeline.js +160 -0
- package/dist/retrieval/RetrieverPipeline.js.map +1 -0
- package/dist/schema/builders.d.ts +40 -0
- package/dist/schema/builders.d.ts.map +1 -0
- package/dist/schema/builders.js +10 -0
- package/dist/schema/builders.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/mg-tables.d.ts +7 -0
- package/dist/schema/mg-tables.d.ts.map +1 -0
- package/dist/schema/mg-tables.js +180 -0
- package/dist/schema/mg-tables.js.map +1 -0
- package/dist/store/GraphStore.d.ts +19 -1
- package/dist/store/GraphStore.d.ts.map +1 -1
- package/dist/store/postgres-pgvector/GraphStore.d.ts +33 -1
- package/dist/store/postgres-pgvector/GraphStore.d.ts.map +1 -1
- package/dist/store/postgres-pgvector/GraphStore.js +491 -16
- package/dist/store/postgres-pgvector/GraphStore.js.map +1 -1
- package/dist/tsconfig.cli.tsbuildinfo +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/drift/adaptiveDriftSensitivity.d.ts +1 -1
- package/dist/utils/drift/adaptiveDriftSensitivity.d.ts.map +1 -1
- package/dist/utils/drift/driftScore.d.ts +1 -1
- package/dist/utils/drift/driftScore.d.ts.map +1 -1
- package/dist/utils/drift/driftThreshold.d.ts +1 -1
- package/dist/utils/drift/driftThreshold.d.ts.map +1 -1
- package/dist/utils/drift/reentryMatch.d.ts +1 -1
- package/dist/utils/drift/reentryMatch.d.ts.map +1 -1
- package/dist/utils/extraction/segmentExtraction.d.ts +1 -1
- package/dist/utils/extraction/segmentExtraction.d.ts.map +1 -1
- package/dist/utils/reentry/reentryEdges.d.ts +1 -1
- package/dist/utils/reentry/reentryEdges.d.ts.map +1 -1
- package/dist/utils/reentry/reentrySimilarity.d.ts +1 -1
- package/dist/utils/reentry/reentrySimilarity.d.ts.map +1 -1
- package/dist/utils/reentry/reentryText.d.ts +1 -1
- package/dist/utils/reentry/reentryText.d.ts.map +1 -1
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -38,10 +38,14 @@ MemoGrafter stores conversation turns, tracks which messages have already been i
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
npm install memo-grafter
|
|
41
|
+
npx memo-grafter init
|
|
42
|
+
npx memo-grafter migrate
|
|
41
43
|
```
|
|
42
44
|
|
|
43
45
|
MemoGrafter runs server-side on Node.js. The built-in storage backend uses PostgreSQL with `pgvector`.
|
|
44
46
|
|
|
47
|
+
`init` creates local project files under `src/memo-grafter/` (`mg-schema.ts`, `schema.ts`, and `mg.config.ts`) without touching your database. `migrate` creates or updates MemoGrafter-owned `mg_*` tables. Application tables remain managed by your existing tool, such as Prisma, Drizzle, or SQL migrations.
|
|
48
|
+
|
|
45
49
|
## Minimal Example
|
|
46
50
|
|
|
47
51
|
```ts
|
|
@@ -68,12 +72,34 @@ await agent.ingestText("The product roadmap now prioritizes document imports.",
|
|
|
68
72
|
source: "import",
|
|
69
73
|
});
|
|
70
74
|
|
|
75
|
+
await agent.remember("The user prefers concise TypeScript examples.");
|
|
76
|
+
|
|
71
77
|
const recall = await agent.recall("travel preferences");
|
|
72
78
|
console.log(recall.facts);
|
|
73
79
|
|
|
74
80
|
await agent.close();
|
|
75
81
|
```
|
|
76
82
|
|
|
83
|
+
## Shared Fleet Memory
|
|
84
|
+
|
|
85
|
+
Fleets can store common knowledge once and make it available to workers without
|
|
86
|
+
copying it into each worker session.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const fleet = new MemoGrafterFleet(config, {
|
|
90
|
+
id: "support-fleet",
|
|
91
|
+
defaultWorkerMemory: "both",
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await fleet.initialize();
|
|
95
|
+
await fleet.ingestToFleet("Refund policy: customers can request a refund within 30 days.");
|
|
96
|
+
|
|
97
|
+
const support = await fleet.createWorker({ color: "support" });
|
|
98
|
+
const recall = await support.recall("refund policy", { memory: "both" });
|
|
99
|
+
|
|
100
|
+
console.log(recall.facts);
|
|
101
|
+
```
|
|
102
|
+
|
|
77
103
|
## Learn More
|
|
78
104
|
|
|
79
105
|
- [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.
|
package/USER_GUIDE.md
CHANGED
|
@@ -69,13 +69,20 @@ REDIS_URL=redis://localhost:6379
|
|
|
69
69
|
|
|
70
70
|
`REDIS_URL` is optional and only needed when you pass `queue` or `cache` config.
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
Initialize MemoGrafter project files and migrate the MemoGrafter tables:
|
|
73
73
|
|
|
74
|
-
```
|
|
75
|
-
|
|
74
|
+
```bash
|
|
75
|
+
npx memo-grafter init
|
|
76
|
+
npx memo-grafter migrate
|
|
76
77
|
```
|
|
77
78
|
|
|
78
|
-
|
|
79
|
+
`memo-grafter init` creates local project files only:
|
|
80
|
+
|
|
81
|
+
- `src/memo-grafter/mg-schema.ts`: generated MemoGrafter schema reference for `mg_*` tables. This file is regenerated on every `init` run.
|
|
82
|
+
- `src/memo-grafter/schema.ts`: user-owned schema composition file. It is created only if missing and is never overwritten.
|
|
83
|
+
- `src/memo-grafter/mg.config.ts`: user-editable MemoGrafter CLI config.
|
|
84
|
+
|
|
85
|
+
`memo-grafter migrate` creates `pgvector`, `pgcrypto`, and MemoGrafter-owned `mg_*` tables in the database. It does not migrate app tables from `schema.ts`; keep using Prisma, Drizzle, raw SQL, or another migration tool for application tables.
|
|
79
86
|
|
|
80
87
|
Current v1 tables:
|
|
81
88
|
|
|
@@ -94,6 +101,13 @@ Current v1 tables:
|
|
|
94
101
|
|
|
95
102
|
## Quick Start
|
|
96
103
|
|
|
104
|
+
Run the setup commands once for your app:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx memo-grafter init
|
|
108
|
+
npx memo-grafter migrate
|
|
109
|
+
```
|
|
110
|
+
|
|
97
111
|
Create `src/index.ts`:
|
|
98
112
|
|
|
99
113
|
```ts
|
|
@@ -185,6 +199,8 @@ Important fields:
|
|
|
185
199
|
- `messageRange`: source message range.
|
|
186
200
|
- `topicOrder`: chronological order.
|
|
187
201
|
- `driftScore`: topic-change score.
|
|
202
|
+
- `suppressed`: whether the topic is temporarily hidden from recall, grafting, crawler maintenance, and active topic reads.
|
|
203
|
+
- `suppressedAt`: timestamp for the latest suppression, or `null` when active.
|
|
188
204
|
- `agentColor`, `fleetId`, `agentId`: nullable fleet metadata.
|
|
189
205
|
|
|
190
206
|
Topic nodes are stored in `mg_topic_nodes`.
|
|
@@ -201,12 +217,14 @@ Important fields:
|
|
|
201
217
|
- `topicNodeId`: parent topic node ID.
|
|
202
218
|
- `tags`: optional normalized tags copied from the session or ingest call.
|
|
203
219
|
- `decayed`: whether the memory is stale.
|
|
220
|
+
- `forgotten`: whether the memory has been explicitly hidden by an application.
|
|
221
|
+
- `forgottenAt`: timestamp for the explicit forget action, or `null` when active.
|
|
204
222
|
- `hasConflict`: whether crawler maintenance found a conflicting active fact.
|
|
205
223
|
- `supersededBy`: newer memory ID when this memory has been replaced.
|
|
206
224
|
|
|
207
225
|
Memory nodes are stored in `mg_memory_nodes`.
|
|
208
226
|
|
|
209
|
-
`decayed`, `hasConflict`, and `supersededBy` are maintenance fields. Normal ingestion creates active memories. Optional crawler passes can later annotate existing memory rows, but they do not delete rows or rewrite topic summaries.
|
|
227
|
+
`decayed`, `hasConflict`, and `supersededBy` are maintenance fields. `forgotten` is an application-controlled lifecycle field. Normal ingestion creates active memories. Optional crawler passes can later annotate existing memory rows, but they do not delete rows or rewrite topic summaries.
|
|
210
228
|
|
|
211
229
|
### Graph Edges
|
|
212
230
|
|
|
@@ -241,7 +259,7 @@ There are two common forms:
|
|
|
241
259
|
- Preview memory with `graft()`.
|
|
242
260
|
- Copy memory into another chatbot with `absorbFromAgent()` or `ingestGraftedNodes()`.
|
|
243
261
|
|
|
244
|
-
When topic nodes are absorbed into another session, MemoGrafter also copies their active memory nodes so targeted recall can find the transferred facts. Copied memory rows get fresh IDs, keep their existing embeddings, and are copied as active memories only when the source row is not decayed or
|
|
262
|
+
When topic nodes are absorbed into another session, MemoGrafter also copies their active memory nodes so targeted recall can find the transferred facts. Copied memory rows get fresh IDs, keep their existing embeddings, and are copied as active memories only when the source row is not decayed, superseded, forgotten, or attached to a suppressed topic.
|
|
245
263
|
|
|
246
264
|
Absorbed topic nodes are also registered in `mg_graft_registry`. The registry records the destination session, copied node ID, source session ID, source node ID, and graft timestamp so applications can inspect provenance or remove a graft later.
|
|
247
265
|
|
|
@@ -324,6 +342,19 @@ Without `replace`, each text call appends to the current session memory. Later `
|
|
|
324
342
|
|
|
325
343
|
In queue mode, `await agent.ingestText()` confirms that the ingestion job was queued. Reads may need to wait for the worker to finish before the new graph content is visible.
|
|
326
344
|
|
|
345
|
+
### Remembering Explicit Facts
|
|
346
|
+
|
|
347
|
+
Use `remember()` when your application already knows a fact, preference, or note and wants to store it without running an assistant turn:
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
await agent.remember("The user prefers concise TypeScript examples.", {
|
|
351
|
+
label: "User preference",
|
|
352
|
+
source: "profile-settings",
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
`remember()` is a convenience wrapper around `ingestText()`. It uses the same extraction pipeline, applies the current session tags automatically, does not change `getHistory()`, and defaults `source` to `"remember"` when you do not provide one. The extraction LLM still decides which structured memories to create, so this API is best for natural-language facts and preferences rather than exact row-level inserts.
|
|
357
|
+
|
|
327
358
|
### Clearing A Session
|
|
328
359
|
|
|
329
360
|
Use `clearSession()` when you intentionally want to reset an agent:
|
|
@@ -334,6 +365,117 @@ await agent.clearSession();
|
|
|
334
365
|
|
|
335
366
|
This waits for pending ingestion, clears the agent's local in-memory history, removes stored messages, topic nodes, memory nodes, graph edges, segments, and resets the session ingest cursor. It is a destructive operation and is not part of normal `invoke()` processing.
|
|
336
367
|
|
|
368
|
+
### Memory Lifecycle Controls
|
|
369
|
+
|
|
370
|
+
Use lifecycle controls when your application needs user-controlled memory management without physically deleting graph rows by default.
|
|
371
|
+
|
|
372
|
+
Forget a single memory node:
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
const recall = await agent.recall("food preferences");
|
|
376
|
+
const memoryId = recall.facts[0]!.id;
|
|
377
|
+
|
|
378
|
+
const changed = await agent.forget(memoryId);
|
|
379
|
+
console.log(changed); // true when the memory was newly marked forgotten
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Forget several memory nodes at once:
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
const changedCount = await agent.forgetMany([
|
|
386
|
+
"memory-id-a",
|
|
387
|
+
"memory-id-b",
|
|
388
|
+
]);
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Suppress a topic temporarily:
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
const nodes = await agent.getActiveNodes();
|
|
395
|
+
const topicId = nodes[0]!.id;
|
|
396
|
+
|
|
397
|
+
await agent.suppressTopic(topicId);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Restore a suppressed topic:
|
|
401
|
+
|
|
402
|
+
```ts
|
|
403
|
+
await agent.restoreTopic(topicId);
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Forgotten memories stay in `mg_memory_nodes` with `forgotten = TRUE` and `forgotten_at` set. Suppressed topics stay in `mg_topic_nodes` with `suppressed = TRUE` and `suppressed_at` set. These rows are excluded from targeted recall, invoke-time recall, graft prompt assembly, semantic graft seed selection, absorption, active topic listing, and crawler maintenance until restored where applicable.
|
|
407
|
+
|
|
408
|
+
`forget()` and `forgetMany()` are one-way soft lifecycle operations. There is no built-in `restoreMemory()` API because user-requested memory deletion and privacy flows usually need conservative behavior. Applications that require undo or hard deletion can implement that policy at the storage layer.
|
|
409
|
+
|
|
410
|
+
`getGraphSnapshot()` remains useful for audit and visualization. Snapshot memory reads include forgotten, decayed, conflicted, and superseded rows, and snapshot topic reads include suppressed topics, so UIs can display lifecycle state explicitly.
|
|
411
|
+
|
|
412
|
+
The lower-level `MemoGrafter` class exposes the same methods when you manage sessions yourself:
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
await memo.forget(memoryId);
|
|
416
|
+
await memo.forgetMany(memoryIds);
|
|
417
|
+
await memo.suppressTopic(topicId);
|
|
418
|
+
await memo.restoreTopic(topicId);
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Memory History And Diff
|
|
422
|
+
|
|
423
|
+
Use memory history APIs when your application needs audit trails, explainability, or debugging for facts that changed over time.
|
|
424
|
+
|
|
425
|
+
Look up history from a specific memory node:
|
|
426
|
+
|
|
427
|
+
```ts
|
|
428
|
+
const history = await agent.getMemoryHistory(memoryId);
|
|
429
|
+
|
|
430
|
+
for (const entry of history.entries) {
|
|
431
|
+
console.log(entry.versionIndex);
|
|
432
|
+
console.log(entry.status);
|
|
433
|
+
console.log(entry.memory.value);
|
|
434
|
+
console.log(entry.supersededBy);
|
|
435
|
+
console.log(entry.supersedes);
|
|
436
|
+
console.log(entry.conflictsWith);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
console.log(history.currentMemory);
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Look up history by fact key:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
const history = await agent.getMemoryHistory("user", "location");
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`MemoGrafterAgent` scopes history lookups to the current session. If you manage sessions yourself with `MemoGrafter`, pass the session explicitly:
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
const history = await memo.getMemoryHistory("user", "location", {
|
|
452
|
+
sessionId,
|
|
453
|
+
});
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Compare two memory versions:
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
const diff = await agent.getMemoryDiff(oldMemoryId, newMemoryId);
|
|
460
|
+
|
|
461
|
+
console.log(diff.changedFields);
|
|
462
|
+
console.log(diff.relationship.supersededBy);
|
|
463
|
+
console.log(diff.relationship.updateEdges);
|
|
464
|
+
console.log(diff.relationship.conflictEdges);
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
History results are read-only and derived from existing memory rows plus `supersededBy`, `updates`, and `conflicts` metadata. They intentionally include superseded, decayed, forgotten, and suppressed-topic memories, even though those rows are excluded from normal recall and grafting.
|
|
468
|
+
|
|
469
|
+
`MemoryHistoryEntry.status` is one of:
|
|
470
|
+
|
|
471
|
+
- `"active"`: not superseded, decayed, forgotten, or conflicting.
|
|
472
|
+
- `"superseded"`: the memory has `supersededBy` set.
|
|
473
|
+
- `"conflicting"`: the memory has `hasConflict` or a `conflicts` edge.
|
|
474
|
+
- `"decayed"`: crawler decay marked the memory stale.
|
|
475
|
+
- `"forgotten"`: an application explicitly forgot the memory.
|
|
476
|
+
|
|
477
|
+
`getMemoryDiff()` is structural. It compares stored fields such as `value`, `confidence`, lifecycle flags, tags, source metadata, and timestamps. It does not call an LLM or generate prose explanations.
|
|
478
|
+
|
|
337
479
|
### Session Tags
|
|
338
480
|
|
|
339
481
|
Use session tags when you want to organize memory by project, planning area, week, domain, or worker route.
|
|
@@ -418,7 +560,7 @@ const projectMemory = await agent.recall("deployment decisions", {
|
|
|
418
560
|
});
|
|
419
561
|
```
|
|
420
562
|
|
|
421
|
-
This can return matching active memories from older or different sessions with the same tag. If your development database contains repeated smoke-test runs, you may see more than one matching fact because the older tagged rows are still present.
|
|
563
|
+
This can return matching active memories from older or different sessions with the same tag. Active recall excludes decayed, superseded, forgotten, and suppressed-topic memories. If your development database contains repeated smoke-test runs, you may see more than one matching fact because the older tagged rows are still present.
|
|
422
564
|
|
|
423
565
|
`MemoGrafterAgent.invoke()` also calls `recall()` internally before answering when the session has topic nodes. In that automatic path, the returned `systemPrompt` is pinned as a single system message before the recent raw chat window. Automatic recall uses `inject.recallLimit` and `inject.recallMinSimilarity`, defaulting to `6` and `0.55`.
|
|
424
566
|
|
|
@@ -436,6 +578,7 @@ console.log(snapshot.nodes);
|
|
|
436
578
|
console.log(snapshot.snapshotNodes);
|
|
437
579
|
console.log(snapshot.edges);
|
|
438
580
|
console.log(snapshot.memories);
|
|
581
|
+
console.log(snapshot.snapshotMemories);
|
|
439
582
|
console.log(snapshot.memoryEdges);
|
|
440
583
|
console.log(snapshot.capturedAt);
|
|
441
584
|
```
|
|
@@ -443,18 +586,30 @@ console.log(snapshot.capturedAt);
|
|
|
443
586
|
`getGraphSnapshot()` returns a `GraphSnapshot`:
|
|
444
587
|
|
|
445
588
|
- `sessionId`: current agent session ID.
|
|
446
|
-
- `nodes`:
|
|
447
|
-
- `snapshotNodes`:
|
|
589
|
+
- `nodes`: topic nodes for the session, including suppressed nodes for audit views.
|
|
590
|
+
- `snapshotNodes`: topic nodes wrapped with lifecycle metadata and optional graft provenance.
|
|
448
591
|
- `edges`: topic edges where either endpoint belongs to a session topic node.
|
|
449
|
-
- `memories`: all memory nodes for the session, including decayed or superseded rows.
|
|
592
|
+
- `memories`: all memory nodes for the session, including forgotten, decayed, conflicted, or superseded rows.
|
|
593
|
+
- `snapshotMemories`: memory nodes wrapped with lifecycle metadata.
|
|
450
594
|
- `memoryEdges`: memory-level edges such as `semantic`, `conflicts`, `updates`, and `related`.
|
|
451
595
|
- `capturedAt`: ISO timestamp for when the snapshot was produced.
|
|
452
596
|
|
|
453
|
-
Each `snapshotNodes` entry contains
|
|
597
|
+
Each `snapshotNodes` entry contains:
|
|
598
|
+
|
|
599
|
+
- `node`: the topic node.
|
|
600
|
+
- `lifecycle`: `{ suppressed, suppressedAt }`.
|
|
601
|
+
- `graftOrigin`: optional `{ sourceSessionId, sourceNodeId, graftedAt }` when the node came from a graft.
|
|
602
|
+
|
|
603
|
+
Each `snapshotMemories` entry contains:
|
|
604
|
+
|
|
605
|
+
- `memory`: the memory node.
|
|
606
|
+
- `lifecycle`: `{ forgotten, forgottenAt, decayed, supersededBy, hasConflict }`.
|
|
607
|
+
|
|
608
|
+
The `nodes`, `edges`, `memories`, and `memoryEdges` arrays remain available for backward-compatible callers that already read the raw graph rows directly. Snapshot arrays are sorted deterministically so graph UIs can use them as a stable primary data source.
|
|
454
609
|
|
|
455
610
|
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.
|
|
456
611
|
|
|
457
|
-
Graph snapshots intentionally include stale and maintenance metadata so visualizers can show memory lifecycle state. For example, a UI can fade `decayed` memories, show `hasConflict` badges, draw `conflicts` edges between contradictory facts,
|
|
612
|
+
Graph snapshots intentionally include stale and maintenance metadata so visualizers can show memory lifecycle state. For example, a UI can hide or label `forgotten` memories, fade `decayed` memories, show `hasConflict` badges, draw `conflicts` edges between contradictory facts, draw `updates` edges from the current fact to the older fact it replaced, and show suppressed topics separately from active topics.
|
|
458
613
|
|
|
459
614
|
Read active topic nodes:
|
|
460
615
|
|
|
@@ -553,6 +708,8 @@ Active memory facts:
|
|
|
553
708
|
|
|
554
709
|
This keeps history intact while telling the downstream model which fact is current.
|
|
555
710
|
|
|
711
|
+
Suppressed topics are not included in graft prompts, even if their IDs are passed explicitly. Forgotten memories are not included as active facts or as replacement details in maintenance notes.
|
|
712
|
+
|
|
556
713
|
## Maintaining Memory With The Crawler
|
|
557
714
|
|
|
558
715
|
`MemoGrafterCrawler` is an optional graph maintenance worker. It can run once on demand or on a simple in-process interval. It does not use Redis, BullMQ, OpenAI, embeddings, or LLMs for the built-in conflict/versioning/decay passes.
|
|
@@ -608,6 +765,7 @@ The built-in conflict and versioning passes use separate deterministic classifie
|
|
|
608
765
|
- a group conflicts when it has different normalized `value` strings and the newest value does not contain an explicit update cue;
|
|
609
766
|
- a group versions only when its newest value contains an explicit replacement or update cue such as `actually`, `now`, `changed to`, or `instead`;
|
|
610
767
|
- decayed memories are skipped;
|
|
768
|
+
- forgotten memories and memories attached to suppressed topics are skipped;
|
|
611
769
|
- already superseded memories are skipped;
|
|
612
770
|
- broad topic memories with generic subject/predicate pairs are skipped unless they match a recognized competing trip-plan pattern;
|
|
613
771
|
- version replacement candidates are selected by `createdAt`;
|
|
@@ -624,7 +782,7 @@ recency_factor = exp(-(ln(2) / half_life_days) * age_days)
|
|
|
624
782
|
decay_score = confidence * recency_factor
|
|
625
783
|
```
|
|
626
784
|
|
|
627
|
-
If `decay_score < minScore`, the memory is marked `decayed: true`. Superseded memories and already decayed memories are skipped. Conservative defaults are used when options are omitted:
|
|
785
|
+
If `decay_score < minScore`, the memory is marked `decayed: true`. Superseded memories, forgotten memories, and already decayed memories are skipped. Conservative defaults are used when options are omitted:
|
|
628
786
|
|
|
629
787
|
```ts
|
|
630
788
|
new DecayScoringPass({
|
|
@@ -647,7 +805,7 @@ When explicit replacements are found:
|
|
|
647
805
|
- an `updates` edge is created as `newer_memory --updates--> older_memory`.
|
|
648
806
|
- stale active memories can be marked `decayed: true` by the decay pass.
|
|
649
807
|
|
|
650
|
-
Crawler maintenance is non-destructive. It annotates existing memory rows and creates memory edges. It does not delete nodes, does not rebuild topics, and does not rewrite topic summaries.
|
|
808
|
+
Crawler maintenance is non-destructive. It annotates existing memory rows and creates memory edges. It does not delete nodes, does not rebuild topics, and does not rewrite topic summaries. Forgotten memories and memories attached to suppressed topics are ignored by maintenance scans.
|
|
651
809
|
|
|
652
810
|
Existing incorrect conflict edges are not automatically deleted. If an older crawler run created a false-positive edge, handle cleanup with a future explicit pruning pass or filter displayed memory edges to active memories in your app.
|
|
653
811
|
|
|
@@ -689,7 +847,7 @@ const response = await writingBot.invoke(
|
|
|
689
847
|
console.log(response);
|
|
690
848
|
```
|
|
691
849
|
|
|
692
|
-
Absorbing copies selected topic nodes into the target session and creates `grafted` edges back to their source nodes. It also copies active memory facts attached to those topic nodes into the target session so future `recall()` and `invoke()` calls can surface the transferred context. Decayed or
|
|
850
|
+
Absorbing copies selected topic nodes into the target session and creates `grafted` edges back to their source nodes. It also copies active memory facts attached to those topic nodes into the target session so future `recall()` and `invoke()` calls can surface the transferred context. Decayed, superseded, forgotten, or suppressed-topic source memories are not copied.
|
|
693
851
|
|
|
694
852
|
Each copied topic node is recorded in the graft registry. Registry entries let you answer where a graft came from and which copied destination node owns it.
|
|
695
853
|
|
|
@@ -1030,6 +1188,18 @@ Run the semantic grafting smoke with a real PostgreSQL database:
|
|
|
1030
1188
|
npx tsx --env-file=.env ./tests/manual/graft/graft-by-relevance-smoke.ts
|
|
1031
1189
|
```
|
|
1032
1190
|
|
|
1191
|
+
Run the memory lifecycle smoke with a real PostgreSQL database and `OPENAI_API_KEY`:
|
|
1192
|
+
|
|
1193
|
+
```powershell
|
|
1194
|
+
npx tsx --env-file=.env ./tests/manual/graft/memory-lifecycle-smoke.ts
|
|
1195
|
+
```
|
|
1196
|
+
|
|
1197
|
+
Run the memory history smoke with a real PostgreSQL database:
|
|
1198
|
+
|
|
1199
|
+
```powershell
|
|
1200
|
+
npx tsx --env-file=.env ./tests/manual/graft/memory-history-smoke.ts
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1033
1203
|
Use the forward-slash path in PowerShell. An unquoted backslash path can be collapsed before `tsx` receives it.
|
|
1034
1204
|
|
|
1035
1205
|
The smoke creates two tagged sessions, writes one memory into each, verifies current-session tag filtering with `getActiveNodes()`, and verifies cross-session project recall with `recall(..., { scope: "tagged" })`. If you run it repeatedly against the same database, tagged recall can return rows from previous smoke runs because those historical sessions are still present.
|
|
@@ -1158,6 +1328,7 @@ import {
|
|
|
1158
1328
|
} from "memo-grafter";
|
|
1159
1329
|
|
|
1160
1330
|
const store = new PostgresGraphStore(process.env.DATABASE_URL!);
|
|
1331
|
+
await store.migrate(); // Or run `npx memo-grafter migrate` before app startup.
|
|
1161
1332
|
await store.initialize();
|
|
1162
1333
|
|
|
1163
1334
|
const embedder = new OpenAIEmbedAdapter("text-embedding-3-small");
|
|
@@ -1234,6 +1405,63 @@ await fleet.close();
|
|
|
1234
1405
|
|
|
1235
1406
|
The worker color `conductor` is reserved.
|
|
1236
1407
|
|
|
1408
|
+
### Shared fleet memory
|
|
1409
|
+
|
|
1410
|
+
Fleet memory is a shared parent scope for every worker in a fleet. Use it for
|
|
1411
|
+
common knowledge such as product docs, company policies, operating procedures,
|
|
1412
|
+
or global application context.
|
|
1413
|
+
|
|
1414
|
+
```ts
|
|
1415
|
+
await fleet.ingestToFleet(
|
|
1416
|
+
"Refund policy: customers can request a refund within 30 days.",
|
|
1417
|
+
{
|
|
1418
|
+
tags: ["policy"],
|
|
1419
|
+
source: "support-handbook",
|
|
1420
|
+
}
|
|
1421
|
+
);
|
|
1422
|
+
|
|
1423
|
+
const shared = await fleet.getSharedMemory();
|
|
1424
|
+
console.log(shared.memories);
|
|
1425
|
+
|
|
1426
|
+
const recall = await fleet.recallFromFleet("refund policy");
|
|
1427
|
+
console.log(recall.facts);
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
Workers keep their own session memory. When a worker should also inherit fleet
|
|
1431
|
+
knowledge, configure its memory mode:
|
|
1432
|
+
|
|
1433
|
+
```ts
|
|
1434
|
+
const support = await fleet.createWorker({
|
|
1435
|
+
color: "support",
|
|
1436
|
+
memory: "both",
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1439
|
+
await support.invoke("What is the refund window?");
|
|
1440
|
+
```
|
|
1441
|
+
|
|
1442
|
+
Worker retrieval and relevance grafting can also choose the scope per call:
|
|
1443
|
+
|
|
1444
|
+
```ts
|
|
1445
|
+
await support.recall("refund policy", {
|
|
1446
|
+
memory: "fleet",
|
|
1447
|
+
});
|
|
1448
|
+
|
|
1449
|
+
await support.graftByRelevance("refund policy", {
|
|
1450
|
+
memory: "both",
|
|
1451
|
+
minSimilarity: 0.55,
|
|
1452
|
+
});
|
|
1453
|
+
```
|
|
1454
|
+
|
|
1455
|
+
Memory modes:
|
|
1456
|
+
|
|
1457
|
+
- `"local"`: only the worker session memory.
|
|
1458
|
+
- `"fleet"`: only the shared fleet memory.
|
|
1459
|
+
- `"both"`: worker session memory plus shared fleet memory.
|
|
1460
|
+
|
|
1461
|
+
The default worker mode is `"local"` for compatibility. You can set
|
|
1462
|
+
`defaultWorkerMemory: "both"` when creating the fleet if all workers should
|
|
1463
|
+
inherit shared fleet memory unless overridden.
|
|
1464
|
+
|
|
1237
1465
|
Prompt-guided fleet grafting:
|
|
1238
1466
|
|
|
1239
1467
|
```ts
|
|
@@ -1405,6 +1633,7 @@ Practical notes:
|
|
|
1405
1633
|
- Tune `tokenBudget` to control prompt size and cost.
|
|
1406
1634
|
- Use queue mode if ingestion becomes slow.
|
|
1407
1635
|
- Use `clearSession()` only for intentional resets; normal ingestion preserves the graph incrementally.
|
|
1636
|
+
- Use `forget()`, `forgetMany()`, `suppressTopic()`, and `restoreTopic()` for user-controlled memory lifecycle flows.
|
|
1408
1637
|
- Use the optional recall cache for long sessions with repeated direct or invoke-time recall.
|
|
1409
1638
|
- Store your own user/session mapping outside MemoGrafter.
|
|
1410
1639
|
- Call `close()` during graceful shutdown.
|
|
@@ -1440,6 +1669,7 @@ Main exports:
|
|
|
1440
1669
|
- `TagFilterOptions`
|
|
1441
1670
|
- `IngestOptions`
|
|
1442
1671
|
- `IngestTextOptions`
|
|
1672
|
+
- `RememberOptions`
|
|
1443
1673
|
- public shared and fleet types
|
|
1444
1674
|
|
|
1445
1675
|
Useful `GraphStore` inspection methods:
|
|
@@ -1453,21 +1683,36 @@ Useful `GraphStore` inspection methods:
|
|
|
1453
1683
|
- `getMemoryEdgesBySession(sessionId)`
|
|
1454
1684
|
- `getSessionNodeCount(sessionId)`
|
|
1455
1685
|
- `getSessionIngestState(sessionId)`
|
|
1686
|
+
- `forgetMemory(memoryId)`
|
|
1687
|
+
- `forgetMemories(memoryIds)`
|
|
1688
|
+
- `suppressTopic(topicId)`
|
|
1689
|
+
- `restoreTopic(topicId)`
|
|
1690
|
+
- `getMemoryHistoryById(memoryId, options?)`
|
|
1691
|
+
- `getMemoryHistoryByFact(subject, predicate, options?)`
|
|
1692
|
+
- `getMemoryDiff(fromMemoryId, toMemoryId)`
|
|
1456
1693
|
|
|
1457
1694
|
Common `MemoGrafterAgent` methods:
|
|
1458
1695
|
|
|
1459
|
-
- `initialize()`:
|
|
1696
|
+
- `initialize()`: verify that MemoGrafter storage has already been migrated.
|
|
1460
1697
|
- `invoke(message)`: send a user message and receive an assistant response.
|
|
1461
1698
|
- `ingestText(text, options?)`: ingest raw text without generating an assistant response.
|
|
1699
|
+
- `remember(text, options?)`: store explicit natural-language facts or preferences through the text ingestion path.
|
|
1462
1700
|
- `getHistory()`: read local chat history.
|
|
1463
1701
|
- `getSessionId()`: read the current session ID.
|
|
1464
|
-
- `getGraphSnapshot()`: read
|
|
1702
|
+
- `getGraphSnapshot()`: read a stable graph snapshot with raw topic and memory rows, graph edges, lifecycle metadata, graft metadata, session ID, and capture timestamp for visualization or inspection.
|
|
1465
1703
|
- `getGraftRegistry()`: inspect provenance for grafted nodes in the current session.
|
|
1466
1704
|
- `getActiveNodes(options?)`: inspect topic nodes, optionally filtered by tags.
|
|
1467
1705
|
- `getActiveSegments()`: inspect topic segments.
|
|
1468
1706
|
- `setSessionTags(tags)`: replace tags on the current session and apply them to future ingested memories.
|
|
1469
1707
|
- `getSessionTags()`: read the current agent's normalized session tags.
|
|
1470
1708
|
- `clearSession()`: explicitly clear local history and stored session memory.
|
|
1709
|
+
- `forget(memoryId)`: soft-forget a memory node so it is excluded from future recall, grafting, absorption, and crawler maintenance.
|
|
1710
|
+
- `forgetMany(memoryIds)`: soft-forget several memory nodes and return the number changed.
|
|
1711
|
+
- `suppressTopic(topicId)`: hide a topic from active reads, recall, grafting, absorption, and crawler maintenance.
|
|
1712
|
+
- `restoreTopic(topicId)`: make a suppressed topic active again.
|
|
1713
|
+
- `getMemoryHistory(memoryId)`: inspect the current session lineage for a specific memory.
|
|
1714
|
+
- `getMemoryHistory(subject, predicate)`: inspect the current session lineage for a fact key.
|
|
1715
|
+
- `getMemoryDiff(fromMemoryId, toMemoryId)`: compare two memory versions and their maintenance relationship.
|
|
1471
1716
|
- `recall(query, options?)`: retrieve structured memory by semantic query, optionally filtered by tags.
|
|
1472
1717
|
- `graft(topicIds?)`: preview memory injection.
|
|
1473
1718
|
- `graftByRelevance(query, options?)`: preview memory injection selected by semantic topic-node relevance.
|
package/dist/MemoGrafter.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Redis } from "ioredis";
|
|
|
2
2
|
import { MemoGrafterFleet } from "./fleet/MemoGrafterFleet.js";
|
|
3
3
|
import type { MemoGrafterFleetOptions } from "./fleet/types.js";
|
|
4
4
|
import type { GraphStore } from "./store/index.js";
|
|
5
|
-
import type { AbsorbFromAgentOptions, EmbedAdapter, GraftByRelevanceOptions, IngestOptions, IngestTextOptions, InjectionResult, LLMAdapter, MemoGrafterConfig, Message, TopicNode, TopicSegment } from "./types.js";
|
|
5
|
+
import type { AbsorbFromAgentOptions, EmbedAdapter, GraftByRelevanceOptions, IngestOptions, IngestTextOptions, InjectionResult, LLMAdapter, MemoryDiff, MemoryHistoryOptions, MemoryHistoryResult, MemoGrafterConfig, Message, TagFilterOptions, TopicNode, TopicSegment } from "./types.js";
|
|
6
6
|
export declare class MemoGrafter {
|
|
7
7
|
readonly llm: LLMAdapter;
|
|
8
8
|
readonly embedder: EmbedAdapter;
|
|
@@ -20,14 +20,18 @@ export declare class MemoGrafter {
|
|
|
20
20
|
enqueueIngest(messages: Message[], sessionId: string, options?: IngestOptions): Promise<void>;
|
|
21
21
|
ingestText(text: string, sessionId: string, options?: IngestTextOptions & IngestOptions): Promise<TopicNode[]>;
|
|
22
22
|
enqueueTextIngest(text: string, sessionId: string, options?: IngestTextOptions & IngestOptions): Promise<void>;
|
|
23
|
-
getTopics(sessionId: string, options?: {
|
|
24
|
-
tags?: string[];
|
|
25
|
-
tagMode?: "all" | "any";
|
|
26
|
-
}): Promise<{
|
|
23
|
+
getTopics(sessionId: string, options?: TagFilterOptions): Promise<{
|
|
27
24
|
nodes: TopicNode[];
|
|
28
25
|
segments: TopicSegment[];
|
|
29
26
|
}>;
|
|
30
27
|
inject(sessionId: string, topicIds: string[]): Promise<InjectionResult>;
|
|
28
|
+
forget(memoryId: string): Promise<boolean>;
|
|
29
|
+
forgetMany(memoryIds: string[]): Promise<number>;
|
|
30
|
+
suppressTopic(topicId: string): Promise<boolean>;
|
|
31
|
+
restoreTopic(topicId: string): Promise<boolean>;
|
|
32
|
+
getMemoryHistory(memoryId: string, options?: MemoryHistoryOptions): Promise<MemoryHistoryResult>;
|
|
33
|
+
getMemoryHistory(subject: string, predicate: string, options?: MemoryHistoryOptions): Promise<MemoryHistoryResult>;
|
|
34
|
+
getMemoryDiff(fromMemoryId: string, toMemoryId: string): Promise<MemoryDiff>;
|
|
31
35
|
graftByRelevance(sessionId: string, query: string, options?: GraftByRelevanceOptions): Promise<InjectionResult>;
|
|
32
36
|
ingestGraftedNodes(nodes: TopicNode[], targetSessionId: string): Promise<TopicNode[]>;
|
|
33
37
|
selectNodesForAbsorb(sourceSessionId: string, options: AbsorbFromAgentOptions): Promise<TopicNode[]>;
|
|
@@ -36,5 +40,7 @@ export declare class MemoGrafter {
|
|
|
36
40
|
close(): Promise<void>;
|
|
37
41
|
private assertServerEnvironment;
|
|
38
42
|
private toTextPipelineOptions;
|
|
43
|
+
private clearRecallCache;
|
|
44
|
+
private resolveSessionIds;
|
|
39
45
|
}
|
|
40
46
|
//# sourceMappingURL=MemoGrafter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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,uBAAuB,EACvB,aAAa,EAEb,iBAAiB,EACjB,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;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,MAAM,EAAE,iBAAiB;IAuDrC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQjG,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAI9F,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IASvG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAiB,GAAG,aAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAS5G,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAiB,GAAG,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,
|
|
1
|
+
{"version":3,"file":"MemoGrafter.d.ts","sourceRoot":"","sources":["../src/MemoGrafter.ts"],"names":[],"mappings":"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"}
|
package/dist/MemoGrafter.js
CHANGED
|
@@ -107,18 +107,61 @@ export class MemoGrafter {
|
|
|
107
107
|
inject(sessionId, topicIds) {
|
|
108
108
|
return this.grafterPipeline.run(sessionId, topicIds);
|
|
109
109
|
}
|
|
110
|
+
async forget(memoryId) {
|
|
111
|
+
const changed = await this.store.forgetMemory(memoryId);
|
|
112
|
+
if (changed)
|
|
113
|
+
await this.clearRecallCache();
|
|
114
|
+
return changed;
|
|
115
|
+
}
|
|
116
|
+
async forgetMany(memoryIds) {
|
|
117
|
+
const changed = await this.store.forgetMemories(memoryIds);
|
|
118
|
+
if (changed > 0)
|
|
119
|
+
await this.clearRecallCache();
|
|
120
|
+
return changed;
|
|
121
|
+
}
|
|
122
|
+
async suppressTopic(topicId) {
|
|
123
|
+
const changed = await this.store.suppressTopic(topicId);
|
|
124
|
+
if (changed)
|
|
125
|
+
await this.clearRecallCache();
|
|
126
|
+
return changed;
|
|
127
|
+
}
|
|
128
|
+
async restoreTopic(topicId) {
|
|
129
|
+
const changed = await this.store.restoreTopic(topicId);
|
|
130
|
+
if (changed)
|
|
131
|
+
await this.clearRecallCache();
|
|
132
|
+
return changed;
|
|
133
|
+
}
|
|
134
|
+
getMemoryHistory(memoryIdOrSubject, predicateOrOptions, options = {}) {
|
|
135
|
+
if (typeof predicateOrOptions === "string") {
|
|
136
|
+
return this.store.getMemoryHistoryByFact(memoryIdOrSubject, predicateOrOptions, options);
|
|
137
|
+
}
|
|
138
|
+
return this.store.getMemoryHistoryById(memoryIdOrSubject, predicateOrOptions ?? {});
|
|
139
|
+
}
|
|
140
|
+
getMemoryDiff(fromMemoryId, toMemoryId) {
|
|
141
|
+
return this.store.getMemoryDiff(fromMemoryId, toMemoryId);
|
|
142
|
+
}
|
|
110
143
|
async graftByRelevance(sessionId, query, options = {}) {
|
|
111
144
|
const embedding = await this.embedder.embed(query);
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
145
|
+
const configuredSessionIds = options.sessionIds?.filter(Boolean) ?? [];
|
|
146
|
+
const sessionIds = this.resolveSessionIds(sessionId, configuredSessionIds);
|
|
147
|
+
const useConfiguredSessions = configuredSessionIds.length > 0
|
|
148
|
+
&& (sessionIds.length > 1 || sessionIds[0] !== sessionId);
|
|
149
|
+
const seedNodes = useConfiguredSessions
|
|
150
|
+
? await this.store.getSimilarNodesAcrossSessions(embedding, sessionIds, {
|
|
151
|
+
k: options.topK ?? this.graphTopK,
|
|
152
|
+
minSimilarity: options.minSimilarity ?? 0.6,
|
|
153
|
+
})
|
|
154
|
+
: await this.store.getSimilarNodes(embedding, sessionId, {
|
|
155
|
+
k: options.topK ?? this.graphTopK,
|
|
156
|
+
minSimilarity: options.minSimilarity ?? 0.6,
|
|
157
|
+
});
|
|
116
158
|
if (seedNodes.length === 0) {
|
|
117
159
|
return { systemPrompt: "", nodes: [], tokenCount: 0 };
|
|
118
160
|
}
|
|
119
161
|
return this.grafterPipeline.run(sessionId, seedNodes.map((node) => node.id), {
|
|
120
162
|
hopDepth: options.hopDepth ?? this.graphHopDepth,
|
|
121
163
|
expansionStrategy: options.expansionStrategy ?? "graph",
|
|
164
|
+
...(configuredSessionIds.length > 0 ? { sessionIds } : {}),
|
|
122
165
|
});
|
|
123
166
|
}
|
|
124
167
|
async ingestGraftedNodes(nodes, targetSessionId) {
|
|
@@ -172,5 +215,22 @@ export class MemoGrafter {
|
|
|
172
215
|
sourceType: "document",
|
|
173
216
|
};
|
|
174
217
|
}
|
|
218
|
+
async clearRecallCache() {
|
|
219
|
+
if (!this.recallCache)
|
|
220
|
+
return;
|
|
221
|
+
try {
|
|
222
|
+
const keys = await this.recallCache.keys("mg:recall:*");
|
|
223
|
+
if (keys.length > 0) {
|
|
224
|
+
await this.recallCache.del(...keys);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
console.warn("MemoGrafter recall cache invalidation warning:", error);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
resolveSessionIds(sessionId, configured) {
|
|
232
|
+
const sessionIds = configured && configured.length > 0 ? configured : [sessionId];
|
|
233
|
+
return [...new Set(sessionIds)];
|
|
234
|
+
}
|
|
175
235
|
}
|
|
176
236
|
//# sourceMappingURL=MemoGrafter.js.map
|