Skip to main content
Programmable Agents can spawn and coordinate other agents, enabling complex multi-agent workflows where each agent has a focused responsibility.

How Delegation Works

An agent with invoke_agent in its tool allowlist can spawn child agents. Each child runs in its own pod and, if a Slack channel is configured, posts to its own thread in that channel. When an orchestrator fans out several issues, each one gets its own session and its own thread instead of stacking updates into the parent’s. To allow delegation, two things must be configured in the parent agent’s YAML:
  1. invoke_agent must be included in tools.list
  2. The child agent name must be listed under agents_squad

Callback / Resume Pattern

For workflows where the parent needs the child’s result before continuing, pass callback_session_id to invoke_agent. The parent pod idles until the child calls notify_parent_session, then wakes up with the child’s output as its next input. The parent does not idle forever: it stays alive up to its inactivity timeout (24 hours) and hard lifetime limit (48 hours). If the child takes longer than that, or fails to call back, the parent shuts down.

Checking on Delegated Agents

Callbacks are a push: the right tool when the parent must act on completion. For questions, the parent can pull instead. The check_delegated_agents tool reports the current state of every agent the session delegated to with invoke_agent: the agent name, session id, run status, and latest output. Use it when someone asks the orchestrator “how are those going” mid-run. It costs nothing until asked, always reflects the present (including children still running), and composes with callbacks: delegate most children fire-and-forget, give one a callback, and pull status when asked.

Limiting Delegation Depth

Depth is implicitly limited by whether invoke_agent appears in a child agent’s allowlist. If the test-maintainer above does not include invoke_agent in its tools, it cannot delegate further: the chain stops there. This is the recommended approach: only give invoke_agent to orchestrator agents, not to leaf agents.

invoke_agent vs run_subagent

Both let an agent hand off work, but they are different mechanisms:
  • invoke_agent spawns a named agent (defined under .dinoai/agents/) in its own pod, running asynchronously with its own tools and Slack thread. Use it for durable, specialized agents and for the callback pattern above.
  • run_subagent runs a lightweight, read-only research task in the same pod, synchronously, and returns its findings inline. It has no YAML definition, no Slack thread, and no callback. Use it for quick lookups where spawning a full agent is overkill.