@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,354 @@
1
+ /**
2
+ * Intent Router Plugin
3
+ *
4
+ * Smart query → agent/tool mapping using @ruvector/wasm semantic matching.
5
+ * Routes user intents to optimal handlers with confidence scoring.
6
+ *
7
+ * Features:
8
+ * - Semantic intent classification (<1ms)
9
+ * - Multi-label routing (can route to multiple handlers)
10
+ * - Confidence-based fallback
11
+ * - Intent history for optimization
12
+ * - Dynamic route learning
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { intentRouterPlugin } from '@sparkleideas/plugins/examples/ruvector-plugins';
17
+ * await getDefaultRegistry().register(intentRouterPlugin);
18
+ * ```
19
+ */
20
+
21
+ import {
22
+ PluginBuilder,
23
+ MCPToolBuilder,
24
+ HookBuilder,
25
+ HookEvent,
26
+ HookPriority,
27
+ Security,
28
+ } from '../../src/index.js';
29
+
30
+ // Import shared vector utilities (consolidated from all plugins)
31
+ import {
32
+ IVectorDB,
33
+ createVectorDB,
34
+ generateHashEmbedding,
35
+ } from './shared/vector-utils.js';
36
+
37
+ // ============================================================================
38
+ // Types
39
+ // ============================================================================
40
+
41
+ export interface Intent {
42
+ id: string;
43
+ pattern: string;
44
+ category: string;
45
+ handlers: IntentHandler[];
46
+ priority: number;
47
+ examples: string[];
48
+ embedding?: Float32Array;
49
+ metadata: {
50
+ createdAt: Date;
51
+ updatedAt: Date;
52
+ usageCount: number;
53
+ successRate: number;
54
+ };
55
+ }
56
+
57
+ export interface IntentHandler {
58
+ type: 'agent' | 'tool' | 'workflow' | 'skill';
59
+ name: string;
60
+ config?: Record<string, unknown>;
61
+ weight: number;
62
+ }
63
+
64
+ export interface RouteResult {
65
+ intent: Intent;
66
+ confidence: number;
67
+ handlers: Array<IntentHandler & { score: number }>;
68
+ alternatives: Array<{ intent: Intent; confidence: number }>;
69
+ }
70
+
71
+ export interface RouterConfig {
72
+ minConfidence: number;
73
+ maxAlternatives: number;
74
+ enableLearning: boolean;
75
+ defaultHandler?: IntentHandler;
76
+ }
77
+
78
+ // ============================================================================
79
+ // Intent Router Core
80
+ // ============================================================================
81
+
82
+ export class IntentRouter {
83
+ private vectorDb: IVectorDB | null = null;
84
+ private intents = new Map<string, Intent>();
85
+ private routeHistory: Array<{ query: string; intentId: string; success: boolean; timestamp: Date }> = [];
86
+ private config: RouterConfig;
87
+ private dimensions = 768;
88
+ private nextId = 1;
89
+ private initPromise: Promise<void> | null = null;
90
+
91
+ constructor(config?: Partial<RouterConfig>) {
92
+ this.config = {
93
+ minConfidence: 0.4,
94
+ maxAlternatives: 3,
95
+ enableLearning: true,
96
+ ...config,
97
+ };
98
+ }
99
+
100
+ async initialize(): Promise<void> {
101
+ if (this.vectorDb) return;
102
+ if (this.initPromise) return this.initPromise;
103
+
104
+ this.initPromise = (async () => {
105
+ this.vectorDb = await createVectorDB(this.dimensions);
106
+ await this.initializeDefaultIntents();
107
+ })();
108
+
109
+ return this.initPromise;
110
+ }
111
+
112
+ private async ensureInitialized(): Promise<IVectorDB> {
113
+ await this.initialize();
114
+ return this.vectorDb!;
115
+ }
116
+
117
+ /**
118
+ * Register a new intent pattern.
119
+ */
120
+ async registerIntent(
121
+ pattern: string,
122
+ category: string,
123
+ handlers: IntentHandler[],
124
+ options?: { priority?: number; examples?: string[] }
125
+ ): Promise<Intent> {
126
+ const db = await this.ensureInitialized();
127
+
128
+ const safePattern = Security.validateString(pattern, { maxLength: 500 });
129
+ const safeCategory = Security.validateString(category, { maxLength: 100 });
130
+
131
+ const id = `intent-${this.nextId++}`;
132
+ const examples = options?.examples ?? [];
133
+ const allText = [safePattern, ...examples].join(' ');
134
+ const embedding = this.generateEmbedding(allText);
135
+
136
+ const intent: Intent = {
137
+ id,
138
+ pattern: safePattern,
139
+ category: safeCategory,
140
+ handlers,
141
+ priority: options?.priority ?? 0,
142
+ examples,
143
+ embedding,
144
+ metadata: { createdAt: new Date(), updatedAt: new Date(), usageCount: 0, successRate: 1.0 },
145
+ };
146
+
147
+ db.insert(embedding, id, { pattern: safePattern, category: safeCategory, priority: intent.priority });
148
+ this.intents.set(id, intent);
149
+ return intent;
150
+ }
151
+
152
+ /**
153
+ * Route a query to the best matching intent handlers (<1ms).
154
+ */
155
+ async route(query: string): Promise<RouteResult> {
156
+ const db = await this.ensureInitialized();
157
+
158
+ const safeQuery = Security.validateString(query, { maxLength: 1000 });
159
+ const queryEmbedding = this.generateEmbedding(safeQuery);
160
+ const searchResults = db.search(queryEmbedding, this.config.maxAlternatives + 1);
161
+
162
+ if (searchResults.length === 0 || searchResults[0].score < this.config.minConfidence) {
163
+ if (this.config.defaultHandler) {
164
+ const fallbackIntent: Intent = {
165
+ id: 'fallback', pattern: 'default', category: 'general',
166
+ handlers: [this.config.defaultHandler], priority: -1, examples: [],
167
+ metadata: { createdAt: new Date(), updatedAt: new Date(), usageCount: 0, successRate: 0 },
168
+ };
169
+ return { intent: fallbackIntent, confidence: 0, handlers: [{ ...this.config.defaultHandler, score: 0 }], alternatives: [] };
170
+ }
171
+ throw new Error('No matching intent found');
172
+ }
173
+
174
+ const bestMatch = searchResults[0];
175
+ const intent = this.intents.get(bestMatch.id)!;
176
+
177
+ intent.metadata.usageCount++;
178
+ intent.metadata.updatedAt = new Date();
179
+
180
+ if (this.config.enableLearning) {
181
+ this.routeHistory.push({ query: safeQuery, intentId: intent.id, success: true, timestamp: new Date() });
182
+ if (this.routeHistory.length > 1000) this.routeHistory = this.routeHistory.slice(-500);
183
+ }
184
+
185
+ const scoredHandlers = intent.handlers.map(h => ({ ...h, score: h.weight * bestMatch.score })).sort((a, b) => b.score - a.score);
186
+ const alternatives = searchResults.slice(1, this.config.maxAlternatives + 1)
187
+ .filter(r => r.score >= this.config.minConfidence * 0.7)
188
+ .map(r => ({ intent: this.intents.get(r.id)!, confidence: r.score }))
189
+ .filter(a => a.intent);
190
+
191
+ return { intent, confidence: bestMatch.score, handlers: scoredHandlers, alternatives };
192
+ }
193
+
194
+ /**
195
+ * Provide feedback on a routing decision.
196
+ */
197
+ async feedback(intentId: string, success: boolean): Promise<void> {
198
+ const intent = this.intents.get(intentId);
199
+ if (!intent) return;
200
+
201
+ const alpha = 0.1;
202
+ intent.metadata.successRate = alpha * (success ? 1 : 0) + (1 - alpha) * intent.metadata.successRate;
203
+
204
+ const lastRoute = this.routeHistory.find(r => r.intentId === intentId);
205
+ if (lastRoute) lastRoute.success = success;
206
+ }
207
+
208
+ /**
209
+ * Get router statistics.
210
+ */
211
+ getStats(): {
212
+ totalIntents: number;
213
+ byCategory: Record<string, number>;
214
+ topIntents: Array<{ id: string; pattern: string; usageCount: number; successRate: number }>;
215
+ recentRoutes: number;
216
+ } {
217
+ const byCategory: Record<string, number> = {};
218
+ for (const intent of this.intents.values()) {
219
+ byCategory[intent.category] = (byCategory[intent.category] ?? 0) + 1;
220
+ }
221
+
222
+ const topIntents = Array.from(this.intents.values())
223
+ .sort((a, b) => b.metadata.usageCount - a.metadata.usageCount)
224
+ .slice(0, 5)
225
+ .map(i => ({ id: i.id, pattern: i.pattern, usageCount: i.metadata.usageCount, successRate: i.metadata.successRate }));
226
+
227
+ return { totalIntents: this.intents.size, byCategory, topIntents, recentRoutes: this.routeHistory.length };
228
+ }
229
+
230
+ listIntents(): Intent[] {
231
+ return Array.from(this.intents.values()).sort((a, b) => b.priority - a.priority);
232
+ }
233
+
234
+ // =========================================================================
235
+ // Private Helpers
236
+ // =========================================================================
237
+
238
+ private async initializeDefaultIntents(): Promise<void> {
239
+ const defaults: Array<{ pattern: string; category: string; handlers: IntentHandler[]; priority: number; examples: string[] }> = [
240
+ { pattern: 'write code implement function', category: 'coding', handlers: [{ type: 'agent', name: 'coder', weight: 1.0 }], priority: 10, examples: ['create a function', 'implement feature'] },
241
+ { pattern: 'review code analyze quality', category: 'coding', handlers: [{ type: 'agent', name: 'reviewer', weight: 1.0 }], priority: 10, examples: ['review my code', 'check for bugs'] },
242
+ { pattern: 'test write unit test', category: 'testing', handlers: [{ type: 'agent', name: 'tester', weight: 1.0 }], priority: 10, examples: ['write tests', 'add unit tests'] },
243
+ { pattern: 'search find research', category: 'research', handlers: [{ type: 'agent', name: 'researcher', weight: 1.0 }, { type: 'tool', name: 'WebSearch', weight: 0.8 }], priority: 8, examples: ['look up', 'research topic'] },
244
+ { pattern: 'plan design architecture', category: 'planning', handlers: [{ type: 'agent', name: 'planner', weight: 1.0 }], priority: 8, examples: ['plan implementation', 'design system'] },
245
+ { pattern: 'read file open', category: 'files', handlers: [{ type: 'tool', name: 'Read', weight: 1.0 }], priority: 5, examples: ['show me file', 'read content'] },
246
+ { pattern: 'edit modify change', category: 'files', handlers: [{ type: 'tool', name: 'Edit', weight: 1.0 }], priority: 5, examples: ['change this', 'update file'] },
247
+ { pattern: 'search grep find', category: 'files', handlers: [{ type: 'tool', name: 'Grep', weight: 1.0 }, { type: 'tool', name: 'Glob', weight: 0.8 }], priority: 5, examples: ['find in files', 'search codebase'] },
248
+ { pattern: 'commit git save', category: 'git', handlers: [{ type: 'skill', name: 'commit', weight: 1.0 }], priority: 7, examples: ['commit changes', 'save to git'] },
249
+ { pattern: 'swarm coordinate agents', category: 'swarm', handlers: [{ type: 'agent', name: 'hierarchical-coordinator', weight: 1.0 }], priority: 9, examples: ['run swarm', 'coordinate agents'] },
250
+ ];
251
+
252
+ for (const def of defaults) {
253
+ await this.registerIntent(def.pattern, def.category, def.handlers, { priority: def.priority, examples: def.examples });
254
+ }
255
+ }
256
+
257
+ private generateEmbedding(text: string): Float32Array {
258
+ const embedding = new Float32Array(this.dimensions);
259
+ const normalized = text.toLowerCase();
260
+ let hash = 0;
261
+ for (let i = 0; i < normalized.length; i++) { hash = ((hash << 5) - hash) + normalized.charCodeAt(i); hash = hash & hash; }
262
+ for (let i = 0; i < this.dimensions; i++) { embedding[i] = Math.sin(hash * (i + 1) * 0.001) * 0.5 + 0.5; }
263
+ let norm = 0;
264
+ for (let i = 0; i < this.dimensions; i++) norm += embedding[i] * embedding[i];
265
+ norm = Math.sqrt(norm);
266
+ for (let i = 0; i < this.dimensions; i++) embedding[i] /= norm;
267
+ return embedding;
268
+ }
269
+ }
270
+
271
+ // ============================================================================
272
+ // Plugin Definition
273
+ // ============================================================================
274
+
275
+ let routerInstance: IntentRouter | null = null;
276
+
277
+ async function getRouter(): Promise<IntentRouter> {
278
+ if (!routerInstance) {
279
+ routerInstance = new IntentRouter({ defaultHandler: { type: 'agent', name: 'general-purpose', weight: 0.5 } });
280
+ await routerInstance.initialize();
281
+ }
282
+ return routerInstance;
283
+ }
284
+
285
+ export const intentRouterPlugin = new PluginBuilder('intent-router', '1.0.0')
286
+ .withDescription('Smart intent → handler routing using @ruvector/wasm HNSW (<1ms)')
287
+ .withAuthor('Claude Flow Team')
288
+ .withTags(['routing', 'intent', 'semantic', 'ruvector', 'hnsw'])
289
+ .withMCPTools([
290
+ new MCPToolBuilder('intent-route')
291
+ .withDescription('Route a query to best handlers (<1ms)')
292
+ .addStringParam('query', 'User query or intent', { required: true })
293
+ .withHandler(async (params) => {
294
+ try {
295
+ const router = await getRouter();
296
+ const result = await router.route(params.query as string);
297
+ const handlersOutput = result.handlers.map((h, i) => ` ${i + 1}. [${h.type}] ${h.name} (${(h.score * 100).toFixed(0)}%)`).join('\n');
298
+ return { content: [{ type: 'text', text: `🎯 **${result.intent.pattern}** (${(result.confidence * 100).toFixed(0)}%)\n\n**Handlers:**\n${handlersOutput}` }] };
299
+ } catch (error) {
300
+ return { content: [{ type: 'text', text: `❌ Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
301
+ }
302
+ })
303
+ .build(),
304
+
305
+ new MCPToolBuilder('intent-register')
306
+ .withDescription('Register a new intent')
307
+ .addStringParam('pattern', 'Intent pattern', { required: true })
308
+ .addStringParam('category', 'Category', { required: true })
309
+ .addStringParam('handlers', 'JSON handlers [{type, name, weight}]', { required: true })
310
+ .withHandler(async (params) => {
311
+ try {
312
+ const router = await getRouter();
313
+ const handlers = JSON.parse(params.handlers as string) as IntentHandler[];
314
+ const intent = await router.registerIntent(params.pattern as string, params.category as string, handlers);
315
+ return { content: [{ type: 'text', text: `✅ Registered: ${intent.id}` }] };
316
+ } catch (error) {
317
+ return { content: [{ type: 'text', text: `❌ Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
318
+ }
319
+ })
320
+ .build(),
321
+
322
+ new MCPToolBuilder('intent-stats')
323
+ .withDescription('Get router statistics')
324
+ .withHandler(async () => {
325
+ const router = await getRouter();
326
+ const stats = router.getStats();
327
+ return { content: [{ type: 'text', text: `📊 **Intent Router:**\n\n**Intents:** ${stats.totalIntents}\n**Routes:** ${stats.recentRoutes}\n**Backend:** @ruvector/wasm HNSW` }] };
328
+ })
329
+ .build(),
330
+ ])
331
+ .withHooks([
332
+ new HookBuilder(HookEvent.PreTaskExecute)
333
+ .withName('intent-auto-route')
334
+ .withDescription('Auto-route tasks')
335
+ .withPriority(HookPriority.High)
336
+ .when((ctx) => (ctx.data as { autoRoute?: boolean; query?: string } | undefined)?.autoRoute === true)
337
+ .handle(async (ctx) => {
338
+ const data = ctx.data as { query: string };
339
+ try {
340
+ const router = await getRouter();
341
+ const result = await router.route(data.query);
342
+ return { success: true, data: { ...data, routedIntent: result.intent.id, routedHandlers: result.handlers }, modified: true };
343
+ } catch { return { success: true }; }
344
+ })
345
+ .build(),
346
+ ])
347
+ .onInitialize(async (ctx) => {
348
+ ctx.logger.info('Intent Router initializing with @ruvector/wasm...');
349
+ const router = await getRouter();
350
+ ctx.logger.info(`Intent Router ready - ${router.listIntents().length} intents, HNSW enabled`);
351
+ })
352
+ .build();
353
+
354
+ export default intentRouterPlugin;