@workflow/world-testing 5.0.0-beta.24 → 5.0.0-beta.26

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.
@@ -350,11 +350,11 @@ var init_dist5 = __esm({
350
350
  });
351
351
 
352
352
  // ../errors/dist/error-codes.js
353
- var RUN_ERROR_CODES;
353
+ var RUN_ERROR_CODES2;
354
354
  var init_error_codes2 = __esm({
355
355
  "../errors/dist/error-codes.js"() {
356
356
  "use strict";
357
- RUN_ERROR_CODES = {
357
+ RUN_ERROR_CODES2 = {
358
358
  /** Error thrown in user workflow or step code */
359
359
  USER_ERROR: "USER_ERROR",
360
360
  /** Internal runtime error (missing timestamps, runtime invariant failures) */
@@ -398,7 +398,7 @@ function buildFramedDetails2(hint3, slug) {
398
398
  out.push({ label: "docs", value: `${BASE_URL2}/${slug}` });
399
399
  return out;
400
400
  }
401
- var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError, WorkflowNotRegisteredError, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError, TooEarlyError, ThrottleError2, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2;
401
+ var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError2, WorkflowNotRegisteredError2, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError, TooEarlyError, ThrottleError2, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2;
402
402
  var init_dist6 = __esm({
403
403
  "../errors/dist/index.js"() {
404
404
  "use strict";
@@ -597,7 +597,7 @@ Caused by: ${options.cause.stack}`;
597
597
  return isError2(value) && value.name === "SerializationError";
598
598
  }
599
599
  };
600
- StepNotRegisteredError = class extends WorkflowRuntimeError2 {
600
+ StepNotRegisteredError2 = class extends WorkflowRuntimeError2 {
601
601
  static {
602
602
  __name(this, "StepNotRegisteredError");
603
603
  }
@@ -611,7 +611,7 @@ Caused by: ${options.cause.stack}`;
611
611
  return isError2(value) && value.name === "StepNotRegisteredError";
612
612
  }
613
613
  };
614
- WorkflowNotRegisteredError = class extends WorkflowRuntimeError2 {
614
+ WorkflowNotRegisteredError2 = class extends WorkflowRuntimeError2 {
615
615
  static {
616
616
  __name(this, "WorkflowNotRegisteredError");
617
617
  }
@@ -19204,7 +19204,7 @@ var version4;
19204
19204
  var init_version3 = __esm({
19205
19205
  "../core/dist/version.js"() {
19206
19206
  "use strict";
19207
- version4 = "5.0.0-beta.24";
19207
+ version4 = "5.0.0-beta.26";
19208
19208
  }
19209
19209
  });
19210
19210
 
@@ -19272,7 +19272,7 @@ async function handleHealthCheckMessage(healthCheck3, endpoint, worldSpecVersion
19272
19272
  await world.streams.close(fakeRunId, streamName);
19273
19273
  }
19274
19274
  function eventPaginationContractError(runId, message) {
19275
- return new WorkflowWorldError2(`Event pagination ${message} for workflow run "${runId}".`, { code: RUN_ERROR_CODES.WORLD_CONTRACT_ERROR });
19275
+ return new WorkflowWorldError2(`Event pagination ${message} for workflow run "${runId}".`, { code: RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR });
19276
19276
  }
19277
19277
  function recordRequestedEventCursor(runId, cursor, requestedCursors) {
19278
19278
  if (!cursor) {
@@ -25537,7 +25537,7 @@ function attachAbortListenerOnce2(signal, streamName, runId, cryptoKey, ops) {
25537
25537
  })());
25538
25538
  }, { once: true });
25539
25539
  }
25540
- function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
25540
+ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
25541
25541
  return {
25542
25542
  ...getAllBaseReducers2(global2),
25543
25543
  ReadableStream: /* @__PURE__ */ __name((value) => {
@@ -25551,7 +25551,7 @@ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, frame
25551
25551
  const streamId = (global2[STABLE_ULID2] || defaultUlid2)();
25552
25552
  const name = `strm_${streamId}`;
25553
25553
  const type = getStreamType2(value);
25554
- const writable = new WorkflowServerWritableStream2(runId, name);
25554
+ const writable = new WorkflowServerWritableStream2(runId, name, runReadyBarrier);
25555
25555
  if (type === "bytes") {
25556
25556
  if (framedByteStreams) {
25557
25557
  ops.push(value.pipeThrough(getByteFramingStream2()).pipeTo(writable));
@@ -25559,7 +25559,7 @@ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, frame
25559
25559
  ops.push(value.pipeTo(writable));
25560
25560
  }
25561
25561
  } else {
25562
- ops.push(value.pipeThrough(getSerializeStream2(getExternalReducers2(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
25562
+ ops.push(value.pipeThrough(getSerializeStream2(getExternalReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
25563
25563
  }
25564
25564
  const s = { name };
25565
25565
  if (type)
@@ -25668,7 +25668,7 @@ function getWorkflowReducers2(global2 = globalThis) {
25668
25668
  }, "AbortSignal")
25669
25669
  };
25670
25670
  }
25671
- function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
25671
+ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
25672
25672
  return {
25673
25673
  ...getAllBaseReducers2(global2),
25674
25674
  ReadableStream: /* @__PURE__ */ __name((value) => {
@@ -25687,7 +25687,7 @@ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByt
25687
25687
  name = `strm_${streamId}`;
25688
25688
  type = getStreamType2(value);
25689
25689
  framing = type === "bytes" && framedByteStreams ? "framed-v1" : framing;
25690
- const writable = new WorkflowServerWritableStream2(runId, name);
25690
+ const writable = new WorkflowServerWritableStream2(runId, name, runReadyBarrier);
25691
25691
  if (type === "bytes") {
25692
25692
  if (framing === "framed-v1") {
25693
25693
  ops.push(value.pipeThrough(getByteFramingStream2()).pipeTo(writable));
@@ -25695,7 +25695,7 @@ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByt
25695
25695
  ops.push(value.pipeTo(writable));
25696
25696
  }
25697
25697
  } else {
25698
- ops.push(value.pipeThrough(getSerializeStream2(getStepReducers2(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
25698
+ ops.push(value.pipeThrough(getSerializeStream2(getStepReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
25699
25699
  }
25700
25700
  }
25701
25701
  const s = { name };
@@ -26304,16 +26304,16 @@ async function hydrateStepArguments2(value, runId, key, ops = [], global2 = glob
26304
26304
  await recordCompression2(compressionStats, "deserialize");
26305
26305
  return result;
26306
26306
  }
26307
- async function dehydrateStepReturnValue2(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false) {
26307
+ async function dehydrateStepReturnValue2(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier) {
26308
26308
  if (v1Compat) {
26309
- const str = stringify2(value, getStepReducers2(global2, ops, runId, key, framedByteStreams));
26309
+ const str = stringify2(value, getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier));
26310
26310
  return revive2(str);
26311
26311
  }
26312
26312
  try {
26313
26313
  const compressionStats = {};
26314
26314
  const result = await serialize3(value, key, {
26315
26315
  global: global2,
26316
- extraReducers: getStreamAndRequestReducers2(getStepReducers2(global2, ops, runId, key, framedByteStreams)),
26316
+ extraReducers: getStreamAndRequestReducers2(getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier)),
26317
26317
  compression,
26318
26318
  compressionStats
26319
26319
  });
@@ -26514,7 +26514,16 @@ var init_serialization4 = __esm({
26514
26514
  static {
26515
26515
  __name(this, "WorkflowServerWritableStream");
26516
26516
  }
26517
- constructor(runId, name) {
26517
+ /**
26518
+ * @param runReadyBarrier Turbo mode only: a promise that resolves once the
26519
+ * backgrounded `run_started` has landed. When the step body runs
26520
+ * optimistically (before `run_started` is durable), the first chunk write to
26521
+ * a brand-new stream would otherwise reach the World before the run exists
26522
+ * and be rejected as run-not-found. Awaiting this once before the first
26523
+ * flush/close orders the write after the run's creation. `undefined` outside
26524
+ * turbo and on the await path, where the run was already durable.
26525
+ */
26526
+ constructor(runId, name, runReadyBarrier) {
26518
26527
  if (typeof runId !== "string") {
26519
26528
  throw new WorkflowRuntimeError2(`"runId" must be a string, got "${typeof runId}"`);
26520
26529
  }
@@ -26522,6 +26531,16 @@ var init_serialization4 = __esm({
26522
26531
  throw new WorkflowRuntimeError2(`"name" is required, got "${name}"`);
26523
26532
  }
26524
26533
  const worldPromise = getWorldLazy2();
26534
+ let pendingRunReady = runReadyBarrier;
26535
+ const ensureRunReady = /* @__PURE__ */ __name(async () => {
26536
+ if (pendingRunReady) {
26537
+ try {
26538
+ await pendingRunReady;
26539
+ } catch {
26540
+ }
26541
+ pendingRunReady = void 0;
26542
+ }
26543
+ }, "ensureRunReady");
26525
26544
  let buffer3 = [];
26526
26545
  let flushTimer = null;
26527
26546
  let flushPromise = null;
@@ -26533,6 +26552,7 @@ var init_serialization4 = __esm({
26533
26552
  }
26534
26553
  if (buffer3.length === 0)
26535
26554
  return;
26555
+ await ensureRunReady();
26536
26556
  const chunksToFlush = buffer3.slice();
26537
26557
  const world = await worldPromise;
26538
26558
  if (resolvedFlushIntervalMs === void 0) {
@@ -26582,6 +26602,7 @@ var init_serialization4 = __esm({
26582
26602
  flushPromise = null;
26583
26603
  }
26584
26604
  await flush();
26605
+ await ensureRunReady();
26585
26606
  const world = await worldPromise;
26586
26607
  await world.streams.close(runId, name);
26587
26608
  },
@@ -53042,7 +53063,7 @@ var require_token_util = __commonJS({
53042
53063
  findProjectInfo: /* @__PURE__ */ __name(() => findProjectInfo, "findProjectInfo"),
53043
53064
  getTokenPayload: /* @__PURE__ */ __name(() => getTokenPayload, "getTokenPayload"),
53044
53065
  getVercelDataDir: /* @__PURE__ */ __name(() => getVercelDataDir, "getVercelDataDir"),
53045
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
53066
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken5, "getVercelOidcToken"),
53046
53067
  getVercelToken: /* @__PURE__ */ __name(() => getVercelToken2, "getVercelToken"),
53047
53068
  isExpired: /* @__PURE__ */ __name(() => isExpired, "isExpired"),
53048
53069
  loadToken: /* @__PURE__ */ __name(() => loadToken, "loadToken"),
@@ -53104,7 +53125,7 @@ var require_token_util = __commonJS({
53104
53125
  }
53105
53126
  }
53106
53127
  __name(getVercelToken2, "getVercelToken");
53107
- async function getVercelOidcToken6(authToken, projectId, teamId) {
53128
+ async function getVercelOidcToken5(authToken, projectId, teamId) {
53108
53129
  const url3 = `https://api.vercel.com/v1/projects/${projectId}/token?source=vercel-oidc-refresh${teamId ? `&teamId=${teamId}` : ""}`;
53109
53130
  const res = await fetch(url3, {
53110
53131
  method: "POST",
@@ -53121,7 +53142,7 @@ var require_token_util = __commonJS({
53121
53142
  assertVercelOidcTokenResponse(tokenRes);
53122
53143
  return tokenRes;
53123
53144
  }
53124
- __name(getVercelOidcToken6, "getVercelOidcToken");
53145
+ __name(getVercelOidcToken5, "getVercelOidcToken");
53125
53146
  function assertVercelOidcTokenResponse(res) {
53126
53147
  if (!res || typeof res !== "object") {
53127
53148
  throw new TypeError(
@@ -53296,13 +53317,13 @@ var require_get_vercel_oidc_token = __commonJS({
53296
53317
  var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps3(__defProp3({}, "__esModule", { value: true }), mod), "__toCommonJS");
53297
53318
  var get_vercel_oidc_token_exports = {};
53298
53319
  __export3(get_vercel_oidc_token_exports, {
53299
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
53320
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken5, "getVercelOidcToken"),
53300
53321
  getVercelOidcTokenSync: /* @__PURE__ */ __name(() => getVercelOidcTokenSync2, "getVercelOidcTokenSync")
53301
53322
  });
53302
53323
  module.exports = __toCommonJS(get_vercel_oidc_token_exports);
53303
53324
  var import_get_context = require_get_context3();
53304
53325
  var import_token_error = require_token_error();
53305
- async function getVercelOidcToken6(options) {
53326
+ async function getVercelOidcToken5(options) {
53306
53327
  let token = "";
53307
53328
  let err;
53308
53329
  try {
@@ -53332,7 +53353,7 @@ ${error95.message}`;
53332
53353
  }
53333
53354
  return token;
53334
53355
  }
53335
- __name(getVercelOidcToken6, "getVercelOidcToken");
53356
+ __name(getVercelOidcToken5, "getVercelOidcToken");
53336
53357
  function getVercelOidcTokenSync2() {
53337
53358
  const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN;
53338
53359
  if (!token) {
@@ -55074,9 +55095,26 @@ var init_dist = __esm2({
55074
55095
  init_world_target();
55075
55096
  }
55076
55097
  });
55098
+ var RUN_ERROR_CODES;
55077
55099
  var init_error_codes = __esm2({
55078
55100
  "../errors/dist/error-codes.js"() {
55079
55101
  "use strict";
55102
+ RUN_ERROR_CODES = {
55103
+ /** Error thrown in user workflow or step code */
55104
+ USER_ERROR: "USER_ERROR",
55105
+ /** Internal runtime error (missing timestamps, runtime invariant failures) */
55106
+ RUNTIME_ERROR: "RUNTIME_ERROR",
55107
+ /** Event log contains orphaned or mismatched events and cannot be replayed */
55108
+ CORRUPTED_EVENT_LOG: "CORRUPTED_EVENT_LOG",
55109
+ /** One replay could not consume the event log deterministically; retryable */
55110
+ REPLAY_DIVERGENCE: "REPLAY_DIVERGENCE",
55111
+ /** Run exceeded the maximum number of queue deliveries */
55112
+ MAX_DELIVERIES_EXCEEDED: "MAX_DELIVERIES_EXCEEDED",
55113
+ /** Workflow replay exceeded the maximum allowed duration */
55114
+ REPLAY_TIMEOUT: "REPLAY_TIMEOUT",
55115
+ /** World response violated the SDK contract and cannot be retried safely */
55116
+ WORLD_CONTRACT_ERROR: "WORLD_CONTRACT_ERROR"
55117
+ };
55080
55118
  }
55081
55119
  });
55082
55120
  function isError(value) {
@@ -55120,6 +55158,8 @@ var WorkflowRunNotCompletedError;
55120
55158
  var WorkflowRuntimeError;
55121
55159
  var RuntimeDecryptionError;
55122
55160
  var SerializationError;
55161
+ var StepNotRegisteredError;
55162
+ var WorkflowNotRegisteredError;
55123
55163
  var WorkflowRunNotFoundError;
55124
55164
  var HookConflictError;
55125
55165
  var HookNotFoundError;
@@ -55323,6 +55363,44 @@ Caused by: ${options.cause.stack}`;
55323
55363
  return isError(value) && value.name === "SerializationError";
55324
55364
  }
55325
55365
  };
55366
+ StepNotRegisteredError = class extends WorkflowRuntimeError {
55367
+ static {
55368
+ __name(this, "StepNotRegisteredError");
55369
+ }
55370
+ static {
55371
+ __name2(this, "StepNotRegisteredError");
55372
+ }
55373
+ stepName;
55374
+ constructor(stepName) {
55375
+ super(`Step "${stepName}" is not registered in the current deployment. This usually indicates a build or bundling issue that caused the step to not be included in the deployment.`, {
55376
+ slug: ERROR_SLUGS.STEP_NOT_REGISTERED
55377
+ });
55378
+ this.name = "StepNotRegisteredError";
55379
+ this.stepName = stepName;
55380
+ }
55381
+ static is(value) {
55382
+ return isError(value) && value.name === "StepNotRegisteredError";
55383
+ }
55384
+ };
55385
+ WorkflowNotRegisteredError = class extends WorkflowRuntimeError {
55386
+ static {
55387
+ __name(this, "WorkflowNotRegisteredError");
55388
+ }
55389
+ static {
55390
+ __name2(this, "WorkflowNotRegisteredError");
55391
+ }
55392
+ workflowName;
55393
+ constructor(workflowName) {
55394
+ super(`Workflow "${workflowName}" is not registered in the current deployment. This usually means a run was started against a deployment that does not have this workflow, or there was a build/bundling issue.`, {
55395
+ slug: ERROR_SLUGS.WORKFLOW_NOT_REGISTERED
55396
+ });
55397
+ this.name = "WorkflowNotRegisteredError";
55398
+ this.workflowName = workflowName;
55399
+ }
55400
+ static is(value) {
55401
+ return isError(value) && value.name === "WorkflowNotRegisteredError";
55402
+ }
55403
+ };
55326
55404
  WorkflowRunNotFoundError = class extends WorkflowError {
55327
55405
  static {
55328
55406
  __name(this, "WorkflowRunNotFoundError");
@@ -79586,7 +79664,7 @@ var version2;
79586
79664
  var init_version = __esm2({
79587
79665
  "../core/dist/version.js"() {
79588
79666
  "use strict";
79589
- version2 = "5.0.0-beta.24";
79667
+ version2 = "5.0.0-beta.26";
79590
79668
  }
79591
79669
  });
79592
79670
  function getWorkflowQueueName(workflowName, namespace) {
@@ -81524,7 +81602,7 @@ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
81524
81602
  });
81525
81603
  }
81526
81604
  __name(attachAbortListenerOnce, "attachAbortListenerOnce");
81527
- function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
81605
+ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
81528
81606
  return {
81529
81607
  ...getAllBaseReducers(global2),
81530
81608
  ReadableStream: /* @__PURE__ */ __name2((value) => {
@@ -81537,7 +81615,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
81537
81615
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
81538
81616
  const name = `strm_${streamId}`;
81539
81617
  const type = getStreamType(value);
81540
- const writable = new WorkflowServerWritableStream(runId, name);
81618
+ const writable = new WorkflowServerWritableStream(runId, name, runReadyBarrier);
81541
81619
  if (type === "bytes") {
81542
81620
  if (framedByteStreams) {
81543
81621
  ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
@@ -81545,7 +81623,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
81545
81623
  ops.push(value.pipeTo(writable));
81546
81624
  }
81547
81625
  } else {
81548
- ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
81626
+ ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
81549
81627
  }
81550
81628
  const s = {
81551
81629
  name
@@ -81653,7 +81731,7 @@ function getWorkflowReducers(global2 = globalThis) {
81653
81731
  };
81654
81732
  }
81655
81733
  __name(getWorkflowReducers, "getWorkflowReducers");
81656
- function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
81734
+ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
81657
81735
  return {
81658
81736
  ...getAllBaseReducers(global2),
81659
81737
  ReadableStream: /* @__PURE__ */ __name2((value) => {
@@ -81671,7 +81749,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
81671
81749
  name = `strm_${streamId}`;
81672
81750
  type = getStreamType(value);
81673
81751
  framing = type === "bytes" && framedByteStreams ? "framed-v1" : framing;
81674
- const writable = new WorkflowServerWritableStream(runId, name);
81752
+ const writable = new WorkflowServerWritableStream(runId, name, runReadyBarrier);
81675
81753
  if (type === "bytes") {
81676
81754
  if (framing === "framed-v1") {
81677
81755
  ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
@@ -81679,7 +81757,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
81679
81757
  ops.push(value.pipeTo(writable));
81680
81758
  }
81681
81759
  } else {
81682
- ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
81760
+ ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
81683
81761
  }
81684
81762
  }
81685
81763
  const s = {
@@ -82200,16 +82278,16 @@ async function hydrateStepArguments(value, runId, key, ops = [], global2 = globa
82200
82278
  return result;
82201
82279
  }
82202
82280
  __name(hydrateStepArguments, "hydrateStepArguments");
82203
- async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false) {
82281
+ async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier) {
82204
82282
  if (v1Compat) {
82205
- const str = stringify(value, getStepReducers(global2, ops, runId, key, framedByteStreams));
82283
+ const str = stringify(value, getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier));
82206
82284
  return revive(str);
82207
82285
  }
82208
82286
  try {
82209
82287
  const compressionStats = {};
82210
82288
  const result = await serialize2(value, key, {
82211
82289
  global: global2,
82212
- extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams)),
82290
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier)),
82213
82291
  compression,
82214
82292
  compressionStats
82215
82293
  });
@@ -82367,7 +82445,16 @@ var init_serialization2 = __esm2({
82367
82445
  static {
82368
82446
  __name2(this, "WorkflowServerWritableStream");
82369
82447
  }
82370
- constructor(runId, name) {
82448
+ /**
82449
+ * @param runReadyBarrier Turbo mode only: a promise that resolves once the
82450
+ * backgrounded `run_started` has landed. When the step body runs
82451
+ * optimistically (before `run_started` is durable), the first chunk write to
82452
+ * a brand-new stream would otherwise reach the World before the run exists
82453
+ * and be rejected as run-not-found. Awaiting this once before the first
82454
+ * flush/close orders the write after the run's creation. `undefined` outside
82455
+ * turbo and on the await path, where the run was already durable.
82456
+ */
82457
+ constructor(runId, name, runReadyBarrier) {
82371
82458
  if (typeof runId !== "string") {
82372
82459
  throw new WorkflowRuntimeError(`"runId" must be a string, got "${typeof runId}"`);
82373
82460
  }
@@ -82375,6 +82462,16 @@ var init_serialization2 = __esm2({
82375
82462
  throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
82376
82463
  }
82377
82464
  const worldPromise = getWorldLazy();
82465
+ let pendingRunReady = runReadyBarrier;
82466
+ const ensureRunReady = /* @__PURE__ */ __name2(async () => {
82467
+ if (pendingRunReady) {
82468
+ try {
82469
+ await pendingRunReady;
82470
+ } catch {
82471
+ }
82472
+ pendingRunReady = void 0;
82473
+ }
82474
+ }, "ensureRunReady");
82378
82475
  let buffer22 = [];
82379
82476
  let flushTimer = null;
82380
82477
  let flushPromise = null;
@@ -82385,6 +82482,7 @@ var init_serialization2 = __esm2({
82385
82482
  flushTimer = null;
82386
82483
  }
82387
82484
  if (buffer22.length === 0) return;
82485
+ await ensureRunReady();
82388
82486
  const chunksToFlush = buffer22.slice();
82389
82487
  const world = await worldPromise;
82390
82488
  if (resolvedFlushIntervalMs === void 0) {
@@ -82434,6 +82532,7 @@ var init_serialization2 = __esm2({
82434
82532
  flushPromise = null;
82435
82533
  }
82436
82534
  await flush();
82535
+ await ensureRunReady();
82437
82536
  const world = await worldPromise;
82438
82537
  await world.streams.close(runId, name);
82439
82538
  },
@@ -82626,6 +82725,40 @@ function normalizeAttributeChanges(attrs, options = {}) {
82626
82725
  __name(normalizeAttributeChanges, "normalizeAttributeChanges");
82627
82726
  __name2(normalizeAttributeChanges, "normalizeAttributeChanges");
82628
82727
  init_capabilities();
82728
+ init_dist2();
82729
+ var WORLD_CONTRACT_ERROR_CODES = /* @__PURE__ */ new Set([
82730
+ "PARSE_ERROR",
82731
+ "SCHEMA_VALIDATION",
82732
+ RUN_ERROR_CODES.WORLD_CONTRACT_ERROR
82733
+ ]);
82734
+ var RETRYABLE_WORLD_ERROR_CODES = /* @__PURE__ */ new Set([
82735
+ "TRANSPORT",
82736
+ "TIMEOUT"
82737
+ ]);
82738
+ var RUNTIME_ERROR_CHECKS = [
82739
+ WorkflowRuntimeError.is,
82740
+ StepNotRegisteredError.is,
82741
+ WorkflowNotRegisteredError.is,
82742
+ // SDK-level encryption failures (most notably AES-GCM auth-tag
82743
+ // mismatches surfacing as a native `OperationError` from
82744
+ // `AESCipherJob.onDone`) are wrapped in `RuntimeDecryptionError` at
82745
+ // the encryption module boundary.
82746
+ RuntimeDecryptionError.is
82747
+ ];
82748
+ function isRetryableWorldError(err) {
82749
+ if (ThrottleError.is(err)) {
82750
+ return true;
82751
+ }
82752
+ if (!WorkflowWorldError.is(err)) {
82753
+ return false;
82754
+ }
82755
+ if (err.status !== void 0 && err.status >= 500) {
82756
+ return true;
82757
+ }
82758
+ return err.code !== void 0 && RETRYABLE_WORLD_ERROR_CODES.has(err.code);
82759
+ }
82760
+ __name(isRetryableWorldError, "isRetryableWorldError");
82761
+ __name2(isRetryableWorldError, "isRetryableWorldError");
82629
82762
  init_encryption();
82630
82763
  init_logger();
82631
82764
  init_serialization2();
@@ -82778,7 +82911,7 @@ async function start(workflow, argsOrOptions, options) {
82778
82911
  if (runCreatedResult.status === "rejected") {
82779
82912
  const err = runCreatedResult.reason;
82780
82913
  if (EntityConflictError.is(err)) {
82781
- } else if (isRetryableStartError(err)) {
82914
+ } else if (isRetryableWorldError(err)) {
82782
82915
  resilientStart = true;
82783
82916
  runtimeLogger.warn("Run creation event failed, but the run was accepted via the queue. The run_created event will be re-tried async by the runtime.", {
82784
82917
  workflowRunId: runId,
@@ -82823,14 +82956,7 @@ __name2(start, "start");
82823
82956
  value: "start",
82824
82957
  configurable: true
82825
82958
  });
82826
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.24//start");
82827
- function isRetryableStartError(err) {
82828
- if (ThrottleError.is(err)) return true;
82829
- if (WorkflowWorldError.is(err) && err.status && err.status >= 500) return true;
82830
- return false;
82831
- }
82832
- __name(isRetryableStartError, "isRetryableStartError");
82833
- __name2(isRetryableStartError, "isRetryableStartError");
82959
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.26//start");
82834
82960
  async function wakeUpRun(world, runId, options) {
82835
82961
  try {
82836
82962
  const run22 = await world.runs.get(runId, {
@@ -83157,7 +83283,7 @@ var Run = class _Run {
83157
83283
  value: "wakeUp",
83158
83284
  configurable: true
83159
83285
  });
83160
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#wakeUp");
83286
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#wakeUp");
83161
83287
  (function(__wf_fn, __wf_id) {
83162
83288
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83163
83289
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83166,7 +83292,7 @@ var Run = class _Run {
83166
83292
  value: "cancel",
83167
83293
  configurable: true
83168
83294
  });
83169
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#cancel");
83295
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#cancel");
83170
83296
  (function(__wf_fn, __wf_id) {
83171
83297
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83172
83298
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83175,7 +83301,7 @@ var Run = class _Run {
83175
83301
  value: "getReadable",
83176
83302
  configurable: true
83177
83303
  });
83178
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#getReadable");
83304
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#getReadable");
83179
83305
  (function(__wf_fn, __wf_id) {
83180
83306
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83181
83307
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83184,7 +83310,7 @@ var Run = class _Run {
83184
83310
  value: "exists",
83185
83311
  configurable: true
83186
83312
  });
83187
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#exists");
83313
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#exists");
83188
83314
  (function(__wf_fn, __wf_id) {
83189
83315
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83190
83316
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83193,7 +83319,7 @@ var Run = class _Run {
83193
83319
  value: "status",
83194
83320
  configurable: true
83195
83321
  });
83196
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#status");
83322
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#status");
83197
83323
  (function(__wf_fn, __wf_id) {
83198
83324
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83199
83325
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83202,7 +83328,7 @@ var Run = class _Run {
83202
83328
  value: "returnValue",
83203
83329
  configurable: true
83204
83330
  });
83205
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#returnValue");
83331
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#returnValue");
83206
83332
  (function(__wf_fn, __wf_id) {
83207
83333
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83208
83334
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83211,7 +83337,7 @@ var Run = class _Run {
83211
83337
  value: "workflowName",
83212
83338
  configurable: true
83213
83339
  });
83214
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#workflowName");
83340
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#workflowName");
83215
83341
  (function(__wf_fn, __wf_id) {
83216
83342
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83217
83343
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83220,7 +83346,7 @@ var Run = class _Run {
83220
83346
  value: "createdAt",
83221
83347
  configurable: true
83222
83348
  });
83223
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#createdAt");
83349
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#createdAt");
83224
83350
  (function(__wf_fn, __wf_id) {
83225
83351
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83226
83352
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83229,7 +83355,7 @@ var Run = class _Run {
83229
83355
  value: "startedAt",
83230
83356
  configurable: true
83231
83357
  });
83232
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#startedAt");
83358
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#startedAt");
83233
83359
  (function(__wf_fn, __wf_id) {
83234
83360
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83235
83361
  __wf_reg.set(__wf_id, __wf_fn);
@@ -83238,7 +83364,7 @@ var Run = class _Run {
83238
83364
  value: "completedAt",
83239
83365
  configurable: true
83240
83366
  });
83241
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.24//Run#completedAt");
83367
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.26//Run#completedAt");
83242
83368
  (function(__wf_cls, __wf_id) {
83243
83369
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
83244
83370
  __wf_reg.set(__wf_id, __wf_cls);
@@ -83248,7 +83374,7 @@ var Run = class _Run {
83248
83374
  enumerable: false,
83249
83375
  configurable: false
83250
83376
  });
83251
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.24//Run");
83377
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.26//Run");
83252
83378
  async function fetch2(...args) {
83253
83379
  return globalThis.fetch(...args);
83254
83380
  }
@@ -83710,15 +83836,16 @@ import { types as types6 } from "node:util";
83710
83836
 
83711
83837
  // ../core/dist/classify-error.js
83712
83838
  init_dist6();
83713
- var WORLD_CONTRACT_ERROR_CODES = /* @__PURE__ */ new Set([
83839
+ var WORLD_CONTRACT_ERROR_CODES2 = /* @__PURE__ */ new Set([
83714
83840
  "PARSE_ERROR",
83715
83841
  "SCHEMA_VALIDATION",
83716
- RUN_ERROR_CODES.WORLD_CONTRACT_ERROR
83842
+ RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR
83717
83843
  ]);
83718
- var RUNTIME_ERROR_CHECKS = [
83844
+ var RETRYABLE_WORLD_ERROR_CODES2 = /* @__PURE__ */ new Set(["TRANSPORT", "TIMEOUT"]);
83845
+ var RUNTIME_ERROR_CHECKS2 = [
83719
83846
  WorkflowRuntimeError2.is,
83720
- StepNotRegisteredError.is,
83721
- WorkflowNotRegisteredError.is,
83847
+ StepNotRegisteredError2.is,
83848
+ WorkflowNotRegisteredError2.is,
83722
83849
  // SDK-level encryption failures (most notably AES-GCM auth-tag
83723
83850
  // mismatches surfacing as a native `OperationError` from
83724
83851
  // `AESCipherJob.onDone`) are wrapped in `RuntimeDecryptionError` at
@@ -83730,25 +83857,38 @@ function isWorldContractError(err) {
83730
83857
  return false;
83731
83858
  }
83732
83859
  const cause = "cause" in err ? err.cause : void 0;
83733
- return err.code !== void 0 && WORLD_CONTRACT_ERROR_CODES.has(err.code) || err.message.startsWith("Failed to parse response body for ") || err.message.startsWith("Schema validation failed for ") || typeof cause === "object" && cause !== null && "name" in cause && cause.name === "ZodError";
83860
+ return err.code !== void 0 && WORLD_CONTRACT_ERROR_CODES2.has(err.code) || err.message.startsWith("Failed to parse response body for ") || err.message.startsWith("Schema validation failed for ") || typeof cause === "object" && cause !== null && "name" in cause && cause.name === "ZodError";
83734
83861
  }
83735
83862
  __name(isWorldContractError, "isWorldContractError");
83863
+ function isRetryableWorldError2(err) {
83864
+ if (ThrottleError2.is(err)) {
83865
+ return true;
83866
+ }
83867
+ if (!WorkflowWorldError2.is(err)) {
83868
+ return false;
83869
+ }
83870
+ if (err.status !== void 0 && err.status >= 500) {
83871
+ return true;
83872
+ }
83873
+ return err.code !== void 0 && RETRYABLE_WORLD_ERROR_CODES2.has(err.code);
83874
+ }
83875
+ __name(isRetryableWorldError2, "isRetryableWorldError");
83736
83876
  function classifyRunError(err) {
83737
83877
  if (ReplayDivergenceError.is(err)) {
83738
- return RUN_ERROR_CODES.REPLAY_DIVERGENCE;
83878
+ return RUN_ERROR_CODES2.REPLAY_DIVERGENCE;
83739
83879
  }
83740
83880
  if (CorruptedEventLogError.is(err)) {
83741
- return RUN_ERROR_CODES.CORRUPTED_EVENT_LOG;
83881
+ return RUN_ERROR_CODES2.CORRUPTED_EVENT_LOG;
83742
83882
  }
83743
- if (isWorldContractError(err)) {
83744
- return RUN_ERROR_CODES.WORLD_CONTRACT_ERROR;
83883
+ if (isWorldContractError(err) || isRetryableWorldError2(err)) {
83884
+ return RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR;
83745
83885
  }
83746
- for (const isMatch of RUNTIME_ERROR_CHECKS) {
83886
+ for (const isMatch of RUNTIME_ERROR_CHECKS2) {
83747
83887
  if (isMatch(err)) {
83748
- return RUN_ERROR_CODES.RUNTIME_ERROR;
83888
+ return RUN_ERROR_CODES2.RUNTIME_ERROR;
83749
83889
  }
83750
83890
  }
83751
- return RUN_ERROR_CODES.USER_ERROR;
83891
+ return RUN_ERROR_CODES2.USER_ERROR;
83752
83892
  }
83753
83893
  __name(classifyRunError, "classifyRunError");
83754
83894
 
@@ -83972,28 +84112,28 @@ function describeError(err, errorCode) {
83972
84112
  hint: RUNTIME_ERROR_HINT
83973
84113
  };
83974
84114
  }
83975
- if (effectiveCode === RUN_ERROR_CODES.REPLAY_TIMEOUT) {
84115
+ if (effectiveCode === RUN_ERROR_CODES2.REPLAY_TIMEOUT) {
83976
84116
  return {
83977
84117
  attribution: "sdk",
83978
84118
  errorCode: effectiveCode,
83979
84119
  hint: REPLAY_TIMEOUT_HINT
83980
84120
  };
83981
84121
  }
83982
- if (effectiveCode === RUN_ERROR_CODES.MAX_DELIVERIES_EXCEEDED) {
84122
+ if (effectiveCode === RUN_ERROR_CODES2.MAX_DELIVERIES_EXCEEDED) {
83983
84123
  return {
83984
84124
  attribution: "sdk",
83985
84125
  errorCode: effectiveCode,
83986
84126
  hint: MAX_DELIVERIES_HINT
83987
84127
  };
83988
84128
  }
83989
- if (effectiveCode === RUN_ERROR_CODES.CORRUPTED_EVENT_LOG) {
84129
+ if (effectiveCode === RUN_ERROR_CODES2.CORRUPTED_EVENT_LOG) {
83990
84130
  return {
83991
84131
  attribution: "sdk",
83992
84132
  errorCode: effectiveCode,
83993
84133
  hint: CORRUPTED_EVENT_LOG_HINT
83994
84134
  };
83995
84135
  }
83996
- if (effectiveCode === RUN_ERROR_CODES.WORLD_CONTRACT_ERROR) {
84136
+ if (effectiveCode === RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR) {
83997
84137
  return {
83998
84138
  attribution: "sdk",
83999
84139
  errorCode: effectiveCode,
@@ -84458,6 +84598,10 @@ function hasTag(fileId, tag) {
84458
84598
  return fileId.endsWith(`.${tag}`);
84459
84599
  }
84460
84600
  __name(hasTag, "hasTag");
84601
+ function isUntagged(fileId) {
84602
+ return !TAG_PATTERN.test(fileId);
84603
+ }
84604
+ __name(isUntagged, "isUntagged");
84461
84605
  function taggedPath(basedir, entityDir, fileId, tag) {
84462
84606
  assertSafeEntityId("fileId", fileId);
84463
84607
  if (tag !== void 0)
@@ -85199,34 +85343,54 @@ function createQueue(config4) {
85199
85343
  await semaphore.acquire();
85200
85344
  }
85201
85345
  const MAX_LOCAL_SAFETY_LIMIT = 256;
85346
+ let delivery = 0;
85202
85347
  try {
85203
- for (let attempt = 0; attempt < MAX_LOCAL_SAFETY_LIMIT; attempt++) {
85348
+ for (let loop = 0; loop < MAX_LOCAL_SAFETY_LIMIT; loop++) {
85204
85349
  const headers = {
85205
85350
  ...opts?.headers,
85206
85351
  "content-type": "application/json",
85207
85352
  "x-vqs-queue-name": queueName,
85208
85353
  "x-vqs-message-id": messageId,
85209
- "x-vqs-message-attempt": String(attempt + 1)
85354
+ "x-vqs-message-attempt": String(delivery + 1)
85210
85355
  };
85211
85356
  const directHandler = directHandlers.get(prefix);
85212
85357
  let response;
85213
- if (directHandler) {
85214
- const req = new Request(`http://localhost/.well-known/workflow/v1/${pathname}`, {
85215
- method: "POST",
85216
- headers,
85217
- body
85218
- });
85219
- response = await directHandler(req);
85220
- } else {
85221
- const baseUrl = await resolveBaseUrl(config4);
85222
- response = await fetch(`${baseUrl}/.well-known/workflow/v1/${pathname}`, {
85223
- method: "POST",
85224
- duplex: "half",
85225
- dispatcher: httpAgent,
85226
- headers,
85227
- body
85358
+ try {
85359
+ if (directHandler) {
85360
+ const req = new Request(`http://localhost/.well-known/workflow/v1/${pathname}`, {
85361
+ method: "POST",
85362
+ headers,
85363
+ body
85364
+ });
85365
+ response = await directHandler(req);
85366
+ } else {
85367
+ const baseUrl = await resolveBaseUrl(config4);
85368
+ response = await fetch(`${baseUrl}/.well-known/workflow/v1/${pathname}`, {
85369
+ method: "POST",
85370
+ duplex: "half",
85371
+ dispatcher: httpAgent,
85372
+ headers,
85373
+ body
85374
+ });
85375
+ }
85376
+ } catch (err) {
85377
+ const name = err?.name;
85378
+ if (closeSignal.aborted || name === "AbortError" || name === "ResponseAborted") {
85379
+ return;
85380
+ }
85381
+ if (isDetachedArrayBufferQueueError(err))
85382
+ throw err;
85383
+ console.error(`[world-local] Queue delivery failed at the transport (loop ${loop + 1}), retrying`, {
85384
+ queueName,
85385
+ messageId,
85386
+ ...runId && { runId },
85387
+ ...stepId && { stepId },
85388
+ error: String(err)
85228
85389
  });
85390
+ await setTimeout2(5e3, void 0, { signal: closeSignal });
85391
+ continue;
85229
85392
  }
85393
+ delivery++;
85230
85394
  const text = await response.text();
85231
85395
  if (response.ok) {
85232
85396
  try {
@@ -85244,7 +85408,7 @@ function createQueue(config4) {
85244
85408
  }
85245
85409
  return;
85246
85410
  }
85247
- console.error(`[world-local] Queue message failed (attempt ${attempt + 1}, HTTP ${response.status})`, {
85411
+ console.error(`[world-local] Queue message failed (attempt ${delivery}, HTTP ${response.status})`, {
85248
85412
  queueName,
85249
85413
  messageId,
85250
85414
  ...runId && { runId },
@@ -87031,13 +87195,14 @@ function createLocalWorld(args) {
87031
87195
  if (!recoverActiveRuns) {
87032
87196
  return;
87033
87197
  }
87034
- const recoveryRuns = tag ? {
87198
+ const fileIdFilter = tag ? (fileId) => hasTag(fileId, tag) : isUntagged;
87199
+ const recoveryRuns = {
87035
87200
  ...storage.runs,
87036
87201
  list: /* @__PURE__ */ __name(((params) => storage.runs.list({
87037
87202
  ...params,
87038
- fileIdFilter: /* @__PURE__ */ __name((fileId) => hasTag(fileId, tag), "fileIdFilter")
87203
+ fileIdFilter
87039
87204
  })), "list")
87040
- } : storage.runs;
87205
+ };
87041
87206
  await reenqueueActiveRuns(recoveryRuns, queue.queue, "world-local");
87042
87207
  },
87043
87208
  async close() {
@@ -87089,41 +87254,316 @@ __name(createLocalWorld, "createLocalWorld");
87089
87254
  init_dist7();
87090
87255
 
87091
87256
  // ../world-vercel/dist/encryption.js
87092
- var import_oidc = __toESM(require_dist(), 1);
87093
87257
  init_zod2();
87094
87258
  import { webcrypto } from "node:crypto";
87095
87259
 
87096
87260
  // ../world-vercel/dist/http-client.js
87097
87261
  var import_undici2 = __toESM(require_undici(), 1);
87098
87262
  var _dispatcher;
87263
+ var _eventsDispatcher;
87264
+ var _streamDispatcher;
87265
+ var BASE_AGENT_OPTIONS = {
87266
+ connections: 8,
87267
+ keepAliveTimeout: 1e4,
87268
+ // HTTP/1.1 pipelining is disabled (pipelining: 1) because it causes
87269
+ // head-of-line blocking that deadlocks the webhook respondWith mechanism.
87270
+ pipelining: 1
87271
+ };
87272
+ var DEFAULT_AGENT_OPTIONS = {
87273
+ ...BASE_AGENT_OPTIONS,
87274
+ allowH2: false
87275
+ };
87276
+ var EVENTS_AGENT_OPTIONS = {
87277
+ ...BASE_AGENT_OPTIONS,
87278
+ allowH2: true
87279
+ };
87280
+ var RETRY_AGENT_OPTIONS = {
87281
+ // Observe Retry-After header if received
87282
+ retryAfter: true,
87283
+ // Retry 5xx in-process (genuine transient blips recover fast), but NOT 429.
87284
+ // The Vercel firewall issues a challenge as a 429: our server-to-server
87285
+ // client cannot solve a challenge, so in-process retries just re-trigger it
87286
+ // ~5× per request and amplify load against an already-overloaded firewall
87287
+ // during an incident. Letting 429 pass through surfaces it immediately to
87288
+ // makeRequest — which maps it to a ThrottleError carrying the
87289
+ // `x-vercel-mitigated` / `x-vercel-id` headers — and the queue does the
87290
+ // (backed-off) retry instead. This is the long-standing "let 429s pass
87291
+ // through" intent. (undici default is [500, 502, 503, 504, 429].)
87292
+ statusCodes: [500, 502, 503, 504]
87293
+ };
87294
+ var STREAM_RETRY_OPTIONS = {
87295
+ retryAfter: true,
87296
+ methods: ["PUT"],
87297
+ statusCodes: [429]
87298
+ };
87099
87299
  function getDispatcher(config4) {
87100
87300
  return config4?.dispatcher ?? getDefaultDispatcher();
87101
87301
  }
87102
87302
  __name(getDispatcher, "getDispatcher");
87303
+ function getEventsDispatcher(config4) {
87304
+ return config4?.dispatcher ?? getDefaultEventsDispatcher();
87305
+ }
87306
+ __name(getEventsDispatcher, "getEventsDispatcher");
87307
+ function getStreamDispatcher(config4) {
87308
+ return config4?.dispatcher ?? getDefaultStreamDispatcher();
87309
+ }
87310
+ __name(getStreamDispatcher, "getStreamDispatcher");
87311
+ function makeRetryDispatcher(agentOptions, retryOptions) {
87312
+ return new import_undici2.RetryAgent(new import_undici2.Agent(agentOptions), retryOptions);
87313
+ }
87314
+ __name(makeRetryDispatcher, "makeRetryDispatcher");
87103
87315
  function getDefaultDispatcher() {
87104
- if (!_dispatcher) {
87105
- _dispatcher = new import_undici2.RetryAgent(new import_undici2.Agent({
87106
- connections: 8,
87107
- keepAliveTimeout: 1e4,
87108
- // H2 is specifically incompatible with SvelteKit on Vercel prod. Everything else
87109
- // runs fine.
87110
- // TODO: Investigate/fix the failure on SvelteKit so we can re-enable H2.
87111
- allowH2: false,
87112
- // HTTP/1.1 pipelining is disabled (pipelining: 1) because it causes
87113
- // head-of-line blocking that deadlocks the webhook respondWith mechanism.
87114
- pipelining: 1
87115
- }), {
87116
- // Observe Retry-After header if received
87117
- retryAfter: true
87118
- // By default, we observe re-try headers, and also separately
87119
- // re-try on these status codes: 429 / 500 / 502 / 503 / 504.
87120
- // TODO: We might want to let 429s pass through, so that we can do
87121
- // runtime retry-after handling through the queue.
87122
- });
87123
- }
87316
+ _dispatcher ??= makeRetryDispatcher(DEFAULT_AGENT_OPTIONS, RETRY_AGENT_OPTIONS);
87124
87317
  return _dispatcher;
87125
87318
  }
87126
87319
  __name(getDefaultDispatcher, "getDefaultDispatcher");
87320
+ function getDefaultEventsDispatcher() {
87321
+ _eventsDispatcher ??= makeRetryDispatcher(EVENTS_AGENT_OPTIONS, RETRY_AGENT_OPTIONS);
87322
+ return _eventsDispatcher;
87323
+ }
87324
+ __name(getDefaultEventsDispatcher, "getDefaultEventsDispatcher");
87325
+ function getDefaultStreamDispatcher() {
87326
+ _streamDispatcher ??= makeRetryDispatcher(EVENTS_AGENT_OPTIONS, STREAM_RETRY_OPTIONS);
87327
+ return _streamDispatcher;
87328
+ }
87329
+ __name(getDefaultStreamDispatcher, "getDefaultStreamDispatcher");
87330
+
87331
+ // ../world-vercel/dist/http-core.js
87332
+ var import_oidc = __toESM(require_dist(), 1);
87333
+ init_dist6();
87334
+
87335
+ // ../world-vercel/dist/telemetry.js
87336
+ var otelApiPromise2 = null;
87337
+ async function getOtelApi2() {
87338
+ if (!otelApiPromise2) {
87339
+ otelApiPromise2 = Promise.resolve().then(() => (init_esm(), esm_exports)).catch(() => null);
87340
+ }
87341
+ return otelApiPromise2;
87342
+ }
87343
+ __name(getOtelApi2, "getOtelApi");
87344
+ var tracerPromise2 = null;
87345
+ async function getTracer2() {
87346
+ if (!tracerPromise2) {
87347
+ tracerPromise2 = getOtelApi2().then((otel) => otel ? otel.trace.getTracer("workflow") : null);
87348
+ }
87349
+ return tracerPromise2;
87350
+ }
87351
+ __name(getTracer2, "getTracer");
87352
+ async function trace5(spanName, ...args) {
87353
+ const [tracer, otel] = await Promise.all([getTracer2(), getOtelApi2()]);
87354
+ const { fn, opts } = typeof args[0] === "function" ? { fn: args[0], opts: {} } : { fn: args[1], opts: args[0] };
87355
+ if (!fn)
87356
+ throw new Error("Function to trace must be provided");
87357
+ if (!tracer || !otel) {
87358
+ return await fn();
87359
+ }
87360
+ return tracer.startActiveSpan(spanName, opts, async (span) => {
87361
+ try {
87362
+ const result = await fn(span);
87363
+ span.setStatus({ code: otel.SpanStatusCode.OK });
87364
+ return result;
87365
+ } catch (e) {
87366
+ span.setStatus({
87367
+ code: otel.SpanStatusCode.ERROR,
87368
+ message: e.message
87369
+ });
87370
+ throw e;
87371
+ } finally {
87372
+ span.end();
87373
+ }
87374
+ });
87375
+ }
87376
+ __name(trace5, "trace");
87377
+ async function getSpanKind3(field) {
87378
+ const otel = await getOtelApi2();
87379
+ if (!otel)
87380
+ return void 0;
87381
+ return otel.SpanKind[field];
87382
+ }
87383
+ __name(getSpanKind3, "getSpanKind");
87384
+ async function injectTraceContextIntoHeaders(headers) {
87385
+ const otel = await getOtelApi2();
87386
+ if (!otel)
87387
+ return;
87388
+ const carrier = {};
87389
+ otel.propagation.inject(otel.context.active(), carrier);
87390
+ for (const [key, value] of Object.entries(carrier)) {
87391
+ headers.set(key, value);
87392
+ }
87393
+ }
87394
+ __name(injectTraceContextIntoHeaders, "injectTraceContextIntoHeaders");
87395
+ function SemanticConvention4(...names) {
87396
+ return (value) => Object.fromEntries(names.map((name) => [name, value]));
87397
+ }
87398
+ __name(SemanticConvention4, "SemanticConvention");
87399
+ var HttpRequestMethod3 = SemanticConvention4("http.request.method");
87400
+ var UrlFull3 = SemanticConvention4("url.full");
87401
+ var ServerAddress3 = SemanticConvention4("server.address");
87402
+ var ServerPort3 = SemanticConvention4("server.port");
87403
+ var HttpResponseStatusCode3 = SemanticConvention4("http.response.status_code");
87404
+ var ErrorType3 = SemanticConvention4("error.type");
87405
+ var WorldParseFormat3 = SemanticConvention4("workflow.world.parse.format");
87406
+ var PeerService4 = SemanticConvention4("peer.service");
87407
+ var RpcSystem4 = SemanticConvention4("rpc.system");
87408
+ var RpcService4 = SemanticConvention4("rpc.service");
87409
+ var RpcMethod4 = SemanticConvention4("rpc.method");
87410
+ var WorkflowRunId4 = SemanticConvention4("workflow.run.id");
87411
+ var StepId4 = SemanticConvention4("step.id");
87412
+
87413
+ // ../world-vercel/dist/http-core.js
87414
+ var REQUEST_TIMEOUT_MS = 6e4;
87415
+ var HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
87416
+ var DIAGNOSTIC_HEADERS = [
87417
+ "x-vercel-id",
87418
+ "x-vercel-error",
87419
+ "x-vercel-mitigated"
87420
+ ];
87421
+ function getVercelDiagnostics(headers) {
87422
+ return DIAGNOSTIC_HEADERS.flatMap((header) => {
87423
+ const value = headers.get(header);
87424
+ return value ? [`${header}=${value}`] : [];
87425
+ });
87426
+ }
87427
+ __name(getVercelDiagnostics, "getVercelDiagnostics");
87428
+ function formatVercelDiagnostics(headers) {
87429
+ const diagnostics = getVercelDiagnostics(headers);
87430
+ return diagnostics.length > 0 ? ` (${diagnostics.join("; ")})` : "";
87431
+ }
87432
+ __name(formatVercelDiagnostics, "formatVercelDiagnostics");
87433
+ function httpLog(method, label, response, ms2) {
87434
+ if (!HTTP_DEBUG_ENABLED)
87435
+ return;
87436
+ const diagnostics = getVercelDiagnostics(response.headers);
87437
+ const suffix = diagnostics.length > 0 ? `; ${diagnostics.join("; ")}` : "";
87438
+ console.debug(`[workflow:world-vercel:http] ${method} ${label} -> ${response.status} (${ms2}ms${suffix})`);
87439
+ }
87440
+ __name(httpLog, "httpLog");
87441
+ function logCurlRepro(method, url3, headers) {
87442
+ if (!process.env.DEBUG)
87443
+ return;
87444
+ const stringifiedHeaders = Array.from(headers.entries()).filter(([key]) => key.toLowerCase() !== "authorization").map(([key, value]) => `-H "${key}: ${value}"`).join(" ");
87445
+ console.error(`Failed to fetch, reproduce with:
87446
+ curl -X ${method} ${stringifiedHeaders} "${url3}"`);
87447
+ }
87448
+ __name(logCurlRepro, "logCurlRepro");
87449
+ function parseRetryAfter(value) {
87450
+ if (!value)
87451
+ return void 0;
87452
+ const parsed = parseInt(value, 10);
87453
+ return Number.isNaN(parsed) ? void 0 : parsed;
87454
+ }
87455
+ __name(parseRetryAfter, "parseRetryAfter");
87456
+ function errorForResponse(status, message, opts = {}) {
87457
+ const { retryAfter, code: code3, url: url3, mitigated } = opts;
87458
+ if (status === 409)
87459
+ return new EntityConflictError2(message);
87460
+ if (status === 410)
87461
+ return new RunExpiredError(message);
87462
+ if (status === 425)
87463
+ return new TooEarlyError(message, { retryAfter });
87464
+ if (status === 429) {
87465
+ if (isFirewallChallenge429(status, mitigated)) {
87466
+ return new WorkflowWorldError2(`${message} (x-vercel-mitigated=challenge)`, {
87467
+ url: url3,
87468
+ status,
87469
+ code: "TRANSPORT",
87470
+ retryAfter
87471
+ });
87472
+ }
87473
+ return new ThrottleError2(message, { retryAfter });
87474
+ }
87475
+ return new WorkflowWorldError2(message, { url: url3, status, code: code3, retryAfter });
87476
+ }
87477
+ __name(errorForResponse, "errorForResponse");
87478
+ function isFirewallChallenge429(status, mitigated) {
87479
+ return status === 429 && mitigated === "challenge";
87480
+ }
87481
+ __name(isFirewallChallenge429, "isFirewallChallenge429");
87482
+ async function resolveVercelApiToken(opts) {
87483
+ return opts?.token ?? process.env.VERCEL_TOKEN ?? await (0, import_oidc.getVercelOidcToken)().catch(() => null);
87484
+ }
87485
+ __name(resolveVercelApiToken, "resolveVercelApiToken");
87486
+ function parseServer(url3) {
87487
+ try {
87488
+ const parsed = new URL(url3);
87489
+ return {
87490
+ serverAddress: parsed.hostname,
87491
+ serverPort: parsed.port ? parseInt(parsed.port, 10) : parsed.protocol === "https:" ? 443 : 80
87492
+ };
87493
+ } catch {
87494
+ return {};
87495
+ }
87496
+ }
87497
+ __name(parseServer, "parseServer");
87498
+ function httpClientSpanAttributes(args) {
87499
+ const { method, url: url3, peerService } = args;
87500
+ const { serverAddress, serverPort } = parseServer(url3);
87501
+ return {
87502
+ ...HttpRequestMethod3(method),
87503
+ ...UrlFull3(url3),
87504
+ ...serverAddress ? ServerAddress3(serverAddress) : {},
87505
+ ...serverPort ? ServerPort3(serverPort) : {},
87506
+ ...PeerService4(peerService),
87507
+ ...RpcSystem4("http"),
87508
+ ...RpcService4(peerService)
87509
+ };
87510
+ }
87511
+ __name(httpClientSpanAttributes, "httpClientSpanAttributes");
87512
+ async function instrumentedFetch(opts) {
87513
+ const { method, url: url3, headers, body, dispatcher, peerService = "workflow-server", timeoutMs = REQUEST_TIMEOUT_MS, signal: callerSignal, injectTraceContext = true, cacheBust = true, logLabel, buildError } = opts;
87514
+ const label = logLabel ?? url3;
87515
+ return trace5(`http ${method}`, { kind: await getSpanKind3("CLIENT") }, async (span) => {
87516
+ span?.setAttributes(httpClientSpanAttributes({ method, url: url3, peerService }));
87517
+ if (injectTraceContext)
87518
+ await injectTraceContextIntoHeaders(headers);
87519
+ if (cacheBust)
87520
+ headers.set("X-Request-Time", Date.now().toString());
87521
+ const timeoutSignal = timeoutMs != null ? AbortSignal.timeout(timeoutMs) : void 0;
87522
+ const signal = callerSignal && timeoutSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : callerSignal ?? timeoutSignal;
87523
+ const start3 = Date.now();
87524
+ let response;
87525
+ try {
87526
+ response = await fetch(url3, {
87527
+ method,
87528
+ headers,
87529
+ body,
87530
+ signal,
87531
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
87532
+ dispatcher
87533
+ });
87534
+ } catch (error95) {
87535
+ const elapsed = Date.now() - start3;
87536
+ if (error95 instanceof Error && (error95.name === "TimeoutError" || error95.name === "AbortError")) {
87537
+ const timeoutError = new WorkflowWorldError2(`${method} ${label} timed out after ${elapsed}ms`, { url: url3, cause: error95 });
87538
+ span?.setAttributes({ ...ErrorType3("TIMEOUT") });
87539
+ span?.recordException?.(timeoutError);
87540
+ throw timeoutError;
87541
+ }
87542
+ throw error95;
87543
+ }
87544
+ const ms2 = Date.now() - start3;
87545
+ httpLog(method, label, response, ms2);
87546
+ span?.setAttributes({ ...HttpResponseStatusCode3(response.status) });
87547
+ if (!response.ok) {
87548
+ span?.setAttributes({ ...ErrorType3(`HTTP ${response.status}`) });
87549
+ logCurlRepro(method, url3, headers);
87550
+ if (buildError) {
87551
+ const error96 = await buildError(response);
87552
+ span?.recordException?.(error96);
87553
+ throw error96;
87554
+ }
87555
+ const text = await response.text().catch(() => "");
87556
+ const error95 = errorForResponse(response.status, `${method} ${label} -> HTTP ${response.status}: ${response.statusText}${text ? ` ${text}` : ""}${formatVercelDiagnostics(response.headers)}`, {
87557
+ url: url3,
87558
+ retryAfter: parseRetryAfter(response.headers.get("Retry-After"))
87559
+ });
87560
+ span?.recordException?.(error95);
87561
+ throw error95;
87562
+ }
87563
+ return response;
87564
+ });
87565
+ }
87566
+ __name(instrumentedFetch, "instrumentedFetch");
87127
87567
 
87128
87568
  // ../world-vercel/dist/encryption.js
87129
87569
  var KEY_BYTES = 32;
@@ -87151,7 +87591,7 @@ async function deriveRunKey(deploymentKey, projectId, runId) {
87151
87591
  }
87152
87592
  __name(deriveRunKey, "deriveRunKey");
87153
87593
  async function fetchRunKey(deploymentId, projectId, runId, options) {
87154
- const token = options?.token ?? process.env.VERCEL_TOKEN ?? await (0, import_oidc.getVercelOidcToken)().catch(() => null);
87594
+ const token = await resolveVercelApiToken({ token: options?.token });
87155
87595
  if (!token) {
87156
87596
  throw new Error("Cannot fetch run key: no OIDC token or VERCEL_TOKEN available");
87157
87597
  }
@@ -87159,23 +87599,25 @@ async function fetchRunKey(deploymentId, projectId, runId, options) {
87159
87599
  if (options?.teamId) {
87160
87600
  params.set("teamId", options.teamId);
87161
87601
  }
87162
- const response = await fetch(`https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`, {
87602
+ const response = await instrumentedFetch({
87163
87603
  method: "GET",
87164
- headers: {
87165
- Authorization: `Bearer ${token}`
87166
- },
87167
- // @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit
87168
- dispatcher: getDispatcher({ dispatcher: options?.dispatcher })
87604
+ url: `https://api.vercel.com/v1/workflow/run-key/${deploymentId}?${params}`,
87605
+ headers: new Headers({ Authorization: `Bearer ${token}` }),
87606
+ dispatcher: getDispatcher({ dispatcher: options?.dispatcher }),
87607
+ peerService: "vercel-api",
87608
+ // Preserve the prior no-timeout behavior for this Vercel-API call; the
87609
+ // shared RetryAgent still handles transient/5xx retries.
87610
+ timeoutMs: null,
87611
+ buildError: /* @__PURE__ */ __name(async (res) => {
87612
+ let body;
87613
+ try {
87614
+ body = await res.text();
87615
+ } catch {
87616
+ body = "<unable to read response body>";
87617
+ }
87618
+ return new Error(`Failed to fetch run key for ${runId} (deployment ${deploymentId}): HTTP ${res.status} ${res.statusText}${body ? ` \u2014 ${body}` : ""}`);
87619
+ }, "buildError")
87169
87620
  });
87170
- if (!response.ok) {
87171
- let body;
87172
- try {
87173
- body = await response.text();
87174
- } catch {
87175
- body = "<unable to read response body>";
87176
- }
87177
- throw new Error(`Failed to fetch run key for ${runId} (deployment ${deploymentId}): HTTP ${response.status} ${response.statusText}${body ? ` \u2014 ${body}` : ""}`);
87178
- }
87179
87621
  const data = await response.json();
87180
87622
  const result = object2({ key: string5().nullable() }).safeParse(data);
87181
87623
  if (!result.success) {
@@ -87224,84 +87666,6 @@ function createGetEncryptionKeyForRun(projectId, teamId, token, dispatcher) {
87224
87666
  }
87225
87667
  __name(createGetEncryptionKeyForRun, "createGetEncryptionKeyForRun");
87226
87668
 
87227
- // ../world-vercel/dist/telemetry.js
87228
- var otelApiPromise2 = null;
87229
- async function getOtelApi2() {
87230
- if (!otelApiPromise2) {
87231
- otelApiPromise2 = Promise.resolve().then(() => (init_esm(), esm_exports)).catch(() => null);
87232
- }
87233
- return otelApiPromise2;
87234
- }
87235
- __name(getOtelApi2, "getOtelApi");
87236
- var tracerPromise2 = null;
87237
- async function getTracer2() {
87238
- if (!tracerPromise2) {
87239
- tracerPromise2 = getOtelApi2().then((otel) => otel ? otel.trace.getTracer("workflow") : null);
87240
- }
87241
- return tracerPromise2;
87242
- }
87243
- __name(getTracer2, "getTracer");
87244
- async function trace5(spanName, ...args) {
87245
- const [tracer, otel] = await Promise.all([getTracer2(), getOtelApi2()]);
87246
- const { fn, opts } = typeof args[0] === "function" ? { fn: args[0], opts: {} } : { fn: args[1], opts: args[0] };
87247
- if (!fn)
87248
- throw new Error("Function to trace must be provided");
87249
- if (!tracer || !otel) {
87250
- return await fn();
87251
- }
87252
- return tracer.startActiveSpan(spanName, opts, async (span) => {
87253
- try {
87254
- const result = await fn(span);
87255
- span.setStatus({ code: otel.SpanStatusCode.OK });
87256
- return result;
87257
- } catch (e) {
87258
- span.setStatus({
87259
- code: otel.SpanStatusCode.ERROR,
87260
- message: e.message
87261
- });
87262
- throw e;
87263
- } finally {
87264
- span.end();
87265
- }
87266
- });
87267
- }
87268
- __name(trace5, "trace");
87269
- async function getSpanKind3(field) {
87270
- const otel = await getOtelApi2();
87271
- if (!otel)
87272
- return void 0;
87273
- return otel.SpanKind[field];
87274
- }
87275
- __name(getSpanKind3, "getSpanKind");
87276
- async function injectTraceContextIntoHeaders(headers) {
87277
- const otel = await getOtelApi2();
87278
- if (!otel)
87279
- return;
87280
- const carrier = {};
87281
- otel.propagation.inject(otel.context.active(), carrier);
87282
- for (const [key, value] of Object.entries(carrier)) {
87283
- headers.set(key, value);
87284
- }
87285
- }
87286
- __name(injectTraceContextIntoHeaders, "injectTraceContextIntoHeaders");
87287
- function SemanticConvention4(...names) {
87288
- return (value) => Object.fromEntries(names.map((name) => [name, value]));
87289
- }
87290
- __name(SemanticConvention4, "SemanticConvention");
87291
- var HttpRequestMethod3 = SemanticConvention4("http.request.method");
87292
- var UrlFull3 = SemanticConvention4("url.full");
87293
- var ServerAddress3 = SemanticConvention4("server.address");
87294
- var ServerPort3 = SemanticConvention4("server.port");
87295
- var HttpResponseStatusCode3 = SemanticConvention4("http.response.status_code");
87296
- var ErrorType3 = SemanticConvention4("error.type");
87297
- var WorldParseFormat3 = SemanticConvention4("workflow.world.parse.format");
87298
- var PeerService4 = SemanticConvention4("peer.service");
87299
- var RpcSystem4 = SemanticConvention4("rpc.system");
87300
- var RpcService4 = SemanticConvention4("rpc.service");
87301
- var RpcMethod4 = SemanticConvention4("rpc.method");
87302
- var WorkflowRunId4 = SemanticConvention4("workflow.run.id");
87303
- var StepId4 = SemanticConvention4("step.id");
87304
-
87305
87669
  // ../world-vercel/dist/instrumentObject.js
87306
87670
  var WORKFLOW_SERVER_SERVICE = {
87307
87671
  peerService: "workflow-server",
@@ -94331,35 +94695,41 @@ import os from "node:os";
94331
94695
  import { inspect } from "node:util";
94332
94696
 
94333
94697
  // ../world-vercel/dist/version.js
94334
- var version5 = "5.0.0-beta.20";
94698
+ var version5 = "5.0.0-beta.22";
94335
94699
 
94336
94700
  // ../world-vercel/dist/utils.js
94337
- var HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
94338
- function httpLog(method, endpoint, response, ms2) {
94339
- if (HTTP_DEBUG_ENABLED) {
94340
- const responseContext = getResponseDiagnosticHeaders(response);
94341
- const diagnosticSuffix = responseContext.length > 0 ? `; ${responseContext.join("; ")}` : "";
94342
- console.debug(`[workflow:world-vercel:http] ${method} ${endpoint} -> ${response.status} (${ms2}ms${diagnosticSuffix})`);
94343
- }
94344
- }
94345
- __name(httpLog, "httpLog");
94346
- function getResponseDiagnosticHeaders(response) {
94347
- return ["x-vercel-id", "x-vercel-error"].flatMap((header) => {
94348
- const value = response.headers.get(header);
94349
- return value ? [`${header}=${value}`] : [];
94350
- });
94351
- }
94352
- __name(getResponseDiagnosticHeaders, "getResponseDiagnosticHeaders");
94353
- function formatResponseDiagnostics(response) {
94354
- const headers = getResponseDiagnosticHeaders(response);
94355
- return headers.length > 0 ? ` (${headers.join("; ")})` : "";
94356
- }
94357
- __name(formatResponseDiagnostics, "formatResponseDiagnostics");
94358
94701
  var WORKFLOW_SERVER_URL_OVERRIDE = "";
94359
- var REQUEST_TIMEOUT_MS = 6e4;
94360
94702
  var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
94361
94703
  var MAX_BODY_PARSE_RETRIES = 2;
94362
94704
  var BODY_PARSE_RETRY_BASE_MS = 100;
94705
+ var TRANSIENT_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
94706
+ "UND_ERR_REQ_RETRY",
94707
+ "UND_ERR_SOCKET",
94708
+ "UND_ERR_CONNECT",
94709
+ "UND_ERR_CONNECT_TIMEOUT",
94710
+ "UND_ERR_HEADERS_TIMEOUT",
94711
+ "UND_ERR_BODY_TIMEOUT",
94712
+ "UND_ERR_CLOSED",
94713
+ "ECONNRESET",
94714
+ "ECONNREFUSED",
94715
+ "ENOTFOUND",
94716
+ "EAI_AGAIN",
94717
+ "EPIPE"
94718
+ ]);
94719
+ function getTransientTransportCode(error95) {
94720
+ let current = error95;
94721
+ for (let depth = 0; current != null && depth < 5; depth++) {
94722
+ if (typeof current === "object" && "code" in current) {
94723
+ const code3 = current.code;
94724
+ if (typeof code3 === "string" && TRANSIENT_TRANSPORT_ERROR_CODES.has(code3)) {
94725
+ return code3;
94726
+ }
94727
+ }
94728
+ current = current?.cause;
94729
+ }
94730
+ return void 0;
94731
+ }
94732
+ __name(getTransientTransportCode, "getTransientTransportCode");
94363
94733
  var getWorkflowServerUrlOverride = /* @__PURE__ */ __name(() => WORKFLOW_SERVER_URL_OVERRIDE || process.env.VERCEL_WORKFLOW_SERVER_URL || "", "getWorkflowServerUrlOverride");
94364
94734
  var DEFAULT_RESOLVE_DATA_OPTION2 = "all";
94365
94735
  function deserializeError(obj) {
@@ -94430,25 +94800,12 @@ async function makeRequest({ endpoint, options = {}, config: config4 = {}, schem
94430
94800
  const method = options.method || "GET";
94431
94801
  const { baseUrl, headers } = await getHttpConfig(config4);
94432
94802
  const url3 = `${baseUrl}${endpoint}`;
94433
- let serverAddress;
94434
- let serverPort;
94435
- try {
94436
- const parsedUrl = new URL(url3);
94437
- serverAddress = parsedUrl.hostname;
94438
- serverPort = parsedUrl.port ? parseInt(parsedUrl.port, 10) : parsedUrl.protocol === "https:" ? 443 : 80;
94439
- } catch {
94440
- }
94441
94803
  return trace5(`http ${method}`, { kind: await getSpanKind3("CLIENT") }, async (span) => {
94442
- span?.setAttributes({
94443
- ...HttpRequestMethod3(method),
94444
- ...UrlFull3(url3),
94445
- ...serverAddress && ServerAddress3(serverAddress),
94446
- ...serverPort && ServerPort3(serverPort),
94447
- // Peer service for Datadog service maps
94448
- ...PeerService4("workflow-server"),
94449
- ...RpcSystem4("http"),
94450
- ...RpcService4("workflow-server")
94451
- });
94804
+ span?.setAttributes(httpClientSpanAttributes({
94805
+ method,
94806
+ url: url3,
94807
+ peerService: "workflow-server"
94808
+ }));
94452
94809
  headers.set("Accept", "application/cbor");
94453
94810
  await injectTraceContextIntoHeaders(headers);
94454
94811
  let body;
@@ -94478,60 +94835,42 @@ async function makeRequest({ endpoint, options = {}, config: config4 = {}, schem
94478
94835
  } catch (error95) {
94479
94836
  const elapsed = Date.now() - fetchStart;
94480
94837
  if (error95 instanceof Error && (error95.name === "TimeoutError" || error95.name === "AbortError")) {
94481
- const timeoutError = new WorkflowWorldError2(`${method} ${endpoint} timed out after ${elapsed}ms`, { url: url3, cause: error95 });
94838
+ const timeoutError = new WorkflowWorldError2(`${method} ${endpoint} timed out after ${elapsed}ms`, { url: url3, code: "TIMEOUT", cause: error95 });
94482
94839
  span?.setAttributes({ ...ErrorType3("TIMEOUT") });
94483
94840
  span?.recordException?.(timeoutError);
94484
94841
  throw timeoutError;
94485
94842
  }
94843
+ const transportCode = getTransientTransportCode(error95);
94844
+ if (transportCode) {
94845
+ const transportError = new WorkflowWorldError2(`${method} ${endpoint} transport failure after ${elapsed}ms (${transportCode})`, { url: url3, code: "TRANSPORT", cause: error95 });
94846
+ span?.setAttributes({ ...ErrorType3("TRANSPORT") });
94847
+ span?.recordException?.(transportError);
94848
+ throw transportError;
94849
+ }
94486
94850
  throw error95;
94487
94851
  }
94488
94852
  const fetchMs = Date.now() - fetchStart;
94489
- responseDiagnostics = formatResponseDiagnostics(response);
94853
+ responseDiagnostics = formatVercelDiagnostics(response.headers);
94490
94854
  httpLog(method, endpoint, response, fetchMs);
94491
94855
  span?.setAttributes({
94492
94856
  ...HttpResponseStatusCode3(response.status)
94493
94857
  });
94494
94858
  if (!response.ok) {
94495
94859
  const errorData = await parseResponseBody(response).then((r) => r.data).catch(() => ({}));
94496
- if (process.env.DEBUG) {
94497
- const stringifiedHeaders = Array.from(headers.entries()).filter(([key]) => key.toLowerCase() !== "authorization").map(([key, value]) => `-H "${key}: ${value}"`).join(" ");
94498
- console.error(`Failed to fetch, reproduce with:
94499
- curl -X ${request.method} ${stringifiedHeaders} "${url3}"`);
94500
- }
94501
- let retryAfter;
94502
- const retryAfterHeader = response.headers.get("Retry-After");
94503
- if (retryAfterHeader) {
94504
- const parsed = parseInt(retryAfterHeader, 10);
94505
- if (!Number.isNaN(parsed)) {
94506
- retryAfter = parsed;
94507
- }
94508
- }
94860
+ logCurlRepro(request.method, url3, headers);
94861
+ const retryAfter = parseRetryAfter(response.headers.get("Retry-After"));
94509
94862
  const defaultMessage = (errorData.message || `${request.method} ${endpoint} -> HTTP ${response.status}: ${response.statusText}`) + responseDiagnostics;
94510
- const throwWithTrace = /* @__PURE__ */ __name((error95) => {
94511
- span?.setAttributes({
94512
- ...ErrorType3(errorData.code || `HTTP ${response.status}`)
94513
- });
94514
- span?.recordException?.(error95);
94515
- throw error95;
94516
- }, "throwWithTrace");
94517
- if (response.status === 409) {
94518
- throwWithTrace(new EntityConflictError2(defaultMessage));
94519
- }
94520
- if (response.status === 410) {
94521
- throwWithTrace(new RunExpiredError(defaultMessage));
94522
- }
94523
- if (response.status === 425) {
94524
- throwWithTrace(new TooEarlyError(defaultMessage, { retryAfter }));
94525
- }
94526
- if (response.status === 429) {
94527
- throwWithTrace(new ThrottleError2(defaultMessage, { retryAfter }));
94528
- }
94529
- throwWithTrace(new WorkflowWorldError2(defaultMessage, {
94863
+ const error95 = errorForResponse(response.status, defaultMessage, {
94530
94864
  url: url3,
94531
- status: response.status,
94532
94865
  code: errorData.code,
94533
- retryAfter
94534
- }));
94866
+ retryAfter,
94867
+ mitigated: response.headers.get("x-vercel-mitigated")
94868
+ });
94869
+ span?.setAttributes({
94870
+ ...ErrorType3(errorData.code || `HTTP ${response.status}`)
94871
+ });
94872
+ span?.recordException?.(error95);
94873
+ throw error95;
94535
94874
  }
94536
94875
  onResponse?.(response);
94537
94876
  try {
@@ -94688,7 +95027,7 @@ var MAX_DELAY_SECONDS = Number(
94688
95027
  // 23 hours - leave 1h buffer before 24h retention limit
94689
95028
  );
94690
95029
  var HANDLER_ERROR_RETRY_AFTER_SECONDS = 1;
94691
- var HANDLER_ERROR_MAX_RETRY_AFTER_SECONDS = 60;
95030
+ var HANDLER_ERROR_MAX_RETRY_AFTER_SECONDS = 900;
94692
95031
  var HANDLER_ERROR_RETRY_JITTER_RATIO = 0.25;
94693
95032
  function getHandlerErrorRetryAfterSeconds(deliveryCount) {
94694
95033
  const backoffSeconds = Math.min(Math.max(HANDLER_ERROR_RETRY_AFTER_SECONDS, 2 ** (deliveryCount - 1)), HANDLER_ERROR_MAX_RETRY_AFTER_SECONDS);
@@ -94818,7 +95157,6 @@ function createQueue2(config4) {
94818
95157
  __name(createQueue2, "createQueue");
94819
95158
 
94820
95159
  // ../world-vercel/dist/resolve-latest-deployment.js
94821
- var import_oidc4 = __toESM(require_dist(), 1);
94822
95160
  init_zod2();
94823
95161
  var ResolveLatestDeploymentResponseSchema = object2({
94824
95162
  id: string5()
@@ -94829,28 +95167,30 @@ function createResolveLatestDeploymentId(config4) {
94829
95167
  if (!currentDeploymentId) {
94830
95168
  throw new Error("Cannot resolve latest deployment: VERCEL_DEPLOYMENT_ID environment variable is not set");
94831
95169
  }
94832
- const token = config4?.token ?? process.env.VERCEL_TOKEN ?? await (0, import_oidc4.getVercelOidcToken)().catch(() => null);
95170
+ const token = await resolveVercelApiToken(config4);
94833
95171
  if (!token) {
94834
95172
  throw new Error("Cannot resolve latest deployment: no OIDC token or VERCEL_TOKEN available");
94835
95173
  }
94836
95174
  const url3 = `https://api.vercel.com/v1/workflow/resolve-latest-deployment/${encodeURIComponent(currentDeploymentId)}`;
94837
- const response = await fetch(url3, {
95175
+ const response = await instrumentedFetch({
94838
95176
  method: "GET",
94839
- headers: {
94840
- Authorization: `Bearer ${token}`
94841
- },
94842
- // @ts-expect-error -- undici dispatcher is accepted by Node.js fetch but not in @types/node's RequestInit
94843
- dispatcher: getDispatcher(config4)
95177
+ url: url3,
95178
+ headers: new Headers({ Authorization: `Bearer ${token}` }),
95179
+ dispatcher: getDispatcher(config4),
95180
+ peerService: "vercel-api",
95181
+ // Preserve the prior no-timeout behavior for this Vercel-API call; the
95182
+ // shared RetryAgent still handles transient/5xx retries.
95183
+ timeoutMs: null,
95184
+ buildError: /* @__PURE__ */ __name(async (res) => {
95185
+ let body;
95186
+ try {
95187
+ body = await res.text();
95188
+ } catch {
95189
+ body = "<unable to read response body>";
95190
+ }
95191
+ return new Error(`Failed to resolve latest deployment for ${currentDeploymentId}: HTTP ${res.status} ${res.statusText}${body ? ` \u2014 ${body}` : ""}`);
95192
+ }, "buildError")
94844
95193
  });
94845
- if (!response.ok) {
94846
- let body;
94847
- try {
94848
- body = await response.text();
94849
- } catch {
94850
- body = "<unable to read response body>";
94851
- }
94852
- throw new Error(`Failed to resolve latest deployment for ${currentDeploymentId}: HTTP ${response.status} ${response.statusText}${body ? ` \u2014 ${body}` : ""}`);
94853
- }
94854
95194
  const data = await response.json();
94855
95195
  const result = ResolveLatestDeploymentResponseSchema.safeParse(data);
94856
95196
  if (!result.success) {
@@ -94865,8 +95205,187 @@ __name(createResolveLatestDeploymentId, "createResolveLatestDeploymentId");
94865
95205
  init_dist6();
94866
95206
  init_dist7();
94867
95207
 
94868
- // ../world-vercel/dist/events-v4.js
95208
+ // ../world-vercel/dist/event-retry.js
94869
95209
  init_dist6();
95210
+ var EVENT_RETRY_ELIGIBILITY = {
95211
+ // Creates: conditional create → 409 EntityConflictError if it already exists.
95212
+ run_created: {
95213
+ retryable: true,
95214
+ reason: "conditional create \u2192 409 if exists"
95215
+ },
95216
+ step_created: {
95217
+ retryable: true,
95218
+ reason: "conditional create \u2192 409 if exists"
95219
+ },
95220
+ wait_created: {
95221
+ retryable: true,
95222
+ reason: "conditional create \u2192 409 if exists"
95223
+ },
95224
+ hook_created: {
95225
+ retryable: true,
95226
+ reason: "transactional token uniqueness \u2192 409 if exists"
95227
+ },
95228
+ // Run start: early-returns if already running, writes no duplicate row.
95229
+ run_started: {
95230
+ retryable: true,
95231
+ reason: "early-returns if already running, no duplicate row"
95232
+ },
95233
+ // Terminal transitions: conditional `.where()` excludes terminal states →
95234
+ // 409 before the event row is written.
95235
+ run_completed: {
95236
+ retryable: true,
95237
+ reason: "terminal-state guard \u2192 409, no duplicate row"
95238
+ },
95239
+ run_failed: {
95240
+ retryable: true,
95241
+ reason: "terminal-state guard \u2192 409, no duplicate row"
95242
+ },
95243
+ run_cancelled: {
95244
+ retryable: true,
95245
+ reason: "terminal-state guard \u2192 409, no duplicate row"
95246
+ },
95247
+ step_completed: {
95248
+ retryable: true,
95249
+ reason: "terminal-state guard \u2192 409, no duplicate row"
95250
+ },
95251
+ step_failed: {
95252
+ retryable: true,
95253
+ reason: "terminal-state guard \u2192 409, no duplicate row"
95254
+ },
95255
+ wait_completed: {
95256
+ retryable: true,
95257
+ reason: "waiting-state guard \u2192 409, no duplicate row"
95258
+ },
95259
+ hook_disposed: {
95260
+ retryable: true,
95261
+ reason: "conditional delete (exists) \u2192 409, no duplicate row"
95262
+ },
95263
+ // True idempotency via a correlationId constraint that reuses the eventId.
95264
+ attr_set: {
95265
+ retryable: true,
95266
+ reason: "correlationId constraint reuses eventId (idempotent replay)"
95267
+ },
95268
+ // NOT safe to retry — see the module comment.
95269
+ step_started: {
95270
+ retryable: false,
95271
+ reason: "unconditional attempt increment \u2192 a retry double-counts attempts"
95272
+ },
95273
+ step_retrying: {
95274
+ retryable: false,
95275
+ reason: "no duplicate guard \u2192 a retry appends a second event row"
95276
+ },
95277
+ hook_received: {
95278
+ retryable: false,
95279
+ reason: "no server guard \u2192 a retry duplicates the row / re-delivers payload"
95280
+ },
95281
+ // Server-originated; the SDK never POSTs it.
95282
+ hook_conflict: {
95283
+ retryable: false,
95284
+ reason: "server-originated; never POSTed by the SDK"
95285
+ }
95286
+ };
95287
+ var MAX_EVENT_POST_RETRIES = 2;
95288
+ var EVENT_POST_RETRY_BASE_MS = 100;
95289
+ var EVENT_POST_RETRY_JITTER_MS = 50;
95290
+ var TRANSIENT_CODES = /* @__PURE__ */ new Set([
95291
+ "ECONNRESET",
95292
+ "ECONNREFUSED",
95293
+ "ENOTFOUND",
95294
+ "ENETDOWN",
95295
+ "ENETUNREACH",
95296
+ "EHOSTDOWN",
95297
+ "EHOSTUNREACH",
95298
+ "EPIPE",
95299
+ "ETIMEDOUT",
95300
+ "UND_ERR_SOCKET",
95301
+ "UND_ERR_REQ_RETRY",
95302
+ "UND_ERR_CONNECT_TIMEOUT",
95303
+ "UND_ERR_HEADERS_TIMEOUT",
95304
+ "UND_ERR_BODY_TIMEOUT",
95305
+ // Names (undici/Node surface these on the error or its cause).
95306
+ // `TimeoutError` is our own per-request deadline (`AbortSignal.timeout` in
95307
+ // makeRequest) — a genuinely ambiguous failure worth retrying. We deliberately
95308
+ // do NOT include `AbortError`: that is how an external/caller-supplied
95309
+ // cancellation surfaces (makeRequest composes the caller's signal via
95310
+ // `AbortSignal.any`), and re-issuing a write the caller asked to cancel —
95311
+ // stalling the abort by the full backoff budget — would be wrong.
95312
+ "TimeoutError",
95313
+ "RequestRetryError"
95314
+ ]);
95315
+ function collectErrorMarkers(err, depth = 0) {
95316
+ if (depth > 5 || err === null || typeof err !== "object")
95317
+ return [];
95318
+ const markers = [];
95319
+ const e = err;
95320
+ if (typeof e.code === "string")
95321
+ markers.push(e.code);
95322
+ if (typeof e.name === "string")
95323
+ markers.push(e.name);
95324
+ if (e.cause)
95325
+ markers.push(...collectErrorMarkers(e.cause, depth + 1));
95326
+ return markers;
95327
+ }
95328
+ __name(collectErrorMarkers, "collectErrorMarkers");
95329
+ function isRetryableEventPostError(err) {
95330
+ if (EntityConflictError2.is(err) || RunExpiredError.is(err) || TooEarlyError.is(err) || ThrottleError2.is(err)) {
95331
+ return false;
95332
+ }
95333
+ if (WorkflowWorldError2.is(err)) {
95334
+ if (err.code === "PARSE_ERROR")
95335
+ return true;
95336
+ if (typeof err.status === "number") {
95337
+ return err.status >= 500 && err.status <= 599;
95338
+ }
95339
+ }
95340
+ return collectErrorMarkers(err).some((m) => TRANSIENT_CODES.has(m));
95341
+ }
95342
+ __name(isRetryableEventPostError, "isRetryableEventPostError");
95343
+ var sleep = /* @__PURE__ */ __name((ms2) => new Promise((resolve3) => setTimeout(resolve3, ms2)), "sleep");
95344
+ var RETRY_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
95345
+ function logRetry(message, fields) {
95346
+ if (!RETRY_DEBUG_ENABLED)
95347
+ return;
95348
+ const suffix = Object.entries(fields).map(([k, v]) => `${k}=${v}`).join(" ");
95349
+ console.debug(`[workflow:world-vercel:event-retry] ${message} ${suffix}`);
95350
+ }
95351
+ __name(logRetry, "logRetry");
95352
+ function errorMarker(err) {
95353
+ if (WorkflowWorldError2.is(err)) {
95354
+ return err.code ?? (err.status != null ? `status_${err.status}` : err.name);
95355
+ }
95356
+ return collectErrorMarkers(err)[0] ?? (err instanceof Error ? err.name : "unknown");
95357
+ }
95358
+ __name(errorMarker, "errorMarker");
95359
+ async function withEventPostRetry(fn, eventType) {
95360
+ const retryable = EVENT_RETRY_ELIGIBILITY[eventType]?.retryable ?? false;
95361
+ for (let attempt = 0; ; attempt++) {
95362
+ try {
95363
+ return await fn();
95364
+ } catch (err) {
95365
+ const transient = retryable && isRetryableEventPostError(err);
95366
+ if (transient && attempt < MAX_EVENT_POST_RETRIES) {
95367
+ const backoff = EVENT_POST_RETRY_BASE_MS * 2 ** attempt + Math.floor(Math.random() * EVENT_POST_RETRY_JITTER_MS);
95368
+ logRetry("retrying event POST after transient failure", {
95369
+ eventType,
95370
+ attempt: attempt + 1,
95371
+ backoffMs: backoff,
95372
+ error: errorMarker(err)
95373
+ });
95374
+ await sleep(backoff);
95375
+ continue;
95376
+ }
95377
+ if (transient) {
95378
+ logRetry("exhausted in-process retries; surfacing for queue redelivery", {
95379
+ eventType,
95380
+ attempts: attempt + 1,
95381
+ error: errorMarker(err)
95382
+ });
95383
+ }
95384
+ throw err;
95385
+ }
95386
+ }
95387
+ }
95388
+ __name(withEventPostRetry, "withEventPostRetry");
94870
95389
 
94871
95390
  // ../world-vercel/dist/frames.js
94872
95391
  var V4_FRAME_CONTENT_TYPE = "application/vnd.workflow.v4-frames";
@@ -94943,15 +95462,16 @@ async function* readerToIterator(reader) {
94943
95462
  __name(readerToIterator, "readerToIterator");
94944
95463
 
94945
95464
  // ../world-vercel/dist/events-v4.js
94946
- async function fetchV4(url3, init, config4) {
94947
- init.headers.set("X-Request-Time", Date.now().toString());
94948
- await injectTraceContextIntoHeaders(init.headers);
94949
- return fetch(url3, {
95465
+ async function fetchV4(url3, init, config4, opName) {
95466
+ return instrumentedFetch({
94950
95467
  method: init.method,
95468
+ url: url3,
94951
95469
  headers: init.headers,
94952
95470
  body: init.body,
94953
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
94954
- dispatcher: getDispatcher(config4)
95471
+ dispatcher: getEventsDispatcher(config4),
95472
+ timeoutMs: null,
95473
+ logLabel: opName,
95474
+ buildError: /* @__PURE__ */ __name(async (response) => errorFromV4Response(response.status, headersToRecord(response.headers), await response.text(), opName, url3), "buildError")
94955
95475
  });
94956
95476
  }
94957
95477
  __name(fetchV4, "fetchV4");
@@ -95021,7 +95541,7 @@ function buildPostFrameMeta(input) {
95021
95541
  return meta5;
95022
95542
  }
95023
95543
  __name(buildPostFrameMeta, "buildPostFrameMeta");
95024
- function throwForErrorResponse(statusCode, responseHeaders, errorBody, opName, url3) {
95544
+ function errorFromV4Response(statusCode, responseHeaders, errorBody, opName, url3) {
95025
95545
  let message = `v4 ${opName} failed: HTTP ${statusCode}`;
95026
95546
  let code3;
95027
95547
  try {
@@ -95034,40 +95554,22 @@ function throwForErrorResponse(statusCode, responseHeaders, errorBody, opName, u
95034
95554
  if (errorBody)
95035
95555
  message += ` ${errorBody}`;
95036
95556
  }
95037
- let retryAfter;
95038
- const retryAfterHeader = readHeader(responseHeaders, "retry-after");
95039
- if (retryAfterHeader) {
95040
- const parsed = parseInt(retryAfterHeader, 10);
95041
- if (!Number.isNaN(parsed))
95042
- retryAfter = parsed;
95043
- }
95044
- if (statusCode === 409)
95045
- throw new EntityConflictError2(message);
95046
- if (statusCode === 410)
95047
- throw new RunExpiredError(message);
95048
- if (statusCode === 425)
95049
- throw new TooEarlyError(message, { retryAfter });
95050
- if (statusCode === 429)
95051
- throw new ThrottleError2(message, { retryAfter });
95052
- throw new WorkflowWorldError2(message, {
95053
- status: statusCode,
95557
+ const retryAfter = parseRetryAfter(readHeader(responseHeaders, "retry-after"));
95558
+ return errorForResponse(statusCode, message, {
95559
+ retryAfter,
95054
95560
  code: code3,
95055
95561
  url: url3,
95056
- retryAfter
95562
+ mitigated: readHeader(responseHeaders, "x-vercel-mitigated")
95057
95563
  });
95058
95564
  }
95059
- __name(throwForErrorResponse, "throwForErrorResponse");
95565
+ __name(errorFromV4Response, "errorFromV4Response");
95060
95566
  async function createWorkflowRunEventV4(input, config4) {
95061
95567
  const { baseUrl, headers: baseHeaders } = await getHttpConfig(config4);
95062
95568
  const headers = new Headers(baseHeaders);
95063
95569
  headers.set("Content-Type", "application/octet-stream");
95064
95570
  const frame3 = encodeFrame(buildPostFrameMeta(input), input.payload ?? new Uint8Array(0));
95065
95571
  const url3 = `${baseUrl}/v4/runs/${encodeURIComponent(input.runId)}/events/${encodeURIComponent(input.eventType)}`;
95066
- const response = await fetchV4(url3, { method: "POST", headers, body: frame3 }, config4);
95067
- if (!response.ok) {
95068
- const errorBody = await response.text();
95069
- throwForErrorResponse(response.status, headersToRecord(response.headers), errorBody, "createEvent", url3);
95070
- }
95572
+ const response = await fetchV4(url3, { method: "POST", headers, body: frame3 }, config4, "createEvent");
95071
95573
  const eventId = response.headers.get(V4_RESPONSE_HEADERS.eventId);
95072
95574
  const runId = response.headers.get(V4_RESPONSE_HEADERS.runId);
95073
95575
  const createdAt = response.headers.get(V4_RESPONSE_HEADERS.createdAt);
@@ -95091,11 +95593,7 @@ __name(readHeader, "readHeader");
95091
95593
  async function getEventV4(runId, eventId, config4) {
95092
95594
  const { baseUrl, headers } = await getHttpConfig(config4);
95093
95595
  const url3 = `${baseUrl}/v4/runs/${encodeURIComponent(runId)}/events/${encodeURIComponent(eventId)}`;
95094
- const response = await fetchV4(url3, { method: "GET", headers }, config4);
95095
- if (!response.ok) {
95096
- const errorBody = await response.text();
95097
- throwForErrorResponse(response.status, headersToRecord(response.headers), errorBody, "getEvent", url3);
95098
- }
95596
+ const response = await fetchV4(url3, { method: "GET", headers }, config4, "getEvent");
95099
95597
  const contentType = response.headers.get("content-type");
95100
95598
  if (!contentType?.startsWith(V4_FRAME_CONTENT_TYPE)) {
95101
95599
  throw new Error(`v4 getEvent: expected ${V4_FRAME_CONTENT_TYPE}, got ${contentType ?? "(none)"}`);
@@ -95108,11 +95606,7 @@ async function getEventV4(runId, eventId, config4) {
95108
95606
  }
95109
95607
  __name(getEventV4, "getEventV4");
95110
95608
  async function consumeListFrameStream(url3, headers, config4, opName) {
95111
- const response = await fetchV4(url3, { method: "GET", headers }, config4);
95112
- if (!response.ok) {
95113
- const errorBody = await response.text();
95114
- throwForErrorResponse(response.status, headersToRecord(response.headers), errorBody, opName, url3);
95115
- }
95609
+ const response = await fetchV4(url3, { method: "GET", headers }, config4, opName);
95116
95610
  const contentType = response.headers.get("content-type");
95117
95611
  if (!contentType?.startsWith(V4_FRAME_CONTENT_TYPE)) {
95118
95612
  throw new Error(`v4 ${opName}: expected ${V4_FRAME_CONTENT_TYPE}, got ${contentType ?? "(none)"}`);
@@ -95588,7 +96082,7 @@ async function getWorkflowRunEvents(params, config4) {
95588
96082
  __name(getWorkflowRunEvents, "getWorkflowRunEvents");
95589
96083
  async function createWorkflowRunEvent(id, data, params, config4) {
95590
96084
  try {
95591
- return await createWorkflowRunEventInner(id, data, params, config4);
96085
+ return await withEventPostRetry(() => createWorkflowRunEventInner(id, data, params, config4), data.eventType);
95592
96086
  } catch (err) {
95593
96087
  if (hookEventsRequiringExistence.has(data.eventType) && WorkflowWorldError2.is(err) && err.status === 404 && data.correlationId) {
95594
96088
  throw new HookNotFoundError2(data.correlationId);
@@ -95793,13 +96287,10 @@ function getStreamReadUrl(name, runId, httpConfig) {
95793
96287
  }
95794
96288
  __name(getStreamReadUrl, "getStreamReadUrl");
95795
96289
  function createStreamRequestError(operation, url3, response, text) {
95796
- const context2 = [`PUT ${url3.origin}${url3.pathname}`];
95797
- for (const header of ["x-vercel-id", "x-vercel-error"]) {
95798
- const value = response.headers.get(header);
95799
- if (value) {
95800
- context2.push(`${header}=${value}`);
95801
- }
95802
- }
96290
+ const context2 = [
96291
+ `PUT ${url3.origin}${url3.pathname}`,
96292
+ ...getVercelDiagnostics(response.headers)
96293
+ ];
95803
96294
  return new Error(`Stream ${operation} failed: HTTP ${response.status} (${context2.join("; ")}): ${text}`);
95804
96295
  }
95805
96296
  __name(createStreamRequestError, "createStreamRequestError");
@@ -95844,15 +96335,17 @@ function createStreamer2(config4) {
95844
96335
  const resolvedRunId = await runId;
95845
96336
  const httpConfig = await getHttpConfig(config4);
95846
96337
  const url3 = getStreamUrl(name, resolvedRunId, httpConfig);
95847
- const response = await fetch(url3, {
96338
+ const response = await instrumentedFetch({
95848
96339
  method: "PUT",
96340
+ url: url3.toString(),
95849
96341
  body: chunk,
95850
- headers: httpConfig.headers
96342
+ headers: httpConfig.headers,
96343
+ dispatcher: getStreamDispatcher(config4),
96344
+ timeoutMs: null,
96345
+ logLabel: url3.pathname,
96346
+ buildError: /* @__PURE__ */ __name(async (res) => createStreamRequestError("write", url3, res, await res.text()), "buildError")
95851
96347
  });
95852
- const text = await response.text();
95853
- if (!response.ok) {
95854
- throw createStreamRequestError("write", url3, response, text);
95855
- }
96348
+ await response.text();
95856
96349
  },
95857
96350
  async writeMulti(runId, name, chunks) {
95858
96351
  if (chunks.length === 0)
@@ -95864,15 +96357,17 @@ function createStreamer2(config4) {
95864
96357
  const batch = chunks.slice(i, i + MAX_CHUNKS_PER_REQUEST);
95865
96358
  const body = encodeMultiChunks(batch);
95866
96359
  const url3 = getStreamUrl(name, resolvedRunId, httpConfig);
95867
- const response = await fetch(url3, {
96360
+ const response = await instrumentedFetch({
95868
96361
  method: "PUT",
96362
+ url: url3.toString(),
95869
96363
  body,
95870
- headers: httpConfig.headers
96364
+ headers: httpConfig.headers,
96365
+ dispatcher: getStreamDispatcher(config4),
96366
+ timeoutMs: null,
96367
+ logLabel: url3.pathname,
96368
+ buildError: /* @__PURE__ */ __name(async (res) => createStreamRequestError("write", url3, res, await res.text()), "buildError")
95871
96369
  });
95872
- const text = await response.text();
95873
- if (!response.ok) {
95874
- throw createStreamRequestError("write", url3, response, text);
95875
- }
96370
+ await response.text();
95876
96371
  }
95877
96372
  },
95878
96373
  async close(runId, name) {
@@ -95880,14 +96375,16 @@ function createStreamer2(config4) {
95880
96375
  const httpConfig = await getHttpConfig(config4);
95881
96376
  httpConfig.headers.set("X-Stream-Done", "true");
95882
96377
  const url3 = getStreamUrl(name, resolvedRunId, httpConfig);
95883
- const response = await fetch(url3, {
96378
+ const response = await instrumentedFetch({
95884
96379
  method: "PUT",
95885
- headers: httpConfig.headers
96380
+ url: url3.toString(),
96381
+ headers: httpConfig.headers,
96382
+ dispatcher: getStreamDispatcher(config4),
96383
+ timeoutMs: null,
96384
+ logLabel: url3.pathname,
96385
+ buildError: /* @__PURE__ */ __name(async (res) => createStreamRequestError("close", url3, res, await res.text()), "buildError")
95886
96386
  });
95887
- const text = await response.text();
95888
- if (!response.ok) {
95889
- throw createStreamRequestError("close", url3, response, text);
95890
- }
96387
+ await response.text();
95891
96388
  },
95892
96389
  async get(runId, name, startIndex) {
95893
96390
  const httpConfig = await getHttpConfig(config4);
@@ -95895,12 +96392,15 @@ function createStreamer2(config4) {
95895
96392
  if (typeof startIndex === "number") {
95896
96393
  url3.searchParams.set("startIndex", String(startIndex));
95897
96394
  }
95898
- const response = await fetch(url3, {
95899
- headers: httpConfig.headers
96395
+ const response = await instrumentedFetch({
96396
+ method: "GET",
96397
+ url: url3.toString(),
96398
+ headers: httpConfig.headers,
96399
+ dispatcher: void 0,
96400
+ timeoutMs: null,
96401
+ logLabel: url3.pathname,
96402
+ buildError: /* @__PURE__ */ __name((res) => new Error(`Failed to fetch stream: ${res.status}`), "buildError")
95900
96403
  });
95901
- if (!response.ok) {
95902
- throw new Error(`Failed to fetch stream: ${response.status}`);
95903
- }
95904
96404
  if (!response.body) {
95905
96405
  throw new Error("No response body for stream");
95906
96406
  }
@@ -95933,12 +96433,15 @@ function createStreamer2(config4) {
95933
96433
  async list(runId) {
95934
96434
  const httpConfig = await getHttpConfig(config4);
95935
96435
  const url3 = new URL(`${httpConfig.baseUrl}/v2/runs/${encodeURIComponent(runId)}/streams`);
95936
- const response = await fetch(url3, {
95937
- headers: httpConfig.headers
96436
+ const response = await instrumentedFetch({
96437
+ method: "GET",
96438
+ url: url3.toString(),
96439
+ headers: httpConfig.headers,
96440
+ dispatcher: void 0,
96441
+ timeoutMs: null,
96442
+ logLabel: url3.pathname,
96443
+ buildError: /* @__PURE__ */ __name((res) => new Error(`Failed to list streams: ${res.status}`), "buildError")
95938
96444
  });
95939
- if (!response.ok) {
95940
- throw new Error(`Failed to list streams: ${response.status}`);
95941
- }
95942
96445
  return await response.json();
95943
96446
  }
95944
96447
  }
@@ -96148,7 +96651,7 @@ async function handleReplayBudgetExhausted(args) {
96148
96651
  specVersion: SPEC_VERSION_CURRENT2,
96149
96652
  eventData: {
96150
96653
  error: await dehydrateRunError(timeoutErr, runId, await getEncryptionKey()),
96151
- errorCode: RUN_ERROR_CODES.REPLAY_TIMEOUT
96654
+ errorCode: RUN_ERROR_CODES2.REPLAY_TIMEOUT
96152
96655
  }
96153
96656
  }, { requestId });
96154
96657
  } catch (err) {
@@ -96168,7 +96671,7 @@ async function handleReplayBudgetExhausted(args) {
96168
96671
  });
96169
96672
  process.exit(1);
96170
96673
  }
96171
- const replayTimeoutDescription = describeError(void 0, RUN_ERROR_CODES.REPLAY_TIMEOUT);
96674
+ const replayTimeoutDescription = describeError(void 0, RUN_ERROR_CODES2.REPLAY_TIMEOUT);
96172
96675
  runLogger.error("Workflow replay exceeded timeout and max retries exceeded. Failing the run", {
96173
96676
  timeoutMs: limitMs,
96174
96677
  attempt,
@@ -96184,7 +96687,7 @@ async function handleReplayBudgetExhausted(args) {
96184
96687
  specVersion: SPEC_VERSION_CURRENT2,
96185
96688
  eventData: {
96186
96689
  error: await dehydrateRunError(timeoutErr, runId, await getEncryptionKey()),
96187
- errorCode: RUN_ERROR_CODES.REPLAY_TIMEOUT
96690
+ errorCode: RUN_ERROR_CODES2.REPLAY_TIMEOUT
96188
96691
  }
96189
96692
  }, { requestId });
96190
96693
  } catch (err) {
@@ -96562,13 +97065,14 @@ async function executeStep(params) {
96562
97065
  return { type: "failed" };
96563
97066
  }
96564
97067
  const preCompletionOps = [];
97068
+ const ops = [];
97069
+ let opsSettled = true;
96565
97070
  try {
96566
97071
  const attempt = step.attempt;
96567
97072
  if (!step.startedAt) {
96568
97073
  throw new WorkflowRuntimeError2(`Step "${stepId}" has no "startedAt" timestamp`);
96569
97074
  }
96570
97075
  const stepStartedAt = step.startedAt;
96571
- const ops = [];
96572
97076
  const encryptionKey = params.encryptionKey ?? await getEncryptionKey();
96573
97077
  const hydratedInput = await trace3("step.hydrate", {}, async (hydrateSpan) => {
96574
97078
  const startTime = Date.now();
@@ -96603,7 +97107,12 @@ async function executeStep(params) {
96603
97107
  ops,
96604
97108
  preCompletionOps,
96605
97109
  closureVars: hydratedInput.closureVars,
96606
- encryptionKey
97110
+ encryptionKey,
97111
+ // Turbo optimistic start runs this body before `run_started` is
97112
+ // durable. Expose the barrier so a direct step-body world write
97113
+ // (e.g. `experimental_setAttributes`) can order itself after the
97114
+ // run exists. Undefined on the await path (run already durable).
97115
+ runReadyBarrier: optimisticStart ? params.runReadyBarrier : void 0
96607
97116
  }, () => stepFn.apply(thisVal, args));
96608
97117
  });
96609
97118
  const executionTimeMs = Date.now() - executionStartTime;
@@ -96612,7 +97121,20 @@ async function executeStep(params) {
96612
97121
  });
96613
97122
  result = await trace3("step.dehydrate", {}, async (dehydrateSpan) => {
96614
97123
  const startTime = Date.now();
96615
- const dehydrated = await dehydrateStepReturnValue2(result, workflowRunId, encryptionKey, ops, globalThis, false, false, compression);
97124
+ const dehydrated = await dehydrateStepReturnValue2(
97125
+ result,
97126
+ workflowRunId,
97127
+ encryptionKey,
97128
+ ops,
97129
+ globalThis,
97130
+ false,
97131
+ false,
97132
+ compression,
97133
+ // Turbo optimistic start: a returned stream is piped to the server
97134
+ // after the body but within this same op flush, so gate its first
97135
+ // write on the run-ready barrier. Undefined on the await path.
97136
+ optimisticStart ? params.runReadyBarrier : void 0
97137
+ );
96616
97138
  const durationMs = Date.now() - startTime;
96617
97139
  dehydrateSpan?.setAttributes({
96618
97140
  ...QueueSerializeTimeMs2(durationMs),
@@ -96620,7 +97142,6 @@ async function executeStep(params) {
96620
97142
  });
96621
97143
  return dehydrated;
96622
97144
  });
96623
- let opsSettled = true;
96624
97145
  if (ops.length > 0) {
96625
97146
  const opsPromise = Promise.all(ops);
96626
97147
  safeWaitUntil2(opsPromise, (err) => {
@@ -96649,45 +97170,6 @@ async function executeStep(params) {
96649
97170
  await Promise.all(preCompletionOps).catch(() => {
96650
97171
  });
96651
97172
  }
96652
- let stepCompleted409 = false;
96653
- const completedResult = await world.events.create(workflowRunId, {
96654
- eventType: "step_completed",
96655
- specVersion: SPEC_VERSION_CURRENT2,
96656
- correlationId: stepId,
96657
- eventData: {
96658
- stepName,
96659
- workflowName,
96660
- result
96661
- }
96662
- }, params.inlineDeltaSinceCursor !== void 0 ? { sinceCursor: params.inlineDeltaSinceCursor } : void 0).catch((err) => {
96663
- if (EntityConflictError2.is(err)) {
96664
- runtimeLogger2.info("Tried completing step, but step has already finished.", {
96665
- workflowRunId,
96666
- stepId,
96667
- stepName,
96668
- message: err.message
96669
- });
96670
- stepCompleted409 = true;
96671
- return void 0;
96672
- }
96673
- throw err;
96674
- });
96675
- if (stepCompleted409) {
96676
- return { type: "skipped" };
96677
- }
96678
- const inlineDelta = completedResult ? extractInlineDelta(completedResult, params.inlineDeltaSinceCursor !== void 0) : void 0;
96679
- span?.setAttributes({
96680
- ...StepStatus2("completed"),
96681
- ...StepResultType2(typeof result)
96682
- });
96683
- if (ops.length > 0) {
96684
- stepLogger2.debug("Step has pending ops", {
96685
- workflowRunId,
96686
- stepName,
96687
- opsCount: ops.length
96688
- });
96689
- }
96690
- return { type: "completed", hasPendingOps: !opsSettled, inlineDelta };
96691
97173
  } catch (err) {
96692
97174
  if (optimisticStart) {
96693
97175
  const reconcile = await reconcileOptimisticStart();
@@ -96848,6 +97330,51 @@ async function executeStep(params) {
96848
97330
  });
96849
97331
  return { type: "retry", timeoutSeconds };
96850
97332
  }
97333
+ let completedResult;
97334
+ try {
97335
+ completedResult = await world.events.create(workflowRunId, {
97336
+ eventType: "step_completed",
97337
+ specVersion: SPEC_VERSION_CURRENT2,
97338
+ correlationId: stepId,
97339
+ eventData: {
97340
+ stepName,
97341
+ workflowName,
97342
+ result
97343
+ }
97344
+ }, params.inlineDeltaSinceCursor !== void 0 ? { sinceCursor: params.inlineDeltaSinceCursor } : void 0);
97345
+ } catch (err) {
97346
+ if (EntityConflictError2.is(err)) {
97347
+ runtimeLogger2.info("Tried completing step, but step has already finished.", {
97348
+ workflowRunId,
97349
+ stepId,
97350
+ stepName,
97351
+ message: err.message
97352
+ });
97353
+ return { type: "skipped" };
97354
+ }
97355
+ if (RunExpiredError.is(err)) {
97356
+ stepLogger2.info("Workflow run already completed, skipping step", {
97357
+ workflowRunId,
97358
+ stepId,
97359
+ message: err.message
97360
+ });
97361
+ return { type: "gone" };
97362
+ }
97363
+ throw err;
97364
+ }
97365
+ const inlineDelta = extractInlineDelta(completedResult, params.inlineDeltaSinceCursor !== void 0);
97366
+ span?.setAttributes({
97367
+ ...StepStatus2("completed"),
97368
+ ...StepResultType2(typeof result)
97369
+ });
97370
+ if (ops.length > 0) {
97371
+ stepLogger2.debug("Step has pending ops", {
97372
+ workflowRunId,
97373
+ stepName,
97374
+ opsCount: ops.length
97375
+ });
97376
+ }
97377
+ return { type: "completed", hasPendingOps: !opsSettled, inlineDelta };
96851
97378
  });
96852
97379
  }
96853
97380
  __name(executeStep, "executeStep");
@@ -98987,7 +99514,7 @@ function createSleep(ctx) {
98987
99514
  __name(createSleep, "createSleep");
98988
99515
 
98989
99516
  // ../core/dist/workflow.js
98990
- async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflowRun, outcome) {
99517
+ async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflowRun, outcome, runReadyBarrier) {
98991
99518
  if (pendingQueue.size === 0)
98992
99519
  return;
98993
99520
  for (const item of pendingQueue.values()) {
@@ -99001,7 +99528,8 @@ async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflo
99001
99528
  await handleSuspension({
99002
99529
  suspension: synthesized,
99003
99530
  world,
99004
- run: workflowRun
99531
+ run: workflowRun,
99532
+ runReadyBarrier
99005
99533
  });
99006
99534
  } catch (err) {
99007
99535
  runtimeLogger2.warn(`Failed to drain pending queue items for ${outcome} workflow run`, {
@@ -99011,7 +99539,7 @@ async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflo
99011
99539
  }
99012
99540
  }
99013
99541
  __name(drainPendingQueueItems, "drainPendingQueueItems");
99014
- async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, stepHydrationCache) {
99542
+ async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, stepHydrationCache, runReadyBarrier) {
99015
99543
  return trace3(`workflow.run ${workflowRun.workflowName}`, async (span) => {
99016
99544
  span?.setAttributes({
99017
99545
  ...WorkflowName2(workflowRun.workflowName),
@@ -99090,12 +99618,12 @@ async function runWorkflow(workflowCode2, workflowRun, events, encryptionKey, st
99090
99618
  });
99091
99619
  const useStep = createUseStep(workflowContext);
99092
99620
  const createHook = createCreateHook(workflowContext);
99093
- const sleep = createSleep(workflowContext);
99621
+ const sleep2 = createSleep(workflowContext);
99094
99622
  const setAttributes = createSetAttributes(workflowContext);
99095
99623
  vmGlobalThis[WORKFLOW_USE_STEP] = useStep;
99096
99624
  vmGlobalThis[WORKFLOW_SET_ATTRIBUTES] = setAttributes;
99097
99625
  vmGlobalThis[WORKFLOW_CREATE_HOOK] = createHook;
99098
- vmGlobalThis[WORKFLOW_SLEEP] = sleep;
99626
+ vmGlobalThis[WORKFLOW_SLEEP] = sleep2;
99099
99627
  vmGlobalThis[WORKFLOW_GET_STREAM_ID] = (namespace) => getWorkflowRunStreamId2(workflowRun.runId, namespace);
99100
99628
  const url3 = isVercel ? `https://${process.env.VERCEL_URL}` : `http://localhost:${port ?? 3e3}`;
99101
99629
  const ctx = {
@@ -99494,7 +100022,7 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
99494
100022
  runCachedWorkflowScript(workflowCode2, filename, context2);
99495
100023
  const workflowFn = runCachedWorkflowScript(`globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, filename, context2);
99496
100024
  if (typeof workflowFn !== "function") {
99497
- throw new WorkflowNotRegisteredError(workflowRun.workflowName);
100025
+ throw new WorkflowNotRegisteredError2(workflowRun.workflowName);
99498
100026
  }
99499
100027
  let args = [];
99500
100028
  workflowContext.promiseQueue = workflowContext.promiseQueue.then(async () => {
@@ -99523,13 +100051,13 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
99523
100051
  span?.setAttributes({
99524
100052
  ...WorkflowResultType2(typeof result)
99525
100053
  });
99526
- await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, "completed");
100054
+ await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, "completed", runReadyBarrier);
99527
100055
  return dehydrated;
99528
100056
  } catch (err) {
99529
100057
  if (WorkflowSuspension2.is(err) || ReplayDivergenceError.is(err)) {
99530
100058
  throw err;
99531
100059
  }
99532
- await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, "failed");
100060
+ await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, "failed", runReadyBarrier);
99533
100061
  throw err;
99534
100062
  }
99535
100063
  });
@@ -99889,10 +100417,10 @@ var Run2 = class _Run2 {
99889
100417
  // ../core/dist/runtime.js
99890
100418
  function getWorkflowSetupErrorCode(err) {
99891
100419
  if (WorkflowRuntimeError2.is(err)) {
99892
- return RUN_ERROR_CODES.RUNTIME_ERROR;
100420
+ return RUN_ERROR_CODES2.RUNTIME_ERROR;
99893
100421
  }
99894
100422
  if (isWorldContractError(err)) {
99895
- return RUN_ERROR_CODES.WORLD_CONTRACT_ERROR;
100423
+ return RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR;
99896
100424
  }
99897
100425
  return null;
99898
100426
  }
@@ -99920,7 +100448,7 @@ async function recordFatalRunError({ world, workflowRun, runId, requestId, err,
99920
100448
  if (isWorldContractError(failErr)) {
99921
100449
  runtimeLogger2.error("Fatal world contract error while recording workflow failure", {
99922
100450
  workflowRunId: runId,
99923
- errorCode: RUN_ERROR_CODES.WORLD_CONTRACT_ERROR,
100451
+ errorCode: RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR,
99924
100452
  error: failErr instanceof Error ? failErr.message : String(failErr)
99925
100453
  });
99926
100454
  return;
@@ -99979,7 +100507,7 @@ function workflowEntrypoint(workflowCode2, options) {
99979
100507
  const workflowName = metadata.queueName.slice(workflowPrefix.length);
99980
100508
  const runLogger = runtimeLogger2.forRun(runId, workflowName);
99981
100509
  if (metadata.attempt > MAX_QUEUE_DELIVERIES) {
99982
- const maxDeliveriesDescription = describeError(void 0, RUN_ERROR_CODES.MAX_DELIVERIES_EXCEEDED);
100510
+ const maxDeliveriesDescription = describeError(void 0, RUN_ERROR_CODES2.MAX_DELIVERIES_EXCEEDED);
99983
100511
  runLogger.error(`Workflow handler exceeded max deliveries (${metadata.attempt}/${MAX_QUEUE_DELIVERIES})`, {
99984
100512
  attempt: metadata.attempt,
99985
100513
  errorCode: maxDeliveriesDescription.errorCode,
@@ -99994,7 +100522,7 @@ function workflowEntrypoint(workflowCode2, options) {
99994
100522
  specVersion: SPEC_VERSION_CURRENT2,
99995
100523
  eventData: {
99996
100524
  error: await dehydrateRunError(err, runId, await getEncryptionKey()),
99997
- errorCode: RUN_ERROR_CODES.MAX_DELIVERIES_EXCEEDED
100525
+ errorCode: RUN_ERROR_CODES2.MAX_DELIVERIES_EXCEEDED
99998
100526
  }
99999
100527
  }, { requestId });
100000
100528
  } catch (err) {
@@ -100419,7 +100947,18 @@ function workflowEntrypoint(workflowCode2, options) {
100419
100947
  eventCount: events.length
100420
100948
  });
100421
100949
  replayStart = Date.now();
100422
- const result = await runWorkflow(workflowCode2, workflowRun, events, encryptionKey, stepHydrationCache);
100950
+ const result = await runWorkflow(
100951
+ workflowCode2,
100952
+ workflowRun,
100953
+ events,
100954
+ encryptionKey,
100955
+ stepHydrationCache,
100956
+ // Turbo: the end-of-run drain inside runWorkflow commits
100957
+ // fire-and-forget `*_created` events before the terminal
100958
+ // `awaitRunReady()` below, so gate those writes on the
100959
+ // backgrounded run_started too. Undefined outside turbo.
100960
+ runReadyBarrier
100961
+ );
100423
100962
  runtimeLogger2.debug("Workflow replay completed", {
100424
100963
  workflowRunId: runId,
100425
100964
  loopIteration,
@@ -100665,12 +101204,20 @@ function workflowEntrypoint(workflowCode2, options) {
100665
101204
  }
100666
101205
  }
100667
101206
  } else {
101207
+ if (isRetryableWorldError2(err)) {
101208
+ runLogger.warn("Transient world error during replay; redelivering via queue instead of failing the run", {
101209
+ errorName: err instanceof Error ? err.name : "UnknownError",
101210
+ errorMessage: err instanceof Error ? err.message : String(err),
101211
+ deliveryAttempt: metadata.attempt
101212
+ });
101213
+ throw err;
101214
+ }
100668
101215
  let terminalError = err;
100669
101216
  if (ReplayDivergenceError.is(err)) {
100670
101217
  const divergenceCount = (replayDivergence?.count ?? 0) + 1;
100671
101218
  if (divergenceCount <= REPLAY_DIVERGENCE_MAX_RETRIES) {
100672
101219
  runLogger.warn("Workflow replay diverged; queueing a recovery replay before declaring the event log corrupted", {
100673
- errorCode: RUN_ERROR_CODES.REPLAY_DIVERGENCE,
101220
+ errorCode: RUN_ERROR_CODES2.REPLAY_DIVERGENCE,
100674
101221
  divergenceEventId: err.eventId,
100675
101222
  priorDivergenceEventId: replayDivergence?.eventId,
100676
101223
  divergenceCount,
@@ -100734,7 +101281,7 @@ function workflowEntrypoint(workflowCode2, options) {
100734
101281
  if (isWorldContractError(failErr)) {
100735
101282
  runtimeLogger2.error("Fatal world contract error while recording workflow failure", {
100736
101283
  workflowRunId: runId,
100737
- errorCode: RUN_ERROR_CODES.WORLD_CONTRACT_ERROR,
101284
+ errorCode: RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR,
100738
101285
  error: failErr instanceof Error ? failErr.message : String(failErr)
100739
101286
  });
100740
101287
  return;
@@ -117072,10 +117619,10 @@ var Run = class _Run {
117072
117619
  return this.getReadable();
117073
117620
  }
117074
117621
  };
117075
- Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#wakeUp");
117076
- Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#cancel");
117077
- Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#getReadable");
117078
- var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#exists");
117622
+ Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#wakeUp");
117623
+ Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#cancel");
117624
+ Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#getReadable");
117625
+ var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#exists");
117079
117626
  Object.defineProperty(Run.prototype, "exists", {
117080
117627
  get() {
117081
117628
  return __step_Run$exists.call(this);
@@ -117083,7 +117630,7 @@ Object.defineProperty(Run.prototype, "exists", {
117083
117630
  configurable: true,
117084
117631
  enumerable: false
117085
117632
  });
117086
- var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#status");
117633
+ var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#status");
117087
117634
  Object.defineProperty(Run.prototype, "status", {
117088
117635
  get() {
117089
117636
  return __step_Run$status.call(this);
@@ -117091,7 +117638,7 @@ Object.defineProperty(Run.prototype, "status", {
117091
117638
  configurable: true,
117092
117639
  enumerable: false
117093
117640
  });
117094
- var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#returnValue");
117641
+ var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#returnValue");
117095
117642
  Object.defineProperty(Run.prototype, "returnValue", {
117096
117643
  get() {
117097
117644
  return __step_Run$returnValue.call(this);
@@ -117099,7 +117646,7 @@ Object.defineProperty(Run.prototype, "returnValue", {
117099
117646
  configurable: true,
117100
117647
  enumerable: false
117101
117648
  });
117102
- var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#workflowName");
117649
+ var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#workflowName");
117103
117650
  Object.defineProperty(Run.prototype, "workflowName", {
117104
117651
  get() {
117105
117652
  return __step_Run$workflowName.call(this);
@@ -117107,7 +117654,7 @@ Object.defineProperty(Run.prototype, "workflowName", {
117107
117654
  configurable: true,
117108
117655
  enumerable: false
117109
117656
  });
117110
- var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#createdAt");
117657
+ var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#createdAt");
117111
117658
  Object.defineProperty(Run.prototype, "createdAt", {
117112
117659
  get() {
117113
117660
  return __step_Run$createdAt.call(this);
@@ -117115,7 +117662,7 @@ Object.defineProperty(Run.prototype, "createdAt", {
117115
117662
  configurable: true,
117116
117663
  enumerable: false
117117
117664
  });
117118
- var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#startedAt");
117665
+ var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#startedAt");
117119
117666
  Object.defineProperty(Run.prototype, "startedAt", {
117120
117667
  get() {
117121
117668
  return __step_Run$startedAt.call(this);
@@ -117123,7 +117670,7 @@ Object.defineProperty(Run.prototype, "startedAt", {
117123
117670
  configurable: true,
117124
117671
  enumerable: false
117125
117672
  });
117126
- var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.24//Run#completedAt");
117673
+ var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.26//Run#completedAt");
117127
117674
  Object.defineProperty(Run.prototype, "completedAt", {
117128
117675
  get() {
117129
117676
  return __step_Run$completedAt.call(this);
@@ -117140,7 +117687,7 @@ Object.defineProperty(Run.prototype, "completedAt", {
117140
117687
  enumerable: false,
117141
117688
  configurable: false
117142
117689
  });
117143
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.24//Run");
117690
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.26//Run");
117144
117691
 
117145
117692
  // ../core/dist/workflow/create-hook.js
117146
117693
  aliasSerializationClass(RUN_CLASS_ID, Run);