Runs: how work executes
Every piece of agent work is a durable run: one leased turn at a time, resumed if a worker dies, continued in parts, and recoverable without anyone having the app open.
Updated 2026-10-13
A run is a database row. It has a goal, a status, steps, a conversation, outputs and a verdict. Pytheus’s runs have no employee; everyone else’s do.
Statuses
| Status | Meaning |
|---|---|
| queued | Created, waiting for a worker or a free slot. |
| running | A worker holds the lease and is taking a turn. |
| waiting_input | Parked on a question to you (or on helper runs). |
| waiting_approval | Parked on an approval for an outside action. |
| completed | Finished. It has a verdict. |
| failed | Did not finish, with an error code and a plain message. |
| cancelled | Stopped by you. |
One turn at a time
Each invocation claims the run’s lease and does one model turn plus its tool calls. It saves the conversation, then chains to the next turn. Edge time limits never cut a run short, and closing the tab does not stop it.
- The lease lasts 120 seconds and is renewed by a heartbeat every 20 seconds.
- A worker that left tool calls half done does not repeat them: finished calls are read back first.
- A message that arrives while a run works goes to its inbox and is read before the next step.
- The step is saved after each tool, so a crash loses at most one.
Concurrency
Employees’ runs count against your plan’s running-at-once limit. The slot is claimed in the same database transaction that claims the lease, so several workers cannot each see a free slot. Pytheus is never queued behind teammates. A run that cannot start stays queued.
Idempotency
One intent is one run. A key such as task:<id>:work or an idempotency_key from the MCP assign_task tool means a second create returns the first run instead of a duplicate. There is also at most one live Pytheus run per chat.
Long jobs continue in parts
A job that needs more steps than its first budget continues in a further part of up to 14 turns. A job may take up to 4 parts in all (2 on Free). Each part starts from a compact version of the conversation: the brief, a checkpoint of each earlier part with the files so far, and the last messages. A part only starts when the task’s budget and your credits can cover it.
When the model is down
If all AI providers fail for a whole turn, the run is re-queued instead of failing, waiting 1, then 3, then 10 minutes. After that it fails as “provider busy”. The sweeper wakes it when the time comes.
Recovery without the app
A scheduled sweeper runs every minute. It wakes queued and stalled runs, resumes parents whose helpers have finished, fails runs older than six hours with a message that retry picks up from where it got to, stops parked runs nobody answered for a day, closes approvals of runs that ended, and marks approvals whose outcome was lost as such. A send is never repeated because its acknowledgement was lost.
If the sweeper is not scheduled, stalled work only recovers when someone opens the app. HQ’s setup status card reports whether the scheduler has run recently, and which tables, functions or secrets are missing.
What you can do with a run
| Action | Effect |
|---|---|
| Watch | Open Watch on whoever is working. See Watching the work. |
| Answer | Reply to the question a run is waiting on. |
| Stop | Cancel. Work already saved stays saved; anything waiting for approval is closed. |
| Retry | Start again; it picks up from where it got to. |
| Carry on (reopen) | Continue a run that ran out of steps or made only part of what was asked for. |