Async Tasks

MiniBot can hand long-running work to a background worker instead of blocking the turn. The [tasks] section gates both the consumer service and the task tools: when it is disabled, the model never sees them.

Note

Async tasks are disabled by default ([tasks].enabled = false). The default SQLite backend needs no broker and no extra; backend = "rabbitmq" requires the rabbitmq extra and a broker configured in [rabbitmq].

Backends

backend

Behavior

Requires

"sqlite" (default)

Polled queue in a local SQLite file. Survives a crash via lease expiry, so a stalled task is redelivered to another worker.

Nothing beyond the base install; storage under [tasks.sqlite].

"rabbitmq"

Push-based queue. The API process publishes tasks to a broker and a consumer drains them.

The rabbitmq extra and a running broker ([rabbitmq]).

Tool Surface

Tool

Purpose

spawn_task

Queue a worker task from a prompt. Optionally target a specialist with agent_name, pass structured context_json, and cap timeout_seconds, max_steps, and max_tool_calls (each may not exceed the configured worker ceiling).

cancel_task

Cancel an active task by task_id.

list_tasks

List the owner’s tasks, optionally filtered by status (up to 100).

get_task

Retrieve one task’s result, structured progress, and compact event history (include_events defaults to true).

Statuses

A task moves through pending, leased, running, and a terminal state: done, failed, cancelled, or timed_out. A retrying task was redelivered after a failed attempt. These are the persisted, filterable states (list_tasks accepts them); the status = "queued" returned by spawn_task is only an immediate acknowledgement that the task was enqueued, not a stored state. Each record also carries a stop_reason (for example completed, max_steps, max_tool_calls, timeout, or provider_error) that explains why the worker stopped.

Results and history

Worker results and their compact event history are persisted. get_task returns the result text, attachments, metadata, and any recorded events; attachments are delivered to the user through the same outbound pipeline as the main agent. While a task runs, the worker publishes progress updates to the originating channel. Terminal rows and their event history are retained for [tasks.sqlite].done_retention_seconds (30 days by default) before being purged.

Configuration

See minibot.adapters.config.schema.TasksConfig and minibot.adapters.config.schema.SqliteTaskQueueConfig for every option. The relevant TOML sections are [tasks] and [tasks.sqlite]; the broker settings are under [rabbitmq].

Worker limits live on [tasks]:

  • worker_timeout_seconds — hard per-task processing timeout (default 1800).

  • worker_max_steps / worker_max_tool_calls — optional ceilings, or "unlimited" (the default).

  • max_concurrent_workers — maximum parallel handlers (default 4).

Warning

For the SQLite backend, [tasks.sqlite].lease_timeout_seconds must be greater than [tasks].worker_timeout_seconds. A shorter lease expires while the worker is still running and the task is handed to a second worker, running it twice. Startup rejects that combination.

Operational notes

  • Task workers build their own tool registry: configured extension tools are available, but worker registries do not start extension services or event subscriptions.

  • spawn_task requires channel context so the worker knows where to post progress and results.

  • spawn_task returns a task_id immediately with status = "queued"; poll it with get_task rather than waiting in the turn.