Delegation turns a sealed XsafAgent into a parent model tool. The child keeps its own configuration, model, resources, and lifecycle.
Seal a child
const researcher = xsaf
.agent({
...researchConfig,
name: "researcher",
description: "Research one focused question",
})
.asAgent();The configured name must be lowercase snake_case and shares the parent’s model-visible namespace with local tools. The description defaults to Delegate a task to <name> when omitted. .asAgent(name, description) remains available as an alpha compatibility override.
Register it on a parent
const parent = xsaf.agent(parentConfig).sandbox(sandbox).delegate(researcher, {
passContext: false,
approval: "human",
});The model sees a tool accepting { prompt: string }. Its derived child session ID is:
<parent-session>:delegate:<delegate-name>Starting the parent starts delegated agents. Stopping it closes them through normal reverse-order lifecycle cleanup.
Context isolation
passContext defaults to false. The child receives the delegated prompt but no parent history, tools, memory driver, sandbox permissions, or channel metadata automatically.
Set passContext: true only when the child needs the parent’s message history:
.delegate(researcher, { passContext: true })The child still uses its own model-visible tools and runtime configuration.
Approval, sandbox, and events
Delegation supports the same approval choices as tools. Execution uses a per-delegate sandbox when configured, otherwise the parent’s default sandbox. A parent containing executable delegates cannot be sealed or started without an applicable explicit sandbox.
The parent emits delegate.started and delegate.completed, both with the delegate name and parent session ID. delegate.completed is emitted even when the child request fails, allowing telemetry to close the span without exposing the delegated prompt.