@workflow/world-testing 5.0.0-beta.41 → 5.0.0-beta.42

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.
@@ -15289,6 +15289,9 @@ function isStepEventType(eventType) {
15289
15289
  function isTerminalStepEventType(eventType) {
15290
15290
  return TERMINAL_STEP_EVENT_TYPES2.includes(eventType);
15291
15291
  }
15292
+ function entityEventClass(eventType) {
15293
+ return ENTITY_EVENT_CLASS_BY_TYPE[eventType];
15294
+ }
15292
15295
  function isHookLifecycleEventType(eventType) {
15293
15296
  return HOOK_LIFECYCLE_EVENT_TYPES2.includes(eventType);
15294
15297
  }
@@ -15335,7 +15338,7 @@ function isChildEntityCreationEvent(event) {
15335
15338
  return true;
15336
15339
  return event.eventType === "step_started" && typeof event.eventData?.stepName === "string" && event.eventData.input !== void 0;
15337
15340
  }
15338
- var EventTypeSchema2, RunEventTypeSchema2, RUN_EVENT_TYPES2, TerminalRunEventTypeSchema2, TERMINAL_RUN_EVENT_TYPES2, StepEventTypeSchema2, STEP_EVENT_TYPES2, TerminalStepEventTypeSchema2, TERMINAL_STEP_EVENT_TYPES2, HookLifecycleEventTypeSchema2, HOOK_LIFECYCLE_EVENT_TYPES2, HookEventRequiringExistenceTypeSchema2, HOOK_EVENTS_REQUIRING_EXISTENCE2, WaitEventTypeSchema2, WAIT_EVENT_TYPES2, ChildEntityCreationEventTypeSchema2, CHILD_ENTITY_CREATION_EVENT_TYPES2, EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE2, EVENT_DATA_REF_FIELDS2, BaseEventSchema2, stepLatencyTelemetryFields2, StepCompletedEventSchema2, StepFailedEventSchema2, StepRetryingEventSchema2, StepStartedEventSchema2, StepCreatedEventSchema2, HookCreatedEventSchema2, HookReceivedEventSchema2, HookDisposedEventSchema2, HookConflictEventSchema2, WaitCreatedEventSchema2, WaitCompletedEventSchema2, AttributeWriterSchema2, AttrSetEventSchema2, RunCreatedEventSchema2, RunStartedEventSchema2, RunCompletedEventSchema2, RunFailedEventSchema2, RunCancelledEventSchema2, CreateEventSchema2, AllEventsSchema2, EventSchema2;
15341
+ var EventTypeSchema2, RunEventTypeSchema2, RUN_EVENT_TYPES2, TerminalRunEventTypeSchema2, TERMINAL_RUN_EVENT_TYPES2, StepEventTypeSchema2, STEP_EVENT_TYPES2, TerminalStepEventTypeSchema2, TERMINAL_STEP_EVENT_TYPES2, ENTITY_EVENT_CLASS_BY_TYPE, HookLifecycleEventTypeSchema2, HOOK_LIFECYCLE_EVENT_TYPES2, HookEventRequiringExistenceTypeSchema2, HOOK_EVENTS_REQUIRING_EXISTENCE2, WaitEventTypeSchema2, WAIT_EVENT_TYPES2, ChildEntityCreationEventTypeSchema2, CHILD_ENTITY_CREATION_EVENT_TYPES2, EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE2, EVENT_DATA_REF_FIELDS2, BaseEventSchema2, stepLatencyTelemetryFields2, StepCompletedEventSchema2, StepFailedEventSchema2, StepRetryingEventSchema2, StepStartedEventSchema2, StepCreatedEventSchema2, HookCreatedEventSchema2, HookReceivedEventSchema2, HookDisposedEventSchema2, HookConflictEventSchema2, WaitCreatedEventSchema2, WaitCompletedEventSchema2, AttributeWriterSchema2, AttrSetEventSchema2, RunCreatedEventSchema2, RunStartedEventSchema2, RunCompletedEventSchema2, RunFailedEventSchema2, RunCancelledEventSchema2, CreateEventSchema2, AllEventsSchema2, EventSchema2;
15339
15342
  var init_events2 = __esm({
15340
15343
  "../world/dist/events.js"() {
15341
15344
  "use strict";
@@ -15398,6 +15401,19 @@ var init_events2 = __esm({
15398
15401
  ]);
15399
15402
  TERMINAL_STEP_EVENT_TYPES2 = TerminalStepEventTypeSchema2.options;
15400
15403
  __name(isTerminalStepEventType, "isTerminalStepEventType");
15404
+ ENTITY_EVENT_CLASS_BY_TYPE = {
15405
+ step_created: "step_created",
15406
+ step_started: "step_started",
15407
+ step_retrying: "step_retrying",
15408
+ step_completed: "step_terminal",
15409
+ step_failed: "step_terminal",
15410
+ wait_created: "wait_created",
15411
+ wait_completed: "wait_completed",
15412
+ hook_created: "hook_created",
15413
+ hook_disposed: "hook_disposed",
15414
+ run_started: "run_started"
15415
+ };
15416
+ __name(entityEventClass, "entityEventClass");
15401
15417
  HookLifecycleEventTypeSchema2 = EventTypeSchema2.extract([
15402
15418
  "hook_created",
15403
15419
  "hook_received",
@@ -16024,7 +16040,7 @@ var init_waits2 = __esm({
16024
16040
  });
16025
16041
 
16026
16042
  // ../world/dist/analytics.js
16027
- var NAIVE_DATETIME2, UTCDateSchema2, NullableDateSchema2, NullableStringSchema2, NullableBooleanSchema2, AnalyticsRunSchema2, AnalyticsStepSchema2, AnalyticsEventSchema2, AnalyticsHookSchema2, AnalyticsWaitSchema2, AnalyticsAttributeKeySchema2;
16043
+ var NAIVE_DATETIME2, UTCDateSchema2, NullableDateSchema2, NullableStringSchema2, NullableBooleanSchema2, AnalyticsRunSchema2, AnalyticsStepSchema2, AnalyticsEventSchema2, AnalyticsHookSchema2, AnalyticsWaitSchema2, AnalyticsAttributeKeySchema2, ANALYTICS_EVENTS_GET_MANY_LIMIT;
16028
16044
  var init_analytics2 = __esm({
16029
16045
  "../world/dist/analytics.js"() {
16030
16046
  "use strict";
@@ -16130,6 +16146,7 @@ var init_analytics2 = __esm({
16130
16146
  firstSeenAt: external_exports2.coerce.date(),
16131
16147
  lastSeenAt: external_exports2.coerce.date()
16132
16148
  });
16149
+ ANALYTICS_EVENTS_GET_MANY_LIMIT = 100;
16133
16150
  }
16134
16151
  });
16135
16152
 
@@ -16220,7 +16237,7 @@ function parseQueueName(name) {
16220
16237
  id: match2[2]
16221
16238
  };
16222
16239
  }
16223
- var QueuePrefix2, ValidQueueName2, QueueNamespace2, MessageId2, TraceCarrierSchema2, RunInputSchema2, HookResumeInputSchema2, WorkflowInvokePayloadSchema2, HealthCheckPayloadSchema2, QueuePayloadSchema2;
16240
+ var QueuePrefix2, ValidQueueName2, QueueNamespace2, MessageId2, TraceCarrierSchema2, RunInputSchema2, StepDispatchInputSchema2, HookResumeInputSchema2, HookResumeTimingSchema2, WorkflowInvokePayloadSchema2, HealthCheckPayloadSchema2, QueuePayloadSchema2;
16224
16241
  var init_queue2 = __esm({
16225
16242
  "../world/dist/queue.js"() {
16226
16243
  "use strict";
@@ -16268,6 +16285,19 @@ var init_queue2 = __esm({
16268
16285
  */
16269
16286
  environment: external_exports2.string().optional()
16270
16287
  });
16288
+ StepDispatchInputSchema2 = external_exports2.object({
16289
+ /**
16290
+ * The serialized step input, reused verbatim from the direct write. Always
16291
+ * binary: producers only attach `stepInput` when the dehydrated input is a
16292
+ * `Uint8Array` and the run's queue transport preserves bytes (CBOR).
16293
+ * Validated here so a malformed or transport-mangled payload fails the
16294
+ * message parse instead of being silently written into a `step_created` as
16295
+ * non-binary data. `Buffer` is a `Uint8Array` subclass and passes.
16296
+ */
16297
+ input: external_exports2.custom((value) => value instanceof Uint8Array, {
16298
+ message: "stepInput.input must be a Uint8Array"
16299
+ })
16300
+ });
16271
16301
  HookResumeInputSchema2 = external_exports2.object({
16272
16302
  /** Stable idempotency key minted once per `resumeHook()` call. */
16273
16303
  resumeId: external_exports2.string(),
@@ -16301,6 +16331,22 @@ var init_queue2 = __esm({
16301
16331
  */
16302
16332
  deploymentId: external_exports2.string().optional()
16303
16333
  });
16334
+ HookResumeTimingSchema2 = external_exports2.object({
16335
+ /** Epoch ms at entry into `resumeHook()` — the start of the TTR window. */
16336
+ resumeRequestedAtMs: external_exports2.number(),
16337
+ /** Epoch ms immediately before the queue publish was requested. */
16338
+ queuePublishRequestedAtMs: external_exports2.number(),
16339
+ /** Which `resumeHook()` dispatch path ran: `parallel` or `sequential`. */
16340
+ strategy: external_exports2.string().optional(),
16341
+ /** Epoch ms the final consumer's queue handler was entered. */
16342
+ consumerStartedAtMs: external_exports2.number().optional(),
16343
+ /** Epoch ms this invocation's first replay pass began. */
16344
+ replayStartedAtMs: external_exports2.number().optional(),
16345
+ /** Epoch ms replay first encountered a durable step after the resume. */
16346
+ nextStepEncounteredAtMs: external_exports2.number().optional(),
16347
+ /** How the consumer initialized replay state: see `ResumeSetupSource`. */
16348
+ setupSource: external_exports2.string().optional()
16349
+ });
16304
16350
  WorkflowInvokePayloadSchema2 = external_exports2.object({
16305
16351
  runId: external_exports2.string(),
16306
16352
  traceCarrier: TraceCarrierSchema2.optional(),
@@ -16334,7 +16380,28 @@ var init_queue2 = __esm({
16334
16380
  * fast path. A consumer that understands this field idempotently ensures the
16335
16381
  * `hook_received` event exists (keyed by `resumeId`) before replaying.
16336
16382
  */
16337
- hookInput: HookResumeInputSchema2.optional()
16383
+ hookInput: HookResumeInputSchema2.optional(),
16384
+ /**
16385
+ * Resilient step dispatch data, only present alongside `stepId` when the
16386
+ * producer parallelized the `step_created` write with this queue publish. A
16387
+ * consumer that understands this field idempotently ensures the
16388
+ * `step_created` event exists (keyed by `stepId`) before executing the step.
16389
+ */
16390
+ stepInput: StepDispatchInputSchema2.optional(),
16391
+ /**
16392
+ * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
16393
+ * (unlike `hookInput`, which only rides the parallel fast path), and
16394
+ * forwarded onto a dispatched step message when the resuming invocation
16395
+ * hands the next durable step to another invocation. Purely observational —
16396
+ * see {@link HookResumeTimingSchema}.
16397
+ *
16398
+ * `.catch(undefined)` because this field must never be able to fail the
16399
+ * parse of the invocation payload: a malformed value (a NaN boundary, a
16400
+ * shape change from a future producer) would otherwise throw on every
16401
+ * delivery of that message and burn the run's delivery budget over a
16402
+ * telemetry field. Anything unparseable degrades to "no measurement".
16403
+ */
16404
+ hookResumeTiming: HookResumeTimingSchema2.optional().catch(void 0)
16338
16405
  });
16339
16406
  HealthCheckPayloadSchema2 = external_exports2.object({
16340
16407
  __healthCheck: external_exports2.literal(true),
@@ -16541,6 +16608,13 @@ function eventIdToSlot(eventId) {
16541
16608
  const slot = Number(body);
16542
16609
  return Number.isSafeInteger(slot) && slot >= FIRST_EVENT_SLOT ? slot : null;
16543
16610
  }
16611
+ function requireEventSlot(eventId) {
16612
+ const slot = eventIdToSlot(eventId);
16613
+ if (slot === null) {
16614
+ throw new Error(`Event id is not slot-numbered: ${eventId}. This World allocates event positions the runtime cannot read.`);
16615
+ }
16616
+ return slot;
16617
+ }
16544
16618
  var EVENT_ID_BODY_LENGTH, SLOT_LEADING_ZEROS, FIRST_EVENT_SLOT, MAX_EVENT_SLOT2, EVENT_ID_PREFIX;
16545
16619
  var init_slot_identity2 = __esm({
16546
16620
  "../world/dist/slot-identity.js"() {
@@ -16555,6 +16629,7 @@ var init_slot_identity2 = __esm({
16555
16629
  __name(isSlotEventId, "isSlotEventId");
16556
16630
  __name(slotToEventId, "slotToEventId");
16557
16631
  __name(eventIdToSlot, "eventIdToSlot");
16632
+ __name(requireEventSlot, "requireEventSlot");
16558
16633
  }
16559
16634
  });
16560
16635
 
@@ -16577,7 +16652,7 @@ var init_spec_version2 = __esm({
16577
16652
  SPEC_VERSION_SUPPORTS_ATTRIBUTES2 = 4;
16578
16653
  SPEC_VERSION_SUPPORTS_COMPRESSION2 = 5;
16579
16654
  SPEC_VERSION_SUPPORTS_SLOT_IDENTITY2 = 6;
16580
- SPEC_VERSION_CURRENT2 = SPEC_VERSION_SUPPORTS_COMPRESSION2;
16655
+ SPEC_VERSION_CURRENT2 = SPEC_VERSION_SUPPORTS_SLOT_IDENTITY2;
16581
16656
  SPEC_VERSION_MAX_SUPPORTED2 = SPEC_VERSION_SUPPORTS_SLOT_IDENTITY2;
16582
16657
  __name(isLegacySpecVersion2, "isLegacySpecVersion");
16583
16658
  __name(requiresNewerWorld, "requiresNewerWorld");
@@ -16805,6 +16880,7 @@ var init_ulid2 = __esm({
16805
16880
  // ../world/dist/index.js
16806
16881
  var dist_exports = {};
16807
16882
  __export(dist_exports, {
16883
+ ANALYTICS_EVENTS_GET_MANY_LIMIT: () => ANALYTICS_EVENTS_GET_MANY_LIMIT,
16808
16884
  ATTRIBUTE_KEY_MAX_LENGTH: () => ATTRIBUTE_KEY_MAX_LENGTH2,
16809
16885
  ATTRIBUTE_MAX_PER_RUN: () => ATTRIBUTE_MAX_PER_RUN2,
16810
16886
  ATTRIBUTE_VALUE_MAX_BYTES: () => ATTRIBUTE_VALUE_MAX_BYTES2,
@@ -16883,6 +16959,7 @@ __export(dist_exports, {
16883
16959
  WorkflowRunStatusSchema: () => WorkflowRunStatusSchema2,
16884
16960
  _resetEnvWarnCacheForTests: () => _resetEnvWarnCacheForTests,
16885
16961
  applyAttributeChanges: () => applyAttributeChanges,
16962
+ entityEventClass: () => entityEventClass,
16886
16963
  envNumber: () => envNumber2,
16887
16964
  eventIdToSlot: () => eventIdToSlot,
16888
16965
  getEventDataPayloadField: () => getEventDataPayloadField,
@@ -16905,6 +16982,7 @@ __export(dist_exports, {
16905
16982
  isWaitEventType: () => isWaitEventType,
16906
16983
  parseQueueName: () => parseQueueName,
16907
16984
  reenqueueActiveRuns: () => reenqueueActiveRuns,
16985
+ requireEventSlot: () => requireEventSlot,
16908
16986
  requiresNewerWorld: () => requiresNewerWorld,
16909
16987
  resolveQueueNamespace: () => resolveQueueNamespace2,
16910
16988
  slotToEventId: () => slotToEventId,
@@ -16992,7 +17070,7 @@ function buildFramedDetails2(hint3, slug) {
16992
17070
  out.push({ label: "docs", value: `${BASE_URL2}/${slug}` });
16993
17071
  return out;
16994
17072
  }
16995
- var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, MaxEventsExceededError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError2, WorkflowNotRegisteredError2, WorkflowDeploymentMismatchError, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError2, TooEarlyError, ThrottleError2, PreconditionFailedError, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2;
17073
+ var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, MaxEventsExceededError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError2, WorkflowNotRegisteredError2, WorkflowDeploymentMismatchError, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError2, StreamExpiredError2, TooEarlyError, ThrottleError2, PreconditionFailedError, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2;
16996
17074
  var init_dist7 = __esm({
16997
17075
  "../errors/dist/index.js"() {
16998
17076
  "use strict";
@@ -17335,6 +17413,24 @@ Caused by: ${options.cause.stack}`;
17335
17413
  return isError2(value) && value.name === "RunExpiredError";
17336
17414
  }
17337
17415
  };
17416
+ StreamExpiredError2 = class extends WorkflowWorldError2 {
17417
+ static {
17418
+ __name(this, "StreamExpiredError");
17419
+ }
17420
+ runId;
17421
+ streamId;
17422
+ expiredAt;
17423
+ constructor(message, runId, streamId, expiredAt) {
17424
+ super(message, { status: 410, code: "stream-expired" });
17425
+ this.runId = runId;
17426
+ this.streamId = streamId;
17427
+ this.expiredAt = expiredAt;
17428
+ this.name = "StreamExpiredError";
17429
+ }
17430
+ static is(value) {
17431
+ return isError2(value) && value.name === "StreamExpiredError";
17432
+ }
17433
+ };
17338
17434
  TooEarlyError = class extends WorkflowWorldError2 {
17339
17435
  static {
17340
17436
  __name(this, "TooEarlyError");
@@ -49911,7 +50007,7 @@ async function writeRunUnderLifecycleLock(basedir, runId, tag, proposed) {
49911
50007
  function createEventsStorage(basedir, tag) {
49912
50008
  const hookRetentionLimitMs = getHookRetentionLimitMs();
49913
50009
  const maxCachedEventBytes = 4 * 1024 * 1024;
49914
- const maxCachedEventEntries = 1e3;
50010
+ const maxCachedEventEntries = MAX_CACHED_EVENT_ENTRIES;
49915
50011
  const eventCache = /* @__PURE__ */ new Map();
49916
50012
  const cachedEventBytes = /* @__PURE__ */ new Map();
49917
50013
  const cachedPathsByRunId = /* @__PURE__ */ new Map();
@@ -50882,13 +50978,10 @@ function createEventsStorage(basedir, tag) {
50882
50978
  if (terminalByMarker || runNow && isTerminalWorkflowRunStatus2(runNow.status)) {
50883
50979
  throw new RunExpiredError2(`Workflow run "${effectiveRunId}" is already in a terminal state`);
50884
50980
  }
50885
- const stagedPath = pendingHookEventPath(basedir, effectiveRunId, eventId, tag);
50981
+ const stagedPath = pendingHookEventPath(basedir, effectiveRunId, `${eventId}.${monotonicUlid()}`, tag);
50886
50982
  const staged = await writeExclusive(stagedPath, serializedEvent);
50887
50983
  if (!staged) {
50888
- if (await bumpEventSlot(attempt)) {
50889
- continue;
50890
- }
50891
- throw new EntityConflictError2(`Event "${eventId}" already exists for run "${effectiveRunId}"`);
50984
+ throw new WorkflowWorldError2(`Failed to stage event "${eventId}" for run "${effectiveRunId}": staging path already exists`);
50892
50985
  }
50893
50986
  try {
50894
50987
  if (await isRunTerminalCommitted(basedir, effectiveRunId, tag)) {
@@ -50910,6 +51003,17 @@ function createEventsStorage(basedir, tag) {
50910
51003
  notePublishedSlot(effectiveRunId, eventId);
50911
51004
  break;
50912
51005
  }
51006
+ if (data.eventType === "hook_received" && params?.resumeId) {
51007
+ const occupant = await readJSONWithFallback(basedir, "events", `${effectiveRunId}-${eventId}`, EventSchema2, tag);
51008
+ if (occupant && isResumeEvent(occupant, {
51009
+ runId: effectiveRunId,
51010
+ resumeId: params.resumeId,
51011
+ hookId: data.correlationId,
51012
+ eventId
51013
+ })) {
51014
+ return { event: occupant };
51015
+ }
51016
+ }
50913
51017
  if (!await bumpEventSlot(attempt)) {
50914
51018
  break;
50915
51019
  }
@@ -51078,7 +51182,7 @@ function createEventsStorage(basedir, tag) {
51078
51182
  }), "create");
51079
51183
  return { ...storage, create };
51080
51184
  }
51081
- var DAY_MS, HookRecoveryMarkerSchema, HookResumeClaimSchema;
51185
+ var DAY_MS, MAX_CACHED_EVENT_ENTRIES, HookRecoveryMarkerSchema, HookResumeClaimSchema;
51082
51186
  var init_events_storage = __esm({
51083
51187
  "../world-local/dist/storage/events-storage.js"() {
51084
51188
  "use strict";
@@ -51094,6 +51198,7 @@ var init_events_storage = __esm({
51094
51198
  init_legacy();
51095
51199
  init_runs_storage();
51096
51200
  DAY_MS = 24 * 60 * 60 * 1e3;
51201
+ MAX_CACHED_EVENT_ENTRIES = 1e3;
51097
51202
  __name(getHookRetentionLimitMs, "getHookRetentionLimitMs");
51098
51203
  HookRecoveryMarkerSchema = external_exports2.object({
51099
51204
  eventId: external_exports2.string()
@@ -51626,11 +51731,7 @@ function createWorld(args) {
51626
51731
  // `(runId, resumeId)` via a filesystem sidecar claim (see
51627
51732
  // events-storage.ts `claimHookResume`), so resumeHook()'s parallel fast
51628
51733
  // path converges on one event in dev exactly as it does on Vercel.
51629
- hookResumeDedup: true,
51630
- // New runs get dense per-run slot event ids. Runs created before this
51631
- // keep their ULIDs; the scheme is pinned by a run's own first event id,
51632
- // not by this flag, which only says what new runs get.
51633
- slotEventIds: true
51734
+ hookResumeDedup: true
51634
51735
  },
51635
51736
  ...queue,
51636
51737
  ...storage,
@@ -55781,7 +55882,7 @@ async function injectTraceContextIntoHeaders(headers) {
55781
55882
  function SemanticConvention3(...names) {
55782
55883
  return (value) => Object.fromEntries(names.map((name) => [name, value]));
55783
55884
  }
55784
- var otelApiPromise2, tracerPromise2, otelDiagLogged2, HttpRequestMethod2, UrlFull2, ServerAddress2, ServerPort2, HttpResponseStatusCode2, ErrorType2, WorldParseFormat2, PeerService3, RpcSystem3, RpcService3, RpcMethod3, WorkflowRunId3, StepId3, WorkflowStreamName, WorkflowStreamOperation, WorkflowStreamStartIndex;
55885
+ var otelApiPromise2, tracerPromise2, otelDiagLogged2, HttpRequestMethod2, UrlFull2, ServerAddress2, ServerPort2, HttpResponseStatusCode2, ErrorType2, NetworkProtocolName, WorldParseFormat2, PeerService3, RpcSystem3, RpcService3, RpcMethod3, WorkflowRunId3, StepId3, WorkflowStreamName, WorkflowStreamOperation, WorkflowStreamStartIndex, WorkflowEventsTransport, WorkflowEventType, WorkflowClientVersion, StepStsoMs2, StepLatencyOptimizations2, WorkflowWsUrl, WorkflowWsRequestId, WorkflowWsReconnectAttempt;
55785
55886
  var init_telemetry3 = __esm({
55786
55887
  "../world-vercel/dist/telemetry.js"() {
55787
55888
  "use strict";
@@ -55802,6 +55903,7 @@ var init_telemetry3 = __esm({
55802
55903
  ServerPort2 = SemanticConvention3("server.port");
55803
55904
  HttpResponseStatusCode2 = SemanticConvention3("http.response.status_code");
55804
55905
  ErrorType2 = SemanticConvention3("error.type");
55906
+ NetworkProtocolName = SemanticConvention3("network.protocol.name");
55805
55907
  WorldParseFormat2 = SemanticConvention3("workflow.world.parse.format");
55806
55908
  PeerService3 = SemanticConvention3("peer.service");
55807
55909
  RpcSystem3 = SemanticConvention3("rpc.system");
@@ -55812,6 +55914,14 @@ var init_telemetry3 = __esm({
55812
55914
  WorkflowStreamName = SemanticConvention3("workflow.stream.name");
55813
55915
  WorkflowStreamOperation = SemanticConvention3("workflow.stream.operation");
55814
55916
  WorkflowStreamStartIndex = SemanticConvention3("workflow.stream.start_index");
55917
+ WorkflowEventsTransport = SemanticConvention3("workflow.events.transport");
55918
+ WorkflowEventType = SemanticConvention3("workflow.event.type");
55919
+ WorkflowClientVersion = SemanticConvention3("workflow.client.version");
55920
+ StepStsoMs2 = SemanticConvention3("step.stso_ms");
55921
+ StepLatencyOptimizations2 = SemanticConvention3("step.latency_optimizations");
55922
+ WorkflowWsUrl = SemanticConvention3("workflow.events.ws.url");
55923
+ WorkflowWsRequestId = SemanticConvention3("workflow.events.ws.req_id");
55924
+ WorkflowWsReconnectAttempt = SemanticConvention3("workflow.events.ws.reconnect_attempt");
55815
55925
  }
55816
55926
  });
55817
55927
 
@@ -55857,8 +55967,14 @@ function errorForResponse(status, message, opts = {}) {
55857
55967
  const { retryAfter, code: code3, url: url3, mitigated, details } = opts;
55858
55968
  if (status === 409)
55859
55969
  return new EntityConflictError2(message);
55860
- if (status === 410)
55970
+ if (status === 410) {
55971
+ if (code3 === "stream-expired") {
55972
+ const streamDetails = details && typeof details === "object" ? details : void 0;
55973
+ const expiredAt = typeof streamDetails?.expiredAt === "string" ? new Date(streamDetails.expiredAt) : void 0;
55974
+ return new StreamExpiredError2(message, typeof streamDetails?.runId === "string" ? streamDetails.runId : void 0, typeof streamDetails?.streamId === "string" ? streamDetails.streamId : void 0, expiredAt && !Number.isNaN(expiredAt.getTime()) ? expiredAt : void 0);
55975
+ }
55861
55976
  return new RunExpiredError2(message);
55977
+ }
55862
55978
  if (status === 412)
55863
55979
  return new PreconditionFailedError(message, { retryAfter, details });
55864
55980
  if (status === 425)
@@ -55885,9 +56001,10 @@ async function resolveVercelApiToken(opts) {
55885
56001
  function parseServer(url3) {
55886
56002
  try {
55887
56003
  const parsed = new URL(url3);
56004
+ const secure = parsed.protocol === "https:" || parsed.protocol === "wss:";
55888
56005
  return {
55889
56006
  serverAddress: parsed.hostname,
55890
- serverPort: parsed.port ? parseInt(parsed.port, 10) : parsed.protocol === "https:" ? 443 : 80
56007
+ serverPort: parsed.port ? parseInt(parsed.port, 10) : secure ? 443 : 80
55891
56008
  };
55892
56009
  } catch {
55893
56010
  return {};
@@ -55906,9 +56023,8 @@ function httpClientSpanAttributes(args) {
55906
56023
  ...RpcService3(peerService)
55907
56024
  };
55908
56025
  }
55909
- async function instrumentedFetch(opts) {
55910
- const { method, url: url3, headers, body, dispatcher, peerService = "workflow-server", timeoutMs = getRequestTimeoutMs(), signal: callerSignal, injectTraceContext: injectTraceContext2 = true, cacheBust = true, logLabel, buildError, spanName, attributes, durationAttribute, onTransportOutcome } = opts;
55911
- const label = logLabel ?? url3;
56026
+ async function withHttpClientSpan(opts, fn) {
56027
+ const { method, url: url3, peerService = "workflow-server", spanName, attributes } = opts;
55912
56028
  return trace4(spanName ?? `http ${method}`, { kind: await getSpanKind3("CLIENT") }, async (span) => {
55913
56029
  if (spanName && HTTP_DEBUG_ENABLED && span) {
55914
56030
  const ctx = span.spanContext();
@@ -55922,6 +56038,19 @@ async function instrumentedFetch(opts) {
55922
56038
  span?.setAttributes(httpClientSpanAttributes({ method, url: url3, peerService }));
55923
56039
  if (attributes)
55924
56040
  span?.setAttributes(attributes);
56041
+ return fn(span);
56042
+ });
56043
+ }
56044
+ function recordClientSpanStatus(span, status) {
56045
+ span?.setAttributes({ ...HttpResponseStatusCode2(status) });
56046
+ if (status < 200 || status >= 300) {
56047
+ span?.setAttributes({ ...ErrorType2(`HTTP ${status}`) });
56048
+ }
56049
+ }
56050
+ async function instrumentedFetch(opts) {
56051
+ const { method, url: url3, headers, body, dispatcher, peerService, timeoutMs = getRequestTimeoutMs(), signal: callerSignal, injectTraceContext: injectTraceContext2 = true, cacheBust = true, logLabel, buildError, spanName, attributes, durationAttribute, onTransportOutcome } = opts;
56052
+ const label = logLabel ?? url3;
56053
+ return withHttpClientSpan({ method, url: url3, peerService, spanName, attributes }, async (span) => {
55925
56054
  if (injectTraceContext2)
55926
56055
  await injectTraceContextIntoHeaders(headers);
55927
56056
  if (cacheBust)
@@ -55953,11 +56082,10 @@ async function instrumentedFetch(opts) {
55953
56082
  const ms3 = Date.now() - start3;
55954
56083
  onTransportOutcome?.();
55955
56084
  httpLog(method, label, response, ms3);
55956
- span?.setAttributes({ ...HttpResponseStatusCode2(response.status) });
56085
+ recordClientSpanStatus(span, response.status);
55957
56086
  if (durationAttribute)
55958
56087
  span?.setAttributes({ [durationAttribute]: ms3 });
55959
56088
  if (!response.ok) {
55960
- span?.setAttributes({ ...ErrorType2(`HTTP ${response.status}`) });
55961
56089
  logCurlRepro(method, url3, headers);
55962
56090
  if (buildError) {
55963
56091
  const error96 = await buildError(response);
@@ -56005,6 +56133,8 @@ var init_http_core = __esm({
56005
56133
  __name(resolveVercelApiToken, "resolveVercelApiToken");
56006
56134
  __name(parseServer, "parseServer");
56007
56135
  __name(httpClientSpanAttributes, "httpClientSpanAttributes");
56136
+ __name(withHttpClientSpan, "withHttpClientSpan");
56137
+ __name(recordClientSpanStatus, "recordClientSpanStatus");
56008
56138
  __name(instrumentedFetch, "instrumentedFetch");
56009
56139
  }
56010
56140
  });
@@ -56014,7 +56144,7 @@ var version4;
56014
56144
  var init_version3 = __esm({
56015
56145
  "../world-vercel/dist/version.js"() {
56016
56146
  "use strict";
56017
- version4 = "5.0.0-beta.37";
56147
+ version4 = "5.0.0-beta.38";
56018
56148
  }
56019
56149
  });
56020
56150
 
@@ -56134,7 +56264,8 @@ async function makeRequest({ endpoint, options = {}, config: config4 = {}, schem
56134
56264
  url: url3,
56135
56265
  code: errorCode,
56136
56266
  retryAfter,
56137
- mitigated: response.headers.get("x-vercel-mitigated")
56267
+ mitigated: response.headers.get("x-vercel-mitigated"),
56268
+ details: errorData.details
56138
56269
  });
56139
56270
  span?.setAttributes({
56140
56271
  ...ErrorType2(errorCode || `HTTP ${response.status}`)
@@ -56315,6 +56446,16 @@ function createQueryString(params) {
56315
56446
  const query = params.toString();
56316
56447
  return query ? `?${query}` : "";
56317
56448
  }
56449
+ function normalizeEventIds(eventIds) {
56450
+ const uniqueEventIds = [...new Set(eventIds)];
56451
+ if (uniqueEventIds.length === 0) {
56452
+ throw new RangeError("eventIds must contain at least one event ID");
56453
+ }
56454
+ if (uniqueEventIds.length > ANALYTICS_EVENTS_GET_MANY_LIMIT) {
56455
+ throw new RangeError(`eventIds must contain at most ${ANALYTICS_EVENTS_GET_MANY_LIMIT} unique event IDs`);
56456
+ }
56457
+ return uniqueEventIds;
56458
+ }
56318
56459
  function appendAttributeListParams(searchParams, params) {
56319
56460
  if (params.workflowName) {
56320
56461
  searchParams.set("workflowName", params.workflowName);
@@ -56395,6 +56536,15 @@ function createAnalytics(config4) {
56395
56536
  schema: AnalyticsEventSchema2
56396
56537
  });
56397
56538
  },
56539
+ getMany(runId, eventIds) {
56540
+ return makeRequest({
56541
+ endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}/events/get-many`,
56542
+ options: { method: "POST" },
56543
+ data: { eventIds: normalizeEventIds(eventIds) },
56544
+ config: config4,
56545
+ schema: AnalyticsEventSchema2.array()
56546
+ });
56547
+ },
56398
56548
  list(params) {
56399
56549
  const searchParams = new URLSearchParams();
56400
56550
  if (params.eventType) {
@@ -56474,6 +56624,7 @@ var init_analytics3 = __esm({
56474
56624
  init_utils4();
56475
56625
  __name(appendPagination, "appendPagination");
56476
56626
  __name(createQueryString, "createQueryString");
56627
+ __name(normalizeEventIds, "normalizeEventIds");
56477
56628
  __name(appendAttributeListParams, "appendAttributeListParams");
56478
56629
  __name(createAnalytics, "createAnalytics");
56479
56630
  }
@@ -67265,7 +67416,7 @@ var init_ws_transport = __esm({
67265
67416
  if (conn && conn.ws.readyState === import_websocket2.default.OPEN) {
67266
67417
  return Promise.resolve(conn);
67267
67418
  }
67268
- this.connecting ??= this.connect().finally(() => {
67419
+ this.connecting ??= this.connectWithSpan().finally(() => {
67269
67420
  this.connecting = null;
67270
67421
  });
67271
67422
  return this.connecting;
@@ -67303,6 +67454,43 @@ var init_ws_transport = __esm({
67303
67454
  if (reason === "auth_expiry")
67304
67455
  this.needsFreshToken = true;
67305
67456
  }
67457
+ /**
67458
+ * The handshake, wrapped in its own CLIENT span.
67459
+ *
67460
+ * The upgrade is the one genuinely-HTTP request this transport makes, and
67461
+ * until it had a span it was the invisible half of every WS write's latency:
67462
+ * a write that waits on a handshake shows the wait inside its own span with
67463
+ * nothing to attribute it to, and an eager reconnect between two writes shows
67464
+ * up nowhere at all. Named for the operation rather than `http GET` so it
67465
+ * doesn't land in the same bucket as the event writes it enables.
67466
+ *
67467
+ * It also puts `resolveUpgradeHeaders`' trace-context injection inside a
67468
+ * client span, matching `makeRequest`'s contract (CLAUDE.md): the server's
67469
+ * per-event spans parent to *this* span rather than directly to whichever
67470
+ * invocation happened to open the socket, so the handshake and everything the
67471
+ * server does over the connection hang together.
67472
+ */
67473
+ connectWithSpan() {
67474
+ return withHttpClientSpan({
67475
+ method: "GET",
67476
+ url: this.wsUrl,
67477
+ spanName: "workflow.events.ws.connect",
67478
+ attributes: {
67479
+ ...WorkflowEventsTransport("ws"),
67480
+ ...NetworkProtocolName("websocket"),
67481
+ ...WorkflowWsReconnectAttempt(this.reconnectAttempts)
67482
+ }
67483
+ }, async (span) => {
67484
+ try {
67485
+ return await this.connect();
67486
+ } catch (err) {
67487
+ span?.setAttributes({ ...ErrorType2("TRANSPORT") });
67488
+ if (err instanceof Error)
67489
+ span?.recordException?.(err);
67490
+ throw err;
67491
+ }
67492
+ });
67493
+ }
67306
67494
  connect() {
67307
67495
  return new Promise((resolve3, reject) => {
67308
67496
  void (async () => {
@@ -67902,36 +68090,61 @@ function errorMarker(err) {
67902
68090
  }
67903
68091
  return collectErrorMarkers(err)[0] ?? (err instanceof Error ? err.name : "unknown");
67904
68092
  }
68093
+ function createThrottleWaiter(eventType) {
68094
+ let waitedMs = 0;
68095
+ return async (err) => {
68096
+ const waitMs = Math.max(1, typeof err.retryAfter === "number" ? err.retryAfter : DEFAULT_THROTTLE_RETRY_AFTER_SECONDS) * 1e3;
68097
+ if (waitedMs + waitMs > THROTTLE_RETRY_BUDGET_MS) {
68098
+ logRetry("throttle retry budget exhausted; surfacing to the queue", {
68099
+ eventType,
68100
+ waitedMs,
68101
+ retryAfter: err.retryAfter
68102
+ });
68103
+ throw err;
68104
+ }
68105
+ waitedMs += waitMs;
68106
+ console.warn(`[workflow] Throttled (429) writing ${eventType} event; retrying in-process in ${waitMs / 1e3}s`);
68107
+ await sleep(waitMs);
68108
+ };
68109
+ }
68110
+ function isEligibleForTransientRetry(eventType, options) {
68111
+ return eventType === "hook_received" && options?.idempotentHookResume === true || (EVENT_RETRY_ELIGIBILITY[eventType]?.retryable ?? false);
68112
+ }
67905
68113
  async function withEventPostRetry(fn, eventType, options) {
67906
- const retryable = eventType === "hook_received" && options?.idempotentHookResume === true || (EVENT_RETRY_ELIGIBILITY[eventType]?.retryable ?? false);
67907
- for (let attempt = 0; ; attempt++) {
68114
+ const retryable = isEligibleForTransientRetry(eventType, options);
68115
+ const waitOutThrottle = createThrottleWaiter(eventType);
68116
+ for (let attempt = 0; ; ) {
67908
68117
  try {
67909
68118
  return await fn();
67910
68119
  } catch (err) {
67911
- const transient = retryable && isRetryableEventPostError(err);
67912
- if (transient && attempt < MAX_EVENT_POST_RETRIES) {
67913
- const backoff = EVENT_POST_RETRY_BASE_MS * 2 ** attempt + Math.floor(Math.random() * EVENT_POST_RETRY_JITTER_MS);
67914
- logRetry("retrying event POST after transient failure", {
67915
- eventType,
67916
- attempt: attempt + 1,
67917
- backoffMs: backoff,
67918
- error: errorMarker(err)
67919
- });
67920
- await sleep(backoff);
68120
+ if (ThrottleError2.is(err)) {
68121
+ await waitOutThrottle(err);
67921
68122
  continue;
67922
68123
  }
67923
- if (transient) {
68124
+ if (!retryable || !isRetryableEventPostError(err)) {
68125
+ throw err;
68126
+ }
68127
+ if (attempt >= MAX_EVENT_POST_RETRIES) {
67924
68128
  logRetry("exhausted in-process retries; surfacing for queue redelivery", {
67925
68129
  eventType,
67926
68130
  attempts: attempt + 1,
67927
68131
  error: errorMarker(err)
67928
68132
  });
68133
+ throw err;
67929
68134
  }
67930
- throw err;
68135
+ const backoff = EVENT_POST_RETRY_BASE_MS * 2 ** attempt + Math.floor(Math.random() * EVENT_POST_RETRY_JITTER_MS);
68136
+ attempt++;
68137
+ logRetry("retrying event POST after transient failure", {
68138
+ eventType,
68139
+ attempt,
68140
+ backoffMs: backoff,
68141
+ error: errorMarker(err)
68142
+ });
68143
+ await sleep(backoff);
67931
68144
  }
67932
68145
  }
67933
68146
  }
67934
- var EVENT_RETRY_ELIGIBILITY, MAX_EVENT_POST_RETRIES, EVENT_POST_RETRY_BASE_MS, EVENT_POST_RETRY_JITTER_MS, TRANSIENT_CODES, sleep, RETRY_DEBUG_ENABLED;
68147
+ var EVENT_RETRY_ELIGIBILITY, MAX_EVENT_POST_RETRIES, THROTTLE_RETRY_BUDGET_MS, DEFAULT_THROTTLE_RETRY_AFTER_SECONDS, EVENT_POST_RETRY_BASE_MS, EVENT_POST_RETRY_JITTER_MS, TRANSIENT_CODES, sleep, RETRY_DEBUG_ENABLED;
67935
68148
  var init_event_retry = __esm({
67936
68149
  "../world-vercel/dist/event-retry.js"() {
67937
68150
  "use strict";
@@ -68014,6 +68227,8 @@ var init_event_retry = __esm({
68014
68227
  }
68015
68228
  };
68016
68229
  MAX_EVENT_POST_RETRIES = 2;
68230
+ THROTTLE_RETRY_BUDGET_MS = 3e4;
68231
+ DEFAULT_THROTTLE_RETRY_AFTER_SECONDS = 1;
68017
68232
  EVENT_POST_RETRY_BASE_MS = 100;
68018
68233
  EVENT_POST_RETRY_JITTER_MS = 50;
68019
68234
  TRANSIENT_CODES = /* @__PURE__ */ new Set([
@@ -68047,6 +68262,8 @@ var init_event_retry = __esm({
68047
68262
  RETRY_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
68048
68263
  __name(logRetry, "logRetry");
68049
68264
  __name(errorMarker, "errorMarker");
68265
+ __name(createThrottleWaiter, "createThrottleWaiter");
68266
+ __name(isEligibleForTransientRetry, "isEligibleForTransientRetry");
68050
68267
  __name(withEventPostRetry, "withEventPostRetry");
68051
68268
  }
68052
68269
  });
@@ -68229,7 +68446,7 @@ var init_steps3 = __esm({
68229
68446
 
68230
68447
  // ../world-vercel/dist/events-v4.js
68231
68448
  import assert4 from "node:assert/strict";
68232
- async function fetchV4(url3, init, config4, opName) {
68449
+ async function fetchV4(url3, init, config4, opName, attributes) {
68233
68450
  const dispatcher = getEventsDispatcher(config4);
68234
68451
  return instrumentedFetch({
68235
68452
  method: init.method,
@@ -68237,6 +68454,7 @@ async function fetchV4(url3, init, config4, opName) {
68237
68454
  headers: init.headers,
68238
68455
  body: init.body,
68239
68456
  dispatcher,
68457
+ attributes,
68240
68458
  // Repeated transport failures retire the shared events pool and the next
68241
68459
  // request builds a fresh one. undici keeps a black-holed HTTP/2 session in
68242
68460
  // service indefinitely, so without this every request routed onto it fails
@@ -68249,6 +68467,9 @@ async function fetchV4(url3, init, config4, opName) {
68249
68467
  buildError: /* @__PURE__ */ __name(async (response) => errorFromV4Response(response.status, headersToRecord(response.headers), new Uint8Array(await response.arrayBuffer()), opName, url3), "buildError")
68250
68468
  });
68251
68469
  }
68470
+ function eventsV4Url(baseUrl, runId, eventType) {
68471
+ return `${baseUrl}/v4/runs/${encodeURIComponent(runId)}/events/${encodeURIComponent(eventType)}`;
68472
+ }
68252
68473
  function decodeLegacyStructuredError(payload) {
68253
68474
  if (hasSerializedDataFormatPrefix(payload))
68254
68475
  return payload;
@@ -68355,14 +68576,6 @@ function buildPostFrameMeta(input) {
68355
68576
  meta5.sinceCursor = input.sinceCursor;
68356
68577
  if (input.skipPreload)
68357
68578
  meta5.skipPreload = true;
68358
- if (input.stateUpdatedAt !== void 0) {
68359
- meta5.stateUpdatedAt = input.stateUpdatedAt;
68360
- }
68361
- if (input.stateEventCount !== void 0) {
68362
- meta5.stateEventCount = input.stateEventCount;
68363
- }
68364
- if (input.stateCursor !== void 0)
68365
- meta5.stateCursor = input.stateCursor;
68366
68579
  if (input.maxSlot !== void 0)
68367
68580
  meta5.maxSlot = input.maxSlot;
68368
68581
  if (input.replayDivergenceCount !== void 0) {
@@ -68371,6 +68584,9 @@ function buildPostFrameMeta(input) {
68371
68584
  if (input.resumePayloadDigest !== void 0) {
68372
68585
  meta5.resumePayloadDigest = input.resumePayloadDigest;
68373
68586
  }
68587
+ if (input.viaStepDispatch !== void 0) {
68588
+ meta5.viaStepDispatch = input.viaStepDispatch;
68589
+ }
68374
68590
  return meta5;
68375
68591
  }
68376
68592
  function errorFromV4Response(statusCode, responseHeaders, errorBody, opName, url3) {
@@ -68463,8 +68679,14 @@ async function postWorkflowRunEventV4(input, responseType, config4) {
68463
68679
  headers.set("Accept", V4_FRAME_CONTENT_TYPE);
68464
68680
  }
68465
68681
  const frame3 = encodeFrame(buildPostFrameMeta(input), input.payload ?? new Uint8Array(0));
68466
- const url3 = `${baseUrl}/v4/runs/${encodeURIComponent(input.runId)}/events/${encodeURIComponent(input.eventType)}`;
68467
- return fetchV4(url3, { method: "POST", headers, body: frame3 }, config4, "createEvent");
68682
+ const url3 = eventsV4Url(baseUrl, input.runId, input.eventType);
68683
+ return fetchV4(url3, { method: "POST", headers, body: frame3 }, config4, "createEvent", {
68684
+ ...WorkflowEventsTransport("http"),
68685
+ ...WorkflowEventType(input.eventType),
68686
+ ...WorkflowClientVersion(`@workflow/world-vercel/${version4}`),
68687
+ ...input.stso !== void 0 ? StepStsoMs2(input.stso) : {},
68688
+ ...input.optimizations !== void 0 ? StepLatencyOptimizations2(input.optimizations) : {}
68689
+ });
68468
68690
  }
68469
68691
  async function createWorkflowRunEventV4(input, config4) {
68470
68692
  if (isWsEventsTransportEnabled()) {
@@ -68533,21 +68755,51 @@ async function postEventFrameOverWs(input, config4) {
68533
68755
  return void 0;
68534
68756
  const { transport, wsUrl } = resolved;
68535
68757
  const endpoint = `${wsUrl}#runs/${encodeURIComponent(runId)}/events`;
68536
- let reply;
68537
- try {
68538
- reply = await transport.request((reqId) => encodeFrame({ reqId, type: "event", event: buildPostFrameMeta(input) }, input.payload ?? new Uint8Array(0)));
68539
- } catch (err) {
68540
- throw new WorkflowWorldError2(`POST ${endpoint} transport failure: ${err instanceof Error ? err.message : String(err)}`, { url: wsUrl, code: "TRANSPORT", cause: err });
68541
- }
68542
- const status = wsReplyStatus(reply, endpoint);
68543
- const headerRecord = replyMetaToHeaderRecord(reply.meta);
68544
- if (status < 200 || status >= 300) {
68545
- throw errorFromV4Response(status, headerRecord, new TextDecoder().decode(reply.body), "createEvent", endpoint);
68546
- }
68547
- return {
68548
- headers: { get: /* @__PURE__ */ __name((name) => headerRecord[name.toLowerCase()] ?? null, "get") },
68549
- arrayBuffer: /* @__PURE__ */ __name(async () => reply.body.slice().buffer, "arrayBuffer")
68550
- };
68758
+ const restUrl = eventsV4Url(getHttpUrl(config4).baseUrl, runId, input.eventType);
68759
+ return withHttpClientSpan({
68760
+ method: "POST",
68761
+ url: restUrl,
68762
+ attributes: {
68763
+ ...WorkflowEventsTransport("ws"),
68764
+ ...WorkflowEventType(input.eventType),
68765
+ ...WorkflowClientVersion(`@workflow/world-vercel/${version4}`),
68766
+ ...input.stso !== void 0 ? StepStsoMs2(input.stso) : {},
68767
+ ...input.optimizations !== void 0 ? StepLatencyOptimizations2(input.optimizations) : {},
68768
+ ...NetworkProtocolName("websocket"),
68769
+ ...WorkflowWsUrl(wsUrl)
68770
+ }
68771
+ }, async (span) => {
68772
+ const start3 = Date.now();
68773
+ let reply;
68774
+ try {
68775
+ reply = await transport.request((reqId) => {
68776
+ span?.setAttributes({ ...WorkflowWsRequestId(reqId) });
68777
+ return encodeFrame({ reqId, type: "event", event: buildPostFrameMeta(input) }, input.payload ?? new Uint8Array(0));
68778
+ });
68779
+ } catch (err) {
68780
+ const error95 = new WorkflowWorldError2(`POST ${endpoint} transport failure: ${err instanceof Error ? err.message : String(err)}`, { url: wsUrl, code: "TRANSPORT", cause: err });
68781
+ span?.setAttributes({ ...ErrorType2("TRANSPORT") });
68782
+ span?.recordException?.(error95);
68783
+ throw error95;
68784
+ }
68785
+ const ms3 = Date.now() - start3;
68786
+ const status = wsReplyStatus(reply, endpoint);
68787
+ const headerRecord = replyMetaToHeaderRecord(reply.meta);
68788
+ const headers = {
68789
+ get: /* @__PURE__ */ __name((name) => headerRecord[name.toLowerCase()] ?? null, "get")
68790
+ };
68791
+ httpLog("POST", "createEvent", { status, headers }, ms3);
68792
+ recordClientSpanStatus(span, status);
68793
+ if (status < 200 || status >= 300) {
68794
+ const error95 = errorFromV4Response(status, headerRecord, new TextDecoder().decode(reply.body), "createEvent", endpoint);
68795
+ span?.recordException?.(error95);
68796
+ throw error95;
68797
+ }
68798
+ return {
68799
+ headers,
68800
+ arrayBuffer: /* @__PURE__ */ __name(async () => reply.body.slice().buffer, "arrayBuffer")
68801
+ };
68802
+ });
68551
68803
  }
68552
68804
  async function createHookReceivedPreloadEventV4(input, config4) {
68553
68805
  const response = await postWorkflowRunEventV4({ ...input, eventType: "hook_received" }, "event-stream", config4);
@@ -68673,11 +68925,14 @@ var init_events_v4 = __esm({
68673
68925
  init_http_core();
68674
68926
  init_serialized_data();
68675
68927
  init_steps3();
68928
+ init_telemetry3();
68676
68929
  init_utils4();
68930
+ init_version3();
68677
68931
  init_ws_transport_enabled();
68678
68932
  __name(fetchV4, "fetchV4");
68679
68933
  EVENT_ID_HEADER = "x-wf-event-id";
68680
68934
  MAX_EVENTS_HEADER = "x-wf-max-events";
68935
+ __name(eventsV4Url, "eventsV4Url");
68681
68936
  CreateEventV4BodyBaseSchema = external_exports2.object({
68682
68937
  event: EventSchema2,
68683
68938
  run: WorkflowRunSchema2.optional(),
@@ -69152,11 +69407,7 @@ async function createWorkflowRunEventInner(id, data, params, config4) {
69152
69407
  ...data.correlationId ? { correlationId: data.correlationId } : {},
69153
69408
  ...params?.requestId ? { vercelId: params.requestId } : {},
69154
69409
  ...params?.computeInstanceId ? { computeInstanceId: params.computeInstanceId } : {},
69155
- stateUpdatedAt: params?.stateUpdatedAt,
69156
- stateEventCount: params?.stateEventCount,
69157
- ...params?.stateCursor ? { stateCursor: params.stateCursor } : {},
69158
- // Slot-identity snapshot. The runtime sends `eventCount` instead of the
69159
- // watermark triple once the run's own ids are slot-shaped; it rides as
69410
+ // Slot-identity snapshot: how much of the log the writer held. Rides as
69160
69411
  // `maxSlot` because the v4 meta already has an unrelated telemetry
69161
69412
  // `eventCount`.
69162
69413
  ...params?.eventCount !== void 0 ? { maxSlot: params.eventCount } : {},
@@ -69172,6 +69423,11 @@ async function createWorkflowRunEventInner(id, data, params, config4) {
69172
69423
  ...params?.sinceCursor ? { sinceCursor: params.sinceCursor } : {},
69173
69424
  ...params?.resumeId ? { resumeId: params.resumeId } : {},
69174
69425
  ...params?.resumePayloadDigest ? { resumePayloadDigest: params.resumePayloadDigest } : {},
69426
+ // Resilient step dispatch re-ensure marker (step_created only). Advisory
69427
+ // — the server MAY refuse it with 410 → RunExpiredError as
69428
+ // defense-in-depth when it recorded a 412 rejection for this correlation
69429
+ // id and no step entity exists.
69430
+ ...params?.viaStepDispatch ? { viaStepDispatch: true } : {},
69175
69431
  remoteRefBehavior,
69176
69432
  payload,
69177
69433
  ...meta5
@@ -69439,6 +69695,17 @@ function streamSpanAttributes(args) {
69439
69695
  ...typeof args.startIndex === "number" ? WorkflowStreamStartIndex(args.startIndex) : {}
69440
69696
  };
69441
69697
  }
69698
+ async function createStreamReadError(response) {
69699
+ const fallback = `Failed to fetch stream: ${response.status}`;
69700
+ if (response.status !== 410)
69701
+ return new Error(fallback);
69702
+ try {
69703
+ const body = await response.json();
69704
+ return errorForResponse(response.status, typeof body.message === "string" ? body.message : fallback, { code: body.error, details: body.details });
69705
+ } catch {
69706
+ return new Error(fallback);
69707
+ }
69708
+ }
69442
69709
  function createStreamRequestError(operation, url3, response, text) {
69443
69710
  const context2 = [
69444
69711
  `PUT ${url3.origin}${url3.pathname}`,
@@ -69552,6 +69819,7 @@ function createStreamer2(config4) {
69552
69819
  },
69553
69820
  async get(runId, name, startIndex) {
69554
69821
  const httpConfig = await getHttpConfig(config4);
69822
+ httpConfig.headers.set("Accept", "application/json");
69555
69823
  const url3 = getStreamReadUrl(name, runId, httpConfig);
69556
69824
  if (typeof startIndex === "number") {
69557
69825
  url3.searchParams.set("startIndex", String(startIndex));
@@ -69570,7 +69838,7 @@ function createStreamer2(config4) {
69570
69838
  operation: "read",
69571
69839
  startIndex
69572
69840
  }),
69573
- buildError: /* @__PURE__ */ __name((res) => new Error(`Failed to fetch stream: ${res.status}`), "buildError")
69841
+ buildError: createStreamReadError
69574
69842
  });
69575
69843
  if (!response.body) {
69576
69844
  throw new Error("No response body for stream");
@@ -69636,6 +69904,7 @@ var init_streamer2 = __esm({
69636
69904
  __name(getStreamUrl, "getStreamUrl");
69637
69905
  __name(getStreamReadUrl, "getStreamReadUrl");
69638
69906
  __name(streamSpanAttributes, "streamSpanAttributes");
69907
+ __name(createStreamReadError, "createStreamReadError");
69639
69908
  __name(createStreamRequestError, "createStreamRequestError");
69640
69909
  __name(encodeMultiChunks, "encodeMultiChunks");
69641
69910
  StreamInfoResponseSchema = external_exports2.object({
@@ -69659,31 +69928,25 @@ var init_streamer2 = __esm({
69659
69928
  function createWorld2(config4) {
69660
69929
  const projectId = config4?.projectConfig?.projectId || process.env.VERCEL_PROJECT_ID;
69661
69930
  return {
69662
- // Spec v6 adds slot-numbered event ids on top of v5's client-side
69663
- // zstd/gzip payload compression. The version is what tells the backend
69664
- // which id scheme a run uses: it is stamped on `run_created` and read back
69665
- // on every later write, so a run created before v6 keeps its ULIDs even
69666
- // though this adapter now asks for slots.
69667
- specVersion: SPEC_VERSION_SUPPORTS_SLOT_IDENTITY2,
69931
+ // The version is what tells the backend which id scheme a run uses: it is
69932
+ // stamped on `run_created` and read back on every later write, so a run
69933
+ // created before spec 6 keeps its ULIDs for its whole life even though this
69934
+ // adapter now asks for slot-numbered ids.
69935
+ //
69936
+ // Declared as the runtime's current version rather than as the literal
69937
+ // version that introduced slots: a bump has to move this declaration with
69938
+ // it, or the runtime's compatibility floor rises past the adapter shipped
69939
+ // alongside it and rejects it (see `assertWorldSupportsRuntimeProtocol`).
69940
+ specVersion: SPEC_VERSION_CURRENT2,
69668
69941
  capabilities: {
69669
69942
  hookRetention: { active: true },
69670
- // workflow-server enforces the `stateUpdatedAt` optimistic-concurrency
69671
- // guard: creations carrying a stale snapshot are rejected with 412
69672
- // (PreconditionFailedError) when the run's outside-event marker is
69673
- // newer. See vercel/workflow-server#484.
69674
- preconditionGuard: true,
69675
69943
  // Vercel Queues supports maxConcurrency-limited consumers, which
69676
69944
  // WORKFLOW_SEQUENTIAL_REPLAYS=1 uses for per-run `maxConcurrency: 1`
69677
69945
  // flow topics (see queue.ts and @workflow/builders).
69678
69946
  maxConcurrency: true,
69679
69947
  // Vercel deployments are atomic and immutable, so a deployment id names
69680
69948
  // one fixed build for its whole lifetime.
69681
- deploymentAffinity: true,
69682
- // New runs get dense per-run slot event ids. Runs created before the
69683
- // backend adopted them keep their ULIDs; the scheme is pinned by the
69684
- // spec version stamped on each run, not by this flag, which only says
69685
- // what new runs get.
69686
- slotEventIds: true
69949
+ deploymentAffinity: true
69687
69950
  // NOTE: the backend half of resumeHook()'s parallel fast path — that
69688
69951
  // the server enforces the `(runId, resumeId)` dedup constraint — is
69689
69952
  // NO LONGER a static world capability here. It is attested per-lookup by
@@ -70660,7 +70923,7 @@ var init_log_format2 = __esm({
70660
70923
  function SemanticConvention4(...names) {
70661
70924
  return (value) => Object.fromEntries(names.map((name) => [name, value]));
70662
70925
  }
70663
- var WorkflowName2, WorkflowOperation2, WorkflowRunId4, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowExecutionMode2, WorkflowParkedEventsCount2, WorkflowParkedEventId2, WorkflowParkedEventType2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowVm2, QuickJSOutcome2, QuickJSEventsPreloaded2, QuickJSEventsFetchedCount2, QuickJSEventsFetchedPages2, QuickJSPendingOpsCount2, QuickJSInlineSteps2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowOwnedRecoverySteps2, WorkflowBackstopWakesArmed2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, FaasInstance2, StepName2, StepId4, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepTtfsMs2, StepStsoMs2, StepRsfsMs2, StepFinalSchedulingReplayMs2, StepLatencyOptimizations2, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, WorkflowRunPinnedDeploymentId2, WorkflowDeploymentMismatchRetryCount2, WorkflowDeploymentMismatchRecovered2, HookToken2, HookId2, HookFound2, HookResilientResume2, HookResilientResumeMaterialized2, HookResumeSetupSource2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod3, HttpRoute2, UrlFull3, ServerAddress3, ServerPort3, HttpResponseStatusCode3, ErrorType3, WorldParseFormat3, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, SerializationGuestCodeExecutions2, SerializationGuestCodeDetails2, PeerService4, RpcSystem4, RpcService4, RpcMethod4, ErrorRetryable2, ErrorCategory2;
70926
+ var WorkflowName2, WorkflowOperation2, WorkflowRunId4, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowExecutionMode2, WorkflowParkedEventsCount2, WorkflowParkedEventId2, WorkflowParkedEventType2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowVm2, QuickJSOutcome2, QuickJSEventsPreloaded2, QuickJSEventsFetchedCount2, QuickJSEventsFetchedPages2, QuickJSPendingOpsCount2, QuickJSInlineSteps2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowOwnedRecoverySteps2, WorkflowBackstopWakesArmed2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, FaasInstance2, StepName2, StepId4, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepTtfsMs2, StepStsoMs3, StepRsfsMs2, StepFinalSchedulingReplayMs2, StepLatencyOptimizations3, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, WorkflowRunPinnedDeploymentId2, WorkflowDeploymentMismatchRetryCount2, WorkflowDeploymentMismatchRecovered2, HookToken2, HookId2, HookFound2, HookResilientResume2, HookResilientResumeMaterialized2, HookResumeSetupSource2, StepResilientDispatchRecovered2, StepResilientDispatchMaterialized2, ResumeTotalMs2, ResumeProducerPrepMs2, ResumeQueueDeliveryMs2, ResumeSetupMs2, ResumeReplayMs2, ResumeStepDispatchMs2, ResumeStepClaimMs2, ResumeStepPrepareMs2, ResumeTrigger2, ResumeStrategy2, ResumeSetupSource2, ResumeStepExecution2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod3, HttpRoute2, UrlFull3, ServerAddress3, ServerPort3, HttpResponseStatusCode3, ErrorType3, WorldParseFormat3, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, SerializationGuestCodeExecutions2, SerializationGuestCodeDetails2, PeerService4, RpcSystem4, RpcService4, RpcMethod4, ErrorRetryable2, ErrorCategory2;
70664
70927
  var init_semantic_conventions2 = __esm({
70665
70928
  "../core/dist/telemetry/semantic-conventions.js"() {
70666
70929
  "use strict";
@@ -70708,10 +70971,10 @@ var init_semantic_conventions2 = __esm({
70708
70971
  StepMaxRetries2 = SemanticConvention4("step.max_retries");
70709
70972
  StepTracePropagated2 = SemanticConvention4("step.trace.propagated");
70710
70973
  StepTtfsMs2 = SemanticConvention4("step.ttfs_ms");
70711
- StepStsoMs2 = SemanticConvention4("step.stso_ms");
70974
+ StepStsoMs3 = SemanticConvention4("step.stso_ms");
70712
70975
  StepRsfsMs2 = SemanticConvention4("step.rsfs_ms");
70713
70976
  StepFinalSchedulingReplayMs2 = SemanticConvention4("step.final_scheduling_replay_ms");
70714
- StepLatencyOptimizations2 = SemanticConvention4("step.latency_optimizations");
70977
+ StepLatencyOptimizations3 = SemanticConvention4("step.latency_optimizations");
70715
70978
  StepSkipped2 = SemanticConvention4("step.skipped");
70716
70979
  StepSkipReason2 = SemanticConvention4("step.skip_reason");
70717
70980
  StepArgumentsCount2 = SemanticConvention4("step.arguments.count");
@@ -70737,6 +71000,20 @@ var init_semantic_conventions2 = __esm({
70737
71000
  HookResilientResume2 = SemanticConvention4("workflow.hook.resilient_resume");
70738
71001
  HookResilientResumeMaterialized2 = SemanticConvention4("workflow.hook.resilient_resume_materialized");
70739
71002
  HookResumeSetupSource2 = SemanticConvention4("workflow.resume_setup_source");
71003
+ StepResilientDispatchRecovered2 = SemanticConvention4("workflow.step.resilient_dispatch_recovered");
71004
+ StepResilientDispatchMaterialized2 = SemanticConvention4("workflow.step.resilient_dispatch_materialized");
71005
+ ResumeTotalMs2 = SemanticConvention4("workflow.resume.total_ms");
71006
+ ResumeProducerPrepMs2 = SemanticConvention4("workflow.resume.phase.producer_prep_ms");
71007
+ ResumeQueueDeliveryMs2 = SemanticConvention4("workflow.resume.phase.queue_delivery_ms");
71008
+ ResumeSetupMs2 = SemanticConvention4("workflow.resume.phase.resume_setup_ms");
71009
+ ResumeReplayMs2 = SemanticConvention4("workflow.resume.phase.replay_ms");
71010
+ ResumeStepDispatchMs2 = SemanticConvention4("workflow.resume.phase.step_dispatch_ms");
71011
+ ResumeStepClaimMs2 = SemanticConvention4("workflow.resume.phase.step_claim_ms");
71012
+ ResumeStepPrepareMs2 = SemanticConvention4("workflow.resume.phase.step_prepare_ms");
71013
+ ResumeTrigger2 = SemanticConvention4("workflow.resume.trigger");
71014
+ ResumeStrategy2 = SemanticConvention4("workflow.resume.strategy");
71015
+ ResumeSetupSource2 = SemanticConvention4("workflow.resume.setup_source");
71016
+ ResumeStepExecution2 = SemanticConvention4("workflow.resume.step_execution");
70740
71017
  WebhookHandlersTriggered2 = SemanticConvention4("webhook.handlers.triggered");
70741
71018
  WorkflowSuspensionState2 = SemanticConvention4("workflow.suspension.state");
70742
71019
  WorkflowSuspensionHookCount2 = SemanticConvention4("workflow.suspension.hook_count");
@@ -71246,7 +71523,7 @@ var init_private2 = __esm({
71246
71523
  __name(getBuiltinResponseStepAlias2, "getBuiltinResponseStepAlias");
71247
71524
  __name(getStepFunction2, "getStepFunction");
71248
71525
  DEFER_BEHIND = {
71249
- hook: ["wait", "step"],
71526
+ hook: ["hook", "wait", "step"],
71250
71527
  wait: ["hook", "step"],
71251
71528
  step: ["wait", "hook", "step"]
71252
71529
  };
@@ -73668,7 +73945,7 @@ function getReviversForMode2(mode, global2 = globalThis, extraRevivers) {
73668
73945
  }
73669
73946
  return base;
73670
73947
  }
73671
- var encoder2, decoder3, devalueCodec2;
73948
+ var encoder2, decoder3, MAX_SPARSE_ARRAY_LENGTH2, parseOptions2, devalueCodec2;
73672
73949
  var init_codec_devalue2 = __esm({
73673
73950
  "../core/dist/serialization/codec-devalue.js"() {
73674
73951
  "use strict";
@@ -73680,6 +73957,17 @@ var init_codec_devalue2 = __esm({
73680
73957
  init_types3();
73681
73958
  encoder2 = new TextEncoder();
73682
73959
  decoder3 = new TextDecoder();
73960
+ MAX_SPARSE_ARRAY_LENGTH2 = 1e5;
73961
+ parseOptions2 = {
73962
+ operations: {
73963
+ createSparseArray(length) {
73964
+ if (length > MAX_SPARSE_ARRAY_LENGTH2) {
73965
+ throw new RangeError(`Sparse array length ${length} exceeds the maximum of ${MAX_SPARSE_ARRAY_LENGTH2}`);
73966
+ }
73967
+ return default_parse_operations2.createSparseArray(length);
73968
+ }
73969
+ }
73970
+ };
73683
73971
  __name(getReducersForMode2, "getReducersForMode");
73684
73972
  __name(getReviversForMode2, "getReviversForMode");
73685
73973
  devalueCodec2 = {
@@ -73692,11 +73980,11 @@ var init_codec_devalue2 = __esm({
73692
73980
  deserialize(data, mode, options) {
73693
73981
  const revivers = getReviversForMode2(mode, options?.global, options?.extraRevivers);
73694
73982
  const str = decoder3.decode(data);
73695
- return parse6(str, revivers);
73983
+ return parse6(str, revivers, parseOptions2);
73696
73984
  },
73697
73985
  deserializeLegacy(data, mode, options) {
73698
73986
  const revivers = getReviversForMode2(mode, options?.global, options?.extraRevivers);
73699
- return unflatten2(data, revivers);
73987
+ return unflatten2(data, revivers, parseOptions2);
73700
73988
  }
73701
73989
  };
73702
73990
  }
@@ -74295,8 +74583,17 @@ var init_events_consumer2 = __esm({
74295
74583
  * rather than parked for a consumer that cannot exist.
74296
74584
  */
74297
74585
  resolved = /* @__PURE__ */ new Set();
74586
+ /**
74587
+ * `<class>:<correlationId>` for every event class the walk has already
74588
+ * consumed, mapped to the event type that recorded it. The type is kept so a
74589
+ * repeat that decided the same class *differently* (a `step_failed` behind a
74590
+ * `step_completed`) can be reported as more than a re-commit. See
74591
+ * {@link EventsConsumer.firstEventTypeOfClass}.
74592
+ */
74593
+ seenEventClasses = /* @__PURE__ */ new Map();
74298
74594
  onConsumedEvent;
74299
74595
  onUnconsumedEvent;
74596
+ onDuplicateEvent;
74300
74597
  getPromiseQueue;
74301
74598
  isDeliveryIdle;
74302
74599
  pendingUnconsumedCheck = null;
@@ -74307,6 +74604,7 @@ var init_events_consumer2 = __esm({
74307
74604
  this.eventIndex = 0;
74308
74605
  this.onConsumedEvent = options.onConsumedEvent;
74309
74606
  this.onUnconsumedEvent = options.onUnconsumedEvent;
74607
+ this.onDuplicateEvent = options.onDuplicateEvent;
74310
74608
  this.getPromiseQueue = options.getPromiseQueue;
74311
74609
  this.isDeliveryIdle = options.isDeliveryIdle;
74312
74610
  }
@@ -74394,6 +74692,11 @@ var init_events_consumer2 = __esm({
74394
74692
  return;
74395
74693
  }
74396
74694
  if (!consumed) {
74695
+ const firstType = this.firstEventTypeOfClass(currentEvent);
74696
+ if (firstType !== void 0) {
74697
+ this.skipDuplicateEvent(currentEvent, firstType);
74698
+ continue;
74699
+ }
74397
74700
  this.scheduleUnconsumedCheck(currentEvent, true);
74398
74701
  return;
74399
74702
  }
@@ -74420,6 +74723,7 @@ var init_events_consumer2 = __esm({
74420
74723
  if (currentEvent.correlationId && ONE_SHOT_EVENT_TYPES.has(currentEvent.eventType)) {
74421
74724
  this.resolved.add(resolutionKey(currentEvent.eventType, currentEvent.correlationId));
74422
74725
  }
74726
+ this.recordEventClass(currentEvent);
74423
74727
  this.notifyConsumedEvent(currentEvent);
74424
74728
  }
74425
74729
  if (handled === EventConsumerResult2.Finished) {
@@ -74482,6 +74786,93 @@ var init_events_consumer2 = __esm({
74482
74786
  });
74483
74787
  return true;
74484
74788
  }
74789
+ /**
74790
+ * The key `event`'s class is tracked under, or `undefined` for the event
74791
+ * types that belong to no class (`hook_received`, `hook_conflict`,
74792
+ * `attr_set`, `run_created`) and are therefore never skipped.
74793
+ *
74794
+ * Run events carry no correlation id. They are classes of the run itself, so
74795
+ * they all key off the same bucket.
74796
+ */
74797
+ eventClassKey(event) {
74798
+ const eventClass = entityEventClass(event.eventType);
74799
+ return eventClass === void 0 ? void 0 : `${eventClass}:${event.correlationId}`;
74800
+ }
74801
+ /**
74802
+ * Remembers that `event`'s class is now decided for its entity, if the type
74803
+ * belongs to a class. First writer wins: the recorded type is the one the
74804
+ * workflow observed, and a later repeat is measured against it.
74805
+ */
74806
+ recordEventClass(event) {
74807
+ const key = this.eventClassKey(event);
74808
+ if (key !== void 0 && !this.seenEventClasses.has(key)) {
74809
+ this.seenEventClasses.set(key, event.eventType);
74810
+ }
74811
+ }
74812
+ /**
74813
+ * The type that already decided `event`'s class for the same entity, or
74814
+ * `undefined` when nothing has: a second `step_created` for one step, a
74815
+ * second terminal outcome, a second `step_started` after the step's result is
74816
+ * already in the log.
74817
+ *
74818
+ * Such an event is committed but inert. Concurrent replays write into one
74819
+ * log without a currency guard, so a replay working from a prefix that
74820
+ * predates another replay's write can commit its own copy of work the log
74821
+ * already records. That copy cannot change what the workflow observed: the
74822
+ * outcome was decided by the first event of the class and every later replay
74823
+ * reads that same event at the same log position, so ignoring the straggler
74824
+ * is deterministic across replays.
74825
+ *
74826
+ * Classes are tracked separately, so passing one does not suppress another.
74827
+ * A step whose result is in the log still reaches its `step_created` and
74828
+ * `step_started` consumers if it has yet to see those classes.
74829
+ *
74830
+ * Consulted only after every registered callback has declined the event, so
74831
+ * it can never take an event a consumer wanted. A retry's `step_started` is
74832
+ * claimed by the step's live consumer and counts as an attempt exactly as
74833
+ * before, and a second `step_created` reaching a step that has not finished
74834
+ * is likewise consumed rather than skipped; only the copies nobody claims are
74835
+ * skipped.
74836
+ *
74837
+ * Unlike the divergence report, this does *not* wait out the deferred window
74838
+ * first, and it does not need to. The window buys time for a consumer that
74839
+ * has yet to register, and no such consumer can want this event: the class
74840
+ * was recorded by a consumption in this same replay, which means the entity's
74841
+ * consumer was registered and took an event of this class, and correlation
74842
+ * ids are minted from a monotonic ULID per body position, so nothing later in
74843
+ * the body registers a second consumer under this id. Waiting would cost
74844
+ * `getDeferredCheckDelayMs()` per straggler per replay for information that
74845
+ * cannot arrive — 0.75% of production runs carry at least one straggler, and
74846
+ * the p99 among those carries 155.
74847
+ *
74848
+ * The invariant to preserve if hook identity ever becomes caller-supplied
74849
+ * (an idempotency key rather than a minted id): two `createHook` calls in one
74850
+ * body could then share a correlation id, and the second consumer's
74851
+ * `hook_created` would be a repeat of a class this replay already recorded.
74852
+ * That would make skipping wrong for `hook_created`, and is the reason the
74853
+ * class map lives next to the event types rather than being inferred.
74854
+ */
74855
+ firstEventTypeOfClass(event) {
74856
+ const key = this.eventClassKey(event);
74857
+ return key === void 0 ? void 0 : this.seenEventClasses.get(key);
74858
+ }
74859
+ /** Steps the walk over a repeat of an already-consumed class. */
74860
+ skipDuplicateEvent(event, firstType) {
74861
+ this.eventIndex++;
74862
+ eventsLogger2.debug("Skipping event that repeats a class already in the log", {
74863
+ eventId: event.eventId,
74864
+ eventType: event.eventType,
74865
+ firstEventType: firstType,
74866
+ correlationId: event.correlationId
74867
+ });
74868
+ try {
74869
+ this.onDuplicateEvent?.(event, firstType);
74870
+ } catch (error95) {
74871
+ eventsLogger2.error("onDuplicateEvent callback threw an error", {
74872
+ error: error95
74873
+ });
74874
+ }
74875
+ }
74485
74876
  handleEndOfLog() {
74486
74877
  if (this.parked.length === 0) {
74487
74878
  return;
@@ -74514,20 +74905,39 @@ var init_events_consumer2 = __esm({
74514
74905
  return;
74515
74906
  }
74516
74907
  this.pendingUnconsumedCheck = null;
74517
- if (mayPark) {
74518
- if (this.events[this.eventIndex] !== currentEvent) {
74519
- return;
74520
- }
74521
- if (this.park(currentEvent)) {
74522
- this.consume();
74523
- return;
74524
- }
74525
- }
74526
- this.onUnconsumedEvent(currentEvent);
74908
+ this.resolveUnconsumedEvent(currentEvent, mayPark);
74527
74909
  }, getDeferredCheckDelayMs());
74528
74910
  });
74529
74911
  });
74530
74912
  }
74913
+ /**
74914
+ * Decide what a still-unconsumed event is, now that the promise queue has
74915
+ * drained and the delivery gate says the VM is not mid-reaction.
74916
+ *
74917
+ * `mayPark` is false only for the end-of-log recheck of an event {@link park}
74918
+ * already holds. Nothing in the first branch applies to one of those: it is
74919
+ * not the event at the cursor, so the identity guard is not meaningful, and
74920
+ * it is parked already.
74921
+ *
74922
+ * A duplicate class never arrives here. {@link consume} steps over one in the
74923
+ * pass that offered it, before this check is ever scheduled, and a class
74924
+ * recorded while the check was in flight can only have been recorded by a
74925
+ * consumption inside {@link consume}, whose next pass re-offers this event
74926
+ * and steps over it there — leaving the identity guard above to drop the
74927
+ * in-flight check.
74928
+ */
74929
+ resolveUnconsumedEvent(currentEvent, mayPark) {
74930
+ if (mayPark) {
74931
+ if (this.events[this.eventIndex] !== currentEvent) {
74932
+ return;
74933
+ }
74934
+ if (this.park(currentEvent)) {
74935
+ this.consume();
74936
+ return;
74937
+ }
74938
+ }
74939
+ this.onUnconsumedEvent(currentEvent);
74940
+ }
74531
74941
  /**
74532
74942
  * Run `fn` once no data delivery is in flight, polling the way
74533
74943
  * `scheduleWhenIdle` does: let the promise queue drain, re-check a timer
@@ -74945,7 +75355,7 @@ var require_parse_options2 = __commonJS({
74945
75355
  "use strict";
74946
75356
  var looseOption = Object.freeze({ loose: true });
74947
75357
  var emptyOpts = Object.freeze({});
74948
- var parseOptions = /* @__PURE__ */ __name((options) => {
75358
+ var parseOptions3 = /* @__PURE__ */ __name((options) => {
74949
75359
  if (!options) {
74950
75360
  return emptyOpts;
74951
75361
  }
@@ -74954,7 +75364,7 @@ var require_parse_options2 = __commonJS({
74954
75364
  }
74955
75365
  return options;
74956
75366
  }, "parseOptions");
74957
- module.exports = parseOptions;
75367
+ module.exports = parseOptions3;
74958
75368
  }
74959
75369
  });
74960
75370
 
@@ -74990,14 +75400,14 @@ var require_semver4 = __commonJS({
74990
75400
  var debug = require_debug2();
74991
75401
  var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants9();
74992
75402
  var { safeRe: re2, t } = require_re2();
74993
- var parseOptions = require_parse_options2();
75403
+ var parseOptions3 = require_parse_options2();
74994
75404
  var { compareIdentifiers } = require_identifiers2();
74995
75405
  var SemVer = class _SemVer {
74996
75406
  static {
74997
75407
  __name(this, "SemVer");
74998
75408
  }
74999
75409
  constructor(version6, options) {
75000
- options = parseOptions(options);
75410
+ options = parseOptions3(options);
75001
75411
  if (version6 instanceof _SemVer) {
75002
75412
  if (version6.loose === !!options.loose && version6.includePrerelease === !!options.includePrerelease) {
75003
75413
  return version6;
@@ -75695,7 +76105,7 @@ var require_range2 = __commonJS({
75695
76105
  __name(this, "Range");
75696
76106
  }
75697
76107
  constructor(range2, options) {
75698
- options = parseOptions(options);
76108
+ options = parseOptions3(options);
75699
76109
  if (range2 instanceof _Range) {
75700
76110
  if (range2.loose === !!options.loose && range2.includePrerelease === !!options.includePrerelease) {
75701
76111
  return range2;
@@ -75834,7 +76244,7 @@ var require_range2 = __commonJS({
75834
76244
  module.exports = Range;
75835
76245
  var LRU = require_lrucache2();
75836
76246
  var cache = new LRU();
75837
- var parseOptions = require_parse_options2();
76247
+ var parseOptions3 = require_parse_options2();
75838
76248
  var Comparator = require_comparator2();
75839
76249
  var debug = require_debug2();
75840
76250
  var SemVer = require_semver4();
@@ -76078,7 +76488,7 @@ var require_comparator2 = __commonJS({
76078
76488
  return ANY;
76079
76489
  }
76080
76490
  constructor(comp, options) {
76081
- options = parseOptions(options);
76491
+ options = parseOptions3(options);
76082
76492
  if (comp instanceof _Comparator) {
76083
76493
  if (comp.loose === !!options.loose) {
76084
76494
  return comp;
@@ -76146,7 +76556,7 @@ var require_comparator2 = __commonJS({
76146
76556
  }
76147
76557
  return new Range(this.value, options).test(comp.semver);
76148
76558
  }
76149
- options = parseOptions(options);
76559
+ options = parseOptions3(options);
76150
76560
  if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) {
76151
76561
  return false;
76152
76562
  }
@@ -76172,7 +76582,7 @@ var require_comparator2 = __commonJS({
76172
76582
  }
76173
76583
  };
76174
76584
  module.exports = Comparator;
76175
- var parseOptions = require_parse_options2();
76585
+ var parseOptions3 = require_parse_options2();
76176
76586
  var { safeRe: re2, t } = require_re2();
76177
76587
  var cmp = require_cmp2();
76178
76588
  var debug = require_debug2();
@@ -76828,7 +77238,7 @@ var version5;
76828
77238
  var init_version4 = __esm({
76829
77239
  "../core/dist/version.js"() {
76830
77240
  "use strict";
76831
- version5 = "5.0.0-beta.41";
77241
+ version5 = "5.0.0-beta.42";
76832
77242
  }
76833
77243
  });
76834
77244
 
@@ -77008,48 +77418,36 @@ async function loadWorkflowRunEvents(runId, afterCursor) {
77008
77418
  return { events: loadedEvents, cursor };
77009
77419
  });
77010
77420
  }
77011
- function isPreconditionGuardEnabled() {
77012
- return process.env.WORKFLOW_PRECONDITION_GUARD !== "0";
77013
- }
77014
77421
  function isSlotGapCheckEnabled() {
77015
77422
  return process.env.WORKFLOW_SLOT_GAP_CHECK !== "0";
77016
77423
  }
77017
- function latestEventStateUpdatedAt(events) {
77018
- let latest;
77019
- for (const event of events) {
77020
- if (latest === void 0 || event.eventId > latest) {
77021
- latest = event.eventId;
77022
- }
77023
- }
77024
- if (latest === void 0) {
77025
- return void 0;
77026
- }
77027
- const eventId = latest;
77028
- const underscore = eventId.lastIndexOf("_");
77029
- const rawUlid = underscore === -1 ? eventId : eventId.slice(underscore + 1);
77030
- const time5 = ulidToDate(rawUlid)?.getTime();
77031
- if (time5 === void 0) {
77032
- runtimeLogger2.debug("Precondition guard: latest event id is not a decodable ULID; sending no snapshot", { eventId });
77033
- return void 0;
77034
- }
77035
- return time5;
77036
- }
77037
77424
  function mergeReportedEvents(target2, events) {
77038
77425
  const before = target2.length;
77039
77426
  appendUniqueEvents(target2, events);
77040
77427
  const added = target2.length - before;
77041
- if (added > 0 && maxEventSlot(target2) !== void 0) {
77428
+ if (added > 0) {
77042
77429
  target2.sort((a, b) => a.eventId < b.eventId ? -1 : a.eventId > b.eventId ? 1 : 0);
77043
77430
  }
77044
77431
  return added;
77045
77432
  }
77433
+ function absorbSkippedSlotReport(target2, result2) {
77434
+ const offered = result2.events?.length ?? 0;
77435
+ if (offered === 0) {
77436
+ return { added: 0, offered: 0, truncated: false };
77437
+ }
77438
+ if (result2.hasMore === true) {
77439
+ return { added: 0, offered, truncated: true };
77440
+ }
77441
+ return {
77442
+ added: mergeReportedEvents(target2, result2.events ?? []),
77443
+ offered,
77444
+ truncated: false
77445
+ };
77446
+ }
77046
77447
  function maxEventSlot(events) {
77047
77448
  let max;
77048
77449
  for (const event of events) {
77049
- const slot = eventIdToSlot(event.eventId);
77050
- if (slot === null) {
77051
- return void 0;
77052
- }
77450
+ const slot = requireEventSlot(event.eventId);
77053
77451
  if (max === void 0 || slot > max) {
77054
77452
  max = slot;
77055
77453
  }
@@ -77060,10 +77458,7 @@ function findEventSlotGap(events) {
77060
77458
  const occupied = /* @__PURE__ */ new Set();
77061
77459
  let maxSlot = 0;
77062
77460
  for (const event of events) {
77063
- const slot = eventIdToSlot(event.eventId);
77064
- if (slot === null) {
77065
- return void 0;
77066
- }
77461
+ const slot = requireEventSlot(event.eventId);
77067
77462
  occupied.add(slot);
77068
77463
  if (slot > maxSlot) {
77069
77464
  maxSlot = slot;
@@ -77099,23 +77494,9 @@ async function settleEventSlotGap(runId, loaded) {
77099
77494
  }
77100
77495
  return { log, gap };
77101
77496
  }
77102
- function preconditionSnapshotParams(events, cursor) {
77103
- if (!isPreconditionGuardEnabled()) {
77104
- return {};
77105
- }
77497
+ function slotSnapshotParams(events) {
77106
77498
  const eventCount = maxEventSlot(events);
77107
- if (eventCount !== void 0) {
77108
- return { eventCount };
77109
- }
77110
- const stateUpdatedAt = latestEventStateUpdatedAt(events);
77111
- if (stateUpdatedAt === void 0) {
77112
- return {};
77113
- }
77114
- return {
77115
- stateUpdatedAt,
77116
- stateEventCount: events.length,
77117
- ...cursor ? { stateCursor: cursor } : {}
77118
- };
77499
+ return eventCount === void 0 ? {} : { eventCount };
77119
77500
  }
77120
77501
  function preconditionEventDelta(error95, runId) {
77121
77502
  if (!PreconditionFailedError.is(error95)) {
@@ -77166,6 +77547,17 @@ function withHealthCheck(handler, worldSpecVersion) {
77166
77547
  return await handler(req);
77167
77548
  };
77168
77549
  }
77550
+ function fnv1a32Hex(value) {
77551
+ let hash3 = 2166136261;
77552
+ for (let i = 0; i < value.length; i++) {
77553
+ hash3 ^= value.charCodeAt(i);
77554
+ hash3 = Math.imul(hash3, 16777619);
77555
+ }
77556
+ return (hash3 >>> 0).toString(16).padStart(8, "0");
77557
+ }
77558
+ function stepDispatchIdempotencyKey(correlationId, stepName) {
77559
+ return `${correlationId}:${fnv1a32Hex(stepName)}`;
77560
+ }
77169
77561
  async function queueMessage(world, ...args) {
77170
77562
  const queueName = args[0];
77171
77563
  await trace5("queue.publish", {
@@ -77237,16 +77629,15 @@ var init_helpers3 = __esm({
77237
77629
  __name(assertEventPaginationProgress, "assertEventPaginationProgress");
77238
77630
  __name(shouldRetryWithoutEventCursor, "shouldRetryWithoutEventCursor");
77239
77631
  __name(loadWorkflowRunEvents, "loadWorkflowRunEvents");
77240
- __name(isPreconditionGuardEnabled, "isPreconditionGuardEnabled");
77241
77632
  __name(isSlotGapCheckEnabled, "isSlotGapCheckEnabled");
77242
- __name(latestEventStateUpdatedAt, "latestEventStateUpdatedAt");
77243
77633
  __name(mergeReportedEvents, "mergeReportedEvents");
77634
+ __name(absorbSkippedSlotReport, "absorbSkippedSlotReport");
77244
77635
  __name(maxEventSlot, "maxEventSlot");
77245
77636
  __name(findEventSlotGap, "findEventSlotGap");
77246
77637
  SLOT_GAP_RECHECK_ATTEMPTS = 3;
77247
77638
  SLOT_GAP_RECHECK_BASE_DELAY_MS = 25;
77248
77639
  __name(settleEventSlotGap, "settleEventSlotGap");
77249
- __name(preconditionSnapshotParams, "preconditionSnapshotParams");
77640
+ __name(slotSnapshotParams, "slotSnapshotParams");
77250
77641
  __name(preconditionEventDelta, "preconditionEventDelta");
77251
77642
  HEALTH_CHECK_CORS_HEADERS = {
77252
77643
  "Access-Control-Allow-Origin": "*",
@@ -77254,6 +77645,8 @@ var init_helpers3 = __esm({
77254
77645
  "Access-Control-Allow-Headers": "Content-Type"
77255
77646
  };
77256
77647
  __name(withHealthCheck, "withHealthCheck");
77648
+ __name(fnv1a32Hex, "fnv1a32Hex");
77649
+ __name(stepDispatchIdempotencyKey, "stepDispatchIdempotencyKey");
77257
77650
  __name(queueMessage, "queueMessage");
77258
77651
  __name(getQueueOverhead, "getQueueOverhead");
77259
77652
  __name(memoizeEncryptionKey, "memoizeEncryptionKey");
@@ -77359,9 +77752,9 @@ async function getHookByToken3(token) {
77359
77752
  return hook;
77360
77753
  }
77361
77754
  async function resumeHook2(tokenOrHook, payload, encryptionKeyOverride) {
77362
- return resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, false);
77755
+ return resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, false, Date.now());
77363
77756
  }
77364
- async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp) {
77757
+ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs) {
77365
77758
  return await waitedUntil2(() => {
77366
77759
  return trace5("hook.resume", async (span) => {
77367
77760
  const world = await getWorldLazy2();
@@ -77449,23 +77842,24 @@ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hook
77449
77842
  }
77450
77843
  throw err;
77451
77844
  }
77845
+ const queuePublishRequestedAtMs = Date.now();
77452
77846
  await world.queue(queueName, {
77453
77847
  runId: hook.runId,
77454
- traceCarrier: resumeContext.traceCarrier ?? void 0
77848
+ traceCarrier: resumeContext.traceCarrier ?? void 0,
77849
+ hookResumeTiming: {
77850
+ resumeRequestedAtMs,
77851
+ queuePublishRequestedAtMs,
77852
+ strategy: "sequential"
77853
+ }
77455
77854
  }, queueOptions);
77456
77855
  return hook;
77457
77856
  }
77458
77857
  const resumeId = generateResumeId2();
77459
77858
  const payloadDigest = await computeResumePayloadDigest2(dehydratedPayload);
77460
77859
  span?.setAttributes({ "workflow.hook.resume_id": resumeId });
77461
- const [eventResult, queueResult] = await Promise.allSettled([
77462
- world.events.create(hook.runId, {
77463
- eventType: "hook_received",
77464
- specVersion: SPEC_VERSION_CURRENT2,
77465
- correlationId: hook.hookId,
77466
- eventData
77467
- }, { v1Compat, resumeId, resumePayloadDigest: payloadDigest }),
77468
- world.queue(queueName, {
77860
+ const publishInvocation = /* @__PURE__ */ __name(() => {
77861
+ const queuePublishRequestedAtMs = Date.now();
77862
+ return world.queue(queueName, {
77469
77863
  runId: hook.runId,
77470
77864
  traceCarrier: resumeContext.traceCarrier ?? void 0,
77471
77865
  hookInput: {
@@ -77478,8 +77872,22 @@ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hook
77478
77872
  // check: lets a misrouted delivery re-route before its
77479
77873
  // hoisted hook_received write instead of after.
77480
77874
  deploymentId: resumeContext.deploymentId
77875
+ },
77876
+ hookResumeTiming: {
77877
+ resumeRequestedAtMs,
77878
+ queuePublishRequestedAtMs,
77879
+ strategy: "parallel"
77481
77880
  }
77482
- }, queueOptions)
77881
+ }, queueOptions);
77882
+ }, "publishInvocation");
77883
+ const [eventResult, queueResult] = await Promise.allSettled([
77884
+ world.events.create(hook.runId, {
77885
+ eventType: "hook_received",
77886
+ specVersion: SPEC_VERSION_CURRENT2,
77887
+ correlationId: hook.hookId,
77888
+ eventData
77889
+ }, { v1Compat, resumeId, resumePayloadDigest: payloadDigest }),
77890
+ publishInvocation()
77483
77891
  ]);
77484
77892
  if (queueResult.status === "rejected") {
77485
77893
  throw queueResult.reason;
@@ -77519,6 +77927,7 @@ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hook
77519
77927
  });
77520
77928
  }
77521
77929
  async function resumeWebhook2(token, request) {
77930
+ const resumeRequestedAtMs = Date.now();
77522
77931
  const { hook, encryptionKey } = await getHookByTokenWithKey2(token);
77523
77932
  if (hook.isWebhook === false) {
77524
77933
  throw new HookNotFoundError2(token);
@@ -77538,7 +77947,7 @@ async function resumeWebhook2(token, request) {
77538
77947
  } else {
77539
77948
  response = new Response(null, { status: 202 });
77540
77949
  }
77541
- await resumeHookImpl2(hook, request, encryptionKey, true);
77950
+ await resumeHookImpl2(hook, request, encryptionKey, true, resumeRequestedAtMs);
77542
77951
  if (responseReadable) {
77543
77952
  const reader = responseReadable.getReader();
77544
77953
  const chunk = await reader.read();
@@ -77903,7 +78312,9 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
77903
78312
  try {
77904
78313
  await connect2();
77905
78314
  return;
77906
- } catch {
78315
+ } catch (error95) {
78316
+ if (StreamExpiredError2.is(error95))
78317
+ throw error95;
77907
78318
  }
77908
78319
  }
77909
78320
  }
@@ -79598,6 +80009,9 @@ function getMaxInlineSteps() {
79598
80009
  }
79599
80010
  return parsed;
79600
80011
  }
80012
+ function isResilientStepDispatchEnabled() {
80013
+ return process.env.WORKFLOW_RESILIENT_STEP_DISPATCH === "1";
80014
+ }
79601
80015
  function getMaxEventsOverride() {
79602
80016
  const raw = process.env.WORKFLOW_MAX_EVENTS_OVERRIDE;
79603
80017
  if (!raw)
@@ -79666,7 +80080,7 @@ function getPreconditionReinvokeDelaySeconds() {
79666
80080
  function getDeploymentMismatchMaxRetries() {
79667
80081
  return envNumber2("WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES", DEPLOYMENT_MISMATCH_MAX_RETRIES, { integer: true, min: 0 });
79668
80082
  }
79669
- var MAX_QUEUE_DELIVERIES, REPLAY_TIMEOUT_MS, MIN_REPLAY_TIMEOUT_MS, MAX_REPLAY_TIMEOUT_MS, warnedReplayTimeoutValues, REPLAY_TIMEOUT_MAX_RETRIES, MAX_INLINE_STEPS, MIN_MAX_INLINE_STEPS, MAX_MAX_INLINE_STEPS, warnedMaxInlineStepsValues, warnedMaxEventsValues, INLINE_OWNERSHIP_LEASE_SECONDS, MAX_INLINE_OWNERSHIP_LEASE_SECONDS, REPLAY_DIVERGENCE_MAX_RETRIES, PRECONDITION_MAX_INPROCESS_RESTARTS, PRECONDITION_MAX_REINVOCATIONS, PRECONDITION_REINVOKE_DELAY_SECONDS, DEPLOYMENT_MISMATCH_MAX_RETRIES;
80083
+ var MAX_QUEUE_DELIVERIES, REPLAY_TIMEOUT_MS, MIN_REPLAY_TIMEOUT_MS, MAX_REPLAY_TIMEOUT_MS, warnedReplayTimeoutValues, REPLAY_TIMEOUT_MAX_RETRIES, MAX_INLINE_STEPS, MIN_MAX_INLINE_STEPS, MAX_MAX_INLINE_STEPS, warnedMaxInlineStepsValues, MAX_RESILIENT_STEP_INPUT_BYTES, warnedMaxEventsValues, INLINE_OWNERSHIP_LEASE_SECONDS, MAX_INLINE_OWNERSHIP_LEASE_SECONDS, REPLAY_DIVERGENCE_MAX_RETRIES, PRECONDITION_MAX_INPROCESS_RESTARTS, PRECONDITION_MAX_REINVOCATIONS, PRECONDITION_REINVOKE_DELAY_SECONDS, DEPLOYMENT_MISMATCH_MAX_RETRIES;
79670
80084
  var init_constants3 = __esm({
79671
80085
  "../core/dist/runtime/constants.js"() {
79672
80086
  "use strict";
@@ -79687,6 +80101,8 @@ var init_constants3 = __esm({
79687
80101
  MAX_MAX_INLINE_STEPS = 16;
79688
80102
  warnedMaxInlineStepsValues = /* @__PURE__ */ new Set();
79689
80103
  __name(getMaxInlineSteps, "getMaxInlineSteps");
80104
+ MAX_RESILIENT_STEP_INPUT_BYTES = 128 * 1024;
80105
+ __name(isResilientStepDispatchEnabled, "isResilientStepDispatchEnabled");
79690
80106
  warnedMaxEventsValues = /* @__PURE__ */ new Set();
79691
80107
  __name(getMaxEventsOverride, "getMaxEventsOverride");
79692
80108
  __name(isOptimisticInlineStartEnabled, "isOptimisticInlineStartEnabled");
@@ -79713,7 +80129,7 @@ var init_constants3 = __esm({
79713
80129
 
79714
80130
  // ../core/dist/runtime/replay-budget.js
79715
80131
  async function handleReplayBudgetExhausted(args) {
79716
- const { runId, workflowName, requestId, attempt, limitMs } = args;
80132
+ const { runId, workflowName, requestId, attempt, limitMs, slotSnapshot } = args;
79717
80133
  const runLogger = runtimeLogger2.forRun(runId, workflowName);
79718
80134
  const maxRetries = getReplayTimeoutMaxRetries();
79719
80135
  if (attempt <= maxRetries) {
@@ -79742,7 +80158,7 @@ async function handleReplayBudgetExhausted(args) {
79742
80158
  error: await dehydrateRunError(timeoutErr, runId, await getEncryptionKey()),
79743
80159
  errorCode: RUN_ERROR_CODES2.REPLAY_TIMEOUT
79744
80160
  }
79745
- }, { requestId });
80161
+ }, { requestId, ...slotSnapshot });
79746
80162
  }
79747
80163
  var ReplayBudget, ReplayTimeoutRetryError;
79748
80164
  var init_replay_budget = __esm({
@@ -79886,6 +80302,110 @@ var init_replay_recovery_reporter = __esm({
79886
80302
  }
79887
80303
  });
79888
80304
 
80305
+ // ../core/dist/runtime/resume-latency.js
80306
+ function resumeTrackingFromMessage(timing, stepExecution) {
80307
+ if (!timing)
80308
+ return void 0;
80309
+ if (!Number.isFinite(timing.resumeRequestedAtMs) || !Number.isFinite(timing.queuePublishRequestedAtMs)) {
80310
+ return void 0;
80311
+ }
80312
+ return {
80313
+ trigger: "hook",
80314
+ ...timing.strategy === "parallel" || timing.strategy === "sequential" ? { strategy: timing.strategy } : {},
80315
+ resumeRequestedAtMs: timing.resumeRequestedAtMs,
80316
+ queuePublishRequestedAtMs: timing.queuePublishRequestedAtMs,
80317
+ // A dispatched step reads the resuming invocation's boundaries off the
80318
+ // message; an inline one has them stamped locally by the caller, which
80319
+ // overwrites this placeholder immediately after construction.
80320
+ consumerStartedAtMs: timing.consumerStartedAtMs ?? Number.NaN,
80321
+ ...timing.replayStartedAtMs !== void 0 ? { replayStartedAtMs: timing.replayStartedAtMs } : {},
80322
+ ...timing.nextStepEncounteredAtMs !== void 0 ? { nextStepEncounteredAtMs: timing.nextStepEncounteredAtMs } : {},
80323
+ ...timing.setupSource === "hook_preload" || timing.setupSource === "run_started" || timing.setupSource === "event_load" ? { setupSource: timing.setupSource } : {},
80324
+ stepExecution
80325
+ };
80326
+ }
80327
+ function resumeTimingForMessage(tracking) {
80328
+ if (!tracking)
80329
+ return void 0;
80330
+ if (!Number.isFinite(tracking.consumerStartedAtMs))
80331
+ return void 0;
80332
+ return {
80333
+ resumeRequestedAtMs: tracking.resumeRequestedAtMs,
80334
+ queuePublishRequestedAtMs: tracking.queuePublishRequestedAtMs,
80335
+ ...tracking.strategy !== void 0 ? { strategy: tracking.strategy } : {},
80336
+ consumerStartedAtMs: tracking.consumerStartedAtMs,
80337
+ ...tracking.replayStartedAtMs !== void 0 ? { replayStartedAtMs: tracking.replayStartedAtMs } : {},
80338
+ ...tracking.nextStepEncounteredAtMs !== void 0 ? { nextStepEncounteredAtMs: tracking.nextStepEncounteredAtMs } : {},
80339
+ ...tracking.setupSource !== void 0 ? { setupSource: tracking.setupSource } : {}
80340
+ };
80341
+ }
80342
+ function validateBoundaries(b) {
80343
+ const ordered = [
80344
+ b.resumeRequestedAtMs,
80345
+ b.queuePublishRequestedAtMs,
80346
+ b.consumerStartedAtMs,
80347
+ b.replayStartedAtMs,
80348
+ b.nextStepEncounteredAtMs,
80349
+ b.stepClaimStartedAtMs,
80350
+ ...b.stepClaimCompletedAtMs !== void 0 ? [b.stepClaimCompletedAtMs] : [],
80351
+ b.stepCodeStartedAtMs
80352
+ ];
80353
+ for (const value of ordered) {
80354
+ if (typeof value !== "number" || !Number.isFinite(value))
80355
+ return void 0;
80356
+ }
80357
+ for (let i = 1; i < ordered.length; i++) {
80358
+ if (ordered[i] < ordered[i - 1])
80359
+ return void 0;
80360
+ }
80361
+ return ordered;
80362
+ }
80363
+ function computeResumeTtrAttributes(params) {
80364
+ const { tracking } = params;
80365
+ if (!tracking || params.attempt !== 1)
80366
+ return void 0;
80367
+ if (tracking.replayStartedAtMs === void 0 || tracking.nextStepEncounteredAtMs === void 0 || params.stepClaimStartedAtMs === void 0) {
80368
+ return void 0;
80369
+ }
80370
+ const boundaries = {
80371
+ resumeRequestedAtMs: tracking.resumeRequestedAtMs,
80372
+ queuePublishRequestedAtMs: tracking.queuePublishRequestedAtMs,
80373
+ consumerStartedAtMs: tracking.consumerStartedAtMs,
80374
+ replayStartedAtMs: tracking.replayStartedAtMs,
80375
+ nextStepEncounteredAtMs: tracking.nextStepEncounteredAtMs,
80376
+ stepClaimStartedAtMs: params.stepClaimStartedAtMs,
80377
+ stepClaimCompletedAtMs: params.stepClaimCompletedAtMs,
80378
+ stepCodeStartedAtMs: params.stepCodeStartedAtMs
80379
+ };
80380
+ if (!validateBoundaries(boundaries))
80381
+ return void 0;
80382
+ const { resumeRequestedAtMs: t0, queuePublishRequestedAtMs: t1, consumerStartedAtMs: t2, replayStartedAtMs: t3, nextStepEncounteredAtMs: t4, stepClaimStartedAtMs: t5, stepClaimCompletedAtMs: t6, stepCodeStartedAtMs: t7 } = boundaries;
80383
+ return {
80384
+ ...ResumeTotalMs2(t7 - t0),
80385
+ ...ResumeProducerPrepMs2(t1 - t0),
80386
+ ...ResumeQueueDeliveryMs2(t2 - t1),
80387
+ ...ResumeSetupMs2(t3 - t2),
80388
+ ...ResumeReplayMs2(t4 - t3),
80389
+ ...ResumeStepDispatchMs2(t5 - t4),
80390
+ ...t6 !== void 0 ? ResumeStepClaimMs2(t6 - t5) : {},
80391
+ ...ResumeStepPrepareMs2(t7 - (t6 ?? t5)),
80392
+ ...ResumeTrigger2(tracking.trigger),
80393
+ ...tracking.strategy !== void 0 ? ResumeStrategy2(tracking.strategy) : {},
80394
+ ...tracking.setupSource !== void 0 ? ResumeSetupSource2(tracking.setupSource) : {},
80395
+ ...ResumeStepExecution2(tracking.stepExecution)
80396
+ };
80397
+ }
80398
+ var init_resume_latency = __esm({
80399
+ "../core/dist/runtime/resume-latency.js"() {
80400
+ "use strict";
80401
+ init_semantic_conventions2();
80402
+ __name(resumeTrackingFromMessage, "resumeTrackingFromMessage");
80403
+ __name(resumeTimingForMessage, "resumeTimingForMessage");
80404
+ __name(validateBoundaries, "validateBoundaries");
80405
+ __name(computeResumeTtrAttributes, "computeResumeTtrAttributes");
80406
+ }
80407
+ });
80408
+
79889
80409
  // ../core/dist/runtime/run-id-time.js
79890
80410
  function runIdCreatedAt(runId) {
79891
80411
  const ulidPart = runId.startsWith(RUN_ID_PREFIX2) ? runId.slice(RUN_ID_PREFIX2.length) : runId;
@@ -80159,7 +80679,30 @@ async function executeStep(params) {
80159
80679
  const isVercel = Boolean(process.env.VERCEL_URL);
80160
80680
  const compression = (params.runSpecVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2;
80161
80681
  const replayRecoveryReporter = params.replayRecoveryReporter ?? ReplayRecoveryReporter.inert();
80162
- const createEvent = /* @__PURE__ */ __name((data, eventParams) => replayRecoveryReporter.withEventCreate(eventParams, (p) => world.events.create(workflowRunId, data, p)), "createEvent");
80682
+ let knownSlot = params.slotSnapshot?.eventCount;
80683
+ const observeSlot = /* @__PURE__ */ __name((result2) => {
80684
+ if (knownSlot === void 0) {
80685
+ return;
80686
+ }
80687
+ const observed = [];
80688
+ if (result2.event) {
80689
+ observed.push(requireEventSlot(result2.event.eventId));
80690
+ }
80691
+ const reported = maxEventSlot(result2.events ?? []);
80692
+ if (reported !== void 0) {
80693
+ observed.push(reported);
80694
+ }
80695
+ for (const slot of observed) {
80696
+ if (slot > knownSlot) {
80697
+ knownSlot = slot;
80698
+ }
80699
+ }
80700
+ }, "observeSlot");
80701
+ const createEvent = /* @__PURE__ */ __name(async (data, eventParams) => {
80702
+ const result2 = await replayRecoveryReporter.withEventCreate(knownSlot === void 0 ? eventParams : { eventCount: knownSlot, ...eventParams }, (p) => world.events.create(workflowRunId, data, p));
80703
+ observeSlot(result2);
80704
+ return result2;
80705
+ }, "createEvent");
80163
80706
  const spanName = `step.execute ${stepDisplayName(stepName)}`;
80164
80707
  return trace5(spanName, {}, async (span) => {
80165
80708
  span?.setAttributes({
@@ -80316,12 +80859,10 @@ async function executeStep(params) {
80316
80859
  params.suppressOptimisticStart !== true && (isOptimisticInlineStartEnabled() || params.forceOptimisticStart === true && !isOptimisticInlineStartExplicitlyDisabled());
80317
80860
  let step;
80318
80861
  const startEventParams = {
80319
- computeInstanceId: COMPUTE_INSTANCE_ID,
80320
- // Spread as a unit: the three snapshot fields describe one snapshot and
80321
- // must travel together — see StepExecutorParams.preconditionSnapshot.
80322
- ...params.preconditionSnapshot
80862
+ computeInstanceId: COMPUTE_INSTANCE_ID
80323
80863
  };
80324
80864
  let stepStartPostSentAtMs;
80865
+ let stepClaimCompletedAtMs;
80325
80866
  let optimisticStartSettled;
80326
80867
  const reconcileOptimisticStart = /* @__PURE__ */ __name(async () => {
80327
80868
  if (!optimisticStartSettled)
@@ -80350,7 +80891,7 @@ async function executeStep(params) {
80350
80891
  ...params.ownerMessageId !== void 0 ? { ownerMessageId: params.ownerMessageId } : {}
80351
80892
  }
80352
80893
  },
80353
- // Guard the claim — see StepExecutorParams.preconditionSnapshot. A
80894
+ // Guard the claim — see StepExecutorParams.slotSnapshot. A
80354
80895
  // stale (412) rejection surfaces via reconcileOptimisticStart as a
80355
80896
  // non-translatable error: the body result is discarded and the
80356
80897
  // rejection propagates to the caller.
@@ -80386,12 +80927,13 @@ async function executeStep(params) {
80386
80927
  ...ownershipStamp
80387
80928
  } : { stepName, ...ownershipStamp }
80388
80929
  },
80389
- // Guard the claim — see StepExecutorParams.preconditionSnapshot. A
80930
+ // Guard the claim — see StepExecutorParams.slotSnapshot. A
80390
80931
  // stale (412) rejection is intentionally NOT translated by
80391
80932
  // startErrorToResult below, so it propagates to the caller for a
80392
80933
  // fresh replay.
80393
80934
  startEventParams
80394
80935
  );
80936
+ stepClaimCompletedAtMs = Date.now();
80395
80937
  step = startResult.step;
80396
80938
  } catch (err) {
80397
80939
  const mapped = startErrorToResult(err);
@@ -80504,12 +81046,28 @@ async function executeStep(params) {
80504
81046
  if (latencyEventData) {
80505
81047
  span?.setAttributes({
80506
81048
  ...latencyEventData.ttfs !== void 0 ? StepTtfsMs2(latencyEventData.ttfs) : {},
80507
- ...latencyEventData.stso !== void 0 ? StepStsoMs2(latencyEventData.stso) : {},
81049
+ ...latencyEventData.stso !== void 0 ? StepStsoMs3(latencyEventData.stso) : {},
80508
81050
  ...latencyEventData.rsfs !== void 0 ? StepRsfsMs2(latencyEventData.rsfs) : {},
80509
81051
  ...latencyEventData.finalSchedulingReplay !== void 0 ? StepFinalSchedulingReplayMs2(latencyEventData.finalSchedulingReplay) : {},
80510
- ...StepLatencyOptimizations2(latencyEventData.optimizations ?? [])
81052
+ ...StepLatencyOptimizations3(latencyEventData.optimizations ?? [])
80511
81053
  });
80512
81054
  }
81055
+ const reportResumeTtr = /* @__PURE__ */ __name(() => {
81056
+ const tracking = params.resumeTracking;
81057
+ if (!tracking || tracking.reported)
81058
+ return;
81059
+ const attributes = computeResumeTtrAttributes({
81060
+ tracking,
81061
+ attempt,
81062
+ stepClaimStartedAtMs: stepStartPostSentAtMs,
81063
+ stepClaimCompletedAtMs,
81064
+ stepCodeStartedAtMs: Date.now()
81065
+ });
81066
+ if (!attributes)
81067
+ return;
81068
+ tracking.reported = true;
81069
+ span?.setAttributes(attributes);
81070
+ }, "reportResumeTtr");
80513
81071
  try {
80514
81072
  result2 = await trace5("step.execute", {}, async () => {
80515
81073
  return await contextStorage2.run({
@@ -80537,7 +81095,10 @@ async function executeStep(params) {
80537
81095
  // (e.g. `setAttributes`) can order itself after the
80538
81096
  // run exists. Undefined on the await path (run already durable).
80539
81097
  runReadyBarrier: optimisticStart ? params.runReadyBarrier : void 0
80540
- }, () => stepFn.apply(thisVal, args));
81098
+ }, () => {
81099
+ reportResumeTtr();
81100
+ return stepFn.apply(thisVal, args);
81101
+ });
80541
81102
  });
80542
81103
  } catch (err) {
80543
81104
  userCodeError = err;
@@ -80833,6 +81394,7 @@ var init_step_executor = __esm({
80833
81394
  init_get_port_lazy();
80834
81395
  init_helpers3();
80835
81396
  init_replay_recovery_reporter();
81397
+ init_resume_latency();
80836
81398
  init_step_latency();
80837
81399
  init_wait_until2();
80838
81400
  DEFAULT_STEP_MAX_RETRIES = 3;
@@ -88802,29 +89364,39 @@ function isFirstInvocation(preloadedEvents) {
88802
89364
  return preloadedEvents.every((e) => e.eventType === "run_created" || e.eventType === "run_started");
88803
89365
  }
88804
89366
  async function queueStepMessage(params) {
88805
- const { world, runId, workflowRun, step, delaySeconds, namespace, nextTraceCarrier, purpose, wfdiag } = params;
89367
+ const { world, runId, workflowRun, step, delaySeconds, namespace, nextTraceCarrier, purpose, stepInput, wfdiag } = params;
88806
89368
  const traceCarrier = await nextTraceCarrier();
88807
89369
  await queueMessage(world, getWorkflowQueueName2(workflowRun.workflowName, namespace), {
88808
89370
  runId,
88809
89371
  stepId: step.correlationId,
88810
89372
  stepName: step.stepId,
88811
89373
  traceCarrier,
88812
- requestedAt: /* @__PURE__ */ new Date()
89374
+ requestedAt: /* @__PURE__ */ new Date(),
89375
+ ...stepInput !== void 0 ? { stepInput: { input: stepInput } } : {}
88813
89376
  }, {
88814
- idempotencyKey: purpose === "dispatch" ? step.correlationId : `${step.correlationId}:${purpose}`,
89377
+ // The 'dispatch' key is step-identity-scoped (correlationId + hashed
89378
+ // step name) — shared with the node engine's dispatch of the same step
89379
+ // so the two stay mutually exclusive, without a revoked resilient
89380
+ // message absorbing a reassigned correlation id's legitimate dispatch.
89381
+ // See stepDispatchIdempotencyKey.
89382
+ idempotencyKey: purpose === "dispatch" ? stepDispatchIdempotencyKey(step.correlationId, step.stepId) : `${step.correlationId}:${purpose}`,
88815
89383
  ...delaySeconds && delaySeconds > 0 ? { delaySeconds } : {}
88816
89384
  });
88817
89385
  wfdiag("step_queued", {
88818
89386
  stepId: step.stepId,
88819
89387
  correlationId: step.correlationId,
88820
89388
  purpose,
88821
- delaySeconds: delaySeconds ?? 0
89389
+ delaySeconds: delaySeconds ?? 0,
89390
+ ...stepInput !== void 0 ? { resilient: true } : {}
88822
89391
  });
88823
89392
  }
88824
89393
  async function dispatchPendingOps(params) {
88825
89394
  const { world, runId, workflowRun, encryptionKey, pendingOperations, namespace, nextTraceCarrier } = params;
88826
89395
  const skipStepCreation = params.skipStepCreation;
89396
+ const queueStepCids = params.queueStepCids;
88827
89397
  const wfdiag = params.wfdiag;
89398
+ const queuedStepCids = /* @__PURE__ */ new Set();
89399
+ const resilientDispatchEligible = queueStepCids !== void 0 && queueStepCids.size > 0 && isResilientStepDispatchEnabled() && (workflowRun.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT2;
88828
89400
  let createdGetConflictHook = false;
88829
89401
  let createdAttributeEvent = false;
88830
89402
  const opsPromises = [];
@@ -88955,6 +89527,56 @@ async function dispatchPendingOps(params) {
88955
89527
  if (op.type === "step" && !op.hasCreatedEvent && !skipStepCreation?.has(op.correlationId)) {
88956
89528
  const step = op;
88957
89529
  opsPromises.push((async () => {
89530
+ const encryptedInput = await encrypt4(step.input, encryptionKey);
89531
+ if (resilientDispatchEligible && queueStepCids?.has(step.correlationId) && encryptedInput instanceof Uint8Array && encryptedInput.byteLength <= MAX_RESILIENT_STEP_INPUT_BYTES) {
89532
+ const [createResult, queueResult] = await Promise.allSettled([
89533
+ world.events.create(runId, {
89534
+ eventType: "step_created",
89535
+ specVersion: SPEC_VERSION_CURRENT2,
89536
+ correlationId: step.correlationId,
89537
+ eventData: {
89538
+ stepName: step.stepId,
89539
+ input: encryptedInput
89540
+ }
89541
+ }),
89542
+ queueStepMessage({
89543
+ world,
89544
+ runId,
89545
+ workflowRun,
89546
+ step,
89547
+ namespace,
89548
+ nextTraceCarrier,
89549
+ purpose: "dispatch",
89550
+ stepInput: encryptedInput,
89551
+ wfdiag
89552
+ })
89553
+ ]);
89554
+ if (queueResult.status === "rejected") {
89555
+ throw queueResult.reason;
89556
+ }
89557
+ queuedStepCids.add(step.correlationId);
89558
+ if (createResult.status === "rejected") {
89559
+ const err = createResult.reason;
89560
+ if (EntityConflictError2.is(err)) {
89561
+ return;
89562
+ }
89563
+ if (isRetryableWorldError2(err)) {
89564
+ runtimeLogger2.warn("Step creation event write failed, but the step was dispatched via the queue. The step_created event will be ensured by the queue consumer.", {
89565
+ workflowRunId: runId,
89566
+ correlationId: step.correlationId,
89567
+ stepName: step.stepId,
89568
+ error: err instanceof Error ? err.message : String(err)
89569
+ });
89570
+ wfdiag("step_resilient_dispatch_recovered", {
89571
+ stepId: step.stepId,
89572
+ correlationId: step.correlationId
89573
+ });
89574
+ return;
89575
+ }
89576
+ throw err;
89577
+ }
89578
+ return;
89579
+ }
88958
89580
  try {
88959
89581
  await world.events.create(runId, {
88960
89582
  eventType: "step_created",
@@ -88962,7 +89584,7 @@ async function dispatchPendingOps(params) {
88962
89584
  correlationId: step.correlationId,
88963
89585
  eventData: {
88964
89586
  stepName: step.stepId,
88965
- input: await encrypt4(step.input, encryptionKey)
89587
+ input: encryptedInput
88966
89588
  }
88967
89589
  });
88968
89590
  } catch (err) {
@@ -89015,7 +89637,7 @@ async function dispatchPendingOps(params) {
89015
89637
  }
89016
89638
  }
89017
89639
  await Promise.all(opsPromises);
89018
- return { createdAttributeEvent, createdGetConflictHook };
89640
+ return { createdAttributeEvent, createdGetConflictHook, queuedStepCids };
89019
89641
  }
89020
89642
  async function runWorkflowWithQuickJS(params) {
89021
89643
  const { workflowCode: workflowCode2, workflowName, workflowRun, preloadedEvents, preloadedEventsComplete, runInput, parentSpan, maxEventsLimit, deliveryAttempt, ownerMessageId, namespace } = params;
@@ -89239,6 +89861,7 @@ async function runWorkflowWithQuickJS(params) {
89239
89861
  recordedAbortIds.add(op.correlationId);
89240
89862
  }
89241
89863
  }
89864
+ const overflowSteps = freshSteps.slice(inlineCandidates.length);
89242
89865
  const dispatched = await dispatchPendingOps({
89243
89866
  world,
89244
89867
  runId,
@@ -89248,15 +89871,18 @@ async function runWorkflowWithQuickJS(params) {
89248
89871
  nextTraceCarrier,
89249
89872
  pendingOperations: opsToDispatch,
89250
89873
  skipStepCreation: inlineClaimCids,
89874
+ queueStepCids: new Set(overflowSteps.map((s) => s.correlationId)),
89251
89875
  wfdiag
89252
89876
  });
89253
89877
  if (dispatched.createdAttributeEvent || dispatched.createdGetConflictHook) {
89254
89878
  pendingRequeueSignal = true;
89255
89879
  }
89256
- const overflowSteps = freshSteps.slice(inlineCandidates.length);
89257
- for (const step of overflowSteps) {
89880
+ for (const cid of dispatched.queuedStepCids) {
89881
+ queuedStepIds.add(cid);
89882
+ }
89883
+ await Promise.all(overflowSteps.filter((step) => !dispatched.queuedStepCids.has(step.correlationId)).map((step) => {
89258
89884
  queuedStepIds.add(step.correlationId);
89259
- await queueStepMessage({
89885
+ return queueStepMessage({
89260
89886
  world,
89261
89887
  runId,
89262
89888
  workflowRun,
@@ -89266,7 +89892,7 @@ async function runWorkflowWithQuickJS(params) {
89266
89892
  purpose: "dispatch",
89267
89893
  wfdiag
89268
89894
  });
89269
- }
89895
+ }));
89270
89896
  const waitCompletePromises = [];
89271
89897
  for (const op of pendingOperations) {
89272
89898
  if (op.type !== "wait")
@@ -89429,7 +90055,7 @@ async function runWorkflowWithQuickJS(params) {
89429
90055
  namespace,
89430
90056
  nextTraceCarrier,
89431
90057
  // Suffixed key: this step was inline-claimed, so no dispatch
89432
- // publish exists under the bare correlationId — but suffixing
90058
+ // publish exists under the dispatch key — but suffixing
89433
90059
  // keeps the retry enqueueable even if a world retired a
89434
90060
  // historical key for this step (see the purpose docs above).
89435
90061
  purpose: "retry:1",
@@ -90161,6 +90787,7 @@ var HookConflictError;
90161
90787
  var HookNotFoundError;
90162
90788
  var EntityConflictError;
90163
90789
  var RunExpiredError;
90790
+ var StreamExpiredError;
90164
90791
  var ThrottleError;
90165
90792
  var WorkflowRunCancelledError;
90166
90793
  var FatalError;
@@ -90486,6 +91113,30 @@ Caused by: ${options.cause.stack}`;
90486
91113
  return isError(value) && value.name === "RunExpiredError";
90487
91114
  }
90488
91115
  };
91116
+ StreamExpiredError = class extends WorkflowWorldError {
91117
+ static {
91118
+ __name(this, "StreamExpiredError");
91119
+ }
91120
+ static {
91121
+ __name2(this, "StreamExpiredError");
91122
+ }
91123
+ runId;
91124
+ streamId;
91125
+ expiredAt;
91126
+ constructor(message, runId, streamId, expiredAt) {
91127
+ super(message, {
91128
+ status: 410,
91129
+ code: "stream-expired"
91130
+ });
91131
+ this.runId = runId;
91132
+ this.streamId = streamId;
91133
+ this.expiredAt = expiredAt;
91134
+ this.name = "StreamExpiredError";
91135
+ }
91136
+ static is(value) {
91137
+ return isError(value) && value.name === "StreamExpiredError";
91138
+ }
91139
+ };
90489
91140
  ThrottleError = class extends WorkflowWorldError {
90490
91141
  static {
90491
91142
  __name(this, "ThrottleError");
@@ -107894,7 +108545,9 @@ var QueueNamespace;
107894
108545
  var MessageId;
107895
108546
  var TraceCarrierSchema;
107896
108547
  var RunInputSchema;
108548
+ var StepDispatchInputSchema;
107897
108549
  var HookResumeInputSchema;
108550
+ var HookResumeTimingSchema;
107898
108551
  var WorkflowInvokePayloadSchema;
107899
108552
  var HealthCheckPayloadSchema;
107900
108553
  var QueuePayloadSchema;
@@ -107944,6 +108597,19 @@ var init_queue = __esm2({
107944
108597
  */
107945
108598
  environment: external_exports.string().optional()
107946
108599
  });
108600
+ StepDispatchInputSchema = external_exports.object({
108601
+ /**
108602
+ * The serialized step input, reused verbatim from the direct write. Always
108603
+ * binary: producers only attach `stepInput` when the dehydrated input is a
108604
+ * `Uint8Array` and the run's queue transport preserves bytes (CBOR).
108605
+ * Validated here so a malformed or transport-mangled payload fails the
108606
+ * message parse instead of being silently written into a `step_created` as
108607
+ * non-binary data. `Buffer` is a `Uint8Array` subclass and passes.
108608
+ */
108609
+ input: external_exports.custom((value) => value instanceof Uint8Array, {
108610
+ message: "stepInput.input must be a Uint8Array"
108611
+ })
108612
+ });
107947
108613
  HookResumeInputSchema = external_exports.object({
107948
108614
  /** Stable idempotency key minted once per `resumeHook()` call. */
107949
108615
  resumeId: external_exports.string(),
@@ -107977,6 +108643,22 @@ var init_queue = __esm2({
107977
108643
  */
107978
108644
  deploymentId: external_exports.string().optional()
107979
108645
  });
108646
+ HookResumeTimingSchema = external_exports.object({
108647
+ /** Epoch ms at entry into `resumeHook()` — the start of the TTR window. */
108648
+ resumeRequestedAtMs: external_exports.number(),
108649
+ /** Epoch ms immediately before the queue publish was requested. */
108650
+ queuePublishRequestedAtMs: external_exports.number(),
108651
+ /** Which `resumeHook()` dispatch path ran: `parallel` or `sequential`. */
108652
+ strategy: external_exports.string().optional(),
108653
+ /** Epoch ms the final consumer's queue handler was entered. */
108654
+ consumerStartedAtMs: external_exports.number().optional(),
108655
+ /** Epoch ms this invocation's first replay pass began. */
108656
+ replayStartedAtMs: external_exports.number().optional(),
108657
+ /** Epoch ms replay first encountered a durable step after the resume. */
108658
+ nextStepEncounteredAtMs: external_exports.number().optional(),
108659
+ /** How the consumer initialized replay state: see `ResumeSetupSource`. */
108660
+ setupSource: external_exports.string().optional()
108661
+ });
107980
108662
  WorkflowInvokePayloadSchema = external_exports.object({
107981
108663
  runId: external_exports.string(),
107982
108664
  traceCarrier: TraceCarrierSchema.optional(),
@@ -108010,7 +108692,28 @@ var init_queue = __esm2({
108010
108692
  * fast path. A consumer that understands this field idempotently ensures the
108011
108693
  * `hook_received` event exists (keyed by `resumeId`) before replaying.
108012
108694
  */
108013
- hookInput: HookResumeInputSchema.optional()
108695
+ hookInput: HookResumeInputSchema.optional(),
108696
+ /**
108697
+ * Resilient step dispatch data, only present alongside `stepId` when the
108698
+ * producer parallelized the `step_created` write with this queue publish. A
108699
+ * consumer that understands this field idempotently ensures the
108700
+ * `step_created` event exists (keyed by `stepId`) before executing the step.
108701
+ */
108702
+ stepInput: StepDispatchInputSchema.optional(),
108703
+ /**
108704
+ * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
108705
+ * (unlike `hookInput`, which only rides the parallel fast path), and
108706
+ * forwarded onto a dispatched step message when the resuming invocation
108707
+ * hands the next durable step to another invocation. Purely observational —
108708
+ * see {@link HookResumeTimingSchema}.
108709
+ *
108710
+ * `.catch(undefined)` because this field must never be able to fail the
108711
+ * parse of the invocation payload: a malformed value (a NaN boundary, a
108712
+ * shape change from a future producer) would otherwise throw on every
108713
+ * delivery of that message and burn the run's delivery budget over a
108714
+ * telemetry field. Anything unparseable degrades to "no measurement".
108715
+ */
108716
+ hookResumeTiming: HookResumeTimingSchema.optional().catch(void 0)
108014
108717
  });
108015
108718
  HealthCheckPayloadSchema = external_exports.object({
108016
108719
  __healthCheck: external_exports.literal(true),
@@ -108170,7 +108873,7 @@ var init_spec_version = __esm2({
108170
108873
  SPEC_VERSION_SUPPORTS_ATTRIBUTES = 4;
108171
108874
  SPEC_VERSION_SUPPORTS_COMPRESSION = 5;
108172
108875
  SPEC_VERSION_SUPPORTS_SLOT_IDENTITY = 6;
108173
- SPEC_VERSION_CURRENT = SPEC_VERSION_SUPPORTS_COMPRESSION;
108876
+ SPEC_VERSION_CURRENT = SPEC_VERSION_SUPPORTS_SLOT_IDENTITY;
108174
108877
  SPEC_VERSION_MAX_SUPPORTED = SPEC_VERSION_SUPPORTS_SLOT_IDENTITY;
108175
108878
  __name2(isLegacySpecVersion, "isLegacySpecVersion");
108176
108879
  }
@@ -111181,6 +111884,8 @@ function getReviversForMode(mode, global2 = globalThis, extraRevivers) {
111181
111884
  __name(getReviversForMode, "getReviversForMode");
111182
111885
  var encoder;
111183
111886
  var decoder;
111887
+ var MAX_SPARSE_ARRAY_LENGTH;
111888
+ var parseOptions;
111184
111889
  var devalueCodec;
111185
111890
  var init_codec_devalue = __esm2({
111186
111891
  "../core/dist/serialization/codec-devalue.js"() {
@@ -111193,6 +111898,17 @@ var init_codec_devalue = __esm2({
111193
111898
  init_types();
111194
111899
  encoder = new TextEncoder();
111195
111900
  decoder = new TextDecoder();
111901
+ MAX_SPARSE_ARRAY_LENGTH = 1e5;
111902
+ parseOptions = {
111903
+ operations: {
111904
+ createSparseArray(length) {
111905
+ if (length > MAX_SPARSE_ARRAY_LENGTH) {
111906
+ throw new RangeError(`Sparse array length ${length} exceeds the maximum of ${MAX_SPARSE_ARRAY_LENGTH}`);
111907
+ }
111908
+ return default_parse_operations.createSparseArray(length);
111909
+ }
111910
+ }
111911
+ };
111196
111912
  __name2(getReducersForMode, "getReducersForMode");
111197
111913
  __name2(getReviversForMode, "getReviversForMode");
111198
111914
  devalueCodec = {
@@ -111207,11 +111923,11 @@ var init_codec_devalue = __esm2({
111207
111923
  deserialize(data, mode, options) {
111208
111924
  const revivers = getReviversForMode(mode, options?.global, options?.extraRevivers);
111209
111925
  const str = decoder.decode(data);
111210
- return parse3(str, revivers);
111926
+ return parse3(str, revivers, parseOptions);
111211
111927
  },
111212
111928
  deserializeLegacy(data, mode, options) {
111213
111929
  const revivers = getReviversForMode(mode, options?.global, options?.extraRevivers);
111214
- return unflatten(data, revivers);
111930
+ return unflatten(data, revivers, parseOptions);
111215
111931
  }
111216
111932
  };
111217
111933
  }
@@ -111831,6 +112547,20 @@ var HookFound;
111831
112547
  var HookResilientResume;
111832
112548
  var HookResilientResumeMaterialized;
111833
112549
  var HookResumeSetupSource;
112550
+ var StepResilientDispatchRecovered;
112551
+ var StepResilientDispatchMaterialized;
112552
+ var ResumeTotalMs;
112553
+ var ResumeProducerPrepMs;
112554
+ var ResumeQueueDeliveryMs;
112555
+ var ResumeSetupMs;
112556
+ var ResumeReplayMs;
112557
+ var ResumeStepDispatchMs;
112558
+ var ResumeStepClaimMs;
112559
+ var ResumeStepPrepareMs;
112560
+ var ResumeTrigger;
112561
+ var ResumeStrategy;
112562
+ var ResumeSetupSource;
112563
+ var ResumeStepExecution;
111834
112564
  var WebhookHandlersTriggered;
111835
112565
  var WorkflowSuspensionState;
111836
112566
  var WorkflowSuspensionHookCount;
@@ -111938,6 +112668,20 @@ var init_semantic_conventions = __esm2({
111938
112668
  HookResilientResume = SemanticConvention("workflow.hook.resilient_resume");
111939
112669
  HookResilientResumeMaterialized = SemanticConvention("workflow.hook.resilient_resume_materialized");
111940
112670
  HookResumeSetupSource = SemanticConvention("workflow.resume_setup_source");
112671
+ StepResilientDispatchRecovered = SemanticConvention("workflow.step.resilient_dispatch_recovered");
112672
+ StepResilientDispatchMaterialized = SemanticConvention("workflow.step.resilient_dispatch_materialized");
112673
+ ResumeTotalMs = SemanticConvention("workflow.resume.total_ms");
112674
+ ResumeProducerPrepMs = SemanticConvention("workflow.resume.phase.producer_prep_ms");
112675
+ ResumeQueueDeliveryMs = SemanticConvention("workflow.resume.phase.queue_delivery_ms");
112676
+ ResumeSetupMs = SemanticConvention("workflow.resume.phase.resume_setup_ms");
112677
+ ResumeReplayMs = SemanticConvention("workflow.resume.phase.replay_ms");
112678
+ ResumeStepDispatchMs = SemanticConvention("workflow.resume.phase.step_dispatch_ms");
112679
+ ResumeStepClaimMs = SemanticConvention("workflow.resume.phase.step_claim_ms");
112680
+ ResumeStepPrepareMs = SemanticConvention("workflow.resume.phase.step_prepare_ms");
112681
+ ResumeTrigger = SemanticConvention("workflow.resume.trigger");
112682
+ ResumeStrategy = SemanticConvention("workflow.resume.strategy");
112683
+ ResumeSetupSource = SemanticConvention("workflow.resume.setup_source");
112684
+ ResumeStepExecution = SemanticConvention("workflow.resume.step_execution");
111941
112685
  WebhookHandlersTriggered = SemanticConvention("webhook.handlers.triggered");
111942
112686
  WorkflowSuspensionState = SemanticConvention("workflow.suspension.state");
111943
112687
  WorkflowSuspensionHookCount = SemanticConvention("workflow.suspension.hook_count");
@@ -114697,7 +115441,7 @@ var require_parse_options = __commonJS2({
114697
115441
  loose: true
114698
115442
  });
114699
115443
  var emptyOpts = Object.freeze({});
114700
- var parseOptions = /* @__PURE__ */ __name2((options) => {
115444
+ var parseOptions22 = /* @__PURE__ */ __name2((options) => {
114701
115445
  if (!options) {
114702
115446
  return emptyOpts;
114703
115447
  }
@@ -114706,7 +115450,7 @@ var require_parse_options = __commonJS2({
114706
115450
  }
114707
115451
  return options;
114708
115452
  }, "parseOptions");
114709
- module.exports = parseOptions;
115453
+ module.exports = parseOptions22;
114710
115454
  }
114711
115455
  });
114712
115456
  var require_identifiers = __commonJS2({
@@ -114738,7 +115482,7 @@ var require_semver2 = __commonJS2({
114738
115482
  var debug = require_debug();
114739
115483
  var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
114740
115484
  var { safeRe: re2, t } = require_re();
114741
- var parseOptions = require_parse_options();
115485
+ var parseOptions22 = require_parse_options();
114742
115486
  var { compareIdentifiers } = require_identifiers();
114743
115487
  var SemVer = class _SemVer {
114744
115488
  static {
@@ -114748,7 +115492,7 @@ var require_semver2 = __commonJS2({
114748
115492
  __name2(this, "SemVer");
114749
115493
  }
114750
115494
  constructor(version32, options) {
114751
- options = parseOptions(options);
115495
+ options = parseOptions22(options);
114752
115496
  if (version32 instanceof _SemVer) {
114753
115497
  if (version32.loose === !!options.loose && version32.includePrerelease === !!options.includePrerelease) {
114754
115498
  return version32;
@@ -115404,7 +116148,7 @@ var require_range = __commonJS2({
115404
116148
  __name2(this, "Range");
115405
116149
  }
115406
116150
  constructor(range2, options) {
115407
- options = parseOptions(options);
116151
+ options = parseOptions22(options);
115408
116152
  if (range2 instanceof _Range) {
115409
116153
  if (range2.loose === !!options.loose && range2.includePrerelease === !!options.includePrerelease) {
115410
116154
  return range2;
@@ -115555,7 +116299,7 @@ var require_range = __commonJS2({
115555
116299
  module.exports = Range;
115556
116300
  var LRU = require_lrucache();
115557
116301
  var cache = new LRU();
115558
- var parseOptions = require_parse_options();
116302
+ var parseOptions22 = require_parse_options();
115559
116303
  var Comparator = require_comparator();
115560
116304
  var debug = require_debug();
115561
116305
  var SemVer = require_semver2();
@@ -115794,7 +116538,7 @@ var require_comparator = __commonJS2({
115794
116538
  return ANY;
115795
116539
  }
115796
116540
  constructor(comp, options) {
115797
- options = parseOptions(options);
116541
+ options = parseOptions22(options);
115798
116542
  if (comp instanceof _Comparator) {
115799
116543
  if (comp.loose === !!options.loose) {
115800
116544
  return comp;
@@ -115862,7 +116606,7 @@ var require_comparator = __commonJS2({
115862
116606
  }
115863
116607
  return new Range(this.value, options).test(comp.semver);
115864
116608
  }
115865
- options = parseOptions(options);
116609
+ options = parseOptions22(options);
115866
116610
  if (options.includePrerelease && (this.value === "<0.0.0-0" || comp.value === "<0.0.0-0")) {
115867
116611
  return false;
115868
116612
  }
@@ -115888,7 +116632,7 @@ var require_comparator = __commonJS2({
115888
116632
  }
115889
116633
  };
115890
116634
  module.exports = Comparator;
115891
- var parseOptions = require_parse_options();
116635
+ var parseOptions22 = require_parse_options();
115892
116636
  var { safeRe: re2, t } = require_re();
115893
116637
  var cmp = require_cmp();
115894
116638
  var debug = require_debug();
@@ -116576,7 +117320,7 @@ var version2;
116576
117320
  var init_version = __esm2({
116577
117321
  "../core/dist/version.js"() {
116578
117322
  "use strict";
116579
- version2 = "5.0.0-beta.41";
117323
+ version2 = "5.0.0-beta.42";
116580
117324
  }
116581
117325
  });
116582
117326
  function getWorkflowQueueName(workflowName, namespace) {
@@ -121843,10 +122587,10 @@ async function getHookByToken(token) {
121843
122587
  }
121844
122588
  __name(getHookByToken, "getHookByToken");
121845
122589
  async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
121846
- return resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, false);
122590
+ return resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, false, Date.now());
121847
122591
  }
121848
122592
  __name(resumeHook, "resumeHook");
121849
- async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp) {
122593
+ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs) {
121850
122594
  return await waitedUntil(() => {
121851
122595
  return trace("hook.resume", async (span) => {
121852
122596
  const world = await getWorldLazy();
@@ -121938,9 +122682,15 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
121938
122682
  }
121939
122683
  throw err;
121940
122684
  }
122685
+ const queuePublishRequestedAtMs = Date.now();
121941
122686
  await world.queue(queueName, {
121942
122687
  runId: hook.runId,
121943
- traceCarrier: resumeContext.traceCarrier ?? void 0
122688
+ traceCarrier: resumeContext.traceCarrier ?? void 0,
122689
+ hookResumeTiming: {
122690
+ resumeRequestedAtMs,
122691
+ queuePublishRequestedAtMs,
122692
+ strategy: "sequential"
122693
+ }
121944
122694
  }, queueOptions);
121945
122695
  return hook;
121946
122696
  }
@@ -121949,18 +122699,9 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
121949
122699
  span?.setAttributes({
121950
122700
  "workflow.hook.resume_id": resumeId
121951
122701
  });
121952
- const [eventResult, queueResult] = await Promise.allSettled([
121953
- world.events.create(hook.runId, {
121954
- eventType: "hook_received",
121955
- specVersion: SPEC_VERSION_CURRENT,
121956
- correlationId: hook.hookId,
121957
- eventData
121958
- }, {
121959
- v1Compat,
121960
- resumeId,
121961
- resumePayloadDigest: payloadDigest
121962
- }),
121963
- world.queue(queueName, {
122702
+ const publishInvocation = /* @__PURE__ */ __name2(() => {
122703
+ const queuePublishRequestedAtMs = Date.now();
122704
+ return world.queue(queueName, {
121964
122705
  runId: hook.runId,
121965
122706
  traceCarrier: resumeContext.traceCarrier ?? void 0,
121966
122707
  hookInput: {
@@ -121973,8 +122714,26 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
121973
122714
  // check: lets a misrouted delivery re-route before its
121974
122715
  // hoisted hook_received write instead of after.
121975
122716
  deploymentId: resumeContext.deploymentId
122717
+ },
122718
+ hookResumeTiming: {
122719
+ resumeRequestedAtMs,
122720
+ queuePublishRequestedAtMs,
122721
+ strategy: "parallel"
121976
122722
  }
121977
- }, queueOptions)
122723
+ }, queueOptions);
122724
+ }, "publishInvocation");
122725
+ const [eventResult, queueResult] = await Promise.allSettled([
122726
+ world.events.create(hook.runId, {
122727
+ eventType: "hook_received",
122728
+ specVersion: SPEC_VERSION_CURRENT,
122729
+ correlationId: hook.hookId,
122730
+ eventData
122731
+ }, {
122732
+ v1Compat,
122733
+ resumeId,
122734
+ resumePayloadDigest: payloadDigest
122735
+ }),
122736
+ publishInvocation()
121978
122737
  ]);
121979
122738
  if (queueResult.status === "rejected") {
121980
122739
  throw queueResult.reason;
@@ -122018,6 +122777,7 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
122018
122777
  }
122019
122778
  __name(resumeHookImpl, "resumeHookImpl");
122020
122779
  async function resumeWebhook(token, request) {
122780
+ const resumeRequestedAtMs = Date.now();
122021
122781
  const { hook, encryptionKey } = await getHookByTokenWithKey(token);
122022
122782
  if (hook.isWebhook === false) {
122023
122783
  throw new HookNotFoundError(token);
@@ -122041,7 +122801,7 @@ async function resumeWebhook(token, request) {
122041
122801
  status: 202
122042
122802
  });
122043
122803
  }
122044
- await resumeHookImpl(hook, request, encryptionKey, true);
122804
+ await resumeHookImpl(hook, request, encryptionKey, true, resumeRequestedAtMs);
122045
122805
  if (responseReadable) {
122046
122806
  const reader = responseReadable.getReader();
122047
122807
  const chunk = await reader.read();
@@ -122429,7 +123189,8 @@ function createReconnectingFramedStream(runId, name, startIndex) {
122429
123189
  try {
122430
123190
  await connect2();
122431
123191
  return;
122432
- } catch {
123192
+ } catch (error482) {
123193
+ if (StreamExpiredError.is(error482)) throw error482;
122433
123194
  }
122434
123195
  }
122435
123196
  }
@@ -124268,7 +125029,7 @@ __name2(start, "start");
124268
125029
  value: "start",
124269
125030
  configurable: true
124270
125031
  });
124271
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.41//start");
125032
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.42//start");
124272
125033
  async function wakeUpRun(world, runId, options) {
124273
125034
  try {
124274
125035
  const run22 = await world.runs.get(runId, {
@@ -124613,7 +125374,7 @@ var Run = class _Run {
124613
125374
  value: "wakeUp",
124614
125375
  configurable: true
124615
125376
  });
124616
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#wakeUp");
125377
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#wakeUp");
124617
125378
  (function(__wf_fn, __wf_id) {
124618
125379
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124619
125380
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124622,7 +125383,7 @@ var Run = class _Run {
124622
125383
  value: "cancel",
124623
125384
  configurable: true
124624
125385
  });
124625
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#cancel");
125386
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#cancel");
124626
125387
  (function(__wf_fn, __wf_id) {
124627
125388
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124628
125389
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124631,7 +125392,7 @@ var Run = class _Run {
124631
125392
  value: "getReadable",
124632
125393
  configurable: true
124633
125394
  });
124634
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#getReadable");
125395
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#getReadable");
124635
125396
  (function(__wf_fn, __wf_id) {
124636
125397
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124637
125398
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124640,7 +125401,7 @@ var Run = class _Run {
124640
125401
  value: "exists",
124641
125402
  configurable: true
124642
125403
  });
124643
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#exists");
125404
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#exists");
124644
125405
  (function(__wf_fn, __wf_id) {
124645
125406
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124646
125407
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124649,7 +125410,7 @@ var Run = class _Run {
124649
125410
  value: "status",
124650
125411
  configurable: true
124651
125412
  });
124652
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#status");
125413
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#status");
124653
125414
  (function(__wf_fn, __wf_id) {
124654
125415
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124655
125416
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124658,7 +125419,7 @@ var Run = class _Run {
124658
125419
  value: "returnValue",
124659
125420
  configurable: true
124660
125421
  });
124661
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#returnValue");
125422
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#returnValue");
124662
125423
  (function(__wf_fn, __wf_id) {
124663
125424
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124664
125425
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124667,7 +125428,7 @@ var Run = class _Run {
124667
125428
  value: "workflowName",
124668
125429
  configurable: true
124669
125430
  });
124670
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#workflowName");
125431
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#workflowName");
124671
125432
  (function(__wf_fn, __wf_id) {
124672
125433
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124673
125434
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124676,7 +125437,7 @@ var Run = class _Run {
124676
125437
  value: "createdAt",
124677
125438
  configurable: true
124678
125439
  });
124679
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#createdAt");
125440
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#createdAt");
124680
125441
  (function(__wf_fn, __wf_id) {
124681
125442
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124682
125443
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124685,7 +125446,7 @@ var Run = class _Run {
124685
125446
  value: "startedAt",
124686
125447
  configurable: true
124687
125448
  });
124688
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#startedAt");
125449
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#startedAt");
124689
125450
  (function(__wf_fn, __wf_id) {
124690
125451
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124691
125452
  __wf_reg.set(__wf_id, __wf_fn);
@@ -124694,7 +125455,7 @@ var Run = class _Run {
124694
125455
  value: "completedAt",
124695
125456
  configurable: true
124696
125457
  });
124697
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.41//Run#completedAt");
125458
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.42//Run#completedAt");
124698
125459
  (function(__wf_cls, __wf_id) {
124699
125460
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
124700
125461
  __wf_reg.set(__wf_id, __wf_cls);
@@ -124704,7 +125465,7 @@ var Run = class _Run {
124704
125465
  enumerable: false,
124705
125466
  configurable: false
124706
125467
  });
124707
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.41//Run");
125468
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.42//Run");
124708
125469
  async function fetch2(...args) {
124709
125470
  return globalThis.fetch(...args);
124710
125471
  }
@@ -125535,6 +126296,7 @@ __name(guardDeploymentAffinity, "guardDeploymentAffinity");
125535
126296
  init_helpers3();
125536
126297
  init_replay_budget();
125537
126298
  init_replay_recovery_reporter();
126299
+ init_resume_latency();
125538
126300
  init_run_id_time();
125539
126301
  init_step_executor();
125540
126302
  init_step_latency();
@@ -125585,6 +126347,7 @@ init_step_single_flight();
125585
126347
  // ../core/dist/runtime/suspension-handler.js
125586
126348
  init_dist7();
125587
126349
  init_dist6();
126350
+ init_classify_error2();
125588
126351
  init_encryption4();
125589
126352
  init_logger2();
125590
126353
  init_serialization4();
@@ -125638,7 +126401,7 @@ async function createHookEvent({ runId, hookEvent, queueItem, requestId, createE
125638
126401
  }
125639
126402
  }
125640
126403
  __name(createHookEvent, "createHookEvent");
125641
- async function handleSuspension({ suspension, world, run: run3, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter }) {
126404
+ async function handleSuspension({ suspension, world, run: run3, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, stepDispatch }) {
125642
126405
  const runId = run3.runId;
125643
126406
  const ensureRunReady = /* @__PURE__ */ __name(async () => {
125644
126407
  if (runReadyBarrier) {
@@ -125664,25 +126427,23 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
125664
126427
  const log = eventLog;
125665
126428
  const result2 = await createEvent(data, {
125666
126429
  ...params,
125667
- ...preconditionSnapshotParams(log.events, log.cursor)
126430
+ ...slotSnapshotParams(log.events)
125668
126431
  });
125669
- if (result2.events?.length && result2.hasMore !== true) {
125670
- const added = mergeReportedEvents(log.events, result2.events);
125671
- reportedEvents += added;
125672
- if (added > 0) {
125673
- runtimeLogger2.debug("Suspension write skipped occupied slots", {
125674
- workflowRunId: runId,
125675
- eventType: data.eventType,
125676
- eventId: result2.event?.eventId,
125677
- reported: added
125678
- });
125679
- }
125680
- } else if (result2.events?.length) {
126432
+ const report = absorbSkippedSlotReport(log.events, result2);
126433
+ reportedEvents += report.added;
126434
+ if (report.truncated) {
125681
126435
  runtimeLogger2.debug("Dropped a truncated skipped-slot report", {
125682
126436
  workflowRunId: runId,
125683
126437
  eventType: data.eventType,
125684
126438
  eventId: result2.event?.eventId,
125685
- offered: result2.events.length
126439
+ offered: report.offered
126440
+ });
126441
+ } else if (report.added > 0) {
126442
+ runtimeLogger2.debug("Suspension write skipped occupied slots", {
126443
+ workflowRunId: runId,
126444
+ eventType: data.eventType,
126445
+ eventId: result2.event?.eventId,
126446
+ reported: report.added
125686
126447
  });
125687
126448
  }
125688
126449
  return result2;
@@ -125828,6 +126589,14 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
125828
126589
  const lazyInlineCorrelationIds = new Set(hasAwaitedHookCreation === false ? stepItems.filter((item) => stepsNeedingCreation.has(item.correlationId)).slice(0, getMaxInlineSteps()).map((item) => item.correlationId) : []);
125829
126590
  const lazyInlineByCorrelationId = /* @__PURE__ */ new Map();
125830
126591
  const ops = [];
126592
+ const queuedStepCorrelationIds = /* @__PURE__ */ new Set();
126593
+ const resilientDispatchEligible = stepDispatch !== void 0 && isResilientStepDispatchEnabled() && (run3.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT2;
126594
+ let stepDispatchTraceCarrier;
126595
+ const getStepDispatchTraceCarrier = /* @__PURE__ */ __name(() => {
126596
+ stepDispatchTraceCarrier ??= stepDispatch?.getTraceCarrier() ?? Promise.resolve({});
126597
+ return stepDispatchTraceCarrier;
126598
+ }, "getStepDispatchTraceCarrier");
126599
+ let resilientDispatchRecovered = 0;
125831
126600
  for (const queueItem of stepItems) {
125832
126601
  if (stepsNeedingCreation.has(queueItem.correlationId)) {
125833
126602
  ops.push((async () => {
@@ -125856,6 +126625,61 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
125856
126625
  input: dehydratedInput
125857
126626
  }
125858
126627
  };
126628
+ if (resilientDispatchEligible && dehydratedInput instanceof Uint8Array && dehydratedInput.byteLength <= MAX_RESILIENT_STEP_INPUT_BYTES) {
126629
+ await ensureRunReady();
126630
+ const traceCarrier = await getStepDispatchTraceCarrier();
126631
+ const [createResult, queueResult] = await Promise.allSettled([
126632
+ createGuarded(stepEvent, { requestId }),
126633
+ queueMessage(
126634
+ world,
126635
+ // biome-ignore lint/style/noNonNullAssertion: implied by resilientDispatchEligible
126636
+ stepDispatch.queueName,
126637
+ {
126638
+ runId,
126639
+ stepId: queueItem.correlationId,
126640
+ stepName: queueItem.stepName,
126641
+ traceCarrier,
126642
+ requestedAt: /* @__PURE__ */ new Date(),
126643
+ stepInput: { input: dehydratedInput }
126644
+ },
126645
+ // Same key as the caller's dispatch pass and any concurrent
126646
+ // handler's — redundant publishes for this step dedupe. The
126647
+ // key is step-identity-scoped so a revoked message for a
126648
+ // reassigned correlation id cannot absorb the corrected
126649
+ // schedule's dispatch — see stepDispatchIdempotencyKey.
126650
+ {
126651
+ idempotencyKey: stepDispatchIdempotencyKey(queueItem.correlationId, queueItem.stepName)
126652
+ }
126653
+ )
126654
+ ]);
126655
+ if (queueResult.status === "rejected") {
126656
+ throw queueResult.reason;
126657
+ }
126658
+ queuedStepCorrelationIds.add(queueItem.correlationId);
126659
+ if (createResult.status === "rejected") {
126660
+ const err = createResult.reason;
126661
+ if (EntityConflictError2.is(err)) {
126662
+ runtimeLogger2.info("Step already exists, continuing", {
126663
+ workflowRunId: runId,
126664
+ correlationId: queueItem.correlationId,
126665
+ message: err.message
126666
+ });
126667
+ } else if (isRetryableWorldError2(err)) {
126668
+ resilientDispatchRecovered++;
126669
+ runtimeLogger2.warn("Step creation event write failed, but the step was dispatched via the queue. The step_created event will be ensured by the queue consumer.", {
126670
+ workflowRunId: runId,
126671
+ correlationId: queueItem.correlationId,
126672
+ stepName: queueItem.stepName,
126673
+ error: err instanceof Error ? err.message : String(err)
126674
+ });
126675
+ } else {
126676
+ throw err;
126677
+ }
126678
+ } else {
126679
+ createdStepCorrelationIds.add(queueItem.correlationId);
126680
+ }
126681
+ return;
126682
+ }
125859
126683
  try {
125860
126684
  await ensureRunReady();
125861
126685
  await createGuarded(stepEvent, { requestId });
@@ -125964,11 +126788,13 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
125964
126788
  ...WorkflowRunStatus2("workflow_suspended"),
125965
126789
  ...WorkflowStepsCreated2(stepItems.length),
125966
126790
  ...WorkflowHooksCreated2(hooksNeedingCreation.length),
125967
- ...WorkflowWaitsCreated2(waitItems.length)
126791
+ ...WorkflowWaitsCreated2(waitItems.length),
126792
+ ...resilientDispatchRecovered > 0 ? StepResilientDispatchRecovered2(resilientDispatchRecovered) : {}
125968
126793
  });
125969
126794
  return {
125970
126795
  pendingSteps: stepItems,
125971
126796
  createdStepCorrelationIds,
126797
+ queuedStepCorrelationIds,
125972
126798
  lazyInlineSteps,
125973
126799
  // On hook conflict the caller re-invokes immediately and never reads
125974
126800
  // the wait timeout, so don't report one.
@@ -127373,6 +128199,20 @@ async function createWorkflowSession({ workflowCode: workflowCode2, workflowRun,
127373
128199
  onUnconsumedEvent: /* @__PURE__ */ __name((event) => {
127374
128200
  onWorkflowError(new ReplayDivergenceError(`Replay could not consume event: eventType=${event.eventType}, correlationId=${event.correlationId}, eventId=${event.eventId}.`, { eventId: event.eventId }));
127375
128201
  }, "onUnconsumedEvent"),
128202
+ onDuplicateEvent: /* @__PURE__ */ __name((event, firstEventType) => {
128203
+ const details = {
128204
+ workflowRunId: workflowRun.runId,
128205
+ eventId: event.eventId,
128206
+ eventType: event.eventType,
128207
+ firstEventType,
128208
+ correlationId: event.correlationId
128209
+ };
128210
+ if (firstEventType !== event.eventType) {
128211
+ runtimeLogger2.error("Ignoring event that decides an already-decided outcome differently", details);
128212
+ return;
128213
+ }
128214
+ runtimeLogger2.info("Ignoring event that repeats a class already in the event log", details);
128215
+ }, "onDuplicateEvent"),
127376
128216
  getPromiseQueue: /* @__PURE__ */ __name(() => promiseQueueHolder.current, "getPromiseQueue"),
127377
128217
  isDeliveryIdle: /* @__PURE__ */ __name(() => deliveryIdleHolder.current(), "isDeliveryIdle")
127378
128218
  });
@@ -127400,6 +128240,7 @@ async function createWorkflowSession({ workflowCode: workflowCode2, workflowRun,
127400
128240
  replayPayloadCache
127401
128241
  };
127402
128242
  deliveryIdleHolder.current = () => isDeliveryIdle(workflowContext);
128243
+ let consumedRunStarted = false;
127403
128244
  workflowContext.eventsConsumer.subscribe((event) => {
127404
128245
  if (!event) {
127405
128246
  return EventConsumerResult2.NotConsumed;
@@ -127408,6 +128249,10 @@ async function createWorkflowSession({ workflowCode: workflowCode2, workflowRun,
127408
128249
  return EventConsumerResult2.Consumed;
127409
128250
  }
127410
128251
  if (event.eventType === "run_started") {
128252
+ if (consumedRunStarted) {
128253
+ return EventConsumerResult2.NotConsumed;
128254
+ }
128255
+ consumedRunStarted = true;
127411
128256
  return EventConsumerResult2.Consumed;
127412
128257
  }
127413
128258
  if (event.eventType === "attr_set" && event.eventData.writer.type === "step") {
@@ -128335,6 +129180,14 @@ function getWorkflowSetupErrorCode(err) {
128335
129180
  return null;
128336
129181
  }
128337
129182
  __name(getWorkflowSetupErrorCode, "getWorkflowSetupErrorCode");
129183
+ function isStepMissingError(err) {
129184
+ if (!WorkflowWorldError2.is(err))
129185
+ return false;
129186
+ if (err.status !== void 0 && err.status !== 404)
129187
+ return false;
129188
+ return /step/i.test(err.message) && /not found/i.test(err.message);
129189
+ }
129190
+ __name(isStepMissingError, "isStepMissingError");
128338
129191
  async function recordFatalRunError({ world, workflowRun, runId, requestId, err, errorCode, logMessage }) {
128339
129192
  runtimeLogger2.error(logMessage, {
128340
129193
  workflowRunId: runId,
@@ -128468,12 +129321,20 @@ function workflowEntrypoint(workflowCode2, options) {
128468
129321
  const namespace = resolveQueueNamespace2(options?.namespace);
128469
129322
  const workflowPrefix = getQueueTopicPrefix2("workflow", namespace);
128470
129323
  const handler = /* @__PURE__ */ __name((worldHandlers) => worldHandlers.createQueueHandler(workflowPrefix, async (message_, metadata) => {
129324
+ const handlerEnteredAtMs = Date.now();
128471
129325
  const healthCheck3 = parseHealthCheckPayload(message_);
128472
129326
  if (healthCheck3) {
128473
129327
  await handleHealthCheckMessage(healthCheck3, worldHandlers.specVersion);
128474
129328
  return;
128475
129329
  }
128476
- const { runId, traceCarrier: incomingTraceCarrier, requestedAt, stepId: incomingStepId, stepName: incomingStepName, replayDivergence, preconditionReinvocations, deploymentMismatchRetryCount, runInput, hookInput } = WorkflowInvokePayloadSchema2.parse(message_);
129330
+ const { runId, traceCarrier: incomingTraceCarrier, requestedAt, stepId: incomingStepId, stepName: incomingStepName, replayDivergence, preconditionReinvocations, deploymentMismatchRetryCount, runInput, hookInput, stepInput, hookResumeTiming } = WorkflowInvokePayloadSchema2.parse(message_);
129331
+ let resumeTracking = resumeTrackingFromMessage(hookResumeTiming, incomingStepId !== void 0 ? "dispatched" : "inline");
129332
+ if (resumeTracking && incomingStepId === void 0) {
129333
+ resumeTracking.consumerStartedAtMs = handlerEnteredAtMs;
129334
+ }
129335
+ if (resumeTracking && !Number.isFinite(resumeTracking.consumerStartedAtMs)) {
129336
+ resumeTracking = void 0;
129337
+ }
128477
129338
  const traceContext = isUsableTraceCarrier(incomingTraceCarrier) ? incomingTraceCarrier : void 0;
128478
129339
  const { requestId } = metadata;
128479
129340
  const workflowName = metadata.queueName.slice(workflowPrefix.length);
@@ -128553,12 +129414,14 @@ function workflowEntrypoint(workflowCode2, options) {
128553
129414
  const replayRecoveryReporter = replayDivergence ? new ReplayRecoveryReporter(replayDivergence.count) : ReplayRecoveryReporter.inert();
128554
129415
  const createEvent = /* @__PURE__ */ __name(async (data, params) => {
128555
129416
  const sinceCursor = deltaRequestCursor(data, params);
128556
- const result2 = await replayRecoveryReporter.withEventCreate(sinceCursor === void 0 ? params : { ...params, sinceCursor }, (p) => world.events.create(runId, data, p));
129417
+ const withSnapshot = { ...slotSnapshot(), ...params };
129418
+ const result2 = await replayRecoveryReporter.withEventCreate(sinceCursor === void 0 ? withSnapshot : { ...withSnapshot, sinceCursor }, (p) => world.events.create(runId, data, p));
128557
129419
  if (sinceCursor !== void 0) {
128558
129420
  absorbCreateDelta(sinceCursor, result2);
128559
129421
  }
128560
129422
  return result2;
128561
129423
  }, "createEvent");
129424
+ const slotSnapshot = /* @__PURE__ */ __name(() => eventLog.type === "loadAll" ? {} : slotSnapshotParams(eventLog.events), "slotSnapshot");
128562
129425
  const deltaRequestCursor = /* @__PURE__ */ __name((data, params) => {
128563
129426
  if (turbo || eventLog.type !== "ready" || params?.sinceCursor !== void 0 || params?.preloadEvents === true || isTerminalRunEventType(data.eventType)) {
128564
129427
  return void 0;
@@ -128717,9 +129580,58 @@ function workflowEntrypoint(workflowCode2, options) {
128717
129580
  }, "guardDeployment");
128718
129581
  if (incomingStepId && incomingStepName) {
128719
129582
  try {
128720
- const bgRun = await world.runs.get(runId, {
128721
- resolveData: "none"
128722
- });
129583
+ const ensureStepFromMessage = /* @__PURE__ */ __name(async () => {
129584
+ if (!stepInput)
129585
+ return "ok";
129586
+ try {
129587
+ await world.events.create(runId, {
129588
+ eventType: "step_created",
129589
+ specVersion: SPEC_VERSION_CURRENT2,
129590
+ correlationId: incomingStepId,
129591
+ eventData: {
129592
+ stepName: incomingStepName,
129593
+ workflowName,
129594
+ // Typed Uint8Array by StepDispatchInputSchema:
129595
+ // a non-binary (mangled) payload fails the
129596
+ // message parse above and never reaches this
129597
+ // write.
129598
+ input: stepInput.input
129599
+ }
129600
+ }, {
129601
+ requestId,
129602
+ // Marks this create as a dispatch re-ensure so
129603
+ // a guard-enforcing backend can refuse it when
129604
+ // the producer's write was 412-rejected (the
129605
+ // dispatch was revoked). Surfaces as
129606
+ // RunExpiredError → 'gone' below, acking the
129607
+ // message. Worlds without the guard ignore it.
129608
+ viaStepDispatch: true
129609
+ });
129610
+ span?.setAttributes(StepResilientDispatchMaterialized2(true));
129611
+ runtimeLogger2.warn("Materialized step_created from the queue message \u2014 the producer\u2019s direct write did not land", {
129612
+ workflowRunId: runId,
129613
+ stepId: incomingStepId,
129614
+ stepName: incomingStepName
129615
+ });
129616
+ } catch (err) {
129617
+ if (EntityConflictError2.is(err))
129618
+ return "ok";
129619
+ if (RunExpiredError2.is(err))
129620
+ return "gone";
129621
+ throw err;
129622
+ }
129623
+ return "ok";
129624
+ }, "ensureStepFromMessage");
129625
+ const [bgRun, ensureOutcome] = await Promise.all([
129626
+ world.runs.get(runId, {
129627
+ resolveData: "none"
129628
+ }),
129629
+ stepInput && metadata.attempt > 1 ? ensureStepFromMessage() : "ok"
129630
+ ]);
129631
+ if (ensureOutcome === "gone") {
129632
+ runtimeLogger2.debug("Run already finished, skipping background step", { workflowRunId: runId });
129633
+ return;
129634
+ }
128723
129635
  if (bgRun.status !== "running") {
128724
129636
  runtimeLogger2.debug("Run already finished, skipping background step", { workflowRunId: runId, status: bgRun.status });
128725
129637
  return;
@@ -128727,7 +129639,11 @@ function workflowEntrypoint(workflowCode2, options) {
128727
129639
  if (await guardDeployment(bgRun, async () => ({
128728
129640
  ...await replayMessage(),
128729
129641
  stepId: incomingStepId,
128730
- stepName: incomingStepName
129642
+ stepName: incomingStepName,
129643
+ // Carry the resume timing verbatim so the re-routed
129644
+ // hop stays inside `step_dispatch` rather than
129645
+ // vanishing from the TTR decomposition.
129646
+ ...hookResumeTiming ? { hookResumeTiming } : {}
128731
129647
  })) !== "continue") {
128732
129648
  return;
128733
129649
  }
@@ -128738,10 +129654,12 @@ function workflowEntrypoint(workflowCode2, options) {
128738
129654
  const loaded = await loadWorkflowRunEvents(runId);
128739
129655
  bgAuthoritativeAttempt = countStepStartedEvents(loaded.events, incomingStepId, { type: "totalAttempts" }) + 1;
128740
129656
  }
129657
+ const bgResumeTracking = resumeTracking;
129658
+ resumeTracking = void 0;
128741
129659
  replayBudget.pause();
128742
129660
  let stepResult;
128743
129661
  try {
128744
- stepResult = await runStepSingleFlight(runId, incomingStepId, () => executeStep({
129662
+ const executeQueuedStep = /* @__PURE__ */ __name(() => executeStep({
128745
129663
  world,
128746
129664
  workflowRunId: runId,
128747
129665
  workflowDeploymentId: bgRun.deploymentId,
@@ -128754,8 +129672,22 @@ function workflowEntrypoint(workflowCode2, options) {
128754
129672
  // Retry ceiling: the queue delivery count as a fast
128755
129673
  // gate, verified against the recorded step_started
128756
129674
  // count once it crosses the ceiling (see above).
128757
- authoritativeAttempt: bgAuthoritativeAttempt
128758
- }));
129675
+ authoritativeAttempt: bgAuthoritativeAttempt,
129676
+ ...bgResumeTracking ? { resumeTracking: bgResumeTracking } : {}
129677
+ }), "executeQueuedStep");
129678
+ stepResult = await runStepSingleFlight(runId, incomingStepId, async () => {
129679
+ try {
129680
+ return await executeQueuedStep();
129681
+ } catch (err) {
129682
+ if (!stepInput || !isStepMissingError(err)) {
129683
+ throw err;
129684
+ }
129685
+ if (await ensureStepFromMessage() === "gone") {
129686
+ return { type: "gone" };
129687
+ }
129688
+ return await executeQueuedStep();
129689
+ }
129690
+ });
128759
129691
  } finally {
128760
129692
  replayBudget.resume();
128761
129693
  }
@@ -128863,7 +129795,12 @@ function workflowEntrypoint(workflowCode2, options) {
128863
129795
  });
128864
129796
  if (await guardDeployment(run3, async () => ({
128865
129797
  ...await replayMessage(),
128866
- hookInput
129798
+ hookInput,
129799
+ // Forwarded UNMODIFIED — in particular without
129800
+ // this delivery's entry time — so the misrouted
129801
+ // hop is attributed to `queue_delivery` and T2
129802
+ // ends up being the final consumer's entry.
129803
+ ...hookResumeTiming ? { hookResumeTiming } : {}
128867
129804
  }), awaitRunReady) !== "continue") {
128868
129805
  return;
128869
129806
  }
@@ -128915,6 +129852,9 @@ function workflowEntrypoint(workflowCode2, options) {
128915
129852
  workflowRun = result2.run;
128916
129853
  maxEventsLimit = clampMaxEvents(result2.maxEvents);
128917
129854
  runStartedReceivedAtMs = Date.now();
129855
+ if (resumeTracking) {
129856
+ resumeTracking.setupSource = "hook_preload";
129857
+ }
128918
129858
  eventLog = {
128919
129859
  type: "ready",
128920
129860
  events: result2.events,
@@ -129028,6 +129968,9 @@ function workflowEntrypoint(workflowCode2, options) {
129028
129968
  workflowRun = result2.run;
129029
129969
  maxEventsLimit = clampMaxEvents(result2.maxEvents);
129030
129970
  runStartedReceivedAtMs = Date.now();
129971
+ if (resumeTracking) {
129972
+ resumeTracking.setupSource = "run_started";
129973
+ }
129031
129974
  if (result2.events?.length) {
129032
129975
  const loaded = {
129033
129976
  events: [...result2.events],
@@ -129071,9 +130014,15 @@ function workflowEntrypoint(workflowCode2, options) {
129071
130014
  }
129072
130015
  }
129073
130016
  assert5(workflowRun, "Workflow run must be loaded before replay");
130017
+ if (resumeTracking && resumeTracking.setupSource === void 0) {
130018
+ resumeTracking.setupSource = "event_load";
130019
+ }
129074
130020
  if (await guardDeployment(workflowRun, async () => ({
129075
130021
  ...await replayMessage(),
129076
- ...hookInput ? { hookInput } : {}
130022
+ ...hookInput ? { hookInput } : {},
130023
+ // See the pre-check re-route above: forwarded as
130024
+ // received, so the extra hop is queue delivery.
130025
+ ...hookResumeTiming ? { hookResumeTiming } : {}
129077
130026
  }), awaitRunReady) !== "continue") {
129078
130027
  return;
129079
130028
  }
@@ -129137,7 +130086,8 @@ function workflowEntrypoint(workflowCode2, options) {
129137
130086
  workflowName,
129138
130087
  requestId,
129139
130088
  attempt: metadata.attempt,
129140
- limitMs: replayBudget.configuredLimitMs
130089
+ limitMs: replayBudget.configuredLimitMs,
130090
+ slotSnapshot: slotSnapshot()
129141
130091
  });
129142
130092
  return;
129143
130093
  }
@@ -129221,12 +130171,9 @@ function workflowEntrypoint(workflowCode2, options) {
129221
130171
  for (const waitEvent of waitsToComplete) {
129222
130172
  try {
129223
130173
  const created = await createEvent(waitEvent, {
129224
- requestId,
129225
- ...preconditionSnapshotParams(eventLog.events, eventLog.cursor)
130174
+ requestId
129226
130175
  });
129227
- if (created.events?.length && created.hasMore !== true) {
129228
- mergeReportedEvents(eventLog.events, created.events);
129229
- }
130176
+ absorbSkippedSlotReport(eventLog.events, created);
129230
130177
  } catch (err) {
129231
130178
  if (EntityConflictError2.is(err)) {
129232
130179
  runtimeLogger2.info("Wait already completed, skipping", {
@@ -129285,6 +130232,9 @@ function workflowEntrypoint(workflowCode2, options) {
129285
130232
  executionMode: retainedSession ? "retained" : "replay"
129286
130233
  });
129287
130234
  replayStart = Date.now();
130235
+ if (resumeTracking) {
130236
+ resumeTracking.replayStartedAtMs ??= replayStart;
130237
+ }
129288
130238
  const payloadPrewarm = replayPayloadCache.prewarm(workflowRun, eventLog.events);
129289
130239
  let workflowResult = retainedSession ? await resumeWorkflow(retainedSession, eventLog.events) : { type: "replay" };
129290
130240
  if (workflowResult.type === "replay") {
@@ -129321,10 +130271,7 @@ function workflowEntrypoint(workflowCode2, options) {
129321
130271
  eventType: "run_completed",
129322
130272
  specVersion: SPEC_VERSION_CURRENT2,
129323
130273
  eventData: { output: result2 }
129324
- }, {
129325
- requestId,
129326
- ...preconditionSnapshotParams(eventLog.events, eventLog.cursor)
129327
- });
130274
+ }, { requestId });
129328
130275
  } catch (err) {
129329
130276
  if (EntityConflictError2.is(err) || RunExpiredError2.is(err)) {
129330
130277
  runtimeLogger2.info("Tried completing workflow run, but run has already finished.", { workflowRunId: runId, message: err.message });
@@ -129339,7 +130286,11 @@ function workflowEntrypoint(workflowCode2, options) {
129339
130286
  } catch (err) {
129340
130287
  if (WorkflowSuspension2.is(err)) {
129341
130288
  replayRecoveryReporter.activate();
129342
- const replayDurationMs = Date.now() - replayStart;
130289
+ const suspendedAtMs = Date.now();
130290
+ const replayDurationMs = suspendedAtMs - replayStart;
130291
+ if (resumeTracking && err.stepCount > 0) {
130292
+ resumeTracking.nextStepEncounteredAtMs ??= suspendedAtMs;
130293
+ }
129343
130294
  runtimeLogger2.debug("Workflow suspended", {
129344
130295
  workflowRunId: runId,
129345
130296
  loopIteration,
@@ -129364,7 +130315,17 @@ function workflowEntrypoint(workflowCode2, options) {
129364
130315
  requestId,
129365
130316
  eventLog,
129366
130317
  runReadyBarrier,
129367
- replayRecoveryReporter
130318
+ replayRecoveryReporter,
130319
+ // Resilient step dispatch: lets eligible newly
130320
+ // created steps publish their step-execution
130321
+ // message (carrying `stepInput`) in parallel with
130322
+ // the step_created write. Steps queued there are
130323
+ // reported back in `queuedStepCorrelationIds` and
130324
+ // skipped by the dispatch pass below.
130325
+ stepDispatch: {
130326
+ queueName: getWorkflowQueueName2(workflowName, namespace),
130327
+ getTraceCarrier: nextTraceCarrier
130328
+ }
129368
130329
  });
129369
130330
  } catch (suspensionError) {
129370
130331
  if (PreconditionFailedError.is(suspensionError)) {
@@ -129454,10 +130415,14 @@ function workflowEntrypoint(workflowCode2, options) {
129454
130415
  const dispatchNowMs = Date.now();
129455
130416
  const ownedRecoverySteps = [];
129456
130417
  let backstopWakesArmed = 0;
130418
+ let handOffResumeTiming = resumeTracking !== void 0 && lazyInlineSteps.length === 0 && !pendingSteps.some((step) => !inlineCorrelationIds.has(step.correlationId) && inlineOwnership && isStepOwnershipActive(step) && step.ownerMessageId === metadata.messageId);
129457
130419
  for (const step of pendingSteps) {
129458
130420
  if (inlineCorrelationIds.has(step.correlationId)) {
129459
130421
  continue;
129460
130422
  }
130423
+ if (suspensionResult.queuedStepCorrelationIds.has(step.correlationId)) {
130424
+ continue;
130425
+ }
129461
130426
  const ownershipActive = inlineOwnership && isStepOwnershipActive(step);
129462
130427
  if (ownershipActive && step.ownerMessageId === metadata.messageId) {
129463
130428
  ownedRecoverySteps.push(step);
@@ -129482,14 +130447,27 @@ function workflowEntrypoint(workflowCode2, options) {
129482
130447
  }));
129483
130448
  continue;
129484
130449
  }
130450
+ const stepResumeTiming = handOffResumeTiming ? resumeTimingForMessage(resumeTracking) : void 0;
130451
+ if (stepResumeTiming) {
130452
+ handOffResumeTiming = false;
130453
+ resumeTracking = void 0;
130454
+ }
129485
130455
  dispatches.push(queueMessage(world, getWorkflowQueueName2(workflowName, namespace), {
129486
130456
  runId,
129487
130457
  stepId: step.correlationId,
129488
130458
  stepName: step.stepName,
129489
130459
  traceCarrier,
129490
- requestedAt: /* @__PURE__ */ new Date()
130460
+ requestedAt: /* @__PURE__ */ new Date(),
130461
+ ...stepResumeTiming ? { hookResumeTiming: stepResumeTiming } : {}
129491
130462
  }, {
129492
- idempotencyKey: step.correlationId
130463
+ // Step-identity-scoped: dedupes against every
130464
+ // other dispatch of THIS step (concurrent
130465
+ // handlers, crash-recovery re-dispatch, the
130466
+ // suspension handler's resilient publish)
130467
+ // without absorbing a dispatch of a different
130468
+ // step under a reassigned correlation id —
130469
+ // see stepDispatchIdempotencyKey.
130470
+ idempotencyKey: stepDispatchIdempotencyKey(step.correlationId, step.stepName)
129493
130471
  }));
129494
130472
  }
129495
130473
  if (suspensionResult.waitTimeout) {
@@ -129530,9 +130508,8 @@ function workflowEntrypoint(workflowCode2, options) {
129530
130508
  return;
129531
130509
  }
129532
130510
  const openHookWaitState = openHookWait.value;
129533
- const guardEnforced = isPreconditionGuardEnabled() && world.capabilities?.preconditionGuard === true;
129534
- const requestInlineDelta = typeof eventLog.cursor === "string" && err.stepCount === 1 && err.waitCount === 0 && pendingSteps.length === 1 && lazyInlineSteps.length === 1 && ownedRecoverySteps.length === 0 && !suspensionResult.waitTimeout && !openHookWaitState.openWait && (guardEnforced || err.hookCount === 0 && !openHookWaitState.openHook);
129535
- const suppressOptimisticStart = guardEnforced && (openHookWaitState.openHook || err.hookCount > 0 || suspensionResult.hasHookEvents);
130511
+ const requestInlineDelta = typeof eventLog.cursor === "string" && err.stepCount === 1 && err.waitCount === 0 && pendingSteps.length === 1 && lazyInlineSteps.length === 1 && ownedRecoverySteps.length === 0 && !suspensionResult.waitTimeout && !openHookWaitState.openWait;
130512
+ const suppressOptimisticStart = openHookWaitState.openHook || err.hookCount > 0 || suspensionResult.hasHookEvents;
129536
130513
  const forceOptimisticStart = turbo && !suspensionResult.hasAttributeEvents && !suspensionResult.waitTimeout && !suspensionResult.hasHookEvents && !suspensionResult.hasAwaitedHookCreation && !openHookWaitState.openHook && !openHookWaitState.openWait;
129537
130514
  const latencyTracking = computeStepLatencyTracking({
129538
130515
  events: eventLog.events,
@@ -129548,7 +130525,9 @@ function workflowEntrypoint(workflowCode2, options) {
129548
130525
  suspensionCreatedHooks: err.hookCount > 0 || suspensionResult.hasHookEvents,
129549
130526
  turbo
129550
130527
  });
129551
- const inlineClaimSnapshot = preconditionSnapshotParams(eventLog.events, eventLog.cursor);
130528
+ const inlineClaimSnapshot = slotSnapshotParams(eventLog.events);
130529
+ const batchResumeTracking = resumeTracking;
130530
+ resumeTracking = void 0;
129552
130531
  replayBudget.pause();
129553
130532
  let stepResults;
129554
130533
  const stepExecutionPromises = inlineExecutions.map((s, stepIndex) => {
@@ -129614,8 +130593,9 @@ function workflowEntrypoint(workflowCode2, options) {
129614
130593
  // see suppressOptimisticStart above.
129615
130594
  suppressOptimisticStart,
129616
130595
  runReadyBarrier,
129617
- preconditionSnapshot: inlineClaimSnapshot,
130596
+ slotSnapshot: inlineClaimSnapshot,
129618
130597
  ...stepIndex === 0 && s.lazyStepInput !== void 0 && latencyTracking ? { latencyTracking } : {},
130598
+ ...batchResumeTracking ? { resumeTracking: batchResumeTracking } : {},
129619
130599
  ...requestInlineDelta && eventLog.cursor ? {
129620
130600
  inlineDeltaSinceCursor: eventLog.cursor
129621
130601
  } : {},
@@ -129677,10 +130657,10 @@ function workflowEntrypoint(workflowCode2, options) {
129677
130657
  }, {
129678
130658
  delaySeconds,
129679
130659
  // Key the delayed retry on the step's
129680
- // correlationId so it dedupes against the
130660
+ // dispatch key so it dedupes against the
129681
130661
  // keyed re-dispatch the suspension handler
129682
- // performs on replay (it also uses
129683
- // `idempotencyKey: step.correlationId`).
130662
+ // performs on replay (it uses the same
130663
+ // stepDispatchIdempotencyKey).
129684
130664
  //
129685
130665
  // Without this, a mixed batch where one step
129686
130666
  // `completed` with unflushed background ops
@@ -129699,7 +130679,7 @@ function workflowEntrypoint(workflowCode2, options) {
129699
130679
  // retry body could run early/concurrently.
129700
130680
  // Sharing the key lets the earlier delayed
129701
130681
  // message win, honoring the backoff.
129702
- idempotencyKey: step.correlationId
130682
+ idempotencyKey: stepDispatchIdempotencyKey(step.correlationId, step.stepName)
129703
130683
  })));
129704
130684
  }
129705
130685
  if (anyPendingOps) {
@@ -146406,6 +147386,19 @@ var RunInputSchema = external_exports.object({
146406
147386
  */
146407
147387
  environment: external_exports.string().optional()
146408
147388
  });
147389
+ var StepDispatchInputSchema = external_exports.object({
147390
+ /**
147391
+ * The serialized step input, reused verbatim from the direct write. Always
147392
+ * binary: producers only attach \`stepInput\` when the dehydrated input is a
147393
+ * \`Uint8Array\` and the run's queue transport preserves bytes (CBOR).
147394
+ * Validated here so a malformed or transport-mangled payload fails the
147395
+ * message parse instead of being silently written into a \`step_created\` as
147396
+ * non-binary data. \`Buffer\` is a \`Uint8Array\` subclass and passes.
147397
+ */
147398
+ input: external_exports.custom((value) => value instanceof Uint8Array, {
147399
+ message: "stepInput.input must be a Uint8Array"
147400
+ })
147401
+ });
146409
147402
  var HookResumeInputSchema = external_exports.object({
146410
147403
  /** Stable idempotency key minted once per \`resumeHook()\` call. */
146411
147404
  resumeId: external_exports.string(),
@@ -146439,6 +147432,22 @@ var HookResumeInputSchema = external_exports.object({
146439
147432
  */
146440
147433
  deploymentId: external_exports.string().optional()
146441
147434
  });
147435
+ var HookResumeTimingSchema = external_exports.object({
147436
+ /** Epoch ms at entry into \`resumeHook()\` \u2014 the start of the TTR window. */
147437
+ resumeRequestedAtMs: external_exports.number(),
147438
+ /** Epoch ms immediately before the queue publish was requested. */
147439
+ queuePublishRequestedAtMs: external_exports.number(),
147440
+ /** Which \`resumeHook()\` dispatch path ran: \`parallel\` or \`sequential\`. */
147441
+ strategy: external_exports.string().optional(),
147442
+ /** Epoch ms the final consumer's queue handler was entered. */
147443
+ consumerStartedAtMs: external_exports.number().optional(),
147444
+ /** Epoch ms this invocation's first replay pass began. */
147445
+ replayStartedAtMs: external_exports.number().optional(),
147446
+ /** Epoch ms replay first encountered a durable step after the resume. */
147447
+ nextStepEncounteredAtMs: external_exports.number().optional(),
147448
+ /** How the consumer initialized replay state: see \`ResumeSetupSource\`. */
147449
+ setupSource: external_exports.string().optional()
147450
+ });
146442
147451
  var WorkflowInvokePayloadSchema = external_exports.object({
146443
147452
  runId: external_exports.string(),
146444
147453
  traceCarrier: TraceCarrierSchema.optional(),
@@ -146472,7 +147481,28 @@ var WorkflowInvokePayloadSchema = external_exports.object({
146472
147481
  * fast path. A consumer that understands this field idempotently ensures the
146473
147482
  * \`hook_received\` event exists (keyed by \`resumeId\`) before replaying.
146474
147483
  */
146475
- hookInput: HookResumeInputSchema.optional()
147484
+ hookInput: HookResumeInputSchema.optional(),
147485
+ /**
147486
+ * Resilient step dispatch data, only present alongside \`stepId\` when the
147487
+ * producer parallelized the \`step_created\` write with this queue publish. A
147488
+ * consumer that understands this field idempotently ensures the
147489
+ * \`step_created\` event exists (keyed by \`stepId\`) before executing the step.
147490
+ */
147491
+ stepInput: StepDispatchInputSchema.optional(),
147492
+ /**
147493
+ * Hook-resume TTR timing. Present on both \`resumeHook()\` dispatch paths
147494
+ * (unlike \`hookInput\`, which only rides the parallel fast path), and
147495
+ * forwarded onto a dispatched step message when the resuming invocation
147496
+ * hands the next durable step to another invocation. Purely observational \u2014
147497
+ * see {@link HookResumeTimingSchema}.
147498
+ *
147499
+ * \`.catch(undefined)\` because this field must never be able to fail the
147500
+ * parse of the invocation payload: a malformed value (a NaN boundary, a
147501
+ * shape change from a future producer) would otherwise throw on every
147502
+ * delivery of that message and burn the run's delivery budget over a
147503
+ * telemetry field. Anything unparseable degrades to "no measurement".
147504
+ */
147505
+ hookResumeTiming: HookResumeTimingSchema.optional().catch(void 0)
146476
147506
  });
146477
147507
  var HealthCheckPayloadSchema = external_exports.object({
146478
147508
  __healthCheck: external_exports.literal(true),
@@ -146630,10 +147660,10 @@ var Run = class _Run {
146630
147660
  return this.getReadable();
146631
147661
  }
146632
147662
  };
146633
- Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#wakeUp");
146634
- Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#cancel");
146635
- Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#getReadable");
146636
- var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#exists");
147663
+ Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#wakeUp");
147664
+ Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#cancel");
147665
+ Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#getReadable");
147666
+ var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#exists");
146637
147667
  Object.defineProperty(Run.prototype, "exists", {
146638
147668
  get() {
146639
147669
  return __step_Run$exists.call(this);
@@ -146641,7 +147671,7 @@ Object.defineProperty(Run.prototype, "exists", {
146641
147671
  configurable: true,
146642
147672
  enumerable: false
146643
147673
  });
146644
- var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#status");
147674
+ var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#status");
146645
147675
  Object.defineProperty(Run.prototype, "status", {
146646
147676
  get() {
146647
147677
  return __step_Run$status.call(this);
@@ -146649,7 +147679,7 @@ Object.defineProperty(Run.prototype, "status", {
146649
147679
  configurable: true,
146650
147680
  enumerable: false
146651
147681
  });
146652
- var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#returnValue");
147682
+ var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#returnValue");
146653
147683
  Object.defineProperty(Run.prototype, "returnValue", {
146654
147684
  get() {
146655
147685
  return __step_Run$returnValue.call(this);
@@ -146657,7 +147687,7 @@ Object.defineProperty(Run.prototype, "returnValue", {
146657
147687
  configurable: true,
146658
147688
  enumerable: false
146659
147689
  });
146660
- var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#workflowName");
147690
+ var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#workflowName");
146661
147691
  Object.defineProperty(Run.prototype, "workflowName", {
146662
147692
  get() {
146663
147693
  return __step_Run$workflowName.call(this);
@@ -146665,7 +147695,7 @@ Object.defineProperty(Run.prototype, "workflowName", {
146665
147695
  configurable: true,
146666
147696
  enumerable: false
146667
147697
  });
146668
- var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#createdAt");
147698
+ var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#createdAt");
146669
147699
  Object.defineProperty(Run.prototype, "createdAt", {
146670
147700
  get() {
146671
147701
  return __step_Run$createdAt.call(this);
@@ -146673,7 +147703,7 @@ Object.defineProperty(Run.prototype, "createdAt", {
146673
147703
  configurable: true,
146674
147704
  enumerable: false
146675
147705
  });
146676
- var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#startedAt");
147706
+ var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#startedAt");
146677
147707
  Object.defineProperty(Run.prototype, "startedAt", {
146678
147708
  get() {
146679
147709
  return __step_Run$startedAt.call(this);
@@ -146681,7 +147711,7 @@ Object.defineProperty(Run.prototype, "startedAt", {
146681
147711
  configurable: true,
146682
147712
  enumerable: false
146683
147713
  });
146684
- var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.41//Run#completedAt");
147714
+ var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.42//Run#completedAt");
146685
147715
  Object.defineProperty(Run.prototype, "completedAt", {
146686
147716
  get() {
146687
147717
  return __step_Run$completedAt.call(this);
@@ -146698,7 +147728,7 @@ Object.defineProperty(Run.prototype, "completedAt", {
146698
147728
  enumerable: false,
146699
147729
  configurable: false
146700
147730
  });
146701
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.41//Run");
147731
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.42//Run");
146702
147732
 
146703
147733
  // ../core/dist/workflow/create-hook.js
146704
147734
  aliasSerializationClass(RUN_CLASS_ID, Run);
@@ -146861,7 +147891,7 @@ hookWorkflow.workflowId = "workflow//./workflows/inline-execution//hookWorkflow"
146861
147891
  globalThis.__private_workflows.set("workflow//./workflows/inline-execution//hookWorkflow", hookWorkflow);
146862
147892
 
146863
147893
  // ../core/dist/runtime/start.js
146864
- var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.41//start");
147894
+ var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.42//start");
146865
147895
 
146866
147896
  // workflows/lineage.ts
146867
147897
  var noop = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//./workflows/lineage//noop");