@ewhauser/world-celld 0.9.0 → 0.9.1

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.9.1 (2026-10-13)
6
+
7
+ ## What's Changed
8
+ * chore: qualify stable Workflow 5 packages for world-celld by @ewhauser in https://github.com/ewhauser/world-celld/pull/93
9
+ * fix: repair hook index records stranded by an interrupted creation by @ewhauser in https://github.com/ewhauser/world-celld/pull/96
10
+
11
+
12
+ **Full Changelog**: https://github.com/ewhauser/world-celld/compare/v0.9.0...v0.9.1
13
+
5
14
  ## 0.9.0 (2026-10-06)
6
15
 
7
16
  ## What's Changed
package/README.md CHANGED
@@ -14,7 +14,7 @@ self-hosted alternative to platform-specific Workflow backends.
14
14
 
15
15
  ## World protocol compatibility
16
16
 
17
- This adapter supports World spec v8 with the Workflow 5 beta packages. This is
17
+ This adapter supports World spec v8 with the Workflow 5 stable packages. This is
18
18
  a breaking upgrade for applications using a v7 Workflow runtime: that runtime
19
19
  rejects a World advertising v8. This adapter also rejects event writes to runs
20
20
  stamped v7. Keep the v7 adapter and matching Workflow packages in place until
@@ -92,6 +92,22 @@ const world = createCelldWorld({
92
92
  `WORKFLOW_BASE_URL` (or `baseUrl`) is where the native Queue bridge delivers flow
93
93
  requests. It must be reachable from every celld node.
94
94
 
95
+ For overlapping Workflow builds, give each build a distinct `CELLD_DEPLOYMENT_ID`
96
+ and keep its compiled workflow endpoints available while any of its runs remain
97
+ active. Set `WORKFLOW_DEPLOYMENT_URLS` on every app that may accept hooks for those
98
+ runs and in the primary celld worker's private `vars` to the same JSON map, for
99
+ example `{"celld-default":"https://beta.internal","stable-v1":"https://stable.internal"}`.
100
+ The equivalent `createCelldWorld({ deploymentUrls: { ... } })` option configures
101
+ an app directly. Each URL must be an absolute HTTP(S) origin or base path without
102
+ credentials, query, or fragment. Keep every mapped destination reachable from
103
+ the Queue delivery worker. A mapped run's stored deployment ID selects its
104
+ callback build, including for messages queued before this setting was added;
105
+ new messages also snapshot their destination at enqueue. Missing mappings and
106
+ unavailable destinations remain retryable rather than acknowledging the work.
107
+ Keep the map and old build in service through the last old run and pending
108
+ delivery. Do not change an existing deployment ID to point at different
109
+ compiled workflow code. The in-process test queue accepts the same map.
110
+
95
111
  ## Deploy the worker
96
112
 
97
113
  Before deploying, you need a celld v0.6.0 fleet, `esbuild` on `PATH`, and an
@@ -227,16 +243,17 @@ post-compaction costs are recorded in
227
243
  Application options can be passed to `createCelldWorld()` unless an environment
228
244
  variable is shown below.
229
245
 
230
- | Option | Environment variable | Default |
231
- | ----------------------- | ------------------------ | ------------------------ |
232
- | `fleetUrl` | `CELLD_FLEET_URL` | required |
233
- | `secret` | `CELLD_WORLD_SECRET` | required with `fleetUrl` |
234
- | `baseUrl` | `WORKFLOW_BASE_URL` | `http://localhost:$PORT` |
235
- | `deploymentId` | `CELLD_DEPLOYMENT_ID` | `celld-default` |
236
- | `runRetentionMs` | `CELLD_RUN_RETENTION_MS` | `0` (disabled) |
237
- | `streamLongPollMs` | — | `20000` |
238
- | `streamFlushIntervalMs` | — | `0` |
239
- | `rpcTimeoutMs` | — | `30000` (max `300000`) |
246
+ | Option | Environment variable | Default |
247
+ | ----------------------- | -------------------------- | ------------------------ |
248
+ | `fleetUrl` | `CELLD_FLEET_URL` | required |
249
+ | `secret` | `CELLD_WORLD_SECRET` | required with `fleetUrl` |
250
+ | `baseUrl` | `WORKFLOW_BASE_URL` | `http://localhost:$PORT` |
251
+ | `deploymentId` | `CELLD_DEPLOYMENT_ID` | `celld-default` |
252
+ | `deploymentUrls` | `WORKFLOW_DEPLOYMENT_URLS` | unset |
253
+ | `runRetentionMs` | `CELLD_RUN_RETENTION_MS` | `0` (disabled) |
254
+ | `streamLongPollMs` | — | `20000` |
255
+ | `streamFlushIntervalMs` | — | `0` |
256
+ | `rpcTimeoutMs` | — | `30000` (max `300000`) |
240
257
 
241
258
  The deployed worker also accepts these celld variables:
242
259
 
@@ -244,6 +261,7 @@ The deployed worker also accepts these celld variables:
244
261
  | ------------------------------- | ------- | ---------------------------------------------------- |
245
262
  | `WORLD_SECRET` | none | Required bearer secret for RPC routes |
246
263
  | `WORKFLOW_CALLBACK_SECRET` | none | Sent with deliveries as `x-workflow-callback-secret` |
264
+ | `WORKFLOW_DEPLOYMENT_URLS` | unset | JSON map of pinned deployment IDs to callback URLs |
247
265
  | `WORKFLOW_RETENTION_MS` | `0` | Maximum run age from creation; includes active runs |
248
266
  | `WORKFLOW_RETENTION_BATCH_SIZE` | `128` | Runs admitted by each cron sweep (maximum `1000`) |
249
267
 
@@ -49,6 +49,15 @@ in the primary Wrangler config and redeploy to enable a maximum workflow age
49
49
  measured from run creation. celld rejects `CELLD_VAR_*` node overrides.
50
50
  `.dev.vars` overrides apply only to `celld dev`, not production deployments.
51
51
 
52
+ To keep in-flight runs on their original compiled Workflow build, set
53
+ `vars.WORKFLOW_DEPLOYMENT_URLS` in the private primary worker config to a JSON
54
+ object of deployment IDs and reachable HTTP(S) callback URLs. Configure the
55
+ same map in the applications with `WORKFLOW_DEPLOYMENT_URLS` or `deploymentUrls`.
56
+ The worker resolves already queued run messages from the persisted run ID, so
57
+ the map must retain old destinations until their runs and queued deliveries
58
+ finish. Keep each old compiled app available at its mapped URL. An unknown or
59
+ unavailable destination is retried, including a callback 404.
60
+
52
61
  `7776000000` is 90 days. The policy includes pending and running workflows as
53
62
  well as terminal ones. Each cron occurrence admits at most
54
63
  `WORKFLOW_RETENTION_BATCH_SIZE` runs (default `128`); the existing per-run alarm
@@ -48,6 +48,9 @@
48
48
  "WORLD_SECRET": "",
49
49
  // Optional: forwarded as x-workflow-callback-secret on queue deliveries.
50
50
  "WORKFLOW_CALLBACK_SECRET": "",
51
+ // Optional trusted JSON map of persisted deployment IDs to immutable app
52
+ // callback URLs. Keep celld-default mapped to its original beta build.
53
+ "WORKFLOW_DEPLOYMENT_URLS": "",
51
54
  // Optional fleet-wide maximum workflow age, measured from run creation.
52
55
  // Applies to pending, running, and terminal runs. "0" disables it.
53
56
  "WORKFLOW_RETENTION_MS": "0",
package/dist/index.d.ts CHANGED
@@ -313,6 +313,10 @@ interface StreamDOId {
313
313
  toString(): string;
314
314
  }
315
315
  //#endregion
316
+ //#region src/deployment-routing.d.ts
317
+ /** Operator-owned immutable callback destinations, keyed by stored deployment ID. */
318
+ type DeploymentUrls = Readonly<Record<string, string>>;
319
+ //#endregion
316
320
  //#region src/queue.d.ts
317
321
  interface CelldQueueProducer {
318
322
  send(envelope: NativeQueueEnvelope, options?: NativeQueueSendOptions): Promise<NativeQueueSendResult>;
@@ -426,6 +430,8 @@ interface CelldWorldConfig {
426
430
  * Default: process.env.WORKFLOW_BASE_URL || `http://localhost:${PORT ?? 3000}`
427
431
  */
428
432
  baseUrl?: string;
433
+ /** Immutable callback URLs for explicitly targeted deployments. Optional. */
434
+ deploymentUrls?: DeploymentUrls;
429
435
  /**
430
436
  * Keep terminal run payloads for this many milliseconds before replacing
431
437
  * them with metadata-only tombstones. Zero disables automatic cleanup.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/retention.ts","../src/apply-event.ts","../src/storage.ts","../src/stream-protocol.ts","../src/streamer.ts","../src/queue.ts","../src/run-list.ts","../src/indexes.ts","../src/config.ts","../src/index.ts"],"mappings":";;;KAOY;UAEK;EACf;EACA;EACA;EACA,WAAW;;EAEX,SAAS;;EAET,cAAc;;EAEd,iBAAiB;EACjB;EACA,OAAO;EACP,OAAO;;EAEP;EACA;EACA;EACA,gBAAgB;EAChB,eAAe;EACf;EACA;;EAEA;;UAGe;EACf;EACA;;EAEA,SAAS;EACT,cAAc;EACd,iBAAiB;EACjB,WAAW;EACX,cAAc;;EAEd,SAAS;;KAGC;KAEA,eAAe;EACrB;EAAU,OAAO;;EACjB;EAAW;EAAqB;EAAiB,WAAW;;UAEjD;EACf;EACA;;UAae;EACf;EACA,OAAO;;UAGQ;EACf;;UAGe;EACf;EACA,OAAO;EACP;;UAGe;EACf;;UAGe;EACf;;UAGe;;EAEf;EACA;;UAGe;;EAEf;;EAEA;;EAEA;EACA;;UAGe;EACf;;;;UC0Ce;;EAEf;EACA,MAAM,qBAAqB;;EAE3B,SAAS;;;;;EAKT;IAAgB;IAAe;;;EAE/B;;EAEA,UAAU;;KAiFA;UAWK;EACf;EACA,MAAM;EACN;;EAEA;;EAEA;;UAGe;EACf;;EAEA,QAAQ;EACR,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;;EAEP;;EAEA,eAAe;IAAQ;IAAgB;;;EAEvC;IAAe;IAAsB,WAAW;;;EAEhD,cAAc;;EAEd,SAAS;;EAET;EACA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;EAKA,YAAY;;KAGF,oBAAoB,oBAAoB;;;;;;;UClPnC;EACf,WAAW,SAAS,oBAAoB,QAAQ;EAChD,sBAAsB;IACpB;IACA;IACA;MACE;IAAU;;EACd,wBAAwB;IACtB;IACA;IACA;MACE,QAAQ;EACZ,sBAAsB,QADlB;EAEJ,UAAU,QAAQ,eAAe;EACjC,QAAQ,iBAAiB,QAAQ,eAAe;EAChD,SAAS,kBAAkB,QAAQ,eAAe;EAClD,WAAW;IACT;IACA;IACA;MACE,QAAQ;IAAiB,MAAM;IAAS;IAAuB;;EACnE,UAAU;IACR;IACA;IACA;MACE,QAAQ;IAAiB,MAAM;IAAQ;IAAuB;;EAClE,UAAU;IACR;IACA;IACA;MACE,QAAQ;IAAiB,MAAM;IAAQ;IAAuB;;EAClE,oBAAoB,QADhB;EAEJ,gBACE,SAFkB,yBAGjB,QADiC;EAEpC,WACE,SAFC,yBAGA,QADiC;EAEpC,gBAAgB,QADb;;UAIY;EACf,WAAW,eAAe;EAC1B,IAAI,IAAI,sBAAsB;;UAGf;EACf;;;;;;;;cChGW;;cAEA;;cAEA;;cAEA;cAKA;cACA;;cAEA;KAED;UAEK;EACf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA,QAAQ;EACR,OAAO;EACP;EACA,QAAQ;;;;UClBO,sBAAsB,KAAK;EAC1C,SAAS;IACP,KAAK,eAAe,cAAc,OAAO,2BAA2B;;EAEtE,cACE,cACA,gBAAgB,iBAChB,gBAAgB,aACf;EACH,oBACE,cACA,gBAAgB,iBAChB,2BAA2B,gBAC1B;EACH,YAAY,cAAc,gBAAgB,kBAAkB;EAC5D,YACE,cACA,gBAAgB,iBAChB,OAAO,2BACN;EACH,eACE,cACA,eACA,sBACC,QAAQ,eAAe;EAC1B,mBAAmB,gBAAgB;EACnC,gBACE,cACA,eACA,UAAU,mBACT,QAAQ;EACX,cAAc,cAAc,gBAAgB,QAAQ;;;UAIrC;;;;;EAKf;;EAEA;EACA,YAAY,eAAe,QAAQ,eAAe,QAAQ;EAC1D,WAAW,SAAS,mBAAmB,SAAS,cAAc,QAAQ;EACtE,YAAY,gBAAgB;EAC5B,WAAW,eAAe,OAAO,2BAA2B;EAC5D,eAAe,eAAe,eAAe;EAC7C,eAAe;EACf,eACE,eACA,mBACA;IAAY;MACX,QAAQ;EACX,iBAAiB,eAAe,oBAAoB,QAAQ;EAC5D,aACE,eACA,mBACA;IAAY;IAAgB;MAC3B,QAAQ;;UAGI;EACf,WAAW,eAAe;EAC1B,IAAI,IAAI,aAAa;;UAGN;EACf;;;;UCPe;EACf,KACE,UAAU,qBACV,UAAU,yBACT,QAAQ;;;;KC9FD,YAAY;;UAGP;EACf;EACA,WAAW;EACX;EACA;EACA;;EAEA;;UAGe;EACf,MAAM;EACN;EACA;;;;UCPe;EACf;EACA;;EAEA;EACA;EACA;;UAGe;;EAEf,MAAM;IAAQ;IAAc;IAAe;;EAC3C;EACA;;UAuBe;EACf;EACA;EACA;;KAGU;EACN;EAAgB,aAAa;;EAC7B;EAAiB,QAAQ;;;UAgDd;EACf,UACE,KAAK,aACL,4BACA,+BACC;IAAU;;EACb,SAAS,UAAU,mBAAmB,QAAQ;;;;;EAK9C,kBAAkB,SAAS,iBAAiB,QAAQ;EACpD,eAAe,gBAAgB;EAC/B,YAAY,iBAAiB;EAC7B,YAAY,eAAe,OAAO,iBAAiB,QAAQ;EAC3D,oBACE,eACA,gBACA,wBACA,OAAO,gBACP,cAAc,kBACb;EACH,uBACE,eACA,OAAO,gBACP,aAAa,kBACZ;EACH,mBAAmB,SAAS,4BAA4B,QAAQ;EAChE,UAAU,SAAS,0BAA0B,QAAQ;;;;;KChI3C,iBAAiB;UAEZ;EACf;EACA;;UAGe;EACf,aAAa;EACb,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;;UAGH;;;;;;;EAOf;;;;;EAKA;;;;;EAKA,MAAM;;EAEN;;;;;;EAMA;;;;;;EAMA;;EAEA;;EAEA;;EAEA;;;;UCpBe;EACf,UAAU,gBAAgB,QAAQ;EAClC,SAAS,gBAAgB,QAAQ;EACjC,WAAW,gBAAgB,QAAQ;EACnC,MAAM,gBAAgB,QAAQ;;KAGpB,aAAa,QAAQ;EAAkB,WAAW;;iBAS9C,iBAAiB,SAAS,mBAAmB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/retention.ts","../src/apply-event.ts","../src/storage.ts","../src/stream-protocol.ts","../src/streamer.ts","../src/deployment-routing.ts","../src/queue.ts","../src/run-list.ts","../src/indexes.ts","../src/config.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as normalizeStreamError, A as boundedIntegerOption, B as MAX_STREAM_LONG_POLL_MS, D as MAX_QUEUE_DERIVED_DEADLINE_HEADROOM_MS, E as MAX_QUEUE_DELIVERY_TIMEOUT_MS, F as queueDelayDeadline, G as STREAM_CHUNK_LIMIT_HEADER, H as MAX_STREAM_READ_CHUNKS, I as strictIntegerSetting, J as decodeStreamWriteResult, K as decodeStreamReadResult, L as MAX_STREAM_BATCH_BYTES, Q as isChunkLimitRejection, R as MAX_STREAM_CHUNK_BYTES, T as MAX_FLEET_RPC_TIMEOUT_MS, U as MAX_STREAM_WRITE_CHUNKS, V as MAX_STREAM_READ_BYTES, W as STREAM_BATCH_CONTENT_TYPE, X as encodeStreamWriteBatch, _ as rpcStringify, b as createWorkflowIndex, c as nativeQueueDelaySeconds, g as rpcParse, h as compact, j as checkedQueueTimestampAdd, l as queueClaimName, n as listRunsPage, v as parse, x as runIndexMetadata, y as stringify, z as MAX_STREAM_ERROR_BYTES } from "./run-list-C4B4SBYW.js";
1
+ import { $ as encodeStreamWriteBatch, A as MAX_QUEUE_DERIVED_DEADLINE_HEADROOM_MS, B as MAX_STREAM_BATCH_BYTES, C as parseDeploymentUrls, G as MAX_STREAM_READ_CHUNKS, H as MAX_STREAM_ERROR_BYTES, J as STREAM_CHUNK_LIMIT_HEADER, K as MAX_STREAM_WRITE_CHUNKS, N as boundedIntegerOption, O as MAX_FLEET_RPC_TIMEOUT_MS, P as checkedQueueTimestampAdd, R as queueDelayDeadline, S as configuredDeploymentUrl, U as MAX_STREAM_LONG_POLL_MS, V as MAX_STREAM_CHUNK_BYTES, W as MAX_STREAM_READ_BYTES, Y as decodeStreamReadResult, Z as decodeStreamWriteResult, _ as rpcStringify, b as createWorkflowIndex, c as nativeQueueDelaySeconds, g as rpcParse, h as compact, k as MAX_QUEUE_DELIVERY_TIMEOUT_MS, l as queueClaimName, n as listRunsPage, nt as normalizeStreamError, q as STREAM_BATCH_CONTENT_TYPE, tt as isChunkLimitRejection, v as parse, w as validateDeploymentUrls, x as runIndexMetadata, y as stringify, z as strictIntegerSetting } from "./run-list-CHRaDRvU.js";
2
2
  import { CreateEventSchema, EventSchema, HookSchema, MessageId, QueuePayloadSchema, SPEC_VERSION_CURRENT, StepSchema, WaitSchema, WorkflowRunSchema, parseQueueName } from "@workflow/world";
3
3
  import { EntityConflictError, HookNotFoundError, RunExpiredError, RunNotSupportedError, TooEarlyError, WorkflowRunNotFoundError, WorkflowWorldError } from "@workflow/errors";
4
4
  import { monotonicFactory } from "ulid";
@@ -18,6 +18,7 @@ function resolveConfig(config) {
18
18
  env: config?.env,
19
19
  deploymentId: config?.deploymentId ?? process.env.CELLD_DEPLOYMENT_ID ?? "celld-default",
20
20
  baseUrl: config?.baseUrl,
21
+ deploymentUrls: config?.deploymentUrls === void 0 ? parseDeploymentUrls(process.env.WORKFLOW_DEPLOYMENT_URLS) : validateDeploymentUrls(config.deploymentUrls),
21
22
  runRetentionMs,
22
23
  streamLongPollMs,
23
24
  streamFlushIntervalMs,
@@ -609,7 +610,8 @@ function createTestPump(config) {
609
610
  });
610
611
  }
611
612
  function retry(envelope, pathname, reason) {
612
- if (envelope.attempt >= maxAttempts) {
613
+ const mappedRun = config.deploymentUrls !== void 0 && "runId" in envelope.message;
614
+ if (envelope.attempt >= maxAttempts && !mappedRun) {
613
615
  release(envelope);
614
616
  console.error(`[world-celld test pump] dropping ${envelope.messageId} after ${envelope.attempt} attempts: ${reason}`);
615
617
  return;
@@ -627,7 +629,7 @@ function createTestPump(config) {
627
629
  delayFor(backoff).then(() => enqueue(pathname, next));
628
630
  }
629
631
  async function dispatch(envelope, pathname) {
630
- const url = `${resolveBaseUrl(config)}/.well-known/workflow/v1/${pathname}`;
632
+ const url = `${envelope.targetBaseUrl}/.well-known/workflow/v1/${pathname}`;
631
633
  const response = await fetch(url, {
632
634
  method: "POST",
633
635
  headers: {
@@ -639,7 +641,7 @@ function createTestPump(config) {
639
641
  body: stringify(envelope.message),
640
642
  signal: AbortSignal.timeout(httpTimeoutMs)
641
643
  });
642
- if (response.ok || PERMANENT_ERROR_STATUSES.has(response.status)) {
644
+ if (response.ok || !config.deploymentUrls && PERMANENT_ERROR_STATUSES.has(response.status) || !("runId" in envelope.message) && PERMANENT_ERROR_STATUSES.has(response.status)) {
643
645
  try {
644
646
  await response.body?.cancel();
645
647
  } catch {}
@@ -701,6 +703,7 @@ function createTestPump(config) {
701
703
  }
702
704
  function createQueue(config) {
703
705
  const { env, deploymentId } = config;
706
+ const deploymentUrls = config.deploymentUrls === void 0 ? void 0 : validateDeploymentUrls(config.deploymentUrls);
704
707
  if (!env?.WORKFLOW_QUEUE) throw new Error("world-celld queue missing WORKFLOW_QUEUE binding");
705
708
  const generateMessageId = monotonicFactory();
706
709
  const testPump = createTestPump(config);
@@ -711,6 +714,17 @@ function createQueue(config) {
711
714
  if (!parsedMessage.success) throw new WorkflowWorldError("world-celld queue payload is invalid", { status: 422 });
712
715
  if (queueDelayDeadline(Date.now(), opts?.delaySeconds ?? 0, 0, 900001) === null) throw new Error("world-celld queue delaySeconds lacks required delivery headroom");
713
716
  const runId = "runId" in parsedMessage.data && typeof parsedMessage.data.runId === "string" ? parsedMessage.data.runId : void 0;
717
+ const targetIds = [
718
+ opts?.deploymentId,
719
+ "runInput" in parsedMessage.data ? parsedMessage.data.runInput?.deploymentId : void 0,
720
+ "runContext" in parsedMessage.data ? parsedMessage.data.runContext?.deploymentId : void 0,
721
+ "hookInput" in parsedMessage.data ? parsedMessage.data.hookInput?.deploymentId : void 0
722
+ ].filter((id) => typeof id === "string");
723
+ if (targetIds.some((id) => id !== targetIds[0])) throw new Error("world-celld: queue deployment hints disagree");
724
+ const targetId = targetIds[0] ?? deploymentId;
725
+ if (deploymentUrls && runId && targetIds.length === 0) throw new Error("world-celld: queued run has no deployment routing hint");
726
+ if (!deploymentUrls && opts?.deploymentId && targetId !== deploymentId) throw new Error(`world-celld: no callback URL configured for deployment ${targetId}`);
727
+ const targetBaseUrl = deploymentUrls ? configuredDeploymentUrl(deploymentUrls, targetId) : resolveBaseUrl(config).replace(/\/$/, "");
714
728
  if (isTestMode()) {
715
729
  const existing = testPump.inflight(queueName, opts?.idempotencyKey);
716
730
  if (existing) return { messageId: existing };
@@ -720,7 +734,8 @@ function createQueue(config) {
720
734
  queueName,
721
735
  attempt: 1,
722
736
  message: parsedMessage.data,
723
- idempotencyKey: opts?.idempotencyKey
737
+ idempotencyKey: opts?.idempotencyKey,
738
+ targetBaseUrl
724
739
  }, opts?.delaySeconds);
725
740
  return { messageId };
726
741
  }
@@ -731,7 +746,7 @@ function createQueue(config) {
731
746
  version: 1,
732
747
  messageId,
733
748
  queueName,
734
- targetBaseUrl: resolveBaseUrl(config),
749
+ targetBaseUrl,
735
750
  runId,
736
751
  idempotencyKey: opts?.idempotencyKey,
737
752
  body,
@@ -1488,7 +1503,8 @@ function createCelldWorld(config) {
1488
1503
  const queue = createQueue({
1489
1504
  env: { WORKFLOW_QUEUE: env.WORKFLOW_QUEUE },
1490
1505
  deploymentId: resolved.deploymentId,
1491
- baseUrl: resolved.baseUrl
1506
+ baseUrl: resolved.baseUrl,
1507
+ deploymentUrls: resolved.deploymentUrls
1492
1508
  });
1493
1509
  const streamer = createStreamer({
1494
1510
  env: { WORKFLOW_STREAMS: env.WORKFLOW_STREAMS },