Skip to content

Confirm words

A tool that asks can have confirm(input). It returns what’s about to happen, in words a person would use, for the approval card.

media_request: {
access: 'control',
label: 'Requested a title',
input: z.object({ id: z.number() }),
description: 'Ask for a film or show to be added.',
confirm: async ({ id }) => {
const t = await lookup(id);
return { title: `Request ${t.title}?`, detail: t.year, image: ctx.image(t.poster), verb: 'Request' };
},
async run({ id }) { /* ... */ },
},
An approval card with a title, a detail line, Not now and a button named for the action
The title, a line of detail, and a button that says what it does.
FieldWhat it does
titleThe question: Stop Sam's stream?
detailOne more line: The downloaded files are kept.
verbThe button’s word: Stop, Pause, Request. Allow by default.
dangerA red button.
imageArtwork, such as a poster.
iconAn icon by name.
logoThe app’s icon. Valet fills this in from the integration’s type.

With no confirm, the card says “Allow this:” and the tool’s label, and lists the input.

  • It may look things up, and must never change them. It runs before you’ve agreed to anything, and it can run more than once.
  • Show what the service says, not what the model typed. If the model passes an id, look the title up. Then the card shows what will really happen. This is the point of confirm: a model can get an id wrong, and a card that repeats its words wouldn’t show that.
  • Write a question. Say the thing and the outcome in plain words.
  • Name the button after the action. Pause is better than OK.
  • Say what it leaves alone. qBittorrent’s remove says The downloaded files are kept.
  • Use danger sparingly. Only for what’s hard to take back. If everything’s red, nothing is.

If confirm throws, the card falls back to the plain form, and the tool still asks. The card’s text goes through the redactor.

Tooltitleverbdanger
Pi-hole, adblock_pausePause ad blocking for 5 minutes?Pauseno
qBittorrent, pause_downloadsPause all downloads?Pauseno
Sonarr / Radarr, library_searchSearch for The Long Tide?Searchno
Ollama, ollama_unloadUnload llama3.2:8b?Unloadno
Plex (Tautulli), plex_stop_streamStop Sam's stream?Stopyes

Not now and Allow come from labels, as notNow and allow, so they can be translated.

Where a tool can be reversed, name the tool that does it. It’s called with the same input, and adds Undo to the activity log.

pause_downloads: {
access: 'control',
undo: 'resume_downloads',
// ...
},

See undo.