How to Spawn Sub-Agents Using AgentTool in OpenClaude

OpenClaude's AgentTool lets the main Claude assistant launch isolated "sub-agents" (forked agents) to perform specialized tasks either synchronously or in the background.

The AgentTool is a core component of the Gitlawb/openclaude repository that enables recursive agent workflows. When you spawn sub-agents using AgentTool in OpenClaude, the system creates fresh AgentSession instances with independent prompt loops, optional Git work-tree isolation, and dedicated UI progress tracking.

Understanding the AgentTool Architecture

The AgentTool implementation spans several modules in src/tools/AgentTool/, each handling specific lifecycle stages from definition loading to result finalization.

Agent Definitions and Configuration

Agent configurations are resolved by loadAgentsDir.ts, which scans both the built-in agents directory (src/tools/AgentTool/built-in/) and the user's local agents/ folder. This module reads JSON/YAML agent definitions, merges configuration overrides, and validates the schema before execution.

Built-in agents like plan, explore, and codeReviewer ship with the repository and provide ready-made sub-agent behaviors for common tasks.

Entry Point and Tool Invocation

The AgentTool.tsx file serves as the primary entry point. When the system receives a tool use request with "name": "agent", this component:

  1. Parses the input payload containing the agent identifier and optional prompt
  2. Resolves the target agent definition via the loader
  3. Determines isolation level (foreground, background, or worktree)
  4. Delegates to either runAgent() for synchronous execution or resumeAgent() for background scheduling

Spawning Sub-Agents in Practice

OpenClaude supports three execution modes depending on your isolation and concurrency requirements.

Foreground Execution with runAgent

For synchronous, blocking operations, runAgent.ts contains the runAgent() function that:

  • Instantiates a fresh AgentSession with the sub-agent's model and system prompt
  • Optionally creates a temporary Git work-tree via createAgentWorktree() from src/utils/worktree.ts
  • Executes the sub-agent's prompt loop until completion or maxSteps exhaustion
  • Returns a consolidated ToolResult to the parent agent

This mode blocks the main conversation turn until the sub-agent completes, making it suitable for quick, dependent tasks.

Background Asynchronous Tasks

When isolation: "background" is specified (and the DISABLE_BACKGROUND_TASKS global flag is not set), resumeAgent.ts schedules the sub-agent as an asynchronous task. This allows the main session to continue while the sub-agent runs in parallel.

The UI components in UI.tsx render progress indicators for background tasks, and upon completion, the parent can retrieve results through the standard tool result mechanism.

Isolation with Git Worktrees

For repository operations that must not affect the main working directory, src/utils/worktree.ts provides createAgentWorktree(). When worktree: true is set in the tool input, OpenClaude creates a temporary Git work-tree that the sub-agent can modify freely. This isolation ensures that exploratory code changes, searches, or refactoring attempts by sub-agents remain sandboxed until explicitly merged.

Built-in and Custom Agent Types

The AgentTool supports both pre-configured agents shipped with OpenClaude and user-defined custom configurations.

Using Built-in Agents

Built-in agents reside in src/tools/AgentTool/built-in/ and include specialized agents like planAgent.ts and codeReviewerAgent.ts. These agents come with optimized system prompts and step limits for specific workflows. Invoke them by name without additional configuration:

{
  "type": "tool_use",
  "name": "agent",
  "input": {
    "agent": "plan",
    "prompt": "Create a 3-step outline for a blog post about AI safety.",
    "isolation": "foreground"
  }
}

Defining Custom Agents

Users can create custom agent definitions in the agents/ directory. Each definition specifies the model, system prompt, maximum steps, and default isolation level. The loadAgentsDir.ts loader automatically picks up these files at runtime, making them available alongside built-in agents.

Code Examples

The following examples demonstrate how to spawn sub-agents using AgentTool for different use cases.

1. Simple Foreground Sub-Agent Call

Use this pattern for synchronous tasks that must complete before the main conversation continues:

import { AgentTool } from './tools/AgentTool/AgentTool.tsx';

// Tool use payload
{
  "type": "tool_use",
  "name": "agent",
  "input": {
    "agent": "plan",
    "prompt": "Create a 3-step outline for a blog post about AI safety.",
    "isolation": "foreground"
  }
}

The AgentTool parses this input, resolves the plan agent definition, and calls runAgent(). The sub-agent runs its reasoning loop and returns a single ToolResult that appears as the assistant's reply.

2. Background Sub-Agent with Work-Tree Isolation

Use this pattern for long-running repository analysis that should not block the main conversation:

import { AgentTool } from './tools/AgentTool/AgentTool.tsx';

// Tool use payload
{
  "type": "tool_use",
  "name": "agent",
  "input": {
    "agent": "explore",
    "prompt": "Search the repo for any TODO comments and list them.",
    "isolation": "background",
    "worktree": true
  }
}

When isolation is "background", the request delegates to resumeAgent(). The UI shows a progress bar, and the main conversation continues while the sub-agent works in an isolated Git work-tree. Upon completion, a notification emits and the result becomes available.

3. Custom User-Defined Agent

Assume you created agents/customAgent.json:

{
  "name": "customAgent",
  "model": "claude-3-opus-20240307",
  "systemPrompt": "You are a helpful assistant that only returns JSON.",
  "maxSteps": 4,
  "isolation": "foreground"
}

Invoke your custom agent by name:

{
  "type": "tool_use",
  "name": "agent",
  "input": {
    "agent": "customAgent",
    "prompt": "Summarize the README of this repository in one sentence."
  }
}

The loadAgentsDir() function discovers this definition, runAgent() instantiates a fresh session with the specified model, and the result returns to the parent turn.

Summary

  • AgentTool is the primary interface for spawning sub-agents in OpenClaude, implemented in src/tools/AgentTool/AgentTool.tsx.
  • runAgent.ts handles synchronous foreground execution with full blocking behavior, while resumeAgent.ts manages asynchronous background tasks.
  • Git work-tree isolation via src/utils/worktree.ts creates sandboxed environments for repository-modifying sub-agents.
  • Built-in agents provide immediate utility for planning and code review, while the agents/ directory supports custom JSON/YAML definitions.
  • The UI.tsx components render progress and results for both foreground and background agent operations.

Frequently Asked Questions

What is the difference between foreground and background isolation when spawning sub-agents?

Foreground isolation blocks the parent agent's conversation turn until the sub-agent completes, returning a ToolResult synchronously via runAgent.ts. Background isolation delegates the task to resumeAgent.ts, allowing the main conversation to continue while the sub-agent executes asynchronously. Background tasks emit UI notifications upon completion rather than blocking the conversation flow.

How does the work-tree isolation protect the main repository?

When you set worktree: true in the AgentTool input, createAgentWorktree() in src/utils/worktree.ts creates a temporary Git work-tree—a separate working directory linked to the same repository. The sub-agent operates in this isolated directory, so any file modifications, deletions, or git operations cannot affect the main working tree or the parent agent's environment. The work-tree is cleaned up automatically after the sub-agent finishes.

Can I use a different model for the sub-agent than the parent Claude instance?

Yes. The agent definition JSON/YAML file specifies the model field independently of the parent session. When runAgent() creates the sub-agent's AgentSession, it uses the model specified in the definition (e.g., claude-3-opus-20240307 or claude-3-sonnet-20240229), allowing lightweight sub-agents to use smaller models while complex tasks use larger ones, regardless of the parent agent's configuration.

Where should I place custom agent definitions in my OpenClaude project?

Place custom agent definitions in the agents/ directory at your project root. The loadAgentsDir.ts loader automatically scans this directory at runtime, merging your custom JSON/YAML files with the built-in agents located in src/tools/AgentTool/built-in/. Ensure each file contains a valid agent definition with required fields: name, model, systemPrompt, and maxSteps.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →