wolbarg 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -42,6 +42,11 @@ var WolbargError = class extends Error {
42
42
  reason;
43
43
  suggestion;
44
44
  operation;
45
+ /**
46
+ * @param message - Human-readable error message.
47
+ * @param code - Stable error code string.
48
+ * @param options - Optional cause, reason, suggestion, and operation name.
49
+ */
45
50
  constructor(message, code, options) {
46
51
  super(message, options);
47
52
  this.name = "WolbargError";
@@ -53,48 +58,80 @@ var WolbargError = class extends Error {
53
58
  }
54
59
  };
55
60
  var InitializationError = class extends WolbargError {
61
+ /**
62
+ * @param message - Description of the initialization failure.
63
+ * @param options - Optional cause and structured hints.
64
+ */
56
65
  constructor(message, options) {
57
66
  super(message, "INITIALIZATION_ERROR", options);
58
67
  this.name = "InitializationError";
59
68
  }
60
69
  };
61
70
  var ConfigurationError = class extends WolbargError {
71
+ /**
72
+ * @param message - Description of the misconfiguration.
73
+ * @param options - Optional cause, reason, suggestion, and operation name.
74
+ */
62
75
  constructor(message, options) {
63
76
  super(message, "CONFIGURATION_ERROR", options);
64
77
  this.name = "ConfigurationError";
65
78
  }
66
79
  };
67
80
  var ValidationError = class extends WolbargError {
81
+ /**
82
+ * @param message - Which argument failed and why.
83
+ * @param options - Optional cause and structured hints.
84
+ */
68
85
  constructor(message, options) {
69
86
  super(message, "VALIDATION_ERROR", options);
70
87
  this.name = "ValidationError";
71
88
  }
72
89
  };
73
90
  var DatabaseError = class extends WolbargError {
91
+ /**
92
+ * @param message - Operation-scoped failure message.
93
+ * @param options - Optional underlying `cause` and hints.
94
+ */
74
95
  constructor(message, options) {
75
96
  super(message, "DATABASE_ERROR", options);
76
97
  this.name = "DatabaseError";
77
98
  }
78
99
  };
79
100
  var StorageLockedError = class extends WolbargError {
101
+ /**
102
+ * @param message - Lock contention description.
103
+ * @param options - Typically includes suggestion to tune concurrency or use Postgres.
104
+ */
80
105
  constructor(message, options) {
81
106
  super(message, "WOLBARG_STORAGE_LOCKED", options);
82
107
  this.name = "StorageLockedError";
83
108
  }
84
109
  };
85
110
  var EmbeddingError = class extends WolbargError {
111
+ /**
112
+ * @param message - Embedding failure description.
113
+ * @param options - Optional HTTP cause and provider hints.
114
+ */
86
115
  constructor(message, options) {
87
116
  super(message, "EMBEDDING_ERROR", options);
88
117
  this.name = "EmbeddingError";
89
118
  }
90
119
  };
91
120
  var CompressionError = class extends WolbargError {
121
+ /**
122
+ * @param message - Compression failure description.
123
+ * @param options - Optional LLM cause chain.
124
+ */
92
125
  constructor(message, options) {
93
126
  super(message, "COMPRESSION_ERROR", options);
94
127
  this.name = "CompressionError";
95
128
  }
96
129
  };
97
130
  var MemoryNotFoundError = class extends WolbargError {
131
+ /**
132
+ * @param message - Which memory was not found.
133
+ * @param options - Optional operation context.
134
+ */
98
135
  constructor(message, options) {
99
136
  super(message, "MEMORY_NOT_FOUND", options);
100
137
  this.name = "MemoryNotFoundError";
@@ -102,6 +139,11 @@ var MemoryNotFoundError = class extends WolbargError {
102
139
  };
103
140
  var ProviderNotConfiguredError = class extends ConfigurationError {
104
141
  provider;
142
+ /**
143
+ * @param provider - Provider name (e.g. `"reranker"`, `"graph"`).
144
+ * @param method - Facade method that requires the provider.
145
+ * @param hint - Install or config instruction shown to the developer.
146
+ */
105
147
  constructor(provider, method, hint) {
106
148
  super(`${method} requires ${provider} \u2014 ${hint}`, {
107
149
  operation: method,
@@ -113,6 +155,10 @@ var ProviderNotConfiguredError = class extends ConfigurationError {
113
155
  }
114
156
  };
115
157
  var GraphCheckpointNotSupportedError = class extends WolbargError {
158
+ /**
159
+ * @param backend - Graph backend name (e.g. `"neo4j"`).
160
+ * @param operation - Requested operation (e.g. `"checkpoint"`).
161
+ */
116
162
  constructor(backend, operation) {
117
163
  super(
118
164
  `graph checkpoint not supported for network-backed graph providers (${backend})`,
@@ -185,9 +231,11 @@ Rules:
185
231
  var LlmCompressionProvider = class {
186
232
  name = "llm";
187
233
  llm;
234
+ /** @param llm - Configured LLM used for summarization. */
188
235
  constructor(llm) {
189
236
  this.llm = llm;
190
237
  }
238
+ /** @inheritdoc */
191
239
  async compress(memories) {
192
240
  return compressMemories(this.llm, memories);
193
241
  }
@@ -296,6 +344,7 @@ function slidingWindow(text, chunkSize, overlap) {
296
344
  }
297
345
  var FixedChunkingStrategy = class {
298
346
  name = "fixed";
347
+ /** @inheritdoc */
299
348
  chunk(text, options) {
300
349
  const { chunkSize, overlap } = clampOptions(options);
301
350
  return slidingWindow(text, chunkSize, overlap);
@@ -303,6 +352,7 @@ var FixedChunkingStrategy = class {
303
352
  };
304
353
  var SentenceChunkingStrategy = class {
305
354
  name = "sentence";
355
+ /** @inheritdoc */
306
356
  chunk(text, options) {
307
357
  const { chunkSize, overlap } = clampOptions(options);
308
358
  const sentences = text.split(/(?<=[.!?])\s+/).map((s) => s.trim()).filter(Boolean);
@@ -311,6 +361,7 @@ var SentenceChunkingStrategy = class {
311
361
  };
312
362
  var ParagraphChunkingStrategy = class {
313
363
  name = "paragraph";
364
+ /** @inheritdoc */
314
365
  chunk(text, options) {
315
366
  const { chunkSize, overlap } = clampOptions(options);
316
367
  const paragraphs = text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
@@ -319,6 +370,7 @@ var ParagraphChunkingStrategy = class {
319
370
  };
320
371
  var MarkdownChunkingStrategy = class {
321
372
  name = "markdown";
373
+ /** @inheritdoc */
322
374
  chunk(text, options) {
323
375
  const { chunkSize, overlap } = clampOptions(options);
324
376
  const sections = text.split(/(?=^#{1,6}\s)/m).map((s) => s.trim()).filter(Boolean);
@@ -330,6 +382,7 @@ var MarkdownChunkingStrategy = class {
330
382
  };
331
383
  var HeadingChunkingStrategy = class {
332
384
  name = "heading";
385
+ /** @inheritdoc */
333
386
  chunk(text, options) {
334
387
  return new MarkdownChunkingStrategy().chunk(text, options);
335
388
  }
@@ -411,6 +464,12 @@ function distanceToSimilarity(distance) {
411
464
  }
412
465
  var AsyncMutex = class {
413
466
  chain = Promise.resolve();
467
+ /**
468
+ * Run `fn` exclusively — concurrent callers queue on the same mutex.
469
+ *
470
+ * @param fn - Async or sync work to serialize.
471
+ * @returns The value returned by `fn`.
472
+ */
414
473
  async runExclusive(fn) {
415
474
  let release;
416
475
  const next = new Promise((resolve) => {
@@ -434,16 +493,32 @@ function joinUrl(baseUrl, path8) {
434
493
 
435
494
  // src/embedding/index.ts
436
495
  var OpenAICompatibleEmbeddingProvider = class {
496
+ /** Model name sent in the request body. */
437
497
  model;
438
498
  baseUrl;
439
499
  apiKey;
440
500
  timeoutMs;
501
+ /**
502
+ * @param config - OpenAI-compatible embedding endpoint settings.
503
+ * @param config.baseUrl - API root, e.g. `https://api.openai.com/v1`.
504
+ * @param config.apiKey - Bearer token. Use any non-empty string for local
505
+ * servers that ignore auth.
506
+ * @param config.model - Embedding model id (e.g. `"text-embedding-3-small"`).
507
+ * @param config.timeoutMs - Abort after this many ms. Defaults to `30_000`.
508
+ */
441
509
  constructor(config) {
442
510
  this.baseUrl = config.baseUrl;
443
511
  this.apiKey = config.apiKey;
444
512
  this.model = config.model;
445
513
  this.timeoutMs = config.timeoutMs ?? 3e4;
446
514
  }
515
+ /**
516
+ * Embed a single string.
517
+ *
518
+ * @param text - Input text.
519
+ * @returns Embedding vector.
520
+ * @throws {EmbeddingError} On HTTP errors, timeouts, or empty vectors.
521
+ */
447
522
  async embed(text) {
448
523
  const response = await this.request(text);
449
524
  const vector = response.data?.[0]?.embedding;
@@ -452,6 +527,13 @@ var OpenAICompatibleEmbeddingProvider = class {
452
527
  }
453
528
  return Float32Array.from(vector);
454
529
  }
530
+ /**
531
+ * Embed multiple strings in one API call when the server supports batch input.
532
+ * Falls back to sequential {@link embed} if the response length mismatches.
533
+ *
534
+ * @param texts - Inputs to embed.
535
+ * @returns One vector per input, same order.
536
+ */
455
537
  async embedBatch(texts) {
456
538
  if (texts.length === 0) {
457
539
  return [];
@@ -478,6 +560,12 @@ var OpenAICompatibleEmbeddingProvider = class {
478
560
  return Float32Array.from(item.embedding);
479
561
  });
480
562
  }
563
+ /**
564
+ * Probe the endpoint and report vector dimensionality.
565
+ *
566
+ * @returns `{ dimensions }` from a fixed health-check string.
567
+ * @throws {EmbeddingError} When the probe fails.
568
+ */
481
569
  async validate() {
482
570
  try {
483
571
  const embedding = await this.embed("Wolbarg health check");
@@ -492,6 +580,12 @@ var OpenAICompatibleEmbeddingProvider = class {
492
580
  );
493
581
  }
494
582
  }
583
+ /**
584
+ * Low-level HTTP request to `/embeddings`.
585
+ *
586
+ * @param input - Single string or batch of strings.
587
+ * @returns Parsed OpenAI-style JSON body.
588
+ */
495
589
  async request(input) {
496
590
  const url = joinUrl(this.baseUrl, "/embeddings");
497
591
  const controller = new AbortController();
@@ -539,6 +633,7 @@ var OpenAICompatibleEmbeddingProvider = class {
539
633
  clearTimeout(timer);
540
634
  }
541
635
  }
636
+ /** @param error - Unknown thrown value. @returns Human-readable message. */
542
637
  describe(error) {
543
638
  if (error instanceof Error) {
544
639
  return error.message;
@@ -795,6 +890,10 @@ var SqliteEmbeddingCacheStore = class {
795
890
  pendingSets = /* @__PURE__ */ new Map();
796
891
  persistScheduled = false;
797
892
  stmts = null;
893
+ /**
894
+ * @param dbOrGetter - SQLite `DatabaseSync` or lazy getter (allows late bind).
895
+ * @param options.ttlMs - Optional TTL for cache entries on read.
896
+ */
798
897
  constructor(dbOrGetter, options) {
799
898
  this.ttlMs = options?.ttlMs ?? null;
800
899
  this.getDb = typeof dbOrGetter === "function" ? dbOrGetter : () => dbOrGetter;
@@ -1071,12 +1170,23 @@ var PostgresEmbeddingCacheStore = class {
1071
1170
 
1072
1171
  // src/llm/index.ts
1073
1172
  var OpenAICompatibleLlmProvider = class {
1173
+ /** Model name sent in the request body and exposed on the provider. */
1074
1174
  model;
1075
1175
  baseUrl;
1076
1176
  apiKey;
1077
1177
  temperature;
1078
1178
  maxTokens;
1079
1179
  timeoutMs;
1180
+ /**
1181
+ * @param config - OpenAI-compatible endpoint settings.
1182
+ * @param config.baseUrl - API root, e.g. `https://api.openai.com/v1` (no trailing `/chat/completions`).
1183
+ * @param config.apiKey - Bearer token (`Authorization: Bearer …`). Use any non-empty
1184
+ * string for local servers that ignore auth (e.g. `"ollama"`).
1185
+ * @param config.model - Chat model id (e.g. `"gpt-4o-mini"`, `"llama3.2"`).
1186
+ * @param config.temperature - Sampling temperature. Defaults to `0.2`.
1187
+ * @param config.maxTokens - Max completion tokens. Defaults to `4096`.
1188
+ * @param config.timeoutMs - Abort after this many ms. Defaults to `60_000`.
1189
+ */
1080
1190
  constructor(config) {
1081
1191
  this.baseUrl = config.baseUrl;
1082
1192
  this.apiKey = config.apiKey;
@@ -1085,6 +1195,13 @@ var OpenAICompatibleLlmProvider = class {
1085
1195
  this.maxTokens = config.maxTokens ?? 4096;
1086
1196
  this.timeoutMs = config.timeoutMs ?? 6e4;
1087
1197
  }
1198
+ /**
1199
+ * Call `/chat/completions` and return the first choice’s message content.
1200
+ *
1201
+ * @param messages - Chat turns in OpenAI message format.
1202
+ * @returns Trimmed assistant text.
1203
+ * @throws {CompressionError} On HTTP errors, timeouts, or empty content.
1204
+ */
1088
1205
  async complete(messages) {
1089
1206
  const response = await this.request(messages);
1090
1207
  const content = response.choices?.[0]?.message?.content;
@@ -1093,6 +1210,11 @@ var OpenAICompatibleLlmProvider = class {
1093
1210
  }
1094
1211
  return content.trim();
1095
1212
  }
1213
+ /**
1214
+ * Probe the endpoint with a fixed `"ok"` prompt.
1215
+ *
1216
+ * @throws {CompressionError} When validation fails.
1217
+ */
1096
1218
  async validate() {
1097
1219
  try {
1098
1220
  await this.complete([
@@ -1114,6 +1236,12 @@ var OpenAICompatibleLlmProvider = class {
1114
1236
  );
1115
1237
  }
1116
1238
  }
1239
+ /**
1240
+ * Low-level HTTP request to `/chat/completions`.
1241
+ *
1242
+ * @param messages - Chat turns to send.
1243
+ * @returns Parsed OpenAI-style JSON body.
1244
+ */
1117
1245
  async request(messages) {
1118
1246
  const url = joinUrl(this.baseUrl, "/chat/completions");
1119
1247
  const controller = new AbortController();
@@ -1162,6 +1290,7 @@ var OpenAICompatibleLlmProvider = class {
1162
1290
  clearTimeout(timer);
1163
1291
  }
1164
1292
  }
1293
+ /** @param error - Unknown thrown value. @returns Human-readable message. */
1165
1294
  describe(error) {
1166
1295
  if (error instanceof Error) {
1167
1296
  return error.message;
@@ -1557,28 +1686,48 @@ var LEVEL_ORDER = {
1557
1686
  trace: 10
1558
1687
  };
1559
1688
  var WolbargLogger = class {
1689
+ /** @param level - Minimum level to print (default `"info"`). */
1560
1690
  constructor(level = "info") {
1561
1691
  this.level = level;
1562
1692
  }
1563
1693
  level;
1694
+ /** Change the minimum log level at runtime. */
1564
1695
  setLevel(level) {
1565
1696
  this.level = level;
1566
1697
  }
1698
+ /** @returns Current minimum log level. */
1567
1699
  getLevel() {
1568
1700
  return this.level;
1569
1701
  }
1702
+ /** Log at error level. */
1570
1703
  error(message, extra) {
1571
1704
  this.write("error", message, extra);
1572
1705
  }
1706
+ /** Log at warn level.
1707
+ * @param message - Primary log line.
1708
+ * @param extra - Optional structured payload.
1709
+ */
1573
1710
  warn(message, extra) {
1574
1711
  this.write("warn", message, extra);
1575
1712
  }
1713
+ /** Log at info level.
1714
+ * @param message - Primary log line.
1715
+ * @param extra - Optional structured payload.
1716
+ */
1576
1717
  info(message, extra) {
1577
1718
  this.write("info", message, extra);
1578
1719
  }
1720
+ /** Log at debug level.
1721
+ * @param message - Primary log line.
1722
+ * @param extra - Optional structured payload.
1723
+ */
1579
1724
  debug(message, extra) {
1580
1725
  this.write("debug", message, extra);
1581
1726
  }
1727
+ /** Log at trace level.
1728
+ * @param message - Primary log line.
1729
+ * @param extra - Optional structured payload.
1730
+ */
1582
1731
  trace(message, extra) {
1583
1732
  this.write("trace", message, extra);
1584
1733
  }
@@ -1921,18 +2070,29 @@ var InMemoryVectorIndex = class {
1921
2070
  data;
1922
2071
  count = 0;
1923
2072
  rowidToSlot = /* @__PURE__ */ new Map();
2073
+ /**
2074
+ * @param dimensions - Embedding vector length.
2075
+ * @param initialCapacity - Initial slot capacity (default `256`).
2076
+ */
1924
2077
  constructor(dimensions, initialCapacity = 256) {
1925
2078
  this.dims = dimensions;
1926
2079
  this.data = new Float32Array(initialCapacity * dimensions);
1927
2080
  }
2081
+ /** Number of indexed vectors. */
1928
2082
  get size() {
1929
2083
  return this.count;
1930
2084
  }
2085
+ /** Remove all vectors from the index. */
1931
2086
  clear() {
1932
2087
  this.rowids.length = 0;
1933
2088
  this.rowidToSlot.clear();
1934
2089
  this.count = 0;
1935
2090
  }
2091
+ /**
2092
+ * Insert or replace a vector for `rowid` (L2-normalized internally).
2093
+ * @param rowid - Memory table row identifier.
2094
+ * @param embedding - Raw embedding vector.
2095
+ */
1936
2096
  upsert(rowid, embedding) {
1937
2097
  const existing = this.rowidToSlot.get(rowid);
1938
2098
  const slot = existing !== void 0 ? existing : (() => {
@@ -1963,6 +2123,10 @@ var InMemoryVectorIndex = class {
1963
2123
  }
1964
2124
  }
1965
2125
  }
2126
+ /**
2127
+ * Remove a vector by `rowid`.
2128
+ * @param rowid - Memory table row identifier.
2129
+ */
1966
2130
  remove(rowid) {
1967
2131
  const slot = this.rowidToSlot.get(rowid);
1968
2132
  if (slot === void 0) {
@@ -1982,7 +2146,12 @@ var InMemoryVectorIndex = class {
1982
2146
  this.rowidToSlot.delete(rowid);
1983
2147
  this.count = last;
1984
2148
  }
1985
- /** Top-k by cosine distance (1 - dot) assuming query is L2-normalized. */
2149
+ /**
2150
+ * Top-k by cosine distance (1 - dot) assuming query is L2-normalized.
2151
+ *
2152
+ * @param queryNormalized - L2-normalized query vector (use {@link normalizeEmbedding}).
2153
+ * @param topK - Maximum hits to return.
2154
+ */
1986
2155
  search(queryNormalized, topK) {
1987
2156
  const n = this.count;
1988
2157
  if (n === 0 || topK <= 0) {
@@ -2258,6 +2427,9 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2258
2427
  /** Coalesce concurrent insertMemory callers into one IMMEDIATE transaction. */
2259
2428
  insertQueue = [];
2260
2429
  insertFlushScheduled = false;
2430
+ /**
2431
+ * @param options - SQLite path / `:memory:` and optional concurrency config.
2432
+ */
2261
2433
  constructor(options) {
2262
2434
  this.connectionString = options.connectionString;
2263
2435
  this.concurrency = resolveConcurrencyConfig(options.concurrency);
@@ -2270,9 +2442,11 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2270
2442
  getDatabase() {
2271
2443
  return this.db;
2272
2444
  }
2445
+ /** Register a callback invoked when SQLite busy retries occur (tests / diagnostics). */
2273
2446
  setRetryLogger(fn) {
2274
2447
  this.retryLog = fn;
2275
2448
  }
2449
+ /** Open the database, run migrations, and prepare statements. */
2276
2450
  async open() {
2277
2451
  try {
2278
2452
  const dbPath = this.resolvePath(this.connectionString);
@@ -2332,6 +2506,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2332
2506
  );
2333
2507
  }
2334
2508
  }
2509
+ /** Drain pending inserts, optimize, and close the SQLite connection. */
2335
2510
  async close() {
2336
2511
  const deadline = Date.now() + 2e3;
2337
2512
  while (this.insertQueue.length > 0 && Date.now() < deadline) {
@@ -2362,6 +2537,11 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2362
2537
  this.batchBlobEmbStatements.clear();
2363
2538
  }
2364
2539
  }
2540
+ /**
2541
+ * Create or validate vec0 / blob vector storage for the given dimensionality.
2542
+ *
2543
+ * @param dimensions - Embedding length from the configured model.
2544
+ */
2365
2545
  async ensureVectorSchema(dimensions) {
2366
2546
  const existing = await this.getEmbeddingDimensions();
2367
2547
  if (existing !== null && existing !== dimensions) {
@@ -2384,13 +2564,16 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2384
2564
  this.reprepareVectorStatements();
2385
2565
  this.hydrateMemoryIndex();
2386
2566
  }
2567
+ /** @inheritdoc StorageProvider.getEmbeddingDimensions */
2387
2568
  async getEmbeddingDimensions() {
2388
2569
  return this.readMetaNumber(META_KEYS.embeddingDimensions);
2389
2570
  }
2571
+ /** @inheritdoc StorageProvider.setEmbeddingDimensions */
2390
2572
  async setEmbeddingDimensions(dimensions) {
2391
2573
  await this.setMeta(META_KEYS.embeddingDimensions, String(dimensions));
2392
2574
  this.vectorDimensions = dimensions;
2393
2575
  }
2576
+ /** Insert a single memory row (coalesced under concurrent writers). */
2394
2577
  async insertMemory(input) {
2395
2578
  this.requireVectorReady();
2396
2579
  return new Promise((resolve, reject) => {
@@ -2472,6 +2655,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2472
2655
  return row;
2473
2656
  });
2474
2657
  }
2658
+ /** Batch insert memories in chunked multi-row transactions. */
2475
2659
  async insertMemoriesBatch(inputs) {
2476
2660
  if (inputs.length === 0) {
2477
2661
  return [];
@@ -2487,6 +2671,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2487
2671
  return rows;
2488
2672
  });
2489
2673
  }
2674
+ /** Update memory content, metadata, embedding, and content hash. */
2490
2675
  async updateMemory(input) {
2491
2676
  const stmts = this.requireStatements();
2492
2677
  return this.withTransaction(() => {
@@ -2530,6 +2715,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2530
2715
  return stmts.getMemoryById.get(input.id, input.organization);
2531
2716
  });
2532
2717
  }
2718
+ /** Find an active memory by org, agent, and content hash (dedupe). */
2533
2719
  async findActiveByContentHash(organization, agent, contentHash) {
2534
2720
  const stmts = this.requireStatements();
2535
2721
  const row = stmts.findActiveByContentHash.get(
@@ -2539,6 +2725,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2539
2725
  );
2540
2726
  return row ?? null;
2541
2727
  }
2728
+ /** Scan memories matching metadata filters (may paginate in SQL). */
2542
2729
  async searchByMetadata(filter, limit) {
2543
2730
  const rows = await this.listMemories(filter, limit);
2544
2731
  if (!filter.metadata) {
@@ -2549,6 +2736,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2549
2736
  );
2550
2737
  }
2551
2738
  /** Keyword search via FTS5 BM25. Returns memory IDs ranked by relevance. */
2739
+ /** BM25 keyword search via FTS5 (`memories_fts`). */
2552
2740
  async searchKeyword(query, organization, topK) {
2553
2741
  const stmts = this.requireStatements();
2554
2742
  if (!stmts.searchFts) {
@@ -2584,16 +2772,19 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2584
2772
  return [];
2585
2773
  }
2586
2774
  }
2775
+ /** Fetch a memory row by UUID within an organization. */
2587
2776
  async getMemoryById(id, organization) {
2588
2777
  const stmts = this.requireStatements();
2589
2778
  const row = stmts.getMemoryById.get(id, organization);
2590
2779
  return row ?? null;
2591
2780
  }
2781
+ /** Fetch a memory row by SQLite integer rowid within an organization. */
2592
2782
  async getMemoryByRowid(rowid, organization) {
2593
2783
  const stmts = this.requireStatements();
2594
2784
  const row = stmts.getMemoryByRowid.get(rowid, organization);
2595
2785
  return row ?? null;
2596
2786
  }
2787
+ /** Batch-fetch memory rows by SQLite rowids within an organization. */
2597
2788
  async getMemoriesByRowids(rowids, organization) {
2598
2789
  const out = /* @__PURE__ */ new Map();
2599
2790
  if (rowids.length === 0) {
@@ -2612,6 +2803,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2612
2803
  }
2613
2804
  return out;
2614
2805
  }
2806
+ /** List memories matching repository filters with optional limit. */
2615
2807
  async listMemories(filter, limit) {
2616
2808
  try {
2617
2809
  if (filter.metadata) {
@@ -2624,6 +2816,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2624
2816
  });
2625
2817
  }
2626
2818
  }
2819
+ /** Approximate nearest-neighbor search (vec0 or in-memory blob index). */
2627
2820
  async searchVectors(embedding, topK) {
2628
2821
  this.requireVectorReady();
2629
2822
  if (this.vectorBackend === "sqlite-vec") {
@@ -2635,6 +2828,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2635
2828
  * Org-scoped KNN + memory rows with adaptive overfetch.
2636
2829
  * Global ANN is post-filtered by org/agent/archived; underfill triggers larger k.
2637
2830
  */
2831
+ /** ANN search joined with memory rows and org/archived post-filters. */
2638
2832
  async searchVectorsWithMemories(embedding, topK, organization, options) {
2639
2833
  this.requireVectorReady();
2640
2834
  if (topK <= 0) {
@@ -2673,6 +2867,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2673
2867
  }
2674
2868
  return out;
2675
2869
  }
2870
+ /** Soft-archive memories (compression / forget paths). */
2676
2871
  async archiveMemories(ids, organization, compressedIntoId, archivedAt) {
2677
2872
  const stmts = this.requireStatements();
2678
2873
  const archived = [];
@@ -2710,6 +2905,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2710
2905
  return archived;
2711
2906
  });
2712
2907
  }
2908
+ /** Hard-delete a single memory by id; returns whether a row was removed. */
2713
2909
  async deleteMemoryById(id, organization) {
2714
2910
  const stmts = this.requireStatements();
2715
2911
  return this.withTransaction(() => {
@@ -2723,6 +2919,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2723
2919
  return Number(result.changes) > 0;
2724
2920
  });
2725
2921
  }
2922
+ /** Hard-delete memories matching org / agent / metadata filters. */
2726
2923
  async deleteMemoriesByFilter(filter) {
2727
2924
  const stmts = this.requireStatements();
2728
2925
  const agent = filter.agent;
@@ -2739,6 +2936,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2739
2936
  return Number(result.changes);
2740
2937
  });
2741
2938
  }
2939
+ /** Remove all memories (and side tables) for an organization. */
2742
2940
  async clearOrganization(organization) {
2743
2941
  const stmts = this.requireStatements();
2744
2942
  return this.withTransaction(() => {
@@ -2755,10 +2953,12 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2755
2953
  return Number(result.changes);
2756
2954
  });
2757
2955
  }
2956
+ /** List audit history events for a memory id. */
2758
2957
  async getHistory(memoryId) {
2759
2958
  const stmts = this.requireStatements();
2760
2959
  return stmts.getHistory.all(memoryId);
2761
2960
  }
2961
+ /** Append a history row (created / archived / compressed / updated). */
2762
2962
  async insertHistoryEvent(event) {
2763
2963
  const stmts = this.requireStatements();
2764
2964
  stmts.insertHistory.run(
@@ -2769,6 +2969,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2769
2969
  event.created_at
2770
2970
  );
2771
2971
  }
2972
+ /** Aggregate memory counts for an organization (single-pass SQL). */
2772
2973
  async getStats(organization) {
2773
2974
  const stmts = this.requireStatements();
2774
2975
  const row = stmts.getStats.get(organization);
@@ -2779,6 +2980,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2779
2980
  totalAgents: Number(row.agents)
2780
2981
  };
2781
2982
  }
2983
+ /** On-disk database file size in bytes (0 for `:memory:`). */
2782
2984
  async getDatabaseSizeBytes() {
2783
2985
  const db = this.requireDb();
2784
2986
  if (this.connectionString === ":memory:") {
@@ -3837,11 +4039,17 @@ var PostgresSubscribeListener = class {
3837
4039
  reconnectDelayMs;
3838
4040
  connect;
3839
4041
  onError;
4042
+ /**
4043
+ * @param options.connect - Factory returning a dedicated LISTEN client.
4044
+ * @param options.reconnectDelayMs - Delay before reconnect attempts (default 1000).
4045
+ * @param options.onError - Optional error hook for connection failures.
4046
+ */
3840
4047
  constructor(options) {
3841
4048
  this.connect = options.connect;
3842
4049
  this.reconnectDelayMs = options.reconnectDelayMs ?? 1e3;
3843
4050
  this.onError = options.onError;
3844
4051
  }
4052
+ /** Open the LISTEN connection (lazy — also started on first subscribe). */
3845
4053
  async start() {
3846
4054
  if (this.closed) {
3847
4055
  return;
@@ -3938,6 +4146,13 @@ var PostgresSubscribeListener = class {
3938
4146
  }
3939
4147
  }
3940
4148
  }
4149
+ /**
4150
+ * Register a filtered callback for memory change events.
4151
+ *
4152
+ * @param filter - Organization / agent / event-type filter.
4153
+ * @param callback - Invoked synchronously on each matching NOTIFY.
4154
+ * @returns Unsubscribe function.
4155
+ */
3941
4156
  subscribe(filter, callback) {
3942
4157
  if (this.closed) {
3943
4158
  throw new Error("Subscribe backend is closed");
@@ -3959,6 +4174,7 @@ var PostgresSubscribeListener = class {
3959
4174
  */
3960
4175
  emit(_event) {
3961
4176
  }
4177
+ /** Tear down LISTEN connection and clear subscriptions. */
3962
4178
  async close() {
3963
4179
  this.closed = true;
3964
4180
  this.subscriptions.clear();
@@ -4123,6 +4339,9 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4123
4339
  insertFlushScheduled = false;
4124
4340
  insertFlushTimer = null;
4125
4341
  insertFlushInFlight = 0;
4342
+ /**
4343
+ * @param options - Connection string, pool size, and durability flags.
4344
+ */
4126
4345
  constructor(options) {
4127
4346
  this.maxPoolSize = options.maxPoolSize ?? 64;
4128
4347
  this.durableWrites = options.durableWrites !== false;
@@ -4131,6 +4350,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4131
4350
  this.durableWrites
4132
4351
  );
4133
4352
  }
4353
+ /** Current pg pool occupancy stats (for diagnostics / subscribe setup). */
4134
4354
  getPoolStats() {
4135
4355
  const pool = this.pool;
4136
4356
  return {
@@ -4144,6 +4364,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4144
4364
  getPool() {
4145
4365
  return this.pool;
4146
4366
  }
4367
+ /** Open the connection pool and run migrations. */
4147
4368
  async open() {
4148
4369
  let PoolCtor;
4149
4370
  try {
@@ -4192,6 +4413,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4192
4413
  );
4193
4414
  }
4194
4415
  }
4416
+ /** Drain coalesced inserts and end the connection pool. */
4195
4417
  async close() {
4196
4418
  if (this.insertFlushTimer) {
4197
4419
  clearTimeout(this.insertFlushTimer);
@@ -4232,6 +4454,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4232
4454
  async ensureVectorIndex() {
4233
4455
  await this.ensureHnswIndex();
4234
4456
  }
4457
+ /**
4458
+ * Create pgvector tables and HNSW index for the given dimensionality.
4459
+ *
4460
+ * @param dimensions - Embedding length from the configured model.
4461
+ */
4235
4462
  async ensureVectorSchema(dimensions) {
4236
4463
  const existing = await this.getEmbeddingDimensions();
4237
4464
  if (existing !== null && existing !== dimensions) {
@@ -4296,6 +4523,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4296
4523
  }
4297
4524
  }
4298
4525
  /** Cross-process subscribe: NOTIFY after a committed write. */
4526
+ /**
4527
+ * Issue `pg_notify` for cross-process {@link subscribe} delivery.
4528
+ *
4529
+ * @param event - Memory change payload (IDs + metadata only).
4530
+ */
4299
4531
  async notifyChange(event) {
4300
4532
  await notifyMemoryChange(this.requirePool(), event);
4301
4533
  }
@@ -4303,6 +4535,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4303
4535
  * Soft reset for a single organization. Drops HNSW only when the embeddings
4304
4536
  * table is empty so other corpora on a shared bench DB stay intact.
4305
4537
  */
4538
+ /** Delete all rows for an organization (dev / test helper). */
4306
4539
  async resetOrganization(organization) {
4307
4540
  await this.query(`DELETE FROM memories WHERE organization = $1`, [
4308
4541
  organization
@@ -4320,6 +4553,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4320
4553
  /**
4321
4554
  * Wipe all Wolbarg tables (explicit opt-in). Prefer {@link resetOrganization}.
4322
4555
  */
4556
+ /** Truncate all Wolbarg tables (dev / test helper). */
4323
4557
  async wipeAllData() {
4324
4558
  await this.query(`TRUNCATE TABLE memories CASCADE`).catch(() => void 0);
4325
4559
  await this.query(
@@ -4379,6 +4613,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4379
4613
  }
4380
4614
  }
4381
4615
  }
4616
+ /** @inheritdoc StorageProvider.getEmbeddingDimensions */
4382
4617
  async getEmbeddingDimensions() {
4383
4618
  const result = await this.query(
4384
4619
  `SELECT value FROM Wolbarg_meta WHERE key = $1`,
@@ -4391,6 +4626,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4391
4626
  const parsed = Number(value);
4392
4627
  return Number.isFinite(parsed) ? parsed : null;
4393
4628
  }
4629
+ /** @inheritdoc StorageProvider.setEmbeddingDimensions */
4394
4630
  async setEmbeddingDimensions(dimensions) {
4395
4631
  await this.query(
4396
4632
  `INSERT INTO Wolbarg_meta (key, value) VALUES ($1, $2)
@@ -4399,6 +4635,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4399
4635
  );
4400
4636
  this.vectorDimensions = dimensions;
4401
4637
  }
4638
+ /** Insert a single memory row (coalesced under concurrent writers). */
4402
4639
  async insertMemory(input) {
4403
4640
  this.requireVectorReady();
4404
4641
  return new Promise((resolve, reject) => {
@@ -4485,6 +4722,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4485
4722
  }
4486
4723
  return this.insertOneBlob(input);
4487
4724
  }
4725
+ /** Batch insert via unnest / COPY paths with optional HNSW deferral. */
4488
4726
  async insertMemoriesBatch(inputs) {
4489
4727
  if (inputs.length === 0) {
4490
4728
  return [];
@@ -4633,6 +4871,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4633
4871
  return row;
4634
4872
  });
4635
4873
  }
4874
+ /** Update memory content, metadata, embedding, and content hash. */
4636
4875
  async updateMemory(input) {
4637
4876
  return this.withTransaction(async () => {
4638
4877
  const existing = await this.getMemoryById(input.id, input.organization);
@@ -4668,6 +4907,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4668
4907
  return this.getMemoryById(input.id, input.organization);
4669
4908
  });
4670
4909
  }
4910
+ /** Find an active memory by org, agent, and content hash (dedupe). */
4671
4911
  async findActiveByContentHash(organization, agent, contentHash) {
4672
4912
  const result = await this.query(
4673
4913
  `SELECT id, organization, agent, content_text, metadata_json,
@@ -4680,6 +4920,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4680
4920
  const row = result.rows[0];
4681
4921
  return row ? this.mapRow(row) : null;
4682
4922
  }
4923
+ /** Fetch a memory row by UUID within an organization. */
4683
4924
  async getMemoryById(id, organization) {
4684
4925
  const result = await this.query(
4685
4926
  `SELECT id, organization, agent, content_text, metadata_json,
@@ -4690,6 +4931,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4690
4931
  const row = result.rows[0];
4691
4932
  return row ? this.mapRow(row) : null;
4692
4933
  }
4934
+ /** Fetch a memory row by internal rowid within an organization. */
4693
4935
  async getMemoryByRowid(rowid, organization) {
4694
4936
  const result = await this.query(
4695
4937
  `SELECT m.id, m.organization, m.agent, m.content_text, m.metadata_json,
@@ -4703,6 +4945,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4703
4945
  const row = result.rows[0];
4704
4946
  return row ? this.mapRow(row) : null;
4705
4947
  }
4948
+ /** Batch-fetch memory rows by rowids within an organization. */
4706
4949
  async getMemoriesByRowids(rowids, organization) {
4707
4950
  const out = /* @__PURE__ */ new Map();
4708
4951
  if (rowids.length === 0) {
@@ -4725,6 +4968,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4725
4968
  }
4726
4969
  return out;
4727
4970
  }
4971
+ /** List memories matching repository filters with optional limit. */
4728
4972
  async listMemories(filter, limit) {
4729
4973
  const want = limit !== void 0 ? limit : filter.metadata ? 1e4 : void 0;
4730
4974
  const compiled = filter.metadata ? compileMetadataFilterToPostgres(filter.metadata, 2) : null;
@@ -4786,9 +5030,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4786
5030
  }
4787
5031
  return rows;
4788
5032
  }
5033
+ /** Scan memories matching metadata filters. */
4789
5034
  async searchByMetadata(filter, limit) {
4790
5035
  return this.listMemories(filter, limit);
4791
5036
  }
5037
+ /** Full-text keyword search via `tsvector` / GIN index. */
4792
5038
  async searchKeyword(query, organization, topK) {
4793
5039
  const trimmed = query.trim();
4794
5040
  if (!trimmed || topK <= 0) {
@@ -4828,6 +5074,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4828
5074
  return [];
4829
5075
  }
4830
5076
  }
5077
+ /** pgvector cosine ANN search (HNSW when index is present). */
4831
5078
  async searchVectors(embedding, topK) {
4832
5079
  this.requireVectorReady();
4833
5080
  if (this.hasPgvector) {
@@ -4877,6 +5124,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4877
5124
  scored.sort((a, b) => a.distance - b.distance);
4878
5125
  return scored.slice(0, topK);
4879
5126
  }
5127
+ /** ANN search joined with memory rows and org/archived post-filters. */
4880
5128
  async searchVectorsWithMemories(embedding, topK, organization, options) {
4881
5129
  this.requireVectorReady();
4882
5130
  if (!this.hasPgvector) {
@@ -4941,6 +5189,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4941
5189
  );
4942
5190
  return mapHits(result.rows);
4943
5191
  }
5192
+ /** Soft-archive memories (compression / forget paths). */
4944
5193
  async archiveMemories(ids, organization, compressedIntoId, archivedAt) {
4945
5194
  return this.withTransaction(async () => {
4946
5195
  if (ids.length === 0) {
@@ -4983,6 +5232,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4983
5232
  return archived;
4984
5233
  });
4985
5234
  }
5235
+ /** Hard-delete a single memory by id; returns whether a row was removed. */
4986
5236
  async deleteMemoryById(id, organization) {
4987
5237
  const result = await this.query(
4988
5238
  `DELETE FROM memories WHERE id = $1 AND organization = $2`,
@@ -4990,6 +5240,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4990
5240
  );
4991
5241
  return (result.rowCount ?? 0) > 0;
4992
5242
  }
5243
+ /** Hard-delete memories matching org / agent / metadata filters. */
4993
5244
  async deleteMemoriesByFilter(filter) {
4994
5245
  if (!filter.agent) {
4995
5246
  throw new DatabaseError("deleteMemoriesByFilter requires an agent filter");
@@ -5000,6 +5251,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5000
5251
  );
5001
5252
  return result.rowCount ?? 0;
5002
5253
  }
5254
+ /** Remove all memories for an organization. */
5003
5255
  async clearOrganization(organization) {
5004
5256
  const result = await this.query(
5005
5257
  `DELETE FROM memories WHERE organization = $1`,
@@ -5007,6 +5259,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5007
5259
  );
5008
5260
  return result.rowCount ?? 0;
5009
5261
  }
5262
+ /** List audit history events for a memory id. */
5010
5263
  async getHistory(memoryId) {
5011
5264
  const result = await this.query(
5012
5265
  `SELECT id, memory_id, event_type, related_memory_id, created_at
@@ -5021,6 +5274,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5021
5274
  created_at: String(row.created_at)
5022
5275
  }));
5023
5276
  }
5277
+ /** Append a history row (created / archived / compressed / updated). */
5024
5278
  async insertHistoryEvent(event) {
5025
5279
  await this.query(
5026
5280
  `INSERT INTO memory_history (id, memory_id, event_type, related_memory_id, created_at)
@@ -5034,6 +5288,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5034
5288
  ]
5035
5289
  );
5036
5290
  }
5291
+ /** Aggregate memory counts for an organization. */
5037
5292
  async getStats(organization) {
5038
5293
  const result = await this.query(
5039
5294
  `SELECT
@@ -5051,6 +5306,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5051
5306
  totalAgents: Number(result.rows[0]?.agents ?? 0)
5052
5307
  };
5053
5308
  }
5309
+ /** Approximate on-disk database size in bytes (`pg_database_size`). */
5054
5310
  async getDatabaseSizeBytes() {
5055
5311
  const result = await this.query(
5056
5312
  `SELECT pg_database_size(current_database())::bigint AS size`
@@ -5398,7 +5654,7 @@ function createDatabaseProvider(config) {
5398
5654
  }
5399
5655
 
5400
5656
  // src/version.ts
5401
- var SDK_VERSION = "0.5.4";
5657
+ var SDK_VERSION = "0.5.5";
5402
5658
 
5403
5659
  // src/memory/transfer.ts
5404
5660
  var warnedMissingExportManifest = false;
@@ -5867,6 +6123,9 @@ var SqliteGraphProvider = class {
5867
6123
  concurrency;
5868
6124
  db = null;
5869
6125
  opened = false;
6126
+ /**
6127
+ * @param options - Graph SQLite path and optional concurrency tuning.
6128
+ */
5870
6129
  constructor(options) {
5871
6130
  if (!options?.path || typeof options.path !== "string" || !options.path.trim()) {
5872
6131
  throw new ConfigurationError("sqlite graph requires a non-empty path");
@@ -5874,12 +6133,15 @@ var SqliteGraphProvider = class {
5874
6133
  this.dbPath = path7__default.default.resolve(options.path.trim());
5875
6134
  this.concurrency = resolveConcurrencyConfig(options.concurrency);
5876
6135
  }
6136
+ /** Whether this provider supports file snapshots for checkpoint / export. */
5877
6137
  supportsFileSnapshot() {
5878
6138
  return this.dbPath !== ":memory:";
5879
6139
  }
6140
+ /** Absolute graph database path, or `null` for `:memory:`. */
5880
6141
  getDataPath() {
5881
6142
  return this.dbPath === ":memory:" ? null : this.dbPath;
5882
6143
  }
6144
+ /** Open the graph SQLite file, apply pragmas, and create schema if needed. */
5883
6145
  async open() {
5884
6146
  if (this.opened) return;
5885
6147
  try {
@@ -5916,6 +6178,7 @@ var SqliteGraphProvider = class {
5916
6178
  );
5917
6179
  }
5918
6180
  }
6181
+ /** Close the graph database connection. */
5919
6182
  async close() {
5920
6183
  if (!this.db) {
5921
6184
  this.opened = false;
@@ -5937,6 +6200,14 @@ var SqliteGraphProvider = class {
5937
6200
  this.opened = false;
5938
6201
  }
5939
6202
  }
6203
+ /**
6204
+ * Create or replace a directed memory↔memory edge.
6205
+ *
6206
+ * @param fromId - Source memory UUID.
6207
+ * @param toId - Target memory UUID.
6208
+ * @param relation - Edge label (e.g. `"related_to"`, `"caused_by"`).
6209
+ * @param metadata - Optional JSON metadata stored on the edge.
6210
+ */
5940
6211
  async linkMemories(fromId, toId, relation, metadata) {
5941
6212
  const db = this.requireDb();
5942
6213
  await this.withTx(() => {
@@ -5959,6 +6230,13 @@ var SqliteGraphProvider = class {
5959
6230
  );
5960
6231
  });
5961
6232
  }
6233
+ /**
6234
+ * Remove edges between two memories.
6235
+ *
6236
+ * @param fromId - Source memory UUID.
6237
+ * @param toId - Target memory UUID.
6238
+ * @param relation - When set, only delete edges with this relation label.
6239
+ */
5962
6240
  async unlinkMemories(fromId, toId, relation) {
5963
6241
  const db = this.requireDb();
5964
6242
  await this.withTx(() => {
@@ -6008,6 +6286,12 @@ var SqliteGraphProvider = class {
6008
6286
  }
6009
6287
  return out;
6010
6288
  }
6289
+ /**
6290
+ * Insert or update a named entity node.
6291
+ *
6292
+ * @param entity - Entity name, type, and optional metadata.
6293
+ * @returns Stable entity id ({@link entityIdFrom}).
6294
+ */
6011
6295
  async upsertEntity(entity) {
6012
6296
  const id = entityIdFrom(entity.name, entity.type);
6013
6297
  const db = this.requireDb();
@@ -6032,6 +6316,13 @@ var SqliteGraphProvider = class {
6032
6316
  });
6033
6317
  return id;
6034
6318
  }
6319
+ /**
6320
+ * Link an entity to a memory via a `MENTIONS` edge (not traversed by {@link getRelated}).
6321
+ *
6322
+ * @param entityId - Entity id from {@link upsertEntity}.
6323
+ * @param memoryId - Target memory UUID.
6324
+ * @param role - Optional role string stored on the edge metadata.
6325
+ */
6035
6326
  async linkEntityToMemory(entityId, memoryId, role) {
6036
6327
  const db = this.requireDb();
6037
6328
  await this.withTx(() => {
@@ -6061,6 +6352,11 @@ var SqliteGraphProvider = class {
6061
6352
  );
6062
6353
  });
6063
6354
  }
6355
+ /**
6356
+ * Remove the memory node and incident edges when a memory is hard-deleted.
6357
+ *
6358
+ * @param memoryId - Wolbarg memory UUID.
6359
+ */
6064
6360
  async deleteMemory(memoryId) {
6065
6361
  const db = this.requireDb();
6066
6362
  await this.withTx(() => {
@@ -6080,6 +6376,7 @@ var SqliteGraphProvider = class {
6080
6376
  }
6081
6377
  );
6082
6378
  }
6379
+ /** Lightweight connectivity and schema statistics check. */
6083
6380
  async health() {
6084
6381
  try {
6085
6382
  if (!this.opened || !this.db) {
@@ -6225,6 +6522,9 @@ var Neo4jGraphProvider = class {
6225
6522
  database;
6226
6523
  driver = null;
6227
6524
  opened = false;
6525
+ /**
6526
+ * @param options - Bolt URL, credentials, and optional database name.
6527
+ */
6228
6528
  constructor(options) {
6229
6529
  if (!options?.url?.trim()) {
6230
6530
  throw new ConfigurationError("neo4j graph requires a non-empty url");
@@ -6240,12 +6540,15 @@ var Neo4jGraphProvider = class {
6240
6540
  this.password = options.password;
6241
6541
  this.database = options.database?.trim() || void 0;
6242
6542
  }
6543
+ /** Neo4j does not support local file snapshots for checkpoint pairing. */
6243
6544
  supportsFileSnapshot() {
6244
6545
  return false;
6245
6546
  }
6547
+ /** Always `null` — graph data lives in the remote Neo4j cluster. */
6246
6548
  getDataPath() {
6247
6549
  return null;
6248
6550
  }
6551
+ /** Connect to Neo4j, verify connectivity, and ensure uniqueness constraints. */
6249
6552
  async open() {
6250
6553
  if (this.opened) return;
6251
6554
  let mod;
@@ -6277,6 +6580,7 @@ var Neo4jGraphProvider = class {
6277
6580
  }
6278
6581
  });
6279
6582
  }
6583
+ /** Close the neo4j-driver connection. */
6280
6584
  async close() {
6281
6585
  if (this.driver) {
6282
6586
  await this.driver.close();
@@ -6338,6 +6642,14 @@ var Neo4jGraphProvider = class {
6338
6642
  }
6339
6643
  await this.run(cypher, { id });
6340
6644
  }
6645
+ /**
6646
+ * MERGE a directed `RELATED` relationship between two memory nodes.
6647
+ *
6648
+ * @param fromId - Source memory UUID.
6649
+ * @param toId - Target memory UUID.
6650
+ * @param relation - Relationship label stored on `RELATED.relation`.
6651
+ * @param metadata - Optional JSON metadata on the relationship.
6652
+ */
6341
6653
  async linkMemories(fromId, toId, relation, metadata) {
6342
6654
  await this.withSession(async (session) => {
6343
6655
  await this.ensureMemoryNode(fromId, session);
@@ -6356,6 +6668,13 @@ var Neo4jGraphProvider = class {
6356
6668
  );
6357
6669
  });
6358
6670
  }
6671
+ /**
6672
+ * Delete `RELATED` relationship(s) between two memories.
6673
+ *
6674
+ * @param fromId - Source memory UUID.
6675
+ * @param toId - Target memory UUID.
6676
+ * @param relation - When set, only delete edges with this relation property.
6677
+ */
6359
6678
  async unlinkMemories(fromId, toId, relation) {
6360
6679
  if (relation !== void 0) {
6361
6680
  await this.run(
@@ -6401,6 +6720,12 @@ var Neo4jGraphProvider = class {
6401
6720
  (row) => rowToMemoryRecord(unwrapRow(row))
6402
6721
  );
6403
6722
  }
6723
+ /**
6724
+ * MERGE an `Entity` node keyed by deterministic id.
6725
+ *
6726
+ * @param entity - Entity name, type, and optional metadata.
6727
+ * @returns Stable entity id ({@link entityIdFrom}).
6728
+ */
6404
6729
  async upsertEntity(entity) {
6405
6730
  const id = entityIdFrom(entity.name, entity.type);
6406
6731
  await this.run(
@@ -6415,6 +6740,13 @@ var Neo4jGraphProvider = class {
6415
6740
  );
6416
6741
  return id;
6417
6742
  }
6743
+ /**
6744
+ * MERGE a `MENTIONS` relationship from entity to memory.
6745
+ *
6746
+ * @param entityId - Entity id from {@link upsertEntity}.
6747
+ * @param memoryId - Target memory UUID.
6748
+ * @param role - Optional role string on the relationship.
6749
+ */
6418
6750
  async linkEntityToMemory(entityId, memoryId, role) {
6419
6751
  await this.withSession(async (session) => {
6420
6752
  await this.ensureMemoryNode(memoryId, session);
@@ -6437,6 +6769,11 @@ var Neo4jGraphProvider = class {
6437
6769
  );
6438
6770
  });
6439
6771
  }
6772
+ /**
6773
+ * DETACH DELETE the memory node and all incident relationships.
6774
+ *
6775
+ * @param memoryId - Wolbarg memory UUID.
6776
+ */
6440
6777
  async deleteMemory(memoryId) {
6441
6778
  await this.run(
6442
6779
  `MATCH (m:Memory { id: $id })
@@ -6444,9 +6781,17 @@ var Neo4jGraphProvider = class {
6444
6781
  { id: memoryId }
6445
6782
  );
6446
6783
  }
6784
+ /**
6785
+ * Run arbitrary parameterized Cypher (escape hatch for advanced graph queries).
6786
+ *
6787
+ * @param cypher - Cypher query string.
6788
+ * @param params - Bound parameters for the query.
6789
+ * @returns Raw row objects from the driver.
6790
+ */
6447
6791
  async query(cypher, params) {
6448
6792
  return this.run(cypher, params ?? {});
6449
6793
  }
6794
+ /** Verify connectivity and return server metadata when available. */
6450
6795
  async health() {
6451
6796
  try {
6452
6797
  if (!this.opened || !this.driver) {
@@ -6937,21 +7282,32 @@ function createChildTrace(parent) {
6937
7282
  // src/telemetry/emitter.ts
6938
7283
  var NoopTelemetryProvider = class {
6939
7284
  name = "noop";
7285
+ /** @inheritdoc TelemetryProvider.open */
6940
7286
  async open() {
6941
7287
  }
7288
+ /** @inheritdoc TelemetryProvider.close */
6942
7289
  async close() {
6943
7290
  }
7291
+ /** @inheritdoc TelemetryProvider.emit */
6944
7292
  emit(_event) {
6945
7293
  }
7294
+ /** @inheritdoc TelemetryProvider.flush */
6946
7295
  async flush() {
6947
7296
  }
6948
7297
  };
6949
7298
  var TelemetryEmitter = class {
7299
+ /** Stable session id for this Wolbarg instance lifetime. */
6950
7300
  sessionId;
7301
+ /** Structured logger gated by telemetry log level. */
6951
7302
  logger;
6952
7303
  provider;
6953
7304
  config;
6954
7305
  context;
7306
+ /**
7307
+ * @param provider - Telemetry backend, or `null` for {@link NoopTelemetryProvider}.
7308
+ * @param config - Capture flags and log level.
7309
+ * @param context - Default organization injected into events.
7310
+ */
6955
7311
  constructor(provider, config, context = {}) {
6956
7312
  this.sessionId = createSessionId();
6957
7313
  this.provider = provider ?? new NoopTelemetryProvider();
@@ -6967,25 +7323,37 @@ var TelemetryEmitter = class {
6967
7323
  this.context = context;
6968
7324
  this.logger = new WolbargLogger(this.config.level);
6969
7325
  }
7326
+ /** Whether telemetry is enabled and backed by a non-noop provider. */
6970
7327
  get enabled() {
6971
7328
  return this.config.enabled && this.provider.name !== "noop";
6972
7329
  }
7330
+ /** Replace the underlying telemetry provider (e.g. after lazy init). */
6973
7331
  setProvider(provider) {
6974
7332
  this.provider = provider;
6975
7333
  }
7334
+ /** Open the underlying telemetry provider when enabled. */
6976
7335
  async open() {
6977
7336
  if (!this.config.enabled) {
6978
7337
  return;
6979
7338
  }
6980
7339
  await this.provider.open();
6981
7340
  }
7341
+ /** Flush pending events and close the telemetry provider. */
6982
7342
  async close() {
6983
7343
  await this.provider.flush();
6984
7344
  await this.provider.close();
6985
7345
  }
7346
+ /** Flush pending telemetry events without closing the provider. */
6986
7347
  async flush() {
6987
7348
  await this.provider.flush();
6988
7349
  }
7350
+ /**
7351
+ * Begin tracing an operation.
7352
+ *
7353
+ * @param operation - Public telemetry operation name.
7354
+ * @param parent - Optional parent trace for nested spans.
7355
+ * @returns Handle — call `success()` or `failure()` when done.
7356
+ */
6989
7357
  start(operation, parent) {
6990
7358
  const context = parent ? createChildTrace(parent) : createRootTrace(this.sessionId);
6991
7359
  const startedAt = performance.now();
@@ -7060,10 +7428,12 @@ var TelemetryEmitter = class {
7060
7428
  }
7061
7429
  };
7062
7430
  }
7431
+ /** Emit a startup telemetry event. */
7063
7432
  emitStartup(provider) {
7064
7433
  const trace = this.start("startup");
7065
7434
  trace.success({ provider });
7066
7435
  }
7436
+ /** Emit a shutdown telemetry event. */
7067
7437
  emitShutdown(provider) {
7068
7438
  const trace = this.start("shutdown");
7069
7439
  trace.success({ provider });
@@ -7129,10 +7499,15 @@ var SqliteEventDatabase = class {
7129
7499
  db = null;
7130
7500
  insertStmt = null;
7131
7501
  columns = /* @__PURE__ */ new Set();
7502
+ /**
7503
+ * @param options.url - Path to the telemetry SQLite file.
7504
+ * @param options.readonly - Open read-only (Studio / analytics).
7505
+ */
7132
7506
  constructor(options) {
7133
7507
  this.url = options.url;
7134
7508
  this.readonly = options.readonly ?? false;
7135
7509
  }
7510
+ /** Open the telemetry database and run schema migrations. */
7136
7511
  async open() {
7137
7512
  try {
7138
7513
  const dbPath = this.resolvePath(this.url);
@@ -7187,6 +7562,7 @@ var SqliteEventDatabase = class {
7187
7562
  );
7188
7563
  }
7189
7564
  }
7565
+ /** Close the telemetry database connection. */
7190
7566
  async close() {
7191
7567
  if (!this.db) return;
7192
7568
  try {
@@ -7197,6 +7573,7 @@ var SqliteEventDatabase = class {
7197
7573
  this.columns.clear();
7198
7574
  }
7199
7575
  }
7576
+ /** Insert one normalized telemetry event row. */
7200
7577
  async insertEvent(input) {
7201
7578
  const event = normalizeEvent(input);
7202
7579
  const stmt = this.insertStmt;
@@ -7242,6 +7619,7 @@ var SqliteEventDatabase = class {
7242
7619
  );
7243
7620
  }
7244
7621
  }
7622
+ /** Insert many events in a single transaction. */
7245
7623
  async insertEvents(inputs) {
7246
7624
  const db = this.requireDb();
7247
7625
  const out = [];
@@ -7260,6 +7638,7 @@ var SqliteEventDatabase = class {
7260
7638
  throw error;
7261
7639
  }
7262
7640
  }
7641
+ /** Query telemetry events with filters, sort, and pagination. */
7263
7642
  async query(options) {
7264
7643
  const db = this.requireDb();
7265
7644
  const clauses = [];
@@ -7340,11 +7719,13 @@ var SqliteEventDatabase = class {
7340
7719
  offset
7341
7720
  };
7342
7721
  }
7722
+ /** Fetch one event by primary key. */
7343
7723
  async getEvent(id) {
7344
7724
  const db = this.requireDb();
7345
7725
  const row = db.prepare(`SELECT * FROM telemetry_events WHERE id = ?`).get(id);
7346
7726
  return row ? rowToEvent(row) : null;
7347
7727
  }
7728
+ /** Count events optionally filtered by time and operation. */
7348
7729
  async countEvents(filter) {
7349
7730
  const db = this.requireDb();
7350
7731
  const clauses = [];
@@ -7495,9 +7876,13 @@ var SqliteTelemetryProvider = class {
7495
7876
  openPromise = null;
7496
7877
  warnedQueueDrop = false;
7497
7878
  warnedFlushFailure = false;
7879
+ /**
7880
+ * @param options.url - Path to the independent telemetry SQLite database file.
7881
+ */
7498
7882
  constructor(options) {
7499
7883
  this.db = new SqliteEventDatabase({ url: options.url });
7500
7884
  }
7885
+ /** Open the telemetry EventDatabase (lazy — also invoked on first emit). */
7501
7886
  async open() {
7502
7887
  if (!this.openPromise) {
7503
7888
  this.openPromise = this.db.open();
@@ -7505,12 +7890,18 @@ var SqliteTelemetryProvider = class {
7505
7890
  await this.openPromise;
7506
7891
  this.closed = false;
7507
7892
  }
7893
+ /** Flush pending events and close the telemetry database. */
7508
7894
  async close() {
7509
7895
  this.closed = true;
7510
7896
  await this.flush();
7511
7897
  await this.db.close();
7512
7898
  this.openPromise = null;
7513
7899
  }
7900
+ /**
7901
+ * Enqueue a telemetry event for async persistence (never throws).
7902
+ *
7903
+ * @param event - Partial or complete {@link TelemetryEventInput}.
7904
+ */
7514
7905
  emit(event) {
7515
7906
  if (this.closed) {
7516
7907
  return;
@@ -7527,6 +7918,7 @@ var SqliteTelemetryProvider = class {
7527
7918
  this.queue.push(event);
7528
7919
  void this.scheduleFlush();
7529
7920
  }
7921
+ /** Block until all queued events are written (or dropped on failure). */
7530
7922
  async flush() {
7531
7923
  while (this.queue.length > 0 || this.flushing) {
7532
7924
  await this.scheduleFlush();
@@ -7535,10 +7927,12 @@ var SqliteTelemetryProvider = class {
7535
7927
  }
7536
7928
  }
7537
7929
  }
7930
+ /** Query persisted telemetry events with filters and pagination. */
7538
7931
  async query(options) {
7539
7932
  await this.open();
7540
7933
  return this.db.query(options);
7541
7934
  }
7935
+ /** Fetch a single telemetry event by id. */
7542
7936
  async getEvent(id) {
7543
7937
  await this.open();
7544
7938
  return this.db.getEvent(id);
@@ -7580,16 +7974,28 @@ var SqliteCheckpointProvider = class {
7580
7974
  name = "sqlite";
7581
7975
  directory;
7582
7976
  ready = false;
7977
+ /**
7978
+ * @param options.directory - Folder for `.json` metadata and `.db` snapshot files.
7979
+ */
7583
7980
  constructor(options) {
7584
7981
  this.directory = options?.directory ?? path7__default.default.resolve(process.cwd(), ".wolbarg", "checkpoints");
7585
7982
  }
7983
+ /** Ensure the checkpoint directory exists. */
7586
7984
  async open() {
7587
7985
  fs6__default.default.mkdirSync(this.directory, { recursive: true });
7588
7986
  this.ready = true;
7589
7987
  }
7988
+ /** Mark the provider closed (does not delete snapshots). */
7590
7989
  async close() {
7591
7990
  this.ready = false;
7592
7991
  }
7992
+ /**
7993
+ * Create an immutable SQLite backup of `sourcePath` under a unique name.
7994
+ *
7995
+ * @param name - Checkpoint label (must not already exist).
7996
+ * @param sourcePath - Live memory database path to snapshot.
7997
+ * @param options.description - Optional human-readable description stored in metadata.
7998
+ */
7593
7999
  async checkpoint(name, sourcePath, options) {
7594
8000
  this.requireReady();
7595
8001
  assertCheckpointName(name);
@@ -7644,6 +8050,12 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7644
8050
  fs6__default.default.renameSync(tmpMetaPath, metaPath);
7645
8051
  return meta2;
7646
8052
  }
8053
+ /**
8054
+ * Restore a named checkpoint over `targetPath` (replaces WAL/SHM side files).
8055
+ *
8056
+ * @param name - Existing checkpoint name.
8057
+ * @param targetPath - Live memory database path to overwrite.
8058
+ */
7647
8059
  async rollback(name, targetPath) {
7648
8060
  this.requireReady();
7649
8061
  const meta2 = await this.getCheckpoint(name);
@@ -7666,6 +8078,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7666
8078
  await safeSqliteBackup(meta2.snapshotPath, resolvedTarget);
7667
8079
  return meta2;
7668
8080
  }
8081
+ /** Delete checkpoint metadata and snapshot files for `name`. */
7669
8082
  async deleteCheckpoint(name) {
7670
8083
  this.requireReady();
7671
8084
  const metaPath = this.metaPath(name);
@@ -7681,6 +8094,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7681
8094
  }
7682
8095
  return removed;
7683
8096
  }
8097
+ /** List all checkpoints sorted by creation time. */
7684
8098
  async listCheckpoints() {
7685
8099
  this.requireReady();
7686
8100
  if (!fs6__default.default.existsSync(this.directory)) {
@@ -7697,6 +8111,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7697
8111
  }
7698
8112
  return out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
7699
8113
  }
8114
+ /** Load checkpoint metadata by name, or `null` if missing / corrupt. */
7700
8115
  async getCheckpoint(name) {
7701
8116
  this.requireReady();
7702
8117
  const metaPath = this.metaPath(name);
@@ -7881,6 +8296,13 @@ var SqliteSubscribeEmitter = class {
7881
8296
  }
7882
8297
  });
7883
8298
  }
8299
+ /**
8300
+ * Register a filtered callback for in-process memory change events.
8301
+ *
8302
+ * @param filter - Organization / agent / event-type filter.
8303
+ * @param callback - Invoked synchronously on each matching emit.
8304
+ * @returns Unsubscribe function.
8305
+ */
7884
8306
  subscribe(filter, callback) {
7885
8307
  if (this.closed) {
7886
8308
  throw new Error("Subscribe backend is closed");
@@ -7891,12 +8313,14 @@ var SqliteSubscribeEmitter = class {
7891
8313
  this.subscriptions.delete(id);
7892
8314
  };
7893
8315
  }
8316
+ /** Emit a memory change event to registered subscribers. */
7894
8317
  emit(event) {
7895
8318
  if (this.closed) {
7896
8319
  return;
7897
8320
  }
7898
8321
  this.emitter.emit("change", event);
7899
8322
  }
8323
+ /** Remove all listeners and mark the emitter closed. */
7900
8324
  async close() {
7901
8325
  this.closed = true;
7902
8326
  this.subscriptions.clear();
@@ -7934,6 +8358,20 @@ var Wolbarg = class {
7934
8358
  memoryDedupe = resolveMemoryDedupeConfig();
7935
8359
  embeddingCacheConfig = resolveEmbeddingCacheConfig();
7936
8360
  rawEmbedding = null;
8361
+ /**
8362
+ * @param options - Full {@link WolbargOptions}. Key fields:
8363
+ * - `organization` — namespace isolating memories in a shared DB
8364
+ * - `database` / `storage` — SQLite/Postgres config **or** a custom
8365
+ * {@link StorageProvider} instance
8366
+ * - `embedding` — {@link EmbeddingProvider} instance **or**
8367
+ * {@link EmbeddingConfig} / {@link openaiEmbedding} (etc.)
8368
+ * - `llm` — optional {@link LlmProvider} or {@link LlmConfig} / {@link openaiLlm};
8369
+ * required for {@link Wolbarg.compress} and extract-mode
8370
+ * {@link Wolbarg.rememberFromMessages}
8371
+ * - `graph`, `telemetry`, `reranker`, `keywordSearch`, `ocr`, `vision`,
8372
+ * `compression`, `chunking`, `retrieval`, `concurrency`, `embeddingCache`,
8373
+ * `memory.dedupe` — optional plugins / tuning
8374
+ */
7937
8375
  constructor(options) {
7938
8376
  this.telemetry = new TelemetryEmitter(null, { enabled: false, level: "off" });
7939
8377
  if (!options) {
@@ -7992,6 +8430,12 @@ var Wolbarg = class {
7992
8430
  }
7993
8431
  /**
7994
8432
  * Backwards-compatible initialization (v0.1 API).
8433
+ * Prefer constructing with options + {@link Wolbarg.ready} instead.
8434
+ *
8435
+ * @param options - Organization, database, embedding, and optional LLM config.
8436
+ * @returns Resolves when storage is open and the vector schema is ready.
8437
+ * @throws {InitializationError} If already initialized.
8438
+ * @throws {ConfigurationError} | {ValidationError} On invalid options.
7995
8439
  */
7996
8440
  async init(options) {
7997
8441
  if (this.initialized || this.storage) {
@@ -8023,7 +8467,14 @@ var Wolbarg = class {
8023
8467
  }
8024
8468
  await this.ready();
8025
8469
  }
8026
- /** Ensure storage (and optional telemetry) are open. */
8470
+ /**
8471
+ * Open storage, optional telemetry / checkpoint / graph providers, wrap the
8472
+ * embedding cache, and probe embedding dimensions. Safe to call multiple times;
8473
+ * concurrent callers share one boot promise.
8474
+ *
8475
+ * @returns Resolves when the instance is ready for remember/recall.
8476
+ * @throws {InitializationError} If neither constructor options nor {@link init} were used.
8477
+ */
8027
8478
  async ready() {
8028
8479
  if (this.initialized) {
8029
8480
  return;
@@ -8039,6 +8490,7 @@ var Wolbarg = class {
8039
8490
  this.booting = null;
8040
8491
  }
8041
8492
  }
8493
+ /** Internal boot sequence invoked by {@link Wolbarg.ready}. */
8042
8494
  async boot() {
8043
8495
  if (!this.storage || !this.embedding || !this.organization) {
8044
8496
  throw new InitializationError(
@@ -8114,7 +8566,17 @@ var Wolbarg = class {
8114
8566
  );
8115
8567
  }
8116
8568
  }
8117
- /** Store a semantic memory for an agent (may upsert when dedupe is enabled). */
8569
+ /**
8570
+ * Store a semantic memory for an agent. Embeds `content.text`, writes the row,
8571
+ * and may **upsert** an existing active memory when dedupe is enabled
8572
+ * (constructor `memory.dedupe` or per-call `options.dedupe`).
8573
+ *
8574
+ * @param options - Agent id, text content, optional metadata / dedupe overrides.
8575
+ * See {@link RememberOptions}.
8576
+ * @returns The stored record plus `action` (`"created"` | `"updated"`).
8577
+ * @throws {ValidationError} On empty agent/content.
8578
+ * @throws {InitializationError} If not configured / ready.
8579
+ */
8118
8580
  async remember(options) {
8119
8581
  const trace = this.telemetry.start("remember");
8120
8582
  try {
@@ -8136,7 +8598,15 @@ var Wolbarg = class {
8136
8598
  throw wrapOperationError("remember", error);
8137
8599
  }
8138
8600
  }
8139
- /** Batch remember — sequential when dedupe enabled; otherwise one TX batch. */
8601
+ /**
8602
+ * Remember many memories in one call. Runs sequentially when any item (or the
8603
+ * global config) enables dedupe; otherwise embeds in batch and inserts in one
8604
+ * transaction for throughput.
8605
+ *
8606
+ * @param items - Non-empty list of {@link RememberOptions}.
8607
+ * @returns One {@link RememberResult} per input, same order.
8608
+ * @throws {ValidationError} If `items` is empty or an entry is invalid.
8609
+ */
8140
8610
  async rememberBatch(items) {
8141
8611
  const parent = this.telemetry.start("rememberBatch");
8142
8612
  try {
@@ -8262,7 +8732,15 @@ var Wolbarg = class {
8262
8732
  * **Experimental** until 1.0 — API shape may change.
8263
8733
  *
8264
8734
  * - `mode: "raw"` (default) — remember user message text (no LLM).
8265
- * - `mode: "extract"` — require configured `llm`; extract atomic facts then remember each.
8735
+ * - `mode: "extract"` — requires configured `llm`; extracts atomic facts then
8736
+ * remembers each. Pass a custom {@link LlmProvider} or {@link openaiLlm}
8737
+ * in the constructor.
8738
+ *
8739
+ * @param messages - Conversation turns (`role` + `content`).
8740
+ * @param options - Agent, mode, optional metadata/dedupe. See
8741
+ * {@link RememberFromMessagesOptions}.
8742
+ * @returns One {@link RememberResult} per remembered fact/message.
8743
+ * @throws {ProviderNotConfiguredError} When `mode: "extract"` but no `llm` was configured.
8266
8744
  */
8267
8745
  async rememberFromMessages(messages, options) {
8268
8746
  const parent = this.telemetry.start("rememberFromMessages");
@@ -8332,7 +8810,14 @@ var Wolbarg = class {
8332
8810
  }
8333
8811
  }
8334
8812
  /**
8335
- * Update an existing memory by id (re-embeds when content changes).
8813
+ * Update an existing memory by id. Re-embeds when `content` changes; merges
8814
+ * metadata when provided.
8815
+ *
8816
+ * @param options.id - Memory id to update.
8817
+ * @param options.content - Optional new `{ text }` (triggers re-embed + content hash).
8818
+ * @param options.metadata - Optional metadata merged onto the existing record.
8819
+ * @returns Updated record with `action: "updated"`.
8820
+ * @throws {MemoryNotFoundError} If the id is unknown in this organization.
8336
8821
  */
8337
8822
  async update(options) {
8338
8823
  const trace = this.telemetry.start("update");
@@ -8402,10 +8887,18 @@ var Wolbarg = class {
8402
8887
  }
8403
8888
  }
8404
8889
  /**
8405
- * Subscribe to memory change events.
8890
+ * Subscribe to memory change events (remember / update / forget / compress / clear).
8406
8891
  *
8407
8892
  * **SQLite:** delivers events only within this Node.js process.
8408
8893
  * A second process writing the same `memory.db` will not notify subscribers here.
8894
+ *
8895
+ * **Postgres:** uses LISTEN/NOTIFY across processes (lazy connection on first subscribe).
8896
+ *
8897
+ * @param filter - Scope by `organization` (defaults to this instance’s org),
8898
+ * optional `agent`, and optional `events` allow-list. See {@link SubscribeFilter}.
8899
+ * @param callback - Invoked with each {@link MemoryChangeEvent}.
8900
+ * @returns {@link Unsubscribe} function — call to stop receiving events.
8901
+ * @throws {ValidationError} If organization cannot be resolved.
8409
8902
  */
8410
8903
  subscribe(filter, callback) {
8411
8904
  const org = filter.organization || this.organization;
@@ -8434,6 +8927,7 @@ var Wolbarg = class {
8434
8927
  }
8435
8928
  return this.subscribeBackend.subscribe(normalized, callback);
8436
8929
  }
8930
+ /** Broadcast a memory change event to in-process or Postgres NOTIFY subscribers. */
8437
8931
  emitChange(event) {
8438
8932
  try {
8439
8933
  if (this.storage instanceof PostgresStorageProvider) {
@@ -8659,6 +9153,17 @@ var Wolbarg = class {
8659
9153
  throw error;
8660
9154
  }
8661
9155
  }
9156
+ /**
9157
+ * Find the best active near-duplicate memory for upsert (cosine similarity ≥ threshold).
9158
+ *
9159
+ * @param storage - Open storage provider.
9160
+ * @param organization - Org namespace.
9161
+ * @param agent - Agent scope for the search.
9162
+ * @param vector - Embedding of the candidate text.
9163
+ * @param threshold - Minimum similarity (0–1) to treat as a duplicate.
9164
+ * @param limit - Max vector candidates to inspect.
9165
+ * @returns Matching memory row, or `null` if none qualify.
9166
+ */
8662
9167
  async findNearDuplicate(storage, organization, agent, vector, threshold, limit) {
8663
9168
  if (typeof storage.searchVectorsWithMemories === "function") {
8664
9169
  const hits2 = await storage.searchVectorsWithMemories(
@@ -8996,7 +9501,13 @@ var Wolbarg = class {
8996
9501
  throw wrapOperationError("recall", error);
8997
9502
  }
8998
9503
  }
8999
- /** Batch recall — parent event + child traces. */
9504
+ /**
9505
+ * Run multiple recalls sequentially under one parent telemetry span.
9506
+ *
9507
+ * @param queries - Non-empty list of recall options (`explain` is forced off).
9508
+ * @returns One hit array per query, same order.
9509
+ * @throws {ValidationError} If `queries` is empty.
9510
+ */
9000
9511
  async recallBatch(queries) {
9001
9512
  const parent = this.telemetry.start("recallBatch");
9002
9513
  try {
@@ -9030,10 +9541,21 @@ var Wolbarg = class {
9030
9541
  throw wrapOperationError("recallBatch", error);
9031
9542
  }
9032
9543
  }
9544
+ /**
9545
+ * Compress the newest active memories for an agent into one summary memory
9546
+ * and archive the sources. Requires an `llm` (or custom `compression`) at
9547
+ * construction — typed only on `Wolbarg<true>`.
9548
+ *
9549
+ * @param options - `agent` required; optional `limit` (default 50, min 2).
9550
+ * See {@link CompressOptions}.
9551
+ * @returns Summary record plus archived source ids. See {@link CompressResult}.
9552
+ * @throws {ProviderNotConfiguredError} If no LLM/compression provider is set.
9553
+ * @throws {ValidationError} If fewer than 2 active memories exist for the agent.
9554
+ */
9033
9555
  async compress(options) {
9034
9556
  return this.runCompress(options);
9035
9557
  }
9036
- /** @internal */
9558
+ /** @internal Runs compress for both typed and untyped call sites. */
9037
9559
  async runCompress(options) {
9038
9560
  const trace = this.telemetry.start("compress");
9039
9561
  try {
@@ -9122,6 +9644,16 @@ var Wolbarg = class {
9122
9644
  throw wrapOperationError("compress", error);
9123
9645
  }
9124
9646
  }
9647
+ /**
9648
+ * Ingest a document (path, URL, Buffer, or text), chunk it, embed chunks, and
9649
+ * store each as a memory. Images use optional `ocr` / `vision` providers from
9650
+ * the constructor.
9651
+ *
9652
+ * @param options - `agent`, `source`, optional chunking overrides / metadata.
9653
+ * See {@link IngestOptions}.
9654
+ * @returns Counts and created memory ids. See {@link IngestResult}.
9655
+ * @throws {ValidationError} If no text can be extracted or chunking yields zero chunks.
9656
+ */
9125
9657
  async ingest(options) {
9126
9658
  const trace = this.telemetry.start("ingest");
9127
9659
  try {
@@ -9292,8 +9824,14 @@ var Wolbarg = class {
9292
9824
  }
9293
9825
  }
9294
9826
  /**
9295
- * Link two memories in the optional graph layer.
9296
- * Throws {@link ProviderNotConfiguredError} when no graph provider is set.
9827
+ * Link two memories in the optional graph layer with a typed relation edge.
9828
+ *
9829
+ * @param fromId - Source memory id.
9830
+ * @param toId - Target memory id.
9831
+ * @param relation - Edge label (e.g. `"supports"`, `"caused_by"`).
9832
+ * @param metadata - Optional edge properties stored on the graph provider.
9833
+ * @throws {ProviderNotConfiguredError} When no `graph` was configured.
9834
+ * @throws {ValidationError} On empty ids/relation.
9297
9835
  */
9298
9836
  async linkMemories(fromId, toId, relation, metadata) {
9299
9837
  const trace = this.telemetry.start("linkMemories");
@@ -9323,8 +9861,13 @@ var Wolbarg = class {
9323
9861
  }
9324
9862
  /**
9325
9863
  * Traverse related memories via the optional graph layer.
9326
- * Throws {@link ProviderNotConfiguredError} when no graph provider is set.
9327
- * Results are re-hydrated from SQL storage when available.
9864
+ * Neighbor stubs from the graph are re-hydrated from SQL storage when available.
9865
+ *
9866
+ * @param memoryId - Seed memory id.
9867
+ * @param options - Optional `relation`, `direction`, `depth`, `limit`.
9868
+ * See {@link GetRelatedOptions}.
9869
+ * @returns Related {@link MemoryRecord} list (may be empty).
9870
+ * @throws {ProviderNotConfiguredError} When no `graph` was configured.
9328
9871
  */
9329
9872
  async getRelated(memoryId, options) {
9330
9873
  const trace = this.telemetry.start("getRelated");
@@ -9361,6 +9904,14 @@ var Wolbarg = class {
9361
9904
  throw wrapOperationError("getRelated", error);
9362
9905
  }
9363
9906
  }
9907
+ /**
9908
+ * Delete memories by id or by agent filter. Cascades graph nodes/edges when
9909
+ * a graph provider is configured.
9910
+ *
9911
+ * @param options - Either `{ id }` or `{ filter: { agent } }`. See {@link ForgetOptions}.
9912
+ * @returns Number of memories deleted.
9913
+ * @throws {ValidationError} If neither `id` nor `filter.agent` is provided.
9914
+ */
9364
9915
  async forget(options) {
9365
9916
  const trace = this.telemetry.start("forget");
9366
9917
  try {
@@ -9425,6 +9976,13 @@ var Wolbarg = class {
9425
9976
  throw wrapOperationError("forget", error);
9426
9977
  }
9427
9978
  }
9979
+ /**
9980
+ * Return the audit/history timeline for a single memory.
9981
+ *
9982
+ * @param options - `{ id }` of the memory. See {@link HistoryOptions}.
9983
+ * @returns Memory record plus ordered {@link HistoryEvent} list.
9984
+ * @throws {MemoryNotFoundError} If the id is unknown.
9985
+ */
9428
9986
  async history(options) {
9429
9987
  const trace = this.telemetry.start("history");
9430
9988
  try {
@@ -9452,6 +10010,11 @@ var Wolbarg = class {
9452
10010
  throw wrapOperationError("history", error);
9453
10011
  }
9454
10012
  }
10013
+ /**
10014
+ * Aggregate counts for this organization (active / archived / agents / etc.).
10015
+ *
10016
+ * @returns {@link StatsResult} snapshot.
10017
+ */
9455
10018
  async stats() {
9456
10019
  const trace = this.telemetry.start("stats");
9457
10020
  try {
@@ -9479,6 +10042,13 @@ var Wolbarg = class {
9479
10042
  throw wrapOperationError("stats", error);
9480
10043
  }
9481
10044
  }
10045
+ /**
10046
+ * Delete all memories for this organization (optionally scoped by agent).
10047
+ * Cascades graph cleanup when a graph provider is configured.
10048
+ *
10049
+ * @param options - Optional `{ agent }` scope. See {@link ClearOptions}.
10050
+ * @returns Number of memories deleted.
10051
+ */
9482
10052
  async clear(options) {
9483
10053
  const trace = this.telemetry.start("clear");
9484
10054
  try {
@@ -9507,7 +10077,16 @@ var Wolbarg = class {
9507
10077
  throw wrapOperationError("clear", error);
9508
10078
  }
9509
10079
  }
9510
- /** Create an immutable named checkpoint of the memory database. */
10080
+ /**
10081
+ * Create an immutable named checkpoint of the file-backed SQLite memory DB
10082
+ * (and SQLite graph snapshot when applicable).
10083
+ *
10084
+ * @param name - Checkpoint name (unique).
10085
+ * @param options - Optional metadata. See {@link CheckpointOptions}.
10086
+ * @returns {@link CheckpointInfo} for the new checkpoint.
10087
+ * @throws {ProviderNotConfiguredError} Without a checkpoint provider / file DB.
10088
+ * @throws {GraphCheckpointNotSupportedError} For Neo4j graph backends.
10089
+ */
9511
10090
  async checkpoint(name, options) {
9512
10091
  const trace = this.telemetry.start("checkpoint");
9513
10092
  try {
@@ -9538,7 +10117,12 @@ var Wolbarg = class {
9538
10117
  throw wrapOperationError("checkpoint", error);
9539
10118
  }
9540
10119
  }
9541
- /** Restore the memory database from a named checkpoint. */
10120
+ /**
10121
+ * Restore the memory database from a named checkpoint (replaces the live DB file).
10122
+ *
10123
+ * @param name - Checkpoint name previously created with {@link Wolbarg.checkpoint}.
10124
+ * @returns {@link CheckpointInfo} of the restored checkpoint.
10125
+ */
9542
10126
  async rollback(name) {
9543
10127
  const trace = this.telemetry.start("rollback");
9544
10128
  let storageClosed = false;
@@ -9584,6 +10168,12 @@ var Wolbarg = class {
9584
10168
  throw wrapOperationError("rollback", error);
9585
10169
  }
9586
10170
  }
10171
+ /**
10172
+ * Delete a named checkpoint from disk / the checkpoint store.
10173
+ *
10174
+ * @param name - Checkpoint name.
10175
+ * @returns `true` if a checkpoint was removed.
10176
+ */
9587
10177
  async deleteCheckpoint(name) {
9588
10178
  const trace = this.telemetry.start("deleteCheckpoint");
9589
10179
  try {
@@ -9610,6 +10200,11 @@ var Wolbarg = class {
9610
10200
  throw wrapOperationError("deleteCheckpoint", error);
9611
10201
  }
9612
10202
  }
10203
+ /**
10204
+ * List all known checkpoints for this instance.
10205
+ *
10206
+ * @returns Array of {@link CheckpointInfo} (may be empty).
10207
+ */
9613
10208
  async listCheckpoints() {
9614
10209
  const trace = this.telemetry.start("listCheckpoints");
9615
10210
  try {
@@ -9628,6 +10223,12 @@ var Wolbarg = class {
9628
10223
  throw wrapOperationError("listCheckpoints", error);
9629
10224
  }
9630
10225
  }
10226
+ /**
10227
+ * Look up a single checkpoint by name.
10228
+ *
10229
+ * @param name - Checkpoint name.
10230
+ * @returns {@link CheckpointInfo} or `null` if missing.
10231
+ */
9631
10232
  async getCheckpoint(name) {
9632
10233
  const trace = this.telemetry.start("getCheckpoint");
9633
10234
  try {
@@ -9647,7 +10248,13 @@ var Wolbarg = class {
9647
10248
  throw wrapOperationError("getCheckpoint", error);
9648
10249
  }
9649
10250
  }
9650
- /** Export the memory database to a portable SQLite + manifest bundle. */
10251
+ /**
10252
+ * Export the memory database to a portable SQLite + manifest bundle
10253
+ * (includes SQLite graph sidecar when applicable).
10254
+ *
10255
+ * @param exportPath - Destination file path for the export bundle.
10256
+ * @returns {@link ExportResult} with path, size, and timestamp.
10257
+ */
9651
10258
  async export(exportPath) {
9652
10259
  const trace = this.telemetry.start("export");
9653
10260
  try {
@@ -9678,7 +10285,13 @@ var Wolbarg = class {
9678
10285
  throw wrapOperationError("export", error);
9679
10286
  }
9680
10287
  }
9681
- /** Import a previously exported memory database, replacing the current file. */
10288
+ /**
10289
+ * Import a previously exported memory database, replacing the current file.
10290
+ * Closes and reopens storage around the swap.
10291
+ *
10292
+ * @param exportPath - Path to a bundle produced by {@link Wolbarg.export}.
10293
+ * @returns {@link ImportResult} with restored path and timestamp.
10294
+ */
9682
10295
  async import(exportPath) {
9683
10296
  const trace = this.telemetry.start("import");
9684
10297
  let storageClosed = false;
@@ -9728,11 +10341,17 @@ var Wolbarg = class {
9728
10341
  throw wrapOperationError("import", error);
9729
10342
  }
9730
10343
  }
9731
- /** Flush pending telemetry (useful in tests). */
10344
+ /**
10345
+ * Flush pending telemetry writes (useful in tests / before process exit).
10346
+ *
10347
+ * @returns Resolves when the telemetry provider has flushed.
10348
+ */
9732
10349
  async flushTelemetry() {
9733
10350
  await this.telemetry.flush();
9734
10351
  }
9735
- /** Session id for this SDK instance (telemetry traces). */
10352
+ /**
10353
+ * Session id for this SDK instance (attached to telemetry traces and change events).
10354
+ */
9736
10355
  get sessionId() {
9737
10356
  return this.telemetry.sessionId;
9738
10357
  }
@@ -9747,6 +10366,12 @@ var Wolbarg = class {
9747
10366
  }
9748
10367
  return fn();
9749
10368
  }
10369
+ /**
10370
+ * Close storage, graph, telemetry, checkpoints, and subscribe backends.
10371
+ * The instance can be discarded afterward; construct a new one to reopen.
10372
+ *
10373
+ * @returns Resolves when all providers have closed (errors are swallowed per-provider).
10374
+ */
9750
10375
  async close() {
9751
10376
  if (this.storage) {
9752
10377
  this.telemetry.emitShutdown(this.storage.name);
@@ -9771,9 +10396,11 @@ var Wolbarg = class {
9771
10396
  this.embeddingDimensions = null;
9772
10397
  this.initialized = false;
9773
10398
  }
10399
+ /** Whether {@link Wolbarg.ready} / {@link Wolbarg.init} has completed successfully. */
9774
10400
  get isInitialized() {
9775
10401
  return this.initialized;
9776
10402
  }
10403
+ /** Ensure {@link Wolbarg.ready} completed and core providers are available. */
9777
10404
  async requireReady() {
9778
10405
  await this.ready();
9779
10406
  if (!this.initialized || !this.storage || !this.embedding || !this.organization) {
@@ -9787,6 +10414,7 @@ var Wolbarg = class {
9787
10414
  organization: this.organization
9788
10415
  };
9789
10416
  }
10417
+ /** Reject embeddings whose dimensionality differs from the initialized model. */
9790
10418
  assertEmbeddingDimensions(dimensions) {
9791
10419
  if (this.embeddingDimensions !== null && dimensions !== this.embeddingDimensions) {
9792
10420
  throw new ValidationError(
@@ -9794,6 +10422,7 @@ var Wolbarg = class {
9794
10422
  );
9795
10423
  }
9796
10424
  }
10425
+ /** Return the configured checkpoint provider or throw {@link ProviderNotConfiguredError}. */
9797
10426
  requireCheckpointProvider() {
9798
10427
  if (!this.checkpointProvider) {
9799
10428
  throw new ProviderNotConfiguredError(
@@ -9804,6 +10433,7 @@ var Wolbarg = class {
9804
10433
  }
9805
10434
  return this.checkpointProvider;
9806
10435
  }
10436
+ /** Return the configured graph provider or throw with a setup hint for `method`. */
9807
10437
  requireGraph(method) {
9808
10438
  if (!this.graph) {
9809
10439
  throw new ProviderNotConfiguredError(
@@ -9814,20 +10444,24 @@ var Wolbarg = class {
9814
10444
  }
9815
10445
  return this.graph;
9816
10446
  }
10447
+ /** Throw when graph checkpoint pairing is requested on a non-file-backed graph backend. */
9817
10448
  assertGraphCheckpointSupported(operation) {
9818
10449
  if (!this.graph) return;
9819
10450
  if (!this.graph.supportsFileSnapshot()) {
9820
10451
  throw new GraphCheckpointNotSupportedError(this.graph.name, operation);
9821
10452
  }
9822
10453
  }
10454
+ /** Directory path where a graph file snapshot is stored alongside a memory checkpoint. */
9823
10455
  graphSnapshotDir(alongsidePath) {
9824
10456
  return `${alongsidePath}.graph`;
9825
10457
  }
10458
+ /** Close the graph provider before copying files; returns whether a close occurred. */
9826
10459
  async closeGraphForSnapshot() {
9827
10460
  if (!this.graph || !this.graph.supportsFileSnapshot()) return false;
9828
10461
  await this.graph.close();
9829
10462
  return true;
9830
10463
  }
10464
+ /** Copy the SQLite graph database next to a memory checkpoint directory. */
9831
10465
  async snapshotGraphAlongside(alongsidePath, operation) {
9832
10466
  if (!this.graph) return;
9833
10467
  if (!this.graph.supportsFileSnapshot()) {
@@ -9866,6 +10500,7 @@ var Wolbarg = class {
9866
10500
  await this.graph.open();
9867
10501
  }
9868
10502
  }
10503
+ /** Restore a graph file snapshot written by {@link snapshotGraphAlongside}. */
9869
10504
  async restoreGraphAlongside(alongsidePath, operation) {
9870
10505
  if (!this.graph) return;
9871
10506
  if (!this.graph.supportsFileSnapshot()) {
@@ -9889,6 +10524,7 @@ var Wolbarg = class {
9889
10524
  fs6__default.default.cpSync(src, dataPath, { recursive: true });
9890
10525
  }
9891
10526
  }
10527
+ /** Run graph traversal then re-hydrate stub records from storage when rows exist. */
9892
10528
  async hydrateRelated(memoryId, options) {
9893
10529
  const graph = this.requireGraph("getRelated");
9894
10530
  const related = await graph.getRelated(memoryId, options);
@@ -9904,6 +10540,7 @@ var Wolbarg = class {
9904
10540
  }
9905
10541
  return out;
9906
10542
  }
10543
+ /** Resolve the on-disk SQLite memory database path (throws for Postgres / `:memory:`). */
9907
10544
  requireMemoryDbPath() {
9908
10545
  if (this.storage && !(this.storage instanceof SqliteStorageProvider)) {
9909
10546
  throw new ConfigurationError(
@@ -9955,6 +10592,7 @@ function commonTags(metadata) {
9955
10592
 
9956
10593
  // src/filters/types.ts
9957
10594
  var meta = {
10595
+ /** Field equals value (strict equality). */
9958
10596
  eq: (field, value) => ({
9959
10597
  field,
9960
10598
  op: { eq: value }
@@ -10038,16 +10676,23 @@ function createTelemetryProvider(config) {
10038
10676
  function wolbarg2(options) {
10039
10677
  return new Wolbarg(options);
10040
10678
  }
10679
+ var createWolbarg = wolbarg2;
10041
10680
 
10042
10681
  // src/keyword/index.ts
10043
10682
  var Bm25KeywordSearchProvider = class {
10044
10683
  name = "bm25";
10045
10684
  k1;
10046
10685
  b;
10686
+ /**
10687
+ * @param options - BM25 tuning parameters.
10688
+ * @param options.k1 - Term frequency saturation (default `1.2`).
10689
+ * @param options.b - Length normalization (default `0.75`).
10690
+ */
10047
10691
  constructor(options) {
10048
10692
  this.k1 = options?.k1 ?? 1.2;
10049
10693
  this.b = options?.b ?? 0.75;
10050
10694
  }
10695
+ /** @inheritdoc */
10051
10696
  async search(query, documents, topK) {
10052
10697
  if (documents.length === 0 || topK <= 0) {
10053
10698
  return [];
@@ -10540,7 +11185,7 @@ exports.createEmbeddingProvider = createEmbeddingProvider;
10540
11185
  exports.createLlmProvider = createLlmProvider;
10541
11186
  exports.createStorageProvider = createStorageProvider;
10542
11187
  exports.createTelemetryProvider = createTelemetryProvider;
10543
- exports.createWolbarg = wolbarg2;
11188
+ exports.createWolbarg = createWolbarg;
10544
11189
  exports.crossEncoder = crossEncoder;
10545
11190
  exports.geminiEmbedding = geminiEmbedding;
10546
11191
  exports.geminiVision = geminiVision;