jeevesagent.architecture.supervisor

Supervisor: workers + a delegate tool injected into the loop.

Anthropic Multi-Agent Research System (2026 internal report) + Anthropic Agent Teams (Feb 2026). The 2026 production consensus: hierarchical Supervisor is the multi-agent pattern that earns its cost in production. Anthropic reports +90.2% on their MA research benchmark vs single-agent baseline.

Pattern

The supervisor itself runs an architecture (default ReAct). Its tool host is augmented with one extra tool: delegate(worker, instructions). When the supervising model calls delegate, the named worker Agent runs to completion with the supervisor’s instructions and returns its final answer as the tool result.

Because ReAct’s tool dispatch is already parallel (anyio.create_task_group() over all tool calls in a turn), the supervisor gets parallel delegation for free — emit two delegate calls in one turn and both workers run concurrently.

Replay correctness

Each delegate call is wrapped by runtime.step at the parent’s tool dispatch layer (see ReAct), so the worker’s full RunResult.output is journaled in the parent’s session. Replays return the cached worker output without re-running the worker. The worker is itself an Agent and uses a collision-free session id (parent + worker name + a fresh ULID) when it does run.

Composition

  • Workers can be any architecture themselves (DeepAgent worker for research, ActorCritic worker for code, plain Agent for simple specialists).

  • Workers can be supervisors (nested teams).

  • Wrap Supervisor in Reflexion for cross-session learning of which worker handles which intent best.

Attributes

Classes

Supervisor

Coordinator + workers, glued by a delegate tool.

Module Contents

class jeevesagent.architecture.supervisor.Supervisor(*, workers: dict[str, jeevesagent.agent.api.Agent], base: jeevesagent.architecture.base.Architecture | None = None, instructions_template: str | None = None, delegate_tool_name: str = 'delegate', forward_tool_name: str = 'forward_message')[source]

Coordinator + workers, glued by a delegate tool.

The supervisor’s base architecture (default ReAct) sees a fresh delegate(worker, instructions) tool that routes calls to the named worker Agent. Worker outputs come back as tool results just like any other tool call.

Constructor

  • workers: dict mapping role-names to fully-built Agent instances. Names must be valid identifiers (the model emits them as the worker argument).

  • base: the architecture the supervisor itself runs. Default ReAct. Wrap inside Reflexion to learn delegation patterns across runs.

  • instructions_template: format string with {worker_descriptions}. Default teaches the supervisor to delegate effectively. The agent’s own instructions are prepended (so domain context survives).

  • delegate_tool_name: defaults to "delegate". Customize to avoid clashes with user-defined tools that happen to have the same name.

  • forward_tool_name: defaults to "forward_message". The supervisor calls this with a worker name to return that worker’s last output VERBATIM as the supervisor’s final response. Skips a synthesis round-trip — the `langchain.com/blog/benchmarking-multi-agent-architectures`_ benchmark showed +50% quality on tasks where the supervisor would otherwise paraphrase a worker’s output.

add_worker(name: str, agent: jeevesagent.agent.api.Agent) None[source]

Register a worker between runs.

Safe to call between Agent.run() invocations on the agent that owns this supervisor; the new worker becomes available for delegate(name, ...) on the next run. Calling mid-run is undefined — the supervisor’s prompt is composed at run start.

declared_workers() dict[str, jeevesagent.agent.api.Agent][source]
remove_worker(name: str) jeevesagent.agent.api.Agent | None[source]

Unregister a worker by name. Returns the removed Agent if it was registered, None otherwise. Same lifecycle rules as add_worker().

async run(session: jeevesagent.architecture.base.AgentSession, deps: jeevesagent.architecture.base.Dependencies, prompt: str) collections.abc.AsyncIterator[jeevesagent.core.types.Event][source]
name = 'supervisor'
jeevesagent.architecture.supervisor.DEFAULT_SUPERVISOR_TEMPLATE = Multiline-String
Show Value
"""You are a supervisor coordinating specialist worker agents.

For each task you receive:
1. Decide which workers are needed.
2. Call `delegate(worker, instructions)` to invoke a specialist.
3. Each worker runs independently and returns its final answer.
4. Either synthesize worker outputs into a unified response, OR
   call `forward_message(worker)` if a single worker's output IS
   already the final answer the user wants. Forwarding skips a
   paraphrase round-trip: the worker's output is returned verbatim
   as YOUR final response. End your turn immediately after a
   forward_message call.

You can delegate multiple workers in a single turn — they will run
in parallel. Be specific in the ``instructions`` you pass; workers
do NOT see the user's original message, only what you write.

Available workers:
{worker_descriptions}
"""