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

# Subagent Tool

> Spawn subagents dynamically with model and permission control

The Subagent Tool lets a parent agent spawn specialised subagents for specific tasks — synchronously, or in the **background** so the parent keeps working and collects the result later.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents.tools.subagent_tool import create_subagent_tool

parent = Agent(
    name="Coordinator",
    instructions="Delegate exploration to subagents when needed.",
    tools=[create_subagent_tool(default_permission_mode="plan")],
)

parent.start("Explore the auth module read-only")
```

The user asks the coordinator; the parent spawns a subagent with the requested permissions.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Subagent Tool Flow"
        A[🤖 Parent Agent] --> B[🔧 create_subagent_tool]
        B --> C{spawn_subagent}
        C -->|background=False| S[⚡ Synchronous]
        C -->|background=True| K[📨 job_id]
        K --> R[🔁 subagent_result]
        S --> G[✅ Result]
        R --> G
    end

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef config fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff

    class A agent
    class B,C,R tool
    class S,K config
    class G result
```

## Quick Start

<Steps>
  <Step title="Create Subagent Tool">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents.tools.subagent_tool import create_subagent_tool

    tool = create_subagent_tool()
    ```
  </Step>

  <Step title="Spawn a Subagent">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    func = tool["function"]
    result = func(task="Analyze the authentication module")

    if result["success"]:
        print(result["output"])
    ```
  </Step>

  <Step title="With Model and Permission Mode">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    tool = create_subagent_tool(
        default_llm="gpt-4o-mini",
        default_permission_mode="plan"
    )

    func = tool["function"]
    result = func(
        task="Explore the codebase",
        llm="gpt-4o",  # Override model
        permission_mode="plan"  # Read-only mode
    )
    ```
  </Step>
</Steps>

***

## Configuration Options

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.tools.subagent_tool import create_subagent_tool

tool = create_subagent_tool(
    agent_factory=my_factory,      # Custom agent factory
    allowed_agents=["explorer"],   # Restrict agent types
    max_depth=3,                   # Maximum nesting depth
    default_llm="gpt-4o-mini",     # Default LLM model
    default_permission_mode="plan" # Default permission mode
)
```

| Parameter                 | Type        | Default | Description                               |
| ------------------------- | ----------- | ------- | ----------------------------------------- |
| `agent_factory`           | `Callable`  | `None`  | Custom function to create agents          |
| `allowed_agents`          | `List[str]` | `None`  | Restrict which agent types can be spawned |
| `max_depth`               | `int`       | `3`     | Maximum subagent nesting depth            |
| `default_llm`             | `str`       | `None`  | Default LLM model for subagents           |
| `default_permission_mode` | `str`       | `None`  | Default permission mode                   |

***

## Spawn Parameters

When calling the subagent function:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
func = tool["function"]
result = func(
    task="Your task description",
    agent_name="explorer",
    context="Additional context",
    tools=["read_file", "search"],
    llm="gpt-4o",
    permission_mode="plan"
)
```

| Parameter         | Type        | Required | Description                                                                                                                                                                    |
| ----------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `task`            | `str`       | ✅ Yes    | Task description for the subagent                                                                                                                                              |
| `agent_name`      | `str`       | No       | Specific agent type to use                                                                                                                                                     |
| `context`         | `str`       | No       | Additional context for the task                                                                                                                                                |
| `tools`           | `List[str]` | No       | Tools to give the subagent                                                                                                                                                     |
| `llm`             | `str`       | No       | LLM model override                                                                                                                                                             |
| `permission_mode` | `str`       | No       | Permission mode override                                                                                                                                                       |
| `background`      | `bool`      | No       | When `True`, enqueue on the background job runner and return immediately with a `job_id`                                                                                       |
| `deliver`         | `str`       | No       | Delivery target for a background job's result — e.g. `"origin"`, `"all"`, or `"telegram:12345"`. Only meaningful with `background=True`. Empty (default) keeps jobs pull-only. |
| `platform`        | `str`       | No       | Origin platform (e.g. `"telegram"`) — captured for `deliver="origin"`. Usually supplied by the gateway context automatically.                                                  |
| `chat_id`         | `str`       | No       | Origin chat/channel ID — captured for `deliver="origin"`.                                                                                                                      |
| `thread_id`       | `str`       | No       | Optional origin thread ID.                                                                                                                                                     |
| `session_id`      | `str`       | No       | Optional origin session ID to preserve context.                                                                                                                                |

***

## Deliver Background Job Results Back to Chat

When a background job finishes, its result can be pushed back to the user's chat automatically — no polling required.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.tools.subagent_tool import create_subagent_tool

tool = create_subagent_tool()
spawn = tool["function"]

handle = spawn(
    task="Run a full analysis of the repository",
    background=True,
    deliver="origin",
)
```

### Delivery targets

| Target                         | Behaviour                                                                    |
| ------------------------------ | ---------------------------------------------------------------------------- |
| `""` (empty, default)          | Pull-only — use `subagent_result(job_id)` to collect                         |
| `"origin"`                     | Deliver to the chat that started the job (requires parent to have an origin) |
| `"all"`                        | Deliver to all channels registered on the gateway                            |
| `"platform:chat_id"`           | Deliver to a specific platform/channel (e.g. `"telegram:123456"`)            |
| `"platform:chat_id:thread_id"` | Deliver to a specific thread                                                 |

<Note>
  `deliver="origin"` requires the parent to have an origin context — inside a BotOS chat it does. From a plain script with no active chat context, the pull-only default (`deliver=""`) applies. Failures are also delivered as a failure notice, so the user is never left waiting silently.
</Note>

The `deliver` vocabulary mirrors the scheduling tool's `deliver=` parameter. See [JOB\_COMPLETED Hook](/docs/features/job-completed-hook) for the hook that fires on completion.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Parent as Parent Agent
    participant BG as Background Runner
    participant GW as BotOS / Gateway

    User->>Parent: "analyse the repo and tell me when done"
    Parent->>BG: spawn_subagent(background=True, deliver="origin")
    BG-->>Parent: job_id (immediate)
    Parent-->>User: "Kicked off — I'll let you know"
    BG->>BG: execute task
    BG->>GW: on_background_job_complete
    GW-->>User: "Analysis complete: [summary]"
```

**Backward compatibility:** with no `deliver` target set, behaviour is byte-for-byte identical to before — pull-only via `subagent_result`.

***

## Background Mode

Run a long subtask without blocking the parent agent. Use it for full test runs, broad codebase scans, or large refactors — anything where the parent agent should keep working instead of waiting.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Parent as Parent Agent
    participant BG as Background Runner
    participant Sub as Subagent

    User->>Parent: "refactor utils & keep working"
    Parent->>BG: spawn_subagent(background=True)
    BG-->>Parent: job_id
    Parent->>Parent: continue other work
    Parent->>BG: subagent_result(job_id, wait=True)
    BG->>Sub: execute
    Sub-->>BG: result
    BG-->>Parent: completed + result
    Parent-->>User: final answer
```

<Steps>
  <Step title="Kick off in the background">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents.tools.subagent_tool import create_subagent_tool

    tool = create_subagent_tool()
    spawn = tool["function"]

    handle = spawn(
        task="Run the full test suite",
        background=True,
    )
    job_id = handle["job_id"]
    ```
  </Step>

  <Step title="Keep working, then collect the result">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    collect = tool["result_tool"]["function"]

    # Non-blocking poll — returns status="running" or status="completed"
    status = collect(job_id)

    # Or block until done
    final = collect(job_id, wait=True)
    if final["status"] == "completed":
        print(final["result"]["output"])
    ```
  </Step>

  <Step title="Handle failures cleanly">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    result = collect(job_id, wait=True)

    if not result["success"]:
        print("Job failed:", result.get("error"))
    elif result["result"]["success"] is False:
        print("Subagent error:", result["result"]["error"])
    else:
        print(result["result"]["output"])
    ```
  </Step>
</Steps>

### When to use background mode

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{Will the subtask take<br/>more than a few seconds?}
    Q -->|No| Sync[Use synchronous<br/>spawn_subagent]
    Q -->|Yes| B{Does the parent agent<br/>have other work to do<br/>right now?}
    B -->|No| Sync
    B -->|Yes| BG[Use background=True<br/>+ subagent_result]

    classDef question fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef sync fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef async fill:#10B981,stroke:#7C90A0,color:#fff

    class Q,B question
    class Sync sync
    class BG async
```

### Background return shapes

`spawn_subagent(..., background=True)` returns a **handle** (not a final result):

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
    "success": True,
    "job_id": "...",
    "status": "running",
    "agent_name": "subagent",
    "task": "...",
    "llm": "...",
    "permission_mode": "...",
}
```

`subagent_result(job_id)` polls without blocking:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# While running
{"success": True, "job_id": "...", "status": "running"}
```

`subagent_result(job_id, wait=True)` blocks until done:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# On completion — the subagent's normal result dict is under "result"
{
    "success": True,
    "job_id": "...",
    "status": "completed",
    "result": {"success": True, "output": "...", "agent_name": "...", ...},
}

# On failure
{"success": False, "job_id": "...", "status": "failed", "error": "..."}

# Unknown job_id
{"success": False, "job_id": "...", "error": "Job '...' not found"}
```

<Note>
  Depth (`max_depth`), `allowed_agents`, and per-call `tools` / `llm` / `permission_mode` apply to background subagents identically to synchronous ones. Background jobs run on a worker thread but inherit the same scoping the parent set up.
</Note>

***

## Model Selection

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    subgraph "Model Resolution"
        A[Per-call llm parameter] --> D{Use this model}
        B[default_llm parameter] --> D
        C[Agent default] --> D
    end
    
    classDef priority fill:#10B981,stroke:#7C90A0,color:#fff
    classDef fallback fill:#F59E0B,stroke:#7C90A0,color:#fff
    
    class A priority
    class B,C fallback
```

Model selection priority:

1. **Per-call `llm` parameter** - Highest priority
2. **`default_llm` from tool creation** - Fallback
3. **Agent's default model** - Final fallback

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Set default for all subagents
tool = create_subagent_tool(default_llm="gpt-4o-mini")

# Override for specific call
result = func(task="Complex analysis", llm="gpt-4o")
```

***

## Permission Modes

| Mode                 | Value       | Description                |
| -------------------- | ----------- | -------------------------- |
| `default`            | Standard    | Normal permission checking |
| `accept_edits`       | Auto-accept | Auto-accept file edits     |
| `dont_ask`           | Auto-deny   | Auto-deny all prompts      |
| `bypass_permissions` | Bypass      | Skip all checks            |
| `plan`               | Read-only   | Exploration mode only      |

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Read-only exploration
tool = create_subagent_tool(default_permission_mode="plan")

# Auto-accept for refactoring
result = func(
    task="Refactor the utils module",
    permission_mode="accept_edits"
)
```

***

## Custom Agent Factory

Create agents with custom configurations:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

def my_agent_factory(name, tools=None, llm=None):
    return Agent(
        name=name,
        instructions=f"You are a {name} agent",
        tools=tools or [],
        llm=llm or "gpt-4o-mini"
    )

tool = create_subagent_tool(
    agent_factory=my_agent_factory,
    default_llm="gpt-4o-mini"
)
```

***

## Depth Limiting

Prevent infinite subagent recursion:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Limit to 2 levels of nesting
tool = create_subagent_tool(max_depth=2)

# First subagent can spawn another
# Second subagent cannot spawn more
```

<Warning>
  The default `max_depth=3` prevents runaway subagent spawning. Increase with caution.
</Warning>

***

## Agent Restrictions

Limit which agent types can be spawned:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
tool = create_subagent_tool(
    allowed_agents=["explorer", "reviewer"]
)

# This works
result = func(task="Explore code", agent_name="explorer")

# This fails
result = func(task="Write code", agent_name="coder")
# Returns: {"success": False, "error": "Agent 'coder' not in allowed list"}
```

***

## Result Structure

Synchronous calls (`background=False`, the default) return the final result directly:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
result = func(task="Analyze code")

# Success response
{
    "success": True,
    "output": "Analysis results...",
    "agent_name": "subagent",
    "task": "Analyze code",
    "llm": "gpt-4o-mini",
    "permission_mode": "plan"
}

# Error response
{
    "success": False,
    "error": "Error message",
    "output": None
}
```

Background calls return a handle — see [Background Mode](#background-mode) for `subagent_result` shapes.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use appropriate models">
    Use smaller models like `gpt-4o-mini` for simple tasks and larger models for complex analysis.
  </Accordion>

  <Accordion title="Set permission modes">
    Always set `permission_mode="plan"` for exploration tasks to prevent accidental modifications.
  </Accordion>

  <Accordion title="Limit allowed agents">
    Restrict `allowed_agents` to only the agent types needed for your use case.
  </Accordion>

  <Accordion title="Handle errors">
    Always check `result["success"]` before accessing the output.
  </Accordion>

  <Accordion title="Use background mode for long tasks">
    For test suites, broad scans, or refactors, use `background=True` so the parent agent can keep working and collect results with `subagent_result`.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Subagent Delegation" icon="users" href="/docs/features/subagent-delegation">
    Advanced subagent management
  </Card>

  <Card title="Permission Modes" icon="shield-check" href="/docs/features/permission-modes">
    Permission mode details
  </Card>

  <Card title="JOB_COMPLETED Hook" icon="check-circle" href="/docs/features/job-completed-hook">
    Hook that fires when a background job finishes — success or failure
  </Card>
</CardGroup>
