agentic-flow 2.0.1-alpha.12 → 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.
- package/CHANGELOG.md +48 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/cli/commands/hooks.d.ts.map +1 -1
- package/dist/cli/commands/hooks.js +6 -1
- package/dist/cli/commands/hooks.js.map +1 -1
- package/dist/intelligence/EmbeddingService.d.ts +95 -0
- package/dist/intelligence/EmbeddingService.d.ts.map +1 -0
- package/dist/intelligence/EmbeddingService.js +297 -0
- package/dist/intelligence/EmbeddingService.js.map +1 -0
- package/dist/intelligence/IntelligenceStore.d.ts +168 -0
- package/dist/intelligence/IntelligenceStore.d.ts.map +1 -0
- package/dist/intelligence/IntelligenceStore.js +364 -0
- package/dist/intelligence/IntelligenceStore.js.map +1 -0
- package/dist/intelligence/embedding-benchmark.d.ts +7 -0
- package/dist/intelligence/embedding-benchmark.d.ts.map +1 -0
- package/dist/intelligence/embedding-benchmark.js +151 -0
- package/dist/intelligence/embedding-benchmark.js.map +1 -0
- package/dist/mcp/fastmcp/tools/hooks/intelligence-bridge.d.ts +13 -0
- package/dist/mcp/fastmcp/tools/hooks/intelligence-bridge.d.ts.map +1 -1
- package/dist/mcp/fastmcp/tools/hooks/intelligence-bridge.js +48 -21
- package/dist/mcp/fastmcp/tools/hooks/intelligence-bridge.js.map +1 -1
- package/dist/mcp/fastmcp/tools/hooks/intelligence-tools.d.ts.map +1 -1
- package/dist/mcp/fastmcp/tools/hooks/intelligence-tools.js +8 -0
- package/dist/mcp/fastmcp/tools/hooks/intelligence-tools.js.map +1 -1
- package/package.json +3 -1
- package/wasm/reasoningbank/reasoningbank_wasm_bg.js +2 -2
- package/wasm/reasoningbank/reasoningbank_wasm_bg.wasm +0 -0
|
@@ -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,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IntelligenceStore - SQLite persistence for RuVector intelligence layer
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform (Linux, macOS, Windows) persistent storage for:
|
|
5
|
+
* - Learning trajectories
|
|
6
|
+
* - Routing patterns
|
|
7
|
+
* - SONA adaptations
|
|
8
|
+
* - HNSW vectors
|
|
9
|
+
*/
|
|
10
|
+
export interface StoredTrajectory {
|
|
11
|
+
id: number;
|
|
12
|
+
taskDescription: string;
|
|
13
|
+
agent: string;
|
|
14
|
+
steps: number;
|
|
15
|
+
outcome: 'success' | 'failure' | 'partial';
|
|
16
|
+
startTime: number;
|
|
17
|
+
endTime: number;
|
|
18
|
+
metadata?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface StoredPattern {
|
|
21
|
+
id: number;
|
|
22
|
+
taskType: string;
|
|
23
|
+
approach: string;
|
|
24
|
+
embedding: Buffer;
|
|
25
|
+
similarity: number;
|
|
26
|
+
usageCount: number;
|
|
27
|
+
successRate: number;
|
|
28
|
+
createdAt: number;
|
|
29
|
+
updatedAt: number;
|
|
30
|
+
}
|
|
31
|
+
export interface StoredRouting {
|
|
32
|
+
id: number;
|
|
33
|
+
task: string;
|
|
34
|
+
recommendedAgent: string;
|
|
35
|
+
confidence: number;
|
|
36
|
+
latencyMs: number;
|
|
37
|
+
wasSuccessful: boolean;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
}
|
|
40
|
+
export interface LearningStats {
|
|
41
|
+
totalTrajectories: number;
|
|
42
|
+
successfulTrajectories: number;
|
|
43
|
+
totalRoutings: number;
|
|
44
|
+
successfulRoutings: number;
|
|
45
|
+
totalPatterns: number;
|
|
46
|
+
sonaAdaptations: number;
|
|
47
|
+
hnswQueries: number;
|
|
48
|
+
lastUpdated: number;
|
|
49
|
+
}
|
|
50
|
+
export declare class IntelligenceStore {
|
|
51
|
+
private db;
|
|
52
|
+
private static instance;
|
|
53
|
+
private constructor();
|
|
54
|
+
/**
|
|
55
|
+
* Get singleton instance
|
|
56
|
+
*/
|
|
57
|
+
static getInstance(dbPath?: string): IntelligenceStore;
|
|
58
|
+
/**
|
|
59
|
+
* Get default database path (cross-platform)
|
|
60
|
+
*/
|
|
61
|
+
static getDefaultPath(): string;
|
|
62
|
+
/**
|
|
63
|
+
* Initialize database schema
|
|
64
|
+
*/
|
|
65
|
+
private initSchema;
|
|
66
|
+
/**
|
|
67
|
+
* Start a new trajectory
|
|
68
|
+
*/
|
|
69
|
+
startTrajectory(taskDescription: string, agent: string): number;
|
|
70
|
+
/**
|
|
71
|
+
* Add step to trajectory
|
|
72
|
+
*/
|
|
73
|
+
addTrajectoryStep(trajectoryId: number): void;
|
|
74
|
+
/**
|
|
75
|
+
* End trajectory with outcome
|
|
76
|
+
*/
|
|
77
|
+
endTrajectory(trajectoryId: number, outcome: 'success' | 'failure' | 'partial', metadata?: Record<string, any>): void;
|
|
78
|
+
/**
|
|
79
|
+
* Get active trajectories (no end_time)
|
|
80
|
+
*/
|
|
81
|
+
getActiveTrajectories(): StoredTrajectory[];
|
|
82
|
+
/**
|
|
83
|
+
* Get recent trajectories
|
|
84
|
+
*/
|
|
85
|
+
getRecentTrajectories(limit?: number): StoredTrajectory[];
|
|
86
|
+
/**
|
|
87
|
+
* Store a pattern
|
|
88
|
+
*/
|
|
89
|
+
storePattern(taskType: string, approach: string, embedding?: Float32Array): number;
|
|
90
|
+
/**
|
|
91
|
+
* Update pattern usage
|
|
92
|
+
*/
|
|
93
|
+
updatePatternUsage(patternId: number, wasSuccessful: boolean): void;
|
|
94
|
+
/**
|
|
95
|
+
* Find patterns by task type
|
|
96
|
+
*/
|
|
97
|
+
findPatterns(taskType: string, limit?: number): StoredPattern[];
|
|
98
|
+
/**
|
|
99
|
+
* Record a routing decision
|
|
100
|
+
*/
|
|
101
|
+
recordRouting(task: string, recommendedAgent: string, confidence: number, latencyMs: number): number;
|
|
102
|
+
/**
|
|
103
|
+
* Update routing outcome
|
|
104
|
+
*/
|
|
105
|
+
updateRoutingOutcome(routingId: number, wasSuccessful: boolean): void;
|
|
106
|
+
/**
|
|
107
|
+
* Get routing accuracy for an agent
|
|
108
|
+
*/
|
|
109
|
+
getAgentAccuracy(agent: string): {
|
|
110
|
+
total: number;
|
|
111
|
+
successful: number;
|
|
112
|
+
accuracy: number;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Get all stats
|
|
116
|
+
*/
|
|
117
|
+
getStats(): LearningStats;
|
|
118
|
+
/**
|
|
119
|
+
* Increment a stat counter
|
|
120
|
+
*/
|
|
121
|
+
incrementStat(statName: string, amount?: number): void;
|
|
122
|
+
/**
|
|
123
|
+
* Record SONA adaptation
|
|
124
|
+
*/
|
|
125
|
+
recordSonaAdaptation(): void;
|
|
126
|
+
/**
|
|
127
|
+
* Record HNSW query
|
|
128
|
+
*/
|
|
129
|
+
recordHnswQuery(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Get summary for display (simplified for UI)
|
|
132
|
+
*/
|
|
133
|
+
getSummary(): {
|
|
134
|
+
trajectories: number;
|
|
135
|
+
routings: number;
|
|
136
|
+
patterns: number;
|
|
137
|
+
operations: number;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Get detailed summary for reports
|
|
141
|
+
*/
|
|
142
|
+
getDetailedSummary(): {
|
|
143
|
+
trajectories: {
|
|
144
|
+
total: number;
|
|
145
|
+
active: number;
|
|
146
|
+
successful: number;
|
|
147
|
+
};
|
|
148
|
+
routings: {
|
|
149
|
+
total: number;
|
|
150
|
+
accuracy: number;
|
|
151
|
+
};
|
|
152
|
+
patterns: number;
|
|
153
|
+
operations: {
|
|
154
|
+
sona: number;
|
|
155
|
+
hnsw: number;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Close database connection
|
|
160
|
+
*/
|
|
161
|
+
close(): void;
|
|
162
|
+
/**
|
|
163
|
+
* Reset all data (for testing)
|
|
164
|
+
*/
|
|
165
|
+
reset(): void;
|
|
166
|
+
}
|
|
167
|
+
export declare function getIntelligenceStore(dbPath?: string): IntelligenceStore;
|
|
168
|
+
//# sourceMappingURL=IntelligenceStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntelligenceStore.d.ts","sourceRoot":"","sources":["../../src/intelligence/IntelligenceStore.ts"],"names":[],"mappings":"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"}
|