@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 +0,0 @@
1
- {"version":3,"file":"agent-repository.interface.js","sourceRoot":"","sources":["agent-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -1,69 +0,0 @@
1
- /**
2
- * Agent Repository Interface - Domain Layer
3
- *
4
- * Defines the contract for agent persistence.
5
- *
6
- * @module v3/swarm/domain/repositories
7
- */
8
-
9
- import { Agent, AgentStatus, AgentRole } from '../entities/agent.js';
10
-
11
- /**
12
- * Agent query options
13
- */
14
- export interface AgentQueryOptions {
15
- status?: AgentStatus;
16
- role?: AgentRole;
17
- domain?: string;
18
- parentId?: string;
19
- capability?: string;
20
- limit?: number;
21
- offset?: number;
22
- }
23
-
24
- /**
25
- * Agent statistics
26
- */
27
- export interface AgentStatistics {
28
- total: number;
29
- byStatus: Record<AgentStatus, number>;
30
- byRole: Record<string, number>;
31
- byDomain: Record<string, number>;
32
- totalTasksCompleted: number;
33
- averageUtilization: number;
34
- }
35
-
36
- /**
37
- * Agent Repository Interface
38
- */
39
- export interface IAgentRepository {
40
- // CRUD
41
- save(agent: Agent): Promise<void>;
42
- findById(id: string): Promise<Agent | null>;
43
- findByName(name: string): Promise<Agent | null>;
44
- delete(id: string): Promise<boolean>;
45
- exists(id: string): Promise<boolean>;
46
-
47
- // Bulk operations
48
- saveMany(agents: Agent[]): Promise<void>;
49
- findByIds(ids: string[]): Promise<Agent[]>;
50
- deleteMany(ids: string[]): Promise<number>;
51
-
52
- // Query operations
53
- findAll(options?: AgentQueryOptions): Promise<Agent[]>;
54
- findByStatus(status: AgentStatus): Promise<Agent[]>;
55
- findByRole(role: AgentRole): Promise<Agent[]>;
56
- findByDomain(domain: string): Promise<Agent[]>;
57
- findByParent(parentId: string): Promise<Agent[]>;
58
- findByCapability(capability: string): Promise<Agent[]>;
59
- findAvailable(): Promise<Agent[]>;
60
-
61
- // Statistics
62
- getStatistics(): Promise<AgentStatistics>;
63
- count(options?: AgentQueryOptions): Promise<number>;
64
-
65
- // Lifecycle
66
- initialize(): Promise<void>;
67
- shutdown(): Promise<void>;
68
- clear(): Promise<void>;
69
- }
@@ -1,61 +0,0 @@
1
- /**
2
- * Task Repository Interface - Domain Layer
3
- *
4
- * Defines the contract for task persistence.
5
- *
6
- * @module v3/swarm/domain/repositories
7
- */
8
- import { Task, TaskStatus, TaskPriority } from '../entities/task.js';
9
- /**
10
- * Task query options
11
- */
12
- export interface TaskQueryOptions {
13
- status?: TaskStatus;
14
- priority?: TaskPriority;
15
- type?: string;
16
- assignedAgentId?: string;
17
- limit?: number;
18
- offset?: number;
19
- orderBy?: 'createdAt' | 'priority' | 'startedAt';
20
- orderDirection?: 'asc' | 'desc';
21
- }
22
- /**
23
- * Task statistics
24
- */
25
- export interface TaskStatistics {
26
- total: number;
27
- byStatus: Record<TaskStatus, number>;
28
- byPriority: Record<TaskPriority, number>;
29
- byType: Record<string, number>;
30
- averageExecutionTime: number;
31
- successRate: number;
32
- retryRate: number;
33
- }
34
- /**
35
- * Task Repository Interface
36
- */
37
- export interface ITaskRepository {
38
- save(task: Task): Promise<void>;
39
- findById(id: string): Promise<Task | null>;
40
- delete(id: string): Promise<boolean>;
41
- exists(id: string): Promise<boolean>;
42
- saveMany(tasks: Task[]): Promise<void>;
43
- findByIds(ids: string[]): Promise<Task[]>;
44
- deleteMany(ids: string[]): Promise<number>;
45
- findAll(options?: TaskQueryOptions): Promise<Task[]>;
46
- findByStatus(status: TaskStatus): Promise<Task[]>;
47
- findByPriority(priority: TaskPriority): Promise<Task[]>;
48
- findByAgent(agentId: string): Promise<Task[]>;
49
- findPending(): Promise<Task[]>;
50
- findQueued(): Promise<Task[]>;
51
- findRunning(): Promise<Task[]>;
52
- findTimedOut(): Promise<Task[]>;
53
- getNextTask(agentCapabilities?: string[]): Promise<Task | null>;
54
- getTaskQueue(limit?: number): Promise<Task[]>;
55
- getStatistics(): Promise<TaskStatistics>;
56
- count(options?: TaskQueryOptions): Promise<number>;
57
- initialize(): Promise<void>;
58
- shutdown(): Promise<void>;
59
- clear(): Promise<void>;
60
- }
61
- //# sourceMappingURL=task-repository.interface.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-repository.interface.d.ts","sourceRoot":"","sources":["task-repository.interface.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- /**
2
- * Task Repository Interface - Domain Layer
3
- *
4
- * Defines the contract for task persistence.
5
- *
6
- * @module v3/swarm/domain/repositories
7
- */
8
- export {};
9
- //# sourceMappingURL=task-repository.interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-repository.interface.js","sourceRoot":"","sources":["task-repository.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -1,75 +0,0 @@
1
- /**
2
- * Task Repository Interface - Domain Layer
3
- *
4
- * Defines the contract for task persistence.
5
- *
6
- * @module v3/swarm/domain/repositories
7
- */
8
-
9
- import { Task, TaskStatus, TaskPriority } from '../entities/task.js';
10
-
11
- /**
12
- * Task query options
13
- */
14
- export interface TaskQueryOptions {
15
- status?: TaskStatus;
16
- priority?: TaskPriority;
17
- type?: string;
18
- assignedAgentId?: string;
19
- limit?: number;
20
- offset?: number;
21
- orderBy?: 'createdAt' | 'priority' | 'startedAt';
22
- orderDirection?: 'asc' | 'desc';
23
- }
24
-
25
- /**
26
- * Task statistics
27
- */
28
- export interface TaskStatistics {
29
- total: number;
30
- byStatus: Record<TaskStatus, number>;
31
- byPriority: Record<TaskPriority, number>;
32
- byType: Record<string, number>;
33
- averageExecutionTime: number;
34
- successRate: number;
35
- retryRate: number;
36
- }
37
-
38
- /**
39
- * Task Repository Interface
40
- */
41
- export interface ITaskRepository {
42
- // CRUD
43
- save(task: Task): Promise<void>;
44
- findById(id: string): Promise<Task | null>;
45
- delete(id: string): Promise<boolean>;
46
- exists(id: string): Promise<boolean>;
47
-
48
- // Bulk operations
49
- saveMany(tasks: Task[]): Promise<void>;
50
- findByIds(ids: string[]): Promise<Task[]>;
51
- deleteMany(ids: string[]): Promise<number>;
52
-
53
- // Query operations
54
- findAll(options?: TaskQueryOptions): Promise<Task[]>;
55
- findByStatus(status: TaskStatus): Promise<Task[]>;
56
- findByPriority(priority: TaskPriority): Promise<Task[]>;
57
- findByAgent(agentId: string): Promise<Task[]>;
58
- findPending(): Promise<Task[]>;
59
- findQueued(): Promise<Task[]>;
60
- findRunning(): Promise<Task[]>;
61
- findTimedOut(): Promise<Task[]>;
62
-
63
- // Queue operations
64
- getNextTask(agentCapabilities?: string[]): Promise<Task | null>;
65
- getTaskQueue(limit?: number): Promise<Task[]>;
66
-
67
- // Statistics
68
- getStatistics(): Promise<TaskStatistics>;
69
- count(options?: TaskQueryOptions): Promise<number>;
70
-
71
- // Lifecycle
72
- initialize(): Promise<void>;
73
- shutdown(): Promise<void>;
74
- clear(): Promise<void>;
75
- }
@@ -1,320 +0,0 @@
1
- /**
2
- * Coordination Domain Service - Domain Layer
3
- *
4
- * Contains coordination logic that spans multiple entities.
5
- * Handles task assignment, load balancing, and swarm orchestration.
6
- *
7
- * @module v3/swarm/domain/services
8
- */
9
-
10
- import { Agent, AgentRole } from '../entities/agent.js';
11
- import { Task, TaskPriority } from '../entities/task.js';
12
- import { IAgentRepository } from '../repositories/agent-repository.interface.js';
13
- import { ITaskRepository } from '../repositories/task-repository.interface.js';
14
-
15
- /**
16
- * Load balancing strategy
17
- */
18
- export type LoadBalancingStrategy = 'round-robin' | 'least-loaded' | 'capability-match' | 'random';
19
-
20
- /**
21
- * Task assignment result
22
- */
23
- export interface TaskAssignmentResult {
24
- success: boolean;
25
- taskId: string;
26
- agentId?: string;
27
- reason?: string;
28
- }
29
-
30
- /**
31
- * Swarm health status
32
- */
33
- export interface SwarmHealth {
34
- healthy: boolean;
35
- totalAgents: number;
36
- activeAgents: number;
37
- errorAgents: number;
38
- pendingTasks: number;
39
- runningTasks: number;
40
- queueDepth: number;
41
- averageUtilization: number;
42
- issues: string[];
43
- }
44
-
45
- /**
46
- * Coordination Domain Service
47
- *
48
- * Provides domain-level coordination operations.
49
- */
50
- export class CoordinationService {
51
- constructor(
52
- private readonly agentRepository: IAgentRepository,
53
- private readonly taskRepository: ITaskRepository
54
- ) {}
55
-
56
- /**
57
- * Assign a task to the best available agent
58
- */
59
- async assignTask(
60
- taskId: string,
61
- strategy: LoadBalancingStrategy = 'capability-match'
62
- ): Promise<TaskAssignmentResult> {
63
- const task = await this.taskRepository.findById(taskId);
64
- if (!task) {
65
- return { success: false, taskId, reason: 'Task not found' };
66
- }
67
-
68
- // Check dependencies
69
- const completedTasks = await this.taskRepository.findByStatus('completed');
70
- const completedIds = new Set(completedTasks.map((t) => t.id));
71
-
72
- if (!task.areDependenciesSatisfied(completedIds)) {
73
- return { success: false, taskId, reason: 'Dependencies not satisfied' };
74
- }
75
-
76
- // Find best agent
77
- const agent = await this.findBestAgent(task, strategy);
78
- if (!agent) {
79
- return { success: false, taskId, reason: 'No available agents' };
80
- }
81
-
82
- // Assign task
83
- task.assign(agent.id);
84
- agent.assignTask(taskId);
85
-
86
- await this.taskRepository.save(task);
87
- await this.agentRepository.save(agent);
88
-
89
- return { success: true, taskId, agentId: agent.id };
90
- }
91
-
92
- /**
93
- * Find the best agent for a task based on strategy
94
- */
95
- private async findBestAgent(
96
- task: Task,
97
- strategy: LoadBalancingStrategy
98
- ): Promise<Agent | null> {
99
- const availableAgents = await this.agentRepository.findAvailable();
100
-
101
- if (availableAgents.length === 0) return null;
102
-
103
- switch (strategy) {
104
- case 'round-robin':
105
- return this.roundRobinSelection(availableAgents);
106
-
107
- case 'least-loaded':
108
- return this.leastLoadedSelection(availableAgents);
109
-
110
- case 'capability-match':
111
- return this.capabilityMatchSelection(availableAgents, task);
112
-
113
- case 'random':
114
- return availableAgents[Math.floor(Math.random() * availableAgents.length)];
115
-
116
- default:
117
- return availableAgents[0];
118
- }
119
- }
120
-
121
- private roundRobinSelection(agents: Agent[]): Agent {
122
- // Sort by last active time and pick least recently used
123
- return [...agents].sort(
124
- (a, b) => a.lastActiveAt.getTime() - b.lastActiveAt.getTime()
125
- )[0];
126
- }
127
-
128
- private leastLoadedSelection(agents: Agent[]): Agent {
129
- return [...agents].sort((a, b) => a.getUtilization() - b.getUtilization())[0];
130
- }
131
-
132
- private capabilityMatchSelection(agents: Agent[], task: Task): Agent | null {
133
- // Extract required capabilities from task type and metadata
134
- const requiredCapabilities = this.extractRequiredCapabilities(task);
135
-
136
- // Score agents by capability match
137
- const scored = agents.map((agent) => {
138
- let score = 0;
139
- for (const cap of requiredCapabilities) {
140
- if (agent.hasCapability(cap)) score++;
141
- }
142
- // Factor in utilization (prefer less loaded)
143
- score -= agent.getUtilization() * 0.5;
144
- return { agent, score };
145
- });
146
-
147
- scored.sort((a, b) => b.score - a.score);
148
-
149
- // Return best match if any capabilities matched
150
- if (scored.length > 0 && scored[0].score > 0) {
151
- return scored[0].agent;
152
- }
153
-
154
- // Fallback to least loaded
155
- return this.leastLoadedSelection(agents);
156
- }
157
-
158
- private extractRequiredCapabilities(task: Task): string[] {
159
- const capabilities: string[] = [task.type];
160
-
161
- // Map task types to required capabilities
162
- const capabilityMap: Record<string, string[]> = {
163
- implementation: ['coding', 'testing'],
164
- review: ['review', 'analysis'],
165
- testing: ['testing', 'qa'],
166
- documentation: ['documentation', 'writing'],
167
- security: ['security', 'audit'],
168
- performance: ['performance', 'optimization'],
169
- };
170
-
171
- if (capabilityMap[task.type]) {
172
- capabilities.push(...capabilityMap[task.type]);
173
- }
174
-
175
- return capabilities;
176
- }
177
-
178
- /**
179
- * Process completed tasks and release agents
180
- */
181
- async processTaskCompletion(taskId: string, output?: unknown): Promise<void> {
182
- const task = await this.taskRepository.findById(taskId);
183
- if (!task || !task.assignedAgentId) return;
184
-
185
- const agent = await this.agentRepository.findById(task.assignedAgentId);
186
-
187
- task.complete(output);
188
- await this.taskRepository.save(task);
189
-
190
- if (agent) {
191
- agent.completeTask(taskId);
192
- await this.agentRepository.save(agent);
193
- }
194
-
195
- // Check for dependent tasks that can now be queued
196
- await this.queueDependentTasks(taskId);
197
- }
198
-
199
- /**
200
- * Queue tasks whose dependencies are now satisfied
201
- */
202
- private async queueDependentTasks(completedTaskId: string): Promise<void> {
203
- const pendingTasks = await this.taskRepository.findPending();
204
- const completedTasks = await this.taskRepository.findByStatus('completed');
205
- const completedIds = new Set(completedTasks.map((t) => t.id));
206
-
207
- for (const task of pendingTasks) {
208
- if (
209
- task.dependencies.includes(completedTaskId) &&
210
- task.areDependenciesSatisfied(completedIds)
211
- ) {
212
- task.queue();
213
- await this.taskRepository.save(task);
214
- }
215
- }
216
- }
217
-
218
- /**
219
- * Handle task failure with retry logic
220
- */
221
- async processTaskFailure(taskId: string, error: string): Promise<boolean> {
222
- const task = await this.taskRepository.findById(taskId);
223
- if (!task) return false;
224
-
225
- const agentId = task.assignedAgentId;
226
-
227
- task.fail(error);
228
- await this.taskRepository.save(task);
229
-
230
- if (agentId) {
231
- const agent = await this.agentRepository.findById(agentId);
232
- if (agent) {
233
- agent.completeTask(taskId);
234
- await this.agentRepository.save(agent);
235
- }
236
- }
237
-
238
- // Return true if task was requeued for retry
239
- return task.status === 'queued';
240
- }
241
-
242
- /**
243
- * Get overall swarm health
244
- */
245
- async getSwarmHealth(): Promise<SwarmHealth> {
246
- const agentStats = await this.agentRepository.getStatistics();
247
- const taskStats = await this.taskRepository.getStatistics();
248
- const queuedTasks = await this.taskRepository.findQueued();
249
-
250
- const issues: string[] = [];
251
-
252
- // Check for issues
253
- if (agentStats.byStatus.error > 0) {
254
- issues.push(`${agentStats.byStatus.error} agents in error state`);
255
- }
256
- if (queuedTasks.length > agentStats.byStatus.active * 10) {
257
- issues.push('Task queue backlog detected');
258
- }
259
- if (agentStats.averageUtilization > 0.9) {
260
- issues.push('High agent utilization');
261
- }
262
-
263
- const timedOutTasks = await this.taskRepository.findTimedOut();
264
- if (timedOutTasks.length > 0) {
265
- issues.push(`${timedOutTasks.length} timed out tasks`);
266
- }
267
-
268
- return {
269
- healthy: issues.length === 0,
270
- totalAgents: agentStats.total,
271
- activeAgents: agentStats.byStatus.active + agentStats.byStatus.busy,
272
- errorAgents: agentStats.byStatus.error,
273
- pendingTasks: taskStats.byStatus.pending,
274
- runningTasks: taskStats.byStatus.running,
275
- queueDepth: queuedTasks.length,
276
- averageUtilization: agentStats.averageUtilization,
277
- issues,
278
- };
279
- }
280
-
281
- /**
282
- * Scale agents based on workload
283
- */
284
- async calculateScalingRecommendation(): Promise<{
285
- action: 'scale-up' | 'scale-down' | 'none';
286
- count: number;
287
- reason: string;
288
- }> {
289
- const health = await this.getSwarmHealth();
290
- const queuedTasks = await this.taskRepository.findQueued();
291
-
292
- // Scale up if queue is deep and agents are highly utilized
293
- if (queuedTasks.length > 10 && health.averageUtilization > 0.8) {
294
- const additionalAgents = Math.ceil(queuedTasks.length / 5);
295
- return {
296
- action: 'scale-up',
297
- count: additionalAgents,
298
- reason: 'High queue depth with high agent utilization',
299
- };
300
- }
301
-
302
- // Scale down if queue is empty and many agents are idle
303
- if (queuedTasks.length === 0 && health.averageUtilization < 0.2) {
304
- const excessAgents = Math.floor(health.totalAgents * 0.3);
305
- if (excessAgents > 0) {
306
- return {
307
- action: 'scale-down',
308
- count: excessAgents,
309
- reason: 'Low utilization with empty queue',
310
- };
311
- }
312
- }
313
-
314
- return {
315
- action: 'none',
316
- count: 0,
317
- reason: 'Current scaling is appropriate',
318
- };
319
- }
320
- }