@bastani/atomic 0.9.26-alpha.3 → 0.9.26-alpha.4

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.
@@ -67501,10 +67501,10 @@ function recordPendingStageMessageDeliveries(messages, runId, messageId, records
67501
67501
  if (index < 0)
67502
67502
  return messages;
67503
67503
  const entry = messages[index];
67504
- const recorded = new Set((entry.deliveries ?? []).map((delivery) => `${delivery.runId}\x00${delivery.stageId}`));
67504
+ const recorded = new Set((entry.deliveries ?? []).map((delivery) => JSON.stringify([delivery.runId, delivery.stageId, delivery.sessionId, delivery.admission])));
67505
67505
  const additions = [];
67506
67506
  for (const record of records) {
67507
- const key = `${record.runId}\x00${record.stageId}`;
67507
+ const key = JSON.stringify([record.runId, record.stageId, record.sessionId, record.admission]);
67508
67508
  if (recorded.has(key))
67509
67509
  continue;
67510
67510
  recorded.add(key);
@@ -67512,6 +67512,8 @@ function recordPendingStageMessageDeliveries(messages, runId, messageId, records
67512
67512
  runId: record.runId,
67513
67513
  stageId: record.stageId,
67514
67514
  ...record.stageName === undefined ? {} : { stageName: record.stageName },
67515
+ ...record.sessionId === undefined ? {} : { sessionId: record.sessionId },
67516
+ ...record.admission === undefined ? {} : { admission: record.admission },
67515
67517
  deliveredAt
67516
67518
  });
67517
67519
  }
@@ -92282,6 +92284,292 @@ function observeRunExecution(run, now = Date.now()) {
92282
92284
  };
92283
92285
  }
92284
92286
 
92287
+ // dist/builtin/workflows/src/durable/prompt-reservations.ts
92288
+ function durablePromptScope(backend, workflowId) {
92289
+ return backend.promptReservationScope(workflowId);
92290
+ }
92291
+ function claimDurablePromptToken(backend, workflowId, reservationId) {
92292
+ return backend.pendingPromptToken(workflowId, reservationId);
92293
+ }
92294
+ function reserveDurablePrompt(backend, workflowId, reservationId) {
92295
+ return backend.reservePendingPrompt(workflowId, reservationId);
92296
+ }
92297
+ function releaseDurablePrompt(backend, workflowId, reservationId, token) {
92298
+ backend.releasePendingPrompt(workflowId, reservationId, token);
92299
+ }
92300
+
92301
+ // dist/builtin/workflows/src/durable/scoped-backend.ts
92302
+ class ScopedDurableBackend {
92303
+ persistent;
92304
+ inner;
92305
+ scope;
92306
+ constructor(inner, scope) {
92307
+ this.inner = inner;
92308
+ this.scope = scope;
92309
+ this.persistent = inner.persistent;
92310
+ }
92311
+ registerWorkflow(_handle) {}
92312
+ persistPendingStageMessages(workflowId, messages, logicalRunId = workflowId) {
92313
+ return this.inner.persistPendingStageMessages(this.scope.rootWorkflowId, messages, logicalRunId);
92314
+ }
92315
+ recordCheckpoint(checkpoint) {
92316
+ this.inner.recordCheckpoint(this.remap(checkpoint));
92317
+ }
92318
+ async recordCheckpointAsync(checkpoint, options) {
92319
+ await this.inner.recordCheckpointAsync(this.remap(checkpoint), options);
92320
+ }
92321
+ async recordAdditiveCheckpointBestEffort(checkpoint) {
92322
+ return await this.inner.recordAdditiveCheckpointBestEffort(this.remap(checkpoint));
92323
+ }
92324
+ flush(workflowId) {
92325
+ return workflowId === undefined ? this.inner.flush() : this.inner.flush(this.scope.rootWorkflowId);
92326
+ }
92327
+ getToolOutput(_workflowId, argsHash) {
92328
+ return this.inner.getToolOutput(this.scope.rootWorkflowId, this.scopeKey(argsHash));
92329
+ }
92330
+ getToolCheckpoint(_workflowId, argsHash) {
92331
+ return this.inner.getToolCheckpoint(this.scope.rootWorkflowId, this.scopeKey(argsHash));
92332
+ }
92333
+ getUiResponse(_workflowId, promptHash) {
92334
+ return this.inner.getUiResponse(this.scope.rootWorkflowId, this.scopeKey(promptHash));
92335
+ }
92336
+ getStageOutput(_workflowId, replayKey) {
92337
+ return this.inner.getStageOutput(this.scope.rootWorkflowId, this.scopeKey(replayKey));
92338
+ }
92339
+ getStageSession(_workflowId, replayKey) {
92340
+ return this.inner.getStageSession(this.scope.rootWorkflowId, this.scopeKey(replayKey));
92341
+ }
92342
+ listCheckpoints(workflowId) {
92343
+ const prefix = `${this.scope.scopePrefix}:`;
92344
+ return this.inner.listCheckpoints(this.scope.rootWorkflowId).filter((checkpoint) => checkpointHasPrefix(checkpoint, prefix)).map((checkpoint) => localCheckpoint(checkpoint, workflowId, prefix));
92345
+ }
92346
+ getWorkflow(_workflowId) {
92347
+ return;
92348
+ }
92349
+ getLoadableWorkflow(_workflowId) {
92350
+ return;
92351
+ }
92352
+ setWorkflowStatus(_workflowId, _status, _pendingPrompts, _resumable) {}
92353
+ async transitionWorkflowStatus(_workflowId, _expectedStatuses, _status, _pendingPrompts, _resumable) {
92354
+ return false;
92355
+ }
92356
+ adjustPendingPrompts(_workflowId, delta) {
92357
+ this.inner.adjustPendingPrompts(this.scope.rootWorkflowId, delta);
92358
+ }
92359
+ promptReservationScope(_workflowId) {
92360
+ return this.effectivePromptScope();
92361
+ }
92362
+ pendingPromptToken(_workflowId, reservationId) {
92363
+ return claimDurablePromptToken(this.inner, this.scope.rootWorkflowId, reservationId);
92364
+ }
92365
+ reservePendingPrompt(_workflowId, reservationId) {
92366
+ return reserveDurablePrompt(this.inner, this.scope.rootWorkflowId, reservationId);
92367
+ }
92368
+ releasePendingPrompt(_workflowId, reservationId, token) {
92369
+ releaseDurablePrompt(this.inner, this.scope.rootWorkflowId, reservationId, token);
92370
+ }
92371
+ listResumableWorkflows() {
92372
+ return [];
92373
+ }
92374
+ listCompletedWorkflows() {
92375
+ return [];
92376
+ }
92377
+ async prepareWorkflowCatalog() {
92378
+ return { resumable: [], completed: [] };
92379
+ }
92380
+ toMetadata(_workflowId) {
92381
+ return;
92382
+ }
92383
+ async deleteWorkflow(_workflowId) {}
92384
+ async deleteWorkflowIfInactive(_workflowId) {
92385
+ return { ok: false, reason: "not_found" };
92386
+ }
92387
+ isWorkflowLoadable(_workflowId) {
92388
+ return false;
92389
+ }
92390
+ reset() {}
92391
+ hydrateWorkflow(_workflowId) {
92392
+ return Promise.resolve();
92393
+ }
92394
+ hydrateWorkflowForInspection(_workflowId) {
92395
+ return Promise.resolve({ kind: "absent" });
92396
+ }
92397
+ hydrateResumableWorkflows() {
92398
+ return Promise.resolve();
92399
+ }
92400
+ effectivePromptScope() {
92401
+ const parent = durablePromptScope(this.inner, this.scope.rootWorkflowId);
92402
+ const scope = parent.scope === "root" ? this.scope.scopePrefix : `${parent.scope}:${this.scope.scopePrefix}`;
92403
+ return {
92404
+ rootWorkflowId: parent.rootWorkflowId,
92405
+ scope
92406
+ };
92407
+ }
92408
+ scopeKey(key) {
92409
+ return `${this.scope.scopePrefix}:${key}`;
92410
+ }
92411
+ remap(checkpoint) {
92412
+ const workflowId = this.scope.rootWorkflowId;
92413
+ if (checkpoint.kind === "tool") {
92414
+ return {
92415
+ ...checkpoint,
92416
+ workflowId,
92417
+ checkpointId: this.scopeKey(checkpoint.checkpointId),
92418
+ argsHash: this.scopeKey(checkpoint.argsHash)
92419
+ };
92420
+ }
92421
+ if (checkpoint.kind === "ui") {
92422
+ return {
92423
+ ...checkpoint,
92424
+ workflowId,
92425
+ checkpointId: this.scopeKey(checkpoint.checkpointId),
92426
+ promptHash: this.scopeKey(checkpoint.promptHash)
92427
+ };
92428
+ }
92429
+ return {
92430
+ ...checkpoint,
92431
+ workflowId,
92432
+ checkpointId: this.scopeKey(checkpoint.checkpointId),
92433
+ replayKey: this.scopeKey(checkpoint.replayKey),
92434
+ ...remappedBoundaryScope(checkpoint, this.scopeKey(checkpoint.topology?.boundary?.replayScope ?? ""))
92435
+ };
92436
+ }
92437
+ }
92438
+ function checkpointHasPrefix(checkpoint, prefix) {
92439
+ if (!checkpoint.checkpointId.startsWith(prefix))
92440
+ return false;
92441
+ if (checkpoint.kind === "tool")
92442
+ return checkpoint.argsHash.startsWith(prefix);
92443
+ if (checkpoint.kind === "ui")
92444
+ return checkpoint.promptHash.startsWith(prefix);
92445
+ return checkpoint.replayKey.startsWith(prefix);
92446
+ }
92447
+ function localCheckpoint(checkpoint, workflowId, prefix) {
92448
+ const checkpointId = checkpoint.checkpointId.slice(prefix.length);
92449
+ if (checkpoint.kind === "tool") {
92450
+ return { ...checkpoint, workflowId, checkpointId, argsHash: checkpoint.argsHash.slice(prefix.length) };
92451
+ }
92452
+ if (checkpoint.kind === "ui") {
92453
+ return { ...checkpoint, workflowId, checkpointId, promptHash: checkpoint.promptHash.slice(prefix.length) };
92454
+ }
92455
+ const replayKey = checkpoint.replayKey.slice(prefix.length);
92456
+ const replayScope = stripOnePrefix(checkpoint.topology?.boundary?.replayScope, prefix);
92457
+ return {
92458
+ ...checkpoint,
92459
+ workflowId,
92460
+ checkpointId,
92461
+ replayKey,
92462
+ ...remappedBoundaryScope(checkpoint, replayScope)
92463
+ };
92464
+ }
92465
+ function remappedBoundaryScope(checkpoint, replayScope) {
92466
+ const topology = checkpoint.topology;
92467
+ if (topology?.boundary === undefined || replayScope === undefined)
92468
+ return {};
92469
+ return {
92470
+ topology: {
92471
+ ...topology,
92472
+ boundary: { ...topology.boundary, replayScope }
92473
+ }
92474
+ };
92475
+ }
92476
+ function stripOnePrefix(value2, prefix) {
92477
+ if (value2 === undefined || !value2.startsWith(prefix))
92478
+ return value2;
92479
+ return value2.slice(prefix.length);
92480
+ }
92481
+
92482
+ // dist/builtin/workflows/src/durable/run-owner-backend.ts
92483
+ function durableRootRunIdForRun(runs, runId) {
92484
+ return reciprocalWorkflowRootRunId(new Map(runs.map((run) => [run.id, run])), runId);
92485
+ }
92486
+ function durableBackendForRun(backend, runs, runId) {
92487
+ const rootRunId = durableRootRunIdForRun(runs, runId);
92488
+ if (rootRunId === undefined)
92489
+ return;
92490
+ const runById = new Map(runs.map((run) => [run.id, run]));
92491
+ if (rootRunId === runId)
92492
+ return backend;
92493
+ const scopes = [];
92494
+ let current = runById.get(runId);
92495
+ while (current !== undefined && current.id !== rootRunId) {
92496
+ const parent = current.parentRunId === undefined ? undefined : runById.get(current.parentRunId);
92497
+ const boundary = parent?.stages.find((stage) => stage.id === current?.parentStageId);
92498
+ if (parent === undefined || boundary?.replayKey === undefined)
92499
+ return;
92500
+ scopes.push(boundary.replayKey);
92501
+ current = parent;
92502
+ }
92503
+ if (current?.id !== rootRunId)
92504
+ return;
92505
+ let view = backend;
92506
+ for (const scopePrefix of scopes.reverse()) {
92507
+ view = new ScopedDurableBackend(view, { rootWorkflowId: rootRunId, scopePrefix });
92508
+ }
92509
+ return view;
92510
+ }
92511
+
92512
+ // dist/builtin/workflows/src/shared/sticky-stage-delivery-status.ts
92513
+ function stickyStageDeliveryStatuses(runs, rootRunId) {
92514
+ const root = runs.find((run) => run.id === rootRunId);
92515
+ const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
92516
+ const result = [];
92517
+ for (const run of runs) {
92518
+ if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunIdForRun(runs, run.id) !== rootRunId)
92519
+ continue;
92520
+ const resolved = durableRootRunIdForRun(runs, run.id) === rootRunId;
92521
+ const hops = workflowBoundaryHops(runs, run.id);
92522
+ for (const stage of run.stages) {
92523
+ if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
92524
+ continue;
92525
+ for (const entry of entries) {
92526
+ const target = entry.targetPath ?? entry.stageKey;
92527
+ const parsed = parseWorkflowStageTarget(target);
92528
+ if (!parsed || parsed.rootRunId !== rootRunId)
92529
+ continue;
92530
+ if (resolved && hops && !stageMatchesPathPattern(parsed.segments, hops, [stage.id, stage.name]))
92531
+ continue;
92532
+ const receipts = (entry.deliveries ?? []).filter((delivery) => delivery.runId === run.id && delivery.stageId === stage.id);
92533
+ const delivered = receipts.some((delivery) => delivery.admission === "context" && delivery.sessionId !== undefined && (stage.sessionId === undefined || delivery.sessionId === stage.sessionId));
92534
+ let state;
92535
+ let reason;
92536
+ if (!resolved || !hops) {
92537
+ state = "root-unresolved";
92538
+ reason = "Repair reciprocal parent/boundary ownership before startup";
92539
+ } else if (delivered) {
92540
+ state = "delivered";
92541
+ reason = "Startup context admission confirmed; sticky subscription remains for future stages";
92542
+ } else if (["completed", "failed", "skipped"].includes(stage.status)) {
92543
+ state = "stage-terminal";
92544
+ reason = `${stage.error ? `${stage.error}; ` : ""}Stage ended without confirmed context admission; steer a live stage or start a new stage`;
92545
+ } else if (receipts.some((delivery) => delivery.admission !== "context" && (delivery.sessionId === undefined || stage.sessionId === undefined || delivery.sessionId === stage.sessionId))) {
92546
+ state = "receipt-unverified";
92547
+ reason = "Legacy or live transport receipt only; inspect the session transcript to confirm context admission";
92548
+ } else if (stage.pendingStageDeliveryAvailable !== true) {
92549
+ state = "delivery-unavailable";
92550
+ reason = "Stage has no pre-start Intercom helper; enable Intercom in the invocation group";
92551
+ } else if (receipts.length > 0) {
92552
+ state = "session-replaced";
92553
+ reason = "Only a previous session has a receipt; replacement must drain before its first turn";
92554
+ } else {
92555
+ state = "queued";
92556
+ reason = "No delivery receipt; stage startup must drain before its first turn";
92557
+ }
92558
+ result.push({
92559
+ messageId: entry.message.id,
92560
+ target,
92561
+ runId: run.id,
92562
+ stageId: stage.id,
92563
+ ...stage.sessionId === undefined ? {} : { sessionId: stage.sessionId },
92564
+ state,
92565
+ reason
92566
+ });
92567
+ }
92568
+ }
92569
+ }
92570
+ return result;
92571
+ }
92572
+
92285
92573
  // dist/builtin/workflows/src/runs/background/run-inspect.ts
92286
92574
  function inspectRun(runId, opts) {
92287
92575
  const activeStore = opts?.store ?? store;
@@ -92312,6 +92600,7 @@ function inspectRun(runId, opts) {
92312
92600
  inputs: copy.inputs,
92313
92601
  stages: expandedStages.map((stage) => structuredClone(stage)),
92314
92602
  tools: expandedGraph.tools.map((tool) => structuredClone(tool)),
92603
+ deliveryStates: stickyStageDeliveryStatuses(activeStore.runs(), copy.rootRunId ?? copy.id).filter((delivery) => copy.id === (copy.rootRunId ?? copy.id) || delivery.runId === copy.id),
92315
92604
  result: copy.result,
92316
92605
  error: copy.error ?? (strandedRoot ? IMPOSSIBLE_ROOT_LIVENESS_MESSAGE : effectiveRunStatus(copy) === copy.status ? undefined : structuredRecoverableWorkflowFailureText(copy) ?? actionableReturnedStatusText(copy.result)),
92317
92606
  exited: copy.exited,
@@ -102244,201 +102533,6 @@ function hasInvocationData(checkpoints, replayKey) {
102244
102533
  // dist/builtin/workflows/src/engine/run.ts
102245
102534
  init_dbos_admission();
102246
102535
 
102247
- // dist/builtin/workflows/src/durable/prompt-reservations.ts
102248
- function durablePromptScope(backend, workflowId) {
102249
- return backend.promptReservationScope(workflowId);
102250
- }
102251
- function claimDurablePromptToken(backend, workflowId, reservationId) {
102252
- return backend.pendingPromptToken(workflowId, reservationId);
102253
- }
102254
- function reserveDurablePrompt(backend, workflowId, reservationId) {
102255
- return backend.reservePendingPrompt(workflowId, reservationId);
102256
- }
102257
- function releaseDurablePrompt(backend, workflowId, reservationId, token) {
102258
- backend.releasePendingPrompt(workflowId, reservationId, token);
102259
- }
102260
-
102261
- // dist/builtin/workflows/src/durable/scoped-backend.ts
102262
- class ScopedDurableBackend {
102263
- persistent;
102264
- inner;
102265
- scope;
102266
- constructor(inner, scope) {
102267
- this.inner = inner;
102268
- this.scope = scope;
102269
- this.persistent = inner.persistent;
102270
- }
102271
- registerWorkflow(_handle) {}
102272
- persistPendingStageMessages(workflowId, messages, logicalRunId = workflowId) {
102273
- return this.inner.persistPendingStageMessages(this.scope.rootWorkflowId, messages, logicalRunId);
102274
- }
102275
- recordCheckpoint(checkpoint) {
102276
- this.inner.recordCheckpoint(this.remap(checkpoint));
102277
- }
102278
- async recordCheckpointAsync(checkpoint, options) {
102279
- await this.inner.recordCheckpointAsync(this.remap(checkpoint), options);
102280
- }
102281
- async recordAdditiveCheckpointBestEffort(checkpoint) {
102282
- return await this.inner.recordAdditiveCheckpointBestEffort(this.remap(checkpoint));
102283
- }
102284
- flush(workflowId) {
102285
- return workflowId === undefined ? this.inner.flush() : this.inner.flush(this.scope.rootWorkflowId);
102286
- }
102287
- getToolOutput(_workflowId, argsHash) {
102288
- return this.inner.getToolOutput(this.scope.rootWorkflowId, this.scopeKey(argsHash));
102289
- }
102290
- getToolCheckpoint(_workflowId, argsHash) {
102291
- return this.inner.getToolCheckpoint(this.scope.rootWorkflowId, this.scopeKey(argsHash));
102292
- }
102293
- getUiResponse(_workflowId, promptHash) {
102294
- return this.inner.getUiResponse(this.scope.rootWorkflowId, this.scopeKey(promptHash));
102295
- }
102296
- getStageOutput(_workflowId, replayKey) {
102297
- return this.inner.getStageOutput(this.scope.rootWorkflowId, this.scopeKey(replayKey));
102298
- }
102299
- getStageSession(_workflowId, replayKey) {
102300
- return this.inner.getStageSession(this.scope.rootWorkflowId, this.scopeKey(replayKey));
102301
- }
102302
- listCheckpoints(workflowId) {
102303
- const prefix = `${this.scope.scopePrefix}:`;
102304
- return this.inner.listCheckpoints(this.scope.rootWorkflowId).filter((checkpoint) => checkpointHasPrefix(checkpoint, prefix)).map((checkpoint) => localCheckpoint(checkpoint, workflowId, prefix));
102305
- }
102306
- getWorkflow(_workflowId) {
102307
- return;
102308
- }
102309
- getLoadableWorkflow(_workflowId) {
102310
- return;
102311
- }
102312
- setWorkflowStatus(_workflowId, _status, _pendingPrompts, _resumable) {}
102313
- async transitionWorkflowStatus(_workflowId, _expectedStatuses, _status, _pendingPrompts, _resumable) {
102314
- return false;
102315
- }
102316
- adjustPendingPrompts(_workflowId, delta) {
102317
- this.inner.adjustPendingPrompts(this.scope.rootWorkflowId, delta);
102318
- }
102319
- promptReservationScope(_workflowId) {
102320
- return this.effectivePromptScope();
102321
- }
102322
- pendingPromptToken(_workflowId, reservationId) {
102323
- return claimDurablePromptToken(this.inner, this.scope.rootWorkflowId, reservationId);
102324
- }
102325
- reservePendingPrompt(_workflowId, reservationId) {
102326
- return reserveDurablePrompt(this.inner, this.scope.rootWorkflowId, reservationId);
102327
- }
102328
- releasePendingPrompt(_workflowId, reservationId, token) {
102329
- releaseDurablePrompt(this.inner, this.scope.rootWorkflowId, reservationId, token);
102330
- }
102331
- listResumableWorkflows() {
102332
- return [];
102333
- }
102334
- listCompletedWorkflows() {
102335
- return [];
102336
- }
102337
- async prepareWorkflowCatalog() {
102338
- return { resumable: [], completed: [] };
102339
- }
102340
- toMetadata(_workflowId) {
102341
- return;
102342
- }
102343
- async deleteWorkflow(_workflowId) {}
102344
- async deleteWorkflowIfInactive(_workflowId) {
102345
- return { ok: false, reason: "not_found" };
102346
- }
102347
- isWorkflowLoadable(_workflowId) {
102348
- return false;
102349
- }
102350
- reset() {}
102351
- hydrateWorkflow(_workflowId) {
102352
- return Promise.resolve();
102353
- }
102354
- hydrateWorkflowForInspection(_workflowId) {
102355
- return Promise.resolve({ kind: "absent" });
102356
- }
102357
- hydrateResumableWorkflows() {
102358
- return Promise.resolve();
102359
- }
102360
- effectivePromptScope() {
102361
- const parent = durablePromptScope(this.inner, this.scope.rootWorkflowId);
102362
- const scope = parent.scope === "root" ? this.scope.scopePrefix : `${parent.scope}:${this.scope.scopePrefix}`;
102363
- return {
102364
- rootWorkflowId: parent.rootWorkflowId,
102365
- scope
102366
- };
102367
- }
102368
- scopeKey(key) {
102369
- return `${this.scope.scopePrefix}:${key}`;
102370
- }
102371
- remap(checkpoint) {
102372
- const workflowId = this.scope.rootWorkflowId;
102373
- if (checkpoint.kind === "tool") {
102374
- return {
102375
- ...checkpoint,
102376
- workflowId,
102377
- checkpointId: this.scopeKey(checkpoint.checkpointId),
102378
- argsHash: this.scopeKey(checkpoint.argsHash)
102379
- };
102380
- }
102381
- if (checkpoint.kind === "ui") {
102382
- return {
102383
- ...checkpoint,
102384
- workflowId,
102385
- checkpointId: this.scopeKey(checkpoint.checkpointId),
102386
- promptHash: this.scopeKey(checkpoint.promptHash)
102387
- };
102388
- }
102389
- return {
102390
- ...checkpoint,
102391
- workflowId,
102392
- checkpointId: this.scopeKey(checkpoint.checkpointId),
102393
- replayKey: this.scopeKey(checkpoint.replayKey),
102394
- ...remappedBoundaryScope(checkpoint, this.scopeKey(checkpoint.topology?.boundary?.replayScope ?? ""))
102395
- };
102396
- }
102397
- }
102398
- function checkpointHasPrefix(checkpoint, prefix) {
102399
- if (!checkpoint.checkpointId.startsWith(prefix))
102400
- return false;
102401
- if (checkpoint.kind === "tool")
102402
- return checkpoint.argsHash.startsWith(prefix);
102403
- if (checkpoint.kind === "ui")
102404
- return checkpoint.promptHash.startsWith(prefix);
102405
- return checkpoint.replayKey.startsWith(prefix);
102406
- }
102407
- function localCheckpoint(checkpoint, workflowId, prefix) {
102408
- const checkpointId = checkpoint.checkpointId.slice(prefix.length);
102409
- if (checkpoint.kind === "tool") {
102410
- return { ...checkpoint, workflowId, checkpointId, argsHash: checkpoint.argsHash.slice(prefix.length) };
102411
- }
102412
- if (checkpoint.kind === "ui") {
102413
- return { ...checkpoint, workflowId, checkpointId, promptHash: checkpoint.promptHash.slice(prefix.length) };
102414
- }
102415
- const replayKey = checkpoint.replayKey.slice(prefix.length);
102416
- const replayScope = stripOnePrefix(checkpoint.topology?.boundary?.replayScope, prefix);
102417
- return {
102418
- ...checkpoint,
102419
- workflowId,
102420
- checkpointId,
102421
- replayKey,
102422
- ...remappedBoundaryScope(checkpoint, replayScope)
102423
- };
102424
- }
102425
- function remappedBoundaryScope(checkpoint, replayScope) {
102426
- const topology = checkpoint.topology;
102427
- if (topology?.boundary === undefined || replayScope === undefined)
102428
- return {};
102429
- return {
102430
- topology: {
102431
- ...topology,
102432
- boundary: { ...topology.boundary, replayScope }
102433
- }
102434
- };
102435
- }
102436
- function stripOnePrefix(value2, prefix) {
102437
- if (value2 === undefined || !value2.startsWith(prefix))
102438
- return value2;
102439
- return value2.slice(prefix.length);
102440
- }
102441
-
102442
102536
  // dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts
102443
102537
  import { isAbsolute as isAbsolute12, join as join28, resolve as resolve12 } from "node:path";
102444
102538
  import { CONFIG_DIR_NAME as CONFIG_DIR_NAME2 } from "@bastani/atomic";
@@ -109433,36 +109527,6 @@ function createReplayStageContext(input) {
109433
109527
  };
109434
109528
  }
109435
109529
 
109436
- // dist/builtin/workflows/src/durable/run-owner-backend.ts
109437
- function durableRootRunIdForRun(runs, runId) {
109438
- return reciprocalWorkflowRootRunId(new Map(runs.map((run) => [run.id, run])), runId);
109439
- }
109440
- function durableBackendForRun(backend, runs, runId) {
109441
- const rootRunId = durableRootRunIdForRun(runs, runId);
109442
- if (rootRunId === undefined)
109443
- return;
109444
- const runById = new Map(runs.map((run) => [run.id, run]));
109445
- if (rootRunId === runId)
109446
- return backend;
109447
- const scopes = [];
109448
- let current = runById.get(runId);
109449
- while (current !== undefined && current.id !== rootRunId) {
109450
- const parent = current.parentRunId === undefined ? undefined : runById.get(current.parentRunId);
109451
- const boundary = parent?.stages.find((stage) => stage.id === current?.parentStageId);
109452
- if (parent === undefined || boundary?.replayKey === undefined)
109453
- return;
109454
- scopes.push(boundary.replayKey);
109455
- current = parent;
109456
- }
109457
- if (current?.id !== rootRunId)
109458
- return;
109459
- let view = backend;
109460
- for (const scopePrefix of scopes.reverse()) {
109461
- view = new ScopedDurableBackend(view, { rootWorkflowId: rootRunId, scopePrefix });
109462
- }
109463
- return view;
109464
- }
109465
-
109466
109530
  // dist/builtin/workflows/src/shared/pending-stage-route-capability.ts
109467
109531
  import { randomUUID as randomUUID9 } from "node:crypto";
109468
109532
  var routeCapabilities = new WeakMap;
@@ -109521,14 +109585,21 @@ function createWorkflowPendingStageDelivery(activeStore, runId, stageId, stageNa
109521
109585
  };
109522
109586
  return {
109523
109587
  routeCapability: workflowPendingStageRouteCapability(activeStore, runId),
109524
- deliverPending(deliver) {
109588
+ deliverPending(deliver, recipient) {
109525
109589
  if (drainPromise !== undefined)
109526
109590
  return drainPromise;
109527
109591
  if (terminalError !== undefined)
109528
109592
  return Promise.resolve();
109529
109593
  drainError = undefined;
109530
- const attempt = deliverPendingStageMessages(activeStore, runId, stageId, stageName, deliver);
109531
- const drain = attempt.then(() => resolveReady?.(), (error) => {
109594
+ const attempt = deliverPendingStageMessages(activeStore, runId, stageId, stageName, deliver, recipient);
109595
+ const drain = attempt.then(() => {
109596
+ resolveReady?.();
109597
+ readyPromise = undefined;
109598
+ resolveReady = undefined;
109599
+ rejectReady = undefined;
109600
+ if (drainPromise === drain)
109601
+ drainPromise = undefined;
109602
+ }, (error) => {
109532
109603
  drainError = error;
109533
109604
  rejectReady?.(error);
109534
109605
  readyPromise = undefined;
@@ -109541,8 +109612,8 @@ function createWorkflowPendingStageDelivery(activeStore, runId, stageId, stageNa
109541
109612
  drainPromise = drain;
109542
109613
  return drainPromise;
109543
109614
  },
109544
- ready() {
109545
- if (activeStore.pendingStageMessagesFor(runId, stageId).length === 0 && (stageId === stageName || activeStore.pendingStageMessagesFor(runId, stageName).length === 0) && stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName).length === 0) {
109615
+ ready(sessionId) {
109616
+ if (activeStore.pendingStageMessagesFor(runId, stageId).length === 0 && (stageId === stageName || activeStore.pendingStageMessagesFor(runId, stageName).length === 0) && stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName, sessionId === undefined ? undefined : { sessionId }).length === 0) {
109546
109617
  return;
109547
109618
  }
109548
109619
  if (terminalError !== undefined)
@@ -109560,8 +109631,8 @@ function createWorkflowPendingStageDelivery(activeStore, runId, stageId, stageNa
109560
109631
  }
109561
109632
  };
109562
109633
  }
109563
- async function deliverPendingStageMessages(activeStore, runId, stageId, stageName, deliver) {
109564
- const stickyEntries = stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName);
109634
+ async function deliverPendingStageMessages(activeStore, runId, stageId, stageName, deliver, recipient) {
109635
+ const stickyEntries = stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName, recipient);
109565
109636
  const candidateIds = new Set([
109566
109637
  ...activeStore.pendingStageMessagesFor(runId, stageId),
109567
109638
  ...activeStore.pendingStageMessagesFor(runId, stageName),
@@ -109583,7 +109654,8 @@ async function deliverPendingStageMessages(activeStore, runId, stageId, stageNam
109583
109654
  if (releaseClaim === undefined)
109584
109655
  continue;
109585
109656
  try {
109586
- await deliver(toPendingStageSender(entry), entry.message);
109657
+ if (!recipient?.receivedMessageIds.includes(entry.message.id))
109658
+ await deliver(toPendingStageSender(entry), entry.message);
109587
109659
  if (entry.sticky === true) {
109588
109660
  const entryBackend = durableBackendForRun(rootBackend, activeStore.runs(), entry.runId);
109589
109661
  if (entryBackend === undefined) {
@@ -109593,7 +109665,8 @@ async function deliverPendingStageMessages(activeStore, runId, stageId, stageNam
109593
109665
  {
109594
109666
  runId,
109595
109667
  stageId,
109596
- ...stageName === stageId ? {} : { stageName }
109668
+ ...stageName === stageId ? {} : { stageName },
109669
+ ...recipient === undefined ? {} : { sessionId: recipient.sessionId, admission: "context" }
109597
109670
  }
109598
109671
  ], new Date().toISOString(), entryBackend)) {
109599
109672
  throw new Error(`atomic-workflows: pending-stage message ${entry.id} changed during delivery`);
@@ -109608,7 +109681,7 @@ async function deliverPendingStageMessages(activeStore, runId, stageId, stageNam
109608
109681
  }
109609
109682
  }
109610
109683
  }
109611
- function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName) {
109684
+ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageName, recipient) {
109612
109685
  const runs = activeStore.runs();
109613
109686
  const rootRunId = durableRootRunIdForRun(runs, runId);
109614
109687
  if (rootRunId === undefined)
@@ -109625,9 +109698,8 @@ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageNam
109625
109698
  const parsed = entry.targetPath === undefined ? undefined : parseWorkflowStageTarget(entry.targetPath);
109626
109699
  if (parsed === undefined || parsed.rootRunId !== rootRunId)
109627
109700
  return false;
109628
- if ((entry.deliveries ?? []).some((delivery) => delivery.runId === runId && delivery.stageId === stageId)) {
109701
+ if ((entry.deliveries ?? []).some((delivery) => delivery.runId === runId && delivery.stageId === stageId && (recipient === undefined || delivery.admission === "context" && delivery.sessionId === recipient.sessionId && (recipient.receivedMessageIds === undefined || recipient.receivedMessageIds.includes(entry.message.id)))))
109629
109702
  return false;
109630
- }
109631
109703
  return stageMatchesPathPattern(parsed.segments, hops, [stageId, stageName]);
109632
109704
  });
109633
109705
  }
@@ -112155,7 +112227,7 @@ class StageSessionController {
112155
112227
  const attachedSession = session instanceof Promise ? await session : session;
112156
112228
  this.reportStartupPhase("delivery-readiness");
112157
112229
  try {
112158
- await this.sharedOrchestrationContext?.pendingStageDelivery?.ready();
112230
+ await this.sharedOrchestrationContext?.pendingStageDelivery?.ready(attachedSession.sessionId);
112159
112231
  await this.opts.onSessionReady?.();
112160
112232
  if (this.disposed || this.opts.signal?.aborted || this.abortGeneration !== startGeneration)
112161
112233
  throw this.staleCreationReason(startGeneration);
@@ -117623,6 +117695,22 @@ function possibleStageRows(runs, rootRunId, rootRun) {
117623
117695
  return segments !== undefined && segments.length === 1 && segments[0] === "**";
117624
117696
  }).length
117625
117697
  });
117698
+ const statuses = stickyStageDeliveryStatuses(runs, rootRunId);
117699
+ for (const target of new Set(statuses.map((status) => status.target))) {
117700
+ if (rows.some((row) => row.target === target))
117701
+ continue;
117702
+ rows.push({
117703
+ target,
117704
+ queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
117705
+ deliveryOnly: true
117706
+ });
117707
+ }
117708
+ for (let index = 0;index < rows.length; index++) {
117709
+ const row = rows[index];
117710
+ const deliveryStates = statuses.filter((status) => status.target === row.target);
117711
+ if (deliveryStates.length > 0)
117712
+ rows[index] = { ...row, deliveryStates };
117713
+ }
117626
117714
  return rows;
117627
117715
  }
117628
117716
  function materializedStageMatches(runs, rootRunId, entrySegments) {
@@ -117863,7 +117951,9 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
117863
117951
  const records = matchingLiveStages(runs, rootRunId, parsedTarget.segments).filter((match) => delivered.has(match.target)).map((match) => ({
117864
117952
  runId: match.run.id,
117865
117953
  stageId: match.stage.id,
117866
- ...match.stage.name === match.stage.id ? {} : { stageName: match.stage.name }
117954
+ ...match.stage.name === match.stage.id ? {} : { stageName: match.stage.name },
117955
+ ...match.stage.sessionId === undefined ? {} : { sessionId: match.stage.sessionId },
117956
+ admission: "transport"
117867
117957
  }));
117868
117958
  if (records.length === 0)
117869
117959
  return false;
@@ -120870,6 +120960,7 @@ function summarizeRunSnapshot(run, now = Date.now(), options) {
120870
120960
  status: stage.status
120871
120961
  })),
120872
120962
  pendingStages: pendingWorkflowStageStatuses(run, options?.owningRunStatus, options?.resolveBoundarySegments),
120963
+ deliveryStates: stickyStageDeliveryStatuses(options?.allRuns ?? [run], run.id),
120873
120964
  tools: (run.toolNodes ?? []).map((tool) => {
120874
120965
  const owner = tool;
120875
120966
  return {
@@ -121158,6 +121249,9 @@ function renderStatusToolContent(result) {
121158
121249
  }
121159
121250
  for (const entry of run.awaitingInput)
121160
121251
  lines.push(statusAwaitingInputLine(entry));
121252
+ for (const delivery of run.deliveryStates ?? stickyStageDeliveryStatuses(allRuns, run.runId)) {
121253
+ lines.push(` Intercom delivery ${delivery.messageId} target=${delivery.target} stage=${delivery.runId}/${delivery.stageId}${delivery.sessionId === undefined ? "" : ` session=${delivery.sessionId}`} state=${delivery.state} — ${delivery.reason}`);
121254
+ }
121161
121255
  for (const stage of run.pendingStages.slice(0, STATUS_PENDING_STAGE_LIMIT)) {
121162
121256
  lines.push(statusPendingStageLine(stage));
121163
121257
  }
@@ -122334,6 +122428,7 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
122334
122428
  const statusByRunId = new Map(capturedRuns.map((run) => [run.id, run.status]));
122335
122429
  const listing = buildWorkflowStatusListing(topLevelExpandedSnapshots(store), args.statusFilter ?? "all", Date.now(), {
122336
122430
  toolControlRegistry,
122431
+ allRuns: capturedRuns,
122337
122432
  owningRunStatus: (owningRunId) => statusByRunId.get(owningRunId),
122338
122433
  resolveBoundarySegments: (runId) => workflowBoundarySegments(capturedRuns, runId)
122339
122434
  });