@memstack/core 0.7.3 → 0.8.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 +67 -4
- package/dist/index.cjs +665 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -5
- package/dist/index.d.ts +178 -5
- package/dist/index.js +660 -117
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# MemStack
|
|
2
2
|
|
|
3
|
-
> Implementation priority is maintained in the [canonical roadmap](docs/ROADMAP.md).
|
|
4
|
-
|
|
5
3
|
> The open-source memory layer for AI agents — store, retrieve, summarize, and prune.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/@memstack/core)
|
|
@@ -94,6 +92,32 @@ Think of it as the open-source alternative to [Mem0](https://mem0.ai/) — plugg
|
|
|
94
92
|
|
|
95
93
|
## Quick Start
|
|
96
94
|
|
|
95
|
+
### Claude Code and Codex
|
|
96
|
+
|
|
97
|
+
Persistent memory across agent harnesses: what you tell Claude Code, Codex
|
|
98
|
+
recalls in the same project, and the reverse.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm install -g @memstack/cli @memstack/mcp better-sqlite3@^11.10.0 # MemStack never installs storage drivers for you
|
|
102
|
+
memstack init # choose an LLM provider and a store
|
|
103
|
+
memstack connect claude-code
|
|
104
|
+
memstack connect codex
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Memories are scoped to the git repository by its first commit, so clones,
|
|
108
|
+
worktrees, renamed remotes, and moved folders all share them (pin a name with
|
|
109
|
+
`memstack project pin <id>`). `connect` also installs a session-start hook, so every
|
|
110
|
+
new session starts with the project's key memories (Codex asks you to approve
|
|
111
|
+
it once with `/hooks`). For Codex, `connect` also adds a marked block to
|
|
112
|
+
`~/.codex/AGENTS.md` so it saves memories when asked. Recall runs locally
|
|
113
|
+
without an LLM call, and any
|
|
114
|
+
supported store works: swap `better-sqlite3` for `postgres@^3.4.9` or
|
|
115
|
+
`ioredis@^5.11.1` and pick that store in `memstack init`. `memstack status`,
|
|
116
|
+
`memstack doctor`, and `memstack memories` show what is connected and
|
|
117
|
+
stored. See [the harness profile](docs/MCP_SETUP.md#harness-profile-claude-code-and-codex).
|
|
118
|
+
|
|
119
|
+
### As a library
|
|
120
|
+
|
|
97
121
|
```bash
|
|
98
122
|
npm install @memstack/core
|
|
99
123
|
```
|
|
@@ -122,7 +146,7 @@ import { MemStack, OpenAILLMAdapter, InMemoryStorageAdapter } from "@memstack/co
|
|
|
122
146
|
const llm = new OpenAILLMAdapter({
|
|
123
147
|
apiKey: process.env.DEEPSEEK_API_KEY!,
|
|
124
148
|
baseURL: "https://api.deepseek.com/v1",
|
|
125
|
-
defaultModel: "deepseek-
|
|
149
|
+
defaultModel: "deepseek-flash",
|
|
126
150
|
});
|
|
127
151
|
|
|
128
152
|
const memstack = new MemStack({
|
|
@@ -209,7 +233,7 @@ Every agent interaction becomes a `Memory` with metadata that controls how it's
|
|
|
209
233
|
interface Memory {
|
|
210
234
|
id: string;
|
|
211
235
|
actorId: string; // Who this memory belongs to (user ID, agent ID, session ID)
|
|
212
|
-
memoryType: MemoryType; // "interaction" | "summary" | "observation" | "fact" | "reflection"
|
|
236
|
+
memoryType: MemoryType; // "interaction" | "summary" | "observation" | "fact" | "reflection" | "preference" | "decision" | "instruction"
|
|
213
237
|
content: string; // The actual text
|
|
214
238
|
importance: number; // 0-1 — higher = survives pruning, ranks higher in retrieval
|
|
215
239
|
emotionalValence: number; // -1 to 1 — for tone-aware retrieval
|
|
@@ -505,6 +529,9 @@ const userCount = await ms.memory.count({ actorId: "user-42" });
|
|
|
505
529
|
| `observation` | Passive knowledge — facts, documents, things the agent knows but didn't interact with. | "Company refund policy is 30 days from purchase." |
|
|
506
530
|
| `fact` | Verified knowledge — discrete truths the agent has confirmed. | "The user's subscription tier is Enterprise." |
|
|
507
531
|
| `reflection` | Self-generated insight — the agent thinking about its own experiences. | "I tend to over-explain billing policies — should be more concise." |
|
|
532
|
+
| `preference` | How the user likes things done. | "Prefer small pull requests with one concern each." |
|
|
533
|
+
| `decision` | A choice made, ideally with its reason. | "Chose Hono over Express for edge runtime support." |
|
|
534
|
+
| `instruction` | A standing rule to follow. | "Never commit directly to main." |
|
|
508
535
|
|
|
509
536
|
Types control retrieval behavior — `compileContext()` treats `interaction` and `summary` differently from `observation`. Use types to separate "what happened" from "what I know."
|
|
510
537
|
|
|
@@ -534,6 +561,29 @@ await ms.memory.retrieve({ actorId: "x", query: "login bug", strategy: "hybrid"
|
|
|
534
561
|
- Use `semantic` for RAG, document search, knowledge base queries
|
|
535
562
|
- Use `hybrid` for most agent memory — it balances meaning with significance
|
|
536
563
|
|
|
564
|
+
### Keyword recall on any storage adapter
|
|
565
|
+
|
|
566
|
+
`LexicalRetriever` answers natural questions without embeddings or an LLM
|
|
567
|
+
call, and behaves the same on every storage adapter. It loads the memories
|
|
568
|
+
in the given actors through `retrieve()`, then ranks them in MemStack with
|
|
569
|
+
BM25 over content and tags, with stemming and prefix matching. When nothing
|
|
570
|
+
matches, it returns the most important memories instead.
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
import { LexicalRetriever } from "@memstack/core";
|
|
574
|
+
|
|
575
|
+
const retriever = new LexicalRetriever(storage);
|
|
576
|
+
const { hits, fallback } = await retriever.recall({
|
|
577
|
+
actorIds: ["project:abc", "global"], // Searched together
|
|
578
|
+
query: "What framework does this project use?",
|
|
579
|
+
limit: 10, // Max results
|
|
580
|
+
maxChars: 8000, // Max total content; the top hit is always returned
|
|
581
|
+
});
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Up to 2,000 memories per actor are ranked (`candidateLimit`). Only returned
|
|
585
|
+
memories are marked as accessed.
|
|
586
|
+
|
|
537
587
|
---
|
|
538
588
|
|
|
539
589
|
## Embeddings
|
|
@@ -935,6 +985,19 @@ const ms = new MemStack({
|
|
|
935
985
|
|
|
936
986
|
Implement `StorageProvider` for any database. The interface is 9 methods. See the reference section above for the full contract.
|
|
937
987
|
|
|
988
|
+
Optional members, none of them required:
|
|
989
|
+
|
|
990
|
+
- `capabilities: { multiProcess?, textSearch? }` declares whether several
|
|
991
|
+
processes can share the store safely and whether `search()` is native.
|
|
992
|
+
- `search(query)` provides native full-text search. `LexicalRetriever` uses
|
|
993
|
+
it when `textSearch` is declared and ranks memories itself otherwise.
|
|
994
|
+
- `retrieve()` should honor `touch: false` by returning memories without
|
|
995
|
+
marking them as accessed.
|
|
996
|
+
|
|
997
|
+
`SQLiteStorageAdapter` enables WAL and a 5-second busy timeout so several
|
|
998
|
+
processes can share one database file. Set `walMode: false` or
|
|
999
|
+
`busyTimeoutMs` to change this.
|
|
1000
|
+
|
|
938
1001
|
### Custom LLM / Embedding
|
|
939
1002
|
|
|
940
1003
|
Implement `LLMProvider` or `EmbeddingProvider` for any service:
|