v1.3.11

Running Tasks

Last updated


How tasks in one session run side by side, how to cancel them, and how interrupted work resumes.

Per-session concurrency


MAX_SESSION_TASKS (half the CPU count, at least 3, since v1.3.0; a flat 3 from v1.1.2; NumCPU × 4 before) limits how many concurrent Execute() calls a single session can run. A task publishes its ToriiDB online marker and registers its cancel function before competing for a slot, so a queued task stays visible and cancellable instead of blocking invisibly. The marker carries a 60 s TTL refreshed every 55 s, so a killed or crashed process stops counting as online by expiry rather than by a PID check. The value is computed once at startup — it is not read from config.json. Background jobs (v1.3.0) do not take these slots: they have their own per-session limit, MAX_BACKGROUND_TASKS, with the same value.

Cancelling work


Cancellation is per task, not per session: POST /v1/session/:id/cancel/:task_hash stops one running task ({"cancelled": true}); when that task hash is not running in this process it records a canceled event and returns {"cancelled": false, "stale": true}. The former once_id identifier was replaced by the task hash. Tool confirmations are answered separately with POST /v1/session/:id/confirm/:confirm_hash, where confirm_hash comes from the confirm event. There is deliberately no cancel-everything variant, so one long-running job can be dropped without disturbing the session's other tasks. In the TUI, Esc during a run (after any open / command picker and notice box are closed) opens the cancel-confirmation popup for the active task, or cancels it at once when nothing has been shown yet; since v1.2.0 the TUI sends the cancel to the daemon as a cancel frame on its socket. Since v1.3.0 cancelling a task, through either path, also stops its background jobs.

Resuming interrupted work


A run that stopped on an ask_user or a confirmation leaves a pending task behind. GET /v1/session/:id/task lists the ones that are actually resumable: a live run refreshes action:<session_id>:<task_hash> in ToriiDB every 55 s with a 60 s TTL, so a task abandoned by a closed window or a killed process reappears in that list within a minute, while a task still being worked on does not. Answer it with POST .../resume, or drop it with DELETE .../:task_hash. In the TUI this is /pending, which since v1.2.0 resumes through the daemon with a pending frame and asks any saved question inline. From v1.3.0 a TUI task also stayed pending while background jobs it started were running, resumed on each report and was marked [Active] in /pending; this was Removed in v1.3.8: the task now ends normally and its background reports are delivered as described in Pending Tasks and Cancellation.
Completed runs stay queryable too: GET /v1/session/:id/task/history lists them as task_hash, end_at, objective, model, and reasoning (optional keyword filter), and GET .../:task_hash/history returns one run's full action record as content.
中文