Named Agent Delegation

Let a running agent delegate to your named .praisonai/agents by name — no Python

A running agent can delegate sub-tasks to your own named agents in .praisonai/agents/*.md — by name, mid-run, with no Python.

bash
# .praisonai/agents/researcher.md carries `mode: subagent`
praisonai run --agent lead "Draft a market brief on WebAssembly adoption"
markdown
<!-- .praisonai/agents/lead.md -->
---
model: gpt-4o
role: Team Lead
goal: Coordinate research and review, then write the final brief
---
You lead a small team. Delegate research and review to your teammates, then synthesise the result.
markdown
<!-- .praisonai/agents/researcher.md -->
---
model: gpt-4o-mini
role: Research Specialist
goal: Gather accurate, cited facts on a topic
mode: subagent
tools:
  - web_search
---
You are a meticulous researcher. Provide concise, cited findings.
markdown
<!-- .praisonai/agents/reviewer.md -->
---
model: gpt-4o
role: Editorial Reviewer
goal: Check drafts for accuracy and clarity
mode: subagent
---
You review drafts for accuracy, tone, and clarity. Suggest concrete edits.

Prefer to opt agents in per run instead of editing frontmatter? Use the --subagents allow-list:

bash
praisonai run --agent lead --subagents researcher,reviewer "Draft and review a market brief on X"
Diagram

👤 User

🤖 Lead agent

🔧 spawn_subagent
agent_name=researcher

🔎 Resolver
.praisonai/agents/researcher.md

📄 Researcher
own model / tools / permissions

A primary agent assembles a team: it hands specific sub-tasks to specific named agents (researcher, coder, reviewer, …) that already live in .praisonai/agents/*.md. Unlike a generic spawn_subagent — which spins up an anonymous scoped worker — the delegatee here is a user-authored profile with its own model, tools, and permissions.

Quick Start

  1. Mark an agent as delegatable

    Add mode: subagent to any agent’s frontmatter. The agent’s author opts it in once, and every run can delegate to it.

    markdown
    <!-- .praisonai/agents/researcher.md -->
    ---
    model: gpt-4o-mini
    role: Research Specialist
    mode: subagent
    ---
    You are a meticulous researcher.
  2. Or opt agents in from the CLI

    Pass --subagents to expose exact agents for a single run, no frontmatter changes required.

    bash
    praisonai run --agent lead --subagents researcher,reviewer "Write a brief on X"
  3. Run the primary agent
    bash
    praisonai run --agent lead "Draft a market brief on WebAssembly adoption"

    The lead agent calls spawn_subagent(agent_name="researcher"), the resolver loads researcher.md, and the researcher runs under its own model, tools, and permissions.

How It Works

The primary agent picks a teammate by name; a resolver instantiates that agent from its Markdown definition and runs the sub-task.

Diagram
sequenceDiagram
    participant User
    participant Primary as Primary Agent
    participant Tool as spawn_subagent
    participant Resolver as agent_resolver
    participant Named as Named Agent

    User->>Primary: "Draft and review a brief on X"
    Primary->>Tool: spawn_subagent(agent_name="researcher", task="...")
    Tool->>Resolver: resolve("researcher")
    Resolver->>Named: instantiate from .praisonai/agents/researcher.md
    Named->>Named: .chat(prompt) under own model/tools/permissions
    Named-->>Tool: result
    Tool-->>Primary: {output, agent_name: "researcher"}
    Primary-->>User: final brief

    classDef user fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef named fill:#10B981,stroke:#7C90A0,color:#fff

    class User user
    class Primary agent
    class Tool,Resolver tool
    class Named named

How delegation is chosen

Which agents become delegation targets depends on whether --subagents is set.

Diagram

Yes

No

Yes

No

–subagents a,b,c passed?

Expose exactly those named agents
marker ignored

Any agent has
mode: subagent?

Expose all marked agents

No tool attached
run unchanged

  • Explicit --subagents a,b,c wins — any named agent can be opted in, ignoring mode:.
  • Otherwise every agent whose frontmatter has mode: subagent is exposed.
  • If neither yields anything, no spawn_subagent tool is attached — the run behaves exactly as before (backward compatible).

Two ways to opt agents in

Choose per-agent frontmatter for stable teammates, or the CLI flag for ad-hoc runs.

Diagram

Stable teammate,
opt in once

One-off run,
no file edits

How should this agent
become delegatable?

Add mode: subagent
to frontmatter

Pass –subagents a,b,c

Exposed on every run

Exposed for this run only

RouteSet whereScopeBest for
mode: subagentAgent frontmatterEvery runStable teammates you always want available
--subagents a,b,cCLI flagSingle runAd-hoc delegation without editing files

When --subagents is passed, those exact names are exposed regardless of mode. When it is omitted, every agent whose frontmatter has mode: subagent is exposed. If neither yields any agent, the spawn_subagent tool is not wired at all and the run is identical to before.

What the delegated agent inherits

Each named agent runs under its own model, tools, and permissions from its frontmatter. The primary agent does not override them.

Generic spawn_subagentNamed agent delegation
Parent chooses the model, tools, and permission mode per callEach named agent brings its own model, tools, and permissions
Spawns a generic workerRuns your pre-defined .praisonai/agents/*.md agent

A named agent’s mode: subagent marker never changes its permissions — it only marks the agent as delegatable (see Delegatability vs permissions).

How the model discovers them

The tool description lists each delegatable agent so the primary model can pick one by purpose:

You can delegate to these named agents by passing their name as agent_name
(each runs under its own model/tools/permissions):
- researcher: Gather accurate, cited facts on a topic
- reviewer: Check drafts for accuracy and clarity

Each line’s text is the agent’s description, falling back to goal, then role, then an empty string when none is set. Give every delegatable agent a clear goal or description so the primary model chooses the right teammate.

Fallback behaviour

Delegation is purely additive — nothing changes when there is nothing to delegate to.

  • Unknown name: if agent_name targets a name the resolver cannot find, the resolver returns None and the existing generic-spawn path runs instead.
  • No delegatable agents: if no agent is marked mode: subagent and --subagents is omitted, the spawn_subagent tool is not wired at all — the run is byte-identical to before.

Delegatability vs permissions

mode: subagent is a delegatability marker, not a permission mode. It is ignored (case-insensitive) when computing permissions, so it is never rejected as an unknown mode. Any other mode value — read-only, plan, accept-edits — still flows through the permission engine as before. See Custom Agents & Commands for the full mode reference.

markdown
---
name: reviewer
model: gpt-4o-mini
mode: read-only
permission:
  bash:
    "git *": ask
    "*": deny
---
You are a meticulous code reviewer.
bash
# read-only agents are opted in explicitly since they lack the subagent marker
praisonai run --agent lead --subagents researcher,reviewer "Draft and review a script"

Configuration Options

OptionTypeDefaultDescription
agent_resolverCallable[[str], Agent]NoneSDK callback that returns a ready-to-run Agent for a name. When a passed agent_name resolves, that named agent runs the sub-task under its own model/tools/permissions. None preserves generic-spawn behaviour.
resolvable_agentsDict[str, str]NoneSDK {name: description} map of delegatable agents; each entry enriches the tool description so the model can pick one.
--subagentsCLI flag—Comma-separated named agents (.praisonai/agents/*.md) the running agent may delegate to. Omit to expose agents marked mode: subagent.

--subagents CLI flag

FlagValueBehaviour
--subagents a,b,ccomma-separated namesExplicit allow-list — takes precedence over mode: subagent. Any named agent can be opted in.
--subagents omitted—Every .praisonai/agents/*.md with mode: subagent is exposed.
No delegatable agents at all—No tool attached; the run is unchanged.

Result shape

When the resolver runs a named agent, spawn_subagent returns:

python
{
    "success": True,
    "output": "...",             # named agent's chat() result
    "agent_name": "researcher",  # the resolved name
    "task": "...",
    "llm": "...",                # resolved from the tool's effective llm
    "permission_mode": "...",
}

Common Patterns

Researcher + Reviewer

A lead delegates to two teammates marked mode: subagent:

bash
praisonai run --agent lead "Draft and review a launch brief for our new API"

The lead calls spawn_subagent(agent_name="researcher") and spawn_subagent(agent_name="reviewer"), each running under its own frontmatter.

One-off CLI allow-list

Expose agents for a single run without touching any frontmatter:

bash
praisonai run --agent lead --subagents researcher,reviewer "Quick competitive scan on X"

Mixing markers + override

Some agents carry mode: subagent, but --subagents takes precedence for this run — only the named agents are exposed:

bash
# Only editor is delegatable this run, even if others carry mode: subagent
praisonai run --agent lead --subagents editor "Polish the final draft"

Python-side wiring

For advanced SDK use without the CLI:

python
from praisonaiagents import Agent
from praisonaiagents.tools.subagent_tool import create_subagent_tool
from praisonai_code.cli.features.custom_definitions import build_subagent_resolver

resolver, descriptions = build_subagent_resolver(["researcher", "coder"])

lead = Agent(
    name="Lead",
    instructions="Delegate research/coding to the named subagents.",
    tools=[create_subagent_tool(
        agent_resolver=resolver,
        allowed_agents=list(descriptions.keys()),
        resolvable_agents=descriptions,
    )],
)

lead.start("Draft an evaluation script for 3 vector DBs")

Best Practices

Prefer mode: subagent for stable teammates, –subagents for ad-hoc runs

Mark agents you always want available with mode: subagent and commit them to git. Reach for --subagents when you need a one-off delegation without editing files.

Give each named agent a clear description or goal

The primary model picks teammates by their description (falling back to goal, then role). A vague goal makes the model guess; a specific one routes the right sub-task to the right agent.

Keep the primary agent's tools narrow

Put heavy tools on the delegated agents and keep the primary agent focused on coordination.

Use permission blocks to sandbox delegated agents

Each named agent runs under its own permissions. Add a permission: block (or a mode: like read-only) to a delegated agent to sandbox its side-effects independently of the primary agent.

Keep delegation shallow

A delegated agent chatting to finish its sub-task is fine. Nested delegation — a delegated agent delegating again — is not part of this feature; design flat teams with a single coordinating agent.


Related