Async Tasks¶
MiniBot hands 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
spawn_task and delegate are also the only ways to hand work to a specialist agent (see Multi-Agent Orchestration), so
disabling this section disables multi-agent orchestration too. The reverse does not hold:
[orchestration.specialists].enabled = false keeps the task system and its generic worker
while removing the specialist roster and named delegation. With [tasks] off and
[orchestration.specialists] left at its default, the roster is disabled too; setting
specialists.enabled = true explicitly with [tasks].enabled = false is a config error.
Note
Async tasks are enabled by default ([tasks].enabled = true). The default SQLite backend
needs no broker and no extra; backend = "rabbitmq" requires the rabbitmq extra and a
broker configured in [rabbitmq].
Backends¶
|
Behavior |
Requires |
|---|---|---|
|
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 |
|
Push-based queue. The API process publishes tasks to a broker and a consumer drains them. |
The |
Tool Surface¶
Tool |
Purpose |
|---|---|
|
Queue a worker task from a |
|
Same parameters as |
|
Cancel an active task by |
|
Send a |
|
List the owner’s tasks, optionally filtered by |
|
Retrieve one task’s result, structured progress, and compact event history (by full id or a
unique prefix of at least 8 characters)
( |
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 and delegate 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 (default1800).worker_max_steps/worker_max_tool_calls— optional ceilings, or"unlimited"(the default).max_concurrent_workers— maximum parallel handlers (default4).delegation_mode—"auto"(default) registers bothdelegateandspawn_taskand the model picks by tool;"delegate"registers onlydelegate, so every result returns to the main agent as a new turn, falling back to direct delivery past the continuation limit. It replacescontinue_turn_mode = "always"; the removedcontinue_turn_modeandcontinue_turn_defaultkeys are rejected at config load. A[orchestration.main_agent] tools_allowlist must namedelegateas well asspawn_task, or the main agent loses the tool that returns results to it. See Multi-Agent Orchestration.worker_extensions— bundled tool extensions a worker loads on top of the scheduler and utility ones (default[])."kv_memory","rag"and"codemode"(therun_tools_scripttool, which calls the tools that specialist has and replaces them as direct calls) are accepted, each at most once, and each needs its[tools.*]section enabled. Their storage is prepared on the first call in each worker.[tasks] worker_extensions = ["rag"]
Only a specialist that claims the tools gets them, for example with
tools_allow: ["rag_*"]. A specialist that sets onlytools_denygets every tool it does not deny, these included. A task without an agent never gets them. MCP servers need no entry here: a specialist claims them throughmcp_servers.Each worker process is separate, so a task that calls RAG loads the embedding model (and the reranker for a search) itself: expect that latency on its first RAG call and that memory per concurrent worker.
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 and the bundles listed in
worker_extensionsare available, but worker registries do not start extension services or event subscriptions.spawn_taskanddelegaterequire channel context so the worker knows where to post progress and results.spawn_taskanddelegatereturn atask_idimmediately withstatus = "queued"; poll it withget_taskrather than waiting in the turn.