@keystrokehq/keystroke 0.0.82 → 0.0.84
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.cjs +2 -2
- package/dist/agent.mjs +2 -2
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/{dist-D9kmfOVj.cjs → dist-B1Dy8DVb.cjs} +60 -2
- package/dist/{dist-D9kmfOVj.cjs.map → dist-B1Dy8DVb.cjs.map} +1 -1
- package/dist/dist-BdtvGgfO.mjs +380 -0
- package/dist/dist-BdtvGgfO.mjs.map +1 -0
- package/dist/dist-CZZMGcuu.cjs +409 -0
- package/dist/dist-CZZMGcuu.cjs.map +1 -0
- package/dist/{dist-D6CLdIst.mjs → dist-DgIJtGrg.mjs} +60 -2
- package/dist/{dist-D6CLdIst.mjs.map → dist-DgIJtGrg.mjs.map} +1 -1
- package/dist/{index-BzsZvKGT.d.mts → index-Bv6uZ8Xd.d.mts} +87 -11
- package/dist/index-Bv6uZ8Xd.d.mts.map +1 -0
- package/dist/{index-CtyQ1EEq.d.cts → index-CpJJgeJ2.d.cts} +87 -11
- package/dist/index-CpJJgeJ2.d.cts.map +1 -0
- package/dist/{mistral-1tV3Hawf.cjs → mistral-Deqt4GvJ.cjs} +2 -2
- package/dist/{mistral-1tV3Hawf.cjs.map → mistral-Deqt4GvJ.cjs.map} +1 -1
- package/dist/{mistral-YEx-0Ny0.mjs → mistral-wT_K1dZn.mjs} +2 -2
- package/dist/{mistral-YEx-0Ny0.mjs.map → mistral-wT_K1dZn.mjs.map} +1 -1
- package/dist/{sse-CYVBGHvF.mjs → sse-D12n5Ckf.mjs} +2 -2
- package/dist/{sse-CYVBGHvF.mjs.map → sse-D12n5Ckf.mjs.map} +1 -1
- package/dist/{sse-_Xt5AdRl.cjs → sse-DvOq9Ntd.cjs} +2 -2
- package/dist/{sse-_Xt5AdRl.cjs.map → sse-DvOq9Ntd.cjs.map} +1 -1
- package/dist/trigger.cjs +1 -1
- package/dist/trigger.d.cts +1 -1
- package/dist/trigger.d.mts +1 -1
- package/dist/trigger.mjs +1 -1
- package/dist/workflow.cjs +2 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.mts +2 -2
- package/dist/workflow.mjs +2 -2
- package/package.json +1 -1
- package/dist/dist-BgFwZKGS.mjs +0 -154
- package/dist/dist-BgFwZKGS.mjs.map +0 -1
- package/dist/dist-NUfD1tQj.cjs +0 -177
- package/dist/dist-NUfD1tQj.cjs.map +0 -1
- package/dist/index-BzsZvKGT.d.mts.map +0 -1
- package/dist/index-CtyQ1EEq.d.cts.map +0 -1
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { U as SandboxDefinitionSchema } from "./dist-f_JGyGWx.mjs";
|
|
2
|
+
import { a as getActionCredentialRequirements, b as normalizeCredentialList, i as executeAction, l as registerWorkflowRunGetter } from "./dist-DYbhRy-F.mjs";
|
|
3
|
+
import { i as withSpan, l as resolveActionCredentials, r as logSystem, t as captureConsole } from "./dist-DgIJtGrg.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
|
+
//#region ../workflow/dist/index.mjs
|
|
7
|
+
const zodSchema = z.custom((v) => v instanceof z.ZodType, "must be a Zod schema");
|
|
8
|
+
/** Runtime validation for an unbranded workflow definition. */
|
|
9
|
+
const workflowCoreSchema = z.object({
|
|
10
|
+
key: z.string().trim().min(1),
|
|
11
|
+
name: z.string().optional(),
|
|
12
|
+
description: z.string().optional(),
|
|
13
|
+
subscription: z.object({ mode: z.enum(["system", "subscribable"]).optional() }).optional(),
|
|
14
|
+
sandbox: SandboxDefinitionSchema.optional(),
|
|
15
|
+
input: zodSchema,
|
|
16
|
+
output: zodSchema,
|
|
17
|
+
run: z.function()
|
|
18
|
+
});
|
|
19
|
+
const WORKFLOW = Symbol.for("keystroke.workflow");
|
|
20
|
+
/**
|
|
21
|
+
* Validates brand + shape via `workflowCoreSchema` so discovery and guards
|
|
22
|
+
* reject malformed definitions.
|
|
23
|
+
*/
|
|
24
|
+
function isWorkflow(value) {
|
|
25
|
+
if (typeof value !== "object" || value === null) return false;
|
|
26
|
+
if (!(WORKFLOW in value) || value[WORKFLOW] !== true) return false;
|
|
27
|
+
return workflowCoreSchema.safeParse(value).success;
|
|
28
|
+
}
|
|
29
|
+
function defineWorkflow(def) {
|
|
30
|
+
const result = workflowCoreSchema.safeParse(def);
|
|
31
|
+
if (!result.success) throw new Error(`Invalid workflow definition: ${formatIssues(result.error.issues)}`);
|
|
32
|
+
return {
|
|
33
|
+
...result.data,
|
|
34
|
+
[WORKFLOW]: true
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function formatIssues(issues) {
|
|
38
|
+
return issues.map((issue) => {
|
|
39
|
+
return `${issue.path.length > 0 ? `${issue.path.join(".")}: ` : ""}${issue.message}`;
|
|
40
|
+
}).join("; ");
|
|
41
|
+
}
|
|
42
|
+
function withCredentialChainOverride(requirements, chain) {
|
|
43
|
+
if (!requirements || !chain) return requirements;
|
|
44
|
+
return normalizeCredentialList(requirements).map((requirement) => ({
|
|
45
|
+
...requirement,
|
|
46
|
+
chain
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
function createActionRunner(store, runId, options = {}) {
|
|
50
|
+
return async (action, input, runOptions) => {
|
|
51
|
+
const actionKey = runOptions?.id ?? action.key;
|
|
52
|
+
const cached = await store.get(runId, actionKey);
|
|
53
|
+
if (cached !== void 0) {
|
|
54
|
+
await withSpan({
|
|
55
|
+
kind: "action",
|
|
56
|
+
name: actionKey,
|
|
57
|
+
refId: `${runId}:${actionKey}`,
|
|
58
|
+
metadata: {
|
|
59
|
+
runId,
|
|
60
|
+
actionKey,
|
|
61
|
+
replayed: true
|
|
62
|
+
}
|
|
63
|
+
}, async () => {
|
|
64
|
+
await logSystem("info", "action replayed from checkpoint", {
|
|
65
|
+
runId,
|
|
66
|
+
actionKey
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
return action.output.parse(cached);
|
|
70
|
+
}
|
|
71
|
+
return withSpan({
|
|
72
|
+
kind: "action",
|
|
73
|
+
name: actionKey,
|
|
74
|
+
refId: `${runId}:${actionKey}`,
|
|
75
|
+
metadata: {
|
|
76
|
+
runId,
|
|
77
|
+
actionKey
|
|
78
|
+
}
|
|
79
|
+
}, async () => captureConsole(async () => {
|
|
80
|
+
const requirements = withCredentialChainOverride(getActionCredentialRequirements(action), runOptions?.credentialChain);
|
|
81
|
+
const contextOverride = runOptions?.credentialSelection ? { selection: runOptions.credentialSelection } : void 0;
|
|
82
|
+
const validatedOutput = await executeAction(action, input, requirements?.length ? await resolveActionCredentials(requirements, {
|
|
83
|
+
resolveCredentials: options.resolveCredentials,
|
|
84
|
+
context: options.credentialContext,
|
|
85
|
+
oauthAdapter: options.oauthAdapter,
|
|
86
|
+
consumer: {
|
|
87
|
+
kind: "action",
|
|
88
|
+
name: action.key
|
|
89
|
+
},
|
|
90
|
+
contextOverride
|
|
91
|
+
}) : {});
|
|
92
|
+
await store.set(runId, actionKey, validatedOutput);
|
|
93
|
+
return validatedOutput;
|
|
94
|
+
}));
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
var MemoryActionStore = class {
|
|
98
|
+
records = /* @__PURE__ */ new Map();
|
|
99
|
+
key(runId, actionKey) {
|
|
100
|
+
return `${runId}:${actionKey}`;
|
|
101
|
+
}
|
|
102
|
+
async get(runId, actionKey) {
|
|
103
|
+
return this.records.get(this.key(runId, actionKey));
|
|
104
|
+
}
|
|
105
|
+
async set(runId, actionKey, output) {
|
|
106
|
+
this.records.set(this.key(runId, actionKey), output);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const storage = new AsyncLocalStorage();
|
|
110
|
+
registerWorkflowRunGetter(() => {
|
|
111
|
+
const store = storage.getStore();
|
|
112
|
+
if (!store) return;
|
|
113
|
+
return { actionRunner: store.actionRunner };
|
|
114
|
+
});
|
|
115
|
+
function runWithWorkflowContext(store, fn) {
|
|
116
|
+
return storage.run(store, fn);
|
|
117
|
+
}
|
|
118
|
+
/** Indexes replay events by correlationId for O(1) cache-hit checks during replay. */
|
|
119
|
+
var EventsConsumer = class {
|
|
120
|
+
byCorrelationId = /* @__PURE__ */ new Map();
|
|
121
|
+
constructor(events) {
|
|
122
|
+
for (const event of events) {
|
|
123
|
+
if (!event.correlationId) continue;
|
|
124
|
+
const list = this.byCorrelationId.get(event.correlationId);
|
|
125
|
+
if (list) list.push(event);
|
|
126
|
+
else this.byCorrelationId.set(event.correlationId, [event]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
events(correlationId) {
|
|
130
|
+
return this.byCorrelationId.get(correlationId) ?? [];
|
|
131
|
+
}
|
|
132
|
+
hasEventType(correlationId, type) {
|
|
133
|
+
return this.events(correlationId).some((event) => event.type === type);
|
|
134
|
+
}
|
|
135
|
+
isSleepCompleted(correlationId) {
|
|
136
|
+
return this.hasEventType(correlationId, "sleep_completed");
|
|
137
|
+
}
|
|
138
|
+
/** Returns the persisted resumeAt for a scheduled-but-not-completed sleep, if any. */
|
|
139
|
+
getSleepResumeAt(correlationId) {
|
|
140
|
+
const scheduled = this.events(correlationId).find((event) => event.type === "sleep_scheduled");
|
|
141
|
+
if (!scheduled) return;
|
|
142
|
+
const data = scheduled.data;
|
|
143
|
+
return data?.resumeAt ? new Date(data.resumeAt) : void 0;
|
|
144
|
+
}
|
|
145
|
+
getHookToken(correlationId) {
|
|
146
|
+
return (this.events(correlationId).find((event) => event.type === "hook_created")?.data)?.token;
|
|
147
|
+
}
|
|
148
|
+
getHookResult(correlationId) {
|
|
149
|
+
const resumed = this.events(correlationId).find((event) => event.type === "hook_resumed");
|
|
150
|
+
if (!resumed) return { resolved: false };
|
|
151
|
+
return {
|
|
152
|
+
resolved: true,
|
|
153
|
+
payload: resumed.data?.payload
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/** In-memory durable log for inline execution and tests. */
|
|
158
|
+
var MemoryEventLog = class {
|
|
159
|
+
events = [];
|
|
160
|
+
ids = /* @__PURE__ */ new Set();
|
|
161
|
+
async append(event) {
|
|
162
|
+
const id = event.id ?? crypto.randomUUID();
|
|
163
|
+
if (this.ids.has(id)) return false;
|
|
164
|
+
this.ids.add(id);
|
|
165
|
+
this.events.push({
|
|
166
|
+
id,
|
|
167
|
+
runId: event.runId,
|
|
168
|
+
seq: this.events.length,
|
|
169
|
+
type: event.type,
|
|
170
|
+
correlationId: event.correlationId ?? null,
|
|
171
|
+
data: event.data ?? null
|
|
172
|
+
});
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
async listReplay(runId) {
|
|
176
|
+
return this.events.filter((event) => event.runId === runId).map((event) => ({ ...event }));
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const UNIT_MS = {
|
|
180
|
+
ms: 1,
|
|
181
|
+
s: 1e3,
|
|
182
|
+
m: 6e4,
|
|
183
|
+
h: 36e5,
|
|
184
|
+
d: 864e5
|
|
185
|
+
};
|
|
186
|
+
/** Resolve a sleep duration to an absolute resume time. */
|
|
187
|
+
function resolveResumeAt(duration, now = /* @__PURE__ */ new Date()) {
|
|
188
|
+
if (duration instanceof Date) return duration;
|
|
189
|
+
if (typeof duration === "number") return new Date(now.getTime() + Math.max(0, duration));
|
|
190
|
+
return new Date(now.getTime() + parseDurationToMs(duration));
|
|
191
|
+
}
|
|
192
|
+
function parseDurationToMs(value) {
|
|
193
|
+
const match = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/.exec(value.trim());
|
|
194
|
+
if (!match) throw new Error(`Invalid sleep duration "${value}". Use a number of ms, a Date, or a string like "5s", "10m", "1h".`);
|
|
195
|
+
const amount = Number(match[1]);
|
|
196
|
+
const unit = match[2];
|
|
197
|
+
return Math.round(amount * UNIT_MS[unit]);
|
|
198
|
+
}
|
|
199
|
+
/** A promise that never settles — returned by a suspending primitive so the body parks. */
|
|
200
|
+
function createPendingPromise() {
|
|
201
|
+
return new Promise(() => {});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Collects pending items requested within a single tick and resolves once, so
|
|
205
|
+
* parallel suspensions (e.g. Promise.all of two sleeps) batch into one suspension.
|
|
206
|
+
*/
|
|
207
|
+
var SuspensionCoordinator = class {
|
|
208
|
+
items = /* @__PURE__ */ new Map();
|
|
209
|
+
scheduled = false;
|
|
210
|
+
resolve;
|
|
211
|
+
promise;
|
|
212
|
+
constructor() {
|
|
213
|
+
this.promise = new Promise((resolve) => {
|
|
214
|
+
this.resolve = resolve;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
request(item) {
|
|
218
|
+
this.items.set(item.correlationId, item);
|
|
219
|
+
if (!this.scheduled) {
|
|
220
|
+
this.scheduled = true;
|
|
221
|
+
queueMicrotask(() => {
|
|
222
|
+
this.resolve([...this.items.values()]);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
waitForSuspension() {
|
|
227
|
+
return this.promise;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
function createReplayState(params) {
|
|
231
|
+
return {
|
|
232
|
+
runId: params.runId,
|
|
233
|
+
consumer: params.consumer,
|
|
234
|
+
coordinator: params.coordinator,
|
|
235
|
+
newEvents: [],
|
|
236
|
+
now: params.now ?? /* @__PURE__ */ new Date(),
|
|
237
|
+
hookBaseUrl: params.hookBaseUrl,
|
|
238
|
+
sleepCounter: 0,
|
|
239
|
+
hookCounter: 0
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function createSleep(state) {
|
|
243
|
+
return function sleep(duration) {
|
|
244
|
+
const correlationId = `sleep#${state.sleepCounter++}`;
|
|
245
|
+
if (state.consumer.isSleepCompleted(correlationId)) return Promise.resolve();
|
|
246
|
+
const scheduledResumeAt = state.consumer.getSleepResumeAt(correlationId);
|
|
247
|
+
const resumeAt = scheduledResumeAt ?? resolveResumeAt(duration, state.now);
|
|
248
|
+
if (scheduledResumeAt && resumeAt.getTime() <= state.now.getTime()) {
|
|
249
|
+
state.newEvents.push({
|
|
250
|
+
id: `sleep_completed:${state.runId}:${correlationId}`,
|
|
251
|
+
runId: state.runId,
|
|
252
|
+
type: "sleep_completed",
|
|
253
|
+
correlationId
|
|
254
|
+
});
|
|
255
|
+
return Promise.resolve();
|
|
256
|
+
}
|
|
257
|
+
if (!scheduledResumeAt) state.newEvents.push({
|
|
258
|
+
id: `sleep_scheduled:${state.runId}:${correlationId}`,
|
|
259
|
+
runId: state.runId,
|
|
260
|
+
type: "sleep_scheduled",
|
|
261
|
+
correlationId,
|
|
262
|
+
data: { resumeAt: resumeAt.toISOString() }
|
|
263
|
+
});
|
|
264
|
+
state.coordinator.request({
|
|
265
|
+
kind: "sleep",
|
|
266
|
+
correlationId,
|
|
267
|
+
resumeAt
|
|
268
|
+
});
|
|
269
|
+
return createPendingPromise();
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function createHook(state) {
|
|
273
|
+
return function hook(options) {
|
|
274
|
+
const correlationId = `hook#${state.hookCounter++}`;
|
|
275
|
+
const token = options?.token ?? state.consumer.getHookToken(correlationId) ?? `hook_${crypto.randomUUID()}`;
|
|
276
|
+
return {
|
|
277
|
+
token,
|
|
278
|
+
resumeUrl: state.hookBaseUrl ? `${state.hookBaseUrl}/hooks/${token}/resume` : `/hooks/${token}/resume`,
|
|
279
|
+
then(onFulfilled, onRejected) {
|
|
280
|
+
const result = state.consumer.getHookResult(correlationId);
|
|
281
|
+
if (result.resolved) {
|
|
282
|
+
const payload = options?.schema ? options.schema.parse(result.payload) : result.payload;
|
|
283
|
+
return Promise.resolve(payload).then(onFulfilled, onRejected);
|
|
284
|
+
}
|
|
285
|
+
if (!state.consumer.hasEventType(correlationId, "hook_created")) state.newEvents.push({
|
|
286
|
+
id: `hook_created:${state.runId}:${correlationId}`,
|
|
287
|
+
runId: state.runId,
|
|
288
|
+
type: "hook_created",
|
|
289
|
+
correlationId,
|
|
290
|
+
data: { token }
|
|
291
|
+
});
|
|
292
|
+
state.coordinator.request({
|
|
293
|
+
kind: "hook",
|
|
294
|
+
correlationId,
|
|
295
|
+
token
|
|
296
|
+
});
|
|
297
|
+
return createPendingPromise().then(onFulfilled, onRejected);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* The single way to run a workflow: replay its event log from the top, execute
|
|
304
|
+
* un-cached primitives, and either complete/fail or suspend at the first
|
|
305
|
+
* un-satisfied sleep/hook. New events (sleep_scheduled/sleep_completed/
|
|
306
|
+
* hook_created/run_completed/run_failed) are flushed before returning.
|
|
307
|
+
*
|
|
308
|
+
* Durability comes entirely from the log — a suspended run resumes by calling
|
|
309
|
+
* this again with the same `runId` and event log once the sleep is due or the
|
|
310
|
+
* hook is resumed.
|
|
311
|
+
*/
|
|
312
|
+
async function executeWorkflow(workflow, input, options = {}) {
|
|
313
|
+
const runId = options.runId ?? crypto.randomUUID();
|
|
314
|
+
const eventLog = options.eventLog ?? new MemoryEventLog();
|
|
315
|
+
const actionStore = options.actionStore ?? new MemoryActionStore();
|
|
316
|
+
const consumer = new EventsConsumer(await eventLog.listReplay(runId));
|
|
317
|
+
const coordinator = new SuspensionCoordinator();
|
|
318
|
+
const state = createReplayState({
|
|
319
|
+
runId,
|
|
320
|
+
consumer,
|
|
321
|
+
coordinator,
|
|
322
|
+
hookBaseUrl: options.hookBaseUrl,
|
|
323
|
+
now: options.now
|
|
324
|
+
});
|
|
325
|
+
const actionRunner = createActionRunner(actionStore, runId, {
|
|
326
|
+
resolveCredentials: options.resolveCredentials,
|
|
327
|
+
credentialContext: options.credentialContext,
|
|
328
|
+
oauthAdapter: options.oauthAdapter
|
|
329
|
+
});
|
|
330
|
+
const ctx = {
|
|
331
|
+
runId,
|
|
332
|
+
sleep: createSleep(state),
|
|
333
|
+
hook: createHook(state),
|
|
334
|
+
...options.context
|
|
335
|
+
};
|
|
336
|
+
const validatedInput = workflow.input.parse(input);
|
|
337
|
+
const bodyPromise = runWithWorkflowContext({
|
|
338
|
+
actionRunner,
|
|
339
|
+
runId
|
|
340
|
+
}, () => captureConsole(async () => workflow.run(validatedInput, ctx)));
|
|
341
|
+
const outcome = await Promise.race([bodyPromise.then((output) => ({
|
|
342
|
+
type: "done",
|
|
343
|
+
output
|
|
344
|
+
}), (error) => ({
|
|
345
|
+
type: "error",
|
|
346
|
+
error
|
|
347
|
+
})), coordinator.waitForSuspension().then((items) => ({
|
|
348
|
+
type: "suspended",
|
|
349
|
+
items
|
|
350
|
+
}))]);
|
|
351
|
+
let result;
|
|
352
|
+
if (outcome.type === "suspended") {
|
|
353
|
+
bodyPromise.catch(() => {});
|
|
354
|
+
result = {
|
|
355
|
+
status: "suspended",
|
|
356
|
+
items: outcome.items
|
|
357
|
+
};
|
|
358
|
+
} else if (outcome.type === "done") {
|
|
359
|
+
const output = workflow.output.parse(outcome.output);
|
|
360
|
+
state.newEvents.push({
|
|
361
|
+
id: `run_completed:${runId}`,
|
|
362
|
+
runId,
|
|
363
|
+
type: "run_completed",
|
|
364
|
+
data: { output }
|
|
365
|
+
});
|
|
366
|
+
result = {
|
|
367
|
+
status: "completed",
|
|
368
|
+
output
|
|
369
|
+
};
|
|
370
|
+
} else result = {
|
|
371
|
+
status: "failed",
|
|
372
|
+
error: outcome.error
|
|
373
|
+
};
|
|
374
|
+
for (const event of state.newEvents) await eventLog.append(event);
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
378
|
+
export { isWorkflow as a, executeWorkflow as i, MemoryEventLog as n, defineWorkflow as r, MemoryActionStore as t };
|
|
379
|
+
|
|
380
|
+
//# sourceMappingURL=dist-BdtvGgfO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist-BdtvGgfO.mjs","names":[],"sources":["../../workflow/dist/index.mjs"],"sourcesContent":["import { z } from \"zod\";\nimport { SandboxDefinitionSchema } from \"@keystrokehq/sandbox\";\nimport { captureConsole, logSystem, withSpan } from \"@keystrokehq/tracing\";\nimport { executeAction, getActionCredentialRequirements, normalizeCredentialList, registerWorkflowRunGetter } from \"@keystrokehq/action\";\nimport { resolveActionCredentials } from \"@keystrokehq/credentials\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n//#region src/workflow-definition.ts\nconst zodSchema = z.custom((v) => v instanceof z.ZodType, \"must be a Zod schema\");\n/** Runtime validation for an unbranded workflow definition. */\nconst workflowCoreSchema = z.object({\n\tkey: z.string().trim().min(1),\n\tname: z.string().optional(),\n\tdescription: z.string().optional(),\n\tsubscription: z.object({ mode: z.enum([\"system\", \"subscribable\"]).optional() }).optional(),\n\tsandbox: SandboxDefinitionSchema.optional(),\n\tinput: zodSchema,\n\toutput: zodSchema,\n\trun: z.function()\n});\nconst WORKFLOW = Symbol.for(\"keystroke.workflow\");\n/**\n* Validates brand + shape via `workflowCoreSchema` so discovery and guards\n* reject malformed definitions.\n*/\nfunction isWorkflow(value) {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (!(WORKFLOW in value) || value[WORKFLOW] !== true) return false;\n\treturn workflowCoreSchema.safeParse(value).success;\n}\n//#endregion\n//#region src/define-workflow.ts\nfunction defineWorkflow(def) {\n\tconst result = workflowCoreSchema.safeParse(def);\n\tif (!result.success) throw new Error(`Invalid workflow definition: ${formatIssues(result.error.issues)}`);\n\treturn {\n\t\t...result.data,\n\t\t[WORKFLOW]: true\n\t};\n}\nfunction formatIssues(issues) {\n\treturn issues.map((issue) => {\n\t\treturn `${issue.path.length > 0 ? `${issue.path.join(\".\")}: ` : \"\"}${issue.message}`;\n\t}).join(\"; \");\n}\n//#endregion\n//#region src/create-action-runner.ts\nfunction withCredentialChainOverride(requirements, chain) {\n\tif (!requirements || !chain) return requirements;\n\treturn normalizeCredentialList(requirements).map((requirement) => ({\n\t\t...requirement,\n\t\tchain\n\t}));\n}\nfunction createActionRunner(store, runId, options = {}) {\n\treturn async (action, input, runOptions) => {\n\t\tconst actionKey = runOptions?.id ?? action.key;\n\t\tconst cached = await store.get(runId, actionKey);\n\t\tif (cached !== void 0) {\n\t\t\tawait withSpan({\n\t\t\t\tkind: \"action\",\n\t\t\t\tname: actionKey,\n\t\t\t\trefId: `${runId}:${actionKey}`,\n\t\t\t\tmetadata: {\n\t\t\t\t\trunId,\n\t\t\t\t\tactionKey,\n\t\t\t\t\treplayed: true\n\t\t\t\t}\n\t\t\t}, async () => {\n\t\t\t\tawait logSystem(\"info\", \"action replayed from checkpoint\", {\n\t\t\t\t\trunId,\n\t\t\t\t\tactionKey\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn action.output.parse(cached);\n\t\t}\n\t\treturn withSpan({\n\t\t\tkind: \"action\",\n\t\t\tname: actionKey,\n\t\t\trefId: `${runId}:${actionKey}`,\n\t\t\tmetadata: {\n\t\t\t\trunId,\n\t\t\t\tactionKey\n\t\t\t}\n\t\t}, async () => captureConsole(async () => {\n\t\t\tconst requirements = withCredentialChainOverride(getActionCredentialRequirements(action), runOptions?.credentialChain);\n\t\t\tconst contextOverride = runOptions?.credentialSelection ? { selection: runOptions.credentialSelection } : void 0;\n\t\t\tconst validatedOutput = await executeAction(action, input, requirements?.length ? await resolveActionCredentials(requirements, {\n\t\t\t\tresolveCredentials: options.resolveCredentials,\n\t\t\t\tcontext: options.credentialContext,\n\t\t\t\toauthAdapter: options.oauthAdapter,\n\t\t\t\tconsumer: {\n\t\t\t\t\tkind: \"action\",\n\t\t\t\t\tname: action.key\n\t\t\t\t},\n\t\t\t\tcontextOverride\n\t\t\t}) : {});\n\t\t\tawait store.set(runId, actionKey, validatedOutput);\n\t\t\treturn validatedOutput;\n\t\t}));\n\t};\n}\n//#endregion\n//#region src/memory-action-store.ts\nvar MemoryActionStore = class {\n\trecords = /* @__PURE__ */ new Map();\n\tkey(runId, actionKey) {\n\t\treturn `${runId}:${actionKey}`;\n\t}\n\tasync get(runId, actionKey) {\n\t\treturn this.records.get(this.key(runId, actionKey));\n\t}\n\tasync set(runId, actionKey, output) {\n\t\tthis.records.set(this.key(runId, actionKey), output);\n\t}\n};\n//#endregion\n//#region src/run-context.ts\nconst storage = new AsyncLocalStorage();\nregisterWorkflowRunGetter(() => {\n\tconst store = storage.getStore();\n\tif (!store) return;\n\treturn { actionRunner: store.actionRunner };\n});\nfunction runWithWorkflowContext(store, fn) {\n\treturn storage.run(store, fn);\n}\n//#endregion\n//#region src/replay/events-consumer.ts\n/** Indexes replay events by correlationId for O(1) cache-hit checks during replay. */\nvar EventsConsumer = class {\n\tbyCorrelationId = /* @__PURE__ */ new Map();\n\tconstructor(events) {\n\t\tfor (const event of events) {\n\t\t\tif (!event.correlationId) continue;\n\t\t\tconst list = this.byCorrelationId.get(event.correlationId);\n\t\t\tif (list) list.push(event);\n\t\t\telse this.byCorrelationId.set(event.correlationId, [event]);\n\t\t}\n\t}\n\tevents(correlationId) {\n\t\treturn this.byCorrelationId.get(correlationId) ?? [];\n\t}\n\thasEventType(correlationId, type) {\n\t\treturn this.events(correlationId).some((event) => event.type === type);\n\t}\n\tisSleepCompleted(correlationId) {\n\t\treturn this.hasEventType(correlationId, \"sleep_completed\");\n\t}\n\t/** Returns the persisted resumeAt for a scheduled-but-not-completed sleep, if any. */\n\tgetSleepResumeAt(correlationId) {\n\t\tconst scheduled = this.events(correlationId).find((event) => event.type === \"sleep_scheduled\");\n\t\tif (!scheduled) return;\n\t\tconst data = scheduled.data;\n\t\treturn data?.resumeAt ? new Date(data.resumeAt) : void 0;\n\t}\n\tgetHookToken(correlationId) {\n\t\treturn (this.events(correlationId).find((event) => event.type === \"hook_created\")?.data)?.token;\n\t}\n\tgetHookResult(correlationId) {\n\t\tconst resumed = this.events(correlationId).find((event) => event.type === \"hook_resumed\");\n\t\tif (!resumed) return { resolved: false };\n\t\treturn {\n\t\t\tresolved: true,\n\t\t\tpayload: resumed.data?.payload\n\t\t};\n\t}\n};\n//#endregion\n//#region src/replay/memory-event-log.ts\n/** In-memory durable log for inline execution and tests. */\nvar MemoryEventLog = class {\n\tevents = [];\n\tids = /* @__PURE__ */ new Set();\n\tasync append(event) {\n\t\tconst id = event.id ?? crypto.randomUUID();\n\t\tif (this.ids.has(id)) return false;\n\t\tthis.ids.add(id);\n\t\tthis.events.push({\n\t\t\tid,\n\t\t\trunId: event.runId,\n\t\t\tseq: this.events.length,\n\t\t\ttype: event.type,\n\t\t\tcorrelationId: event.correlationId ?? null,\n\t\t\tdata: event.data ?? null\n\t\t});\n\t\treturn true;\n\t}\n\tasync listReplay(runId) {\n\t\treturn this.events.filter((event) => event.runId === runId).map((event) => ({ ...event }));\n\t}\n};\n//#endregion\n//#region src/replay/duration.ts\nconst UNIT_MS = {\n\tms: 1,\n\ts: 1e3,\n\tm: 6e4,\n\th: 36e5,\n\td: 864e5\n};\n/** Resolve a sleep duration to an absolute resume time. */\nfunction resolveResumeAt(duration, now = /* @__PURE__ */ new Date()) {\n\tif (duration instanceof Date) return duration;\n\tif (typeof duration === \"number\") return new Date(now.getTime() + Math.max(0, duration));\n\treturn new Date(now.getTime() + parseDurationToMs(duration));\n}\nfunction parseDurationToMs(value) {\n\tconst match = /^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/.exec(value.trim());\n\tif (!match) throw new Error(`Invalid sleep duration \"${value}\". Use a number of ms, a Date, or a string like \"5s\", \"10m\", \"1h\".`);\n\tconst amount = Number(match[1]);\n\tconst unit = match[2];\n\treturn Math.round(amount * UNIT_MS[unit]);\n}\n//#endregion\n//#region src/replay/suspension.ts\n/** A promise that never settles — returned by a suspending primitive so the body parks. */\nfunction createPendingPromise() {\n\treturn new Promise(() => {});\n}\n/**\n* Collects pending items requested within a single tick and resolves once, so\n* parallel suspensions (e.g. Promise.all of two sleeps) batch into one suspension.\n*/\nvar SuspensionCoordinator = class {\n\titems = /* @__PURE__ */ new Map();\n\tscheduled = false;\n\tresolve;\n\tpromise;\n\tconstructor() {\n\t\tthis.promise = new Promise((resolve) => {\n\t\t\tthis.resolve = resolve;\n\t\t});\n\t}\n\trequest(item) {\n\t\tthis.items.set(item.correlationId, item);\n\t\tif (!this.scheduled) {\n\t\t\tthis.scheduled = true;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tthis.resolve([...this.items.values()]);\n\t\t\t});\n\t\t}\n\t}\n\twaitForSuspension() {\n\t\treturn this.promise;\n\t}\n};\n//#endregion\n//#region src/replay/replay-context.ts\nfunction createReplayState(params) {\n\treturn {\n\t\trunId: params.runId,\n\t\tconsumer: params.consumer,\n\t\tcoordinator: params.coordinator,\n\t\tnewEvents: [],\n\t\tnow: params.now ?? /* @__PURE__ */ new Date(),\n\t\thookBaseUrl: params.hookBaseUrl,\n\t\tsleepCounter: 0,\n\t\thookCounter: 0\n\t};\n}\nfunction createSleep(state) {\n\treturn function sleep(duration) {\n\t\tconst correlationId = `sleep#${state.sleepCounter++}`;\n\t\tif (state.consumer.isSleepCompleted(correlationId)) return Promise.resolve();\n\t\tconst scheduledResumeAt = state.consumer.getSleepResumeAt(correlationId);\n\t\tconst resumeAt = scheduledResumeAt ?? resolveResumeAt(duration, state.now);\n\t\tif (scheduledResumeAt && resumeAt.getTime() <= state.now.getTime()) {\n\t\t\tstate.newEvents.push({\n\t\t\t\tid: `sleep_completed:${state.runId}:${correlationId}`,\n\t\t\t\trunId: state.runId,\n\t\t\t\ttype: \"sleep_completed\",\n\t\t\t\tcorrelationId\n\t\t\t});\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tif (!scheduledResumeAt) state.newEvents.push({\n\t\t\tid: `sleep_scheduled:${state.runId}:${correlationId}`,\n\t\t\trunId: state.runId,\n\t\t\ttype: \"sleep_scheduled\",\n\t\t\tcorrelationId,\n\t\t\tdata: { resumeAt: resumeAt.toISOString() }\n\t\t});\n\t\tstate.coordinator.request({\n\t\t\tkind: \"sleep\",\n\t\t\tcorrelationId,\n\t\t\tresumeAt\n\t\t});\n\t\treturn createPendingPromise();\n\t};\n}\nfunction createHook(state) {\n\treturn function hook(options) {\n\t\tconst correlationId = `hook#${state.hookCounter++}`;\n\t\tconst token = options?.token ?? state.consumer.getHookToken(correlationId) ?? `hook_${crypto.randomUUID()}`;\n\t\treturn {\n\t\t\ttoken,\n\t\t\tresumeUrl: state.hookBaseUrl ? `${state.hookBaseUrl}/hooks/${token}/resume` : `/hooks/${token}/resume`,\n\t\t\tthen(onFulfilled, onRejected) {\n\t\t\t\tconst result = state.consumer.getHookResult(correlationId);\n\t\t\t\tif (result.resolved) {\n\t\t\t\t\tconst payload = options?.schema ? options.schema.parse(result.payload) : result.payload;\n\t\t\t\t\treturn Promise.resolve(payload).then(onFulfilled, onRejected);\n\t\t\t\t}\n\t\t\t\tif (!state.consumer.hasEventType(correlationId, \"hook_created\")) state.newEvents.push({\n\t\t\t\t\tid: `hook_created:${state.runId}:${correlationId}`,\n\t\t\t\t\trunId: state.runId,\n\t\t\t\t\ttype: \"hook_created\",\n\t\t\t\t\tcorrelationId,\n\t\t\t\t\tdata: { token }\n\t\t\t\t});\n\t\t\t\tstate.coordinator.request({\n\t\t\t\t\tkind: \"hook\",\n\t\t\t\t\tcorrelationId,\n\t\t\t\t\ttoken\n\t\t\t\t});\n\t\t\t\treturn createPendingPromise().then(onFulfilled, onRejected);\n\t\t\t}\n\t\t};\n\t};\n}\n//#endregion\n//#region src/execute-workflow.ts\n/**\n* The single way to run a workflow: replay its event log from the top, execute\n* un-cached primitives, and either complete/fail or suspend at the first\n* un-satisfied sleep/hook. New events (sleep_scheduled/sleep_completed/\n* hook_created/run_completed/run_failed) are flushed before returning.\n*\n* Durability comes entirely from the log — a suspended run resumes by calling\n* this again with the same `runId` and event log once the sleep is due or the\n* hook is resumed.\n*/\nasync function executeWorkflow(workflow, input, options = {}) {\n\tconst runId = options.runId ?? crypto.randomUUID();\n\tconst eventLog = options.eventLog ?? new MemoryEventLog();\n\tconst actionStore = options.actionStore ?? new MemoryActionStore();\n\tconst consumer = new EventsConsumer(await eventLog.listReplay(runId));\n\tconst coordinator = new SuspensionCoordinator();\n\tconst state = createReplayState({\n\t\trunId,\n\t\tconsumer,\n\t\tcoordinator,\n\t\thookBaseUrl: options.hookBaseUrl,\n\t\tnow: options.now\n\t});\n\tconst actionRunner = createActionRunner(actionStore, runId, {\n\t\tresolveCredentials: options.resolveCredentials,\n\t\tcredentialContext: options.credentialContext,\n\t\toauthAdapter: options.oauthAdapter\n\t});\n\tconst ctx = {\n\t\trunId,\n\t\tsleep: createSleep(state),\n\t\thook: createHook(state),\n\t\t...options.context\n\t};\n\tconst validatedInput = workflow.input.parse(input);\n\tconst bodyPromise = runWithWorkflowContext({\n\t\tactionRunner,\n\t\trunId\n\t}, () => captureConsole(async () => workflow.run(validatedInput, ctx)));\n\tconst outcome = await Promise.race([bodyPromise.then((output) => ({\n\t\ttype: \"done\",\n\t\toutput\n\t}), (error) => ({\n\t\ttype: \"error\",\n\t\terror\n\t})), coordinator.waitForSuspension().then((items) => ({\n\t\ttype: \"suspended\",\n\t\titems\n\t}))]);\n\tlet result;\n\tif (outcome.type === \"suspended\") {\n\t\tbodyPromise.catch(() => {});\n\t\tresult = {\n\t\t\tstatus: \"suspended\",\n\t\t\titems: outcome.items\n\t\t};\n\t} else if (outcome.type === \"done\") {\n\t\tconst output = workflow.output.parse(outcome.output);\n\t\tstate.newEvents.push({\n\t\t\tid: `run_completed:${runId}`,\n\t\t\trunId,\n\t\t\ttype: \"run_completed\",\n\t\t\tdata: { output }\n\t\t});\n\t\tresult = {\n\t\t\tstatus: \"completed\",\n\t\t\toutput\n\t\t};\n\t} else result = {\n\t\tstatus: \"failed\",\n\t\terror: outcome.error\n\t};\n\tfor (const event of state.newEvents) await eventLog.append(event);\n\treturn result;\n}\n//#endregion\nexport { MemoryActionStore, MemoryEventLog, defineWorkflow, executeWorkflow, isWorkflow };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":"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"}
|