agentic-qe 2.5.7 → 2.5.9

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 (98) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +1 -1
  3. package/dist/agents/BaseAgent.d.ts +231 -4
  4. package/dist/agents/BaseAgent.d.ts.map +1 -1
  5. package/dist/agents/BaseAgent.js +535 -5
  6. package/dist/agents/BaseAgent.js.map +1 -1
  7. package/dist/agents/CoverageAnalyzerAgent.d.ts +20 -23
  8. package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -1
  9. package/dist/agents/CoverageAnalyzerAgent.js +95 -145
  10. package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
  11. package/dist/agents/QualityAnalyzerAgent.d.ts +2 -2
  12. package/dist/agents/QualityAnalyzerAgent.d.ts.map +1 -1
  13. package/dist/agents/QualityAnalyzerAgent.js.map +1 -1
  14. package/dist/agents/QualityGateAgent.d.ts +35 -18
  15. package/dist/agents/QualityGateAgent.d.ts.map +1 -1
  16. package/dist/agents/QualityGateAgent.js +72 -97
  17. package/dist/agents/QualityGateAgent.js.map +1 -1
  18. package/dist/agents/TestGeneratorAgent.d.ts +5 -0
  19. package/dist/agents/TestGeneratorAgent.d.ts.map +1 -1
  20. package/dist/agents/TestGeneratorAgent.js +38 -0
  21. package/dist/agents/TestGeneratorAgent.js.map +1 -1
  22. package/dist/agents/index.d.ts +1 -1
  23. package/dist/agents/index.d.ts.map +1 -1
  24. package/dist/agents/index.js +17 -4
  25. package/dist/agents/index.js.map +1 -1
  26. package/dist/core/memory/HNSWVectorMemory.js +1 -1
  27. package/dist/core/memory/RuVectorPatternStore.d.ts +90 -0
  28. package/dist/core/memory/RuVectorPatternStore.d.ts.map +1 -1
  29. package/dist/core/memory/RuVectorPatternStore.js +209 -0
  30. package/dist/core/memory/RuVectorPatternStore.js.map +1 -1
  31. package/dist/learning/FederatedManager.d.ts +232 -0
  32. package/dist/learning/FederatedManager.d.ts.map +1 -0
  33. package/dist/learning/FederatedManager.js +489 -0
  34. package/dist/learning/FederatedManager.js.map +1 -0
  35. package/dist/learning/HNSWPatternAdapter.d.ts +117 -0
  36. package/dist/learning/HNSWPatternAdapter.d.ts.map +1 -0
  37. package/dist/learning/HNSWPatternAdapter.js +262 -0
  38. package/dist/learning/HNSWPatternAdapter.js.map +1 -0
  39. package/dist/learning/LearningEngine.d.ts +27 -0
  40. package/dist/learning/LearningEngine.d.ts.map +1 -1
  41. package/dist/learning/LearningEngine.js +75 -1
  42. package/dist/learning/LearningEngine.js.map +1 -1
  43. package/dist/learning/PatternCurator.d.ts +217 -0
  44. package/dist/learning/PatternCurator.d.ts.map +1 -0
  45. package/dist/learning/PatternCurator.js +393 -0
  46. package/dist/learning/PatternCurator.js.map +1 -0
  47. package/dist/learning/index.d.ts +6 -0
  48. package/dist/learning/index.d.ts.map +1 -1
  49. package/dist/learning/index.js +16 -1
  50. package/dist/learning/index.js.map +1 -1
  51. package/dist/learning/types.d.ts +4 -0
  52. package/dist/learning/types.d.ts.map +1 -1
  53. package/dist/mcp/server-instructions.d.ts +1 -1
  54. package/dist/mcp/server-instructions.js +1 -1
  55. package/dist/mcp/tools.d.ts +6 -0
  56. package/dist/mcp/tools.d.ts.map +1 -1
  57. package/dist/mcp/tools.js +121 -0
  58. package/dist/mcp/tools.js.map +1 -1
  59. package/dist/memory/HNSWPatternStore.d.ts +176 -0
  60. package/dist/memory/HNSWPatternStore.d.ts.map +1 -0
  61. package/dist/memory/HNSWPatternStore.js +392 -0
  62. package/dist/memory/HNSWPatternStore.js.map +1 -0
  63. package/dist/memory/index.d.ts +8 -0
  64. package/dist/memory/index.d.ts.map +1 -0
  65. package/dist/memory/index.js +13 -0
  66. package/dist/memory/index.js.map +1 -0
  67. package/dist/providers/HybridRouter.d.ts +85 -4
  68. package/dist/providers/HybridRouter.d.ts.map +1 -1
  69. package/dist/providers/HybridRouter.js +332 -10
  70. package/dist/providers/HybridRouter.js.map +1 -1
  71. package/dist/providers/LLMBaselineTracker.d.ts +120 -0
  72. package/dist/providers/LLMBaselineTracker.d.ts.map +1 -0
  73. package/dist/providers/LLMBaselineTracker.js +305 -0
  74. package/dist/providers/LLMBaselineTracker.js.map +1 -0
  75. package/dist/providers/OpenRouterProvider.d.ts +26 -0
  76. package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
  77. package/dist/providers/OpenRouterProvider.js +75 -6
  78. package/dist/providers/OpenRouterProvider.js.map +1 -1
  79. package/dist/providers/RuVectorClient.d.ts +259 -0
  80. package/dist/providers/RuVectorClient.d.ts.map +1 -0
  81. package/dist/providers/RuVectorClient.js +416 -0
  82. package/dist/providers/RuVectorClient.js.map +1 -0
  83. package/dist/providers/RuvllmPatternCurator.d.ts +116 -0
  84. package/dist/providers/RuvllmPatternCurator.d.ts.map +1 -0
  85. package/dist/providers/RuvllmPatternCurator.js +323 -0
  86. package/dist/providers/RuvllmPatternCurator.js.map +1 -0
  87. package/dist/providers/RuvllmProvider.d.ts +233 -1
  88. package/dist/providers/RuvllmProvider.d.ts.map +1 -1
  89. package/dist/providers/RuvllmProvider.js +781 -11
  90. package/dist/providers/RuvllmProvider.js.map +1 -1
  91. package/dist/providers/index.d.ts +5 -1
  92. package/dist/providers/index.d.ts.map +1 -1
  93. package/dist/providers/index.js +12 -2
  94. package/dist/providers/index.js.map +1 -1
  95. package/dist/utils/ruvllm-loader.d.ts +98 -1
  96. package/dist/utils/ruvllm-loader.d.ts.map +1 -1
  97. package/dist/utils/ruvllm-loader.js.map +1 -1
  98. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
  /**
3
3
  * BaseAgent - Abstract base class for all QE agents
4
4
  * Phase 2 B1.2: Decomposed with strategy pattern (~500 LOC target)
5
+ * Phase 0: LLM Provider integration with RuvLLM support
5
6
  */
6
7
  Object.defineProperty(exports, "__esModule", { value: true });
7
8
  exports.BaseAgentFactory = exports.BaseAgent = exports.validateLearningConfig = exports.isSwarmMemoryManager = void 0;
@@ -12,9 +13,15 @@ const MemoryStoreAdapter_1 = require("../adapters/MemoryStoreAdapter");
12
13
  const PerformanceTracker_1 = require("../learning/PerformanceTracker");
13
14
  const SwarmMemoryManager_1 = require("../core/memory/SwarmMemoryManager");
14
15
  const LearningEngine_1 = require("../learning/LearningEngine");
16
+ // Federated Learning (Phase 0 M0.5 - Team-wide pattern sharing)
17
+ const FederatedManager_1 = require("../learning/FederatedManager");
15
18
  const AgentLifecycleManager_1 = require("./lifecycle/AgentLifecycleManager");
16
19
  const AgentCoordinator_1 = require("./coordination/AgentCoordinator");
17
20
  const AgentMemoryService_1 = require("./memory/AgentMemoryService");
21
+ const RuvllmProvider_1 = require("../providers/RuvllmProvider");
22
+ const LLMProviderFactory_1 = require("../providers/LLMProviderFactory");
23
+ // HybridRouter with RuVector cache (Phase 0.5 - GNN Self-Learning)
24
+ const HybridRouter_1 = require("../providers/HybridRouter");
18
25
  const adapters_1 = require("./adapters");
19
26
  // Extracted utilities (B1.2)
20
27
  const utils_1 = require("./utils");
@@ -24,13 +31,16 @@ class BaseAgent extends events_1.EventEmitter {
24
31
  constructor(config) {
25
32
  super();
26
33
  this.performanceMetrics = { tasksCompleted: 0, averageExecutionTime: 0, errorCount: 0, lastActivity: new Date() };
34
+ this.federatedInitialized = false;
27
35
  this.agentId = { id: config.id || (0, utils_1.generateAgentId)(config.type), type: config.type, created: new Date() };
28
- this.capabilities = new Map(config.capabilities.map(cap => [cap.name, cap]));
36
+ this.capabilities = new Map((config.capabilities || []).map(cap => [cap.name, cap]));
29
37
  this.context = config.context;
30
38
  this.memoryStore = config.memoryStore;
31
- this.eventBus = config.eventBus;
39
+ this.eventBus = config.eventBus || new events_1.EventEmitter();
32
40
  this.enableLearning = config.enableLearning ?? true;
33
41
  this.learningConfig = config.learningConfig;
42
+ // LLM configuration (Phase 0 - default enabled with RuvLLM)
43
+ this.llmConfig = config.llm ?? { enabled: true, preferredProvider: 'ruvllm' };
34
44
  // Early validation (Issue #137)
35
45
  const validation = (0, utils_1.validateLearningConfig)(config);
36
46
  if (!validation.valid && validation.warning) {
@@ -91,6 +101,10 @@ class BaseAgent extends events_1.EventEmitter {
91
101
  else if (this.enableLearning) {
92
102
  console.warn(`[${this.agentId.id}] Learning disabled: memoryStore is ${this.memoryStore.constructor.name}`);
93
103
  }
104
+ // Initialize LLM Provider (Phase 0 - RuvLLM Integration)
105
+ await this.initializeLLMProvider();
106
+ // Initialize Federated Learning (Phase 0 M0.5)
107
+ await this.initializeFederatedLearning();
94
108
  await this.initializeComponents();
95
109
  await this.executeHook('post-initialization');
96
110
  this.coordinator.emitEvent('agent.initialized', { agentId: this.agentId });
@@ -144,6 +158,8 @@ class BaseAgent extends events_1.EventEmitter {
144
158
  await this.executeHook('pre-termination');
145
159
  await this.saveState();
146
160
  await this.cleanup();
161
+ await this.cleanupLLM(); // Phase 0: Cleanup LLM resources
162
+ await this.cleanupFederated(); // Phase 0 M0.5: Cleanup federated learning
147
163
  this.coordinator.clearAllHandlers();
148
164
  },
149
165
  onPostTermination: async () => {
@@ -356,18 +372,34 @@ class BaseAgent extends events_1.EventEmitter {
356
372
  duration: executionTime, metadata: { taskId: data.assignment.id, accuracy: result.accuracy, metrics: this.extractTaskMetrics(data.result) }
357
373
  });
358
374
  }
375
+ // Share successful patterns with team via federated learning (Phase 0 M0.5)
376
+ if (result.valid && this.federatedInitialized && this.llmProvider) {
377
+ try {
378
+ // Generate embedding for the task pattern
379
+ const taskDescription = `${data.assignment.task.type}: ${JSON.stringify(data.assignment.task.payload || {}).slice(0, 200)}`;
380
+ const embedding = await this.llmEmbed(taskDescription);
381
+ await this.shareLearnedPattern({
382
+ embedding,
383
+ quality: result.accuracy ?? 0.8,
384
+ category: data.assignment.task.type,
385
+ });
386
+ }
387
+ catch {
388
+ // Pattern sharing failed - non-critical, continue
389
+ }
390
+ }
359
391
  this.emitEvent('hook.post-task.completed', { agentId: this.agentId, result });
360
392
  }
361
393
  async onTaskError(data) {
362
394
  const executionTime = this.taskStartTime ? Date.now() - this.taskStartTime : 0;
363
395
  await this.storeMemory(`error:${data.assignment.id}`, {
364
396
  error: { message: data.error.message, name: data.error.name },
365
- assignment: { id: data.assignment.id, taskType: data.assignment.task.type },
397
+ assignment: { id: data.assignment.id, taskType: data.assignment.task?.type ?? 'unknown' },
366
398
  timestamp: new Date(), agentId: this.agentId.id
367
399
  });
368
400
  if (this.strategies.lifecycle.onTaskError)
369
401
  await this.strategies.lifecycle.onTaskError(data);
370
- if (this.strategies.learning?.recordExecution) {
402
+ if (this.strategies.learning?.recordExecution && data.assignment.task) {
371
403
  await this.strategies.learning.recordExecution({
372
404
  task: data.assignment.task, error: data.error, success: false,
373
405
  duration: executionTime, metadata: { taskId: data.assignment.id }
@@ -383,7 +415,8 @@ class BaseAgent extends events_1.EventEmitter {
383
415
  await this[method](data);
384
416
  }
385
417
  catch (error) {
386
- console.error(`Hook ${hookName} failed:`, error);
418
+ // Use warn - hooks are optional and failures shouldn't break agent operation
419
+ console.warn(`Hook ${hookName} failed:`, error);
387
420
  }
388
421
  }
389
422
  setupEventHandlers() {
@@ -437,6 +470,503 @@ class BaseAgent extends events_1.EventEmitter {
437
470
  async saveState() {
438
471
  await this.memoryService.saveState({ performanceMetrics: this.performanceMetrics, timestamp: new Date() });
439
472
  }
473
+ // ============================================
474
+ // LLM Provider Methods (Phase 0 - RuvLLM Integration)
475
+ // ============================================
476
+ /**
477
+ * Initialize LLM provider for agent use
478
+ * Supports RuvLLM (local), Claude, OpenRouter, and HybridRouter with RuVector cache
479
+ */
480
+ async initializeLLMProvider() {
481
+ if (!this.llmConfig.enabled) {
482
+ console.log(`[${this.agentId.id}] LLM disabled by configuration`);
483
+ return;
484
+ }
485
+ try {
486
+ // If a provider was injected, use it directly
487
+ if (this.llmConfig.provider) {
488
+ this.llmProvider = this.llmConfig.provider;
489
+ console.log(`[${this.agentId.id}] Using injected LLM provider`);
490
+ return;
491
+ }
492
+ // Phase 0.5: Create HybridRouter with RuVector GNN cache for intelligent routing
493
+ if (this.llmConfig.enableHybridRouter || this.llmConfig.preferredProvider === 'hybrid') {
494
+ const hybridConfig = {
495
+ // RuVector cache configuration (GNN self-learning)
496
+ ruvector: {
497
+ enabled: true,
498
+ baseUrl: this.llmConfig.ruvectorCache?.baseUrl || 'http://localhost:8080',
499
+ cacheThreshold: this.llmConfig.ruvectorCache?.cacheThreshold ?? 0.85,
500
+ learningEnabled: this.llmConfig.ruvectorCache?.learningEnabled ?? true,
501
+ loraRank: this.llmConfig.ruvectorCache?.loraRank ?? 8,
502
+ ewcEnabled: this.llmConfig.ruvectorCache?.ewcEnabled ?? true,
503
+ ...this.llmConfig.ruvectorCache,
504
+ },
505
+ // Local LLM via ruvllm
506
+ ruvllm: {
507
+ name: `${this.agentId.id}-ruvllm`,
508
+ enableSessions: this.llmConfig.enableSessions ?? true,
509
+ enableTRM: true,
510
+ enableSONA: true,
511
+ ...this.llmConfig.ruvllm,
512
+ },
513
+ // Routing strategy
514
+ defaultStrategy: this.llmConfig.hybridRouterConfig?.defaultStrategy || HybridRouter_1.RoutingStrategy.BALANCED,
515
+ ...this.llmConfig.hybridRouterConfig,
516
+ };
517
+ this.hybridRouter = new HybridRouter_1.HybridRouter(hybridConfig);
518
+ await this.hybridRouter.initialize();
519
+ this.llmProvider = this.hybridRouter;
520
+ console.log(`[${this.agentId.id}] HybridRouter initialized with RuVector GNN cache`);
521
+ return;
522
+ }
523
+ // Create RuvLLM provider directly (preferred for local inference)
524
+ if (this.llmConfig.preferredProvider === 'ruvllm' || !this.llmConfig.preferredProvider) {
525
+ const ruvllmConfig = {
526
+ name: `${this.agentId.id}-ruvllm`,
527
+ enableSessions: this.llmConfig.enableSessions ?? true,
528
+ enableTRM: true,
529
+ enableSONA: true,
530
+ debug: false,
531
+ ...this.llmConfig.ruvllm
532
+ };
533
+ this.llmProvider = new RuvllmProvider_1.RuvllmProvider(ruvllmConfig);
534
+ await this.llmProvider.initialize();
535
+ // Create session for this agent if sessions enabled
536
+ if (this.llmConfig.enableSessions) {
537
+ const ruvllm = this.llmProvider;
538
+ const session = ruvllm.createSession();
539
+ this.llmSessionId = session.id;
540
+ console.log(`[${this.agentId.id}] LLM session created: ${this.llmSessionId}`);
541
+ }
542
+ console.log(`[${this.agentId.id}] RuvLLM provider initialized`);
543
+ return;
544
+ }
545
+ // Use factory for other providers (Claude, OpenRouter)
546
+ this.llmFactory = new LLMProviderFactory_1.LLMProviderFactory(this.llmConfig.factoryConfig || {});
547
+ await this.llmFactory.initialize();
548
+ this.llmProvider = this.llmFactory.getProvider(this.llmConfig.preferredProvider);
549
+ if (!this.llmProvider) {
550
+ console.warn(`[${this.agentId.id}] Preferred provider ${this.llmConfig.preferredProvider} not available, trying auto-select`);
551
+ this.llmProvider = this.llmFactory.selectBestProvider();
552
+ }
553
+ if (this.llmProvider) {
554
+ console.log(`[${this.agentId.id}] LLM provider initialized: ${this.llmConfig.preferredProvider}`);
555
+ }
556
+ else {
557
+ console.warn(`[${this.agentId.id}] No LLM provider available`);
558
+ }
559
+ }
560
+ catch (error) {
561
+ // Use warn instead of error - this is expected fallback behavior, not a failure
562
+ console.warn(`[${this.agentId.id}] LLM initialization failed:`, error.message);
563
+ // Don't throw - agent can still work without LLM (algorithmic fallback)
564
+ }
565
+ }
566
+ /**
567
+ * Initialize Federated Learning for team-wide pattern sharing
568
+ * Phase 0 M0.5 - Reduces Claude Code dependency through collective learning
569
+ */
570
+ async initializeFederatedLearning() {
571
+ if (!this.llmConfig.enableFederated) {
572
+ return;
573
+ }
574
+ try {
575
+ // Use shared FederatedManager or create new one
576
+ if (this.llmConfig.federatedManager) {
577
+ this.federatedManager = this.llmConfig.federatedManager;
578
+ }
579
+ else {
580
+ this.federatedManager = new FederatedManager_1.FederatedManager(this.llmConfig.federatedConfig);
581
+ await this.federatedManager.initialize();
582
+ }
583
+ // Register this agent for federated learning
584
+ this.ephemeralAgent = this.federatedManager.registerAgent(this.agentId.id);
585
+ this.federatedInitialized = true;
586
+ console.log(`[${this.agentId.id}] Federated learning initialized`);
587
+ // Sync with existing team knowledge on startup
588
+ try {
589
+ await this.federatedManager.syncFromTeam(this.agentId.id);
590
+ console.log(`[${this.agentId.id}] Synced with team knowledge`);
591
+ }
592
+ catch {
593
+ // First agent or no prior knowledge - expected
594
+ }
595
+ }
596
+ catch (error) {
597
+ // Use warn instead of error - this is expected fallback behavior
598
+ console.warn(`[${this.agentId.id}] Federated learning initialization failed:`, error.message);
599
+ // Don't throw - agent can work without federated learning
600
+ }
601
+ }
602
+ /**
603
+ * Check if federated learning is available
604
+ */
605
+ hasFederatedLearning() {
606
+ return this.federatedInitialized && this.federatedManager !== undefined;
607
+ }
608
+ /**
609
+ * Share a learned pattern with the team via federated learning
610
+ * Call this when the agent learns something useful (e.g., after successful task)
611
+ *
612
+ * @param pattern - The pattern to share (embedding, quality score, category)
613
+ */
614
+ async shareLearnedPattern(pattern) {
615
+ if (!this.federatedManager || !this.federatedInitialized) {
616
+ return;
617
+ }
618
+ const fullPattern = {
619
+ ...pattern,
620
+ id: `pattern-${this.agentId.id}-${Date.now()}`,
621
+ sourceAgent: this.agentId.id,
622
+ timestamp: Date.now(),
623
+ };
624
+ await this.federatedManager.sharePattern(this.agentId.id, fullPattern);
625
+ }
626
+ /**
627
+ * Sync this agent with team-wide learned knowledge
628
+ * Call this periodically or before complex tasks
629
+ */
630
+ async syncWithTeam() {
631
+ if (!this.federatedManager || !this.federatedInitialized) {
632
+ return;
633
+ }
634
+ await this.federatedManager.syncFromTeam(this.agentId.id);
635
+ }
636
+ /**
637
+ * Submit this agent's learning updates to the team
638
+ * Call after completing a batch of tasks
639
+ */
640
+ async submitLearningUpdate() {
641
+ if (!this.federatedManager || !this.federatedInitialized) {
642
+ return;
643
+ }
644
+ await this.federatedManager.submitAgentUpdate(this.agentId.id);
645
+ }
646
+ /**
647
+ * Get federated learning metrics
648
+ */
649
+ getFederatedMetrics() {
650
+ if (!this.federatedManager) {
651
+ return null;
652
+ }
653
+ return this.federatedManager.getMetrics();
654
+ }
655
+ /**
656
+ * Check if LLM is available for this agent
657
+ */
658
+ hasLLM() {
659
+ return this.llmProvider !== undefined;
660
+ }
661
+ /**
662
+ * Get LLM provider (for advanced usage)
663
+ */
664
+ getLLMProvider() {
665
+ return this.llmProvider;
666
+ }
667
+ /**
668
+ * Make an LLM completion call
669
+ * Uses RuvLLM's session management for 50% latency reduction on multi-turn
670
+ *
671
+ * @param prompt - The prompt to send to the LLM
672
+ * @param options - Additional completion options
673
+ * @returns The LLM response text
674
+ * @throws Error if LLM is not available
675
+ */
676
+ async llmComplete(prompt, options) {
677
+ if (!this.llmProvider) {
678
+ throw new Error(`[${this.agentId.id}] LLM not available - initialize agent first`);
679
+ }
680
+ const completionOptions = {
681
+ model: options?.model || this.llmConfig.ruvllm?.defaultModel || 'llama-3.2-3b-instruct',
682
+ messages: [{ role: 'user', content: prompt }],
683
+ maxTokens: options?.maxTokens,
684
+ temperature: options?.temperature,
685
+ stream: options?.stream,
686
+ metadata: {
687
+ ...options?.metadata,
688
+ sessionId: this.llmSessionId, // Use session for faster multi-turn
689
+ agentId: this.agentId.id,
690
+ agentType: this.agentId.type
691
+ }
692
+ };
693
+ const response = await this.llmProvider.complete(completionOptions);
694
+ // Extract text from response
695
+ const text = response.content
696
+ .filter(block => block.type === 'text')
697
+ .map(block => block.text)
698
+ .join('\n');
699
+ return text;
700
+ }
701
+ /**
702
+ * Make a batch LLM completion call (4x throughput)
703
+ * Uses RuvLLM's native batch API for parallel processing
704
+ *
705
+ * @param prompts - Array of prompts to process in parallel
706
+ * @param options - Shared completion options
707
+ * @returns Array of response texts in same order as prompts
708
+ */
709
+ async llmBatchComplete(prompts, options) {
710
+ if (!this.llmProvider) {
711
+ throw new Error(`[${this.agentId.id}] LLM not available - initialize agent first`);
712
+ }
713
+ // Check if provider supports batch (RuvLLM does)
714
+ const ruvllm = this.llmProvider;
715
+ if (typeof ruvllm.batchComplete === 'function') {
716
+ const defaultModel = options?.model || this.llmConfig.ruvllm?.defaultModel || 'llama-3.2-3b-instruct';
717
+ const requests = prompts.map(prompt => ({
718
+ model: defaultModel,
719
+ messages: [{ role: 'user', content: prompt }],
720
+ maxTokens: options?.maxTokens,
721
+ temperature: options?.temperature,
722
+ metadata: {
723
+ ...options?.metadata,
724
+ agentId: this.agentId.id,
725
+ agentType: this.agentId.type
726
+ }
727
+ }));
728
+ const responses = await ruvllm.batchComplete(requests);
729
+ return responses.map(response => response.content
730
+ .filter(block => block.type === 'text')
731
+ .map(block => block.text)
732
+ .join('\n'));
733
+ }
734
+ // Fallback: sequential processing for non-batch providers
735
+ console.warn(`[${this.agentId.id}] Provider doesn't support batch, using sequential`);
736
+ const results = [];
737
+ for (const prompt of prompts) {
738
+ results.push(await this.llmComplete(prompt, options));
739
+ }
740
+ return results;
741
+ }
742
+ /**
743
+ * Generate embeddings for text
744
+ * Uses RuvLLM's SIMD-optimized embedding generation
745
+ *
746
+ * @param text - Text to embed
747
+ * @returns Embedding vector
748
+ */
749
+ async llmEmbed(text) {
750
+ if (!this.llmProvider) {
751
+ throw new Error(`[${this.agentId.id}] LLM not available - initialize agent first`);
752
+ }
753
+ const response = await this.llmProvider.embed({ text });
754
+ return response.embedding || [];
755
+ }
756
+ /**
757
+ * Chat within agent's session (50% faster for multi-turn)
758
+ * Only works with RuvLLM provider with sessions enabled
759
+ *
760
+ * @param input - User input to chat
761
+ * @returns Assistant response
762
+ */
763
+ async llmChat(input) {
764
+ if (!this.llmProvider) {
765
+ throw new Error(`[${this.agentId.id}] LLM not available`);
766
+ }
767
+ if (!this.llmSessionId) {
768
+ // Fallback to regular complete if no session
769
+ return this.llmComplete(input);
770
+ }
771
+ const ruvllm = this.llmProvider;
772
+ if (typeof ruvllm.sessionChat === 'function') {
773
+ return ruvllm.sessionChat(this.llmSessionId, input);
774
+ }
775
+ // Fallback
776
+ return this.llmComplete(input);
777
+ }
778
+ /**
779
+ * Get routing decision for observability
780
+ * Shows which model was selected and why
781
+ */
782
+ getLLMRoutingDecision(input) {
783
+ if (!this.llmProvider) {
784
+ return null;
785
+ }
786
+ const ruvllm = this.llmProvider;
787
+ if (typeof ruvllm.getRoutingDecision === 'function') {
788
+ return ruvllm.getRoutingDecision(input);
789
+ }
790
+ return null;
791
+ }
792
+ /**
793
+ * Get LLM usage statistics for this agent
794
+ */
795
+ getLLMStats() {
796
+ return {
797
+ available: this.hasLLM(),
798
+ sessionId: this.llmSessionId,
799
+ provider: this.hybridRouter ? 'hybrid' : (this.llmProvider ? 'ruvllm' : undefined),
800
+ hasRuVectorCache: this.hasRuVectorCache(),
801
+ };
802
+ }
803
+ // ============================================
804
+ // RuVector Cache Methods (Phase 0.5 - GNN Self-Learning)
805
+ // ============================================
806
+ /**
807
+ * Check if RuVector GNN cache is available
808
+ */
809
+ hasRuVectorCache() {
810
+ return this.hybridRouter !== undefined;
811
+ }
812
+ /**
813
+ * Get RuVector cache metrics
814
+ * Returns cache hit rate, pattern count, and learning metrics
815
+ */
816
+ async getRuVectorMetrics() {
817
+ if (!this.hybridRouter) {
818
+ return null;
819
+ }
820
+ try {
821
+ return await this.hybridRouter.getRuVectorMetrics();
822
+ }
823
+ catch {
824
+ return null;
825
+ }
826
+ }
827
+ /**
828
+ * Get cache hit rate for this agent's requests
829
+ */
830
+ getCacheHitRate() {
831
+ if (!this.hybridRouter) {
832
+ return 0;
833
+ }
834
+ return this.hybridRouter.getCacheHitRate();
835
+ }
836
+ /**
837
+ * Get routing statistics including cache savings
838
+ */
839
+ getRoutingStats() {
840
+ if (!this.hybridRouter) {
841
+ return {
842
+ totalDecisions: 0,
843
+ localDecisions: 0,
844
+ cloudDecisions: 0,
845
+ cacheHits: 0,
846
+ cacheMisses: 0,
847
+ cacheHitRate: 0,
848
+ averageLocalLatency: 0,
849
+ averageCloudLatency: 0,
850
+ successRate: 0,
851
+ };
852
+ }
853
+ return this.hybridRouter.getRoutingStats();
854
+ }
855
+ /**
856
+ * Force learning consolidation in the RuVector cache
857
+ * Triggers LoRA adaptation and EWC++ protection
858
+ */
859
+ async forceRuVectorLearn() {
860
+ if (!this.hybridRouter) {
861
+ return { success: false, error: 'RuVector not enabled' };
862
+ }
863
+ return await this.hybridRouter.forceRuVectorLearn();
864
+ }
865
+ /**
866
+ * Get cost savings report from using RuVector cache
867
+ */
868
+ getCostSavingsReport() {
869
+ if (!this.hybridRouter) {
870
+ return {
871
+ totalRequests: 0,
872
+ localRequests: 0,
873
+ cloudRequests: 0,
874
+ totalCost: 0,
875
+ estimatedCloudCost: 0,
876
+ savings: 0,
877
+ savingsPercentage: 0,
878
+ cacheHits: 0,
879
+ cacheSavings: 0,
880
+ };
881
+ }
882
+ return this.hybridRouter.getCostSavingsReport();
883
+ }
884
+ /**
885
+ * Make an LLM call with automatic caching and learning
886
+ * Uses RuVector GNN cache when available for sub-ms pattern matching
887
+ *
888
+ * @param prompt - The prompt to process
889
+ * @param options - Additional options
890
+ * @returns The response text
891
+ */
892
+ async llmCompleteWithLearning(prompt, options) {
893
+ if (!this.llmProvider) {
894
+ throw new Error(`[${this.agentId.id}] LLM not available - initialize agent first`);
895
+ }
896
+ // If using HybridRouter, it automatically handles caching and learning
897
+ if (this.hybridRouter) {
898
+ const completionOptions = {
899
+ model: options?.model || 'auto',
900
+ messages: [{ role: 'user', content: prompt }],
901
+ maxTokens: options?.maxTokens,
902
+ temperature: options?.temperature,
903
+ metadata: {
904
+ ...options?.metadata,
905
+ agentId: this.agentId.id,
906
+ agentType: this.agentId.type,
907
+ complexity: options?.complexity,
908
+ },
909
+ };
910
+ const response = await this.hybridRouter.complete(completionOptions);
911
+ // Extract text from response
912
+ const text = response.content
913
+ .filter(block => block.type === 'text')
914
+ .map(block => block.text)
915
+ .join('\n');
916
+ return {
917
+ response: text,
918
+ source: response.metadata?.source || 'local',
919
+ confidence: response.metadata?.confidence,
920
+ };
921
+ }
922
+ // Fallback to regular completion
923
+ const text = await this.llmComplete(prompt, options);
924
+ return { response: text, source: 'local' };
925
+ }
926
+ /**
927
+ * Cleanup LLM resources on agent termination
928
+ */
929
+ async cleanupLLM() {
930
+ if (this.llmSessionId && this.llmProvider) {
931
+ const ruvllm = this.llmProvider;
932
+ if (typeof ruvllm.endSession === 'function') {
933
+ ruvllm.endSession(this.llmSessionId);
934
+ console.log(`[${this.agentId.id}] LLM session ended: ${this.llmSessionId}`);
935
+ }
936
+ }
937
+ if (this.llmProvider) {
938
+ await this.llmProvider.shutdown();
939
+ }
940
+ if (this.llmFactory) {
941
+ await this.llmFactory.shutdown();
942
+ }
943
+ }
944
+ /**
945
+ * Cleanup federated learning resources on agent termination
946
+ * Submits final learning updates and unregisters from the coordinator
947
+ */
948
+ async cleanupFederated() {
949
+ if (!this.federatedManager || !this.federatedInitialized) {
950
+ return;
951
+ }
952
+ try {
953
+ // Submit final learning updates before terminating
954
+ await this.submitLearningUpdate();
955
+ // Unregister this agent from federated learning
956
+ this.federatedManager.unregisterAgent(this.agentId.id);
957
+ console.log(`[${this.agentId.id}] Federated learning cleanup complete`);
958
+ }
959
+ catch (error) {
960
+ console.warn(`[${this.agentId.id}] Federated cleanup error:`, error.message);
961
+ }
962
+ this.federatedInitialized = false;
963
+ this.ephemeralAgent = undefined;
964
+ // Only shutdown the manager if we created it (not if it was shared)
965
+ if (!this.llmConfig.federatedManager && this.federatedManager) {
966
+ await this.federatedManager.shutdown();
967
+ this.federatedManager = undefined;
968
+ }
969
+ }
440
970
  }
441
971
  exports.BaseAgent = BaseAgent;
442
972
  class BaseAgentFactory {