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

# Task Lifecycle

> The state machine every phone task moves through, and how to drive it.

Every phone task follows the same loop: **start it, monitor until something actionable happens, act on the outcome.** This page is the complete map.

## The four states

```text theme={null}
                    ┌──────────┐
   phone_run_task ─>│ pending  │  waiting for the phone
                    └────┬─────┘
                         │ phone picks it up
                    ┌────▼─────┐
              ┌─────│ running  │─────┐
   task pause │     └────┬─────┘     │ terminal outcome
              │          │           │
        ┌─────▼────┐     │      ┌────▼──────┐
        │  paused  │─────┘      │ completed │  + terminal
        └──────────┘  resume    └───────────┘
```

| Status      | Meaning                                                          |
| ----------- | ---------------------------------------------------------------- |
| `pending`   | Accepted by the server and waiting for the phone.                |
| `running`   | The phone has started executing the task.                        |
| `paused`    | Execution is suspended and can be resumed on the same `task_id`. |
| `completed` | The task reached a terminal outcome.                             |

## The monitor loop

[`phone_task_monitor`](/api-reference/tools/phone-task-monitor) is how you wait. It returns as soon as the task is `paused` or `completed`; otherwise it returns `monitor_timed_out: true` after its timeout (default and cap 120 s):

```text theme={null}
loop:
    result = phone_task_monitor(task_id)
    if result.monitor_timed_out:      # still pending/running
        continue                       # just call it again
    if result.status == "paused":
        phone_task_resume(...)         # or leave it paused deliberately
        continue
    # status == "completed" → read result.terminal
```

Use [`phone_task_status`](/api-reference/tools/phone-task-status) only for a point-in-time snapshot, never as a polling loop.

## Terminal outcomes

When `status` is `completed`, exactly one `terminal` explains why:

| Terminal              | Meaning                                                                                                              | What to do                                                                   |
| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `ok`                  | The task completed successfully.                                                                                     | Read `result`.                                                               |
| `needs_user_control`  | The phone needs user input or confirmation.                                                                          | Answer with [`phone_task_message`](/api-reference/tools/phone-task-message). |
| `timeout`             | Execution exceeded its deadline.                                                                                     | Retry with a higher `per_call_timeout_s` or a narrower prompt.               |
| `queue_wait_exceeded` | The phone did not start the task before its queue deadline.                                                          | Confirm the device is online and free, then start a new task.                |
| `stopped_by_user`     | Cancelled - via `phone_task_cancel`, `phone_session_end`, or displaced by a new `phone_run_task` on the same device. | Start a new task if still needed.                                            |
| `agent_error`         | The phone agent failed while executing.                                                                              | Retry; check `error` for details.                                            |
| `device_offline`      | The task could not be delivered to the selected device.                                                              | Reconnect the device, then retry.                                            |
| `session_expired`     | The session expired before completion.                                                                               | Start a new session and task.                                                |
| `iteration_limit`     | The phone agent reached its action limit.                                                                            | Break the task into smaller steps.                                           |

Handling patterns for each are in [Error handling](/guides/best-practices/error-handling).

## Human-in-the-loop handoffs

Sensitive moments - logins, confirmations, CAPTCHAs - are never handled by the agent alone. The phone hands control back:

<Steps>
  <Step title="The task completes with terminal: needs_user_control">
    Mobile `message_user`, `needs_confirmation`, `need_login`,
    `need_login_details`, and CAPTCHA actions all surface this way.
  </Step>

  <Step title="Inspect what the phone needs">
    The task's `error.control_type` and `error.prompt` describe the request -
    a confirmation, login details, a CAPTCHA to solve.
  </Step>

  <Step title="Answer with phone_task_message">
    Collect the user's answer - or let them complete the step directly on the
    device and send a short acknowledgement. The response contains a
    `continuation_task_id`.
  </Step>

  <Step title="Monitor the continuation task">
    Not the completed original - it will never run again. A continuation task
    can itself finish with `needs_user_control`; repeat until a terminal
    outcome no longer requests control.
  </Step>
</Steps>

<Note>
  In the handoff reply, `delivered_to_device: false` is **not** a failure -
  the original task is already completed. The presence of
  `continuation_task_id` is the success signal.
</Note>

## Pause and resume

* [`phone_task_pause`](/api-reference/tools/phone-task-pause) returns `pausing`
  immediately; monitor until the task reports `paused` or `completed`.
* [`phone_task_resume`](/api-reference/tools/phone-task-resume) continues the
  **same** `task_id`, optionally with a course-correcting `instruction`.
* Time spent paused does not count against the execution timeout.

## Steering a running task

[`phone_task_message`](/api-reference/tools/phone-task-message) adds guidance to a running task without pausing it - "use the second option", "skip that dialog". Keep monitoring the same `task_id`; check `delivered_to_device` in the response.

## Displacement

One task per device: starting a new `phone_run_task` on a device cancels its existing pending, running, or paused MCP task (`terminal: "stopped_by_user"`). Tasks started from the phone app itself are not cancelled and can hold the execution lane, keeping new MCP tasks `pending`.

## Next

<CardGroup cols={2}>
  <Card title="Error handling" icon="shield-halved" href="/guides/best-practices/error-handling">
    A handling pattern for every terminal outcome
  </Card>

  <Card title="Monitoring" icon="chart-line" href="/guides/best-practices/monitoring">
    Steps, snapshots, and debugging live tasks
  </Card>
</CardGroup>
