Confirmations
A tool that books, sends, pays or cancels should run only after the caller has
said yes to exactly what will happen. Give it confirm: the question read back
to the caller, built from the validated input, in the agent’s language.
Only for such actions. To repeat a name or a number back so the caller can correct
it, say it in the reply: a confirm tool makes the caller’s next turn the answer to
its question, so a caller who simply goes on with the next detail leaves the tool
waiting and unconfirmed.
<Tool
schema={bookSchema}
name="book_meeting"
description="Book the chosen slot."
confirm={(input) => `${input.start} for ${input.email}, is that right?`}
onSubmit={async (input) => ({ ok: true, message: `Booked for ${input.start}.` })}
/>
- The model calls
book_meeting, andonSubmitdoes not run. The input is validated as for any call, the caller hears theconfirmquestion word for word, and the turn ends there. The model’s tool result says that nothing has happened yet. - The caller’s next words are checked against that question with one short
call on the agent’s own LLM, which answers yes, no or unclear:
- Yes:
onSubmitruns and the model answers from its result. The transcript records the call with the words that confirmed it. - No, or a changed detail: nothing runs, and the model is told so. It handles the correction; calling the tool again reads the new details back.
- Unclear, or the check failed: nothing runs, the question stays open, and the model asks once more.
- Yes:
- While the question is open, the model’s context shows
Waiting for the caller to confirm: "…". Calling the tool again replaces the open question; holding anotherconfirmtool does too, and the model is told that the replaced action will not run.
The model cannot run a confirm tool itself: only the caller’s yes on a later
turn does, in preview chat, local voice, hosted calls and tests alike.
- Only words that arrived after the caller heard the question answer it: in chat and tests as soon as it is said, on a call once it played to its end. Input already waiting, and the framework’s silence follow-up, do not; a turn the caller cancels before the question is said asks nothing.
- On a call, a caller who speaks before the question played to its end has not been asked: their words drop it, and the model is told to call the tool again so the whole question is said.
- A yes runs the tool from the skill that asked. If that skill no longer owns the tool’s name, nothing runs and the model is told.
- A step that asks never hangs up: an
end_callin the same step is refused, and its goodbye is not said. - Rewinding, or reopening a stored conversation, to just after the question keeps it open. Rewinding anywhere else drops it.
- A confirmed action is not replayed when a conversation is reopened or rewound; the preview names it as not replayed.
- Limit: when the model writes two or more sentences before the call in the same step, all but the last are said before the question. The tool’s description already tells the model not to claim success, and nothing runs without the yes.
When you write one:
- Name what the caller must check (date, time, email, amount), so that a plain yes means “do exactly this”.
- The question is said word for word. Build it only from the input the tool sends, never from a free-text field the model fills, such as a summary, so the yes approves exactly what runs. A phone number, IBAN or plate the tool sends belongs in its read-back.
- Throw
ToolInputErrorinconfirmto send the model back for better input, for example a slot that cannot be booked. - Do not also ask for the confirmation in your prompt. The model is told that calling the tool asks the caller.
- If
onSubmitfails after the yes ({ ok: false }or a thrown error), the model learns it like any failed tool call. confirmworks on bothonSubmitvariants (schema, or<Field>children), inline or indefineTool.
Next steps
- Testing: keep the confirmation as a scenario.