@msm-core/jobs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/approval/policy.d.ts +8 -0
- package/dist/approval/policy.d.ts.map +1 -0
- package/dist/approval/policy.js +22 -0
- package/dist/approval/policy.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -0
- package/dist/enums.d.ts +16 -0
- package/dist/enums.d.ts.map +1 -0
- package/dist/enums.js +35 -0
- package/dist/enums.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +26 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +408 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/port.d.ts +127 -0
- package/dist/port.d.ts.map +1 -0
- package/dist/port.js +17 -0
- package/dist/port.js.map +1 -0
- package/dist/reconciler.d.ts +25 -0
- package/dist/reconciler.d.ts.map +1 -0
- package/dist/reconciler.js +75 -0
- package/dist/reconciler.js.map +1 -0
- package/dist/resume-token.d.ts +40 -0
- package/dist/resume-token.d.ts.map +1 -0
- package/dist/resume-token.js +116 -0
- package/dist/resume-token.js.map +1 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/workflow/registry.d.ts +10 -0
- package/dist/workflow/registry.d.ts.map +1 -0
- package/dist/workflow/registry.js +114 -0
- package/dist/workflow/registry.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @msm-core/jobs
|
|
2
|
+
|
|
3
|
+
Durable job / mission orchestration engine — a crash-safe state machine for long-running,
|
|
4
|
+
resumable, human-gated agent work.
|
|
5
|
+
|
|
6
|
+
**Pure decision logic over injected ports.** The engine carries NO `mongoose` / `bullmq` /
|
|
7
|
+
`ioredis` dependency (only `jsonwebtoken`, for resume tokens). Storage, queue, lock, clock and
|
|
8
|
+
the step executor are supplied by the consumer via the interfaces in `@msm-core/jobs/port` —
|
|
9
|
+
exactly the way `@msm-core/memory` keeps persistence out of its core. A platform writes thin
|
|
10
|
+
adapters (e.g. Mongo + BullMQ + Redis) and gets durable jobs.
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- **CAS + idempotency state machine** — version-guarded compare-and-swap on every transition;
|
|
15
|
+
an append-only step timeline keyed by a unique idempotency key. Crash-safe and exactly-once.
|
|
16
|
+
- **Wait + resume** — `waiting_time` (delayed resume) and `waiting_event` (signed resume token,
|
|
17
|
+
one-time-use nonce). A wait-reconciler re-enqueues due jobs as a durability backstop.
|
|
18
|
+
- **Pluggable workflows** — declarative `WorkflowDefinition`s (data, not code) resolve each step.
|
|
19
|
+
- **Pluggable step executor** — `run_interaction_task` runs whatever the consumer wires (e.g. an
|
|
20
|
+
LLM agent turn); pure transitions (`wait_time` / `complete` / …) are no-ops.
|
|
21
|
+
- **HITL approval hook** — a step can transition to `awaiting_approval` and resume on a decision.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { createJobEngine, createWorkflowRegistry, DEFAULT_JOB_ENGINE_CONFIG } from "@msm-core/jobs";
|
|
27
|
+
import type { JobStore, QueuePort /* … */ } from "@msm-core/jobs/port";
|
|
28
|
+
|
|
29
|
+
const engine = createJobEngine({
|
|
30
|
+
jobStore, queue, lock, nonce, ops, clock, // your adapters (implement ./port)
|
|
31
|
+
registry: createWorkflowRegistry(definitions), // manifest-fed workflow definitions
|
|
32
|
+
stepExecutor, // run_interaction_task → your agent turn
|
|
33
|
+
config: { ...DEFAULT_JOB_ENGINE_CONFIG, resumeToken: { secret, ttlSeconds: 86400 } },
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await engine.orchestrateJobStep({ jobId, tenantId, reason: "create" });
|
|
37
|
+
await engine.reconcileWaitingTimeJobs(); // periodic durability backstop
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The ports (`JobStore.claim` / `finalizeStep` / `insertStep`, `QueuePort`, `LockPort`,
|
|
41
|
+
`NoncePort`, `ClockPort`, `JobOpsPort`, `StepExecutorPort`, `WorkflowRegistry`) are documented
|
|
42
|
+
in `port.ts`. `JobStore.insertStep` must throw `DuplicateStepError` on a repeated idempotency key
|
|
43
|
+
(the adapter maps its store's duplicate-key error onto it).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const JOB_APPROVAL_POLICIES: readonly ["customer_facing", "internal_operational", "content_social"];
|
|
2
|
+
export type JobApprovalPolicy = (typeof JOB_APPROVAL_POLICIES)[number];
|
|
3
|
+
export type JobApprovalTimeoutOutcome = "escalate_to_human" | "notify_owner_paused" | "save_draft_remind_owner_next_day";
|
|
4
|
+
export declare const DEFAULT_JOB_APPROVAL_POLICY: JobApprovalPolicy;
|
|
5
|
+
export declare function isJobApprovalPolicy(value: unknown): value is JobApprovalPolicy;
|
|
6
|
+
export declare function parseJobApprovalPolicy(value: unknown, fallback?: JobApprovalPolicy): JobApprovalPolicy;
|
|
7
|
+
export declare function resolveJobApprovalTimeoutOutcome(policy: JobApprovalPolicy): JobApprovalTimeoutOutcome;
|
|
8
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/approval/policy.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,wEAIxB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,MAAM,MAAM,yBAAyB,GACjC,mBAAmB,GACnB,qBAAqB,GACrB,kCAAkC,CAAC;AAEvC,eAAO,MAAM,2BAA2B,EAAE,iBAA0C,CAAC;AAErF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAE9E;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,QAAQ,GAAE,iBAA+C,GACxD,iBAAiB,CAEnB;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,iBAAiB,GACxB,yBAAyB,CAI3B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Pure approval policy resolution — no I/O. Ported verbatim from kader's
|
|
2
|
+
// job-approval-policy.ts so the timeout-outcome semantics stay identical.
|
|
3
|
+
export const JOB_APPROVAL_POLICIES = [
|
|
4
|
+
"customer_facing",
|
|
5
|
+
"internal_operational",
|
|
6
|
+
"content_social",
|
|
7
|
+
];
|
|
8
|
+
export const DEFAULT_JOB_APPROVAL_POLICY = "internal_operational";
|
|
9
|
+
export function isJobApprovalPolicy(value) {
|
|
10
|
+
return typeof value === "string" && JOB_APPROVAL_POLICIES.includes(value);
|
|
11
|
+
}
|
|
12
|
+
export function parseJobApprovalPolicy(value, fallback = DEFAULT_JOB_APPROVAL_POLICY) {
|
|
13
|
+
return isJobApprovalPolicy(value) ? value : fallback;
|
|
14
|
+
}
|
|
15
|
+
export function resolveJobApprovalTimeoutOutcome(policy) {
|
|
16
|
+
if (policy === "customer_facing")
|
|
17
|
+
return "escalate_to_human";
|
|
18
|
+
if (policy === "content_social")
|
|
19
|
+
return "save_draft_remind_owner_next_day";
|
|
20
|
+
return "notify_owner_paused";
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/approval/policy.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,0EAA0E;AAE1E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,iBAAiB;IACjB,sBAAsB;IACtB,gBAAgB;CACR,CAAC;AASX,MAAM,CAAC,MAAM,2BAA2B,GAAsB,sBAAsB,CAAC;AAErF,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,qBAA2C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAc,EACd,WAA8B,2BAA2B;IAEzD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,MAAyB;IAEzB,IAAI,MAAM,KAAK,iBAAiB;QAAE,OAAO,mBAAmB,CAAC;IAC7D,IAAI,MAAM,KAAK,gBAAgB;QAAE,OAAO,kCAAkC,CAAC;IAC3E,OAAO,qBAAqB,CAAC;AAC/B,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type ResumeMode = "delayed" | "scan_only";
|
|
2
|
+
export interface JobEngineConfig {
|
|
3
|
+
/** Steps executed per orchestrator tick (clamped to 1..3, matching kader). */
|
|
4
|
+
maxStepsPerTick: number;
|
|
5
|
+
/** A waiting_time shorter than this is resumed inline within the same tick. */
|
|
6
|
+
inlineResumeMaxDelayMs: number;
|
|
7
|
+
/**
|
|
8
|
+
* How waiting_time resumes:
|
|
9
|
+
* - "delayed": orchestrator self-enqueues a delayed BullMQ tick (durable via Redis),
|
|
10
|
+
* wait-reconciler is OFF.
|
|
11
|
+
* - "scan_only": orchestrator does NOT self-enqueue; the wait-reconciler scan re-enqueues
|
|
12
|
+
* due jobs (durable via the periodic scan).
|
|
13
|
+
*/
|
|
14
|
+
resumeMode: ResumeMode;
|
|
15
|
+
/** Default wait_time delay when a workflow step omits one. */
|
|
16
|
+
defaultWaitMs: number;
|
|
17
|
+
/** Reconciler batch size per scan. */
|
|
18
|
+
waitReconcileBatchSize: number;
|
|
19
|
+
/** Resume-token (waiting_event) signing. */
|
|
20
|
+
resumeToken: {
|
|
21
|
+
secret: string;
|
|
22
|
+
ttlSeconds: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare const DEFAULT_JOB_ENGINE_CONFIG: JobEngineConfig;
|
|
26
|
+
export interface OrchestratorRunConfig {
|
|
27
|
+
maxStepsPerTick: number;
|
|
28
|
+
inlineResumeMaxDelayMs: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveRunConfig(config: JobEngineConfig): OrchestratorRunConfig;
|
|
31
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED,eAAO,MAAM,yBAAyB,EAAE,eAOvC,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,qBAAqB,CAK/E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Engine configuration. The consumer (platform-ai) builds this from env/manifest.
|
|
2
|
+
export const DEFAULT_JOB_ENGINE_CONFIG = {
|
|
3
|
+
maxStepsPerTick: 3,
|
|
4
|
+
inlineResumeMaxDelayMs: 2_000,
|
|
5
|
+
resumeMode: "delayed",
|
|
6
|
+
defaultWaitMs: 60_000,
|
|
7
|
+
waitReconcileBatchSize: 50,
|
|
8
|
+
resumeToken: { secret: "", ttlSeconds: 86_400 },
|
|
9
|
+
};
|
|
10
|
+
export function resolveRunConfig(config) {
|
|
11
|
+
return {
|
|
12
|
+
maxStepsPerTick: Math.min(3, Math.max(1, config.maxStepsPerTick)),
|
|
13
|
+
inlineResumeMaxDelayMs: Math.max(0, config.inlineResumeMaxDelayMs),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAyBlF,MAAM,CAAC,MAAM,yBAAyB,GAAoB;IACxD,eAAe,EAAE,CAAC;IAClB,sBAAsB,EAAE,KAAK;IAC7B,UAAU,EAAE,SAAS;IACrB,aAAa,EAAE,MAAM;IACrB,sBAAsB,EAAE,EAAE;IAC1B,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;CAChD,CAAC;AAOF,MAAM,UAAU,gBAAgB,CAAC,MAAuB;IACtD,OAAO;QACL,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;QACjE,sBAAsB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC;KACnE,CAAC;AACJ,CAAC"}
|
package/dist/enums.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const JOB_STATUSES: readonly ["queued", "running", "waiting_time", "waiting_event", "awaiting_approval", "paused", "completed", "failed", "cancelled"];
|
|
2
|
+
export type JobStatus = (typeof JOB_STATUSES)[number];
|
|
3
|
+
export declare const TERMINAL_JOB_STATUSES: readonly ["completed", "failed", "cancelled"];
|
|
4
|
+
export type TerminalJobStatus = (typeof TERMINAL_JOB_STATUSES)[number];
|
|
5
|
+
export declare const RUNNABLE_JOB_STATUSES: readonly ["queued", "running"];
|
|
6
|
+
export declare const JOB_STEP_TYPES: readonly ["run_interaction_task", "wait_time", "wait_event", "notify_owner", "notify_customer", "complete", "fail"];
|
|
7
|
+
export type JobStepType = (typeof JOB_STEP_TYPES)[number];
|
|
8
|
+
export declare const JOB_STEP_STATUSES: readonly ["running", "completed", "failed", "skipped"];
|
|
9
|
+
export type JobStepStatus = (typeof JOB_STEP_STATUSES)[number];
|
|
10
|
+
export declare const JOB_STEP_TRIGGERED_BY: readonly ["time", "event", "manual", "mission", "task"];
|
|
11
|
+
export type JobStepTriggeredBy = (typeof JOB_STEP_TRIGGERED_BY)[number];
|
|
12
|
+
export declare const MISSION_RUN_STATUSES: readonly ["started", "completed", "skipped", "failed"];
|
|
13
|
+
export type MissionRunStatus = (typeof MISSION_RUN_STATUSES)[number];
|
|
14
|
+
export declare function isTerminalJobStatus(status: string): status is TerminalJobStatus;
|
|
15
|
+
export declare function isRunnableJobStatus(status: string): boolean;
|
|
16
|
+
//# sourceMappingURL=enums.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,oIAUf,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,eAAO,MAAM,qBAAqB,+CAAgD,CAAC;AACnF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,eAAO,MAAM,qBAAqB,gCAAiC,CAAC;AAEpE,eAAO,MAAM,cAAc,qHAQjB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,iBAAiB,wDAAyD,CAAC;AACxF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,qBAAqB,yDAA0D,CAAC;AAC7F,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,eAAO,MAAM,oBAAoB,wDAAyD,CAAC;AAC3F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,iBAAiB,CAE/E;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D"}
|
package/dist/enums.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @msm-core/jobs — string enums for the durable job/mission engine.
|
|
2
|
+
// Exported as `as const` arrays + derived union types: the pure engine uses the
|
|
3
|
+
// union types; the storage adapter uses the value arrays to build its schema enums.
|
|
4
|
+
export const JOB_STATUSES = [
|
|
5
|
+
"queued",
|
|
6
|
+
"running",
|
|
7
|
+
"waiting_time",
|
|
8
|
+
"waiting_event",
|
|
9
|
+
"awaiting_approval",
|
|
10
|
+
"paused",
|
|
11
|
+
"completed",
|
|
12
|
+
"failed",
|
|
13
|
+
"cancelled",
|
|
14
|
+
];
|
|
15
|
+
export const TERMINAL_JOB_STATUSES = ["completed", "failed", "cancelled"];
|
|
16
|
+
export const RUNNABLE_JOB_STATUSES = ["queued", "running"];
|
|
17
|
+
export const JOB_STEP_TYPES = [
|
|
18
|
+
"run_interaction_task",
|
|
19
|
+
"wait_time",
|
|
20
|
+
"wait_event",
|
|
21
|
+
"notify_owner",
|
|
22
|
+
"notify_customer",
|
|
23
|
+
"complete",
|
|
24
|
+
"fail",
|
|
25
|
+
];
|
|
26
|
+
export const JOB_STEP_STATUSES = ["running", "completed", "failed", "skipped"];
|
|
27
|
+
export const JOB_STEP_TRIGGERED_BY = ["time", "event", "manual", "mission", "task"];
|
|
28
|
+
export const MISSION_RUN_STATUSES = ["started", "completed", "skipped", "failed"];
|
|
29
|
+
export function isTerminalJobStatus(status) {
|
|
30
|
+
return TERMINAL_JOB_STATUSES.includes(status);
|
|
31
|
+
}
|
|
32
|
+
export function isRunnableJobStatus(status) {
|
|
33
|
+
return RUNNABLE_JOB_STATUSES.includes(status);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=enums.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enums.js","sourceRoot":"","sources":["../src/enums.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,gFAAgF;AAChF,oFAAoF;AAEpF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,SAAS;IACT,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,QAAQ;IACR,WAAW;IACX,QAAQ;IACR,WAAW;CACH,CAAC;AAGX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAGnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAU,CAAC;AAEpE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,sBAAsB;IACtB,WAAW;IACX,YAAY;IACZ,cAAc;IACd,iBAAiB;IACjB,UAAU;IACV,MAAM;CACE,CAAC;AAGX,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAGxF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAG7F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAG3F,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAQ,qBAA2C,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAQ,qBAA2C,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Orchestrator, type OrchestrateJobStepInput } from "./orchestrator.js";
|
|
2
|
+
import { type Reconciler } from "./reconciler.js";
|
|
3
|
+
import { type ResumeTokenService } from "./resume-token.js";
|
|
4
|
+
import { DEFAULT_JOB_ENGINE_CONFIG, type JobEngineConfig } from "./config.js";
|
|
5
|
+
import type { ApprovalCreatorPort, ClockPort, JobOpsPort, JobStore, LockPort, NoncePort, QueuePort, StepExecutorPort, WorkflowRegistry } from "./port.js";
|
|
6
|
+
export interface CreateJobEngineDeps {
|
|
7
|
+
jobStore: JobStore;
|
|
8
|
+
queue: QueuePort;
|
|
9
|
+
lock: LockPort;
|
|
10
|
+
nonce: NoncePort;
|
|
11
|
+
ops: JobOpsPort;
|
|
12
|
+
clock: ClockPort;
|
|
13
|
+
registry: WorkflowRegistry;
|
|
14
|
+
stepExecutor: StepExecutorPort;
|
|
15
|
+
config: JobEngineConfig;
|
|
16
|
+
approvalCreator?: ApprovalCreatorPort;
|
|
17
|
+
/** Override the step-id generator (default: crypto.randomUUID). */
|
|
18
|
+
genStepId?: () => string;
|
|
19
|
+
/** Reconciler lock TTL (default: derived from the scan interval). */
|
|
20
|
+
reconcileLockTtlMs?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface JobEngine {
|
|
23
|
+
orchestrateJobStep: Orchestrator["orchestrateJobStep"];
|
|
24
|
+
reconcileWaitingTimeJobs: Reconciler["reconcileWaitingTimeJobs"];
|
|
25
|
+
resumeToken: ResumeTokenService;
|
|
26
|
+
}
|
|
27
|
+
/** Assemble the durable job engine from ports + config. */
|
|
28
|
+
export declare function createJobEngine(deps: CreateJobEngineDeps): JobEngine;
|
|
29
|
+
export { DEFAULT_JOB_ENGINE_CONFIG };
|
|
30
|
+
export type { JobEngineConfig, OrchestrateJobStepInput };
|
|
31
|
+
export type { ResumeTokenService };
|
|
32
|
+
export { createResumeTokenService, ResumeTokenError, type IssuedResumeToken, type ConsumedResumeToken, } from "./resume-token.js";
|
|
33
|
+
export { createWorkflowRegistry, BUILTIN_JOB_BASIC } from "./workflow/registry.js";
|
|
34
|
+
export type { WaitingTimeReconcileResult } from "./reconciler.js";
|
|
35
|
+
export { JOB_STATUSES, TERMINAL_JOB_STATUSES, RUNNABLE_JOB_STATUSES, JOB_STEP_TYPES, JOB_STEP_STATUSES, JOB_STEP_TRIGGERED_BY, MISSION_RUN_STATUSES, isTerminalJobStatus, isRunnableJobStatus, type JobStatus, type TerminalJobStatus, type JobStepType, type JobStepStatus, type JobStepTriggeredBy, type MissionRunStatus, } from "./enums.js";
|
|
36
|
+
export type { JobBudget, JobWaitEvent, JobSnapshot, JobStepRecord, JobStepToolCall, CreateJobInput, JobOpsEventInput, WorkflowResolution, WorkflowContext, WorkflowSequenceStep, WorkflowDefinition, } from "./types.js";
|
|
37
|
+
export { JOB_APPROVAL_POLICIES, DEFAULT_JOB_APPROVAL_POLICY, isJobApprovalPolicy, parseJobApprovalPolicy, resolveJobApprovalTimeoutOutcome, type JobApprovalPolicy, type JobApprovalTimeoutOutcome, } from "./approval/policy.js";
|
|
38
|
+
export * from "./port.js";
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;IACzB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,kBAAkB,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACvD,wBAAwB,EAAE,UAAU,CAAC,0BAA0B,CAAC,CAAC;IACjE,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAqCpE;AAGD,OAAO,EAAE,yBAAyB,EAAE,CAAC;AACrC,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,CAAC;AACnC,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACnF,YAAY,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,gCAAgC,EAChC,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,GAC/B,MAAM,sBAAsB,CAAC;AAG9B,cAAc,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @msm-core/jobs — durable job/mission orchestration engine. Pure decision logic over
|
|
2
|
+
// injected ports (./port.js); no mongoose/bullmq/ioredis dependency. The consumer
|
|
3
|
+
// (e.g. platform-ai's @platform/jobs) supplies the Mongo/BullMQ/Redis adapters.
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { createOrchestrator } from "./orchestrator.js";
|
|
6
|
+
import { createReconciler } from "./reconciler.js";
|
|
7
|
+
import { createResumeTokenService } from "./resume-token.js";
|
|
8
|
+
import { DEFAULT_JOB_ENGINE_CONFIG } from "./config.js";
|
|
9
|
+
/** Assemble the durable job engine from ports + config. */
|
|
10
|
+
export function createJobEngine(deps) {
|
|
11
|
+
const genStepId = deps.genStepId ?? (() => randomUUID());
|
|
12
|
+
const resumeToken = createResumeTokenService({
|
|
13
|
+
secret: deps.config.resumeToken.secret,
|
|
14
|
+
ttlSeconds: deps.config.resumeToken.ttlSeconds,
|
|
15
|
+
nonce: deps.nonce,
|
|
16
|
+
});
|
|
17
|
+
const orchestrator = createOrchestrator({
|
|
18
|
+
jobStore: deps.jobStore,
|
|
19
|
+
queue: deps.queue,
|
|
20
|
+
ops: deps.ops,
|
|
21
|
+
clock: deps.clock,
|
|
22
|
+
registry: deps.registry,
|
|
23
|
+
stepExecutor: deps.stepExecutor,
|
|
24
|
+
resumeToken,
|
|
25
|
+
config: deps.config,
|
|
26
|
+
genStepId,
|
|
27
|
+
...(deps.approvalCreator ? { approvalCreator: deps.approvalCreator } : {}),
|
|
28
|
+
});
|
|
29
|
+
const reconciler = createReconciler({
|
|
30
|
+
jobStore: deps.jobStore,
|
|
31
|
+
queue: deps.queue,
|
|
32
|
+
lock: deps.lock,
|
|
33
|
+
ops: deps.ops,
|
|
34
|
+
clock: deps.clock,
|
|
35
|
+
config: deps.config,
|
|
36
|
+
lockTtlMs: deps.reconcileLockTtlMs ?? 30_000,
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
orchestrateJobStep: orchestrator.orchestrateJobStep,
|
|
40
|
+
reconcileWaitingTimeJobs: reconciler.reconcileWaitingTimeJobs,
|
|
41
|
+
resumeToken,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ── Public surface ──
|
|
45
|
+
export { DEFAULT_JOB_ENGINE_CONFIG };
|
|
46
|
+
export { createResumeTokenService, ResumeTokenError, } from "./resume-token.js";
|
|
47
|
+
export { createWorkflowRegistry, BUILTIN_JOB_BASIC } from "./workflow/registry.js";
|
|
48
|
+
// Enums + types
|
|
49
|
+
export { JOB_STATUSES, TERMINAL_JOB_STATUSES, RUNNABLE_JOB_STATUSES, JOB_STEP_TYPES, JOB_STEP_STATUSES, JOB_STEP_TRIGGERED_BY, MISSION_RUN_STATUSES, isTerminalJobStatus, isRunnableJobStatus, } from "./enums.js";
|
|
50
|
+
export { JOB_APPROVAL_POLICIES, DEFAULT_JOB_APPROVAL_POLICY, isJobApprovalPolicy, parseJobApprovalPolicy, resolveJobApprovalTimeoutOutcome, } from "./approval/policy.js";
|
|
51
|
+
// Ports + the typed atomic-failure error
|
|
52
|
+
export * from "./port.js";
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,kFAAkF;AAClF,gFAAgF;AAEhF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAmD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAA2B,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAwB,MAAM,aAAa,CAAC;AAoC9E,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;IAEzD,MAAM,WAAW,GAAG,wBAAwB,CAAC;QAC3C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM;QACtC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU;QAC9C,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,kBAAkB,CAAC;QACtC,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW;QACX,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS;QACT,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,gBAAgB,CAAC;QAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,kBAAkB,IAAI,MAAM;KAC7C,CAAC,CAAC;IAEH,OAAO;QACL,kBAAkB,EAAE,YAAY,CAAC,kBAAkB;QACnD,wBAAwB,EAAE,UAAU,CAAC,wBAAwB;QAC7D,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,uBAAuB;AACvB,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAGrC,OAAO,EACL,wBAAwB,EACxB,gBAAgB,GAGjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGnF,gBAAgB;AAChB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GAOpB,MAAM,YAAY,CAAC;AAcpB,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,gCAAgC,GAGjC,MAAM,sBAAsB,CAAC;AAE9B,yCAAyC;AACzC,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ApprovalCreatorPort, ClockPort, JobOpsPort, JobStore, QueuePort, StepExecutorPort, WorkflowRegistry } from "./port.js";
|
|
2
|
+
import { type JobEngineConfig } from "./config.js";
|
|
3
|
+
import type { ResumeTokenService } from "./resume-token.js";
|
|
4
|
+
export interface OrchestrateJobStepInput {
|
|
5
|
+
jobId: string;
|
|
6
|
+
tenantId: string;
|
|
7
|
+
idempotencyKey?: string;
|
|
8
|
+
reason?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface OrchestratorDeps {
|
|
11
|
+
jobStore: JobStore;
|
|
12
|
+
queue: QueuePort;
|
|
13
|
+
ops: JobOpsPort;
|
|
14
|
+
clock: ClockPort;
|
|
15
|
+
registry: WorkflowRegistry;
|
|
16
|
+
stepExecutor: StepExecutorPort;
|
|
17
|
+
resumeToken: ResumeTokenService;
|
|
18
|
+
config: JobEngineConfig;
|
|
19
|
+
genStepId: () => string;
|
|
20
|
+
approvalCreator?: ApprovalCreatorPort;
|
|
21
|
+
}
|
|
22
|
+
export interface Orchestrator {
|
|
23
|
+
orchestrateJobStep(input: OrchestrateJobStepInput): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createOrchestrator(deps: OrchestratorDeps): Orchestrator;
|
|
26
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAInB,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAI5D,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CA6bvE"}
|