@memberjunction/task-graph 0.0.0 → 6.1.0-edge.1
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/LICENSE +7 -0
- package/dist/DispatcherConditionEvaluator.d.ts +10 -0
- package/dist/DispatcherConditionEvaluator.d.ts.map +1 -0
- package/dist/DispatcherConditionEvaluator.js +27 -0
- package/dist/DispatcherConditionEvaluator.js.map +1 -0
- package/dist/TaskClaimStore.d.ts +114 -0
- package/dist/TaskClaimStore.d.ts.map +1 -0
- package/dist/TaskClaimStore.js +218 -0
- package/dist/TaskClaimStore.js.map +1 -0
- package/dist/TaskGraphDispatcher.d.ts +186 -0
- package/dist/TaskGraphDispatcher.d.ts.map +1 -0
- package/dist/TaskGraphDispatcher.js +735 -0
- package/dist/TaskGraphDispatcher.js.map +1 -0
- package/dist/TaskGraphService.d.ts +138 -0
- package/dist/TaskGraphService.d.ts.map +1 -0
- package/dist/TaskGraphService.js +314 -0
- package/dist/TaskGraphService.js.map +1 -0
- package/dist/TaskGraphSubmitterImpl.d.ts +7 -0
- package/dist/TaskGraphSubmitterImpl.d.ts.map +1 -0
- package/dist/TaskGraphSubmitterImpl.js +52 -0
- package/dist/TaskGraphSubmitterImpl.js.map +1 -0
- package/dist/WorkflowSpecSync.d.ts +171 -0
- package/dist/WorkflowSpecSync.d.ts.map +1 -0
- package/dist/WorkflowSpecSync.js +393 -0
- package/dist/WorkflowSpecSync.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/operations/TaskGraphOperations.d.ts +39 -0
- package/dist/operations/TaskGraphOperations.d.ts.map +1 -0
- package/dist/operations/TaskGraphOperations.js +164 -0
- package/dist/operations/TaskGraphOperations.js.map +1 -0
- package/dist/operations/WorkflowOperations.d.ts +22 -0
- package/dist/operations/WorkflowOperations.d.ts.map +1 -0
- package/dist/operations/WorkflowOperations.js +99 -0
- package/dist/operations/WorkflowOperations.js.map +1 -0
- package/dist/types.d.ts +214 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +33 -8
- package/README.md +0 -45
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Persists a `WorkflowSpec` by **reconciling substrates that already exist**.
|
|
3
|
+
*
|
|
4
|
+
* **The central design constraint: no new storage.** There is no `Workflow` table and there will not
|
|
5
|
+
* be one. A workflow's WHAT is a Flow agent (the graph); its WHEN is a Scheduled Job or an Entity
|
|
6
|
+
* Action binding. Inventing a parallel `Workflow` row would create a second definition of "a
|
|
7
|
+
* scheduled thing", and the scheduler would then have two masters that can disagree — which is
|
|
8
|
+
* exactly the class of divergence this whole program has been removing.
|
|
9
|
+
*
|
|
10
|
+
* So this is a **reconciler**, not a writer. It follows the pattern
|
|
11
|
+
* `MJRecordProcessEntityServer.Save()` already proved: resolve the job type, find the rows this
|
|
12
|
+
* definition owns, then upsert or disable them so the substrate matches the spec. Rows are matched
|
|
13
|
+
* by a marker in their own `Configuration`, which is what makes ownership survive a rename.
|
|
14
|
+
*
|
|
15
|
+
* **Agent persistence crosses a seam.** Writing the Flow agent behind the graph is `AgentSpecSync`'s
|
|
16
|
+
* job — it already owns atomic multi-entity agent writes and the mutation audit. Importing it here
|
|
17
|
+
* would pull the agent-manager package into the execution substrate, so the host injects it instead.
|
|
18
|
+
* A caller with no agent writer still gets correct trigger reconciliation and an honest error rather
|
|
19
|
+
* than a half-persisted workflow.
|
|
20
|
+
*
|
|
21
|
+
* @module @memberjunction/task-graph
|
|
22
|
+
*/
|
|
23
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
24
|
+
import { type WorkflowSpec } from '@memberjunction/ai-core-plus';
|
|
25
|
+
/**
|
|
26
|
+
* Scheduled Job Type that runs a workflow's Flow agent.
|
|
27
|
+
*
|
|
28
|
+
* `'Agent'` is an existing seeded type backed by `AgentScheduledJobDriver` — a workflow's schedule
|
|
29
|
+
* reuses it rather than introducing a parallel one. `ScheduledJobType.DriverClass` is UNIQUE, so a
|
|
30
|
+
* second type for the same driver is not merely redundant, it is impossible; discovering that is
|
|
31
|
+
* what confirmed the substrate was already there and only the authoring surface was missing.
|
|
32
|
+
*/
|
|
33
|
+
export declare const RUN_WORKFLOW_JOB_TYPE = "Agent";
|
|
34
|
+
/** Marker written into an owned row's `Configuration`, so ownership survives a rename. */
|
|
35
|
+
export declare const WORKFLOW_OWNER_KEY = "WorkflowAgentID";
|
|
36
|
+
/**
|
|
37
|
+
* The Action an entity-change trigger dispatches to.
|
|
38
|
+
*
|
|
39
|
+
* `Execute Agent` already exists and was written for exactly this: "a concrete dispatch target for
|
|
40
|
+
* `AIAgent.ExposeAsAction`". Entity-action *invocation* is likewise already wired — the save pipeline
|
|
41
|
+
* fires validate / before-save / after-save / before-delete / after-delete through
|
|
42
|
+
* `HandleEntityActions`. So an entity-change trigger needs no new machinery at all; it needs a
|
|
43
|
+
* binding row, which is what this creates.
|
|
44
|
+
*/
|
|
45
|
+
export declare const EXECUTE_AGENT_ACTION = "Execute Agent";
|
|
46
|
+
/** Everything reconciliation needs beyond the spec itself. */
|
|
47
|
+
export type WorkflowSyncContext = {
|
|
48
|
+
ContextUser: UserInfo;
|
|
49
|
+
Provider: IMetadataProvider;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Persists the Flow agent behind a workflow's graph.
|
|
53
|
+
*
|
|
54
|
+
* Injected rather than imported so this package does not depend on the agent-manager. The host
|
|
55
|
+
* supplies an implementation backed by `AgentSpecSync`, which is the one place that writes an agent.
|
|
56
|
+
*/
|
|
57
|
+
export type WorkflowAgentWriter = {
|
|
58
|
+
/** Creates or updates the Flow agent for this workflow. Returns its ID. */
|
|
59
|
+
PersistFlowAgent(spec: WorkflowSpec, context: WorkflowSyncContext): Promise<string>;
|
|
60
|
+
};
|
|
61
|
+
export type WorkflowSyncResult = {
|
|
62
|
+
Success: boolean;
|
|
63
|
+
/** The Flow agent the workflow's graph persisted as — the handle for everything downstream. */
|
|
64
|
+
AgentID?: string;
|
|
65
|
+
/** Scheduled Jobs created, updated or disabled by this reconciliation. */
|
|
66
|
+
ScheduledJobIDs: string[];
|
|
67
|
+
/** Triggers the spec asked for that this build cannot yet reconcile, stated rather than dropped. */
|
|
68
|
+
Unreconciled: string[];
|
|
69
|
+
ErrorMessage?: string;
|
|
70
|
+
};
|
|
71
|
+
export declare class WorkflowSpecSync {
|
|
72
|
+
private readonly agentWriter;
|
|
73
|
+
constructor(agentWriter?: WorkflowAgentWriter | null);
|
|
74
|
+
/**
|
|
75
|
+
* Reconciles every substrate a workflow owns, so they match the spec.
|
|
76
|
+
*
|
|
77
|
+
* Order matters: the agent is persisted first because a Scheduled Job needs its ID to point at,
|
|
78
|
+
* and a job pointing at an agent that does not exist would be a scheduled no-op — the failure
|
|
79
|
+
* mode where everything looks configured and nothing ever runs.
|
|
80
|
+
*/
|
|
81
|
+
Persist(spec: WorkflowSpec, context: WorkflowSyncContext): Promise<WorkflowSyncResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Brings the workflow's owned trigger rows in line with its spec.
|
|
84
|
+
*
|
|
85
|
+
* A trigger the spec no longer names has its owned row **disabled rather than deleted**. Deleting
|
|
86
|
+
* would destroy the run history attached to it, and a workflow whose schedule someone removed by
|
|
87
|
+
* mistake should be recoverable — the row carries counts, last-run and next-run that are the only
|
|
88
|
+
* record that it ever fired.
|
|
89
|
+
*/
|
|
90
|
+
private reconcileTriggers;
|
|
91
|
+
/** Identity of a schedule within a workflow — cron plus zone, matching `TriggerKey`. */
|
|
92
|
+
private scheduleKey;
|
|
93
|
+
/** The same identity, read back off a persisted job. */
|
|
94
|
+
private scheduleKeyOf;
|
|
95
|
+
/**
|
|
96
|
+
* Binds an entity-change trigger by creating the Entity Action rows the save pipeline already
|
|
97
|
+
* reads.
|
|
98
|
+
*
|
|
99
|
+
* Nothing here teaches the platform a new trick. `HandleEntityActions` has fired entity actions
|
|
100
|
+
* from the save pipeline all along; what was missing was a row saying "when an Invoice is
|
|
101
|
+
* updated, run Execute Agent with this agent". Three rows express that: the `EntityAction`
|
|
102
|
+
* (which entity, which action), the `EntityActionInvocation` (which change fires it), and an
|
|
103
|
+
* `EntityActionParam` carrying the agent to run.
|
|
104
|
+
*
|
|
105
|
+
* Idempotent by lookup rather than by delete-and-recreate: re-saving a workflow must not detach
|
|
106
|
+
* and re-attach a live trigger, because a change landing in that window would be missed.
|
|
107
|
+
*
|
|
108
|
+
* **Scope reconciles onto the binding's own `ScopeEntityID`/`ScopeRecordID`.** Those columns and
|
|
109
|
+
* the engine's scope resolver already exist for exactly this; leaving them unset while the spec
|
|
110
|
+
* declared a scope produced a workflow firing on every record of the entity while its author
|
|
111
|
+
* believed it was watching one. `filter` is refused upstream by `ValidateWorkflowSpec` for the
|
|
112
|
+
* same reason — it cannot be honored yet, so it must not be quietly accepted.
|
|
113
|
+
*/
|
|
114
|
+
private reconcileEntityEvent;
|
|
115
|
+
/**
|
|
116
|
+
* Turn the spec's scope names into the IDs the binding stores.
|
|
117
|
+
*
|
|
118
|
+
* A scope that names an entity the instance does not have is an error rather than a silent
|
|
119
|
+
* widening: "watch this one invoice" degrading to "watch every invoice" is the failure the
|
|
120
|
+
* scope columns exist to prevent.
|
|
121
|
+
*/
|
|
122
|
+
private resolveScope;
|
|
123
|
+
/**
|
|
124
|
+
* Finds or creates the Entity Action binding this workflow needs.
|
|
125
|
+
*
|
|
126
|
+
* **Each workflow owns its own binding row.** `Execute Agent` is one shared action, so every
|
|
127
|
+
* workflow watching a given entity would otherwise land on the same `(EntityID, ActionID)` pair
|
|
128
|
+
* — and reusing that row means rewriting its `AgentID`, which silently repoints the first
|
|
129
|
+
* workflow's trigger at the second workflow's agent. Workflow A keeps looking configured, keeps
|
|
130
|
+
* showing its trigger, and never runs again.
|
|
131
|
+
*
|
|
132
|
+
* That shape was briefly impossible: `UQ_EntityAction_ActionID_EntityID`, added by the v5.37.x
|
|
133
|
+
* junction sweep, permitted one binding per (entity, action). The sweep's own stated scope was
|
|
134
|
+
* "pure junction tables ... with no other meaningful data columns", which `EntityAction` — with
|
|
135
|
+
* Status, Sequence, LoggingMode, scope columns and three owned child collections — never met.
|
|
136
|
+
* `V202608080100__v6.1.x__Drop_EntityAction_Uniqueness` removes it, which also unblocks the
|
|
137
|
+
* ordinary case of one action bound to one entity at two different events with different params.
|
|
138
|
+
*
|
|
139
|
+
* Ownership is therefore matched on the agent and the scope, not on entity + action alone.
|
|
140
|
+
*/
|
|
141
|
+
private upsertEntityAction;
|
|
142
|
+
/**
|
|
143
|
+
* This workflow's own binding at this scope, if it already has one.
|
|
144
|
+
*
|
|
145
|
+
* Ownership lives in the `AgentID` param rather than on the binding row, so candidates are
|
|
146
|
+
* narrowed in SQL by entity + action + scope and then matched on that param. Scope is part of
|
|
147
|
+
* the identity because narrowing a trigger to a different record is a *different* subscription,
|
|
148
|
+
* not an edit of the existing one — matching without it would silently re-point the old binding.
|
|
149
|
+
*/
|
|
150
|
+
private findOwnedEntityAction;
|
|
151
|
+
/** Finds or creates the invocation row that says which change fires the action. */
|
|
152
|
+
private upsertInvocation;
|
|
153
|
+
/**
|
|
154
|
+
* Finds or creates one Entity Action Param binding.
|
|
155
|
+
*
|
|
156
|
+
* `value` is null for value types the platform derives at invocation time (`Entity Object Data`,
|
|
157
|
+
* `Entity Object`, `Entity Field`) — for those the ValueType *is* the instruction.
|
|
158
|
+
*/
|
|
159
|
+
private upsertActionParam;
|
|
160
|
+
private resolveJobTypeID;
|
|
161
|
+
/**
|
|
162
|
+
* Finds the Scheduled Jobs this workflow owns.
|
|
163
|
+
*
|
|
164
|
+
* Matched on a marker inside `Configuration` rather than on name, so renaming a workflow does not
|
|
165
|
+
* orphan its schedule and leave a second one firing alongside the new row.
|
|
166
|
+
*/
|
|
167
|
+
private findOwnedJobs;
|
|
168
|
+
/** Creates or updates one owned Scheduled Job so it matches the trigger. */
|
|
169
|
+
private upsertScheduledJob;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=WorkflowSpecSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowSpecSync.d.ts","sourceRoot":"","sources":["../src/WorkflowSpecSync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,iBAAiB,EAAgC,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAYjG,OAAO,EAOH,KAAK,YAAY,EACpB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,UAAU,CAAC;AAE7C,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAUpD,8DAA8D;AAC9D,MAAM,MAAM,mBAAmB,GAAG;IAC9B,WAAW,EAAE,QAAQ,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B,2EAA2E;IAC3E,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,oGAAoG;IACpG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,qBAAa,gBAAgB;IACb,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,GAAE,mBAAmB,GAAG,IAAW;IAE3E;;;;;;OAMG;IACU,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgCnG;;;;;;;OAOG;YACW,iBAAiB;IA+C/B,wFAAwF;IACxF,OAAO,CAAC,WAAW;IAInB,wDAAwD;IACxD,OAAO,CAAC,aAAa;IAIrB;;;;;;;;;;;;;;;;;;OAkBG;YACW,oBAAoB;IAiDlC;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;;;;;;;;;;;;;OAiBG;YACW,kBAAkB;IA+BhC;;;;;;;OAOG;YACW,qBAAqB;IAoCnC,mFAAmF;YACrE,gBAAgB;IAgC9B;;;;;OAKG;YACW,iBAAiB;YA4CjB,gBAAgB;IAkB9B;;;;;OAKG;YACW,aAAa;IAkB3B,4EAA4E;YAC9D,kBAAkB;CAoCnC"}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Persists a `WorkflowSpec` by **reconciling substrates that already exist**.
|
|
3
|
+
*
|
|
4
|
+
* **The central design constraint: no new storage.** There is no `Workflow` table and there will not
|
|
5
|
+
* be one. A workflow's WHAT is a Flow agent (the graph); its WHEN is a Scheduled Job or an Entity
|
|
6
|
+
* Action binding. Inventing a parallel `Workflow` row would create a second definition of "a
|
|
7
|
+
* scheduled thing", and the scheduler would then have two masters that can disagree — which is
|
|
8
|
+
* exactly the class of divergence this whole program has been removing.
|
|
9
|
+
*
|
|
10
|
+
* So this is a **reconciler**, not a writer. It follows the pattern
|
|
11
|
+
* `MJRecordProcessEntityServer.Save()` already proved: resolve the job type, find the rows this
|
|
12
|
+
* definition owns, then upsert or disable them so the substrate matches the spec. Rows are matched
|
|
13
|
+
* by a marker in their own `Configuration`, which is what makes ownership survive a rename.
|
|
14
|
+
*
|
|
15
|
+
* **Agent persistence crosses a seam.** Writing the Flow agent behind the graph is `AgentSpecSync`'s
|
|
16
|
+
* job — it already owns atomic multi-entity agent writes and the mutation audit. Importing it here
|
|
17
|
+
* would pull the agent-manager package into the execution substrate, so the host injects it instead.
|
|
18
|
+
* A caller with no agent writer still gets correct trigger reconciliation and an honest error rather
|
|
19
|
+
* than a half-persisted workflow.
|
|
20
|
+
*
|
|
21
|
+
* @module @memberjunction/task-graph
|
|
22
|
+
*/
|
|
23
|
+
import { LogError, LogStatus, RunView } from '@memberjunction/core';
|
|
24
|
+
import { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
|
|
25
|
+
import { FormatWorkflowValidationErrors, NormalizeInvocationType, NormalizeTriggers, ValidateWorkflowSpec, } from '@memberjunction/ai-core-plus';
|
|
26
|
+
/**
|
|
27
|
+
* Scheduled Job Type that runs a workflow's Flow agent.
|
|
28
|
+
*
|
|
29
|
+
* `'Agent'` is an existing seeded type backed by `AgentScheduledJobDriver` — a workflow's schedule
|
|
30
|
+
* reuses it rather than introducing a parallel one. `ScheduledJobType.DriverClass` is UNIQUE, so a
|
|
31
|
+
* second type for the same driver is not merely redundant, it is impossible; discovering that is
|
|
32
|
+
* what confirmed the substrate was already there and only the authoring surface was missing.
|
|
33
|
+
*/
|
|
34
|
+
export const RUN_WORKFLOW_JOB_TYPE = 'Agent';
|
|
35
|
+
/** Marker written into an owned row's `Configuration`, so ownership survives a rename. */
|
|
36
|
+
export const WORKFLOW_OWNER_KEY = 'WorkflowAgentID';
|
|
37
|
+
/**
|
|
38
|
+
* The Action an entity-change trigger dispatches to.
|
|
39
|
+
*
|
|
40
|
+
* `Execute Agent` already exists and was written for exactly this: "a concrete dispatch target for
|
|
41
|
+
* `AIAgent.ExposeAsAction`". Entity-action *invocation* is likewise already wired — the save pipeline
|
|
42
|
+
* fires validate / before-save / after-save / before-delete / after-delete through
|
|
43
|
+
* `HandleEntityActions`. So an entity-change trigger needs no new machinery at all; it needs a
|
|
44
|
+
* binding row, which is what this creates.
|
|
45
|
+
*/
|
|
46
|
+
export const EXECUTE_AGENT_ACTION = 'Execute Agent';
|
|
47
|
+
export class WorkflowSpecSync {
|
|
48
|
+
constructor(agentWriter = null) {
|
|
49
|
+
this.agentWriter = agentWriter;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Reconciles every substrate a workflow owns, so they match the spec.
|
|
53
|
+
*
|
|
54
|
+
* Order matters: the agent is persisted first because a Scheduled Job needs its ID to point at,
|
|
55
|
+
* and a job pointing at an agent that does not exist would be a scheduled no-op — the failure
|
|
56
|
+
* mode where everything looks configured and nothing ever runs.
|
|
57
|
+
*/
|
|
58
|
+
async Persist(spec, context) {
|
|
59
|
+
const validation = ValidateWorkflowSpec(spec);
|
|
60
|
+
if (!validation.Valid) {
|
|
61
|
+
const message = `Workflow "${spec?.name}" is invalid:\n${FormatWorkflowValidationErrors(validation.Errors)}`;
|
|
62
|
+
LogError(`[WorkflowSpecSync] ${message}`);
|
|
63
|
+
return { Success: false, ScheduledJobIDs: [], Unreconciled: [], ErrorMessage: message };
|
|
64
|
+
}
|
|
65
|
+
if (!this.agentWriter) {
|
|
66
|
+
const message = 'No workflow agent writer is registered on this host, so the workflow could not be saved. ' +
|
|
67
|
+
'Persisting a workflow requires the agent-authoring package to be loaded.';
|
|
68
|
+
LogError(`[WorkflowSpecSync] ${message}`);
|
|
69
|
+
return { Success: false, ScheduledJobIDs: [], Unreconciled: [], ErrorMessage: message };
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const agentID = await this.agentWriter.PersistFlowAgent(spec, context);
|
|
73
|
+
const { ScheduledJobIDs, Unreconciled } = await this.reconcileTriggers(spec, agentID, context);
|
|
74
|
+
LogStatus(`[WorkflowSpecSync] Saved "${spec.name}" as agent ${agentID}; ` +
|
|
75
|
+
`${ScheduledJobIDs.length} scheduled job(s) reconciled.`);
|
|
76
|
+
return { Success: true, AgentID: agentID, ScheduledJobIDs, Unreconciled };
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
80
|
+
LogError(`[WorkflowSpecSync] Persist failed for "${spec.name}": ${message}`);
|
|
81
|
+
return { Success: false, ScheduledJobIDs: [], Unreconciled: [], ErrorMessage: message };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Brings the workflow's owned trigger rows in line with its spec.
|
|
86
|
+
*
|
|
87
|
+
* A trigger the spec no longer names has its owned row **disabled rather than deleted**. Deleting
|
|
88
|
+
* would destroy the run history attached to it, and a workflow whose schedule someone removed by
|
|
89
|
+
* mistake should be recoverable — the row carries counts, last-run and next-run that are the only
|
|
90
|
+
* record that it ever fired.
|
|
91
|
+
*/
|
|
92
|
+
async reconcileTriggers(spec, agentID, context) {
|
|
93
|
+
const triggers = NormalizeTriggers(spec);
|
|
94
|
+
const schedules = triggers.filter((t) => t.type === 'Schedule');
|
|
95
|
+
const events = triggers.filter((t) => t.type === 'EntityEvent');
|
|
96
|
+
const unreconciled = [];
|
|
97
|
+
for (const event of events) {
|
|
98
|
+
try {
|
|
99
|
+
await this.reconcileEntityEvent(event, agentID, context);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
// Reported, never dropped: a user who asked for "run this when an invoice changes"
|
|
103
|
+
// and got a workflow that never fires has no way to discover why from the UI.
|
|
104
|
+
unreconciled.push(`EntityEvent on ${event.entityName}: ${e instanceof Error ? e.message : String(e)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const typeID = await this.resolveJobTypeID(context);
|
|
108
|
+
const owned = await this.findOwnedJobs(typeID, agentID, context);
|
|
109
|
+
const jobIDs = [];
|
|
110
|
+
const keep = new Set();
|
|
111
|
+
for (const schedule of schedules) {
|
|
112
|
+
const key = this.scheduleKey(schedule);
|
|
113
|
+
keep.add(key);
|
|
114
|
+
const existing = owned.find((j) => this.scheduleKeyOf(j) === key) ?? null;
|
|
115
|
+
jobIDs.push(await this.upsertScheduledJob(spec, agentID, typeID, schedule, existing, context));
|
|
116
|
+
}
|
|
117
|
+
for (const job of owned) {
|
|
118
|
+
if (keep.has(this.scheduleKeyOf(job) ?? ''))
|
|
119
|
+
continue;
|
|
120
|
+
if (job.Status === 'Disabled')
|
|
121
|
+
continue;
|
|
122
|
+
job.Status = 'Disabled';
|
|
123
|
+
if (await job.Save()) {
|
|
124
|
+
jobIDs.push(job.ID);
|
|
125
|
+
LogStatus(`[WorkflowSpecSync] Disabled scheduled job ${job.ID} — its trigger is no longer in the workflow.`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
LogError(`[WorkflowSpecSync] Could not disable scheduled job ${job.ID}: ${job.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { ScheduledJobIDs: jobIDs, Unreconciled: unreconciled };
|
|
132
|
+
}
|
|
133
|
+
/** Identity of a schedule within a workflow — cron plus zone, matching `TriggerKey`. */
|
|
134
|
+
scheduleKey(trigger) {
|
|
135
|
+
return `${trigger.cron}|${trigger.timezone ?? ''}`;
|
|
136
|
+
}
|
|
137
|
+
/** The same identity, read back off a persisted job. */
|
|
138
|
+
scheduleKeyOf(job) {
|
|
139
|
+
return job.CronExpression ? `${job.CronExpression}|${job.Timezone ?? ''}` : null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Binds an entity-change trigger by creating the Entity Action rows the save pipeline already
|
|
143
|
+
* reads.
|
|
144
|
+
*
|
|
145
|
+
* Nothing here teaches the platform a new trick. `HandleEntityActions` has fired entity actions
|
|
146
|
+
* from the save pipeline all along; what was missing was a row saying "when an Invoice is
|
|
147
|
+
* updated, run Execute Agent with this agent". Three rows express that: the `EntityAction`
|
|
148
|
+
* (which entity, which action), the `EntityActionInvocation` (which change fires it), and an
|
|
149
|
+
* `EntityActionParam` carrying the agent to run.
|
|
150
|
+
*
|
|
151
|
+
* Idempotent by lookup rather than by delete-and-recreate: re-saving a workflow must not detach
|
|
152
|
+
* and re-attach a live trigger, because a change landing in that window would be missed.
|
|
153
|
+
*
|
|
154
|
+
* **Scope reconciles onto the binding's own `ScopeEntityID`/`ScopeRecordID`.** Those columns and
|
|
155
|
+
* the engine's scope resolver already exist for exactly this; leaving them unset while the spec
|
|
156
|
+
* declared a scope produced a workflow firing on every record of the entity while its author
|
|
157
|
+
* believed it was watching one. `filter` is refused upstream by `ValidateWorkflowSpec` for the
|
|
158
|
+
* same reason — it cannot be honored yet, so it must not be quietly accepted.
|
|
159
|
+
*/
|
|
160
|
+
async reconcileEntityEvent(trigger, agentID, context) {
|
|
161
|
+
const rv = RunView.FromMetadataProvider(context.Provider);
|
|
162
|
+
const entity = context.Provider.EntityByName(trigger.entityName);
|
|
163
|
+
if (!entity)
|
|
164
|
+
throw new Error(`entity "${trigger.entityName}" not found in metadata`);
|
|
165
|
+
const scope = this.resolveScope(trigger, context);
|
|
166
|
+
const actionResult = await rv.RunView({ EntityName: 'MJ: Actions', ExtraFilter: `Name='${EXECUTE_AGENT_ACTION}'`, ResultType: 'entity_object' }, context.ContextUser);
|
|
167
|
+
const action = actionResult.Results?.[0];
|
|
168
|
+
if (!action)
|
|
169
|
+
throw new Error(`the '${EXECUTE_AGENT_ACTION}' action is not present — has the metadata seed been pushed?`);
|
|
170
|
+
// Resolved through the shared normalizer so the shorthand an author writes ("Update") and
|
|
171
|
+
// the name the platform fires ("AfterUpdate") cannot drift apart.
|
|
172
|
+
const invocationName = NormalizeInvocationType(trigger.invocationType);
|
|
173
|
+
if (!invocationName)
|
|
174
|
+
throw new Error(`invocation type "${trigger.invocationType}" is not one this platform fires`);
|
|
175
|
+
const invocationResult = await rv.RunView({
|
|
176
|
+
EntityName: 'MJ: Entity Action Invocation Types',
|
|
177
|
+
ExtraFilter: `Name='${invocationName}'`,
|
|
178
|
+
ResultType: 'entity_object',
|
|
179
|
+
}, context.ContextUser);
|
|
180
|
+
const invocationType = invocationResult.Results?.[0];
|
|
181
|
+
if (!invocationType)
|
|
182
|
+
throw new Error(`invocation type "${invocationName}" is not seeded`);
|
|
183
|
+
const entityAction = await this.upsertEntityAction(entity.ID, action.ID, agentID, scope, context);
|
|
184
|
+
await this.upsertInvocation(entityAction.ID, invocationType.ID, context);
|
|
185
|
+
// Which agent to run — fixed for the life of the binding.
|
|
186
|
+
await this.upsertActionParam(entityAction.ID, action.ID, 'AgentID', 'Static', agentID, context);
|
|
187
|
+
// WHICH RECORD changed. Without this the trigger fires and the agent has no idea what it is
|
|
188
|
+
// looking at — a workflow that runs on every invoice update knowing nothing about any
|
|
189
|
+
// invoice. `Entity Object Data` rather than `Entity Object` is not a preference: a
|
|
190
|
+
// BaseEntity serializes to `{}` because its fields are getters, not enumerable own
|
|
191
|
+
// properties, so the live instance would arrive empty. `GetAll()` is what survives the wire.
|
|
192
|
+
await this.upsertActionParam(entityAction.ID, action.ID, 'Data', 'Entity Object Data', null, context);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Turn the spec's scope names into the IDs the binding stores.
|
|
196
|
+
*
|
|
197
|
+
* A scope that names an entity the instance does not have is an error rather than a silent
|
|
198
|
+
* widening: "watch this one invoice" degrading to "watch every invoice" is the failure the
|
|
199
|
+
* scope columns exist to prevent.
|
|
200
|
+
*/
|
|
201
|
+
resolveScope(trigger, context) {
|
|
202
|
+
if (!trigger.scopeEntityName?.trim()) {
|
|
203
|
+
return { EntityID: null, RecordID: null };
|
|
204
|
+
}
|
|
205
|
+
const scopeEntity = context.Provider.EntityByName(trigger.scopeEntityName);
|
|
206
|
+
if (!scopeEntity)
|
|
207
|
+
throw new Error(`scope entity "${trigger.scopeEntityName}" not found in metadata`);
|
|
208
|
+
return { EntityID: scopeEntity.ID, RecordID: trigger.scopeRecordID?.trim() || null };
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Finds or creates the Entity Action binding this workflow needs.
|
|
212
|
+
*
|
|
213
|
+
* **Each workflow owns its own binding row.** `Execute Agent` is one shared action, so every
|
|
214
|
+
* workflow watching a given entity would otherwise land on the same `(EntityID, ActionID)` pair
|
|
215
|
+
* — and reusing that row means rewriting its `AgentID`, which silently repoints the first
|
|
216
|
+
* workflow's trigger at the second workflow's agent. Workflow A keeps looking configured, keeps
|
|
217
|
+
* showing its trigger, and never runs again.
|
|
218
|
+
*
|
|
219
|
+
* That shape was briefly impossible: `UQ_EntityAction_ActionID_EntityID`, added by the v5.37.x
|
|
220
|
+
* junction sweep, permitted one binding per (entity, action). The sweep's own stated scope was
|
|
221
|
+
* "pure junction tables ... with no other meaningful data columns", which `EntityAction` — with
|
|
222
|
+
* Status, Sequence, LoggingMode, scope columns and three owned child collections — never met.
|
|
223
|
+
* `V202608080100__v6.1.x__Drop_EntityAction_Uniqueness` removes it, which also unblocks the
|
|
224
|
+
* ordinary case of one action bound to one entity at two different events with different params.
|
|
225
|
+
*
|
|
226
|
+
* Ownership is therefore matched on the agent and the scope, not on entity + action alone.
|
|
227
|
+
*/
|
|
228
|
+
async upsertEntityAction(entityID, actionID, agentID, scope, context) {
|
|
229
|
+
const existing = await this.findOwnedEntityAction(entityID, actionID, agentID, scope, context);
|
|
230
|
+
if (existing) {
|
|
231
|
+
if (existing.Status !== 'Active') {
|
|
232
|
+
existing.Status = 'Active';
|
|
233
|
+
if (!(await existing.Save())) {
|
|
234
|
+
throw new Error(`could not reactivate the entity-action binding: ${existing.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return existing;
|
|
238
|
+
}
|
|
239
|
+
const row = await context.Provider.GetEntityObject('MJ: Entity Actions', context.ContextUser);
|
|
240
|
+
row.NewRecord();
|
|
241
|
+
row.EntityID = entityID;
|
|
242
|
+
row.ActionID = actionID;
|
|
243
|
+
row.ScopeEntityID = scope.EntityID;
|
|
244
|
+
row.ScopeRecordID = scope.RecordID;
|
|
245
|
+
row.Status = 'Active';
|
|
246
|
+
if (!(await row.Save())) {
|
|
247
|
+
throw new Error(`could not create the entity-action binding: ${row.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
248
|
+
}
|
|
249
|
+
return row;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* This workflow's own binding at this scope, if it already has one.
|
|
253
|
+
*
|
|
254
|
+
* Ownership lives in the `AgentID` param rather than on the binding row, so candidates are
|
|
255
|
+
* narrowed in SQL by entity + action + scope and then matched on that param. Scope is part of
|
|
256
|
+
* the identity because narrowing a trigger to a different record is a *different* subscription,
|
|
257
|
+
* not an edit of the existing one — matching without it would silently re-point the old binding.
|
|
258
|
+
*/
|
|
259
|
+
async findOwnedEntityAction(entityID, actionID, agentID, scope, context) {
|
|
260
|
+
const rv = RunView.FromMetadataProvider(context.Provider);
|
|
261
|
+
const scopeFilter = `AND ScopeEntityID ${scope.EntityID ? `= '${scope.EntityID}'` : 'IS NULL'} ` +
|
|
262
|
+
`AND ScopeRecordID ${scope.RecordID ? `= '${scope.RecordID}'` : 'IS NULL'}`;
|
|
263
|
+
const result = await rv.RunView({
|
|
264
|
+
EntityName: 'MJ: Entity Actions',
|
|
265
|
+
ExtraFilter: `EntityID='${entityID}' AND ActionID='${actionID}' ${scopeFilter}`,
|
|
266
|
+
ResultType: 'entity_object',
|
|
267
|
+
}, context.ContextUser);
|
|
268
|
+
const candidates = result.Results ?? [];
|
|
269
|
+
if (candidates.length === 0)
|
|
270
|
+
return null;
|
|
271
|
+
const params = await rv.RunView({
|
|
272
|
+
EntityName: 'MJ: Entity Action Params',
|
|
273
|
+
ExtraFilter: `ActionParam='AgentID' AND EntityActionID IN (${candidates.map((c) => `'${c.ID}'`).join(',')})`,
|
|
274
|
+
ResultType: 'entity_object',
|
|
275
|
+
}, context.ContextUser);
|
|
276
|
+
const mine = (params.Results ?? []).find((p) => p.Value != null && UUIDsEqual(p.Value, agentID));
|
|
277
|
+
return mine ? candidates.find((c) => UUIDsEqual(c.ID, mine.EntityActionID)) ?? null : null;
|
|
278
|
+
}
|
|
279
|
+
/** Finds or creates the invocation row that says which change fires the action. */
|
|
280
|
+
async upsertInvocation(entityActionID, invocationTypeID, context) {
|
|
281
|
+
const result = await RunView.FromMetadataProvider(context.Provider).RunView({
|
|
282
|
+
EntityName: 'MJ: Entity Action Invocations',
|
|
283
|
+
ExtraFilter: `EntityActionID='${entityActionID}' AND InvocationTypeID='${invocationTypeID}'`,
|
|
284
|
+
ResultType: 'entity_object',
|
|
285
|
+
}, context.ContextUser);
|
|
286
|
+
const existing = result.Results?.[0];
|
|
287
|
+
if (existing) {
|
|
288
|
+
if (existing.Status !== 'Active') {
|
|
289
|
+
existing.Status = 'Active';
|
|
290
|
+
await existing.Save();
|
|
291
|
+
}
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const row = await context.Provider.GetEntityObject('MJ: Entity Action Invocations', context.ContextUser);
|
|
295
|
+
row.NewRecord();
|
|
296
|
+
row.EntityActionID = entityActionID;
|
|
297
|
+
row.InvocationTypeID = invocationTypeID;
|
|
298
|
+
row.Status = 'Active';
|
|
299
|
+
if (!(await row.Save())) {
|
|
300
|
+
throw new Error(`could not create the invocation binding: ${row.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Finds or creates one Entity Action Param binding.
|
|
305
|
+
*
|
|
306
|
+
* `value` is null for value types the platform derives at invocation time (`Entity Object Data`,
|
|
307
|
+
* `Entity Object`, `Entity Field`) — for those the ValueType *is* the instruction.
|
|
308
|
+
*/
|
|
309
|
+
async upsertActionParam(entityActionID, actionID, paramName, valueType, value, context) {
|
|
310
|
+
const rv = RunView.FromMetadataProvider(context.Provider);
|
|
311
|
+
const paramResult = await rv.RunView({
|
|
312
|
+
EntityName: 'MJ: Action Params',
|
|
313
|
+
ExtraFilter: `ActionID='${actionID}' AND Name='${paramName}'`,
|
|
314
|
+
ResultType: 'entity_object',
|
|
315
|
+
}, context.ContextUser);
|
|
316
|
+
const actionParam = paramResult.Results?.[0];
|
|
317
|
+
if (!actionParam) {
|
|
318
|
+
// Surfaced rather than left as a trigger that fires and does nothing useful.
|
|
319
|
+
throw new Error(`the '${EXECUTE_AGENT_ACTION}' action has no ${paramName} parameter to bind`);
|
|
320
|
+
}
|
|
321
|
+
const existingResult = await rv.RunView({
|
|
322
|
+
EntityName: 'MJ: Entity Action Params',
|
|
323
|
+
ExtraFilter: `EntityActionID='${entityActionID}' AND ActionParamID='${actionParam.ID}'`,
|
|
324
|
+
ResultType: 'entity_object',
|
|
325
|
+
}, context.ContextUser);
|
|
326
|
+
const row = existingResult.Results?.[0]
|
|
327
|
+
?? await context.Provider.GetEntityObject('MJ: Entity Action Params', context.ContextUser);
|
|
328
|
+
if (!existingResult.Results?.[0])
|
|
329
|
+
row.NewRecord();
|
|
330
|
+
row.EntityActionID = entityActionID;
|
|
331
|
+
row.ActionParamID = actionParam.ID;
|
|
332
|
+
row.ValueType = valueType;
|
|
333
|
+
row.Value = value;
|
|
334
|
+
if (!(await row.Save())) {
|
|
335
|
+
throw new Error(`could not bind ${paramName} to the trigger: ${row.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async resolveJobTypeID(context) {
|
|
339
|
+
const result = await RunView.FromMetadataProvider(context.Provider).RunView({
|
|
340
|
+
EntityName: 'MJ: Scheduled Job Types',
|
|
341
|
+
ExtraFilter: `Name='${RUN_WORKFLOW_JOB_TYPE}'`,
|
|
342
|
+
Fields: ['ID'],
|
|
343
|
+
ResultType: 'simple',
|
|
344
|
+
}, context.ContextUser);
|
|
345
|
+
if (!result.Success || (result.Results?.length ?? 0) === 0) {
|
|
346
|
+
throw new Error(`Scheduled Job Type '${RUN_WORKFLOW_JOB_TYPE}' not found — has the metadata seed been pushed?`);
|
|
347
|
+
}
|
|
348
|
+
return result.Results[0].ID;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Finds the Scheduled Jobs this workflow owns.
|
|
352
|
+
*
|
|
353
|
+
* Matched on a marker inside `Configuration` rather than on name, so renaming a workflow does not
|
|
354
|
+
* orphan its schedule and leave a second one firing alongside the new row.
|
|
355
|
+
*/
|
|
356
|
+
async findOwnedJobs(typeID, agentID, context) {
|
|
357
|
+
const result = await RunView.FromMetadataProvider(context.Provider).RunView({ EntityName: 'MJ: Scheduled Jobs', ExtraFilter: `JobTypeID='${typeID}'`, ResultType: 'entity_object' }, context.ContextUser);
|
|
358
|
+
if (!result.Success)
|
|
359
|
+
return [];
|
|
360
|
+
return (result.Results ?? []).filter((job) => {
|
|
361
|
+
const cfg = SafeJSONParse(job.Configuration ?? '');
|
|
362
|
+
const owner = cfg?.[WORKFLOW_OWNER_KEY];
|
|
363
|
+
return !!owner && UUIDsEqual(owner, agentID);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/** Creates or updates one owned Scheduled Job so it matches the trigger. */
|
|
367
|
+
async upsertScheduledJob(spec, agentID, typeID, trigger, existing, context) {
|
|
368
|
+
const job = existing ?? await context.Provider.GetEntityObject('MJ: Scheduled Jobs', context.ContextUser);
|
|
369
|
+
if (!existing) {
|
|
370
|
+
job.NewRecord();
|
|
371
|
+
if (context.ContextUser?.ID)
|
|
372
|
+
job.OwnerUserID = context.ContextUser.ID;
|
|
373
|
+
}
|
|
374
|
+
job.JobTypeID = typeID;
|
|
375
|
+
job.Name = `Workflow: ${spec.name}`;
|
|
376
|
+
job.Description = spec.description ?? null;
|
|
377
|
+
job.CronExpression = trigger.cron;
|
|
378
|
+
job.Timezone = trigger.timezone ?? null;
|
|
379
|
+
job.Configuration = JSON.stringify({ [WORKFLOW_OWNER_KEY]: agentID, AgentID: agentID });
|
|
380
|
+
// The spec's own status governs. A Draft or Paused workflow persists its schedule but does
|
|
381
|
+
// not fire — which is what lets someone build the whole thing, look at it, and then turn it on.
|
|
382
|
+
job.Status = spec.status === 'Active' ? 'Active' : 'Disabled';
|
|
383
|
+
if (spec.notifications) {
|
|
384
|
+
job.NotifyOnFailure = true;
|
|
385
|
+
job.NotifyOnSuccess = spec.notifications.condition === 'Always';
|
|
386
|
+
}
|
|
387
|
+
if (!(await job.Save())) {
|
|
388
|
+
throw new Error(`Could not save the schedule for workflow "${spec.name}": ${job.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
389
|
+
}
|
|
390
|
+
return job.ID;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=WorkflowSpecSync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowSpecSync.js","sourceRoot":"","sources":["../src/WorkflowSpecSync.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @memberjunction/task-graph — producer-agnostic submission and durable execution of
|
|
3
|
+
* dependency-ordered task graphs.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately not AI-prefixed (D11): an LLM, deterministic code, or a human UI can all construct
|
|
6
|
+
* and submit a DAG. The graph semantics themselves live in the pure algorithms in
|
|
7
|
+
* `@memberjunction/ai-core-plus`, which both this dispatcher and the in-run executor consume.
|
|
8
|
+
*/
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
export * from './TaskGraphService.js';
|
|
11
|
+
export * from './TaskClaimStore.js';
|
|
12
|
+
export * from './DispatcherConditionEvaluator.js';
|
|
13
|
+
export * from './TaskGraphDispatcher.js';
|
|
14
|
+
export * from './TaskGraphSubmitterImpl.js';
|
|
15
|
+
export * from './WorkflowSpecSync.js';
|
|
16
|
+
export * from './operations/TaskGraphOperations.js';
|
|
17
|
+
export * from './operations/WorkflowOperations.js';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @memberjunction/task-graph — producer-agnostic submission and durable execution of
|
|
3
|
+
* dependency-ordered task graphs.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately not AI-prefixed (D11): an LLM, deterministic code, or a human UI can all construct
|
|
6
|
+
* and submit a DAG. The graph semantics themselves live in the pure algorithms in
|
|
7
|
+
* `@memberjunction/ai-core-plus`, which both this dispatcher and the in-run executor consume.
|
|
8
|
+
*/
|
|
9
|
+
export * from './types.js';
|
|
10
|
+
export * from './TaskGraphService.js';
|
|
11
|
+
export * from './TaskClaimStore.js';
|
|
12
|
+
export * from './DispatcherConditionEvaluator.js';
|
|
13
|
+
export * from './TaskGraphDispatcher.js';
|
|
14
|
+
export * from './TaskGraphSubmitterImpl.js';
|
|
15
|
+
export * from './WorkflowSpecSync.js';
|
|
16
|
+
export * from './operations/TaskGraphOperations.js';
|
|
17
|
+
export * from './operations/WorkflowOperations.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC"}
|