eve 0.38.1 → 0.38.2

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 (104) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/src/cli/commands/registry.js +1 -1
  3. package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
  4. package/dist/src/compiled/.vendor-stamp.json +5 -5
  5. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +97 -0
  6. package/dist/src/compiled/@workflow/core/index.js +2 -2
  7. package/dist/src/compiled/@workflow/core/private.js +1 -1
  8. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +35 -0
  9. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +127 -93
  10. package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +8 -9
  11. package/dist/src/compiled/@workflow/core/runtime/replay-budget.d.ts +8 -0
  12. package/dist/src/compiled/@workflow/core/runtime/resume-latency.d.ts +143 -0
  13. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +27 -12
  14. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +39 -8
  15. package/dist/src/compiled/@workflow/core/runtime/world-compatibility.d.ts +6 -5
  16. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  17. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +81 -0
  18. package/dist/src/compiled/@workflow/core/test-support/orchestrator-context.d.ts +25 -0
  19. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  20. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  21. package/dist/src/compiled/@workflow/errors/index.d.ts +18 -2
  22. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  23. package/dist/src/compiled/@workflow/world/analytics.d.ts +9 -0
  24. package/dist/src/compiled/@workflow/world/events.d.ts +76 -87
  25. package/dist/src/compiled/@workflow/world/index.d.ts +3 -3
  26. package/dist/src/compiled/@workflow/world/interfaces.d.ts +45 -45
  27. package/dist/src/compiled/@workflow/world/queue.d.ts +86 -0
  28. package/dist/src/compiled/@workflow/world/slot-identity.d.ts +15 -0
  29. package/dist/src/compiled/@workflow/world/spec-version.d.ts +30 -18
  30. package/dist/src/compiled/@workflow/world/test-support/duplicate-event-fixtures.d.ts +41 -0
  31. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  32. package/dist/src/compiled/@workflow/world-vercel/index.js +12 -12
  33. package/dist/src/compiled/_chunks/workflow/{attribute-changes-DZtQkszH.js → attribute-changes-B8K0pwpH.js} +1 -1
  34. package/dist/src/compiled/_chunks/workflow/{dist-CPlyFOVo.js → dist-BRGbNjhD.js} +1 -1
  35. package/dist/src/compiled/_chunks/workflow/{dist-xQXN70ED.js → dist-CqvWKNQv.js} +1 -1
  36. package/dist/src/compiled/_chunks/workflow/frames-DoexhtxJ.js +3 -0
  37. package/dist/src/compiled/_chunks/workflow/private-z_2Kcwee.js +1 -0
  38. package/dist/src/compiled/_chunks/workflow/resume-hook-DO_MuJlY.js +1 -0
  39. package/dist/src/compiled/_chunks/workflow/run-lq7-eG0l.js +1 -0
  40. package/dist/src/compiled/_chunks/workflow/sleep-7TgF3i-e.js +1 -0
  41. package/dist/src/compiled/_chunks/workflow/wait-until-BPSgt1Wg.js +15 -0
  42. package/dist/src/compiled/_chunks/workflow/ws-transport-TYZ9zwoZ.js +1 -0
  43. package/dist/src/compiler/model-catalog.js +1 -1
  44. package/dist/src/compiler/normalize-agent-config.js +1 -1
  45. package/dist/src/execution/create-session-step.d.ts +1 -0
  46. package/dist/src/execution/create-session-step.js +1 -1
  47. package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +1 -1
  48. package/dist/src/execution/node-step.js +1 -1
  49. package/dist/src/execution/session-callback-step.d.ts +8 -0
  50. package/dist/src/execution/session-callback-step.js +1 -1
  51. package/dist/src/execution/session.d.ts +2 -0
  52. package/dist/src/execution/session.js +1 -1
  53. package/dist/src/execution/task-event-callback.d.ts +5 -6
  54. package/dist/src/execution/task-event-callback.js +1 -1
  55. package/dist/src/execution/tasks/child/instructions.d.ts +3 -0
  56. package/dist/src/execution/tasks/child/instructions.js +1 -0
  57. package/dist/src/execution/tasks/child/steps.d.ts +7 -1
  58. package/dist/src/execution/tasks/child/steps.js +1 -1
  59. package/dist/src/execution/tasks/child/update.d.ts +10 -0
  60. package/dist/src/execution/tasks/child/update.js +1 -0
  61. package/dist/src/execution/tasks/child/workflow.d.ts +3 -3
  62. package/dist/src/execution/tasks/child/workflow.js +1 -1
  63. package/dist/src/execution/tasks/parent/agent-views.js +1 -1
  64. package/dist/src/execution/tasks/parent/control-shared.d.ts +1 -1
  65. package/dist/src/execution/tasks/parent/dispatch-task-step.d.ts +1 -1
  66. package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
  67. package/dist/src/execution/tasks/parent/dispatch.d.ts +5 -3
  68. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  69. package/dist/src/execution/workflow-entry.js +1 -1
  70. package/dist/src/execution/workflow-steps.js +1 -1
  71. package/dist/src/harness/advertised-tools.d.ts +3 -0
  72. package/dist/src/harness/advertised-tools.js +1 -1
  73. package/dist/src/harness/tool-loop.js +2 -2
  74. package/dist/src/internal/application/package.js +1 -1
  75. package/dist/src/internal/workflow/development-world-client.js +1 -1
  76. package/dist/src/runtime/framework-tools/index.js +1 -1
  77. package/dist/src/runtime/framework-tools/tasks.d.ts +6 -7
  78. package/dist/src/runtime/framework-tools/tasks.js +1 -1
  79. package/dist/src/runtime/prompt/compose.js +1 -1
  80. package/dist/src/runtime/session-callback-route.js +1 -1
  81. package/dist/src/setup/scaffold/create/project.js +1 -1
  82. package/dist/src/tasks/task-id.d.ts +1 -2
  83. package/dist/src/tasks/task-id.js +1 -1
  84. package/dist/src/tasks/task-inbox-token.d.ts +2 -0
  85. package/dist/src/tasks/task-inbox-token.js +1 -0
  86. package/dist/src/tasks/types.d.ts +9 -1
  87. package/dist/src/tasks/wire.d.ts +2 -3
  88. package/docs/channels/custom.mdx +1 -0
  89. package/docs/channels/mcp.mdx +185 -0
  90. package/docs/channels/meta.json +1 -0
  91. package/docs/channels/overview.mdx +6 -1
  92. package/docs/guides/auth-and-route-protection.md +1 -0
  93. package/docs/guides/dev-tui.md +1 -0
  94. package/docs/instructions.mdx +1 -0
  95. package/package.json +6 -6
  96. package/dist/src/compiled/_chunks/workflow/frames-BBs-9k1d.js +0 -3
  97. package/dist/src/compiled/_chunks/workflow/private-UQtz8ZcW.js +0 -1
  98. package/dist/src/compiled/_chunks/workflow/resume-hook-CYtSorp6.js +0 -1
  99. package/dist/src/compiled/_chunks/workflow/run-Cjo0A3NO.js +0 -1
  100. package/dist/src/compiled/_chunks/workflow/sleep-C1P0OWBm.js +0 -1
  101. package/dist/src/compiled/_chunks/workflow/wait-until-CT1ve8qB.js +0 -15
  102. package/dist/src/compiled/_chunks/workflow/ws-transport-beXxD0s_.js +0 -1
  103. package/dist/src/execution/tasks/parent/send.d.ts +0 -25
  104. package/dist/src/execution/tasks/parent/send.js +0 -1
@@ -417,6 +417,87 @@ export declare const HookResilientResumeMaterialized: (value: boolean) => {
417
417
  export declare const HookResumeSetupSource: (value: string) => {
418
418
  [k: string]: string;
419
419
  };
420
+ /**
421
+ * Producer-side signal (on the suspension span) counting steps whose direct
422
+ * `step_created` write failed transiently while their `stepInput`-carrying
423
+ * queue publish succeeded, so step creation is recovered via the consumer's
424
+ * re-ensure. Mirrors {@link HookResilientResume}.
425
+ */
426
+ export declare const StepResilientDispatchRecovered: (value: number) => {
427
+ [k: string]: number;
428
+ };
429
+ /**
430
+ * Consumer-side signal (on the workflow execution span) that this delivery
431
+ * materialized the `step_created` event from the queue message's `stepInput`
432
+ * because the producer's direct write had not landed — the completion of the
433
+ * recovery path {@link StepResilientDispatchRecovered} began.
434
+ */
435
+ export declare const StepResilientDispatchMaterialized: (value: boolean) => {
436
+ [k: string]: boolean;
437
+ };
438
+ /** Total TTR: entry into `resumeHook()` → immediately before `stepFn.apply()`. */
439
+ export declare const ResumeTotalMs: (value: number) => {
440
+ [k: string]: number;
441
+ };
442
+ /** Phase: `resumeHook()` entry → the queue publish being requested. */
443
+ export declare const ResumeProducerPrepMs: (value: number) => {
444
+ [k: string]: number;
445
+ };
446
+ /** Phase: queue publish requested → the final consumer's handler being entered. */
447
+ export declare const ResumeQueueDeliveryMs: (value: number) => {
448
+ [k: string]: number;
449
+ };
450
+ /** Phase: consumer entry → replay beginning. */
451
+ export declare const ResumeSetupMs: (value: number) => {
452
+ [k: string]: number;
453
+ };
454
+ /** Phase: replay beginning → the next durable step being encountered. */
455
+ export declare const ResumeReplayMs: (value: number) => {
456
+ [k: string]: number;
457
+ };
458
+ /** Phase: step encountered → the `step_started` request beginning. */
459
+ export declare const ResumeStepDispatchMs: (value: number) => {
460
+ [k: string]: number;
461
+ };
462
+ /**
463
+ * Phase: `step_started` request beginning → its response returning. Omitted
464
+ * under optimistic inline start, where the claim is not awaited before the
465
+ * body runs and therefore has no completion instant at that point; the time
466
+ * is then reported entirely as {@link ResumeStepPrepareMs}.
467
+ */
468
+ export declare const ResumeStepClaimMs: (value: number) => {
469
+ [k: string]: number;
470
+ };
471
+ /**
472
+ * Phase: claim returning → immediately before `stepFn.apply()`. Deliberately
473
+ * includes encryption-key resolution, argument hydration, and step-context
474
+ * setup; `workflow.queue.deserialize_time_ms` still isolates hydration.
475
+ */
476
+ export declare const ResumeStepPrepareMs: (value: number) => {
477
+ [k: string]: number;
478
+ };
479
+ /** What triggered the measured resumption. */
480
+ export declare const ResumeTrigger: (value: "hook") => {
481
+ [k: string]: "hook";
482
+ };
483
+ /** Which `resumeHook()` dispatch path produced this resume. */
484
+ export declare const ResumeStrategy: (value: "parallel" | "sequential") => {
485
+ [k: string]: "parallel" | "sequential";
486
+ };
487
+ /**
488
+ * How the consuming invocation initialized replay state. Distinct from the
489
+ * pre-existing {@link HookResumeSetupSource} (`workflow.resume_setup_source`,
490
+ * on the workflow execution span), which reports the finer-grained
491
+ * hoisted-write outcome; this one is the TTR dimension and shares the metric's
492
+ * three-value vocabulary.
493
+ */
494
+ export declare const ResumeSetupSource: (value: "hook_preload" | "run_started" | "event_load") => {
495
+ [k: string]: "hook_preload" | "run_started" | "event_load";
496
+ };
497
+ /** Whether the measured step ran in the resuming invocation or a queued one. */
498
+ export declare const ResumeStepExecution: (value: "inline" | "dispatched") => {
499
+ [k: string]: "inline" | "dispatched";
500
+ };
420
501
  /** Number of webhook handlers triggered */
421
502
  export declare const WebhookHandlersTriggered: (value: number) => {
422
503
  [k: string]: number;
@@ -0,0 +1,25 @@
1
+ import type { Event } from '#compiled/@workflow/world/index.js';
2
+ import type { WorkflowOrchestratorContext } from '../private.js';
3
+ /**
4
+ * Builds an orchestrator context that replays a hand-written event log through
5
+ * the real workflow primitives (`createUseStep`, `createSleep`,
6
+ * `createCreateHook`), without a World or a VM entrypoint.
7
+ */
8
+ export declare function setupWorkflowContext(events: Event[], options?: {
9
+ onDuplicateEvent?: (event: Event) => void;
10
+ }): WorkflowOrchestratorContext;
11
+ /**
12
+ * Deterministic correlation IDs from the ULID generator with seed 'test', in
13
+ * the order {@link setupWorkflowContext}'s generator mints them.
14
+ */
15
+ export declare const CORR_IDS: string[];
16
+ /**
17
+ * Runs `workflowFn` against `ctx`, racing it against the context's error
18
+ * channel so a `WorkflowSuspension` or a detected divergence surfaces as
19
+ * `error` rather than hanging.
20
+ */
21
+ export declare function runWithDiscontinuation(ctx: WorkflowOrchestratorContext, workflowFn: () => Promise<any>): Promise<{
22
+ result?: any;
23
+ error?: any;
24
+ }>;
25
+ //# sourceMappingURL=orchestrator-context.d.ts.map
@@ -1,2 +1,2 @@
1
- export declare const version = "5.0.0-beta.41";
1
+ export declare const version = "5.0.0-beta.42";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- import{Fn as e,In as t,Zn as n,ir as r,nr as i,rr as a}from"../../_chunks/workflow/wait-until-CT1ve8qB.js";import{i as o,u as s}from"../../_chunks/workflow/dist-xQXN70ED.js";import"../../_chunks/workflow/dist-DpYyXbJv.js";import{i as c}from"../../_chunks/workflow/workflow-routes-CwqB063q.js";import{c as l,i as u,o as d,r as f,t as p}from"../../_chunks/workflow/attribute-changes-DZtQkszH.js";import{t as m}from"../../_chunks/workflow/sleep-C1P0OWBm.js";import{t as h}from"../../_chunks/workflow/run-Cjo0A3NO.js";t(e,h);function g(e){let t=globalThis[i];return t||u(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,g),t(e)}function _(e){let{respondWith:t,token:n,...r}=e??{};if(n!==void 0)throw Error("`createWebhook()` does not accept a `token` option. Webhook tokens are always randomly generated. Use `createHook()` with `resumeHook()` for deterministic token patterns.");let i;t!==void 0&&(i={respondWith:t});let a=g({...r,metadata:i,isWebhook:!0}),{url:o}=l();return a.url=c(o,{type:`webhook`,token:a.token}),a}function v(){function e(t,n){d(`defineHook().resume()`,`https://workflow-sdk.dev/docs/api-reference/workflow-api/resume-hook`,e)}return{create(e){return g(e)},resume:e}}async function y(e,t={}){let n=p(e,t);if(n.length===0)return;let i=t.allowReservedAttributes===!0,a=globalThis[r];if(!a)throw new o("setAttributes() called outside a workflow runtime context. It must be called from within a workflow body (`use workflow`).");await a(n,i?{allowReservedAttributes:!0}:{})}function b(e={}){let{namespace:t}=e,r=globalThis[a](t);return Object.create(globalThis.WritableStream.prototype,{[n]:{value:r,writable:!1}})}function x(){f(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,x)}function S(){d(`resumeHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow-api/resume-hook`,S)}export{o as FatalError,s as RetryableError,g as createHook,_ as createWebhook,v as defineHook,x as getStepMetadata,l as getWorkflowMetadata,b as getWritable,S as resumeHook,y as setAttributes,m as sleep};
1
+ import{Xn as e,Zn as t,_r as n,fr as r,vr as i,yr as a}from"../../_chunks/workflow/wait-until-BPSgt1Wg.js";import{i as o,u as s}from"../../_chunks/workflow/dist-CqvWKNQv.js";import"../../_chunks/workflow/dist-DpYyXbJv.js";import{i as c}from"../../_chunks/workflow/workflow-routes-CwqB063q.js";import{c as l,i as u,o as d,r as f,t as p}from"../../_chunks/workflow/attribute-changes-B8K0pwpH.js";import{t as m}from"../../_chunks/workflow/sleep-7TgF3i-e.js";import{t as h}from"../../_chunks/workflow/run-lq7-eG0l.js";t(e,h);function g(e){let t=globalThis[n];return t||u(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,g),t(e)}function _(e){let{respondWith:t,token:n,...r}=e??{};if(n!==void 0)throw Error("`createWebhook()` does not accept a `token` option. Webhook tokens are always randomly generated. Use `createHook()` with `resumeHook()` for deterministic token patterns.");let i;t!==void 0&&(i={respondWith:t});let a=g({...r,metadata:i,isWebhook:!0}),{url:o}=l();return a.url=c(o,{type:`webhook`,token:a.token}),a}function v(){function e(t,n){d(`defineHook().resume()`,`https://workflow-sdk.dev/docs/api-reference/workflow-api/resume-hook`,e)}return{create(e){return g(e)},resume:e}}async function y(e,t={}){let n=p(e,t);if(n.length===0)return;let r=t.allowReservedAttributes===!0,i=globalThis[a];if(!i)throw new o("setAttributes() called outside a workflow runtime context. It must be called from within a workflow body (`use workflow`).");await i(n,r?{allowReservedAttributes:!0}:{})}function b(e={}){let{namespace:t}=e,n=globalThis[i](t);return Object.create(globalThis.WritableStream.prototype,{[r]:{value:n,writable:!1}})}function x(){f(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,x)}function S(){d(`resumeHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow-api/resume-hook`,S)}export{o as FatalError,s as RetryableError,g as createHook,_ as createWebhook,v as defineHook,x as getStepMetadata,l as getWorkflowMetadata,b as getWritable,S as resumeHook,y as setAttributes,m as sleep};
@@ -437,6 +437,20 @@ export declare class RunExpiredError extends WorkflowWorldError {
437
437
  constructor(message: string);
438
438
  static is(value: unknown): value is RunExpiredError;
439
439
  }
440
+ /**
441
+ * Thrown when a stream is no longer readable because its owning run passed its
442
+ * storage-retention boundary. This is terminal: retrying cannot restore data.
443
+ *
444
+ * Unlike {@link RunExpiredError}, this identifies the failed stream read and
445
+ * exposes the server's authoritative expiry timestamp for user-facing errors.
446
+ */
447
+ export declare class StreamExpiredError extends WorkflowWorldError {
448
+ readonly runId?: string | undefined;
449
+ readonly streamId?: string | undefined;
450
+ readonly expiredAt?: Date | undefined;
451
+ constructor(message: string, runId?: string | undefined, streamId?: string | undefined, expiredAt?: Date | undefined);
452
+ static is(value: unknown): value is StreamExpiredError;
453
+ }
440
454
  /**
441
455
  * Thrown when an operation cannot proceed because a required timestamp
442
456
  * (e.g. retryAfter) has not been reached yet.
@@ -482,8 +496,10 @@ export declare class ThrottleError extends WorkflowWorldError {
482
496
  * does not read this field.
483
497
  * @property details - Optional rejection detail supplied by the World. A World
484
498
  * MAY attach the events the client's snapshot was missing so the client can
485
- * correct its log without a follow-up fetch; see the `stateCursor` contract
486
- * on `CreateEventParams`. Typed `unknown` because this package cannot depend
499
+ * correct its log without a follow-up fetch. The attached set must account
500
+ * for the whole discrepancy the rejection reported or be omitted entirely; a
501
+ * client that receives nothing does the authoritative full reload, which is
502
+ * always correct. Typed `unknown` because this package cannot depend
487
503
  * on the event type — consumers narrow it themselves and must treat a
488
504
  * missing or malformed value as "no detail" (a full reload is always
489
505
  * correct).
@@ -1 +1 @@
1
- import{C as e,D as t,E as n,O as r,S as i,T as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,k as h,l as g,m as _,n as v,o as y,p as b,r as x,s as S,t as C,u as w,v as T,w as E,x as D,y as O}from"../../_chunks/workflow/dist-xQXN70ED.js";export{C as CorruptedEventLogError,v as ERROR_SLUGS,x as EntityConflictError,m as FatalError,s as HookConflictError,y as HookNotFoundError,S as MaxEventsExceededError,l as PreconditionFailedError,h as RUN_ERROR_CODES,g as ReplayDivergenceError,w as RetryableError,u as RunExpiredError,d as RunNotSupportedError,b as RuntimeDecryptionError,_ as SerializationError,p as StepNotRegisteredError,f as ThrottleError,o as TooEarlyError,T as VERCEL_403_ERROR_MESSAGE,O as WorkflowBuildError,c as WorkflowDeploymentMismatchError,D as WorkflowError,i as WorkflowNotRegisteredError,e as WorkflowRunCancelledError,E as WorkflowRunFailedError,a as WorkflowRunNotCompletedError,n as WorkflowRunNotFoundError,t as WorkflowRuntimeError,r as WorkflowWorldError};
1
+ import{A as e,C as t,D as n,E as r,O as i,S as a,T as o,_ as s,a as c,b as l,c as u,d,f,g as p,h as m,i as h,k as g,l as _,m as v,n as y,o as b,p as x,r as S,s as C,t as w,u as T,v as E,w as D,x as O,y as k}from"../../_chunks/workflow/dist-CqvWKNQv.js";export{w as CorruptedEventLogError,y as ERROR_SLUGS,S as EntityConflictError,h as FatalError,c as HookConflictError,b as HookNotFoundError,C as MaxEventsExceededError,u as PreconditionFailedError,e as RUN_ERROR_CODES,_ as ReplayDivergenceError,T as RetryableError,d as RunExpiredError,f as RunNotSupportedError,x as RuntimeDecryptionError,v as SerializationError,m as StepNotRegisteredError,p as StreamExpiredError,s as ThrottleError,E as TooEarlyError,k as VERCEL_403_ERROR_MESSAGE,l as WorkflowBuildError,O as WorkflowDeploymentMismatchError,a as WorkflowError,t as WorkflowNotRegisteredError,D as WorkflowRunCancelledError,o as WorkflowRunFailedError,r as WorkflowRunNotCompletedError,n as WorkflowRunNotFoundError,i as WorkflowRuntimeError,g as WorkflowWorldError};
@@ -178,6 +178,8 @@ export interface AnalyticsListEventsByCorrelationIdParams {
178
178
  runId: string;
179
179
  pagination?: PaginationOptions;
180
180
  }
181
+ /** Maximum number of event IDs accepted by one analytics batch lookup. */
182
+ export declare const ANALYTICS_EVENTS_GET_MANY_LIMIT = 100;
181
183
  export interface AnalyticsListHooksParams {
182
184
  runId: string;
183
185
  pagination?: PaginationOptions;
@@ -204,6 +206,13 @@ export interface Analytics {
204
206
  };
205
207
  events: {
206
208
  get(runId: string, eventId: string): Promise<AnalyticsEvent>;
209
+ /**
210
+ * Retrieves the analytics rows present for a bounded set of event IDs in
211
+ * one run. Missing rows are omitted because analytics ingestion may lag
212
+ * canonical storage. Duplicate IDs are looked up once; result ordering is
213
+ * not guaranteed.
214
+ */
215
+ getMany(runId: string, eventIds: readonly string[]): Promise<AnalyticsEvent[]>;
207
216
  list(params: AnalyticsListEventsParams): Promise<PaginatedResponse<AnalyticsEvent>>;
208
217
  listByCorrelationId(params: AnalyticsListEventsByCorrelationIdParams): Promise<PaginatedResponse<AnalyticsEvent>>;
209
218
  };
@@ -59,6 +59,49 @@ declare const TerminalStepEventTypeSchema: z.ZodEnum<{
59
59
  export type TerminalStepEventType = z.infer<typeof TerminalStepEventTypeSchema>;
60
60
  export declare const TERMINAL_STEP_EVENT_TYPES: ("step_completed" | "step_failed")[];
61
61
  export declare function isTerminalStepEventType(eventType: string): eventType is TerminalStepEventType;
62
+ /**
63
+ * Groups event types into the classes a replay tracks per entity: the entity
64
+ * named by the event's `correlationId`, or the run itself for run events,
65
+ * which carry none.
66
+ *
67
+ * Types that share a class are the mutually exclusive outcomes of one
68
+ * decision, so the log records the class once and the first event of it is the
69
+ * one that counts: a step either completes or fails.
70
+ *
71
+ * Classes are independent of each other. A step whose result is in the log has
72
+ * still recorded exactly one `step_created`, and can still record another
73
+ * `step_started` if an attempt is running somewhere. What a class bounds is
74
+ * which events can be *ignored*: a replay may pass over an event whose class
75
+ * it already recorded for that entity and which no consumer wants (see
76
+ * `EventsConsumer`), and only then.
77
+ *
78
+ * Note the omissions, all of them types a mapping would be dead weight for.
79
+ * `hook_received` and `hook_conflict` are deliveries whose consumer subscribes
80
+ * lazily, `attr_set` is written on every attribute write, and `run_created`
81
+ * precedes every replay. The terminal run types are absent for a different
82
+ * reason: recording a class requires a consumer to take an event of it, and no
83
+ * consumer takes `run_completed` / `run_failed` / `run_cancelled` — the runtime
84
+ * exits before replaying the body once the log holds one, so they never reach a
85
+ * consumer at all. An entry for them could never match.
86
+ */
87
+ declare const ENTITY_EVENT_CLASS_BY_TYPE: {
88
+ readonly step_created: "step_created";
89
+ readonly step_started: "step_started";
90
+ readonly step_retrying: "step_retrying";
91
+ readonly step_completed: "step_terminal";
92
+ readonly step_failed: "step_terminal";
93
+ readonly wait_created: "wait_created";
94
+ readonly wait_completed: "wait_completed";
95
+ readonly hook_created: "hook_created";
96
+ readonly hook_disposed: "hook_disposed";
97
+ readonly run_started: "run_started";
98
+ };
99
+ export type EntityEventClass = (typeof ENTITY_EVENT_CLASS_BY_TYPE)[keyof typeof ENTITY_EVENT_CLASS_BY_TYPE];
100
+ /**
101
+ * The per-entity class `eventType` belongs to, or `undefined` when it belongs
102
+ * to none. See {@link ENTITY_EVENT_CLASS_BY_TYPE}.
103
+ */
104
+ export declare function entityEventClass(eventType: string): EntityEventClass | undefined;
62
105
  declare const HookLifecycleEventTypeSchema: z.ZodEnum<{
63
106
  hook_created: "hook_created";
64
107
  hook_received: "hook_received";
@@ -607,6 +650,26 @@ export interface CreateEventParams {
607
650
  * alongside {@link resumeId}.
608
651
  */
609
652
  resumePayloadDigest?: string;
653
+ /**
654
+ * Marks a `step_created` create as the queue consumer's re-ensure of a
655
+ * resilient step dispatch (a step message carrying `stepInput` — see
656
+ * `WorkflowInvokePayload.stepInput`): the producer's direct write was
657
+ * parallelized with the queue publish and may have failed. Only meaningful
658
+ * for `step_created`.
659
+ *
660
+ * Advisory. Parallelizing a create with its publish is opt-in and off by
661
+ * default (`WORKFLOW_RESILIENT_STEP_DISPATCH`), precisely because a create
662
+ * can come back refused while the message carrying its payload is already
663
+ * out. A deployment that opts in accepts that window, and a backend MAY use
664
+ * this flag to narrow it: refuse the re-ensure (world-vercel surfaces the
665
+ * backend's 410 as `RunExpiredError`, which the consumer treats as "nothing
666
+ * left to execute" and acks the message) when it has recorded a refusal for
667
+ * this correlation id and no step entity exists. Best-effort by nature — a
668
+ * marker written at refusal time cannot be ordered before the redelivery it
669
+ * is meant to stop — so it hardens, and does not close, the window. Worlds
670
+ * may ignore this flag entirely.
671
+ */
672
+ viaStepDispatch?: boolean;
610
673
  /** Request ID (x-vercel-id when on Vercel) for correlating request logs with workflow events. */
611
674
  requestId?: string;
612
675
  /**
@@ -616,86 +679,16 @@ export interface CreateEventParams {
616
679
  * `AnalyticsEventSchema` / `AnalyticsStepSchema`.
617
680
  */
618
681
  computeInstanceId?: string;
619
- /**
620
- * Epoch ms (the ULID time of the latest event the runtime has loaded during
621
- * replay). Sent by replay-context creates so the backend can reject the event
622
- * when a newer out-of-band event was recorded after this snapshot, enabling
623
- * an optimistic-concurrency guard. Omitted by callers without a loaded event
624
- * log.
625
- *
626
- * Backend contract (for World implementers who want to support the guard):
627
- * maintain a per-run marker holding the ULID time of the most recent
628
- * *externally-originated* event — a `hook_received` or `step_completed`
629
- * created **without** a `stateUpdatedAt` (replay-origin events carry one and
630
- * must not advance the marker). On a create that carries `stateUpdatedAt`,
631
- * reject with 412 when `stateUpdatedAt < marker` (strictly older); an equal
632
- * timestamp must pass (anti-livelock, so an up-to-date client is never
633
- * rejected). A backend that ignores this field simply disables the guard —
634
- * the client falls open and behaves as before.
635
- *
636
- * A watermark alone cannot see an event *missing at or below* it, which is
637
- * the failure that actually corrupts a replay — see {@link stateEventCount}
638
- * for the second half of the guard.
639
- */
640
- stateUpdatedAt?: number;
641
- /**
642
- * How many loaded events have a ULID time at or below {@link stateUpdatedAt}.
643
- * Since `stateUpdatedAt` is the *maximum* ULID time in the loaded log, this
644
- * equals the loaded array's length. Sent **only** together with
645
- * `stateUpdatedAt`; a World must ignore a count that arrives without one.
646
- *
647
- * This closes the hole a watermark cannot: the watermark proves only "no
648
- * newer event exists", while a replay corrupts its log by missing an event
649
- * at or *below* its own frontier — a concurrent writer commits in the same
650
- * ULID millisecond as the client's last loaded event, so the two watermarks
651
- * compare equal and the write is accepted against a log that is one event
652
- * short. Because correlation IDs are positional ordinals of a single seeded
653
- * sequence, that one-event difference renames every entity after it.
654
- *
655
- * Backend contract (for World implementers who want to support this half):
656
- *
657
- * - Count **every** created event for the run, including replay-origin ones.
658
- * Unlike the watermark, this is not restricted to out-of-band writes: the
659
- * race being fenced is one replay against another.
660
- * - Reject with 412 when the count of recorded events at ULID time
661
- * `<= stateUpdatedAt` is strictly **greater** than `stateEventCount`.
662
- * - Compare **at or below** `stateUpdatedAt`, never strictly below (the
663
- * missing event routinely shares the client's frontier millisecond) and
664
- * never against a total (all the creates of one suspension share one
665
- * snapshot, so a total would reject every sibling after the first).
666
- * - **One-sided safety is mandatory.** Anything that makes the backend's
667
- * count incomplete, uncomputable, or expired must *allow* the write. A
668
- * rejection has to imply a real hole, because the client responds to it by
669
- * discarding and re-deriving its whole replay.
670
- *
671
- * See also the millisecond-granularity caveat on `stateUpdatedAt`: the count
672
- * is what makes an equal-timestamp snapshot safe to accept.
673
- */
674
- stateEventCount?: number;
675
- /**
676
- * The client's current event-log cursor (advisory). Sent alongside the other
677
- * two snapshot fields so a World that rejects the write MAY return the
678
- * events the client is missing on the 412 itself, saving the client a
679
- * follow-up `events.list`.
680
- *
681
- * Distinct from {@link sinceCursor}: a World must **not** compute a delta for
682
- * this on the accepted path — it exists purely to make a rejection cheaper.
683
- * Returning events on a 412 is OPTIONAL, and the returned set must be
684
- * provably complete (it must account for the entire discrepancy the
685
- * rejection reported) or omitted entirely: a cursor filters by lexicographic
686
- * event id while a hole is defined by ULID time, so a naive
687
- * "everything after the cursor" delta can silently exclude the very event
688
- * the client is missing. A client that receives nothing does the
689
- * authoritative full reload, which is always correct.
690
- */
691
- stateCursor?: string;
692
682
  /**
693
683
  * How many events the writer held in its loaded log when it decided to write
694
- * this one — equivalently, the slot it expects to land on minus one.
684
+ * this one — equivalently, the slot it expects to land on minus one. Sent by
685
+ * every replay-context create; omitted by callers with no loaded log to be
686
+ * stale against.
695
687
  *
696
- * Only meaningful against a World that declares
697
- * `WorldCapabilities.slotEventIds`, where slots are dense and 1-based so a
698
- * count and a position are the same number. Such a World attempts
688
+ * A World's slots are dense and 1-based (see `Storage.events`), so a count
689
+ * and a position are the same number. An id that is not a position does not
690
+ * produce a count here — it throws, since the runtime cannot state a
691
+ * snapshot for a log it cannot place. Such a World attempts
699
692
  * `eventCount + 1`, and on contention **bumps** to the next free slot and
700
693
  * commits there anyway — a stale count never rejects a write. What it does
701
694
  * instead is report: when the committed slot is higher than the one asked
@@ -703,13 +696,10 @@ export interface CreateEventParams {
703
696
  * response in {@link EventResult.events} / `cursor` / `hasMore`, so the
704
697
  * writer learns exactly what it had not seen.
705
698
  *
706
- * This supersedes the {@link stateUpdatedAt} / {@link stateEventCount} /
707
- * {@link stateCursor} triple for slot Worlds. That triple approximates a
708
- * position with a ULID-time watermark plus a count of events at or below it,
709
- * which is why a *complete but stale* prefix passes it: every event the
710
- * writer holds is at or below its own watermark, so the count matches and no
711
- * fence fires. A dense position has no such blind spot. Worlds without slots
712
- * ignore this field and keep using the triple.
699
+ * Understating is safe and overstating is not. A count below the writer's
700
+ * true position only widens the reported span, and the client discards what
701
+ * its log already holds. A count above it makes the World report less than
702
+ * the writer is missing, which is a hole the writer never learns about.
713
703
  *
714
704
  * A batch of writes issued from one snapshot starts from the same
715
705
  * `eventCount`; they land on consecutive slots in whatever order the World
@@ -863,9 +853,8 @@ export type EventResult<T extends EventType = EventType> = {
863
853
  * log through the canonical `hook_received`, so the lazy hook queue
864
854
  * consumer can skip both the `run_started` write and the initial
865
855
  * `events.list`.
866
- * - On any response from a slot-allocating World (see
867
- * `WorldCapabilities.slotEventIds`) whose committed slot came out
868
- * higher than the one {@link CreateEventParams.eventCount} asked for:
856
+ * - On any response whose committed slot came out higher than the one
857
+ * {@link CreateEventParams.eventCount} asked for:
869
858
  * the events occupying the slots that were skipped over, in slot
870
859
  * order. This is the "report" half of bump-and-report — the write
871
860
  * succeeded, and these are the events the writer had not seen when it
@@ -1,10 +1,10 @@
1
1
  export type * from './analytics.js';
2
- export { AnalyticsAttributeKeySchema, AnalyticsEventSchema, AnalyticsHookSchema, AnalyticsRunSchema, AnalyticsStepSchema, AnalyticsWaitSchema, } from './analytics.js';
2
+ export { ANALYTICS_EVENTS_GET_MANY_LIMIT, AnalyticsAttributeKeySchema, AnalyticsEventSchema, AnalyticsHookSchema, AnalyticsRunSchema, AnalyticsStepSchema, AnalyticsWaitSchema, } from './analytics.js';
3
3
  export type * from './attributes.js';
4
4
  export { ATTRIBUTE_KEY_MAX_LENGTH, ATTRIBUTE_MAX_PER_RUN, ATTRIBUTE_VALUE_MAX_BYTES, AttributeChangeSchema, AttributeChangesSchema, AttributeValidationError, applyAttributeChanges, PARENT_RUN_ID_ATTRIBUTE, RESERVED_ATTRIBUTE_KEY_PREFIX, ROOT_RUN_ID_ATTRIBUTE, validateAttributeChanges, validateAttributeKey, validateAttributeValue, } from './attributes.js';
5
5
  export { _resetEnvWarnCacheForTests, type EnvNumberOptions, envNumber, getMaxEventsPerRun, } from './env-config.js';
6
6
  export type * from './events.js';
7
- export { BaseEventSchema, CHILD_ENTITY_CREATION_EVENT_TYPES, CreateEventSchema, EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE, EVENT_DATA_REF_FIELDS, EventSchema, EventTypeSchema, getEventDataPayloadField, getEventDataRefFields, HOOK_EVENTS_REQUIRING_EXISTENCE, HOOK_LIFECYCLE_EVENT_TYPES, HookCreatedEventSchema, isChildEntityCreationEvent, isChildEntityCreationEventType, isHookEventRequiringExistence, isHookLifecycleEventType, isRunEventType, isStepEventType, isTerminalRunEventType, isTerminalStepEventType, isWaitEventType, RUN_EVENT_TYPES, STEP_EVENT_TYPES, stripEventDataRefs, TERMINAL_RUN_EVENT_TYPES, TERMINAL_STEP_EVENT_TYPES, TerminalRunEventTypeSchema, WAIT_EVENT_TYPES, } from './events.js';
7
+ export { BaseEventSchema, CHILD_ENTITY_CREATION_EVENT_TYPES, CreateEventSchema, EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE, EVENT_DATA_REF_FIELDS, EventSchema, EventTypeSchema, entityEventClass, getEventDataPayloadField, getEventDataRefFields, HOOK_EVENTS_REQUIRING_EXISTENCE, HOOK_LIFECYCLE_EVENT_TYPES, HookCreatedEventSchema, isChildEntityCreationEvent, isChildEntityCreationEventType, isHookEventRequiringExistence, isHookLifecycleEventType, isRunEventType, isStepEventType, isTerminalRunEventType, isTerminalStepEventType, isWaitEventType, RUN_EVENT_TYPES, STEP_EVENT_TYPES, stripEventDataRefs, TERMINAL_RUN_EVENT_TYPES, TERMINAL_STEP_EVENT_TYPES, TerminalRunEventTypeSchema, WAIT_EVENT_TYPES, } from './events.js';
8
8
  export type * from './hooks.js';
9
9
  export { HOOK_RESUME_DEDUP_VERSION, HOOK_RESUME_INPUT_VERSION, HookResumeCapabilitiesSchema, HookSchema, } from './hooks.js';
10
10
  export type * from './interfaces.js';
@@ -18,7 +18,7 @@ export { LegacySerializedDataSchemaV1, SerializedDataSchema, } from './serializa
18
18
  export type * from './shared.js';
19
19
  export type { GetChunksOptions, StreamChunk, StreamChunksResponse, StreamInfoResponse, } from './shared.js';
20
20
  export { PaginatedResponseSchema, StructuredErrorSchema, } from './shared.js';
21
- export { EVENT_ID_BODY_LENGTH, EVENT_ID_PREFIX, eventIdToSlot, FIRST_EVENT_SLOT, isSlotBody, isSlotEventId, MAX_EVENT_SLOT, slotToEventId, } from './slot-identity.js';
21
+ export { EVENT_ID_BODY_LENGTH, EVENT_ID_PREFIX, eventIdToSlot, FIRST_EVENT_SLOT, isSlotBody, isSlotEventId, MAX_EVENT_SLOT, requireEventSlot, slotToEventId, } from './slot-identity.js';
22
22
  export type { SpecVersion } from './spec-version.js';
23
23
  export { isLegacySpecVersion, requiresNewerWorld, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, SPEC_VERSION_MAX_SUPPORTED, SPEC_VERSION_SUPPORTS_ATTRIBUTES, SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT, SPEC_VERSION_SUPPORTS_COMPRESSION, SPEC_VERSION_SUPPORTS_EVENT_SOURCING, SPEC_VERSION_SUPPORTS_SLOT_IDENTITY, } from './spec-version.js';
24
24
  export type * from './steps.js';
@@ -107,6 +107,14 @@ export interface Storage {
107
107
  }): Promise<(WorkflowRun | null)[]>;
108
108
  (ids: readonly string[], params?: GetWorkflowRunParams): Promise<(WorkflowRun | WorkflowRunWithoutData | null)[]>;
109
109
  };
110
+ /**
111
+ * Lists canonical workflow storage records.
112
+ *
113
+ * @remarks Observability and inspection usage of this method is
114
+ * deprecated. Use `world.analytics?.runs.list()` for plan-aware
115
+ * observability queries. This storage API remains available for
116
+ * operational and payload-bearing callers.
117
+ */
110
118
  list(params: ListWorkflowRunsParams & {
111
119
  resolveData: 'none';
112
120
  }): Promise<PaginatedResponse<WorkflowRunWithoutData>>;
@@ -168,6 +176,35 @@ export interface Storage {
168
176
  }): Promise<PaginatedResponse<Step>>;
169
177
  list(params: ListWorkflowRunStepsParams): Promise<PaginatedResponse<Step | StepWithoutData>>;
170
178
  };
179
+ /**
180
+ * The event log, and the one part of this interface with a requirement the
181
+ * types cannot express: **the World allocates every event id, and every id
182
+ * is a slot** — `evnt_` followed by the event's dense, 1-based position in
183
+ * its run's log, zero-padded to 26 characters. Use `slotToEventId()` to
184
+ * format one.
185
+ *
186
+ * Not a capability to opt into. The runtime reads a position out of every id
187
+ * it loads (`requireEventSlot`) and fails the run if it cannot, so a World
188
+ * whose ids are not positions cannot replay anything at all. Two properties
189
+ * are what the runtime actually relies on:
190
+ *
191
+ * - **Density.** A run's slots are contiguous from 1, so the number of
192
+ * events a reader holds *is* the position of the last one. That is what
193
+ * makes {@link CreateEventParams.eventCount} a complete statement of the
194
+ * writer's snapshot in a single integer, and what lets a reader tell a
195
+ * complete log from a truncated one by its length.
196
+ * - **Bump and report.** A create never fails because its requested slot is
197
+ * taken. The World advances to the next free slot, commits there, and
198
+ * returns the events occupying the slots it skipped over on the success
199
+ * response (see {@link EventResult.events}). The writer learns its
200
+ * snapshot was stale without the write being rejected — which is why no
201
+ * World needs a precondition guard.
202
+ *
203
+ * Allocating at the commit is what makes a reader's log a *prefix* of the
204
+ * run's log rather than a prefix with a hole in it. A World that hands a
205
+ * position out earlier, and can therefore let an event land behind one a
206
+ * reader has already passed, breaks the property every replay depends on.
207
+ */
171
208
  events: {
172
209
  /**
173
210
  * Create a run_created event to start a new workflow run.
@@ -227,25 +264,6 @@ export interface WorldCapabilities {
227
264
  hookRetention?: {
228
265
  active: boolean;
229
266
  };
230
- /**
231
- * The World enforces the optimistic-concurrency precondition guard: an
232
- * event creation carrying a `stateUpdatedAt` snapshot is rejected with a
233
- * `PreconditionFailedError` (412) when a newer out-of-band event (e.g. a
234
- * received hook) was recorded after that snapshot. Worlds that accept but
235
- * ignore `stateUpdatedAt` must leave this unset so runtime optimizations
236
- * that rely on the 412 fence (see `WORKFLOW_PRECONDITION_GUARD`) are not
237
- * enabled without an actual fence behind them.
238
- *
239
- * A World declaring this should honour the whole snapshot the runtime sends,
240
- * not just the watermark: `stateUpdatedAt`, `stateEventCount` (the count
241
- * fence, which catches an event missing at or below the watermark — the case
242
- * the watermark provably cannot see) and, optionally, `stateCursor` (return
243
- * the missing events on the 412 to save the client a reload). See
244
- * `CreateEventParams` for each field's contract. The runtime does not branch
245
- * on which halves are implemented; a World that ignores the count simply
246
- * fences less.
247
- */
248
- preconditionGuard?: boolean;
249
267
  /**
250
268
  * The World's queue supports `maxConcurrency`-limited consumption — in
251
269
  * particular the per-run flow topics consumed with `maxConcurrency: 1`
@@ -305,29 +323,6 @@ export interface WorldCapabilities {
305
323
  * fail ordinary runs after a version bump.
306
324
  */
307
325
  deploymentAffinity?: boolean;
308
- /**
309
- * The World allocates **slot-numbered** event ids: `evnt_` plus the event's
310
- * dense, 1-based position in its run's log, zero-padded to 26 characters
311
- * (see `slot-identity.ts`). Two guarantees come with it, and the runtime
312
- * relies on both:
313
- *
314
- * - **Density.** A run's slots are contiguous from 1, so the number of
315
- * events a reader holds *is* the position of the last one. That is what
316
- * makes {@link CreateEventParams.eventCount} a complete statement of the
317
- * writer's snapshot, where the `stateUpdatedAt` / `stateEventCount`
318
- * watermark pair could only approximate it.
319
- * - **Bump and report.** A create never fails because its requested slot is
320
- * taken. The World advances to the next free slot, commits there, and
321
- * returns the events occupying the slots it skipped over on the success
322
- * response (see {@link EventResult.events}). The writer learns its
323
- * snapshot was stale without the write being rejected.
324
- *
325
- * A run's scheme is pinned by the run, not by this flag: it is readable off
326
- * the shape of the run's own first event id, so a World that turns slots on
327
- * keeps replaying its existing ULID-numbered runs unchanged. The capability
328
- * only says what *new* runs get.
329
- */
330
- slotEventIds?: boolean;
331
326
  }
332
327
  /**
333
328
  * The "World" interface represents how Workflows are able to communicate with the outside world.
@@ -343,10 +338,15 @@ export interface World extends Queue, Streamer, Storage {
343
338
  */
344
339
  analytics?: Analytics;
345
340
  /**
346
- * The Workflow protocol spec version this World implements.
341
+ * The Workflow protocol spec version this World implements, and the version
342
+ * stamped on every run it creates.
347
343
  *
348
- * Current runtimes require this to exactly match their
349
- * `SPEC_VERSION_CURRENT` before they create or replay runs.
344
+ * Declare `SPEC_VERSION_CURRENT` rather than a literal. The runtime checks
345
+ * this against `[SPEC_VERSION_CURRENT, SPEC_VERSION_MAX_SUPPORTED]` before it
346
+ * creates or replays anything, and refuses a World outside that range: below
347
+ * the floor the World allocates event ids the runtime cannot read positions
348
+ * out of (see the event log contract above), above the ceiling it speaks a
349
+ * spec this runtime has not learned.
350
350
  */
351
351
  specVersion: number;
352
352
  /**