@gotza02/seq-thinking 1.1.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.
Files changed (106) hide show
  1. package/README.md +149 -0
  2. package/SYSTEM_INSTRUCTIONS.md +50 -0
  3. package/agents_test.log +15 -0
  4. package/dist/__tests__/agents.test.d.ts +2 -0
  5. package/dist/__tests__/agents.test.d.ts.map +1 -0
  6. package/dist/__tests__/agents.test.js +673 -0
  7. package/dist/__tests__/agents.test.js.map +1 -0
  8. package/dist/__tests__/mcp-server.test.d.ts +2 -0
  9. package/dist/__tests__/mcp-server.test.d.ts.map +1 -0
  10. package/dist/__tests__/mcp-server.test.js +315 -0
  11. package/dist/__tests__/mcp-server.test.js.map +1 -0
  12. package/dist/__tests__/sequential-thinking.test.d.ts +2 -0
  13. package/dist/__tests__/sequential-thinking.test.d.ts.map +1 -0
  14. package/dist/__tests__/sequential-thinking.test.js +545 -0
  15. package/dist/__tests__/sequential-thinking.test.js.map +1 -0
  16. package/dist/__tests__/swarm-coordinator.test.d.ts +2 -0
  17. package/dist/__tests__/swarm-coordinator.test.d.ts.map +1 -0
  18. package/dist/__tests__/swarm-coordinator.test.js +606 -0
  19. package/dist/__tests__/swarm-coordinator.test.js.map +1 -0
  20. package/dist/__tests__/types.test.d.ts +2 -0
  21. package/dist/__tests__/types.test.d.ts.map +1 -0
  22. package/dist/__tests__/types.test.js +741 -0
  23. package/dist/__tests__/types.test.js.map +1 -0
  24. package/dist/__tests__/utils.test.d.ts +2 -0
  25. package/dist/__tests__/utils.test.d.ts.map +1 -0
  26. package/dist/__tests__/utils.test.js +264 -0
  27. package/dist/__tests__/utils.test.js.map +1 -0
  28. package/dist/agents/base-agent.d.ts +126 -0
  29. package/dist/agents/base-agent.d.ts.map +1 -0
  30. package/dist/agents/base-agent.js +214 -0
  31. package/dist/agents/base-agent.js.map +1 -0
  32. package/dist/agents/critic-agent.d.ts +134 -0
  33. package/dist/agents/critic-agent.d.ts.map +1 -0
  34. package/dist/agents/critic-agent.js +484 -0
  35. package/dist/agents/critic-agent.js.map +1 -0
  36. package/dist/agents/index.d.ts +11 -0
  37. package/dist/agents/index.d.ts.map +1 -0
  38. package/dist/agents/index.js +11 -0
  39. package/dist/agents/index.js.map +1 -0
  40. package/dist/agents/meta-reasoning-agent.d.ts +143 -0
  41. package/dist/agents/meta-reasoning-agent.d.ts.map +1 -0
  42. package/dist/agents/meta-reasoning-agent.js +532 -0
  43. package/dist/agents/meta-reasoning-agent.js.map +1 -0
  44. package/dist/agents/reasoner-agent.d.ts +75 -0
  45. package/dist/agents/reasoner-agent.d.ts.map +1 -0
  46. package/dist/agents/reasoner-agent.js +226 -0
  47. package/dist/agents/reasoner-agent.js.map +1 -0
  48. package/dist/agents/synthesizer-agent.d.ts +174 -0
  49. package/dist/agents/synthesizer-agent.d.ts.map +1 -0
  50. package/dist/agents/synthesizer-agent.js +583 -0
  51. package/dist/agents/synthesizer-agent.js.map +1 -0
  52. package/dist/index.d.ts +21 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +27 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/mcp-server.d.ts +823 -0
  57. package/dist/mcp-server.d.ts.map +1 -0
  58. package/dist/mcp-server.js +377 -0
  59. package/dist/mcp-server.js.map +1 -0
  60. package/dist/sequential-thinking.d.ts +91 -0
  61. package/dist/sequential-thinking.d.ts.map +1 -0
  62. package/dist/sequential-thinking.js +540 -0
  63. package/dist/sequential-thinking.js.map +1 -0
  64. package/dist/swarm-coordinator.d.ts +188 -0
  65. package/dist/swarm-coordinator.d.ts.map +1 -0
  66. package/dist/swarm-coordinator.js +627 -0
  67. package/dist/swarm-coordinator.js.map +1 -0
  68. package/dist/types/index.d.ts +806 -0
  69. package/dist/types/index.d.ts.map +1 -0
  70. package/dist/types/index.js +279 -0
  71. package/dist/types/index.js.map +1 -0
  72. package/dist/utils/index.d.ts +421 -0
  73. package/dist/utils/index.d.ts.map +1 -0
  74. package/dist/utils/index.js +864 -0
  75. package/dist/utils/index.js.map +1 -0
  76. package/dist/utils/llm-adapter.d.ts +23 -0
  77. package/dist/utils/llm-adapter.d.ts.map +1 -0
  78. package/dist/utils/llm-adapter.js +68 -0
  79. package/dist/utils/llm-adapter.js.map +1 -0
  80. package/dist/utils/persistence.d.ts +33 -0
  81. package/dist/utils/persistence.d.ts.map +1 -0
  82. package/dist/utils/persistence.js +108 -0
  83. package/dist/utils/persistence.js.map +1 -0
  84. package/package.json +41 -0
  85. package/src/__tests__/agents.test.ts +858 -0
  86. package/src/__tests__/mcp-server.test.ts +380 -0
  87. package/src/__tests__/sequential-thinking.test.ts +687 -0
  88. package/src/__tests__/swarm-coordinator.test.ts +903 -0
  89. package/src/__tests__/types.test.ts +839 -0
  90. package/src/__tests__/utils.test.ts +322 -0
  91. package/src/agents/base-agent.ts +285 -0
  92. package/src/agents/critic-agent.ts +582 -0
  93. package/src/agents/index.ts +11 -0
  94. package/src/agents/meta-reasoning-agent.ts +672 -0
  95. package/src/agents/reasoner-agent.ts +312 -0
  96. package/src/agents/synthesizer-agent.ts +758 -0
  97. package/src/index.ts +118 -0
  98. package/src/mcp-server.ts +387 -0
  99. package/src/sequential-thinking.ts +560 -0
  100. package/src/swarm-coordinator.ts +744 -0
  101. package/src/types/index.ts +915 -0
  102. package/src/utils/index.ts +1004 -0
  103. package/src/utils/llm-adapter.ts +76 -0
  104. package/src/utils/persistence.ts +108 -0
  105. package/test_output.log +0 -0
  106. package/tsconfig.json +21 -0
@@ -0,0 +1,744 @@
1
+ /**
2
+ * Swarm Coordinator
3
+ * Handles agent registration, task queueing, message brokering, consensus, and conflict resolution.
4
+ */
5
+ import {
6
+ MessageType,
7
+ ConsensusAlgorithm,
8
+ ConflictResolutionStrategy,
9
+ AgentConfig,
10
+ AgentCapability,
11
+ Task,
12
+ TaskResult,
13
+ SwarmMessage,
14
+ ConsensusVote,
15
+ ConsensusResult,
16
+ Conflict,
17
+ ConflictResolution,
18
+ ConflictPosition,
19
+ TaskStatus,
20
+ AgentStatus,
21
+ ConflictStatus
22
+ } from './types/index.js';
23
+ import { BaseAgent } from './agents/base-agent.js';
24
+
25
+ import { PersistenceManager } from './utils/persistence.js';
26
+
27
+ /**
28
+ * Registry to track all agents in the swarm
29
+ */
30
+ export class AgentRegistry {
31
+ private agents = new Map<string, {
32
+ config: AgentConfig;
33
+ status: AgentStatus;
34
+ currentTasks: string[];
35
+ performanceHistory: { taskId: string; quality: number; timeMs: number; timestamp: Date }[];
36
+ instance?: BaseAgent;
37
+ }>();
38
+
39
+ private agentsByType = new Map<string, Set<string>>();
40
+ private agentsByCapability = new Map<string, Set<string>>();
41
+ private persistence: PersistenceManager | null = null;
42
+
43
+ constructor(persistenceDir?: string) {
44
+ if (persistenceDir) {
45
+ this.persistence = new PersistenceManager(persistenceDir);
46
+ }
47
+ }
48
+
49
+ async initialize() {
50
+ if (this.persistence) {
51
+ await this.persistence.initialize(['agents']);
52
+ await this.loadAgents();
53
+ }
54
+ }
55
+
56
+ private async loadAgents() {
57
+ if (!this.persistence) return;
58
+ const ids = await this.persistence.list('agents');
59
+ for (const id of ids) {
60
+ const savedData = await this.persistence.load<any>('agents', id);
61
+ if (savedData) {
62
+ // We only persist the config and metadata, instances must be re-registered
63
+ const agent = {
64
+ config: savedData.config,
65
+ status: AgentStatus.OFFLINE, // Loaded agents start offline until instances are registered
66
+ currentTasks: [],
67
+ performanceHistory: savedData.performanceHistory || [],
68
+ };
69
+ this.agents.set(id, agent);
70
+ this.indexAgent(agent.config);
71
+ }
72
+ }
73
+ }
74
+
75
+ private indexAgent(config: AgentConfig) {
76
+ if (!this.agentsByType.has(config.type)) {
77
+ this.agentsByType.set(config.type, new Set());
78
+ }
79
+ this.agentsByType.get(config.type)!.add(config.id);
80
+
81
+ for (const capability of config.capabilities) {
82
+ if (!this.agentsByCapability.has(capability.name)) {
83
+ this.agentsByCapability.set(capability.name, new Set());
84
+ }
85
+ this.agentsByCapability.get(capability.name)!.add(config.id);
86
+ }
87
+ }
88
+
89
+ async registerAgent(config: AgentConfig, instance?: BaseAgent) {
90
+ const agent = {
91
+ config,
92
+ status: AgentStatus.IDLE, // Default to IDLE for registered agents
93
+ currentTasks: [],
94
+ performanceHistory: [],
95
+ instance
96
+ };
97
+ this.agents.set(config.id, agent);
98
+ this.indexAgent(config);
99
+
100
+ if (this.persistence) {
101
+ await this.persistence.save('agents', config.id, {
102
+ config,
103
+ performanceHistory: agent.performanceHistory
104
+ });
105
+ }
106
+
107
+ return agent;
108
+ }
109
+
110
+ async unregisterAgent(agentId: string) {
111
+ const agent = this.agents.get(agentId);
112
+ if (!agent) return false;
113
+
114
+ this.agents.delete(agentId);
115
+ this.agentsByType.get(agent.config.type)?.delete(agentId);
116
+
117
+ for (const capability of agent.config.capabilities) {
118
+ this.agentsByCapability.get(capability.name)?.delete(agentId);
119
+ }
120
+
121
+ if (this.persistence) {
122
+ await this.persistence.delete('agents', agentId);
123
+ }
124
+
125
+ return true;
126
+ }
127
+
128
+ getAgent(agentId: string) {
129
+ return this.agents.get(agentId);
130
+ }
131
+
132
+ getAgentsByType(type: string) {
133
+ const ids = this.agentsByType.get(type);
134
+ if (!ids) return [];
135
+ return Array.from(ids)
136
+ .map(id => this.agents.get(id))
137
+ .filter((a): a is any => a !== undefined);
138
+ }
139
+
140
+ getAgentsByCapability(capability: string) {
141
+ const ids = this.agentsByCapability.get(capability);
142
+ if (!ids) return [];
143
+ return Array.from(ids)
144
+ .map(id => this.agents.get(id))
145
+ .filter((a): a is any => a !== undefined);
146
+ }
147
+
148
+ getAllAgents() {
149
+ return Array.from(this.agents.values());
150
+ }
151
+
152
+ getAvailableAgents() {
153
+ return this.getAllAgents().filter(a => a.status === AgentStatus.IDLE);
154
+ }
155
+
156
+ updateAgentStatus(agentId: string, status: AgentStatus) {
157
+ const agent = this.agents.get(agentId);
158
+ if (agent) agent.status = status;
159
+ }
160
+
161
+ recordPerformance(agentId: string, taskId: string, quality: number, timeMs: number) {
162
+ const agent = this.agents.get(agentId);
163
+ if (agent) {
164
+ agent.performanceHistory.push({ taskId, quality, timeMs, timestamp: new Date() });
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Broker for swarm communication
171
+ */
172
+ export class MessageBroker {
173
+ private messages = new Map<string, SwarmMessage>();
174
+ private subscriptions = new Map<string, Set<(message: SwarmMessage) => void>>();
175
+
176
+ sendMessage(message: Partial<SwarmMessage> & { type: MessageType; senderId: string; payload: any }): SwarmMessage {
177
+ const fullMessage: SwarmMessage = {
178
+ id: `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
179
+ timestamp: new Date(),
180
+ type: message.type,
181
+ senderId: message.senderId,
182
+ recipientId: message.recipientId || null,
183
+ payload: message.payload,
184
+ context: message.context || {},
185
+ metadata: message.metadata || { priority: 1, ttl: 60000, retryCount: 0 }
186
+ };
187
+
188
+ this.messages.set(fullMessage.id, fullMessage);
189
+
190
+ if (fullMessage.recipientId) {
191
+ this.deliverToRecipient(fullMessage);
192
+ } else {
193
+ this.broadcast(fullMessage);
194
+ }
195
+
196
+ return fullMessage;
197
+ }
198
+
199
+ public broadcast(message: SwarmMessage) {
200
+ const subscribers = this.subscriptions.get('broadcast');
201
+ if (subscribers) {
202
+ subscribers.forEach(callback => {
203
+ try { callback(message); } catch (e) { /* ignore */ }
204
+ });
205
+ }
206
+ }
207
+
208
+ public deliverToRecipient(message: SwarmMessage) {
209
+ if (!message.recipientId) return;
210
+ const subscribers = this.subscriptions.get(message.recipientId);
211
+ if (subscribers) {
212
+ subscribers.forEach(callback => {
213
+ try { callback(message); } catch (e) { /* ignore */ }
214
+ });
215
+ }
216
+ }
217
+
218
+ subscribe(agentId: string, callback: (message: SwarmMessage) => void) {
219
+ if (!this.subscriptions.has(agentId)) {
220
+ this.subscriptions.set(agentId, new Set());
221
+ }
222
+ this.subscriptions.get(agentId)!.add(callback);
223
+ return () => { this.subscriptions.get(agentId)?.delete(callback); };
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Manager for task lifecycle
229
+ */
230
+ export class TaskQueueManager {
231
+ private tasks = new Map<string, Task>();
232
+ private pendingQueue: string[] = [];
233
+
234
+ createTask(type: string, description: string, input: any, requirements: any, context: any = { dependencies: [] }) {
235
+ const task: Task = {
236
+ id: `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
237
+ type,
238
+ description,
239
+ input,
240
+ context,
241
+ requirements,
242
+ assignedAgentId: null,
243
+ status: TaskStatus.PENDING,
244
+ result: null,
245
+ metadata: { createdAt: new Date() }
246
+ };
247
+ this.tasks.set(task.id, task);
248
+ this.pendingQueue.push(task.id);
249
+ return task;
250
+ }
251
+
252
+ assignTask(taskId: string, agentId: string) {
253
+ const task = this.tasks.get(taskId);
254
+ if (!task || task.status !== TaskStatus.PENDING) return null;
255
+
256
+ task.assignedAgentId = agentId;
257
+ task.status = TaskStatus.ASSIGNED;
258
+ task.metadata.assignedAt = new Date();
259
+
260
+ const index = this.pendingQueue.indexOf(taskId);
261
+ if (index > -1) this.pendingQueue.splice(index, 1);
262
+
263
+ return task;
264
+ }
265
+
266
+ startTask(taskId: string) {
267
+ const task = this.tasks.get(taskId);
268
+ if (!task || task.status !== TaskStatus.ASSIGNED) return null;
269
+
270
+ task.status = TaskStatus.IN_PROGRESS;
271
+ task.metadata.startedAt = new Date();
272
+ return task;
273
+ }
274
+
275
+ completeTask(taskId: string, result: TaskResult) {
276
+ const task = this.tasks.get(taskId);
277
+ if (!task) return;
278
+
279
+ task.status = TaskStatus.COMPLETED;
280
+ task.result = result;
281
+ task.metadata.completedAt = new Date();
282
+ }
283
+
284
+ failTask(taskId: string, error: string) {
285
+ const task = this.tasks.get(taskId);
286
+ if (!task) return;
287
+
288
+ task.status = TaskStatus.FAILED;
289
+ task.result = {
290
+ taskId,
291
+ agentId: task.assignedAgentId || 'unknown',
292
+ success: false,
293
+ output: null,
294
+ confidence: 0,
295
+ processingTimeMs: 0,
296
+ metadata: { tokensUsed: 0, reasoningSteps: 0, intermediateResults: [], error }
297
+ };
298
+ task.metadata.completedAt = new Date();
299
+ }
300
+
301
+ getTask(taskId: string) {
302
+ return this.tasks.get(taskId);
303
+ }
304
+
305
+ getTasksByStatus(status: TaskStatus) {
306
+ return Array.from(this.tasks.values()).filter(t => t.status === status);
307
+ }
308
+
309
+ getPendingTasks() {
310
+ return this.getTasksByStatus(TaskStatus.PENDING);
311
+ }
312
+
313
+ getInProgressTasks() {
314
+ return this.getTasksByStatus(TaskStatus.IN_PROGRESS);
315
+ }
316
+
317
+ getCompletedTasks() {
318
+ return this.getTasksByStatus(TaskStatus.COMPLETED);
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Strategy for assigning tasks to agents
324
+ */
325
+ export class TaskAssigner {
326
+ private lastAssignmentIndex = new Map<string, number>();
327
+
328
+ constructor(private registry: AgentRegistry) {}
329
+
330
+ assignTask(task: Task, strategy: string = 'adaptive') {
331
+ const availableAgents = this.registry.getAvailableAgents()
332
+ .filter(a => this.hasRequiredCapabilities(a, task.requirements?.requiredCapabilities || task.requiredCapabilities || []));
333
+
334
+ if (availableAgents.length === 0) return null;
335
+
336
+ switch (strategy) {
337
+ case 'round_robin':
338
+ return this.roundRobin(availableAgents, task.type);
339
+ case 'capability_based':
340
+ return this.capabilityBased(availableAgents, task);
341
+ case 'load_balanced':
342
+ return this.loadBalanced(availableAgents);
343
+ default:
344
+ // Default to best capable
345
+ return this.capabilityBased(availableAgents, task);
346
+ }
347
+ }
348
+
349
+ private hasRequiredCapabilities(agent: any, required: string[]) {
350
+ const agentCaps = agent.config.capabilities.map((c: any) => c.name);
351
+ return required.every(cap => agentCaps.includes(cap));
352
+ }
353
+
354
+ private roundRobin(agents: any[], taskType: string) {
355
+ const lastIndex = this.lastAssignmentIndex.get(taskType) ?? -1;
356
+ const nextIndex = (lastIndex + 1) % agents.length;
357
+ this.lastAssignmentIndex.set(taskType, nextIndex);
358
+ return agents[nextIndex];
359
+ }
360
+
361
+ private capabilityBased(agents: any[], task: Task) {
362
+ return agents.reduce((best, current) => {
363
+ const bestScore = this.calculateCapabilityScore(best, task);
364
+ const currentScore = this.calculateCapabilityScore(current, task);
365
+ return currentScore > bestScore ? current : best;
366
+ });
367
+ }
368
+
369
+ private calculateCapabilityScore(agent: any, task: Task) {
370
+ const requiredCaps = task.requirements?.requiredCapabilities || task.requiredCapabilities || [];
371
+ if (requiredCaps.length === 0) return 1.0;
372
+
373
+ const agentCaps = agent.config.capabilities;
374
+ let score = 0;
375
+ for (const reqCap of requiredCaps) {
376
+ const cap = agentCaps.find((c: any) => c.name === reqCap);
377
+ if (cap) score += cap.confidence;
378
+ }
379
+ return score / requiredCaps.length;
380
+ }
381
+
382
+ private loadBalanced(agents: any[]) {
383
+ return agents.reduce((best, current) =>
384
+ current.currentTasks.length < best.currentTasks.length ? current : best
385
+ );
386
+ }
387
+ }
388
+
389
+ /**
390
+ * Engine for reaching consensus among agents
391
+ */
392
+ export class ConsensusEngine {
393
+ async reachConsensus(
394
+ proposalId: string,
395
+ algorithm: ConsensusAlgorithm,
396
+ votes: ConsensusVote[],
397
+ minAgreementRatio: number = 0.67,
398
+ maxRounds: number = 1
399
+ ): Promise<ConsensusResult> {
400
+ const counts = new Map<any, number>();
401
+ for (const vote of votes) {
402
+ counts.set(vote.vote, (counts.get(vote.vote) || 0) + vote.confidence);
403
+ }
404
+
405
+ let winner: any = null;
406
+ let maxCount = 0;
407
+ for (const [option, count] of counts) {
408
+ if (count > maxCount) {
409
+ maxCount = count;
410
+ winner = option;
411
+ }
412
+ }
413
+
414
+ const totalWeight = Array.from(counts.values()).reduce((a, b) => a + b, 0);
415
+ const agreementRatio = totalWeight > 0 ? maxCount / totalWeight : 0;
416
+
417
+ return {
418
+ proposalId,
419
+ algorithm,
420
+ winningOption: winner,
421
+ confidence: votes.length > 0 ? votes.reduce((s, v) => s + v.confidence, 0) / votes.length : 0,
422
+ votes,
423
+ agreementRatio,
424
+ dissentingOpinions: votes.filter(v => v.vote !== winner).map(v => ({
425
+ agentId: v.agentId,
426
+ opinion: v.vote,
427
+ reasoning: v.reasoning
428
+ })),
429
+ metadata: {
430
+ rounds: maxRounds,
431
+ totalVotingTimeMs: 0,
432
+ convergenceRate: agreementRatio
433
+ }
434
+ };
435
+ }
436
+ }
437
+
438
+ /**
439
+ * Resolver for conflicts between agents
440
+ */
441
+ export class ConflictResolver {
442
+ private conflicts = new Map<string, Conflict>();
443
+
444
+ identifyConflict(type: string, description: string, positions: ConflictPosition[]) {
445
+ const conflict: Conflict = {
446
+ id: `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
447
+ type,
448
+ description,
449
+ involvedAgents: positions.map(p => p.agentId),
450
+ conflictingPositions: positions,
451
+ status: ConflictStatus.DETECTED,
452
+ resolution: null,
453
+ metadata: { createdAt: new Date() }
454
+ };
455
+ this.conflicts.set(conflict.id, conflict);
456
+ return conflict;
457
+ }
458
+
459
+ resolveConflict(conflictId: string, strategy: ConflictResolutionStrategy, resolverAgentId: string) {
460
+ const conflict = this.conflicts.get(conflictId);
461
+ if (!conflict) throw new Error(`Conflict not found: ${conflictId}`);
462
+
463
+ conflict.status = ConflictStatus.RESOLVING;
464
+
465
+ let resolution: ConflictResolution;
466
+ switch (strategy) {
467
+ case ConflictResolutionStrategy.ARBITRATION:
468
+ const highest = conflict.conflictingPositions.reduce((max, p) => p.confidence > max.confidence ? p : max);
469
+ resolution = {
470
+ strategy: ConflictResolutionStrategy.ARBITRATION,
471
+ result: highest.position,
472
+ confidence: highest.confidence,
473
+ reasoning: highest.reasoning || 'Highest confidence position'
474
+ };
475
+ break;
476
+ case ConflictResolutionStrategy.VOTING:
477
+ const votes = new Map<any, number>();
478
+ for (const pos of conflict.conflictingPositions) {
479
+ votes.set(pos.position, (votes.get(pos.position) || 0) + pos.confidence);
480
+ }
481
+ let winner: any = null;
482
+ let maxVotes = 0;
483
+ for (const [pos, count] of votes) {
484
+ if (count > maxVotes) {
485
+ maxVotes = count;
486
+ winner = pos;
487
+ }
488
+ }
489
+ resolution = {
490
+ strategy: ConflictResolutionStrategy.VOTING,
491
+ result: winner,
492
+ confidence: conflict.conflictingPositions.length > 0 ? maxVotes / conflict.conflictingPositions.length : 0,
493
+ reasoning: 'Majority vote'
494
+ };
495
+ break;
496
+ default:
497
+ resolution = {
498
+ strategy: strategy,
499
+ result: conflict.conflictingPositions[0]?.position,
500
+ confidence: 0.5,
501
+ reasoning: `Resolved via ${strategy}`
502
+ };
503
+ }
504
+
505
+ conflict.resolution = resolution;
506
+ conflict.status = ConflictStatus.RESOLVED;
507
+ conflict.metadata.resolvedAt = new Date();
508
+ conflict.metadata.resolutionStrategy = strategy;
509
+ conflict.metadata.resolverAgentId = resolverAgentId;
510
+
511
+ return { conflict, resolution };
512
+ }
513
+
514
+ getConflict(conflictId: string) {
515
+ return this.conflicts.get(conflictId);
516
+ }
517
+
518
+ getAllConflicts() {
519
+ return Array.from(this.conflicts.values());
520
+ }
521
+ }
522
+
523
+ /**
524
+ * Orchestrates all swarm activities
525
+ */
526
+ export class SwarmCoordinator {
527
+ public registry: AgentRegistry;
528
+ public messageBroker = new MessageBroker();
529
+ public taskQueue = new TaskQueueManager();
530
+ public taskAssigner: TaskAssigner;
531
+ public consensusEngine = new ConsensusEngine();
532
+ public conflictResolver = new ConflictResolver();
533
+
534
+ constructor(persistenceDir?: string) {
535
+ this.registry = new AgentRegistry(persistenceDir);
536
+ this.taskAssigner = new TaskAssigner(this.registry);
537
+ }
538
+
539
+ async initialize() {
540
+ await this.registry.initialize();
541
+ }
542
+
543
+ async registerAgent(agentOrConfig: BaseAgent | AgentConfig) {
544
+ if (agentOrConfig instanceof BaseAgent || typeof (agentOrConfig as any).execute === 'function') {
545
+ const agent = agentOrConfig as BaseAgent;
546
+ return await this.registry.registerAgent(agent.config, agent);
547
+ }
548
+ return await this.registry.registerAgent(agentOrConfig as AgentConfig);
549
+ }
550
+
551
+ getAllAgents() {
552
+ return this.registry.getAllAgents();
553
+ }
554
+
555
+ async unregisterAgent(agentId: string) {
556
+ return await this.registry.unregisterAgent(agentId);
557
+ }
558
+
559
+ submitTask(type: string, description: string, input: any, requirements: any, strategy: string = 'adaptive') {
560
+ const task = this.taskQueue.createTask(type, description, input, requirements);
561
+ const agent = this.taskAssigner.assignTask(task, strategy);
562
+
563
+ if (agent) {
564
+ this.taskQueue.assignTask(task.id, agent.config.id);
565
+ this.registry.updateAgentStatus(agent.config.id, AgentStatus.BUSY);
566
+ }
567
+ return { task, assignedAgent: agent };
568
+ }
569
+
570
+ async executeTask(taskId: string, maxRetries: number = 3) {
571
+ let retries = 0;
572
+ let lastError: any = null;
573
+
574
+ while (retries < maxRetries) {
575
+ const task = this.taskQueue.getTask(taskId);
576
+ if (!task) throw new Error(`Task not found: ${taskId}`);
577
+
578
+ if (!task.assignedAgentId) {
579
+ throw new Error(`Task ${taskId} is not assigned to any agent`);
580
+ }
581
+
582
+ const agentState = this.registry.getAgent(task.assignedAgentId);
583
+ if (!agentState || !agentState.instance) {
584
+ throw new Error(`Agent execution instance not found for agent: ${task.assignedAgentId}`);
585
+ }
586
+
587
+ this.taskQueue.startTask(taskId);
588
+ const startTime = Date.now();
589
+
590
+ try {
591
+ const result = await agentState.instance.execute(task);
592
+ this.taskQueue.completeTask(taskId, result);
593
+ this.registry.updateAgentStatus(task.assignedAgentId, AgentStatus.IDLE);
594
+ this.registry.recordPerformance(task.assignedAgentId, taskId, result.confidence, result.processingTimeMs);
595
+ return result;
596
+ } catch (error) {
597
+ lastError = error;
598
+ retries++;
599
+ console.warn(`Task ${taskId} failed (attempt ${retries}/${maxRetries}):`, error);
600
+
601
+ if (retries < maxRetries) {
602
+ // Wait before retry
603
+ await new Promise(resolve => setTimeout(resolve, 1000 * retries));
604
+ // Reset status to ASSIGNED for retry
605
+ task.status = TaskStatus.ASSIGNED;
606
+ }
607
+ }
608
+ }
609
+
610
+ const processingTime = 0;
611
+ this.taskQueue.failTask(taskId, String(lastError));
612
+ const task = this.taskQueue.getTask(taskId);
613
+ if (task?.assignedAgentId) {
614
+ this.registry.updateAgentStatus(task.assignedAgentId, AgentStatus.IDLE);
615
+ }
616
+
617
+ const result: TaskResult = {
618
+ taskId,
619
+ agentId: task?.assignedAgentId || 'unknown',
620
+ success: false,
621
+ output: null,
622
+ confidence: 0,
623
+ processingTimeMs: processingTime,
624
+ metadata: { tokensUsed: 0, reasoningSteps: 0, intermediateResults: [], error: String(lastError) }
625
+ };
626
+ return result;
627
+ }
628
+
629
+ async reachConsensus(
630
+ proposal: any,
631
+ options: any[],
632
+ algorithm: ConsensusAlgorithm = ConsensusAlgorithm.WEIGHTED_VOTE,
633
+ participatingAgents?: string[],
634
+ minAgreementRatio: number = 0.67,
635
+ maxRounds: number = 3,
636
+ context: any = {}
637
+ ): Promise<ConsensusResult> {
638
+ const agentIds = participatingAgents || this.registry.getAllAgents().map(a => a.config.id);
639
+ const proposalId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
640
+
641
+ const votes: ConsensusVote[] = [];
642
+ const startTime = Date.now();
643
+
644
+ const votePromises = agentIds.map(async (agentId) => {
645
+ const agentState = this.registry.getAgent(agentId);
646
+ if (!agentState || !agentState.instance) return null;
647
+
648
+ // Enhanced context for consensus voting
649
+ const task = this.taskQueue.createTask(
650
+ 'consensus_vote',
651
+ `Vote on proposal: ${typeof proposal === 'string' ? proposal : JSON.stringify(proposal)}`,
652
+ {
653
+ proposal,
654
+ options,
655
+ proposalId,
656
+ algorithm,
657
+ context: {
658
+ ...context,
659
+ swarmStats: this.getSwarmStats(),
660
+ previousVotes: votes.map(v => ({ agentId: v.agentId, vote: v.vote }))
661
+ }
662
+ },
663
+ { requiredCapabilities: ['consensus_vote'], minConfidence: 0, maxTimeMs: 10000 }
664
+ );
665
+
666
+ this.taskQueue.assignTask(task.id, agentId);
667
+ this.registry.updateAgentStatus(agentId, AgentStatus.BUSY);
668
+
669
+ try {
670
+ const result = await agentState.instance.execute(task);
671
+ this.taskQueue.completeTask(task.id, result);
672
+ this.registry.updateAgentStatus(agentId, AgentStatus.IDLE);
673
+
674
+ if (result.success && result.output) {
675
+ const output = result.output as any;
676
+ return {
677
+ agentId,
678
+ proposalId,
679
+ vote: output.vote ?? options[0],
680
+ confidence: result.confidence,
681
+ reasoning: output.reasoning || 'No reasoning provided',
682
+ timestamp: new Date()
683
+ } as ConsensusVote;
684
+ }
685
+ } catch (error) {
686
+ this.taskQueue.failTask(task.id, String(error));
687
+ this.registry.updateAgentStatus(agentId, AgentStatus.IDLE);
688
+ }
689
+ return null;
690
+ });
691
+
692
+ const results = await Promise.all(votePromises);
693
+ for (const res of results) {
694
+ if (res) votes.push(res);
695
+ }
696
+
697
+ const consensus = await this.consensusEngine.reachConsensus(proposalId, algorithm, votes, minAgreementRatio, 1);
698
+ consensus.metadata.totalVotingTimeMs = Date.now() - startTime;
699
+
700
+ return consensus;
701
+ }
702
+
703
+ identifyConflict(type: string, description: string, positions: ConflictPosition[]) {
704
+ return this.conflictResolver.identifyConflict(type, description, positions);
705
+ }
706
+
707
+ resolveConflict(conflictId: string, strategy: ConflictResolutionStrategy, resolverAgentId?: string) {
708
+ return this.conflictResolver.resolveConflict(conflictId, strategy, resolverAgentId || 'coordinator');
709
+ }
710
+
711
+ broadcastMessage(senderId: string, payload: any) {
712
+ return this.messageBroker.sendMessage({
713
+ type: MessageType.BROADCAST,
714
+ senderId,
715
+ recipientId: null,
716
+ payload,
717
+ context: {},
718
+ metadata: { priority: 1, ttl: 60000, retryCount: 0 }
719
+ });
720
+ }
721
+
722
+ sendDirectMessage(senderId: string, recipientId: string, payload: any) {
723
+ return this.messageBroker.sendMessage({
724
+ type: MessageType.DIRECT,
725
+ senderId,
726
+ recipientId,
727
+ payload,
728
+ context: {},
729
+ metadata: { priority: 1, ttl: 60000, retryCount: 0 }
730
+ });
731
+ }
732
+
733
+ getSwarmStats() {
734
+ return {
735
+ totalAgents: this.registry.getAllAgents().length,
736
+ availableAgents: this.registry.getAvailableAgents().length,
737
+ busyAgents: this.registry.getAllAgents().filter(a => a.status === AgentStatus.BUSY).length,
738
+ pendingTasks: this.taskQueue.getPendingTasks().length,
739
+ inProgressTasks: this.taskQueue.getInProgressTasks().length,
740
+ completedTasks: this.taskQueue.getCompletedTasks().length,
741
+ activeConflicts: this.conflictResolver.getAllConflicts().filter(c => c.status !== ConflictStatus.RESOLVED).length
742
+ };
743
+ }
744
+ }