> ## Documentation Index
> Fetch the complete documentation index at: https://docs.argide.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Running Tasks

> Start, monitor, cancel, and recover agent tasks

A task is one goal handed to the agent. This page covers the full lifecycle: starting a task, the one-goal-at-a-time rule, reading the outcome, cancelling, and what happens when the agent navigates the page out from under itself.

## Start a task

```ts theme={null}
const { taskId } = await ArgideAgent.do({ goal: "cancel my subscription" });
```

`do()` resolves as soon as the task exists — not when it finishes. It also waits internally for `init` and the claim to complete, so you can call it right after `init` with no readiness check.

## One goal at a time

Each session runs at most one task. What `do()` does while a task is running depends on the goal:

| While a task is running...       | Result                                                                                |
| -------------------------------- | ------------------------------------------------------------------------------------- |
| `do()` with a **different** goal | Rejects with `409 SESSION_BUSY`. Wait for the task to settle, or `cancel()` it first. |
| `do()` with the **same** goal    | Treated as a rejoin — resolves with the same `taskId`.                                |

## Read the outcome

```ts theme={null}
const outcome = await ArgideAgent.check({ taskId });
// { taskId, status, summary }
```

`status` is one of `running`, `completed`, `failed`, or `cancelled`; `summary` is a string or `null`.

`check()` is the authoritative source for how a task ended. Activity events (below) are ephemeral and per-tab; when you need to decide what actually happened, use `check()`.

## End a task early

```ts theme={null}
await ArgideAgent.cancel({ taskId });
```

## Handle errors

`check()` and `cancel()` reject on any non-2xx response. The rejection is a plain `Error` — there's no `.status` or `.code` property to branch on — but its message carries the HTTP status, so inspect the message:

```ts theme={null}
try {
  await ArgideAgent.cancel({ taskId });
} catch (err) {
  const message = err instanceof Error ? err.message : String(err);
  // e.g. "agent task cancel failed: HTTP 404" or "agent task cancel failed: HTTP 409"
  if (message.includes("HTTP 404")) {
    // unknown task, or a task belonging to another session
  } else if (message.includes("HTTP 409")) {
    // the task is already terminal
  }
}
```

## Watch progress

Three signals, three jobs:

| Signal                             | What it tells you                                                                                   | Use it for                              |
| ---------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `onActivity(cb)`                   | Ephemeral, per-tab events as the agent works: `{ kind: "tool-start" \| "tool-end" \| "idle", ... }` | Live "agent is working" UI              |
| `onStateChange` (an `init` option) | Facade lifecycle: `"starting" \| "ready" \| "error" \| "stopped"`                                   | Enabling or disabling your entry points |
| `check({ taskId })`                | The authoritative task outcome                                                                      | Deciding what happened                  |

```ts theme={null}
const off = ArgideAgent.onActivity((activity) => {
  // { kind: "tool-start" | "tool-end" | "idle", ... }
  console.log(activity);
});
// later, to unsubscribe: off()
```
