Agent tools
Tools and agents are part of the flow's definition, not of a call. That way they exist before the first call, and they are versioned with your code.
Declare a tool
tool({ description, input, handler, timeout?, afterSpeech? }):
descriptionandinput(a zod schema, sent as JSON Schema) are what the agent sees, and they are part of the flow version.handler(args, call, ctx)gets the parsed args, the call, andctx.toolCallId,ctx.eventIdandctx.agent({ id, alias }).- Return JSON for the agent, or
handoff(name, data)to end the session.c.connectthen returns withhandoffanddata, and the flow moves the call. afterSpeech: truewaits for the agent to finish speaking before the tool runs, on platforms that support it. Use it for a tool that returnshandoff, so a transfer doesn't cut the agent off.
A tool that returns JSON never runs again, because the agent is waiting on that result. A retried tool call reuses ctx.eventId and gets the first result without running again, on platforms that send a tool call id. ElevenLabs doesn't send one, so a retry there runs the handler again: use something from the arguments to make side effects idempotent.
Bind it to an agent
agents: { alias: agent(id, { tools, variables?, provider? }) }:
c.connect('alias')andc.transfer('alias')connect that agent with its bound tools.agent(id)still works anywhere.toolslists declared tool names, or'all'. Unknown names and aliases are type errors, anddefineCallFlowthrows on them.- The code after
c.connecthandles the end of the session.
What a deploy does
PUT /v1/flows (hcc deploy, hcc.serve's report or hcc.flows.deploy) checks each bound agent:
- an unknown agent is a 422;
- a binding to an undeclared tool is a 400;
- a disabled agent comes back in
warnings.
Platforms that take tools per call need no sync: the bound tools ride with each conversation.
Platforms that keep tools on the agent (ElevenLabs): when a version becomes active, we sync its bound tools onto the agent.
- We create, update and remove only tools we created. Tools you made yourself are never touched, and a sync fails rather than shadow one of yours with the same name.
- The Agents page shows the status, with "Retry sync" on error.
- The agent holds one tool set, so if live and test bind the same agent, the latest activation wins, with a warning. Use separate agents per environment on these platforms.