@exellix/jobs-api
Jobs HTTP API — Fastify REST server and programmatic query library over the Exellix job queue. Handles enqueue, retry, cancel, job-def CRUD, work-factory routes, Memorix record views, and inline worker execution.
| Package | Role |
|---|---|
@exellix/jobs |
Jobs manager — queue runtime, worker loop, CLI |
@exellix/jobs-api (this) |
Jobs HTTP API — REST + programmatic queries |
@exellix/jobs-ui |
Jobs dashboard — React operator SPA |
@exellix/jobs-db |
Jobs data tier — Mongo persistence |
A JobRun is one graph run on one input. See
temp/jobs/for the design.
Install
npm install @exellix/jobs-api @exellix/jobs-db @exellix/jobs
Quick start
# MONGO_URI must be set (or in ../../graph-packages/graph-engine/.env)
npm run dev # build + serve on :3099
npm run serve # serve already-built dist/
Set PORT to override default 3099. Set LOG_LEVEL=debug for verbose Fastify logs.
Serving the dashboard
The API can optionally serve the built @exellix/jobs-ui static bundle on the same port (same-origin /api for the SPA):
- Build the UI:
cd ../jobs-ui && npm run build - Start the API — it auto-detects
../jobs-ui/dist, or setJOBS_UI_STATIC_DIR=/path/to/jobs-ui/dist
For local dev with HMR, run the full stack (API + worker + UI) with one command:
# from jobs-ui or repo root
npm run dev # jobs-ui — runs scripts/dev-jobs.mjs
npm run dev:jobs # repo root
Or run API and UI in separate terminals:
# terminal 1
cd jobs-api && npm run serve
# terminal 2
cd jobs-ui && npm run dev:ui # Vite on :5190, proxies /api → :3099
Deployment posture
| Variable | Default | Effect |
|---|---|---|
JOBS_UI_TOKEN |
unset | When set, all /api/* routes require Authorization: Bearer <token> |
JOBS_UI_STATIC_DIR |
auto-detect sibling jobs-ui/dist |
Path to built dashboard static files |
WORK_FACTORY_POLL_INTERVAL_MS |
inherits JOBS_POLL_INTERVAL_MS |
Continuous work evaluation interval (ms) |
WORK_EVAL_BATCH_SIZE |
500 |
Max records enqueued per evaluation tick |
JOBS_WORKER_CONCURRENCY |
app maxConcurrentJobs (default 10) |
Parallel run slots in inline worker |
WOREX_GRAPH_CONCURRENCY |
4 | Parallel task nodes per graph run |
ACTIVIX_STORAGE_MODE |
database (recommended) |
Mongo-only Activix; avoids silent playground/ folder fallback |
MONGO_LOGS_URI |
falls back to MONGO_URI |
Activix logs database connection |
Activix observability
Graph runs and per-node activity are persisted to Mongo via Activix (exellix-graph-runs, exellix-node-activity). The Live Console in jobs-ui reads GET /api/factory-runs/:id/activities — backed by getActivixClient().getJobActivities(), not local files.
Set ACTIVIX_STORAGE_MODE=database in .env (see .env.example). With the default Activix automatic mode, a unreachable Mongo connection causes Activix to write debug artifacts under playground/ in the process cwd — safe to delete; they are not used by the API or UI.
AI task phases (@exellix/ai-tasks) use a separate Activix client (default collection task-activities); the same ACTIVIX_STORAGE_MODE env applies.
HTTP API
All routes are under /api (legacy unprefixed aliases may also exist). See the route tables in the previous combined README — full listing preserved in docs/handoff/jobs-ui.md.
Key groups: runs/stats, job-defs, enqueue, settings/queue admission, entities/records/sources, work-factory (work, batches, on-demand, factory-runs), catalox graphs, memorix agents proxy.
Programmatic queries
import { createJobRunStore } from '@exellix/jobs-db';
import { listRuns, getRun, recentFailures, throughputStats } from '@exellix/jobs-api';
const { store } = await createJobRunStore({ mongoUri: process.env.MONGO_URI });
await listRuns(store, { status: 'pending', page: 1 });
await recentFailures(store, { limit: 10 });
Scripts
npm run build # tsc → dist/
npm test # unit tests (HTTP + queries)
npm run test:live # live Mongo integration
npm run serve # production server
npm run queue-worker
npm run clean-jobs # interactive wipe of job runs / batches / evaluations
npm run cancel-jobs # interactive cancel of pending/running runs
npm run bind:catalox
CLI (exellix-jobs-api)
exellix-jobs-api serve
exellix-jobs-api queue-worker [--worker-id=...] [--concurrency=...] [--verbose]
# Queue health
exellix-jobs-api status [--batch=<id>] [--mongo] [--json]
exellix-jobs-api settings show
exellix-jobs-api settings set --queue-mode=running|paused [--max-concurrent=<n>]
# Batch operations
exellix-jobs-api preview-batch --entity= --graph= [--collection=snapshots]
exellix-jobs-api queue-batch --file=batch.json [--yes]
exellix-jobs-api queue-single --entity= --record= --graph=
# Recovery workflow (retry failed runs in place, then drain)
exellix-jobs-api retry-runs --batch=<id> --status=failed [--error-contains=MongoNetwork] --yes
exellix-jobs-api drain [--concurrency=<n>] [--verbose]
exellix-jobs-api watch --batch=<id> [--interval=5000]
exellix-jobs-api complete-batch --batch=<id> --yes --verbose
# Maintenance
exellix-jobs-api clean-jobs [--yes] [--dry-run]
exellix-jobs-api cancel-jobs [--yes] [--status=pending]
Recover a batch after transient Mongo failures (same graph/batch, no re-queue):
# One-shot orchestration: resume → retry failed → drain → watch
exellix-jobs-api complete-batch \
--batch=33b6919c-efea-4156-b3a3-30f1f7f8e926 \
--yes --verbose
# Or step-by-step:
exellix-jobs-api settings set --queue-mode=running
exellix-jobs-api retry-runs --batch=33b6919c-... --status=failed --yes
exellix-jobs-api drain --verbose
exellix-jobs-api watch --batch=33b6919c-...
Global flags: --yes / -y, --dry-run, --json, --verbose, -h / --help.
clean-jobs removes all factory job runs, batch records, and work evaluation history from the runtime Mongo DB. Continuous work definitions, queue settings, and Memorix data are kept. Requires MONGO_URI (loads .env from the current directory or jobs-api/.env when run from the monorepo root).
Backlog
Deferred items: backlog/README.md
License
exellix-license