@claude-flow/swarm 3.0.0-alpha.7 → 3.0.0-alpha.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 (130) hide show
  1. package/dist/agent-pool.d.ts.map +1 -1
  2. package/dist/agent-pool.js +10 -2
  3. package/dist/agent-pool.js.map +1 -1
  4. package/dist/attention-coordinator.d.ts +5 -4
  5. package/dist/attention-coordinator.d.ts.map +1 -1
  6. package/dist/attention-coordinator.js +17 -10
  7. package/dist/attention-coordinator.js.map +1 -1
  8. package/dist/consensus/byzantine.d.ts +2 -1
  9. package/dist/consensus/byzantine.d.ts.map +1 -1
  10. package/dist/consensus/byzantine.js +34 -8
  11. package/dist/consensus/byzantine.js.map +1 -1
  12. package/dist/consensus/gossip.d.ts +2 -1
  13. package/dist/consensus/gossip.d.ts.map +1 -1
  14. package/dist/consensus/gossip.js +27 -8
  15. package/dist/consensus/gossip.js.map +1 -1
  16. package/dist/consensus/index.d.ts +1 -1
  17. package/dist/consensus/index.d.ts.map +1 -1
  18. package/dist/consensus/index.js +2 -2
  19. package/dist/consensus/index.js.map +1 -1
  20. package/dist/consensus/raft.d.ts +2 -1
  21. package/dist/consensus/raft.d.ts.map +1 -1
  22. package/dist/consensus/raft.js +25 -9
  23. package/dist/consensus/raft.js.map +1 -1
  24. package/dist/coordination/agent-registry.d.ts +2 -2
  25. package/dist/coordination/agent-registry.d.ts.map +1 -1
  26. package/dist/coordination/agent-registry.js +1 -1
  27. package/dist/coordination/agent-registry.js.map +1 -1
  28. package/dist/coordination/swarm-hub.d.ts +5 -5
  29. package/dist/coordination/swarm-hub.d.ts.map +1 -1
  30. package/dist/coordination/swarm-hub.js +5 -5
  31. package/dist/coordination/swarm-hub.js.map +1 -1
  32. package/dist/coordination/task-orchestrator.d.ts +3 -3
  33. package/dist/coordination/task-orchestrator.d.ts.map +1 -1
  34. package/dist/coordination/task-orchestrator.js +1 -1
  35. package/dist/coordination/task-orchestrator.js.map +1 -1
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +4 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/message-bus.d.ts.map +1 -1
  41. package/dist/message-bus.js +13 -4
  42. package/dist/message-bus.js.map +1 -1
  43. package/dist/queen-coordinator.d.ts +1 -1
  44. package/dist/queen-coordinator.d.ts.map +1 -1
  45. package/dist/queen-coordinator.js +10 -3
  46. package/dist/queen-coordinator.js.map +1 -1
  47. package/dist/topology-manager.d.ts.map +1 -1
  48. package/dist/topology-manager.js +26 -1
  49. package/dist/topology-manager.js.map +1 -1
  50. package/dist/types.d.ts +3 -2
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/types.js.map +1 -1
  53. package/dist/unified-coordinator.d.ts +1 -1
  54. package/dist/unified-coordinator.d.ts.map +1 -1
  55. package/dist/unified-coordinator.js +85 -29
  56. package/dist/unified-coordinator.js.map +1 -1
  57. package/package.json +7 -2
  58. package/.claude-flow/data/pending-insights.jsonl +0 -12
  59. package/__tests__/byzantine-transport.test.ts +0 -147
  60. package/__tests__/consensus-failure-injection.test.ts +0 -161
  61. package/__tests__/consensus-transport.test.ts +0 -200
  62. package/__tests__/consensus.test.ts +0 -577
  63. package/__tests__/coordinator.test.ts +0 -501
  64. package/__tests__/federation-transport.test.ts +0 -145
  65. package/__tests__/gossip-transport.test.ts +0 -81
  66. package/__tests__/queen-coordinator.test.ts +0 -1335
  67. package/__tests__/raft-transport.test.ts +0 -121
  68. package/__tests__/topology.test.ts +0 -621
  69. package/ruvector.db +0 -0
  70. package/src/agent-pool.ts +0 -476
  71. package/src/application/commands/create-task.command.ts +0 -124
  72. package/src/application/commands/spawn-agent.command.ts +0 -122
  73. package/src/application/index.ts +0 -30
  74. package/src/application/services/swarm-application-service.ts +0 -200
  75. package/src/attention-coordinator.ts +0 -1000
  76. package/src/consensus/byzantine.ts +0 -514
  77. package/src/consensus/federation-transport.ts +0 -185
  78. package/src/consensus/gossip.ts +0 -599
  79. package/src/consensus/index.ts +0 -296
  80. package/src/consensus/raft.ts +0 -561
  81. package/src/consensus/transport.ts +0 -284
  82. package/src/coordination/agent-registry.ts +0 -544
  83. package/src/coordination/index.ts +0 -23
  84. package/src/coordination/swarm-hub.ts +0 -776
  85. package/src/coordination/task-orchestrator.ts +0 -605
  86. package/src/domain/entities/agent.d.ts +0 -151
  87. package/src/domain/entities/agent.d.ts.map +0 -1
  88. package/src/domain/entities/agent.js +0 -280
  89. package/src/domain/entities/agent.js.map +0 -1
  90. package/src/domain/entities/agent.ts +0 -370
  91. package/src/domain/entities/task.d.ts +0 -133
  92. package/src/domain/entities/task.d.ts.map +0 -1
  93. package/src/domain/entities/task.js +0 -261
  94. package/src/domain/entities/task.js.map +0 -1
  95. package/src/domain/entities/task.ts +0 -319
  96. package/src/domain/index.ts +0 -41
  97. package/src/domain/repositories/agent-repository.interface.d.ts +0 -57
  98. package/src/domain/repositories/agent-repository.interface.d.ts.map +0 -1
  99. package/src/domain/repositories/agent-repository.interface.js +0 -9
  100. package/src/domain/repositories/agent-repository.interface.js.map +0 -1
  101. package/src/domain/repositories/agent-repository.interface.ts +0 -69
  102. package/src/domain/repositories/task-repository.interface.d.ts +0 -61
  103. package/src/domain/repositories/task-repository.interface.d.ts.map +0 -1
  104. package/src/domain/repositories/task-repository.interface.js +0 -9
  105. package/src/domain/repositories/task-repository.interface.js.map +0 -1
  106. package/src/domain/repositories/task-repository.interface.ts +0 -75
  107. package/src/domain/services/coordination-service.ts +0 -320
  108. package/src/federation-hub.d.ts +0 -284
  109. package/src/federation-hub.d.ts.map +0 -1
  110. package/src/federation-hub.js +0 -692
  111. package/src/federation-hub.js.map +0 -1
  112. package/src/federation-hub.ts +0 -979
  113. package/src/index.ts +0 -348
  114. package/src/message-bus.ts +0 -607
  115. package/src/queen-coordinator.ts +0 -2025
  116. package/src/shared/events.ts +0 -285
  117. package/src/shared/types.ts +0 -389
  118. package/src/topology-manager.ts +0 -656
  119. package/src/types.ts +0 -545
  120. package/src/unified-coordinator.ts +0 -1844
  121. package/src/workers/index.ts +0 -65
  122. package/src/workers/worker-dispatch.d.ts +0 -234
  123. package/src/workers/worker-dispatch.d.ts.map +0 -1
  124. package/src/workers/worker-dispatch.js +0 -842
  125. package/src/workers/worker-dispatch.js.map +0 -1
  126. package/src/workers/worker-dispatch.ts +0 -1076
  127. package/tmp.json +0 -0
  128. package/tsconfig.json +0 -9
  129. package/tsconfig.tsbuildinfo +0 -1
  130. package/vitest.config.ts +0 -20
package/src/agent-pool.ts DELETED
@@ -1,476 +0,0 @@
1
- /**
2
- * V3 Agent Pool
3
- * Manages agent lifecycle, pooling, and auto-scaling
4
- */
5
-
6
- import { EventEmitter } from 'events';
7
- import {
8
- AgentState,
9
- AgentType,
10
- AgentStatus,
11
- AgentCapabilities,
12
- AgentMetrics,
13
- AgentPoolConfig,
14
- AgentPoolState,
15
- IAgentPool,
16
- SWARM_CONSTANTS,
17
- } from './types.js';
18
-
19
- interface PooledAgent {
20
- agent: AgentState;
21
- acquiredAt?: Date;
22
- lastUsed: Date;
23
- usageCount: number;
24
- }
25
-
26
- export class AgentPool extends EventEmitter implements IAgentPool {
27
- private config: AgentPoolConfig;
28
- private pooledAgents: Map<string, PooledAgent> = new Map();
29
- private available: Set<string> = new Set();
30
- private busy: Set<string> = new Set();
31
- private pendingScale: number = 0;
32
- private lastScaleOperation?: Date;
33
- private healthCheckInterval?: NodeJS.Timeout;
34
- private agentCounter: number = 0;
35
-
36
- constructor(config: Partial<AgentPoolConfig> = {}) {
37
- super();
38
- this.config = {
39
- name: config.name ?? 'default-pool',
40
- type: config.type ?? 'worker',
41
- minSize: config.minSize ?? 1,
42
- maxSize: config.maxSize ?? 10,
43
- scaleUpThreshold: config.scaleUpThreshold ?? 0.8,
44
- scaleDownThreshold: config.scaleDownThreshold ?? 0.2,
45
- cooldownMs: config.cooldownMs ?? 30000,
46
- healthCheckIntervalMs: config.healthCheckIntervalMs ?? SWARM_CONSTANTS.DEFAULT_HEALTH_CHECK_INTERVAL_MS,
47
- };
48
- }
49
-
50
- async initialize(config?: AgentPoolConfig): Promise<void> {
51
- if (config) {
52
- this.config = { ...this.config, ...config };
53
- }
54
-
55
- // Start with minimum pool size - create agents in parallel
56
- const createPromises = Array.from(
57
- { length: this.config.minSize },
58
- () => this.createPooledAgent()
59
- );
60
- await Promise.all(createPromises);
61
-
62
- // Start health checks
63
- this.startHealthChecks();
64
-
65
- this.emit('initialized', {
66
- poolName: this.config.name,
67
- size: this.pooledAgents.size
68
- });
69
- }
70
-
71
- async shutdown(): Promise<void> {
72
- if (this.healthCheckInterval) {
73
- clearInterval(this.healthCheckInterval);
74
- this.healthCheckInterval = undefined;
75
- }
76
-
77
- // Mark all agents as terminated
78
- for (const pooled of this.pooledAgents.values()) {
79
- pooled.agent.status = 'terminated';
80
- }
81
-
82
- this.pooledAgents.clear();
83
- this.available.clear();
84
- this.busy.clear();
85
-
86
- this.emit('shutdown');
87
- }
88
-
89
- async acquire(): Promise<AgentState | undefined> {
90
- // Try to get an available agent
91
- const availableId = this.available.values().next().value as string | undefined;
92
-
93
- if (availableId) {
94
- const pooled = this.pooledAgents.get(availableId);
95
- if (pooled) {
96
- this.available.delete(availableId);
97
- this.busy.add(availableId);
98
- pooled.acquiredAt = new Date();
99
- pooled.usageCount++;
100
- pooled.agent.status = 'busy';
101
-
102
- this.emit('agent.acquired', { agentId: availableId });
103
-
104
- // Check if we need to scale up
105
- await this.checkScaling();
106
-
107
- return pooled.agent;
108
- }
109
- }
110
-
111
- // No available agents, try to scale up
112
- if (this.pooledAgents.size < this.config.maxSize) {
113
- const agent = await this.createPooledAgent();
114
- if (agent) {
115
- const pooled = this.pooledAgents.get(agent.id.id)!;
116
- this.available.delete(agent.id.id);
117
- this.busy.add(agent.id.id);
118
- pooled.acquiredAt = new Date();
119
- pooled.usageCount++;
120
- agent.status = 'busy';
121
-
122
- this.emit('agent.acquired', { agentId: agent.id.id });
123
-
124
- return agent;
125
- }
126
- }
127
-
128
- // Pool exhausted
129
- this.emit('pool.exhausted');
130
- return undefined;
131
- }
132
-
133
- async release(agentId: string): Promise<void> {
134
- const pooled = this.pooledAgents.get(agentId);
135
- if (!pooled) {
136
- return;
137
- }
138
-
139
- this.busy.delete(agentId);
140
- this.available.add(agentId);
141
- pooled.acquiredAt = undefined;
142
- pooled.lastUsed = new Date();
143
- pooled.agent.status = 'idle';
144
- pooled.agent.currentTask = undefined;
145
-
146
- this.emit('agent.released', { agentId });
147
-
148
- // Check if we need to scale down
149
- await this.checkScaling();
150
- }
151
-
152
- async add(agent: AgentState): Promise<void> {
153
- if (this.pooledAgents.size >= this.config.maxSize) {
154
- throw new Error(`Pool ${this.config.name} is at maximum capacity`);
155
- }
156
-
157
- const pooled: PooledAgent = {
158
- agent,
159
- lastUsed: new Date(),
160
- usageCount: 0,
161
- };
162
-
163
- this.pooledAgents.set(agent.id.id, pooled);
164
- this.available.add(agent.id.id);
165
-
166
- this.emit('agent.added', { agentId: agent.id.id });
167
- }
168
-
169
- async remove(agentId: string): Promise<void> {
170
- const pooled = this.pooledAgents.get(agentId);
171
- if (!pooled) {
172
- return;
173
- }
174
-
175
- this.pooledAgents.delete(agentId);
176
- this.available.delete(agentId);
177
- this.busy.delete(agentId);
178
- pooled.agent.status = 'terminated';
179
-
180
- this.emit('agent.removed', { agentId });
181
- }
182
-
183
- async scale(delta: number): Promise<void> {
184
- const now = new Date();
185
-
186
- // Check cooldown
187
- if (this.lastScaleOperation) {
188
- const timeSinceLastScale = now.getTime() - this.lastScaleOperation.getTime();
189
- if (timeSinceLastScale < this.config.cooldownMs) {
190
- return;
191
- }
192
- }
193
-
194
- if (delta > 0) {
195
- // Scale up - create agents in parallel
196
- const targetSize = Math.min(
197
- this.pooledAgents.size + delta,
198
- this.config.maxSize
199
- );
200
- const toCreate = targetSize - this.pooledAgents.size;
201
-
202
- const createPromises = Array.from(
203
- { length: toCreate },
204
- () => this.createPooledAgent()
205
- );
206
- await Promise.all(createPromises);
207
-
208
- this.emit('pool.scaled_up', { added: toCreate });
209
- } else if (delta < 0) {
210
- // Scale down - remove agents in parallel
211
- const targetSize = Math.max(
212
- this.pooledAgents.size + delta,
213
- this.config.minSize
214
- );
215
- const toRemove = this.pooledAgents.size - targetSize;
216
-
217
- // Remove least recently used available agents
218
- const sortedAvailable = Array.from(this.available)
219
- .map(id => this.pooledAgents.get(id)!)
220
- .filter(p => p !== undefined)
221
- .sort((a, b) => a.lastUsed.getTime() - b.lastUsed.getTime());
222
-
223
- const agentsToRemove = sortedAvailable.slice(0, toRemove);
224
- await Promise.all(agentsToRemove.map(pooled => this.remove(pooled.agent.id.id)));
225
-
226
- this.emit('pool.scaled_down', { removed: agentsToRemove.length });
227
- }
228
-
229
- this.lastScaleOperation = now;
230
- }
231
-
232
- getState(): AgentPoolState {
233
- return {
234
- id: `pool_${this.config.name}`,
235
- config: { ...this.config },
236
- agents: new Map(
237
- Array.from(this.pooledAgents.entries()).map(
238
- ([id, pooled]) => [id, pooled.agent]
239
- )
240
- ),
241
- availableAgents: Array.from(this.available),
242
- busyAgents: Array.from(this.busy),
243
- pendingScale: this.pendingScale,
244
- lastScaleOperation: this.lastScaleOperation,
245
- };
246
- }
247
-
248
- getAvailableCount(): number {
249
- return this.available.size;
250
- }
251
-
252
- getBusyCount(): number {
253
- return this.busy.size;
254
- }
255
-
256
- getTotalCount(): number {
257
- return this.pooledAgents.size;
258
- }
259
-
260
- getUtilization(): number {
261
- if (this.pooledAgents.size === 0) return 0;
262
- return this.busy.size / this.pooledAgents.size;
263
- }
264
-
265
- // ===== PRIVATE METHODS =====
266
-
267
- private async createPooledAgent(): Promise<AgentState | undefined> {
268
- if (this.pooledAgents.size >= this.config.maxSize) {
269
- return undefined;
270
- }
271
-
272
- this.agentCounter++;
273
- const agentId = `${this.config.name}_agent_${this.agentCounter}`;
274
-
275
- const agent: AgentState = {
276
- id: {
277
- id: agentId,
278
- swarmId: 'pool',
279
- type: this.config.type,
280
- instance: this.agentCounter,
281
- },
282
- name: `${this.config.name}-${this.agentCounter}`,
283
- type: this.config.type,
284
- status: 'idle',
285
- capabilities: this.createDefaultCapabilities(),
286
- metrics: this.createDefaultMetrics(),
287
- workload: 0,
288
- health: 1.0,
289
- lastHeartbeat: new Date(),
290
- connections: [],
291
- };
292
-
293
- const pooled: PooledAgent = {
294
- agent,
295
- lastUsed: new Date(),
296
- usageCount: 0,
297
- };
298
-
299
- this.pooledAgents.set(agentId, pooled);
300
- this.available.add(agentId);
301
-
302
- this.emit('agent.created', { agentId });
303
-
304
- return agent;
305
- }
306
-
307
- private createDefaultCapabilities(): AgentCapabilities {
308
- return {
309
- codeGeneration: true,
310
- codeReview: true,
311
- testing: true,
312
- documentation: true,
313
- research: true,
314
- analysis: true,
315
- coordination: this.config.type === 'coordinator',
316
- languages: ['typescript', 'javascript', 'python'],
317
- frameworks: ['node', 'deno', 'react'],
318
- domains: ['development', 'testing', 'analysis'],
319
- tools: ['git', 'npm', 'editor'],
320
- maxConcurrentTasks: 3,
321
- maxMemoryUsage: 512 * 1024 * 1024,
322
- maxExecutionTime: SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT_MS,
323
- reliability: 0.95,
324
- speed: 1.0,
325
- quality: 0.9,
326
- };
327
- }
328
-
329
- private createDefaultMetrics(): AgentMetrics {
330
- return {
331
- tasksCompleted: 0,
332
- tasksFailed: 0,
333
- averageExecutionTime: 0,
334
- successRate: 1.0,
335
- cpuUsage: 0,
336
- memoryUsage: 0,
337
- messagesProcessed: 0,
338
- lastActivity: new Date(),
339
- responseTime: 0,
340
- health: 1.0,
341
- };
342
- }
343
-
344
- private async checkScaling(): Promise<void> {
345
- const utilization = this.getUtilization();
346
-
347
- if (utilization >= this.config.scaleUpThreshold &&
348
- this.pooledAgents.size < this.config.maxSize) {
349
- // Scale up by 1
350
- this.pendingScale = 1;
351
- await this.scale(1);
352
- this.pendingScale = 0;
353
- } else if (utilization <= this.config.scaleDownThreshold &&
354
- this.pooledAgents.size > this.config.minSize) {
355
- // Scale down by 1
356
- this.pendingScale = -1;
357
- await this.scale(-1);
358
- this.pendingScale = 0;
359
- }
360
- }
361
-
362
- private startHealthChecks(): void {
363
- this.healthCheckInterval = setInterval(() => {
364
- this.performHealthChecks();
365
- }, this.config.healthCheckIntervalMs);
366
- }
367
-
368
- private performHealthChecks(): void {
369
- const now = new Date();
370
- const unhealthyThresholdMs = this.config.healthCheckIntervalMs * 3;
371
-
372
- for (const [agentId, pooled] of this.pooledAgents) {
373
- const timeSinceLastActivity = now.getTime() - pooled.agent.lastHeartbeat.getTime();
374
-
375
- if (timeSinceLastActivity > unhealthyThresholdMs) {
376
- // Agent is unhealthy
377
- pooled.agent.health = Math.max(0, pooled.agent.health - 0.2);
378
- pooled.agent.status = 'error';
379
-
380
- this.emit('agent.unhealthy', { agentId, health: pooled.agent.health });
381
-
382
- // If completely unhealthy, remove and replace
383
- if (pooled.agent.health <= 0) {
384
- this.replaceUnhealthyAgent(agentId);
385
- }
386
- } else {
387
- // Update health positively
388
- pooled.agent.health = Math.min(1.0, pooled.agent.health + 0.1);
389
- pooled.agent.lastHeartbeat = now;
390
- }
391
- }
392
- }
393
-
394
- private async replaceUnhealthyAgent(agentId: string): Promise<void> {
395
- const pooled = this.pooledAgents.get(agentId);
396
- if (!pooled) return;
397
-
398
- const wasBusy = this.busy.has(agentId);
399
- await this.remove(agentId);
400
-
401
- // Create replacement if below min size or was busy
402
- if (this.pooledAgents.size < this.config.minSize || wasBusy) {
403
- await this.createPooledAgent();
404
- }
405
-
406
- this.emit('agent.replaced', { oldAgentId: agentId });
407
- }
408
-
409
- // ===== UTILITY METHODS =====
410
-
411
- getAgent(agentId: string): AgentState | undefined {
412
- return this.pooledAgents.get(agentId)?.agent;
413
- }
414
-
415
- getAllAgents(): AgentState[] {
416
- return Array.from(this.pooledAgents.values()).map(p => p.agent);
417
- }
418
-
419
- getAvailableAgents(): AgentState[] {
420
- return Array.from(this.available)
421
- .map(id => this.pooledAgents.get(id)?.agent)
422
- .filter((a): a is AgentState => a !== undefined);
423
- }
424
-
425
- getBusyAgents(): AgentState[] {
426
- return Array.from(this.busy)
427
- .map(id => this.pooledAgents.get(id)?.agent)
428
- .filter((a): a is AgentState => a !== undefined);
429
- }
430
-
431
- updateAgentHeartbeat(agentId: string): void {
432
- const pooled = this.pooledAgents.get(agentId);
433
- if (pooled) {
434
- pooled.agent.lastHeartbeat = new Date();
435
- pooled.agent.health = Math.min(1.0, pooled.agent.health + 0.05);
436
- }
437
- }
438
-
439
- updateAgentMetrics(agentId: string, metrics: Partial<AgentMetrics>): void {
440
- const pooled = this.pooledAgents.get(agentId);
441
- if (pooled) {
442
- pooled.agent.metrics = { ...pooled.agent.metrics, ...metrics };
443
- pooled.agent.lastHeartbeat = new Date();
444
- }
445
- }
446
-
447
- getPoolStats(): {
448
- total: number;
449
- available: number;
450
- busy: number;
451
- utilization: number;
452
- avgHealth: number;
453
- avgUsageCount: number;
454
- } {
455
- const agents = Array.from(this.pooledAgents.values());
456
- const avgHealth = agents.length > 0
457
- ? agents.reduce((sum, p) => sum + p.agent.health, 0) / agents.length
458
- : 1.0;
459
- const avgUsageCount = agents.length > 0
460
- ? agents.reduce((sum, p) => sum + p.usageCount, 0) / agents.length
461
- : 0;
462
-
463
- return {
464
- total: this.pooledAgents.size,
465
- available: this.available.size,
466
- busy: this.busy.size,
467
- utilization: this.getUtilization(),
468
- avgHealth,
469
- avgUsageCount,
470
- };
471
- }
472
- }
473
-
474
- export function createAgentPool(config?: Partial<AgentPoolConfig>): AgentPool {
475
- return new AgentPool(config);
476
- }
@@ -1,124 +0,0 @@
1
- /**
2
- * Create Task Command - Application Layer (CQRS)
3
- *
4
- * Command for creating new tasks in the swarm.
5
- *
6
- * @module v3/swarm/application/commands
7
- */
8
-
9
- import { Task, TaskPriority, TaskProps } from '../../domain/entities/task.js';
10
- import { ITaskRepository } from '../../domain/repositories/task-repository.interface.js';
11
-
12
- /**
13
- * Create Task Command Input
14
- */
15
- export interface CreateTaskInput {
16
- title: string;
17
- description: string;
18
- type: string;
19
- priority?: TaskPriority;
20
- dependencies?: string[];
21
- metadata?: Record<string, unknown>;
22
- input?: unknown;
23
- timeout?: number;
24
- maxRetries?: number;
25
- autoQueue?: boolean;
26
- }
27
-
28
- /**
29
- * Create Task Command Result
30
- */
31
- export interface CreateTaskResult {
32
- success: boolean;
33
- taskId: string;
34
- task: Task;
35
- queuedAutomatically: boolean;
36
- }
37
-
38
- /**
39
- * Create Task Command Handler
40
- */
41
- export class CreateTaskCommandHandler {
42
- constructor(private readonly repository: ITaskRepository) {}
43
-
44
- async execute(input: CreateTaskInput): Promise<CreateTaskResult> {
45
- // Validate dependencies exist
46
- if (input.dependencies && input.dependencies.length > 0) {
47
- for (const depId of input.dependencies) {
48
- const exists = await this.repository.exists(depId);
49
- if (!exists) {
50
- throw new Error(`Dependency task '${depId}' not found`);
51
- }
52
- }
53
- }
54
-
55
- // Create task
56
- const task = Task.create({
57
- title: input.title,
58
- description: input.description,
59
- type: input.type,
60
- priority: input.priority,
61
- dependencies: input.dependencies,
62
- metadata: input.metadata,
63
- input: input.input,
64
- timeout: input.timeout,
65
- maxRetries: input.maxRetries,
66
- });
67
-
68
- // Auto-queue if requested and no dependencies
69
- let queuedAutomatically = false;
70
- if (input.autoQueue && (!input.dependencies || input.dependencies.length === 0)) {
71
- task.queue();
72
- queuedAutomatically = true;
73
- }
74
-
75
- await this.repository.save(task);
76
-
77
- return {
78
- success: true,
79
- taskId: task.id,
80
- task,
81
- queuedAutomatically,
82
- };
83
- }
84
- }
85
-
86
- /**
87
- * Cancel Task Command Input
88
- */
89
- export interface CancelTaskInput {
90
- taskId: string;
91
- }
92
-
93
- /**
94
- * Cancel Task Command Result
95
- */
96
- export interface CancelTaskResult {
97
- success: boolean;
98
- taskId: string;
99
- previousStatus: string;
100
- }
101
-
102
- /**
103
- * Cancel Task Command Handler
104
- */
105
- export class CancelTaskCommandHandler {
106
- constructor(private readonly repository: ITaskRepository) {}
107
-
108
- async execute(input: CancelTaskInput): Promise<CancelTaskResult> {
109
- const task = await this.repository.findById(input.taskId);
110
- if (!task) {
111
- throw new Error(`Task '${input.taskId}' not found`);
112
- }
113
-
114
- const previousStatus = task.status;
115
- task.cancel();
116
- await this.repository.save(task);
117
-
118
- return {
119
- success: true,
120
- taskId: input.taskId,
121
- previousStatus,
122
- };
123
- }
124
- }
@@ -1,122 +0,0 @@
1
- /**
2
- * Spawn Agent Command - Application Layer (CQRS)
3
- *
4
- * Command for spawning a new agent in the swarm.
5
- *
6
- * @module v3/swarm/application/commands
7
- */
8
-
9
- import { Agent, AgentRole, AgentProps } from '../../domain/entities/agent.js';
10
- import { IAgentRepository } from '../../domain/repositories/agent-repository.interface.js';
11
-
12
- /**
13
- * Spawn Agent Command Input
14
- */
15
- export interface SpawnAgentInput {
16
- name: string;
17
- role: AgentRole;
18
- domain: string;
19
- capabilities: string[];
20
- parentId?: string;
21
- metadata?: Record<string, unknown>;
22
- maxConcurrentTasks?: number;
23
- autoStart?: boolean;
24
- }
25
-
26
- /**
27
- * Spawn Agent Command Result
28
- */
29
- export interface SpawnAgentResult {
30
- success: boolean;
31
- agentId: string;
32
- agent: Agent;
33
- startedAutomatically: boolean;
34
- }
35
-
36
- /**
37
- * Spawn Agent Command Handler
38
- */
39
- export class SpawnAgentCommandHandler {
40
- constructor(private readonly repository: IAgentRepository) {}
41
-
42
- async execute(input: SpawnAgentInput): Promise<SpawnAgentResult> {
43
- // Check if agent with same name exists
44
- const existing = await this.repository.findByName(input.name);
45
- if (existing) {
46
- throw new Error(`Agent with name '${input.name}' already exists`);
47
- }
48
-
49
- // Create agent
50
- const agent = Agent.create({
51
- name: input.name,
52
- role: input.role,
53
- domain: input.domain,
54
- capabilities: input.capabilities,
55
- parentId: input.parentId,
56
- metadata: input.metadata,
57
- maxConcurrentTasks: input.maxConcurrentTasks,
58
- });
59
-
60
- // Auto-start if requested
61
- let startedAutomatically = false;
62
- if (input.autoStart) {
63
- agent.start();
64
- startedAutomatically = true;
65
- }
66
-
67
- await this.repository.save(agent);
68
-
69
- return {
70
- success: true,
71
- agentId: agent.id,
72
- agent,
73
- startedAutomatically,
74
- };
75
- }
76
- }
77
-
78
- /**
79
- * Terminate Agent Command Input
80
- */
81
- export interface TerminateAgentInput {
82
- agentId: string;
83
- force?: boolean;
84
- }
85
-
86
- /**
87
- * Terminate Agent Command Result
88
- */
89
- export interface TerminateAgentResult {
90
- success: boolean;
91
- agentId: string;
92
- tasksReassigned: number;
93
- }
94
-
95
- /**
96
- * Terminate Agent Command Handler
97
- */
98
- export class TerminateAgentCommandHandler {
99
- constructor(private readonly repository: IAgentRepository) {}
100
-
101
- async execute(input: TerminateAgentInput): Promise<TerminateAgentResult> {
102
- const agent = await this.repository.findById(input.agentId);
103
- if (!agent) {
104
- throw new Error(`Agent '${input.agentId}' not found`);
105
- }
106
-
107
- const currentTasks = agent.currentTaskCount;
108
-
109
- if (currentTasks > 0 && !input.force) {
110
- throw new Error(`Agent has ${currentTasks} active tasks. Use force=true to terminate anyway.`);
111
- }
112
-
113
- agent.terminate();
114
- await this.repository.save(agent);
115
-
116
- return {
117
- success: true,
118
- agentId: input.agentId,
119
- tasksReassigned: currentTasks,
120
- };
121
- }
122
- }