claude-flow 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +612 -0
- package/bin/claude-flow +0 -0
- package/bin/claude-flow-simple +0 -0
- package/bin/claude-flow-typecheck +0 -0
- package/deno.json +84 -0
- package/package.json +45 -0
- package/scripts/check-links.ts +274 -0
- package/scripts/check-performance-regression.ts +168 -0
- package/scripts/claude-sparc.sh +562 -0
- package/scripts/coverage-report.ts +692 -0
- package/scripts/demo-task-system.ts +224 -0
- package/scripts/install.js +72 -0
- package/scripts/test-batch-tasks.ts +29 -0
- package/scripts/test-coordination-features.ts +238 -0
- package/scripts/test-mcp.ts +251 -0
- package/scripts/test-runner.ts +571 -0
- package/scripts/validate-examples.ts +288 -0
- package/src/cli/cli-core.ts +273 -0
- package/src/cli/commands/agent.ts +83 -0
- package/src/cli/commands/config.ts +442 -0
- package/src/cli/commands/help.ts +765 -0
- package/src/cli/commands/index.ts +963 -0
- package/src/cli/commands/mcp.ts +191 -0
- package/src/cli/commands/memory.ts +74 -0
- package/src/cli/commands/monitor.ts +403 -0
- package/src/cli/commands/session.ts +595 -0
- package/src/cli/commands/start.ts +156 -0
- package/src/cli/commands/status.ts +345 -0
- package/src/cli/commands/task.ts +79 -0
- package/src/cli/commands/workflow.ts +763 -0
- package/src/cli/completion.ts +553 -0
- package/src/cli/formatter.ts +310 -0
- package/src/cli/index.ts +211 -0
- package/src/cli/main.ts +23 -0
- package/src/cli/repl.ts +1050 -0
- package/src/cli/simple-cli.js +211 -0
- package/src/cli/simple-cli.ts +211 -0
- package/src/coordination/README.md +400 -0
- package/src/coordination/advanced-scheduler.ts +487 -0
- package/src/coordination/circuit-breaker.ts +366 -0
- package/src/coordination/conflict-resolution.ts +490 -0
- package/src/coordination/dependency-graph.ts +475 -0
- package/src/coordination/index.ts +63 -0
- package/src/coordination/manager.ts +460 -0
- package/src/coordination/messaging.ts +290 -0
- package/src/coordination/metrics.ts +585 -0
- package/src/coordination/resources.ts +322 -0
- package/src/coordination/scheduler.ts +390 -0
- package/src/coordination/work-stealing.ts +224 -0
- package/src/core/config.ts +627 -0
- package/src/core/event-bus.ts +186 -0
- package/src/core/json-persistence.ts +183 -0
- package/src/core/logger.ts +262 -0
- package/src/core/orchestrator-fixed.ts +312 -0
- package/src/core/orchestrator.ts +1234 -0
- package/src/core/persistence.ts +276 -0
- package/src/mcp/auth.ts +438 -0
- package/src/mcp/claude-flow-tools.ts +1280 -0
- package/src/mcp/load-balancer.ts +510 -0
- package/src/mcp/router.ts +240 -0
- package/src/mcp/server.ts +548 -0
- package/src/mcp/session-manager.ts +418 -0
- package/src/mcp/tools.ts +180 -0
- package/src/mcp/transports/base.ts +21 -0
- package/src/mcp/transports/http.ts +457 -0
- package/src/mcp/transports/stdio.ts +254 -0
- package/src/memory/backends/base.ts +22 -0
- package/src/memory/backends/markdown.ts +283 -0
- package/src/memory/backends/sqlite.ts +329 -0
- package/src/memory/cache.ts +238 -0
- package/src/memory/indexer.ts +238 -0
- package/src/memory/manager.ts +572 -0
- package/src/terminal/adapters/base.ts +29 -0
- package/src/terminal/adapters/native.ts +504 -0
- package/src/terminal/adapters/vscode.ts +340 -0
- package/src/terminal/manager.ts +308 -0
- package/src/terminal/pool.ts +271 -0
- package/src/terminal/session.ts +250 -0
- package/src/terminal/vscode-bridge.ts +242 -0
- package/src/utils/errors.ts +231 -0
- package/src/utils/helpers.ts +476 -0
- package/src/utils/types.ts +493 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordination manager for task scheduling and resource management
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Task, CoordinationConfig, SystemEvents } from '../utils/types.ts';
|
|
6
|
+
import { IEventBus } from '../core/event-bus.ts';
|
|
7
|
+
import { ILogger } from '../core/logger.ts';
|
|
8
|
+
import { CoordinationError, DeadlockError } from '../utils/errors.ts';
|
|
9
|
+
import { TaskScheduler } from './scheduler.ts';
|
|
10
|
+
import { ResourceManager } from './resources.ts';
|
|
11
|
+
import { MessageRouter } from './messaging.ts';
|
|
12
|
+
import { AdvancedTaskScheduler } from './advanced-scheduler.ts';
|
|
13
|
+
import { ConflictResolver } from './conflict-resolution.ts';
|
|
14
|
+
import { CoordinationMetricsCollector } from './metrics.ts';
|
|
15
|
+
|
|
16
|
+
export interface ICoordinationManager {
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
shutdown(): Promise<void>;
|
|
19
|
+
assignTask(task: Task, agentId: string): Promise<void>;
|
|
20
|
+
getAgentTaskCount(agentId: string): Promise<number>;
|
|
21
|
+
getAgentTasks(agentId: string): Promise<Task[]>;
|
|
22
|
+
cancelTask(taskId: string, reason?: string): Promise<void>;
|
|
23
|
+
acquireResource(resourceId: string, agentId: string): Promise<void>;
|
|
24
|
+
releaseResource(resourceId: string, agentId: string): Promise<void>;
|
|
25
|
+
sendMessage(from: string, to: string, message: unknown): Promise<void>;
|
|
26
|
+
getHealthStatus(): Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>;
|
|
27
|
+
performMaintenance(): Promise<void>;
|
|
28
|
+
getCoordinationMetrics(): Promise<Record<string, unknown>>;
|
|
29
|
+
enableAdvancedScheduling(): void;
|
|
30
|
+
reportConflict(type: 'resource' | 'task', id: string, agents: string[]): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Coordination manager implementation
|
|
35
|
+
*/
|
|
36
|
+
export class CoordinationManager implements ICoordinationManager {
|
|
37
|
+
private scheduler: TaskScheduler;
|
|
38
|
+
private resourceManager: ResourceManager;
|
|
39
|
+
private messageRouter: MessageRouter;
|
|
40
|
+
private conflictResolver: ConflictResolver;
|
|
41
|
+
private metricsCollector: CoordinationMetricsCollector;
|
|
42
|
+
private initialized = false;
|
|
43
|
+
private deadlockCheckInterval?: ReturnType<typeof setInterval>;
|
|
44
|
+
private advancedSchedulingEnabled = false;
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
private config: CoordinationConfig,
|
|
48
|
+
private eventBus: IEventBus,
|
|
49
|
+
private logger: ILogger,
|
|
50
|
+
) {
|
|
51
|
+
this.scheduler = new TaskScheduler(config, eventBus, logger);
|
|
52
|
+
this.resourceManager = new ResourceManager(config, eventBus, logger);
|
|
53
|
+
this.messageRouter = new MessageRouter(config, eventBus, logger);
|
|
54
|
+
this.conflictResolver = new ConflictResolver(logger, eventBus);
|
|
55
|
+
this.metricsCollector = new CoordinationMetricsCollector(logger, eventBus);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async initialize(): Promise<void> {
|
|
59
|
+
if (this.initialized) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.logger.info('Initializing coordination manager...');
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
// Initialize components
|
|
67
|
+
await this.scheduler.initialize();
|
|
68
|
+
await this.resourceManager.initialize();
|
|
69
|
+
await this.messageRouter.initialize();
|
|
70
|
+
|
|
71
|
+
// Start metrics collection
|
|
72
|
+
this.metricsCollector.start();
|
|
73
|
+
|
|
74
|
+
// Start deadlock detection if enabled
|
|
75
|
+
if (this.config.deadlockDetection) {
|
|
76
|
+
this.startDeadlockDetection();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Set up event handlers
|
|
80
|
+
this.setupEventHandlers();
|
|
81
|
+
|
|
82
|
+
this.initialized = true;
|
|
83
|
+
this.logger.info('Coordination manager initialized');
|
|
84
|
+
} catch (error) {
|
|
85
|
+
this.logger.error('Failed to initialize coordination manager', error);
|
|
86
|
+
throw new CoordinationError('Coordination manager initialization failed', { error });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async shutdown(): Promise<void> {
|
|
91
|
+
if (!this.initialized) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.logger.info('Shutting down coordination manager...');
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
// Stop deadlock detection
|
|
99
|
+
if (this.deadlockCheckInterval) {
|
|
100
|
+
clearInterval(this.deadlockCheckInterval);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Stop metrics collection
|
|
104
|
+
this.metricsCollector.stop();
|
|
105
|
+
|
|
106
|
+
// Shutdown components
|
|
107
|
+
await Promise.all([
|
|
108
|
+
this.scheduler.shutdown(),
|
|
109
|
+
this.resourceManager.shutdown(),
|
|
110
|
+
this.messageRouter.shutdown(),
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
this.initialized = false;
|
|
114
|
+
this.logger.info('Coordination manager shutdown complete');
|
|
115
|
+
} catch (error) {
|
|
116
|
+
this.logger.error('Error during coordination manager shutdown', error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async assignTask(task: Task, agentId: string): Promise<void> {
|
|
122
|
+
if (!this.initialized) {
|
|
123
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
await this.scheduler.assignTask(task, agentId);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async getAgentTaskCount(agentId: string): Promise<number> {
|
|
130
|
+
if (!this.initialized) {
|
|
131
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return this.scheduler.getAgentTaskCount(agentId);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async acquireResource(resourceId: string, agentId: string): Promise<void> {
|
|
138
|
+
if (!this.initialized) {
|
|
139
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await this.resourceManager.acquire(resourceId, agentId);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async releaseResource(resourceId: string, agentId: string): Promise<void> {
|
|
146
|
+
if (!this.initialized) {
|
|
147
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
await this.resourceManager.release(resourceId, agentId);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async sendMessage(from: string, to: string, message: unknown): Promise<void> {
|
|
154
|
+
if (!this.initialized) {
|
|
155
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await this.messageRouter.send(from, to, message);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async getHealthStatus(): Promise<{
|
|
162
|
+
healthy: boolean;
|
|
163
|
+
error?: string;
|
|
164
|
+
metrics?: Record<string, number>;
|
|
165
|
+
}> {
|
|
166
|
+
try {
|
|
167
|
+
const [schedulerHealth, resourceHealth, messageHealth] = await Promise.all([
|
|
168
|
+
this.scheduler.getHealthStatus(),
|
|
169
|
+
this.resourceManager.getHealthStatus(),
|
|
170
|
+
this.messageRouter.getHealthStatus(),
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
const metrics = {
|
|
174
|
+
...schedulerHealth.metrics,
|
|
175
|
+
...resourceHealth.metrics,
|
|
176
|
+
...messageHealth.metrics,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const healthy = schedulerHealth.healthy &&
|
|
180
|
+
resourceHealth.healthy &&
|
|
181
|
+
messageHealth.healthy;
|
|
182
|
+
|
|
183
|
+
const errors = [
|
|
184
|
+
schedulerHealth.error,
|
|
185
|
+
resourceHealth.error,
|
|
186
|
+
messageHealth.error,
|
|
187
|
+
].filter(Boolean);
|
|
188
|
+
|
|
189
|
+
const status: { healthy: boolean; error?: string; metrics?: Record<string, number> } = {
|
|
190
|
+
healthy,
|
|
191
|
+
metrics,
|
|
192
|
+
};
|
|
193
|
+
if (errors.length > 0) {
|
|
194
|
+
status.error = errors.join('; ');
|
|
195
|
+
}
|
|
196
|
+
return status;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
healthy: false,
|
|
200
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private setupEventHandlers(): void {
|
|
206
|
+
// Handle task events
|
|
207
|
+
this.eventBus.on(SystemEvents.TASK_COMPLETED, async (data: unknown) => {
|
|
208
|
+
const { taskId, result } = data as { taskId: string; result: unknown };
|
|
209
|
+
try {
|
|
210
|
+
await this.scheduler.completeTask(taskId, result);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
this.logger.error('Error handling task completion', { taskId, error });
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
this.eventBus.on(SystemEvents.TASK_FAILED, async (data: unknown) => {
|
|
217
|
+
const { taskId, error } = data as { taskId: string; error: Error };
|
|
218
|
+
try {
|
|
219
|
+
await this.scheduler.failTask(taskId, error);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
this.logger.error('Error handling task failure', { taskId, error: err });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Handle agent termination
|
|
226
|
+
this.eventBus.on(SystemEvents.AGENT_TERMINATED, async (data: unknown) => {
|
|
227
|
+
const { agentId } = data as { agentId: string };
|
|
228
|
+
try {
|
|
229
|
+
// Release all resources held by the agent
|
|
230
|
+
await this.resourceManager.releaseAllForAgent(agentId);
|
|
231
|
+
|
|
232
|
+
// Cancel all tasks assigned to the agent
|
|
233
|
+
await this.scheduler.cancelAgentTasks(agentId);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
this.logger.error('Error handling agent termination', { agentId, error });
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private startDeadlockDetection(): void {
|
|
241
|
+
this.deadlockCheckInterval = setInterval(async () => {
|
|
242
|
+
try {
|
|
243
|
+
const deadlock = await this.detectDeadlock();
|
|
244
|
+
|
|
245
|
+
if (deadlock) {
|
|
246
|
+
this.logger.error('Deadlock detected', deadlock);
|
|
247
|
+
|
|
248
|
+
// Emit deadlock event
|
|
249
|
+
this.eventBus.emit(SystemEvents.DEADLOCK_DETECTED, deadlock);
|
|
250
|
+
|
|
251
|
+
// Attempt to resolve deadlock
|
|
252
|
+
await this.resolveDeadlock(deadlock);
|
|
253
|
+
}
|
|
254
|
+
} catch (error) {
|
|
255
|
+
this.logger.error('Error during deadlock detection', error);
|
|
256
|
+
}
|
|
257
|
+
}, 10000); // Check every 10 seconds
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private async detectDeadlock(): Promise<{
|
|
261
|
+
agents: string[];
|
|
262
|
+
resources: string[];
|
|
263
|
+
} | null> {
|
|
264
|
+
// Get resource allocation graph
|
|
265
|
+
const allocations = await this.resourceManager.getAllocations();
|
|
266
|
+
const waitingFor = await this.resourceManager.getWaitingRequests();
|
|
267
|
+
|
|
268
|
+
// Build dependency graph
|
|
269
|
+
const graph = new Map<string, Set<string>>();
|
|
270
|
+
|
|
271
|
+
// Add edges for resources agents are waiting for
|
|
272
|
+
for (const [agentId, resources] of waitingFor) {
|
|
273
|
+
if (!graph.has(agentId)) {
|
|
274
|
+
graph.set(agentId, new Set());
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Find who owns these resources
|
|
278
|
+
for (const resource of resources) {
|
|
279
|
+
const owner = allocations.get(resource);
|
|
280
|
+
if (owner && owner !== agentId) {
|
|
281
|
+
graph.get(agentId)!.add(owner);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Detect cycles using DFS
|
|
287
|
+
const visited = new Set<string>();
|
|
288
|
+
const recursionStack = new Set<string>();
|
|
289
|
+
const cycle: string[] = [];
|
|
290
|
+
|
|
291
|
+
const hasCycle = (node: string): boolean => {
|
|
292
|
+
visited.add(node);
|
|
293
|
+
recursionStack.add(node);
|
|
294
|
+
|
|
295
|
+
const neighbors = graph.get(node) || new Set();
|
|
296
|
+
for (const neighbor of neighbors) {
|
|
297
|
+
if (!visited.has(neighbor)) {
|
|
298
|
+
if (hasCycle(neighbor)) {
|
|
299
|
+
cycle.unshift(node);
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
} else if (recursionStack.has(neighbor)) {
|
|
303
|
+
cycle.unshift(node);
|
|
304
|
+
cycle.unshift(neighbor);
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
recursionStack.delete(node);
|
|
310
|
+
return false;
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// Check for cycles
|
|
314
|
+
for (const node of graph.keys()) {
|
|
315
|
+
if (!visited.has(node) && hasCycle(node)) {
|
|
316
|
+
// Extract unique agents in cycle
|
|
317
|
+
const agents = Array.from(new Set(cycle));
|
|
318
|
+
|
|
319
|
+
// Find resources involved
|
|
320
|
+
const resources: string[] = [];
|
|
321
|
+
for (const agent of agents) {
|
|
322
|
+
const waiting = waitingFor.get(agent) || [];
|
|
323
|
+
resources.push(...waiting);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
agents,
|
|
328
|
+
resources: Array.from(new Set(resources)),
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private async resolveDeadlock(deadlock: {
|
|
337
|
+
agents: string[];
|
|
338
|
+
resources: string[];
|
|
339
|
+
}): Promise<void> {
|
|
340
|
+
this.logger.warn('Attempting to resolve deadlock', deadlock);
|
|
341
|
+
|
|
342
|
+
// Simple resolution: release resources from the lowest priority agent
|
|
343
|
+
// In a real implementation, use more sophisticated strategies
|
|
344
|
+
|
|
345
|
+
try {
|
|
346
|
+
// Find the agent with the lowest priority or least work done
|
|
347
|
+
const agentToPreempt = deadlock.agents[0]; // Simplified
|
|
348
|
+
|
|
349
|
+
// Release all resources held by this agent
|
|
350
|
+
await this.resourceManager.releaseAllForAgent(agentToPreempt);
|
|
351
|
+
|
|
352
|
+
// Reschedule the agent's tasks
|
|
353
|
+
await this.scheduler.rescheduleAgentTasks(agentToPreempt);
|
|
354
|
+
|
|
355
|
+
this.logger.info('Deadlock resolved by preempting agent', {
|
|
356
|
+
agentId: agentToPreempt,
|
|
357
|
+
});
|
|
358
|
+
} catch (error) {
|
|
359
|
+
throw new DeadlockError(
|
|
360
|
+
'Failed to resolve deadlock',
|
|
361
|
+
deadlock.agents,
|
|
362
|
+
deadlock.resources,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async getAgentTasks(agentId: string): Promise<Task[]> {
|
|
368
|
+
if (!this.initialized) {
|
|
369
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return this.scheduler.getAgentTasks(agentId);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async cancelTask(taskId: string, reason?: string): Promise<void> {
|
|
376
|
+
if (!this.initialized) {
|
|
377
|
+
throw new CoordinationError('Coordination manager not initialized');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
await this.scheduler.cancelTask(taskId, reason || 'User requested cancellation');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async performMaintenance(): Promise<void> {
|
|
384
|
+
if (!this.initialized) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
this.logger.debug('Performing coordination manager maintenance');
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
await Promise.all([
|
|
392
|
+
this.scheduler.performMaintenance(),
|
|
393
|
+
this.resourceManager.performMaintenance(),
|
|
394
|
+
this.messageRouter.performMaintenance(),
|
|
395
|
+
]);
|
|
396
|
+
|
|
397
|
+
// Clean up old conflicts
|
|
398
|
+
this.conflictResolver.cleanupOldConflicts(24 * 60 * 60 * 1000); // 24 hours
|
|
399
|
+
} catch (error) {
|
|
400
|
+
this.logger.error('Error during coordination manager maintenance', error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
async getCoordinationMetrics(): Promise<Record<string, unknown>> {
|
|
405
|
+
const baseMetrics = await this.getHealthStatus();
|
|
406
|
+
const coordinationMetrics = this.metricsCollector.getCurrentMetrics();
|
|
407
|
+
const conflictStats = this.conflictResolver.getStats();
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
...baseMetrics.metrics,
|
|
411
|
+
coordination: coordinationMetrics,
|
|
412
|
+
conflicts: conflictStats,
|
|
413
|
+
advancedScheduling: this.advancedSchedulingEnabled,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
enableAdvancedScheduling(): void {
|
|
418
|
+
if (this.advancedSchedulingEnabled) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this.logger.info('Enabling advanced scheduling features');
|
|
423
|
+
|
|
424
|
+
// Replace basic scheduler with advanced one
|
|
425
|
+
const advancedScheduler = new AdvancedTaskScheduler(
|
|
426
|
+
this.config,
|
|
427
|
+
this.eventBus,
|
|
428
|
+
this.logger,
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
// Transfer state if needed (in a real implementation)
|
|
432
|
+
this.scheduler = advancedScheduler;
|
|
433
|
+
this.advancedSchedulingEnabled = true;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
async reportConflict(
|
|
437
|
+
type: 'resource' | 'task',
|
|
438
|
+
id: string,
|
|
439
|
+
agents: string[],
|
|
440
|
+
): Promise<void> {
|
|
441
|
+
this.logger.warn('Conflict reported', { type, id, agents });
|
|
442
|
+
|
|
443
|
+
let conflict;
|
|
444
|
+
if (type === 'resource') {
|
|
445
|
+
conflict = await this.conflictResolver.reportResourceConflict(id, agents);
|
|
446
|
+
} else {
|
|
447
|
+
conflict = await this.conflictResolver.reportTaskConflict(id, agents, 'assignment');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Auto-resolve using default strategy
|
|
451
|
+
try {
|
|
452
|
+
await this.conflictResolver.autoResolve(conflict.id);
|
|
453
|
+
} catch (error) {
|
|
454
|
+
this.logger.error('Failed to auto-resolve conflict', {
|
|
455
|
+
conflictId: conflict.id,
|
|
456
|
+
error,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|