experimental-ash 0.22.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/docs/internals/hooks.md +13 -16
  3. package/dist/docs/internals/message-runtime.md +1 -1
  4. package/dist/docs/public/auth-and-route-protection.md +3 -3
  5. package/dist/docs/public/faqs.md +67 -0
  6. package/dist/docs/public/meta.json +1 -0
  7. package/dist/docs/public/schedules.md +11 -0
  8. package/dist/docs/public/session-context.md +46 -89
  9. package/dist/docs/public/skills.md +13 -0
  10. package/dist/docs/public/subagents.md +12 -6
  11. package/dist/docs/public/tools.md +9 -13
  12. package/dist/docs/public/typescript-api.md +4 -4
  13. package/dist/src/channel/types.d.ts +10 -12
  14. package/dist/src/chunks/{client-CKsU8Li3.js → client-nshDsWNF.js} +1 -1
  15. package/dist/src/chunks/{dev-authored-source-watcher-BLzYWh05.js → dev-authored-source-watcher-B4PaZGUr.js} +1 -1
  16. package/dist/src/chunks/host-DsW72Q-w.js +65 -0
  17. package/dist/src/chunks/paths-OknjaYR8.js +89 -0
  18. package/dist/src/chunks/prewarm-B4YblQ5m.js +6 -0
  19. package/dist/src/cli/commands/info.js +1 -1
  20. package/dist/src/cli/dev/repl.js +2 -2
  21. package/dist/src/cli/run.js +1 -1
  22. package/dist/src/client/session.js +8 -0
  23. package/dist/src/client/types.d.ts +12 -1
  24. package/dist/src/compiled/.vendor-stamp.json +3 -3
  25. package/dist/src/compiled/@workflow/core/_ms.d.ts +4 -0
  26. package/dist/src/compiled/@workflow/core/_workflow-serde.d.ts +5 -0
  27. package/dist/src/compiled/@workflow/core/_workflow-utils.d.ts +8 -0
  28. package/dist/src/compiled/@workflow/core/_workflow-world.d.ts +59 -0
  29. package/dist/src/compiled/@workflow/core/capabilities.d.ts +45 -0
  30. package/dist/src/compiled/@workflow/core/capture-stack.d.ts +16 -0
  31. package/dist/src/compiled/@workflow/core/class-serialization.d.ts +31 -0
  32. package/dist/src/compiled/@workflow/core/classify-error.d.ts +20 -0
  33. package/dist/src/compiled/@workflow/core/context-errors.d.ts +27 -0
  34. package/dist/src/compiled/@workflow/core/context-violation-error.d.ts +97 -0
  35. package/dist/src/compiled/@workflow/core/create-hook.d.ts +179 -0
  36. package/dist/src/compiled/@workflow/core/define-hook.d.ts +68 -0
  37. package/dist/src/compiled/@workflow/core/describe-error.d.ts +70 -0
  38. package/dist/src/compiled/@workflow/core/encryption.d.ts +51 -0
  39. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +64 -0
  40. package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +82 -0
  41. package/dist/src/compiled/@workflow/core/global.d.ts +48 -0
  42. package/dist/src/compiled/@workflow/core/index.d.ts +19 -38
  43. package/dist/src/compiled/@workflow/core/index.js +2 -2
  44. package/dist/src/compiled/@workflow/core/log-format.d.ts +25 -0
  45. package/dist/src/compiled/@workflow/core/logger.d.ts +29 -0
  46. package/dist/src/compiled/@workflow/core/package.json +1 -1
  47. package/dist/src/compiled/@workflow/core/private.d.ts +59 -10
  48. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +51 -0
  49. package/dist/src/compiled/@workflow/core/runtime/get-port-lazy.d.ts +10 -0
  50. package/dist/src/compiled/@workflow/core/runtime/get-world-lazy.d.ts +32 -0
  51. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +97 -0
  52. package/dist/src/compiled/@workflow/core/runtime/replay-budget.d.ts +98 -0
  53. package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +77 -0
  54. package/dist/src/compiled/@workflow/core/runtime/run.d.ts +134 -0
  55. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +50 -0
  56. package/dist/src/compiled/@workflow/core/runtime/start.d.ts +59 -0
  57. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +40 -0
  58. package/dist/src/compiled/@workflow/core/runtime/step-handler.d.ts +2 -0
  59. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +42 -0
  60. package/dist/src/compiled/@workflow/core/runtime/world-init.d.ts +75 -0
  61. package/dist/src/compiled/@workflow/core/runtime/world.d.ts +32 -0
  62. package/dist/src/compiled/@workflow/core/runtime.d.ts +22 -67
  63. package/dist/src/compiled/@workflow/core/runtime.js +27 -27
  64. package/dist/src/compiled/@workflow/core/schemas.d.ts +15 -0
  65. package/dist/src/compiled/@workflow/core/serialization/client.d.ts +17 -0
  66. package/dist/src/compiled/@workflow/core/serialization/codec-devalue.d.ts +14 -0
  67. package/dist/src/compiled/@workflow/core/serialization/codec.d.ts +90 -0
  68. package/dist/src/compiled/@workflow/core/serialization/encryption.d.ts +32 -0
  69. package/dist/src/compiled/@workflow/core/serialization/errors.d.ts +21 -0
  70. package/dist/src/compiled/@workflow/core/serialization/format.d.ts +60 -0
  71. package/dist/src/compiled/@workflow/core/serialization/index.d.ts +18 -0
  72. package/dist/src/compiled/@workflow/core/serialization/reducers/class.d.ts +11 -0
  73. package/dist/src/compiled/@workflow/core/serialization/reducers/common.d.ts +16 -0
  74. package/dist/src/compiled/@workflow/core/serialization/reducers/step-function.d.ts +35 -0
  75. package/dist/src/compiled/@workflow/core/serialization/step.d.ts +17 -0
  76. package/dist/src/compiled/@workflow/core/serialization/types.d.ts +215 -0
  77. package/dist/src/compiled/@workflow/core/serialization/workflow.d.ts +29 -0
  78. package/dist/src/compiled/@workflow/core/serialization-format.d.ts +171 -0
  79. package/dist/src/compiled/@workflow/core/serialization.d.ts +337 -0
  80. package/dist/src/compiled/@workflow/core/sleep.d.ts +33 -0
  81. package/dist/src/compiled/@workflow/core/source-map.d.ts +10 -0
  82. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +13 -0
  83. package/dist/src/compiled/@workflow/core/step/get-closure-vars.d.ts +9 -0
  84. package/dist/src/compiled/@workflow/core/step/get-step-metadata.d.ts +42 -0
  85. package/dist/src/compiled/@workflow/core/step/get-workflow-metadata.d.ts +7 -0
  86. package/dist/src/compiled/@workflow/core/step/writable-stream.d.ts +22 -0
  87. package/dist/src/compiled/@workflow/core/step.d.ts +4 -0
  88. package/dist/src/compiled/@workflow/core/symbols.d.ts +36 -0
  89. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +283 -0
  90. package/dist/src/compiled/@workflow/core/telemetry.d.ts +53 -0
  91. package/dist/src/compiled/@workflow/core/types.d.ts +14 -0
  92. package/dist/src/compiled/@workflow/core/util.d.ts +40 -0
  93. package/dist/src/compiled/@workflow/core/version.d.ts +2 -0
  94. package/dist/src/compiled/@workflow/core/vm/index.d.ts +17 -0
  95. package/dist/src/compiled/@workflow/core/vm/uint8array-base64.d.ts +21 -0
  96. package/dist/src/compiled/@workflow/core/vm/uuid.d.ts +10 -0
  97. package/dist/src/compiled/@workflow/core/workflow/abort-controller.d.ts +65 -0
  98. package/dist/src/compiled/@workflow/core/workflow/create-hook.d.ts +7 -0
  99. package/dist/src/compiled/@workflow/core/workflow/define-hook.d.ts +10 -0
  100. package/dist/src/compiled/@workflow/core/workflow/get-workflow-metadata.d.ts +32 -0
  101. package/dist/src/compiled/@workflow/core/workflow/hook.d.ts +4 -0
  102. package/dist/src/compiled/@workflow/core/workflow/index.d.ts +11 -0
  103. package/dist/src/compiled/@workflow/core/workflow/sleep.d.ts +4 -0
  104. package/dist/src/compiled/@workflow/core/workflow/world-init-stub.d.ts +15 -0
  105. package/dist/src/compiled/@workflow/core/workflow/writable-stream.d.ts +3 -0
  106. package/dist/src/compiled/@workflow/core/workflow.d.ts +1 -38
  107. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  108. package/dist/src/compiled/@workflow/errors/error-codes.d.ts +5 -1
  109. package/dist/src/compiled/@workflow/errors/index.d.ts +15 -1
  110. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  111. package/dist/src/compiled/@workflow/errors/package.json +1 -1
  112. package/dist/src/compiled/_chunks/workflow/{context-errors-zbKocOyk.js → context-errors-Bbvvp-li.js} +2 -2
  113. package/dist/src/compiled/_chunks/workflow/{dist-0iNBqPYp.js → dist-C7wPwOI9.js} +2 -2
  114. package/dist/src/compiled/_chunks/workflow/{dist-D774SUM4.js → dist-C_oiE-l7.js} +1 -1
  115. package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +12 -0
  116. package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +1 -0
  117. package/dist/src/compiled/_chunks/workflow/{symbols-D-4tVV8x.js → symbols-QezhMuLg.js} +1 -1
  118. package/dist/src/evals/cli/eval.js +1 -1
  119. package/dist/src/execution/await-authorization-orchestrator.d.ts +2 -1
  120. package/dist/src/execution/await-authorization-orchestrator.js +4 -0
  121. package/dist/src/execution/connection-auth-steps.d.ts +4 -0
  122. package/dist/src/execution/connection-auth-steps.js +9 -11
  123. package/dist/src/execution/node-step.d.ts +4 -5
  124. package/dist/src/execution/subagent-adapter.d.ts +0 -27
  125. package/dist/src/execution/subagent-adapter.js +2 -66
  126. package/dist/src/execution/subagent-hitl-proxy.d.ts +2 -2
  127. package/dist/src/execution/subagent-hitl-proxy.js +2 -2
  128. package/dist/src/execution/task-mode.d.ts +3 -3
  129. package/dist/src/execution/task-mode.js +3 -3
  130. package/dist/src/execution/turn-workflow.d.ts +41 -0
  131. package/dist/src/execution/turn-workflow.js +96 -0
  132. package/dist/src/execution/workflow-entry.js +77 -87
  133. package/dist/src/execution/workflow-errors.d.ts +14 -0
  134. package/dist/src/execution/workflow-errors.js +54 -0
  135. package/dist/src/execution/workflow-runtime.d.ts +34 -3
  136. package/dist/src/execution/workflow-runtime.js +52 -10
  137. package/dist/src/execution/workflow-steps.d.ts +27 -2
  138. package/dist/src/execution/workflow-steps.js +31 -26
  139. package/dist/src/harness/instrumentation-config.js +14 -7
  140. package/dist/src/harness/messages.d.ts +7 -7
  141. package/dist/src/harness/messages.js +4 -4
  142. package/dist/src/harness/runtime-actions.d.ts +4 -4
  143. package/dist/src/internal/application/package.js +1 -1
  144. package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +1 -1
  145. package/dist/src/internal/workflow-bundle/workflow-builders.js +20 -8
  146. package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +13 -0
  147. package/dist/src/internal/workflow-bundle/workflow-transformer.js +10 -4
  148. package/dist/src/protocol/message.d.ts +6 -1
  149. package/dist/src/public/channels/ash.js +50 -3
  150. package/dist/src/public/context/index.d.ts +4 -7
  151. package/dist/src/public/context/index.js +4 -5
  152. package/dist/src/public/definitions/state.d.ts +33 -0
  153. package/dist/src/public/definitions/state.js +34 -0
  154. package/dist/src/public/next/index.d.ts +7 -0
  155. package/dist/src/public/next/index.js +2 -0
  156. package/dist/src/public/next/vercel-json.d.ts +1 -0
  157. package/dist/src/public/next/vercel-json.js +1 -0
  158. package/dist/src/react/index.d.ts +1 -1
  159. package/dist/src/react/use-ash-agent.d.ts +8 -0
  160. package/dist/src/react/use-ash-agent.js +26 -4
  161. package/dist/src/services/dev-client.d.ts +4 -1
  162. package/dist/src/services/dev-client.js +1 -0
  163. package/package.json +4 -4
  164. package/dist/src/chunks/host-DREC8e8Z.js +0 -65
  165. package/dist/src/chunks/paths-C6sp4T2U.js +0 -88
  166. package/dist/src/chunks/prewarm-hz8p2jlZ.js +0 -6
  167. package/dist/src/compiled/_chunks/workflow/resume-hook-CL8Ed91K.js +0 -12
  168. package/dist/src/compiled/_chunks/workflow/sleep-Dn3i9nxI.js +0 -1
  169. package/dist/src/execution/continuous-entry.d.ts +0 -59
  170. package/dist/src/execution/continuous-entry.js +0 -487
  171. package/dist/src/execution/continuous-runtime.d.ts +0 -17
  172. package/dist/src/execution/continuous-runtime.js +0 -123
@@ -0,0 +1,97 @@
1
+ import type { Event, HealthCheckPayload, ValidQueueName, WorkflowRun, World } from '../_workflow-world.js';
2
+ import { type CryptoKey } from '../encryption.js';
3
+ /**
4
+ * Validates a workflow name and returns the corresponding queue name.
5
+ * Ensures the workflow name only contains safe characters before
6
+ * interpolating it into the queue name string.
7
+ */
8
+ export declare function getWorkflowQueueName(workflowName: string): ValidQueueName;
9
+ /**
10
+ * Result of a health check operation.
11
+ */
12
+ export interface HealthCheckResult {
13
+ healthy: boolean;
14
+ /** Error message if health check failed */
15
+ error?: string;
16
+ /** Latency if the health check was successful */
17
+ latencyMs?: number;
18
+ /** Spec version of the responding deployment */
19
+ specVersion?: number;
20
+ }
21
+ /**
22
+ * Checks if the given message is a health check payload.
23
+ * If so, returns the parsed payload. Otherwise returns undefined.
24
+ */
25
+ export declare function parseHealthCheckPayload(message: unknown): HealthCheckPayload | undefined;
26
+ /**
27
+ * Handles a health check message by writing the result to the world's stream.
28
+ * The caller can listen to this stream to get the health check response.
29
+ *
30
+ * @param healthCheck - The parsed health check payload
31
+ * @param endpoint - Which endpoint is responding ('workflow' or 'step')
32
+ */
33
+ export declare function handleHealthCheckMessage(healthCheck: HealthCheckPayload, endpoint: 'workflow' | 'step', worldSpecVersion?: number): Promise<void>;
34
+ export type HealthCheckEndpoint = 'workflow' | 'step';
35
+ export interface HealthCheckOptions {
36
+ /** Timeout in milliseconds to wait for health check response. Default: 30000 (30s) */
37
+ timeout?: number;
38
+ /** Deployment ID to send the health check to. Falls back to process.env.VERCEL_DEPLOYMENT_ID. */
39
+ deploymentId?: string;
40
+ }
41
+ export declare function healthCheck(world: World, endpoint: HealthCheckEndpoint, options?: HealthCheckOptions): Promise<HealthCheckResult>;
42
+ /**
43
+ * Loads workflow run events by iterating through all pages of paginated
44
+ * results. Events are returned in chronological (ascending) order for
45
+ * deterministic workflow replay.
46
+ *
47
+ * @param runId - The workflow run ID.
48
+ * @param afterCursor - If provided, only events after this cursor are
49
+ * returned (incremental load). If omitted, all events are returned.
50
+ * The returned cursor can be passed back in on a subsequent call for
51
+ * incremental loading.
52
+ */
53
+ export declare function loadWorkflowRunEvents(runId: string, afterCursor?: string): Promise<{
54
+ events: Event[];
55
+ cursor: string | null;
56
+ }>;
57
+ /**
58
+ * Wraps a request/response handler and adds a health check "mode"
59
+ * based on the presence of a `__health` query parameter.
60
+ */
61
+ export declare function withHealthCheck(handler: (req: Request) => Promise<Response>, worldSpecVersion?: number): (req: Request) => Promise<Response>;
62
+ /**
63
+ * Queues a message to the specified queue with tracing.
64
+ */
65
+ export declare function queueMessage(world: World, ...args: Parameters<typeof world.queue>): Promise<void>;
66
+ /**
67
+ * Calculates the queue overhead time in milliseconds for a given message.
68
+ */
69
+ export declare function getQueueOverhead(message: {
70
+ requestedAt?: Date;
71
+ }): {
72
+ [k: string]: number;
73
+ } | undefined;
74
+ /**
75
+ * Returns a memoized accessor for the per-run AES-256 encryption key.
76
+ *
77
+ * The first call resolves the key via `world.getEncryptionKeyForRun` (which
78
+ * may do HKDF derivation locally on Vercel, or a network fetch from
79
+ * external contexts) and imports it as a `CryptoKey`; subsequent calls
80
+ * await the same cached promise. If the world doesn't support encryption
81
+ * or the run has no key configured, the cached value is `undefined`.
82
+ *
83
+ * Used by step / workflow handlers to defer the (potentially expensive)
84
+ * key fetch until the first code path that actually needs it — typically
85
+ * input hydration on the success path, or error dehydration on a failure
86
+ * path. Both paths can race-call the accessor without triggering duplicate
87
+ * fetches.
88
+ *
89
+ * Errors thrown by `getEncryptionKeyForRun` propagate to every caller
90
+ * (the cached promise rejects). This is intentional: when encryption is
91
+ * configured, we never want to silently fall back to plaintext
92
+ * serialization. A propagated error in an event-emission path leaves the
93
+ * outer try/catch to log and surface the issue; the queue's redelivery
94
+ * semantics will retry the key fetch on the next attempt.
95
+ */
96
+ export declare function memoizeEncryptionKey(world: World, runOrId: WorkflowRun | string): () => Promise<CryptoKey | undefined>;
97
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Per-invocation accounting of the *non-step* portion of a workflow
3
+ * handler run: deterministic event-log replay, workflow-VM execution
4
+ * between step boundaries, suspension handling, queue round-trips, etc.
5
+ * Inline step bodies (`"use step"` functions invoked via `executeStep`)
6
+ * are intentionally excluded — they are bounded by the platform's
7
+ * function `maxDuration` and the `NO_INLINE_REPLAY_AFTER_MS` early-return
8
+ * guard.
9
+ *
10
+ * Usage:
11
+ *
12
+ * ```ts
13
+ * const budget = new ReplayBudget();
14
+ * // …non-step work happens here, accumulates against the budget…
15
+ * budget.pause();
16
+ * try {
17
+ * await executeStep(...); // not charged
18
+ * } finally {
19
+ * budget.resume();
20
+ * }
21
+ * // back to charging
22
+ * if (budget.isExhausted()) { ... }
23
+ * ```
24
+ *
25
+ * Implementation notes:
26
+ *
27
+ * - `pause()` and `resume()` are idempotent: calling `pause()` while
28
+ * already paused (or `resume()` while already resumed) is a no-op.
29
+ * This protects against double-counting in future refactors that nest
30
+ * step execution or take an early-return path between a `pause()` and
31
+ * the matching `resume()`.
32
+ * - `isExhausted()` is checked at loop boundaries by the caller — the
33
+ * budget itself does not arm any timers. This means an in-flight
34
+ * pathological `runWorkflow` call (e.g. a huge event-log replay) can
35
+ * overshoot the budget by up to one iteration's worth of work before
36
+ * the next check fires. In practice the 20s headroom built into
37
+ * `MAX_REPLAY_TIMEOUT_MS` (and the function `maxDuration` ceiling)
38
+ * gives us slack; the old `setTimeout`-based approach also ultimately
39
+ * relied on the platform SIGTERM as the hard backstop.
40
+ */
41
+ export declare class ReplayBudget {
42
+ private readonly limitMs;
43
+ private elapsedMs;
44
+ private intervalStart;
45
+ constructor(limitMs?: number);
46
+ /**
47
+ * The configured replay-timeout limit, in ms. Useful for log messages.
48
+ */
49
+ get configuredLimitMs(): number;
50
+ /**
51
+ * Total non-step time accumulated so far, in ms. Includes the
52
+ * currently-active interval if the budget is not paused.
53
+ */
54
+ elapsed(): number;
55
+ /**
56
+ * Stop counting elapsed time toward the budget. Idempotent — safe to
57
+ * call multiple times in a row; subsequent calls are no-ops until
58
+ * `resume()` reopens an interval.
59
+ */
60
+ pause(): void;
61
+ /**
62
+ * Resume counting elapsed time toward the budget. Idempotent — safe to
63
+ * call multiple times in a row; subsequent calls re-anchor the
64
+ * interval start to `now()`, which is fine because no time accrues
65
+ * between back-to-back `resume()` calls.
66
+ */
67
+ resume(): void;
68
+ /**
69
+ * True if the budget has been exhausted (`elapsed() >= limitMs`).
70
+ * Callers should invoke `handleExhausted(...)` afterward and return
71
+ * from the handler.
72
+ */
73
+ isExhausted(): boolean;
74
+ }
75
+ /**
76
+ * Fail the run (or retry, on early attempts) when the replay budget is
77
+ * exhausted. The handling depends on whether the underlying World
78
+ * supports `process.exit(1)` as a queue redelivery signal (see
79
+ * `World.processExitTriggersQueueRedelivery`):
80
+ *
81
+ * - **Managed-platform Worlds** (`world-vercel`): on attempts <=
82
+ * `REPLAY_TIMEOUT_MAX_RETRIES` exit the process so the platform fails
83
+ * the invocation and the queue redelivers; on the next attempt write
84
+ * `run_failed` with `RUN_ERROR_CODES.REPLAY_TIMEOUT` and exit.
85
+ *
86
+ * - **In-process Worlds** (`world-local`, dev servers): calling
87
+ * `process.exit()` would terminate the host (e.g. `pnpm dev`), so
88
+ * instead log a warning, write `run_failed` best-effort, and return.
89
+ * The framework completes the request normally.
90
+ */
91
+ export declare function handleReplayBudgetExhausted(args: {
92
+ runId: string;
93
+ workflowName: string;
94
+ requestId: string | undefined;
95
+ attempt: number;
96
+ limitMs: number;
97
+ }): Promise<void>;
98
+ //# sourceMappingURL=replay-budget.d.ts.map
@@ -0,0 +1,77 @@
1
+ import { type Hook } from '../_workflow-world.js';
2
+ import { type CryptoKey } from '../encryption.js';
3
+ /**
4
+ * Get the hook by token to find the associated workflow run,
5
+ * and hydrate the `metadata` property if it was set from within
6
+ * the workflow run.
7
+ *
8
+ * @param token - The unique token identifying the hook
9
+ */
10
+ export declare function getHookByToken(token: string): Promise<Hook>;
11
+ /**
12
+ * Resumes a workflow run by sending a payload to a hook identified by its token.
13
+ *
14
+ * This function is called externally (e.g., from an API route or server action)
15
+ * to send data to a hook and resume the associated workflow run.
16
+ *
17
+ * @param tokenOrHook - The unique token identifying the hook, or the hook object itself
18
+ * @param payload - The data payload to send to the hook
19
+ * @returns Promise resolving to the hook
20
+ * @throws Error if the hook is not found or if there's an error during the process
21
+ *
22
+ * @example
23
+ *
24
+ * ```ts
25
+ * // In an API route
26
+ * import { resumeHook } from '@workflow/core/runtime';
27
+ *
28
+ * export async function POST(request: Request) {
29
+ * const { token, data } = await request.json();
30
+ *
31
+ * try {
32
+ * const hook = await resumeHook(token, data);
33
+ * return Response.json({ runId: hook.runId });
34
+ * } catch (error) {
35
+ * return new Response('Hook not found', { status: 404 });
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ export declare function resumeHook<T = any>(tokenOrHook: string | Hook, payload: T, encryptionKeyOverride?: CryptoKey): Promise<Hook>;
41
+ /**
42
+ * Resumes a webhook by sending a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request | Request}
43
+ * object to a hook identified by its token.
44
+ *
45
+ * This function is called externally (e.g., from an API route or server action)
46
+ * to send a request to a webhook and resume the associated workflow run.
47
+ *
48
+ * @param token - The unique token identifying the hook
49
+ * @param request - The request to send to the hook
50
+ * @returns Promise resolving to the response
51
+ * @throws Error if the hook is not found or if there's an error during the process
52
+ *
53
+ * @example
54
+ *
55
+ * ```ts
56
+ * // In an API route
57
+ * import { resumeWebhook } from '@workflow/core/runtime';
58
+ *
59
+ * export async function POST(request: Request) {
60
+ * const url = new URL(request.url);
61
+ * const token = url.searchParams.get('token');
62
+ *
63
+ * if (!token) {
64
+ * return new Response('Missing token', { status: 400 });
65
+ * }
66
+ *
67
+ * try {
68
+ * const response = await resumeWebhook(token, request);
69
+ * return response;
70
+ * } catch (error) {
71
+ * return new Response('Webhook not found', { status: 404 });
72
+ * }
73
+ * }
74
+ * ```
75
+ */
76
+ export declare function resumeWebhook(token: string, request: Request): Promise<Response>;
77
+ //# sourceMappingURL=resume-hook.d.ts.map
@@ -0,0 +1,134 @@
1
+ import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '../_workflow-serde.js';
2
+ import { type WorkflowRunStatus } from '../_workflow-world.js';
3
+ import { type StopSleepOptions, type StopSleepResult } from './runs.js';
4
+ /**
5
+ * A `ReadableStream` extended with workflow-specific helpers.
6
+ */
7
+ export type WorkflowReadableStream<R = any> = ReadableStream<R> & {
8
+ /**
9
+ * Returns the tail index (index of the last known chunk, 0-based) of the
10
+ * underlying workflow stream. Useful for resolving a negative `startIndex`
11
+ * into an absolute position — for example, when building reconnection
12
+ * endpoints that need to inform the client where the stream starts.
13
+ *
14
+ * Returns `-1` when no chunks have been written yet.
15
+ */
16
+ getTailIndex(): Promise<number>;
17
+ };
18
+ /**
19
+ * Options for configuring a workflow's readable stream.
20
+ */
21
+ export interface WorkflowReadableStreamOptions {
22
+ /**
23
+ * An optional namespace to distinguish between multiple streams associated
24
+ * with the same workflow run.
25
+ */
26
+ namespace?: string;
27
+ /**
28
+ * The index number of the starting chunk to begin reading the stream from.
29
+ * Negative values start from the end (e.g. -3 reads the last 3 chunks).
30
+ */
31
+ startIndex?: number;
32
+ /**
33
+ * Any asynchronous operations that need to be performed before the execution
34
+ * environment is paused / terminated
35
+ * (i.e. using [`waitUntil()`](https://developer.mozilla.org/docs/Web/API/ExtendableEvent/waitUntil) or similar).
36
+ */
37
+ ops?: Promise<any>[];
38
+ /**
39
+ * The global object to use for hydrating types from the global scope.
40
+ *
41
+ * Defaults to {@link [`globalThis`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/globalThis)}.
42
+ */
43
+ global?: Record<string, any>;
44
+ }
45
+ /**
46
+ * A handler class for a workflow run.
47
+ */
48
+ export declare class Run<TResult> {
49
+ #private;
50
+ static [WORKFLOW_SERIALIZE](instance: Run<unknown>): {
51
+ runId: string;
52
+ resilientStart: boolean;
53
+ };
54
+ static [WORKFLOW_DESERIALIZE](data: {
55
+ runId: string;
56
+ resilientStart?: boolean;
57
+ }): Run<unknown>;
58
+ /**
59
+ * The ID of the workflow run.
60
+ */
61
+ runId: string;
62
+ constructor(runId: string, opts?: {
63
+ resilientStart?: boolean;
64
+ });
65
+ /**
66
+ * Interrupts pending `sleep()` calls, resuming the workflow early.
67
+ *
68
+ * @param options - Optional settings to target specific sleep calls by correlation ID.
69
+ * If not provided, all pending sleep calls will be interrupted.
70
+ * @returns A {@link StopSleepResult} object containing the number of sleep calls that were interrupted.
71
+ */
72
+ wakeUp(options?: StopSleepOptions): Promise<StopSleepResult>;
73
+ /**
74
+ * Cancels the workflow run.
75
+ */
76
+ cancel(): Promise<void>;
77
+ /**
78
+ * Whether the workflow run exists.
79
+ */
80
+ get exists(): Promise<boolean>;
81
+ /**
82
+ * The status of the workflow run.
83
+ */
84
+ get status(): Promise<WorkflowRunStatus>;
85
+ /**
86
+ * The return value of the workflow run.
87
+ * Polls the workflow return value until it is completed.
88
+ */
89
+ get returnValue(): Promise<TResult>;
90
+ /**
91
+ * The name of the workflow.
92
+ */
93
+ get workflowName(): Promise<string>;
94
+ /**
95
+ * The timestamp when the workflow run was created.
96
+ */
97
+ get createdAt(): Promise<Date>;
98
+ /**
99
+ * The timestamp when the workflow run started execution.
100
+ * Returns undefined if the workflow has not started yet.
101
+ */
102
+ get startedAt(): Promise<Date | undefined>;
103
+ /**
104
+ * The timestamp when the workflow run completed.
105
+ * Returns undefined if the workflow has not completed yet.
106
+ */
107
+ get completedAt(): Promise<Date | undefined>;
108
+ /**
109
+ * The readable stream of the workflow run.
110
+ */
111
+ get readable(): WorkflowReadableStream;
112
+ /**
113
+ * Retrieves the workflow run's default readable stream, which reads chunks
114
+ * written to the corresponding writable stream {@link getWritable}.
115
+ *
116
+ * The returned stream has an additional {@link WorkflowReadableStream.getTailIndex | getTailIndex()}
117
+ * helper that returns the index of the last known chunk. This is useful when
118
+ * building reconnection endpoints that need to inform clients where the
119
+ * stream starts.
120
+ *
121
+ * @param options - The options for the readable stream.
122
+ * @returns A `WorkflowReadableStream` for the workflow run.
123
+ */
124
+ getReadable<R = any>(options?: WorkflowReadableStreamOptions): WorkflowReadableStream<R>;
125
+ }
126
+ /**
127
+ * Retrieves a `Run` object for a given run ID.
128
+ *
129
+ * @param runId - The workflow run ID obtained from {@link start}.
130
+ * @returns A `Run` object.
131
+ * @throws WorkflowRunNotFoundError if the run ID is not found.
132
+ */
133
+ export declare function getRun<TResult>(runId: string): Run<TResult>;
134
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1,50 @@
1
+ import { type World } from '../_workflow-world.js';
2
+ export interface RecreateRunOptions {
3
+ deploymentId?: string;
4
+ specVersion?: number;
5
+ }
6
+ export interface StopSleepResult {
7
+ /** Number of pending sleeps that were stopped */
8
+ stoppedCount: number;
9
+ }
10
+ export interface ReadStreamOptions {
11
+ /**
12
+ * The index to start reading from. Defaults to 0.
13
+ * Negative values start from the end (e.g. -3 reads the last 3 chunks).
14
+ */
15
+ startIndex?: number;
16
+ }
17
+ export interface StopSleepOptions {
18
+ /**
19
+ * Optional list of specific correlation IDs to target.
20
+ * If provided, only these sleep calls will be interrupted.
21
+ * If not provided, all pending sleep calls will be interrupted.
22
+ */
23
+ correlationIds?: string[];
24
+ }
25
+ /**
26
+ * Start a new workflow run based on an existing run.
27
+ */
28
+ export declare function recreateRunFromExisting(world: World, runId: string, options?: RecreateRunOptions): Promise<string>;
29
+ /**
30
+ * Cancel a workflow run.
31
+ */
32
+ export declare function cancelRun(world: World, runId: string): Promise<void>;
33
+ /**
34
+ * Re-enqueue a workflow run.
35
+ */
36
+ export declare function reenqueueRun(world: World, runId: string): Promise<void>;
37
+ /**
38
+ * Wake up a workflow run by interrupting pending sleep() calls.
39
+ */
40
+ export declare function wakeUpRun(world: World, runId: string, options?: StopSleepOptions): Promise<StopSleepResult>;
41
+ /**
42
+ * Read from a stream by stream ID.
43
+ * Returns a ReadableStream of Uint8Array chunks.
44
+ */
45
+ export declare function readStream(world: World, runId: string, streamId: string, options?: ReadStreamOptions): Promise<ReadableStream<Uint8Array>>;
46
+ /**
47
+ * List all stream IDs for a workflow run.
48
+ */
49
+ export declare function listStreams(world: World, runId: string): Promise<string[]>;
50
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1,59 @@
1
+ import type { World } from '../_workflow-world.js';
2
+ import { Run } from './run.js';
3
+ export interface StartOptionsBase {
4
+ /**
5
+ * The world to use for the workflow run creation,
6
+ * by default the world is inferred from the environment variables.
7
+ */
8
+ world?: World;
9
+ /**
10
+ * The spec version to use for the workflow run. Defaults to the latest version.
11
+ */
12
+ specVersion?: number;
13
+ }
14
+ export interface StartOptionsWithDeploymentId extends StartOptionsBase {
15
+ /**
16
+ * The deployment ID to use for the workflow run.
17
+ *
18
+ * By default, this is automatically inferred from environment variables
19
+ * when deploying to Vercel.
20
+ *
21
+ * Set to `'latest'` to automatically resolve the most recent deployment
22
+ * for the current environment (same production target or git branch).
23
+ * This is currently a Vercel-specific feature.
24
+ *
25
+ * **Note:** When `deploymentId` is provided, the argument and return types become `unknown`
26
+ * since there is no guarantee the types will be consistent across deployments.
27
+ */
28
+ deploymentId: 'latest' | (string & {});
29
+ }
30
+ export interface StartOptionsWithoutDeploymentId extends StartOptionsBase {
31
+ deploymentId?: undefined;
32
+ }
33
+ /**
34
+ * Options for starting a workflow run.
35
+ */
36
+ export type StartOptions = StartOptionsWithDeploymentId | StartOptionsWithoutDeploymentId;
37
+ /**
38
+ * Represents an imported workflow function.
39
+ */
40
+ export type WorkflowFunction<TArgs extends unknown[], TResult> = (...args: TArgs) => Promise<TResult>;
41
+ /**
42
+ * Represents the generated metadata of a workflow function.
43
+ */
44
+ export type WorkflowMetadata = {
45
+ workflowId: string;
46
+ };
47
+ /**
48
+ * Starts a workflow run.
49
+ *
50
+ * @param workflow - The imported workflow function to start.
51
+ * @param args - The arguments to pass to the workflow (optional).
52
+ * @param options - The options for the workflow run (optional).
53
+ * @returns The unique run ID for the newly started workflow invocation.
54
+ */
55
+ export declare function start<TArgs extends unknown[], TResult>(workflow: WorkflowFunction<TArgs, TResult> | WorkflowMetadata, args: unknown[], options: StartOptionsWithDeploymentId): Promise<Run<unknown>>;
56
+ export declare function start<TResult>(workflow: WorkflowFunction<[], TResult> | WorkflowMetadata, options: StartOptionsWithDeploymentId): Promise<Run<unknown>>;
57
+ export declare function start<TArgs extends unknown[], TResult>(workflow: WorkflowFunction<TArgs, TResult> | WorkflowMetadata, args: TArgs, options?: StartOptionsWithoutDeploymentId): Promise<Run<TResult>>;
58
+ export declare function start<TResult>(workflow: WorkflowFunction<[], TResult> | WorkflowMetadata, options?: StartOptionsWithoutDeploymentId): Promise<Run<TResult>>;
59
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1,40 @@
1
+ import type { World } from '../_workflow-world.js';
2
+ import type { CryptoKey } from '../encryption.js';
3
+ export interface StepExecutorParams {
4
+ world: World;
5
+ workflowRunId: string;
6
+ workflowName: string;
7
+ workflowStartedAt: number;
8
+ stepId: string;
9
+ stepName: string;
10
+ encryptionKey?: CryptoKey;
11
+ }
12
+ /**
13
+ * Result of a step execution attempt. The caller decides what to do
14
+ * based on the result type (e.g., queue workflow continuation, replay inline, etc.).
15
+ */
16
+ export type StepExecutionResult = {
17
+ type: 'completed';
18
+ hasPendingOps?: boolean;
19
+ } | {
20
+ type: 'failed';
21
+ } | {
22
+ type: 'retry';
23
+ timeoutSeconds: number;
24
+ } | {
25
+ type: 'skipped';
26
+ } | {
27
+ type: 'gone';
28
+ } | {
29
+ type: 'throttled';
30
+ timeoutSeconds: number;
31
+ };
32
+ /**
33
+ * Executes a single step: creates step_started event, hydrates input,
34
+ * runs the step function, creates step_completed/step_failed/step_retrying events.
35
+ *
36
+ * Does NOT queue workflow continuation messages — the caller decides what to do next.
37
+ * Used by both the V1 step handler and the V2 combined handler.
38
+ */
39
+ export declare function executeStep(params: StepExecutorParams): Promise<StepExecutionResult>;
40
+ //# sourceMappingURL=step-executor.d.ts.map
@@ -0,0 +1,2 @@
1
+ export declare const stepEntrypoint: (req: Request) => Promise<Response>;
2
+ //# sourceMappingURL=step-handler.d.ts.map
@@ -0,0 +1,42 @@
1
+ import type { Span } from '#compiled/@opentelemetry/api/index.js';
2
+ import { type WorkflowRun, type World } from '../_workflow-world.js';
3
+ import type { StepInvocationQueueItem, WorkflowSuspension } from '../global.js';
4
+ export interface SuspensionHandlerParams {
5
+ suspension: WorkflowSuspension;
6
+ world: World;
7
+ run: WorkflowRun;
8
+ span?: Span;
9
+ requestId?: string;
10
+ }
11
+ /**
12
+ * Result of handling a suspension. Returns pending step items so the caller
13
+ * can decide which to execute inline vs queue to background.
14
+ */
15
+ export interface SuspensionHandlerResult {
16
+ /** Pending step items with events created but NOT queued */
17
+ pendingSteps: StepInvocationQueueItem[];
18
+ /**
19
+ * Correlation IDs for which this suspension call actually wrote the
20
+ * step_created event (as opposed to catching EntityConflictError because
21
+ * a concurrent handler wrote it first). Only the handler that wrote the
22
+ * step_created event should queue / inline-execute the step — this
23
+ * guarantees a single owner per step, even when multiple handlers race
24
+ * into the same batch boundary.
25
+ */
26
+ createdStepCorrelationIds: Set<string>;
27
+ /** Timeout from waits, if any */
28
+ timeoutSeconds?: number;
29
+ /** Whether a hook conflict was detected (should re-invoke immediately) */
30
+ hasHookConflict: boolean;
31
+ }
32
+ /**
33
+ * Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
34
+ * Creates events for all operations but does NOT queue step messages — returns the pending
35
+ * steps so the caller can decide which to execute inline vs queue to background.
36
+ *
37
+ * Processing order:
38
+ * 1. Hooks are processed first to prevent race conditions with webhook receivers
39
+ * 2. Step events and wait events are created in parallel
40
+ */
41
+ export declare function handleSuspension({ suspension, world, run, span, requestId, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
42
+ //# sourceMappingURL=suspension-handler.d.ts.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Server-only side-effect module that ensures `world.ts` is loaded so its
3
+ * module-load side effect — `globalThis[GetWorldFnKey] ??= getWorld` —
4
+ * fires in host bundles.
5
+ *
6
+ * # Why this exists
7
+ *
8
+ * `getWorldLazy()` in `./get-world-lazy.ts` checks the globalThis cache
9
+ * (populated by `world.ts`'s module-load side effect) before falling back
10
+ * to a runtime-built dynamic `import('./world.js')`. When a server route
11
+ * only consumes a single helper that goes through `getWorldLazy` — most
12
+ * commonly `start` from `workflow/api` — webpack/turbopack tree-shake the
13
+ * named import `{ getWorld } from './runtime/world.js'` out of
14
+ * `runtime.ts`, taking `world.ts`'s module evaluation with it. The
15
+ * globalThis registration never fires.
16
+ *
17
+ * `getWorldLazy` then falls through to its dynamic-import fallback, which
18
+ * itself fails: webpack inlines `get-world-lazy.js` into the bundled route
19
+ * file, so the relative specifier `./world.js` resolves against
20
+ * `/var/task/<app>/.next/server/app/<...>/route.js` — where no sibling
21
+ * `world.js` exists — and Node throws `MODULE_NOT_FOUND`. The symptom is a
22
+ * cold-start regression: the very first user request that goes through
23
+ * `start()` fails until some other code path (typically the queue-driven
24
+ * `/.well-known/workflow/v1/flow` route, which uses `getWorld` directly
25
+ * via `workflowEntrypoint`) has loaded `world.ts` and populated the
26
+ * cache.
27
+ *
28
+ * Importing this module for its side effect — exactly once, from the
29
+ * host-side `workflow/api` (`packages/workflow/src/api.ts`) — guarantees
30
+ * `world.ts` enters the bundle, the global is registered at module load,
31
+ * and `getWorldLazy()` short-circuits to the registered function on the
32
+ * first call.
33
+ *
34
+ * # Why a separate module instead of importing `./world.js` directly
35
+ *
36
+ * `world.ts` is internal to `@workflow/core` and not part of the public
37
+ * exports surface. Adding a dedicated public init entry (this file)
38
+ * keeps the side-effect intent obvious to anyone reading
39
+ * `packages/workflow/src/api.ts`, and lets the `workflow` export
40
+ * condition route to a stub for VM/step bundles (see below).
41
+ *
42
+ * # Why this doesn't break VM/step bundles
43
+ *
44
+ * The `@workflow/core/runtime/world-init` export resolves via the
45
+ * `workflow` condition to `./dist/workflow/world-init-stub.js`, an empty
46
+ * module. Esbuild runs the workflow VM and step bundlers with the
47
+ * `workflow` condition active, so they pick up the stub and never reach
48
+ * `world.ts`. Host bundlers (webpack, turbopack, Node.js) use the
49
+ * `default` (or `node`) condition and pick up this file, loading
50
+ * `world.ts` as intended. The split keeps `@workflow/world-vercel`,
51
+ * `@workflow/world-local`, `cbor-x`, and other server-only deps out of
52
+ * the workflow sandbox bundle.
53
+ *
54
+ * # Why we keep the `getWorldLazy` dynamic-import fallback
55
+ *
56
+ * The fallback remains in `./get-world-lazy.ts` as a defense-in-depth for
57
+ * environments we haven't accounted for (CJS test runners, scripts that
58
+ * import `start` without going through `workflow/api`, future bundlers
59
+ * with stricter tree-shaking). With this init module in place, the
60
+ * fallback should never fire in normal use — but if it does, the
61
+ * dynamic-import branch still resolves correctly when `world.js` is
62
+ * physically adjacent on disk (e.g., direct Node.js execution of
63
+ * unbundled source).
64
+ *
65
+ * # Maintenance notes
66
+ *
67
+ * If you add another `getWorldLazy()` consumer that's reachable from a
68
+ * host route without going through `workflow/api` (e.g., a new helper in
69
+ * `workflow/runtime`), make sure that entry also imports this module —
70
+ * or that it transitively reaches `world.ts` via a non-tree-shakeable
71
+ * path. Adding a regression test in `world-init.test.ts` is preferred to
72
+ * relying on careful manual tracing.
73
+ */
74
+ import './world.js';
75
+ //# sourceMappingURL=world-init.d.ts.map