@stackmemoryai/stackmemory 0.3.22 → 0.3.25

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 (44) hide show
  1. package/dist/cli/commands/ralph.js +294 -0
  2. package/dist/cli/commands/ralph.js.map +7 -0
  3. package/dist/cli/index.js +2 -0
  4. package/dist/cli/index.js.map +2 -2
  5. package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +586 -0
  6. package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +7 -0
  7. package/dist/integrations/ralph/context/context-budget-manager.js +297 -0
  8. package/dist/integrations/ralph/context/context-budget-manager.js.map +7 -0
  9. package/dist/integrations/ralph/context/stackmemory-context-loader.js +356 -0
  10. package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +7 -0
  11. package/dist/integrations/ralph/index.js +14 -0
  12. package/dist/integrations/ralph/index.js.map +7 -0
  13. package/dist/integrations/ralph/learning/pattern-learner.js +397 -0
  14. package/dist/integrations/ralph/learning/pattern-learner.js.map +7 -0
  15. package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js +444 -0
  16. package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js.map +7 -0
  17. package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +459 -0
  18. package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +7 -0
  19. package/dist/integrations/ralph/performance/performance-optimizer.js +354 -0
  20. package/dist/integrations/ralph/performance/performance-optimizer.js.map +7 -0
  21. package/dist/integrations/ralph/ralph-integration-demo.js +178 -0
  22. package/dist/integrations/ralph/ralph-integration-demo.js.map +7 -0
  23. package/dist/integrations/ralph/state/state-reconciler.js +400 -0
  24. package/dist/integrations/ralph/state/state-reconciler.js.map +7 -0
  25. package/dist/integrations/ralph/swarm/git-workflow-manager.js +309 -0
  26. package/dist/integrations/ralph/swarm/git-workflow-manager.js.map +7 -0
  27. package/dist/integrations/ralph/swarm/swarm-coordinator.js +656 -0
  28. package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +7 -0
  29. package/dist/integrations/ralph/types.js +1 -0
  30. package/dist/integrations/ralph/types.js.map +7 -0
  31. package/dist/integrations/ralph/visualization/ralph-debugger.js +581 -0
  32. package/dist/integrations/ralph/visualization/ralph-debugger.js.map +7 -0
  33. package/package.json +1 -1
  34. package/scripts/deploy-ralph-swarm.sh +365 -0
  35. package/scripts/ralph-integration-test.js +274 -0
  36. package/scripts/ralph-loop-implementation.js +404 -0
  37. package/scripts/swarm-monitor.js +509 -0
  38. package/scripts/test-parallel-swarms.js +443 -0
  39. package/scripts/test-pre-publish-quick.sh +4 -2
  40. package/scripts/test-swarm-git-workflow.js +338 -0
  41. package/scripts/testing/ralph-cli-test.js +88 -0
  42. package/scripts/testing/ralph-integration-validation.js +727 -0
  43. package/scripts/testing/ralph-swarm-test-scenarios.js +613 -0
  44. package/scripts/validate-swarm-implementation.js +467 -0
@@ -0,0 +1,656 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import * as fs from "fs/promises";
3
+ import * as path from "path";
4
+ import { logger } from "../../../core/monitoring/logger.js";
5
+ import { FrameManager } from "../../../core/context/frame-manager.js";
6
+ import { sessionManager } from "../../../core/session/index.js";
7
+ import { sharedContextLayer } from "../../../core/context/shared-context-layer.js";
8
+ import { RalphStackMemoryBridge } from "../bridge/ralph-stackmemory-bridge.js";
9
+ import { GitWorkflowManager } from "./git-workflow-manager.js";
10
+ class SwarmCoordinator {
11
+ frameManager;
12
+ activeAgents = /* @__PURE__ */ new Map();
13
+ swarmState;
14
+ config;
15
+ coordinationTimer;
16
+ plannerWakeupQueue = /* @__PURE__ */ new Map();
17
+ gitWorkflowManager;
18
+ constructor(config) {
19
+ this.config = {
20
+ maxAgents: 10,
21
+ coordinationInterval: 3e4,
22
+ // 30 seconds
23
+ driftDetectionThreshold: 5,
24
+ // 5 failed iterations before considering drift
25
+ freshStartInterval: 36e5,
26
+ // 1 hour
27
+ conflictResolutionStrategy: "expertise",
28
+ enableDynamicPlanning: true,
29
+ pathologicalBehaviorDetection: true,
30
+ ...config
31
+ };
32
+ this.swarmState = {
33
+ id: uuidv4(),
34
+ status: "idle",
35
+ startTime: Date.now(),
36
+ activeTaskCount: 0,
37
+ completedTaskCount: 0,
38
+ coordination: {
39
+ events: [],
40
+ conflicts: [],
41
+ resolutions: []
42
+ },
43
+ performance: {
44
+ throughput: 0,
45
+ efficiency: 0,
46
+ coordination_overhead: 0
47
+ }
48
+ };
49
+ this.gitWorkflowManager = new GitWorkflowManager({
50
+ enableGitWorkflow: true,
51
+ branchStrategy: "agent",
52
+ autoCommit: true,
53
+ commitFrequency: 5,
54
+ mergStrategy: "squash"
55
+ });
56
+ logger.info("Swarm coordinator initialized", this.config);
57
+ }
58
+ async initialize() {
59
+ try {
60
+ await sessionManager.initialize();
61
+ await sharedContextLayer.initialize();
62
+ const session = await sessionManager.getOrCreateSession({});
63
+ if (session.database) {
64
+ this.frameManager = new FrameManager(session.database, session.projectId);
65
+ }
66
+ this.startCoordinationLoop();
67
+ logger.info("Swarm coordinator initialized successfully");
68
+ } catch (error) {
69
+ logger.error("Failed to initialize swarm coordinator", error);
70
+ throw error;
71
+ }
72
+ }
73
+ /**
74
+ * Launch a swarm of agents to work on a complex project
75
+ */
76
+ async launchSwarm(projectDescription, agents, coordination) {
77
+ logger.info("Launching swarm", {
78
+ project: projectDescription.substring(0, 100),
79
+ agentCount: agents.length
80
+ });
81
+ const swarmId = uuidv4();
82
+ try {
83
+ if (agents.length > this.config.maxAgents) {
84
+ throw new Error(`Too many agents requested: ${agents.length} > ${this.config.maxAgents}`);
85
+ }
86
+ const swarmTasks = await this.decomposeProjectIntoSwarmTasks(projectDescription);
87
+ const initializedAgents = await this.initializeSpecializedAgents(agents, swarmTasks);
88
+ const allocation = await this.allocateTasksToAgents(swarmTasks, initializedAgents);
89
+ this.swarmState = {
90
+ ...this.swarmState,
91
+ id: swarmId,
92
+ status: "active",
93
+ activeTaskCount: swarmTasks.length,
94
+ project: projectDescription,
95
+ agents: initializedAgents,
96
+ tasks: swarmTasks,
97
+ allocation
98
+ };
99
+ await this.executeSwarmTasks(allocation);
100
+ logger.info("Swarm launched successfully", { swarmId, agentCount: initializedAgents.length });
101
+ return swarmId;
102
+ } catch (error) {
103
+ logger.error("Failed to launch swarm", error);
104
+ throw error;
105
+ }
106
+ }
107
+ /**
108
+ * Decompose project into tasks suitable for swarm execution
109
+ */
110
+ async decomposeProjectIntoSwarmTasks(projectDescription) {
111
+ const tasks = [];
112
+ const complexity = this.analyzeProjectComplexity(projectDescription);
113
+ if (complexity.needsArchitecture) {
114
+ tasks.push({
115
+ id: uuidv4(),
116
+ type: "architecture",
117
+ title: "System Architecture Design",
118
+ description: "Design overall system architecture and component relationships",
119
+ priority: 1,
120
+ estimatedEffort: "high",
121
+ requiredRoles: ["architect", "system_designer"],
122
+ dependencies: [],
123
+ acceptanceCriteria: [
124
+ "Architecture diagram created",
125
+ "Component interfaces defined",
126
+ "Data flow documented"
127
+ ]
128
+ });
129
+ }
130
+ const coreFeatures = this.extractCoreFeatures(projectDescription);
131
+ for (const feature of coreFeatures) {
132
+ tasks.push({
133
+ id: uuidv4(),
134
+ type: "implementation",
135
+ title: `Implement ${feature.name}`,
136
+ description: feature.description,
137
+ priority: 2,
138
+ estimatedEffort: feature.complexity,
139
+ requiredRoles: ["developer", feature.specialization || "fullstack"],
140
+ dependencies: complexity.needsArchitecture ? [tasks[0].id] : [],
141
+ acceptanceCriteria: feature.criteria
142
+ });
143
+ }
144
+ if (complexity.needsTesting) {
145
+ tasks.push({
146
+ id: uuidv4(),
147
+ type: "testing",
148
+ title: "Comprehensive Testing Suite",
149
+ description: "Create unit, integration, and end-to-end tests",
150
+ priority: 3,
151
+ estimatedEffort: "medium",
152
+ requiredRoles: ["qa_engineer", "test_automation"],
153
+ dependencies: tasks.filter((t) => t.type === "implementation").map((t) => t.id),
154
+ acceptanceCriteria: [
155
+ "Unit tests achieve >90% coverage",
156
+ "Integration tests pass",
157
+ "Performance benchmarks met"
158
+ ]
159
+ });
160
+ }
161
+ if (complexity.needsDocumentation) {
162
+ tasks.push({
163
+ id: uuidv4(),
164
+ type: "documentation",
165
+ title: "Documentation and Examples",
166
+ description: "Create user documentation, API docs, and usage examples",
167
+ priority: 4,
168
+ estimatedEffort: "low",
169
+ requiredRoles: ["technical_writer", "developer"],
170
+ dependencies: [],
171
+ // Can run in parallel
172
+ acceptanceCriteria: [
173
+ "README with setup instructions",
174
+ "API documentation complete",
175
+ "Usage examples provided"
176
+ ]
177
+ });
178
+ }
179
+ return tasks;
180
+ }
181
+ /**
182
+ * Initialize specialized agents with role-specific configurations
183
+ */
184
+ async initializeSpecializedAgents(specifications, tasks) {
185
+ const agents = [];
186
+ for (const spec of specifications) {
187
+ const agent = {
188
+ id: uuidv4(),
189
+ role: spec.role,
190
+ specialization: spec,
191
+ status: "initializing",
192
+ capabilities: this.defineCapabilities(spec.role),
193
+ workingDirectory: `.swarm/${spec.role}-${Date.now()}`,
194
+ currentTask: null,
195
+ performance: {
196
+ tasksCompleted: 0,
197
+ successRate: 1,
198
+ averageTaskTime: 0,
199
+ driftDetected: false,
200
+ lastFreshStart: Date.now()
201
+ },
202
+ coordination: {
203
+ communicationStyle: this.defineCommuncationStyle(spec.role),
204
+ conflictResolution: spec.conflictResolution || "defer_to_expertise",
205
+ collaborationPreferences: spec.collaborationPreferences || []
206
+ }
207
+ };
208
+ await this.setupAgentEnvironment(agent);
209
+ await this.configureAgentPrompts(agent);
210
+ agents.push(agent);
211
+ this.activeAgents.set(agent.id, agent);
212
+ }
213
+ logger.info(`Initialized ${agents.length} specialized agents`);
214
+ return agents;
215
+ }
216
+ /**
217
+ * Allocate tasks to agents based on specialization and workload
218
+ */
219
+ async allocateTasksToAgents(tasks, agents) {
220
+ const allocation = {
221
+ assignments: /* @__PURE__ */ new Map(),
222
+ loadBalancing: "capability_based",
223
+ conflictResolution: this.config.conflictResolutionStrategy
224
+ };
225
+ const sortedTasks = this.topologicalSort(tasks);
226
+ for (const task of sortedTasks) {
227
+ const suitableAgents = agents.filter(
228
+ (agent) => task.requiredRoles.some((role) => this.agentCanHandle(agent, role))
229
+ );
230
+ if (suitableAgents.length === 0) {
231
+ logger.warn(`No suitable agents found for task: ${task.title}`);
232
+ continue;
233
+ }
234
+ const selectedAgent = this.selectOptimalAgent(suitableAgents, task);
235
+ allocation.assignments.set(task.id, {
236
+ agentId: selectedAgent.id,
237
+ taskId: task.id,
238
+ assignedAt: Date.now(),
239
+ estimatedCompletion: Date.now() + this.estimateTaskDuration(task),
240
+ coordination: {
241
+ collaborators: this.findCollaborators(selectedAgent, task, agents),
242
+ reviewers: this.findReviewers(selectedAgent, task, agents)
243
+ }
244
+ });
245
+ selectedAgent.currentTask = task.id;
246
+ }
247
+ return allocation;
248
+ }
249
+ /**
250
+ * Execute swarm tasks with coordination
251
+ */
252
+ async executeSwarmTasks(allocation) {
253
+ const executionPromises = [];
254
+ for (const [taskId, assignment] of allocation.assignments) {
255
+ const agent = this.activeAgents.get(assignment.agentId);
256
+ const task = this.swarmState.tasks?.find((t) => t.id === taskId);
257
+ if (!agent || !task) continue;
258
+ const executionPromise = this.executeAgentTask(agent, task, assignment);
259
+ executionPromises.push(executionPromise);
260
+ }
261
+ await Promise.allSettled(executionPromises);
262
+ }
263
+ /**
264
+ * Execute a single agent task with coordination
265
+ */
266
+ async executeAgentTask(agent, task, assignment) {
267
+ logger.info(`Agent ${agent.role} starting task: ${task.title}`);
268
+ try {
269
+ agent.status = "active";
270
+ await this.gitWorkflowManager.initializeAgentWorkflow(agent, task);
271
+ const ralph = new RalphStackMemoryBridge({
272
+ baseDir: path.join(agent.workingDirectory, task.id),
273
+ maxIterations: this.calculateMaxIterations(task),
274
+ useStackMemory: true
275
+ });
276
+ const contextualPrompt = await this.synthesizeContextualPrompt(agent, task);
277
+ await ralph.initialize({
278
+ task: contextualPrompt,
279
+ criteria: task.acceptanceCriteria.join("\n")
280
+ });
281
+ this.setupAgentCoordination(agent, ralph, assignment);
282
+ await ralph.run();
283
+ await this.gitWorkflowManager.commitAgentWork(agent, task);
284
+ this.updateAgentPerformance(agent, true);
285
+ await this.gitWorkflowManager.mergeAgentWork(agent, task);
286
+ await this.notifyTaskCompletion(agent, task, true);
287
+ agent.status = "idle";
288
+ logger.info(`Agent ${agent.role} completed task: ${task.title}`);
289
+ } catch (error) {
290
+ logger.error(`Agent ${agent.role} failed task: ${task.title}`, error);
291
+ this.updateAgentPerformance(agent, false);
292
+ await this.handleTaskFailure(agent, task, error);
293
+ agent.status = "error";
294
+ }
295
+ }
296
+ /**
297
+ * Synthesize contextual prompt incorporating swarm knowledge
298
+ */
299
+ async synthesizeContextualPrompt(agent, task) {
300
+ const basePrompt = task.description;
301
+ const roleSpecificInstructions = this.getRoleSpecificInstructions(agent.role);
302
+ const swarmContext = await this.getSwarmContext(task);
303
+ const coordinationInstructions = this.getCoordinationInstructions(agent);
304
+ return `
305
+ ${roleSpecificInstructions}
306
+
307
+ TASK: ${basePrompt}
308
+
309
+ SWARM CONTEXT:
310
+ ${swarmContext}
311
+
312
+ COORDINATION GUIDELINES:
313
+ ${coordinationInstructions}
314
+
315
+ Remember:
316
+ - You are part of a swarm working on: ${this.swarmState.project}
317
+ - Other agents are working on related tasks
318
+ - Communicate findings through StackMemory shared context
319
+ - Focus on your specialization while being aware of the bigger picture
320
+ - Detect and avoid pathological behaviors (infinite loops, tunnel vision)
321
+ - Request fresh starts if you detect drift in your approach
322
+
323
+ ACCEPTANCE CRITERIA:
324
+ ${task.acceptanceCriteria.map((c) => `- ${c}`).join("\n")}
325
+ `;
326
+ }
327
+ /**
328
+ * Start coordination monitoring loop
329
+ */
330
+ startCoordinationLoop() {
331
+ this.coordinationTimer = setInterval(() => {
332
+ this.performCoordinationCycle().catch((error) => {
333
+ logger.error("Coordination cycle failed", error);
334
+ });
335
+ }, this.config.coordinationInterval);
336
+ }
337
+ /**
338
+ * Perform coordination cycle
339
+ */
340
+ async performCoordinationCycle() {
341
+ if (this.swarmState.status !== "active") return;
342
+ logger.debug("Performing coordination cycle");
343
+ if (this.config.pathologicalBehaviorDetection) {
344
+ await this.detectPathologicalBehaviors();
345
+ }
346
+ if (this.config.enableDynamicPlanning) {
347
+ await this.wakeUpPlanners();
348
+ }
349
+ await this.resolveActiveConflicts();
350
+ await this.rebalanceWorkload();
351
+ await this.triggerFreshStartsIfNeeded();
352
+ this.updateSwarmMetrics();
353
+ }
354
+ /**
355
+ * Detect pathological behaviors in agents
356
+ */
357
+ async detectPathologicalBehaviors() {
358
+ for (const agent of this.activeAgents.values()) {
359
+ if (agent.status !== "active") continue;
360
+ if (agent.performance.driftDetected) {
361
+ logger.warn(`Drift detected in agent ${agent.role}, triggering fresh start`);
362
+ await this.triggerFreshStart(agent);
363
+ continue;
364
+ }
365
+ if (await this.detectTunnelVision(agent)) {
366
+ logger.warn(`Tunnel vision detected in agent ${agent.role}, providing alternative approach`);
367
+ await this.provideAlternativeApproach(agent);
368
+ }
369
+ if (await this.detectExcessiveRuntime(agent)) {
370
+ logger.warn(`Excessive runtime detected in agent ${agent.role}, requesting checkpoint`);
371
+ await this.requestCheckpoint(agent);
372
+ }
373
+ }
374
+ }
375
+ /**
376
+ * Wake up planners when their tasks complete
377
+ */
378
+ async wakeUpPlanners() {
379
+ for (const [agentId, wakeupCallback] of this.plannerWakeupQueue) {
380
+ const agent = this.activeAgents.get(agentId);
381
+ if (!agent || agent.status !== "idle") continue;
382
+ logger.info(`Waking up planner agent: ${agent.role}`);
383
+ wakeupCallback();
384
+ this.plannerWakeupQueue.delete(agentId);
385
+ }
386
+ }
387
+ // Helper methods for role specialization and coordination
388
+ defineCapabilities(role) {
389
+ const capabilityMap = {
390
+ "architect": ["system_design", "component_modeling", "architecture_validation"],
391
+ "planner": ["task_decomposition", "dependency_analysis", "resource_planning"],
392
+ "developer": ["code_implementation", "debugging", "refactoring"],
393
+ "reviewer": ["code_review", "quality_assessment", "best_practice_enforcement"],
394
+ "tester": ["test_design", "automation", "validation"],
395
+ "optimizer": ["performance_analysis", "resource_optimization", "bottleneck_identification"],
396
+ "documenter": ["technical_writing", "api_documentation", "example_creation"],
397
+ "coordinator": ["task_coordination", "conflict_resolution", "progress_tracking"]
398
+ };
399
+ return capabilityMap[role] || [];
400
+ }
401
+ defineCommuncationStyle(role) {
402
+ const styleMap = {
403
+ "architect": "high_level_design_focused",
404
+ "planner": "structured_and_methodical",
405
+ "developer": "implementation_focused",
406
+ "reviewer": "quality_focused_constructive",
407
+ "tester": "validation_focused",
408
+ "optimizer": "performance_metrics_focused",
409
+ "documenter": "clarity_focused",
410
+ "coordinator": "facilitative_and_diplomatic"
411
+ };
412
+ return styleMap[role] || "collaborative";
413
+ }
414
+ getRoleSpecificInstructions(role) {
415
+ const instructionMap = {
416
+ "architect": `
417
+ You are a SYSTEM ARCHITECT. Your role is to:
418
+ - Design high-level system architecture
419
+ - Define component interfaces and relationships
420
+ - Ensure architectural consistency across the project
421
+ - Think in terms of scalability, maintainability, and extensibility
422
+ - Collaborate with developers to validate feasibility`,
423
+ "planner": `
424
+ You are a PROJECT PLANNER. Your role is to:
425
+ - Break down complex tasks into manageable steps
426
+ - Identify dependencies and critical path
427
+ - Coordinate with other agents on sequencing
428
+ - Wake up when tasks complete to plan next steps
429
+ - Adapt plans based on actual progress`,
430
+ "developer": `
431
+ You are a SPECIALIZED DEVELOPER. Your role is to:
432
+ - Implement features according to specifications
433
+ - Write clean, maintainable code
434
+ - Follow established patterns and conventions
435
+ - Integrate with other components
436
+ - Communicate implementation details clearly`,
437
+ "reviewer": `
438
+ You are a CODE REVIEWER. Your role is to:
439
+ - Review code for quality, correctness, and best practices
440
+ - Provide constructive feedback
441
+ - Ensure consistency with project standards
442
+ - Identify potential issues before they become problems
443
+ - Approve or request changes`,
444
+ "tester": `
445
+ You are a QA ENGINEER. Your role is to:
446
+ - Design comprehensive test strategies
447
+ - Implement automated tests
448
+ - Validate functionality and performance
449
+ - Report bugs clearly and reproducibly
450
+ - Ensure quality gates are met`,
451
+ "optimizer": `
452
+ You are a PERFORMANCE OPTIMIZER. Your role is to:
453
+ - Analyze system performance and identify bottlenecks
454
+ - Implement optimizations
455
+ - Monitor resource usage
456
+ - Establish performance benchmarks
457
+ - Ensure scalability requirements are met`,
458
+ "documenter": `
459
+ You are a TECHNICAL WRITER. Your role is to:
460
+ - Create clear, comprehensive documentation
461
+ - Write API documentation and usage examples
462
+ - Ensure documentation stays up-to-date
463
+ - Focus on user experience and clarity
464
+ - Collaborate with developers to understand features`,
465
+ "coordinator": `
466
+ You are a PROJECT COORDINATOR. Your role is to:
467
+ - Facilitate communication between agents
468
+ - Resolve conflicts and blockers
469
+ - Track overall project progress
470
+ - Ensure no tasks fall through cracks
471
+ - Maintain project timeline and quality`
472
+ };
473
+ return instructionMap[role] || "You are a specialized agent contributing to a larger project.";
474
+ }
475
+ // Additional helper methods would be implemented here...
476
+ analyzeProjectComplexity(description) {
477
+ return {
478
+ needsArchitecture: description.length > 500 || description.includes("system") || description.includes("platform"),
479
+ needsTesting: true,
480
+ // Almost all projects need testing
481
+ needsDocumentation: description.includes("API") || description.includes("library"),
482
+ complexity: "medium"
483
+ };
484
+ }
485
+ extractCoreFeatures(description) {
486
+ return [{
487
+ name: "Core Feature",
488
+ description: "Main functionality implementation",
489
+ complexity: "medium",
490
+ criteria: ["Feature works correctly", "Handles edge cases", "Follows coding standards"]
491
+ }];
492
+ }
493
+ // Implement remaining helper methods...
494
+ async setupAgentEnvironment(agent) {
495
+ try {
496
+ await fs.mkdir(agent.workingDirectory, { recursive: true });
497
+ logger.debug(`Created working directory for agent ${agent.id}: ${agent.workingDirectory}`);
498
+ } catch (error) {
499
+ logger.warn(`Could not create working directory for agent ${agent.id}`, error);
500
+ }
501
+ }
502
+ async configureAgentPrompts(agent) {
503
+ logger.debug(`Configured prompts for agent ${agent.role}`);
504
+ }
505
+ topologicalSort(tasks) {
506
+ const sorted = [];
507
+ const visited = /* @__PURE__ */ new Set();
508
+ const visiting = /* @__PURE__ */ new Set();
509
+ const visit = (task) => {
510
+ if (visited.has(task.id)) return;
511
+ if (visiting.has(task.id)) {
512
+ logger.warn(`Circular dependency detected for task: ${task.id}`);
513
+ return;
514
+ }
515
+ visiting.add(task.id);
516
+ for (const depId of task.dependencies) {
517
+ const depTask = tasks.find((t) => t.id === depId);
518
+ if (depTask) visit(depTask);
519
+ }
520
+ visiting.delete(task.id);
521
+ visited.add(task.id);
522
+ sorted.push(task);
523
+ };
524
+ tasks.forEach(visit);
525
+ return sorted;
526
+ }
527
+ agentCanHandle(agent, role) {
528
+ return agent.role === role || agent.capabilities.includes(role);
529
+ }
530
+ selectOptimalAgent(agents, task) {
531
+ return agents.reduce((best, current) => {
532
+ const bestLoad = best.currentTask ? 1 : 0;
533
+ const currentLoad = current.currentTask ? 1 : 0;
534
+ return currentLoad < bestLoad ? current : best;
535
+ });
536
+ }
537
+ estimateTaskDuration(task) {
538
+ const durations = {
539
+ low: 6e4,
540
+ // 1 minute
541
+ medium: 3e5,
542
+ // 5 minutes
543
+ high: 9e5
544
+ // 15 minutes
545
+ };
546
+ return durations[task.estimatedEffort] || 3e5;
547
+ }
548
+ findCollaborators(agent, task, agents) {
549
+ return agents.filter((a) => a.id !== agent.id && a.currentTask).map((a) => a.id).slice(0, 2);
550
+ }
551
+ findReviewers(agent, task, agents) {
552
+ return agents.filter((a) => a.role === "reviewer" && a.id !== agent.id).map((a) => a.id);
553
+ }
554
+ calculateMaxIterations(task) {
555
+ const iterations = {
556
+ low: 5,
557
+ medium: 10,
558
+ high: 20
559
+ };
560
+ return iterations[task.estimatedEffort] || 10;
561
+ }
562
+ async getSwarmContext(task) {
563
+ const relatedTasks = Array.from(this.activeAgents.values()).filter((a) => a.currentTask).map((a) => `- Agent ${a.role} is working on task ${a.currentTask}`).join("\n");
564
+ return relatedTasks || "No other agents currently active";
565
+ }
566
+ getCoordinationInstructions(agent) {
567
+ return `
568
+ - Save progress to shared context regularly
569
+ - Check for updates from collaborators
570
+ - Request help if blocked for more than 2 iterations
571
+ - Report completion immediately`;
572
+ }
573
+ setupAgentCoordination(agent, ralph, assignment) {
574
+ logger.debug(`Setting up coordination for agent ${agent.id}`);
575
+ }
576
+ updateAgentPerformance(agent, success) {
577
+ agent.performance.tasksCompleted++;
578
+ if (!success) {
579
+ agent.performance.successRate = agent.performance.successRate * (agent.performance.tasksCompleted - 1) / agent.performance.tasksCompleted;
580
+ }
581
+ }
582
+ async notifyTaskCompletion(agent, task, success) {
583
+ const event = {
584
+ type: "task_completion",
585
+ agentId: agent.id,
586
+ timestamp: Date.now(),
587
+ data: {
588
+ taskId: task.id,
589
+ success,
590
+ agent: agent.role
591
+ }
592
+ };
593
+ this.swarmState.coordination?.events.push(event);
594
+ logger.info(`Task ${task.id} completed by agent ${agent.role}: ${success ? "SUCCESS" : "FAILED"}`);
595
+ }
596
+ async handleTaskFailure(agent, task, error) {
597
+ logger.error(`Agent ${agent.role} failed task ${task.id}`, error);
598
+ if (this.swarmState.coordination) {
599
+ this.swarmState.coordination.conflicts.push({
600
+ type: "task_failure",
601
+ agents: [agent.id],
602
+ timestamp: Date.now(),
603
+ description: error.message
604
+ });
605
+ }
606
+ }
607
+ async detectTunnelVision(agent) {
608
+ return false;
609
+ }
610
+ async provideAlternativeApproach(agent) {
611
+ logger.info(`Providing alternative approach to agent ${agent.role}`);
612
+ }
613
+ async detectExcessiveRuntime(agent) {
614
+ if (!agent.performance.lastFreshStart) return false;
615
+ return Date.now() - agent.performance.lastFreshStart > 36e5;
616
+ }
617
+ async requestCheckpoint(agent) {
618
+ logger.info(`Requesting checkpoint from agent ${agent.role}`);
619
+ }
620
+ async triggerFreshStart(agent) {
621
+ logger.info(`Triggering fresh start for agent ${agent.role}`);
622
+ agent.performance.lastFreshStart = Date.now();
623
+ agent.performance.driftDetected = false;
624
+ }
625
+ async resolveActiveConflicts() {
626
+ if (this.swarmState.coordination?.conflicts.length) {
627
+ logger.debug(`Resolving ${this.swarmState.coordination.conflicts.length} conflicts`);
628
+ }
629
+ }
630
+ async rebalanceWorkload() {
631
+ const activeAgents = Array.from(this.activeAgents.values()).filter((a) => a.status === "active");
632
+ if (activeAgents.length > 0) {
633
+ logger.debug(`Rebalancing workload among ${activeAgents.length} active agents`);
634
+ }
635
+ }
636
+ async triggerFreshStartsIfNeeded() {
637
+ for (const agent of this.activeAgents.values()) {
638
+ if (agent.performance.driftDetected) {
639
+ await this.triggerFreshStart(agent);
640
+ }
641
+ }
642
+ }
643
+ updateSwarmMetrics() {
644
+ if (!this.swarmState.performance) return;
645
+ const activeCount = Array.from(this.activeAgents.values()).filter((a) => a.status === "active").length;
646
+ this.swarmState.performance.throughput = this.swarmState.completedTaskCount / ((Date.now() - this.swarmState.startTime) / 1e3);
647
+ this.swarmState.performance.efficiency = activeCount > 0 ? this.swarmState.completedTaskCount / activeCount : 0;
648
+ }
649
+ [Symbol.toStringTag] = "SwarmCoordinator";
650
+ }
651
+ const swarmCoordinator = new SwarmCoordinator();
652
+ export {
653
+ SwarmCoordinator,
654
+ swarmCoordinator
655
+ };
656
+ //# sourceMappingURL=swarm-coordinator.js.map