Skip to main content

Agent node - capabilities

What an Agent node has at its disposal: the tools it can call, the rich media it can show, and the variables it can read and write.

Nothing you change in the drawer is committed until you press Save; Cancel discards the lot.

Capabilities

Tools, Rich media and Allowed variables sit together in one panel in the drawer, because they answer the same question: what does this step have at its disposal? Each is covered in full below.

One rule applies to all three: attach only what this step needs. A node with one tool and two variables is predictable. A node carrying everything the assistant can do is slower, costs more per turn, and picks wrong more often. They're shared definitions, so attaching the same tool to five nodes is free and correct - never widen one node so it can serve several steps.


Tools

Workflows and tools this agent can call.

The actions this step is allowed to take: run a workflow, search a knowledge base, escalate to a human. Tools are defined once under AI Agent → Tools; here you pick which of them this step can reach, with + Add tool.

What attaching actually does

Four things, and only the first is obvious:

  1. It puts the tool within reach for this step. While this node holds the conversation, these are the tools on offer. When the flow moves on, they're withdrawn and the next node's set takes over - a tool attached here is not available two nodes later.
  2. It makes the tool @-mentionable in the Instructions.
  3. It makes the tool eligible as a Tool exit. The exits picker only offers tools attached to this node.
  4. It does not make the tool run. Nothing here causes a call. The agent decides, based on your Instructions and the tool's own description.

That last point is the one to internalise. Attaching is a grant; the Instructions are the trigger. They're two separate decisions, and a tool attached but never mentioned is a coin flip - it may fire at the wrong moment, or never.

If a tool must always run, say so plainly: "Always call @Check Eligibility before answering."

Some tools may be published to every agent centrally, so a node can have a few beyond the ones you attached here. If an agent is calling something you didn't add, that's where to look.

Per-tool settings

Each attached tool has its own configuration, opened from its row:

SettingWhat it does
Inputs mappingSupplies the tool's inputs - from a variable, from the session, or a fixed value. A workflow with no declared inputs has nothing to map, and the panel tells you so.
Store output inWrites the tool's result into a variable instead of handing the payload back to the agent.
AcknowledgementWhat the customer hears while the tool runs. Either intelligent (generated to fit the moment) or a static list you write.
Fallback settingsWhat happens if the tool fails: send an AI-powered apology, and optionally raise a ticket.

Store output in deserves attention, because it's the one that changes behaviour most and is easiest to miss.

By default a tool's result goes back to the agent, which reads it and decides what to say. That's right when the result is small and the agent needs to reason about it - an eligibility flag, a balance, a yes/no.

It's wrong when the result is a large payload. The agent then has a wall of JSON in its context: it costs more, it distracts from the procedure, and it invites the agent to narrate raw fields at the customer. Storing the output instead writes it to a variable, hands the agent a short confirmation, and leaves the value available to the rest of the flow.

Acknowledgement is about perceived latency. A tool that takes three seconds feels broken in silence and fine with "Let me check that for you". This matters most on voice, where dead air has no spinner to explain it.

What happens when a tool fails

A tool failure does not send the flow down on_error. This is the most consequential thing on this page after the empty-Instructions trap.

What actually happens: the agent is told the call failed and carries on. It can retry, take a different route, or tell the customer - and it's instructed never to read raw error text aloud. With Send AI-powered apology enabled it also sends a contextual apology automatically ("Sorry, I'm having trouble fetching plans right now"), and the error policy can raise a ticket instead.

The consequence for you: your Instructions decide the recovery. If a failed tool ought to end the step, you have to write that - add a branch and say when to take it. Left unwritten, the agent improvises, and the flow carries on as though nothing happened.

Call @Check Return Eligibility with the order ID.

If the tool fails or returns nothing, apologise briefly and finish on
`system_unavailable`. Do not guess whether the order is eligible.

Good use

PatternWhy it works
One tool, @-mentioned, with a stated trigger - "Always call @Check Eligibility before answering"The grant and the trigger both exist. No ambiguity about when.
A big lookup with Store output in set, and a later node reading the variableKeeps the payload out of the conversation and passes the value on properly.
The escalation tool attached and wired as a Tool exitThe action and the outcome are the same event, so the exit carries the flow onward.
An acknowledgement on anything slowCovers the wait. Essential on voice.
Explicit ordering in the Instructions when two tools must run in sequenceTool descriptions don't convey order. Your numbered steps do.

Problems

PatternWhat goes wrong
Attaching every available toolMore options means worse selection. The agent picks the wrong one, the prompt is longer, and every turn costs more.
Attaching a tool and never mentioning itIt may fire at the wrong moment or never fire at all. Nothing warns you.
Mentioning a tool you haven't attachedThe reference doesn't resolve, and the agent is left with a fragment it can't act on.
Expecting a failed tool to take on_errorIt doesn't. The agent continues. Write the failure path yourself.
Letting a large payload back into the conversationThe agent reads out fields, or paraphrases them wrongly. Use Store output in.
Two tools that do nearly the same thingThe agent chooses between them inconsistently, and the behaviour looks random. Attach one.
Assuming the tool description conveys sequencingIt describes what the tool is for, not when it runs relative to another. Put the order in the Instructions.

How to think about it

Grant and trigger are separate decisions. Attaching answers "may it?"; the Instructions answer "when?". Almost every tool problem is one of those two missing.

Attach the fewest tools that make the step possible. Not the fewest that make it convenient - a tool the step could theoretically use is a tool it can misuse.

Decide who the result is for. If the agent needs to reason about it, let it come back. If the flow needs it - a later node, a condition, a record - store it in a variable.

A tool that ends the step is an exit, not just a tool. If calling it means this step is over, make it a Tool exit so the flow moves on properly rather than leaving the agent to work out that it's finished.

Write the failure path. The happy path is easy to imagine and easy to test. The tool-is-down path is neither, and it's the one that will page you.


Rich media

Quick replies, widgets and workflows the agent can show.

The visual elements this step can put in the chat instead of plain text - tappable options, a card or carousel, a formatted response.

The three kinds

KindWhat it isHow many
Quick repliesTappable option buttons alongside a message.Once per node
WidgetA saved widget - cards, carousels, formatted layouts. You give each one a description telling the agent when to use it.As many as you need
WorkflowA workflow that builds a rich response.As many as you need

What attaching actually does

The same grant-not-trigger rule as Tools, with one extra consequence that catches people out:

  1. It makes the element available to this step, and @-mentionable in the Instructions. It doesn't make it appear - the agent shows it when your Instructions say to.
  2. Showing rich media ends the turn. The agent displays the element and stops - it doesn't display buttons and then carry on talking, and it won't take an exit in the same breath. The node hands back and waits for the user. This is almost always what you want (you're offering a choice, so you want the choice made) but it does mean "show the options and then confirm and finish" can't happen in one turn.

Where the content comes from

This is the part that surprises people, and it differs from First response.

You don't type quick-reply options into this panel. Attaching Quick replies grants the ability to show buttons; the actual options are supplied by the agent at the moment it shows them - and it's explicitly constrained to use only options that came from your Instructions or from a tool result. It must not make them up.

So the options live in your Instructions:

Ask which size they'd like and offer @Quick Replies with exactly these
options: Small, Medium, Large, Extra Large.

Attach the capability, then say what goes in it. Attaching Quick replies and writing only "offer some quick replies" leaves the agent with nothing legitimate to render - and inconsistent buttons between runs is the symptom.

For widgets, the equivalent lever is the description you write when attaching. That description is what the agent reads to decide whether this widget fits the moment, so "the order summary card, showing line items and total" works and "card" does not.

Compare with First response, where you do type the options into the UI - because that message is scripted and never involves the agent. Same buttons, opposite authoring model.

On voice, this does nothing

Rich media is skipped entirely on voice calls - there's no screen to render it on. A voice step built around tappable options doesn't fail loudly, it just talks.

If a flow serves both chat and voice, write instructions that stand on their own without the buttons - "ask which size they'd like: small, medium, large or extra large, and offer @Quick Replies". The chat customer taps; the voice caller hears the options and answers. One set of instructions, both channels.

Good use

PatternWhy it works
Quick replies for a closed set of choices, with the options listed in the InstructionsThe agent has a legitimate source for the buttons, so they're identical every run.
Quick replies whose options come from a tool result - available appointment slots, the customer's ordersGenuinely dynamic buttons, still not invented.
A widget with a description that says when to use it, not just what it isDescription is the whole selection signal.
Wording that works spoken as well as tappedSurvives the voice channel.
Offering options at a decision point that maps to your exitsThe taps line up with the branches, so routing gets easier and more accurate.

Problems

PatternWhat goes wrong
Attaching quick replies, never listing the optionsNothing legitimate to show. Buttons vary run to run, or don't appear.
Expecting the agent to keep talking after showing rich mediaIt won't - the turn ends there. Say what you need said in the same message as the buttons.
Designing a voice step around quick repliesSilently degrades to plain speech. Nothing in the drawer warns you.
A widget described as card or infoThe agent has no basis to pick it, so it picks badly or not at all.
Long button labelsTrimmed at 40 characters. Write short ones rather than discovering the cut.
Attaching a widget but never mentioning itSame as an unmentioned tool - it may never be shown.
Options that don't match your exitsThe customer taps "Speak to an agent" and the node has no branch for it.

How to think about it

Attach the capability, author the content. The panel grants; the Instructions supply. Every quick-replies problem is one of those two halves missing.

Rich media is a turn-ender, so put it where the conversation should pause. It fits a question that needs an answer, not a mid-turn flourish.

Make the options and the exits match. If you offer four buttons, the node should be able to handle all four outcomes. Buttons that lead nowhere are worse than no buttons - the customer picked something and the flow ignored it.

Write for the channel that can't see it. Instructions that read fine aloud work everywhere; instructions that depend on buttons work in one place.

Allowed variables

Context the agent can read. Make a variable writable to let the agent fill it during the conversation.

This is an allowlist. A variable existing in the conversation does not mean this step can see it - if it isn't in this list, the agent has no idea it exists. The panel says as much: "This agent can only read the variables and user properties you add here."

The two states

Every variable you add sits in one of two states, shown as a badge on its chip:

BadgeWhat the agent can doToggle
Read-onlySee the current value and use it in its reasoning and replies.The agent reads this value.
Agent fills thisSee it and set it from the conversation. The value goes back to the flow when the step ends.Let the agent set this too

Read-only is the default, and most attached variables should stay that way. The writable ones are the point of the step - what it's there to collect.

Read-only is not "the agent will fill it anyway"

Adding a variable and leaving it read-only, while expecting the agent to populate it, is the most common mistake on this panel. Nothing is written, no error appears, and the variable is simply empty when a later node reads it. The symptom shows up somewhere else entirely - a downstream condition that never matches, or a message with a blank in it.

If this step is meant to capture something, the variable needs Agent fills this turned on. Read-only means read-only.

What has to be true before a variable can be writable

Four gates, each with its own message in the UI when it blocks you:

RequirementWhyIf it's not met
It has a descriptionThe description is the agent's only guidance for what to put in the slot - the drawer asks you to "Describe this variable for the agent" before it will let you.You're prompted to write one first
A fillable typeText, number, yes/no, and list."Only text, number, yes/no and list variables can be filled by the agent"
A fillable scopeGlobal and journey variables only - user properties are a customer's profile, and a step doesn't rewrite those."The agent can only fill in global and journey variables."
Under the limitFive writable variables per node."Write limit of 5 reached"

That scope row is a decision, not just a constraint. The picker lists globals, journey variables and user properties together, each tagged with its scope, and which one you attach decides who sees the value afterwards: a global reaches every other agent, a journey variable dies with this flow run. If a later agent needs what this step collects, it has to be global - see which scope it belongs in.

The description requirement is worth dwelling on. It isn't paperwork - it's the entire instruction the agent gets about that slot. postcode tells it nothing; "the customer's delivery postcode, UK format, e.g. SW1A 1AA" tells it what counts as valid, what shape to store, and when it's got one.

Writable is a slot, not a promise

Marking a variable writable gives the agent permission and a place to put a value. It does not guarantee a value arrives. If the conversation never surfaces the postcode, the variable stays empty and the step can still exit.

So if a value is required before moving on, that belongs in your Instructions - "Do not finish until you have their postcode; if they won't give one after three attempts, finish on max_retry." The panel grants; the Instructions insist.

Three ways a value gets written - pick the right one

Much of the confusion here is the write toggle being asked to do jobs that belong elsewhere:

To capture…UseConfigured on
Something the customer saidAgent fills thisThis panel
A tool's resultStore output inThe tool's own settings (Tools)
Something derived after the turnA workflow that writes a variableLifecycle Hooks

If you're trying to save what an API returned, the write toggle is the wrong lever - that's Store output in on the tool.

Scopes

The picker groups variables by where they live:

ScopeLifetimeWritable by the agent
JourneyThis flow runYes
GlobalThe wider conversation and customer memoryYes
UserThe customer's profile propertiesNo - read-only

Example

An address-collection node:

VariableStateWhy
customer_nameRead-onlySo it can address the customer properly. Nothing here sets it.
shipping_addressAgent fills thisThe thing this step exists to collect. Described as "the full delivery address including postcode".
delivery_countryAgent fills thisNeeded by the eligibility check two nodes later.
account_tierRead-onlyChanges the wording for premium customers. The step has no business editing it.

Problems

PatternWhat goes wrong
Left read-only, expected to be filledNothing is written. Silent, and the symptom appears in a later node.
Not attached at allThe agent can't see the value even though it exists, and will ask for something it was already told.
Writable with a vague descriptionThe agent fills the slot with something loosely related. Worse than empty, because it looks fine.
Using the write toggle for a tool resultWrong mechanism - see Store output in.
Everything marked writableYou'll hit the five-variable limit, and each extra slot is another thing the agent can fill wrongly.
Treating writable as guaranteedIt's permission, not enforcement. Requiring a value is a job for the Instructions.
Re-collecting a value a previous node already wroteAttach it read-only instead. Asking twice reads as not listening.

How to think about it

Attach what the step must know; make writable what the step must learn. Two different questions, asked in the same panel, and worth answering separately.

Write the description for someone who can't see your flow. The agent has your description and nothing else to go on for that slot.

Pass decisions forward. If this node worked out return vs exchange, store it. A later node re-deriving it will sometimes disagree with this one.

Keep the writable set small on purpose. The limit is five, but two is a healthy node. A step collecting five separate things is usually several steps.

Variables and exits - which one do I want?

These two get conflated constantly, because both feel like "the output of the step". They do completely different jobs.

ExitVariable
AnswersWhere does the conversation go next?What does the rest of the flow know?
How many per stepExactly one, when the step finishesNone to five, during the step
Shows on the canvasYes - it's a branch you wireNo
Affects routingThat's its only jobNever

They aren't alternatives. Most collect steps want both: write shipping_address, and finish on collected. Reaching for one instead of the other is where it goes wrong.

The test:

  • Does the next step differ depending on the answer? → that's an exit.
  • Does anything later need the value? → that's a variable.
  • Both? → do both. That's normal.

The trap: exits used as data. A node collecting a country with exits uk, us, france, germany, spain. It reads naturally and it's wrong: you hit the five-branch ceiling immediately, the canvas becomes unreadable, and adding a country means editing the flow. If every branch would go to the same next node, they aren't outcomes - they're a value. Use one variable and one exit.

Flip it round and the same rule holds: if the branches genuinely go to different places, they are outcomes, and burying them in a variable to fork later hides your routing from the canvas.

Worth knowing: the exit a node takes decides the edge and nothing more - it isn't readable later as a value. So if a downstream step needs to know which way this node went, write that decision to a variable as well as exiting on it. This is the clearest case where you genuinely need both.