@memstack/core 0.2.0 → 0.4.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 +144 -56
- package/dist/index.cjs +2212 -262
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +496 -27
- package/dist/index.d.ts +496 -27
- package/dist/index.js +2203 -260
- package/dist/index.js.map +1 -1
- package/package.json +32 -32
- package/src/adapters/embedding/cohere.ts +0 -77
- package/src/adapters/embedding/openai.ts +0 -65
- package/src/adapters/llm/anthropic.ts +0 -69
- package/src/adapters/llm/groq.ts +0 -185
- package/src/adapters/llm/ollama.ts +0 -85
- package/src/adapters/llm/openai.ts +0 -178
- package/src/adapters/storage/disk.ts +0 -334
- package/src/adapters/storage/memory.ts +0 -147
- package/src/adapters/storage/postgres.ts +0 -310
- package/src/adapters/storage/redis.ts +0 -274
- package/src/client.ts +0 -236
- package/src/errors.ts +0 -47
- package/src/index.ts +0 -52
- package/src/interfaces.ts +0 -154
- package/src/memory/ContextCompiler.ts +0 -158
- package/src/memory/MemoryStore.ts +0 -266
- package/src/memory/Pruner.ts +0 -66
- package/src/memory/Summarizer.ts +0 -46
- package/src/types.ts +0 -50
package/README.md
CHANGED
|
@@ -83,11 +83,12 @@ Think of it as the open-source alternative to [Mem0](https://mem0.ai/) — plugg
|
|
|
83
83
|
## Quick Start
|
|
84
84
|
|
|
85
85
|
```typescript
|
|
86
|
-
import { MemStack, OpenAILLMAdapter, OpenAIEmbeddingAdapter } from "@memstack/core";
|
|
86
|
+
import { MemStack, OpenAILLMAdapter, OpenAIEmbeddingAdapter, InMemoryStorageAdapter } from "@memstack/core";
|
|
87
87
|
|
|
88
88
|
const memstack = new MemStack({
|
|
89
89
|
llm: new OpenAILLMAdapter({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
90
90
|
embedding: new OpenAIEmbeddingAdapter({ apiKey: process.env.OPENAI_API_KEY! }),
|
|
91
|
+
storage: new InMemoryStorageAdapter(),
|
|
91
92
|
});
|
|
92
93
|
|
|
93
94
|
// 1. Store what happened
|
|
@@ -134,7 +135,7 @@ Every agent interaction becomes a `Memory` with metadata that controls how it's
|
|
|
134
135
|
interface Memory {
|
|
135
136
|
id: string;
|
|
136
137
|
actorId: string; // Who this memory belongs to (user ID, agent ID, session ID)
|
|
137
|
-
memoryType: MemoryType; // "interaction" | "summary" | "observation"
|
|
138
|
+
memoryType: MemoryType; // "interaction" | "summary" | "observation" | "fact" | "reflection"
|
|
138
139
|
content: string; // The actual text
|
|
139
140
|
importance: number; // 0-1 — higher = survives pruning, ranks higher in retrieval
|
|
140
141
|
emotionalValence: number; // -1 to 1 — for tone-aware retrieval
|
|
@@ -403,7 +404,8 @@ const userCount = await ms.memory.count({ actorId: "user-42" });
|
|
|
403
404
|
| `interaction` | Default. Direct exchanges between agent and user/other agent. | "User asked about billing." |
|
|
404
405
|
| `summary` | Compressed collection of old interactions. Created by `summarize()`. | "Over 3 weeks, user reported 5 login failures..." |
|
|
405
406
|
| `observation` | Passive knowledge — facts, documents, things the agent knows but didn't interact with. | "Company refund policy is 30 days from purchase." |
|
|
406
|
-
| `
|
|
407
|
+
| `fact` | Verified knowledge — discrete truths the agent has confirmed. | "The user's subscription tier is Enterprise." |
|
|
408
|
+
| `reflection` | Self-generated insight — the agent thinking about its own experiences. | "I tend to over-explain billing policies — should be more concise." |
|
|
407
409
|
|
|
408
410
|
Types control retrieval behavior — `compileContext()` treats `interaction` and `summary` differently from `observation`. Use types to separate "what happened" from "what I know."
|
|
409
411
|
|
|
@@ -462,16 +464,17 @@ MemStack is provider-agnostic. Every boundary is an interface — bring your own
|
|
|
462
464
|
|
|
463
465
|
### LLM Adapters
|
|
464
466
|
|
|
465
|
-
Used by `summarize()` and `compileContext()`. Ships with OpenAI and
|
|
467
|
+
Used by `summarize()` and `compileContext()`. Ships with OpenAI, Anthropic, Ollama, and Groq built-in — and via `baseURL`, the OpenAI adapter works with **any OpenAI-compatible API** (DeepSeek, Mistral, Gemini, Together AI, Perplexity, Fireworks, xAI, and dozens more).
|
|
466
468
|
|
|
467
469
|
```typescript
|
|
468
470
|
// OpenAI
|
|
469
471
|
import { OpenAILLMAdapter } from "@memstack/core";
|
|
470
|
-
const llm = new OpenAILLMAdapter({
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
});
|
|
472
|
+
const llm = new OpenAILLMAdapter({ apiKey: "..." });
|
|
473
|
+
|
|
474
|
+
// Any OpenAI-compatible API — just change baseURL
|
|
475
|
+
const deepseek = new OpenAILLMAdapter({ apiKey: "...", baseURL: "https://api.deepseek.com/v1" });
|
|
476
|
+
const mistral = new OpenAILLMAdapter({ apiKey: "...", baseURL: "https://api.mistral.ai/v1" });
|
|
477
|
+
const together = new OpenAILLMAdapter({ apiKey: "...", baseURL: "https://api.together.xyz/v1" });
|
|
475
478
|
|
|
476
479
|
// Anthropic
|
|
477
480
|
import { AnthropicLLMAdapter } from "@memstack/core";
|
|
@@ -480,62 +483,147 @@ const llm = new AnthropicLLMAdapter({
|
|
|
480
483
|
defaultModel: "claude-sonnet-4-5-20250929",
|
|
481
484
|
});
|
|
482
485
|
|
|
483
|
-
// Ollama (
|
|
484
|
-
import
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
method: "POST",
|
|
490
|
-
body: JSON.stringify({ model: req.model ?? "llama3.2", prompt: `${req.system}\n\n${req.user}`, stream: false }),
|
|
491
|
-
});
|
|
492
|
-
const data = await res.json() as { response: string };
|
|
493
|
-
return { text: data.response, tokens: { prompt: 0, completion: 0, total: 0 } };
|
|
494
|
-
}
|
|
495
|
-
}
|
|
486
|
+
// Ollama (built-in)
|
|
487
|
+
import { OllamaLLMAdapter } from "@memstack/core";
|
|
488
|
+
const llm = new OllamaLLMAdapter({
|
|
489
|
+
baseURL: "http://localhost:11434",
|
|
490
|
+
defaultModel: "llama3.2",
|
|
491
|
+
});
|
|
496
492
|
```
|
|
497
493
|
|
|
498
494
|
### Embedding Adapters
|
|
499
495
|
|
|
500
|
-
Used by semantic retrieval. Ships with OpenAI built-in.
|
|
496
|
+
Used by semantic retrieval. Ships with OpenAI and Cohere built-in — and via `baseURL`, the OpenAI adapter works with **any OpenAI-compatible embedding API** (Together AI, Voyage AI, Jina, Nomic, and more).
|
|
501
497
|
|
|
502
498
|
```typescript
|
|
503
|
-
import { OpenAIEmbeddingAdapter } from "@memstack/core";
|
|
504
|
-
const embedding = new OpenAIEmbeddingAdapter({
|
|
505
|
-
apiKey: process.env.OPENAI_API_KEY!,
|
|
506
|
-
model: "text-embedding-3-small", // 1536 dimensions (default)
|
|
507
|
-
// model: "text-embedding-3-large", // 3072 dimensions
|
|
508
|
-
});
|
|
509
|
-
```
|
|
499
|
+
import { OpenAIEmbeddingAdapter, CohereEmbeddingAdapter } from "@memstack/core";
|
|
510
500
|
|
|
511
|
-
|
|
501
|
+
// OpenAI
|
|
502
|
+
new OpenAIEmbeddingAdapter({ apiKey: "...", model: "text-embedding-3-small" }); // 1536 dims
|
|
512
503
|
|
|
513
|
-
|
|
504
|
+
// Cohere
|
|
505
|
+
new CohereEmbeddingAdapter({ apiKey: "..." }); // embed-english-v3.0, 1024 dims
|
|
514
506
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const storage = new InMemoryStorage();
|
|
507
|
+
// Any OpenAI-compatible embedding API
|
|
508
|
+
new OpenAIEmbeddingAdapter({ apiKey: "...", baseURL: "https://api.voyageai.com/v1", model: "voyage-3" });
|
|
518
509
|
```
|
|
519
510
|
|
|
520
|
-
|
|
511
|
+
### Storage Adapters
|
|
521
512
|
|
|
522
|
-
|
|
513
|
+
MemStack ships with **11 production-ready storage adapters (7 experimental)** — every major backend, zero peer dependencies, all client-injected.
|
|
514
|
+
|
|
515
|
+
**Built-in (zero external deps):**
|
|
516
|
+
| Adapter | Backend | Use case |
|
|
517
|
+
|---|---|---|
|
|
518
|
+
| `InMemoryStorageAdapter` | In-memory Map | Testing, prototyping |
|
|
519
|
+
| `DiskStorageAdapter` | Local JSON files | Simple local persistence |
|
|
520
|
+
| `MarkdownStorageAdapter` | Append-only .md files | Human-readable, git-diffable, debug-friendly |
|
|
521
|
+
| `HybridStorageAdapter` | Compose any two StorageProviders | Cache + durable, edge + durable |
|
|
522
|
+
|
|
523
|
+
**Relational / SQL:**
|
|
524
|
+
| Adapter | Backend | Vector search |
|
|
525
|
+
|---|---|---|
|
|
526
|
+
| `PostgresStorageAdapter` | PostgreSQL + pgvector | HNSW native |
|
|
527
|
+
| `SQLiteStorageAdapter` | SQLite (better-sqlite3) | In-memory cosine |
|
|
528
|
+
| `TursoStorageAdapter` | Turso (libsql) | DiskANN native |
|
|
529
|
+
|
|
530
|
+
**Aggregators:**
|
|
531
|
+
| Adapter | Delegates to |
|
|
532
|
+
|---|---|
|
|
533
|
+
| `Mem0StorageAdapter` | Mem0 OSS or Cloud |
|
|
534
|
+
| `ZepStorageAdapter` | Zep Cloud or Community Edition |
|
|
535
|
+
|
|
536
|
+
**Vector databases:**
|
|
537
|
+
| Adapter | Backend |
|
|
538
|
+
|---|---|
|
|
539
|
+
| `QdrantStorageAdapter` | Qdrant |
|
|
540
|
+
| `PineconeStorageAdapter` | Pinecone |
|
|
541
|
+
| `ChromaStorageAdapter` | ChromaDB |
|
|
542
|
+
| `WeaviateStorageAdapter` | Weaviate |
|
|
543
|
+
| `LanceDBStorageAdapter` | LanceDB |
|
|
544
|
+
| `MongoDBStorageAdapter` | MongoDB Atlas Vector Search |
|
|
545
|
+
|
|
546
|
+
**Cache / KV:**
|
|
547
|
+
| Adapter | Backend |
|
|
548
|
+
|---|---|
|
|
549
|
+
| `RedisStorageAdapter` | Redis (ioredis) |
|
|
550
|
+
| `UpstashStorageAdapter` | Upstash Redis + Vector |
|
|
551
|
+
|
|
552
|
+
**Graph:**
|
|
553
|
+
| Adapter | Backend |
|
|
554
|
+
|---|---|
|
|
555
|
+
| `Neo4jStorageAdapter` | Neo4j |
|
|
556
|
+
|
|
557
|
+
**Quick-start per backend:**
|
|
558
|
+
|
|
559
|
+
```ts
|
|
560
|
+
// Postgres
|
|
561
|
+
import { PostgresStorageAdapter } from "@memstack/core";
|
|
562
|
+
const storage = new PostgresStorageAdapter({ connectionString: "postgres://..." });
|
|
563
|
+
|
|
564
|
+
// SQLite
|
|
565
|
+
import Database from "better-sqlite3";
|
|
566
|
+
import { SQLiteStorageAdapter } from "@memstack/core";
|
|
567
|
+
const storage = new SQLiteStorageAdapter({ db: new Database("memory.db") });
|
|
568
|
+
|
|
569
|
+
// Redis
|
|
570
|
+
import Redis from "ioredis";
|
|
571
|
+
import { RedisStorageAdapter } from "@memstack/core";
|
|
572
|
+
const storage = new RedisStorageAdapter({ redis: new Redis() });
|
|
573
|
+
|
|
574
|
+
// Markdown (append-only, human-readable)
|
|
575
|
+
import { MarkdownStorageAdapter } from "@memstack/core";
|
|
576
|
+
const storage = new MarkdownStorageAdapter({ dir: "./memories" });
|
|
577
|
+
|
|
578
|
+
// Hybrid (Redis cache + Postgres durable)
|
|
579
|
+
import { HybridStorageAdapter } from "@memstack/core";
|
|
580
|
+
const storage = new HybridStorageAdapter({
|
|
581
|
+
cache: new RedisStorageAdapter({ redis: new Redis() }),
|
|
582
|
+
durable: new PostgresStorageAdapter({ connectionString: "postgres://..." }),
|
|
583
|
+
});
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Custom storage:**
|
|
587
|
+
```ts
|
|
523
588
|
import type { StorageProvider, MemoryStoreInput } from "@memstack/core";
|
|
524
589
|
|
|
525
|
-
class
|
|
526
|
-
async store(input: MemoryStoreInput): Promise<Memory> { /*
|
|
527
|
-
async get(id: string): Promise<Memory | null> { /*
|
|
528
|
-
async retrieve(query: MemoryRetrieveQuery, embedding?: number[]): Promise<Memory[]> { /*
|
|
529
|
-
async count(filter?: MemoryCountFilter): Promise<number> { /*
|
|
530
|
-
async delete(id: string): Promise<void> { /*
|
|
531
|
-
async deleteMany(ids: string[]): Promise<number> { /*
|
|
532
|
-
async storeBatch(inputs: MemoryStoreInput[]): Promise<Memory[]> { /*
|
|
533
|
-
async initialize(): Promise<void> { /*
|
|
534
|
-
async close(): Promise<void> { /*
|
|
590
|
+
class MyStorage implements StorageProvider {
|
|
591
|
+
async store(input: MemoryStoreInput): Promise<Memory> { /* ... */ }
|
|
592
|
+
async get(id: string): Promise<Memory | null> { /* ... */ }
|
|
593
|
+
async retrieve(query: MemoryRetrieveQuery, embedding?: number[]): Promise<Memory[]> { /* ... */ }
|
|
594
|
+
async count(filter?: MemoryCountFilter): Promise<number> { /* ... */ }
|
|
595
|
+
async delete(id: string): Promise<void> { /* ... */ }
|
|
596
|
+
async deleteMany(ids: string[]): Promise<number> { /* ... */ }
|
|
597
|
+
async storeBatch(inputs: MemoryStoreInput[]): Promise<Memory[]> { /* ... */ }
|
|
598
|
+
async initialize(): Promise<void> { /* ... */ }
|
|
599
|
+
async close(): Promise<void> { /* ... */ }
|
|
535
600
|
}
|
|
536
601
|
```
|
|
537
602
|
|
|
538
|
-
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## Backend Comparison
|
|
606
|
+
|
|
607
|
+
| Backend | Vector search | Touch | Best for |
|
|
608
|
+
|---|---|---|---|
|
|
609
|
+
| InMemory | Cosine in-memory | Yes | Testing, prototyping |
|
|
610
|
+
| Disk (JSON) | Keyword + importance | Yes | Simple local persistence |
|
|
611
|
+
| Markdown | Keyword + importance | No | Human-readable, git-diffable |
|
|
612
|
+
| Postgres | pgvector HNSW | Yes | Production relational |
|
|
613
|
+
| SQLite | Cosine in-memory | Yes | Local dev, solo apps |
|
|
614
|
+
| Turso | DiskANN native | Yes | Edge/serverless |
|
|
615
|
+
| Redis | RediSearch KNN (auto-detect) | Yes | Sub-5ms hot session state |
|
|
616
|
+
| Upstash | Native vector (vector mode) | No | CF Workers, Vercel Edge |
|
|
617
|
+
| Qdrant | ANN native | No | Best filtered search |
|
|
618
|
+
| Pinecone | ANN native | No | Zero-ops managed |
|
|
619
|
+
| Chroma | Native | No | LangChain prototyping |
|
|
620
|
+
| Weaviate | BM25 + vector hybrid | No | Hybrid search |
|
|
621
|
+
| LanceDB | DiskANN native | No | Embedded local vector |
|
|
622
|
+
| MongoDB | Atlas Vector Search | No | Existing MongoDB deployments |
|
|
623
|
+
| Neo4j | Neo4j vector index | No | Relationship-aware agents |
|
|
624
|
+
| Hybrid | Delegates to cache/durable | If durable supports | Read-through cache pattern |
|
|
625
|
+
| Mem0 | Delegates to Mem0 | No | Multi-backend via Mem0 |
|
|
626
|
+
| Zep | Graphiti temporal graph | No | Temporal graph memory |
|
|
539
627
|
|
|
540
628
|
---
|
|
541
629
|
|
|
@@ -549,7 +637,7 @@ import { MemStack } from "@memstack/core";
|
|
|
549
637
|
const ms = new MemStack({
|
|
550
638
|
llm: LLMProvider, // Required — for summarization
|
|
551
639
|
embedding?: EmbeddingProvider, // Optional — for semantic search
|
|
552
|
-
storage?: StorageProvider, // Optional — defaults to
|
|
640
|
+
storage?: StorageProvider, // Optional — defaults to InMemoryStorageAdapter
|
|
553
641
|
defaults?: {
|
|
554
642
|
summarizationThreshold?: number, // Auto-summarize every N interactions. Default: 100
|
|
555
643
|
embedOnStore?: boolean, // Auto-embed on store(). Default: true
|
|
@@ -696,7 +784,7 @@ git clone https://github.com/isiomaC/memstack.git
|
|
|
696
784
|
cd memstack
|
|
697
785
|
pnpm install
|
|
698
786
|
|
|
699
|
-
pnpm test #
|
|
787
|
+
pnpm test # 393 tests, no external services needed
|
|
700
788
|
pnpm test:watch # Watch mode
|
|
701
789
|
pnpm build # CJS + ESM + type declarations
|
|
702
790
|
pnpm check # TypeScript type-check only
|
|
@@ -723,7 +811,7 @@ const ms = new MemStack({
|
|
|
723
811
|
| `CONFIG_ERROR: LLM provider is required` | No LLM adapter | Pass any `LLMProvider` to config |
|
|
724
812
|
| Empty retrieval results | Wrong `actorId` or no memories stored | Check `await ms.memory.count({ actorId })` |
|
|
725
813
|
| Semantic search not working | No embedding adapter or `embedOnStore: false` | Add embedding adapter or use `strategy: "recent"` |
|
|
726
|
-
| High memory usage in production | Using
|
|
814
|
+
| High memory usage in production | Using InMemoryStorageAdapter | Implement `StorageProvider` for Postgres/Redis/etc |
|
|
727
815
|
| Poor summarization quality | Default prompt doesn't match your domain | Use `summarizationPrompt` in `defaults` config |
|
|
728
816
|
|
|
729
817
|
**Inspecting state at runtime:**
|
|
@@ -759,11 +847,11 @@ The `@memstack` scope requires `--access public` on first publish.
|
|
|
759
847
|
|
|
760
848
|
Most needed contributions:
|
|
761
849
|
|
|
762
|
-
- **
|
|
763
|
-
- **LLM adapters**:
|
|
764
|
-
- **Embedding adapters**:
|
|
765
|
-
- **
|
|
766
|
-
- **
|
|
850
|
+
- **Docker Compose** for integration testing
|
|
851
|
+
- **LLM adapters**: Google Gemini (native), Amazon Bedrock, Vertex AI
|
|
852
|
+
- **Embedding adapters**: local inference (transformers.js, ONNX)
|
|
853
|
+
- **Benchmarks**: retrieval quality, latency, cost comparisons
|
|
854
|
+
- **Python port**: `pip install memstack`
|
|
767
855
|
|
|
768
856
|
Open an issue or PR at [github.com/isiomaC/memstack](https://github.com/isiomaC/memstack).
|
|
769
857
|
|