> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instructorphp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent subagents

## Overview

Subagents enable decomposition of complex tasks into isolated subtasks. The main agent
orchestrates multiple subagents, each with specialized roles and tools. This pattern
provides:

* **Context isolation**: Each subagent has clean context without cross-contamination
* **Isolated execution**: Each subagent runs independently with its own state
* **Specialized capabilities**: Each subagent has specific tools for its role
* **Scalability**: Handle many independent subtasks without context overflow
* **Result aggregation**: Main agent synthesizes subagent outputs

Key concepts:

* `UseSubagents`: Capability that enables subagent spawning
* `AgentDefinitionRegistry`: Registry of available subagent definitions
* `AgentDefinition`: Defines subagent role, tools, and behavior
* `AgentEventConsoleObserver`: Shows parent/child agent IDs for tracking orchestration

## Example

```php theme={null}
<?php
require 'examples/boot.php';

use Cognesy\Agents\Builder\AgentBuilder;
use Cognesy\Agents\Capability\Core\UseGuards;
use Cognesy\Agents\Capability\File\UseFileTools;
use Cognesy\Agents\Capability\Subagent\UseSubagents;
use Cognesy\Agents\Collections\NameList;
use Cognesy\Agents\Data\AgentState;
use Cognesy\Agents\Events\Support\AgentEventConsoleObserver;
use Cognesy\Agents\Template\AgentDefinitionRegistry;
use Cognesy\Agents\Template\Data\AgentDefinition;
use Cognesy\Messages\Messages;

// Create console logger - shows agent IDs for parent/child tracking
$logger = new AgentEventConsoleObserver(
    useColors: true,
    showTimestamps: true,
    showContinuation: true,
    showToolArgs: true,
);

// Configure working directory
$workDir = dirname(__DIR__, 3);

// Create subagent registry
$registry = new AgentDefinitionRegistry();

// Register code reviewer subagent
$registry->register(new AgentDefinition(
    name: 'reviewer',
    description: 'Reviews code files and identifies issues',
    systemPrompt: 'You review code files and identify issues. Read the file and provide a concise assessment focusing on code quality, potential bugs, and improvements.',
    tools: NameList::fromArray(['read_file']),
));

// Register documentation generator subagent
$registry->register(new AgentDefinition(
    name: 'documenter',
    description: 'Generates documentation for code',
    systemPrompt: 'You generate documentation for code. Read the file and create brief, clear documentation explaining what the code does and how to use it.',
    tools: NameList::fromArray(['read_file']),
));

// Build main orchestration agent
$agent = AgentBuilder::base()
    ->withCapability(new UseFileTools($workDir))
    ->withCapability(new UseSubagents(provider: $registry))
    ->withCapability(new UseGuards(maxSteps: 10, maxTokens: 12288, maxExecutionTime: 90))
    ->build()
    ->wiretap($logger->wiretap());

// Task requiring multiple isolated reviews (small files to keep token usage low)
$task = <<<TASK
Review these three capability files and provide a summary:
1. packages/agents/src/Capability/Core/UseTools.php
2. packages/agents/src/Capability/File/UseFileTools.php
3. packages/agents/src/Capability/SelfCritique/UseSelfCritique.php

For each file, spawn a reviewer subagent. Then summarize the findings.
TASK;

$state = AgentState::empty()->withMessages(
    Messages::fromString($task)
);

echo "=== Agent Execution Log ===\n";
echo "Task: Review multiple files using subagents\n\n";

// Execute agent until completion
$finalState = $agent->execute($state);

echo "\n=== Result ===\n";
$summary = $finalState->finalResponse()->toString() ?: 'No summary';
echo "Answer: {$summary}\n";
echo "Steps: {$finalState->stepCount()}\n";
echo "Tokens: {$finalState->usage()->total()}\n";
echo "Status: {$finalState->status()->value}\n";

if ($finalState->status()->value !== 'completed') {
    echo "Skipping assertions because execution status is {$finalState->status()->value}.\n";
    exit(1);
}

// Assertions
assert(!empty($finalState->finalResponse()->toString()), 'Expected non-empty response');
assert($finalState->stepCount() >= 1, 'Expected at least 1 step');
assert($finalState->usage()->total() > 0, 'Expected token usage > 0');
?>
```
