@keystrokehq/keystroke 0.0.83 → 0.0.85

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.
Files changed (39) hide show
  1. package/dist/agent.cjs +2 -2
  2. package/dist/agent.mjs +2 -2
  3. package/dist/config.d.cts.map +1 -1
  4. package/dist/config.d.mts.map +1 -1
  5. package/dist/{dist-D9kmfOVj.cjs → dist-B1Dy8DVb.cjs} +60 -2
  6. package/dist/{dist-D9kmfOVj.cjs.map → dist-B1Dy8DVb.cjs.map} +1 -1
  7. package/dist/dist-BdtvGgfO.mjs +380 -0
  8. package/dist/dist-BdtvGgfO.mjs.map +1 -0
  9. package/dist/dist-CZZMGcuu.cjs +409 -0
  10. package/dist/dist-CZZMGcuu.cjs.map +1 -0
  11. package/dist/{dist-D6CLdIst.mjs → dist-DgIJtGrg.mjs} +60 -2
  12. package/dist/{dist-D6CLdIst.mjs.map → dist-DgIJtGrg.mjs.map} +1 -1
  13. package/dist/{index-BzsZvKGT.d.mts → index-Bv6uZ8Xd.d.mts} +87 -11
  14. package/dist/index-Bv6uZ8Xd.d.mts.map +1 -0
  15. package/dist/{index-CtyQ1EEq.d.cts → index-CpJJgeJ2.d.cts} +87 -11
  16. package/dist/index-CpJJgeJ2.d.cts.map +1 -0
  17. package/dist/{mistral-1tV3Hawf.cjs → mistral-Deqt4GvJ.cjs} +2 -2
  18. package/dist/{mistral-1tV3Hawf.cjs.map → mistral-Deqt4GvJ.cjs.map} +1 -1
  19. package/dist/{mistral-YEx-0Ny0.mjs → mistral-wT_K1dZn.mjs} +2 -2
  20. package/dist/{mistral-YEx-0Ny0.mjs.map → mistral-wT_K1dZn.mjs.map} +1 -1
  21. package/dist/{sse-CYVBGHvF.mjs → sse-D12n5Ckf.mjs} +2 -2
  22. package/dist/{sse-CYVBGHvF.mjs.map → sse-D12n5Ckf.mjs.map} +1 -1
  23. package/dist/{sse-_Xt5AdRl.cjs → sse-DvOq9Ntd.cjs} +2 -2
  24. package/dist/{sse-_Xt5AdRl.cjs.map → sse-DvOq9Ntd.cjs.map} +1 -1
  25. package/dist/trigger.cjs +1 -1
  26. package/dist/trigger.d.cts +1 -1
  27. package/dist/trigger.d.mts +1 -1
  28. package/dist/trigger.mjs +1 -1
  29. package/dist/workflow.cjs +2 -1
  30. package/dist/workflow.d.cts +2 -2
  31. package/dist/workflow.d.mts +2 -2
  32. package/dist/workflow.mjs +2 -2
  33. package/package.json +1 -1
  34. package/dist/dist-BgFwZKGS.mjs +0 -154
  35. package/dist/dist-BgFwZKGS.mjs.map +0 -1
  36. package/dist/dist-NUfD1tQj.cjs +0 -177
  37. package/dist/dist-NUfD1tQj.cjs.map +0 -1
  38. package/dist/index-BzsZvKGT.d.mts.map +0 -1
  39. package/dist/index-CtyQ1EEq.d.cts.map +0 -1
@@ -0,0 +1,409 @@
1
+ const require_dist = require("./dist-CLqJza2Y.cjs");
2
+ const require_dist$1 = require("./dist-BM_f7hFN.cjs");
3
+ const require_dist$2 = require("./dist-B1Dy8DVb.cjs");
4
+ let zod = require("zod");
5
+ let node_async_hooks = require("node:async_hooks");
6
+ //#region ../workflow/dist/index.mjs
7
+ const zodSchema = zod.z.custom((v) => v instanceof zod.z.ZodType, "must be a Zod schema");
8
+ /** Runtime validation for an unbranded workflow definition. */
9
+ const workflowCoreSchema = zod.z.object({
10
+ key: zod.z.string().trim().min(1),
11
+ name: zod.z.string().optional(),
12
+ description: zod.z.string().optional(),
13
+ subscription: zod.z.object({ mode: zod.z.enum(["system", "subscribable"]).optional() }).optional(),
14
+ sandbox: require_dist.SandboxDefinitionSchema.optional(),
15
+ input: zodSchema,
16
+ output: zodSchema,
17
+ run: zod.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 require_dist$1.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 require_dist$2.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 require_dist$2.logSystem("info", "action replayed from checkpoint", {
65
+ runId,
66
+ actionKey
67
+ });
68
+ });
69
+ return action.output.parse(cached);
70
+ }
71
+ return require_dist$2.withSpan({
72
+ kind: "action",
73
+ name: actionKey,
74
+ refId: `${runId}:${actionKey}`,
75
+ metadata: {
76
+ runId,
77
+ actionKey
78
+ }
79
+ }, async () => require_dist$2.captureConsole(async () => {
80
+ const requirements = withCredentialChainOverride(require_dist$1.getActionCredentialRequirements(action), runOptions?.credentialChain);
81
+ const contextOverride = runOptions?.credentialSelection ? { selection: runOptions.credentialSelection } : void 0;
82
+ const validatedOutput = await require_dist$1.executeAction(action, input, requirements?.length ? await require_dist$2.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 node_async_hooks.AsyncLocalStorage();
110
+ require_dist$1.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
+ }, () => require_dist$2.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
+ Object.defineProperty(exports, "MemoryActionStore", {
379
+ enumerable: true,
380
+ get: function() {
381
+ return MemoryActionStore;
382
+ }
383
+ });
384
+ Object.defineProperty(exports, "MemoryEventLog", {
385
+ enumerable: true,
386
+ get: function() {
387
+ return MemoryEventLog;
388
+ }
389
+ });
390
+ Object.defineProperty(exports, "defineWorkflow", {
391
+ enumerable: true,
392
+ get: function() {
393
+ return defineWorkflow;
394
+ }
395
+ });
396
+ Object.defineProperty(exports, "executeWorkflow", {
397
+ enumerable: true,
398
+ get: function() {
399
+ return executeWorkflow;
400
+ }
401
+ });
402
+ Object.defineProperty(exports, "isWorkflow", {
403
+ enumerable: true,
404
+ get: function() {
405
+ return isWorkflow;
406
+ }
407
+ });
408
+
409
+ //# sourceMappingURL=dist-CZZMGcuu.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dist-CZZMGcuu.cjs","names":["z","SandboxDefinitionSchema","normalizeCredentialList","withSpan","logSystem","captureConsole","getActionCredentialRequirements","executeAction","resolveActionCredentials","AsyncLocalStorage","registerWorkflowRunGetter"],"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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"}
@@ -13255,7 +13255,7 @@ async function connectMcpServer(name, options) {
13255
13255
  }
13256
13256
  async function createTransport(url, transport, requestInit, fetchImpl) {
13257
13257
  if (transport === "sse") {
13258
- const { SSEClientTransport } = await import("./sse-CYVBGHvF.mjs");
13258
+ const { SSEClientTransport } = await import("./sse-D12n5Ckf.mjs");
13259
13259
  return new SSEClientTransport(url, {
13260
13260
  requestInit,
13261
13261
  fetch: fetchImpl
@@ -16587,6 +16587,56 @@ const triggerSchedulesSqlite = sqliteTable("trigger_schedules", {
16587
16587
  enabled: integer("enabled").notNull(),
16588
16588
  updatedAt: integer("updated_at", { mode: "timestamp_ms" }).notNull()
16589
16589
  }, (table) => [uniqueIndex("trigger_schedules_project_id_attachment_key_idx").on(table.projectId, table.attachmentKey), index("trigger_schedules_next_run_at_idx").on(table.nextRunAt, table.enabled)]);
16590
+ const workflowEvents = pgTable("workflow_events", {
16591
+ id: text$1("id").primaryKey(),
16592
+ runId: text$1("run_id").notNull().references(() => workflowRuns.id),
16593
+ projectId: text$1("project_id").notNull(),
16594
+ seq: integer$1("seq").notNull(),
16595
+ type: text$1("type").$type().notNull(),
16596
+ correlationId: text$1("correlation_id"),
16597
+ data: jsonb("data"),
16598
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull()
16599
+ }, (table) => [
16600
+ uniqueIndex$1("workflow_events_run_id_seq_unique").on(table.runId, table.seq),
16601
+ index$1("workflow_events_run_id_type_idx").on(table.runId, table.type),
16602
+ index$1("workflow_events_correlation_id_idx").on(table.correlationId)
16603
+ ]);
16604
+ const workflowEventsSqlite = sqliteTable("workflow_events", {
16605
+ id: text("id").primaryKey(),
16606
+ runId: text("run_id").notNull().references(() => workflowRunsSqlite.id),
16607
+ projectId: text("project_id").notNull(),
16608
+ seq: integer("seq").notNull(),
16609
+ type: text("type").$type().notNull(),
16610
+ correlationId: text("correlation_id"),
16611
+ data: text("data", { mode: "json" }),
16612
+ createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull()
16613
+ }, (table) => [
16614
+ uniqueIndex("workflow_events_run_id_seq_unique").on(table.runId, table.seq),
16615
+ index("workflow_events_run_id_type_idx").on(table.runId, table.type),
16616
+ index("workflow_events_correlation_id_idx").on(table.correlationId)
16617
+ ]);
16618
+ const workflowHooks = pgTable("workflow_hooks", {
16619
+ hookId: text$1("hook_id").primaryKey(),
16620
+ runId: text$1("run_id").notNull().references(() => workflowRuns.id),
16621
+ projectId: text$1("project_id").notNull(),
16622
+ token: text$1("token").notNull(),
16623
+ correlationId: text$1("correlation_id").notNull(),
16624
+ status: text$1("status").$type().notNull(),
16625
+ payload: jsonb("payload"),
16626
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull(),
16627
+ resumedAt: timestamp("resumed_at", { withTimezone: true })
16628
+ }, (table) => [uniqueIndex$1("workflow_hooks_token_unique").on(table.token), index$1("workflow_hooks_run_id_idx").on(table.runId)]);
16629
+ const workflowHooksSqlite = sqliteTable("workflow_hooks", {
16630
+ hookId: text("hook_id").primaryKey(),
16631
+ runId: text("run_id").notNull().references(() => workflowRunsSqlite.id),
16632
+ projectId: text("project_id").notNull(),
16633
+ token: text("token").notNull(),
16634
+ correlationId: text("correlation_id").notNull(),
16635
+ status: text("status").$type().notNull(),
16636
+ payload: text("payload", { mode: "json" }),
16637
+ createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
16638
+ resumedAt: integer("resumed_at", { mode: "timestamp_ms" })
16639
+ }, (table) => [uniqueIndex("workflow_hooks_token_unique").on(table.token), index("workflow_hooks_run_id_idx").on(table.runId)]);
16590
16640
  const oauthApps$1 = pgTable("oauth_apps", {
16591
16641
  id: text$1("id").primaryKey(),
16592
16642
  projectId: text$1("project_id").notNull(),
@@ -16879,6 +16929,14 @@ const tableRegistry = {
16879
16929
  pg: workflowRuns,
16880
16930
  sqlite: workflowRunsSqlite
16881
16931
  },
16932
+ workflowEvents: {
16933
+ pg: workflowEvents,
16934
+ sqlite: workflowEventsSqlite
16935
+ },
16936
+ workflowHooks: {
16937
+ pg: workflowHooks,
16938
+ sqlite: workflowHooksSqlite
16939
+ },
16882
16940
  credentialInstances: {
16883
16941
  pg: credentialInstances,
16884
16942
  sqlite: credentialInstancesSqlite
@@ -18036,4 +18094,4 @@ async function withSpan(input, fn) {
18036
18094
  //#endregion
18037
18095
  export { JSONRPCMessageSchema as A, createParser as C, createFetchWithInit as D, extractWWWAuthenticateParams as E, normalizeHeaders as O, isMcp as S, auth as T, touchSession as _, buildCredentialRunContext as a, connectMcpStdio as b, isCredentialError as c, MESSAGE_EVENT_TYPE as d, appendEvent as f, listMessageEvents as g, getSession as h, withSpan as i, zodToJsonSchema as k, resolveActionCredentials as l, getAgentByRoute as m, getTraceContext as n, captureCredentialToolErrors as o, createSession as p, logSystem as r, createCredentialResolver as s, captureConsole as t, resolveMcpTools as u, connectMcpDefinition as v, UnauthorizedError as w, defineMcp as x, connectMcpServer as y };
18038
18096
 
18039
- //# sourceMappingURL=dist-D6CLdIst.mjs.map
18097
+ //# sourceMappingURL=dist-DgIJtGrg.mjs.map