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

# Subagents

> Autonomous codebase exploration with bidirectional messaging

Subagents are autonomous agents that run in their own context window. The Explore subagent searches your codebase using WarpGrep, decides what to search next based on results, and returns a structured summary. Your main agent's context stays clean.

### Why?

Codebase exploration is context-heavy. A single WarpGrep call returns relevant code, but understanding how a system works often takes 3-8 searches. The Explore subagent handles this loop autonomously on a cheap/fast model (Haiku), then returns only the summary to your primary agent.

The subagent also supports **pause-and-ask messaging**: if it hits a fork in the road ("Found JWT and OAuth auth. Which should I focus on?"), it can ask your app and wait for a reply before continuing.

## Quick Start

<Tabs>
  <Tab title="Anthropic">
    ```typescript theme={null}
    import Anthropic from '@anthropic-ai/sdk';
    import { MorphClient } from '@morphllm/morphsdk';

    const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });
    const anthropic = new Anthropic();

    // Create the subagent
    const explore = morph.anthropic.createExploreSubagent({
      client: anthropic,
      model: 'claude-haiku-4-5-20251001',
      repoRoot: '.',
    });

    // Run an exploration
    const session = explore.run('How does the authentication system work?');

    session.on('step', (step) => {
      console.log(`Step ${step.step}: searching "${step.searchRequest}"`);
    });

    const result = await session.result;
    console.log(result.summary);   // Concise summary for your agent
    console.log(result.contexts);  // Full code contexts for your app
    ```
  </Tab>

  <Tab title="Vercel AI SDK">
    ```typescript theme={null}
    import { generateText, stepCountIs } from 'ai';
    import { anthropic } from '@ai-sdk/anthropic';
    import { MorphClient } from '@morphllm/morphsdk';

    const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });

    // Create the subagent
    const explore = morph.vercel.createExploreSubagent({
      model: anthropic('claude-haiku-4-5-20251001'),
      repoRoot: '.',
    });

    // Use as a tool in your parent agent
    const result = await generateText({
      model: anthropic('claude-sonnet-4-5-20250929'),
      tools: { explore: explore.tool },
      stopWhen: stepCountIs(5),
      prompt: 'How does the auth flow work in this codebase?',
    });
    ```
  </Tab>
</Tabs>

## Three Ways to Use

### 1. As a Tool in a Parent Agent

The subagent exposes a `.tool` property you can pass to any agent. The parent model calls it like any other tool, and the subagent runs its full search loop internally.

<Tabs>
  <Tab title="Anthropic">
    ```typescript theme={null}
    const explore = morph.anthropic.createExploreSubagent({
      client: anthropic,
      model: 'claude-haiku-4-5-20251001',
      repoRoot: '.',
    });

    // Use alongside other tools
    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-5-20250929',
      max_tokens: 8000,
      tools: [explore.tool, editTool],
      messages: [{ role: 'user', content: 'Find and fix the auth bug' }]
    });

    // Execute when the model calls it
    const toolUse = response.content.find(c => c.type === 'tool_use' && c.name === 'explore');
    if (toolUse) {
      const result = await explore.tool.execute(toolUse.input);
      console.log(result.summary);
    }
    ```
  </Tab>

  <Tab title="Vercel AI SDK">
    ```typescript theme={null}
    const explore = morph.vercel.createExploreSubagent({
      model: anthropic('claude-haiku-4-5-20251001'),
      repoRoot: '.',
    });

    // Vercel AI SDK handles the tool loop
    const result = await generateText({
      model: anthropic('claude-sonnet-4-5-20250929'),
      tools: { explore: explore.tool, edit: editTool },
      stopWhen: stepCountIs(5),
      prompt: 'Find and fix the auth bug',
    });
    ```
  </Tab>
</Tabs>

### 2. Direct Run with Messaging

Call `.run()` to start an exploration and listen for events. The subagent can pause and ask questions via `send_message`, and your app replies.

```typescript theme={null}
const session = explore.run('Explore the payment processing system');

// Listen for progress
session.on('step', (step) => {
  console.log(`Step ${step.step}: searching "${step.searchRequest}" -> ${step.contextsFound} files`);
});

// Handle pause-and-ask messages
session.on('message', (msg, reply) => {
  console.log(`Subagent asks: ${msg.content}`);
  // e.g. "Found Stripe and PayPal integrations. Which should I focus on?"
  reply('Focus on Stripe');
});

const result = await session.result;
// result.success, result.summary, result.contexts, result.searchCount, result.durationMs
```

### 3. Streaming

Use `.stream()` to get events as an async generator.

```typescript theme={null}
for await (const event of explore.stream('Find all API routes')) {
  if (event.type === 'step') {
    console.log(`Searching: ${event.searchRequest} -> ${event.contextsFound} files`);
  }
  if (event.type === 'message') {
    console.log(`Subagent: ${event.content}`);
  }
}
```

## Messaging Protocol

The subagent has two internal tools: `codebase_search` (WarpGrep) and `send_message`. The system prompt instructs it to use `send_message` when it:

* Hits a fork: *"Found auth in both `src/middleware/` and `legacy/auth/`. Should I focus on one or cover both?"*
* Needs clarification: *"There are 3 auth strategies (JWT, session, OAuth). Which one?"*
* Has a key finding to share before continuing: *"The main handler is in `src/auth/index.ts`. Continuing to trace the JWT flow."*

When `send_message` is called, the tool **blocks** until your app replies (or a timeout fires). The reply is injected back as the tool result, and the subagent continues with that context.

```
Your App                           Explore Subagent
  |                                      |
  |---- run("How does auth work?") ----->|
  |                                      |-- codebase_search("auth")
  |<-- step: searching "auth" ----------|-- WarpGrep returns results
  |                                      |-- model has a question
  |                                      |-- send_message("Found JWT and OAuth...")
  |<-- message: "Found JWT and..." -----|-- BLOCKS, waiting for reply
  |                                      |
  |---- reply("Focus on JWT") --------->|-- tool returns "Response: Focus on JWT"
  |                                      |-- codebase_search("JWT validation")
  |<-- step: searching "JWT..." --------|-- WarpGrep returns results
  |                                      |-- model has enough info
  |<-- result: ExploreResult ------------|
```

## Configuration

```typescript theme={null}
const explore = morph.vercel.createExploreSubagent({
  model: anthropic('claude-haiku-4-5-20251001'),
  repoRoot: '.',
  thoroughness: 'medium',
  replyTimeout: 30000,
  excludes: ['dist', '*.test.ts'],
});
```

| Option         | Default             | Description                                                    |
| -------------- | ------------------- | -------------------------------------------------------------- |
| `model`        | (required)          | Vercel AI SDK model instance, or `model` string for Anthropic  |
| `client`       | (Anthropic only)    | Anthropic SDK client instance                                  |
| `repoRoot`     | (required)          | Root directory of the repository to search                     |
| `thoroughness` | `'medium'`          | `'quick'` (1-2 searches), `'medium'` (2-4), `'thorough'` (4-8) |
| `maxTurns`     | (auto)              | Override the max model turns (defaults based on thoroughness)  |
| `timeout`      | (none)              | Timeout in ms for the entire exploration                       |
| `replyTimeout` | `30000`             | Timeout in ms for waiting for host reply to `send_message`     |
| `excludes`     | (WarpGrep defaults) | Glob patterns to exclude from search                           |
| `includes`     | (all files)         | Glob patterns to include in search                             |

## Result Shape

```typescript theme={null}
interface ExploreResult {
  success: boolean;        // Whether the exploration completed
  summary: string;         // Concise summary (for model consumption)
  contexts: WarpGrepContext[]; // Full code contexts (for your app)
  searchCount: number;     // Number of WarpGrep searches performed
  durationMs: number;      // Total wall-clock time
  error?: string;          // Error message if failed
}
```

Each context in `contexts` contains:

```typescript theme={null}
interface WarpGrepContext {
  file: string;      // File path relative to repoRoot
  content: string;   // Relevant code with line numbers
  lines?: '*' | Array<[number, number]>;  // Line ranges
}
```

## Direct Import

You can also import the subagent creators directly without `MorphClient`:

<Tabs>
  <Tab title="Anthropic">
    ```typescript theme={null}
    import { createExploreSubagent } from '@morphllm/morphsdk/subagents/anthropic';

    const explore = createExploreSubagent({
      client: new Anthropic(),
      model: 'claude-haiku-4-5-20251001',
      morphApiKey: process.env.MORPH_API_KEY,
      repoRoot: '.',
    });
    ```
  </Tab>

  <Tab title="Vercel AI SDK">
    ```typescript theme={null}
    import { createExploreSubagent } from '@morphllm/morphsdk/subagents/vercel';

    const explore = createExploreSubagent({
      model: anthropic('claude-haiku-4-5-20251001'),
      morphApiKey: process.env.MORPH_API_KEY,
      repoRoot: '.',
    });
    ```
  </Tab>
</Tabs>
