@sparkleideas/plugins 3.0.0-alpha.10

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.
Files changed (80) hide show
  1. package/README.md +401 -0
  2. package/__tests__/collection-manager.test.ts +332 -0
  3. package/__tests__/dependency-graph.test.ts +434 -0
  4. package/__tests__/enhanced-plugin-registry.test.ts +488 -0
  5. package/__tests__/plugin-registry.test.ts +368 -0
  6. package/__tests__/ruvector-bridge.test.ts +2429 -0
  7. package/__tests__/ruvector-integration.test.ts +1602 -0
  8. package/__tests__/ruvector-migrations.test.ts +1099 -0
  9. package/__tests__/ruvector-quantization.test.ts +846 -0
  10. package/__tests__/ruvector-streaming.test.ts +1088 -0
  11. package/__tests__/sdk.test.ts +325 -0
  12. package/__tests__/security.test.ts +348 -0
  13. package/__tests__/utils/ruvector-test-utils.ts +860 -0
  14. package/examples/plugin-creator/index.ts +636 -0
  15. package/examples/plugin-creator/plugin-creator.test.ts +312 -0
  16. package/examples/ruvector/README.md +288 -0
  17. package/examples/ruvector/attention-patterns.ts +394 -0
  18. package/examples/ruvector/basic-usage.ts +288 -0
  19. package/examples/ruvector/docker-compose.yml +75 -0
  20. package/examples/ruvector/gnn-analysis.ts +501 -0
  21. package/examples/ruvector/hyperbolic-hierarchies.ts +557 -0
  22. package/examples/ruvector/init-db.sql +119 -0
  23. package/examples/ruvector/quantization.ts +680 -0
  24. package/examples/ruvector/self-learning.ts +447 -0
  25. package/examples/ruvector/semantic-search.ts +576 -0
  26. package/examples/ruvector/streaming-large-data.ts +507 -0
  27. package/examples/ruvector/transactions.ts +594 -0
  28. package/examples/ruvector-plugins/hook-pattern-library.ts +486 -0
  29. package/examples/ruvector-plugins/index.ts +79 -0
  30. package/examples/ruvector-plugins/intent-router.ts +354 -0
  31. package/examples/ruvector-plugins/mcp-tool-optimizer.ts +424 -0
  32. package/examples/ruvector-plugins/reasoning-bank.ts +657 -0
  33. package/examples/ruvector-plugins/ruvector-plugins.test.ts +518 -0
  34. package/examples/ruvector-plugins/semantic-code-search.ts +498 -0
  35. package/examples/ruvector-plugins/shared/index.ts +20 -0
  36. package/examples/ruvector-plugins/shared/vector-utils.ts +257 -0
  37. package/examples/ruvector-plugins/sona-learning.ts +445 -0
  38. package/package.json +97 -0
  39. package/src/collections/collection-manager.ts +661 -0
  40. package/src/collections/index.ts +56 -0
  41. package/src/collections/official/index.ts +1040 -0
  42. package/src/core/base-plugin.ts +416 -0
  43. package/src/core/plugin-interface.ts +215 -0
  44. package/src/hooks/index.ts +685 -0
  45. package/src/index.ts +378 -0
  46. package/src/integrations/agentic-flow.ts +743 -0
  47. package/src/integrations/index.ts +88 -0
  48. package/src/integrations/ruvector/ARCHITECTURE.md +1245 -0
  49. package/src/integrations/ruvector/attention-advanced.ts +1040 -0
  50. package/src/integrations/ruvector/attention-executor.ts +782 -0
  51. package/src/integrations/ruvector/attention-mechanisms.ts +757 -0
  52. package/src/integrations/ruvector/attention.ts +1063 -0
  53. package/src/integrations/ruvector/gnn.ts +3050 -0
  54. package/src/integrations/ruvector/hyperbolic.ts +1948 -0
  55. package/src/integrations/ruvector/index.ts +394 -0
  56. package/src/integrations/ruvector/migrations/001_create_extension.sql +135 -0
  57. package/src/integrations/ruvector/migrations/002_create_vector_tables.sql +259 -0
  58. package/src/integrations/ruvector/migrations/003_create_indices.sql +328 -0
  59. package/src/integrations/ruvector/migrations/004_create_functions.sql +598 -0
  60. package/src/integrations/ruvector/migrations/005_create_attention_functions.sql +654 -0
  61. package/src/integrations/ruvector/migrations/006_create_gnn_functions.sql +728 -0
  62. package/src/integrations/ruvector/migrations/007_create_hyperbolic_functions.sql +762 -0
  63. package/src/integrations/ruvector/migrations/index.ts +35 -0
  64. package/src/integrations/ruvector/migrations/migrations.ts +647 -0
  65. package/src/integrations/ruvector/quantization.ts +2036 -0
  66. package/src/integrations/ruvector/ruvector-bridge.ts +2000 -0
  67. package/src/integrations/ruvector/self-learning.ts +2376 -0
  68. package/src/integrations/ruvector/streaming.ts +1737 -0
  69. package/src/integrations/ruvector/types.ts +1945 -0
  70. package/src/providers/index.ts +643 -0
  71. package/src/registry/dependency-graph.ts +568 -0
  72. package/src/registry/enhanced-plugin-registry.ts +994 -0
  73. package/src/registry/plugin-registry.ts +604 -0
  74. package/src/sdk/index.ts +563 -0
  75. package/src/security/index.ts +594 -0
  76. package/src/types/index.ts +446 -0
  77. package/src/workers/index.ts +700 -0
  78. package/tmp.json +0 -0
  79. package/tsconfig.json +25 -0
  80. package/vitest.config.ts +23 -0
@@ -0,0 +1,1040 @@
1
+ /**
2
+ * RuVector PostgreSQL Bridge - Advanced Attention Mechanisms
3
+ *
4
+ * Part 3: Graph, Temporal, Multimodal, Retrieval, and Specialized attention.
5
+ *
6
+ * @module @sparkleideas/plugins/integrations/ruvector/attention-advanced
7
+ */
8
+
9
+ import type {
10
+ AttentionMechanism,
11
+ AttentionInput,
12
+ } from './types.js';
13
+
14
+ import {
15
+ BaseAttentionMechanism,
16
+ type AttentionCategory,
17
+ } from './attention.js';
18
+
19
+ // ============================================================================
20
+ // Graph Attention Implementations
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Graph Attention (GAT-style).
25
+ */
26
+ export class GraphAttention extends BaseAttentionMechanism {
27
+ readonly type: AttentionMechanism = 'graph_attention';
28
+ readonly name = 'Graph Attention';
29
+ readonly description = 'Graph attention network for structured data';
30
+ readonly category: AttentionCategory = 'graph';
31
+
32
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
33
+ const scale = this.getScale();
34
+ const negativeSlope = 0.2; // LeakyReLU
35
+
36
+ // Compute attention coefficients with LeakyReLU
37
+ const scores = keys.map(k => {
38
+ const combined = [...query, ...k];
39
+ const attention = combined.reduce((sum, v) => sum + v, 0) / combined.length;
40
+ return attention > 0 ? attention / scale : negativeSlope * attention / scale;
41
+ });
42
+
43
+ const weights = this.softmax(scores);
44
+ return this.weightedSum(values, weights);
45
+ }
46
+
47
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
48
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
49
+ }
50
+
51
+ toSQL(input: AttentionInput): string {
52
+ const q = this.formatMatrix(input.query);
53
+ const k = this.formatMatrix(input.key);
54
+ const v = this.formatMatrix(input.value);
55
+ return `SELECT ruvector.graph_attention(${q}, ${k}, ${v}, ${this.config.numHeads}, 0.2)`;
56
+ }
57
+
58
+ private softmax(x: number[]): number[] {
59
+ const max = Math.max(...x);
60
+ const exp = x.map(v => Math.exp(v - max));
61
+ const sum = exp.reduce((a, b) => a + b, 0);
62
+ return exp.map(v => v / sum);
63
+ }
64
+
65
+ private weightedSum(values: number[][], weights: number[]): number[] {
66
+ const dim = values[0].length;
67
+ const result = new Array(dim).fill(0);
68
+ for (let i = 0; i < values.length; i++) {
69
+ for (let j = 0; j < dim; j++) {
70
+ result[j] += weights[i] * values[i][j];
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Hyperbolic Attention for hierarchical structures.
79
+ */
80
+ export class HyperbolicAttention extends BaseAttentionMechanism {
81
+ readonly type: AttentionMechanism = 'hyperbolic_attention';
82
+ readonly name = 'Hyperbolic Attention';
83
+ readonly description = 'Attention in hyperbolic space for hierarchical data';
84
+ readonly category: AttentionCategory = 'graph';
85
+
86
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
87
+ const curvature = this.config.params?.curvature ?? -1.0;
88
+ const scale = this.getScale();
89
+
90
+ // Compute hyperbolic distances
91
+ const scores = keys.map(k => {
92
+ const dist = this.poincareDistance(query, k, curvature);
93
+ return -dist / scale; // Negative distance as score
94
+ });
95
+
96
+ const weights = this.softmax(scores);
97
+ return this.weightedSum(values, weights);
98
+ }
99
+
100
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
101
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
102
+ }
103
+
104
+ toSQL(input: AttentionInput): string {
105
+ const q = this.formatMatrix(input.query);
106
+ const k = this.formatMatrix(input.key);
107
+ const v = this.formatMatrix(input.value);
108
+ const curvature = this.config.params?.curvature ?? -1.0;
109
+ return `SELECT ruvector.hyperbolic_attention(${q}, ${k}, ${v}, ${curvature}, ${this.getScale()})`;
110
+ }
111
+
112
+ private poincareDistance(u: number[], v: number[], c: number): number {
113
+ const normU = Math.sqrt(u.reduce((s, x) => s + x * x, 0));
114
+ const normV = Math.sqrt(v.reduce((s, x) => s + x * x, 0));
115
+ const diff = u.map((x, i) => x - v[i]);
116
+ const normDiff = Math.sqrt(diff.reduce((s, x) => s + x * x, 0));
117
+
118
+ const sqrtC = Math.sqrt(Math.abs(c));
119
+ const num = 2 * normDiff * normDiff;
120
+ const denom = (1 - normU * normU) * (1 - normV * normV);
121
+
122
+ return (1 / sqrtC) * Math.acosh(1 + num / Math.max(denom, 1e-6));
123
+ }
124
+
125
+ private softmax(x: number[]): number[] {
126
+ const max = Math.max(...x);
127
+ const exp = x.map(v => Math.exp(v - max));
128
+ const sum = exp.reduce((a, b) => a + b, 0);
129
+ return exp.map(v => v / sum);
130
+ }
131
+
132
+ private weightedSum(values: number[][], weights: number[]): number[] {
133
+ const dim = values[0].length;
134
+ const result = new Array(dim).fill(0);
135
+ for (let i = 0; i < values.length; i++) {
136
+ for (let j = 0; j < dim; j++) {
137
+ result[j] += weights[i] * values[i][j];
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Spherical Attention.
146
+ */
147
+ export class SphericalAttention extends BaseAttentionMechanism {
148
+ readonly type: AttentionMechanism = 'spherical_attention';
149
+ readonly name = 'Spherical Attention';
150
+ readonly description = 'Attention on the unit sphere using geodesic distances';
151
+ readonly category: AttentionCategory = 'graph';
152
+
153
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
154
+ const scale = this.getScale();
155
+
156
+ // Normalize to unit sphere
157
+ const normQuery = this.normalize(query);
158
+ const normKeys = keys.map(k => this.normalize(k));
159
+
160
+ // Geodesic distances on sphere
161
+ const scores = normKeys.map(k => {
162
+ const dot = this.dotProduct(normQuery, k);
163
+ const angle = Math.acos(Math.max(-1, Math.min(1, dot)));
164
+ return -angle / scale;
165
+ });
166
+
167
+ const weights = this.softmax(scores);
168
+ return this.weightedSum(values, weights);
169
+ }
170
+
171
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
172
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
173
+ }
174
+
175
+ toSQL(input: AttentionInput): string {
176
+ const q = this.formatMatrix(input.query);
177
+ const k = this.formatMatrix(input.key);
178
+ const v = this.formatMatrix(input.value);
179
+ return `SELECT ruvector.spherical_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
180
+ }
181
+
182
+ private normalize(v: number[]): number[] {
183
+ const norm = Math.sqrt(v.reduce((s, x) => s + x * x, 0));
184
+ return v.map(x => x / (norm + 1e-6));
185
+ }
186
+
187
+ private dotProduct(a: number[], b: number[]): number {
188
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
189
+ }
190
+
191
+ private softmax(x: number[]): number[] {
192
+ const max = Math.max(...x);
193
+ const exp = x.map(v => Math.exp(v - max));
194
+ const sum = exp.reduce((a, b) => a + b, 0);
195
+ return exp.map(v => v / sum);
196
+ }
197
+
198
+ private weightedSum(values: number[][], weights: number[]): number[] {
199
+ const dim = values[0].length;
200
+ const result = new Array(dim).fill(0);
201
+ for (let i = 0; i < values.length; i++) {
202
+ for (let j = 0; j < dim; j++) {
203
+ result[j] += weights[i] * values[i][j];
204
+ }
205
+ }
206
+ return result;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Toroidal Attention for periodic data.
212
+ */
213
+ export class ToroidalAttention extends BaseAttentionMechanism {
214
+ readonly type: AttentionMechanism = 'toroidal_attention';
215
+ readonly name = 'Toroidal Attention';
216
+ readonly description = 'Attention on torus manifold for periodic structures';
217
+ readonly category: AttentionCategory = 'graph';
218
+
219
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
220
+ const scale = this.getScale();
221
+
222
+ // Toroidal distance (periodic in each dimension)
223
+ const scores = keys.map(k => {
224
+ const dist = this.toroidalDistance(query, k);
225
+ return -dist / scale;
226
+ });
227
+
228
+ const weights = this.softmax(scores);
229
+ return this.weightedSum(values, weights);
230
+ }
231
+
232
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
233
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
234
+ }
235
+
236
+ toSQL(input: AttentionInput): string {
237
+ const q = this.formatMatrix(input.query);
238
+ const k = this.formatMatrix(input.key);
239
+ const v = this.formatMatrix(input.value);
240
+ return `SELECT ruvector.toroidal_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
241
+ }
242
+
243
+ private toroidalDistance(a: number[], b: number[]): number {
244
+ let dist = 0;
245
+ for (let i = 0; i < a.length; i++) {
246
+ const diff = Math.abs(a[i] - b[i]);
247
+ const periodic = Math.min(diff, 2 * Math.PI - diff);
248
+ dist += periodic * periodic;
249
+ }
250
+ return Math.sqrt(dist);
251
+ }
252
+
253
+ private softmax(x: number[]): number[] {
254
+ const max = Math.max(...x);
255
+ const exp = x.map(v => Math.exp(v - max));
256
+ const sum = exp.reduce((a, b) => a + b, 0);
257
+ return exp.map(v => v / sum);
258
+ }
259
+
260
+ private weightedSum(values: number[][], weights: number[]): number[] {
261
+ const dim = values[0].length;
262
+ const result = new Array(dim).fill(0);
263
+ for (let i = 0; i < values.length; i++) {
264
+ for (let j = 0; j < dim; j++) {
265
+ result[j] += weights[i] * values[i][j];
266
+ }
267
+ }
268
+ return result;
269
+ }
270
+ }
271
+
272
+ // ============================================================================
273
+ // Temporal Attention Implementations
274
+ // ============================================================================
275
+
276
+ /**
277
+ * Temporal Attention for time-series data.
278
+ */
279
+ export class TemporalAttention extends BaseAttentionMechanism {
280
+ readonly type: AttentionMechanism = 'temporal_attention';
281
+ readonly name = 'Temporal Attention';
282
+ readonly description = 'Time-aware attention with temporal decay';
283
+ readonly category: AttentionCategory = 'temporal';
284
+
285
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
286
+ const scale = this.getScale();
287
+ const decayRate = 0.1;
288
+ const queryIdx = keys.length - 1;
289
+
290
+ const scores = keys.map((k, i) => {
291
+ const timeDiff = queryIdx - i;
292
+ const decay = Math.exp(-decayRate * timeDiff);
293
+ return this.dotProduct(query, k) / scale * decay;
294
+ });
295
+
296
+ const weights = this.softmax(scores);
297
+ return this.weightedSum(values, weights);
298
+ }
299
+
300
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
301
+ return Promise.all(queries.map((q, idx) => {
302
+ const scale = this.getScale();
303
+ const decayRate = 0.1;
304
+
305
+ const scores = keys.map((k, i) => {
306
+ const timeDiff = idx - i;
307
+ const decay = Math.exp(-decayRate * Math.abs(timeDiff));
308
+ return this.dotProduct(q, k) / scale * decay;
309
+ });
310
+
311
+ const weights = this.softmax(scores);
312
+ return this.weightedSum(values, weights);
313
+ }));
314
+ }
315
+
316
+ toSQL(input: AttentionInput): string {
317
+ const q = this.formatMatrix(input.query);
318
+ const k = this.formatMatrix(input.key);
319
+ const v = this.formatMatrix(input.value);
320
+ return `SELECT ruvector.temporal_attention(${q}, ${k}, ${v}, 0.1, ${this.getScale()})`;
321
+ }
322
+
323
+ private dotProduct(a: number[], b: number[]): number {
324
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
325
+ }
326
+
327
+ private softmax(x: number[]): number[] {
328
+ const max = Math.max(...x);
329
+ const exp = x.map(v => Math.exp(v - max));
330
+ const sum = exp.reduce((a, b) => a + b, 0);
331
+ return exp.map(v => v / sum);
332
+ }
333
+
334
+ private weightedSum(values: number[][], weights: number[]): number[] {
335
+ const dim = values[0].length;
336
+ const result = new Array(dim).fill(0);
337
+ for (let i = 0; i < values.length; i++) {
338
+ for (let j = 0; j < dim; j++) {
339
+ result[j] += weights[i] * values[i][j];
340
+ }
341
+ }
342
+ return result;
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Recurrent Attention (LSTM-style gating).
348
+ */
349
+ export class RecurrentAttention extends BaseAttentionMechanism {
350
+ readonly type: AttentionMechanism = 'recurrent_attention';
351
+ readonly name = 'Recurrent Attention';
352
+ readonly description = 'LSTM-style gated attention for sequential processing';
353
+ readonly category: AttentionCategory = 'temporal';
354
+
355
+ private hiddenState: number[] | null = null;
356
+
357
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
358
+ const scale = this.getScale();
359
+ const dim = values[0].length;
360
+
361
+ // Initialize hidden state if needed
362
+ if (!this.hiddenState || this.hiddenState.length !== dim) {
363
+ this.hiddenState = new Array(dim).fill(0);
364
+ }
365
+
366
+ // Compute attention with gating
367
+ const scores = keys.map(k => this.dotProduct(query, k) / scale);
368
+ const weights = this.softmax(scores);
369
+ const context = this.weightedSum(values, weights);
370
+
371
+ // LSTM-style gating
372
+ const gate = this.sigmoid(context.map((c, i) => c + this.hiddenState![i]));
373
+ const output = context.map((c, i) => gate[i] * c + (1 - gate[i]) * this.hiddenState![i]);
374
+
375
+ // Update hidden state
376
+ this.hiddenState = output;
377
+
378
+ return output;
379
+ }
380
+
381
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
382
+ const results: number[][] = [];
383
+ for (const q of queries) {
384
+ results.push(await this.compute(q, keys, values));
385
+ }
386
+ return results;
387
+ }
388
+
389
+ toSQL(input: AttentionInput): string {
390
+ const q = this.formatMatrix(input.query);
391
+ const k = this.formatMatrix(input.key);
392
+ const v = this.formatMatrix(input.value);
393
+ return `SELECT ruvector.recurrent_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
394
+ }
395
+
396
+ private dotProduct(a: number[], b: number[]): number {
397
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
398
+ }
399
+
400
+ private softmax(x: number[]): number[] {
401
+ const max = Math.max(...x);
402
+ const exp = x.map(v => Math.exp(v - max));
403
+ const sum = exp.reduce((a, b) => a + b, 0);
404
+ return exp.map(v => v / sum);
405
+ }
406
+
407
+ private sigmoid(x: number[]): number[] {
408
+ return x.map(v => 1 / (1 + Math.exp(-v)));
409
+ }
410
+
411
+ private weightedSum(values: number[][], weights: number[]): number[] {
412
+ const dim = values[0].length;
413
+ const result = new Array(dim).fill(0);
414
+ for (let i = 0; i < values.length; i++) {
415
+ for (let j = 0; j < dim; j++) {
416
+ result[j] += weights[i] * values[i][j];
417
+ }
418
+ }
419
+ return result;
420
+ }
421
+ }
422
+
423
+ /**
424
+ * State Space Model Attention (S4/Mamba-style).
425
+ */
426
+ export class StateSpaceAttention extends BaseAttentionMechanism {
427
+ readonly type: AttentionMechanism = 'state_space';
428
+ readonly name = 'State Space Attention';
429
+ readonly description = 'State space model attention for efficient sequence modeling';
430
+ readonly category: AttentionCategory = 'temporal';
431
+
432
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
433
+ const scale = this.getScale();
434
+ const dim = values[0].length;
435
+
436
+ // Simplified SSM: compute via convolution-like operation
437
+ const state = new Array(dim).fill(0);
438
+ const deltaT = 1.0 / keys.length;
439
+
440
+ for (let i = 0; i < keys.length; i++) {
441
+ const score = this.dotProduct(query, keys[i]) / scale;
442
+ const weight = Math.exp(-deltaT * (keys.length - i - 1)) * score;
443
+
444
+ for (let d = 0; d < dim; d++) {
445
+ state[d] += weight * values[i][d];
446
+ }
447
+ }
448
+
449
+ // Normalize
450
+ const norm = Math.sqrt(state.reduce((s, v) => s + v * v, 0)) + 1e-6;
451
+ return state.map(v => v / norm);
452
+ }
453
+
454
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
455
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
456
+ }
457
+
458
+ toSQL(input: AttentionInput): string {
459
+ const q = this.formatMatrix(input.query);
460
+ const k = this.formatMatrix(input.key);
461
+ const v = this.formatMatrix(input.value);
462
+ return `SELECT ruvector.state_space_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
463
+ }
464
+
465
+ private dotProduct(a: number[], b: number[]): number {
466
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
467
+ }
468
+ }
469
+
470
+ // ============================================================================
471
+ // Multimodal Attention Implementations
472
+ // ============================================================================
473
+
474
+ /**
475
+ * Cross-Modal Attention.
476
+ */
477
+ export class CrossModalAttention extends BaseAttentionMechanism {
478
+ readonly type: AttentionMechanism = 'cross_modal';
479
+ readonly name = 'Cross-Modal Attention';
480
+ readonly description = 'Attention across different modalities (text, image, audio)';
481
+ readonly category: AttentionCategory = 'multimodal';
482
+
483
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
484
+ const scale = this.getScale();
485
+ const scores = keys.map(k => this.dotProduct(query, k) / scale);
486
+ const weights = this.softmax(scores);
487
+ return this.weightedSum(values, weights);
488
+ }
489
+
490
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
491
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
492
+ }
493
+
494
+ toSQL(input: AttentionInput): string {
495
+ const q = this.formatMatrix(input.query);
496
+ const k = this.formatMatrix(input.key);
497
+ const v = this.formatMatrix(input.value);
498
+ return `SELECT ruvector.cross_modal_attention(${q}, ${k}, ${v}, ${this.config.numHeads}, ${this.getScale()})`;
499
+ }
500
+
501
+ private dotProduct(a: number[], b: number[]): number {
502
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
503
+ }
504
+
505
+ private softmax(x: number[]): number[] {
506
+ const max = Math.max(...x);
507
+ const exp = x.map(v => Math.exp(v - max));
508
+ const sum = exp.reduce((a, b) => a + b, 0);
509
+ return exp.map(v => v / sum);
510
+ }
511
+
512
+ private weightedSum(values: number[][], weights: number[]): number[] {
513
+ const dim = values[0].length;
514
+ const result = new Array(dim).fill(0);
515
+ for (let i = 0; i < values.length; i++) {
516
+ for (let j = 0; j < dim; j++) {
517
+ result[j] += weights[i] * values[i][j];
518
+ }
519
+ }
520
+ return result;
521
+ }
522
+ }
523
+
524
+ /**
525
+ * Perceiver IO Attention.
526
+ */
527
+ export class PerceiverAttention extends BaseAttentionMechanism {
528
+ readonly type: AttentionMechanism = 'perceiver';
529
+ readonly name = 'Perceiver Attention';
530
+ readonly description = 'Perceiver IO style attention with latent array';
531
+ readonly category: AttentionCategory = 'multimodal';
532
+
533
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
534
+ const scale = this.getScale();
535
+ const scores = keys.map(k => this.dotProduct(query, k) / scale);
536
+ const weights = this.softmax(scores);
537
+ return this.weightedSum(values, weights);
538
+ }
539
+
540
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
541
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
542
+ }
543
+
544
+ toSQL(input: AttentionInput): string {
545
+ const q = this.formatMatrix(input.query);
546
+ const k = this.formatMatrix(input.key);
547
+ const v = this.formatMatrix(input.value);
548
+ return `SELECT ruvector.perceiver_attention(${q}, ${k}, ${v}, ${this.config.numHeads}, ${this.getScale()})`;
549
+ }
550
+
551
+ private dotProduct(a: number[], b: number[]): number {
552
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
553
+ }
554
+
555
+ private softmax(x: number[]): number[] {
556
+ const max = Math.max(...x);
557
+ const exp = x.map(v => Math.exp(v - max));
558
+ const sum = exp.reduce((a, b) => a + b, 0);
559
+ return exp.map(v => v / sum);
560
+ }
561
+
562
+ private weightedSum(values: number[][], weights: number[]): number[] {
563
+ const dim = values[0].length;
564
+ const result = new Array(dim).fill(0);
565
+ for (let i = 0; i < values.length; i++) {
566
+ for (let j = 0; j < dim; j++) {
567
+ result[j] += weights[i] * values[i][j];
568
+ }
569
+ }
570
+ return result;
571
+ }
572
+ }
573
+
574
+ /**
575
+ * Flamingo-style Attention.
576
+ */
577
+ export class FlamingoAttention extends BaseAttentionMechanism {
578
+ readonly type: AttentionMechanism = 'flamingo';
579
+ readonly name = 'Flamingo Attention';
580
+ readonly description = 'Flamingo-style gated cross-attention for vision-language';
581
+ readonly category: AttentionCategory = 'multimodal';
582
+
583
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
584
+ const scale = this.getScale();
585
+
586
+ // Gated cross-attention
587
+ const scores = keys.map(k => this.dotProduct(query, k) / scale);
588
+ const weights = this.softmax(scores);
589
+ const context = this.weightedSum(values, weights);
590
+
591
+ // Tanh gating
592
+ const gate = Math.tanh(this.dotProduct(query, context) / query.length);
593
+ return context.map(c => gate * c);
594
+ }
595
+
596
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
597
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
598
+ }
599
+
600
+ toSQL(input: AttentionInput): string {
601
+ const q = this.formatMatrix(input.query);
602
+ const k = this.formatMatrix(input.key);
603
+ const v = this.formatMatrix(input.value);
604
+ return `SELECT ruvector.flamingo_attention(${q}, ${k}, ${v}, ${this.config.numHeads}, ${this.getScale()})`;
605
+ }
606
+
607
+ private dotProduct(a: number[], b: number[]): number {
608
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
609
+ }
610
+
611
+ private softmax(x: number[]): number[] {
612
+ const max = Math.max(...x);
613
+ const exp = x.map(v => Math.exp(v - max));
614
+ const sum = exp.reduce((a, b) => a + b, 0);
615
+ return exp.map(v => v / sum);
616
+ }
617
+
618
+ private weightedSum(values: number[][], weights: number[]): number[] {
619
+ const dim = values[0].length;
620
+ const result = new Array(dim).fill(0);
621
+ for (let i = 0; i < values.length; i++) {
622
+ for (let j = 0; j < dim; j++) {
623
+ result[j] += weights[i] * values[i][j];
624
+ }
625
+ }
626
+ return result;
627
+ }
628
+ }
629
+
630
+ // ============================================================================
631
+ // Retrieval-Augmented Attention Implementations
632
+ // ============================================================================
633
+
634
+ /**
635
+ * Retrieval-Augmented Attention.
636
+ */
637
+ export class RetrievalAttention extends BaseAttentionMechanism {
638
+ readonly type: AttentionMechanism = 'retrieval_attention';
639
+ readonly name = 'Retrieval Attention';
640
+ readonly description = 'Attention augmented with retrieved documents';
641
+ readonly category: AttentionCategory = 'retrieval';
642
+
643
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
644
+ const scale = this.getScale();
645
+ const scores = keys.map(k => this.dotProduct(query, k) / scale);
646
+ const weights = this.softmax(scores);
647
+ return this.weightedSum(values, weights);
648
+ }
649
+
650
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
651
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
652
+ }
653
+
654
+ toSQL(input: AttentionInput): string {
655
+ const q = this.formatMatrix(input.query);
656
+ const k = this.formatMatrix(input.key);
657
+ const v = this.formatMatrix(input.value);
658
+ return `SELECT ruvector.retrieval_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
659
+ }
660
+
661
+ private dotProduct(a: number[], b: number[]): number {
662
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
663
+ }
664
+
665
+ private softmax(x: number[]): number[] {
666
+ const max = Math.max(...x);
667
+ const exp = x.map(v => Math.exp(v - max));
668
+ const sum = exp.reduce((a, b) => a + b, 0);
669
+ return exp.map(v => v / sum);
670
+ }
671
+
672
+ private weightedSum(values: number[][], weights: number[]): number[] {
673
+ const dim = values[0].length;
674
+ const result = new Array(dim).fill(0);
675
+ for (let i = 0; i < values.length; i++) {
676
+ for (let j = 0; j < dim; j++) {
677
+ result[j] += weights[i] * values[i][j];
678
+ }
679
+ }
680
+ return result;
681
+ }
682
+ }
683
+
684
+ /**
685
+ * k-NN Augmented Attention.
686
+ */
687
+ export class KNNAttention extends BaseAttentionMechanism {
688
+ readonly type: AttentionMechanism = 'knn_attention';
689
+ readonly name = 'k-NN Attention';
690
+ readonly description = 'k-nearest neighbor augmented attention';
691
+ readonly category: AttentionCategory = 'retrieval';
692
+
693
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
694
+ const k = Math.min(10, keys.length);
695
+ const scale = this.getScale();
696
+
697
+ // Compute all scores
698
+ const indexedScores = keys.map((key, i) => ({
699
+ index: i,
700
+ score: this.dotProduct(query, key) / scale,
701
+ }));
702
+
703
+ // Get top-k
704
+ indexedScores.sort((a, b) => b.score - a.score);
705
+ const topK = indexedScores.slice(0, k);
706
+
707
+ // Compute weights only for top-k
708
+ const topScores = topK.map(item => item.score);
709
+ const weights = this.softmax(topScores);
710
+
711
+ // Weighted sum of top-k values
712
+ const dim = values[0].length;
713
+ const result = new Array(dim).fill(0);
714
+ for (let i = 0; i < topK.length; i++) {
715
+ const valueIdx = topK[i].index;
716
+ for (let j = 0; j < dim; j++) {
717
+ result[j] += weights[i] * values[valueIdx][j];
718
+ }
719
+ }
720
+ return result;
721
+ }
722
+
723
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
724
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
725
+ }
726
+
727
+ toSQL(input: AttentionInput): string {
728
+ const q = this.formatMatrix(input.query);
729
+ const k = this.formatMatrix(input.key);
730
+ const v = this.formatMatrix(input.value);
731
+ return `SELECT ruvector.knn_attention(${q}, ${k}, ${v}, 10, ${this.getScale()})`;
732
+ }
733
+
734
+ private dotProduct(a: number[], b: number[]): number {
735
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
736
+ }
737
+
738
+ private softmax(x: number[]): number[] {
739
+ const max = Math.max(...x);
740
+ const exp = x.map(v => Math.exp(v - max));
741
+ const sum = exp.reduce((a, b) => a + b, 0);
742
+ return exp.map(v => v / sum);
743
+ }
744
+ }
745
+
746
+ /**
747
+ * Memory-Augmented Attention.
748
+ */
749
+ export class MemoryAugmentedAttention extends BaseAttentionMechanism {
750
+ readonly type: AttentionMechanism = 'memory_augmented';
751
+ readonly name = 'Memory-Augmented Attention';
752
+ readonly description = 'Attention with external memory bank';
753
+ readonly category: AttentionCategory = 'retrieval';
754
+
755
+ private memoryBank: number[][] = [];
756
+
757
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
758
+ const scale = this.getScale();
759
+
760
+ // Combine keys with memory bank
761
+ const allKeys = [...keys, ...this.memoryBank];
762
+ const allValues = [...values, ...this.memoryBank];
763
+
764
+ const scores = allKeys.map(k => this.dotProduct(query, k) / scale);
765
+ const weights = this.softmax(scores);
766
+ return this.weightedSum(allValues, weights);
767
+ }
768
+
769
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
770
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
771
+ }
772
+
773
+ toSQL(input: AttentionInput): string {
774
+ const q = this.formatMatrix(input.query);
775
+ const k = this.formatMatrix(input.key);
776
+ const v = this.formatMatrix(input.value);
777
+ return `SELECT ruvector.memory_augmented_attention(${q}, ${k}, ${v}, ${this.getScale()})`;
778
+ }
779
+
780
+ /**
781
+ * Add vectors to memory bank.
782
+ */
783
+ addToMemory(vectors: number[][]): void {
784
+ this.memoryBank.push(...vectors);
785
+ }
786
+
787
+ /**
788
+ * Clear memory bank.
789
+ */
790
+ clearMemory(): void {
791
+ this.memoryBank = [];
792
+ }
793
+
794
+ private dotProduct(a: number[], b: number[]): number {
795
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
796
+ }
797
+
798
+ private softmax(x: number[]): number[] {
799
+ const max = Math.max(...x);
800
+ const exp = x.map(v => Math.exp(v - max));
801
+ const sum = exp.reduce((a, b) => a + b, 0);
802
+ return exp.map(v => v / sum);
803
+ }
804
+
805
+ private weightedSum(values: number[][], weights: number[]): number[] {
806
+ const dim = values[0].length;
807
+ const result = new Array(dim).fill(0);
808
+ for (let i = 0; i < values.length; i++) {
809
+ for (let j = 0; j < dim; j++) {
810
+ result[j] += weights[i] * values[i][j];
811
+ }
812
+ }
813
+ return result;
814
+ }
815
+ }
816
+
817
+ // ============================================================================
818
+ // Specialized Attention Implementations
819
+ // ============================================================================
820
+
821
+ /**
822
+ * Synthesizer Attention (learned patterns).
823
+ */
824
+ export class SynthesizerAttention extends BaseAttentionMechanism {
825
+ readonly type: AttentionMechanism = 'synthesizer';
826
+ readonly name = 'Synthesizer Attention';
827
+ readonly description = 'Attention with learned synthetic patterns';
828
+ readonly category: AttentionCategory = 'linear';
829
+
830
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
831
+ const seqLen = keys.length;
832
+ const dim = query.length;
833
+
834
+ // Dense synthesizer: learn attention from query alone
835
+ const synthetic = new Array(seqLen).fill(0).map((_, i) =>
836
+ query.reduce((sum, q, j) => sum + q * Math.sin((i + 1) * (j + 1) * 0.1), 0)
837
+ );
838
+
839
+ const weights = this.softmax(synthetic);
840
+ return this.weightedSum(values, weights);
841
+ }
842
+
843
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
844
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
845
+ }
846
+
847
+ toSQL(input: AttentionInput): string {
848
+ const q = this.formatMatrix(input.query);
849
+ const v = this.formatMatrix(input.value);
850
+ return `SELECT ruvector.synthesizer_attention(${q}, ${v}, ${input.key.length})`;
851
+ }
852
+
853
+ private softmax(x: number[]): number[] {
854
+ const max = Math.max(...x);
855
+ const exp = x.map(v => Math.exp(v - max));
856
+ const sum = exp.reduce((a, b) => a + b, 0);
857
+ return exp.map(v => v / sum);
858
+ }
859
+
860
+ private weightedSum(values: number[][], weights: number[]): number[] {
861
+ const dim = values[0].length;
862
+ const result = new Array(dim).fill(0);
863
+ for (let i = 0; i < values.length; i++) {
864
+ for (let j = 0; j < dim; j++) {
865
+ result[j] += weights[i] * values[i][j];
866
+ }
867
+ }
868
+ return result;
869
+ }
870
+ }
871
+
872
+ /**
873
+ * Routing Attention (MoE style).
874
+ */
875
+ export class RoutingAttention extends BaseAttentionMechanism {
876
+ readonly type: AttentionMechanism = 'routing';
877
+ readonly name = 'Routing Attention';
878
+ readonly description = 'Attention with routing to specialized experts';
879
+ readonly category: AttentionCategory = 'linear';
880
+
881
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
882
+ const numExperts = this.config.params?.numExperts ?? 4;
883
+ const topK = this.config.params?.topK ?? 2;
884
+ const scale = this.getScale();
885
+
886
+ // Compute expert routing scores
887
+ const routingScores = Array(numExperts).fill(0).map((_, e) =>
888
+ query.reduce((sum, q, i) => sum + q * Math.cos(e * i * 0.1), 0)
889
+ );
890
+
891
+ // Get top-k experts
892
+ const indexedScores = routingScores.map((s, i) => ({ index: i, score: s }));
893
+ indexedScores.sort((a, b) => b.score - a.score);
894
+ const topExperts = indexedScores.slice(0, topK);
895
+ const expertWeights = this.softmax(topExperts.map(e => e.score));
896
+
897
+ // Each expert processes a subset of keys
898
+ const keysPerExpert = Math.ceil(keys.length / numExperts);
899
+ const dim = values[0].length;
900
+ const result = new Array(dim).fill(0);
901
+
902
+ for (let e = 0; e < topExperts.length; e++) {
903
+ const expertIdx = topExperts[e].index;
904
+ const start = expertIdx * keysPerExpert;
905
+ const end = Math.min(start + keysPerExpert, keys.length);
906
+
907
+ if (start < keys.length) {
908
+ const expertKeys = keys.slice(start, end);
909
+ const expertValues = values.slice(start, end);
910
+
911
+ const scores = expertKeys.map(k => this.dotProduct(query, k) / scale);
912
+ const weights = this.softmax(scores);
913
+ const expertOutput = this.weightedSum(expertValues, weights);
914
+
915
+ for (let d = 0; d < dim; d++) {
916
+ result[d] += expertWeights[e] * expertOutput[d];
917
+ }
918
+ }
919
+ }
920
+
921
+ return result;
922
+ }
923
+
924
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
925
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
926
+ }
927
+
928
+ toSQL(input: AttentionInput): string {
929
+ const q = this.formatMatrix(input.query);
930
+ const k = this.formatMatrix(input.key);
931
+ const v = this.formatMatrix(input.value);
932
+ const numExperts = this.config.params?.numExperts ?? 4;
933
+ const topK = this.config.params?.topK ?? 2;
934
+ return `SELECT ruvector.routing_attention(${q}, ${k}, ${v}, ${numExperts}, ${topK}, ${this.getScale()})`;
935
+ }
936
+
937
+ private dotProduct(a: number[], b: number[]): number {
938
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
939
+ }
940
+
941
+ private softmax(x: number[]): number[] {
942
+ const max = Math.max(...x);
943
+ const exp = x.map(v => Math.exp(v - max));
944
+ const sum = exp.reduce((a, b) => a + b, 0);
945
+ return exp.map(v => v / sum);
946
+ }
947
+
948
+ private weightedSum(values: number[][], weights: number[]): number[] {
949
+ const dim = values[0].length;
950
+ const result = new Array(dim).fill(0);
951
+ for (let i = 0; i < values.length; i++) {
952
+ for (let j = 0; j < dim; j++) {
953
+ result[j] += weights[i] * values[i][j];
954
+ }
955
+ }
956
+ return result;
957
+ }
958
+ }
959
+
960
+ /**
961
+ * Mixture of Experts Attention.
962
+ */
963
+ export class MixtureOfExpertsAttention extends BaseAttentionMechanism {
964
+ readonly type: AttentionMechanism = 'mixture_of_experts';
965
+ readonly name = 'Mixture of Experts Attention';
966
+ readonly description = 'MoE attention with specialized expert networks';
967
+ readonly category: AttentionCategory = 'linear';
968
+
969
+ async compute(query: number[], keys: number[][], values: number[][]): Promise<number[]> {
970
+ const numExperts = this.config.params?.numExperts ?? 8;
971
+ const topK = this.config.params?.topK ?? 2;
972
+ const scale = this.getScale();
973
+
974
+ // Router: compute gating scores
975
+ const gatingScores = Array(numExperts).fill(0).map((_, e) => {
976
+ return query.reduce((sum, q, i) => sum + q * Math.sin(e * i * 0.05), 0);
977
+ });
978
+
979
+ // Top-k gating
980
+ const indexed = gatingScores.map((s, i) => ({ idx: i, score: s }));
981
+ indexed.sort((a, b) => b.score - a.score);
982
+ const selected = indexed.slice(0, topK);
983
+ const gateWeights = this.softmax(selected.map(s => s.score));
984
+
985
+ // Expert computation
986
+ const dim = values[0].length;
987
+ const result = new Array(dim).fill(0);
988
+
989
+ for (let k = 0; k < selected.length; k++) {
990
+ const expertIdx = selected[k].idx;
991
+ const expertScale = scale * (1 + expertIdx * 0.1);
992
+
993
+ const scores = keys.map(key => this.dotProduct(query, key) / expertScale);
994
+ const weights = this.softmax(scores);
995
+ const output = this.weightedSum(values, weights);
996
+
997
+ for (let d = 0; d < dim; d++) {
998
+ result[d] += gateWeights[k] * output[d];
999
+ }
1000
+ }
1001
+
1002
+ return result;
1003
+ }
1004
+
1005
+ async computeBatch(queries: number[][], keys: number[][], values: number[][]): Promise<number[][]> {
1006
+ return Promise.all(queries.map(q => this.compute(q, keys, values)));
1007
+ }
1008
+
1009
+ toSQL(input: AttentionInput): string {
1010
+ const q = this.formatMatrix(input.query);
1011
+ const k = this.formatMatrix(input.key);
1012
+ const v = this.formatMatrix(input.value);
1013
+ const numExperts = this.config.params?.numExperts ?? 8;
1014
+ const topK = this.config.params?.topK ?? 2;
1015
+ return `SELECT ruvector.moe_attention(${q}, ${k}, ${v}, ${numExperts}, ${topK}, ${this.getScale()})`;
1016
+ }
1017
+
1018
+ private dotProduct(a: number[], b: number[]): number {
1019
+ return a.reduce((sum, val, i) => sum + val * b[i], 0);
1020
+ }
1021
+
1022
+ private softmax(x: number[]): number[] {
1023
+ const max = Math.max(...x);
1024
+ const exp = x.map(v => Math.exp(v - max));
1025
+ const sum = exp.reduce((a, b) => a + b, 0);
1026
+ return exp.map(v => v / sum);
1027
+ }
1028
+
1029
+ private weightedSum(values: number[][], weights: number[]): number[] {
1030
+ const dim = values[0].length;
1031
+ const result = new Array(dim).fill(0);
1032
+ for (let i = 0; i < values.length; i++) {
1033
+ for (let j = 0; j < dim; j++) {
1034
+ result[j] += weights[i] * values[i][j];
1035
+ }
1036
+ }
1037
+ return result;
1038
+ }
1039
+ }
1040
+