@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 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
  [![npm version](https://img.shields.io/npm/v/@memstack/core)](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-chat",
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: