External Tasks

Some work cannot run inside the agent process: it belongs to a separate worker, a CI runner, or a human in another system. When a lane is routed to an external handler, tool calls scheduled on that lane are queued as external tasks instead of executed. Your host code drains the pending queue, does the work however it likes, and reports the outcome back with completeExternalTask; the waiting tool call then returns that outcome. Reach for this only when an outside worker is genuinely part of your architecture.

External tasks come from the lane queue. The session needs a queue config (queueConfig / queue_config / QueueConfig) and at least one lane set to external mode. hybrid lanes still execute in process and only emit notifications, so they produce nothing to drain.

The lane queue schedules host-direct tool calls: session.tool(...) and the typed helpers such as bash, readFile, and writeFile. Tool calls the model makes inside a send or stream turn execute directly and never become external tasks.

Rust
Node.js
Python
Go

Notes:

  • Tools map to lanes by name. read, ls, search (behind grep and glob), web_fetch, web_search, and the code-intelligence tools use the query lane; every other tool, including bash, write, and edit, uses execute.
  • Each pending task carries task_id, session_id, lane (the lane name as "Execute", "Query", and so on), command_type (the tool name), payload (the tool arguments), and timeout_ms. Pass the task_id back to completeExternalTask / complete_external_task / CompleteExternalTask.
  • The completion shape is { success, result?, error? }. On success, result becomes the tool result: it must contain an output string and may add exit_code (default 0), metadata, and images ([{ data, media_type }] with base64 data). A result without output turns into a tool error. On failure, the tool call ends with a tool error that includes error (default External task failed). Tool errors come back as the tool's output (for bash, text starting with Tool execution error:), not as a thrown error.
  • If nothing completes the task within the lane's timeoutMs / timeout_ms (default 60000), the task is removed and the waiting call ends with a timeout tool error.
  • Completion returns true when the task was still pending and false otherwise, for example after it timed out. Python queue methods are synchronous; in Node they return promises; in Go they take the caller's context.Context.