Skip to content
Select themeSelect language

Approve or reject agent actions

When an autonomous agent reaches a point it should not pass without a human, it pauses and asks for approval. SupaCloud surfaces that one pending decision as an interactive approval you can answer from any control surface — the web terminal, Telegram, or Discord. The agent stays blocked on exactly that decision until you respond (or its timeout policy resolves it for you).

There are four kinds of approval:

Kind What it is Example
Tool A dangerous tool call the agent wants to run A Bash command, a deploy, a migration
Question An open question the agent asks before continuing “Which environment should I target?”
Visual A before/after screenshot sign-off UI change captured for human review
Model class change The pinned model class ran out and SupaCloud wants to drop to a weaker one “Premium quota exhausted — continue on the standard class?”

Two of them can be raised by SupaCloud itself rather than by the agent: a safety hold (a Tool gate SupaCloud forces after the agent reached for something in the danger set — the run is interrupted and parked) and the model class change above. Both reach your chat with the same card and the same buttons; before, they were visible only in the web UI.

The inbox — one feed over every source that can wait on a human, newest first, with the source filter chips above it.The inbox — one feed over every source that can wait on a human, newest first, with the source filter chips above it.

In the web terminal at /cli, list every paused agent in the active workspace and decide one by its short id.

# List the interactive approvals waiting across the workspace
tool-approvals
# Approve or reject one by its (short) approval id; an optional note
# is passed back to the agent as your reason / answer
approve-tool <id> [note]
reject-tool <id> [note]

The id is resolved by prefix the same way task ids are: a unique prefix decides the gate; an ambiguous or unknown prefix is reported rather than guessed.

You can also list both interactive and workflow approvals together. The filter is a plain word after the command — the same word on every surface:

approvals # both sources, each under its own heading
approvals all # the same thing, stated explicitly
approvals tool # only the interactive tool/question/visual/model-class gates
approvals workflow # only workflow human-gates

The bare command answers the whole question, so all is never something you must type. A word the command does not know (approvals wokflow) is reported as unknown rather than quietly listing half the gates. The web terminal additionally accepts the older --filter=<word> spelling, so approvals --filter=tool is the same command as approvals tool.

When a task you own pauses, SupaCloud posts an approval card to your linked chat — one message with the kind, the task title, the redacted detail, any before/after image previews, a direct link to the task, and inline Approve / Reject buttons. Tap a button to decide; you never type an id.

For a tool gate the card leads with the agent’s intent — the tool call’s own description, or the safety reason that held the run — then shows the actual command in monospace. A shell command whose every part only reads carries a small reads only chip as orientation; the raw call payload stays one tap away in a collapsed quote. After you decide, the card keeps the request visible and appends your verdict beneath it, so the chat history still says what was allowed or denied.

If the agent asks something that is not a gate — an open question mid-run — the push carries the question itself and a Reply button. Press it and simply type your answer: it is routed to that exact task, because the button carries the task reference. /intervene <id> <message> still works for scripts and automation, but it is no longer the only way to answer from a phone.

  • A paused task pushes the card automatically to the chat linked to the task owner. Tap Approve or Reject; the bot replies with a confirmation.

  • To review what is waiting at any time:

    /approvals # both human-gate and interactive approvals
    /approvals all # the same thing, stated explicitly
    /approvals tool # only the interactive tool/question/visual/model-class gates
    /approvals workflow # only workflow human-gates

A visual approval is a sign-off on a UI change. The card carries:

  • The before/after screenshots as signed, time-limited image links (Telegram previews them, Discord embeds them; in the web terminal they print as URLs).
  • The machine judge verdict when one ran — PASS, FAIL, or not run — human review — followed by the reasons the judge gave, so you can see why the automated check thinks the change passes or fails before you decide.

If the screenshot links cannot be built (the capture-serve secret is unset) the card degrades to text-only: it still lists what was captured and the judge verdict, so you can always make a decision.

Every approval carries a timeout policy that decides what happens if no human responds:

Policy Behaviour Used for
Hold Blocks forever until a human decides — never auto-resolved Deploys, migrations, and any action forced to wait on a human
Deny Auto-denied after a deadline so the agent continues without the action Optional questions and lower-risk gates

The deny deadlines are per kind: a tool waits 5 minutes, a question 30 minutes, and a visual sign-off 1 hour. When a deny gate times out the agent is unblocked with a denial and continues; a hold gate simply waits.

A safety hold always stops the agent from getting past the flagged action, but whether deciding it can resume that run depends on the agent — and, for two of them, on how that particular run was launched. The card says which case you are in, in square brackets after the danger reason. Read it before you decide:

What the card adds What actually happened Your next move
nothing The agent paused and is waiting for you Approve or reject — the run carries straight on
not resumable … restart the task The agent was stopped, not paused Decide the gate to record your verdict, then restart the task
not enforced … the run was NOT stopped The interrupt reached nothing; the run is still executing Cancel the task if it must stop
soft hold … deliberately NOT stopped SupaCloud asked without stopping, because the only stop available would have killed a healthy run. The chat card is headed Agent keeps running (not paused) and offers only Allow / Deny — no always rules, because there is nothing to allow Allow dismisses the hold and changes nothing else; Deny cancels the task

A card whose gate was settled somewhere else — on the web inbox, on the other chat surface, by the coordinator, or because the agent ended before anyone decided — is edited in place: the buttons disappear and a line underneath says what happened (decided elsewhere, no longer applies, timed out). A card that still shows buttons is a gate that is still open.

Two agents answer differently from one run to the next, so the same agent name is not a reliable guide:

  • Gemini pauses when the run uses an API key, and is stopped when it signs in with Google OAuth — an OAuth run is driven by the agy command-line tool, which the interrupt can only kill.
  • opencode pauses when the run has interactive approvals armed, and is stopped otherwise.

Where SupaCloud cannot tell which of the two a run took, the card says so (cannot confirm …) and assumes the run was stopped. It never promises you a resumption it has not verified — so a hold that says restart the task may occasionally be a run that could in fact have been resumed, never the other way round.