agentdb 2.0.0-alpha.2.14 → 2.0.0-alpha.2.15

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.
@@ -0,0 +1,1492 @@
1
+ /*! AgentDB Browser Bundle v2.0.0-alpha.2.15 | MIT License | https://agentdb.ruv.io */
2
+
3
+ // src/browser/ProductQuantization.ts
4
+ var ProductQuantization = class {
5
+ config;
6
+ codebook = null;
7
+ trained = false;
8
+ constructor(config) {
9
+ this.config = {
10
+ dimension: config.dimension,
11
+ numSubvectors: config.numSubvectors,
12
+ numCentroids: config.numCentroids,
13
+ maxIterations: config.maxIterations || 50,
14
+ convergenceThreshold: config.convergenceThreshold || 1e-4
15
+ };
16
+ if (this.config.dimension % this.config.numSubvectors !== 0) {
17
+ throw new Error(`Dimension ${this.config.dimension} must be divisible by numSubvectors ${this.config.numSubvectors}`);
18
+ }
19
+ }
20
+ /**
21
+ * Train codebook using k-means on training vectors
22
+ */
23
+ async train(vectors) {
24
+ if (vectors.length === 0) {
25
+ throw new Error("Training requires at least one vector");
26
+ }
27
+ const subvectorDim = this.config.dimension / this.config.numSubvectors;
28
+ const centroids = [];
29
+ console.log(`[PQ] Training ${this.config.numSubvectors} subvectors with ${this.config.numCentroids} centroids each...`);
30
+ for (let s = 0; s < this.config.numSubvectors; s++) {
31
+ const startDim = s * subvectorDim;
32
+ const endDim = startDim + subvectorDim;
33
+ const subvectors = vectors.map((v) => v.slice(startDim, endDim));
34
+ const subCentroids = await this.kMeans(subvectors, this.config.numCentroids);
35
+ centroids.push(...subCentroids);
36
+ if ((s + 1) % 4 === 0 || s === this.config.numSubvectors - 1) {
37
+ console.log(`[PQ] Trained ${s + 1}/${this.config.numSubvectors} subvectors`);
38
+ }
39
+ }
40
+ this.codebook = {
41
+ subvectorDim,
42
+ numSubvectors: this.config.numSubvectors,
43
+ numCentroids: this.config.numCentroids,
44
+ centroids
45
+ };
46
+ this.trained = true;
47
+ console.log("[PQ] Training complete");
48
+ }
49
+ /**
50
+ * K-means clustering for centroids
51
+ */
52
+ async kMeans(vectors, k) {
53
+ const dim = vectors[0].length;
54
+ const n = vectors.length;
55
+ const centroids = this.kMeansPlusPlus(vectors, k);
56
+ const assignments = new Uint32Array(n);
57
+ let prevInertia = Infinity;
58
+ for (let iter = 0; iter < this.config.maxIterations; iter++) {
59
+ let inertia = 0;
60
+ for (let i = 0; i < n; i++) {
61
+ let minDist = Infinity;
62
+ let minIdx = 0;
63
+ for (let j = 0; j < k; j++) {
64
+ const dist = this.squaredDistance(vectors[i], centroids[j]);
65
+ if (dist < minDist) {
66
+ minDist = dist;
67
+ minIdx = j;
68
+ }
69
+ }
70
+ assignments[i] = minIdx;
71
+ inertia += minDist;
72
+ }
73
+ if (Math.abs(prevInertia - inertia) < this.config.convergenceThreshold) {
74
+ break;
75
+ }
76
+ prevInertia = inertia;
77
+ const counts = new Uint32Array(k);
78
+ const sums = Array.from({ length: k }, () => new Float32Array(dim));
79
+ for (let i = 0; i < n; i++) {
80
+ const cluster = assignments[i];
81
+ counts[cluster]++;
82
+ for (let d = 0; d < dim; d++) {
83
+ sums[cluster][d] += vectors[i][d];
84
+ }
85
+ }
86
+ for (let j = 0; j < k; j++) {
87
+ if (counts[j] > 0) {
88
+ for (let d = 0; d < dim; d++) {
89
+ centroids[j][d] = sums[j][d] / counts[j];
90
+ }
91
+ }
92
+ }
93
+ }
94
+ return centroids;
95
+ }
96
+ /**
97
+ * K-means++ initialization for better centroid selection
98
+ */
99
+ kMeansPlusPlus(vectors, k) {
100
+ const n = vectors.length;
101
+ const dim = vectors[0].length;
102
+ const centroids = [];
103
+ const firstIdx = Math.floor(Math.random() * n);
104
+ centroids.push(new Float32Array(vectors[firstIdx]));
105
+ for (let i = 1; i < k; i++) {
106
+ const distances = new Float32Array(n);
107
+ let sumDistances = 0;
108
+ for (let j = 0; j < n; j++) {
109
+ let minDist = Infinity;
110
+ for (const centroid of centroids) {
111
+ const dist = this.squaredDistance(vectors[j], centroid);
112
+ minDist = Math.min(minDist, dist);
113
+ }
114
+ distances[j] = minDist;
115
+ sumDistances += minDist;
116
+ }
117
+ let r = Math.random() * sumDistances;
118
+ for (let j = 0; j < n; j++) {
119
+ r -= distances[j];
120
+ if (r <= 0) {
121
+ centroids.push(new Float32Array(vectors[j]));
122
+ break;
123
+ }
124
+ }
125
+ }
126
+ return centroids;
127
+ }
128
+ /**
129
+ * Compress a vector using trained codebook
130
+ */
131
+ compress(vector) {
132
+ if (!this.trained || !this.codebook) {
133
+ throw new Error("Codebook must be trained before compression");
134
+ }
135
+ const codes = new Uint8Array(this.config.numSubvectors);
136
+ const subvectorDim = this.codebook.subvectorDim;
137
+ let norm = 0;
138
+ for (let i = 0; i < vector.length; i++) {
139
+ norm += vector[i] * vector[i];
140
+ }
141
+ norm = Math.sqrt(norm);
142
+ for (let s = 0; s < this.config.numSubvectors; s++) {
143
+ const startDim = s * subvectorDim;
144
+ const subvector = vector.slice(startDim, startDim + subvectorDim);
145
+ let minDist = Infinity;
146
+ let minIdx = 0;
147
+ const centroidOffset = s * this.config.numCentroids;
148
+ for (let c = 0; c < this.config.numCentroids; c++) {
149
+ const centroid = this.codebook.centroids[centroidOffset + c];
150
+ const dist = this.squaredDistance(subvector, centroid);
151
+ if (dist < minDist) {
152
+ minDist = dist;
153
+ minIdx = c;
154
+ }
155
+ }
156
+ codes[s] = minIdx;
157
+ }
158
+ return { codes, norm };
159
+ }
160
+ /**
161
+ * Decompress a vector (approximate reconstruction)
162
+ */
163
+ decompress(compressed) {
164
+ if (!this.codebook) {
165
+ throw new Error("Codebook not available");
166
+ }
167
+ const vector = new Float32Array(this.config.dimension);
168
+ const subvectorDim = this.codebook.subvectorDim;
169
+ for (let s = 0; s < this.config.numSubvectors; s++) {
170
+ const code = compressed.codes[s];
171
+ const centroidOffset = s * this.config.numCentroids;
172
+ const centroid = this.codebook.centroids[centroidOffset + code];
173
+ const startDim = s * subvectorDim;
174
+ for (let d = 0; d < subvectorDim; d++) {
175
+ vector[startDim + d] = centroid[d];
176
+ }
177
+ }
178
+ return vector;
179
+ }
180
+ /**
181
+ * Asymmetric Distance Computation (ADC)
182
+ * Computes distance from query vector to compressed vector
183
+ */
184
+ asymmetricDistance(query, compressed) {
185
+ if (!this.codebook) {
186
+ throw new Error("Codebook not available");
187
+ }
188
+ let distance = 0;
189
+ const subvectorDim = this.codebook.subvectorDim;
190
+ for (let s = 0; s < this.config.numSubvectors; s++) {
191
+ const code = compressed.codes[s];
192
+ const centroidOffset = s * this.config.numCentroids;
193
+ const centroid = this.codebook.centroids[centroidOffset + code];
194
+ const startDim = s * subvectorDim;
195
+ const querySubvector = query.slice(startDim, startDim + subvectorDim);
196
+ distance += this.squaredDistance(querySubvector, centroid);
197
+ }
198
+ return Math.sqrt(distance);
199
+ }
200
+ /**
201
+ * Batch compression for multiple vectors
202
+ */
203
+ batchCompress(vectors) {
204
+ return vectors.map((v) => this.compress(v));
205
+ }
206
+ /**
207
+ * Get memory savings
208
+ */
209
+ getCompressionRatio() {
210
+ const originalBytes = this.config.dimension * 4;
211
+ const compressedBytes = this.config.numSubvectors + 4;
212
+ return originalBytes / compressedBytes;
213
+ }
214
+ /**
215
+ * Export codebook for persistence
216
+ */
217
+ exportCodebook() {
218
+ if (!this.codebook) {
219
+ throw new Error("No codebook to export");
220
+ }
221
+ return JSON.stringify({
222
+ config: this.config,
223
+ codebook: {
224
+ subvectorDim: this.codebook.subvectorDim,
225
+ numSubvectors: this.codebook.numSubvectors,
226
+ numCentroids: this.codebook.numCentroids,
227
+ centroids: this.codebook.centroids.map((c) => Array.from(c))
228
+ }
229
+ });
230
+ }
231
+ /**
232
+ * Import codebook
233
+ */
234
+ importCodebook(json) {
235
+ const data = JSON.parse(json);
236
+ this.config = data.config;
237
+ this.codebook = {
238
+ subvectorDim: data.codebook.subvectorDim,
239
+ numSubvectors: data.codebook.numSubvectors,
240
+ numCentroids: data.codebook.numCentroids,
241
+ centroids: data.codebook.centroids.map((c) => new Float32Array(c))
242
+ };
243
+ this.trained = true;
244
+ }
245
+ /**
246
+ * Utility: Squared Euclidean distance
247
+ */
248
+ squaredDistance(a, b) {
249
+ let sum = 0;
250
+ for (let i = 0; i < a.length; i++) {
251
+ const diff = a[i] - b[i];
252
+ sum += diff * diff;
253
+ }
254
+ return sum;
255
+ }
256
+ /**
257
+ * Get statistics
258
+ */
259
+ getStats() {
260
+ const compressionRatio = this.getCompressionRatio();
261
+ const memoryPerVector = this.config.numSubvectors + 4;
262
+ const codebookSize = this.codebook ? this.config.numSubvectors * this.config.numCentroids * (this.config.dimension / this.config.numSubvectors) * 4 : 0;
263
+ return {
264
+ trained: this.trained,
265
+ compressionRatio,
266
+ memoryPerVector,
267
+ codebookSize
268
+ };
269
+ }
270
+ };
271
+ function createPQ8(dimension) {
272
+ return new ProductQuantization({
273
+ dimension,
274
+ numSubvectors: 8,
275
+ numCentroids: 256,
276
+ maxIterations: 50
277
+ });
278
+ }
279
+ function createPQ16(dimension) {
280
+ return new ProductQuantization({
281
+ dimension,
282
+ numSubvectors: 16,
283
+ numCentroids: 256,
284
+ maxIterations: 50
285
+ });
286
+ }
287
+ function createPQ32(dimension) {
288
+ return new ProductQuantization({
289
+ dimension,
290
+ numSubvectors: 32,
291
+ numCentroids: 256,
292
+ maxIterations: 50
293
+ });
294
+ }
295
+
296
+ // src/browser/HNSWIndex.ts
297
+ var MinHeap = class {
298
+ items = [];
299
+ push(item, priority) {
300
+ this.items.push({ item, priority });
301
+ this.bubbleUp(this.items.length - 1);
302
+ }
303
+ pop() {
304
+ if (this.items.length === 0) return void 0;
305
+ const result = this.items[0].item;
306
+ const last = this.items.pop();
307
+ if (this.items.length > 0) {
308
+ this.items[0] = last;
309
+ this.bubbleDown(0);
310
+ }
311
+ return result;
312
+ }
313
+ peek() {
314
+ var _a;
315
+ return (_a = this.items[0]) == null ? void 0 : _a.item;
316
+ }
317
+ size() {
318
+ return this.items.length;
319
+ }
320
+ bubbleUp(index) {
321
+ while (index > 0) {
322
+ const parentIndex = Math.floor((index - 1) / 2);
323
+ if (this.items[index].priority >= this.items[parentIndex].priority) break;
324
+ [this.items[index], this.items[parentIndex]] = [this.items[parentIndex], this.items[index]];
325
+ index = parentIndex;
326
+ }
327
+ }
328
+ bubbleDown(index) {
329
+ while (true) {
330
+ const leftChild = 2 * index + 1;
331
+ const rightChild = 2 * index + 2;
332
+ let smallest = index;
333
+ if (leftChild < this.items.length && this.items[leftChild].priority < this.items[smallest].priority) {
334
+ smallest = leftChild;
335
+ }
336
+ if (rightChild < this.items.length && this.items[rightChild].priority < this.items[smallest].priority) {
337
+ smallest = rightChild;
338
+ }
339
+ if (smallest === index) break;
340
+ [this.items[index], this.items[smallest]] = [this.items[smallest], this.items[index]];
341
+ index = smallest;
342
+ }
343
+ }
344
+ };
345
+ var HNSWIndex = class {
346
+ config;
347
+ nodes = /* @__PURE__ */ new Map();
348
+ entryPoint = null;
349
+ currentId = 0;
350
+ ml;
351
+ constructor(config = {}) {
352
+ this.config = {
353
+ dimension: config.dimension || 384,
354
+ M: config.M || 16,
355
+ efConstruction: config.efConstruction || 200,
356
+ efSearch: config.efSearch || 50,
357
+ ml: config.ml || 1 / Math.log(2),
358
+ maxLayers: config.maxLayers || 16,
359
+ distanceFunction: config.distanceFunction || "cosine"
360
+ };
361
+ this.ml = this.config.ml;
362
+ }
363
+ /**
364
+ * Add vector to index
365
+ */
366
+ add(vector, id) {
367
+ const nodeId = id !== void 0 ? id : this.currentId++;
368
+ const level = this.randomLevel();
369
+ const node = {
370
+ id: nodeId,
371
+ vector,
372
+ level,
373
+ connections: /* @__PURE__ */ new Map()
374
+ };
375
+ for (let l = 0; l <= level; l++) {
376
+ node.connections.set(l, []);
377
+ }
378
+ if (this.entryPoint === null) {
379
+ this.entryPoint = nodeId;
380
+ this.nodes.set(nodeId, node);
381
+ return nodeId;
382
+ }
383
+ const ep = this.entryPoint;
384
+ let nearest = ep;
385
+ for (let lc = this.nodes.get(ep).level; lc > level; lc--) {
386
+ nearest = this.searchLayer(vector, nearest, 1, lc)[0];
387
+ }
388
+ for (let lc = Math.min(level, this.nodes.get(ep).level); lc >= 0; lc--) {
389
+ const candidates = this.searchLayer(vector, nearest, this.config.efConstruction, lc);
390
+ const M = lc === 0 ? this.config.M * 2 : this.config.M;
391
+ const neighbors = this.selectNeighbors(vector, candidates, M);
392
+ for (const neighbor of neighbors) {
393
+ this.connect(nodeId, neighbor, lc);
394
+ this.connect(neighbor, nodeId, lc);
395
+ const neighborNode = this.nodes.get(neighbor);
396
+ const neighborConnections = neighborNode.connections.get(lc);
397
+ if (neighborConnections.length > M) {
398
+ const newNeighbors = this.selectNeighbors(
399
+ neighborNode.vector,
400
+ neighborConnections,
401
+ M
402
+ );
403
+ neighborNode.connections.set(lc, newNeighbors);
404
+ }
405
+ }
406
+ nearest = candidates[0];
407
+ }
408
+ if (level > this.nodes.get(this.entryPoint).level) {
409
+ this.entryPoint = nodeId;
410
+ }
411
+ this.nodes.set(nodeId, node);
412
+ return nodeId;
413
+ }
414
+ /**
415
+ * Search for k nearest neighbors
416
+ */
417
+ search(query, k, ef) {
418
+ if (this.entryPoint === null) return [];
419
+ ef = ef || Math.max(this.config.efSearch, k);
420
+ let ep = this.entryPoint;
421
+ let nearest = ep;
422
+ for (let lc = this.nodes.get(ep).level; lc > 0; lc--) {
423
+ nearest = this.searchLayer(query, nearest, 1, lc)[0];
424
+ }
425
+ const candidates = this.searchLayer(query, nearest, ef, 0);
426
+ return candidates.slice(0, k).map((id) => ({
427
+ id,
428
+ distance: this.distance(query, this.nodes.get(id).vector),
429
+ vector: this.nodes.get(id).vector
430
+ }));
431
+ }
432
+ /**
433
+ * Search at specific layer
434
+ */
435
+ searchLayer(query, ep, ef, layer) {
436
+ const visited = /* @__PURE__ */ new Set();
437
+ const candidates = new MinHeap();
438
+ const w = new MinHeap();
439
+ const dist = this.distance(query, this.nodes.get(ep).vector);
440
+ candidates.push(ep, dist);
441
+ w.push(ep, -dist);
442
+ visited.add(ep);
443
+ while (candidates.size() > 0) {
444
+ const c = candidates.pop();
445
+ const fDist = -w.peek();
446
+ const cDist = this.distance(query, this.nodes.get(c).vector);
447
+ if (cDist > fDist) break;
448
+ const neighbors = this.nodes.get(c).connections.get(layer) || [];
449
+ for (const e of neighbors) {
450
+ if (visited.has(e)) continue;
451
+ visited.add(e);
452
+ const eDist = this.distance(query, this.nodes.get(e).vector);
453
+ const fDist2 = -w.peek();
454
+ if (eDist < fDist2 || w.size() < ef) {
455
+ candidates.push(e, eDist);
456
+ w.push(e, -eDist);
457
+ if (w.size() > ef) {
458
+ w.pop();
459
+ }
460
+ }
461
+ }
462
+ }
463
+ const result = [];
464
+ while (w.size() > 0) {
465
+ result.unshift(w.pop());
466
+ }
467
+ return result;
468
+ }
469
+ /**
470
+ * Select best neighbors using heuristic
471
+ */
472
+ selectNeighbors(base, candidates, M) {
473
+ if (candidates.length <= M) return candidates;
474
+ const sorted = candidates.map((id) => ({
475
+ id,
476
+ distance: this.distance(base, this.nodes.get(id).vector)
477
+ })).sort((a, b) => a.distance - b.distance);
478
+ return sorted.slice(0, M).map((x) => x.id);
479
+ }
480
+ /**
481
+ * Connect two nodes at layer
482
+ */
483
+ connect(from, to, layer) {
484
+ const node = this.nodes.get(from);
485
+ const connections = node.connections.get(layer);
486
+ if (!connections.includes(to)) {
487
+ connections.push(to);
488
+ }
489
+ }
490
+ /**
491
+ * Random level assignment
492
+ */
493
+ randomLevel() {
494
+ let level = 0;
495
+ while (Math.random() < this.ml && level < this.config.maxLayers - 1) {
496
+ level++;
497
+ }
498
+ return level;
499
+ }
500
+ /**
501
+ * Distance function
502
+ */
503
+ distance(a, b) {
504
+ switch (this.config.distanceFunction) {
505
+ case "cosine":
506
+ return 1 - this.cosineSimilarity(a, b);
507
+ case "euclidean":
508
+ return this.euclideanDistance(a, b);
509
+ case "manhattan":
510
+ return this.manhattanDistance(a, b);
511
+ default:
512
+ return 1 - this.cosineSimilarity(a, b);
513
+ }
514
+ }
515
+ cosineSimilarity(a, b) {
516
+ let dotProduct = 0;
517
+ let normA = 0;
518
+ let normB = 0;
519
+ for (let i = 0; i < a.length; i++) {
520
+ dotProduct += a[i] * b[i];
521
+ normA += a[i] * a[i];
522
+ normB += b[i] * b[i];
523
+ }
524
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
525
+ }
526
+ euclideanDistance(a, b) {
527
+ let sum = 0;
528
+ for (let i = 0; i < a.length; i++) {
529
+ const diff = a[i] - b[i];
530
+ sum += diff * diff;
531
+ }
532
+ return Math.sqrt(sum);
533
+ }
534
+ manhattanDistance(a, b) {
535
+ let sum = 0;
536
+ for (let i = 0; i < a.length; i++) {
537
+ sum += Math.abs(a[i] - b[i]);
538
+ }
539
+ return sum;
540
+ }
541
+ /**
542
+ * Get index statistics
543
+ */
544
+ getStats() {
545
+ if (this.nodes.size === 0) {
546
+ return {
547
+ numNodes: 0,
548
+ numLayers: 0,
549
+ avgConnections: 0,
550
+ entryPointLevel: 0,
551
+ memoryBytes: 0
552
+ };
553
+ }
554
+ const maxLevel = Math.max(...Array.from(this.nodes.values()).map((n) => n.level));
555
+ let totalConnections = 0;
556
+ for (const node of this.nodes.values()) {
557
+ for (const connections of node.connections.values()) {
558
+ totalConnections += connections.length;
559
+ }
560
+ }
561
+ const avgConnections = totalConnections / this.nodes.size;
562
+ const vectorBytes = this.config.dimension * 4;
563
+ const connectionBytes = avgConnections * 4;
564
+ const metadataBytes = 100;
565
+ const memoryBytes = this.nodes.size * (vectorBytes + connectionBytes + metadataBytes);
566
+ return {
567
+ numNodes: this.nodes.size,
568
+ numLayers: maxLevel + 1,
569
+ avgConnections,
570
+ entryPointLevel: this.entryPoint ? this.nodes.get(this.entryPoint).level : 0,
571
+ memoryBytes
572
+ };
573
+ }
574
+ /**
575
+ * Export index for persistence
576
+ */
577
+ export() {
578
+ const data = {
579
+ config: this.config,
580
+ entryPoint: this.entryPoint,
581
+ currentId: this.currentId,
582
+ nodes: Array.from(this.nodes.entries()).map(([id, node]) => ({
583
+ id,
584
+ vector: Array.from(node.vector),
585
+ level: node.level,
586
+ connections: Array.from(node.connections.entries())
587
+ }))
588
+ };
589
+ return JSON.stringify(data);
590
+ }
591
+ /**
592
+ * Import index from JSON
593
+ */
594
+ import(json) {
595
+ const data = JSON.parse(json);
596
+ this.config = data.config;
597
+ this.entryPoint = data.entryPoint;
598
+ this.currentId = data.currentId;
599
+ this.nodes.clear();
600
+ for (const nodeData of data.nodes) {
601
+ const node = {
602
+ id: nodeData.id,
603
+ vector: new Float32Array(nodeData.vector),
604
+ level: nodeData.level,
605
+ connections: new Map(nodeData.connections)
606
+ };
607
+ this.nodes.set(nodeData.id, node);
608
+ }
609
+ }
610
+ /**
611
+ * Clear index
612
+ */
613
+ clear() {
614
+ this.nodes.clear();
615
+ this.entryPoint = null;
616
+ this.currentId = 0;
617
+ }
618
+ /**
619
+ * Get number of nodes
620
+ */
621
+ size() {
622
+ return this.nodes.size;
623
+ }
624
+ };
625
+ function createHNSW(dimension) {
626
+ return new HNSWIndex({
627
+ dimension,
628
+ M: 16,
629
+ efConstruction: 200,
630
+ efSearch: 50
631
+ });
632
+ }
633
+ function createFastHNSW(dimension) {
634
+ return new HNSWIndex({
635
+ dimension,
636
+ M: 8,
637
+ efConstruction: 100,
638
+ efSearch: 30
639
+ });
640
+ }
641
+ function createAccurateHNSW(dimension) {
642
+ return new HNSWIndex({
643
+ dimension,
644
+ M: 32,
645
+ efConstruction: 400,
646
+ efSearch: 100
647
+ });
648
+ }
649
+
650
+ // src/browser/AdvancedFeatures.ts
651
+ var GraphNeuralNetwork = class {
652
+ config;
653
+ nodes = /* @__PURE__ */ new Map();
654
+ edges = [];
655
+ attentionWeights = /* @__PURE__ */ new Map();
656
+ constructor(config = {}) {
657
+ this.config = {
658
+ hiddenDim: config.hiddenDim || 64,
659
+ numHeads: config.numHeads || 4,
660
+ dropout: config.dropout || 0.1,
661
+ learningRate: config.learningRate || 0.01,
662
+ attentionType: config.attentionType || "gat"
663
+ };
664
+ }
665
+ /**
666
+ * Add node to graph
667
+ */
668
+ addNode(id, features) {
669
+ this.nodes.set(id, {
670
+ id,
671
+ features,
672
+ neighbors: []
673
+ });
674
+ }
675
+ /**
676
+ * Add edge to graph
677
+ */
678
+ addEdge(from, to, weight = 1) {
679
+ this.edges.push({ from, to, weight });
680
+ const fromNode = this.nodes.get(from);
681
+ const toNode = this.nodes.get(to);
682
+ if (fromNode && !fromNode.neighbors.includes(to)) {
683
+ fromNode.neighbors.push(to);
684
+ }
685
+ if (toNode && !toNode.neighbors.includes(from)) {
686
+ toNode.neighbors.push(from);
687
+ }
688
+ }
689
+ /**
690
+ * Graph Attention Network (GAT) message passing
691
+ */
692
+ graphAttention(nodeId) {
693
+ const node = this.nodes.get(nodeId);
694
+ if (!node) throw new Error(`Node ${nodeId} not found`);
695
+ const neighbors = node.neighbors;
696
+ if (neighbors.length === 0) {
697
+ return node.features;
698
+ }
699
+ const headDim = Math.floor(this.config.hiddenDim / this.config.numHeads);
700
+ const aggregated = new Float32Array(this.config.hiddenDim);
701
+ for (let h = 0; h < this.config.numHeads; h++) {
702
+ let attentionSum = 0;
703
+ const headOutput = new Float32Array(headDim);
704
+ for (const neighborId of neighbors) {
705
+ const neighbor = this.nodes.get(neighborId);
706
+ const score = this.computeAttentionScore(
707
+ node.features,
708
+ neighbor.features,
709
+ h
710
+ );
711
+ attentionSum += score;
712
+ for (let i = 0; i < headDim && i < neighbor.features.length; i++) {
713
+ headOutput[i] += score * neighbor.features[i];
714
+ }
715
+ }
716
+ if (attentionSum > 0) {
717
+ for (let i = 0; i < headDim; i++) {
718
+ headOutput[i] /= attentionSum;
719
+ }
720
+ }
721
+ const offset = h * headDim;
722
+ for (let i = 0; i < headDim; i++) {
723
+ aggregated[offset + i] = headOutput[i];
724
+ }
725
+ }
726
+ for (let i = 0; i < aggregated.length; i++) {
727
+ aggregated[i] = aggregated[i] > 0 ? aggregated[i] : 0.01 * aggregated[i];
728
+ }
729
+ return aggregated;
730
+ }
731
+ /**
732
+ * Compute attention score between two nodes
733
+ */
734
+ computeAttentionScore(features1, features2, head) {
735
+ let score = 0;
736
+ const len = Math.min(features1.length, features2.length);
737
+ for (let i = 0; i < len; i++) {
738
+ score += features1[i] * features2[i];
739
+ }
740
+ return Math.exp(score / Math.sqrt(len));
741
+ }
742
+ /**
743
+ * Message passing for all nodes
744
+ */
745
+ messagePass() {
746
+ const newFeatures = /* @__PURE__ */ new Map();
747
+ for (const [nodeId] of this.nodes) {
748
+ newFeatures.set(nodeId, this.graphAttention(nodeId));
749
+ }
750
+ return newFeatures;
751
+ }
752
+ /**
753
+ * Update node features after message passing
754
+ */
755
+ update(newFeatures) {
756
+ for (const [nodeId, features] of newFeatures) {
757
+ const node = this.nodes.get(nodeId);
758
+ if (node) {
759
+ node.features = features;
760
+ }
761
+ }
762
+ }
763
+ /**
764
+ * Compute graph embeddings for query enhancement
765
+ */
766
+ computeGraphEmbedding(nodeId, hops = 2) {
767
+ const features = /* @__PURE__ */ new Map();
768
+ features.set(nodeId, this.nodes.get(nodeId).features);
769
+ for (let h = 0; h < hops; h++) {
770
+ const newFeatures = this.messagePass();
771
+ this.update(newFeatures);
772
+ }
773
+ return this.nodes.get(nodeId).features;
774
+ }
775
+ /**
776
+ * Get statistics
777
+ */
778
+ getStats() {
779
+ return {
780
+ numNodes: this.nodes.size,
781
+ numEdges: this.edges.length,
782
+ avgDegree: this.edges.length / Math.max(this.nodes.size, 1),
783
+ config: this.config
784
+ };
785
+ }
786
+ };
787
+ var MaximalMarginalRelevance = class {
788
+ config;
789
+ constructor(config = {}) {
790
+ this.config = {
791
+ lambda: config.lambda || 0.7,
792
+ metric: config.metric || "cosine"
793
+ };
794
+ }
795
+ /**
796
+ * Rerank results for diversity
797
+ * @param query Query vector
798
+ * @param candidates Candidate vectors with scores
799
+ * @param k Number of results to return
800
+ * @returns Reranked indices
801
+ */
802
+ rerank(query, candidates, k) {
803
+ if (candidates.length === 0) return [];
804
+ const selected = [];
805
+ const remaining = new Set(candidates.map((_, i) => i));
806
+ let bestIdx = 0;
807
+ let bestScore = -Infinity;
808
+ for (let i = 0; i < candidates.length; i++) {
809
+ if (candidates[i].score > bestScore) {
810
+ bestScore = candidates[i].score;
811
+ bestIdx = i;
812
+ }
813
+ }
814
+ selected.push(candidates[bestIdx].id);
815
+ remaining.delete(bestIdx);
816
+ while (selected.length < k && remaining.size > 0) {
817
+ let bestMMR = -Infinity;
818
+ let bestCandidate = -1;
819
+ for (const idx of remaining) {
820
+ const candidate = candidates[idx];
821
+ const relevance = this.similarity(query, candidate.vector);
822
+ let maxSimilarity = -Infinity;
823
+ for (const selectedId of selected) {
824
+ const selectedCandidate = candidates.find((c) => c.id === selectedId);
825
+ const sim = this.similarity(candidate.vector, selectedCandidate.vector);
826
+ maxSimilarity = Math.max(maxSimilarity, sim);
827
+ }
828
+ const mmr = this.config.lambda * relevance - (1 - this.config.lambda) * maxSimilarity;
829
+ if (mmr > bestMMR) {
830
+ bestMMR = mmr;
831
+ bestCandidate = idx;
832
+ }
833
+ }
834
+ if (bestCandidate !== -1) {
835
+ selected.push(candidates[bestCandidate].id);
836
+ remaining.delete(bestCandidate);
837
+ } else {
838
+ break;
839
+ }
840
+ }
841
+ return selected;
842
+ }
843
+ /**
844
+ * Similarity computation
845
+ */
846
+ similarity(a, b) {
847
+ if (this.config.metric === "cosine") {
848
+ return this.cosineSimilarity(a, b);
849
+ } else {
850
+ const dist = this.euclideanDistance(a, b);
851
+ return 1 / (1 + dist);
852
+ }
853
+ }
854
+ cosineSimilarity(a, b) {
855
+ let dotProduct = 0;
856
+ let normA = 0;
857
+ let normB = 0;
858
+ for (let i = 0; i < a.length; i++) {
859
+ dotProduct += a[i] * b[i];
860
+ normA += a[i] * a[i];
861
+ normB += b[i] * b[i];
862
+ }
863
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
864
+ }
865
+ euclideanDistance(a, b) {
866
+ let sum = 0;
867
+ for (let i = 0; i < a.length; i++) {
868
+ const diff = a[i] - b[i];
869
+ sum += diff * diff;
870
+ }
871
+ return Math.sqrt(sum);
872
+ }
873
+ /**
874
+ * Set lambda (relevance vs diversity trade-off)
875
+ */
876
+ setLambda(lambda) {
877
+ this.config.lambda = Math.max(0, Math.min(1, lambda));
878
+ }
879
+ };
880
+ var TensorCompression = class {
881
+ /**
882
+ * Reduce dimensionality using truncated SVD
883
+ * @param vectors Array of vectors to compress
884
+ * @param targetDim Target dimension
885
+ * @returns Compressed vectors
886
+ */
887
+ static compress(vectors, targetDim) {
888
+ if (vectors.length === 0) return [];
889
+ const originalDim = vectors[0].length;
890
+ if (targetDim >= originalDim) return vectors;
891
+ const matrix = vectors.map((v) => Array.from(v));
892
+ const mean = this.computeMean(matrix);
893
+ const centered = matrix.map(
894
+ (row) => row.map((val, i) => val - mean[i])
895
+ );
896
+ const cov = this.computeCovariance(centered);
897
+ const eigenvectors = this.powerIteration(cov, targetDim);
898
+ const compressed = centered.map((row) => {
899
+ const projected = new Float32Array(targetDim);
900
+ for (let i = 0; i < targetDim; i++) {
901
+ let sum = 0;
902
+ for (let j = 0; j < originalDim; j++) {
903
+ sum += row[j] * eigenvectors[i][j];
904
+ }
905
+ projected[i] = sum;
906
+ }
907
+ return projected;
908
+ });
909
+ return compressed;
910
+ }
911
+ /**
912
+ * Compute mean vector
913
+ */
914
+ static computeMean(matrix) {
915
+ const n = matrix.length;
916
+ const dim = matrix[0].length;
917
+ const mean = new Array(dim).fill(0);
918
+ for (const row of matrix) {
919
+ for (let i = 0; i < dim; i++) {
920
+ mean[i] += row[i];
921
+ }
922
+ }
923
+ return mean.map((v) => v / n);
924
+ }
925
+ /**
926
+ * Compute covariance matrix
927
+ */
928
+ static computeCovariance(matrix) {
929
+ const n = matrix.length;
930
+ const dim = matrix[0].length;
931
+ const cov = Array.from(
932
+ { length: dim },
933
+ () => new Array(dim).fill(0)
934
+ );
935
+ for (let i = 0; i < dim; i++) {
936
+ for (let j = 0; j <= i; j++) {
937
+ let sum = 0;
938
+ for (const row of matrix) {
939
+ sum += row[i] * row[j];
940
+ }
941
+ cov[i][j] = cov[j][i] = sum / n;
942
+ }
943
+ }
944
+ return cov;
945
+ }
946
+ /**
947
+ * Power iteration for computing top eigenvectors
948
+ */
949
+ static powerIteration(matrix, k, iterations = 100) {
950
+ const dim = matrix.length;
951
+ const eigenvectors = [];
952
+ for (let i = 0; i < k; i++) {
953
+ let v = new Array(dim).fill(0).map(() => Math.random() - 0.5);
954
+ for (let iter = 0; iter < iterations; iter++) {
955
+ const newV = new Array(dim).fill(0);
956
+ for (let r = 0; r < dim; r++) {
957
+ for (let c = 0; c < dim; c++) {
958
+ newV[r] += matrix[r][c] * v[c];
959
+ }
960
+ }
961
+ for (const prev of eigenvectors) {
962
+ let dot = 0;
963
+ for (let j = 0; j < dim; j++) {
964
+ dot += newV[j] * prev[j];
965
+ }
966
+ for (let j = 0; j < dim; j++) {
967
+ newV[j] -= dot * prev[j];
968
+ }
969
+ }
970
+ let norm = 0;
971
+ for (const val of newV) {
972
+ norm += val * val;
973
+ }
974
+ norm = Math.sqrt(norm);
975
+ if (norm < 1e-10) break;
976
+ v = newV.map((val) => val / norm);
977
+ }
978
+ eigenvectors.push(v);
979
+ }
980
+ return eigenvectors;
981
+ }
982
+ };
983
+ var BatchProcessor = class {
984
+ /**
985
+ * Batch cosine similarity computation
986
+ */
987
+ static batchCosineSimilarity(query, vectors) {
988
+ const similarities = new Float32Array(vectors.length);
989
+ let queryNorm = 0;
990
+ for (let i = 0; i < query.length; i++) {
991
+ queryNorm += query[i] * query[i];
992
+ }
993
+ queryNorm = Math.sqrt(queryNorm);
994
+ for (let v = 0; v < vectors.length; v++) {
995
+ const vector = vectors[v];
996
+ let dotProduct = 0;
997
+ let vectorNorm = 0;
998
+ for (let i = 0; i < query.length; i++) {
999
+ dotProduct += query[i] * vector[i];
1000
+ vectorNorm += vector[i] * vector[i];
1001
+ }
1002
+ vectorNorm = Math.sqrt(vectorNorm);
1003
+ similarities[v] = dotProduct / (queryNorm * vectorNorm);
1004
+ }
1005
+ return similarities;
1006
+ }
1007
+ /**
1008
+ * Batch vector normalization
1009
+ */
1010
+ static batchNormalize(vectors) {
1011
+ return vectors.map((v) => {
1012
+ let norm = 0;
1013
+ for (let i = 0; i < v.length; i++) {
1014
+ norm += v[i] * v[i];
1015
+ }
1016
+ norm = Math.sqrt(norm);
1017
+ const normalized = new Float32Array(v.length);
1018
+ for (let i = 0; i < v.length; i++) {
1019
+ normalized[i] = v[i] / norm;
1020
+ }
1021
+ return normalized;
1022
+ });
1023
+ }
1024
+ };
1025
+
1026
+ // src/browser/AttentionBrowser.ts
1027
+ var AttentionBrowser = class {
1028
+ wasmModule = null;
1029
+ loadingState = "idle";
1030
+ loadError = null;
1031
+ config;
1032
+ constructor(config = {}) {
1033
+ this.config = {
1034
+ dimension: 384,
1035
+ numHeads: 4,
1036
+ blockSize: 64,
1037
+ curvature: -1,
1038
+ useWASM: true,
1039
+ ...config
1040
+ };
1041
+ }
1042
+ /**
1043
+ * Get current loading state
1044
+ */
1045
+ getLoadingState() {
1046
+ return this.loadingState;
1047
+ }
1048
+ /**
1049
+ * Get loading error if any
1050
+ */
1051
+ getError() {
1052
+ return this.loadError;
1053
+ }
1054
+ /**
1055
+ * Initialize WASM module (lazy loaded)
1056
+ */
1057
+ async initialize() {
1058
+ if (this.loadingState === "loaded") return;
1059
+ if (this.loadingState === "loading") {
1060
+ while (this.loadingState === "loading") {
1061
+ await new Promise((resolve) => setTimeout(resolve, 50));
1062
+ }
1063
+ return;
1064
+ }
1065
+ this.loadingState = "loading";
1066
+ try {
1067
+ if (!this.config.useWASM) {
1068
+ this.loadingState = "loaded";
1069
+ return;
1070
+ }
1071
+ const wasmLoader = await import("../../dist/agentdb.wasm-loader.js");
1072
+ this.wasmModule = await wasmLoader.initWASM();
1073
+ this.loadingState = "loaded";
1074
+ } catch (error) {
1075
+ this.loadError = error instanceof Error ? error : new Error(String(error));
1076
+ this.loadingState = "error";
1077
+ console.warn("WASM initialization failed, using fallback:", this.loadError.message);
1078
+ }
1079
+ }
1080
+ /**
1081
+ * Flash Attention - Optimized attention mechanism
1082
+ * O(N) memory complexity instead of O(N²)
1083
+ *
1084
+ * @param query - Query vectors
1085
+ * @param keys - Key vectors
1086
+ * @param values - Value vectors
1087
+ * @returns Attention output
1088
+ */
1089
+ async flashAttention(query, keys, values) {
1090
+ var _a;
1091
+ await this.initialize();
1092
+ if ((_a = this.wasmModule) == null ? void 0 : _a.flashAttention) {
1093
+ try {
1094
+ return this.wasmModule.flashAttention(query, keys, values, this.config);
1095
+ } catch (error) {
1096
+ console.warn("WASM flash attention failed, using fallback:", error);
1097
+ }
1098
+ }
1099
+ return this.flashAttentionFallback(query, keys, values);
1100
+ }
1101
+ /**
1102
+ * Hyperbolic Attention - Attention in hyperbolic space
1103
+ * Better for hierarchical relationships
1104
+ *
1105
+ * @param query - Query vector
1106
+ * @param keys - Key vectors
1107
+ * @returns Similarity scores in hyperbolic space
1108
+ */
1109
+ async hyperbolicAttention(query, keys) {
1110
+ var _a;
1111
+ await this.initialize();
1112
+ if ((_a = this.wasmModule) == null ? void 0 : _a.hyperbolicAttention) {
1113
+ try {
1114
+ return this.wasmModule.hyperbolicAttention(query, keys, this.config);
1115
+ } catch (error) {
1116
+ console.warn("WASM hyperbolic attention failed, using fallback:", error);
1117
+ }
1118
+ }
1119
+ return this.hyperbolicAttentionFallback(query, keys);
1120
+ }
1121
+ /**
1122
+ * Memory Consolidation - Cluster and consolidate similar memories
1123
+ *
1124
+ * @param memories - Array of memory vectors
1125
+ * @param config - Consolidation configuration
1126
+ * @returns Consolidated memory clusters
1127
+ */
1128
+ async consolidateMemories(memories, config = {}) {
1129
+ var _a;
1130
+ await this.initialize();
1131
+ const fullConfig = {
1132
+ threshold: 0.8,
1133
+ maxClusters: 10,
1134
+ minClusterSize: 1,
1135
+ ...config
1136
+ };
1137
+ if ((_a = this.wasmModule) == null ? void 0 : _a.memoryConsolidation) {
1138
+ try {
1139
+ return this.wasmModule.memoryConsolidation(memories, fullConfig);
1140
+ } catch (error) {
1141
+ console.warn("WASM memory consolidation failed, using fallback:", error);
1142
+ }
1143
+ }
1144
+ return this.consolidateMemoriesFallback(memories, fullConfig);
1145
+ }
1146
+ /**
1147
+ * Clean up WASM memory
1148
+ */
1149
+ dispose() {
1150
+ this.wasmModule = null;
1151
+ this.loadingState = "idle";
1152
+ this.loadError = null;
1153
+ }
1154
+ // ========================================================================
1155
+ // Fallback Implementations (Pure JavaScript)
1156
+ // ========================================================================
1157
+ flashAttentionFallback(query, keys, values) {
1158
+ const { dimension = 384 } = this.config;
1159
+ const seqLen = keys.length / dimension;
1160
+ const output = new Float32Array(query.length);
1161
+ for (let i = 0; i < query.length; i += dimension) {
1162
+ const q = query.slice(i, i + dimension);
1163
+ let sumWeights = 0;
1164
+ const weights = new Float32Array(seqLen);
1165
+ for (let j = 0; j < seqLen; j++) {
1166
+ const k = keys.slice(j * dimension, (j + 1) * dimension);
1167
+ let dot = 0;
1168
+ for (let d = 0; d < dimension; d++) {
1169
+ dot += q[d] * k[d];
1170
+ }
1171
+ weights[j] = Math.exp(dot / Math.sqrt(dimension));
1172
+ sumWeights += weights[j];
1173
+ }
1174
+ for (let j = 0; j < seqLen; j++) {
1175
+ weights[j] /= sumWeights || 1;
1176
+ const v = values.slice(j * dimension, (j + 1) * dimension);
1177
+ for (let d = 0; d < dimension; d++) {
1178
+ output[i + d] += weights[j] * v[d];
1179
+ }
1180
+ }
1181
+ }
1182
+ return output;
1183
+ }
1184
+ hyperbolicAttentionFallback(query, keys) {
1185
+ const { curvature = -1 } = this.config;
1186
+ const k = Math.abs(curvature);
1187
+ const similarities = new Float32Array(keys.length / query.length);
1188
+ for (let i = 0; i < similarities.length; i++) {
1189
+ const offset = i * query.length;
1190
+ let dotProduct = 0;
1191
+ let normQ = 0;
1192
+ let normK = 0;
1193
+ for (let j = 0; j < query.length; j++) {
1194
+ dotProduct += query[j] * keys[offset + j];
1195
+ normQ += query[j] * query[j];
1196
+ normK += keys[offset + j] * keys[offset + j];
1197
+ }
1198
+ const euclidean = Math.sqrt(normQ + normK - 2 * dotProduct);
1199
+ const poincare = Math.acosh(1 + 2 * k * euclidean * euclidean);
1200
+ similarities[i] = 1 / (1 + poincare);
1201
+ }
1202
+ return similarities;
1203
+ }
1204
+ consolidateMemoriesFallback(memories, config) {
1205
+ const { threshold = 0.8, maxClusters = 10, minClusterSize = 1 } = config;
1206
+ const consolidated = [];
1207
+ const used = /* @__PURE__ */ new Set();
1208
+ for (let i = 0; i < memories.length; i++) {
1209
+ if (used.has(i)) continue;
1210
+ const cluster = [memories[i]];
1211
+ used.add(i);
1212
+ for (let j = i + 1; j < memories.length; j++) {
1213
+ if (used.has(j)) continue;
1214
+ const similarity = this.cosineSimilarity(memories[i], memories[j]);
1215
+ if (similarity > threshold) {
1216
+ cluster.push(memories[j]);
1217
+ used.add(j);
1218
+ }
1219
+ }
1220
+ if (cluster.length >= minClusterSize) {
1221
+ const centroid = new Float32Array(memories[i].length);
1222
+ for (const mem of cluster) {
1223
+ for (let k = 0; k < centroid.length; k++) {
1224
+ centroid[k] += mem[k] / cluster.length;
1225
+ }
1226
+ }
1227
+ let norm = 0;
1228
+ for (let k = 0; k < centroid.length; k++) {
1229
+ norm += centroid[k] * centroid[k];
1230
+ }
1231
+ norm = Math.sqrt(norm);
1232
+ if (norm > 0) {
1233
+ for (let k = 0; k < centroid.length; k++) {
1234
+ centroid[k] /= norm;
1235
+ }
1236
+ }
1237
+ consolidated.push({
1238
+ memory: centroid,
1239
+ count: cluster.length,
1240
+ members: cluster
1241
+ });
1242
+ }
1243
+ if (consolidated.length >= maxClusters) break;
1244
+ }
1245
+ return consolidated;
1246
+ }
1247
+ cosineSimilarity(a, b) {
1248
+ let dot = 0;
1249
+ let normA = 0;
1250
+ let normB = 0;
1251
+ for (let i = 0; i < a.length; i++) {
1252
+ dot += a[i] * b[i];
1253
+ normA += a[i] * a[i];
1254
+ normB += b[i] * b[i];
1255
+ }
1256
+ const denominator = Math.sqrt(normA * normB);
1257
+ return denominator > 0 ? dot / denominator : 0;
1258
+ }
1259
+ };
1260
+ function createAttention(config) {
1261
+ return new AttentionBrowser(config);
1262
+ }
1263
+ function createFastAttention() {
1264
+ return new AttentionBrowser({
1265
+ dimension: 256,
1266
+ numHeads: 2,
1267
+ blockSize: 32,
1268
+ useWASM: true
1269
+ });
1270
+ }
1271
+ function createAccurateAttention() {
1272
+ return new AttentionBrowser({
1273
+ dimension: 768,
1274
+ numHeads: 8,
1275
+ blockSize: 128,
1276
+ useWASM: true
1277
+ });
1278
+ }
1279
+
1280
+ // src/browser/index.ts
1281
+ function detectFeatures() {
1282
+ return {
1283
+ indexedDB: "indexedDB" in globalThis,
1284
+ broadcastChannel: "BroadcastChannel" in globalThis,
1285
+ webWorkers: typeof globalThis.Worker !== "undefined",
1286
+ wasmSIMD: detectWasmSIMD(),
1287
+ sharedArrayBuffer: typeof SharedArrayBuffer !== "undefined"
1288
+ };
1289
+ }
1290
+ async function detectWasmSIMD() {
1291
+ try {
1292
+ if (typeof globalThis.WebAssembly === "undefined") {
1293
+ return false;
1294
+ }
1295
+ const simdTest = new Uint8Array([
1296
+ 0,
1297
+ 97,
1298
+ 115,
1299
+ 109,
1300
+ 1,
1301
+ 0,
1302
+ 0,
1303
+ 0,
1304
+ 1,
1305
+ 5,
1306
+ 1,
1307
+ 96,
1308
+ 0,
1309
+ 1,
1310
+ 123,
1311
+ 3,
1312
+ 2,
1313
+ 1,
1314
+ 0,
1315
+ 10,
1316
+ 10,
1317
+ 1,
1318
+ 8,
1319
+ 0,
1320
+ 253,
1321
+ 12,
1322
+ 253,
1323
+ 12,
1324
+ 253,
1325
+ 84,
1326
+ 11
1327
+ ]);
1328
+ const WA = globalThis.WebAssembly;
1329
+ const module = await WA.instantiate(simdTest);
1330
+ return module instanceof WA.Instance;
1331
+ } catch {
1332
+ return false;
1333
+ }
1334
+ }
1335
+ var SMALL_DATASET_CONFIG = {
1336
+ pq: { enabled: false },
1337
+ hnsw: { enabled: false },
1338
+ gnn: { enabled: true, numHeads: 2 },
1339
+ mmr: { enabled: true, lambda: 0.7 },
1340
+ svd: { enabled: false }
1341
+ };
1342
+ var MEDIUM_DATASET_CONFIG = {
1343
+ pq: { enabled: true, subvectors: 8 },
1344
+ hnsw: { enabled: true, M: 16 },
1345
+ gnn: { enabled: true, numHeads: 4 },
1346
+ mmr: { enabled: true, lambda: 0.7 },
1347
+ svd: { enabled: false }
1348
+ };
1349
+ var LARGE_DATASET_CONFIG = {
1350
+ pq: { enabled: true, subvectors: 16 },
1351
+ hnsw: { enabled: true, M: 32 },
1352
+ gnn: { enabled: true, numHeads: 4 },
1353
+ mmr: { enabled: true, lambda: 0.7 },
1354
+ svd: { enabled: true, targetDim: 128 }
1355
+ };
1356
+ var MEMORY_OPTIMIZED_CONFIG = {
1357
+ pq: { enabled: true, subvectors: 32 },
1358
+ // 16x compression
1359
+ hnsw: { enabled: true, M: 8 },
1360
+ // Fewer connections
1361
+ gnn: { enabled: false },
1362
+ mmr: { enabled: false },
1363
+ svd: { enabled: true, targetDim: 64 }
1364
+ // Aggressive dimension reduction
1365
+ };
1366
+ var SPEED_OPTIMIZED_CONFIG = {
1367
+ pq: { enabled: false },
1368
+ // No compression overhead
1369
+ hnsw: { enabled: true, M: 32, efSearch: 100 },
1370
+ // Maximum HNSW quality
1371
+ gnn: { enabled: false },
1372
+ mmr: { enabled: false },
1373
+ svd: { enabled: false }
1374
+ };
1375
+ var QUALITY_OPTIMIZED_CONFIG = {
1376
+ pq: { enabled: false },
1377
+ // No compression
1378
+ hnsw: { enabled: true, M: 48, efConstruction: 400 },
1379
+ // Highest quality
1380
+ gnn: { enabled: true, numHeads: 8 },
1381
+ // More attention heads
1382
+ mmr: { enabled: true, lambda: 0.8 },
1383
+ // More diversity
1384
+ svd: { enabled: false }
1385
+ // No dimension loss
1386
+ };
1387
+ var VERSION = {
1388
+ major: 2,
1389
+ minor: 0,
1390
+ patch: 0,
1391
+ prerelease: "alpha.2",
1392
+ features: "advanced",
1393
+ full: "2.0.0-alpha.2+advanced"
1394
+ };
1395
+ function estimateMemoryUsage(numVectors, dimension, config) {
1396
+ var _a, _b, _c;
1397
+ let vectorBytes = numVectors * dimension * 4;
1398
+ if ((_a = config.pq) == null ? void 0 : _a.enabled) {
1399
+ const subvectors = config.pq.subvectors || 8;
1400
+ vectorBytes = numVectors * (subvectors + 4);
1401
+ }
1402
+ if ((_b = config.svd) == null ? void 0 : _b.enabled) {
1403
+ const targetDim = config.svd.targetDim || dimension / 2;
1404
+ vectorBytes = numVectors * targetDim * 4;
1405
+ }
1406
+ let indexBytes = 0;
1407
+ if ((_c = config.hnsw) == null ? void 0 : _c.enabled) {
1408
+ const M = config.hnsw.M || 16;
1409
+ const avgConnections = M * 1.5;
1410
+ indexBytes = numVectors * avgConnections * 4;
1411
+ }
1412
+ const total = vectorBytes + indexBytes;
1413
+ return {
1414
+ vectors: vectorBytes,
1415
+ index: indexBytes,
1416
+ total,
1417
+ totalMB: total / (1024 * 1024)
1418
+ };
1419
+ }
1420
+ function recommendConfig(numVectors, dimension) {
1421
+ if (numVectors < 1e3) {
1422
+ return {
1423
+ name: "SMALL_DATASET",
1424
+ config: SMALL_DATASET_CONFIG,
1425
+ reason: "Small dataset, linear search is fast enough"
1426
+ };
1427
+ } else if (numVectors < 1e4) {
1428
+ return {
1429
+ name: "MEDIUM_DATASET",
1430
+ config: MEDIUM_DATASET_CONFIG,
1431
+ reason: "Medium dataset, HNSW + PQ8 recommended"
1432
+ };
1433
+ } else {
1434
+ return {
1435
+ name: "LARGE_DATASET",
1436
+ config: LARGE_DATASET_CONFIG,
1437
+ reason: "Large dataset, aggressive compression + HNSW recommended"
1438
+ };
1439
+ }
1440
+ }
1441
+ async function benchmarkSearch(searchFn, numQueries = 100, k = 10, dimension = 384) {
1442
+ const times = [];
1443
+ for (let i = 0; i < numQueries; i++) {
1444
+ const query = new Float32Array(dimension);
1445
+ for (let d = 0; d < dimension; d++) {
1446
+ query[d] = Math.random() - 0.5;
1447
+ }
1448
+ const start = performance.now();
1449
+ searchFn(query, k);
1450
+ const end = performance.now();
1451
+ times.push(end - start);
1452
+ }
1453
+ times.sort((a, b) => a - b);
1454
+ return {
1455
+ avgTimeMs: times.reduce((a, b) => a + b, 0) / times.length,
1456
+ minTimeMs: times[0],
1457
+ maxTimeMs: times[times.length - 1],
1458
+ p50Ms: times[Math.floor(times.length * 0.5)],
1459
+ p95Ms: times[Math.floor(times.length * 0.95)],
1460
+ p99Ms: times[Math.floor(times.length * 0.99)]
1461
+ };
1462
+ }
1463
+ export {
1464
+ AttentionBrowser,
1465
+ BatchProcessor,
1466
+ GraphNeuralNetwork,
1467
+ HNSWIndex,
1468
+ LARGE_DATASET_CONFIG,
1469
+ MEDIUM_DATASET_CONFIG,
1470
+ MEMORY_OPTIMIZED_CONFIG,
1471
+ MaximalMarginalRelevance,
1472
+ ProductQuantization,
1473
+ QUALITY_OPTIMIZED_CONFIG,
1474
+ SMALL_DATASET_CONFIG,
1475
+ SPEED_OPTIMIZED_CONFIG,
1476
+ TensorCompression,
1477
+ VERSION,
1478
+ benchmarkSearch,
1479
+ createAccurateAttention,
1480
+ createAccurateHNSW,
1481
+ createAttention,
1482
+ createFastAttention,
1483
+ createFastHNSW,
1484
+ createHNSW,
1485
+ createPQ16,
1486
+ createPQ32,
1487
+ createPQ8,
1488
+ detectFeatures,
1489
+ estimateMemoryUsage,
1490
+ recommendConfig
1491
+ };
1492
+ //# sourceMappingURL=agentdb.browser.js.map