wolbarg 0.5.6 → 0.5.7
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/CHANGELOG.md +22 -0
- package/README.md +73 -322
- package/dist/cli.js +14 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +242 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -6
- package/dist/index.d.ts +36 -6
- package/dist/index.js +242 -108
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ All notable changes to this project are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Postgres `compress()` atomicity:** `insertMemory` no longer joins the coalesce queue inside an ambient transaction (summary + archive now share one TX)
|
|
13
|
+
- **Postgres blob archive:** `archiveMemories` deletes from `memory_embeddings_blob` when pgvector is unavailable (no longer updates missing `memory_embeddings`)
|
|
14
|
+
- **Postgres TX context:** transaction `AsyncLocalStorage` is per-provider instance (no cross-instance leakage)
|
|
15
|
+
- **Compress race:** abort TX when fewer than 2 sources remain active after concurrent compressors
|
|
16
|
+
- **SQLite startup storm:** `open()` now retries the whole connect → WAL switch → migrate sequence on `SQLITE_BUSY` (many processes opening one file no longer fail with "database is locked"). `busy_timeout` is applied before the WAL switch
|
|
17
|
+
- **SQLite savepoint corruption / lost writes under concurrency:** top-level write transactions are serialized on the single connection with an async write mutex, and the ambient-transaction bypass is now gated on an `AsyncLocalStorage` flag instead of a shared depth counter. Fixes intermittent `no such savepoint: wolbarg_sp_N` under many concurrent same-process writers, and materially improves write throughput (e.g. 32-agent same-process inserts ~2k → ~7k ops/s)
|
|
18
|
+
- **CLI `askConfirm`:** used an undefined `defaultValue` (would throw at runtime); now honors the `defaultYes` parameter
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Postgres deadlock/serialization retries (`40P01` / `40001`) with jitter backoff
|
|
23
|
+
- Postgres session timeouts: `statement_timeout`, `lock_timeout`, `idle_in_transaction_session_timeout`
|
|
24
|
+
- Postgres `FOR UPDATE` on `updateMemory` and ordered row locks on archive
|
|
25
|
+
- SQLite `concurrency.lockDeadlineMs` and `concurrency.multiProcess` profile
|
|
26
|
+
- SQLite ambient-TX coalesce bypass (parity with Postgres)
|
|
27
|
+
- Full-jitter SQLITE_BUSY backoff
|
|
28
|
+
- Vector-storage-only benchmark suite: `benchmark/vector-storage-bench.ts`
|
|
29
|
+
|
|
8
30
|
## [0.5.6] — 2026-07-24
|
|
9
31
|
|
|
10
32
|
### Added
|
package/README.md
CHANGED
|
@@ -1,353 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/wolbarg-icon.png" alt="Wolbarg" width="96" height="96" align="absmiddle" />
|
|
3
|
+
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="./assets/wolbarg-name-dark.png" />
|
|
6
|
+
<img src="./assets/wolbarg-name-light.png" alt="wolbarg" height="46" align="absmiddle" />
|
|
7
|
+
</picture>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<b>Modular, provider-agnostic semantic memory for AI agents.</b>
|
|
12
|
+
</p>
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://www.npmjs.com/package/wolbarg"><img alt="npm version" src="https://img.shields.io/npm/v/wolbarg.svg" /></a>
|
|
15
|
+
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-green.svg" /></a>
|
|
16
|
+
<a href="https://nodejs.org"><img alt="Node.js" src="https://img.shields.io/badge/node-%3E%3D22.5-brightgreen.svg" /></a>
|
|
17
|
+
<a href="https://wolbarg.com/docs/quick-start"><img alt="Docs" src="https://img.shields.io/badge/docs-wolbarg.com-black" /></a>
|
|
18
|
+
<a href="https://wolbarg.com/benchmarks"><img alt="Benchmarks" src="https://img.shields.io/badge/benchmarks-wolbarg.com-black" /></a>
|
|
19
|
+
<a href="https://github.com/wolbarg/wolbarg/actions/workflows/sdk-ci.yml"><img alt="SDK CI" src="https://github.com/wolbarg/wolbarg/actions/workflows/sdk-ci.yml/badge.svg?branch=main" /></a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
Wolbarg is **memory infrastructure**, not an agent framework. Agents call `remember()` / `recall()` against durable semantic memory on your disk or Postgres — with optional ingest, graph links, hybrid search, and [Wolbarg Studio](https://wolbarg.com/docs/observability) for observability. You bring any OpenAI-compatible embedding API.
|
|
23
|
+
|
|
24
|
+
> [!TIP]
|
|
25
|
+
> No API key needed to try it — point embeddings at local [Ollama](https://ollama.com) below. For projects, run `npx wolbarg init` and use `createWolbargFromProjectConfig()` — see the [Quick Start](https://wolbarg.com/docs/quick-start).
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
13
28
|
|
|
14
29
|
```bash
|
|
15
30
|
npm install wolbarg
|
|
31
|
+
ollama pull nomic-embed-text
|
|
16
32
|
```
|
|
17
33
|
|
|
18
|
-
### Configure with the CLI (recommended)
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npx wolbarg init
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
You will be prompted (all optional — Enter accepts defaults):
|
|
25
|
-
|
|
26
|
-
1. **Database** — default `.wolbarg/shared-memory/memory.db` (or a Postgres URL)
|
|
27
|
-
2. **Embedding provider** — OpenAI, Ollama, OpenRouter, LM Studio, Gemini, Together, vLLM, or custom
|
|
28
|
-
3. **Base URL** — always shown with that provider’s default (edit or keep)
|
|
29
|
-
4. **Model** — provider default pre-filled
|
|
30
|
-
5. **API key** — written to `.wolbarg/.env` (not into config JSON)
|
|
31
|
-
|
|
32
|
-
Non-interactive:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npx wolbarg init --yes --provider openai --api-key "$OPENAI_API_KEY"
|
|
36
|
-
npx wolbarg init --yes --skip-embedding
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Then in code:
|
|
40
|
-
|
|
41
|
-
```ts
|
|
42
|
-
import { createWolbargFromProjectConfig } from "wolbarg";
|
|
43
|
-
|
|
44
|
-
const ctx = createWolbargFromProjectConfig();
|
|
45
|
-
await ctx.ready();
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Wolbarg is **memory infrastructure**, not an agent framework. Agents call `remember()` / `recall()` (and optionally ingest, compress, subscribe, and link memories in a graph). You bring SQLite or PostgreSQL, any OpenAI-compatible embedding API, and optional peers for PDF/DOCX/OCR/Neo4j.
|
|
49
|
-
|
|
50
|
-
**Current release: [v0.5.6](./CHANGELOG.md)** — `wolbarg init` CLI + project config loader. Still includes official framework adapters (`@wolbarg/openai`, `@wolbarg/langchain`, `@wolbarg/llamaindex`, `@wolbarg/mastra`, `@wolbarg/vercel-ai`), experimental `rememberFromMessages()`, 0.5 graph memory (SQLite + Neo4j), `includeGraph` recall, and [Wolbarg Studio](https://wolbarg.com/docs/observability).
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Why Wolbarg?
|
|
55
|
-
|
|
56
|
-
| Problem | What Wolbarg does |
|
|
57
|
-
| --- | --- |
|
|
58
|
-
| Agents forget between sessions | Durable semantic memory on **your** disk or Postgres |
|
|
59
|
-
| Vendor lock-in | Pluggable embeddings, LLM, rerankers, OCR, vision, storage, graph |
|
|
60
|
-
| Vectors alone are not enough | Hybrid search (semantic + BM25), metadata filters, MMR, optional rerank |
|
|
61
|
-
| Multi-agent writes collide | SQLite `BEGIN IMMEDIATE` + retries; Postgres row-level locking |
|
|
62
|
-
| Duplicate facts pile up | Opt-in write-time dedupe / upsert |
|
|
63
|
-
| Repeated embeds cost money | Transparent embedding cache (default on) |
|
|
64
|
-
| Need structure, not only similarity | Optional **graph** — `linkMemories` / `getRelated` (SQLite ↔ Neo4j) |
|
|
65
|
-
| Hard to debug memory | Telemetry + **Wolbarg Studio** (local, read-only) |
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Features
|
|
70
|
-
|
|
71
|
-
- **Storage** — SQLite (`node:sqlite` + sqlite-vec) or PostgreSQL (+ optional pgvector)
|
|
72
|
-
- **Recall** — semantic, hybrid, metadata filters, MMR, rerank, `explain: true`
|
|
73
|
-
- **Ingest** — text / markdown / PDF / DOCX / images (peers for PDF/DOCX/OCR)
|
|
74
|
-
- **Compress** — optional LLM summarization with archive lineage
|
|
75
|
-
- **`subscribe()`** — real-time change events (SQLite in-process; Postgres LISTEN/NOTIFY)
|
|
76
|
-
- **Concurrency** — multi-writer SQLite hardening (`WOLBARG_STORAGE_LOCKED`)
|
|
77
|
-
- **Embedding cache** — `hash(content) + model`
|
|
78
|
-
- **Dedupe / upsert** — opt-in exact / near / exact-or-near
|
|
79
|
-
- **Graph memory (0.5)** — `sqliteGraph` / `neo4jGraph`, `linkMemories`, `getRelated`, `includeGraph`
|
|
80
|
-
- **Conversation bridge (0.5.2, experimental)** — `rememberFromMessages()` raw or LLM extract
|
|
81
|
-
- **Framework adapter** — official [`@wolbarg/vercel-ai`](../packages/vercel-ai/) middleware (`wrapLanguageModel`)
|
|
82
|
-
- **Checkpoints / export** — file-backed SQLite snapshots (+ graph file when applicable)
|
|
83
|
-
- **Telemetry** — independent event DB; Studio dashboard, Trace Explorer, graph canvas
|
|
84
|
-
|
|
85
|
-
Docs: [Getting started](https://wolbarg.com/docs/getting-started) · [Vercel AI](https://wolbarg.com/docs/integrations/vercel-ai) · [rememberFromMessages](https://wolbarg.com/docs/api/remember-from-messages) · [Graph memory](https://wolbarg.com/docs/graph-memory) · [Studio](https://wolbarg.com/docs/observability)
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Benchmarks (v0.4.0 stress · mock embeddings)
|
|
90
|
-
|
|
91
|
-
Published dual-backend **v4-stress** suite (2026-07-18 · Node v24.13.1 · win32/arm64 · 8 CPUs). Mock embeddings isolate SDK + database cost — not LIVE provider latency.
|
|
92
|
-
|
|
93
|
-
### Headlines
|
|
94
|
-
|
|
95
|
-
| Metric | SQLite | PostgreSQL |
|
|
96
|
-
| --- | --- | --- |
|
|
97
|
-
| Cold `ready()` | **16.18 ms** | **91.39 ms** |
|
|
98
|
-
| Batch remember (200) | **5,795 ops/s** | **2,795 ops/s** |
|
|
99
|
-
| Bulk insert 2k | **7,509 ops/s** | **4,085 ops/s** |
|
|
100
|
-
| Recall p95 @ 2k | **4.83 ms** | **141.5 ms** |
|
|
101
|
-
| 16 writers throughput | **8,660 ops/s** | **3,335 ops/s** |
|
|
102
|
-
| Embedding cache speedup | **1.47×** | **1.18×** |
|
|
103
|
-
| Suite result | 25 pass / 0 fail | 21 pass / 0 fail / 4 skip\* |
|
|
104
|
-
|
|
105
|
-
\*Postgres skips SQLite-only paths (telemetry EventDatabase, file checkpoints, export/import).
|
|
106
|
-
|
|
107
|
-
### SQLite — stress & concurrency
|
|
108
|
-
|
|
109
|
-
| Case | Result |
|
|
110
|
-
| --- | --- |
|
|
111
|
-
| Bulk insert 2k + search | 7,509 insert ops/s · recall p50 **4.12 ms** · p95 **4.83 ms** |
|
|
112
|
-
| 8 writers × 20 ops | **6,084** ops/s · p95 **3.05 ms** · 0 failures |
|
|
113
|
-
| 16 writers × 20 ops | **8,660** ops/s · p95 **2.46 ms** · 0 failures |
|
|
114
|
-
| 32 writers × 20 ops | **6,798** ops/s · p95 **22.94 ms** · 0 failures |
|
|
115
|
-
| Mixed read/write storm | 0 failures |
|
|
116
|
-
|
|
117
|
-
### PostgreSQL — stress & concurrency
|
|
118
|
-
|
|
119
|
-
| Case | Result |
|
|
120
|
-
| --- | --- |
|
|
121
|
-
| Bulk insert 2k + search | 4,085 insert ops/s · recall p50 **23.29 ms** · p95 **141.5 ms** |
|
|
122
|
-
| 8 writers × 20 ops | **2,555** ops/s · p95 **8.51 ms** · 0 failures |
|
|
123
|
-
| 16 writers × 20 ops | **3,335** ops/s · p95 **9.48 ms** · 0 failures |
|
|
124
|
-
| 32 writers × 20 ops | **3,802** ops/s · p95 **14.77 ms** · 0 failures |
|
|
125
|
-
| Mixed read/write storm | 0 failures |
|
|
126
|
-
|
|
127
|
-
**Artifacts:** [SQLite JSON](https://wolbarg.com/benchmarks/version-0.4.0-sqlite-benchmark.json) · [SQLite MD](https://wolbarg.com/benchmarks/version-0.4.0-sqlite-benchmark.md) · [Postgres JSON](https://wolbarg.com/benchmarks/version-0.4.0-postgres-benchmark.json) · [Postgres MD](https://wolbarg.com/benchmarks/version-0.4.0-postgres-benchmark.md) · [Interactive page](https://wolbarg.com/benchmarks) · [Methodology](https://wolbarg.com/docs/benchmarks)
|
|
128
|
-
|
|
129
|
-
Also published: [embedding-cache](https://wolbarg.com/benchmarks/embedding-cache.json) · [multiprocess concurrency](https://wolbarg.com/benchmarks/multiprocess-concurrency.json)
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Installation
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
npm install wolbarg
|
|
137
|
-
# or: pnpm add wolbarg · yarn add wolbarg · bun add wolbarg
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Requires Node.js 22.5+** (built-in `node:sqlite`).
|
|
141
|
-
|
|
142
|
-
### Optional peers
|
|
143
|
-
|
|
144
|
-
Install only what you use:
|
|
145
|
-
|
|
146
|
-
| Peer | Required for |
|
|
147
|
-
| --- | --- |
|
|
148
|
-
| `pg` | PostgreSQL storage |
|
|
149
|
-
| `neo4j-driver` | `neo4jGraph(...)` |
|
|
150
|
-
| `pdf-parse@1.1.4` | PDF ingest |
|
|
151
|
-
| `mammoth` | DOCX ingest |
|
|
152
|
-
| `tesseract.js` | OCR |
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
npm install pg neo4j-driver # production storage + graph
|
|
156
|
-
npm install pdf-parse@1.1.4 mammoth # document ingest
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Peers are **not** bundled. Missing peers fail at use time for that path — not at import. Plain `.txt` / `.md` / `.csv` / `.json` and SQLite graph need no extras.
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Quick start
|
|
164
|
-
|
|
165
34
|
```ts
|
|
166
|
-
import { wolbarg,
|
|
35
|
+
import { wolbarg, sqlite, openaiEmbedding } from "wolbarg";
|
|
167
36
|
|
|
168
37
|
const ctx = wolbarg({
|
|
169
|
-
organization: "
|
|
170
|
-
|
|
38
|
+
organization: "demo",
|
|
39
|
+
storage: sqlite("./memory.db"),
|
|
171
40
|
embedding: openaiEmbedding({
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
llm: openaiLlm({
|
|
176
|
-
apiKey: process.env.OPENAI_API_KEY!,
|
|
177
|
-
model: "gpt-4.1-mini",
|
|
41
|
+
baseUrl: "http://localhost:11434/v1",
|
|
42
|
+
apiKey: "ollama",
|
|
43
|
+
model: "nomic-embed-text",
|
|
178
44
|
}),
|
|
179
|
-
keywordSearch: bm25(),
|
|
180
|
-
concurrency: { maxRetries: 5 },
|
|
181
|
-
embeddingCache: { enabled: true },
|
|
182
|
-
memory: { dedupe: { enabled: true, strategy: "exact-or-near" } },
|
|
183
|
-
telemetry: {
|
|
184
|
-
enabled: true,
|
|
185
|
-
database: { provider: "sqlite", url: "./telemetry.db" },
|
|
186
|
-
level: "debug",
|
|
187
|
-
},
|
|
188
45
|
});
|
|
189
46
|
|
|
190
47
|
await ctx.ready();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
agent: "research",
|
|
48
|
+
await ctx.remember({
|
|
49
|
+
agent: "demo",
|
|
194
50
|
content: { text: "Stripe supports recurring invoices." },
|
|
195
|
-
metadata: { topic: "billing" },
|
|
196
51
|
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const hits = await ctx.recall({
|
|
200
|
-
query: "How do recurring invoices work?",
|
|
201
|
-
topK: 5,
|
|
202
|
-
hybrid: true,
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
ctx.subscribe({ organization: "my-org" }, (e) => {
|
|
206
|
-
console.log(e.event, e.memoryId);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
await ctx.checkpoint("before-compress");
|
|
52
|
+
const hits = await ctx.recall({ query: "How do recurring invoices work?" });
|
|
53
|
+
console.log(hits[0].content.text);
|
|
210
54
|
await ctx.close();
|
|
211
55
|
```
|
|
212
56
|
|
|
213
|
-
|
|
57
|
+
That's the loop: `remember()` writes it, `recall()` finds it by meaning. Swap the embedding config for OpenAI, Gemini, or anything OpenAI-compatible when you're ready for production — nothing else in your code changes.
|
|
214
58
|
|
|
215
|
-
|
|
59
|
+
Requires **Node.js 22.5+**. Optional peers (`pg`, `neo4j-driver`, PDF/DOCX/OCR) — [Installation](https://wolbarg.com/docs/installation).
|
|
216
60
|
|
|
217
|
-
|
|
218
|
-
import { wolbarg, openaiEmbedding, sqliteGraph, neo4jGraph } from "wolbarg";
|
|
61
|
+
## Wolbarg ecosystem
|
|
219
62
|
|
|
220
|
-
|
|
221
|
-
graph: sqliteGraph({ path: "./graph.db" })
|
|
63
|
+
Use the core SDK alone, or plug into the tools around it:
|
|
222
64
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
65
|
+
- **[Docs](https://wolbarg.com/docs/quick-start)** — quick start, configuration, API reference
|
|
66
|
+
- **[@wolbarg/vercel-ai](https://wolbarg.com/docs/integrations/vercel-ai)** — Vercel AI SDK middleware (`wrapLanguageModel`)
|
|
67
|
+
- **[@wolbarg/openai](https://wolbarg.com/docs/integrations/openai)** — OpenAI Agents SDK session
|
|
68
|
+
- **[@wolbarg/langchain](https://wolbarg.com/docs/integrations/langchain)** — LangChain / LangGraph memory
|
|
69
|
+
- **[@wolbarg/llamaindex](https://wolbarg.com/docs/integrations/llamaindex)** — LlamaIndexTS memory block
|
|
70
|
+
- **[@wolbarg/mastra](https://wolbarg.com/docs/integrations/mastra)** — Mastra processor
|
|
71
|
+
- **[Cursor plugin](https://wolbarg.com/docs/connectors/cursor)** — shared memory for Cursor agents
|
|
72
|
+
- **[Wolbarg Studio](https://wolbarg.com/docs/observability)** — local telemetry dashboard, Trace Explorer, graph canvas
|
|
73
|
+
- **[Benchmarks](https://wolbarg.com/benchmarks)** — published SQLite / Postgres stress results
|
|
230
74
|
|
|
231
|
-
|
|
232
|
-
const a = await ctx.remember({
|
|
233
|
-
agent: "support",
|
|
234
|
-
content: { text: "Refunds take 5 business days." },
|
|
235
|
-
});
|
|
236
|
-
const b = await ctx.remember({
|
|
237
|
-
agent: "support",
|
|
238
|
-
content: { text: "Chargebacks escalate to risk." },
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
await ctx.linkMemories(a.id, b.id, "related_to");
|
|
242
|
-
const related = await ctx.getRelated(a.id, { depth: 1 });
|
|
243
|
-
|
|
244
|
-
const withGraph = await ctx.recall({
|
|
245
|
-
query: "refunds",
|
|
246
|
-
includeGraph: true,
|
|
247
|
-
});
|
|
248
|
-
// withGraph[0].related — neighbors from the graph
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Guide: [Graph memory](https://wolbarg.com/docs/graph-memory) · Prefer a [provider-isolated project layout](https://wolbarg.com/docs/installation#project-layout) so backend swaps stay one-file.
|
|
75
|
+
## Why use Wolbarg?
|
|
252
76
|
|
|
253
|
-
|
|
77
|
+
Most agent stacks either bolt memory onto a chat transcript or lock you into a hosted vector database. Wolbarg sits in between: a **shared semantic memory layer** you own, with a small public API and replaceable backends.
|
|
254
78
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
model: "text-embedding-3-small",
|
|
264
|
-
}),
|
|
265
|
-
});
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
**Required:** `organization`, `storage` or `database`, `embedding`.
|
|
269
|
-
**Optional:** `llm`, `keywordSearch`, `reranker`, `ocr`, `vision`, `chunking`, `telemetry`, `concurrency`, `embeddingCache`, `memory.dedupe`, `graph`, `checkpoint` / `checkpointDirectory`.
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
## API surface
|
|
274
|
-
|
|
275
|
-
| Method | Role |
|
|
276
|
-
| --- | --- |
|
|
277
|
-
| `remember` / `rememberBatch` | Embed + store (`RememberResult` includes `action`) |
|
|
278
|
-
| `update` | Edit an existing memory by id |
|
|
279
|
-
| `recall` / `recallBatch` | Semantic / hybrid search; `explain` · `includeGraph` |
|
|
280
|
-
| `ingest` | Documents → chunks → memories |
|
|
281
|
-
| `compress` | LLM summary (requires `llm`) |
|
|
282
|
-
| `linkMemories` / `getRelated` | Graph edges / traversal (requires `graph`) |
|
|
283
|
-
| `subscribe` | Real-time change callbacks |
|
|
284
|
-
| `checkpoint` / `rollback` / `listCheckpoints` / … | SQLite snapshots (+ graph file when SQLite graph) |
|
|
285
|
-
| `export` / `import` | Portable SQLite + manifest |
|
|
286
|
-
| `forget` / `history` / `stats` / `clear` | Lifecycle (forget/clear cascade graph when configured) |
|
|
287
|
-
| `ready` / `close` / `flushTelemetry` | Lifecycle |
|
|
288
|
-
|
|
289
|
-
Full reference: [wolbarg.com/docs/api](https://wolbarg.com/docs/api)
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Wolbarg Studio
|
|
294
|
-
|
|
295
|
-
Local observability dashboard — **not** bundled in the npm package. The SDK writes telemetry; Studio reads it (and can open memory / graph files for the canvas).
|
|
296
|
-
|
|
297
|
-
```bash
|
|
298
|
-
git clone https://github.com/Atharvmunde11/wolbarg-studio
|
|
299
|
-
cd wolbarg-studio
|
|
300
|
-
npm install
|
|
301
|
-
npm run dev # http://localhost:3100
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
Connect telemetry (`./telemetry.db`), optional memory DB, checkpoint directory, and graph backend. Screenshots and setup: [Observability & Studio](https://wolbarg.com/docs/observability).
|
|
79
|
+
- **Agents that forget between sessions** — Durable memory on your SQLite file or Postgres. Facts survive restarts, redeploys, and new agent runs — not trapped in a single conversation window.
|
|
80
|
+
- **No vendor lock-in** — Pluggable embeddings, LLM, rerankers, OCR, vision, storage, and graph. Swap OpenAI ↔ Ollama or SQLite ↔ Postgres by changing a factory, not your agent logic.
|
|
81
|
+
- **Vectors alone are not enough** — Hybrid search (semantic + BM25), metadata filters, MMR, and optional rerank so recall matches how agents actually ask questions.
|
|
82
|
+
- **Multi-agent writes collide** — SQLite hardened with `BEGIN IMMEDIATE` + retries (`WOLBARG_STORAGE_LOCKED` when exhausted); Postgres uses row-level locking. Built for parallel writers, not single-process demos.
|
|
83
|
+
- **Duplicate facts pile up** — Opt-in write-time dedupe / upsert so restated preferences update instead of flooding the store.
|
|
84
|
+
- **Repeated embeds cost money** — Transparent embedding cache keyed by `hash(content) + model` (on by default) cuts provider calls on repeated text.
|
|
85
|
+
- **Need structure, not only similarity** — Optional [graph memory](https://wolbarg.com/docs/graph-memory): `linkMemories` / `getRelated` / `includeGraph` on recall, with the same typed API for local SQLite graph and production Neo4j.
|
|
86
|
+
- **Hard to debug memory** — Independent telemetry DB plus [Wolbarg Studio](https://wolbarg.com/docs/observability) (dashboard, Trace Explorer, graph canvas) so you can see what was remembered and how recall ranked it.
|
|
305
87
|
|
|
306
88
|
---
|
|
307
89
|
|
|
308
|
-
##
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
| Memory upsert | https://wolbarg.com/docs/memory-upsert |
|
|
321
|
-
| What's new in 0.5 | https://wolbarg.com/docs/guides/whats-new |
|
|
322
|
-
| Migration | https://wolbarg.com/docs/migration |
|
|
323
|
-
| Limitations | https://wolbarg.com/docs/guides/limitations |
|
|
324
|
-
| Changelog | [CHANGELOG.md](./CHANGELOG.md) |
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Limitations
|
|
329
|
-
|
|
330
|
-
- **Node 22.5+** required (`node:sqlite`).
|
|
331
|
-
- **Ingest peers** required for PDF / DOCX / OCR paths.
|
|
332
|
-
- **PDF** text-layer via `pdf-parse`; scan PDFs need OCR/vision.
|
|
333
|
-
- **Telemetry** is SQLite-only today (Postgres typed but not implemented).
|
|
334
|
-
- **SQLite `subscribe()`** is in-process only; Postgres uses LISTEN/NOTIFY.
|
|
335
|
-
- **Checkpoints / export** require file-backed SQLite memory (not `:memory:` / not Postgres).
|
|
336
|
-
- **Neo4j** checkpoint / export / import throw `GraphCheckpointNotSupportedError` (refuse, don't skip).
|
|
337
|
-
- **Cypher `query()`** is Neo4j-only; SQLite graph uses typed methods.
|
|
338
|
-
- Not an agent framework, chat UI, or hosted vector SaaS.
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Upgrade
|
|
343
|
-
|
|
344
|
-
```bash
|
|
345
|
-
npm install wolbarg@^0.5.0
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
0.5 is **additive**. Omitting `graph` keeps 0.4 behavior. See [Migration](https://wolbarg.com/docs/migration) and [CHANGELOG](./CHANGELOG.md).
|
|
349
|
-
|
|
350
|
-
---
|
|
90
|
+
## Resources
|
|
91
|
+
|
|
92
|
+
- [Quick start](https://wolbarg.com/docs/quick-start) — remember / recall in under a minute
|
|
93
|
+
- [Installation & project layout](https://wolbarg.com/docs/installation) — peers and recommended folder structure
|
|
94
|
+
- [Configuration](https://wolbarg.com/docs/configuration) — every constructor option
|
|
95
|
+
- [API reference](https://wolbarg.com/docs/api) — public methods and types
|
|
96
|
+
- [Graph memory](https://wolbarg.com/docs/graph-memory) — SQLite ↔ Neo4j graph layer
|
|
97
|
+
- [Examples](https://wolbarg.com/docs/examples) — copy-paste snippets
|
|
98
|
+
- [Migration](https://wolbarg.com/docs/migration) — upgrade guides
|
|
99
|
+
- [Limitations](https://wolbarg.com/docs/guides/limitations) — honest boundaries
|
|
100
|
+
- [Changelog](./CHANGELOG.md) — release history
|
|
101
|
+
- [llms.txt](https://wolbarg.com/llms.txt) — docs index for LLMs
|
|
351
102
|
|
|
352
103
|
## License
|
|
353
104
|
|
package/dist/cli.js
CHANGED
|
@@ -177,36 +177,36 @@ async function withReadline(fn) {
|
|
|
177
177
|
rl.close();
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
async function askText(rl, label,
|
|
181
|
-
const hint =
|
|
180
|
+
async function askText(rl, label, defaultValue) {
|
|
181
|
+
const hint = defaultValue !== void 0 && defaultValue !== "" ? ` [${defaultValue}]` : "";
|
|
182
182
|
const answer = (await rl.question(`${label}${hint}: `)).trim();
|
|
183
|
-
if (answer === "") return
|
|
183
|
+
if (answer === "") return defaultValue ?? "";
|
|
184
184
|
return answer;
|
|
185
185
|
}
|
|
186
|
-
async function askOptionalText(rl, label,
|
|
186
|
+
async function askOptionalText(rl, label, defaultValue) {
|
|
187
187
|
const hintParts = [];
|
|
188
|
-
if (
|
|
189
|
-
hintParts.push(`default: ${
|
|
188
|
+
if (defaultValue !== void 0 && defaultValue !== "") {
|
|
189
|
+
hintParts.push(`default: ${defaultValue}`);
|
|
190
190
|
}
|
|
191
191
|
hintParts.push("Enter to accept", '"-" to skip/clear');
|
|
192
192
|
const answer = (await rl.question(`${label} (${hintParts.join(", ")}): `)).trim();
|
|
193
193
|
if (answer === "-") return void 0;
|
|
194
194
|
if (answer === "") {
|
|
195
|
-
return
|
|
195
|
+
return defaultValue === "" ? void 0 : defaultValue;
|
|
196
196
|
}
|
|
197
197
|
return answer;
|
|
198
198
|
}
|
|
199
|
-
async function askSelect(rl, label, choices,
|
|
199
|
+
async function askSelect(rl, label, choices, defaultValue, allowSkip = true) {
|
|
200
200
|
console.log(`
|
|
201
201
|
${label}`);
|
|
202
202
|
choices.forEach((c, i) => {
|
|
203
|
-
const mark = c.value ===
|
|
203
|
+
const mark = c.value === defaultValue ? " (default)" : "";
|
|
204
204
|
console.log(` ${i + 1}) ${c.label}${mark}`);
|
|
205
205
|
});
|
|
206
206
|
if (allowSkip) {
|
|
207
207
|
console.log(` 0) Skip`);
|
|
208
208
|
}
|
|
209
|
-
const defIndex = choices.findIndex((c) => c.value ===
|
|
209
|
+
const defIndex = choices.findIndex((c) => c.value === defaultValue) + 1 ;
|
|
210
210
|
const raw = (await rl.question(
|
|
211
211
|
`Choose [0-${choices.length}]${defIndex >= 0 ? ` (default ${defIndex})` : ""}: `
|
|
212
212
|
)).trim();
|
|
@@ -216,17 +216,17 @@ ${label}`);
|
|
|
216
216
|
const n = Number(raw);
|
|
217
217
|
if (!Number.isInteger(n) || n < 1 || n > choices.length) {
|
|
218
218
|
console.log("Invalid choice \u2014 skipped.");
|
|
219
|
-
return allowSkip ? void 0 :
|
|
219
|
+
return allowSkip ? void 0 : defaultValue;
|
|
220
220
|
}
|
|
221
221
|
return choices[n - 1].value;
|
|
222
222
|
}
|
|
223
223
|
async function askConfirm(rl, label, defaultYes = true) {
|
|
224
|
-
const hint =
|
|
224
|
+
const hint = defaultYes ? "Y/n" : "y/N";
|
|
225
225
|
const answer = (await rl.question(`${label} (${hint}): `)).trim().toLowerCase();
|
|
226
|
-
if (answer === "") return
|
|
226
|
+
if (answer === "") return defaultYes;
|
|
227
227
|
if (answer === "y" || answer === "yes") return true;
|
|
228
228
|
if (answer === "n" || answer === "no") return false;
|
|
229
|
-
return
|
|
229
|
+
return defaultYes;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
// src/cli/init.ts
|