@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
@@ -1,605 +0,0 @@
1
- /**
2
- * V3 Task Orchestrator
3
- * Manages task decomposition, dependency resolution, and parallel execution
4
- *
5
- * Based on ADR-003 (Single Coordination Engine) and ADR-001 (agentic-flow integration)
6
- */
7
-
8
- import {
9
- TaskId,
10
- TaskType,
11
- TaskStatus,
12
- TaskPriority,
13
- TaskDefinition,
14
- TaskMetadata,
15
- TaskResult,
16
- TaskResultMetrics,
17
- AgentId,
18
- AgentDomain,
19
- PhaseId,
20
- SwarmEvent
21
- } from '../shared/types';
22
- import {
23
- IEventBus,
24
- taskCreatedEvent,
25
- taskQueuedEvent,
26
- taskAssignedEvent,
27
- taskStartedEvent,
28
- taskCompletedEvent,
29
- taskFailedEvent,
30
- taskBlockedEvent
31
- } from '../shared/events';
32
- import { IAgentRegistry } from './agent-registry';
33
-
34
- // =============================================================================
35
- // Task Orchestrator Interface
36
- // =============================================================================
37
-
38
- export interface ITaskOrchestrator {
39
- // Task Creation
40
- createTask(spec: TaskSpec): TaskDefinition;
41
- createBatchTasks(specs: TaskSpec[]): TaskDefinition[];
42
-
43
- // Task Lifecycle
44
- queueTask(taskId: TaskId): void;
45
- assignTask(taskId: TaskId, agentId: AgentId): void;
46
- startTask(taskId: TaskId): void;
47
- completeTask(taskId: TaskId, result: TaskResult): void;
48
- failTask(taskId: TaskId, error: Error): void;
49
- cancelTask(taskId: TaskId): void;
50
-
51
- // Dependency Management
52
- addDependency(taskId: TaskId, dependsOn: TaskId): void;
53
- removeDependency(taskId: TaskId, dependsOn: TaskId): void;
54
- getDependencies(taskId: TaskId): TaskId[];
55
- getDependents(taskId: TaskId): TaskId[];
56
- isBlocked(taskId: TaskId): boolean;
57
- getBlockingTasks(taskId: TaskId): TaskId[];
58
-
59
- // Queries
60
- getTask(taskId: TaskId): TaskDefinition | undefined;
61
- getAllTasks(): TaskDefinition[];
62
- getTasksByStatus(status: TaskStatus): TaskDefinition[];
63
- getTasksByAgent(agentId: AgentId): TaskDefinition[];
64
- getTasksByDomain(domain: AgentDomain): TaskDefinition[];
65
- getTasksByPhase(phase: PhaseId): TaskDefinition[];
66
-
67
- // Queue Management
68
- getNextTask(agentId?: AgentId): TaskDefinition | undefined;
69
- getPriorityQueue(): TaskDefinition[];
70
-
71
- // Metrics
72
- getTaskMetrics(): TaskOrchestratorMetrics;
73
- }
74
-
75
- export interface TaskSpec {
76
- type: TaskType;
77
- title: string;
78
- description: string;
79
- priority?: TaskPriority;
80
- dependencies?: TaskId[];
81
- domain: AgentDomain;
82
- phase: PhaseId;
83
- estimatedDuration?: number;
84
- tags?: string[];
85
- }
86
-
87
- export interface TaskOrchestratorMetrics {
88
- totalTasks: number;
89
- tasksByStatus: Record<TaskStatus, number>;
90
- tasksByPriority: Record<TaskPriority, number>;
91
- tasksByDomain: Record<AgentDomain, number>;
92
- averageQueueTime: number;
93
- averageExecutionTime: number;
94
- throughput: number;
95
- }
96
-
97
- // =============================================================================
98
- // Task Orchestrator Implementation
99
- // =============================================================================
100
-
101
- export class TaskOrchestrator implements ITaskOrchestrator {
102
- private tasks: Map<TaskId, TaskDefinition> = new Map();
103
- private dependencyGraph: Map<TaskId, Set<TaskId>> = new Map();
104
- private dependentGraph: Map<TaskId, Set<TaskId>> = new Map();
105
- private taskCounter: number = 0;
106
- private eventBus: IEventBus;
107
- private agentRegistry: IAgentRegistry;
108
-
109
- constructor(eventBus: IEventBus, agentRegistry: IAgentRegistry) {
110
- this.eventBus = eventBus;
111
- this.agentRegistry = agentRegistry;
112
-
113
- this.eventBus.subscribe('agent:task-completed', this.handleAgentTaskCompleted.bind(this));
114
- }
115
-
116
- // ==========================================================================
117
- // Task Creation
118
- // ==========================================================================
119
-
120
- createTask(spec: TaskSpec): TaskDefinition {
121
- const taskId: TaskId = `task-${Date.now()}-${++this.taskCounter}`;
122
-
123
- const task: TaskDefinition = {
124
- id: taskId,
125
- type: spec.type,
126
- title: spec.title,
127
- description: spec.description,
128
- assignedAgent: null,
129
- status: 'pending',
130
- priority: spec.priority ?? 'medium',
131
- dependencies: spec.dependencies ?? [],
132
- blockedBy: [],
133
- metadata: {
134
- domain: spec.domain,
135
- phase: spec.phase,
136
- estimatedDuration: spec.estimatedDuration ?? 0,
137
- actualDuration: null,
138
- retryCount: 0,
139
- maxRetries: 3,
140
- artifacts: [],
141
- tags: spec.tags ?? []
142
- },
143
- createdAt: Date.now(),
144
- updatedAt: Date.now(),
145
- completedAt: null
146
- };
147
-
148
- this.tasks.set(taskId, task);
149
- this.dependencyGraph.set(taskId, new Set(task.dependencies));
150
- this.dependentGraph.set(taskId, new Set());
151
-
152
- for (const depId of task.dependencies) {
153
- if (this.dependentGraph.has(depId)) {
154
- this.dependentGraph.get(depId)!.add(taskId);
155
- }
156
- }
157
-
158
- this.updateBlockedStatus(taskId);
159
-
160
- this.eventBus.emitSync(taskCreatedEvent(taskId, { type: spec.type, title: spec.title }));
161
-
162
- return task;
163
- }
164
-
165
- createBatchTasks(specs: TaskSpec[]): TaskDefinition[] {
166
- return specs.map(spec => this.createTask(spec));
167
- }
168
-
169
- // ==========================================================================
170
- // Task Lifecycle
171
- // ==========================================================================
172
-
173
- queueTask(taskId: TaskId): void {
174
- const task = this.getTaskOrThrow(taskId);
175
-
176
- if (this.isBlocked(taskId)) {
177
- this.updateTaskStatus(taskId, 'blocked');
178
- return;
179
- }
180
-
181
- this.updateTaskStatus(taskId, 'queued');
182
- this.eventBus.emitSync(taskQueuedEvent(taskId, this.getQueuePosition(taskId)));
183
- }
184
-
185
- assignTask(taskId: TaskId, agentId: AgentId): void {
186
- const task = this.getTaskOrThrow(taskId);
187
-
188
- if (task.status !== 'queued') {
189
- throw new Error(`Task ${taskId} is not queued (status: ${task.status})`);
190
- }
191
-
192
- if (this.isBlocked(taskId)) {
193
- throw new Error(`Task ${taskId} is blocked by dependencies`);
194
- }
195
-
196
- task.assignedAgent = agentId;
197
- this.updateTaskStatus(taskId, 'assigned');
198
-
199
- this.agentRegistry.assignTask(agentId, taskId);
200
-
201
- this.eventBus.emitSync(taskAssignedEvent(taskId, agentId));
202
- }
203
-
204
- startTask(taskId: TaskId): void {
205
- const task = this.getTaskOrThrow(taskId);
206
-
207
- if (task.status !== 'assigned') {
208
- throw new Error(`Task ${taskId} is not assigned (status: ${task.status})`);
209
- }
210
-
211
- this.updateTaskStatus(taskId, 'in-progress');
212
-
213
- if (task.assignedAgent) {
214
- this.eventBus.emitSync(taskStartedEvent(taskId, task.assignedAgent));
215
- }
216
- }
217
-
218
- completeTask(taskId: TaskId, result: TaskResult): void {
219
- const task = this.getTaskOrThrow(taskId);
220
-
221
- if (task.status !== 'in-progress') {
222
- throw new Error(`Task ${taskId} is not in progress (status: ${task.status})`);
223
- }
224
-
225
- task.metadata.actualDuration = result.duration;
226
- task.completedAt = Date.now();
227
-
228
- this.updateTaskStatus(taskId, 'completed');
229
-
230
- if (task.assignedAgent) {
231
- this.agentRegistry.completeTask(task.assignedAgent, taskId);
232
- }
233
-
234
- this.eventBus.emitSync(taskCompletedEvent(taskId, result));
235
-
236
- this.unblockDependentTasks(taskId);
237
- }
238
-
239
- failTask(taskId: TaskId, error: Error): void {
240
- const task = this.getTaskOrThrow(taskId);
241
-
242
- task.metadata.retryCount++;
243
-
244
- if (task.metadata.retryCount < task.metadata.maxRetries) {
245
- this.updateTaskStatus(taskId, 'queued');
246
- task.assignedAgent = null;
247
- } else {
248
- this.updateTaskStatus(taskId, 'failed');
249
-
250
- if (task.assignedAgent) {
251
- const agentState = this.agentRegistry.getState(task.assignedAgent);
252
- if (agentState) {
253
- agentState.metrics.tasksFailed++;
254
- }
255
- }
256
- }
257
-
258
- this.eventBus.emitSync(taskFailedEvent(taskId, error));
259
- }
260
-
261
- cancelTask(taskId: TaskId): void {
262
- const task = this.getTaskOrThrow(taskId);
263
-
264
- if (task.status === 'completed' || task.status === 'failed') {
265
- throw new Error(`Cannot cancel ${task.status} task ${taskId}`);
266
- }
267
-
268
- if (task.assignedAgent) {
269
- this.agentRegistry.updateStatus(task.assignedAgent, 'idle');
270
- }
271
-
272
- this.updateTaskStatus(taskId, 'cancelled');
273
- }
274
-
275
- // ==========================================================================
276
- // Dependency Management
277
- // ==========================================================================
278
-
279
- addDependency(taskId: TaskId, dependsOn: TaskId): void {
280
- const task = this.getTaskOrThrow(taskId);
281
- this.getTaskOrThrow(dependsOn);
282
-
283
- if (this.wouldCreateCycle(taskId, dependsOn)) {
284
- throw new Error(`Adding dependency ${dependsOn} to ${taskId} would create a cycle`);
285
- }
286
-
287
- task.dependencies.push(dependsOn);
288
- this.dependencyGraph.get(taskId)!.add(dependsOn);
289
- this.dependentGraph.get(dependsOn)!.add(taskId);
290
-
291
- this.updateBlockedStatus(taskId);
292
- }
293
-
294
- removeDependency(taskId: TaskId, dependsOn: TaskId): void {
295
- const task = this.getTaskOrThrow(taskId);
296
-
297
- const index = task.dependencies.indexOf(dependsOn);
298
- if (index > -1) {
299
- task.dependencies.splice(index, 1);
300
- }
301
-
302
- this.dependencyGraph.get(taskId)?.delete(dependsOn);
303
- this.dependentGraph.get(dependsOn)?.delete(taskId);
304
-
305
- this.updateBlockedStatus(taskId);
306
- }
307
-
308
- getDependencies(taskId: TaskId): TaskId[] {
309
- return Array.from(this.dependencyGraph.get(taskId) ?? []);
310
- }
311
-
312
- getDependents(taskId: TaskId): TaskId[] {
313
- return Array.from(this.dependentGraph.get(taskId) ?? []);
314
- }
315
-
316
- isBlocked(taskId: TaskId): boolean {
317
- const blockingTasks = this.getBlockingTasks(taskId);
318
- return blockingTasks.length > 0;
319
- }
320
-
321
- getBlockingTasks(taskId: TaskId): TaskId[] {
322
- const dependencies = this.dependencyGraph.get(taskId);
323
- if (!dependencies) {
324
- return [];
325
- }
326
-
327
- return Array.from(dependencies).filter(depId => {
328
- const depTask = this.tasks.get(depId);
329
- return depTask && depTask.status !== 'completed';
330
- });
331
- }
332
-
333
- // ==========================================================================
334
- // Queries
335
- // ==========================================================================
336
-
337
- getTask(taskId: TaskId): TaskDefinition | undefined {
338
- return this.tasks.get(taskId);
339
- }
340
-
341
- getAllTasks(): TaskDefinition[] {
342
- return Array.from(this.tasks.values());
343
- }
344
-
345
- getTasksByStatus(status: TaskStatus): TaskDefinition[] {
346
- return this.getAllTasks().filter(t => t.status === status);
347
- }
348
-
349
- getTasksByAgent(agentId: AgentId): TaskDefinition[] {
350
- return this.getAllTasks().filter(t => t.assignedAgent === agentId);
351
- }
352
-
353
- getTasksByDomain(domain: AgentDomain): TaskDefinition[] {
354
- return this.getAllTasks().filter(t => t.metadata.domain === domain);
355
- }
356
-
357
- getTasksByPhase(phase: PhaseId): TaskDefinition[] {
358
- return this.getAllTasks().filter(t => t.metadata.phase === phase);
359
- }
360
-
361
- // ==========================================================================
362
- // Queue Management
363
- // ==========================================================================
364
-
365
- getNextTask(agentId?: AgentId): TaskDefinition | undefined {
366
- const queuedTasks = this.getTasksByStatus('queued')
367
- .filter(t => !this.isBlocked(t.id))
368
- .sort((a, b) => {
369
- const priorityOrder: Record<TaskPriority, number> = {
370
- 'critical': 0,
371
- 'high': 1,
372
- 'medium': 2,
373
- 'low': 3
374
- };
375
-
376
- const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
377
- if (priorityDiff !== 0) return priorityDiff;
378
-
379
- return a.createdAt - b.createdAt;
380
- });
381
-
382
- if (!agentId) {
383
- return queuedTasks[0];
384
- }
385
-
386
- const agentDef = this.agentRegistry.getDefinition(agentId);
387
- if (!agentDef) {
388
- return queuedTasks[0];
389
- }
390
-
391
- const supportedTypes = agentDef.capabilities.flatMap(c => c.supportedTaskTypes);
392
-
393
- return queuedTasks.find(t => supportedTypes.includes(t.type));
394
- }
395
-
396
- getPriorityQueue(): TaskDefinition[] {
397
- return this.getTasksByStatus('queued')
398
- .filter(t => !this.isBlocked(t.id))
399
- .sort((a, b) => {
400
- const priorityOrder: Record<TaskPriority, number> = {
401
- 'critical': 0,
402
- 'high': 1,
403
- 'medium': 2,
404
- 'low': 3
405
- };
406
- return priorityOrder[a.priority] - priorityOrder[b.priority];
407
- });
408
- }
409
-
410
- // ==========================================================================
411
- // Metrics
412
- // ==========================================================================
413
-
414
- getTaskMetrics(): TaskOrchestratorMetrics {
415
- const allTasks = this.getAllTasks();
416
-
417
- const tasksByStatus: Record<TaskStatus, number> = {
418
- 'pending': 0,
419
- 'queued': 0,
420
- 'assigned': 0,
421
- 'in-progress': 0,
422
- 'blocked': 0,
423
- 'completed': 0,
424
- 'failed': 0,
425
- 'cancelled': 0
426
- };
427
-
428
- const tasksByPriority: Record<TaskPriority, number> = {
429
- 'critical': 0,
430
- 'high': 0,
431
- 'medium': 0,
432
- 'low': 0
433
- };
434
-
435
- const tasksByDomain: Record<AgentDomain, number> = {
436
- 'security': 0,
437
- 'core': 0,
438
- 'integration': 0,
439
- 'quality': 0,
440
- 'performance': 0,
441
- 'deployment': 0
442
- };
443
-
444
- let totalQueueTime = 0;
445
- let totalExecutionTime = 0;
446
- let completedCount = 0;
447
-
448
- for (const task of allTasks) {
449
- tasksByStatus[task.status]++;
450
- tasksByPriority[task.priority]++;
451
- tasksByDomain[task.metadata.domain]++;
452
-
453
- if (task.status === 'completed' && task.metadata.actualDuration) {
454
- totalExecutionTime += task.metadata.actualDuration;
455
- completedCount++;
456
- }
457
- }
458
-
459
- const now = Date.now();
460
- const firstTask = allTasks[0];
461
- const runtimeMs = firstTask ? now - firstTask.createdAt : 1;
462
- const throughput = completedCount / (runtimeMs / 1000 / 60);
463
-
464
- return {
465
- totalTasks: allTasks.length,
466
- tasksByStatus,
467
- tasksByPriority,
468
- tasksByDomain,
469
- averageQueueTime: totalQueueTime / (completedCount || 1),
470
- averageExecutionTime: totalExecutionTime / (completedCount || 1),
471
- throughput
472
- };
473
- }
474
-
475
- // ==========================================================================
476
- // Private Helpers
477
- // ==========================================================================
478
-
479
- private getTaskOrThrow(taskId: TaskId): TaskDefinition {
480
- const task = this.tasks.get(taskId);
481
- if (!task) {
482
- throw new Error(`Task ${taskId} not found`);
483
- }
484
- return task;
485
- }
486
-
487
- private updateTaskStatus(taskId: TaskId, status: TaskStatus): void {
488
- const task = this.getTaskOrThrow(taskId);
489
- task.status = status;
490
- task.updatedAt = Date.now();
491
-
492
- if (status === 'blocked') {
493
- task.blockedBy = this.getBlockingTasks(taskId);
494
- } else {
495
- task.blockedBy = [];
496
- }
497
- }
498
-
499
- private updateBlockedStatus(taskId: TaskId): void {
500
- const task = this.tasks.get(taskId);
501
- if (!task || task.status === 'completed' || task.status === 'failed') {
502
- return;
503
- }
504
-
505
- const isBlocked = this.isBlocked(taskId);
506
-
507
- if (isBlocked && task.status !== 'blocked') {
508
- this.updateTaskStatus(taskId, 'blocked');
509
- const blockingTasks = this.getBlockingTasks(taskId);
510
- this.eventBus.emitSync(taskBlockedEvent(taskId, 'Blocked by dependencies', blockingTasks[0]));
511
- } else if (!isBlocked && task.status === 'blocked') {
512
- this.updateTaskStatus(taskId, 'queued');
513
- }
514
- }
515
-
516
- private unblockDependentTasks(taskId: TaskId): void {
517
- const dependents = this.getDependents(taskId);
518
-
519
- for (const dependentId of dependents) {
520
- this.updateBlockedStatus(dependentId);
521
- }
522
- }
523
-
524
- private wouldCreateCycle(taskId: TaskId, newDependency: TaskId): boolean {
525
- const visited = new Set<TaskId>();
526
- const stack = [newDependency];
527
-
528
- while (stack.length > 0) {
529
- const current = stack.pop()!;
530
-
531
- if (current === taskId) {
532
- return true;
533
- }
534
-
535
- if (visited.has(current)) {
536
- continue;
537
- }
538
-
539
- visited.add(current);
540
-
541
- const deps = this.dependencyGraph.get(current);
542
- if (deps) {
543
- stack.push(...deps);
544
- }
545
- }
546
-
547
- return false;
548
- }
549
-
550
- private handleAgentTaskCompleted(event: SwarmEvent): void {
551
- const payload = event.payload as { taskId: TaskId; result: unknown };
552
-
553
- if (payload.taskId && this.tasks.has(payload.taskId)) {
554
- const task = this.tasks.get(payload.taskId)!;
555
- if (task.status === 'in-progress') {
556
- this.completeTask(payload.taskId, {
557
- taskId: payload.taskId,
558
- success: true,
559
- output: payload.result,
560
- error: null,
561
- duration: Date.now() - task.updatedAt,
562
- metrics: this.createDefaultMetrics()
563
- });
564
- }
565
- }
566
- }
567
-
568
- private createDefaultMetrics(): TaskResultMetrics {
569
- return {
570
- linesOfCode: 0,
571
- testsWritten: 0,
572
- testsPassed: 0,
573
- coveragePercent: 0,
574
- performanceImpact: 0
575
- };
576
- }
577
-
578
- private getQueuePosition(taskId: TaskId): number {
579
- const priorityOrder: Record<string, number> = {
580
- critical: 5,
581
- high: 4,
582
- normal: 3,
583
- low: 2,
584
- background: 1,
585
- };
586
-
587
- const queuedTasks = Array.from(this.tasks.values())
588
- .filter(t => t.status === 'queued')
589
- .sort((a, b) => (priorityOrder[b.priority] || 0) - (priorityOrder[a.priority] || 0));
590
-
591
- const position = queuedTasks.findIndex(t => t.id === taskId);
592
- return position >= 0 ? position + 1 : queuedTasks.length + 1;
593
- }
594
- }
595
-
596
- // =============================================================================
597
- // Factory Function
598
- // =============================================================================
599
-
600
- export function createTaskOrchestrator(
601
- eventBus: IEventBus,
602
- agentRegistry: IAgentRegistry
603
- ): ITaskOrchestrator {
604
- return new TaskOrchestrator(eventBus, agentRegistry);
605
- }