Handoff
Structured context transfer between agents with validation, compression, and optional persistence.
When agent A finishes its work and agent B needs to continue, a handoff validates what A produced, transforms it into what B expects, and optionally compresses it with an LLM to fit B's token budget.
Stateless handoff
For in-process handoffs where both agents run in the same execution context:
import { } from 'zod'
import { } from '@crux/core'
import { } from '@crux/core/agent'
import { } from '@crux/ai'
const = ({
: 'research-to-writer',
: .({
: .(),
: .(.()),
: .(.({ : .(), : .() })),
}),
: .({
: .(),
: .(.()),
}),
: () => ({
: .,
: .,
}),
: {
: ,
: summaryModel,
: 'Summarize the research findings concisely.',
},
: 'research', // devtools identification
: 'writer',
})
// Prepare the handoff payload
const = await .prepare(researchOutput)
.data.summary // string (if summarize was configured)
// Inject into the receiving agent's prompt
const = ({
: [.asContext()], // priority 80
})The optional summarize config compresses the handoff payload with an LLM to fit the receiving agent's token budget.
Omit it if the payload is already small.
Stored handoff
For distributed agents that run in separate processes, actions, or serverless functions, provide a store to enable send() and receive(). Convex apps use cruxConvexStore() and Crux-aware action boundaries; see the Convex storage and boundary guides for the complete setup.
send() and receive() throw if store is not configured. The stateless prepare() and asContext() work without
a store.
Instrumentation
Handoff events appear in Devtools automatically:
handoff:preparefires withinputSize,outputSize,fromAgent,toAgent, and payload snapshots- Canonical traces also attach the validated handoff input to
inspection.inputand the prepared handoff payload toinspection.output - Events are correlated to the enclosing trace when called within a
generate()or agent step