agentic-flow 2.0.1-alpha.13 → 2.0.1-alpha.14

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,95 @@
1
+ /**
2
+ * EmbeddingService - Unified embedding interface for agentic-flow
3
+ *
4
+ * Supports two backends:
5
+ * - Simple: Hash-based, ~0.01ms, not semantic
6
+ * - ONNX: Real neural embeddings via ruvector-onnx-embeddings-wasm, ~10-50ms, semantic
7
+ *
8
+ * Configure via:
9
+ * - AGENTIC_FLOW_EMBEDDINGS=simple|onnx (default: simple)
10
+ * - AGENTIC_FLOW_EMBEDDING_MODEL=all-MiniLM-L6-v2 (default)
11
+ */
12
+ export type EmbeddingBackend = 'simple' | 'onnx' | 'onnx-native';
13
+ export interface EmbeddingStats {
14
+ backend: EmbeddingBackend;
15
+ dimension: number;
16
+ totalEmbeddings: number;
17
+ totalLatencyMs: number;
18
+ avgLatencyMs: number;
19
+ cacheHits: number;
20
+ modelLoaded: boolean;
21
+ modelName?: string;
22
+ simdAvailable?: boolean;
23
+ }
24
+ export declare class EmbeddingService {
25
+ private static instance;
26
+ private backend;
27
+ private dimension;
28
+ private modelName;
29
+ private embedder;
30
+ private wasmModule;
31
+ private loadingPromise;
32
+ private modelLoaded;
33
+ private totalEmbeddings;
34
+ private totalLatencyMs;
35
+ private cacheHits;
36
+ private cache;
37
+ private cacheEnabled;
38
+ private constructor();
39
+ static getInstance(): EmbeddingService;
40
+ /**
41
+ * Get current backend
42
+ */
43
+ getBackend(): EmbeddingBackend;
44
+ /**
45
+ * Get embedding dimension
46
+ */
47
+ getDimension(): number;
48
+ /**
49
+ * Check if ONNX model is loaded
50
+ */
51
+ isModelLoaded(): boolean;
52
+ /**
53
+ * Initialize ONNX embedder (lazy load on first use)
54
+ */
55
+ initOnnx(): Promise<void>;
56
+ private _loadOnnxModel;
57
+ /**
58
+ * Generate embedding for text
59
+ */
60
+ embed(text: string): Promise<Float32Array>;
61
+ /**
62
+ * Generate embeddings for multiple texts
63
+ */
64
+ embedBatch(texts: string[]): Promise<Float32Array[]>;
65
+ /**
66
+ * Compute similarity between two texts
67
+ */
68
+ similarity(text1: string, text2: string): Promise<number>;
69
+ /**
70
+ * Simple hash-based embedding (fast, not semantic)
71
+ */
72
+ simpleEmbed(text: string, dim?: number): Float32Array;
73
+ /**
74
+ * Compute cosine similarity between two embeddings
75
+ */
76
+ cosineSimilarity(a: Float32Array, b: Float32Array): number;
77
+ /**
78
+ * Get statistics
79
+ */
80
+ getStats(): EmbeddingStats;
81
+ /**
82
+ * Clear cache
83
+ */
84
+ clearCache(): void;
85
+ /**
86
+ * Reset instance (for testing)
87
+ */
88
+ static reset(): void;
89
+ }
90
+ export declare function getEmbeddingService(): EmbeddingService;
91
+ export declare function embed(text: string): Promise<Float32Array>;
92
+ export declare function embedBatch(texts: string[]): Promise<Float32Array[]>;
93
+ export declare function textSimilarity(text1: string, text2: string): Promise<number>;
94
+ export declare function simpleEmbed(text: string, dim?: number): Float32Array;
95
+ //# sourceMappingURL=EmbeddingService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmbeddingService.d.ts","sourceRoot":"","sources":["../../src/intelligence/EmbeddingService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiDH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAyCD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiC;IAExD,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,WAAW,CAAkB;IAGrC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,SAAS,CAAa;IAG9B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,YAAY,CAAU;IAE9B,OAAO;IAQP,MAAM,CAAC,WAAW,IAAI,gBAAgB;IAOtC;;OAEG;IACH,UAAU,IAAI,gBAAgB;IAI9B;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAQjB,cAAc;IA+C5B;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAqChD;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAkB1D;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa/D;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAY,GAAG,YAAY;IAwB1D;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM;IAiB1D;;OAEG;IACH,QAAQ,IAAI,cAAc;IAc1B;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;CAMrB;AAGD,wBAAgB,mBAAmB,IAAI,gBAAgB,CAEtD;AAGD,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE/D;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzE;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAElF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAY,GAAG,YAAY,CAEzE"}
@@ -0,0 +1,297 @@
1
+ /**
2
+ * EmbeddingService - Unified embedding interface for agentic-flow
3
+ *
4
+ * Supports two backends:
5
+ * - Simple: Hash-based, ~0.01ms, not semantic
6
+ * - ONNX: Real neural embeddings via ruvector-onnx-embeddings-wasm, ~10-50ms, semantic
7
+ *
8
+ * Configure via:
9
+ * - AGENTIC_FLOW_EMBEDDINGS=simple|onnx (default: simple)
10
+ * - AGENTIC_FLOW_EMBEDDING_MODEL=all-MiniLM-L6-v2 (default)
11
+ */
12
+ // Simple LRU cache for embeddings
13
+ class EmbeddingCache {
14
+ cache = new Map();
15
+ maxSize;
16
+ constructor(maxSize = 1000) {
17
+ this.maxSize = maxSize;
18
+ }
19
+ get(key) {
20
+ const value = this.cache.get(key);
21
+ if (value) {
22
+ // Move to end (most recently used)
23
+ this.cache.delete(key);
24
+ this.cache.set(key, value);
25
+ }
26
+ return value;
27
+ }
28
+ set(key, value) {
29
+ if (this.cache.size >= this.maxSize) {
30
+ // Delete oldest (first) entry
31
+ const firstKey = this.cache.keys().next().value;
32
+ if (firstKey) {
33
+ this.cache.delete(firstKey);
34
+ }
35
+ }
36
+ this.cache.set(key, value);
37
+ }
38
+ clear() {
39
+ this.cache.clear();
40
+ }
41
+ get size() {
42
+ return this.cache.size;
43
+ }
44
+ }
45
+ export class EmbeddingService {
46
+ static instance = null;
47
+ backend;
48
+ dimension;
49
+ modelName;
50
+ // ONNX state
51
+ embedder = null;
52
+ wasmModule = null;
53
+ loadingPromise = null;
54
+ modelLoaded = false;
55
+ // Stats
56
+ totalEmbeddings = 0;
57
+ totalLatencyMs = 0;
58
+ cacheHits = 0;
59
+ // Cache
60
+ cache;
61
+ cacheEnabled;
62
+ constructor() {
63
+ this.backend = process.env.AGENTIC_FLOW_EMBEDDINGS || 'simple';
64
+ this.modelName = process.env.AGENTIC_FLOW_EMBEDDING_MODEL || 'all-MiniLM-L6-v2';
65
+ this.dimension = this.backend === 'onnx' ? 384 : 256; // ONNX uses 384, simple uses 256
66
+ this.cacheEnabled = process.env.AGENTIC_FLOW_EMBEDDING_CACHE !== 'false';
67
+ this.cache = new EmbeddingCache(1000);
68
+ }
69
+ static getInstance() {
70
+ if (!EmbeddingService.instance) {
71
+ EmbeddingService.instance = new EmbeddingService();
72
+ }
73
+ return EmbeddingService.instance;
74
+ }
75
+ /**
76
+ * Get current backend
77
+ */
78
+ getBackend() {
79
+ return this.backend;
80
+ }
81
+ /**
82
+ * Get embedding dimension
83
+ */
84
+ getDimension() {
85
+ return this.dimension;
86
+ }
87
+ /**
88
+ * Check if ONNX model is loaded
89
+ */
90
+ isModelLoaded() {
91
+ return this.modelLoaded;
92
+ }
93
+ /**
94
+ * Initialize ONNX embedder (lazy load on first use)
95
+ */
96
+ async initOnnx() {
97
+ if (this.modelLoaded)
98
+ return;
99
+ if (this.loadingPromise)
100
+ return this.loadingPromise;
101
+ this.loadingPromise = this._loadOnnxModel();
102
+ await this.loadingPromise;
103
+ }
104
+ async _loadOnnxModel() {
105
+ try {
106
+ console.log(`[EmbeddingService] Loading ONNX model: ${this.modelName}`);
107
+ const startTime = performance.now();
108
+ // Import WASM module (auto-initializes with --experimental-wasm-modules)
109
+ const wasmModule = await import('ruvector-onnx-embeddings-wasm');
110
+ this.wasmModule = wasmModule;
111
+ // Import loader for model fetching
112
+ const loaderModule = await import('ruvector-onnx-embeddings-wasm/loader.js');
113
+ const { ModelLoader, MODELS } = loaderModule;
114
+ const modelConfig = MODELS[this.modelName];
115
+ if (!modelConfig) {
116
+ throw new Error(`Unknown model: ${this.modelName}`);
117
+ }
118
+ // Load model files
119
+ const loader = new ModelLoader();
120
+ const { modelBytes, tokenizerJson } = await loader.loadModel(this.modelName);
121
+ // Create embedder with configuration
122
+ const embedderConfig = new wasmModule.WasmEmbedderConfig()
123
+ .setMaxLength(modelConfig.maxLength)
124
+ .setNormalize(true)
125
+ .setPooling(0); // Mean pooling
126
+ this.embedder = wasmModule.WasmEmbedder.withConfig(modelBytes, tokenizerJson, embedderConfig);
127
+ this.dimension = this.embedder.dimension();
128
+ this.modelLoaded = true;
129
+ const loadTime = performance.now() - startTime;
130
+ console.log(`[EmbeddingService] Model loaded in ${loadTime.toFixed(0)}ms, dim=${this.dimension}`);
131
+ }
132
+ catch (error) {
133
+ console.error('[EmbeddingService] Failed to load ONNX model:', error);
134
+ console.log('[EmbeddingService] Falling back to simple embeddings');
135
+ this.backend = 'simple';
136
+ this.dimension = 256;
137
+ }
138
+ }
139
+ /**
140
+ * Generate embedding for text
141
+ */
142
+ async embed(text) {
143
+ const startTime = performance.now();
144
+ // Check cache
145
+ if (this.cacheEnabled) {
146
+ const cached = this.cache.get(text);
147
+ if (cached) {
148
+ this.cacheHits++;
149
+ return cached;
150
+ }
151
+ }
152
+ let embedding;
153
+ if (this.backend === 'onnx') {
154
+ await this.initOnnx();
155
+ if (this.embedder) {
156
+ embedding = this.embedder.embedOne(text);
157
+ }
158
+ else {
159
+ embedding = this.simpleEmbed(text);
160
+ }
161
+ }
162
+ else {
163
+ embedding = this.simpleEmbed(text);
164
+ }
165
+ // Update stats
166
+ this.totalEmbeddings++;
167
+ this.totalLatencyMs += performance.now() - startTime;
168
+ // Cache result
169
+ if (this.cacheEnabled) {
170
+ this.cache.set(text, embedding);
171
+ }
172
+ return embedding;
173
+ }
174
+ /**
175
+ * Generate embeddings for multiple texts
176
+ */
177
+ async embedBatch(texts) {
178
+ if (this.backend === 'onnx' && this.embedder) {
179
+ await this.initOnnx();
180
+ if (this.embedder) {
181
+ const batchEmbedding = this.embedder.embedBatch(texts);
182
+ const dim = this.dimension;
183
+ const embeddings = [];
184
+ for (let i = 0; i < texts.length; i++) {
185
+ embeddings.push(batchEmbedding.slice(i * dim, (i + 1) * dim));
186
+ }
187
+ return embeddings;
188
+ }
189
+ }
190
+ // Fall back to sequential
191
+ return Promise.all(texts.map(t => this.embed(t)));
192
+ }
193
+ /**
194
+ * Compute similarity between two texts
195
+ */
196
+ async similarity(text1, text2) {
197
+ if (this.backend === 'onnx') {
198
+ await this.initOnnx();
199
+ if (this.embedder) {
200
+ return this.embedder.similarity(text1, text2);
201
+ }
202
+ }
203
+ // Fall back to embedding + cosine
204
+ const [e1, e2] = await Promise.all([this.embed(text1), this.embed(text2)]);
205
+ return this.cosineSimilarity(e1, e2);
206
+ }
207
+ /**
208
+ * Simple hash-based embedding (fast, not semantic)
209
+ */
210
+ simpleEmbed(text, dim = 256) {
211
+ const embedding = new Float32Array(dim);
212
+ // Multi-pass hash for better distribution
213
+ for (let i = 0; i < text.length; i++) {
214
+ const code = text.charCodeAt(i);
215
+ embedding[i % dim] += code / 255;
216
+ embedding[(i * 7) % dim] += (code * 0.3) / 255;
217
+ embedding[(i * 13) % dim] += (code * 0.2) / 255;
218
+ }
219
+ // Normalize
220
+ let norm = 0;
221
+ for (let i = 0; i < dim; i++) {
222
+ norm += embedding[i] * embedding[i];
223
+ }
224
+ norm = Math.sqrt(norm) || 1;
225
+ for (let i = 0; i < dim; i++) {
226
+ embedding[i] /= norm;
227
+ }
228
+ return embedding;
229
+ }
230
+ /**
231
+ * Compute cosine similarity between two embeddings
232
+ */
233
+ cosineSimilarity(a, b) {
234
+ if (this.wasmModule) {
235
+ return this.wasmModule.cosineSimilarity(a, b);
236
+ }
237
+ // JS fallback
238
+ let dot = 0;
239
+ let normA = 0;
240
+ let normB = 0;
241
+ for (let i = 0; i < a.length; i++) {
242
+ dot += a[i] * b[i];
243
+ normA += a[i] * a[i];
244
+ normB += b[i] * b[i];
245
+ }
246
+ return dot / (Math.sqrt(normA) * Math.sqrt(normB) || 1);
247
+ }
248
+ /**
249
+ * Get statistics
250
+ */
251
+ getStats() {
252
+ return {
253
+ backend: this.backend,
254
+ dimension: this.dimension,
255
+ totalEmbeddings: this.totalEmbeddings,
256
+ totalLatencyMs: this.totalLatencyMs,
257
+ avgLatencyMs: this.totalEmbeddings > 0 ? this.totalLatencyMs / this.totalEmbeddings : 0,
258
+ cacheHits: this.cacheHits,
259
+ modelLoaded: this.modelLoaded,
260
+ modelName: this.backend === 'onnx' ? this.modelName : undefined,
261
+ simdAvailable: this.wasmModule?.simd_available?.() ?? undefined,
262
+ };
263
+ }
264
+ /**
265
+ * Clear cache
266
+ */
267
+ clearCache() {
268
+ this.cache.clear();
269
+ }
270
+ /**
271
+ * Reset instance (for testing)
272
+ */
273
+ static reset() {
274
+ if (EmbeddingService.instance?.embedder) {
275
+ EmbeddingService.instance.embedder.free();
276
+ }
277
+ EmbeddingService.instance = null;
278
+ }
279
+ }
280
+ // Export singleton getter
281
+ export function getEmbeddingService() {
282
+ return EmbeddingService.getInstance();
283
+ }
284
+ // Export convenience functions
285
+ export async function embed(text) {
286
+ return getEmbeddingService().embed(text);
287
+ }
288
+ export async function embedBatch(texts) {
289
+ return getEmbeddingService().embedBatch(texts);
290
+ }
291
+ export async function textSimilarity(text1, text2) {
292
+ return getEmbeddingService().similarity(text1, text2);
293
+ }
294
+ export function simpleEmbed(text, dim = 256) {
295
+ return getEmbeddingService().simpleEmbed(text, dim);
296
+ }
297
+ //# sourceMappingURL=EmbeddingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmbeddingService.js","sourceRoot":"","sources":["../../src/intelligence/EmbeddingService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EmbeddingService - Unified embedding interface for agentic-flow\n *\n * Supports two backends:\n * - Simple: Hash-based, ~0.01ms, not semantic\n * - ONNX: Real neural embeddings via ruvector-onnx-embeddings-wasm, ~10-50ms, semantic\n *\n * Configure via:\n * - AGENTIC_FLOW_EMBEDDINGS=simple|onnx (default: simple)\n * - AGENTIC_FLOW_EMBEDDING_MODEL=all-MiniLM-L6-v2 (default)\n */\n\n// Types for ONNX Runtime\ninterface OnnxSession {\n run(feeds: Record<string, any>): Promise<Record<string, any>>;\n release(): void;\n}\n\ninterface Tokenizer {\n encode(text: string, addSpecialTokens?: boolean): { ids: number[]; attentionMask: number[] };\n}\n\n// Types for the WASM module\ninterface WasmEmbedder {\n embedOne(text: string): Float32Array;\n embedBatch(texts: string[]): Float32Array;\n similarity(text1: string, text2: string): number;\n dimension(): number;\n maxLength(): number;\n free(): void;\n}\n\ninterface WasmModule {\n default: () => Promise<void>;\n WasmEmbedder: {\n withConfig(modelBytes: Uint8Array, tokenizerJson: string, config: WasmEmbedderConfig): WasmEmbedder;\n };\n WasmEmbedderConfig: new () => WasmEmbedderConfig;\n cosineSimilarity(a: Float32Array, b: Float32Array): number;\n simd_available(): boolean;\n version(): string;\n}\n\ninterface WasmEmbedderConfig {\n setMaxLength(maxLength: number): WasmEmbedderConfig;\n setNormalize(normalize: boolean): WasmEmbedderConfig;\n setPooling(pooling: number): WasmEmbedderConfig;\n}\n\ninterface ModelConfig {\n name: string;\n dimension: number;\n maxLength: number;\n size: string;\n description: string;\n model: string;\n tokenizer: string;\n}\n\nexport type EmbeddingBackend = 'simple' | 'onnx' | 'onnx-native';\n\nexport interface EmbeddingStats {\n backend: EmbeddingBackend;\n dimension: number;\n totalEmbeddings: number;\n totalLatencyMs: number;\n avgLatencyMs: number;\n cacheHits: number;\n modelLoaded: boolean;\n modelName?: string;\n simdAvailable?: boolean;\n}\n\n// Simple LRU cache for embeddings\nclass EmbeddingCache {\n private cache: Map<string, Float32Array> = new Map();\n private maxSize: number;\n\n constructor(maxSize: number = 1000) {\n this.maxSize = maxSize;\n }\n\n get(key: string): Float32Array | undefined {\n const value = this.cache.get(key);\n if (value) {\n // Move to end (most recently used)\n this.cache.delete(key);\n this.cache.set(key, value);\n }\n return value;\n }\n\n set(key: string, value: Float32Array): void {\n if (this.cache.size >= this.maxSize) {\n // Delete oldest (first) entry\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n this.cache.set(key, value);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n\nexport class EmbeddingService {\n private static instance: EmbeddingService | null = null;\n\n private backend: EmbeddingBackend;\n private dimension: number;\n private modelName: string;\n\n // ONNX state\n private embedder: WasmEmbedder | null = null;\n private wasmModule: WasmModule | null = null;\n private loadingPromise: Promise<void> | null = null;\n private modelLoaded: boolean = false;\n\n // Stats\n private totalEmbeddings: number = 0;\n private totalLatencyMs: number = 0;\n private cacheHits: number = 0;\n\n // Cache\n private cache: EmbeddingCache;\n private cacheEnabled: boolean;\n\n private constructor() {\n this.backend = (process.env.AGENTIC_FLOW_EMBEDDINGS as EmbeddingBackend) || 'simple';\n this.modelName = process.env.AGENTIC_FLOW_EMBEDDING_MODEL || 'all-MiniLM-L6-v2';\n this.dimension = this.backend === 'onnx' ? 384 : 256; // ONNX uses 384, simple uses 256\n this.cacheEnabled = process.env.AGENTIC_FLOW_EMBEDDING_CACHE !== 'false';\n this.cache = new EmbeddingCache(1000);\n }\n\n static getInstance(): EmbeddingService {\n if (!EmbeddingService.instance) {\n EmbeddingService.instance = new EmbeddingService();\n }\n return EmbeddingService.instance;\n }\n\n /**\n * Get current backend\n */\n getBackend(): EmbeddingBackend {\n return this.backend;\n }\n\n /**\n * Get embedding dimension\n */\n getDimension(): number {\n return this.dimension;\n }\n\n /**\n * Check if ONNX model is loaded\n */\n isModelLoaded(): boolean {\n return this.modelLoaded;\n }\n\n /**\n * Initialize ONNX embedder (lazy load on first use)\n */\n async initOnnx(): Promise<void> {\n if (this.modelLoaded) return;\n if (this.loadingPromise) return this.loadingPromise;\n\n this.loadingPromise = this._loadOnnxModel();\n await this.loadingPromise;\n }\n\n private async _loadOnnxModel(): Promise<void> {\n try {\n console.log(`[EmbeddingService] Loading ONNX model: ${this.modelName}`);\n const startTime = performance.now();\n\n // Import WASM module (auto-initializes with --experimental-wasm-modules)\n const wasmModule = await import('ruvector-onnx-embeddings-wasm');\n this.wasmModule = wasmModule as unknown as WasmModule;\n\n // Import loader for model fetching\n const loaderModule = await import('ruvector-onnx-embeddings-wasm/loader.js');\n const { ModelLoader, MODELS } = loaderModule;\n\n const modelConfig = MODELS[this.modelName] as ModelConfig;\n if (!modelConfig) {\n throw new Error(`Unknown model: ${this.modelName}`);\n }\n\n // Load model files\n const loader = new ModelLoader();\n const { modelBytes, tokenizerJson } = await loader.loadModel(this.modelName);\n\n // Create embedder with configuration\n const embedderConfig = new (wasmModule as any).WasmEmbedderConfig()\n .setMaxLength(modelConfig.maxLength)\n .setNormalize(true)\n .setPooling(0); // Mean pooling\n\n this.embedder = (wasmModule as any).WasmEmbedder.withConfig(\n modelBytes,\n tokenizerJson,\n embedderConfig\n );\n\n this.dimension = this.embedder!.dimension();\n this.modelLoaded = true;\n\n const loadTime = performance.now() - startTime;\n console.log(`[EmbeddingService] Model loaded in ${loadTime.toFixed(0)}ms, dim=${this.dimension}`);\n } catch (error) {\n console.error('[EmbeddingService] Failed to load ONNX model:', error);\n console.log('[EmbeddingService] Falling back to simple embeddings');\n this.backend = 'simple';\n this.dimension = 256;\n }\n }\n\n /**\n * Generate embedding for text\n */\n async embed(text: string): Promise<Float32Array> {\n const startTime = performance.now();\n\n // Check cache\n if (this.cacheEnabled) {\n const cached = this.cache.get(text);\n if (cached) {\n this.cacheHits++;\n return cached;\n }\n }\n\n let embedding: Float32Array;\n\n if (this.backend === 'onnx') {\n await this.initOnnx();\n if (this.embedder) {\n embedding = this.embedder.embedOne(text);\n } else {\n embedding = this.simpleEmbed(text);\n }\n } else {\n embedding = this.simpleEmbed(text);\n }\n\n // Update stats\n this.totalEmbeddings++;\n this.totalLatencyMs += performance.now() - startTime;\n\n // Cache result\n if (this.cacheEnabled) {\n this.cache.set(text, embedding);\n }\n\n return embedding;\n }\n\n /**\n * Generate embeddings for multiple texts\n */\n async embedBatch(texts: string[]): Promise<Float32Array[]> {\n if (this.backend === 'onnx' && this.embedder) {\n await this.initOnnx();\n if (this.embedder) {\n const batchEmbedding = this.embedder.embedBatch(texts);\n const dim = this.dimension;\n const embeddings: Float32Array[] = [];\n for (let i = 0; i < texts.length; i++) {\n embeddings.push(batchEmbedding.slice(i * dim, (i + 1) * dim));\n }\n return embeddings;\n }\n }\n\n // Fall back to sequential\n return Promise.all(texts.map(t => this.embed(t)));\n }\n\n /**\n * Compute similarity between two texts\n */\n async similarity(text1: string, text2: string): Promise<number> {\n if (this.backend === 'onnx') {\n await this.initOnnx();\n if (this.embedder) {\n return this.embedder.similarity(text1, text2);\n }\n }\n\n // Fall back to embedding + cosine\n const [e1, e2] = await Promise.all([this.embed(text1), this.embed(text2)]);\n return this.cosineSimilarity(e1, e2);\n }\n\n /**\n * Simple hash-based embedding (fast, not semantic)\n */\n simpleEmbed(text: string, dim: number = 256): Float32Array {\n const embedding = new Float32Array(dim);\n\n // Multi-pass hash for better distribution\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i);\n embedding[i % dim] += code / 255;\n embedding[(i * 7) % dim] += (code * 0.3) / 255;\n embedding[(i * 13) % dim] += (code * 0.2) / 255;\n }\n\n // Normalize\n let norm = 0;\n for (let i = 0; i < dim; i++) {\n norm += embedding[i] * embedding[i];\n }\n norm = Math.sqrt(norm) || 1;\n for (let i = 0; i < dim; i++) {\n embedding[i] /= norm;\n }\n\n return embedding;\n }\n\n /**\n * Compute cosine similarity between two embeddings\n */\n cosineSimilarity(a: Float32Array, b: Float32Array): number {\n if (this.wasmModule) {\n return this.wasmModule.cosineSimilarity(a, b);\n }\n\n // JS fallback\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n return dot / (Math.sqrt(normA) * Math.sqrt(normB) || 1);\n }\n\n /**\n * Get statistics\n */\n getStats(): EmbeddingStats {\n return {\n backend: this.backend,\n dimension: this.dimension,\n totalEmbeddings: this.totalEmbeddings,\n totalLatencyMs: this.totalLatencyMs,\n avgLatencyMs: this.totalEmbeddings > 0 ? this.totalLatencyMs / this.totalEmbeddings : 0,\n cacheHits: this.cacheHits,\n modelLoaded: this.modelLoaded,\n modelName: this.backend === 'onnx' ? this.modelName : undefined,\n simdAvailable: this.wasmModule?.simd_available?.() ?? undefined,\n };\n }\n\n /**\n * Clear cache\n */\n clearCache(): void {\n this.cache.clear();\n }\n\n /**\n * Reset instance (for testing)\n */\n static reset(): void {\n if (EmbeddingService.instance?.embedder) {\n EmbeddingService.instance.embedder.free();\n }\n EmbeddingService.instance = null;\n }\n}\n\n// Export singleton getter\nexport function getEmbeddingService(): EmbeddingService {\n return EmbeddingService.getInstance();\n}\n\n// Export convenience functions\nexport async function embed(text: string): Promise<Float32Array> {\n return getEmbeddingService().embed(text);\n}\n\nexport async function embedBatch(texts: string[]): Promise<Float32Array[]> {\n return getEmbeddingService().embedBatch(texts);\n}\n\nexport async function textSimilarity(text1: string, text2: string): Promise<number> {\n return getEmbeddingService().similarity(text1, text2);\n}\n\nexport function simpleEmbed(text: string, dim: number = 256): Float32Array {\n return getEmbeddingService().simpleEmbed(text, dim);\n}\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Embedding Benchmark - Compare simple vs ONNX embeddings
3
+ *
4
+ * Run with: npx ts-node src/intelligence/embedding-benchmark.ts
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=embedding-benchmark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-benchmark.d.ts","sourceRoot":"","sources":["../../src/intelligence/embedding-benchmark.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Embedding Benchmark - Compare simple vs ONNX embeddings
3
+ *
4
+ * Run with: npx ts-node src/intelligence/embedding-benchmark.ts
5
+ */
6
+ import { getEmbeddingService, EmbeddingService } from './EmbeddingService.js';
7
+ const TEST_TEXTS = [
8
+ 'Fix a bug in the authentication system',
9
+ 'Implement user login functionality',
10
+ 'Write unit tests for the API',
11
+ 'Refactor the database layer',
12
+ 'Optimize memory usage',
13
+ 'Add dark mode to the UI',
14
+ 'Deploy to production',
15
+ 'Review pull request',
16
+ 'Document the API endpoints',
17
+ 'Set up CI/CD pipeline',
18
+ ];
19
+ const SEMANTIC_PAIRS = [
20
+ { a: 'I love dogs', b: 'I adore puppies', expected: 'high' },
21
+ { a: 'Fix authentication bug', b: 'Repair login issue', expected: 'high' },
22
+ { a: 'Write unit tests', b: 'Create test cases', expected: 'high' },
23
+ { a: 'Deploy to production', b: 'The weather is nice', expected: 'low' },
24
+ { a: 'Fix bug', b: 'Add feature', expected: 'medium' },
25
+ { a: 'Machine learning', b: 'Artificial intelligence', expected: 'high' },
26
+ { a: 'Pizza recipe', b: 'Quantum physics', expected: 'low' },
27
+ ];
28
+ async function runBenchmark() {
29
+ console.log('='.repeat(60));
30
+ console.log('Embedding Benchmark: Simple vs ONNX');
31
+ console.log('='.repeat(60));
32
+ // Benchmark Simple Embeddings
33
+ console.log('\n--- Simple Embeddings ---');
34
+ process.env.AGENTIC_FLOW_EMBEDDINGS = 'simple';
35
+ EmbeddingService.reset();
36
+ const simpleService = getEmbeddingService();
37
+ const simpleResults = await benchmarkService(simpleService, 'simple');
38
+ // Benchmark ONNX Embeddings
39
+ console.log('\n--- ONNX Embeddings ---');
40
+ process.env.AGENTIC_FLOW_EMBEDDINGS = 'onnx';
41
+ EmbeddingService.reset();
42
+ const onnxService = getEmbeddingService();
43
+ const onnxResults = await benchmarkService(onnxService, 'onnx');
44
+ // Summary
45
+ console.log('\n' + '='.repeat(60));
46
+ console.log('SUMMARY');
47
+ console.log('='.repeat(60));
48
+ console.log(`
49
+ | Metric | Simple | ONNX |
50
+ |-----------------------|-------------|-------------|
51
+ | Avg Latency (cold) | ${simpleResults.avgColdLatency.toFixed(2)}ms | ${onnxResults.avgColdLatency.toFixed(2)}ms |
52
+ | Avg Latency (warm) | ${simpleResults.avgWarmLatency.toFixed(2)}ms | ${onnxResults.avgWarmLatency.toFixed(2)}ms |
53
+ | Batch 10 texts | ${simpleResults.batchLatency.toFixed(2)}ms | ${onnxResults.batchLatency.toFixed(2)}ms |
54
+ | Dimension | ${simpleResults.dimension} | ${onnxResults.dimension} |
55
+ | Semantic Accuracy | ${simpleResults.semanticAccuracy}% | ${onnxResults.semanticAccuracy}% |
56
+ `);
57
+ console.log('\nSemantic Similarity Comparison:');
58
+ console.log('-'.repeat(60));
59
+ for (let i = 0; i < SEMANTIC_PAIRS.length; i++) {
60
+ const pair = SEMANTIC_PAIRS[i];
61
+ console.log(`"${pair.a}" vs "${pair.b}"`);
62
+ console.log(` Expected: ${pair.expected}`);
63
+ console.log(` Simple: ${simpleResults.similarities[i].toFixed(3)}`);
64
+ console.log(` ONNX: ${onnxResults.similarities[i].toFixed(3)}`);
65
+ console.log();
66
+ }
67
+ // Recommendation
68
+ console.log('='.repeat(60));
69
+ console.log('RECOMMENDATION');
70
+ console.log('='.repeat(60));
71
+ if (onnxResults.semanticAccuracy > simpleResults.semanticAccuracy + 20) {
72
+ console.log(`
73
+ ONNX embeddings provide significantly better semantic accuracy
74
+ (${onnxResults.semanticAccuracy}% vs ${simpleResults.semanticAccuracy}%).
75
+
76
+ For tasks requiring semantic understanding (routing, pattern matching),
77
+ use ONNX embeddings:
78
+
79
+ export AGENTIC_FLOW_EMBEDDINGS=onnx
80
+
81
+ Note: First embedding takes ~${(onnxResults.avgColdLatency / 1000).toFixed(1)}s (model loading).
82
+ Subsequent embeddings: ~${onnxResults.avgWarmLatency.toFixed(1)}ms.
83
+ `);
84
+ }
85
+ else {
86
+ console.log(`
87
+ Simple embeddings are sufficient for your use case.
88
+ Semantic accuracy difference is minimal.
89
+
90
+ Keep using simple embeddings for maximum speed:
91
+
92
+ export AGENTIC_FLOW_EMBEDDINGS=simple
93
+ `);
94
+ }
95
+ }
96
+ async function benchmarkService(service, name) {
97
+ // Cold start (first embedding, includes model loading for ONNX)
98
+ console.log(`\n[${name}] Cold start embedding...`);
99
+ const coldStart = performance.now();
100
+ await service.embed(TEST_TEXTS[0]);
101
+ const coldLatency = performance.now() - coldStart;
102
+ console.log(` Cold latency: ${coldLatency.toFixed(2)}ms`);
103
+ // Warm embeddings
104
+ console.log(`[${name}] Warm embeddings (${TEST_TEXTS.length} texts)...`);
105
+ service.clearCache();
106
+ const warmStart = performance.now();
107
+ for (const text of TEST_TEXTS) {
108
+ await service.embed(text);
109
+ }
110
+ const warmTotalLatency = performance.now() - warmStart;
111
+ const avgWarmLatency = warmTotalLatency / TEST_TEXTS.length;
112
+ console.log(` Total: ${warmTotalLatency.toFixed(2)}ms, Avg: ${avgWarmLatency.toFixed(2)}ms`);
113
+ // Batch embedding
114
+ console.log(`[${name}] Batch embedding...`);
115
+ service.clearCache();
116
+ const batchStart = performance.now();
117
+ await service.embedBatch(TEST_TEXTS);
118
+ const batchLatency = performance.now() - batchStart;
119
+ console.log(` Batch latency: ${batchLatency.toFixed(2)}ms`);
120
+ // Semantic similarity tests
121
+ console.log(`[${name}] Semantic similarity tests...`);
122
+ const similarities = [];
123
+ let correctCount = 0;
124
+ for (const pair of SEMANTIC_PAIRS) {
125
+ const sim = await service.similarity(pair.a, pair.b);
126
+ similarities.push(sim);
127
+ // For ONNX (semantic), use proper thresholds
128
+ // For simple (hash-based), it will score incorrectly on unrelated pairs
129
+ const isCorrect = (pair.expected === 'high' && sim > 0.5) ||
130
+ (pair.expected === 'medium' && sim >= 0.2 && sim <= 0.6) ||
131
+ (pair.expected === 'low' && sim < 0.3);
132
+ if (isCorrect)
133
+ correctCount++;
134
+ console.log(` "${pair.a.substring(0, 20)}..." vs "${pair.b.substring(0, 20)}...": ${sim.toFixed(3)} (expected: ${pair.expected})`);
135
+ }
136
+ const semanticAccuracy = Math.round((correctCount / SEMANTIC_PAIRS.length) * 100);
137
+ console.log(` Semantic accuracy: ${semanticAccuracy}%`);
138
+ const stats = service.getStats();
139
+ console.log(` Model: ${stats.modelName || 'N/A'}, SIMD: ${stats.simdAvailable ?? 'N/A'}`);
140
+ return {
141
+ avgColdLatency: coldLatency,
142
+ avgWarmLatency,
143
+ batchLatency,
144
+ dimension: stats.dimension,
145
+ semanticAccuracy,
146
+ similarities,
147
+ };
148
+ }
149
+ // Run if executed directly
150
+ runBenchmark().catch(console.error);
151
+ //# sourceMappingURL=embedding-benchmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding-benchmark.js","sourceRoot":"","sources":["../../src/intelligence/embedding-benchmark.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Embedding Benchmark - Compare simple vs ONNX embeddings\n *\n * Run with: npx ts-node src/intelligence/embedding-benchmark.ts\n */\n\nimport { getEmbeddingService, EmbeddingService } from './EmbeddingService.js';\n\nconst TEST_TEXTS = [\n 'Fix a bug in the authentication system',\n 'Implement user login functionality',\n 'Write unit tests for the API',\n 'Refactor the database layer',\n 'Optimize memory usage',\n 'Add dark mode to the UI',\n 'Deploy to production',\n 'Review pull request',\n 'Document the API endpoints',\n 'Set up CI/CD pipeline',\n];\n\nconst SEMANTIC_PAIRS = [\n { a: 'I love dogs', b: 'I adore puppies', expected: 'high' },\n { a: 'Fix authentication bug', b: 'Repair login issue', expected: 'high' },\n { a: 'Write unit tests', b: 'Create test cases', expected: 'high' },\n { a: 'Deploy to production', b: 'The weather is nice', expected: 'low' },\n { a: 'Fix bug', b: 'Add feature', expected: 'medium' },\n { a: 'Machine learning', b: 'Artificial intelligence', expected: 'high' },\n { a: 'Pizza recipe', b: 'Quantum physics', expected: 'low' },\n];\n\nasync function runBenchmark() {\n console.log('='.repeat(60));\n console.log('Embedding Benchmark: Simple vs ONNX');\n console.log('='.repeat(60));\n\n // Benchmark Simple Embeddings\n console.log('\\n--- Simple Embeddings ---');\n process.env.AGENTIC_FLOW_EMBEDDINGS = 'simple';\n EmbeddingService.reset();\n\n const simpleService = getEmbeddingService();\n const simpleResults = await benchmarkService(simpleService, 'simple');\n\n // Benchmark ONNX Embeddings\n console.log('\\n--- ONNX Embeddings ---');\n process.env.AGENTIC_FLOW_EMBEDDINGS = 'onnx';\n EmbeddingService.reset();\n\n const onnxService = getEmbeddingService();\n const onnxResults = await benchmarkService(onnxService, 'onnx');\n\n // Summary\n console.log('\\n' + '='.repeat(60));\n console.log('SUMMARY');\n console.log('='.repeat(60));\n\n console.log(`\n| Metric | Simple | ONNX |\n|-----------------------|-------------|-------------|\n| Avg Latency (cold) | ${simpleResults.avgColdLatency.toFixed(2)}ms | ${onnxResults.avgColdLatency.toFixed(2)}ms |\n| Avg Latency (warm) | ${simpleResults.avgWarmLatency.toFixed(2)}ms | ${onnxResults.avgWarmLatency.toFixed(2)}ms |\n| Batch 10 texts | ${simpleResults.batchLatency.toFixed(2)}ms | ${onnxResults.batchLatency.toFixed(2)}ms |\n| Dimension | ${simpleResults.dimension} | ${onnxResults.dimension} |\n| Semantic Accuracy | ${simpleResults.semanticAccuracy}% | ${onnxResults.semanticAccuracy}% |\n`);\n\n console.log('\\nSemantic Similarity Comparison:');\n console.log('-'.repeat(60));\n for (let i = 0; i < SEMANTIC_PAIRS.length; i++) {\n const pair = SEMANTIC_PAIRS[i];\n console.log(`\"${pair.a}\" vs \"${pair.b}\"`);\n console.log(` Expected: ${pair.expected}`);\n console.log(` Simple: ${simpleResults.similarities[i].toFixed(3)}`);\n console.log(` ONNX: ${onnxResults.similarities[i].toFixed(3)}`);\n console.log();\n }\n\n // Recommendation\n console.log('='.repeat(60));\n console.log('RECOMMENDATION');\n console.log('='.repeat(60));\n\n if (onnxResults.semanticAccuracy > simpleResults.semanticAccuracy + 20) {\n console.log(`\nONNX embeddings provide significantly better semantic accuracy\n(${onnxResults.semanticAccuracy}% vs ${simpleResults.semanticAccuracy}%).\n\nFor tasks requiring semantic understanding (routing, pattern matching),\nuse ONNX embeddings:\n\n export AGENTIC_FLOW_EMBEDDINGS=onnx\n\nNote: First embedding takes ~${(onnxResults.avgColdLatency / 1000).toFixed(1)}s (model loading).\nSubsequent embeddings: ~${onnxResults.avgWarmLatency.toFixed(1)}ms.\n`);\n } else {\n console.log(`\nSimple embeddings are sufficient for your use case.\nSemantic accuracy difference is minimal.\n\nKeep using simple embeddings for maximum speed:\n\n export AGENTIC_FLOW_EMBEDDINGS=simple\n`);\n }\n}\n\nasync function benchmarkService(\n service: EmbeddingService,\n name: string\n): Promise<{\n avgColdLatency: number;\n avgWarmLatency: number;\n batchLatency: number;\n dimension: number;\n semanticAccuracy: number;\n similarities: number[];\n}> {\n // Cold start (first embedding, includes model loading for ONNX)\n console.log(`\\n[${name}] Cold start embedding...`);\n const coldStart = performance.now();\n await service.embed(TEST_TEXTS[0]);\n const coldLatency = performance.now() - coldStart;\n console.log(` Cold latency: ${coldLatency.toFixed(2)}ms`);\n\n // Warm embeddings\n console.log(`[${name}] Warm embeddings (${TEST_TEXTS.length} texts)...`);\n service.clearCache();\n const warmStart = performance.now();\n for (const text of TEST_TEXTS) {\n await service.embed(text);\n }\n const warmTotalLatency = performance.now() - warmStart;\n const avgWarmLatency = warmTotalLatency / TEST_TEXTS.length;\n console.log(` Total: ${warmTotalLatency.toFixed(2)}ms, Avg: ${avgWarmLatency.toFixed(2)}ms`);\n\n // Batch embedding\n console.log(`[${name}] Batch embedding...`);\n service.clearCache();\n const batchStart = performance.now();\n await service.embedBatch(TEST_TEXTS);\n const batchLatency = performance.now() - batchStart;\n console.log(` Batch latency: ${batchLatency.toFixed(2)}ms`);\n\n // Semantic similarity tests\n console.log(`[${name}] Semantic similarity tests...`);\n const similarities: number[] = [];\n let correctCount = 0;\n\n for (const pair of SEMANTIC_PAIRS) {\n const sim = await service.similarity(pair.a, pair.b);\n similarities.push(sim);\n\n // For ONNX (semantic), use proper thresholds\n // For simple (hash-based), it will score incorrectly on unrelated pairs\n const isCorrect =\n (pair.expected === 'high' && sim > 0.5) ||\n (pair.expected === 'medium' && sim >= 0.2 && sim <= 0.6) ||\n (pair.expected === 'low' && sim < 0.3);\n\n if (isCorrect) correctCount++;\n\n console.log(` \"${pair.a.substring(0, 20)}...\" vs \"${pair.b.substring(0, 20)}...\": ${sim.toFixed(3)} (expected: ${pair.expected})`);\n }\n\n const semanticAccuracy = Math.round((correctCount / SEMANTIC_PAIRS.length) * 100);\n console.log(` Semantic accuracy: ${semanticAccuracy}%`);\n\n const stats = service.getStats();\n console.log(` Model: ${stats.modelName || 'N/A'}, SIMD: ${stats.simdAvailable ?? 'N/A'}`);\n\n return {\n avgColdLatency: coldLatency,\n avgWarmLatency,\n batchLatency,\n dimension: stats.dimension,\n semanticAccuracy,\n similarities,\n };\n}\n\n// Run if executed directly\nrunBenchmark().catch(console.error);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"intelligence-bridge.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/fastmcp/tools/hooks/intelligence-bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"intelligence-bridge.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/fastmcp/tools/hooks/intelligence-bridge.ts"],"names":[],"mappings":"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"}