agentic-qe 2.5.4 → 2.5.6

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/.claude/commands/aqe-costs.md +509 -0
  2. package/CHANGELOG.md +128 -0
  3. package/README.md +1 -1
  4. package/dist/adapters/MemoryStoreAdapter.d.ts +75 -123
  5. package/dist/adapters/MemoryStoreAdapter.d.ts.map +1 -1
  6. package/dist/adapters/MemoryStoreAdapter.js +204 -219
  7. package/dist/adapters/MemoryStoreAdapter.js.map +1 -1
  8. package/dist/agents/AccessibilityAllyAgent.d.ts.map +1 -1
  9. package/dist/agents/AccessibilityAllyAgent.js +17 -1
  10. package/dist/agents/AccessibilityAllyAgent.js.map +1 -1
  11. package/dist/agents/BaseAgent.d.ts +18 -250
  12. package/dist/agents/BaseAgent.d.ts.map +1 -1
  13. package/dist/agents/BaseAgent.js +122 -520
  14. package/dist/agents/BaseAgent.js.map +1 -1
  15. package/dist/agents/SONALifecycleManager.d.ts +226 -0
  16. package/dist/agents/SONALifecycleManager.d.ts.map +1 -0
  17. package/dist/agents/SONALifecycleManager.js +563 -0
  18. package/dist/agents/SONALifecycleManager.js.map +1 -0
  19. package/dist/agents/index.d.ts +2 -0
  20. package/dist/agents/index.d.ts.map +1 -1
  21. package/dist/agents/index.js +7 -1
  22. package/dist/agents/index.js.map +1 -1
  23. package/dist/agents/utils/generators.d.ts +30 -0
  24. package/dist/agents/utils/generators.d.ts.map +1 -0
  25. package/dist/agents/utils/generators.js +44 -0
  26. package/dist/agents/utils/generators.js.map +1 -0
  27. package/dist/agents/utils/index.d.ts +10 -0
  28. package/dist/agents/utils/index.d.ts.map +1 -0
  29. package/dist/agents/utils/index.js +19 -0
  30. package/dist/agents/utils/index.js.map +1 -0
  31. package/dist/agents/utils/validation.d.ts +72 -0
  32. package/dist/agents/utils/validation.d.ts.map +1 -0
  33. package/dist/agents/utils/validation.js +75 -0
  34. package/dist/agents/utils/validation.js.map +1 -0
  35. package/dist/core/memory/HNSWVectorMemory.js +1 -1
  36. package/dist/core/memory/SwarmMemoryManager.d.ts +114 -90
  37. package/dist/core/memory/SwarmMemoryManager.d.ts.map +1 -1
  38. package/dist/core/memory/SwarmMemoryManager.js +277 -235
  39. package/dist/core/memory/SwarmMemoryManager.js.map +1 -1
  40. package/dist/core/metrics/InferenceCostTracker.d.ts +293 -0
  41. package/dist/core/metrics/InferenceCostTracker.d.ts.map +1 -0
  42. package/dist/core/metrics/InferenceCostTracker.js +461 -0
  43. package/dist/core/metrics/InferenceCostTracker.js.map +1 -0
  44. package/dist/core/metrics/index.d.ts +1 -0
  45. package/dist/core/metrics/index.d.ts.map +1 -1
  46. package/dist/core/metrics/index.js +7 -1
  47. package/dist/core/metrics/index.js.map +1 -1
  48. package/dist/core/routing/AdaptiveModelRouter.d.ts +17 -0
  49. package/dist/core/routing/AdaptiveModelRouter.d.ts.map +1 -1
  50. package/dist/core/routing/AdaptiveModelRouter.js +117 -0
  51. package/dist/core/routing/AdaptiveModelRouter.js.map +1 -1
  52. package/dist/core/routing/ModelRules.d.ts +2 -0
  53. package/dist/core/routing/ModelRules.d.ts.map +1 -1
  54. package/dist/core/routing/ModelRules.js +82 -0
  55. package/dist/core/routing/ModelRules.js.map +1 -1
  56. package/dist/core/routing/types.d.ts +14 -1
  57. package/dist/core/routing/types.d.ts.map +1 -1
  58. package/dist/core/routing/types.js +7 -0
  59. package/dist/core/routing/types.js.map +1 -1
  60. package/dist/learning/baselines/StandardTaskSuite.d.ts.map +1 -1
  61. package/dist/learning/baselines/StandardTaskSuite.js +38 -0
  62. package/dist/learning/baselines/StandardTaskSuite.js.map +1 -1
  63. package/dist/mcp/server-instructions.d.ts +1 -1
  64. package/dist/mcp/server-instructions.js +1 -1
  65. package/dist/mcp/services/AgentRegistry.d.ts +35 -0
  66. package/dist/mcp/services/AgentRegistry.d.ts.map +1 -1
  67. package/dist/mcp/services/AgentRegistry.js +126 -1
  68. package/dist/mcp/services/AgentRegistry.js.map +1 -1
  69. package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.d.ts +8 -1
  70. package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.d.ts.map +1 -1
  71. package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.js +134 -46
  72. package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.js.map +1 -1
  73. package/dist/telemetry/metrics/collectors/cost.d.ts.map +1 -1
  74. package/dist/telemetry/metrics/collectors/cost.js +6 -0
  75. package/dist/telemetry/metrics/collectors/cost.js.map +1 -1
  76. package/dist/types/memory-interfaces.d.ts +76 -68
  77. package/dist/types/memory-interfaces.d.ts.map +1 -1
  78. package/dist/types/memory-interfaces.js +3 -0
  79. package/dist/types/memory-interfaces.js.map +1 -1
  80. package/package.json +9 -2
@@ -1,15 +1,11 @@
1
1
  "use strict";
2
2
  /**
3
3
  * BaseAgent - Abstract base class for all QE agents
4
- * Implements core lifecycle hooks, event handling, and memory access
5
- * Based on SPARC Phase 2 Pseudocode and Phase 3 Architecture
4
+ * Phase 2 B1.2: Decomposed with strategy pattern (~500 LOC target)
6
5
  */
7
6
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.BaseAgentFactory = exports.BaseAgent = void 0;
9
- exports.isSwarmMemoryManager = isSwarmMemoryManager;
10
- exports.validateLearningConfig = validateLearningConfig;
7
+ exports.BaseAgentFactory = exports.BaseAgent = exports.validateLearningConfig = exports.isSwarmMemoryManager = void 0;
11
8
  const events_1 = require("events");
12
- const SecureRandom_js_1 = require("../utils/SecureRandom.js");
13
9
  const types_1 = require("../types");
14
10
  const hooks_1 = require("../core/hooks");
15
11
  const MemoryStoreAdapter_1 = require("../adapters/MemoryStoreAdapter");
@@ -20,85 +16,27 @@ const AgentLifecycleManager_1 = require("./lifecycle/AgentLifecycleManager");
20
16
  const AgentCoordinator_1 = require("./coordination/AgentCoordinator");
21
17
  const AgentMemoryService_1 = require("./memory/AgentMemoryService");
22
18
  const adapters_1 = require("./adapters");
23
- /**
24
- * Check if a memory store is SwarmMemoryManager
25
- *
26
- * @remarks
27
- * This is a runtime check using instanceof. Use this to verify if learning
28
- * features are available before attempting to use them.
29
- *
30
- * Note: This is NOT a TypeScript type guard because MemoryStore and
31
- * SwarmMemoryManager have incompatible method signatures. After checking
32
- * with this function, use a type assertion: `store as SwarmMemoryManager`
33
- *
34
- * @example
35
- * ```typescript
36
- * if (isSwarmMemoryManager(config.memoryStore)) {
37
- * const swarm = config.memoryStore as SwarmMemoryManager;
38
- * // Use swarm's learning features
39
- * }
40
- * ```
41
- */
42
- function isSwarmMemoryManager(store) {
43
- return store instanceof SwarmMemoryManager_1.SwarmMemoryManager;
44
- }
45
- /**
46
- * Validate agent config for learning features
47
- *
48
- * @remarks
49
- * Call this early in agent initialization to fail fast with clear error message.
50
- * This helps developers identify configuration issues immediately rather than
51
- * discovering disabled learning features at runtime.
52
- *
53
- * Issue #137: FleetManager was passing MemoryManager instead of SwarmMemoryManager,
54
- * causing learning features to be silently disabled for all agents.
55
- *
56
- * @param config - Agent configuration to validate
57
- * @param options - Validation options
58
- * @param options.throwOnMismatch - If true, throws an error instead of returning warning
59
- * @returns Validation result with valid flag and optional warning message
60
- *
61
- * @example
62
- * ```typescript
63
- * // In agent constructor:
64
- * const validation = validateLearningConfig(config);
65
- * if (!validation.valid) {
66
- * console.warn(validation.warning);
67
- * }
68
- * ```
69
- */
70
- function validateLearningConfig(config, options = {}) {
71
- const enableLearning = config.enableLearning ?? true;
72
- if (enableLearning && !isSwarmMemoryManager(config.memoryStore)) {
73
- const warning = `Learning is enabled but memoryStore is not SwarmMemoryManager. ` +
74
- `Got ${config.memoryStore.constructor.name}. ` +
75
- `Learning features (Q-learning, patterns, metrics) will be DISABLED. ` +
76
- `To fix: Use SwarmMemoryManager or set enableLearning: false.`;
77
- if (options.throwOnMismatch) {
78
- throw new Error(warning);
79
- }
80
- return { valid: false, warning };
81
- }
82
- return { valid: true };
83
- }
19
+ // Extracted utilities (B1.2)
20
+ const utils_1 = require("./utils");
21
+ Object.defineProperty(exports, "isSwarmMemoryManager", { enumerable: true, get: function () { return utils_1.isSwarmMemoryManager; } });
22
+ Object.defineProperty(exports, "validateLearningConfig", { enumerable: true, get: function () { return utils_1.validateLearningConfig; } });
84
23
  class BaseAgent extends events_1.EventEmitter {
85
24
  constructor(config) {
86
25
  super();
87
26
  this.performanceMetrics = { tasksCompleted: 0, averageExecutionTime: 0, errorCount: 0, lastActivity: new Date() };
88
- this.agentId = { id: config.id || this.generateAgentId(config.type), type: config.type, created: new Date() };
27
+ this.agentId = { id: config.id || (0, utils_1.generateAgentId)(config.type), type: config.type, created: new Date() };
89
28
  this.capabilities = new Map(config.capabilities.map(cap => [cap.name, cap]));
90
29
  this.context = config.context;
91
30
  this.memoryStore = config.memoryStore;
92
31
  this.eventBus = config.eventBus;
93
32
  this.enableLearning = config.enableLearning ?? true;
94
33
  this.learningConfig = config.learningConfig;
95
- // Early validation: Warn immediately if learning config is invalid
96
- // Issue #137: Fail-fast pattern to catch configuration issues at construction time
97
- const validation = validateLearningConfig(config);
34
+ // Early validation (Issue #137)
35
+ const validation = (0, utils_1.validateLearningConfig)(config);
98
36
  if (!validation.valid && validation.warning) {
99
37
  console.warn(`[${this.agentId.id}] CONFIG WARNING: ${validation.warning}`);
100
38
  }
101
- // Initialize service classes
39
+ // Initialize services
102
40
  const memoryAdapter = new MemoryStoreAdapter_1.MemoryStoreAdapter(this.memoryStore);
103
41
  this.hookManager = new hooks_1.VerificationHookManager(memoryAdapter);
104
42
  this.lifecycleManager = new AgentLifecycleManager_1.AgentLifecycleManager(this.agentId);
@@ -115,83 +53,47 @@ class BaseAgent extends events_1.EventEmitter {
115
53
  this.setupEventHandlers();
116
54
  this.setupLifecycleHooks();
117
55
  }
118
- // ============================================================================
119
- // Public Interface
120
- // ============================================================================
121
- /**
122
- * Initialize the agent - must be called after construction
123
- * Thread-safe: Multiple concurrent calls will wait for the first to complete
124
- */
56
+ // === Public Interface ===
125
57
  async initialize() {
126
- // Thread-safety: If initialization is in progress, wait for it
127
58
  if (this.initializationMutex) {
128
- console.info(`[${this.agentId.id}] Initialization already in progress, waiting for completion`);
129
59
  await this.initializationMutex;
130
- // Check if initialization succeeded or failed
131
- const statusAfterWait = this.lifecycleManager.getStatus();
132
- if (statusAfterWait === types_1.AgentStatus.ERROR) {
133
- throw new Error(`Initialization failed (status: ${statusAfterWait})`);
60
+ if (this.lifecycleManager.getStatus() === types_1.AgentStatus.ERROR) {
61
+ throw new Error(`Initialization failed`);
134
62
  }
135
63
  return;
136
64
  }
137
- // Guard: Skip if already initialized (ACTIVE or IDLE)
138
65
  const currentStatus = this.lifecycleManager.getStatus();
139
- if (currentStatus === types_1.AgentStatus.ACTIVE || currentStatus === types_1.AgentStatus.IDLE) {
140
- console.warn(`[${this.agentId.id}] Agent already initialized (status: ${currentStatus}), skipping`);
66
+ if (currentStatus === types_1.AgentStatus.ACTIVE || currentStatus === types_1.AgentStatus.IDLE)
141
67
  return;
142
- }
143
- // Create initialization mutex - lock acquired
144
68
  let resolveMutex;
145
- this.initializationMutex = new Promise((resolve) => {
146
- resolveMutex = resolve;
147
- });
69
+ this.initializationMutex = new Promise((resolve) => { resolveMutex = resolve; });
148
70
  try {
149
- // Guard: Reset from ERROR state before initializing
150
- if (currentStatus === types_1.AgentStatus.ERROR) {
151
- console.info(`[${this.agentId.id}] Resetting agent from ERROR state before initialization`);
71
+ if (currentStatus === types_1.AgentStatus.ERROR)
152
72
  this.lifecycleManager.reset(false);
153
- }
154
- // Delegate lifecycle initialization to lifecycleManager
155
73
  await this.lifecycleManager.initialize({
156
- onPreInitialization: async () => {
157
- await this.executeHook('pre-initialization');
158
- },
74
+ onPreInitialization: () => this.executeHook('pre-initialization'),
159
75
  onPostInitialization: async () => {
160
- // Load agent knowledge and state
161
76
  await this.loadKnowledge();
162
77
  const savedState = await this.memoryService.restoreState();
163
- if (savedState && savedState.performanceMetrics) {
78
+ if (savedState?.performanceMetrics) {
164
79
  this.performanceMetrics = { ...this.performanceMetrics, ...savedState.performanceMetrics };
165
80
  }
166
- // Initialize PerformanceTracker if learning is enabled
167
- // Issue #137: FleetManager now provides SwarmMemoryManager to enable learning
81
+ // Initialize learning if SwarmMemoryManager
168
82
  if (this.enableLearning && this.memoryStore instanceof SwarmMemoryManager_1.SwarmMemoryManager) {
169
83
  this.performanceTracker = new PerformanceTracker_1.PerformanceTracker(this.agentId.id, this.memoryStore);
170
84
  await this.performanceTracker.initialize();
171
- // Initialize learning engine for Q-learning
172
- // ARCHITECTURE (v2.2.0): LearningEngine uses SwarmMemoryManager for ALL persistence
173
- // All data (experiences, patterns, Q-values) goes to unified .agentic-qe/memory.db
174
- // No direct database dependency - memoryStore handles all coordination
175
85
  this.learningEngine = new LearningEngine_1.LearningEngine(this.agentId.id, this.memoryStore, this.learningConfig);
176
86
  await this.learningEngine.initialize();
177
- // Phase 2 (B1.2): Create learning strategy adapter
178
- // Only set if not already injected via config
179
87
  if (!this.strategies.learning) {
180
88
  this.strategies.learning = (0, adapters_1.createLearningAdapter)(this.learningEngine);
181
89
  }
182
90
  }
183
- else if (this.enableLearning && !(this.memoryStore instanceof SwarmMemoryManager_1.SwarmMemoryManager)) {
184
- // Runtime check: Warn if learning is enabled but memoryStore doesn't support it
185
- // Note: Early warning was already emitted in constructor (Issue #137)
186
- console.warn(`[${this.agentId.id}] Learning enabled but memoryStore is not SwarmMemoryManager. ` +
187
- `Learning features will be disabled. Expected SwarmMemoryManager, got ${this.memoryStore.constructor.name}`);
91
+ else if (this.enableLearning) {
92
+ console.warn(`[${this.agentId.id}] Learning disabled: memoryStore is ${this.memoryStore.constructor.name}`);
188
93
  }
189
- // Initialize agent-specific components
190
94
  await this.initializeComponents();
191
- // Execute post-initialization hooks
192
95
  await this.executeHook('post-initialization');
193
96
  this.coordinator.emitEvent('agent.initialized', { agentId: this.agentId });
194
- // Report initialization to coordination system
195
97
  await this.coordinator.reportStatus('initialized', this.performanceMetrics);
196
98
  }
197
99
  });
@@ -202,60 +104,39 @@ class BaseAgent extends events_1.EventEmitter {
202
104
  throw error;
203
105
  }
204
106
  finally {
205
- // Release mutex lock - allow future initializations
206
107
  resolveMutex();
207
108
  this.initializationMutex = undefined;
208
109
  }
209
110
  }
210
- /**
211
- * Execute a task assignment with integrated verification hooks
212
- */
213
111
  async executeTask(assignment) {
214
112
  const startTime = Date.now();
215
113
  try {
216
- // Validate task assignment
217
114
  this.validateTaskAssignment(assignment);
218
115
  this.currentTask = assignment;
219
- // Phase 2 (B1.2): Use lifecycle strategy for status transitions
220
116
  await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.ACTIVE);
221
- // Execute pre-task hooks with verification
222
117
  const preTaskData = { assignment };
223
118
  await this.onPreTask(preTaskData);
224
119
  await this.executeHook('pre-task', preTaskData);
225
- // Broadcast task start
226
120
  await this.coordinator.broadcastMessage('task-start', assignment);
227
- // Execute the actual task
228
121
  const result = await this.performTask(assignment.task);
229
- // Execute post-task hooks with validation
230
122
  const postTaskData = { assignment, result };
231
123
  await this.onPostTask(postTaskData);
232
124
  await this.executeHook('post-task', postTaskData);
233
- // Update performance metrics and store result
234
125
  this.updatePerformanceMetrics(startTime, true);
235
126
  await this.memoryService.storeTaskResult(assignment.id, result);
236
127
  this.currentTask = undefined;
237
- // Phase 2 (B1.2): Use lifecycle strategy for status transitions
238
128
  await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.IDLE);
239
129
  return result;
240
130
  }
241
131
  catch (error) {
242
132
  this.updatePerformanceMetrics(startTime, false);
243
133
  this.currentTask = undefined;
244
- // Phase 2 (B1.2): Use lifecycle strategy for error transition
245
- await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.ERROR, `Task execution failed: ${error}`);
246
- // Execute error hooks
247
- const errorData = {
248
- assignment,
249
- error: error
250
- };
251
- await this.onTaskError(errorData);
252
- await this.executeHook('task-error', errorData);
134
+ await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.ERROR, `Task failed: ${error}`);
135
+ await this.onTaskError({ assignment, error: error });
136
+ await this.executeHook('task-error', { assignment, error });
253
137
  throw error;
254
138
  }
255
139
  }
256
- /**
257
- * Terminate the agent gracefully
258
- */
259
140
  async terminate() {
260
141
  try {
261
142
  await this.lifecycleManager.terminate({
@@ -277,17 +158,9 @@ class BaseAgent extends events_1.EventEmitter {
277
158
  throw error;
278
159
  }
279
160
  }
280
- /**
281
- * Get agent ID
282
- */
283
- getAgentId() {
284
- return this.agentId;
285
- }
286
- /**
287
- * Get current agent status and metrics
288
- */
161
+ // === Getters ===
162
+ getAgentId() { return this.agentId; }
289
163
  getStatus() {
290
- // Phase 2 (B1.2): Use lifecycle strategy instead of direct manager call
291
164
  return {
292
165
  agentId: this.agentId,
293
166
  status: this.strategies.lifecycle.getStatus(),
@@ -296,29 +169,25 @@ class BaseAgent extends events_1.EventEmitter {
296
169
  performanceMetrics: { ...this.performanceMetrics }
297
170
  };
298
171
  }
299
- // ============================================================================
300
- // Event-Driven Coordination (Race Condition Elimination)
301
- // ============================================================================
302
- /**
303
- * Wait for agent to reach a specific status with timeout
304
- * Replaces: setTimeout(() => { expect(agent.status).toBe('ready') }, 5000)
305
- * Use: await agent.waitForStatus('ready')
306
- */
172
+ hasCapability(name) { return this.capabilities.has(name); }
173
+ getCapability(name) { return this.capabilities.get(name); }
174
+ getCapabilities() { return Array.from(this.capabilities.values()); }
175
+ getStrategies() { return this.strategies; }
176
+ getLifecycleStrategy() { return this.strategies.lifecycle; }
177
+ getMemoryStrategy() { return this.strategies.memory; }
178
+ getLearningStrategy() { return this.strategies.learning; }
179
+ getCoordinationStrategy() { return this.strategies.coordination; }
180
+ // === Event-Driven Coordination ===
307
181
  async waitForStatus(status, timeout = 10000) {
308
- // Phase 2 (B1.2): Use lifecycle strategy for status waiting
309
- // Strategy provides waitForStatus implementation
310
182
  if (typeof this.strategies.lifecycle.waitForStatus === 'function') {
311
183
  return this.strategies.lifecycle.waitForStatus(status, timeout);
312
184
  }
313
- // Fallback to event-based implementation
314
185
  return new Promise((resolve, reject) => {
315
- // Already at target status
316
- if (this.strategies.lifecycle.getStatus() === status) {
186
+ if (this.strategies.lifecycle.getStatus() === status)
317
187
  return resolve();
318
- }
319
188
  const timer = setTimeout(() => {
320
189
  this.removeListener('status-changed', listener);
321
- reject(new Error(`Agent ${this.agentId.id} did not reach status '${status}' within ${timeout}ms`));
190
+ reject(new Error(`Agent did not reach status '${status}' within ${timeout}ms`));
322
191
  }, timeout);
323
192
  const listener = (newStatus) => {
324
193
  if (newStatus === status) {
@@ -330,146 +199,41 @@ class BaseAgent extends events_1.EventEmitter {
330
199
  this.on('status-changed', listener);
331
200
  });
332
201
  }
333
- /**
334
- * Wait for agent to be ready (initialized and idle)
335
- * Replaces: await new Promise(resolve => setTimeout(resolve, 5000))
336
- * Use: await agent.waitForReady()
337
- */
338
202
  async waitForReady(timeout = 10000) {
339
- // Phase 2 (B1.2): Use lifecycle strategy
340
- // Strategy provides waitForReady implementation
341
203
  if (typeof this.strategies.lifecycle.waitForReady === 'function') {
342
204
  return this.strategies.lifecycle.waitForReady(timeout);
343
205
  }
344
- // Fallback to waitForStatus-based implementation
345
- const currentStatus = this.strategies.lifecycle.getStatus();
346
- if (currentStatus === types_1.AgentStatus.IDLE || currentStatus === types_1.AgentStatus.ACTIVE) {
347
- return; // Already ready
348
- }
206
+ const status = this.strategies.lifecycle.getStatus();
207
+ if (status === types_1.AgentStatus.IDLE || status === types_1.AgentStatus.ACTIVE)
208
+ return;
349
209
  return this.waitForStatus(types_1.AgentStatus.IDLE, timeout);
350
210
  }
351
- /**
352
- * Wait for a specific event to be emitted
353
- * Generic event waiter for custom coordination
354
- */
355
211
  async waitForEvent(eventName, timeout = 10000) {
356
212
  return new Promise((resolve, reject) => {
357
213
  const timer = setTimeout(() => {
358
214
  this.removeListener(eventName, listener);
359
215
  reject(new Error(`Event '${eventName}' not received within ${timeout}ms`));
360
216
  }, timeout);
361
- const listener = (data) => {
362
- clearTimeout(timer);
363
- this.removeListener(eventName, listener);
364
- resolve(data);
365
- };
217
+ const listener = (data) => { clearTimeout(timer); this.removeListener(eventName, listener); resolve(data); };
366
218
  this.once(eventName, listener);
367
219
  });
368
220
  }
369
- /**
370
- * Emit status change events for event-driven coordination
371
- * Called by lifecycle manager when status changes
372
- */
373
- emitStatusChange(newStatus) {
374
- this.emit('status-changed', newStatus);
375
- this.coordinator.emitEvent('agent.status-changed', {
376
- agentId: this.agentId,
377
- status: newStatus,
378
- timestamp: Date.now()
379
- });
380
- }
381
- /**
382
- * Check if agent has a specific capability
383
- */
384
- hasCapability(capabilityName) {
385
- return this.capabilities.has(capabilityName);
386
- }
387
- /**
388
- * Get capability details
389
- */
390
- getCapability(capabilityName) {
391
- return this.capabilities.get(capabilityName);
392
- }
393
- /**
394
- * Get all capabilities
395
- */
396
- getCapabilities() {
397
- return Array.from(this.capabilities.values());
398
- }
399
- /**
400
- * Get strategies (Phase 2 B1.2)
401
- * Lifecycle and memory strategies are always available (adapter or custom)
402
- */
403
- getStrategies() {
404
- return this.strategies;
405
- }
406
- /**
407
- * Get the lifecycle strategy
408
- */
409
- getLifecycleStrategy() {
410
- return this.strategies.lifecycle;
411
- }
412
- /**
413
- * Get the memory strategy
414
- */
415
- getMemoryStrategy() {
416
- return this.strategies.memory;
417
- }
418
- /**
419
- * Get the learning strategy (if enabled)
420
- */
421
- getLearningStrategy() {
422
- return this.strategies.learning;
423
- }
424
- /**
425
- * Get the coordination strategy
426
- */
427
- getCoordinationStrategy() {
428
- return this.strategies.coordination;
429
- }
430
- /**
431
- * Register a new capability dynamically
432
- */
433
- registerCapability(capability) {
434
- this.capabilities.set(capability.name, capability);
435
- this.emitEvent('capability.registered', {
436
- agentId: this.agentId,
437
- capability: capability.name
438
- });
439
- }
440
- /**
441
- * Register multiple capabilities at once
442
- */
443
- registerCapabilities(capabilities) {
444
- for (const capability of capabilities) {
445
- this.registerCapability(capability);
446
- }
447
- }
448
- /**
449
- * Get Q-learning strategy recommendation
450
- */
221
+ // === Learning Interface ===
451
222
  async recommendStrategy(taskState) {
452
223
  if (!this.learningEngine?.isEnabled())
453
224
  return null;
454
225
  try {
455
226
  return await this.learningEngine.recommendStrategy(taskState);
456
227
  }
457
- catch (error) {
458
- console.error(`Strategy recommendation failed:`, error);
228
+ catch {
459
229
  return null;
460
230
  }
461
231
  }
462
- /**
463
- * Get learned patterns from Q-learning
464
- */
465
232
  async getLearnedPatterns() {
466
233
  if (!this.learningEngine)
467
234
  return [];
468
235
  return await this.learningEngine.getPatterns();
469
236
  }
470
- /**
471
- * Get learning engine status
472
- */
473
237
  async getLearningStatus() {
474
238
  if (!this.learningEngine)
475
239
  return null;
@@ -481,51 +245,17 @@ class BaseAgent extends events_1.EventEmitter {
481
245
  patterns: Array.isArray(patterns) ? patterns.length : 0
482
246
  };
483
247
  }
484
- /**
485
- * @deprecated v2.2.0 - AgentDB is deprecated. Use SwarmMemoryManager instead.
486
- * Stub method for backward compatibility - will be removed in v3.0.0.
487
- */
488
- async initializeAgentDB(_config) {
489
- console.warn(`[${this.agentId.id}] AgentDB is DEPRECATED and will be removed in v3.0.0`);
490
- }
491
- /**
492
- * @deprecated v2.2.0 - Use learning strategy instead.
493
- */
494
- async getAgentDBStatus() {
495
- return null;
496
- }
497
- /**
498
- * @deprecated v2.2.0 - Returns false, AgentDB removed.
499
- */
500
- hasAgentDB() {
501
- return false;
502
- }
503
- /**
504
- * Start the agent (idempotent - safe to call multiple times)
505
- */
248
+ // === Start/Stop (FleetManager compatibility) ===
506
249
  async start() {
507
- const currentStatus = this.lifecycleManager.getStatus();
508
- // If already active or idle, no need to initialize again
509
- if (currentStatus === types_1.AgentStatus.ACTIVE || currentStatus === types_1.AgentStatus.IDLE) {
510
- console.info(`[${this.agentId.id}] Agent already started (status: ${currentStatus})`);
250
+ const status = this.lifecycleManager.getStatus();
251
+ if (status === types_1.AgentStatus.ACTIVE || status === types_1.AgentStatus.IDLE)
511
252
  return;
512
- }
513
- // Otherwise, initialize the agent
514
253
  await this.initialize();
515
254
  }
516
- /**
517
- * Stop the agent (alias for terminate)
518
- * Added for FleetManager compatibility
519
- */
520
- async stop() {
521
- await this.terminate();
522
- }
523
- /**
524
- * Assign a task to the agent
525
- */
255
+ async stop() { await this.terminate(); }
526
256
  async assignTask(task) {
527
257
  const assignment = {
528
- id: `task-${Date.now()}-${SecureRandom_js_1.SecureRandom.generateId(5)}`,
258
+ id: (0, utils_1.generateTaskId)(),
529
259
  task,
530
260
  agentId: this.agentId.id,
531
261
  assignedAt: new Date(),
@@ -533,259 +263,160 @@ class BaseAgent extends events_1.EventEmitter {
533
263
  };
534
264
  await this.executeTask(assignment);
535
265
  }
536
- // ============================================================================
537
- // Event System
538
- // ============================================================================
539
- /**
540
- * Register an event handler
541
- */
266
+ // === Deprecated (Remove in v3.0.0) ===
267
+ /** @deprecated v2.2.0 - AgentDB removed. Use SwarmMemoryManager. */
268
+ async initializeAgentDB(_config) {
269
+ console.warn(`[${this.agentId.id}] AgentDB is DEPRECATED`);
270
+ }
271
+ /** @deprecated v2.2.0 */
272
+ async getAgentDBStatus() { return null; }
273
+ /** @deprecated v2.2.0 */
274
+ hasAgentDB() { return false; }
275
+ // === Protected Methods ===
276
+ registerCapability(capability) {
277
+ this.capabilities.set(capability.name, capability);
278
+ this.emitEvent('capability.registered', { agentId: this.agentId, capability: capability.name });
279
+ }
280
+ registerCapabilities(capabilities) {
281
+ capabilities.forEach(cap => this.registerCapability(cap));
282
+ }
542
283
  registerEventHandler(handler) {
543
284
  this.coordinator.registerEventHandler(handler);
544
285
  }
545
- /**
546
- * Emit an event
547
- */
548
286
  emitEvent(type, data, priority = 'medium') {
549
287
  const event = {
550
- id: this.generateEventId(),
551
- type,
552
- source: this.agentId,
553
- data,
554
- timestamp: new Date(),
555
- priority,
556
- scope: 'global'
288
+ id: (0, utils_1.generateEventId)(), type, source: this.agentId, data,
289
+ timestamp: new Date(), priority, scope: 'global'
557
290
  };
558
291
  this.eventBus.emit(type, event);
559
292
  }
560
- /**
561
- * Broadcast message to other agents
562
- * Uses AgentDB if enabled, falls back to EventBus
563
- */
293
+ emitStatusChange(newStatus) {
294
+ this.emit('status-changed', newStatus);
295
+ this.coordinator.emitEvent('agent.status-changed', { agentId: this.agentId, status: newStatus, timestamp: Date.now() });
296
+ }
564
297
  async broadcastMessage(type, payload) {
565
- // Use EventBus for now (AgentDB sync handles distributed state)
566
298
  const message = {
567
- id: this.generateMessageId(),
568
- from: this.agentId,
299
+ id: (0, utils_1.generateMessageId)(), from: this.agentId,
569
300
  to: { id: 'broadcast', type: 'all', created: new Date() },
570
- type: type,
571
- payload,
572
- timestamp: new Date(),
573
- priority: 'medium'
301
+ type: type, payload, timestamp: new Date(), priority: 'medium'
574
302
  };
575
303
  this.eventBus.emit('agent.message', message);
576
304
  }
577
- // ============================================================================
578
- // Memory Operations (Phase 2 B1.2 - delegated to strategy)
579
- // ============================================================================
580
- /**
581
- * Store data in memory with automatic namespacing
582
- * Phase 2 (B1.2): Delegates to memory strategy with aqe/{agentType}/{key} namespace
583
- */
305
+ // === Memory Operations (delegated to strategy) ===
584
306
  async storeMemory(key, value, ttl) {
585
- // Phase 2 (B1.2): Use memory strategy with local namespace
586
- const memoryStrategy = this.strategies.memory;
587
- if (memoryStrategy instanceof adapters_1.MemoryServiceAdapter) {
588
- await memoryStrategy.storeLocal(key, value, ttl);
307
+ const strategy = this.strategies.memory;
308
+ if (strategy instanceof adapters_1.MemoryServiceAdapter) {
309
+ await strategy.storeLocal(key, value, ttl);
589
310
  }
590
311
  else {
591
- // Fallback for custom strategies
592
- await memoryStrategy.store(key, value, { ttl, namespace: this.agentId.type });
312
+ await strategy.store(key, value, { ttl, namespace: this.agentId.type });
593
313
  }
594
314
  }
595
- /**
596
- * Retrieve data from memory
597
- * Phase 2 (B1.2): Delegates to memory strategy with aqe/{agentType}/{key} namespace
598
- */
599
315
  async retrieveMemory(key) {
600
- // Phase 2 (B1.2): Use memory strategy with local namespace
601
- const memoryStrategy = this.strategies.memory;
602
- if (memoryStrategy instanceof adapters_1.MemoryServiceAdapter) {
603
- return await memoryStrategy.retrieveLocal(key);
604
- }
605
- else {
606
- // Fallback for custom strategies - must handle namespace manually
607
- return await memoryStrategy.retrieve(`aqe/${this.agentId.type}/${key}`);
316
+ const strategy = this.strategies.memory;
317
+ if (strategy instanceof adapters_1.MemoryServiceAdapter) {
318
+ return await strategy.retrieveLocal(key);
608
319
  }
320
+ return await strategy.retrieve(`aqe/${this.agentId.type}/${key}`);
609
321
  }
610
- /**
611
- * Store shared data accessible by other agents
612
- * Phase 2 (B1.2): Delegates to memory strategy with aqe/shared/{agentType}/{key} namespace
613
- */
614
322
  async storeSharedMemory(key, value, ttl) {
615
- // Phase 2 (B1.2): Use memory strategy with shared namespace
616
- const memoryStrategy = this.strategies.memory;
617
- if (memoryStrategy instanceof adapters_1.MemoryServiceAdapter) {
618
- await memoryStrategy.storeSharedLocal(key, value, ttl);
323
+ const strategy = this.strategies.memory;
324
+ if (strategy instanceof adapters_1.MemoryServiceAdapter) {
325
+ await strategy.storeSharedLocal(key, value, ttl);
619
326
  }
620
327
  else {
621
- // Fallback for custom strategies
622
- await memoryStrategy.storeShared(this.agentId.type, key, value, { ttl });
328
+ await strategy.storeShared(this.agentId.type, key, value, { ttl });
623
329
  }
624
330
  }
625
- /**
626
- * Retrieve shared data from other agents
627
- * Phase 2 (B1.2): Delegates to memory strategy with aqe/shared/{agentType}/{key} namespace
628
- */
629
331
  async retrieveSharedMemory(agentType, key) {
630
- // Phase 2 (B1.2): Use memory strategy for shared retrieval
631
332
  return await this.strategies.memory.retrieveShared(agentType, key);
632
333
  }
633
- // ============================================================================
634
- // Lifecycle Hooks
635
- // ============================================================================
636
- /**
637
- * Pre-task hook - called before task execution
638
- * Delegates to lifecycle strategy for pre-task processing
639
- */
334
+ // === Lifecycle Hooks ===
640
335
  async onPreTask(data) {
641
336
  this.taskStartTime = Date.now();
642
- // Delegate to lifecycle strategy if available
643
- if (this.strategies.lifecycle.onPreTask) {
337
+ if (this.strategies.lifecycle.onPreTask)
644
338
  await this.strategies.lifecycle.onPreTask(data);
339
+ const result = await this.hookManager.executePreTaskVerification({ task: data.assignment.task.type, context: data.context });
340
+ if (!result.passed) {
341
+ throw new Error(`Pre-task verification failed: score ${result.score}`);
645
342
  }
646
- // Run verification checks
647
- const verificationResult = await this.hookManager.executePreTaskVerification({
648
- task: data.assignment.task.type,
649
- context: data.context
650
- });
651
- if (!verificationResult.passed) {
652
- throw new Error(`Pre-task verification failed with score ${verificationResult.score}. ` +
653
- `Checks: ${verificationResult.checks.join(', ')}`);
654
- }
655
- this.emitEvent('hook.pre-task.completed', {
656
- agentId: this.agentId,
657
- result: verificationResult
658
- });
343
+ this.emitEvent('hook.pre-task.completed', { agentId: this.agentId, result });
659
344
  }
660
- /**
661
- * Post-task hook - called after task execution
662
- * Delegates to lifecycle and learning strategies
663
- */
664
345
  async onPostTask(data) {
665
346
  const executionTime = this.taskStartTime ? Date.now() - this.taskStartTime : 0;
666
- // Run validation checks
667
- const validationResult = await this.hookManager.executePostTaskValidation({
668
- task: data.assignment.task.type,
669
- result: data.result
670
- });
671
- if (!validationResult.valid) {
672
- console.warn(`Post-task validation warning with accuracy ${validationResult.accuracy}. ` +
673
- `Validations: ${validationResult.validations.join(', ')}`);
347
+ const result = await this.hookManager.executePostTaskValidation({ task: data.assignment.task.type, result: data.result });
348
+ if (!result.valid) {
349
+ console.warn(`Post-task validation warning: accuracy ${result.accuracy}`);
674
350
  }
675
- // Delegate to lifecycle strategy
676
- if (this.strategies.lifecycle.onPostTask) {
351
+ if (this.strategies.lifecycle.onPostTask)
677
352
  await this.strategies.lifecycle.onPostTask(data);
678
- }
679
- // Delegate learning to learning strategy (handles Q-learning, performance tracking)
680
353
  if (this.strategies.learning?.recordExecution) {
681
354
  await this.strategies.learning.recordExecution({
682
- task: data.assignment.task,
683
- result: data.result,
684
- success: validationResult.valid,
685
- duration: executionTime,
686
- metadata: {
687
- taskId: data.assignment.id,
688
- accuracy: validationResult.accuracy,
689
- metrics: this.extractTaskMetrics(data.result)
690
- }
355
+ task: data.assignment.task, result: data.result, success: result.valid,
356
+ duration: executionTime, metadata: { taskId: data.assignment.id, accuracy: result.accuracy, metrics: this.extractTaskMetrics(data.result) }
691
357
  });
692
358
  }
693
- this.emitEvent('hook.post-task.completed', {
694
- agentId: this.agentId,
695
- result: validationResult
696
- });
359
+ this.emitEvent('hook.post-task.completed', { agentId: this.agentId, result });
697
360
  }
698
- /**
699
- * Task error hook - called when task execution fails
700
- * Delegates to lifecycle and learning strategies
701
- */
702
361
  async onTaskError(data) {
703
362
  const executionTime = this.taskStartTime ? Date.now() - this.taskStartTime : 0;
704
- // Store error in memory for analysis
705
363
  await this.storeMemory(`error:${data.assignment.id}`, {
706
364
  error: { message: data.error.message, name: data.error.name },
707
365
  assignment: { id: data.assignment.id, taskType: data.assignment.task.type },
708
- timestamp: new Date(),
709
- agentId: this.agentId.id
366
+ timestamp: new Date(), agentId: this.agentId.id
710
367
  });
711
- // Delegate to lifecycle strategy
712
- if (this.strategies.lifecycle.onTaskError) {
368
+ if (this.strategies.lifecycle.onTaskError)
713
369
  await this.strategies.lifecycle.onTaskError(data);
714
- }
715
- // Delegate error recording to learning strategy
716
370
  if (this.strategies.learning?.recordExecution) {
717
371
  await this.strategies.learning.recordExecution({
718
- task: data.assignment.task,
719
- error: data.error,
720
- success: false,
721
- duration: executionTime,
722
- metadata: {
723
- taskId: data.assignment.id
724
- }
372
+ task: data.assignment.task, error: data.error, success: false,
373
+ duration: executionTime, metadata: { taskId: data.assignment.id }
725
374
  });
726
375
  }
727
- this.emitEvent('hook.task-error.completed', {
728
- agentId: this.agentId,
729
- error: data.error
730
- }, 'high');
376
+ this.emitEvent('hook.task-error.completed', { agentId: this.agentId, error: data.error }, 'high');
731
377
  }
378
+ // === Private Helpers ===
732
379
  async executeHook(hookName, data) {
733
380
  try {
734
381
  const method = `on${hookName.charAt(0).toUpperCase()}${hookName.slice(1).replace(/-/g, '')}`;
735
- if (typeof this[method] === 'function') {
382
+ if (typeof this[method] === 'function')
736
383
  await this[method](data);
737
- }
738
384
  }
739
385
  catch (error) {
740
- console.error(`Hook ${hookName} failed for agent ${this.agentId.id}:`, error);
386
+ console.error(`Hook ${hookName} failed:`, error);
741
387
  }
742
388
  }
743
- // ============================================================================
744
- // Helper Methods
745
- // ============================================================================
746
389
  setupEventHandlers() {
747
- // Set up base event handlers that all agents should have
748
- this.registerEventHandler({
749
- eventType: 'fleet.shutdown',
750
- handler: async () => {
751
- await this.terminate();
752
- }
753
- });
390
+ this.registerEventHandler({ eventType: 'fleet.shutdown', handler: async () => { await this.terminate(); } });
754
391
  this.registerEventHandler({
755
392
  eventType: 'agent.ping',
756
393
  handler: async (event) => {
757
- if (event.target?.id === this.agentId.id) {
394
+ if (event.target?.id === this.agentId.id)
758
395
  this.emitEvent('agent.pong', { agentId: this.agentId });
759
- }
760
396
  }
761
397
  });
762
398
  }
763
399
  setupLifecycleHooks() {
764
- // Setup default lifecycle behavior
765
- // Phase 2 (B1.2): Use lifecycle strategy for error transition
766
400
  this.on('error', async (error) => {
767
- await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.ERROR, `Error event: ${error}`);
401
+ await this.strategies.lifecycle.transitionTo(types_1.AgentStatus.ERROR, `Error: ${error}`);
768
402
  this.emitEvent('agent.error', { agentId: this.agentId, error });
769
403
  });
770
404
  }
771
405
  validateTaskAssignment(assignment) {
772
- if (!assignment || !assignment.task) {
406
+ if (!assignment?.task)
773
407
  throw new Error('Invalid task assignment');
774
- }
775
- // Check if agent has required capabilities
776
- const requiredCapabilities = assignment.task.requirements?.capabilities || [];
777
- for (const capability of requiredCapabilities) {
778
- if (!this.hasCapability(capability)) {
779
- throw new Error(`Agent ${this.agentId.id} missing required capability: ${capability}`);
780
- }
408
+ const required = assignment.task.requirements?.capabilities || [];
409
+ for (const cap of required) {
410
+ if (!this.hasCapability(cap))
411
+ throw new Error(`Missing capability: ${cap}`);
781
412
  }
782
413
  }
783
414
  updatePerformanceMetrics(startTime, success) {
784
- const executionTime = Date.now() - startTime;
415
+ const time = Date.now() - startTime;
785
416
  if (success) {
786
417
  this.performanceMetrics.tasksCompleted++;
787
418
  this.performanceMetrics.averageExecutionTime =
788
- (this.performanceMetrics.averageExecutionTime * (this.performanceMetrics.tasksCompleted - 1) + executionTime) /
419
+ (this.performanceMetrics.averageExecutionTime * (this.performanceMetrics.tasksCompleted - 1) + time) /
789
420
  this.performanceMetrics.tasksCompleted;
790
421
  }
791
422
  else {
@@ -793,47 +424,18 @@ class BaseAgent extends events_1.EventEmitter {
793
424
  }
794
425
  this.performanceMetrics.lastActivity = new Date();
795
426
  }
796
- /**
797
- * Extract metrics from task result for learning
798
- * Override in subclasses to provide agent-specific metrics
799
- */
800
427
  extractTaskMetrics(result) {
801
428
  const metrics = {};
802
- // Extract common metrics if available
803
429
  if (result && typeof result === 'object') {
804
- if (typeof result.coverage === 'number') {
805
- metrics.coverage = result.coverage;
806
- }
807
- if (typeof result.testsGenerated === 'number') {
808
- metrics.testsGenerated = result.testsGenerated;
809
- }
810
- if (typeof result.issuesFound === 'number') {
811
- metrics.issuesFound = result.issuesFound;
812
- }
813
- if (typeof result.confidenceScore === 'number') {
814
- metrics.confidenceScore = result.confidenceScore;
815
- }
816
- if (typeof result.qualityScore === 'number') {
817
- metrics.qualityScore = result.qualityScore;
818
- }
430
+ ['coverage', 'testsGenerated', 'issuesFound', 'confidenceScore', 'qualityScore'].forEach(key => {
431
+ if (typeof result[key] === 'number')
432
+ metrics[key] = result[key];
433
+ });
819
434
  }
820
435
  return metrics;
821
436
  }
822
- // State management delegated to memoryService (used in initialize/terminate)
823
437
  async saveState() {
824
- await this.memoryService.saveState({
825
- performanceMetrics: this.performanceMetrics,
826
- timestamp: new Date()
827
- });
828
- }
829
- generateAgentId(type) {
830
- return `${type}-${Date.now()}-${SecureRandom_js_1.SecureRandom.generateId(5)}`;
831
- }
832
- generateEventId() {
833
- return `event-${Date.now()}-${SecureRandom_js_1.SecureRandom.generateId(5)}`;
834
- }
835
- generateMessageId() {
836
- return `msg-${Date.now()}-${SecureRandom_js_1.SecureRandom.generateId(5)}`;
438
+ await this.memoryService.saveState({ performanceMetrics: this.performanceMetrics, timestamp: new Date() });
837
439
  }
838
440
  }
839
441
  exports.BaseAgent = BaseAgent;