BaseUIWorker extends BaseWorker with client visibility. Every job group it dispatches streams its lifecycle to the client as ui-job-group envelopes, so background work appears as a progress card the user can watch and cancel.
It involves no LLM. Instantiate one directly and register it on the runner as a dispatcher when a pipeline app wants client-visible background work driven by its own tools:
Migrating to UIWorker
UIWorker no longer inherits from BaseUIWorker: it reports its own job groups to the client in the same way. Instead of a BaseUIWorker dispatcher that the main pipeline’s tools reach through the runner, give the work a @job handler on your UIWorker and have the tool send that job:
UIWorker page.
What reaches the client
A group dispatched by aBaseUIWorker publishes:
The client’s reserved
__cancel_job_group event is translated into a cancellation for any group dispatched with JobGroupParams(cancellable=True). A group dispatched without it is still reported to the client, but the client cannot stop it.
Dispatching
BaseUIWorker uses the same job API as BaseWorker — job_group(), request_job_group(), and create_job_group_and_request_job(). There is no separate UI-specific dispatch method: every group this worker dispatches is client-visible by virtue of the class.
Give the group a label. It titles the card the user sees, and without one the card has nothing to name the work:
Job hooks
The same hooks asBaseWorker — on_job_update, on_job_response, on_job_stream_end, and on_job_completed — with the client forwarding layered on top. Always call super() when overriding, or the client stops receiving the group’s lifecycle.