Dispatch
Core Concepts

Worker Types

Dispatch has two worker types. The coordinator routes jobs based on each worker's declared capabilities.

Overview

PropertyDesktop WorkerSeeker Worker
Provider typeDESKTOPSEEKER
CapabilitiesLLM_INFER, TASKTASK only
LLM inferenceYes (via Ollama)No
Task executionsummarize, classify, extract_jsonsummarize, classify, extract_json
Intended deviceServers, desktopsMobile phones, lightweight devices
Key storage./data/worker-key.json./data/seeker-key.json

Desktop Worker

The desktop worker is the full-capability node. It runs LLM inference through a local Ollama instance and handles lightweight TASK jobs.

Registration

On startup, the desktop worker:

  1. Loads or generates an ed25519 keypair
  2. Connects to the coordinator via WebSocket
  3. Sends a register message declaring its capabilities
const msg: RegisterMsg = {
  type: "register",
  provider_pubkey: keys.pubkeyHex,
  provider_type: "DESKTOP",
  capabilities: [JobType.LLM_INFER, JobType.TASK],
};
  1. Waits for a register_ack with a worker_id
  2. Starts sending heartbeats every 10 seconds
  3. Optionally claims a trust pairing code if TRUST_PAIRING_CODE is set

Job execution

When the coordinator assigns a job:

  • LLM_INFER: calls the local Ollama API with the prompt and max_tokens
  • TASK: runs built-in logic for the specified task_type

After execution, the worker builds a receipt (SHA-256 hash of output, ed25519 signature) and sends job_complete with the output and receipt bundled together.

Seeker Worker

The seeker is a lightweight worker designed for mobile devices. It handles only TASK jobs, no LLM inference.

Registration

const regMsg: RegisterMsg = {
  type: "register",
  provider_pubkey: keys.pubkeyHex,
  provider_type: "SEEKER",
  capabilities: [JobType.TASK],  // TASK only
};

Supported tasks

All seekers can execute these task types:

summarize

Truncates input to 200 characters and returns a word count:

{ "summary": "Truncated text...", "word_count": 42 }

classify

Performs basic sentiment analysis using keyword matching:

{ "sentiment": "positive", "confidence": 0.5 }

extract_json

Extracts and parses JSON objects from free text:

{ "extracted": [{ "key": "value" }], "count": 1 }

Provider Type Enum

The ProviderType enum defines the two worker types:

enum ProviderType {
  DESKTOP = "DESKTOP",
  SEEKER  = "SEEKER",
}

Sent in the register message and stored by the coordinator to track each worker's role.

How the coordinator routes jobs

When a job arrives, the coordinator's claimWorker() function finds an available worker that:

  1. Has the required capability (e.g., LLM_INFER or TASK)
  2. Is currently online (WebSocket connected, recent heartbeat)
  3. Is not busy with another job
  4. For PRIVATE jobs: is trust-paired with the submitting user

The coordinator does not prefer desktop over seeker for TASK jobs. Any worker with the capability can be assigned.

Running multiple workers

You can run multiple workers on the same machine by using different key file paths:

# Worker 1 (default path)
COORDINATOR_URL=http://localhost:4010 pnpm --filter worker-desktop start

# Worker 2 (custom key path)
COORDINATOR_URL=http://localhost:4010 \
WORKER_KEY_PATH=./data/worker-key-2.json \
pnpm --filter worker-desktop start

Each worker gets its own ed25519 keypair and registers independently with the coordinator.