@exellix/jobs-api
v1.2.0
Published
Exellix jobs HTTP API — Fastify REST server and programmatic read/write queries over the job queue. Queue runtime is @exellix/jobs; dashboard is @exellix/jobs-ui; persistence is @exellix/jobs-db.
Readme
@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/jobsQuick 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 rootOr 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 → :3099Deployment 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.
Processing layer — context preview, associated enrichment, coverage
These routes use @exellix/jobs resolution helpers. They do not dispatch graphs or write associated data unless a separate operational job does so.
| Method | Path | Purpose |
|--------|------|---------|
| POST | /api/context/preview | Preview runtime jobMemory for one input + optional contextSources / Hippox links. Body: { input, sourceEntity?, contextSources?, contextLinks?, hippoxContext? } |
| POST | /api/associated-enrichment/preview | Preview persistent associated* smart-merge for one source record — no Memorix write. Body: { recordId, input, existingAssociatedValue?, config: AssociatedEnrichmentConfig } |
| POST | /api/graph/input-coverage | Sample records from a batch list; report assembly gaps and per-context-source coverage (resolved / missing / filtered / mandatory failures). Body: { graphId, selection, recordIds, contextSources?, sourceEntity?, sampleSize? } |
| POST | /api/graphs/execute | Sync graph execute. When contextSources is set, resolves jobMemory before dispatch (Graph Studio / host clients). Body adds: contextSources?, sourceEntity?, recordId? |
Related assembler routes (unchanged): GET /api/assembler/properties, POST /api/assembler/preview.
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
npm run provision:catalox-graphs # descriptor 1.1.0 (graphKind indexes)
npm run provision:catalox-graphs:full # provision + backfill graph rowsCLI (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
