@contractspec/integration.workflow-devkit 0.1.3 → 0.1.4
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/dist/agent-adapter.js +1 -79
- package/dist/browser/agent-adapter.js +1 -79
- package/dist/browser/chat-routes.js +1 -100
- package/dist/browser/compiler.js +14 -141
- package/dist/browser/helpers.js +1 -80
- package/dist/browser/index.js +14 -443
- package/dist/browser/next.js +1 -8
- package/dist/browser/runtime.js +1 -180
- package/dist/chat-routes.js +1 -100
- package/dist/compiler.js +14 -141
- package/dist/helpers.js +1 -80
- package/dist/index.js +14 -443
- package/dist/next.js +1 -8
- package/dist/node/agent-adapter.js +1 -79
- package/dist/node/chat-routes.js +1 -100
- package/dist/node/compiler.js +14 -141
- package/dist/node/helpers.js +1 -80
- package/dist/node/index.js +14 -443
- package/dist/node/next.js +1 -8
- package/dist/node/runtime.js +1 -180
- package/dist/runtime.js +1 -180
- package/package.json +9 -9
package/dist/node/runtime.js
CHANGED
|
@@ -1,180 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { evaluateExpression } from "@contractspec/lib.contracts-spec/workflow/expression";
|
|
3
|
-
function inferWorkflowDevkitBehavior(step) {
|
|
4
|
-
return step.runtime?.workflowDevkit?.behavior ?? step.type;
|
|
5
|
-
}
|
|
6
|
-
function resolveWorkflowDevkitEntryStepId(spec) {
|
|
7
|
-
const entryStepId = spec.definition.entryStepId ?? spec.definition.steps[0]?.id;
|
|
8
|
-
if (!entryStepId) {
|
|
9
|
-
throw new Error(`Workflow ${spec.meta.key}.v${spec.meta.version} does not define an entry step.`);
|
|
10
|
-
}
|
|
11
|
-
return entryStepId;
|
|
12
|
-
}
|
|
13
|
-
function resolveWorkflowDevkitRunIdentity(spec, runIdentity) {
|
|
14
|
-
if (runIdentity) {
|
|
15
|
-
return runIdentity;
|
|
16
|
-
}
|
|
17
|
-
const strategy = spec.runtime?.workflowDevkit?.runIdentity?.strategy ?? "meta-key-version";
|
|
18
|
-
const prefix = spec.runtime?.workflowDevkit?.runIdentity?.prefix;
|
|
19
|
-
const baseIdentity = strategy === "meta-key-version" ? `${spec.meta.key}.v${spec.meta.version}` : `${spec.meta.key}.v${spec.meta.version}`;
|
|
20
|
-
return prefix ? `${prefix}:${baseIdentity}` : baseIdentity;
|
|
21
|
-
}
|
|
22
|
-
function resolveWorkflowDevkitWaitToken(spec, step, runIdentity) {
|
|
23
|
-
const runtime = step.runtime?.workflowDevkit;
|
|
24
|
-
if (!runtime) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
const explicitToken = runtime.hookWait?.token ?? runtime.webhookWait?.token ?? runtime.approvalWait?.token ?? runtime.streamSession?.followUpToken;
|
|
28
|
-
if (explicitToken) {
|
|
29
|
-
return explicitToken;
|
|
30
|
-
}
|
|
31
|
-
const tokenStrategy = spec.runtime?.workflowDevkit?.hookTokens?.strategy ?? "deterministic";
|
|
32
|
-
const prefix = spec.runtime?.workflowDevkit?.hookTokens?.prefix ?? spec.meta.key;
|
|
33
|
-
const stableStepId = sanitizeIdentifier(step.id);
|
|
34
|
-
if (tokenStrategy === "session-scoped") {
|
|
35
|
-
const resolvedRunIdentity = sanitizeIdentifier(resolveWorkflowDevkitRunIdentity(spec, runIdentity));
|
|
36
|
-
return `${prefix}:${resolvedRunIdentity}:${stableStepId}`;
|
|
37
|
-
}
|
|
38
|
-
if (tokenStrategy === "step-scoped") {
|
|
39
|
-
return `${prefix}:v${spec.meta.version}:${stableStepId}`;
|
|
40
|
-
}
|
|
41
|
-
return `${prefix}:${stableStepId}`;
|
|
42
|
-
}
|
|
43
|
-
function resolveWorkflowDevkitNextStepId(spec, step, data, input, output) {
|
|
44
|
-
const transitions = spec.definition.transitions.filter((transition) => transition.from === step.id);
|
|
45
|
-
for (const transition of transitions) {
|
|
46
|
-
if (evaluateExpression(transition.condition, {
|
|
47
|
-
data,
|
|
48
|
-
input,
|
|
49
|
-
output
|
|
50
|
-
})) {
|
|
51
|
-
return transition.to;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
function mergeWorkflowDevkitData(current, input, output) {
|
|
57
|
-
const next = { ...current };
|
|
58
|
-
if (isRecord(input)) {
|
|
59
|
-
Object.assign(next, input);
|
|
60
|
-
}
|
|
61
|
-
if (isRecord(output)) {
|
|
62
|
-
Object.assign(next, output);
|
|
63
|
-
}
|
|
64
|
-
return next;
|
|
65
|
-
}
|
|
66
|
-
function sanitizeIdentifier(value) {
|
|
67
|
-
return value.replace(/[^a-zA-Z0-9_-]+/g, "-");
|
|
68
|
-
}
|
|
69
|
-
function isRecord(value) {
|
|
70
|
-
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/runtime.ts
|
|
74
|
-
async function runWorkflowSpecWithWorkflowDevkit(options) {
|
|
75
|
-
const history = [];
|
|
76
|
-
let currentStepId = resolveWorkflowDevkitEntryStepId(options.spec);
|
|
77
|
-
let data = { ...options.initialData ?? {} };
|
|
78
|
-
let input = options.initialData;
|
|
79
|
-
while (currentStepId) {
|
|
80
|
-
const step = lookupStep(options.spec, currentStepId);
|
|
81
|
-
const runtime = step.runtime?.workflowDevkit;
|
|
82
|
-
const context = {
|
|
83
|
-
data,
|
|
84
|
-
input,
|
|
85
|
-
runIdentity: options.runIdentity,
|
|
86
|
-
runtime,
|
|
87
|
-
spec: options.spec,
|
|
88
|
-
step
|
|
89
|
-
};
|
|
90
|
-
const behavior = inferWorkflowDevkitBehavior(step);
|
|
91
|
-
const token = resolveWorkflowDevkitWaitToken(options.spec, step, options.runIdentity);
|
|
92
|
-
const output = await executeWorkflowDevkitBehavior(behavior, context, token, options.bridge, options.primitives);
|
|
93
|
-
history.push({
|
|
94
|
-
behavior,
|
|
95
|
-
input,
|
|
96
|
-
output,
|
|
97
|
-
stepId: step.id,
|
|
98
|
-
token
|
|
99
|
-
});
|
|
100
|
-
data = mergeWorkflowDevkitData(data, input, output);
|
|
101
|
-
const nextStepId = resolveWorkflowDevkitNextStepId(options.spec, step, data, input, output);
|
|
102
|
-
if (!nextStepId) {
|
|
103
|
-
return {
|
|
104
|
-
currentStep: null,
|
|
105
|
-
data,
|
|
106
|
-
history,
|
|
107
|
-
status: "completed"
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
currentStepId = nextStepId;
|
|
111
|
-
input = output;
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
currentStep: null,
|
|
115
|
-
data,
|
|
116
|
-
history,
|
|
117
|
-
status: "completed"
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
async function executeWorkflowDevkitBehavior(behavior, context, token, bridge, primitives) {
|
|
121
|
-
switch (behavior) {
|
|
122
|
-
case "sleep":
|
|
123
|
-
if (!context.runtime?.sleep?.duration) {
|
|
124
|
-
throw new Error(`Step "${context.step.id}" is missing sleep.duration.`);
|
|
125
|
-
}
|
|
126
|
-
await primitives.sleep(context.runtime.sleep.duration);
|
|
127
|
-
return { sleptFor: context.runtime.sleep.duration };
|
|
128
|
-
case "hookWait":
|
|
129
|
-
return awaitExternalWait(context, token, bridge?.onExternalWait, primitives.createHook);
|
|
130
|
-
case "webhookWait":
|
|
131
|
-
return awaitExternalWait(context, token, bridge?.onExternalWait, primitives.createWebhook ?? primitives.createHook, context.runtime?.webhookWait?.path, context.runtime?.webhookWait?.method);
|
|
132
|
-
case "approvalWait":
|
|
133
|
-
return awaitExternalWait(context, token, bridge?.onApprovalRequested, primitives.createHook);
|
|
134
|
-
case "streamSession":
|
|
135
|
-
return awaitExternalWait(context, token, bridge?.onStreamSession, primitives.createHook);
|
|
136
|
-
case "automation":
|
|
137
|
-
if (!bridge?.executeAutomationStep) {
|
|
138
|
-
throw new Error("Workflow DevKit bridge requires executeAutomationStep for automation steps.");
|
|
139
|
-
}
|
|
140
|
-
return bridge.executeAutomationStep(context);
|
|
141
|
-
case "human":
|
|
142
|
-
if (!bridge?.awaitHumanInput) {
|
|
143
|
-
throw new Error("Workflow DevKit bridge requires awaitHumanInput for human steps without explicit wait behavior.");
|
|
144
|
-
}
|
|
145
|
-
return bridge.awaitHumanInput(context);
|
|
146
|
-
case "decision":
|
|
147
|
-
return bridge?.executeDecisionStep ? bridge.executeDecisionStep(context) : context.input;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
async function awaitExternalWait(context, token, notifier, factory, path, method) {
|
|
151
|
-
if (!token) {
|
|
152
|
-
throw new Error(`Step "${context.step.id}" requires a Workflow DevKit wait token.`);
|
|
153
|
-
}
|
|
154
|
-
const behavior = context.runtime?.behavior;
|
|
155
|
-
if (behavior !== "approvalWait" && behavior !== "hookWait" && behavior !== "streamSession" && behavior !== "webhookWait") {
|
|
156
|
-
throw new Error(`Step "${context.step.id}" is not configured with an external wait behavior.`);
|
|
157
|
-
}
|
|
158
|
-
const waitContext = {
|
|
159
|
-
...context,
|
|
160
|
-
behavior,
|
|
161
|
-
token
|
|
162
|
-
};
|
|
163
|
-
await notifier?.(waitContext);
|
|
164
|
-
const hook = factory({ method, path, token });
|
|
165
|
-
try {
|
|
166
|
-
return await hook;
|
|
167
|
-
} finally {
|
|
168
|
-
await hook.dispose?.();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function lookupStep(spec, stepId) {
|
|
172
|
-
const step = spec.definition.steps.find((candidate) => candidate.id === stepId);
|
|
173
|
-
if (!step) {
|
|
174
|
-
throw new Error(`Step "${stepId}" not found in workflow ${spec.meta.key}.v${spec.meta.version}.`);
|
|
175
|
-
}
|
|
176
|
-
return step;
|
|
177
|
-
}
|
|
178
|
-
export {
|
|
179
|
-
runWorkflowSpecWithWorkflowDevkit
|
|
180
|
-
};
|
|
1
|
+
import{evaluateExpression as C}from"@contractspec/lib.contracts-spec/workflow/expression";function X(j){return j.runtime?.workflowDevkit?.behavior??j.type}function Y(j){let q=j.definition.entryStepId??j.definition.steps[0]?.id;if(!q)throw Error(`Workflow ${j.meta.key}.v${j.meta.version} does not define an entry step.`);return q}function N(j,q){if(q)return q;let F=j.runtime?.workflowDevkit?.runIdentity?.strategy??"meta-key-version",A=j.runtime?.workflowDevkit?.runIdentity?.prefix,G=F==="meta-key-version"?`${j.meta.key}.v${j.meta.version}`:`${j.meta.key}.v${j.meta.version}`;return A?`${A}:${G}`:G}function Z(j,q,F){let A=q.runtime?.workflowDevkit;if(!A)return;let G=A.hookWait?.token??A.webhookWait?.token??A.approvalWait?.token??A.streamSession?.followUpToken;if(G)return G;let J=j.runtime?.workflowDevkit?.hookTokens?.strategy??"deterministic",H=j.runtime?.workflowDevkit?.hookTokens?.prefix??j.meta.key,K=U(q.id);if(J==="session-scoped"){let L=U(N(j,F));return`${H}:${L}:${K}`}if(J==="step-scoped")return`${H}:v${j.meta.version}:${K}`;return`${H}:${K}`}function _(j,q,F,A,G){let J=j.definition.transitions.filter((H)=>H.from===q.id);for(let H of J)if(C(H.condition,{data:F,input:A,output:G}))return H.to;return null}function $(j,q,F){let A={...j};if(V(q))Object.assign(A,q);if(V(F))Object.assign(A,F);return A}function U(j){return j.replace(/[^a-zA-Z0-9_-]+/g,"-")}function V(j){return j!=null&&typeof j==="object"&&!Array.isArray(j)}async function D(j){let q=[],F=Y(j.spec),A={...j.initialData??{}},G=j.initialData;while(F){let J=B(j.spec,F),H=J.runtime?.workflowDevkit,K={data:A,input:G,runIdentity:j.runIdentity,runtime:H,spec:j.spec,step:J},L=X(J),P=Z(j.spec,J,j.runIdentity),M=await z(L,K,P,j.bridge,j.primitives);q.push({behavior:L,input:G,output:M,stepId:J.id,token:P}),A=$(A,G,M);let Q=_(j.spec,J,A,G,M);if(!Q)return{currentStep:null,data:A,history:q,status:"completed"};F=Q,G=M}return{currentStep:null,data:A,history:q,status:"completed"}}async function z(j,q,F,A,G){switch(j){case"sleep":if(!q.runtime?.sleep?.duration)throw Error(`Step "${q.step.id}" is missing sleep.duration.`);return await G.sleep(q.runtime.sleep.duration),{sleptFor:q.runtime.sleep.duration};case"hookWait":return O(q,F,A?.onExternalWait,G.createHook);case"webhookWait":return O(q,F,A?.onExternalWait,G.createWebhook??G.createHook,q.runtime?.webhookWait?.path,q.runtime?.webhookWait?.method);case"approvalWait":return O(q,F,A?.onApprovalRequested,G.createHook);case"streamSession":return O(q,F,A?.onStreamSession,G.createHook);case"automation":if(!A?.executeAutomationStep)throw Error("Workflow DevKit bridge requires executeAutomationStep for automation steps.");return A.executeAutomationStep(q);case"human":if(!A?.awaitHumanInput)throw Error("Workflow DevKit bridge requires awaitHumanInput for human steps without explicit wait behavior.");return A.awaitHumanInput(q);case"decision":return A?.executeDecisionStep?A.executeDecisionStep(q):q.input}}async function O(j,q,F,A,G,J){if(!q)throw Error(`Step "${j.step.id}" requires a Workflow DevKit wait token.`);let H=j.runtime?.behavior;if(H!=="approvalWait"&&H!=="hookWait"&&H!=="streamSession"&&H!=="webhookWait")throw Error(`Step "${j.step.id}" is not configured with an external wait behavior.`);let K={...j,behavior:H,token:q};await F?.(K);let L=A({method:J,path:G,token:q});try{return await L}finally{await L.dispose?.()}}function B(j,q){let F=j.definition.steps.find((A)=>A.id===q);if(!F)throw Error(`Step "${q}" not found in workflow ${j.meta.key}.v${j.meta.version}.`);return F}export{D as runWorkflowSpecWithWorkflowDevkit};
|
package/dist/runtime.js
CHANGED
|
@@ -1,181 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
import { evaluateExpression } from "@contractspec/lib.contracts-spec/workflow/expression";
|
|
4
|
-
function inferWorkflowDevkitBehavior(step) {
|
|
5
|
-
return step.runtime?.workflowDevkit?.behavior ?? step.type;
|
|
6
|
-
}
|
|
7
|
-
function resolveWorkflowDevkitEntryStepId(spec) {
|
|
8
|
-
const entryStepId = spec.definition.entryStepId ?? spec.definition.steps[0]?.id;
|
|
9
|
-
if (!entryStepId) {
|
|
10
|
-
throw new Error(`Workflow ${spec.meta.key}.v${spec.meta.version} does not define an entry step.`);
|
|
11
|
-
}
|
|
12
|
-
return entryStepId;
|
|
13
|
-
}
|
|
14
|
-
function resolveWorkflowDevkitRunIdentity(spec, runIdentity) {
|
|
15
|
-
if (runIdentity) {
|
|
16
|
-
return runIdentity;
|
|
17
|
-
}
|
|
18
|
-
const strategy = spec.runtime?.workflowDevkit?.runIdentity?.strategy ?? "meta-key-version";
|
|
19
|
-
const prefix = spec.runtime?.workflowDevkit?.runIdentity?.prefix;
|
|
20
|
-
const baseIdentity = strategy === "meta-key-version" ? `${spec.meta.key}.v${spec.meta.version}` : `${spec.meta.key}.v${spec.meta.version}`;
|
|
21
|
-
return prefix ? `${prefix}:${baseIdentity}` : baseIdentity;
|
|
22
|
-
}
|
|
23
|
-
function resolveWorkflowDevkitWaitToken(spec, step, runIdentity) {
|
|
24
|
-
const runtime = step.runtime?.workflowDevkit;
|
|
25
|
-
if (!runtime) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const explicitToken = runtime.hookWait?.token ?? runtime.webhookWait?.token ?? runtime.approvalWait?.token ?? runtime.streamSession?.followUpToken;
|
|
29
|
-
if (explicitToken) {
|
|
30
|
-
return explicitToken;
|
|
31
|
-
}
|
|
32
|
-
const tokenStrategy = spec.runtime?.workflowDevkit?.hookTokens?.strategy ?? "deterministic";
|
|
33
|
-
const prefix = spec.runtime?.workflowDevkit?.hookTokens?.prefix ?? spec.meta.key;
|
|
34
|
-
const stableStepId = sanitizeIdentifier(step.id);
|
|
35
|
-
if (tokenStrategy === "session-scoped") {
|
|
36
|
-
const resolvedRunIdentity = sanitizeIdentifier(resolveWorkflowDevkitRunIdentity(spec, runIdentity));
|
|
37
|
-
return `${prefix}:${resolvedRunIdentity}:${stableStepId}`;
|
|
38
|
-
}
|
|
39
|
-
if (tokenStrategy === "step-scoped") {
|
|
40
|
-
return `${prefix}:v${spec.meta.version}:${stableStepId}`;
|
|
41
|
-
}
|
|
42
|
-
return `${prefix}:${stableStepId}`;
|
|
43
|
-
}
|
|
44
|
-
function resolveWorkflowDevkitNextStepId(spec, step, data, input, output) {
|
|
45
|
-
const transitions = spec.definition.transitions.filter((transition) => transition.from === step.id);
|
|
46
|
-
for (const transition of transitions) {
|
|
47
|
-
if (evaluateExpression(transition.condition, {
|
|
48
|
-
data,
|
|
49
|
-
input,
|
|
50
|
-
output
|
|
51
|
-
})) {
|
|
52
|
-
return transition.to;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
function mergeWorkflowDevkitData(current, input, output) {
|
|
58
|
-
const next = { ...current };
|
|
59
|
-
if (isRecord(input)) {
|
|
60
|
-
Object.assign(next, input);
|
|
61
|
-
}
|
|
62
|
-
if (isRecord(output)) {
|
|
63
|
-
Object.assign(next, output);
|
|
64
|
-
}
|
|
65
|
-
return next;
|
|
66
|
-
}
|
|
67
|
-
function sanitizeIdentifier(value) {
|
|
68
|
-
return value.replace(/[^a-zA-Z0-9_-]+/g, "-");
|
|
69
|
-
}
|
|
70
|
-
function isRecord(value) {
|
|
71
|
-
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// src/runtime.ts
|
|
75
|
-
async function runWorkflowSpecWithWorkflowDevkit(options) {
|
|
76
|
-
const history = [];
|
|
77
|
-
let currentStepId = resolveWorkflowDevkitEntryStepId(options.spec);
|
|
78
|
-
let data = { ...options.initialData ?? {} };
|
|
79
|
-
let input = options.initialData;
|
|
80
|
-
while (currentStepId) {
|
|
81
|
-
const step = lookupStep(options.spec, currentStepId);
|
|
82
|
-
const runtime = step.runtime?.workflowDevkit;
|
|
83
|
-
const context = {
|
|
84
|
-
data,
|
|
85
|
-
input,
|
|
86
|
-
runIdentity: options.runIdentity,
|
|
87
|
-
runtime,
|
|
88
|
-
spec: options.spec,
|
|
89
|
-
step
|
|
90
|
-
};
|
|
91
|
-
const behavior = inferWorkflowDevkitBehavior(step);
|
|
92
|
-
const token = resolveWorkflowDevkitWaitToken(options.spec, step, options.runIdentity);
|
|
93
|
-
const output = await executeWorkflowDevkitBehavior(behavior, context, token, options.bridge, options.primitives);
|
|
94
|
-
history.push({
|
|
95
|
-
behavior,
|
|
96
|
-
input,
|
|
97
|
-
output,
|
|
98
|
-
stepId: step.id,
|
|
99
|
-
token
|
|
100
|
-
});
|
|
101
|
-
data = mergeWorkflowDevkitData(data, input, output);
|
|
102
|
-
const nextStepId = resolveWorkflowDevkitNextStepId(options.spec, step, data, input, output);
|
|
103
|
-
if (!nextStepId) {
|
|
104
|
-
return {
|
|
105
|
-
currentStep: null,
|
|
106
|
-
data,
|
|
107
|
-
history,
|
|
108
|
-
status: "completed"
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
currentStepId = nextStepId;
|
|
112
|
-
input = output;
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
currentStep: null,
|
|
116
|
-
data,
|
|
117
|
-
history,
|
|
118
|
-
status: "completed"
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
async function executeWorkflowDevkitBehavior(behavior, context, token, bridge, primitives) {
|
|
122
|
-
switch (behavior) {
|
|
123
|
-
case "sleep":
|
|
124
|
-
if (!context.runtime?.sleep?.duration) {
|
|
125
|
-
throw new Error(`Step "${context.step.id}" is missing sleep.duration.`);
|
|
126
|
-
}
|
|
127
|
-
await primitives.sleep(context.runtime.sleep.duration);
|
|
128
|
-
return { sleptFor: context.runtime.sleep.duration };
|
|
129
|
-
case "hookWait":
|
|
130
|
-
return awaitExternalWait(context, token, bridge?.onExternalWait, primitives.createHook);
|
|
131
|
-
case "webhookWait":
|
|
132
|
-
return awaitExternalWait(context, token, bridge?.onExternalWait, primitives.createWebhook ?? primitives.createHook, context.runtime?.webhookWait?.path, context.runtime?.webhookWait?.method);
|
|
133
|
-
case "approvalWait":
|
|
134
|
-
return awaitExternalWait(context, token, bridge?.onApprovalRequested, primitives.createHook);
|
|
135
|
-
case "streamSession":
|
|
136
|
-
return awaitExternalWait(context, token, bridge?.onStreamSession, primitives.createHook);
|
|
137
|
-
case "automation":
|
|
138
|
-
if (!bridge?.executeAutomationStep) {
|
|
139
|
-
throw new Error("Workflow DevKit bridge requires executeAutomationStep for automation steps.");
|
|
140
|
-
}
|
|
141
|
-
return bridge.executeAutomationStep(context);
|
|
142
|
-
case "human":
|
|
143
|
-
if (!bridge?.awaitHumanInput) {
|
|
144
|
-
throw new Error("Workflow DevKit bridge requires awaitHumanInput for human steps without explicit wait behavior.");
|
|
145
|
-
}
|
|
146
|
-
return bridge.awaitHumanInput(context);
|
|
147
|
-
case "decision":
|
|
148
|
-
return bridge?.executeDecisionStep ? bridge.executeDecisionStep(context) : context.input;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
async function awaitExternalWait(context, token, notifier, factory, path, method) {
|
|
152
|
-
if (!token) {
|
|
153
|
-
throw new Error(`Step "${context.step.id}" requires a Workflow DevKit wait token.`);
|
|
154
|
-
}
|
|
155
|
-
const behavior = context.runtime?.behavior;
|
|
156
|
-
if (behavior !== "approvalWait" && behavior !== "hookWait" && behavior !== "streamSession" && behavior !== "webhookWait") {
|
|
157
|
-
throw new Error(`Step "${context.step.id}" is not configured with an external wait behavior.`);
|
|
158
|
-
}
|
|
159
|
-
const waitContext = {
|
|
160
|
-
...context,
|
|
161
|
-
behavior,
|
|
162
|
-
token
|
|
163
|
-
};
|
|
164
|
-
await notifier?.(waitContext);
|
|
165
|
-
const hook = factory({ method, path, token });
|
|
166
|
-
try {
|
|
167
|
-
return await hook;
|
|
168
|
-
} finally {
|
|
169
|
-
await hook.dispose?.();
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function lookupStep(spec, stepId) {
|
|
173
|
-
const step = spec.definition.steps.find((candidate) => candidate.id === stepId);
|
|
174
|
-
if (!step) {
|
|
175
|
-
throw new Error(`Step "${stepId}" not found in workflow ${spec.meta.key}.v${spec.meta.version}.`);
|
|
176
|
-
}
|
|
177
|
-
return step;
|
|
178
|
-
}
|
|
179
|
-
export {
|
|
180
|
-
runWorkflowSpecWithWorkflowDevkit
|
|
181
|
-
};
|
|
2
|
+
import{evaluateExpression as C}from"@contractspec/lib.contracts-spec/workflow/expression";function X(j){return j.runtime?.workflowDevkit?.behavior??j.type}function Y(j){let q=j.definition.entryStepId??j.definition.steps[0]?.id;if(!q)throw Error(`Workflow ${j.meta.key}.v${j.meta.version} does not define an entry step.`);return q}function N(j,q){if(q)return q;let F=j.runtime?.workflowDevkit?.runIdentity?.strategy??"meta-key-version",A=j.runtime?.workflowDevkit?.runIdentity?.prefix,G=F==="meta-key-version"?`${j.meta.key}.v${j.meta.version}`:`${j.meta.key}.v${j.meta.version}`;return A?`${A}:${G}`:G}function Z(j,q,F){let A=q.runtime?.workflowDevkit;if(!A)return;let G=A.hookWait?.token??A.webhookWait?.token??A.approvalWait?.token??A.streamSession?.followUpToken;if(G)return G;let J=j.runtime?.workflowDevkit?.hookTokens?.strategy??"deterministic",H=j.runtime?.workflowDevkit?.hookTokens?.prefix??j.meta.key,K=U(q.id);if(J==="session-scoped"){let L=U(N(j,F));return`${H}:${L}:${K}`}if(J==="step-scoped")return`${H}:v${j.meta.version}:${K}`;return`${H}:${K}`}function _(j,q,F,A,G){let J=j.definition.transitions.filter((H)=>H.from===q.id);for(let H of J)if(C(H.condition,{data:F,input:A,output:G}))return H.to;return null}function $(j,q,F){let A={...j};if(V(q))Object.assign(A,q);if(V(F))Object.assign(A,F);return A}function U(j){return j.replace(/[^a-zA-Z0-9_-]+/g,"-")}function V(j){return j!=null&&typeof j==="object"&&!Array.isArray(j)}async function D(j){let q=[],F=Y(j.spec),A={...j.initialData??{}},G=j.initialData;while(F){let J=B(j.spec,F),H=J.runtime?.workflowDevkit,K={data:A,input:G,runIdentity:j.runIdentity,runtime:H,spec:j.spec,step:J},L=X(J),P=Z(j.spec,J,j.runIdentity),M=await z(L,K,P,j.bridge,j.primitives);q.push({behavior:L,input:G,output:M,stepId:J.id,token:P}),A=$(A,G,M);let Q=_(j.spec,J,A,G,M);if(!Q)return{currentStep:null,data:A,history:q,status:"completed"};F=Q,G=M}return{currentStep:null,data:A,history:q,status:"completed"}}async function z(j,q,F,A,G){switch(j){case"sleep":if(!q.runtime?.sleep?.duration)throw Error(`Step "${q.step.id}" is missing sleep.duration.`);return await G.sleep(q.runtime.sleep.duration),{sleptFor:q.runtime.sleep.duration};case"hookWait":return O(q,F,A?.onExternalWait,G.createHook);case"webhookWait":return O(q,F,A?.onExternalWait,G.createWebhook??G.createHook,q.runtime?.webhookWait?.path,q.runtime?.webhookWait?.method);case"approvalWait":return O(q,F,A?.onApprovalRequested,G.createHook);case"streamSession":return O(q,F,A?.onStreamSession,G.createHook);case"automation":if(!A?.executeAutomationStep)throw Error("Workflow DevKit bridge requires executeAutomationStep for automation steps.");return A.executeAutomationStep(q);case"human":if(!A?.awaitHumanInput)throw Error("Workflow DevKit bridge requires awaitHumanInput for human steps without explicit wait behavior.");return A.awaitHumanInput(q);case"decision":return A?.executeDecisionStep?A.executeDecisionStep(q):q.input}}async function O(j,q,F,A,G,J){if(!q)throw Error(`Step "${j.step.id}" requires a Workflow DevKit wait token.`);let H=j.runtime?.behavior;if(H!=="approvalWait"&&H!=="hookWait"&&H!=="streamSession"&&H!=="webhookWait")throw Error(`Step "${j.step.id}" is not configured with an external wait behavior.`);let K={...j,behavior:H,token:q};await F?.(K);let L=A({method:J,path:G,token:q});try{return await L}finally{await L.dispose?.()}}function B(j,q){let F=j.definition.steps.find((A)=>A.id===q);if(!F)throw Error(`Step "${q}" not found in workflow ${j.meta.key}.v${j.meta.version}.`);return F}export{D as runWorkflowSpecWithWorkflowDevkit};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/integration.workflow-devkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Workflow DevKit compiler and runtime bridges for ContractSpec workflows",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -83,21 +83,21 @@
|
|
|
83
83
|
"dev": "contractspec-bun-build dev",
|
|
84
84
|
"clean": "rimraf dist .turbo",
|
|
85
85
|
"lint": "bun lint:fix",
|
|
86
|
-
"lint:fix": "biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .",
|
|
87
|
-
"lint:check": "biome check .",
|
|
86
|
+
"lint:fix": "node ../../../scripts/biome.cjs check --write --unsafe --only=nursery/useSortedClasses . && node ../../../scripts/biome.cjs check --write .",
|
|
87
|
+
"lint:check": "node ../../../scripts/biome.cjs check .",
|
|
88
88
|
"test": "bun test",
|
|
89
89
|
"prebuild": "contractspec-bun-build prebuild",
|
|
90
90
|
"typecheck": "tsc --noEmit"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@contractspec/lib.ai-agent": "8.0.
|
|
94
|
-
"@contractspec/lib.contracts-spec": "5.
|
|
95
|
-
"@workflow/ai": "^4.1.0
|
|
96
|
-
"ai": "6.0.
|
|
97
|
-
"workflow": "^4.2.0
|
|
93
|
+
"@contractspec/lib.ai-agent": "8.0.6",
|
|
94
|
+
"@contractspec/lib.contracts-spec": "5.2.0",
|
|
95
|
+
"@workflow/ai": "^4.1.0",
|
|
96
|
+
"ai": "6.0.156",
|
|
97
|
+
"workflow": "^4.2.0"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
|
-
"@contractspec/tool.bun": "3.7.
|
|
100
|
+
"@contractspec/tool.bun": "3.7.14",
|
|
101
101
|
"@contractspec/tool.typescript": "3.7.13",
|
|
102
102
|
"typescript": "^5.9.3"
|
|
103
103
|
},
|