Calling a sibling agent

Status: retired. The earlier stackbone.agent(name) surface addressed a sibling agent by name and opened a signed, multi-turn session against it. That surface is gone: there is no more session, no continuation cursor, no streaming handle to call another agent this way. callDeepAgent() and subagents replace it.

A workspace can hold several agents. Two surfaces let one agent's work reach another.

From a workflow step: callDeepAgent()

callDeepAgent(name, input) from @stackbone/sdk/workflow runs one turn of another agent in your workspace, in-process, and resolves with its reply. Call it from inside a 'use step' function so the turn becomes a durable checkpoint:

import { callDeepAgent } from '@stackbone/sdk/workflow';

async function askSupport(plan: string) {
  'use step';
  const { text } = await callDeepAgent(
    'support',
    `A customer joined the "${plan}" plan. Give up to 3 onboarding tips.`,
  );
  return text;
}

input is either a non-empty string (one user message, the common case) or a { messages } history when you want to hand the agent more than one turn of context:

const { text } = await callDeepAgent('support', {
  messages: [
    { role: 'system', content: 'Answer in one paragraph.' },
    { role: 'user', content: 'What does the Pro plan include?' },
  ],
});

Each message needs a role of system, user or assistant and non-empty content. Anything else throws before the turn starts, which fails the step.

There is no session object and no cursor to persist: each call is one self-contained turn. If a workflow needs a back-and-forth exchange with an agent, model that as several steps, each calling callDeepAgent() with the context it needs.

See Calling an agent from a workflow for the full contract, including the durability trade-off (a crash mid-turn re-runs the whole turn, so keep the agent's tools idempotent).

streamDeepAgent(name, input), from the same import, is the streaming twin: the same one-turn contract and the same { text } result, but the reply also streams live into the run's chat surface. See Workflow agents.

Within one agent: subagents

Pass subagents to defineDeepAgent(...) when the delegation should happen inside a single agent's own reasoning rather than from a workflow:

import { defineDeepAgent } from '@stackbone/sdk/deep';

export default defineDeepAgent({
  name: 'triage',
  model: 'anthropic/claude-haiku-4.5',
  subagents: [
    {
      name: 'billing',
      description: 'Answers billing and invoice questions.',
      tools: [
        /* the LangChain tools this specialist may use */
      ],
    },
  ],
});

A subagent declares its name and a model-facing description: that description is what the parent model reads when it decides to delegate. Its brief is a prompt in the catalogue owned by the parent agent and keyed by the subagent's name, so two agents can each have a billing subagent with different briefs. Point it at another key, or hand it values to render, with instructions: { key, variables }.

@stackbone/sdk/deep also ships one ready-made subagent. browserSubagent() attaches a web-browsing specialist in one line, with the six browser tools and nothing else. It carries its own text and never appears in the catalogue. See Browser tools.

A subagent lives inside the same graph as its parent and is not a separate top-level agent a chat client can address by model. Use it when you want the model itself to decide when to delegate a sub-task, and callDeepAgent() when a workflow needs to hand work to a top-level agent.

Where to go next

BUILT WITH ❤️ FROM CANADA AND SPAIN