# Wolbarg — Full Documentation > Complete Markdown export of Wolbarg docs for AI systems. Prefer /llms.txt for a curated index. Generated from 73 documentation pages. --- # Architecture > How Wolbarg subsystems connect — Application, Wolbarg, Storage, Retrieval, Providers, and Database. URL: /docs/architecture ## What is it? [#what-is-it] The structural model of Wolbarg: a thin orchestration layer over storage, retrieval, and swappable providers. ## Why does it exist? [#why-does-it-exist] Understanding the pipeline makes configuration and failure modes predictable. ## How does it work? [#how-does-it-work] ### Application [#application] Your agents, tools, or server. They hold one `Wolbarg` instance per process / organization and call the public API. Keep provider factories in a dedicated folder — see [Project layout](/docs/installation#project-layout). ### Wolbarg facade [#wolbarg-facade] Owns lifecycle (`ready`, `close`), validates options, selects providers, and exposes `remember`, `recall`, `ingest`, `compress`, `forget`, `history`, `stats`, `clear`, `subscribe`, and related helpers. ### Memory operations [#memory-operations] * **remember** — embed + insert + optional keyword index update * **ingest** — parse → enrich → chunk → batch embed → batch insert * **compress** — LLM summarize + optional archive * **forget** — archive / delete by id or filter ### Retrieval pipeline [#retrieval-pipeline] 1. Embed query 2. Vector search (+ optional BM25 when `hybrid: true` and `keywordSearch` is configured) 3. Metadata / agent filters 4. Optional MMR 5. Optional rerank (requires `reranker`; fail-closed) 6. Return `RecallResult[]` ### Storage provider [#storage-provider] Abstracts SQLite vs PostgreSQL: vectors, metadata, history, transactions, migrations. ### Providers [#providers] Network or local adapters for embeddings, LLM, keyword search, rerank, OCR, vision, chunking, compression. Missing hybrid/rerank providers fail closed when those flags are set; other optional features fail cleanly per method. ### Database [#database] Physical persistence — a SQLite file with WAL / FTS5 / sqlite-vec, or PostgreSQL with JSONB / optional pgvector. ## When should you read this? [#when-should-you-read-this] Before choosing backends, tuning retrieval, or debugging hybrid/rerank errors (usually missing `keywordSearch` / `reranker`). ## Related pages [#related-pages] * [Provider Architecture](/docs/providers) * [Installation](/docs/installation) * [Semantic Search](/docs/search) * [SQLite Backend](/docs/storage/sqlite) * [PostgreSQL Backend](/docs/storage/postgresql) * [Production](/docs/guides/production) * [What's New](/docs/guides/whats-new) --- # Benchmarks > Methodology and published results for Wolbarg v0.4.0 — dual-backend v4 stress, embedding cache, multi-process concurrency, and how to reproduce locally. URL: /docs/benchmarks ## What is it? [#what-is-it] How Wolbarg **v0.4.0** measures startup, batch/bulk insert, recall latency, embedding-cache behavior, upsert/dedupe correctness, `subscribe()` delivery, and concurrency on **SQLite and PostgreSQL**. Two embedding modes — **do not mix them**: | Suite | Embeddings | What it measures | | --------------------------- | ----------------------------------- | ---------------------------------------------------------------------------------- | | **Storage / stress** (mock) | Local mock OpenAI-compatible server | SDK + database ceiling (I/O, indexes, concurrency, cache hits with instant embeds) | | **LIVE** | Real providers (OpenAI, etc.) | End-to-end latency including network + provider time | Interactive charts: [/benchmarks](/benchmarks). ### Published 0.4 artifacts [#published-04-artifacts] | Artifact | Contents | | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | [`version-0.4.0-sqlite-benchmark.json`](/benchmarks/version-0.4.0-sqlite-benchmark.json) · [`.md`](/benchmarks/version-0.4.0-sqlite-benchmark.md) | Full v4 stress suite on SQLite | | [`version-0.4.0-postgres-benchmark.json`](/benchmarks/version-0.4.0-postgres-benchmark.json) · [`.md`](/benchmarks/version-0.4.0-postgres-benchmark.md) | Full v4 stress suite on Postgres | | [`embedding-cache.json`](/benchmarks/embedding-cache.json) | Provider-call reduction microbench | | [`multiprocess-concurrency.json`](/benchmarks/multiprocess-concurrency.json) | Multi-process SQLite writers (2–20) | | [`benchmark.json`](/benchmarks/benchmark.json) · [`benchmark.md`](/benchmarks/benchmark.md) | Prior dual-backend quick suite (historical) | Public suite repo: [`wolbarg-benchmarks`](https://github.com/wolbarg/wolbarg-benchmarks). ## Why it exists [#why-it-exists] Vendor graphs without methodology mislead. These docs explain *what was measured* so you can compare fairly and reproduce locally — especially the difference between **mock stress** and **live API spots**, and between **same-process** vs **multi-process** concurrency. ## Headlines — v0.4.0 (2026-07-18) [#headlines--v040-2026-07-18] Environment: Node **v24.13.1** · win32/arm64 · **8 CPUs** · mock embeddings · suite `v4-stress`. | Metric | SQLite | PostgreSQL | | ---------------------- | ----------------------------- | ----------------------------- | | Cold `ready()` | **16.18 ms** | **91.39 ms** | | Warm reopen | 1.87 ms | 59.89 ms | | `rememberBatch` 200 | **5,795 ops/s** | **2,795 ops/s** | | Bulk insert 2k | **7,509 ops/s** | **4,085 ops/s** | | Recall p50 @ 2k | 4.12 ms | 23.29 ms | | Recall p95 @ 2k | **4.83 ms** | **141.5 ms** | | Cache speedup (spot) | **1.47×** | **1.18×** | | Concurrency 8 writers | 6,084 ops/s · p95 3.05 ms | 2,555 ops/s · p95 8.51 ms | | Concurrency 16 writers | **8,660 ops/s** · p95 2.46 ms | **3,335 ops/s** · p95 9.48 ms | | Concurrency 32 writers | 6,798 ops/s · p95 22.94 ms | 3,802 ops/s · p95 14.77 ms | | Mixed read/write storm | 0 failures | 0 failures | | Suite result | 25 pass / 0 fail | 21 pass / 0 fail / 4 skip\* | \*Postgres skips SQLite-only checks (schema meta table probe, SQLite EventDatabase telemetry file, file checkpoints, export/import bundles). ### Embedding cache microbench [#embedding-cache-microbench] | Metric | Value | | ----------------------- | --------------------------------- | | Workload | 100 chunks · 20 unique · 2 passes | | Uncached provider calls | 100 | | Cached provider calls | 20 | | **Call reduction** | **90%** | | Hits / misses | 180 / 20 | Source: [`embedding-cache.json`](/benchmarks/embedding-cache.json) · runner `benchmark/embedding-cache-bench.ts`. ### Multi-process SQLite concurrency [#multi-process-sqlite-concurrency] Shared file, separate OS processes, `BEGIN IMMEDIATE` + busy retry (v0.4): | Writers | Throughput (ops/s) | p50 (ms) | p95 (ms) | p99 (ms) | Error rate | Integrity | | ------- | ------------------ | -------- | -------- | -------- | ---------- | --------- | | 2 | 123 | 0.77 | 3.17 | 9.66 | 0% | OK | | 5 | 221 | 0.78 | 6.09 | 43.94 | 0% | OK | | 10 | 246 | 0.81 | 15.48 | 52.66 | 0% | OK | | 20 | 245 | 0.79 | 77.77 | 319.74 | 0% | OK | Source: [`multiprocess-concurrency.json`](/benchmarks/multiprocess-concurrency.json) · runner `benchmark/multiprocess-levels.ts`. ## Feature coverage in the v4 suite [#feature-coverage-in-the-v4-suite] Beyond raw speed, the 0.4 suite asserts product correctness: | Area | Cases | | --------------------------------- | --------------------------------------------------------------------------------- | | Startup / schema | Cold + warm `ready()`, schema version | | Batch throughput | `rememberBatch` ops/sec | | Embedding cache | Cold vs hot embed latency / speedup | | Dedupe | Exact upsert + metadata merge; dedupe-off still duplicates | | Subscribe | `remember` / `update` / `forget` delivery; throwing subscriber isolaton | | Telemetry / checkpoint / transfer | SQLite paths for observability snapshots | | Edge | Org/agent isolation, unicode metadata, filters, hybrid+compress, forget integrity | | Concurrency | 8 / 16 / 32 writers, mixed R/W storm, concurrent exact-dedupe uniqueness | ## Methodology [#methodology] ### Mock vs LIVE (read this) [#mock-vs-live-read-this] **Primary stress and push-to-failure concurrency use a local mock OpenAI-compatible embedding/LLM server.** Live OpenAI is **not** used for failure ramps because API **rate limits and quota errors would dominate long before SQLite or PostgreSQL contention**, masking true Wolbarg/storage breaking points. A separate **LIVE spot suite** (`npm run benchmark:live`) reports real-network latency for representative paths. It does **not** ramp concurrency to failure. ### Failure criteria (breaking ramps) [#failure-criteria-breaking-ramps] When using breaking / brutal modes, a concurrency level fails when: * `errorRate > 1%`, **or** * `p95 latency > 5s`, **or** * a hard integrity/exception failure (duplicate IDs, crash, etc.) Reports record `lastHealthyLevel` and `breakingLevel` with reason (`error_rate` | `p95_sla` | `exception` | `integrity` | `cap`). ### Storage matrix [#storage-matrix] | Backend | Notes | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | SQLite | Local file + WAL + `BEGIN IMMEDIATE` (0.4) | | PostgreSQL | **Local native Postgres only** (`pgvector`). Docker Compose paths/ports are rejected. Hosted Neon/Supabase/Railway URLs measure network RTT, not Wolbarg. | ```bash cd benchmark npm run postgres:up npx tsx v4-stress.ts # or your package script wrapping it npx tsx embedding-cache-bench.ts npx tsx multiprocess-levels.ts ``` Vector backend caveat: benchmarks assume pgvector/HNSW is enabled for Postgres and sqlite-vec is available for SQLite. When extensions are missing/unloadable, Wolbarg falls back to exact cosine scanning, which can change recall latency substantially. ### Commands (legacy + 0.4 runners) [#commands-legacy--04-runners] | Command | Mode | Notes | | ---------------------------------- | ---- | ---------------------------------- | | `npm run benchmark` | mock | Full dual-backend historical suite | | `npm run benchmark:quick` | mock | Quick scale (100 / 1k) | | `npm run benchmark:brutal` | mock | Failure ramps (up to 4096) | | `npm run benchmark:live` | live | Spot only — **no** failure ramp | | `npx tsx v4-stress.ts` | mock | **0.4** feature + stress suite | | `npx tsx embedding-cache-bench.ts` | mock | Cache call-reduction | | `npx tsx multiprocess-levels.ts` | mock | Multi-process SQLite levels | ### Metrics glossary [#metrics-glossary] | Benchmark | What it means | | --------------------------- | ---------------------------------------------------- | | Startup cold/warm | Time to `ready()` + reopen | | Batch / bulk insert ops/sec | Sustained `remember` / `rememberBatch` throughput | | Recall p50/p95 | Semantic search latency at corpus size | | Cache speedup | Hot vs cold embed path | | Concurrency N writers | Fixed writer count throughput + p95 | | Multiprocess levels | Separate OS processes vs shared SQLite file | | Compression % | Active-set reduction after `compress` (legacy suite) | | DB size / memory | On-disk and heap/RSS (legacy suite) | ### Hardware [#hardware] Always read the environment block in the artifact you cite (Node, CPU, RAM, mode, backends, dims). The 0.4 publish used Node v24.13.1 · win32/arm64 · 8 CPUs. ### Dataset [#dataset] Synthetic memories with fixed templates. Mock dims typically **384**; live typically **1536** (`text-embedding-3-small`). Labels (`100`, `1k`, `2k`) are memory counts. ### Reproducibility [#reproducibility] ```bash cd benchmark npm install cp .env.example .env # DATABASE_URL for postgres; API keys for --live npx tsx v4-stress.ts npx tsx embedding-cache-bench.ts npx tsx multiprocess-levels.ts ``` Prefer recording: date, SDK version (`wolbarg@0.4.0`), Node version, CPU/RAM, mode (`mock`/`live`), backends, and git SHA. ## Interpretation [#interpretation] * **Startup ms** — agents open memory without multi-second cold starts * **Bulk insert vs recall** — know when Postgres/pgvector or sharding strategies matter (Postgres recall p95 in this run is network/engine dominated vs SQLite in-process) * **Same-process vs multi-process** — multi-process SQLite serializes; throughput plateaus while p95 climbs (expected) * **Cache reduction** — measure provider **calls**, not only ms, when arguing cost * **Mock ≠ hosted SaaS** — do not compare mock embed timings to managed GPU indexes * **Storage (mock) ≠ LIVE** — never mix the two suites in one comparison cell * **Competitor accuracy evals ≠ storage ops/sec** — see the policy on [/benchmarks](/benchmarks#competitors) ## Related pages [#related-pages] * [Performance](/docs/performance) * [Concurrency](/docs/concurrency) * [Embedding cache](/docs/embedding-cache) * [Architecture](/docs/architecture) * [SQLite](/docs/storage/sqlite) · [PostgreSQL](/docs/storage/postgresql) * Live page: [/benchmarks](/benchmarks) * [What's New](/docs/guides/whats-new) --- # Chunking > Pluggable chunking strategies for document ingest — fixed, sentence, paragraph, markdown, heading. URL: /docs/chunking ## What is it? [#what-is-it] Replaceable strategies that split extracted document text into embeddable chunks before storage. ## Why does it exist? [#why-does-it-exist] Embedding quality depends on chunk boundaries. Markdown headings need different splits than prose or logs. ## How does it work? [#how-does-it-work] ```ts import { createChunkingStrategy } from "wolbarg"; createChunkingStrategy("fixed") createChunkingStrategy("sentence") // default when no markdown headings createChunkingStrategy("paragraph") createChunkingStrategy("markdown") // auto-inferred when headings present createChunkingStrategy("heading") ``` Per-call options: ```ts await ctx.ingest({ agent: "docs", source: { path: "./guide.md" }, chunking: { strategy: "markdown", chunkSize: 800, overlap: 100, }, }); ``` Set a default on the constructor with `chunking: createChunkingStrategy("markdown")`. ## When should it be used? [#when-should-it-be-used] * `markdown` / `heading` for docs sites and READMEs * `paragraph` for long articles * `sentence` for dense prose * `fixed` for uniform token budgets ## Performance notes [#performance-notes] * Smaller chunks improve precision, increase storage and recall noise * Overlap reduces boundary drops for multi-sentence facts * Batch embedding amortizes network cost during ingest ## Related pages [#related-pages] * [Document Ingestion](/docs/document-ingestion) * [Provider Architecture](/docs/providers) * [Performance](/docs/performance) --- # Compression Pipeline > Summarize and archive memories with an optional LLM via compress(). URL: /docs/compression ## What is it? [#what-is-it] `compress()` uses a configured LLM to summarize selected memories into a compact record and optionally archive the originals. ## Why does it exist? [#why-does-it-exist] Long agent histories explode context and storage. Compression keeps signal while shrinking volume. ## How does it work? [#how-does-it-work] Requires `llm` on the constructor (compile-time + runtime): ```ts import { Wolbarg, sqlite, openaiEmbedding, openaiLlm } from "wolbarg"; const ctx = new Wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ /* … */ }), llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }), }); const result = await ctx.compress({ agent: "research", // filter / ids / strategy options per CompressOptions }); ``` Without `llm`, TypeScript rejects `compress` and runtime throws `ProviderNotConfiguredError`. ## When should it be used? [#when-should-it-be-used] Periodic maintenance jobs, end-of-session summarization, or when agent history exceeds a token budget. ## Performance notes [#performance-notes] * Dominated by LLM latency and input size * Published mock suite shows high reduction ratios — verify on your own texts * Archive carefully if you need reversible history (`history()` still tracks events) ## Related pages [#related-pages] * [Provider Architecture](/docs/providers) * [Example — Compression](/docs/examples/compression) * [API lifecycle](/docs/api/lifecycle) --- # Concurrency > Multi-process SQLite write safety in Wolbarg 0.4 — BEGIN IMMEDIATE, busy_timeout, exponential backoff, WOLBARG_STORAGE_LOCKED, and published multi-writer benchmarks. URL: /docs/concurrency ## What is it? [#what-is-it] Wolbarg **0.4** hardens **multi-process writers** against a single SQLite `memory.db` — the topology most multi-agent setups use (one Node process or worker per agent, one shared file). Before 0.4, SQLite mutating paths used deferred `BEGIN`. Under concurrent writers that commonly produced `SQLITE_BUSY` at commit time after work had already started. 0.4 acquires the write lock **up front** and retries with backoff when the lock is contended. ## Guarantees [#guarantees] | Guarantee | Detail | | --------------------- | --------------------------------------------------------------------------------------- | | **WAL mode** | Enabled by default so readers do not block writers | | **`BEGIN IMMEDIATE`** | Mutating transactions take the write lock before doing work | | **Busy timeout** | SQLite `busy_timeout` pragma honors `lockTimeoutMs` | | **App-level retry** | On `SQLITE_BUSY`, exponential backoff + jitter up to `maxRetries` | | **Stable error** | Exhausted retries throw **`WOLBARG_STORAGE_LOCKED`** with an actionable suggestion | | **In-process mutex** | Same-process concurrent writers are additionally serialized | **PostgreSQL** is unchanged for this feature — it already uses row-level locking and connection pooling. Concurrency config is ignored on the Postgres provider. ## Why it matters for agents [#why-it-matters-for-agents] Multi-agent frameworks often open the **same SQLite file** from several processes: * Parallel tool workers writing preferences / facts * Dev servers + background jobs sharing local memory * CLI agents launched side-by-side against one project DB Without write-lock discipline, you get intermittent failures, orphaned retries, or corrupted mental models when agents silently drop writes. Wolbarg 0.4 makes contention **visible**, **retryable**, and **bounded**. ## Configuration [#configuration] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), concurrency: { maxRetries: 5, // default — app-level retry attempts after SQLITE_BUSY baseBackoffMs: 50, // default — first backoff floor maxBackoffMs: 2000, // default — backoff ceiling lockTimeoutMs: 5000, // SQLite busy_timeout pragma (ms) }, }); ``` Defaults are conservative for a handful of concurrent agent processes. Raise `maxRetries` / `lockTimeoutMs` for bursty writers; switch to Postgres when you need high fan-out multi-tenant write throughput. ### Defaults [#defaults] | Field | Default | Meaning | | --------------- | ------- | ------------------------------------------------- | | `maxRetries` | `5` | How many times Wolbarg retries a busy transaction | | `baseBackoffMs` | `50` | Starting delay before retry (grows exponentially) | | `maxBackoffMs` | `2000` | Cap on backoff delay | | `lockTimeoutMs` | `5000` | Passed to SQLite busy handler / busy\_timeout | ## How it works (internals) [#how-it-works-internals] 1. A mutating path (`remember`, `update`, `forget`, ingest writes, compress archive, …) opens a transaction with **`BEGIN IMMEDIATE`**. 2. If another process holds the write lock, SQLite returns busy within `lockTimeoutMs`. 3. Wolbarg sleeps with exponential backoff + jitter and retries up to `maxRetries`. 4. If all attempts fail, it throws `WOLBARG_STORAGE_LOCKED` — not a generic SQLite string. 5. Same-process callers also queue through an in-process mutex so Node async concurrency does not pile on top of OS-level lock storms. ## Tradeoffs [#tradeoffs] | Upside | Cost | | ------------------------------------------ | -------------------------------------------------------- | | Far fewer surprise `SQLITE_BUSY` failures | p95/p99 latency rises under contention | | Bounded, actionable errors | Very high writer fan-out still serializes on one file | | Works with existing local-first topologies | Postgres remains better for SaaS-scale concurrent writes | Tune for your workload, or move shared multi-tenant agents to the [PostgreSQL](/docs/storage/postgresql) backend. ## Errors [#errors] | Code | When | What to do | | ------------------------ | ---------------------------- | ------------------------------------------------------------------------------------- | | `WOLBARG_STORAGE_LOCKED` | Write-lock retries exhausted | Increase `maxRetries` / `lockTimeoutMs`, reduce writer fan-out, or switch to Postgres | Suggestion text on the error points at the same remediation. ## Benchmarks [#benchmarks] ### Same-process stress (v4 suite) [#same-process-stress-v4-suite] Published dual-backend v0.4 stress numbers ([SQLite](/benchmarks/version-0.4.0-sqlite-benchmark.json) · [Postgres](/benchmarks/version-0.4.0-postgres-benchmark.json)): | Writers | SQLite throughput | SQLite p95 | Postgres throughput | Postgres p95 | | ----------- | ----------------- | ---------- | ------------------- | ------------ | | 8 × 20 ops | 6,084 ops/s | 3.05 ms | 2,555 ops/s | 8.51 ms | | 16 × 20 ops | 8,660 ops/s | 2.46 ms | 3,335 ops/s | 9.48 ms | | 32 × 20 ops | 6,798 ops/s | 22.94 ms | 3,802 ops/s | 14.77 ms | Mock embeddings; Node v24 · win32/arm64 · 8 CPUs · generated 2026-07-18. Absolute ops/sec vary by machine. ### Multi-process levels [#multi-process-levels] True multi-process writers (separate OS processes, shared SQLite file): ```bash npx tsx benchmark/multiprocess-levels.ts ``` Artifact: [`/benchmarks/multiprocess-concurrency.json`](/benchmarks/multiprocess-concurrency.json) — levels **2 / 5 / 10 / 20** writers with throughput, p50/p95/p99, error rate, and integrity checks. At 20 writers this run held **0% error rate** with integrity OK (p95 rises as expected under serialization). Interactive charts: [/benchmarks](/benchmarks). Methodology: [Benchmarks](/docs/benchmarks). ## When to use Postgres instead [#when-to-use-postgres-instead] Choose PostgreSQL when: * Many agents share one cluster across hosts * You need cross-process [real-time events](/docs/realtime-events) (`LISTEN`/`NOTIFY`) * Write fan-out regularly exceeds what a single SQLite file can serialize comfortably ## Related pages [#related-pages] * [Real-time events](/docs/realtime-events) * [SQLite](/docs/storage/sqlite) · [PostgreSQL](/docs/storage/postgresql) * [Benchmarks](/docs/benchmarks) * [What's New](/docs/guides/whats-new) * [Errors](/docs/reference/errors) --- # Configuration > Required and optional constructor options for Wolbarg — organization, storage, embedding, providers, concurrency, embeddingCache, memory.dedupe, and AbortSignal. URL: /docs/configuration ## What is it? [#what-is-it] The constructor API for `new Wolbarg(options)` / `wolbarg(options)`. Three options are required; everything else is optional and enables a specific capability. ## Why does it exist? [#why-does-it-exist] Wolbarg uses constructor dependency injection so you compose only the backends you need — no global config files, no hidden services. Keep factories in a dedicated folder so swaps stay local — see [Project layout](/docs/installation#project-layout). ## Required [#required] | Option | Type | Description | | ---------------------- | ---------------------------------------------------- | ---------------------------------------------------------- | | `organization` | `string` | Namespace isolating memories in a shared database | | `storage` / `database` | `StorageProvider \| StorageConfig \| DatabaseConfig` | `sqlite(...)` / `postgres(...)` or `{ provider, url }` | | `embedding` | `EmbeddingProvider \| EmbeddingConfig` | Any OpenAI-compatible embedding factory or custom provider | ## Optional [#optional] | Option | Enables | | ------------------------------------ | --------------------------------------------------------------------------- | | `llm` | `compress()` (typed at compile time) | | `keywordSearch` | Hybrid recall — **required** when `hybrid: true` (fail-closed) | | `reranker` | `recall({ rerank: true })` — **required** when `rerank: true` (fail-closed) | | `ocr` / `vision` | Image ingest enrichment | | `chunking` | Default ingest chunking strategy | | `compression` | Custom compression provider (overrides llm default) | | `retrieval` | Default hybrid / MMR / over-fetch settings | | `telemetry` | Independent EventDatabase observability | | `checkpoint` / `checkpointDirectory` | SQLite first-party snapshots | | `concurrency` | SQLite multi-writer retries / busy\_timeout | | `embeddingCache` | Transparent embedding reuse (default on) | | `memory.dedupe` | Write-time upsert / near-dup detection (default off) | ## Storage options [#storage-options] ### SQLite [#sqlite] ```ts sqlite("./data/memory.db") // or { provider: "sqlite", url: "./data/memory.db" } ``` Prefer **one file per organization** when using export/checkpoint. See [Production](/docs/guides/production). ### PostgreSQL [#postgresql] ```ts postgres({ connectionString: process.env.DATABASE_URL!, schema: "wolbarg", // optional namespaced deployment maxPoolSize: 20, // default; raise only if the host allows // ssl: false, // opt out of default require for remote (not recommended) }) ``` * Non-loopback hosts without `sslmode` / `ssl` in the URL get **`sslmode=require`** * Loopback (`localhost`, `127.0.0.1`, `::1`) is left unchanged * `schema` creates a dedicated Postgres schema for tables, indexes, and a suffixed NOTIFY channel * Schema names: `^[A-Za-z_][A-Za-z0-9_$]*$`, max 48 characters ## AbortSignal [#abortsignal] Pass `signal?: AbortSignal` (or `AbortSignal.timeout(ms)`) on: * `remember` / `rememberFromMessages` * `recall` * `update` * `compress` * `forget` Cancellation throws `CancellationError`; in-flight embedding HTTP aborts. ```ts await ctx.recall({ query: "billing", signal: AbortSignal.timeout(5_000), }); ``` ## Concurrency [#concurrency] ```ts concurrency: { maxRetries?: number; // default 5 baseBackoffMs?: number; // default 50 maxBackoffMs?: number; // default 2000 lockTimeoutMs?: number; // default 5000 — SQLite busy_timeout multiProcess?: boolean; // longer timeouts when multiple OS processes share one file } ``` Ignored for Postgres. Guide: [Concurrency](/docs/concurrency). ## Embedding cache [#embedding-cache] ```ts embeddingCache: { enabled?: boolean; // default true ttlMs?: number; // optional lazy TTL maxEntries?: number; // optional LRU } ``` Guide: [Embedding cache](/docs/embedding-cache). ## Memory dedupe [#memory-dedupe] ```ts memory: { dedupe: { enabled?: boolean; // default false strategy?: "exact" | "near" | "exact-or-near"; nearThreshold?: number; // default 0.92 nearCandidateLimit?: number; // default 8 }, } ``` Guide: [Memory upsert](/docs/memory-upsert). ## Telemetry [#telemetry] ```ts telemetry: { enabled: true, database: { provider: "sqlite", url: "./telemetry.db" }, captureQueries: false, // default since 0.6.0 } ``` ## Full example [#full-example] ```ts import { wolbarg, sqlite, openaiEmbedding, openaiLlm, bm25, jinaReranker, tesseract, geminiVision, } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }), keywordSearch: bm25(), reranker: jinaReranker({ apiKey: process.env.JINA_API_KEY! }), ocr: tesseract(), vision: geminiVision({ apiKey: process.env.GEMINI_API_KEY! }), retrieval: { overFetchFactor: 4, hybrid: { semanticWeight: 0.7, keywordWeight: 0.3 }, }, concurrency: { maxRetries: 5, lockTimeoutMs: 5000 }, embeddingCache: { enabled: true, maxEntries: 10_000 }, memory: { dedupe: { enabled: true, strategy: "exact-or-near" }, }, }); ``` ## Lazy initialization [#lazy-initialization] Storage opens and embedding dimensions are probed on the first API call, or when you call `await ctx.ready()`. Optional providers are not probed until used. Embedding cache wraps the provider after construction. ## Related pages [#related-pages] * [Provider Architecture](/docs/providers) * [Installation](/docs/installation) * [Production](/docs/guides/production) * [SQLite Backend](/docs/storage/sqlite) * [PostgreSQL Backend](/docs/storage/postgresql) * [Concurrency](/docs/concurrency) * [Embedding cache](/docs/embedding-cache) * [Memory upsert](/docs/memory-upsert) * [API](/docs/api) * [What's New](/docs/guides/whats-new) --- # Document Ingestion > Parse PDF, DOCX, Markdown, and other documents into chunked semantic memories with ingest(). URL: /docs/document-ingestion ## What is it? [#what-is-it] `ingest()` parses a document, chunks it, embeds each chunk, and stores memories in batch. ## Why does it exist? [#why-does-it-exist] Agents need grounded knowledge from handbooks, tickets, and product docs — not only free-form `remember()` calls. ## How does it work? [#how-does-it-work] Pipeline: parse → OCR/vision (if configured) → chunk → embed (batch) → store (batch transaction). ### Sources [#sources] ```ts source: { path: "./file.pdf" } source: { buffer: buf, filename: "file.docx" } source: { text: "# Markdown…" } ``` ### Formats [#formats] | Family | Extensions | Peer required | | ------ | ----------------------------- | ----------------- | | Text | `.txt` `.md` `.csv` `.json` | None | | PDF | `.pdf` | `pdf-parse@1.1.4` | | DOCX | `.docx` | `mammoth` | | Images | `.png` `.jpg` `.jpeg` `.webp` | OCR and/or vision | ```bash npm install pdf-parse@1.1.4 # required for .pdf npm install mammoth # required for .docx ``` Peers are not bundled with `Wolbarg`. Missing peers throw when that format is used. ### Example [#example] ```ts const result = await ctx.ingest({ agent: "docs", source: { path: "./handbook.pdf" }, chunking: { strategy: "paragraph", chunkSize: 1000, overlap: 120 }, metadata: { collection: "handbook" }, }); console.log(result.chunkCount); ``` ## When should it be used? [#when-should-it-be-used] Knowledge bases, onboarding PDFs, and any offline corpus that should become recallable memory. ## Related pages [#related-pages] * [Chunking](/docs/chunking) * [Image Ingestion](/docs/image-ingestion) * [OCR](/docs/ocr) * [Example — PDF Memory](/docs/examples/pdf-memory) * [ingest()](/docs/api/ingest) --- # Embedding cache > Transparent hash(content)+model embedding cache in Wolbarg 0.4 — cut provider cost and latency on repeated text with optional LRU and TTL. URL: /docs/embedding-cache ## What is it? [#what-is-it] Wolbarg **0.4** wraps your embedding provider with a **transparent cache** keyed by: ``` hash(content) + model ``` Identical text for the **same model** skips the provider call. A model change always forces a miss — critical so you never mix vectors from different embedding spaces during recall. ## Why it exists [#why-it-exists] Agent memory workloads repeat text constantly: * Re-ingesting the same docs / chunks * Agents restating the same preference or fact * Batch jobs that overlap corpora across runs * Dedupe near-match paths that re-embed candidates Without a cache, every `remember` / ingest / near-dedupe path pays full provider latency and token cost. The cache is **on by default** in 0.4 (disable if you need every call to hit the network). ## Configuration [#configuration] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), embeddingCache: { enabled: true, // default ttlMs: undefined, // no expiry by default maxEntries: 10_000, // optional LRU bound }, }); ``` Disable entirely: ```ts embeddingCache: { enabled: false } ``` ### Options [#options] | Field | Default | Meaning | | ------------ | ------- | ---------------------------------------- | | `enabled` | `true` | Master switch | | `ttlMs` | unset | Lazy expiry on read when set | | `maxEntries` | unset | LRU eviction via `last_used_at` when set | ## How it works [#how-it-works] 1. Every single and batch `embed` path checks the cache first. 2. **Hits** return stored vectors immediately (no provider round-trip). 3. **Misses** call the provider — batch paths only request uncached items. 4. Results persist in the `embedding_cache` table (schema v3+) on SQLite, or an in-memory fallback when a durable store is unavailable. 5. LRU eviction (if `maxEntries` is set) drops least-recently-used rows by `last_used_at`. 6. TTL (if set) is checked **lazily on read** — expired entries miss and re-embed. ### Cache key discipline [#cache-key-discipline] * Content is hashed after the same normalization the write path uses for identity where applicable. * **Model id is part of the key** — changing `text-embedding-3-small` → `text-embedding-3-large` never reuses old vectors. * Provider API keys / base URLs are **not** part of the key; if you point two incompatible endpoints at the same model string, use distinct model labels or disable the cache. ## Cost & latency impact [#cost--latency-impact] Published embedding-cache microbench ([`embedding-cache.json`](/benchmarks/embedding-cache.json)): | Metric | Value | | ----------------------- | ----------------------------------------------- | | Workload | 100 chunks, 20 unique, 2 passes (mock provider) | | Uncached provider calls | 100 | | Cached provider calls | 20 | | Call reduction | **90%** | | Cache hits / misses | 180 / 20 | v4 stress suite headlines (repeated-text spot): | Backend | Cold avg | Hot avg | Speedup | | -------- | -------- | ------- | --------- | | SQLite | 0.34 ms | 0.23 ms | **1.47×** | | Postgres | 0.77 ms | 0.66 ms | **1.18×** | Reproduce: ```bash npx tsx benchmark/embedding-cache-bench.ts ``` ## Interaction with other 0.4 features [#interaction-with-other-04-features] | Feature | Interaction | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | [Memory upsert](/docs/memory-upsert) | Exact matches skip re-embed; near matches re-embed (cache helps paraphrases that hash differently but share substrings only when text matches exactly) | | [Concurrency](/docs/concurrency) | Cache reads are cheap; provider misses still participate in normal write locking when results are persisted | | Schema | Requires schema with `embedding_cache` table (auto-migrated) | ## Operational notes [#operational-notes] * Cache is **correctness-preserving** for identical content+model; it does not change recall ranking for distinct strings. * Clearing the memory DB does not always imply you want to drop the cache — but a full wipe / new file typically recreates schema cleanly. * For compliance environments that forbid persisting embeddings of PII, disable the cache or scope database lifecycle carefully. ## Related pages [#related-pages] * [Memory upsert](/docs/memory-upsert) * [Configuration](/docs/configuration) * [Benchmarks](/docs/benchmarks) * [What's New](/docs/guides/whats-new) --- # FAQ > Frequently asked questions about Wolbarg installation, providers, storage, and retrieval. URL: /docs/faq ## What is Wolbarg Workspace? [#what-is-wolbarg-workspace] [`@wolbarg/workspace`](https://www.npmjs.com/package/@wolbarg/workspace) is the product layer for coding agents (Cursor, Claude Code, Codex). It keeps shared, reconciled project truth on top of the `wolbarg` SDK. See [Wolbarg Workspace](/docs/workspace). ## What is Wolbarg? [#what-is-wolbarg] A TypeScript SDK for shared semantic memory across AI agents. It is not an agent framework and not a hosted vector database. Start with the [Quick Start](/docs/quick-start), then read [Concepts](/docs/getting-started). ## What Node version do I need? [#what-node-version-do-i-need] Node.js **22.5+** because SQLite uses built-in `node:sqlite`. ## Why does hybrid search throw ValidationError? [#why-does-hybrid-search-throw-validationerror] You likely set `hybrid: true` without `keywordSearch: bm25()`. Since **0.6.0**, hybrid is fail-closed — there is no silent semantic-only fallback. See [Hybrid Search](/docs/hybrid-search). ## Do I need an LLM to use Wolbarg? [#do-i-need-an-llm-to-use-wolbarg] No. LLM is required only for `compress()` (and for experimental `rememberFromMessages({ mode: "extract" })`). Remember/recall need storage + embedding. ## Why does PDF ingest fail? [#why-does-pdf-ingest-fail] Install `pdf-parse@1.1.4` in your app. Scan-only PDFs without a text layer need OCR/vision on images. See [Document Ingestion](/docs/document-ingestion) and [Limitations](/docs/guides/limitations). ## Can I use PostgreSQL? [#can-i-use-postgresql] Yes — `npm install pg` then `storage: postgres({ connectionString })`. Remote hosts default to `sslmode=require`. Optional `schema` namespacing and default `maxPoolSize: 20`. See [PostgreSQL Backend](/docs/storage/postgresql) and [Production](/docs/guides/production). ## Where did graph memory go? [#where-did-graph-memory-go] Removed in **0.6.0**. Use [metadata](/docs/metadata-filtering) or an external store. See [Graph memory (removed)](/docs/graph-memory) and [Migration](/docs/migration). ## How do multiple agents share memory? [#how-do-multiple-agents-share-memory] One `Wolbarg` instance, different `agent` ids on remember/recall filters. See [Multi-Agent Memory](/docs/guides/shared-memory). ## Where is the full docs dump for AI tools? [#where-is-the-full-docs-dump-for-ai-tools] * [/llms.txt](/llms.txt) — curated index * [/llms-full.txt](/llms-full.txt) — full Markdown export * Append `.md` to any docs URL for that page as Markdown ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [Concepts](/docs/getting-started) * [Installation](/docs/installation) * [Limitations](/docs/guides/limitations) * [What's New](/docs/guides/whats-new) --- # Concepts > What Wolbarg is, why it exists, and the provider philosophy behind its architecture. URL: /docs/getting-started Ready to code? Start with the [Quick Start](/docs/quick-start) — remember/recall in under a minute. ## What is Wolbarg? [#what-is-wolbarg] Wolbarg is a TypeScript SDK that gives AI agents a shared, persistent semantic memory. Store facts with `remember()`, retrieve them with `recall()`, optionally ingest documents, compress memories with an LLM, and react to changes with `subscribe()`. Everything is built around **replaceable providers**: storage, embeddings, keyword search, rerankers, OCR, vision, chunking, and telemetry. The public API stays small; you swap backends by changing factory calls, not agent logic. ## Why does it exist? [#why-does-it-exist] Most agent stacks either bolt memory onto a chat transcript or depend on a hosted vector database. Wolbarg sits in between: a **shared semantic memory layer for multi-agent systems**, with explicit providers, durable writes, and hybrid retrieval — plus [connectors](/connector) for Cursor and AI SDKs. ## Core philosophy [#core-philosophy] * **Everything is configurable** — swap any provider. * **Nothing is required unless necessary** — only `organization`, `storage`, and `embedding`. * **Optional features fail cleanly** — `hybrid: true` / `rerank: true` without their providers throw `ValidationError` (fail-closed since 0.6.0); `compress` without `llm` is a `ProviderNotConfiguredError`. * **Isolate providers in your app** — keep factories in a dedicated folder so switching SQLite ↔ Postgres is a one-file change. See [Project layout](/docs/installation#project-layout). ## Capabilities [#capabilities] * Constructor DI + factories — SQLite / PostgreSQL storage, hybrid recall, metadata filters, MMR, rerankers, document `ingest`, chunking, optional LLM compression * **Telemetry** — independent event database + trace IDs · [Observability](/docs/observability) * **Wolbarg Studio** — local read-only observability dashboard · [Observability & Studio](/docs/observability) * **Checkpoints** — `checkpoint` / `rollback` / `listCheckpoints` (SQLite file-backed, single-org) * **Import / export** — portable SQLite memory bundles (single-org) * **Batch APIs** — `rememberBatch` / `recallBatch` * **Recall explain** — ranking diagnostics + timings * **`subscribe()`** — real-time memory change events · [Real-time events](/docs/realtime-events) * **AbortSignal** — cancellation on remember / recall / update / compress / forget * **Concurrency hardening** — multi-writer SQLite retries · [Concurrency](/docs/concurrency) * **Embedding cache** — transparent reuse · [Embedding cache](/docs/embedding-cache) * **Memory upsert / dedupe** — update-instead-of-insert · [Memory upsert](/docs/memory-upsert) ## What it is not [#what-it-is-not] * Not an agent / orchestration framework * Not a hosted vector database SaaS * Not a chat UI (Studio is a separate local observability app) * Not a graph database — graph memory APIs were [removed in 0.6.0](/docs/graph-memory) For out-of-the-box shared project truth in Cursor / Claude Code / Codex, see [Wolbarg Workspace](/docs/workspace) (`@wolbarg/workspace`). ## When should you use it? [#when-should-you-use-it] Use Wolbarg when multiple agents (or one long-running agent) need durable, searchable memory with clear backends and no infrastructure lock-in. ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [What's New](/docs/guides/whats-new) * [Installation](/docs/installation) * [Connectors](/connector) * [Observability & Studio](/docs/observability) * [Architecture](/docs/architecture) * [Limitations](/docs/guides/limitations) * [Migration](/docs/migration) --- # Graph memory > Graph memory was removed in Wolbarg 0.6.0. Use metadata or an external store for relationships. URL: /docs/graph-memory ## Removed in 0.6.0 [#removed-in-060] Graph memory is **no longer part of the Wolbarg core SDK**. The following APIs and factories were removed: * `sqliteGraph` / `neo4jGraph` * `linkMemories` / `getRelated` * `recall({ includeGraph: true })` * `neo4j-driver` peer dependency This page is kept so existing links and bookmarks resolve. Full release notes: [What's New](/docs/guides/whats-new) · [Migration](/docs/migration). ## What to use instead [#what-to-use-instead] | Need | Approach | | --------------------- | ------------------------------------------------------------------------------------------ | | Tag related facts | Store relation ids / keys in [metadata](/docs/metadata-filtering) and filter with `meta.*` | | Explicit graph walks | Use an external graph database or your own edge tables outside Wolbarg | | Similarity + keywords | [Semantic search](/docs/search) + [hybrid BM25](/docs/hybrid-search) | ```ts await ctx.remember({ agent: "support", content: { text: "Refund SLA is 5 business days." }, metadata: { topic: "billing", relatedTo: ["pref-email"] }, }); const hits = await ctx.recall({ query: "refund timeline", filter: { metadata: meta.eq("topic", "billing") }, }); ``` ## Upgrade checklist [#upgrade-checklist] 1. Remove `graph`, `sqliteGraph`, `neo4jGraph`, `linkMemories`, `getRelated`, and `includeGraph` from your code 2. Uninstall `neo4j-driver` if you only used it for Wolbarg 3. Install `wolbarg@0.6.0` 4. Re-express relationships with metadata or an external store ## Related pages [#related-pages] * [What's New](/docs/guides/whats-new) * [Migration](/docs/migration) * [Metadata Filtering](/docs/metadata-filtering) * [Limitations](/docs/guides/limitations) * [API Overview](/docs/api) --- # Hybrid Search > Combine semantic vectors with BM25 keyword scores for more robust recall. Fail-closed since 0.6.0. URL: /docs/hybrid-search ## What is it? [#what-is-it] Hybrid search fuses semantic similarity with BM25 keyword scores so recall works for both meaning and exact tokens (IDs, product names, error codes). ## Why does it exist? [#why-does-it-exist] Pure vector search can miss rare tokens. Pure keyword search misses paraphrase. Fusion covers both modes. ## How does it work? [#how-does-it-work] ### Setup [#setup] ```ts import { bm25 } from "wolbarg"; new Wolbarg({ /* organization, storage, embedding */ keywordSearch: bm25(), }); ``` ### Usage [#usage] ```ts await ctx.recall({ query: "quick brown fox", hybrid: true, // or hybrid: { semanticWeight: 0.7, keywordWeight: 0.3 }, }); ``` Scores are normalized then fused. Tune weights for keyword-heavy vs semantic-heavy corpora. ### Fail-closed (0.6.0+) [#fail-closed-060] If `hybrid: true` is set without a configured `keywordSearch` provider, Wolbarg throws **`ValidationError`**. There is no quiet semantic-only fallback. Keyword-channel failures also throw — they do not degrade to semantic-only. Configure `keywordSearch: bm25()` (or a custom provider) before enabling hybrid. ## When should it be used? [#when-should-it-be-used] Enable hybrid when queries contain proprietary names, codes, or short literal strings mixed with natural language. ## Performance notes [#performance-notes] * Requires FTS indexing on SQLite (schema v2) or equivalent keyword path * Keyword index updates happen with remember/ingest/forget * Slightly higher recall-time cost than semantic-only ## Related pages [#related-pages] * [Semantic Search](/docs/search) * [Rerankers](/docs/rerankers) * [Example — Hybrid Search](/docs/examples/hybrid-search) * [Provider Architecture](/docs/providers) * [What's New](/docs/guides/whats-new) --- # Image Ingestion > Store image-derived text as semantic memory using OCR and vision providers. URL: /docs/image-ingestion ## What is it? [#what-is-it] Ingesting `.png`, `.jpg`, `.jpeg`, and `.webp` files so visual content becomes searchable text memories. ## Why does it exist? [#why-does-it-exist] Screenshots, UI captures, and slide photos often carry the facts agents need. Pure image bytes are not useful for text recall without extraction. ## How does it work? [#how-does-it-work] Configure `ocr` and/or `vision`, then call `ingest` with an image path or buffer. ```ts import { tesseract, geminiVision } from "wolbarg"; const ctx = new Wolbarg({ /* organization, storage, embedding */ ocr: tesseract(), vision: geminiVision({ apiKey: process.env.GEMINI_API_KEY! }), }); await ctx.ingest({ agent: "vision", source: { path: "./screenshot.png" }, metadata: { kind: "ui-capture" }, }); ``` OCR text, captions, descriptions, and entities are concatenated before chunking. If neither provider is configured, image ingest errors with a clear message unless other text is available. ## When should it be used? [#when-should-it-be-used] Product screenshots, whiteboard photos, receipts, and charts where text/visual captions matter. ## Related pages [#related-pages] * [OCR](/docs/ocr) * [Vision Models](/docs/vision) * [Example — Image Memory](/docs/examples/image-memory) * [Document Ingestion](/docs/document-ingestion) --- # Installation > Install Wolbarg, optional peers, and a clean project layout that keeps providers swappable without refactoring agent code. URL: /docs/installation ## What is it? [#what-is-it] The install guide for the `wolbarg` npm package, optional peer dependencies, and a **recommended project layout** so storage and embedding factories live in one place — swap backends without rewriting your agents. ## Requirements [#requirements] * Node.js **22.5+** (uses built-in `node:sqlite`) * An OpenAI-compatible embedding endpoint (required for remember/recall) * An LLM endpoint only if you use `compress()` ## Install [#install] ```bash npm install wolbarg ``` ```bash pnpm add wolbarg yarn add wolbarg bun add wolbarg ``` Current release: **0.6.0** — [What's New](/docs/guides/whats-new). Looking for coding-agent project memory instead of the SDK API? Install [Wolbarg Workspace](/docs/workspace) (`@wolbarg/workspace`). ## Optional peers [#optional-peers] Install only what you need: ```bash npm install pg # PostgreSQL storage npm install pdf-parse@1.1.4 # PDF ingest (text-layer PDFs) npm install mammoth # DOCX ingest npm install tesseract.js # OCR on images ``` If you call `ingest()` on PDF or DOCX files, or use PostgreSQL storage, you **must** install the matching peer in the same app: * `pdf-parse` for `.pdf` * `mammoth` for `.docx` * `tesseract.js` and/or a `vision` provider for images / scan-only PDFs * `pg` for PostgreSQL storage Plain text formats (`.txt`, `.md`, `.csv`, `.json`) need no extra packages. Missing peers throw when that path is used — not at import time. Prefer pinning `pdf-parse@1.1.4` for the function API Wolbarg tests against. ## Project layout [#project-layout] Keep **provider wiring** out of agent / business code. When you switch SQLite → Postgres, you change files under `providers/` only — not every `remember` / `recall` call site. ```text src/ providers/ storage.ts # sqlite() | postgres() embedding.ts # openaiEmbedding() | ollamaEmbedding() | … llm.ts # optional — openaiLlm() | … telemetry.ts # optional — sqlite telemetry config index.ts # re-exports + env-based selection memory/ client.ts # wolbarg({ …providers }) — single construction site agents/ support.ts # uses client — never imports sqlite/postgres directly research.ts index.ts ``` ### Example: `providers/storage.ts` [#example-providersstoragets] ```ts import { sqlite, postgres } from "wolbarg"; export function createStorage() { if (process.env.MEMORY_BACKEND === "postgres") { return postgres({ connectionString: process.env.DATABASE_URL!, schema: process.env.WOLBARG_SCHEMA ?? "wolbarg", }); } return sqlite(process.env.MEMORY_PATH ?? "./data/memory.db"); } ``` ### Example: `memory/client.ts` [#example-memoryclientts] ```ts import { wolbarg, bm25 } from "wolbarg"; import { createStorage } from "../providers/storage.js"; import { createEmbedding } from "../providers/embedding.js"; export const memory = wolbarg({ organization: process.env.WOLBARG_ORG ?? "my-org", storage: createStorage(), embedding: createEmbedding(), keywordSearch: bm25(), // required when using hybrid: true }); ``` Agents import `memory` and call `remember` / `recall` — they never branch on database type. Full option table: [Configuration](/docs/configuration). ## Verify [#verify] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "demo", storage: sqlite(":memory:"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await ctx.ready(); console.log(ctx.isInitialized); // true await ctx.close(); ``` ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [Configuration](/docs/configuration) * [Observability & Studio](/docs/observability) * [Document Ingestion](/docs/document-ingestion) * [SQLite Backend](/docs/storage/sqlite) * [PostgreSQL Backend](/docs/storage/postgresql) * [Limitations](/docs/guides/limitations) * [What's New](/docs/guides/whats-new) --- # Memory upsert & deduplication > Opt-in write-time exact and near-duplicate detection in Wolbarg 0.4 — update existing facts instead of inserting duplicates, with RememberResult.action and update(). URL: /docs/memory-upsert ## What is it? [#what-is-it] Wolbarg **0.4** adds **opt-in write-time deduplication**. When enabled, `remember()` can **update** an existing active memory instead of always inserting a new UUID. Without dedupe, every `remember()` inserts a new row. Agents that restate facts create duplicates, inflate `compress()` cost, and noise recall — even when MMR hides near-duplicates at search time. **Use dedupe for facts, preferences, and durable state. Keep append-only (default) for episodic logs and time-series observations.** ## Compatibility [#compatibility] | Behavior | Default | | ------------------- | ------------------------------------------------------------------- | | Dedupe | **Off** (0.3-compatible append-only) | | `remember()` return | `RememberResult` = `MemoryRecord` + `action` (additive field) | | History | New event type `"updated"` when an upsert replaces content/metadata | | Schema | `content_hash` column + unique active hash index (auto-migrated) | Upgrading from 0.3.x requires **no code changes** unless you opt into dedupe or read `action`. ## Enabling [#enabling] ### Constructor [#constructor] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), memory: { dedupe: { enabled: true, strategy: "exact-or-near", // default when enabled nearThreshold: 0.92, // cosine similarity nearCandidateLimit: 8, }, }, }); const result = await ctx.remember({ agent: "assistant", content: { text: "User prefers dark mode" }, metadata: { source: "chat" }, }); // result.action === "created" | "updated" ``` ### Per-call override [#per-call-override] ```ts // Force on for one write await ctx.remember({ agent: "assistant", content: { text: "User prefers dark mode" }, dedupe: true, }); // Exact-only for one write await ctx.remember({ agent: "assistant", content: { text: "Timezone is IST" }, dedupe: { strategy: "exact" }, }); // Force off even if constructor enabled await ctx.remember({ agent: "logger", content: { text: "Heartbeat at T+60s" }, dedupe: false, }); ``` ### Config reference [#config-reference] | Field | Default | Meaning | | -------------------- | ------------------------------ | ------------------------------------------ | | `enabled` | `false` | Master switch | | `strategy` | `"exact-or-near"` when enabled | `"exact"` \| `"near"` \| `"exact-or-near"` | | `nearThreshold` | `0.92` | Minimum cosine similarity for near match | | `nearCandidateLimit` | `8` | Max ANN candidates considered for near-dup | ## Detection pipeline [#detection-pipeline] 1. **Exact** — normalize content (`NFC`, trim, collapse whitespace; **case preserved**), hash, look up unique active hash for the same `organization` + `agent`. 2. **Near** (when strategy includes near) — embed the new text, compare cosine similarity against up to `nearCandidateLimit` active memories for that agent; accept if ≥ `nearThreshold`. 3. **No match** — insert a new row (`action: "created"`). ### Match scope [#match-scope] | Included | Excluded | | ---------------------------- | -------------------------------- | | Same `organization` | Other orgs | | Same `agent` | Other agents | | **Non-archived** active rows | Archived rows after `compress()` | Archived memories are **never** match targets — compress must stay free to summarize history without resurrecting dead hashes as “live” facts. ## Update behavior [#update-behavior] | Case | Behavior | | ----------- | ------------------------------------------------------------------------ | | Exact match | Merge metadata (shallow), bump `updated_at`, **keep** existing embedding | | Near match | Replace content, **re-embed**, merge metadata | | No match | Insert new row | Additional side effects: * History records an `"updated"` event on upsert. * [`subscribe()`](/docs/realtime-events) emits `"update"` (not `"remember"`). * Concurrent exact-dedupe races stay unique (v4 suite: 1 id, 11 updates under contention). ## RememberResult [#rememberresult] ```ts interface RememberResult extends MemoryRecord { action: "created" | "updated"; } ``` `rememberBatch()` returns `RememberResult[]` — each item carries its own action. ## Explicit update() [#explicit-update] When you already know the memory id: ```ts const result = await ctx.update({ id: memoryId, content: { text: "Revised fact" }, metadata: { edited: true }, }); // result.action === "updated" ``` Use `update()` for user edits and admin tools; use dedupe for automatic fact convergence on write. ## When to leave dedupe off [#when-to-leave-dedupe-off] * Audit / event logs where each utterance is a distinct fact * Time-series observations (“temp was 72°F at 10:01”) * Workflows that must never merge paraphrases * Debug sessions where you want append-only archaeology ## Worked example — preference convergence [#worked-example--preference-convergence] ```ts const a = await ctx.remember({ agent: "assistant", content: { text: "User prefers dark mode" }, metadata: { source: "onboarding" }, dedupe: true, }); // a.action === "created" const b = await ctx.remember({ agent: "assistant", content: { text: "User prefers dark mode" }, metadata: { source: "settings", confirmed: true }, dedupe: true, }); // b.action === "updated" // b.id === a.id // metadata merged: { source: "settings", confirmed: true } ``` ## Related pages [#related-pages] * [remember()](/docs/api/remember) * [update()](/docs/api/update) * [Real-time events](/docs/realtime-events) * [Embedding cache](/docs/embedding-cache) * [Compression](/docs/compression) * [What's New](/docs/guides/whats-new) --- # Metadata Filtering > Filter recall with meta.eq, contains, comparisons, and AND/OR/NOT boolean trees. URL: /docs/metadata-filtering ## What is it? [#what-is-it] Structured filters on memory metadata (and agent scope) applied during `recall()`, `forget()`, and related APIs. ## Why does it exist? [#why-does-it-exist] Organizations share one store. Filters keep retrieval scoped to a topic, tenant facet, priority, or agent without re-embedding. ## How does it work? [#how-does-it-work] ```ts import { meta } from "wolbarg"; meta.eq("topic", "billing") meta.contains("title", "invoice") meta.gt("score", 10) meta.gte("score", 10) meta.lt("score", 100) meta.lte("score", 100) meta.between("year", 2020, 2026) meta.and(filterA, filterB) meta.or(filterA, filterB) meta.not(filterA) ``` ```ts await ctx.recall({ query: "pricing", filter: { agent: "sales", metadata: meta.and( meta.eq("region", "eu"), meta.gte("priority", 2), ), }, }); ``` Opaque metadata is never validated by the SDK — store any JSON-serializable object and filter on known fields. ## When should it be used? [#when-should-it-be-used] Always attach meaningful metadata at `remember` / `ingest` time. Prefer filters before raising `topK`. ## Related pages [#related-pages] * [Semantic Search](/docs/search) * [Example — Metadata Filtering](/docs/examples/metadata-filtering) * [Best Practices](/docs/guides/best-practices) --- # Migration > Upgrade Wolbarg — 0.5 → 0.6 production hardening, earlier additive upgrades, and AgentOrc → Wolbarg rebrand notes. URL: /docs/migration ## What is it? [#what-is-it] Guides for moving between Wolbarg releases. Start with **0.5 → 0.6** if you are current; older sections cover earlier upgrades. ## 0.5 → 0.6 (breaking) [#05--06-breaking] ```bash npm install wolbarg@0.6.0 # remove if you only used it for Wolbarg graph npm uninstall neo4j-driver ``` | Area | Action | | ---------------- | ----------------------------------------------------------------------------------------- | | Graph APIs | Remove `graph`, `sqliteGraph`, `neo4jGraph`, `linkMemories`, `getRelated`, `includeGraph` | | Hybrid / rerank | Ensure `keywordSearch` / `reranker` are configured when flags are set — **fail-closed** | | Rerank errors | Catch `RerankError` instead of assuming soft / identity fallback | | Postgres remote | Expect TLS (`sslmode=require`) unless you override with `ssl` | | Pool size | Raise `maxPoolSize` if you relied on the old default of **64** (now **20**) | | Telemetry | Set `captureQueries: true` if you need query strings persisted | | Multi-org SQLite | One file per organization for export / checkpoint / import / rollback | | AbortSignal | Optional on remember / recall / update / compress / forget | From 0.5.x **without** graph: ```bash npm install wolbarg@0.6.0 ``` Most `remember` / `recall` call sites need no changes. Review hybrid, rerank, and Postgres SSL settings. Deep dive: [What's New](/docs/guides/whats-new) · [Production](/docs/guides/production) · [Graph memory (removed)](/docs/graph-memory). ## 0.4 → 0.5 (historical) [#04--05-historical] ```bash npm install wolbarg@^0.5.0 ``` **0.5** introduced optional graph memory. That layer was **removed again in 0.6.0** — do not add new graph call sites. If you are jumping from 0.4 directly to 0.6, skip graph entirely and follow the **0.5 → 0.6** table above for fail-closed hybrid/rerank and Postgres defaults. | Feature (0.5) | Status in 0.6 | | ---------------------------------------------- | ----------------------------- | | Graph memory | **Removed** | | `linkMemories` / `getRelated` / `includeGraph` | **Removed** | | Framework adapters (`@wolbarg/*`) | Separate packages — unchanged | ## 0.3 → 0.4 (additive) [#03--04-additive] ```bash npm install wolbarg@^0.4.0 ``` **No required code changes.** Schema migrates automatically on open. | Feature | Default | Action needed | | -------------------------- | ----------------- | ------------------------------------------------------------- | | Embedding cache | **On** | Disable with `embeddingCache: { enabled: false }` if unwanted | | Memory dedupe / upsert | **Off** | Opt in via `memory.dedupe` | | `concurrency` tuning | Sensible defaults | Optional | | `subscribe()` / `update()` | — | Opt in when needed | | `RememberResult.action` | Always present | Ignore safely if unused | ### Behavior notes [#behavior-notes] * `remember()` / `rememberBatch()` still return a full `MemoryRecord`; they additionally include `action: "created" | "updated"`. * SQLite writers now use `BEGIN IMMEDIATE` — safer under multi-process contention; may change latency shape under lock storms (see [Concurrency](/docs/concurrency)). * New history event `"updated"` appears when upserts run. Guides: [Concurrency](/docs/concurrency) · [Real-time events](/docs/realtime-events) · [Embedding cache](/docs/embedding-cache) · [Memory upsert](/docs/memory-upsert). ## 0.3 — AgentOrc → Wolbarg [#03--agentorc--wolbarg] ```bash npm uninstall agentorc npm install wolbarg ``` ```ts // before import { AgentOrc } from "agentorc"; const ctx = new AgentOrc({ /* … */ }); // after import { Wolbarg, wolbarg } from "wolbarg"; const ctx = wolbarg({ /* … */ }); ``` * Class / options / error: `AgentOrc*` → `Wolbarg*` * Site: [wolbarg.com](https://wolbarg.com) * GitHub: [wolbarg/wolbarg](https://github.com/wolbarg/wolbarg) * Internal meta table: `agentorc_meta` → `wolbarg_meta` (recreate DBs or migrate) ## 0.1 → 0.2 breaking changes [#01--02-breaking-changes] * `llm` is no longer required to operate the SDK * Constructor instances without `llm` do not type `compress` * `stats().llmModel` may be `null` * Package version is **0.2.x+** ## API mapping (0.1 → 0.2) [#api-mapping-01--02] ```ts // 0.1 const ctx = new Wolbarg(); await ctx.init({ organization, database, embedding, llm }); // 0.2+ (recommended) import { wolbarg, sqlite, openaiEmbedding, openaiLlm } from "wolbarg"; const ctx = wolbarg({ organization, storage: sqlite("./memory.db"), embedding: openaiEmbedding({ /* … */ }), llm: openaiLlm({ /* … */ }), // optional }); // init() still works for compatibility ``` ## Schema [#schema] | Version | Notes | | ------- | ------------------------------------------------------------------------------------------------------- | | v2 | FTS5 hybrid | | v3+ | `content_hash`, `embedding_cache`, history `"updated"` | | v4 | drop unused global `created_at` index; strip archived vectors from ANN; add agent-active covering index | SQLite auto-migrates on open. Embedding dimension changes still require a fresh DB. Method names (`remember` / `recall` / …) are unchanged. New optional fields are additive unless called out in the 0.5 → 0.6 section. ## Related pages [#related-pages] * [What's New](/docs/guides/whats-new) * [Production](/docs/guides/production) * [Graph memory](/docs/graph-memory) * [Observability](/docs/observability) * [init() Compatibility](/docs/reference/init-compat) * [Limitations](/docs/guides/limitations) * [Concurrency](/docs/concurrency) * [Memory upsert](/docs/memory-upsert) --- # Observability & Studio > Enable Wolbarg telemetry and explore it in Wolbarg Studio — live dashboard, Trace Explorer waterfalls, and ops surfaces. URL: /docs/observability ## Overview [#overview] Wolbarg records what your agents' memory is doing into an **independent telemetry database** — never the same tables as your memory store. Explore that data with **Wolbarg Studio**, a local read-only dashboard for operations, traces, recalls, and checkpoints. Wolbarg Studio dashboard — live operations, error rate, throughput, and latency ## Enabling telemetry [#enabling-telemetry] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), telemetry: { enabled: true, database: { provider: "sqlite", url: "./telemetry.db" }, level: "debug", // off | error | warn | info | debug | trace captureQueries: false, // default since 0.6.0 — set true to persist query strings captureLatency: true, captureErrors: true, captureSimilarity: true, }, }); ``` Every operation (`remember`, `recall`, `ingest`, `compress`, `checkpoint`, `rollback`, `rememberBatch`, `recallBatch`, …) emits an event with: * `session_id`, `trace_id`, `parent_trace_id` — for waterfall traces * `organization`, `agent`, `tags`, `checkpoint_id` * measured **stage spans** (embedding, vector search, ranking, database read/write) * persisted recall explanations when `explain: true` Call `await ctx.flushTelemetry()` before exiting short-lived scripts to ensure the async emitter drains. Telemetry is **SQLite-only** today (the interface is ready for Postgres). It is fully independent of your memory backend, so you can use Postgres for memory and SQLite for telemetry. Keep telemetry on a **separate file** from memory storage. ## Recall explain mode [#recall-explain-mode] ```ts const explained = await ctx.recall({ query: "recurring invoices", explain: true }); for (const hit of explained.results) { console.log(hit.memory.id, hit.score, hit.rankingReason); } console.log(explained.searchTime, explained.rankingTime, explained.traceId); ``` ## Schema versioning [#schema-versioning] Telemetry SQLite files use an additive, versioned schema. On writable open, **v1** files are migrated in place to **v2** and keep all existing events. V2 adds organization, agent, tags, checkpoint, persisted recall explanations, and stage spans. Read-only access to an unmigrated v1 file remains supported. `SqliteEventDatabase.query()` can filter by `organization`, `agentId`, `tag`, and `checkpointId`. ## Wolbarg Studio [#wolbarg-studio] Studio is a standalone dashboard (Next.js) — **not** bundled into the SDK. The SDK writes events; Studio reads them (and can also open memory files for hydration). ```bash git clone https://github.com/Atharvmunde11/wolbarg-studio cd wolbarg-studio npm install npm run dev # http://localhost:3100 ``` On first launch, use **Connect / Settings** to point at: * Telemetry database (e.g. `./telemetry.db`) * Memory database (optional — for counts / hydration) * Checkpoint directory (optional) Connections persist in your user config directory (`~/.wolbarg/studio.json` or the AppData equivalent), never inside the project. ### Dashboard [#dashboard] Live overview of memory operations from the telemetry database — operations today, error rate, throughput, P95 latency, active agents, and charts. (See the screenshot at the top of this page.) ### Trace Explorer [#trace-explorer] True waterfall of embedding → search → filtering → ranking → response, with expandable stage metadata and the root event JSON. Wolbarg Studio Trace Explorer waterfall ### What Studio shows [#what-studio-shows] | Surface | Purpose | | ---------------------- | ----------------------------------------------------------------- | | **Dashboard** | Live stats and charts | | **Stream** | Live SSE event tail | | **Events** | Filterable operation stream (dedupe `created` / `updated` badges) | | **Trace Explorer** | Waterfall + stage metadata | | **Recalls** | Scores, timings, explain panels | | **Memory Ops** | Per-operation breakdowns | | **Errors** | Failed operations for triage | | **Agents** | Per-agent activity | | **Checkpoints** | List and compare snapshots | | **Connect / Settings** | Wire telemetry, memory, checkpoints | Studio may still show historical or visual graph views from older workflows; those are **Studio UI surfaces**, not SDK graph APIs (graph memory was [removed in 0.6.0](/docs/graph-memory)). ### Notes [#notes] * Studio opens SQLite **read-only** — it never writes to your telemetry or memory databases * Live mode polls on a configurable interval (default 2s) * Postgres telemetry connections are represented in config but not implemented yet ## Related pages [#related-pages] * [What's New](/docs/guides/whats-new) * [Getting Started](/docs/getting-started) * [Production](/docs/guides/production) * [Performance](/docs/performance) * [Architecture](/docs/architecture) --- # OCR > Extract text from images with tesseract.js during Wolbarg ingest. URL: /docs/ocr ## What is it? [#what-is-it] Optical character recognition via the `ocr: tesseract()` provider, used during image ingest. ## Why does it exist? [#why-does-it-exist] Many useful facts live inside pixels (UI text, labels, scanned pages). OCR turns them into embeddable strings. ## How does it work? [#how-does-it-work] ```bash npm install tesseract.js ``` ```ts import { tesseract } from "wolbarg"; ocr: tesseract() ``` OCR requires installing `tesseract.js` in your app. Scan-only PDFs are not OCR'd as PDFs in v0.2 — convert to images or use a vision provider on image fixtures. ## When should it be used? [#when-should-it-be-used] Screenshots and photos with readable text where you do not need scene captions. Combine with [Vision Models](/docs/vision) for richer descriptions. ## Related pages [#related-pages] * [Vision Models](/docs/vision) * [Image Ingestion](/docs/image-ingestion) * [Example — OCR](/docs/examples/ocr) --- # Performance > Tuning guidance for recall latency, ingest throughput, and storage growth in Wolbarg. URL: /docs/performance ## What is it? [#what-is-it] Practical notes on what dominates runtime cost and how to configure Wolbarg for speed vs quality. ## Why does it exist? [#why-does-it-exist] Most latency is not “SQLite being slow” — it is embedding HTTP calls, rerank APIs, and scanning oversized candidate sets. ## How it works — cost drivers [#how-it-works--cost-drivers] | Path | Dominated by | | ---------- | --------------------------------------------- | | `remember` | Embedding API + single insert | | `recall` | Query embed + vector scan (+ hybrid + rerank) | | `ingest` | Parse + N embeddings + batch insert | | `compress` | LLM tokens | ## Tuning checklist [#tuning-checklist] 1. Call `await ctx.ready()` at startup to fail fast 2. Prefer [metadata filters](/docs/metadata-filtering) before raising `topK` 3. Keep `threshold` slightly above 0 for noisy corpora 4. Use hybrid only when you need exact tokens 5. Reserve rerankers for high-precision paths 6. Pick chunk sizes intentionally ([Chunking](/docs/chunking)) 7. Match embedding dimensions to your model and never silently change them mid-database ## When should you use SQLite vs Postgres? [#when-should-you-use-sqlite-vs-postgres] * **SQLite** — single node, lowest ops overhead * **PostgreSQL** — multi-instance sharing and central ops See [Benchmarks](/docs/benchmarks) for methodology and published numbers, and the live charts at [/benchmarks](/benchmarks). ## Related pages [#related-pages] * [Architecture](/docs/architecture) * [Benchmarks](/docs/benchmarks) * [Best Practices](/docs/guides/best-practices) --- # Provider Architecture > Embedding, LLM, keyword search, reranker, OCR, vision, and chunking providers in Wolbarg. URL: /docs/providers ## What is it? [#what-is-it] Wolbarg treats embeddings, LLMs, keyword search, rerankers, OCR, vision, chunking, and storage as swappable providers. Factories ship for common APIs; custom objects work if they match the interface. ## Why does it exist? [#why-does-it-exist] Agents already have preferred models and endpoints. The SDK must not hardcode a single cloud vendor. Isolate factories in your app so backend switches stay in one folder — see [Project layout](/docs/installation#project-layout). ## Embedding providers [#embedding-providers] All factories wrap an OpenAI-compatible `/embeddings` HTTP API: ```ts import { openaiEmbedding, ollamaEmbedding, openRouterEmbedding, lmStudioEmbedding, geminiEmbedding, togetherEmbedding, vllmEmbedding, openaiCompatibleEmbedding, } from "wolbarg"; embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }) embedding: ollamaEmbedding({ apiKey: "ollama", model: "nomic-embed-text", }) ``` ### Custom embedding provider [#custom-embedding-provider] ```ts const embedding = { model: "my-model", async embed(text: string) { /* return Float32Array */ }, async validate() { const v = await this.embed("ping"); return { dimensions: v.length }; }, }; ``` Changing embedding dimensionality on an existing database throws at startup — create a new DB file or wipe data first. ## LLM providers [#llm-providers] ```ts import { openaiLlm, ollamaLlm, openRouterLlm } from "wolbarg"; llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }) ``` Without `llm`, TypeScript will not allow `compress()`. At runtime you get `ProviderNotConfiguredError`. ## Keyword search [#keyword-search] ```ts keywordSearch: bm25() ``` Enables [Hybrid Search](/docs/hybrid-search). Since **0.6.0**, `hybrid: true` without `keywordSearch` throws `ValidationError` — there is no silent semantic-only fallback. ## Rerankers [#rerankers] ```ts import { jinaReranker, cohereReranker, bgeReranker, crossEncoder } from "wolbarg"; reranker: jinaReranker({ apiKey: process.env.JINA_API_KEY! }) ``` Pass `rerank: true` on recall. Missing `reranker` throws `ValidationError`; built-in adapters throw `RerankError` on failure. See [Rerankers](/docs/rerankers). ## OCR and vision [#ocr-and-vision] ```ts import { tesseract, geminiVision, openaiVision } from "wolbarg"; ocr: tesseract(), vision: geminiVision({ apiKey: process.env.GEMINI_API_KEY! }), ``` See [OCR](/docs/ocr) and [Vision Models](/docs/vision). ## Chunking [#chunking] ```ts import { createChunkingStrategy } from "wolbarg"; chunking: createChunkingStrategy("markdown") ``` Strategies: `fixed`, `sentence`, `paragraph`, `markdown`, `heading`. Overridable per `ingest` call. ## Graph providers [#graph-providers] **Removed in 0.6.0.** `sqliteGraph` / `neo4jGraph` are gone. See [Graph memory (removed)](/docs/graph-memory). ## When should it be used? [#when-should-it-be-used] Configure only the providers you exercise. A semantic-only SQLite setup needs organization + storage + embedding. Add LLM for compression, BM25 before enabling hybrid, OCR/vision for images, and a reranker before enabling `rerank: true`. ## Related pages [#related-pages] * [Configuration](/docs/configuration) * [Installation](/docs/installation) * [Hybrid Search](/docs/hybrid-search) * [Rerankers](/docs/rerankers) * [Compression Pipeline](/docs/compression) * [Examples — Providers](/docs/examples/providers) * [What's New](/docs/guides/whats-new) --- # Quick Start > Construct Wolbarg, remember facts, recall them, and optionally use hybrid search and document ingest. URL: /docs/quick-start ## What is it? [#what-is-it] A minimal path from zero to working semantic memory: construct, remember, recall, then optionally hybrid search and document ingest. For production apps, put factories under `providers/` so you can swap SQLite ↔ Postgres without touching agent code — see [Project layout](/docs/installation#project-layout). Use [Wolbarg Workspace](/docs/workspace) instead: `npx @wolbarg/workspace init`. This Quick Start is the **SDK** path for custom agents. **No API key?** Point embeddings at local [Ollama](https://ollama.com) (`nomic-embed-text`) — see the [SDK README](https://github.com/wolbarg/wolbarg/blob/main/README.md) or use `npx wolbarg init` and pick Ollama as the provider. ### Projects (recommended) [#projects-recommended] ```bash npx wolbarg init ``` ```ts import { createWolbargFromProjectConfig } from "wolbarg"; const ctx = createWolbargFromProjectConfig(); await ctx.ready(); ``` Then continue with remember / recall below using that `ctx`. ## 1. Construct [#1-construct] ```ts import { wolbarg, sqlite, openaiEmbedding, openaiLlm, bm25, } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./data/memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), // Optional — enables compress() llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }), // Required when using hybrid: true (fail-closed since 0.6.0) keywordSearch: bm25(), }); ``` ## 2. Remember [#2-remember] ```ts const result = await ctx.remember({ agent: "research", content: { text: "Stripe supports recurring invoices." }, metadata: { topic: "billing", source: "docs" }, }); ``` From a chat transcript (experimental — default needs no LLM): ```ts await ctx.rememberFromMessages( [ { role: "user", content: "Stripe supports recurring invoices." }, { role: "assistant", content: "Noted." }, ], { agent: "research", mode: "raw" }, ); ``` ## 3. Recall [#3-recall] ```ts const results = await ctx.recall({ query: "How do recurring invoices work?", topK: 5, threshold: 0.3, filter: { agent: "research" }, }); console.log(results[0]?.content.text, results[0]?.similarity); ``` ## 4. Hybrid + filters (optional) [#4-hybrid--filters-optional] Since **0.6.0**, `hybrid: true` throws `ValidationError` if `keywordSearch` is not configured. There is no silent semantic-only fallback. ```ts import { meta } from "wolbarg"; const hits = await ctx.recall({ query: "recurring invoices", topK: 5, hybrid: true, filter: { agent: "research", metadata: meta.eq("topic", "billing"), }, }); ``` ## 5. Ingest a document (optional) [#5-ingest-a-document-optional] Markdown / TXT ingest works out of the box. For PDF or DOCX install peers first (`pdf-parse@1.1.4`, `mammoth`). See [Document Ingestion](/docs/document-ingestion). ```bash npm install pdf-parse@1.1.4 # required for .pdf ingest npm install mammoth # required for .docx ingest ``` ```ts const result = await ctx.ingest({ agent: "docs", source: { path: "./guide.md" }, chunking: { strategy: "markdown", chunkSize: 800, overlap: 100 }, }); console.log(result.chunkCount); ``` ## When should you use this pattern? [#when-should-you-use-this-pattern] Start here for every new project. Add hybrid search, rerankers, and ingest only when you need them. Switch backends via [Project layout](/docs/installation#project-layout) instead of scattering factory calls. To debug what agents remembered and how recall ranked results, enable telemetry and open [Wolbarg Studio](/docs/observability). ## Related pages [#related-pages] * [Installation](/docs/installation) * [Configuration](/docs/configuration) * [Observability & Studio](/docs/observability) * [recall()](/docs/api/recall) * [rememberFromMessages()](/docs/api/remember-from-messages) * [ingest()](/docs/api/ingest) * [Example — Vercel AI memory](/docs/examples/vercel-ai-memory) * [Vercel AI integration](/docs/integrations/vercel-ai) * [What's New](/docs/guides/whats-new) * [Examples](/docs/examples) --- # Real-time events > Subscribe to memory changes with wolbarg.subscribe() — in-process EventEmitter for SQLite, LISTEN/NOTIFY for Postgres, with filters and safe callbacks. URL: /docs/realtime-events ## What is it? [#what-is-it] `subscribe()` registers a callback that fires when a memory operation **commits** — no polling `recall()` or `history()`. Use it to: * Mirror writes into UI / dashboards * Trigger downstream agent tools when facts change * Keep secondary indexes or caches coherent * Audit live multi-agent activity ## Quick start [#quick-start] ```ts const unsubscribe = ctx.subscribe( { organization: "my-org", agent: "research", event: ["remember", "update"], }, (event) => { console.log(event.event, event.memoryId, event.upsertAction); }, ); // later unsubscribe(); ``` `close()` tears down **all** subscriptions for that client. ## API [#api] ```ts subscribe( filter: SubscribeFilter, callback: MemoryChangeCallback, ): Unsubscribe interface SubscribeFilter { organization: string; agent?: string; event?: SubscribableEvent | SubscribableEvent[]; } type SubscribableEvent = | "remember" | "update" | "forget" | "compress" | "ingest" | "*"; interface MemoryChangeEvent { event: Exclude; organization: string; agent: string; memoryId: string | string[]; timestamp: string; traceId?: string; sessionId?: string; /** Present when upsert path ran during remember/ingest. */ upsertAction?: "created" | "updated" | "skipped"; } ``` ## Event types [#event-types] | Event | When | | ---------- | -------------------------------------------- | | `remember` | New memory inserted | | `update` | Existing memory upserted / `update()` | | `forget` | Memory deleted | | `compress` | Compression archived sources + wrote summary | | `ingest` | Document ingest completed | | `*` | Subscribe to all of the above | ### Filter matching [#filter-matching] * `organization` is **required** and always matched. * `agent` optional — omit to receive all agents in the org. * `event` optional — omit or pass `"*"` for all event kinds; pass an array for a whitelist. ## SQLite: in-process only (important) [#sqlite-in-process-only-important] **SQLite `subscribe()` only delivers events within the same Node.js process.** A second process writing to the same `memory.db` file will **not** notify subscribers in this process. SQLite has no cross-process pub/sub. This is intentional. | Topology | SQLite subscribe | | -------------------------------------- | --------------------------- | | One process, many async writers | ✅ Events delivered | | Many processes, shared file | ❌ No cross-process delivery | | Need multi-host / multi-process events | Use **PostgreSQL** | For multi-process **write safety** on SQLite, see [Concurrency](/docs/concurrency). For multi-process **event delivery**, use Postgres. ## PostgreSQL: LISTEN / NOTIFY [#postgresql-listen--notify] Postgres backend uses transactional `NOTIFY wolbarg_events` with a dedicated `LISTEN` connection (not borrowed from the query pool). | Detail | Behavior | | --------- | --------------------------------------------------------- | | Delivery | Cross-process and cross-host (same database) | | Filtering | Org / agent / event filtered **client-side** after notify | | Payload | IDs + metadata only (NOTIFY capped at \~8000 bytes) | | Reconnect | Listener reconnects if the connection drops | | Pooling | Listen connection is dedicated — not part of the pool | Payloads intentionally exclude full memory text so notifications stay small and safe under the NOTIFY size limit. ## Safety [#safety] * Subscriber callback errors are **caught and logged**. * A throwing subscriber **never** fails the write that triggered the event. * Unsubscribing is idempotent; closing the client clears remaining listeners. ## Patterns [#patterns] ### React to preference updates only [#react-to-preference-updates-only] ```ts ctx.subscribe( { organization: "my-org", event: "update" }, async (e) => { await refreshUserProfile(e.memoryId); }, ); ``` ### Fan-out all org activity to a log [#fan-out-all-org-activity-to-a-log] ```ts ctx.subscribe({ organization: "my-org", event: "*" }, (e) => { audit.write(e); }); ``` ### Combine with upsert [#combine-with-upsert] When [memory dedupe](/docs/memory-upsert) updates in place, you receive `"update"` (and may see `upsertAction: "updated"`). Fresh inserts still emit `"remember"`. ## Related pages [#related-pages] * [Memory upsert](/docs/memory-upsert) * [Concurrency](/docs/concurrency) * [subscribe() API](/docs/api/subscribe) * [PostgreSQL](/docs/storage/postgresql) * [What's New](/docs/guides/whats-new) --- # Rerankers > Optional cross-encoder reranking and MMR diversification for recall results. Fail-closed since 0.6.0 — throws RerankError on provider failure. URL: /docs/rerankers ## What is it? [#what-is-it] A second-stage ranking step. After vector (and optional hybrid) retrieval, a reranker scores query–document pairs. MMR diversifies the final set to reduce near-duplicates. ## Why does it exist? [#why-does-it-exist] Bi-encoder retrieval is fast but coarse. Cross-encoders improve precision. MMR improves diversity for agent context windows. Incorrect ranking that looks successful is worse than a loud error — so since **0.6.0**, rerank fails closed. ## How does it work? [#how-does-it-work] ### Rerank [#rerank] ```ts import { jinaReranker, cohereReranker } from "wolbarg"; reranker: jinaReranker({ apiKey: process.env.JINA_API_KEY! }) await ctx.recall({ query: "…", topK: 5, rerank: true }); ``` Built-in factories: `jinaReranker`, `cohereReranker`, `bgeReranker`, `crossEncoder`, `openaiReranker`. ### Fail-closed (0.6.0+) [#fail-closed-060] * `rerank: true` without a configured `reranker` throws **`ValidationError`** * Built-in HTTP / OpenAI rerankers throw **`RerankError`** on provider failure or empty rankings — they do **not** fall back to identity order Catch `RerankError` explicitly when you enable rerank. ### MMR [#mmr] ```ts await ctx.recall({ query: "…", topK: 5, mmr: true, // lambda = 0.5 // mmr: { lambda: 0.7 } // higher = more relevance, less diversity }); ``` ## When should it be used? [#when-should-it-be-used] Use rerankers for high-stakes grounding (support answers, code RAG). Use MMR when agents repeatedly get near-duplicate snippets. ## Performance notes [#performance-notes] * Over-fetch (`retrieval.overFetchFactor`) feeds the reranker more candidates * Network latency depends on the remote rerank API * Skip rerank in latency-critical hot paths ## Related pages [#related-pages] * [Hybrid Search](/docs/hybrid-search) * [Semantic Search](/docs/search) * [Example — Rerankers](/docs/examples/rerankers) * [What's New](/docs/guides/whats-new) * [Errors](/docs/reference/errors) --- # Semantic Search > How Wolbarg embeds queries and retrieves memories by cosine similarity. URL: /docs/search ## What is it? [#what-is-it] Semantic search is the default `recall()` path: embed the query, compare against stored memory embeddings, return the top-K closest records. ## Why does it exist? [#why-does-it-exist] Agents ask questions in natural language. Exact string match fails when vocabulary drifts; vectors catch meaning. ## How does it work? [#how-does-it-work] 1. `embedding.embed(query)` produces a query vector 2. Storage runs nearest-neighbor search (sqlite-vec / pgvector or in-process cosine) 3. Optional filters (`agent`, metadata, archived) shrink the candidate set 4. Results are ranked by similarity and trimmed to `topK` ```ts const results = await ctx.recall({ query: "How do recurring invoices work?", topK: 5, threshold: 0.3, filter: { agent: "research" }, }); ``` ## When should it be used? [#when-should-it-be-used] Always. Semantic search is the baseline. Add [Hybrid Search](/docs/hybrid-search) when exact tokens matter, [Rerankers](/docs/rerankers) when precision matters, and [Metadata Filtering](/docs/metadata-filtering) to scope corpora. ## Performance notes [#performance-notes] * Latency is dominated by embedding network calls + vector scan size * Keep `threshold` above 0 for noisy corpora * Prefer metadata filters before raising `topK` ## Related pages [#related-pages] * [Hybrid Search](/docs/hybrid-search) * [recall()](/docs/api/recall) * [Performance](/docs/performance) --- # Vision Models > Caption and describe images with Gemini or OpenAI vision providers during ingest. URL: /docs/vision ## What is it? [#what-is-it] Vision providers that produce captions, descriptions, and entities from images, merged into ingest text before chunking. ## Why does it exist? [#why-does-it-exist] OCR reads glyphs; vision models explain what an image *means* — charts, UI layout, diagrams. ## How does it work? [#how-does-it-work] ```ts import { geminiVision, openaiVision } from "wolbarg"; vision: geminiVision({ apiKey: process.env.GEMINI_API_KEY! }) // or vision: openaiVision({ apiKey: process.env.OPENAI_API_KEY! }) ``` OCR text, captions, descriptions, and entities are concatenated before chunking. Configure either or both providers. ## When should it be used? [#when-should-it-be-used] Charts, product photos, and UI screenshots where labels alone are insufficient. Prefer OCR-only for dense text scans to save cost. ## Performance notes [#performance-notes] * Vision calls dominate ingest latency for images * Cache originals outside Wolbarg if you re-process often ## Related pages [#related-pages] * [OCR](/docs/ocr) * [Image Ingestion](/docs/image-ingestion) * [Provider Architecture](/docs/providers) --- # Wolbarg Workspace > Shared, reconciled project truth for Cursor, Claude Code, and Codex — install from npm with @wolbarg/workspace. URL: /docs/workspace Wolbarg Workspace is the product built on top of the [`wolbarg`](/docs/quick-start) SDK. The SDK stays tool-agnostic; Workspace adds project truth, reconciliation, and agent connectors. ## Why use it? [#why-use-it] Cursor, Claude Code, and Codex forget everything when a session ends. They re-investigate the same code, reopen settled decisions, and act on stale context. Wolbarg Workspace keeps one shared, always-current view of your project — decisions, architecture, tasks, bugs, conventions — and every connected agent reads and updates it automatically. * Stop re-explaining your codebase every session. * A decision made in Cursor is known to Claude Code and Codex. * Old facts get replaced, not piled up. * Runs fully local by default. ## Install [#install] Published on npm as **`@wolbarg/workspace@0.1.0`**. Run inside your project folder (not global): ```bash npm install @wolbarg/workspace npx @wolbarg/workspace init ``` A short wizard asks for storage and an embedding provider. Press Enter to keep the defaults (SQLite + Ollama, fully local). Skip the wizard: ```bash npx @wolbarg/workspace init --yes ``` Packages: | Package | Purpose | | -------------------------------------------------------------------------------- | ----------------------------------- | | [`@wolbarg/workspace`](https://www.npmjs.com/package/@wolbarg/workspace) | CLI + domain library | | [`@wolbarg/workspace-mcp`](https://www.npmjs.com/package/@wolbarg/workspace-mcp) | MCP server (installed by `connect`) | Source: [github.com/wolbarg/workspace](https://github.com/wolbarg/workspace) ## Connect your agent [#connect-your-agent] ```bash npx @wolbarg/workspace connect cursor npx @wolbarg/workspace connect claude npx @wolbarg/workspace connect codex ``` Restart the agent afterwards. No manual MCP JSON editing is required. ## Embedding provider [#embedding-provider] Workspace needs an embedding model to search memory. The default is [Ollama](https://ollama.com): ```bash ollama pull nomic-embed-text ``` The `init` wizard also offers OpenAI, Voyage AI, Gemini, LM Studio, OpenRouter, or any OpenAI-compatible endpoint. API keys go in `.env.wolbarg` — never commit that file. ## Config [#config] `init` writes: | File | What it is | | -------------------------------- | ------------------------------- | | `.wolbarg/workspace/config.json` | Storage + embedding settings | | `.wolbarg/workspace/memory.db` | Local SQLite database (default) | | `.env.wolbarg` | API keys — do not commit | Defaults: SQLite storage, Ollama embeddings, 90-day retention. Teams can switch to Postgres in the wizard. Re-run `init` any time to change providers. ## Check that it works [#check-that-it-works] ```bash npx @wolbarg/workspace doctor npx @wolbarg/workspace status npx @wolbarg/workspace review ``` ## How it relates to the SDK [#how-it-relates-to-the-sdk] | Layer | Package | Job | | ------- | ------------------------------------------------------------------------ | ---------------------------------------------- | | SDK | [`wolbarg`](https://www.npmjs.com/package/wolbarg) | Embeddings, storage, search, providers | | Product | [`@wolbarg/workspace`](https://www.npmjs.com/package/@wolbarg/workspace) | Project truth, reconciliation, CLI, connectors | Use the SDK when you are building your own agent memory. Use Workspace when you want Cursor / Claude Code / Codex to share current project truth out of the box. ## Related pages [#related-pages] * [Quick Start (SDK)](/docs/quick-start) * [Connectors](/connector) * [Installation (SDK)](/docs/installation) * [FAQ](/docs/faq) --- # forget() > Archive or delete memories by id or metadata/agent filter. Supports AbortSignal. URL: /docs/api/forget ## Signature [#signature] ```ts forget(options: ForgetOptions): Promise ``` ## Example [#example] ```ts await ctx.forget({ id: record.id }); await ctx.forget({ filter: { agent: "research" }, signal: AbortSignal.timeout(5_000), }); ``` Optional `signal?: AbortSignal` cancels with `CancellationError`. ## Related pages [#related-pages] * [history()](/docs/api/history) * [Metadata Filtering](/docs/metadata-filtering) * [API Overview](/docs/api) --- # getRelated() > Removed in Wolbarg 0.6.0. Graph memory APIs are no longer part of the core SDK. URL: /docs/api/get-related ## Removed in 0.6.0 [#removed-in-060] `getRelated()` was part of the optional graph memory layer and is **no longer exported** from `wolbarg`. Also removed: `linkMemories`, `sqliteGraph`, `neo4jGraph`, `includeGraph`, and the `neo4j-driver` peer. This page is kept for redirects. See [Graph memory (removed)](/docs/graph-memory), [What's New](/docs/guides/whats-new), and [Migration](/docs/migration). ## Alternatives [#alternatives] Filter related facts with [metadata](/docs/metadata-filtering), or run traversal in an external graph store. ## Related pages [#related-pages] * [Graph memory](/docs/graph-memory) * [linkMemories()](/docs/api/link-memories) * [recall()](/docs/api/recall) * [What's New](/docs/guides/whats-new) * [Migration](/docs/migration) --- # history() > Read audit events for remember, forget, compress, and related operations. URL: /docs/api/history ## Signature [#signature] ```ts history(options?: HistoryOptions): Promise ``` Use history to audit what changed when debugging multi-agent writes or compression jobs. ## Related pages [#related-pages] * [forget()](/docs/api/forget) * [Compression Pipeline](/docs/compression) --- # API Overview > Index of the Wolbarg public API — constructor, remember, rememberFromMessages, update, recall, ingest, forget, history, subscribe, AbortSignal, and lifecycle. URL: /docs/api ## What is it? [#what-is-it] The public surface developers call after constructing `Wolbarg` / `wolbarg()`. Current SDK version: **0.6.0** (`SDK_VERSION`). ## Core entry points [#core-entry-points] | Page | Method | | ---------------------------------------------------------- | --------------------------------- | | [Wolbarg](/docs/api/wolbarg) | construct / ready / close | | [remember()](/docs/api/remember) | Store a memory (`RememberResult`) | | [rememberFromMessages()](/docs/api/remember-from-messages) | Chat → memory (**experimental**) | | [update()](/docs/api/update) | Update a memory by id | | [recall()](/docs/api/recall) | Semantic / hybrid search | | [ingest()](/docs/api/ingest) | Document → memories | | [forget()](/docs/api/forget) | Archive / delete memories | | [history()](/docs/api/history) | Audit events | | [subscribe()](/docs/api/subscribe) | Real-time change events | | [stats() / clear()](/docs/api/lifecycle) | Introspection / wipe | Compression lives under [Compression Pipeline](/docs/compression). ## AbortSignal [#abortsignal] Optional `signal?: AbortSignal` on `remember`, `rememberFromMessages`, `recall`, `update`, `compress`, and `forget`. Cancellation throws `CancellationError`. ## Errors (common) [#errors-common] | Situation | Error | | ------------------------------------------------------------- | ---------------------------- | | `hybrid: true` / `rerank: true` without provider | `ValidationError` | | Built-in reranker HTTP / empty ranking | `RerankError` | | Cancelled via AbortSignal | `CancellationError` | | SQLite lock exhaustion | `StorageLockedError` | | CAS mismatch on `expectedVersion` | `VersionConflictError` | | Feature used without provider (e.g. `compress` without `llm`) | `ProviderNotConfiguredError` | See [Errors](/docs/reference/errors). ## Feature guides linked from the API [#feature-guides-linked-from-the-api] | Capability | Docs | | ------------------ | ---------------------------------------------------------------------------------------------- | | Real-time events | [subscribe()](/docs/api/subscribe) · [guide](/docs/realtime-events) | | Upsert / dedupe | [remember()](/docs/api/remember) · [update()](/docs/api/update) · [guide](/docs/memory-upsert) | | Hybrid / rerank | [Hybrid Search](/docs/hybrid-search) · [Rerankers](/docs/rerankers) | | Embedding cache | [Embedding cache](/docs/embedding-cache) | | SQLite concurrency | [Concurrency](/docs/concurrency) | ## Not in core (0.6.0) [#not-in-core-060] Graph APIs (`linkMemories`, `getRelated`, `sqliteGraph`, `neo4jGraph`, `includeGraph`) were **removed**. Stub pages remain for redirects: [linkMemories](/docs/api/link-memories) · [getRelated](/docs/api/get-related) · [Graph memory](/docs/graph-memory). ## Generated reference [#generated-reference] Every exported type and factory is listed under [API Reference](/docs/api/reference). ## Related pages [#related-pages] * [Configuration](/docs/configuration) * [Quick Start](/docs/quick-start) * [What's New](/docs/guides/whats-new) * [Architecture](/docs/architecture) * [Production](/docs/guides/production) --- # ingest() > Parse documents into chunked semantic memories. URL: /docs/api/ingest ## Signature [#signature] ```ts ingest(options: IngestOptions): Promise // source: { path } | { buffer, filename? } | { text } // chunking?: { strategy, chunkSize, overlap } // metadata?: Record ``` Pipeline: parse → OCR/vision (if configured) → chunk → embed (batch) → store (batch transaction). ## Dependencies [#dependencies] PDF and DOCX require peers: `npm install pdf-parse@1.1.4` · `npm install mammoth` · `npm install tesseract.js` for OCR. ## Example [#example] ```ts await ctx.ingest({ agent: "docs", source: { path: "./guide.md" }, chunking: { strategy: "markdown", chunkSize: 800, overlap: 100 }, }); ``` ## Related pages [#related-pages] * [Document Ingestion](/docs/document-ingestion) * [Chunking](/docs/chunking) * [Limitations](/docs/guides/limitations) --- # stats() / clear() > Introspection and organization-scoped wipe helpers. URL: /docs/api/lifecycle ## stats() [#stats] ```ts const s = await ctx.stats(); // memory counts, models, storage info ``` `llmModel` may be `null` when no LLM is configured. ## clear() [#clear] ```ts await ctx.clear(); // organization-scoped, destructive ``` ## Related pages [#related-pages] * [Wolbarg](/docs/api/wolbarg) * [Best Practices](/docs/guides/best-practices) --- # linkMemories() > Removed in Wolbarg 0.6.0. Graph memory APIs are no longer part of the core SDK. URL: /docs/api/link-memories ## Removed in 0.6.0 [#removed-in-060] `linkMemories()` was part of the optional graph memory layer and is **no longer exported** from `wolbarg`. Also removed: `getRelated`, `sqliteGraph`, `neo4jGraph`, `includeGraph`, and the `neo4j-driver` peer. This page is kept for redirects. See [Graph memory (removed)](/docs/graph-memory), [What's New](/docs/guides/whats-new), and [Migration](/docs/migration). ## Alternatives [#alternatives] Model relationships with [metadata](/docs/metadata-filtering) or an external graph store. ## Related pages [#related-pages] * [Graph memory](/docs/graph-memory) * [getRelated()](/docs/api/get-related) * [What's New](/docs/guides/whats-new) * [Migration](/docs/migration) --- # recall() > Semantic and hybrid search with filters, thresholds, MMR, and rerank. Fail-closed hybrid/rerank since 0.6.0. Supports AbortSignal. URL: /docs/api/recall ## Signature [#signature] ```ts recall(options: RecallOptions): Promise ``` ## Options [#options] | Field | Default | Description | | ----------- | ------- | ----------------------------------------------- | | `query` | — | Natural-language query (required) | | `topK` | `5` | Max results (1–1000) | | `threshold` | `0` | Minimum cosine similarity | | `filter` | — | `agent`, `includeArchived`, `metadata` | | `hybrid` | — | `true` or weights; **requires** `keywordSearch` | | `mmr` | — | Diversification; `true` or `{ lambda }` | | `rerank` | `false` | **Requires** configured `reranker` | | `explain` | `false` | Ranking diagnostics + timings | | `signal` | — | `AbortSignal` — throws `CancellationError` | ## Fail-closed hybrid and rerank [#fail-closed-hybrid-and-rerank] * `hybrid: true` without `keywordSearch` → **`ValidationError`** (no semantic-only fallback) * `rerank: true` without `reranker` → **`ValidationError`** * Built-in rerankers throw **`RerankError`** on failure (no identity-order fallback) ## Example [#example] ```ts import { meta } from "wolbarg"; const hits = await ctx.recall({ query: "billing invoices", topK: 8, threshold: 0.25, hybrid: { semanticWeight: 0.7, keywordWeight: 0.3 }, mmr: { lambda: 0.6 }, rerank: true, filter: { agent: "research", metadata: meta.and( meta.eq("topic", "billing"), meta.gte("priority", 1), ), }, signal: AbortSignal.timeout(10_000), }); ``` ## Related pages [#related-pages] * [Semantic Search](/docs/search) * [Hybrid Search](/docs/hybrid-search) * [Rerankers](/docs/rerankers) * [What's New](/docs/guides/whats-new) * [API Overview](/docs/api) --- # rememberFromMessages() > Experimental conversation → memory bridge — store chat turns as memories (raw or LLM extract). URL: /docs/api/remember-from-messages ## Signature [#signature] ```ts /** @experimental until 1.0 */ rememberFromMessages( messages: ConversationMessage[], options: RememberFromMessagesOptions, ): Promise interface ConversationMessage { role: string; content: string; } interface RememberFromMessagesOptions { agent: string; /** Default: "raw" */ mode?: "raw" | "extract"; /** Default: "last_user" — only for mode "raw" */ rawStrategy?: "last_user" | "all_user"; metadata?: Record; dedupe?: boolean | MemoryDedupeConfig; } ``` **Stability:** experimental until 1.0. Prefer pinning your `wolbarg` version if you depend on this shape. ## Modes [#modes] | Mode | LLM required? | Behavior | | --------------- | -------------------------- | ---------------------------------------------------- | | `raw` (default) | No | Store user message text (`last_user` or `all_user`) | | `extract` | Yes (`llm` in constructor) | Short prompt → one fact per line → `remember()` each | ## Example — raw (no LLM) [#example--raw-no-llm] ```ts const saved = await ctx.rememberFromMessages( [ { role: "user", content: "I prefer dark mode" }, { role: "assistant", content: "Noted." }, { role: "user", content: "Deploy only on Fridays" }, ], { agent: "assistant" }, ); // Default rawStrategy is last_user → one memory: console.log(saved[0]?.content.text); // "Deploy only on Fridays" ``` ## Example — extract (optional LLM) [#example--extract-optional-llm] ```ts import { wolbarg, sqlite, openaiEmbedding, openaiLlm } from "wolbarg"; const ctx = wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }), }); const facts = await ctx.rememberFromMessages( [ { role: "user", content: "I live in Berlin and prefer tea over coffee." }, { role: "assistant", content: "Got it." }, ], { agent: "assistant", mode: "extract" }, ); ``` Without `llm`, `mode: "extract"` throws `ProviderNotConfiguredError`. ## Chat → memory → recall [#chat--memory--recall] ```ts await ctx.rememberFromMessages(messages, { agent: "assistant", mode: "raw" }); const hits = await ctx.recall({ query: "What UI theme does the user like?", topK: 3, filter: { agent: "assistant" }, }); ``` ## Related pages [#related-pages] * [remember()](/docs/api/remember) * [Example — Conversation memory](/docs/examples/conversation-memory) * [Example — Vercel AI memory](/docs/examples/vercel-ai-memory) * [Vercel AI integration](/docs/integrations/vercel-ai) * [Limitations](/docs/guides/limitations) --- # remember() > Store a semantic memory with embedding, optional metadata, optional dedupe, and RememberResult.action. URL: /docs/api/remember ## Signature [#signature] ```ts remember(options: RememberOptions): Promise rememberBatch(items: RememberOptions[]): Promise interface RememberOptions { agent: string; content: { text: string }; metadata?: Record; /** Per-call dedupe override; undefined uses constructor `memory.dedupe`. */ dedupe?: boolean | MemoryDedupeConfig; } interface RememberResult extends MemoryRecord { action: "created" | "updated"; } ``` ## Example [#example] ```ts const result = await ctx.remember({ agent: "research", content: { text: "Acme raised Series B at $50M." }, metadata: { company: "Acme", year: 2024 }, }); console.log(result.id, result.action); ``` ## Dedupe (0.4) [#dedupe-04] Dedupe is **off by default**. Enable via constructor `memory.dedupe` or per call: ```ts await ctx.remember({ agent: "assistant", content: { text: "User prefers dark mode" }, dedupe: { strategy: "exact-or-near", nearThreshold: 0.92 }, }); ``` When an existing active memory matches, `action` is `"updated"` and the row id is reused. Full guide: [Memory upsert](/docs/memory-upsert). ## Related pages [#related-pages] * [Memory upsert](/docs/memory-upsert) * [rememberFromMessages()](/docs/api/remember-from-messages) * [update()](/docs/api/update) * [recall()](/docs/api/recall) * [subscribe()](/docs/api/subscribe) * [Metadata Filtering](/docs/metadata-filtering) * [Example — Basic Memory](/docs/examples/basic-memory) * [Example — Conversation memory](/docs/examples/conversation-memory) --- # subscribe() > Register real-time callbacks for memory change events — filter by organization, agent, and event type. URL: /docs/api/subscribe ## Signature [#signature] ```ts subscribe( filter: SubscribeFilter, callback: (event: MemoryChangeEvent) => void, ): Unsubscribe interface SubscribeFilter { organization: string; agent?: string; event?: SubscribableEvent | SubscribableEvent[]; } type SubscribableEvent = | "remember" | "update" | "forget" | "compress" | "ingest" | "*"; interface MemoryChangeEvent { event: Exclude; organization: string; agent: string; memoryId: string | string[]; timestamp: string; traceId?: string; sessionId?: string; upsertAction?: "created" | "updated" | "skipped"; } type Unsubscribe = () => void; ``` ## Example [#example] ```ts const stop = ctx.subscribe( { organization: "my-org", event: ["remember", "update"] }, (e) => console.log(e.event, e.memoryId), ); await ctx.remember({ agent: "assistant", content: { text: "Ships prefer express checkout" }, }); stop(); await ctx.close(); // also clears remaining subscriptions ``` ## Backend notes [#backend-notes] | Backend | Delivery | | ---------- | ----------------------------------- | | SQLite | Same Node process only | | PostgreSQL | Cross-process via `LISTEN`/`NOTIFY` | Full guide: [Real-time events](/docs/realtime-events). ## Related pages [#related-pages] * [Real-time events](/docs/realtime-events) * [update()](/docs/api/update) * [remember()](/docs/api/remember) * [close()](/docs/api/lifecycle) --- # update() > Explicitly update an existing memory by id — content and/or metadata — returning RememberResult. URL: /docs/api/update ## Signature [#signature] ```ts update(options: { id: string; content?: { text: string }; metadata?: Record; }): Promise interface RememberResult extends MemoryRecord { action: "created" | "updated"; } ``` ## Example [#example] ```ts const result = await ctx.update({ id: memoryId, content: { text: "User prefers dark mode (confirmed)" }, metadata: { editedBy: "admin", editedAt: new Date().toISOString() }, }); console.log(result.action); // "updated" ``` ## Behavior [#behavior] * Replaces content when provided (re-embeds). * Merges metadata when provided (shallow). * Emits history `"updated"` and subscribe `"update"`. * Prefer automatic [dedupe / upsert](/docs/memory-upsert) when the agent restates facts without knowing the id. ## Related pages [#related-pages] * [Memory upsert](/docs/memory-upsert) * [remember()](/docs/api/remember) * [subscribe()](/docs/api/subscribe) * [history()](/docs/api/history) --- # Wolbarg > Lifecycle methods for the Wolbarg class — constructor options including concurrency, embeddingCache, memory.dedupe, ready, close, and subscribe. URL: /docs/api/wolbarg ## Constructor [#constructor] ```ts new Wolbarg(options) // preferred wolbarg(options) // factory (recommended in docs) new Wolbarg() // then init() for v0.1 compat ``` When `llm` is present, the instance type allows `compress`. Without it, calling `compress` is a compile-time error. ### Common options [#common-options] ```ts import { wolbarg, sqlite, openaiEmbedding, bm25 } from "wolbarg"; const ctx = wolbarg({ organization: "my-org", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ /* … */ }), keywordSearch: bm25(), // required when using hybrid: true concurrency: { maxRetries: 5, baseBackoffMs: 50, maxBackoffMs: 2000, lockTimeoutMs: 5000, }, embeddingCache: { enabled: true, ttlMs: undefined, maxEntries: 10_000, }, memory: { dedupe: { enabled: false, // default — opt in for upsert strategy: "exact-or-near", nearThreshold: 0.92, nearCandidateLimit: 8, }, }, }); ``` See [Configuration](/docs/configuration) for the full option table (including Postgres `schema` / SSL / `maxPoolSize`). Isolate factories with [Project layout](/docs/installation#project-layout). ## ready() [#ready] ```ts await ctx.ready(); ``` Opens storage (and telemetry when configured) and probes embedding dimensions. Called automatically by other methods; use explicitly to fail fast at startup. ## close() [#close] ```ts await ctx.close(); ``` Idempotent. Releases database connections and tears down all [`subscribe()`](/docs/api/subscribe) listeners. ## subscribe() [#subscribe] ```ts const stop = ctx.subscribe({ organization: "my-org" }, (e) => { console.log(e.event, e.memoryId); }); ``` See [subscribe()](/docs/api/subscribe) and [Real-time events](/docs/realtime-events). Organization cannot be overridden to another tenant. ## init() shim [#init-shim] ```ts const ctx = new Wolbarg(); await ctx.init({ organization: "my-org", database: { provider: "sqlite", connectionString: "./memory.db" }, embedding: { baseUrl, apiKey, model }, llm: { baseUrl, apiKey, model }, // optional }); ``` Prefer constructor / `wolbarg()` options. See [init() Compatibility](/docs/reference/init-compat). ## Related pages [#related-pages] * [Configuration](/docs/configuration) * [remember()](/docs/api/remember) * [rememberFromMessages()](/docs/api/remember-from-messages) * [update()](/docs/api/update) * [recall()](/docs/api/recall) * [subscribe()](/docs/api/subscribe) * [API Overview](/docs/api) * [What's New](/docs/guides/whats-new) --- # Connectors > Docs index for Wolbarg connectors — the product listing lives at /connector. URL: /docs/connectors ## Product page [#product-page] Browse every connector on the marketing page: **[→ All connectors](/connector)** That page lists **Wolbarg Workspace** (Cursor / Claude Code / Codex) and AI SDK adapters for custom agents. ## Wolbarg Workspace [#wolbarg-workspace] Shared project truth for coding agents: * [Workspace docs](/docs/workspace) * npm: [`@wolbarg/workspace`](https://www.npmjs.com/package/@wolbarg/workspace) ```bash npx @wolbarg/workspace init npx @wolbarg/workspace connect cursor ``` ## AI SDK adapters [#ai-sdk-adapters] | Connector | Package | Docs | | ------------- | --------------------- | -------------------------------------- | | Vercel AI SDK | `@wolbarg/vercel-ai` | [Setup](/docs/integrations/vercel-ai) | | OpenAI Agents | `@wolbarg/openai` | [Setup](/docs/integrations/openai) | | LangChain | `@wolbarg/langchain` | [Setup](/docs/integrations/langchain) | | LlamaIndex | `@wolbarg/llamaindex` | [Setup](/docs/integrations/llamaindex) | | Mastra | `@wolbarg/mastra` | [Setup](/docs/integrations/mastra) | Also see [AI SDKs overview](/docs/integrations). --- # Best Practices > Practical guidance for production Wolbarg usage — scoping, filters, peers, lifecycle, and provider isolation. URL: /docs/guides/best-practices ## Scope memories [#scope-memories] Use stable `agent` ids and meaningful metadata keys (`topic`, `source`, `collection`). ## Prefer metadata filters [#prefer-metadata-filters] Narrow recall with `meta.*` before increasing `topK`. Combine with hybrid search for exact token matches. Model relationships with metadata when you need structure — graph APIs were [removed in 0.6.0](/docs/graph-memory). ## Isolate providers [#isolate-providers] Keep `sqlite` / `postgres` / embedding factories in a `providers/` folder. Agents import one `memory` client. That way switching databases is a one-file change — see [Project layout](/docs/installation#project-layout). ## Configure hybrid and rerank before enabling flags [#configure-hybrid-and-rerank-before-enabling-flags] Since 0.6.0, `hybrid: true` and `rerank: true` **fail closed**. Pass `keywordSearch: bm25()` and a `reranker` before setting those flags, or catch `ValidationError` / `RerankError`. ## Peers on demand [#peers-on-demand] Do not install `pg` / `pdf-parse` / `mammoth` / `tesseract.js` unless you need them. If you ingest those formats or use Postgres, peers are **required**. ## Lifecycle [#lifecycle] * Call `ready()` at process start to fail fast * Always `close()` on shutdown * One `Wolbarg` instance per process / org is enough * Pass `AbortSignal` on long-running remember/recall when callers may cancel ## Production checklist [#production-checklist] See the full [Production guide](/docs/guides/production) for SSL, pool sizing, backups, and troubleshooting. ## Related pages [#related-pages] * [Performance](/docs/performance) * [Production](/docs/guides/production) * [Installation](/docs/installation) * [Metadata Filtering](/docs/metadata-filtering) * [Multi-Agent Memory](/docs/guides/shared-memory) * [Limitations](/docs/guides/limitations) --- # Limitations > Honest boundaries of Wolbarg 0.6 — peers, PDF quality, SQLite, Postgres SSL/pool, fail-closed hybrid/rerank, and removed graph memory. URL: /docs/guides/limitations ## Maturity [#maturity] Core `remember` / `recall` (semantic + hybrid + metadata filters) on SQLite and PostgreSQL is the most battle-tested path. Document ingest, OCR/vision, and LLM compression are supported but depend on optional packages and external services where noted. **Experimental (may change before 1.0):** [`rememberFromMessages()`](/docs/api/remember-from-messages) (especially `mode: "extract"`) and [`subscribe()`](/docs/realtime-events). Pin your `wolbarg` version if you depend on these shapes. Extract-mode quality is owned by your LLM. For Vercel AI apps, prefer the stable middleware path in [`@wolbarg/vercel-ai`](/docs/integrations/vercel-ai) (AI SDK **v7+**) rather than hand-rolling recall/remember around `generateText`. Mid-stream cancel before the model `finish` event does not remember incomplete turns. ## Ingest dependencies [#ingest-dependencies] ```bash npm install pdf-parse@1.1.4 # PDF npm install mammoth # DOCX npm install tesseract.js # OCR npm install pg # PostgreSQL storage ``` * **.txt / .md / .csv / .json** — built-in * **.pdf** — `pdf-parse` required; text-layer only unless OCR/vision on images * **.docx** — `mammoth` required * **images** — configure `ocr` and/or `vision` See [Installation](/docs/installation). ## PDF extraction [#pdf-extraction] * Scan / camera PDFs with no text layer yield empty extract * Prefer simple text PDFs or pin `pdf-parse@1.1.4` ## SQLite [#sqlite] * Uses Node `node:sqlite` — Node **22.5+** * Hybrid BM25 uses FTS5 when available * [`subscribe()`](/docs/realtime-events) on SQLite is **in-process only** (same Node process) * Export / checkpoint / import / rollback are **whole-file** and refuse multi-org files — prefer one file per organization * Under extreme lock contention, callers must handle `StorageLockedError` — see [Concurrency](/docs/concurrency) ## PostgreSQL [#postgresql] * Requires `pg` * `pgvector` optional; otherwise BYTEA + in-process cosine * Remote hosts default to **`sslmode=require`** when unset; loopback is unchanged * Default pool `maxPoolSize` is **20** * Optional `schema` namespacing for tables, indexes, and NOTIFY channels * Checkpoint / export / import require **file-backed SQLite**, not Postgres See [Production](/docs/guides/production). ## Hybrid search and rerank (fail-closed) [#hybrid-search-and-rerank-fail-closed] Since **0.6.0**, there is no silent degradation: | Flag | Missing provider | Provider failure | | -------------- | ----------------- | ------------------------------------ | | `hybrid: true` | `ValidationError` | throws (no semantic-only fallback) | | `rerank: true` | `ValidationError` | `RerankError` from built-in adapters | Configure `keywordSearch: bm25()` (or a custom provider) before enabling hybrid. Catch `RerankError` explicitly — there is no identity-order fallback. ## Graph memory [#graph-memory] **Removed in 0.6.0.** `sqliteGraph`, `neo4jGraph`, `linkMemories`, `getRelated`, and `includeGraph` are gone from core. There is no `neo4j-driver` peer. Model relationships with [metadata filters](/docs/metadata-filtering) or an external store. See [Graph memory (removed)](/docs/graph-memory) and [Migration](/docs/migration). ## Telemetry [#telemetry] * Telemetry database is **SQLite only** today (Postgres is typed but not implemented) * `captureQueries` defaults to **`false`** (privacy) See [Observability](/docs/observability). ## Embedding cache [#embedding-cache] * On Postgres, durable cache defaults **off** (L1-only) unless configured otherwise — [Embedding cache](/docs/embedding-cache) ## Optional providers [#optional-providers] * `compress()` needs `llm` — otherwise `ProviderNotConfiguredError` * `hybrid: true` / `rerank: true` require their providers — see fail-closed table above ## Out of scope [#out-of-scope] * No hosted cloud control plane * No built-in agent framework / chat UI * No application authentication / authorization (`organization` is a namespace, not IAM) * No graph memory APIs (removed in 0.6.0) * No multi-process SQLite `subscribe()` * No Postgres telemetry store * No general memory TTL or cost-accounting APIs yet ## Related pages [#related-pages] * [Production](/docs/guides/production) * [Installation](/docs/installation) * [What's New](/docs/guides/whats-new) * [Migration](/docs/migration) * [Document Ingestion](/docs/document-ingestion) * [FAQ](/docs/faq) --- # Production > Operator guidance for deploying Wolbarg 0.6 — SQLite vs Postgres, SSL, schema, pooling, fail-closed hybrid/rerank, backups, and troubleshooting. URL: /docs/guides/production ## What is it? [#what-is-it] Operator-focused guidance for deploying Wolbarg **0.6.0**. This page prefers accuracy over marketing. For concurrency internals, see [Architecture](/docs/architecture) and [Concurrency](/docs/concurrency). ## Choosing a backend [#choosing-a-backend] | | SQLite | PostgreSQL | | ------------------- | ------------------------------- | --------------------------------- | | Best for | Local agents, CLIs, single node | Multi-process / multi-host fleets | | Subscribe | Same process only | Cross-process via `LISTEN/NOTIFY` | | Checkpoint / export | File-backed SQLite only | Not supported | | Embedding cache | Durable L1+L2 | L1 only | | Isolation | Prefer one file per org | Prefer `schema` + org namespace | ## SQLite [#sqlite] ### Configuration [#configuration] ```ts sqlite("./data/memory.db") // or { provider: "sqlite", url: "./data/memory.db" } ``` ### Concurrency [#concurrency] * WAL + `BEGIN IMMEDIATE` + busy retries * `concurrency.multiProcess: true` raises timeouts for multiple OS processes sharing one file * Exhausted retries throw `StorageLockedError` (`WOLBARG_STORAGE_LOCKED`) * `DatabaseSync` runs on the Node event loop — isolate heavy writers from latency-sensitive API processes, or prefer Postgres ### Backups [#backups] * Stop writers or use SQLite online backup / filesystem snapshots of the DB **and** `-wal` / `-shm` consistently * Prefer `export()` for portable bundles when the file contains a single organization * Multi-org files: export/checkpoint/import/rollback **refuse** — split by organization first ### Migrations [#migrations] Schema migrations run automatically on `open()` / `ready()`. Do not edit `wolbarg_meta` by hand. Keep a backup before upgrading major/minor releases that mention schema changes. ### Limitations [#limitations] * No cross-process `subscribe()` * File-level transfer cannot org-filter rows * Under extreme lock contention, callers must handle `StorageLockedError` ## PostgreSQL [#postgresql] ### Configuration [#configuration-1] ```ts postgres({ connectionString: process.env.DATABASE_URL!, schema: "wolbarg", // recommended for shared DBs maxPoolSize: 20, // default; raise only if the host allows // ssl: false, // opt out of default require for remote (not recommended) }) ``` Install: `npm install pg`. Enable pgvector when you want HNSW ANN: ```sql CREATE EXTENSION IF NOT EXISTS vector; ``` Without a usable `vector` type, Wolbarg falls back to blob cosine search. ### SSL / TLS [#ssl--tls] * Non-loopback hosts without `sslmode` / `ssl` in the URL get **`sslmode=require`** * Loopback (`localhost`, `127.0.0.1`, `::1`) is left unchanged for local Docker * Overrides: `ssl: false` / `"disable"` (warns on remote), `ssl: true` / `"require"`, `"prefer"` ### Schema namespacing [#schema-namespacing] `schema` creates a dedicated Postgres schema for tables, indexes, and a suffixed NOTIFY channel (`wolbarg_events_`). Use this when: * Keeping Wolbarg out of shared `public` * Running multiple deployments in one database * Hosting different embedding dimensions side by side Names: `^[A-Za-z_][A-Za-z0-9_$]*$`, max 48 characters. ### Pooling and timeouts [#pooling-and-timeouts] Session GUCs (via connection URL): `statement_timeout=30000`, `lock_timeout=10000`, `idle_in_transaction_session_timeout=60000`, plus HNSW search settings. Deadlock (`40P01`) and serialization (`40001`) retries use full-jitter backoff. ### Backups [#backups-1] Use normal Postgres backup tooling (`pg_dump`, continuous WAL archiving, managed snapshots). Wolbarg does not ship a Postgres export/checkpoint API. ### Migrations [#migrations-1] DDL is applied on open. Catalog probes are schema-scoped. Prefer throwaway schemas in tests. ## Hybrid search and rerank [#hybrid-search-and-rerank] Fail-closed since 0.6.0: | Flag | Missing provider | Provider failure | | -------------- | ----------------- | ------------------------------------ | | `hybrid: true` | `ValidationError` | throws (no silent semantic-only) | | `rerank: true` | `ValidationError` | `RerankError` from built-in adapters | Configure `keywordSearch: bm25()` (or a custom provider) before enabling hybrid. ## Telemetry [#telemetry] * SQLite telemetry DB only — **Postgres telemetry is not implemented** * `captureQueries` defaults to **`false`** (privacy) * Keep telemetry on a **separate file** from memory storage * Studio (separate product) reads the telemetry database — see [Observability](/docs/observability) ## Security trust boundary [#security-trust-boundary] * `organization` is a **data namespace**, not proof of identity * Authenticate/authorize in your app before constructing a tenant context * Do not pass end-user-controlled embedding/LLM/rerank `baseUrl` values (SSRF) * Keep API keys in process env / `.wolbarg/.env` (gitignored by `wolbarg init`) ## Troubleshooting [#troubleshooting] | Symptom | Likely cause | What to do | | --------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------- | | `StorageLockedError` | SQLite write contention | Retry with backoff; raise `concurrency` timeouts; reduce writers; move to Postgres | | `VersionConflictError` | CAS mismatch on `expectedVersion` | Re-read and retry update | | `RerankError` | Reranker HTTP/empty ranking | Fix provider; catch explicitly; do not assume identity fallback | | `ValidationError` on hybrid/rerank | Flag set without provider | Pass `keywordSearch` / `reranker` | | `ConfigurationError` telemetry postgres | Unsupported | Use SQLite telemetry URL | | Export refused | Multi-org SQLite file | Split orgs to separate files | | ANN slow / missing | No pgvector / wrong search\_path | Install extension; verify `to_regtype('vector')` | | TLS errors to managed Postgres | Cert / sslmode mismatch | Set explicit `ssl` / `sslmode` for your host | ## Performance notes [#performance-notes] * Insert coalescing amortizes commits (SQLite) / `unnest` batches (Postgres) * Embedding cache cuts repeated provider calls; Postgres cache is L1-only * HNSW is built lazily before first KNN (Postgres) * Published website benchmark numbers are from a **v0.4** mock suite — re-benchmark before citing 0.6.0 numbers ## What Wolbarg does not provide [#what-wolbarg-does-not-provide] * Application authentication / authorization * Hosted control plane * Multi-process SQLite subscribe * Postgres telemetry store * Graph memory APIs (removed in 0.6.0) * Guaranteed zero lock contention under arbitrary writer counts ## Related pages [#related-pages] * [What's New](/docs/guides/whats-new) * [Limitations](/docs/guides/limitations) * [Configuration](/docs/configuration) * [Concurrency](/docs/concurrency) * [Migration](/docs/migration) * [Observability](/docs/observability) --- # Multi-Agent Memory > Share one Wolbarg instance across concurrent agents with agent-scoped filters. URL: /docs/guides/shared-memory ## Pattern [#pattern] ```ts const ctx = new Wolbarg({ /* … */ }); await ctx.remember({ agent: "writer", content: { text: "…" } }); await ctx.remember({ agent: "researcher", content: { text: "…" } }); await ctx.recall({ query: "…", filter: { agent: "writer" }, }); // Org-wide shared recall — omit agent filter await ctx.recall({ query: "…" }); ``` ## Isolation [#isolation] Organizations isolate tenants in one database file. Agents isolate authors within an organization. Writes serialize via an in-process mutex and ACID transactions. ## Related pages [#related-pages] * [Architecture](/docs/architecture) * [Metadata Filtering](/docs/metadata-filtering) * [Best Practices](/docs/guides/best-practices) --- # What's New > Wolbarg 0.6.0 release notes — fail-closed hybrid/rerank, Postgres SSL and schema, AbortSignal, concurrency hardening, and graph memory removal. URL: /docs/guides/whats-new ## Highlights [#highlights] Wolbarg **0.6.0** is a production-hardening release. Same core loop — `remember()` / `recall()` — with safer concurrency, fail-closed retrieval, multi-tenant isolation, and Postgres defaults that match real deployments. | Feature | Deep-dive | | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | **Fail-closed hybrid & rerank** — missing providers throw; built-ins throw `RerankError` | [Hybrid Search](/docs/hybrid-search) · [Rerankers](/docs/rerankers) | | **Postgres SSL + schema** — remote TLS defaults to require; optional schema namespacing | [Production](/docs/guides/production) · [Configuration](/docs/configuration) | | **AbortSignal** on remember / rememberFromMessages / recall / update / compress / forget | [API Overview](/docs/api) | | **Concurrency fixes** — SQLite write mutex / busy retries; Postgres `FOR UPDATE`, deadlock retries | [Concurrency](/docs/concurrency) | | **Multi-tenant file safety** — SQLite export/checkpoint refuse mixed-organization files | [Limitations](/docs/guides/limitations) | | **Graph memory removed** — `sqliteGraph`, `neo4jGraph`, `linkMemories`, `getRelated`, `includeGraph` | [Graph memory (removed)](/docs/graph-memory) · [Migration](/docs/migration) | | **Privacy** — `captureQueries` defaults to `false` | [Observability](/docs/observability) | ## Install [#install] ```bash npm install wolbarg@0.6.0 ``` ## Breaking for 0.5.x users [#breaking-for-05x-users] | Change | Migration | | --------------------------- | -------------------------------------------------------------- | | Graph APIs removed | Delete graph imports and call sites | | Hybrid/rerank fail-closed | Always pass `keywordSearch` / `reranker` when flags are set | | Rerank no identity fallback | Catch `RerankError` | | Postgres remote TLS | Expect `sslmode=require` or set `ssl` explicitly | | Pool default 20 | Raise `maxPoolSize` if needed (was 64) | | Multi-org SQLite transfer | One file per organization | | Telemetry query capture | Set `captureQueries: true` if you need query strings persisted | From 0.5.x without graph: ```bash npm install wolbarg@0.6.0 ``` Most `remember` / `recall` call sites need no changes. Review hybrid, rerank, and Postgres SSL settings. Full guide: [Migration](/docs/migration). ## Still experimental [#still-experimental] * [`rememberFromMessages({ mode: "extract" })`](/docs/api/remember-from-messages) — quality depends on your LLM; API may change. * [`subscribe()`](/docs/realtime-events) — still available; SQLite is same-process only. ## What this release does not claim [#what-this-release-does-not-claim] * Postgres telemetry store (not implemented) * Multi-process SQLite `subscribe()` * Graph memory / Neo4j (removed) * Application-layer auth — `organization` is a data namespace, not IAM ## Related pages [#related-pages] * [Production](/docs/guides/production) * [Migration](/docs/migration) * [Limitations](/docs/guides/limitations) * [Configuration](/docs/configuration) * [API Overview](/docs/api) --- # Overview > Connect Wolbarg to agent frameworks and AI SDKs without putting framework types in the core package. URL: /docs/integrations ## What is it? [#what-is-it] Wolbarg stays **framework-agnostic**. Official adapters live in separate packages and docs under **AI SDKs**. | Integration | Package | Docs | | --------------------- | --------------------- | --------------------------------------------- | | Vercel AI SDK | `@wolbarg/vercel-ai` | [Vercel AI SDK](/docs/integrations/vercel-ai) | | OpenAI Agents SDK | `@wolbarg/openai` | [OpenAI Agents](/docs/integrations/openai) | | LangChain / LangGraph | `@wolbarg/langchain` | [LangChain](/docs/integrations/langchain) | | LlamaIndexTS | `@wolbarg/llamaindex` | [LlamaIndex](/docs/integrations/llamaindex) | | Mastra | `@wolbarg/mastra` | [Mastra](/docs/integrations/mastra) | Each shipped package is a thin adapter: your agent stack runs; Wolbarg owns durable shared memory. ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [Example — Vercel AI memory](/docs/examples/vercel-ai-memory) --- # LangChain / LangGraph > Official @wolbarg/langchain — WolbargMemory (BaseMemory), WolbargStore (LangGraph BaseStore), and createWolbargTools. URL: /docs/integrations/langchain ## What is it? [#what-is-it] [`@wolbarg/langchain`](https://www.npmjs.com/package/@wolbarg/langchain) is the official [LangChain JS](https://js.langchain.com/) / [LangGraph JS](https://langchain-ai.github.io/langgraphjs/) adapter for Wolbarg shared memory. Two integration surfaces: 1. **`WolbargMemory`** — `@langchain/core` `BaseMemory` (legacy chain memory: recall on load, remember on save) 2. **`WolbargStore`** — LangGraph `BaseStore` (**preferred** long-term memory for multi-agent / durable graphs) Also: **`createWolbargTools`** — agent tools for `wolbarg_recall` / `wolbarg_remember`. Soft-fail by default: recall/remember/store errors never crash the chain or graph. Provenance metadata always includes `source: "wolbarg-langchain"`. Requires **Node ≥ 22**. ## Install [#install] ```bash npm install wolbarg @wolbarg/langchain @langchain/core @langchain/langgraph ``` Peers: `wolbarg >= 0.6.0`, `@langchain/core >= 0.3 || >= 1`, `@langchain/langgraph >= 0.2 || >= 1`. ## Quick start — BaseMemory [#quick-start--basememory] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { createWolbargMemory } from "@wolbarg/langchain"; const memory = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await memory.ready(); const chatMemory = createWolbargMemory({ memory, agent: "assistant", memoryKey: "history", sessionId: "chat-1", }); const vars = await chatMemory.loadMemoryVariables({ input: "What UI theme do I prefer?", }); // vars.history — formatted string (or BaseMessage[] when returnMessages: true) await chatMemory.saveContext( { input: "I prefer dark mode" }, { output: "Noted — dark mode it is." }, ); ``` ## Quick start — LangGraph BaseStore [#quick-start--langgraph-basestore] ```ts import { createWolbargStore } from "@wolbarg/langchain"; const store = createWolbargStore({ memory, agent: "assistant", }); await store.put(["users", "u1"], "prefs", { text: "dark mode" }); const item = await store.get(["users", "u1"], "prefs"); const hits = await store.search(["users"], { query: "theme preference", limit: 5, }); ``` Pass `store` into LangGraph as the long-term memory store (e.g. graph compile / store config). Prefer **`WolbargStore`** for new LangGraph apps; use **`WolbargMemory`** when you still need classic `BaseMemory` chains. ## Optional tools [#optional-tools] ```ts import { createWolbargTools } from "@wolbarg/langchain"; const tools = createWolbargTools({ memory, agent: "assistant" }); // [wolbarg_recall, wolbarg_remember] ``` ## Options [#options] ### WolbargMemory / createWolbargMemory [#wolbargmemory--createwolbargmemory] | Option | Default | Notes | | ---------------------------------------------------------- | ----------------- | ------------------------------------------------------ | | `memory` | required | Wolbarg instance | | `agent` | required | Agent id for recall/remember filters | | `memoryKey` | `"history"` | Key returned from `loadMemoryVariables` | | `inputKey` / `outputKey` | auto | Passed to LangChain `getInputValue` / `getOutputValue` | | `topK` | `5` | Recall limit | | `returnMessages` | `false` | Return `HumanMessage[]` instead of a string | | `formatContext` | default formatter | Custom string formatter for hits | | `rememberMode` | `"raw"` | Passed to `rememberFromMessages` | | `sessionId` / `userId` / `tags` / `namespace` / `metadata` | — | Copied onto stored metadata | | `onError` | — | Soft-fail hook | ### WolbargStore / createWolbargStore [#wolbargstore--createwolbargstore] | Method | Wolbarg mapping | | -------------------- | --------------------------------------------------------------------- | | `put` | `remember` (text from `value.text` / `value.data` / `JSON.stringify`) | | `get` | metadata key lookup (+ process cache) | | `delete` | `forget` by memory id | | `search` (+ `query`) | `recall` | | `batch` | abstract entry point (put/get/delete/search/listNamespaces) | Namespaces are stored in Wolbarg metadata (`storeNamespace`, `storeKey`, `storeValue`). ## Limitations [#limitations] * BaseMemory is legacy LCEL/chain memory — LangGraph apps should prefer `WolbargStore`. * Exact `get` after restart is best-effort via metadata-filtered recall; process-local cache is authoritative within a run. * Soft-fail means store/memory errors never crash the chain — wire `onError` for observability. ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [remember()](/docs/api/remember) * [recall()](/docs/api/recall) * [Limitations](/docs/guides/limitations) --- # LlamaIndexTS > Official @wolbarg/llamaindex — wolbargBlock / WolbargMemoryBlock for createMemory({ memoryBlocks }). URL: /docs/integrations/llamaindex ## What is it? [#what-is-it] [`@wolbarg/llamaindex`](https://www.npmjs.com/package/@wolbarg/llamaindex) is the official [LlamaIndexTS](https://ts.llamaindex.ai/) long-term memory block for Wolbarg shared memory. It wires Wolbarg into LlamaIndex’s `createMemory({ memoryBlocks })` API via `BaseMemoryBlock`: 1. **`get`** — recalls relevant memories from the last user message 2. **`put`** — persists conversation turns with `rememberFromMessages` Soft-fails by default so memory errors never break an agent turn. Requires **Node ≥ 22**. ## Install [#install] ```bash npm install wolbarg @wolbarg/llamaindex llamaindex ``` Peers: `wolbarg >= 0.6.0`, `@llamaindex/core >= 0.6.0`, optional `llamaindex >= 0.9.0`. ## Quick start [#quick-start] ```ts import { createMemory } from "llamaindex"; import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { wolbargBlock } from "@wolbarg/llamaindex"; const client = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await client.ready(); const memory = createMemory({ memoryBlocks: [ wolbargBlock({ memory: client, agent: "assistant", sessionId: "demo-session", }), ], }); await memory.add({ role: "user", content: "I prefer dark mode." }); await memory.manageMemoryBlocks(); const messages = await memory.getLLM(); ``` `wolbargBlock` mirrors LlamaIndex’s `staticBlock` / `vectorBlock` naming. `createWolbargMemoryBlock` is an alias for `WolbargMemoryBlock`. ## Options [#options] | Option | Default | Description | | --------------------------------------------- | ------------- | ------------------------------------------------ | | `memory` | required | Wolbarg client | | `agent` | required | Agent id for recall filter + remember | | `id` | auto UUID | Block id | | `priority` | `1` | LlamaIndex block priority (`0` = always include) | | `isLongTerm` | `true` | Long-term block flag | | `topK` | `5` | Recall limit | | `threshold` | — | Minimum similarity | | `sessionId` / `userId` / `tags` / `namespace` | — | Attached to remember metadata | | `metadata` | `{}` | Extra remember metadata | | `formatContext` | default list | Format recall hits → memory message text | | `rememberMode` | `"raw"` | `"raw"` or `"extract"` | | `rawStrategy` | `"last_user"` | `"last_user"` or `"all_user"` | | `onError` | — | Soft-fail hook `(error, phase)` | ### Behavior [#behavior] | Method | Behavior | | ---------------- | ---------------------------------------------------------------------------------------------- | | `get(messages?)` | Query = last user message text → `memory.recall` → one `{ role: "memory", content }` (or `[]`) | | `put(messages)` | Convert to conversation turns (skips `memory` role) → `rememberFromMessages` | | Errors | Soft-fail: `get` → `[]`, `put` → no throw; optional `onError` | Remembered rows include `metadata.source = "wolbarg-llamaindex"`. ## Config tips [#config-tips] ```ts wolbargBlock({ memory: client, agent: "assistant", topK: 8, threshold: 0.35, rememberMode: "raw", rawStrategy: "last_user", formatContext: (hits) => hits.map((h) => `- ${h.content.text}`).join("\n"), onError: (err, phase) => console.warn("[wolbarg]", phase, err), }); ``` ## Limitations [#limitations] * Recall query uses the **last user** message only (not a multi-turn window). * `put` skips messages with role `"memory"` and empty content. * Does not replace LlamaIndex short-term chat buffer — use alongside `createMemory`. * Requires Node ≥ 22 and Wolbarg ≥ 0.5.5 (`rememberFromMessages`). ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [rememberFromMessages()](/docs/api/remember-from-messages) * [recall()](/docs/api/recall) * [Limitations](/docs/guides/limitations) --- # Mastra > Official @wolbarg/mastra Processor — createWolbargProcessor for shared semantic recall and remember (not a Storage rewrite). URL: /docs/integrations/mastra ## What is it? [#what-is-it] [`@wolbarg/mastra`](https://www.npmjs.com/package/@wolbarg/mastra) is the official [Mastra](https://mastra.ai/) **Processor** for Wolbarg shared semantic memory. It automatically: 1. **Recalls** relevant memories in `processInput` (from the last user text in `content.parts`) 2. **Injects** them as a system message (preferred) or a prepended memory message 3. **Remembers** the conversation in `processOutputResult` via `rememberFromMessages` This is **not** a Mastra Storage / Memory rewrite. Keep [Mastra Memory](https://mastra.ai/docs/memory/overview) for thread history if you want it; add this processor for **shared semantic memory across agents**. Requires **`@mastra/core` ≥ 1.0** (Processor API) and **Node ≥ 22**. ## Install [#install] ```bash npm install wolbarg @wolbarg/mastra @mastra/core ``` Peers: `wolbarg >= 0.6.0`, `@mastra/core >= 1.0.0`. Optional peer: `@mastra/memory` (thread history only — not required by this package). ## Quick start [#quick-start] ```ts import { Agent } from "@mastra/core/agent"; import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { createWolbargProcessor } from "@wolbarg/mastra"; const memory = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await memory.ready(); // One instance for both input + output hooks const wolbargMem = createWolbargProcessor({ memory, agent: "assistant", sessionId: "optional-session", }); const agent = new Agent({ id: "assistant", name: "Assistant", instructions: "You are a helpful assistant.", model: "openai/gpt-4.1-mini", inputProcessors: [wolbargMem], outputProcessors: [wolbargMem], }); const result = await agent.generate("What UI theme do I prefer?"); console.log(result.text); ``` Alias: `wolbargProcessor` === `createWolbargProcessor`. Register the **same** processor instance in **both** `inputProcessors` and `outputProcessors` — Mastra runs input and output hooks from separate lists. ## Options [#options] | Option | Default | Description | | --------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------ | | `memory` | — | Wolbarg instance (**required**) | | `agent` | — | Agent id for recall filter / remember (**required**) | | `id` | `"wolbarg-memory"` | Processor `id` | | `recall` | `true` | Run recall in `processInput` | | `remember` | `true` | Run remember in `processOutputResult` | | `topK` | `5` | Recall hit count | | `injection` | `"system"` | `"system"` appends to `systemMessages`; `"message"` prepends a system-role MastraDBMessage | | `sessionId` / `userId` / `tags` / `namespace` | — | Stored on remember metadata | | `metadata` | `{}` | Extra remember metadata (`source: "wolbarg-mastra"` always set) | | `formatContext` | default bullet list | Format recall hits into prompt text | | `onError` | — | `(error, phase) => void` | | `onTelemetry` | — | Soft telemetry events for recall / inject / remember | ## With Mastra Memory (optional) [#with-mastra-memory-optional] ```ts import { Memory } from "@mastra/memory"; const agent = new Agent({ // ... memory: new Memory({ /* thread / working memory */ }), inputProcessors: [wolbargMem], outputProcessors: [wolbargMem], }); ``` Mastra Memory handles conversation threads. Wolbarg handles cross-agent semantic recall. ## Soft-fail [#soft-fail] Recall and remember failures **never crash** agent generation. Use `onError` / `onTelemetry` for observability. ## Limitations [#limitations] * Not a Mastra Storage rewrite — thread history stays with Mastra Memory if you use it. * Text extraction iterates `content.parts` where `type === "text"` (`MastraDBMessage` format 2). * You must put the same instance in both processor arrays; input-only or output-only registration skips half the lifecycle. ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [rememberFromMessages()](/docs/api/remember-from-messages) * [recall()](/docs/api/recall) * [Limitations](/docs/guides/limitations) --- # OpenAI Agents SDK > Official @wolbarg/openai Session — persist AgentInputItem history, semantic remember, and recall injection via createWolbargSessionInputCallback. URL: /docs/integrations/openai ## What is it? [#what-is-it] [`@wolbarg/openai`](https://www.npmjs.com/package/@wolbarg/openai) is the official [OpenAI Agents SDK](https://openai.github.io/openai-agents-js/) `Session` for Wolbarg shared memory. It automatically: 1. **Persists** conversation `AgentInputItem[]` as a single Wolbarg session snapshot 2. **Hydrates** that snapshot when you resume with the same `sessionId` 3. **Remembers** user/assistant text as semantic memories on `addItems` (optional) 4. **Recalls** relevant memories via `createWolbargSessionInputCallback` before the model call Drop-in for `MemorySession` — same `Session` surface the runner expects. Requires **`@openai/agents` ≥ 0.13.0** and **Node ≥ 22**. ## Install [#install] ```bash npm install wolbarg @wolbarg/openai @openai/agents ``` Peers: `wolbarg >= 0.6.0`, `@openai/agents >= 0.13.0`. ## Quick start [#quick-start] ```ts import { Agent, run } from "@openai/agents"; import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { createWolbargSession, createWolbargSessionInputCallback, } from "@wolbarg/openai"; const memory = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await memory.ready(); const session = await createWolbargSession({ memory, agent: "assistant", sessionId: "chat-1", }); const agent = new Agent({ name: "Assistant", instructions: "Be concise.", }); await run(agent, "What UI theme do I prefer?", { session, sessionInputCallback: createWolbargSessionInputCallback({ memory, agent: "assistant", }), }); ``` ## WolbargSession [#wolbargsession] Implements the Agents SDK `Session` interface: | Method | Behavior | | ------------------ | -------------------------------------------------------------- | | `getSessionId()` | Returns the stable session id | | `getItems(limit?)` | Returns cloned history (most recent `limit` when set) | | `addItems(items)` | Append locally → persist snapshot → optional semantic remember | | `popItem()` | Pop newest locally → persist snapshot | | `clearSession()` | Clear local items + soft-fail forget snapshot | ```ts import { WolbargSession } from "@wolbarg/openai"; const session = new WolbargSession({ memory, agent: "assistant", sessionId: "chat-1", // omit to auto-generate (no hydrate) semanticRemember: true, // default userId: "u1", tags: ["support"], onError: (err, phase) => console.warn(phase, err), }); await session.ready(); // await soft-fail hydration ``` `createWolbargSession(options)` constructs `WolbargSession` and awaits hydration. ## Semantic recall injection [#semantic-recall-injection] `createWolbargSessionInputCallback` returns a `SessionInputCallback` for `run(..., { sessionInputCallback })`: 1. Takes the last user text from `newItems` 2. Soft-fail `memory.recall` 3. Injects `{ role: "system", content }` when hits exist 4. Returns `[system?, ...historyItems, ...newItems]` Use when the turn input is an `AgentInputItem[]` (string inputs merge history automatically; the callback is optional then). ## Options [#options] | Option | Default | Notes | | -------------------------------------------- | ----------- | ----------------------------------------------------------------------------- | | `memory` | required | Wolbarg instance | | `agent` | required | Agent id for snapshot + semantic memories | | `sessionId` | random UUID | When provided, constructor hydrates from Wolbarg | | `semanticRemember` | `true` | Store user/assistant text on `addItems` | | `topK` | `5` | Used by `createWolbargSessionInputCallback` | | `userId` / `tags` / `namespace` / `metadata` | — | Copied onto stored metadata | | `onError` | — | Soft-fail hook (`recall` \| `remember` \| `persist` \| `hydrate` \| `forget`) | Provenance metadata always includes `source: "wolbarg-openai"`. Session snapshots also set `kind: "wolbarg-session"`. ## Soft-fail [#soft-fail] Snapshot persistence and semantic remember **never throw** into the Agents SDK run path. Wire `onError` for observability. ## Limitations [#limitations] * Hydration finds the snapshot via filtered `recall` (metadata `kind` + `sessionId`). Extremely noisy corpora may need a dedicated agent namespace for session rows. * `forget({ filter: { agent } })` would wipe all agent memories — `clearSession` forgets **by snapshot id** only. * Does not implement optional Session extensions (`applyHistoryMutations`, compaction hooks). * Multimodal user parts become text + `[attachment:…]` placeholders for semantic remember / recall queries. ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [remember()](/docs/api/remember) * [recall()](/docs/api/recall) * [Limitations](/docs/guides/limitations) --- # Vercel AI SDK > Official @wolbarg/vercel-ai middleware — automatic recall, system injection, and remember with generateText and streamText (AI SDK v7+). URL: /docs/integrations/vercel-ai ## What is it? [#what-is-it] [`@wolbarg/vercel-ai`](https://www.npmjs.com/package/@wolbarg/vercel-ai) is the official AI SDK Language Model Middleware for Wolbarg. It follows the same pattern the AI SDK documents for RAG, logging, and guardrails: * **`transformParams`** — recall + inject memory into a tagged system message * **`wrapGenerate` / `wrapStream`** — remember after the model step finishes The core `wolbarg` package stays framework-agnostic. This package is the only place that depends on `ai`. Requires **AI SDK v7+** (`LanguageModelV4` middleware). ## Install [#install] ```bash npm install wolbarg @wolbarg/vercel-ai ai @ai-sdk/openai ``` Requires **Node ≥ 22.5**, `wolbarg >= 0.6.0`, and `ai ^7.0.0`. ## Quick start [#quick-start] ```ts import { generateText, wrapLanguageModel } from "ai"; import { openai } from "@ai-sdk/openai"; import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { wolbargMiddleware } from "@wolbarg/vercel-ai"; const memory = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await memory.ready(); const model = wrapLanguageModel({ model: openai("gpt-4.1-mini"), middleware: wolbargMiddleware({ memory, agent: "assistant", }), }); const { text } = await generateText({ model, system: "You are a concise assistant.", // preserved messages: [{ role: "user", content: "What do I prefer?" }], }); ``` Convenience helper: ```ts import { createWolbargModel } from "@wolbarg/vercel-ai"; const model = createWolbargModel({ model: openai("gpt-4.1-mini"), memory, agent: "assistant", }); ``` ## Streaming [#streaming] ```ts import { streamText } from "ai"; const result = streamText({ model, // already wrapped with wolbargMiddleware messages, }); for await (const chunk of result.textStream) { process.stdout.write(chunk); } ``` Remember starts when the model emits **`finish`** (with a flush backup). Canceling after finish still persists memory. Canceling mid-generation before `finish` does not remember incomplete turns. ## Tools / multi-step [#tools--multi-step] Middleware runs **per model step**. By default `remember: "final-step"` skips intermediate steps where `finishReason.unified === "tool-calls"`, so tool loops do not spam duplicate memories. Recall still runs every step so tools see memory context. ```ts wolbargMiddleware({ memory, agent: "assistant", remember: "final-step", // default — or "every-step" | "never" | false }); ``` ## Per-request metadata [#per-request-metadata] ```ts await generateText({ model, messages, providerOptions: { wolbarg: { sessionId: "s1", userId: "u1", tags: ["support"], namespace: "prod", }, }, }); ``` These fold into `rememberFromMessages` metadata (`source: "wolbarg-vercel-ai"`). ## Multimodal messages [#multimodal-messages] User messages with file/image parts contribute `[attachment:mediaType:filename]` placeholders to the recall query so memory search still has text signal alongside captions. ## Failure semantics [#failure-semantics] Recall and remember failures **never crash** model generation. Use hooks: ```ts wolbargMiddleware({ memory, agent: "assistant", onError: (error, phase) => { console.warn("[wolbarg]", phase, error); }, onTelemetry: (event) => { // phase: recall | remember | inject }, }); ``` ## Options reference [#options-reference] | Option | Default | Meaning | | --------------------------------------------------------------------- | ------------------ | --------------------------------------------- | | `memory` | required | `Wolbarg` instance | | `agent` | required | Agent id for recall filter + remember | | `recall` | `true` | Run recall before generate/stream | | `remember` | `"final-step"` | When to persist after a step | | `topK` / `threshold` | `5` / unset | Recall knobs | | `injection` | `"system-prepend"` | Or `"system-append"` | | `rememberMode` | `"raw"` | Passed to experimental `rememberFromMessages` | | `formatContext` | built-in | Customize memory system text | | `filter` / `metadata` / `sessionId` / `userId` / `tags` / `namespace` | — | Scoping + stored metadata | ## Related pages [#related-pages] * [Example — Vercel AI memory](/docs/examples/vercel-ai-memory) * [rememberFromMessages()](/docs/api/remember-from-messages) * [Quick Start](/docs/quick-start) * [Limitations](/docs/guides/limitations) --- # Example — Basic Memory > Minimal remember and recall with SQLite and OpenAI embeddings. URL: /docs/examples/basic-memory ## What is it? [#what-is-it] The smallest working Wolbarg program. ## Example usage [#example-usage] ```ts import { Wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await ctx.remember({ agent: "assistant", content: { text: "The deploy window is Fridays at 16:00 UTC." }, }); const hits = await ctx.recall({ query: "when can we deploy?", topK: 3 }); console.log(hits[0]?.content.text); await ctx.close(); ``` ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [remember()](/docs/api/remember) --- # Example — Compression > Summarize memories with an LLM via compress(). URL: /docs/examples/compression ```ts import { Wolbarg, sqlite, openaiEmbedding, openaiLlm } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), llm: openaiLlm({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }), }); await ctx.compress({ agent: "research" }); ``` ## Related pages [#related-pages] * [Compression Pipeline](/docs/compression) --- # Example — Conversation memory > Chat transcript → rememberFromMessages → recall without hand-rolled extraction. URL: /docs/examples/conversation-memory ## What is it? [#what-is-it] Side-by-side style demo vs “chat → facts → retrieve” libraries: pass messages into Wolbarg, then recall. Uses experimental [`rememberFromMessages()`](/docs/api/remember-from-messages). Default `mode: "raw"` needs **no LLM**. ## Example usage [#example-usage] ```ts import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); const messages = [ { role: "user", content: "I prefer dark mode in the IDE." }, { role: "assistant", content: "I'll remember that." }, { role: "user", content: "Also, only deploy on Fridays." }, ]; // Store the last user turn (default) await ctx.rememberFromMessages(messages, { agent: "assistant", mode: "raw", }); // Or store every user turn: await ctx.rememberFromMessages(messages, { agent: "assistant", mode: "raw", rawStrategy: "all_user", }); const hits = await ctx.recall({ query: "When can we deploy?", topK: 3, filter: { agent: "assistant" }, }); console.log(hits.map((h) => h.content.text)); await ctx.close(); ``` ## Optional extract mode [#optional-extract-mode] Pass `llm` at construction and `mode: "extract"` to pull atomic facts with your model. Extraction quality is **not** a Wolbarg product promise — you own the LLM. ## Related pages [#related-pages] * [rememberFromMessages()](/docs/api/remember-from-messages) * [Example — Vercel AI memory](/docs/examples/vercel-ai-memory) * [Quick Start](/docs/quick-start) --- # Example — Hybrid Search > Enable BM25 keyword search and fuse it with semantic recall. URL: /docs/examples/hybrid-search ```ts import { Wolbarg, sqlite, openaiEmbedding, bm25 } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), keywordSearch: bm25(), }); await ctx.remember({ agent: "ops", content: { text: "Incident INC-2048: Redis failover completed." }, }); const hits = await ctx.recall({ query: "INC-2048 failover", hybrid: { semanticWeight: 0.6, keywordWeight: 0.4 }, }); ``` ## Related pages [#related-pages] * [Hybrid Search](/docs/hybrid-search) --- # Example — Image Memory > Ingest a PNG with OCR and vision enrichment. URL: /docs/examples/image-memory ```bash npm install tesseract.js ``` ```ts import { Wolbarg, sqlite, openaiEmbedding, tesseract, geminiVision } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), ocr: tesseract(), vision: geminiVision({ apiKey: process.env.GEMINI_API_KEY! }), }); await ctx.ingest({ agent: "vision", source: { path: "./screenshot.png" }, }); ``` ## Related pages [#related-pages] * [Image Ingestion](/docs/image-ingestion) --- # Examples > Independent Wolbarg examples — basic memory, conversation bridge, Vercel AI adapter, hybrid search, storage backends, ingest, and providers. URL: /docs/examples ## What is it? [#what-is-it] Small, self-contained examples. Each page stands alone with copy-paste TypeScript. | Example | Link | | ------------------- | --------------------------------------------------------- | | Basic Memory | [basic-memory](/docs/examples/basic-memory) | | Conversation memory | [conversation-memory](/docs/examples/conversation-memory) | | Vercel AI memory | [vercel-ai-memory](/docs/examples/vercel-ai-memory) | | Hybrid Search | [hybrid-search](/docs/examples/hybrid-search) | | SQLite | [sqlite](/docs/examples/sqlite) | | PostgreSQL | [postgresql](/docs/examples/postgresql) | | Image Memory | [image-memory](/docs/examples/image-memory) | | PDF Memory | [pdf-memory](/docs/examples/pdf-memory) | | Metadata Filtering | [metadata-filtering](/docs/examples/metadata-filtering) | | Compression | [compression](/docs/examples/compression) | | Providers | [providers](/docs/examples/providers) | | Rerankers | [rerankers](/docs/examples/rerankers) | | OCR | [ocr](/docs/examples/ocr) | ## Related pages [#related-pages] * [Quick Start](/docs/quick-start) * [API Overview](/docs/api) --- # Example — Metadata Filtering > Scope recall with meta helpers and agent filters. URL: /docs/examples/metadata-filtering ```ts import { meta } from "wolbarg"; await ctx.remember({ agent: "sales", content: { text: "EU pricing starts at €49/seat." }, metadata: { region: "eu", priority: 3 }, }); const hits = await ctx.recall({ query: "pricing", filter: { agent: "sales", metadata: meta.and(meta.eq("region", "eu"), meta.gte("priority", 2)), }, }); ``` ## Related pages [#related-pages] * [Metadata Filtering](/docs/metadata-filtering) --- # Example — OCR > Extract text from images with tesseract during ingest. URL: /docs/examples/ocr ```bash npm install tesseract.js ``` ```ts import { Wolbarg, sqlite, openaiEmbedding, tesseract } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), ocr: tesseract(), }); await ctx.ingest({ agent: "ocr", source: { path: "./receipt.png" }, }); ``` ## Related pages [#related-pages] * [OCR](/docs/ocr) --- # Example — PDF Memory > Ingest a text-layer PDF into chunked memories. URL: /docs/examples/pdf-memory ```bash npm install pdf-parse@1.1.4 ``` ```ts import { Wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await ctx.ingest({ agent: "docs", source: { path: "./handbook.pdf" }, chunking: { strategy: "paragraph", chunkSize: 900, overlap: 100 }, metadata: { collection: "handbook" }, }); ``` ## Related pages [#related-pages] * [Document Ingestion](/docs/document-ingestion) --- # Example — PostgreSQL > Shared PostgreSQL storage with the pg peer dependency. URL: /docs/examples/postgresql ```bash npm install pg ``` ```ts import { Wolbarg, postgres, openaiEmbedding } from "wolbarg"; const ctx = new Wolbarg({ organization: "prod", storage: postgres({ connectionString: process.env.DATABASE_URL!, schema: "wolbarg", // maxPoolSize defaults to 20; remote TLS defaults to require }), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await ctx.ready(); ``` ## Related pages [#related-pages] * [PostgreSQL Backend](/docs/storage/postgresql) --- # Example — Providers > Mix OpenAI embeddings, Ollama LLM, and BM25 keyword search. URL: /docs/examples/providers ```ts import { Wolbarg, sqlite, openaiEmbedding, ollamaLlm, bm25, } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), llm: ollamaLlm({ apiKey: "ollama", model: "llama3.2" }), keywordSearch: bm25(), }); ``` ## Related pages [#related-pages] * [Provider Architecture](/docs/providers) --- # Example — Rerankers > Attach a Jina reranker and enable rerank on recall. URL: /docs/examples/rerankers ```ts import { Wolbarg, sqlite, openaiEmbedding, jinaReranker } from "wolbarg"; const ctx = new Wolbarg({ organization: "demo", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), reranker: jinaReranker({ apiKey: process.env.JINA_API_KEY! }), retrieval: { overFetchFactor: 4 }, }); await ctx.recall({ query: "refund policy", topK: 5, rerank: true }); ``` ## Related pages [#related-pages] * [Rerankers](/docs/rerankers) --- # Example — SQLite > File-backed and in-memory SQLite storage examples. URL: /docs/examples/sqlite ```ts import { Wolbarg, sqlite, openaiEmbedding } from "wolbarg"; const file = new Wolbarg({ organization: "demo", storage: sqlite("./agent-memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); const mem = new Wolbarg({ organization: "tests", storage: sqlite(":memory:"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); ``` ## Related pages [#related-pages] * [SQLite Backend](/docs/storage/sqlite) --- # Example — Vercel AI memory > Use @wolbarg/vercel-ai middleware with wrapLanguageModel for automatic recall and remember (AI SDK v7+). URL: /docs/examples/vercel-ai-memory ## What is it? [#what-is-it] Production path for apps on the [Vercel AI SDK](https://ai-sdk.dev/): wrap any provider model with [`wolbargMiddleware`](/docs/integrations/vercel-ai) so recall and remember happen automatically. Runnable copy: `examples/adapters/vercel-ai/` (`npm start`, `npm run start:stream`, `npm run start:tools`). Requires **AI SDK v7+**. ## Install [#install] ```bash npm install wolbarg @wolbarg/vercel-ai ai @ai-sdk/openai ``` ## Example usage [#example-usage] ```ts import { generateText, wrapLanguageModel } from "ai"; import { openai } from "@ai-sdk/openai"; import { wolbarg, sqlite, openaiEmbedding } from "wolbarg"; import { wolbargMiddleware } from "@wolbarg/vercel-ai"; const memory = wolbarg({ organization: "my-app", storage: sqlite("./memory.db"), embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }), }); await memory.ready(); const model = wrapLanguageModel({ model: openai("gpt-4.1-mini"), middleware: wolbargMiddleware({ memory, agent: "assistant", }), }); const { text } = await generateText({ model, messages: [{ role: "user", content: "What do I prefer?" }], }); ``` No manual `recall` / `remember` around `generateText` — the middleware owns that loop. ## Streaming + tools [#streaming--tools] ```bash cd examples/adapters/vercel-ai npm run start:stream # streamText npm run start:tools # multi-step tools, final-step remember ``` ## Related pages [#related-pages] * [Vercel AI integration](/docs/integrations/vercel-ai) * [rememberFromMessages()](/docs/api/remember-from-messages) * [Example — Conversation memory](/docs/examples/conversation-memory) * [Quick Start](/docs/quick-start) --- # Errors > Typed error hierarchy for Wolbarg 0.6 — ValidationError, RerankError, StorageLockedError, CancellationError, and more. URL: /docs/reference/errors ## Hierarchy [#hierarchy] * `WolbargError` — base * `ConfigurationError` — bad config * `ProviderNotConfiguredError` — method needs a missing provider (e.g. `compress` without `llm`) * `InitializationError` — open / probe failed * `ValidationError` — bad method arguments (including hybrid/rerank misconfig) * `DatabaseError` / `EmbeddingError` / `CompressionError` * `RerankError` — built-in reranker HTTP / empty ranking failure * `MemoryNotFoundError` * `VersionConflictError` — CAS mismatch on `expectedVersion` * `StorageLockedError` — code `WOLBARG_STORAGE_LOCKED` * `CancellationError` — AbortSignal cancelled an in-flight operation * `wrapOperationError` — helper to wrap unknown errors ## Fail-closed hybrid / rerank (0.6.0) [#fail-closed-hybrid--rerank-060] | Situation | Error | | -------------------------------------- | ----------------- | | `hybrid: true` without `keywordSearch` | `ValidationError` | | `rerank: true` without `reranker` | `ValidationError` | | Built-in reranker provider failure | `RerankError` | There is no silent semantic-only or identity-order fallback. See [Hybrid Search](/docs/hybrid-search) and [Rerankers](/docs/rerankers). ## WOLBARG\_STORAGE\_LOCKED [#wolbarg_storage_locked] Thrown when SQLite write-lock retries are exhausted under multi-process contention. | Field | Meaning | | ---------- | -------------------------------------------------------------------------------- | | Code | `WOLBARG_STORAGE_LOCKED` | | When | `BEGIN IMMEDIATE` / busy retries exceed `concurrency.maxRetries` | | Suggestion | Increase retries / `lockTimeoutMs`, reduce writer fan-out, or switch to Postgres | See [Concurrency](/docs/concurrency). ## CancellationError [#cancellationerror] Thrown when `signal` aborts during `remember` / `recall` / `update` / `compress` / `forget` (and related helpers). In-flight embedding HTTP aborts. ## Graph errors (removed) [#graph-errors-removed] `GraphCheckpointNotSupportedError` and graph-related `ProviderNotConfiguredError` examples are obsolete — graph memory was [removed in 0.6.0](/docs/graph-memory). ## Related pages [#related-pages] * [Types](/docs/reference/types) * [Concurrency](/docs/concurrency) * [API Overview](/docs/api) * [Production](/docs/guides/production) * [FAQ](/docs/faq) --- # init() Compatibility > v0.1 init() API remains supported as a shim. URL: /docs/reference/init-compat ## Usage [#usage] ```ts const ctx = new Wolbarg(); await ctx.init({ organization: "my-org", database: { provider: "sqlite", // or "postgres" connectionString: "./memory.db", }, embedding: { baseUrl: "https://api.openai.com/v1", apiKey: process.env.OPENAI_API_KEY!, model: "text-embedding-3-small", }, llm: { // optional in 0.2 baseUrl: "https://api.openai.com/v1", apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4.1-mini", }, }); ``` ## Notes [#notes] Prefer constructor DI + factories for new code. `init` maps `database` → storage and wires embedding / optional llm the same way. ## Related pages [#related-pages] * [Migration](/docs/migration) * [Wolbarg](/docs/api/wolbarg) --- # Types > Key public TypeScript types in Wolbarg. URL: /docs/reference/types ## Domain [#domain] ```ts MemoryRecord, MemoryContent, MemoryMetadata RecallResult, HistoryEvent, HistoryResult IngestResult, CompressResult, StatsResult ``` ## Options [#options] ```ts WolbargOptions, RememberOptions, RecallOptions IngestOptions, CompressOptions, ForgetOptions MemoryFilter, MetadataFilter, HybridConfig, MmrConfig ``` ## Providers [#providers] ```ts StorageProvider, EmbeddingProvider, LlmProvider KeywordSearchProvider, RerankerProvider OCRProvider, VisionProvider, ChunkingStrategy CompressionProvider ``` ## Related pages [#related-pages] * [API Reference](/docs/api/reference) * [Errors](/docs/reference/errors) --- # PostgreSQL Backend > Shared PostgreSQL storage with connection pooling, JSONB metadata, and optional pgvector. URL: /docs/storage/postgresql ## What is it? [#what-is-it] A `StorageProvider` implementation backed by PostgreSQL via the optional `pg` peer. Same public API as SQLite. ## Why does it exist? [#why-does-it-exist] Teams that already run Postgres, or need multi-process / multi-host readers and writers against one database. ## How does it work? [#how-does-it-work] ```bash npm install pg ``` ```ts import { postgres } from "wolbarg"; storage: postgres(process.env.DATABASE_URL!) // or storage: postgres({ connectionString: process.env.DATABASE_URL!, schema: "wolbarg", // optional namespaced deployment maxPoolSize: 20, // default since 0.6.0; raise only if the host allows }) ``` Features: * Connection pooling (default `maxPoolSize` **20**) * Remote hosts without `sslmode` / `ssl` in the URL get **`sslmode=require`** (loopback unchanged) * Optional `schema` for tables, indexes, and NOTIFY channels * JSONB metadata + GIN index * pgvector when the extension is available (BYTEA + cosine fallback otherwise) Install the optional `pg` peer before using `postgres()`. Operator details: [Production](/docs/guides/production). ## API parity [#api-parity] Both backends implement the same `StorageProvider` contract: insert, batch insert, update, delete, vector search, metadata listing, history, transactions, and migrations. Switch storage by changing one constructor option. ## When should it be used? [#when-should-it-be-used] Use PostgreSQL when multiple application instances share memory, or when you need central backups and ops. Use SQLite when the agent is single-node and file-based storage is enough. ## Related pages [#related-pages] * [SQLite Backend](/docs/storage/sqlite) * [Example — PostgreSQL](/docs/examples/postgresql) * [Limitations](/docs/guides/limitations) --- # SQLite Backend > Local-first SQLite storage with WAL, sqlite-vec vectors, and FTS5 keyword indexing. URL: /docs/storage/sqlite ## What is it? [#what-is-it] The default storage backend. Memories live in a single SQLite file (or `:memory:`) using Node's built-in `node:sqlite`. ## Why does it exist? [#why-does-it-exist] Zero infrastructure for development and most production single-node agents. No Docker, no managed DB — just a file. ## How does it work? [#how-does-it-work] ```ts import { sqlite } from "wolbarg"; storage: sqlite("./memory.db") // or storage: sqlite(":memory:") ``` Uses: * WAL mode for concurrent readers * Prepared statements * sqlite-vec when available (BLOB cosine fallback otherwise) * FTS5 for keyword indexing (schema v2) ## When should it be used? [#when-should-it-be-used] Prefer SQLite for local agents, demos, CI, and single-machine services. Move to [PostgreSQL](/docs/storage/postgresql) when you need multi-host access or central ops tooling. ## Performance notes [#performance-notes] * Cold start is typically single-digit milliseconds in published benchmarks * Database size scales roughly linearly with memory count (\~2.6 MB / 1k records in mock embedding suites) * Hybrid BM25 needs `keywordSearch: bm25()` so FTS stays in sync ## Related pages [#related-pages] * [PostgreSQL Backend](/docs/storage/postgresql) * [Configuration](/docs/configuration) * [Example — SQLite](/docs/examples/sqlite) * [Performance](/docs/performance) --- # Generated Exports > Compact auto-generated catalog of public exports from the Wolbarg package entrypoint. URL: /docs/api/reference/generated ## What is it? [#what-is-it] Machine-generated list of every public symbol re-exported from `wolbarg` (`sdk/src/index.ts`). Prefer [curated API pages](/docs/api) for how-to docs; use this page for exhaustive symbol coverage (LLMs, grepping, audits). Generated **191** exports. ## Public exports [#public-exports] | Export | | --------------------------------- | | `applyEnvFile` | | `assertEmbeddingPreset` | | `BenchmarkReport` | | `BenchmarkSample` | | `bgeReranker` | | `bm25` | | `CancellationError` | | `ChatMessage` | | `CheckpointInfo` | | `CheckpointMeta` | | `CheckpointOptions` | | `CheckpointProvider` | | `Chunk` | | `ChunkingOptions` | | `ChunkingStrategy` | | `ClearOptions` | | `cohereReranker` | | `CompressionError` | | `CompressionProvider` | | `CompressOptions` | | `CompressResult` | | `ConcurrencyConfig` | | `ConfigurationError` | | `ConversationMessage` | | `CreateCheckpointOptions` | | `createChunkingStrategy` | | `createCompressionProvider` | | `createDatabaseProvider` | | `createEmbeddingProvider` | | `CreateFromProjectConfigOptions` | | `createLlmProvider` | | `createStorageProvider` | | `createTelemetryProvider` | | `createWolbarg` | | `createWolbargFromProjectConfig` | | `crossEncoder` | | `DatabaseConfig` | | `DatabaseError` | | `DatabaseProvider` | | `DatabaseProviderName` | | `DEFAULT_CONFIG_PATH` | | `DEFAULT_ENV_PATH` | | `DEFAULT_ORGANIZATION` | | `DEFAULT_SQLITE_DB_PATH` | | `defaultProjectConfig` | | `EMBEDDING_PROVIDER_PRESETS` | | `EmbeddingCacheConfig` | | `EmbeddingConfig` | | `EmbeddingError` | | `EmbeddingProvider` | | `EmbeddingProviderId` | | `EmbeddingProviderPreset` | | `EventDatabase` | | `ExportResult` | | `FixedChunkingStrategy` | | `ForgetByFilterOptions` | | `ForgetByIdOptions` | | `ForgetOptions` | | `geminiEmbedding` | | `geminiVision` | | `getEmbeddingProviderPreset` | | `HeadingChunkingStrategy` | | `HistoryEvent` | | `HistoryOptions` | | `HistoryResult` | | `HybridConfig` | | `ImportResult` | | `IngestOptions` | | `IngestResult` | | `InitializationError` | | `InitOptions` | | `jinaReranker` | | `KeywordDocument` | | `KeywordSearchHit` | | `KeywordSearchProvider` | | `LatencyBreakdown` | | `LlmCompressionProvider` | | `LlmConfig` | | `LlmProvider` | | `lmStudioEmbedding` | | `loadProjectConfig` | | `MarkdownChunkingStrategy` | | `MAX_MEMORY_CONTENT_CHARS` | | `MAX_METADATA_JSON_BYTES` | | `MemoryChangeCallback` | | `MemoryChangeEvent` | | `MemoryContent` | | `MemoryDedupeConfig` | | `MemoryDedupeStrategy` | | `MemoryFilter` | | `MemoryMetadata` | | `MemoryNotFoundError` | | `MemoryProvider` | | `MemoryRecord` | | `meta` | | `MetadataComparison` | | `MetadataFilter` | | `MetaFilter` | | `MmrConfig` | | `NoopTelemetryProvider` | | `OCRProvider` | | `OcrResult` | | `ollamaEmbedding` | | `ollamaLlm` | | `openaiCompatibleEmbedding` | | `openaiCompatibleLlm` | | `openaiEmbedding` | | `openaiLlm` | | `openaiReranker` | | `openaiVision` | | `openRouterEmbedding` | | `openRouterLlm` | | `ParagraphChunkingStrategy` | | `PersistedRecallExplainPayload` | | `postgres` | | `postgresConfig` | | `PostgresDatabaseConfig` | | `PostgresStorageProvider` | | `projectConfigToWolbargOptions` | | `ProviderNotConfiguredError` | | `RecallExplainResponse` | | `RecallExplanationHit` | | `RecallOptions` | | `RecallResult` | | `RememberAction` | | `RememberFromMessagesOptions` | | `RememberFromMessagesRawStrategy` | | `RememberOptions` | | `RememberResult` | | `RerankDocument` | | `RerankerProvider` | | `RerankError` | | `RerankHit` | | `resolveConfigPath` | | `resolveEmbeddingApiKey` | | `resolveEnvPath` | | `RetrievalConfig` | | `runBenchmark` | | `saveProjectConfig` | | `SaveProjectConfigOptions` | | `SDK_VERSION` | | `SentenceChunkingStrategy` | | `sqlite` | | `sqliteCheckpoint` | | `SqliteCheckpointProvider` | | `sqliteConfig` | | `SqliteDatabaseConfig` | | `SqliteDatabaseProvider` | | `SqliteEventDatabase` | | `SqliteStorageProvider` | | `sqliteTelemetry` | | `SqliteTelemetryProvider` | | `StageSpan` | | `StatsResult` | | `StorageConfig` | | `StorageLockedError` | | `StorageProvider` | | `StorageProviderName` | | `SubscribableEvent` | | `SubscribeFilter` | | `summarizeBenchmark` | | `TelemetryConfig` | | `TelemetryEmitter` | | `TelemetryEvent` | | `TelemetryEventInput` | | `TelemetryLogLevel` | | `TelemetryOperation` | | `TelemetryProvider` | | `TelemetryQuery` | | `TelemetryQueryResult` | | `TelemetryStatus` | | `tesseract` | | `togetherEmbedding` | | `Unsubscribe` | | `upsertEnvVar` | | `ValidationError` | | `VersionConflictError` | | `VisionProvider` | | `VisionResult` | | `vllmEmbedding` | | `wolbarg` | | `Wolbarg` | | `WolbargError` | | `WolbargLogger` | | `WolbargOptions` | | `WolbargOptionsWithLlm` | | `WolbargOptionsWithoutLlm` | | `WolbargProjectConfig` | | `WolbargProjectDatabaseConfig` | | `WolbargProjectEmbeddingConfig` | | `wrapOperationError` | ## Related pages [#related-pages] * [API Overview](/docs/api) * [Wolbarg](/docs/api/wolbarg) * [Configuration](/docs/configuration) * [Types](/docs/reference/types) * [Errors](/docs/reference/errors) * [Provider Architecture](/docs/providers) --- # API Reference > Export catalog and curated method pages for the wolbarg package. URL: /docs/api/reference ## What is it? [#what-is-it] Two layers of API docs: 1. **Curated method pages** — how to use `remember`, `recall`, graph, lifecycle, etc. 2. **[Generated Exports](/docs/api/reference/generated)** — exhaustive list of every public symbol from `sdk/src/index.ts` (compact table; regenerate with `npm run docs:api`). Prefer curated pages for learning. Use the generated catalog when you need symbol coverage for tools and LLMs. ### Start here [#start-here] * [Wolbarg](/docs/api/wolbarg) * [remember()](/docs/api/remember) * [recall()](/docs/api/recall) * [Types](/docs/reference/types) * [Errors](/docs/reference/errors) Regenerate the export catalog: ```bash npm run docs:api ``` ## Related pages [#related-pages] * [API Overview](/docs/api) * [Configuration](/docs/configuration)