Agent Skills: Subagent Coordination

Multi-agent coordination patterns for delegating work between specialized agents, managing agent roles, and orchestrating workflows across multiple AI agents.

UncategorizedID: pwarnock/liaison-toolkit/subagent-coordination

Install this agent skill to your local

pnpm dlx add-skill https://github.com/pwarnock/liaison-toolkit/tree/HEAD/.skills/subagent-coordination

Skill Files

Browse the full folder contents for subagent-coordination.

Download Skill

Loading file tree…

.skills/subagent-coordination/SKILL.md

Skill Metadata

Name
subagent-coordination
Description
Multi-agent coordination patterns for delegating work between specialized agents, managing agent roles, and orchestrating workflows across multiple AI agents.

Subagent Coordination

Patterns for coordinating work across multiple specialized AI agents, managing agent roles and responsibilities, and orchestrating delegated workflows.

When to use this skill

Use this skill when:

  • Determining which agent should handle a specific task
  • Delegating work between specialized agents
  • Designing multi-agent workflows
  • Managing agent capability discovery
  • Handling agent handoffs and escalation
  • Orchestrating complex tasks across agents

Agent Roles and Boundaries

Core Agent Types

From agents/ directory structure:

// Primary agents (initiative)
cody-admin.json      → Project coordination, planning, infrastructure
cody-builder.json    → Build processes, compilation, deployment

// Specialized agents (reactive)
cody-general.json     → General assistance, undefined tasks
cody-planner.json     → Task breakdown, dependency analysis
cody-release-manager → Release management, versioning, publishing
qa-subagent.json       → Quality assurance, testing, validation
security-subagent.json  → Security audits, vulnerability scanning
frontend-specialist   → Frontend development (React, Vue, etc.)

Role Responsibility Matrix

| Agent | Primary Role | Delegates To | Avoids | |--------|--------------|--------------|----------| | cody-admin | Infrastructure, planning | All agents | None | | cody-planner | Task breakdown | cody-general | Direct implementation | | qa-subagent | Testing | All | None | | security-subagent | Security audits | All | None | | frontend-specialist | UI/components | cody-general | Backend logic | | cody-builder | Build/deploy | cody-admin | Development tasks |

Capabilities by Agent

// Agent capability mapping
const AGENT_CAPABILITIES = {
  'cody-admin': [
    'task-management',
    'agent-orchestration',
    'build-automation'
  ],
  'cody-planner': [
    'task-decomposition',
    'dependency-analysis',
    'planning'
  ],
  'qa-subagent': [
    'testing-strategy',
    'test-execution',
    'quality-gate-enforcement'
  ],
  'security-subagent': [
    'vulnerability-scanning',
    'security-audit',
    'compliance-validation'
  ],
  'frontend-specialist': [
    'component-creation',
    'styling',
    'ui-testing'
  ]
};

Delegation Patterns

Capability-Based Routing

function findBestAgent(task: Task): string {
  const taskType = inferTaskType(task);

  // Map task types to agents
  const agentMapping: Record<string, string> = {
    'testing': 'qa-subagent',
    'security': 'security-subagent',
    'frontend': 'frontend-specialist',
    'release': 'cody-release-manager',
    'planning': 'cody-planner',
    'infrastructure': 'cody-admin',
    'general': 'cody-general'
  };

  return agentMapping[taskType] || 'cody-general';
}

// Usage
const agent = findBestAgent({ type: 'security-audit' });
console.log(`Delegating to: ${agent}`);
await delegateToAgent(agent, task);

Sequential Delegation

async function executeMultiAgentWorkflow(workflow: Workflow): Promise<void> {
  const steps = workflow.steps;

  for (let i = 0; i < steps.length; i++) {
    const step = steps[i];
    const agent = findBestAgent(step);

    console.log(`Step ${i + 1}/${steps.length}: ${step.name} → ${agent}`);

    const result = await delegateToAgent(agent, step);

    if (!result.success) {
      console.error(`Agent ${agent} failed at step ${i + 1}`);
      await escalateFailure(step, result);
      break;
    }

    // Pass results to next step
    workflow.context[step.name] = result;
  }
}

Parallel Delegation

async function executeParallelTasks(tasks: Task[]): Promise<TaskResult[]> {
  // Group tasks by agent type
  const agentTasks: Record<string, Task[]> = {};

  for (const task of tasks) {
    const agent = findBestAgent(task);
    agentTasks[agent] = agentTasks[agent] || [];
    agentTasks[agent].push(task);
  }

  // Execute each agent's tasks in parallel
  const results = await Promise.all(
    Object.entries(agentTasks).map(([agent, tasks]) =>
      executeAgentBatch(agent, tasks)
    )
  );

  return results.flat();
}

Agent Handoff Procedures

Context Passing

interface AgentHandoff {
  fromAgent: string;
  toAgent: string;
  context: {
    task: string;
    results: any;
    decisions: string[];
    partialState?: any;
  };
}

function handoffAgent(handoff: AgentHandoff): Promise<void> {
  console.log(`Handoff: ${handoff.fromAgent} → ${handoff.toAgent}`);

  // Transfer context to next agent
  const newAgent = loadAgent(handoff.toAgent);
  await newAgent.initialize(handoff.context);

  // Clear previous agent state
  const previousAgent = loadAgent(handoff.fromAgent);
  await previousAgent.cleanup();
}

Handoff Templates

// From cody-planner to qa-subagent
const handoffToQA = {
  fromAgent: 'cody-planner',
  toAgent: 'qa-subagent',
  context: {
    task: 'Validate implementation',
    results: {
      implementationFiles: ['src/command.ts', 'src/utils.ts'],
      decisions: ['Used Bun test runner', 'Implemented with 80% coverage']
    },
    taskBreakdown: {
      'unit-tests': 'cody-general',
      'integration-tests': 'qa-subagent',
      'e2e-tests': 'qa-subagent'
    }
  };
}

Error Escalation

Failure Detection

async function delegateWithRetry(agent: string, task: Task, maxRetries = 3): Promise<any> {
  let lastError: Error | null = null;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const result = await executeAgentTask(agent, task);
      return result;
    } catch (error) {
      lastError = error as Error;
      console.warn(`Agent ${agent} attempt ${attempt} failed: ${error.message}`);

      if (attempt < maxRetries) {
        await sleep(2000 * attempt); // Exponential backoff
      }
    }
  }

  // All retries exhausted - escalate
  return await escalateFailure(agent, task, lastError);
}

Escalation Paths

// Agent → More specialized agent
const escalationPath = {
  'cody-general': 'qa-subagent',
  'cody-planner': 'cody-admin',
  'frontend-specialist': 'security-subagent',
  'qa-subagent': 'cody-admin',
  'security-subagent': 'cody-admin'
};

function escalateToSupervisor(failedAgent: string, error: Error): Promise<void> {
  const supervisor = escalationPath[failedAgent];

  console.error(`Escalating from ${failedAgent} to ${supervisor}`);

  await notifySupervisor(supervisor, {
    agent: failedAgent,
    error: error.message,
    timestamp: new Date()
  });
}

Workflow Orchestration

Agent Graph Definition

interface AgentNode {
  id: string;
  agent: string;
  dependencies: string[];
  outputDependencies: string[];
}

const WORKFLOW_GRAPH: AgentNode[] = [
  {
    id: 'plan',
    agent: 'cody-planner',
    dependencies: [],
    outputDependencies: ['implement']
  },
  {
    id: 'implement',
    agent: 'cody-general',
    dependencies: ['plan'],
    outputDependencies: ['test']
  },
  {
    id: 'test',
    agent: 'qa-subagent',
    dependencies: ['implement'],
    outputDependencies: ['deploy']
  },
  {
    id: 'deploy',
    agent: 'cody-builder',
    dependencies: ['test'],
    outputDependencies: []
  }
];

function executeWorkflow(graph: AgentNode[]): Promise<void> {
  const executionOrder = topologicalSort(graph);

  for (const node of executionOrder) {
    const agent = loadAgent(node.agent);
    console.log(`Executing ${node.id} with ${node.agent}`);

    // Wait for dependencies
    await waitForDependencies(node.dependencies);

    // Execute
    const result = await agent.execute(node);

    // Notify dependent agents
    notifyDependencies(node.outputDependencies, result);
  }
}

Orchestration with Liaison

# Create workflow in liaison
liaison workflow create "multi-agent-release" \
  --trigger "agent:delegated:agent=cody-planner" \
  --actions "delegate-to-general,notify-builder" \
  --condition "all-dependencies-met"

# Trigger workflow
liaison task create "Prepare release" --auto-trigger "multi-agent-release"

Inter-Agent Communication

Message Format

interface AgentMessage {
  from: string;
  to: string;
  type: 'task' | 'result' | 'error' | 'status';
  payload: any;
  timestamp: Date;
  correlationId: string;
}

async function sendAgentMessage(message: AgentMessage): Promise<void> {
  await messageBus.publish({
    topic: `agent.${message.to}`,
    message,
    headers: {
      'X-Agent-From': message.from,
      'X-Correlation-ID': message.correlationId
    }
  });
}

Status Broadcasting

// Agent status updates
async function broadcastStatus(agent: string, status: 'working' | 'idle' | 'error'): Promise<void> {
  await messageBus.publish({
    topic: 'agent.status',
    message: { agent, status, timestamp: new Date() }
  });
}

// Subscribe to agent status
function subscribeToAgentStatus(callback: (status: AgentStatus) => void): void {
  messageBus.subscribe('agent.status', callback);
}

Agent Discovery

Capability Registration

// Agents register their capabilities
interface AgentCapabilities {
  agent: string;
  capabilities: string[];
  maxConcurrency: number;
  supportedTaskTypes: string[];
}

// cody-admin registers agents
await liaison.registerAgent({
  agent: 'qa-subagent',
  capabilities: ['testing', 'validation', 'quality-gates'],
  maxConcurrency: 1,
  supportedTaskTypes: ['testing', 'validation']
});

Finding Agents

# List available agents
liaison agent list

# Find agent by capability
liaison agent find --capability testing

# Check agent status
liaison agent status qa-subagent

Verification

After implementing agent coordination:

  • [ ] Agent roles and responsibilities clearly defined
  • [ ] Delegation logic routes tasks to appropriate agents
  • [ ] Handoff procedures transfer context between agents
  • [ ] Escalation paths are defined for failures
  • [ ] Inter-agent communication is standardized
  • [ ] Workflow graphs are validated for cycles
  • [ ] Agent capabilities are registered and discoverable
  • [ ] Parallel delegation doesn't exceed agent concurrency
  • [ ] Error handling includes retry and escalation

Examples from liaison-toolkit

Example 1: Multi-Agent Release

# 1. cody-planner breaks down release task
liaison task create "Prepare release" --auto-trigger planning

# 2. cody-general implements changes
liaison task create "Implement version bump" --assign cody-general

# 3. qa-subagent validates
liaison task create "Run tests" --assign qa-subagent

# 4. security-subagent scans
liaison task create "Security audit" --assign security-subagent

# 5. cody-builder deploys
liaison task create "Build and publish" --assign cody-builder

Example 2: Error Escalation

// cody-planner delegates to cody-general
const result = await delegateToAgent('cody-general', task);

if (!result.success) {
  // Escalate to cody-admin
  console.error('General agent failed, escalating to admin...');

  await escalateToAdmin({
    originalAgent: 'cody-general',
    task,
    error: result.error
  });
}

Example 3: Capability Discovery

// Find agent for security task
const agent = liaison.findAgent({
  capabilities: ['security-audit', 'vulnerability-scanning']
});

// Returns: 'security-subagent'
console.log(`Delegating security task to: ${agent}`);
await executeAgent(agent, task);

Related Resources