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