@exellix/job-dispatcher
v1.0.11
Published
Graph job dispatch orchestration (validate → compile → execute) for Exellix graph runtimes.
Downloads
1,419
Readme
@exellix/job-dispatcher
Graph job dispatch orchestration for Exellix graph runtimes.
Validate → normalize → compile → execute → diagnostics in one place. Hosts send a JSON request; this package owns the dispatch pipeline and engine wiring.
Published on npm as @exellix/job-dispatcher (currently 1.0.4).
Install
npm install @exellix/job-dispatcherRequires Node >=20.19.0 || >=22.12.0.
Dependencies: @exellix/graph-engine, @exellix/ai-tasks.
Exports
| Import | Use |
|--------|-----|
| @exellix/job-dispatcher | Main re-exports |
| @exellix/job-dispatcher/graph | dispatchGraphJob, dispatchGraphJobWithEngine, createExellixGraphRuntimeFromEnv, compileGraphDispatchPlan, resolveInvocationPlan |
| @exellix/job-dispatcher/studio | Studio compile/execute adapters, dispatchGraphJobWithEngine |
| @exellix/job-dispatcher/jobs | createJobsGraphDispatcher, buildJobsGraphDispatchRequest (used by @exellix/jobs) |
| @exellix/job-dispatcher/node | dispatchGraphNode — single-node runs |
| @exellix/job-dispatcher/matrix | createMatrixGraphExecuteAdapter — matrix batch hosts |
Quick start (orchestration only)
import { dispatchGraphJob } from '@exellix/job-dispatcher/graph';
const result = await dispatchGraphJob(request, {
compileGraph: myCompileGraphAdapter,
executeGraph: myExecuteGraphAdapter,
});Studio graph run
import { dispatchGraphJobWithEngine } from '@exellix/job-dispatcher/studio';
import { createExellixGraphRuntimeFromEnv } from '@exellix/job-dispatcher/graph';
const { exellixRuntime } = await createExellixGraphRuntimeFromEnv({ graphLoader });
const result = await dispatchGraphJobWithEngine(
{
mode: 'graph',
graph: authoringDocument,
runtime: { input: { vulnerabilityType: 'xss' } },
jobId: 'job-abc',
},
{
graphRuntimeEnvelope: { job, jobMemory, runtimeObjects },
agentId: 'my-agent',
exellixRuntime,
},
);Jobs worker / factory
import { createJobsGraphDispatcher } from '@exellix/job-dispatcher/jobs';
const { dispatchGraphRun } = createJobsGraphDispatcher({
graphLoader,
eventEmitter: activix?.eventEmitter,
});
const result = await dispatchGraphRun({
graphId: 'graph-1',
jobId: 'job-1',
runtimeInput: { recordId: 'rec-1' },
context: { jobMemory: resolvedJobMemory },
});@exellix/jobs re-exports the same API for backward compatibility.
Runtime jobMemory
The dispatcher treats runtime.context.jobMemory as host-resolved runtime memory and forwards it unchanged into graph-engine execution as runtime.jobMemory. It validates and diagnoses whether the graph reads jobMemory, but it does not resolve Memorix, Hippox, linked records, or associated snapshot data itself.
For jobs that assemble Memorix snapshot records, @exellix/jobs resolves those host concerns before dispatch (worker, executeGraphJob, Graph Studio BFF — never inside this package):
runtime.inputreceives the graph's primary record fields.runtime.context.jobMemory.context["linked-information"]andextendedInformationreceive configured linked/same-object context source enrichment (resolveJobMemoryForDispatch/ worker context resolution).runtime.context.jobMemory.associated*fields receive associated/enriched sub-objects promoted out of snapshot data.
Graph Studio and other sync hosts should call @exellix/jobs with the same contextSources definition as queued jobs, then pass the resolved jobMemory into dispatchGraphJobWithEngine or createJobsGraphDispatcher().dispatchGraphRun.
Snapshot-associated data should be promoted into jobMemory, not left in the main runtime input and not nested under jobMemory.context. On snapshots, any root data property whose name starts with associated is treated as associated content, so this supports associatedData, associatedInferred, associatedAnalysis, associatedRiskScores, associatedExploitability, and other custom associated<Something> fields without hard-coding the known names. The worker normalizes each associated value to an array of object items and dispatches:
await dispatchGraphRun({
graphId: 'graph-1',
jobId: 'job-1',
runtimeInput: {
recordId: 'rec-1',
cveId: 'CVE-2024-1234',
},
context: {
jobMemory: {
context: {
'linked-information': [
{ context: 'Existing linked context', data: [{ recordId: 'linked-1' }] },
],
},
associatedData: [
{ owner: 'team-x', severity: 'critical' },
],
associatedRiskScores: [
{ score: 91, source: 'risk-model-v2' },
],
},
},
});Graphs or skill templates that need this snapshot-associated content should read it from direct jobMemory.associated* fields such as jobMemory.associatedData or jobMemory.associatedRiskScores. This keeps the business input clean while still making associated/enriched data available to skills that opt into jobMemory, and keeps jobMemory.context dedicated to context-source/Hippox-style context.
Single-node run
import { dispatchGraphNode } from '@exellix/job-dispatcher/node';
await dispatchGraphNode(
{ graph, nodeId, job, jobMemory, execution, variables },
{ exellixRuntime },
);Compile-only preview
import { compileGraphDispatchPlan } from '@exellix/job-dispatcher/graph';
const compiled = await compileGraphDispatchPlan(request, {
agentId,
jobTypeId,
graphRuntimeEnvelope,
});What this package owns
- Request validation, normalization, orchestration, diagnostics
- Studio + jobs compile/execute adapters
- Runtime factory (
createExellixGraphRuntimeFromEnv) - Node and matrix execute facades
- Forwarding host-provided
jobMemoryinto graph runtime and warning when assembled context is unused or missing
What stays in hosts
- Memorix / Hippox context resolution (
@exellix/jobs) - Snapshot record assembly, including promoting associated/enriched
associated*data into directjobMemory.associated*fields - Queue admission, HTTP handlers
- Authoring UI (
@exellix/graph-engine/authoring)
Development
npm run build --workspace=@exellix/job-dispatcher
node --test jobs-packages/job-dispatcher/tests/*.test.mjs
npm publish -w @exellix/job-dispatcher