wolbarg 0.5.4 → 0.5.6

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.js CHANGED
@@ -1,5 +1,5 @@
1
- import fs6 from "node:fs";
2
- import path7 from "node:path";
1
+ import fs6, { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import path7, { isAbsolute, resolve, dirname, join } from "node:path";
3
3
  import { createHash } from 'crypto';
4
4
  import fs from 'fs/promises';
5
5
  import { DatabaseSync } from "node:sqlite";
@@ -15,6 +15,11 @@ var WolbargError = class extends Error {
15
15
  reason;
16
16
  suggestion;
17
17
  operation;
18
+ /**
19
+ * @param message - Human-readable error message.
20
+ * @param code - Stable error code string.
21
+ * @param options - Optional cause, reason, suggestion, and operation name.
22
+ */
18
23
  constructor(message, code, options) {
19
24
  super(message, options);
20
25
  this.name = "WolbargError";
@@ -26,48 +31,80 @@ var WolbargError = class extends Error {
26
31
  }
27
32
  };
28
33
  var InitializationError = class extends WolbargError {
34
+ /**
35
+ * @param message - Description of the initialization failure.
36
+ * @param options - Optional cause and structured hints.
37
+ */
29
38
  constructor(message, options) {
30
39
  super(message, "INITIALIZATION_ERROR", options);
31
40
  this.name = "InitializationError";
32
41
  }
33
42
  };
34
43
  var ConfigurationError = class extends WolbargError {
44
+ /**
45
+ * @param message - Description of the misconfiguration.
46
+ * @param options - Optional cause, reason, suggestion, and operation name.
47
+ */
35
48
  constructor(message, options) {
36
49
  super(message, "CONFIGURATION_ERROR", options);
37
50
  this.name = "ConfigurationError";
38
51
  }
39
52
  };
40
53
  var ValidationError = class extends WolbargError {
54
+ /**
55
+ * @param message - Which argument failed and why.
56
+ * @param options - Optional cause and structured hints.
57
+ */
41
58
  constructor(message, options) {
42
59
  super(message, "VALIDATION_ERROR", options);
43
60
  this.name = "ValidationError";
44
61
  }
45
62
  };
46
63
  var DatabaseError = class extends WolbargError {
64
+ /**
65
+ * @param message - Operation-scoped failure message.
66
+ * @param options - Optional underlying `cause` and hints.
67
+ */
47
68
  constructor(message, options) {
48
69
  super(message, "DATABASE_ERROR", options);
49
70
  this.name = "DatabaseError";
50
71
  }
51
72
  };
52
73
  var StorageLockedError = class extends WolbargError {
74
+ /**
75
+ * @param message - Lock contention description.
76
+ * @param options - Typically includes suggestion to tune concurrency or use Postgres.
77
+ */
53
78
  constructor(message, options) {
54
79
  super(message, "WOLBARG_STORAGE_LOCKED", options);
55
80
  this.name = "StorageLockedError";
56
81
  }
57
82
  };
58
83
  var EmbeddingError = class extends WolbargError {
84
+ /**
85
+ * @param message - Embedding failure description.
86
+ * @param options - Optional HTTP cause and provider hints.
87
+ */
59
88
  constructor(message, options) {
60
89
  super(message, "EMBEDDING_ERROR", options);
61
90
  this.name = "EmbeddingError";
62
91
  }
63
92
  };
64
93
  var CompressionError = class extends WolbargError {
94
+ /**
95
+ * @param message - Compression failure description.
96
+ * @param options - Optional LLM cause chain.
97
+ */
65
98
  constructor(message, options) {
66
99
  super(message, "COMPRESSION_ERROR", options);
67
100
  this.name = "CompressionError";
68
101
  }
69
102
  };
70
103
  var MemoryNotFoundError = class extends WolbargError {
104
+ /**
105
+ * @param message - Which memory was not found.
106
+ * @param options - Optional operation context.
107
+ */
71
108
  constructor(message, options) {
72
109
  super(message, "MEMORY_NOT_FOUND", options);
73
110
  this.name = "MemoryNotFoundError";
@@ -75,6 +112,11 @@ var MemoryNotFoundError = class extends WolbargError {
75
112
  };
76
113
  var ProviderNotConfiguredError = class extends ConfigurationError {
77
114
  provider;
115
+ /**
116
+ * @param provider - Provider name (e.g. `"reranker"`, `"graph"`).
117
+ * @param method - Facade method that requires the provider.
118
+ * @param hint - Install or config instruction shown to the developer.
119
+ */
78
120
  constructor(provider, method, hint) {
79
121
  super(`${method} requires ${provider} \u2014 ${hint}`, {
80
122
  operation: method,
@@ -86,6 +128,10 @@ var ProviderNotConfiguredError = class extends ConfigurationError {
86
128
  }
87
129
  };
88
130
  var GraphCheckpointNotSupportedError = class extends WolbargError {
131
+ /**
132
+ * @param backend - Graph backend name (e.g. `"neo4j"`).
133
+ * @param operation - Requested operation (e.g. `"checkpoint"`).
134
+ */
89
135
  constructor(backend, operation) {
90
136
  super(
91
137
  `graph checkpoint not supported for network-backed graph providers (${backend})`,
@@ -158,9 +204,11 @@ Rules:
158
204
  var LlmCompressionProvider = class {
159
205
  name = "llm";
160
206
  llm;
207
+ /** @param llm - Configured LLM used for summarization. */
161
208
  constructor(llm) {
162
209
  this.llm = llm;
163
210
  }
211
+ /** @inheritdoc */
164
212
  async compress(memories) {
165
213
  return compressMemories(this.llm, memories);
166
214
  }
@@ -269,6 +317,7 @@ function slidingWindow(text, chunkSize, overlap) {
269
317
  }
270
318
  var FixedChunkingStrategy = class {
271
319
  name = "fixed";
320
+ /** @inheritdoc */
272
321
  chunk(text, options) {
273
322
  const { chunkSize, overlap } = clampOptions(options);
274
323
  return slidingWindow(text, chunkSize, overlap);
@@ -276,6 +325,7 @@ var FixedChunkingStrategy = class {
276
325
  };
277
326
  var SentenceChunkingStrategy = class {
278
327
  name = "sentence";
328
+ /** @inheritdoc */
279
329
  chunk(text, options) {
280
330
  const { chunkSize, overlap } = clampOptions(options);
281
331
  const sentences = text.split(/(?<=[.!?])\s+/).map((s) => s.trim()).filter(Boolean);
@@ -284,6 +334,7 @@ var SentenceChunkingStrategy = class {
284
334
  };
285
335
  var ParagraphChunkingStrategy = class {
286
336
  name = "paragraph";
337
+ /** @inheritdoc */
287
338
  chunk(text, options) {
288
339
  const { chunkSize, overlap } = clampOptions(options);
289
340
  const paragraphs = text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
@@ -292,6 +343,7 @@ var ParagraphChunkingStrategy = class {
292
343
  };
293
344
  var MarkdownChunkingStrategy = class {
294
345
  name = "markdown";
346
+ /** @inheritdoc */
295
347
  chunk(text, options) {
296
348
  const { chunkSize, overlap } = clampOptions(options);
297
349
  const sections = text.split(/(?=^#{1,6}\s)/m).map((s) => s.trim()).filter(Boolean);
@@ -303,6 +355,7 @@ var MarkdownChunkingStrategy = class {
303
355
  };
304
356
  var HeadingChunkingStrategy = class {
305
357
  name = "heading";
358
+ /** @inheritdoc */
306
359
  chunk(text, options) {
307
360
  return new MarkdownChunkingStrategy().chunk(text, options);
308
361
  }
@@ -384,10 +437,16 @@ function distanceToSimilarity(distance) {
384
437
  }
385
438
  var AsyncMutex = class {
386
439
  chain = Promise.resolve();
440
+ /**
441
+ * Run `fn` exclusively — concurrent callers queue on the same mutex.
442
+ *
443
+ * @param fn - Async or sync work to serialize.
444
+ * @returns The value returned by `fn`.
445
+ */
387
446
  async runExclusive(fn) {
388
447
  let release;
389
- const next = new Promise((resolve) => {
390
- release = resolve;
448
+ const next = new Promise((resolve3) => {
449
+ release = resolve3;
391
450
  });
392
451
  const previous = this.chain;
393
452
  this.chain = previous.then(() => next);
@@ -407,16 +466,32 @@ function joinUrl(baseUrl, path8) {
407
466
 
408
467
  // src/embedding/index.ts
409
468
  var OpenAICompatibleEmbeddingProvider = class {
469
+ /** Model name sent in the request body. */
410
470
  model;
411
471
  baseUrl;
412
472
  apiKey;
413
473
  timeoutMs;
474
+ /**
475
+ * @param config - OpenAI-compatible embedding endpoint settings.
476
+ * @param config.baseUrl - API root, e.g. `https://api.openai.com/v1`.
477
+ * @param config.apiKey - Bearer token. Use any non-empty string for local
478
+ * servers that ignore auth.
479
+ * @param config.model - Embedding model id (e.g. `"text-embedding-3-small"`).
480
+ * @param config.timeoutMs - Abort after this many ms. Defaults to `30_000`.
481
+ */
414
482
  constructor(config) {
415
483
  this.baseUrl = config.baseUrl;
416
484
  this.apiKey = config.apiKey;
417
485
  this.model = config.model;
418
486
  this.timeoutMs = config.timeoutMs ?? 3e4;
419
487
  }
488
+ /**
489
+ * Embed a single string.
490
+ *
491
+ * @param text - Input text.
492
+ * @returns Embedding vector.
493
+ * @throws {EmbeddingError} On HTTP errors, timeouts, or empty vectors.
494
+ */
420
495
  async embed(text) {
421
496
  const response = await this.request(text);
422
497
  const vector = response.data?.[0]?.embedding;
@@ -425,6 +500,13 @@ var OpenAICompatibleEmbeddingProvider = class {
425
500
  }
426
501
  return Float32Array.from(vector);
427
502
  }
503
+ /**
504
+ * Embed multiple strings in one API call when the server supports batch input.
505
+ * Falls back to sequential {@link embed} if the response length mismatches.
506
+ *
507
+ * @param texts - Inputs to embed.
508
+ * @returns One vector per input, same order.
509
+ */
428
510
  async embedBatch(texts) {
429
511
  if (texts.length === 0) {
430
512
  return [];
@@ -451,6 +533,12 @@ var OpenAICompatibleEmbeddingProvider = class {
451
533
  return Float32Array.from(item.embedding);
452
534
  });
453
535
  }
536
+ /**
537
+ * Probe the endpoint and report vector dimensionality.
538
+ *
539
+ * @returns `{ dimensions }` from a fixed health-check string.
540
+ * @throws {EmbeddingError} When the probe fails.
541
+ */
454
542
  async validate() {
455
543
  try {
456
544
  const embedding = await this.embed("Wolbarg health check");
@@ -465,6 +553,12 @@ var OpenAICompatibleEmbeddingProvider = class {
465
553
  );
466
554
  }
467
555
  }
556
+ /**
557
+ * Low-level HTTP request to `/embeddings`.
558
+ *
559
+ * @param input - Single string or batch of strings.
560
+ * @returns Parsed OpenAI-style JSON body.
561
+ */
468
562
  async request(input) {
469
563
  const url = joinUrl(this.baseUrl, "/embeddings");
470
564
  const controller = new AbortController();
@@ -512,6 +606,7 @@ var OpenAICompatibleEmbeddingProvider = class {
512
606
  clearTimeout(timer);
513
607
  }
514
608
  }
609
+ /** @param error - Unknown thrown value. @returns Human-readable message. */
515
610
  describe(error) {
516
611
  if (error instanceof Error) {
517
612
  return error.message;
@@ -768,6 +863,10 @@ var SqliteEmbeddingCacheStore = class {
768
863
  pendingSets = /* @__PURE__ */ new Map();
769
864
  persistScheduled = false;
770
865
  stmts = null;
866
+ /**
867
+ * @param dbOrGetter - SQLite `DatabaseSync` or lazy getter (allows late bind).
868
+ * @param options.ttlMs - Optional TTL for cache entries on read.
869
+ */
771
870
  constructor(dbOrGetter, options) {
772
871
  this.ttlMs = options?.ttlMs ?? null;
773
872
  this.getDb = typeof dbOrGetter === "function" ? dbOrGetter : () => dbOrGetter;
@@ -1044,12 +1143,23 @@ var PostgresEmbeddingCacheStore = class {
1044
1143
 
1045
1144
  // src/llm/index.ts
1046
1145
  var OpenAICompatibleLlmProvider = class {
1146
+ /** Model name sent in the request body and exposed on the provider. */
1047
1147
  model;
1048
1148
  baseUrl;
1049
1149
  apiKey;
1050
1150
  temperature;
1051
1151
  maxTokens;
1052
1152
  timeoutMs;
1153
+ /**
1154
+ * @param config - OpenAI-compatible endpoint settings.
1155
+ * @param config.baseUrl - API root, e.g. `https://api.openai.com/v1` (no trailing `/chat/completions`).
1156
+ * @param config.apiKey - Bearer token (`Authorization: Bearer …`). Use any non-empty
1157
+ * string for local servers that ignore auth (e.g. `"ollama"`).
1158
+ * @param config.model - Chat model id (e.g. `"gpt-4o-mini"`, `"llama3.2"`).
1159
+ * @param config.temperature - Sampling temperature. Defaults to `0.2`.
1160
+ * @param config.maxTokens - Max completion tokens. Defaults to `4096`.
1161
+ * @param config.timeoutMs - Abort after this many ms. Defaults to `60_000`.
1162
+ */
1053
1163
  constructor(config) {
1054
1164
  this.baseUrl = config.baseUrl;
1055
1165
  this.apiKey = config.apiKey;
@@ -1058,6 +1168,13 @@ var OpenAICompatibleLlmProvider = class {
1058
1168
  this.maxTokens = config.maxTokens ?? 4096;
1059
1169
  this.timeoutMs = config.timeoutMs ?? 6e4;
1060
1170
  }
1171
+ /**
1172
+ * Call `/chat/completions` and return the first choice’s message content.
1173
+ *
1174
+ * @param messages - Chat turns in OpenAI message format.
1175
+ * @returns Trimmed assistant text.
1176
+ * @throws {CompressionError} On HTTP errors, timeouts, or empty content.
1177
+ */
1061
1178
  async complete(messages) {
1062
1179
  const response = await this.request(messages);
1063
1180
  const content = response.choices?.[0]?.message?.content;
@@ -1066,6 +1183,11 @@ var OpenAICompatibleLlmProvider = class {
1066
1183
  }
1067
1184
  return content.trim();
1068
1185
  }
1186
+ /**
1187
+ * Probe the endpoint with a fixed `"ok"` prompt.
1188
+ *
1189
+ * @throws {CompressionError} When validation fails.
1190
+ */
1069
1191
  async validate() {
1070
1192
  try {
1071
1193
  await this.complete([
@@ -1087,6 +1209,12 @@ var OpenAICompatibleLlmProvider = class {
1087
1209
  );
1088
1210
  }
1089
1211
  }
1212
+ /**
1213
+ * Low-level HTTP request to `/chat/completions`.
1214
+ *
1215
+ * @param messages - Chat turns to send.
1216
+ * @returns Parsed OpenAI-style JSON body.
1217
+ */
1090
1218
  async request(messages) {
1091
1219
  const url = joinUrl(this.baseUrl, "/chat/completions");
1092
1220
  const controller = new AbortController();
@@ -1135,6 +1263,7 @@ var OpenAICompatibleLlmProvider = class {
1135
1263
  clearTimeout(timer);
1136
1264
  }
1137
1265
  }
1266
+ /** @param error - Unknown thrown value. @returns Human-readable message. */
1138
1267
  describe(error) {
1139
1268
  if (error instanceof Error) {
1140
1269
  return error.message;
@@ -1530,28 +1659,48 @@ var LEVEL_ORDER = {
1530
1659
  trace: 10
1531
1660
  };
1532
1661
  var WolbargLogger = class {
1662
+ /** @param level - Minimum level to print (default `"info"`). */
1533
1663
  constructor(level = "info") {
1534
1664
  this.level = level;
1535
1665
  }
1536
1666
  level;
1667
+ /** Change the minimum log level at runtime. */
1537
1668
  setLevel(level) {
1538
1669
  this.level = level;
1539
1670
  }
1671
+ /** @returns Current minimum log level. */
1540
1672
  getLevel() {
1541
1673
  return this.level;
1542
1674
  }
1675
+ /** Log at error level. */
1543
1676
  error(message, extra) {
1544
1677
  this.write("error", message, extra);
1545
1678
  }
1679
+ /** Log at warn level.
1680
+ * @param message - Primary log line.
1681
+ * @param extra - Optional structured payload.
1682
+ */
1546
1683
  warn(message, extra) {
1547
1684
  this.write("warn", message, extra);
1548
1685
  }
1686
+ /** Log at info level.
1687
+ * @param message - Primary log line.
1688
+ * @param extra - Optional structured payload.
1689
+ */
1549
1690
  info(message, extra) {
1550
1691
  this.write("info", message, extra);
1551
1692
  }
1693
+ /** Log at debug level.
1694
+ * @param message - Primary log line.
1695
+ * @param extra - Optional structured payload.
1696
+ */
1552
1697
  debug(message, extra) {
1553
1698
  this.write("debug", message, extra);
1554
1699
  }
1700
+ /** Log at trace level.
1701
+ * @param message - Primary log line.
1702
+ * @param extra - Optional structured payload.
1703
+ */
1555
1704
  trace(message, extra) {
1556
1705
  this.write("trace", message, extra);
1557
1706
  }
@@ -1894,18 +2043,29 @@ var InMemoryVectorIndex = class {
1894
2043
  data;
1895
2044
  count = 0;
1896
2045
  rowidToSlot = /* @__PURE__ */ new Map();
2046
+ /**
2047
+ * @param dimensions - Embedding vector length.
2048
+ * @param initialCapacity - Initial slot capacity (default `256`).
2049
+ */
1897
2050
  constructor(dimensions, initialCapacity = 256) {
1898
2051
  this.dims = dimensions;
1899
2052
  this.data = new Float32Array(initialCapacity * dimensions);
1900
2053
  }
2054
+ /** Number of indexed vectors. */
1901
2055
  get size() {
1902
2056
  return this.count;
1903
2057
  }
2058
+ /** Remove all vectors from the index. */
1904
2059
  clear() {
1905
2060
  this.rowids.length = 0;
1906
2061
  this.rowidToSlot.clear();
1907
2062
  this.count = 0;
1908
2063
  }
2064
+ /**
2065
+ * Insert or replace a vector for `rowid` (L2-normalized internally).
2066
+ * @param rowid - Memory table row identifier.
2067
+ * @param embedding - Raw embedding vector.
2068
+ */
1909
2069
  upsert(rowid, embedding) {
1910
2070
  const existing = this.rowidToSlot.get(rowid);
1911
2071
  const slot = existing !== void 0 ? existing : (() => {
@@ -1936,6 +2096,10 @@ var InMemoryVectorIndex = class {
1936
2096
  }
1937
2097
  }
1938
2098
  }
2099
+ /**
2100
+ * Remove a vector by `rowid`.
2101
+ * @param rowid - Memory table row identifier.
2102
+ */
1939
2103
  remove(rowid) {
1940
2104
  const slot = this.rowidToSlot.get(rowid);
1941
2105
  if (slot === void 0) {
@@ -1955,7 +2119,12 @@ var InMemoryVectorIndex = class {
1955
2119
  this.rowidToSlot.delete(rowid);
1956
2120
  this.count = last;
1957
2121
  }
1958
- /** Top-k by cosine distance (1 - dot) assuming query is L2-normalized. */
2122
+ /**
2123
+ * Top-k by cosine distance (1 - dot) assuming query is L2-normalized.
2124
+ *
2125
+ * @param queryNormalized - L2-normalized query vector (use {@link normalizeEmbedding}).
2126
+ * @param topK - Maximum hits to return.
2127
+ */
1959
2128
  search(queryNormalized, topK) {
1960
2129
  const n = this.count;
1961
2130
  if (n === 0 || topK <= 0) {
@@ -2107,7 +2276,7 @@ function isSqliteBusyError(error) {
2107
2276
  return lower.includes("database is locked") || lower.includes("sqlite_busy") || lower.includes("busy");
2108
2277
  }
2109
2278
  function sleep(ms) {
2110
- return new Promise((resolve) => setTimeout(resolve, ms));
2279
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
2111
2280
  }
2112
2281
  function backoffDelay(attempt, config) {
2113
2282
  const exp = Math.min(
@@ -2231,6 +2400,9 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2231
2400
  /** Coalesce concurrent insertMemory callers into one IMMEDIATE transaction. */
2232
2401
  insertQueue = [];
2233
2402
  insertFlushScheduled = false;
2403
+ /**
2404
+ * @param options - SQLite path / `:memory:` and optional concurrency config.
2405
+ */
2234
2406
  constructor(options) {
2235
2407
  this.connectionString = options.connectionString;
2236
2408
  this.concurrency = resolveConcurrencyConfig(options.concurrency);
@@ -2243,9 +2415,11 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2243
2415
  getDatabase() {
2244
2416
  return this.db;
2245
2417
  }
2418
+ /** Register a callback invoked when SQLite busy retries occur (tests / diagnostics). */
2246
2419
  setRetryLogger(fn) {
2247
2420
  this.retryLog = fn;
2248
2421
  }
2422
+ /** Open the database, run migrations, and prepare statements. */
2249
2423
  async open() {
2250
2424
  try {
2251
2425
  const dbPath = this.resolvePath(this.connectionString);
@@ -2305,6 +2479,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2305
2479
  );
2306
2480
  }
2307
2481
  }
2482
+ /** Drain pending inserts, optimize, and close the SQLite connection. */
2308
2483
  async close() {
2309
2484
  const deadline = Date.now() + 2e3;
2310
2485
  while (this.insertQueue.length > 0 && Date.now() < deadline) {
@@ -2335,6 +2510,11 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2335
2510
  this.batchBlobEmbStatements.clear();
2336
2511
  }
2337
2512
  }
2513
+ /**
2514
+ * Create or validate vec0 / blob vector storage for the given dimensionality.
2515
+ *
2516
+ * @param dimensions - Embedding length from the configured model.
2517
+ */
2338
2518
  async ensureVectorSchema(dimensions) {
2339
2519
  const existing = await this.getEmbeddingDimensions();
2340
2520
  if (existing !== null && existing !== dimensions) {
@@ -2357,17 +2537,20 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2357
2537
  this.reprepareVectorStatements();
2358
2538
  this.hydrateMemoryIndex();
2359
2539
  }
2540
+ /** @inheritdoc StorageProvider.getEmbeddingDimensions */
2360
2541
  async getEmbeddingDimensions() {
2361
2542
  return this.readMetaNumber(META_KEYS.embeddingDimensions);
2362
2543
  }
2544
+ /** @inheritdoc StorageProvider.setEmbeddingDimensions */
2363
2545
  async setEmbeddingDimensions(dimensions) {
2364
2546
  await this.setMeta(META_KEYS.embeddingDimensions, String(dimensions));
2365
2547
  this.vectorDimensions = dimensions;
2366
2548
  }
2549
+ /** Insert a single memory row (coalesced under concurrent writers). */
2367
2550
  async insertMemory(input) {
2368
2551
  this.requireVectorReady();
2369
- return new Promise((resolve, reject) => {
2370
- this.insertQueue.push({ input, resolve, reject });
2552
+ return new Promise((resolve3, reject) => {
2553
+ this.insertQueue.push({ input, resolve: resolve3, reject });
2371
2554
  if (this.insertQueue.length >= INSERT_COALESCE_THRESHOLD) {
2372
2555
  this.insertFlushScheduled = false;
2373
2556
  void this.flushInsertQueue();
@@ -2445,6 +2628,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2445
2628
  return row;
2446
2629
  });
2447
2630
  }
2631
+ /** Batch insert memories in chunked multi-row transactions. */
2448
2632
  async insertMemoriesBatch(inputs) {
2449
2633
  if (inputs.length === 0) {
2450
2634
  return [];
@@ -2460,6 +2644,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2460
2644
  return rows;
2461
2645
  });
2462
2646
  }
2647
+ /** Update memory content, metadata, embedding, and content hash. */
2463
2648
  async updateMemory(input) {
2464
2649
  const stmts = this.requireStatements();
2465
2650
  return this.withTransaction(() => {
@@ -2503,6 +2688,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2503
2688
  return stmts.getMemoryById.get(input.id, input.organization);
2504
2689
  });
2505
2690
  }
2691
+ /** Find an active memory by org, agent, and content hash (dedupe). */
2506
2692
  async findActiveByContentHash(organization, agent, contentHash) {
2507
2693
  const stmts = this.requireStatements();
2508
2694
  const row = stmts.findActiveByContentHash.get(
@@ -2512,6 +2698,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2512
2698
  );
2513
2699
  return row ?? null;
2514
2700
  }
2701
+ /** Scan memories matching metadata filters (may paginate in SQL). */
2515
2702
  async searchByMetadata(filter, limit) {
2516
2703
  const rows = await this.listMemories(filter, limit);
2517
2704
  if (!filter.metadata) {
@@ -2522,6 +2709,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2522
2709
  );
2523
2710
  }
2524
2711
  /** Keyword search via FTS5 BM25. Returns memory IDs ranked by relevance. */
2712
+ /** BM25 keyword search via FTS5 (`memories_fts`). */
2525
2713
  async searchKeyword(query, organization, topK) {
2526
2714
  const stmts = this.requireStatements();
2527
2715
  if (!stmts.searchFts) {
@@ -2557,16 +2745,19 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2557
2745
  return [];
2558
2746
  }
2559
2747
  }
2748
+ /** Fetch a memory row by UUID within an organization. */
2560
2749
  async getMemoryById(id, organization) {
2561
2750
  const stmts = this.requireStatements();
2562
2751
  const row = stmts.getMemoryById.get(id, organization);
2563
2752
  return row ?? null;
2564
2753
  }
2754
+ /** Fetch a memory row by SQLite integer rowid within an organization. */
2565
2755
  async getMemoryByRowid(rowid, organization) {
2566
2756
  const stmts = this.requireStatements();
2567
2757
  const row = stmts.getMemoryByRowid.get(rowid, organization);
2568
2758
  return row ?? null;
2569
2759
  }
2760
+ /** Batch-fetch memory rows by SQLite rowids within an organization. */
2570
2761
  async getMemoriesByRowids(rowids, organization) {
2571
2762
  const out = /* @__PURE__ */ new Map();
2572
2763
  if (rowids.length === 0) {
@@ -2585,6 +2776,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2585
2776
  }
2586
2777
  return out;
2587
2778
  }
2779
+ /** List memories matching repository filters with optional limit. */
2588
2780
  async listMemories(filter, limit) {
2589
2781
  try {
2590
2782
  if (filter.metadata) {
@@ -2597,6 +2789,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2597
2789
  });
2598
2790
  }
2599
2791
  }
2792
+ /** Approximate nearest-neighbor search (vec0 or in-memory blob index). */
2600
2793
  async searchVectors(embedding, topK) {
2601
2794
  this.requireVectorReady();
2602
2795
  if (this.vectorBackend === "sqlite-vec") {
@@ -2608,6 +2801,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2608
2801
  * Org-scoped KNN + memory rows with adaptive overfetch.
2609
2802
  * Global ANN is post-filtered by org/agent/archived; underfill triggers larger k.
2610
2803
  */
2804
+ /** ANN search joined with memory rows and org/archived post-filters. */
2611
2805
  async searchVectorsWithMemories(embedding, topK, organization, options) {
2612
2806
  this.requireVectorReady();
2613
2807
  if (topK <= 0) {
@@ -2646,6 +2840,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2646
2840
  }
2647
2841
  return out;
2648
2842
  }
2843
+ /** Soft-archive memories (compression / forget paths). */
2649
2844
  async archiveMemories(ids, organization, compressedIntoId, archivedAt) {
2650
2845
  const stmts = this.requireStatements();
2651
2846
  const archived = [];
@@ -2683,6 +2878,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2683
2878
  return archived;
2684
2879
  });
2685
2880
  }
2881
+ /** Hard-delete a single memory by id; returns whether a row was removed. */
2686
2882
  async deleteMemoryById(id, organization) {
2687
2883
  const stmts = this.requireStatements();
2688
2884
  return this.withTransaction(() => {
@@ -2696,6 +2892,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2696
2892
  return Number(result.changes) > 0;
2697
2893
  });
2698
2894
  }
2895
+ /** Hard-delete memories matching org / agent / metadata filters. */
2699
2896
  async deleteMemoriesByFilter(filter) {
2700
2897
  const stmts = this.requireStatements();
2701
2898
  const agent = filter.agent;
@@ -2712,6 +2909,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2712
2909
  return Number(result.changes);
2713
2910
  });
2714
2911
  }
2912
+ /** Remove all memories (and side tables) for an organization. */
2715
2913
  async clearOrganization(organization) {
2716
2914
  const stmts = this.requireStatements();
2717
2915
  return this.withTransaction(() => {
@@ -2728,10 +2926,12 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2728
2926
  return Number(result.changes);
2729
2927
  });
2730
2928
  }
2929
+ /** List audit history events for a memory id. */
2731
2930
  async getHistory(memoryId) {
2732
2931
  const stmts = this.requireStatements();
2733
2932
  return stmts.getHistory.all(memoryId);
2734
2933
  }
2934
+ /** Append a history row (created / archived / compressed / updated). */
2735
2935
  async insertHistoryEvent(event) {
2736
2936
  const stmts = this.requireStatements();
2737
2937
  stmts.insertHistory.run(
@@ -2742,6 +2942,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2742
2942
  event.created_at
2743
2943
  );
2744
2944
  }
2945
+ /** Aggregate memory counts for an organization (single-pass SQL). */
2745
2946
  async getStats(organization) {
2746
2947
  const stmts = this.requireStatements();
2747
2948
  const row = stmts.getStats.get(organization);
@@ -2752,6 +2953,7 @@ var SqliteStorageProvider = class _SqliteStorageProvider {
2752
2953
  totalAgents: Number(row.agents)
2753
2954
  };
2754
2955
  }
2956
+ /** On-disk database file size in bytes (0 for `:memory:`). */
2755
2957
  async getDatabaseSizeBytes() {
2756
2958
  const db = this.requireDb();
2757
2959
  if (this.connectionString === ":memory:") {
@@ -3810,11 +4012,17 @@ var PostgresSubscribeListener = class {
3810
4012
  reconnectDelayMs;
3811
4013
  connect;
3812
4014
  onError;
4015
+ /**
4016
+ * @param options.connect - Factory returning a dedicated LISTEN client.
4017
+ * @param options.reconnectDelayMs - Delay before reconnect attempts (default 1000).
4018
+ * @param options.onError - Optional error hook for connection failures.
4019
+ */
3813
4020
  constructor(options) {
3814
4021
  this.connect = options.connect;
3815
4022
  this.reconnectDelayMs = options.reconnectDelayMs ?? 1e3;
3816
4023
  this.onError = options.onError;
3817
4024
  }
4025
+ /** Open the LISTEN connection (lazy — also started on first subscribe). */
3818
4026
  async start() {
3819
4027
  if (this.closed) {
3820
4028
  return;
@@ -3911,6 +4119,13 @@ var PostgresSubscribeListener = class {
3911
4119
  }
3912
4120
  }
3913
4121
  }
4122
+ /**
4123
+ * Register a filtered callback for memory change events.
4124
+ *
4125
+ * @param filter - Organization / agent / event-type filter.
4126
+ * @param callback - Invoked synchronously on each matching NOTIFY.
4127
+ * @returns Unsubscribe function.
4128
+ */
3914
4129
  subscribe(filter, callback) {
3915
4130
  if (this.closed) {
3916
4131
  throw new Error("Subscribe backend is closed");
@@ -3932,6 +4147,7 @@ var PostgresSubscribeListener = class {
3932
4147
  */
3933
4148
  emit(_event) {
3934
4149
  }
4150
+ /** Tear down LISTEN connection and clear subscriptions. */
3935
4151
  async close() {
3936
4152
  this.closed = true;
3937
4153
  this.subscriptions.clear();
@@ -4096,6 +4312,9 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4096
4312
  insertFlushScheduled = false;
4097
4313
  insertFlushTimer = null;
4098
4314
  insertFlushInFlight = 0;
4315
+ /**
4316
+ * @param options - Connection string, pool size, and durability flags.
4317
+ */
4099
4318
  constructor(options) {
4100
4319
  this.maxPoolSize = options.maxPoolSize ?? 64;
4101
4320
  this.durableWrites = options.durableWrites !== false;
@@ -4104,6 +4323,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4104
4323
  this.durableWrites
4105
4324
  );
4106
4325
  }
4326
+ /** Current pg pool occupancy stats (for diagnostics / subscribe setup). */
4107
4327
  getPoolStats() {
4108
4328
  const pool = this.pool;
4109
4329
  return {
@@ -4117,6 +4337,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4117
4337
  getPool() {
4118
4338
  return this.pool;
4119
4339
  }
4340
+ /** Open the connection pool and run migrations. */
4120
4341
  async open() {
4121
4342
  let PoolCtor;
4122
4343
  try {
@@ -4165,6 +4386,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4165
4386
  );
4166
4387
  }
4167
4388
  }
4389
+ /** Drain coalesced inserts and end the connection pool. */
4168
4390
  async close() {
4169
4391
  if (this.insertFlushTimer) {
4170
4392
  clearTimeout(this.insertFlushTimer);
@@ -4205,6 +4427,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4205
4427
  async ensureVectorIndex() {
4206
4428
  await this.ensureHnswIndex();
4207
4429
  }
4430
+ /**
4431
+ * Create pgvector tables and HNSW index for the given dimensionality.
4432
+ *
4433
+ * @param dimensions - Embedding length from the configured model.
4434
+ */
4208
4435
  async ensureVectorSchema(dimensions) {
4209
4436
  const existing = await this.getEmbeddingDimensions();
4210
4437
  if (existing !== null && existing !== dimensions) {
@@ -4269,6 +4496,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4269
4496
  }
4270
4497
  }
4271
4498
  /** Cross-process subscribe: NOTIFY after a committed write. */
4499
+ /**
4500
+ * Issue `pg_notify` for cross-process {@link subscribe} delivery.
4501
+ *
4502
+ * @param event - Memory change payload (IDs + metadata only).
4503
+ */
4272
4504
  async notifyChange(event) {
4273
4505
  await notifyMemoryChange(this.requirePool(), event);
4274
4506
  }
@@ -4276,6 +4508,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4276
4508
  * Soft reset for a single organization. Drops HNSW only when the embeddings
4277
4509
  * table is empty so other corpora on a shared bench DB stay intact.
4278
4510
  */
4511
+ /** Delete all rows for an organization (dev / test helper). */
4279
4512
  async resetOrganization(organization) {
4280
4513
  await this.query(`DELETE FROM memories WHERE organization = $1`, [
4281
4514
  organization
@@ -4293,6 +4526,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4293
4526
  /**
4294
4527
  * Wipe all Wolbarg tables (explicit opt-in). Prefer {@link resetOrganization}.
4295
4528
  */
4529
+ /** Truncate all Wolbarg tables (dev / test helper). */
4296
4530
  async wipeAllData() {
4297
4531
  await this.query(`TRUNCATE TABLE memories CASCADE`).catch(() => void 0);
4298
4532
  await this.query(
@@ -4352,6 +4586,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4352
4586
  }
4353
4587
  }
4354
4588
  }
4589
+ /** @inheritdoc StorageProvider.getEmbeddingDimensions */
4355
4590
  async getEmbeddingDimensions() {
4356
4591
  const result = await this.query(
4357
4592
  `SELECT value FROM Wolbarg_meta WHERE key = $1`,
@@ -4364,6 +4599,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4364
4599
  const parsed = Number(value);
4365
4600
  return Number.isFinite(parsed) ? parsed : null;
4366
4601
  }
4602
+ /** @inheritdoc StorageProvider.setEmbeddingDimensions */
4367
4603
  async setEmbeddingDimensions(dimensions) {
4368
4604
  await this.query(
4369
4605
  `INSERT INTO Wolbarg_meta (key, value) VALUES ($1, $2)
@@ -4372,10 +4608,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4372
4608
  );
4373
4609
  this.vectorDimensions = dimensions;
4374
4610
  }
4611
+ /** Insert a single memory row (coalesced under concurrent writers). */
4375
4612
  async insertMemory(input) {
4376
4613
  this.requireVectorReady();
4377
- return new Promise((resolve, reject) => {
4378
- this.insertQueue.push({ input, resolve, reject });
4614
+ return new Promise((resolve3, reject) => {
4615
+ this.insertQueue.push({ input, resolve: resolve3, reject });
4379
4616
  if (this.insertQueue.length >= COALESCE_FLUSH_THRESHOLD) {
4380
4617
  this.clearInsertFlushTimer();
4381
4618
  void this.flushInsertQueue();
@@ -4458,6 +4695,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4458
4695
  }
4459
4696
  return this.insertOneBlob(input);
4460
4697
  }
4698
+ /** Batch insert via unnest / COPY paths with optional HNSW deferral. */
4461
4699
  async insertMemoriesBatch(inputs) {
4462
4700
  if (inputs.length === 0) {
4463
4701
  return [];
@@ -4606,6 +4844,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4606
4844
  return row;
4607
4845
  });
4608
4846
  }
4847
+ /** Update memory content, metadata, embedding, and content hash. */
4609
4848
  async updateMemory(input) {
4610
4849
  return this.withTransaction(async () => {
4611
4850
  const existing = await this.getMemoryById(input.id, input.organization);
@@ -4641,6 +4880,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4641
4880
  return this.getMemoryById(input.id, input.organization);
4642
4881
  });
4643
4882
  }
4883
+ /** Find an active memory by org, agent, and content hash (dedupe). */
4644
4884
  async findActiveByContentHash(organization, agent, contentHash) {
4645
4885
  const result = await this.query(
4646
4886
  `SELECT id, organization, agent, content_text, metadata_json,
@@ -4653,6 +4893,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4653
4893
  const row = result.rows[0];
4654
4894
  return row ? this.mapRow(row) : null;
4655
4895
  }
4896
+ /** Fetch a memory row by UUID within an organization. */
4656
4897
  async getMemoryById(id, organization) {
4657
4898
  const result = await this.query(
4658
4899
  `SELECT id, organization, agent, content_text, metadata_json,
@@ -4663,6 +4904,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4663
4904
  const row = result.rows[0];
4664
4905
  return row ? this.mapRow(row) : null;
4665
4906
  }
4907
+ /** Fetch a memory row by internal rowid within an organization. */
4666
4908
  async getMemoryByRowid(rowid, organization) {
4667
4909
  const result = await this.query(
4668
4910
  `SELECT m.id, m.organization, m.agent, m.content_text, m.metadata_json,
@@ -4676,6 +4918,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4676
4918
  const row = result.rows[0];
4677
4919
  return row ? this.mapRow(row) : null;
4678
4920
  }
4921
+ /** Batch-fetch memory rows by rowids within an organization. */
4679
4922
  async getMemoriesByRowids(rowids, organization) {
4680
4923
  const out = /* @__PURE__ */ new Map();
4681
4924
  if (rowids.length === 0) {
@@ -4698,6 +4941,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4698
4941
  }
4699
4942
  return out;
4700
4943
  }
4944
+ /** List memories matching repository filters with optional limit. */
4701
4945
  async listMemories(filter, limit) {
4702
4946
  const want = limit !== void 0 ? limit : filter.metadata ? 1e4 : void 0;
4703
4947
  const compiled = filter.metadata ? compileMetadataFilterToPostgres(filter.metadata, 2) : null;
@@ -4759,9 +5003,11 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4759
5003
  }
4760
5004
  return rows;
4761
5005
  }
5006
+ /** Scan memories matching metadata filters. */
4762
5007
  async searchByMetadata(filter, limit) {
4763
5008
  return this.listMemories(filter, limit);
4764
5009
  }
5010
+ /** Full-text keyword search via `tsvector` / GIN index. */
4765
5011
  async searchKeyword(query, organization, topK) {
4766
5012
  const trimmed = query.trim();
4767
5013
  if (!trimmed || topK <= 0) {
@@ -4801,6 +5047,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4801
5047
  return [];
4802
5048
  }
4803
5049
  }
5050
+ /** pgvector cosine ANN search (HNSW when index is present). */
4804
5051
  async searchVectors(embedding, topK) {
4805
5052
  this.requireVectorReady();
4806
5053
  if (this.hasPgvector) {
@@ -4850,6 +5097,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4850
5097
  scored.sort((a, b) => a.distance - b.distance);
4851
5098
  return scored.slice(0, topK);
4852
5099
  }
5100
+ /** ANN search joined with memory rows and org/archived post-filters. */
4853
5101
  async searchVectorsWithMemories(embedding, topK, organization, options) {
4854
5102
  this.requireVectorReady();
4855
5103
  if (!this.hasPgvector) {
@@ -4914,6 +5162,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4914
5162
  );
4915
5163
  return mapHits(result.rows);
4916
5164
  }
5165
+ /** Soft-archive memories (compression / forget paths). */
4917
5166
  async archiveMemories(ids, organization, compressedIntoId, archivedAt) {
4918
5167
  return this.withTransaction(async () => {
4919
5168
  if (ids.length === 0) {
@@ -4956,6 +5205,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4956
5205
  return archived;
4957
5206
  });
4958
5207
  }
5208
+ /** Hard-delete a single memory by id; returns whether a row was removed. */
4959
5209
  async deleteMemoryById(id, organization) {
4960
5210
  const result = await this.query(
4961
5211
  `DELETE FROM memories WHERE id = $1 AND organization = $2`,
@@ -4963,6 +5213,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4963
5213
  );
4964
5214
  return (result.rowCount ?? 0) > 0;
4965
5215
  }
5216
+ /** Hard-delete memories matching org / agent / metadata filters. */
4966
5217
  async deleteMemoriesByFilter(filter) {
4967
5218
  if (!filter.agent) {
4968
5219
  throw new DatabaseError("deleteMemoriesByFilter requires an agent filter");
@@ -4973,6 +5224,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4973
5224
  );
4974
5225
  return result.rowCount ?? 0;
4975
5226
  }
5227
+ /** Remove all memories for an organization. */
4976
5228
  async clearOrganization(organization) {
4977
5229
  const result = await this.query(
4978
5230
  `DELETE FROM memories WHERE organization = $1`,
@@ -4980,6 +5232,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4980
5232
  );
4981
5233
  return result.rowCount ?? 0;
4982
5234
  }
5235
+ /** List audit history events for a memory id. */
4983
5236
  async getHistory(memoryId) {
4984
5237
  const result = await this.query(
4985
5238
  `SELECT id, memory_id, event_type, related_memory_id, created_at
@@ -4994,6 +5247,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
4994
5247
  created_at: String(row.created_at)
4995
5248
  }));
4996
5249
  }
5250
+ /** Append a history row (created / archived / compressed / updated). */
4997
5251
  async insertHistoryEvent(event) {
4998
5252
  await this.query(
4999
5253
  `INSERT INTO memory_history (id, memory_id, event_type, related_memory_id, created_at)
@@ -5007,6 +5261,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5007
5261
  ]
5008
5262
  );
5009
5263
  }
5264
+ /** Aggregate memory counts for an organization. */
5010
5265
  async getStats(organization) {
5011
5266
  const result = await this.query(
5012
5267
  `SELECT
@@ -5024,6 +5279,7 @@ var PostgresStorageProvider = class _PostgresStorageProvider {
5024
5279
  totalAgents: Number(result.rows[0]?.agents ?? 0)
5025
5280
  };
5026
5281
  }
5282
+ /** Approximate on-disk database size in bytes (`pg_database_size`). */
5027
5283
  async getDatabaseSizeBytes() {
5028
5284
  const result = await this.query(
5029
5285
  `SELECT pg_database_size(current_database())::bigint AS size`
@@ -5371,7 +5627,7 @@ function createDatabaseProvider(config) {
5371
5627
  }
5372
5628
 
5373
5629
  // src/version.ts
5374
- var SDK_VERSION = "0.5.4";
5630
+ var SDK_VERSION = "0.5.6";
5375
5631
 
5376
5632
  // src/memory/transfer.ts
5377
5633
  var warnedMissingExportManifest = false;
@@ -5840,6 +6096,9 @@ var SqliteGraphProvider = class {
5840
6096
  concurrency;
5841
6097
  db = null;
5842
6098
  opened = false;
6099
+ /**
6100
+ * @param options - Graph SQLite path and optional concurrency tuning.
6101
+ */
5843
6102
  constructor(options) {
5844
6103
  if (!options?.path || typeof options.path !== "string" || !options.path.trim()) {
5845
6104
  throw new ConfigurationError("sqlite graph requires a non-empty path");
@@ -5847,12 +6106,15 @@ var SqliteGraphProvider = class {
5847
6106
  this.dbPath = path7.resolve(options.path.trim());
5848
6107
  this.concurrency = resolveConcurrencyConfig(options.concurrency);
5849
6108
  }
6109
+ /** Whether this provider supports file snapshots for checkpoint / export. */
5850
6110
  supportsFileSnapshot() {
5851
6111
  return this.dbPath !== ":memory:";
5852
6112
  }
6113
+ /** Absolute graph database path, or `null` for `:memory:`. */
5853
6114
  getDataPath() {
5854
6115
  return this.dbPath === ":memory:" ? null : this.dbPath;
5855
6116
  }
6117
+ /** Open the graph SQLite file, apply pragmas, and create schema if needed. */
5856
6118
  async open() {
5857
6119
  if (this.opened) return;
5858
6120
  try {
@@ -5889,6 +6151,7 @@ var SqliteGraphProvider = class {
5889
6151
  );
5890
6152
  }
5891
6153
  }
6154
+ /** Close the graph database connection. */
5892
6155
  async close() {
5893
6156
  if (!this.db) {
5894
6157
  this.opened = false;
@@ -5910,6 +6173,14 @@ var SqliteGraphProvider = class {
5910
6173
  this.opened = false;
5911
6174
  }
5912
6175
  }
6176
+ /**
6177
+ * Create or replace a directed memory↔memory edge.
6178
+ *
6179
+ * @param fromId - Source memory UUID.
6180
+ * @param toId - Target memory UUID.
6181
+ * @param relation - Edge label (e.g. `"related_to"`, `"caused_by"`).
6182
+ * @param metadata - Optional JSON metadata stored on the edge.
6183
+ */
5913
6184
  async linkMemories(fromId, toId, relation, metadata) {
5914
6185
  const db = this.requireDb();
5915
6186
  await this.withTx(() => {
@@ -5932,6 +6203,13 @@ var SqliteGraphProvider = class {
5932
6203
  );
5933
6204
  });
5934
6205
  }
6206
+ /**
6207
+ * Remove edges between two memories.
6208
+ *
6209
+ * @param fromId - Source memory UUID.
6210
+ * @param toId - Target memory UUID.
6211
+ * @param relation - When set, only delete edges with this relation label.
6212
+ */
5935
6213
  async unlinkMemories(fromId, toId, relation) {
5936
6214
  const db = this.requireDb();
5937
6215
  await this.withTx(() => {
@@ -5981,6 +6259,12 @@ var SqliteGraphProvider = class {
5981
6259
  }
5982
6260
  return out;
5983
6261
  }
6262
+ /**
6263
+ * Insert or update a named entity node.
6264
+ *
6265
+ * @param entity - Entity name, type, and optional metadata.
6266
+ * @returns Stable entity id ({@link entityIdFrom}).
6267
+ */
5984
6268
  async upsertEntity(entity) {
5985
6269
  const id = entityIdFrom(entity.name, entity.type);
5986
6270
  const db = this.requireDb();
@@ -6005,6 +6289,13 @@ var SqliteGraphProvider = class {
6005
6289
  });
6006
6290
  return id;
6007
6291
  }
6292
+ /**
6293
+ * Link an entity to a memory via a `MENTIONS` edge (not traversed by {@link getRelated}).
6294
+ *
6295
+ * @param entityId - Entity id from {@link upsertEntity}.
6296
+ * @param memoryId - Target memory UUID.
6297
+ * @param role - Optional role string stored on the edge metadata.
6298
+ */
6008
6299
  async linkEntityToMemory(entityId, memoryId, role) {
6009
6300
  const db = this.requireDb();
6010
6301
  await this.withTx(() => {
@@ -6034,6 +6325,11 @@ var SqliteGraphProvider = class {
6034
6325
  );
6035
6326
  });
6036
6327
  }
6328
+ /**
6329
+ * Remove the memory node and incident edges when a memory is hard-deleted.
6330
+ *
6331
+ * @param memoryId - Wolbarg memory UUID.
6332
+ */
6037
6333
  async deleteMemory(memoryId) {
6038
6334
  const db = this.requireDb();
6039
6335
  await this.withTx(() => {
@@ -6053,6 +6349,7 @@ var SqliteGraphProvider = class {
6053
6349
  }
6054
6350
  );
6055
6351
  }
6352
+ /** Lightweight connectivity and schema statistics check. */
6056
6353
  async health() {
6057
6354
  try {
6058
6355
  if (!this.opened || !this.db) {
@@ -6198,6 +6495,9 @@ var Neo4jGraphProvider = class {
6198
6495
  database;
6199
6496
  driver = null;
6200
6497
  opened = false;
6498
+ /**
6499
+ * @param options - Bolt URL, credentials, and optional database name.
6500
+ */
6201
6501
  constructor(options) {
6202
6502
  if (!options?.url?.trim()) {
6203
6503
  throw new ConfigurationError("neo4j graph requires a non-empty url");
@@ -6213,12 +6513,15 @@ var Neo4jGraphProvider = class {
6213
6513
  this.password = options.password;
6214
6514
  this.database = options.database?.trim() || void 0;
6215
6515
  }
6516
+ /** Neo4j does not support local file snapshots for checkpoint pairing. */
6216
6517
  supportsFileSnapshot() {
6217
6518
  return false;
6218
6519
  }
6520
+ /** Always `null` — graph data lives in the remote Neo4j cluster. */
6219
6521
  getDataPath() {
6220
6522
  return null;
6221
6523
  }
6524
+ /** Connect to Neo4j, verify connectivity, and ensure uniqueness constraints. */
6222
6525
  async open() {
6223
6526
  if (this.opened) return;
6224
6527
  let mod;
@@ -6250,6 +6553,7 @@ var Neo4jGraphProvider = class {
6250
6553
  }
6251
6554
  });
6252
6555
  }
6556
+ /** Close the neo4j-driver connection. */
6253
6557
  async close() {
6254
6558
  if (this.driver) {
6255
6559
  await this.driver.close();
@@ -6311,6 +6615,14 @@ var Neo4jGraphProvider = class {
6311
6615
  }
6312
6616
  await this.run(cypher, { id });
6313
6617
  }
6618
+ /**
6619
+ * MERGE a directed `RELATED` relationship between two memory nodes.
6620
+ *
6621
+ * @param fromId - Source memory UUID.
6622
+ * @param toId - Target memory UUID.
6623
+ * @param relation - Relationship label stored on `RELATED.relation`.
6624
+ * @param metadata - Optional JSON metadata on the relationship.
6625
+ */
6314
6626
  async linkMemories(fromId, toId, relation, metadata) {
6315
6627
  await this.withSession(async (session) => {
6316
6628
  await this.ensureMemoryNode(fromId, session);
@@ -6329,6 +6641,13 @@ var Neo4jGraphProvider = class {
6329
6641
  );
6330
6642
  });
6331
6643
  }
6644
+ /**
6645
+ * Delete `RELATED` relationship(s) between two memories.
6646
+ *
6647
+ * @param fromId - Source memory UUID.
6648
+ * @param toId - Target memory UUID.
6649
+ * @param relation - When set, only delete edges with this relation property.
6650
+ */
6332
6651
  async unlinkMemories(fromId, toId, relation) {
6333
6652
  if (relation !== void 0) {
6334
6653
  await this.run(
@@ -6374,6 +6693,12 @@ var Neo4jGraphProvider = class {
6374
6693
  (row) => rowToMemoryRecord(unwrapRow(row))
6375
6694
  );
6376
6695
  }
6696
+ /**
6697
+ * MERGE an `Entity` node keyed by deterministic id.
6698
+ *
6699
+ * @param entity - Entity name, type, and optional metadata.
6700
+ * @returns Stable entity id ({@link entityIdFrom}).
6701
+ */
6377
6702
  async upsertEntity(entity) {
6378
6703
  const id = entityIdFrom(entity.name, entity.type);
6379
6704
  await this.run(
@@ -6388,6 +6713,13 @@ var Neo4jGraphProvider = class {
6388
6713
  );
6389
6714
  return id;
6390
6715
  }
6716
+ /**
6717
+ * MERGE a `MENTIONS` relationship from entity to memory.
6718
+ *
6719
+ * @param entityId - Entity id from {@link upsertEntity}.
6720
+ * @param memoryId - Target memory UUID.
6721
+ * @param role - Optional role string on the relationship.
6722
+ */
6391
6723
  async linkEntityToMemory(entityId, memoryId, role) {
6392
6724
  await this.withSession(async (session) => {
6393
6725
  await this.ensureMemoryNode(memoryId, session);
@@ -6410,6 +6742,11 @@ var Neo4jGraphProvider = class {
6410
6742
  );
6411
6743
  });
6412
6744
  }
6745
+ /**
6746
+ * DETACH DELETE the memory node and all incident relationships.
6747
+ *
6748
+ * @param memoryId - Wolbarg memory UUID.
6749
+ */
6413
6750
  async deleteMemory(memoryId) {
6414
6751
  await this.run(
6415
6752
  `MATCH (m:Memory { id: $id })
@@ -6417,9 +6754,17 @@ var Neo4jGraphProvider = class {
6417
6754
  { id: memoryId }
6418
6755
  );
6419
6756
  }
6757
+ /**
6758
+ * Run arbitrary parameterized Cypher (escape hatch for advanced graph queries).
6759
+ *
6760
+ * @param cypher - Cypher query string.
6761
+ * @param params - Bound parameters for the query.
6762
+ * @returns Raw row objects from the driver.
6763
+ */
6420
6764
  async query(cypher, params) {
6421
6765
  return this.run(cypher, params ?? {});
6422
6766
  }
6767
+ /** Verify connectivity and return server metadata when available. */
6423
6768
  async health() {
6424
6769
  try {
6425
6770
  if (!this.opened || !this.driver) {
@@ -6910,21 +7255,32 @@ function createChildTrace(parent) {
6910
7255
  // src/telemetry/emitter.ts
6911
7256
  var NoopTelemetryProvider = class {
6912
7257
  name = "noop";
7258
+ /** @inheritdoc TelemetryProvider.open */
6913
7259
  async open() {
6914
7260
  }
7261
+ /** @inheritdoc TelemetryProvider.close */
6915
7262
  async close() {
6916
7263
  }
7264
+ /** @inheritdoc TelemetryProvider.emit */
6917
7265
  emit(_event) {
6918
7266
  }
7267
+ /** @inheritdoc TelemetryProvider.flush */
6919
7268
  async flush() {
6920
7269
  }
6921
7270
  };
6922
7271
  var TelemetryEmitter = class {
7272
+ /** Stable session id for this Wolbarg instance lifetime. */
6923
7273
  sessionId;
7274
+ /** Structured logger gated by telemetry log level. */
6924
7275
  logger;
6925
7276
  provider;
6926
7277
  config;
6927
7278
  context;
7279
+ /**
7280
+ * @param provider - Telemetry backend, or `null` for {@link NoopTelemetryProvider}.
7281
+ * @param config - Capture flags and log level.
7282
+ * @param context - Default organization injected into events.
7283
+ */
6928
7284
  constructor(provider, config, context = {}) {
6929
7285
  this.sessionId = createSessionId();
6930
7286
  this.provider = provider ?? new NoopTelemetryProvider();
@@ -6940,25 +7296,37 @@ var TelemetryEmitter = class {
6940
7296
  this.context = context;
6941
7297
  this.logger = new WolbargLogger(this.config.level);
6942
7298
  }
7299
+ /** Whether telemetry is enabled and backed by a non-noop provider. */
6943
7300
  get enabled() {
6944
7301
  return this.config.enabled && this.provider.name !== "noop";
6945
7302
  }
7303
+ /** Replace the underlying telemetry provider (e.g. after lazy init). */
6946
7304
  setProvider(provider) {
6947
7305
  this.provider = provider;
6948
7306
  }
7307
+ /** Open the underlying telemetry provider when enabled. */
6949
7308
  async open() {
6950
7309
  if (!this.config.enabled) {
6951
7310
  return;
6952
7311
  }
6953
7312
  await this.provider.open();
6954
7313
  }
7314
+ /** Flush pending events and close the telemetry provider. */
6955
7315
  async close() {
6956
7316
  await this.provider.flush();
6957
7317
  await this.provider.close();
6958
7318
  }
7319
+ /** Flush pending telemetry events without closing the provider. */
6959
7320
  async flush() {
6960
7321
  await this.provider.flush();
6961
7322
  }
7323
+ /**
7324
+ * Begin tracing an operation.
7325
+ *
7326
+ * @param operation - Public telemetry operation name.
7327
+ * @param parent - Optional parent trace for nested spans.
7328
+ * @returns Handle — call `success()` or `failure()` when done.
7329
+ */
6962
7330
  start(operation, parent) {
6963
7331
  const context = parent ? createChildTrace(parent) : createRootTrace(this.sessionId);
6964
7332
  const startedAt = performance.now();
@@ -7033,10 +7401,12 @@ var TelemetryEmitter = class {
7033
7401
  }
7034
7402
  };
7035
7403
  }
7404
+ /** Emit a startup telemetry event. */
7036
7405
  emitStartup(provider) {
7037
7406
  const trace = this.start("startup");
7038
7407
  trace.success({ provider });
7039
7408
  }
7409
+ /** Emit a shutdown telemetry event. */
7040
7410
  emitShutdown(provider) {
7041
7411
  const trace = this.start("shutdown");
7042
7412
  trace.success({ provider });
@@ -7102,10 +7472,15 @@ var SqliteEventDatabase = class {
7102
7472
  db = null;
7103
7473
  insertStmt = null;
7104
7474
  columns = /* @__PURE__ */ new Set();
7475
+ /**
7476
+ * @param options.url - Path to the telemetry SQLite file.
7477
+ * @param options.readonly - Open read-only (Studio / analytics).
7478
+ */
7105
7479
  constructor(options) {
7106
7480
  this.url = options.url;
7107
7481
  this.readonly = options.readonly ?? false;
7108
7482
  }
7483
+ /** Open the telemetry database and run schema migrations. */
7109
7484
  async open() {
7110
7485
  try {
7111
7486
  const dbPath = this.resolvePath(this.url);
@@ -7160,6 +7535,7 @@ var SqliteEventDatabase = class {
7160
7535
  );
7161
7536
  }
7162
7537
  }
7538
+ /** Close the telemetry database connection. */
7163
7539
  async close() {
7164
7540
  if (!this.db) return;
7165
7541
  try {
@@ -7170,6 +7546,7 @@ var SqliteEventDatabase = class {
7170
7546
  this.columns.clear();
7171
7547
  }
7172
7548
  }
7549
+ /** Insert one normalized telemetry event row. */
7173
7550
  async insertEvent(input) {
7174
7551
  const event = normalizeEvent(input);
7175
7552
  const stmt = this.insertStmt;
@@ -7215,6 +7592,7 @@ var SqliteEventDatabase = class {
7215
7592
  );
7216
7593
  }
7217
7594
  }
7595
+ /** Insert many events in a single transaction. */
7218
7596
  async insertEvents(inputs) {
7219
7597
  const db = this.requireDb();
7220
7598
  const out = [];
@@ -7233,6 +7611,7 @@ var SqliteEventDatabase = class {
7233
7611
  throw error;
7234
7612
  }
7235
7613
  }
7614
+ /** Query telemetry events with filters, sort, and pagination. */
7236
7615
  async query(options) {
7237
7616
  const db = this.requireDb();
7238
7617
  const clauses = [];
@@ -7313,11 +7692,13 @@ var SqliteEventDatabase = class {
7313
7692
  offset
7314
7693
  };
7315
7694
  }
7695
+ /** Fetch one event by primary key. */
7316
7696
  async getEvent(id) {
7317
7697
  const db = this.requireDb();
7318
7698
  const row = db.prepare(`SELECT * FROM telemetry_events WHERE id = ?`).get(id);
7319
7699
  return row ? rowToEvent(row) : null;
7320
7700
  }
7701
+ /** Count events optionally filtered by time and operation. */
7321
7702
  async countEvents(filter) {
7322
7703
  const db = this.requireDb();
7323
7704
  const clauses = [];
@@ -7468,9 +7849,13 @@ var SqliteTelemetryProvider = class {
7468
7849
  openPromise = null;
7469
7850
  warnedQueueDrop = false;
7470
7851
  warnedFlushFailure = false;
7852
+ /**
7853
+ * @param options.url - Path to the independent telemetry SQLite database file.
7854
+ */
7471
7855
  constructor(options) {
7472
7856
  this.db = new SqliteEventDatabase({ url: options.url });
7473
7857
  }
7858
+ /** Open the telemetry EventDatabase (lazy — also invoked on first emit). */
7474
7859
  async open() {
7475
7860
  if (!this.openPromise) {
7476
7861
  this.openPromise = this.db.open();
@@ -7478,12 +7863,18 @@ var SqliteTelemetryProvider = class {
7478
7863
  await this.openPromise;
7479
7864
  this.closed = false;
7480
7865
  }
7866
+ /** Flush pending events and close the telemetry database. */
7481
7867
  async close() {
7482
7868
  this.closed = true;
7483
7869
  await this.flush();
7484
7870
  await this.db.close();
7485
7871
  this.openPromise = null;
7486
7872
  }
7873
+ /**
7874
+ * Enqueue a telemetry event for async persistence (never throws).
7875
+ *
7876
+ * @param event - Partial or complete {@link TelemetryEventInput}.
7877
+ */
7487
7878
  emit(event) {
7488
7879
  if (this.closed) {
7489
7880
  return;
@@ -7500,6 +7891,7 @@ var SqliteTelemetryProvider = class {
7500
7891
  this.queue.push(event);
7501
7892
  void this.scheduleFlush();
7502
7893
  }
7894
+ /** Block until all queued events are written (or dropped on failure). */
7503
7895
  async flush() {
7504
7896
  while (this.queue.length > 0 || this.flushing) {
7505
7897
  await this.scheduleFlush();
@@ -7508,10 +7900,12 @@ var SqliteTelemetryProvider = class {
7508
7900
  }
7509
7901
  }
7510
7902
  }
7903
+ /** Query persisted telemetry events with filters and pagination. */
7511
7904
  async query(options) {
7512
7905
  await this.open();
7513
7906
  return this.db.query(options);
7514
7907
  }
7908
+ /** Fetch a single telemetry event by id. */
7515
7909
  async getEvent(id) {
7516
7910
  await this.open();
7517
7911
  return this.db.getEvent(id);
@@ -7553,16 +7947,28 @@ var SqliteCheckpointProvider = class {
7553
7947
  name = "sqlite";
7554
7948
  directory;
7555
7949
  ready = false;
7950
+ /**
7951
+ * @param options.directory - Folder for `.json` metadata and `.db` snapshot files.
7952
+ */
7556
7953
  constructor(options) {
7557
7954
  this.directory = options?.directory ?? path7.resolve(process.cwd(), ".wolbarg", "checkpoints");
7558
7955
  }
7956
+ /** Ensure the checkpoint directory exists. */
7559
7957
  async open() {
7560
7958
  fs6.mkdirSync(this.directory, { recursive: true });
7561
7959
  this.ready = true;
7562
7960
  }
7961
+ /** Mark the provider closed (does not delete snapshots). */
7563
7962
  async close() {
7564
7963
  this.ready = false;
7565
7964
  }
7965
+ /**
7966
+ * Create an immutable SQLite backup of `sourcePath` under a unique name.
7967
+ *
7968
+ * @param name - Checkpoint label (must not already exist).
7969
+ * @param sourcePath - Live memory database path to snapshot.
7970
+ * @param options.description - Optional human-readable description stored in metadata.
7971
+ */
7566
7972
  async checkpoint(name, sourcePath, options) {
7567
7973
  this.requireReady();
7568
7974
  assertCheckpointName(name);
@@ -7617,6 +8023,12 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7617
8023
  fs6.renameSync(tmpMetaPath, metaPath);
7618
8024
  return meta2;
7619
8025
  }
8026
+ /**
8027
+ * Restore a named checkpoint over `targetPath` (replaces WAL/SHM side files).
8028
+ *
8029
+ * @param name - Existing checkpoint name.
8030
+ * @param targetPath - Live memory database path to overwrite.
8031
+ */
7620
8032
  async rollback(name, targetPath) {
7621
8033
  this.requireReady();
7622
8034
  const meta2 = await this.getCheckpoint(name);
@@ -7639,6 +8051,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7639
8051
  await safeSqliteBackup(meta2.snapshotPath, resolvedTarget);
7640
8052
  return meta2;
7641
8053
  }
8054
+ /** Delete checkpoint metadata and snapshot files for `name`. */
7642
8055
  async deleteCheckpoint(name) {
7643
8056
  this.requireReady();
7644
8057
  const metaPath = this.metaPath(name);
@@ -7654,6 +8067,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7654
8067
  }
7655
8068
  return removed;
7656
8069
  }
8070
+ /** List all checkpoints sorted by creation time. */
7657
8071
  async listCheckpoints() {
7658
8072
  this.requireReady();
7659
8073
  if (!fs6.existsSync(this.directory)) {
@@ -7670,6 +8084,7 @@ Ensure Wolbarg has been initialized and the database path is correct.`
7670
8084
  }
7671
8085
  return out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
7672
8086
  }
8087
+ /** Load checkpoint metadata by name, or `null` if missing / corrupt. */
7673
8088
  async getCheckpoint(name) {
7674
8089
  this.requireReady();
7675
8090
  const metaPath = this.metaPath(name);
@@ -7854,6 +8269,13 @@ var SqliteSubscribeEmitter = class {
7854
8269
  }
7855
8270
  });
7856
8271
  }
8272
+ /**
8273
+ * Register a filtered callback for in-process memory change events.
8274
+ *
8275
+ * @param filter - Organization / agent / event-type filter.
8276
+ * @param callback - Invoked synchronously on each matching emit.
8277
+ * @returns Unsubscribe function.
8278
+ */
7857
8279
  subscribe(filter, callback) {
7858
8280
  if (this.closed) {
7859
8281
  throw new Error("Subscribe backend is closed");
@@ -7864,12 +8286,14 @@ var SqliteSubscribeEmitter = class {
7864
8286
  this.subscriptions.delete(id);
7865
8287
  };
7866
8288
  }
8289
+ /** Emit a memory change event to registered subscribers. */
7867
8290
  emit(event) {
7868
8291
  if (this.closed) {
7869
8292
  return;
7870
8293
  }
7871
8294
  this.emitter.emit("change", event);
7872
8295
  }
8296
+ /** Remove all listeners and mark the emitter closed. */
7873
8297
  async close() {
7874
8298
  this.closed = true;
7875
8299
  this.subscriptions.clear();
@@ -7907,6 +8331,20 @@ var Wolbarg = class {
7907
8331
  memoryDedupe = resolveMemoryDedupeConfig();
7908
8332
  embeddingCacheConfig = resolveEmbeddingCacheConfig();
7909
8333
  rawEmbedding = null;
8334
+ /**
8335
+ * @param options - Full {@link WolbargOptions}. Key fields:
8336
+ * - `organization` — namespace isolating memories in a shared DB
8337
+ * - `database` / `storage` — SQLite/Postgres config **or** a custom
8338
+ * {@link StorageProvider} instance
8339
+ * - `embedding` — {@link EmbeddingProvider} instance **or**
8340
+ * {@link EmbeddingConfig} / {@link openaiEmbedding} (etc.)
8341
+ * - `llm` — optional {@link LlmProvider} or {@link LlmConfig} / {@link openaiLlm};
8342
+ * required for {@link Wolbarg.compress} and extract-mode
8343
+ * {@link Wolbarg.rememberFromMessages}
8344
+ * - `graph`, `telemetry`, `reranker`, `keywordSearch`, `ocr`, `vision`,
8345
+ * `compression`, `chunking`, `retrieval`, `concurrency`, `embeddingCache`,
8346
+ * `memory.dedupe` — optional plugins / tuning
8347
+ */
7910
8348
  constructor(options) {
7911
8349
  this.telemetry = new TelemetryEmitter(null, { enabled: false, level: "off" });
7912
8350
  if (!options) {
@@ -7965,6 +8403,12 @@ var Wolbarg = class {
7965
8403
  }
7966
8404
  /**
7967
8405
  * Backwards-compatible initialization (v0.1 API).
8406
+ * Prefer constructing with options + {@link Wolbarg.ready} instead.
8407
+ *
8408
+ * @param options - Organization, database, embedding, and optional LLM config.
8409
+ * @returns Resolves when storage is open and the vector schema is ready.
8410
+ * @throws {InitializationError} If already initialized.
8411
+ * @throws {ConfigurationError} | {ValidationError} On invalid options.
7968
8412
  */
7969
8413
  async init(options) {
7970
8414
  if (this.initialized || this.storage) {
@@ -7996,7 +8440,14 @@ var Wolbarg = class {
7996
8440
  }
7997
8441
  await this.ready();
7998
8442
  }
7999
- /** Ensure storage (and optional telemetry) are open. */
8443
+ /**
8444
+ * Open storage, optional telemetry / checkpoint / graph providers, wrap the
8445
+ * embedding cache, and probe embedding dimensions. Safe to call multiple times;
8446
+ * concurrent callers share one boot promise.
8447
+ *
8448
+ * @returns Resolves when the instance is ready for remember/recall.
8449
+ * @throws {InitializationError} If neither constructor options nor {@link init} were used.
8450
+ */
8000
8451
  async ready() {
8001
8452
  if (this.initialized) {
8002
8453
  return;
@@ -8012,6 +8463,7 @@ var Wolbarg = class {
8012
8463
  this.booting = null;
8013
8464
  }
8014
8465
  }
8466
+ /** Internal boot sequence invoked by {@link Wolbarg.ready}. */
8015
8467
  async boot() {
8016
8468
  if (!this.storage || !this.embedding || !this.organization) {
8017
8469
  throw new InitializationError(
@@ -8087,7 +8539,17 @@ var Wolbarg = class {
8087
8539
  );
8088
8540
  }
8089
8541
  }
8090
- /** Store a semantic memory for an agent (may upsert when dedupe is enabled). */
8542
+ /**
8543
+ * Store a semantic memory for an agent. Embeds `content.text`, writes the row,
8544
+ * and may **upsert** an existing active memory when dedupe is enabled
8545
+ * (constructor `memory.dedupe` or per-call `options.dedupe`).
8546
+ *
8547
+ * @param options - Agent id, text content, optional metadata / dedupe overrides.
8548
+ * See {@link RememberOptions}.
8549
+ * @returns The stored record plus `action` (`"created"` | `"updated"`).
8550
+ * @throws {ValidationError} On empty agent/content.
8551
+ * @throws {InitializationError} If not configured / ready.
8552
+ */
8091
8553
  async remember(options) {
8092
8554
  const trace = this.telemetry.start("remember");
8093
8555
  try {
@@ -8109,7 +8571,15 @@ var Wolbarg = class {
8109
8571
  throw wrapOperationError("remember", error);
8110
8572
  }
8111
8573
  }
8112
- /** Batch remember — sequential when dedupe enabled; otherwise one TX batch. */
8574
+ /**
8575
+ * Remember many memories in one call. Runs sequentially when any item (or the
8576
+ * global config) enables dedupe; otherwise embeds in batch and inserts in one
8577
+ * transaction for throughput.
8578
+ *
8579
+ * @param items - Non-empty list of {@link RememberOptions}.
8580
+ * @returns One {@link RememberResult} per input, same order.
8581
+ * @throws {ValidationError} If `items` is empty or an entry is invalid.
8582
+ */
8113
8583
  async rememberBatch(items) {
8114
8584
  const parent = this.telemetry.start("rememberBatch");
8115
8585
  try {
@@ -8235,7 +8705,15 @@ var Wolbarg = class {
8235
8705
  * **Experimental** until 1.0 — API shape may change.
8236
8706
  *
8237
8707
  * - `mode: "raw"` (default) — remember user message text (no LLM).
8238
- * - `mode: "extract"` — require configured `llm`; extract atomic facts then remember each.
8708
+ * - `mode: "extract"` — requires configured `llm`; extracts atomic facts then
8709
+ * remembers each. Pass a custom {@link LlmProvider} or {@link openaiLlm}
8710
+ * in the constructor.
8711
+ *
8712
+ * @param messages - Conversation turns (`role` + `content`).
8713
+ * @param options - Agent, mode, optional metadata/dedupe. See
8714
+ * {@link RememberFromMessagesOptions}.
8715
+ * @returns One {@link RememberResult} per remembered fact/message.
8716
+ * @throws {ProviderNotConfiguredError} When `mode: "extract"` but no `llm` was configured.
8239
8717
  */
8240
8718
  async rememberFromMessages(messages, options) {
8241
8719
  const parent = this.telemetry.start("rememberFromMessages");
@@ -8305,7 +8783,14 @@ var Wolbarg = class {
8305
8783
  }
8306
8784
  }
8307
8785
  /**
8308
- * Update an existing memory by id (re-embeds when content changes).
8786
+ * Update an existing memory by id. Re-embeds when `content` changes; merges
8787
+ * metadata when provided.
8788
+ *
8789
+ * @param options.id - Memory id to update.
8790
+ * @param options.content - Optional new `{ text }` (triggers re-embed + content hash).
8791
+ * @param options.metadata - Optional metadata merged onto the existing record.
8792
+ * @returns Updated record with `action: "updated"`.
8793
+ * @throws {MemoryNotFoundError} If the id is unknown in this organization.
8309
8794
  */
8310
8795
  async update(options) {
8311
8796
  const trace = this.telemetry.start("update");
@@ -8375,10 +8860,18 @@ var Wolbarg = class {
8375
8860
  }
8376
8861
  }
8377
8862
  /**
8378
- * Subscribe to memory change events.
8863
+ * Subscribe to memory change events (remember / update / forget / compress / clear).
8379
8864
  *
8380
8865
  * **SQLite:** delivers events only within this Node.js process.
8381
8866
  * A second process writing the same `memory.db` will not notify subscribers here.
8867
+ *
8868
+ * **Postgres:** uses LISTEN/NOTIFY across processes (lazy connection on first subscribe).
8869
+ *
8870
+ * @param filter - Scope by `organization` (defaults to this instance’s org),
8871
+ * optional `agent`, and optional `events` allow-list. See {@link SubscribeFilter}.
8872
+ * @param callback - Invoked with each {@link MemoryChangeEvent}.
8873
+ * @returns {@link Unsubscribe} function — call to stop receiving events.
8874
+ * @throws {ValidationError} If organization cannot be resolved.
8382
8875
  */
8383
8876
  subscribe(filter, callback) {
8384
8877
  const org = filter.organization || this.organization;
@@ -8407,6 +8900,7 @@ var Wolbarg = class {
8407
8900
  }
8408
8901
  return this.subscribeBackend.subscribe(normalized, callback);
8409
8902
  }
8903
+ /** Broadcast a memory change event to in-process or Postgres NOTIFY subscribers. */
8410
8904
  emitChange(event) {
8411
8905
  try {
8412
8906
  if (this.storage instanceof PostgresStorageProvider) {
@@ -8632,6 +9126,17 @@ var Wolbarg = class {
8632
9126
  throw error;
8633
9127
  }
8634
9128
  }
9129
+ /**
9130
+ * Find the best active near-duplicate memory for upsert (cosine similarity ≥ threshold).
9131
+ *
9132
+ * @param storage - Open storage provider.
9133
+ * @param organization - Org namespace.
9134
+ * @param agent - Agent scope for the search.
9135
+ * @param vector - Embedding of the candidate text.
9136
+ * @param threshold - Minimum similarity (0–1) to treat as a duplicate.
9137
+ * @param limit - Max vector candidates to inspect.
9138
+ * @returns Matching memory row, or `null` if none qualify.
9139
+ */
8635
9140
  async findNearDuplicate(storage, organization, agent, vector, threshold, limit) {
8636
9141
  if (typeof storage.searchVectorsWithMemories === "function") {
8637
9142
  const hits2 = await storage.searchVectorsWithMemories(
@@ -8969,7 +9474,13 @@ var Wolbarg = class {
8969
9474
  throw wrapOperationError("recall", error);
8970
9475
  }
8971
9476
  }
8972
- /** Batch recall — parent event + child traces. */
9477
+ /**
9478
+ * Run multiple recalls sequentially under one parent telemetry span.
9479
+ *
9480
+ * @param queries - Non-empty list of recall options (`explain` is forced off).
9481
+ * @returns One hit array per query, same order.
9482
+ * @throws {ValidationError} If `queries` is empty.
9483
+ */
8973
9484
  async recallBatch(queries) {
8974
9485
  const parent = this.telemetry.start("recallBatch");
8975
9486
  try {
@@ -9003,10 +9514,21 @@ var Wolbarg = class {
9003
9514
  throw wrapOperationError("recallBatch", error);
9004
9515
  }
9005
9516
  }
9517
+ /**
9518
+ * Compress the newest active memories for an agent into one summary memory
9519
+ * and archive the sources. Requires an `llm` (or custom `compression`) at
9520
+ * construction — typed only on `Wolbarg<true>`.
9521
+ *
9522
+ * @param options - `agent` required; optional `limit` (default 50, min 2).
9523
+ * See {@link CompressOptions}.
9524
+ * @returns Summary record plus archived source ids. See {@link CompressResult}.
9525
+ * @throws {ProviderNotConfiguredError} If no LLM/compression provider is set.
9526
+ * @throws {ValidationError} If fewer than 2 active memories exist for the agent.
9527
+ */
9006
9528
  async compress(options) {
9007
9529
  return this.runCompress(options);
9008
9530
  }
9009
- /** @internal */
9531
+ /** @internal Runs compress for both typed and untyped call sites. */
9010
9532
  async runCompress(options) {
9011
9533
  const trace = this.telemetry.start("compress");
9012
9534
  try {
@@ -9095,6 +9617,16 @@ var Wolbarg = class {
9095
9617
  throw wrapOperationError("compress", error);
9096
9618
  }
9097
9619
  }
9620
+ /**
9621
+ * Ingest a document (path, URL, Buffer, or text), chunk it, embed chunks, and
9622
+ * store each as a memory. Images use optional `ocr` / `vision` providers from
9623
+ * the constructor.
9624
+ *
9625
+ * @param options - `agent`, `source`, optional chunking overrides / metadata.
9626
+ * See {@link IngestOptions}.
9627
+ * @returns Counts and created memory ids. See {@link IngestResult}.
9628
+ * @throws {ValidationError} If no text can be extracted or chunking yields zero chunks.
9629
+ */
9098
9630
  async ingest(options) {
9099
9631
  const trace = this.telemetry.start("ingest");
9100
9632
  try {
@@ -9265,8 +9797,14 @@ var Wolbarg = class {
9265
9797
  }
9266
9798
  }
9267
9799
  /**
9268
- * Link two memories in the optional graph layer.
9269
- * Throws {@link ProviderNotConfiguredError} when no graph provider is set.
9800
+ * Link two memories in the optional graph layer with a typed relation edge.
9801
+ *
9802
+ * @param fromId - Source memory id.
9803
+ * @param toId - Target memory id.
9804
+ * @param relation - Edge label (e.g. `"supports"`, `"caused_by"`).
9805
+ * @param metadata - Optional edge properties stored on the graph provider.
9806
+ * @throws {ProviderNotConfiguredError} When no `graph` was configured.
9807
+ * @throws {ValidationError} On empty ids/relation.
9270
9808
  */
9271
9809
  async linkMemories(fromId, toId, relation, metadata) {
9272
9810
  const trace = this.telemetry.start("linkMemories");
@@ -9296,8 +9834,13 @@ var Wolbarg = class {
9296
9834
  }
9297
9835
  /**
9298
9836
  * Traverse related memories via the optional graph layer.
9299
- * Throws {@link ProviderNotConfiguredError} when no graph provider is set.
9300
- * Results are re-hydrated from SQL storage when available.
9837
+ * Neighbor stubs from the graph are re-hydrated from SQL storage when available.
9838
+ *
9839
+ * @param memoryId - Seed memory id.
9840
+ * @param options - Optional `relation`, `direction`, `depth`, `limit`.
9841
+ * See {@link GetRelatedOptions}.
9842
+ * @returns Related {@link MemoryRecord} list (may be empty).
9843
+ * @throws {ProviderNotConfiguredError} When no `graph` was configured.
9301
9844
  */
9302
9845
  async getRelated(memoryId, options) {
9303
9846
  const trace = this.telemetry.start("getRelated");
@@ -9334,6 +9877,14 @@ var Wolbarg = class {
9334
9877
  throw wrapOperationError("getRelated", error);
9335
9878
  }
9336
9879
  }
9880
+ /**
9881
+ * Delete memories by id or by agent filter. Cascades graph nodes/edges when
9882
+ * a graph provider is configured.
9883
+ *
9884
+ * @param options - Either `{ id }` or `{ filter: { agent } }`. See {@link ForgetOptions}.
9885
+ * @returns Number of memories deleted.
9886
+ * @throws {ValidationError} If neither `id` nor `filter.agent` is provided.
9887
+ */
9337
9888
  async forget(options) {
9338
9889
  const trace = this.telemetry.start("forget");
9339
9890
  try {
@@ -9398,6 +9949,13 @@ var Wolbarg = class {
9398
9949
  throw wrapOperationError("forget", error);
9399
9950
  }
9400
9951
  }
9952
+ /**
9953
+ * Return the audit/history timeline for a single memory.
9954
+ *
9955
+ * @param options - `{ id }` of the memory. See {@link HistoryOptions}.
9956
+ * @returns Memory record plus ordered {@link HistoryEvent} list.
9957
+ * @throws {MemoryNotFoundError} If the id is unknown.
9958
+ */
9401
9959
  async history(options) {
9402
9960
  const trace = this.telemetry.start("history");
9403
9961
  try {
@@ -9425,6 +9983,11 @@ var Wolbarg = class {
9425
9983
  throw wrapOperationError("history", error);
9426
9984
  }
9427
9985
  }
9986
+ /**
9987
+ * Aggregate counts for this organization (active / archived / agents / etc.).
9988
+ *
9989
+ * @returns {@link StatsResult} snapshot.
9990
+ */
9428
9991
  async stats() {
9429
9992
  const trace = this.telemetry.start("stats");
9430
9993
  try {
@@ -9452,6 +10015,13 @@ var Wolbarg = class {
9452
10015
  throw wrapOperationError("stats", error);
9453
10016
  }
9454
10017
  }
10018
+ /**
10019
+ * Delete all memories for this organization (optionally scoped by agent).
10020
+ * Cascades graph cleanup when a graph provider is configured.
10021
+ *
10022
+ * @param options - Optional `{ agent }` scope. See {@link ClearOptions}.
10023
+ * @returns Number of memories deleted.
10024
+ */
9455
10025
  async clear(options) {
9456
10026
  const trace = this.telemetry.start("clear");
9457
10027
  try {
@@ -9480,7 +10050,16 @@ var Wolbarg = class {
9480
10050
  throw wrapOperationError("clear", error);
9481
10051
  }
9482
10052
  }
9483
- /** Create an immutable named checkpoint of the memory database. */
10053
+ /**
10054
+ * Create an immutable named checkpoint of the file-backed SQLite memory DB
10055
+ * (and SQLite graph snapshot when applicable).
10056
+ *
10057
+ * @param name - Checkpoint name (unique).
10058
+ * @param options - Optional metadata. See {@link CheckpointOptions}.
10059
+ * @returns {@link CheckpointInfo} for the new checkpoint.
10060
+ * @throws {ProviderNotConfiguredError} Without a checkpoint provider / file DB.
10061
+ * @throws {GraphCheckpointNotSupportedError} For Neo4j graph backends.
10062
+ */
9484
10063
  async checkpoint(name, options) {
9485
10064
  const trace = this.telemetry.start("checkpoint");
9486
10065
  try {
@@ -9511,7 +10090,12 @@ var Wolbarg = class {
9511
10090
  throw wrapOperationError("checkpoint", error);
9512
10091
  }
9513
10092
  }
9514
- /** Restore the memory database from a named checkpoint. */
10093
+ /**
10094
+ * Restore the memory database from a named checkpoint (replaces the live DB file).
10095
+ *
10096
+ * @param name - Checkpoint name previously created with {@link Wolbarg.checkpoint}.
10097
+ * @returns {@link CheckpointInfo} of the restored checkpoint.
10098
+ */
9515
10099
  async rollback(name) {
9516
10100
  const trace = this.telemetry.start("rollback");
9517
10101
  let storageClosed = false;
@@ -9557,6 +10141,12 @@ var Wolbarg = class {
9557
10141
  throw wrapOperationError("rollback", error);
9558
10142
  }
9559
10143
  }
10144
+ /**
10145
+ * Delete a named checkpoint from disk / the checkpoint store.
10146
+ *
10147
+ * @param name - Checkpoint name.
10148
+ * @returns `true` if a checkpoint was removed.
10149
+ */
9560
10150
  async deleteCheckpoint(name) {
9561
10151
  const trace = this.telemetry.start("deleteCheckpoint");
9562
10152
  try {
@@ -9583,6 +10173,11 @@ var Wolbarg = class {
9583
10173
  throw wrapOperationError("deleteCheckpoint", error);
9584
10174
  }
9585
10175
  }
10176
+ /**
10177
+ * List all known checkpoints for this instance.
10178
+ *
10179
+ * @returns Array of {@link CheckpointInfo} (may be empty).
10180
+ */
9586
10181
  async listCheckpoints() {
9587
10182
  const trace = this.telemetry.start("listCheckpoints");
9588
10183
  try {
@@ -9601,6 +10196,12 @@ var Wolbarg = class {
9601
10196
  throw wrapOperationError("listCheckpoints", error);
9602
10197
  }
9603
10198
  }
10199
+ /**
10200
+ * Look up a single checkpoint by name.
10201
+ *
10202
+ * @param name - Checkpoint name.
10203
+ * @returns {@link CheckpointInfo} or `null` if missing.
10204
+ */
9604
10205
  async getCheckpoint(name) {
9605
10206
  const trace = this.telemetry.start("getCheckpoint");
9606
10207
  try {
@@ -9620,7 +10221,13 @@ var Wolbarg = class {
9620
10221
  throw wrapOperationError("getCheckpoint", error);
9621
10222
  }
9622
10223
  }
9623
- /** Export the memory database to a portable SQLite + manifest bundle. */
10224
+ /**
10225
+ * Export the memory database to a portable SQLite + manifest bundle
10226
+ * (includes SQLite graph sidecar when applicable).
10227
+ *
10228
+ * @param exportPath - Destination file path for the export bundle.
10229
+ * @returns {@link ExportResult} with path, size, and timestamp.
10230
+ */
9624
10231
  async export(exportPath) {
9625
10232
  const trace = this.telemetry.start("export");
9626
10233
  try {
@@ -9651,7 +10258,13 @@ var Wolbarg = class {
9651
10258
  throw wrapOperationError("export", error);
9652
10259
  }
9653
10260
  }
9654
- /** Import a previously exported memory database, replacing the current file. */
10261
+ /**
10262
+ * Import a previously exported memory database, replacing the current file.
10263
+ * Closes and reopens storage around the swap.
10264
+ *
10265
+ * @param exportPath - Path to a bundle produced by {@link Wolbarg.export}.
10266
+ * @returns {@link ImportResult} with restored path and timestamp.
10267
+ */
9655
10268
  async import(exportPath) {
9656
10269
  const trace = this.telemetry.start("import");
9657
10270
  let storageClosed = false;
@@ -9701,11 +10314,17 @@ var Wolbarg = class {
9701
10314
  throw wrapOperationError("import", error);
9702
10315
  }
9703
10316
  }
9704
- /** Flush pending telemetry (useful in tests). */
10317
+ /**
10318
+ * Flush pending telemetry writes (useful in tests / before process exit).
10319
+ *
10320
+ * @returns Resolves when the telemetry provider has flushed.
10321
+ */
9705
10322
  async flushTelemetry() {
9706
10323
  await this.telemetry.flush();
9707
10324
  }
9708
- /** Session id for this SDK instance (telemetry traces). */
10325
+ /**
10326
+ * Session id for this SDK instance (attached to telemetry traces and change events).
10327
+ */
9709
10328
  get sessionId() {
9710
10329
  return this.telemetry.sessionId;
9711
10330
  }
@@ -9720,6 +10339,12 @@ var Wolbarg = class {
9720
10339
  }
9721
10340
  return fn();
9722
10341
  }
10342
+ /**
10343
+ * Close storage, graph, telemetry, checkpoints, and subscribe backends.
10344
+ * The instance can be discarded afterward; construct a new one to reopen.
10345
+ *
10346
+ * @returns Resolves when all providers have closed (errors are swallowed per-provider).
10347
+ */
9723
10348
  async close() {
9724
10349
  if (this.storage) {
9725
10350
  this.telemetry.emitShutdown(this.storage.name);
@@ -9744,9 +10369,11 @@ var Wolbarg = class {
9744
10369
  this.embeddingDimensions = null;
9745
10370
  this.initialized = false;
9746
10371
  }
10372
+ /** Whether {@link Wolbarg.ready} / {@link Wolbarg.init} has completed successfully. */
9747
10373
  get isInitialized() {
9748
10374
  return this.initialized;
9749
10375
  }
10376
+ /** Ensure {@link Wolbarg.ready} completed and core providers are available. */
9750
10377
  async requireReady() {
9751
10378
  await this.ready();
9752
10379
  if (!this.initialized || !this.storage || !this.embedding || !this.organization) {
@@ -9760,6 +10387,7 @@ var Wolbarg = class {
9760
10387
  organization: this.organization
9761
10388
  };
9762
10389
  }
10390
+ /** Reject embeddings whose dimensionality differs from the initialized model. */
9763
10391
  assertEmbeddingDimensions(dimensions) {
9764
10392
  if (this.embeddingDimensions !== null && dimensions !== this.embeddingDimensions) {
9765
10393
  throw new ValidationError(
@@ -9767,6 +10395,7 @@ var Wolbarg = class {
9767
10395
  );
9768
10396
  }
9769
10397
  }
10398
+ /** Return the configured checkpoint provider or throw {@link ProviderNotConfiguredError}. */
9770
10399
  requireCheckpointProvider() {
9771
10400
  if (!this.checkpointProvider) {
9772
10401
  throw new ProviderNotConfiguredError(
@@ -9777,6 +10406,7 @@ var Wolbarg = class {
9777
10406
  }
9778
10407
  return this.checkpointProvider;
9779
10408
  }
10409
+ /** Return the configured graph provider or throw with a setup hint for `method`. */
9780
10410
  requireGraph(method) {
9781
10411
  if (!this.graph) {
9782
10412
  throw new ProviderNotConfiguredError(
@@ -9787,20 +10417,24 @@ var Wolbarg = class {
9787
10417
  }
9788
10418
  return this.graph;
9789
10419
  }
10420
+ /** Throw when graph checkpoint pairing is requested on a non-file-backed graph backend. */
9790
10421
  assertGraphCheckpointSupported(operation) {
9791
10422
  if (!this.graph) return;
9792
10423
  if (!this.graph.supportsFileSnapshot()) {
9793
10424
  throw new GraphCheckpointNotSupportedError(this.graph.name, operation);
9794
10425
  }
9795
10426
  }
10427
+ /** Directory path where a graph file snapshot is stored alongside a memory checkpoint. */
9796
10428
  graphSnapshotDir(alongsidePath) {
9797
10429
  return `${alongsidePath}.graph`;
9798
10430
  }
10431
+ /** Close the graph provider before copying files; returns whether a close occurred. */
9799
10432
  async closeGraphForSnapshot() {
9800
10433
  if (!this.graph || !this.graph.supportsFileSnapshot()) return false;
9801
10434
  await this.graph.close();
9802
10435
  return true;
9803
10436
  }
10437
+ /** Copy the SQLite graph database next to a memory checkpoint directory. */
9804
10438
  async snapshotGraphAlongside(alongsidePath, operation) {
9805
10439
  if (!this.graph) return;
9806
10440
  if (!this.graph.supportsFileSnapshot()) {
@@ -9839,6 +10473,7 @@ var Wolbarg = class {
9839
10473
  await this.graph.open();
9840
10474
  }
9841
10475
  }
10476
+ /** Restore a graph file snapshot written by {@link snapshotGraphAlongside}. */
9842
10477
  async restoreGraphAlongside(alongsidePath, operation) {
9843
10478
  if (!this.graph) return;
9844
10479
  if (!this.graph.supportsFileSnapshot()) {
@@ -9862,6 +10497,7 @@ var Wolbarg = class {
9862
10497
  fs6.cpSync(src, dataPath, { recursive: true });
9863
10498
  }
9864
10499
  }
10500
+ /** Run graph traversal then re-hydrate stub records from storage when rows exist. */
9865
10501
  async hydrateRelated(memoryId, options) {
9866
10502
  const graph = this.requireGraph("getRelated");
9867
10503
  const related = await graph.getRelated(memoryId, options);
@@ -9877,6 +10513,7 @@ var Wolbarg = class {
9877
10513
  }
9878
10514
  return out;
9879
10515
  }
10516
+ /** Resolve the on-disk SQLite memory database path (throws for Postgres / `:memory:`). */
9880
10517
  requireMemoryDbPath() {
9881
10518
  if (this.storage && !(this.storage instanceof SqliteStorageProvider)) {
9882
10519
  throw new ConfigurationError(
@@ -9928,6 +10565,7 @@ function commonTags(metadata) {
9928
10565
 
9929
10566
  // src/filters/types.ts
9930
10567
  var meta = {
10568
+ /** Field equals value (strict equality). */
9931
10569
  eq: (field, value) => ({
9932
10570
  field,
9933
10571
  op: { eq: value }
@@ -10011,16 +10649,23 @@ function createTelemetryProvider(config) {
10011
10649
  function wolbarg2(options) {
10012
10650
  return new Wolbarg(options);
10013
10651
  }
10652
+ var createWolbarg = wolbarg2;
10014
10653
 
10015
10654
  // src/keyword/index.ts
10016
10655
  var Bm25KeywordSearchProvider = class {
10017
10656
  name = "bm25";
10018
10657
  k1;
10019
10658
  b;
10659
+ /**
10660
+ * @param options - BM25 tuning parameters.
10661
+ * @param options.k1 - Term frequency saturation (default `1.2`).
10662
+ * @param options.b - Length normalization (default `0.75`).
10663
+ */
10020
10664
  constructor(options) {
10021
10665
  this.k1 = options?.k1 ?? 1.2;
10022
10666
  this.b = options?.b ?? 0.75;
10023
10667
  }
10668
+ /** @inheritdoc */
10024
10669
  async search(query, documents, topK) {
10025
10670
  if (documents.length === 0 || topK <= 0) {
10026
10671
  return [];
@@ -10473,6 +11118,271 @@ function percentile(sorted, p) {
10473
11118
  return sorted[idx];
10474
11119
  }
10475
11120
 
10476
- export { CompressionError, ConfigurationError, DatabaseError, EmbeddingError, FixedChunkingStrategy, GraphCheckpointNotSupportedError, HeadingChunkingStrategy, InitializationError, LlmCompressionProvider, MarkdownChunkingStrategy, MemoryNotFoundError, Neo4jGraphProvider, NoopTelemetryProvider, ParagraphChunkingStrategy, PostgresStorageProvider, ProviderNotConfiguredError, SDK_VERSION, SentenceChunkingStrategy, SqliteCheckpointProvider, SqliteDatabaseProvider, SqliteEventDatabase, SqliteGraphProvider, SqliteStorageProvider, SqliteTelemetryProvider, StorageLockedError, TelemetryEmitter, ValidationError, Wolbarg, WolbargError, WolbargLogger, bgeReranker, bm25, cohereReranker, createChunkingStrategy, createCompressionProvider, createDatabaseProvider, createEmbeddingProvider, createLlmProvider, createStorageProvider, createTelemetryProvider, wolbarg2 as createWolbarg, crossEncoder, geminiEmbedding, geminiVision, jinaReranker, lmStudioEmbedding, meta, neo4jGraph, ollamaEmbedding, ollamaLlm, openRouterEmbedding, openRouterLlm, openaiCompatibleEmbedding, openaiCompatibleLlm, openaiEmbedding, openaiLlm, openaiReranker, openaiVision, postgres, postgresConfig, runBenchmark, sqlite, sqliteCheckpoint, sqliteConfig, sqliteGraph, sqliteTelemetry, summarizeBenchmark, tesseract, togetherEmbedding, vllmEmbedding, wolbarg, wrapOperationError };
11121
+ // src/config/providers.ts
11122
+ var EMBEDDING_PROVIDER_PRESETS = [
11123
+ {
11124
+ id: "openai",
11125
+ label: "OpenAI",
11126
+ defaultBaseUrl: "https://api.openai.com/v1",
11127
+ defaultModel: "text-embedding-3-small",
11128
+ apiKeyEnv: "OPENAI_API_KEY"
11129
+ },
11130
+ {
11131
+ id: "ollama",
11132
+ label: "Ollama (local)",
11133
+ defaultBaseUrl: "http://127.0.0.1:11434/v1",
11134
+ defaultModel: "nomic-embed-text",
11135
+ apiKeyEnv: "OLLAMA_API_KEY",
11136
+ apiKeyHint: "Any non-empty value works locally (e.g. ollama)"
11137
+ },
11138
+ {
11139
+ id: "openrouter",
11140
+ label: "OpenRouter",
11141
+ defaultBaseUrl: "https://openrouter.ai/api/v1",
11142
+ defaultModel: "openai/text-embedding-3-small",
11143
+ apiKeyEnv: "OPENROUTER_API_KEY"
11144
+ },
11145
+ {
11146
+ id: "lmstudio",
11147
+ label: "LM Studio (local)",
11148
+ defaultBaseUrl: "http://127.0.0.1:1234/v1",
11149
+ defaultModel: "text-embedding-nomic-embed-text-v1.5",
11150
+ apiKeyEnv: "LM_STUDIO_API_KEY",
11151
+ apiKeyHint: "Often unused locally \u2014 any non-empty value is fine"
11152
+ },
11153
+ {
11154
+ id: "gemini",
11155
+ label: "Google Gemini",
11156
+ defaultBaseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
11157
+ defaultModel: "text-embedding-004",
11158
+ apiKeyEnv: "GEMINI_API_KEY"
11159
+ },
11160
+ {
11161
+ id: "together",
11162
+ label: "Together AI",
11163
+ defaultBaseUrl: "https://api.together.xyz/v1",
11164
+ defaultModel: "togethercomputer/m2-bert-80M-8k-retrieval",
11165
+ apiKeyEnv: "TOGETHER_API_KEY"
11166
+ },
11167
+ {
11168
+ id: "vllm",
11169
+ label: "vLLM (local/server)",
11170
+ defaultBaseUrl: "http://127.0.0.1:8000/v1",
11171
+ defaultModel: "text-embedding-ada-002",
11172
+ apiKeyEnv: "VLLM_API_KEY",
11173
+ apiKeyHint: "Only if your server requires auth"
11174
+ },
11175
+ {
11176
+ id: "custom",
11177
+ label: "Custom OpenAI-compatible",
11178
+ defaultBaseUrl: "https://api.openai.com/v1",
11179
+ defaultModel: "text-embedding-3-small",
11180
+ apiKeyEnv: "WOLBARG_EMBEDDING_API_KEY"
11181
+ }
11182
+ ];
11183
+ function getEmbeddingProviderPreset(id) {
11184
+ return EMBEDDING_PROVIDER_PRESETS.find((p) => p.id === id);
11185
+ }
11186
+ var DEFAULT_SQLITE_DB_PATH = ".wolbarg/shared-memory/memory.db";
11187
+ var DEFAULT_ORGANIZATION = "default";
11188
+ var DEFAULT_CONFIG_PATH = ".wolbarg/config.json";
11189
+ var DEFAULT_ENV_PATH = ".wolbarg/.env";
11190
+ function defaultProjectConfig() {
11191
+ return {
11192
+ version: 1,
11193
+ organization: DEFAULT_ORGANIZATION,
11194
+ database: {
11195
+ provider: "sqlite",
11196
+ url: DEFAULT_SQLITE_DB_PATH
11197
+ },
11198
+ paths: {
11199
+ config: DEFAULT_CONFIG_PATH
11200
+ }
11201
+ };
11202
+ }
11203
+ function resolveConfigPath(cwd = process.cwd(), configPath) {
11204
+ const rel = configPath ?? DEFAULT_CONFIG_PATH;
11205
+ return isAbsolute(rel) ? rel : resolve(cwd, rel);
11206
+ }
11207
+ function resolveEnvPath(cwd = process.cwd(), envPath) {
11208
+ const rel = envPath ?? DEFAULT_ENV_PATH;
11209
+ return isAbsolute(rel) ? rel : resolve(cwd, rel);
11210
+ }
11211
+ function loadProjectConfig(cwd = process.cwd(), configPath) {
11212
+ const full = resolveConfigPath(cwd, configPath);
11213
+ if (!existsSync(full)) return null;
11214
+ const raw = JSON.parse(readFileSync(full, "utf8"));
11215
+ if (!raw || raw.version !== 1 || !raw.database?.url) {
11216
+ throw new Error(`Invalid Wolbarg config at ${full}`);
11217
+ }
11218
+ return raw;
11219
+ }
11220
+ function saveProjectConfig(config, options = {}) {
11221
+ const cwd = options.cwd ?? process.cwd();
11222
+ const configPath = resolveConfigPath(cwd, options.configPath);
11223
+ const dir = dirname(configPath);
11224
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
11225
+ if (existsSync(configPath) && options.overwrite === false) {
11226
+ throw new Error(`Config already exists: ${configPath} (pass --force to overwrite)`);
11227
+ }
11228
+ const toWrite = {
11229
+ ...config,
11230
+ paths: {
11231
+ config: options.configPath ?? DEFAULT_CONFIG_PATH,
11232
+ ...options.envPath || options.apiKey ? { env: options.envPath ?? DEFAULT_ENV_PATH } : config.paths?.env ? { env: config.paths.env } : {}
11233
+ }
11234
+ };
11235
+ writeFileSync(configPath, `${JSON.stringify(toWrite, null, 2)}
11236
+ `, "utf8");
11237
+ let envPath;
11238
+ if (options.apiKey && config.embedding?.apiKeyEnv) {
11239
+ envPath = resolveEnvPath(cwd, options.envPath);
11240
+ ensureParent(envPath);
11241
+ upsertEnvVar(envPath, config.embedding.apiKeyEnv, options.apiKey);
11242
+ ensureGitignore(cwd, [DEFAULT_ENV_PATH, ".env"]);
11243
+ }
11244
+ if (config.database.provider === "sqlite" && !config.database.url.includes("://")) {
11245
+ const dbPath = isAbsolute(config.database.url) ? config.database.url : resolve(cwd, config.database.url);
11246
+ ensureParent(dbPath);
11247
+ }
11248
+ return { configPath, envPath };
11249
+ }
11250
+ function ensureParent(filePath) {
11251
+ const dir = dirname(filePath);
11252
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
11253
+ }
11254
+ function upsertEnvVar(envPath, key, value) {
11255
+ ensureParent(envPath);
11256
+ let text = existsSync(envPath) ? readFileSync(envPath, "utf8") : "";
11257
+ const line = `${key}=${shellQuoteEnv(value)}`;
11258
+ const re = new RegExp(`^${escapeRegExp(key)}=.*$`, "m");
11259
+ if (re.test(text)) {
11260
+ text = text.replace(re, line);
11261
+ } else {
11262
+ if (text && !text.endsWith("\n")) text += "\n";
11263
+ text += `${line}
11264
+ `;
11265
+ }
11266
+ writeFileSync(envPath, text, "utf8");
11267
+ }
11268
+ function shellQuoteEnv(value) {
11269
+ if (/[\s#"']/.test(value)) {
11270
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
11271
+ }
11272
+ return value;
11273
+ }
11274
+ function escapeRegExp(s) {
11275
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11276
+ }
11277
+ function ensureGitignore(cwd, entries) {
11278
+ const gi = join(cwd, ".gitignore");
11279
+ let text = existsSync(gi) ? readFileSync(gi, "utf8") : "";
11280
+ let changed = false;
11281
+ for (const entry of entries) {
11282
+ if (text.split(/\r?\n/).some((l) => l.trim() === entry)) continue;
11283
+ if (text && !text.endsWith("\n")) text += "\n";
11284
+ text += `${entry}
11285
+ `;
11286
+ changed = true;
11287
+ }
11288
+ if (changed) writeFileSync(gi, text, "utf8");
11289
+ }
11290
+ function resolveEmbeddingApiKey(config, env = process.env) {
11291
+ const name = config.embedding?.apiKeyEnv;
11292
+ if (!name) return "";
11293
+ return env[name] ?? "";
11294
+ }
11295
+ function assertEmbeddingPreset(provider) {
11296
+ const preset = getEmbeddingProviderPreset(provider);
11297
+ if (!preset) {
11298
+ throw new Error(
11299
+ `Unknown embedding provider "${provider}". Choose one of: ${[
11300
+ "openai",
11301
+ "ollama",
11302
+ "openrouter",
11303
+ "lmstudio",
11304
+ "gemini",
11305
+ "together",
11306
+ "vllm",
11307
+ "custom"
11308
+ ].join(", ")}`
11309
+ );
11310
+ }
11311
+ return preset.id;
11312
+ }
11313
+ function applyEnvFile(envPath, base = {}) {
11314
+ const out = { ...base };
11315
+ if (!existsSync(envPath)) return out;
11316
+ const text = readFileSync(envPath, "utf8");
11317
+ for (const rawLine of text.split(/\r?\n/)) {
11318
+ const line = rawLine.trim();
11319
+ if (!line || line.startsWith("#")) continue;
11320
+ const eq = line.indexOf("=");
11321
+ if (eq <= 0) continue;
11322
+ const key = line.slice(0, eq).trim();
11323
+ let value = line.slice(eq + 1).trim();
11324
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
11325
+ value = value.slice(1, -1);
11326
+ }
11327
+ if (out[key] === void 0) out[key] = value;
11328
+ }
11329
+ return out;
11330
+ }
11331
+ function projectConfigToWolbargOptions(config, env = process.env) {
11332
+ if (!config.embedding) {
11333
+ throw new Error(
11334
+ "Project config has no embedding section. Re-run `wolbarg init` and configure an embedding provider, or pass embedding explicitly to wolbarg()."
11335
+ );
11336
+ }
11337
+ const apiKey = resolveEmbeddingApiKey(config, env);
11338
+ if (!apiKey) {
11339
+ throw new Error(
11340
+ `Missing API key. Set ${config.embedding.apiKeyEnv} in the environment or in .wolbarg/.env (from wolbarg init).`
11341
+ );
11342
+ }
11343
+ const dbUrl = config.database.url;
11344
+ return {
11345
+ organization: config.organization,
11346
+ database: {
11347
+ provider: config.database.provider,
11348
+ url: dbUrl,
11349
+ connectionString: dbUrl
11350
+ },
11351
+ embedding: {
11352
+ baseUrl: config.embedding.baseUrl,
11353
+ apiKey,
11354
+ model: config.embedding.model
11355
+ }
11356
+ };
11357
+ }
11358
+ function createWolbargFromProjectConfig(options = {}) {
11359
+ const cwd = options.cwd ?? process.cwd();
11360
+ const config = loadProjectConfig(cwd, options.configPath);
11361
+ if (!config) {
11362
+ throw new Error(
11363
+ `No Wolbarg config found. Run \`wolbarg init\` in ${cwd} (expected .wolbarg/config.json).`
11364
+ );
11365
+ }
11366
+ let env = options.env ?? { ...process.env };
11367
+ if (options.loadEnvFile !== false) {
11368
+ const envFile = resolveEnvPath(
11369
+ cwd,
11370
+ config.paths?.env ?? DEFAULT_ENV_PATH
11371
+ );
11372
+ env = applyEnvFile(envFile, env);
11373
+ }
11374
+ if (options.organization) {
11375
+ config.organization = options.organization;
11376
+ }
11377
+ if (config.database.provider === "sqlite" && !config.database.url.includes("://") && !isAbsolute(config.database.url)) {
11378
+ config.database = {
11379
+ ...config.database,
11380
+ url: resolve(cwd, config.database.url)
11381
+ };
11382
+ }
11383
+ return wolbarg(projectConfigToWolbargOptions(config, env));
11384
+ }
11385
+
11386
+ export { CompressionError, ConfigurationError, DEFAULT_CONFIG_PATH, DEFAULT_ENV_PATH, DEFAULT_ORGANIZATION, DEFAULT_SQLITE_DB_PATH, DatabaseError, EMBEDDING_PROVIDER_PRESETS, EmbeddingError, FixedChunkingStrategy, GraphCheckpointNotSupportedError, HeadingChunkingStrategy, InitializationError, LlmCompressionProvider, MarkdownChunkingStrategy, MemoryNotFoundError, Neo4jGraphProvider, NoopTelemetryProvider, ParagraphChunkingStrategy, PostgresStorageProvider, ProviderNotConfiguredError, SDK_VERSION, SentenceChunkingStrategy, SqliteCheckpointProvider, SqliteDatabaseProvider, SqliteEventDatabase, SqliteGraphProvider, SqliteStorageProvider, SqliteTelemetryProvider, StorageLockedError, TelemetryEmitter, ValidationError, Wolbarg, WolbargError, WolbargLogger, applyEnvFile, assertEmbeddingPreset, bgeReranker, bm25, cohereReranker, createChunkingStrategy, createCompressionProvider, createDatabaseProvider, createEmbeddingProvider, createLlmProvider, createStorageProvider, createTelemetryProvider, createWolbarg, createWolbargFromProjectConfig, crossEncoder, defaultProjectConfig, geminiEmbedding, geminiVision, getEmbeddingProviderPreset, jinaReranker, lmStudioEmbedding, loadProjectConfig, meta, neo4jGraph, ollamaEmbedding, ollamaLlm, openRouterEmbedding, openRouterLlm, openaiCompatibleEmbedding, openaiCompatibleLlm, openaiEmbedding, openaiLlm, openaiReranker, openaiVision, postgres, postgresConfig, projectConfigToWolbargOptions, resolveConfigPath, resolveEmbeddingApiKey, resolveEnvPath, runBenchmark, saveProjectConfig, sqlite, sqliteCheckpoint, sqliteConfig, sqliteGraph, sqliteTelemetry, summarizeBenchmark, tesseract, togetherEmbedding, upsertEnvVar, vllmEmbedding, wolbarg, wrapOperationError };
10477
11387
  //# sourceMappingURL=index.js.map
10478
11388
  //# sourceMappingURL=index.js.map