Multi-AI collaboration with planning discussions, synchronized execution, and consensus-driven review

AI Swarm

The Swarm class orchestrates multiple AI participants working together on a task. It provides a structured three-phase workflow: planning discussion, synchronized parallel execution, and post-task review with consensus synthesis.

Installation

import { Swarm, createSwarm } from "@codmir/ai";
import type {
  SwarmConfig,
  SwarmTask,
  SwarmParticipant,
  SwarmPhase,
  SwarmResult,
  SwarmState,
  SwarmEvent,
} from "@codmir/ai";

Quick Start

import { createSwarm } from "@codmir/ai";

const swarm = createSwarm(
  {
    id: "review-1",
    description: "Review the authentication module for security vulnerabilities",
    context: "The auth module uses JWT tokens with opaque CLI fallback",
    acceptanceCriteria: [
      "All token validation paths are reviewed",
      "SQL injection vectors are checked",
      "Rate limiting is verified",
    ],
  },
  {
    minParticipants: 3,
    maxDiscussionRounds: 5,
    requireConsensus: true,
    enableReview: true,
  },
);

// Add participants
swarm.addParticipant({
  id: "security-lead",
  name: "Morgan",
  role: "Security Analyst",
  provider: "anthropic",
  model: "claude-opus-4-20250514",
  systemPrompt: "You are a senior security analyst specializing in web auth.",
});

swarm.addParticipant({
  id: "backend-dev",
  name: "Jordan",
  role: "Backend Developer",
  provider: "anthropic",
  model: "claude-sonnet-4-20250514",
});

swarm.addParticipant({
  id: "architect",
  name: "Alex",
  role: "System Architect",
  provider: "anthropic",
  model: "claude-sonnet-4-20250514",
});

// Listen to events
swarm.on("consensus_reached", (event) => {
  console.log("Plan agreed:", event.data?.consensus);
});

swarm.on("swarm_complete", (event) => {
  console.log("Final output:", event.data?.finalOutput);
});

// Run the full flow
const state = await swarm.run();
console.log(state.finalOutput);

createSwarm(task, config?): Swarm

Factory function that creates a new Swarm instance.

ParameterTypeDescription
taskSwarmTaskThe task for the swarm to work on
configPartial<SwarmConfig>Configuration options

SwarmConfig

interface SwarmConfig {
  minParticipants: number;       // default: 3
  maxDiscussionRounds: number;   // default: 5
  participantTimeout: number;    // default: 60000 (ms)
  requireConsensus: boolean;     // default: true
  enableReview: boolean;         // default: true
}
PropertyDefaultDescription
minParticipants3Minimum participants required to start
maxDiscussionRounds5Max rounds before forcing consensus
participantTimeout60000Timeout for waiting on participants (ms)
requireConsensustrueForce consensus if not reached naturally
enableReviewtrueEnable post-execution review phase

SwarmTask

interface SwarmTask {
  id: string;
  description: string;
  context?: string;
  acceptanceCriteria?: string[];
  relatedFiles?: string[];
}

Participant Management

addParticipant(participant): SwarmParticipant

Adds a participant to the swarm. Status is automatically set to "thinking".

addParticipant(participant: Omit<SwarmParticipant, "status">): SwarmParticipant
const participant = swarm.addParticipant({
  id: "reviewer-1",
  name: "Casey",
  role: "DevOps Engineer",
  provider: "anthropic",
  model: "claude-sonnet-4-20250514",
  systemPrompt: "You focus on infrastructure and deployment concerns.",
});

getParticipants(): SwarmParticipant[]

Returns all participants with their current status.

SwarmParticipant

interface SwarmParticipant {
  id: string;
  name: string;
  role: string;
  provider: "anthropic" | "google";
  model?: string;
  status: "thinking" | "ready" | "working" | "waiting" | "done";
  systemPrompt?: string;
}

Three-Phase Workflow

Phase 1: Planning Discussion

startPlanningDiscussion(): Promise<SwarmDiscussion>

Initiates a multi-round planning discussion. Each participant contributes their thoughts on the approach. After each round, AI checks for natural consensus. If consensus is not reached within maxDiscussionRounds and requireConsensus is true, a synthesized plan is forced.

const planning = await swarm.startPlanningDiscussion();
console.log(planning.consensus);
// "1. Review token validation in auth middleware\n2. Check SQL parameterization..."

Phase 2: Synchronized Execution

startExecution(): Promise<void>

Transitions the swarm to the execution phase. All participants are marked as "working".

signalReady(participantId): Promise<boolean>

Signals that a participant is ready to execute. Returns true if all participants are now ready.

waitForAllReady(timeout?): Promise<boolean>

Blocks until all participants are ready. Returns false on timeout.

submitResult(participantId, output, approach?): Promise<boolean>

Submits a participant's execution result. Returns true if all results are in.

await swarm.submitResult(
  "security-lead",
  "Found 3 vulnerabilities: 1) Missing rate limit on /api/auth/login...",
  "Focused on OWASP Top 10 categories",
);

waitForAllResults(timeout?): Promise<SwarmResult[]>

Blocks until all participants have submitted results. Throws on timeout (default: participantTimeout * 3).

Phase 3: Review Discussion

startReviewDiscussion(): Promise<SwarmDiscussion>

Each participant reviews all results and provides feedback. A final synthesized output is generated from all approaches and reviews. Throws if enableReview is false.

const review = await swarm.startReviewDiscussion();
console.log(review.consensus);
// Synthesized best output from all participants

Complete Flow

run(): Promise<SwarmState>

Convenience method that runs all three phases sequentially:

  1. Planning discussion with consensus
  2. Execution of each participant
  3. Review discussion and synthesis

Returns the final swarm state with finalOutput.

const state = await swarm.run();
console.log(state.phase);       // "complete"
console.log(state.finalOutput); // Synthesized result
console.log(state.results);     // Individual participant results
console.log(state.discussions); // Planning and review discussions

Events

on(event, handler): () => void

Subscribe to swarm events. Returns an unsubscribe function.

on(event: SwarmEventType | "*", handler: (event: SwarmEvent) => void | Promise<void>): () => void

Event Types

EventFired When
participant_joinedA participant is added
participant_readyA participant signals ready
discussion_startedA discussion phase begins
message_sentA participant sends a discussion message
consensus_reachedNatural consensus is detected
execution_startedExecution phase begins
result_submittedA participant submits a result
all_results_readyAll results are submitted
review_startedReview discussion begins
swarm_completeThe entire flow completes
swarm.on("message_sent", (event) => {
  const msg = event.data?.message as SwarmMessage;
  console.log(`${msg.participantName}: ${msg.content.slice(0, 100)}...`);
});

State

getState(): SwarmState

Returns the full swarm state.

interface SwarmState {
  id: string;
  task: SwarmTask;
  phase: SwarmPhase;                 // "planning" | "executing" | "reviewing" | "complete"
  participants: SwarmParticipant[];
  discussions: SwarmDiscussion[];
  results: SwarmResult[];
  finalOutput?: string;
  createdAt: Date;
  completedAt?: Date;
}

Types

SwarmPhase

type SwarmPhase = "planning" | "executing" | "reviewing" | "complete";

SwarmMessage

interface SwarmMessage {
  participantId: string;
  participantName: string;
  content: string;
  timestamp: Date;
  phase: SwarmPhase;
  replyTo?: string;
}

SwarmResult

interface SwarmResult {
  participantId: string;
  participantName: string;
  output: string;
  approach?: string;
  confidence?: number;
  completedAt: Date;
}

SwarmDiscussion

interface SwarmDiscussion {
  phase: SwarmPhase;
  topic: string;
  messages: SwarmMessage[];
  consensus?: string;
  startedAt: Date;
  endedAt?: Date;
}

SwarmEvent

interface SwarmEvent {
  type: SwarmEventType;
  swarmId: string;
  participantId?: string;
  data?: Record<string, unknown>;
  timestamp: Date;
}