Join our community of builders on Discord!

Dispatcher-free Mode

Lightchain AI assigns jobs on the chain itself. A central dispatcher service used to pick the worker for each session; it no longer runs on testnet or mainnet. In dispatcher-free mode a worker watches SessionManager for session requests it is eligible for, claims one with a single transaction (sortition — a weighted random draw among eligible workers), and then serves that session's jobs from JobRegistry exactly as before. No service picks the worker; the contract does.
CodeTEXT
Two things hold in every mode: the encrypted result settles on-chain as a blob (that is the authoritative response), and live token streaming to the consumer is best-effort.

Where it is live

NetworkAssignment todayWhat a worker should run
Testnet (8200)Dispatcher-free. AIConfig.getSortitionEnabled() returns true, and the testnet worker-gateway no longer delivers dispatcher jobs.The external profile below — the flow in Run a Worker on Testnet.
Mainnet (9200)Dispatcher-free. getSortitionEnabled() returns true (since 18 September 2026), and the dispatcher was switched off on 13 October 2026.The external profile below — the flow in Run a Worker on Mainnet. A worker still started with the older commands is given no jobs: see Move an existing worker to dispatcher-free mode.
Check either network yourself:
CodeBASH

Run profiles

One image, three profiles, selected by two environment variables:
ProfileSORTITION_ENABLEDWORKER_GATEWAY_URLWho assigns jobsRedis
External — for independent operatorstruesetThe chain: the worker self-claimsNot needed. Responses, heartbeat and drain go through the gateway
Gateway (legacy)unsetsetNobody. It waited for a dispatcher to deliver jobs over the gateway WebSocket, so on both networks a worker in this profile is given no workNot needed
Direct — Lightchain-operated nodes onlytrueunsetThe chain: the worker self-claimsRequired
SORTITION_ENABLED=true also requires SESSION_MANAGER_ADDRESS; the worker refuses to start without it. When both SORTITION_ENABLED and WORKER_GATEWAY_URL are set, the startup log carries the line external worker profile: sortition assignment with gateway egress (responses, heartbeat, drain via worker-gateway). The gateway for the external profile is https://worker-gateway.testnet.lightchain.ai on testnet and https://worker-gateway.mainnet.lightchain.ai on mainnet.

Environment reference

Everything below is read by the sidecar; the CLI reads the chain and identity variables too.
VariableDefaultPurpose
SORTITION_ENABLEDfalseWatch SessionManager and self-claim eligible sessions. Set it to true on both networks: nothing else assigns work.
SESSION_MANAGER_ADDRESS—Required when sortition is on. Resolve it with getSessionManagerAddress() above.
SORTITION_STATE_DIRdata/sortition-stateBlock cursors the watchers resume from. Put it on a mounted volume (/data/sortition-state); with an empty directory the worker starts both watchers 2,000 blocks behind the safe head (SORTITION_SESSION_LOOKBACK_BLOCKS).
SORTITION_POLL_INTERVAL4sHow often the watchers poll the chain.
WORKER_GATEWAY_URL—Gateway used for response streaming, heartbeat and drain.
MAX_CONCURRENT_JOBS2Jobs served at once; the watcher stops claiming while the worker is at capacity.
RELEASE_STATE_PATH./release_state.jsonLedger of the release scheduler that settles your earnings. Set /data/release_state.json so it survives docker rm.
SHUTDOWN_TIMEOUT30sHow long a stopped worker lets the jobs it is running finish before it cancels them and exits (worker release v0.0.5 on). The install guides set 240s; keep docker stop -t above it. See Stopping a dispatcher-free worker.
SEARCH_ENABLED, TAVILY_API_KEY, …See Web search.
Chain, identity, model and inference variables (CHAIN_ID, RPC_URL, the *_ADDRESS set, WORKER_KEYSTORE_*, ENCRYPTION_KEYSTORE_PATH, SUPPORTED_MODELS, OLLAMA_URL, BEACON_API_URL, BLOB_MODE) are unchanged from the install guides.

Verify it is claiming

A healthy external-profile start:
CodeTEXT
There is no "job received" line until a session is won — a quiet log is normal while other workers win the draws. When your worker wins you see claimed session request, then the usual stage 1: broadcasting ack tx … job completed sequence for each job in that session:
CodeBASH
lightchain-worker preflight (shown in the install guides) checks everything a claim depends on — registration, stake against the live minimum, each model's whitelist / enabled / added state, gateway login, Ollama tags — and exits 1 on any failure. Run it first whenever a registered worker never claims. Workers can augment a prompt with a live web search when the user turns on Web search in the chat. The worker runs one Tavily query with the prompt, folds the top results into the prompt it sends to the model, and publishes the sources after the answer so the chat renders them beneath it. Search is fail-open: on any error or timeout the job proceeds with the original prompt and no sources. Enable it with your own Tavily API key:
CodeBASH
TAVILY_API_KEY is required when SEARCH_ENABLED=true; the worker refuses to start without it. What the flag changes on the network side:
  • The worker advertises the search capability in its heartbeat, and in dispatcher-free mode declares it on-chain at startup (WorkerRegistry.setCapabilities, one transaction from the worker key, sent only when the mask changes). Sessions that require search are claimable only by workers whose mask includes it; the worker skips requests it cannot satisfy.
  • Capabilities are an owner-managed namespace: a worker can only declare names the network has registered (WorkerRegistry.getCapabilityCount()). Both testnet and mainnet have search registered (mainnet since 2026-09-13). A worker started before its network registered a capability logs capability not registered on-chain; skipping declaration and declares it on its next start.
  • Both published images (registry.lightchain.ai/testnet/worker:latest and mainnet/worker:latest, worker release v0.0.5 since 2026-10-16) support web search; a mainnet image pulled before 2026-09-13 does not.

Stopping a dispatcher-free worker

lightchain-worker drain sets a marker that the dispatcher used to honour. Nothing consults it before a claim, so a running worker keeps claiming sessions until the process stops. To take a worker out of rotation:
  1. Stop it:
    CodeBASH
    On SIGTERM the worker stops both watchers at once, so it claims no new session and starts no new job, and sets the drain marker through the gateway. Jobs it is already running keep going until they finish or SHUTDOWN_TIMEOUT runs out (the install guides set 240 s; unset, it is 30 s). A job still running then is cancelled, times out on-chain, and counts as an offence. Keep docker stop -t above SHUTDOWN_TIMEOUT, or Docker kills the worker first. This is worker release v0.0.5 and later: an older image ends a running job at SIGTERM, so pull latest before you rely on it.
  2. Jobs submitted later in sessions you already claimed still target your worker. While it is offline they time out, and every timeout is recorded as an offence even while slash rates are 0 — see Slashing & Rehabilitation.
  3. To leave for good, continue with the release and deregister steps in Drain & Graceful Exit.