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()andsubagentsreplace 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
- Agents: what a deep agent is and how it is authored.
@stackbone/sdkintegration:callDeepAgent()in the full workspace picture.stackbone.connection: the reach-by-id surface for connectors, the closest surviving id-keyed pattern.@stackbone/sdkoverview: the ambientstackbonehandle and the rest of the modules.