Skip to main content
Tools are where your agent touches the world — sending an email, writing to a connected system, running code. This page describes the reliability you get for those calls: what runs before a tool fires, the protection against duplicate actions, how failures are handled, and the approval gates in front of destructive actions.

What runs before a tool fires

Every tool — built-in, custom code, MCP, Composio, OpenAPI, GraphQL, and skills — goes through the same checks, in the same order:
  1. Your hooks. pre_tool_call hooks run first and can block the call, rewrite its arguments, or supply the result directly.
  2. Parameter guards. Your tool parameter guards validate and adjust the arguments. A rejected call comes back as a plain-English error the model can fix in the same turn, and values you’ve pinned can’t be overridden by the model or a subscriber. See the Tools page.
  3. Duplicate protection. Actions that change something outside the platform are checked so a retry doesn’t repeat them (below).
  4. Execution, within a time limit.
  5. Your hooks again. post_tool_call hooks run on success and failure and can adjust the result.
Every step is recorded, so a blocked, guarded, or timed-out call is visible in Monitoring with its reason.

Approved actions aren’t repeated

An agent can legitimately re-run a turn — for example when quality regeneration tries again, or when a client re-sends after a network hiccup. Your agent won’t repeat an action that already happened: a send or an external write that already went through returns its recorded result instead of firing again. This protection covers external actions (MCP, Composio, OpenAPI, GraphQL) and the built-in send, delegation, and schedule tools. Read-only tools are never affected.
An agent that appears to “refuse” to send the exact same message twice in quick succession is this protection doing its job — change the content or wait a moment.

Time limits and failures

Every tool call is time-bounded, so no single hung call can hold up a reply.
  • A tool that fails returns its error to the model, which can correct itself within the same turn.
  • A tool that times out is reported to the model as an unknown outcome — the action may still have completed — so the agent verifies or tells the user rather than blindly retrying an action that might have side effects.
  • The agent doesn’t blindly re-run actions. The one retry the platform never makes on its own is re-firing an action that changes the world.
Where retries are safe, they happen automatically: connecting to a tool server, and switching to a backup model when the primary can’t be reached. A model your plan doesn’t allow is swapped for the closest one it does, so a misconfigured model never fails a turn. See How a turn executes for model fallback, and Evaluation and quality for judge-driven regeneration.

No undo on completed actions

Once an external action completes — an email delivered, a connector write committed — there’s no automatic undo. The platform’s effort goes into preventing bad or duplicate actions before they happen: consent gates, duplicate protection, and your hooks and guards. Design flows so irreversible actions happen as late in a turn as possible.

Approval gates and caps

When your agent uses confirm_action, the user sees a confirmation card and their Yes/No is recorded. The follow-up commit_action only succeeds if the user actually confirmed — the model can’t proceed by claiming the user said yes.

Prefilled parameter forms

Eligible tools can show the user a prefilled form to review and complete before the tool runs. On web and widget the user fills in a form; on IM the same flow runs as a short question-and-answer; on API, A2A, and email it’s skipped. The tool runs only after the user submits.

Outbound send caps

Your agent has a shared daily limit across email_send and im_send. Set Max outbound sends per day on the Tools page (0 = unlimited); until you set it, a default of 100/day applies, so a new agent starts capped. The count resets daily. Connected-mailbox tools (gmail_send / outlook_send) aren’t counted — they send from the user’s own mailbox.

Sandboxed code limits

The built-in execute_code tool and your custom code tools run in an isolated sandbox with these limits:
  • 30-second wall-clock timeout per execution
  • ~512 MB memory
  • Up to 50 built-in-tool calls back through the ctx bridge per execution
Each execution is billed individually.