run-sequence
Run a predefined series of device interactions—tap, swipe, type, press, wait—in a single call to execute multi-step flows sequentially without observing the screen between actions.
Instructions
Execute multiple device interaction steps in a single call (iOS simulator or physical device, Android emulator, Apple TV / Android TV, or Chromium app).
On a physical iOS device only gesture-tap, gesture-swipe, gesture-custom, button, keyboard, and await-ui-element steps run; others fail at their own gate.
Use when you need sequential actions and do NOT need to observe the screen between them
(e.g. scrolling multiple times, typing then pressing enter, rotating back and forth).
Returns { completed, total, steps } with per-step results. Fails if an unrecognised tool name is used in a step (error returned at that step, execution stops).
One screenshot is captured automatically after the whole sequence (not per step) — call screenshot separately only for a baseline BEFORE it, or to observe an intermediate step.
That single capture is also why a secret belongs in this call rather than in two bare ones: the skip is decided from the whole request, so a {{secret:...}} in any step suppresses the capture that would otherwise follow the submit.
ONLY use this when every step is known in advance. If any step depends on the result of a previous one (e.g. tapping a menu item that only appears after a prior tap), use individual tool calls instead.
Allowed tools and their args (udid is auto-injected, do NOT include it in args):
gesture-tap: { x: number, y: number, clickCount?: number } [ios/android/chromium] gesture-swipe: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number, momentum?: boolean } [ios/android] gesture-scroll: { x: number, y: number, deltaX?: number, deltaY?: number, durationMs?: number } [chromium only] gesture-drag: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number, momentum?: boolean } [chromium only] gesture-custom: { events: [{ type: "Down"|"Move"|"Up", x: number, y: number, x2?: number, y2?: number, delayMs?: number }], interpolate?: number } [ios/android] gesture-pinch: { centerX: number, centerY: number, startDistance: number, endDistance: number, endCenterX?: number, endCenterY?: number, angle?: number, durationMs?: number } [ios/android] gesture-rotate: { centerX: number, centerY: number, radius?: number, radiusX?: number, radiusY?: number, startAngle: number, endAngle: number, durationMs?: number } [ios/android] button: { button: "home"|"back"|"power"|"volumeUp"|"volumeDown"|"appSwitch"|"actionButton" } [ios/android] keyboard: { text?: string, key?: string, delayMs?: number } (text OR key per step, never both; TV: text only) [ios/android/chromium/vega/tv] text supports {{secret:}} placeholders, resolved server-side from ARGENT_SECRET_ env vars or an argent secrets file — credentials never enter agent context paste: { text: string } (device clipboard + paste shortcut; only where a user would paste, e.g. an OTP — keyboard otherwise) [ios sim/android emu] rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android] shake: { count?: number } [ios sim/android emu] tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega] buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute — work on Android TV and Vega; rejected on the Apple TV simulator) await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]
Example — scroll down three times (use gesture-scroll with positive deltaY on Chromium): { "udid": "", "steps": [ { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } } ]}
Example — type text and submit (two keyboard steps; one call cannot carry both): { "udid": "", "steps": [ { "tool": "keyboard", "args": { "text": "hello world" } }, { "tool": "keyboard", "args": { "key": "enter" } } ]}
Example — TV: move focus right twice then activate (one tv-remote step with a path is cheaper): { "udid": "", "steps": [ { "tool": "tv-remote", "args": { "button": ["right", "right", "select"] } } ]}
Example — tap, wait for the next screen's element, then tap it: { "udid": "", "steps": [ { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.9 } }, { "tool": "await-ui-element", "args": { "condition": "visible", "selector": { "text": "Continue" } } }, { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.5 } } ]} If the await-ui-element condition is not met before its timeout, the sequence stops there and the following steps do NOT run — so the tap above only fires once "Continue" is actually on screen.
Stops on the first error (or unmet await-ui-element condition) and returns partial results.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id) — shared across all steps. | |
| steps | Yes | Ordered list of interaction steps to execute sequentially |