Run Controls
Let users pause, resume, or stop a running agent.
Install
npx ax-depute@latest add run-controlspnpm dlx ax-depute@latest add run-controlsyarn dlx ax-depute@latest add run-controlsbunx ax-depute@latest add run-controlsOverview
Minimal execution steering — pause, resume, stop, retry. Intentionally kept simple. Extend via the actions slot for additional controls.
Basic usage
<Run Controls
state="running"
onPause={() => agent.pause()}
onStop={() => agent.kill()}
/>With local state
import { useState } from 'react';
import type { RunState } from '@/types/ax-common';
export function ExecutionWrapper() {
const [state, setState] = useState<RunState>('running');
return (
<Run Controls
state={state}
showLabel={true}
onStart={() => setState('running')}
onPause={() => setState('paused')}
onStop={() => setState('stopped')}
onRetry={() => setState('running')}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
state | RunState | Required | Current execution state ('idle' | 'running' | 'paused' | 'completed' | 'failed' | 'stopped'). |
onStart | () => void | undefined | Callback fired when user clicks start or resume. |
onPause | () => void | undefined | Callback fired when user clicks pause. |
onStop | () => void | undefined | Callback fired when user clicks stop (cancel execution entirely). |
onRetry | () => void | undefined | Callback fired when user clicks retry after a failure state. |
showLabel | boolean | false | Whether to display a text label showing the current state next to the pulsing indicator. |
actions | ReactNode | undefined | Slot for additional custom action buttons (e.g., an Undo button). |
When to use
- An agent is actively running and the user needs the ability to intervene at any time — pause, steer, or hard-stop
- The execution is long-running (multi-step, multi-tool) and the user may need to inspect progress before the agent continues
- Your product has compliance or safety requirements that mandate a human escape hatch during autonomous operation
When not to use
- The agent run is fully instantaneous (< 1 second) — there is no execution window in which a control is meaningful
- The agent is running fully headless/background with no synchronous user session; surfacing controls the user cannot act on is confusing
- You're only displaying results after an agent has already completed — use
Artifact Cardto present the output, notRun Controls
Accessibility
- Buttons use native
<button>elements — nodiv onClickwrappers - Each button has an explicit
aria-label(e.g., "Pause agent run", "Stop agent run") independent of any icon or visual state - Active state is communicated via
aria-pressedwhere applicable (e.g., paused state on the pause button) - The pulsing status indicator is marked
aria-hidden="true"— status is conveyed viaaria-livetext, not animation - All state transitions (running → paused, paused → running) are announced via
aria-live="polite"
Solution Patterns
Run Controls is the central execution steering wheel, usually placed immmediately before or right next to an agent's Tool Trace:
Plan Card → Approval Gate → [Run Controls] → Tool Trace → Artifact CardIt controls whether the Tool Trace continues to append new events or pauses execution.
Design rationale
Why a hard stop? When an agent is running autonomously, the human supervisor must always have an immediate, unambiguous way to halt it — not a "cancel this step" or "skip this action," but a full stop. The same instinct behind the physical emergency stop button on industrial machinery applies here: the safest systems always prioritize the human's ability to exit over the system's ability to complete. Run Controls makes that affordance obvious and persistent throughout the execution lifecycle.
Why derive controls from state? The controls are not a static button group. They derive from the state prop — so if the agent has already completed, the stop button disappears. If it has failed, the retry button appears. This isn't just DX convenience: it prevents the class of bug where a developer shows a stop button on a completed run, or a resume button on a failed one. The UI cannot express an impossible transition because impossible transitions have no visual representation.