@bastani/atomic 0.9.44-alpha.3 → 0.9.44-alpha.5
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 +17 -0
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +92 -37
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +92 -37
- package/dist/builtin/workflows/src/index.js +92 -37
- package/dist/builtin/workflows/src/local-worker-entry.mjs +92 -37
- package/dist/core/storage/errors.d.ts +5 -1
- package/dist/core/storage/errors.d.ts.map +1 -1
- package/dist/core/storage/errors.js +8 -2
- package/dist/core/storage/errors.js.map +1 -1
- package/dist/core/storage/node-sqlite.d.ts +2 -1
- package/dist/core/storage/node-sqlite.d.ts.map +1 -1
- package/dist/core/storage/node-sqlite.js +83 -7
- package/dist/core/storage/node-sqlite.js.map +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.44-alpha.5] - 2026-10-25
|
|
6
|
+
|
|
7
|
+
Large workflow fan-outs keep their Intercom routes and journal writes responsive under load.
|
|
8
|
+
|
|
9
|
+
- **A workflow host that keeps up:** route announcements are batched instead of rebuilt for every run on every store change, so heavy fan-outs no longer saturate the workflow host and time out Intercom sends ([#3939](https://github.com/bastani-inc/atomic/pull/3939))
|
|
10
|
+
- **Stages that start under journal contention:** a busy workflow journal no longer fails pooled stages with `Storage unavailable`; writers wait for the lock without blocking their event loop, and the SQLite reason stays in the error ([#3940](https://github.com/bastani-inc/atomic/pull/3940))
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- A local SQLite store (`node-sqlite`, including the workflow journal) now waits for another process's write lock instead of failing after the 5 second busy timeout. When the lock is busy, it retries the start of the write transaction for up to 30 seconds without blocking the event loop. Single statements outside a transaction still use the configured busy timeout. Other failures, and a lock still held at that point, fail at once. `Storage unavailable` errors now include the SQLite reason, such as `database is locked (SQLite code 5)`, so the reason survives when local workers pass an error to another process
|
|
15
|
+
|
|
16
|
+
## [0.9.44-alpha.4] - 2026-10-25
|
|
17
|
+
|
|
18
|
+
Workflow journals stay small even when many stages write to the same run at once.
|
|
19
|
+
|
|
20
|
+
- **No more full-list rewrites under contention:** a pending-message write that loses a race with another writer rebuilds its change and retries instead of storing the whole pending list. Those rewrites drove journal growth and workflow host load under heavy fan-out ([#3929](https://github.com/bastani-inc/atomic/issues/3929), [#3937](https://github.com/bastani-inc/atomic/pull/3937))
|
|
21
|
+
|
|
5
22
|
## [0.9.44-alpha.3] - 2026-10-25
|
|
6
23
|
|
|
7
24
|
Chatty workflow swarms stay fast and their journals stay small, and Atomic picks up a round of dependency security fixes.
|
|
@@ -4,6 +4,12 @@ All notable changes to the `pi-intercom` extension will be documented in this fi
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.44-alpha.5] - 2026-10-25
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- A pooled workflow stage whose Intercom extension delivers queued messages at startup no longer fails with `Extension startup failed: …intercom…: Storage unavailable: node-sqlite at <journal>` while other processes are writing heavily to the workflow journal. The journal write now waits for the lock, and any remaining failure states its SQLite cause
|
|
12
|
+
|
|
7
13
|
## [0.9.44-alpha.3] - 2026-10-25
|
|
8
14
|
|
|
9
15
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.44-alpha.
|
|
3
|
+
"version": "0.9.44-alpha.5",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.44-alpha.
|
|
3
|
+
"version": "0.9.44-alpha.5",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with parallel execution. Fork of: https://github.com/nicobailon/pi-subagents",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.44-alpha.
|
|
3
|
+
"version": "0.9.44-alpha.5",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.44-alpha.5] - 2026-10-25
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A large workflow fan-out no longer pins the workflow host's main thread rebuilding Intercom routes. Every store change re-announced the route of every run (480 children in a load test), so under a stream of messages and delivery receipts the host spent most of its time on announcements and Intercom sends began to time out. Store changes now publish routes in batches about 25 ms apart, spaced further when needed so announcing takes at most about a fifth of the host's time, and a stage that waits for its route still gets the latest one first.
|
|
14
|
+
|
|
15
|
+
## [0.9.44-alpha.4] - 2026-10-25
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- A pending-message write that loses a race with another writer to the same run (for example a stage's delivery receipt) no longer stores the run's whole list of pending stage messages in the journal. It is rebuilt as a change on top of the other writer's entry and retried, and only falls back to the full list after repeated conflicts. In a 160-worker fan-out, 2% of queued events had fallen back and written 93% of their bytes, up to 1.5 MB each and growing with the list ([#3929](https://github.com/bastani-inc/atomic/issues/3929))
|
|
20
|
+
|
|
9
21
|
## [0.9.44-alpha.3] - 2026-10-25
|
|
10
22
|
|
|
11
23
|
### Fixed
|
|
@@ -7097,16 +7097,20 @@ class JournalDurableBackend {
|
|
|
7097
7097
|
}
|
|
7098
7098
|
*append(runId, event, options) {
|
|
7099
7099
|
const lease = yield* this.ownership(runId);
|
|
7100
|
-
const base = this.sequences.get(runId);
|
|
7101
7100
|
const pinned = options?.expectSeq;
|
|
7102
|
-
|
|
7103
|
-
|
|
7101
|
+
for (let attempt = 0;attempt < CHANGE_APPEND_ATTEMPTS; attempt++) {
|
|
7102
|
+
const base = this.sequences.get(runId);
|
|
7103
|
+
const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
|
|
7104
|
+
if (encoded === undefined)
|
|
7105
|
+
break;
|
|
7104
7106
|
try {
|
|
7105
7107
|
return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
|
|
7106
7108
|
} catch (error) {
|
|
7107
7109
|
if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
|
|
7108
7110
|
throw error;
|
|
7109
7111
|
}
|
|
7112
|
+
for (const entry of yield* this.entries(runId, (this.sequences.get(runId) ?? 0) + 1))
|
|
7113
|
+
this.fold(entry);
|
|
7110
7114
|
}
|
|
7111
7115
|
yield* this.write(runId, lease, event, options);
|
|
7112
7116
|
}
|
|
@@ -7787,7 +7791,7 @@ function decodePendingStageDeliveries(previous, messages) {
|
|
|
7787
7791
|
function hasPendingStageDeliveryDelta(messages) {
|
|
7788
7792
|
return messages?.some(isDeltaEncoded) === true;
|
|
7789
7793
|
}
|
|
7790
|
-
var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
7794
|
+
var PROCESS_HOLDER_ID, CHANGE_APPEND_ATTEMPTS = 4, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
7791
7795
|
var init_journal_backend = __esm(() => {
|
|
7792
7796
|
init_workflow_instance_ownership_error();
|
|
7793
7797
|
init_backend();
|
|
@@ -60859,6 +60863,27 @@ class GraphFrontierTracker {
|
|
|
60859
60863
|
}
|
|
60860
60864
|
}
|
|
60861
60865
|
|
|
60866
|
+
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
60867
|
+
import { isStaleExtensionContextError as isStaleExtensionContextError6 } from "@bastani/atomic";
|
|
60868
|
+
function reportsClosedSession(error) {
|
|
60869
|
+
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError6(error);
|
|
60870
|
+
}
|
|
60871
|
+
function isSessionClosedError(error) {
|
|
60872
|
+
let current = error;
|
|
60873
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH && current !== undefined; depth++) {
|
|
60874
|
+
try {
|
|
60875
|
+
if (reportsClosedSession(current))
|
|
60876
|
+
return true;
|
|
60877
|
+
current = current.cause instanceof Error ? current.cause : undefined;
|
|
60878
|
+
} catch {
|
|
60879
|
+
return false;
|
|
60880
|
+
}
|
|
60881
|
+
}
|
|
60882
|
+
return false;
|
|
60883
|
+
}
|
|
60884
|
+
var MAX_CAUSE_DEPTH = 8;
|
|
60885
|
+
var init_session_closed_error = () => {};
|
|
60886
|
+
|
|
60862
60887
|
// dist/builtin/workflows/src/shared/external-run-routes.ts
|
|
60863
60888
|
function claimExternalRunRoute(store, runId, owner) {
|
|
60864
60889
|
let owners = registry.owners.get(store);
|
|
@@ -61135,7 +61160,10 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
61135
61160
|
};
|
|
61136
61161
|
const announcedRoutes = new Map;
|
|
61137
61162
|
const routeCompletions = new Map;
|
|
61138
|
-
const disposeReadiness = registerWorkflowPendingStageRouteReadiness(activeStore, (runId) =>
|
|
61163
|
+
const disposeReadiness = registerWorkflowPendingStageRouteReadiness(activeStore, (runId) => {
|
|
61164
|
+
announceIfPending();
|
|
61165
|
+
return routeCompletions.get(runId);
|
|
61166
|
+
});
|
|
61139
61167
|
const announceRoutes = () => {
|
|
61140
61168
|
if (disposed)
|
|
61141
61169
|
return;
|
|
@@ -61232,11 +61260,53 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
61232
61260
|
return;
|
|
61233
61261
|
}).catch((error) => reportWarning(`atomic-workflows: pending stage delivery sweep failed: ${error.message}`));
|
|
61234
61262
|
};
|
|
61235
|
-
|
|
61236
|
-
|
|
61263
|
+
let announcementPending = false;
|
|
61264
|
+
let announcementTimer;
|
|
61265
|
+
let announcedAt = Number.NEGATIVE_INFINITY;
|
|
61266
|
+
let announcementCost = 0;
|
|
61267
|
+
const announceNow = () => {
|
|
61268
|
+
if (announcementTimer !== undefined)
|
|
61269
|
+
clearTimeout(announcementTimer);
|
|
61270
|
+
announcementTimer = undefined;
|
|
61271
|
+
announcementPending = false;
|
|
61272
|
+
const started = performance.now();
|
|
61273
|
+
announceRoutes();
|
|
61274
|
+
announcedAt = performance.now();
|
|
61275
|
+
announcementCost = announcedAt - started;
|
|
61276
|
+
};
|
|
61277
|
+
function announceIfPending() {
|
|
61278
|
+
if (announcementPending)
|
|
61279
|
+
announceNow();
|
|
61280
|
+
}
|
|
61281
|
+
const announceBatch = () => {
|
|
61282
|
+
try {
|
|
61283
|
+
announceNow();
|
|
61284
|
+
} catch (error) {
|
|
61285
|
+
if (error instanceof Error && isSessionClosedError(error)) {
|
|
61286
|
+
dispose();
|
|
61287
|
+
return;
|
|
61288
|
+
}
|
|
61289
|
+
try {
|
|
61290
|
+
reportWarning(`atomic-workflows: pending stage route announcement failed: ${String(error)}`);
|
|
61291
|
+
} catch {
|
|
61292
|
+
dispose();
|
|
61293
|
+
}
|
|
61294
|
+
}
|
|
61295
|
+
};
|
|
61296
|
+
const scheduleAnnouncement = () => {
|
|
61297
|
+
if (disposed || announcementTimer !== undefined)
|
|
61298
|
+
return;
|
|
61299
|
+
const idle = announcementCost / ROUTE_ANNOUNCEMENT_EVENT_LOOP_SHARE - announcementCost;
|
|
61300
|
+
const wait = Math.max(ROUTE_ANNOUNCEMENT_BATCH_MS, announcedAt + idle - performance.now());
|
|
61301
|
+
announcementPending = true;
|
|
61302
|
+
announcementTimer = setTimeout(announceBatch, wait);
|
|
61303
|
+
announcementTimer.unref?.();
|
|
61304
|
+
};
|
|
61305
|
+
const unsubscribeStore = activeStore.subscribeInvalidation(scheduleAnnouncement);
|
|
61306
|
+
announceNow();
|
|
61237
61307
|
pi.on?.("session_start", () => {
|
|
61238
61308
|
announcedRoutes.clear();
|
|
61239
|
-
|
|
61309
|
+
announceNow();
|
|
61240
61310
|
});
|
|
61241
61311
|
const routePendingStageMessage = (payload) => {
|
|
61242
61312
|
if (disposed || !isPendingStageMessageEvent(payload) || payload.handled)
|
|
@@ -61318,6 +61388,10 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
61318
61388
|
});
|
|
61319
61389
|
const dispose = () => {
|
|
61320
61390
|
disposed = true;
|
|
61391
|
+
if (announcementTimer !== undefined)
|
|
61392
|
+
clearTimeout(announcementTimer);
|
|
61393
|
+
announcementTimer = undefined;
|
|
61394
|
+
announcementPending = false;
|
|
61321
61395
|
disposeReadiness();
|
|
61322
61396
|
disposeRouter();
|
|
61323
61397
|
routeCompletions.clear();
|
|
@@ -61331,10 +61405,11 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
61331
61405
|
pi.on?.("session_shutdown", dispose);
|
|
61332
61406
|
return Object.assign(dispose, {
|
|
61333
61407
|
async flush() {
|
|
61408
|
+
announceIfPending();
|
|
61334
61409
|
await Promise.allSettled(routeCompletions.values());
|
|
61335
61410
|
await sweepPromise;
|
|
61336
61411
|
},
|
|
61337
|
-
refresh:
|
|
61412
|
+
refresh: announceNow
|
|
61338
61413
|
});
|
|
61339
61414
|
}
|
|
61340
61415
|
function stageRouteTarget(runs, rootRunId, runId, stageId, resolveBoundarySegments = (id) => workflowBoundarySegments(runs, id)) {
|
|
@@ -61809,11 +61884,12 @@ async function settleUndeliverablePendingStageMessages(activeStore, notify, owns
|
|
|
61809
61884
|
}
|
|
61810
61885
|
return settled;
|
|
61811
61886
|
}
|
|
61812
|
-
var PENDING_STAGE_ROUTE_EVENT = "atomic:workflow-pending-stage-route", PENDING_STAGE_MESSAGE_EVENT = "atomic:workflow-pending-stage-message", PENDING_STAGE_UNDELIVERABLE_EVENT = "atomic:workflow-pending-stage-undeliverable", STICKY_LIVE_DELIVERED_EVENT = "atomic:workflow-sticky-live-delivered", PENDING_STAGE_ASK_REFUSAL = "Cannot ask a workflow stage whose session has not initialized. Use send; Atomic will queue the message until the stage session initializes.";
|
|
61887
|
+
var PENDING_STAGE_ROUTE_EVENT = "atomic:workflow-pending-stage-route", PENDING_STAGE_MESSAGE_EVENT = "atomic:workflow-pending-stage-message", PENDING_STAGE_UNDELIVERABLE_EVENT = "atomic:workflow-pending-stage-undeliverable", STICKY_LIVE_DELIVERED_EVENT = "atomic:workflow-sticky-live-delivered", PENDING_STAGE_ASK_REFUSAL = "Cannot ask a workflow stage whose session has not initialized. Use send; Atomic will queue the message until the stage session initializes.", ROUTE_ANNOUNCEMENT_BATCH_MS = 25, ROUTE_ANNOUNCEMENT_EVENT_LOOP_SHARE = 0.2;
|
|
61813
61888
|
var init_pending_stage_intercom = __esm(() => {
|
|
61814
61889
|
init_execution_context_boundary();
|
|
61815
61890
|
init_run_owner_backend();
|
|
61816
61891
|
init_store_backend();
|
|
61892
|
+
init_session_closed_error();
|
|
61817
61893
|
init_external_run_routes();
|
|
61818
61894
|
init_intercom_group();
|
|
61819
61895
|
init_pending_stage_route_capability();
|
|
@@ -64370,7 +64446,7 @@ function isInfrastructureError(value2) {
|
|
|
64370
64446
|
}
|
|
64371
64447
|
function isRetryableWorkflowError(error) {
|
|
64372
64448
|
let current = error;
|
|
64373
|
-
for (let depth = 0;depth <
|
|
64449
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH2 && current !== undefined && current !== null; depth++) {
|
|
64374
64450
|
if (isInfrastructureError(current))
|
|
64375
64451
|
return true;
|
|
64376
64452
|
current = current instanceof Error ? current.cause : undefined;
|
|
@@ -64388,7 +64464,7 @@ function asWorkflowInfrastructureError(error) {
|
|
|
64388
64464
|
const code = workflowInfrastructureFault(error.message);
|
|
64389
64465
|
return code === undefined ? undefined : new WorkflowInfrastructureError(code, error.message, { cause: error });
|
|
64390
64466
|
}
|
|
64391
|
-
var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError",
|
|
64467
|
+
var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError", MAX_CAUSE_DEPTH2 = 8, FAULT_PATTERNS, WorkflowInfrastructureError;
|
|
64392
64468
|
var init_workflow_infrastructure_error = __esm(() => {
|
|
64393
64469
|
FAULT_PATTERNS = [
|
|
64394
64470
|
[/Local worker (?:process )?cleanup (?:was not confirmed|unconfirmed)/, "worker_cleanup_unconfirmed"],
|
|
@@ -68434,7 +68510,7 @@ function describeErrorWithCauses(error) {
|
|
|
68434
68510
|
const messages = [];
|
|
68435
68511
|
const visited = new Set;
|
|
68436
68512
|
let current = error;
|
|
68437
|
-
for (let depth = 0;current !== undefined && depth <
|
|
68513
|
+
for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH3 && !visited.has(current); depth++) {
|
|
68438
68514
|
visited.add(current);
|
|
68439
68515
|
const message = current instanceof Error ? current.message : String(current);
|
|
68440
68516
|
if (!messages.includes(message))
|
|
@@ -68443,7 +68519,7 @@ function describeErrorWithCauses(error) {
|
|
|
68443
68519
|
}
|
|
68444
68520
|
return messages.join(": ");
|
|
68445
68521
|
}
|
|
68446
|
-
var
|
|
68522
|
+
var MAX_CAUSE_DEPTH3 = 5;
|
|
68447
68523
|
|
|
68448
68524
|
// dist/builtin/workflows/src/engine/run-durable-finalize.ts
|
|
68449
68525
|
async function finalizeDurableTerminalStatus(input) {
|
|
@@ -68963,7 +69039,7 @@ function recordedOwners(boundary, reason) {
|
|
|
68963
69039
|
const pending = [{ value: reason, depth: 0 }];
|
|
68964
69040
|
while (pending.length > 0) {
|
|
68965
69041
|
const { value: value2, depth } = pending.pop();
|
|
68966
|
-
if (depth >
|
|
69042
|
+
if (depth > MAX_CAUSE_DEPTH4)
|
|
68967
69043
|
continue;
|
|
68968
69044
|
if (isPrimitive(value2)) {
|
|
68969
69045
|
if (depth === 0 || value2 !== undefined && value2 !== null) {
|
|
@@ -69285,7 +69361,7 @@ function containUiRejections(ui, scope) {
|
|
|
69285
69361
|
custom: (factory, options) => scope.watch(ui.custom(factory, options))
|
|
69286
69362
|
};
|
|
69287
69363
|
}
|
|
69288
|
-
var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections",
|
|
69364
|
+
var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections", MAX_CAUSE_DEPTH4 = 8, MAX_PRIMITIVES_PER_RUN = 64, MAX_STOP_STRINGS = 64, ENDED_RUN_GRACE_MS = 30000, NATIVE_REPORTING_MODES, WATCHED_STAGE_METHODS;
|
|
69289
69365
|
var init_run_rejection_boundary = __esm(() => {
|
|
69290
69366
|
init_prompt_callsite();
|
|
69291
69367
|
init_workflow_source();
|
|
@@ -75131,27 +75207,6 @@ var init_runtime = __esm(() => {
|
|
|
75131
75207
|
init_intercom_group();
|
|
75132
75208
|
});
|
|
75133
75209
|
|
|
75134
|
-
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
75135
|
-
import { isStaleExtensionContextError as isStaleExtensionContextError6 } from "@bastani/atomic";
|
|
75136
|
-
function reportsClosedSession(error) {
|
|
75137
|
-
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError6(error);
|
|
75138
|
-
}
|
|
75139
|
-
function isSessionClosedError(error) {
|
|
75140
|
-
let current = error;
|
|
75141
|
-
for (let depth = 0;depth < MAX_CAUSE_DEPTH4 && current !== undefined; depth++) {
|
|
75142
|
-
try {
|
|
75143
|
-
if (reportsClosedSession(current))
|
|
75144
|
-
return true;
|
|
75145
|
-
current = current.cause instanceof Error ? current.cause : undefined;
|
|
75146
|
-
} catch {
|
|
75147
|
-
return false;
|
|
75148
|
-
}
|
|
75149
|
-
}
|
|
75150
|
-
return false;
|
|
75151
|
-
}
|
|
75152
|
-
var MAX_CAUSE_DEPTH4 = 8;
|
|
75153
|
-
var init_session_closed_error = () => {};
|
|
75154
|
-
|
|
75155
75210
|
// dist/builtin/workflows/src/engine/workflow-activity.ts
|
|
75156
75211
|
import { runCallback as runCallback4 } from "@bastani/atomic";
|
|
75157
75212
|
function nextEventLoopTurn() {
|
|
@@ -1908,16 +1908,20 @@ class JournalDurableBackend {
|
|
|
1908
1908
|
}
|
|
1909
1909
|
*append(runId, event, options) {
|
|
1910
1910
|
const lease = yield* this.ownership(runId);
|
|
1911
|
-
const base = this.sequences.get(runId);
|
|
1912
1911
|
const pinned = options?.expectSeq;
|
|
1913
|
-
|
|
1914
|
-
|
|
1912
|
+
for (let attempt = 0;attempt < CHANGE_APPEND_ATTEMPTS; attempt++) {
|
|
1913
|
+
const base = this.sequences.get(runId);
|
|
1914
|
+
const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
|
|
1915
|
+
if (encoded === undefined)
|
|
1916
|
+
break;
|
|
1915
1917
|
try {
|
|
1916
1918
|
return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
|
|
1917
1919
|
} catch (error) {
|
|
1918
1920
|
if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
|
|
1919
1921
|
throw error;
|
|
1920
1922
|
}
|
|
1923
|
+
for (const entry of yield* this.entries(runId, (this.sequences.get(runId) ?? 0) + 1))
|
|
1924
|
+
this.fold(entry);
|
|
1921
1925
|
}
|
|
1922
1926
|
yield* this.write(runId, lease, event, options);
|
|
1923
1927
|
}
|
|
@@ -2598,7 +2602,7 @@ function decodePendingStageDeliveries(previous, messages) {
|
|
|
2598
2602
|
function hasPendingStageDeliveryDelta(messages) {
|
|
2599
2603
|
return messages?.some(isDeltaEncoded) === true;
|
|
2600
2604
|
}
|
|
2601
|
-
var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
2605
|
+
var PROCESS_HOLDER_ID, CHANGE_APPEND_ATTEMPTS = 4, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
2602
2606
|
var init_journal_backend = __esm(() => {
|
|
2603
2607
|
init_workflow_instance_ownership_error();
|
|
2604
2608
|
init_backend();
|
|
@@ -57397,6 +57401,27 @@ var init_executor = __esm(() => {
|
|
|
57397
57401
|
init_executor_run();
|
|
57398
57402
|
});
|
|
57399
57403
|
|
|
57404
|
+
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
57405
|
+
import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
|
|
57406
|
+
function reportsClosedSession(error) {
|
|
57407
|
+
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError2(error);
|
|
57408
|
+
}
|
|
57409
|
+
function isSessionClosedError(error) {
|
|
57410
|
+
let current = error;
|
|
57411
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH && current !== undefined; depth++) {
|
|
57412
|
+
try {
|
|
57413
|
+
if (reportsClosedSession(current))
|
|
57414
|
+
return true;
|
|
57415
|
+
current = current.cause instanceof Error ? current.cause : undefined;
|
|
57416
|
+
} catch {
|
|
57417
|
+
return false;
|
|
57418
|
+
}
|
|
57419
|
+
}
|
|
57420
|
+
return false;
|
|
57421
|
+
}
|
|
57422
|
+
var MAX_CAUSE_DEPTH = 8;
|
|
57423
|
+
var init_session_closed_error = () => {};
|
|
57424
|
+
|
|
57400
57425
|
// dist/builtin/workflows/src/shared/external-run-routes.ts
|
|
57401
57426
|
function claimExternalRunRoute(store, runId, owner) {
|
|
57402
57427
|
let owners = registry.owners.get(store);
|
|
@@ -57891,7 +57916,10 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
57891
57916
|
};
|
|
57892
57917
|
const announcedRoutes = new Map;
|
|
57893
57918
|
const routeCompletions = new Map;
|
|
57894
|
-
const disposeReadiness = registerWorkflowPendingStageRouteReadiness(activeStore, (runId) =>
|
|
57919
|
+
const disposeReadiness = registerWorkflowPendingStageRouteReadiness(activeStore, (runId) => {
|
|
57920
|
+
announceIfPending();
|
|
57921
|
+
return routeCompletions.get(runId);
|
|
57922
|
+
});
|
|
57895
57923
|
const announceRoutes = () => {
|
|
57896
57924
|
if (disposed)
|
|
57897
57925
|
return;
|
|
@@ -57988,11 +58016,53 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
57988
58016
|
return;
|
|
57989
58017
|
}).catch((error) => reportWarning(`atomic-workflows: pending stage delivery sweep failed: ${error.message}`));
|
|
57990
58018
|
};
|
|
57991
|
-
|
|
57992
|
-
|
|
58019
|
+
let announcementPending = false;
|
|
58020
|
+
let announcementTimer;
|
|
58021
|
+
let announcedAt = Number.NEGATIVE_INFINITY;
|
|
58022
|
+
let announcementCost = 0;
|
|
58023
|
+
const announceNow = () => {
|
|
58024
|
+
if (announcementTimer !== undefined)
|
|
58025
|
+
clearTimeout(announcementTimer);
|
|
58026
|
+
announcementTimer = undefined;
|
|
58027
|
+
announcementPending = false;
|
|
58028
|
+
const started = performance.now();
|
|
58029
|
+
announceRoutes();
|
|
58030
|
+
announcedAt = performance.now();
|
|
58031
|
+
announcementCost = announcedAt - started;
|
|
58032
|
+
};
|
|
58033
|
+
function announceIfPending() {
|
|
58034
|
+
if (announcementPending)
|
|
58035
|
+
announceNow();
|
|
58036
|
+
}
|
|
58037
|
+
const announceBatch = () => {
|
|
58038
|
+
try {
|
|
58039
|
+
announceNow();
|
|
58040
|
+
} catch (error) {
|
|
58041
|
+
if (error instanceof Error && isSessionClosedError(error)) {
|
|
58042
|
+
dispose();
|
|
58043
|
+
return;
|
|
58044
|
+
}
|
|
58045
|
+
try {
|
|
58046
|
+
reportWarning(`atomic-workflows: pending stage route announcement failed: ${String(error)}`);
|
|
58047
|
+
} catch {
|
|
58048
|
+
dispose();
|
|
58049
|
+
}
|
|
58050
|
+
}
|
|
58051
|
+
};
|
|
58052
|
+
const scheduleAnnouncement = () => {
|
|
58053
|
+
if (disposed || announcementTimer !== undefined)
|
|
58054
|
+
return;
|
|
58055
|
+
const idle = announcementCost / ROUTE_ANNOUNCEMENT_EVENT_LOOP_SHARE - announcementCost;
|
|
58056
|
+
const wait = Math.max(ROUTE_ANNOUNCEMENT_BATCH_MS, announcedAt + idle - performance.now());
|
|
58057
|
+
announcementPending = true;
|
|
58058
|
+
announcementTimer = setTimeout(announceBatch, wait);
|
|
58059
|
+
announcementTimer.unref?.();
|
|
58060
|
+
};
|
|
58061
|
+
const unsubscribeStore = activeStore.subscribeInvalidation(scheduleAnnouncement);
|
|
58062
|
+
announceNow();
|
|
57993
58063
|
pi.on?.("session_start", () => {
|
|
57994
58064
|
announcedRoutes.clear();
|
|
57995
|
-
|
|
58065
|
+
announceNow();
|
|
57996
58066
|
});
|
|
57997
58067
|
const routePendingStageMessage = (payload) => {
|
|
57998
58068
|
if (disposed || !isPendingStageMessageEvent(payload) || payload.handled)
|
|
@@ -58074,6 +58144,10 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
58074
58144
|
});
|
|
58075
58145
|
const dispose = () => {
|
|
58076
58146
|
disposed = true;
|
|
58147
|
+
if (announcementTimer !== undefined)
|
|
58148
|
+
clearTimeout(announcementTimer);
|
|
58149
|
+
announcementTimer = undefined;
|
|
58150
|
+
announcementPending = false;
|
|
58077
58151
|
disposeReadiness();
|
|
58078
58152
|
disposeRouter();
|
|
58079
58153
|
routeCompletions.clear();
|
|
@@ -58087,10 +58161,11 @@ function registerPendingStageIntercomBridge(pi, activeStore, ownsRun = () => tru
|
|
|
58087
58161
|
pi.on?.("session_shutdown", dispose);
|
|
58088
58162
|
return Object.assign(dispose, {
|
|
58089
58163
|
async flush() {
|
|
58164
|
+
announceIfPending();
|
|
58090
58165
|
await Promise.allSettled(routeCompletions.values());
|
|
58091
58166
|
await sweepPromise;
|
|
58092
58167
|
},
|
|
58093
|
-
refresh:
|
|
58168
|
+
refresh: announceNow
|
|
58094
58169
|
});
|
|
58095
58170
|
}
|
|
58096
58171
|
function stageRouteTarget(runs, rootRunId, runId, stageId, resolveBoundarySegments = (id) => workflowBoundarySegments(runs, id)) {
|
|
@@ -58565,11 +58640,12 @@ async function settleUndeliverablePendingStageMessages(activeStore, notify, owns
|
|
|
58565
58640
|
}
|
|
58566
58641
|
return settled;
|
|
58567
58642
|
}
|
|
58568
|
-
var PENDING_STAGE_ROUTE_EVENT = "atomic:workflow-pending-stage-route", PENDING_STAGE_MESSAGE_EVENT = "atomic:workflow-pending-stage-message", PENDING_STAGE_UNDELIVERABLE_EVENT = "atomic:workflow-pending-stage-undeliverable", STICKY_LIVE_DELIVERED_EVENT = "atomic:workflow-sticky-live-delivered", PENDING_STAGE_ASK_REFUSAL = "Cannot ask a workflow stage whose session has not initialized. Use send; Atomic will queue the message until the stage session initializes.";
|
|
58643
|
+
var PENDING_STAGE_ROUTE_EVENT = "atomic:workflow-pending-stage-route", PENDING_STAGE_MESSAGE_EVENT = "atomic:workflow-pending-stage-message", PENDING_STAGE_UNDELIVERABLE_EVENT = "atomic:workflow-pending-stage-undeliverable", STICKY_LIVE_DELIVERED_EVENT = "atomic:workflow-sticky-live-delivered", PENDING_STAGE_ASK_REFUSAL = "Cannot ask a workflow stage whose session has not initialized. Use send; Atomic will queue the message until the stage session initializes.", ROUTE_ANNOUNCEMENT_BATCH_MS = 25, ROUTE_ANNOUNCEMENT_EVENT_LOOP_SHARE = 0.2;
|
|
58569
58644
|
var init_pending_stage_intercom = __esm(() => {
|
|
58570
58645
|
init_execution_context_boundary();
|
|
58571
58646
|
init_run_owner_backend();
|
|
58572
58647
|
init_store_backend();
|
|
58648
|
+
init_session_closed_error();
|
|
58573
58649
|
init_external_run_routes();
|
|
58574
58650
|
init_intercom_group();
|
|
58575
58651
|
init_pending_stage_route_capability();
|
|
@@ -61126,7 +61202,7 @@ function isInfrastructureError(value2) {
|
|
|
61126
61202
|
}
|
|
61127
61203
|
function isRetryableWorkflowError(error) {
|
|
61128
61204
|
let current = error;
|
|
61129
|
-
for (let depth = 0;depth <
|
|
61205
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH2 && current !== undefined && current !== null; depth++) {
|
|
61130
61206
|
if (isInfrastructureError(current))
|
|
61131
61207
|
return true;
|
|
61132
61208
|
current = current instanceof Error ? current.cause : undefined;
|
|
@@ -61144,7 +61220,7 @@ function asWorkflowInfrastructureError(error) {
|
|
|
61144
61220
|
const code = workflowInfrastructureFault(error.message);
|
|
61145
61221
|
return code === undefined ? undefined : new WorkflowInfrastructureError(code, error.message, { cause: error });
|
|
61146
61222
|
}
|
|
61147
|
-
var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError",
|
|
61223
|
+
var WORKFLOW_INFRASTRUCTURE_ERROR_NAME = "WorkflowInfrastructureError", MAX_CAUSE_DEPTH2 = 8, FAULT_PATTERNS, WorkflowInfrastructureError;
|
|
61148
61224
|
var init_workflow_infrastructure_error = __esm(() => {
|
|
61149
61225
|
FAULT_PATTERNS = [
|
|
61150
61226
|
[/Local worker (?:process )?cleanup (?:was not confirmed|unconfirmed)/, "worker_cleanup_unconfirmed"],
|
|
@@ -65165,7 +65241,7 @@ function describeErrorWithCauses(error) {
|
|
|
65165
65241
|
const messages = [];
|
|
65166
65242
|
const visited = new Set;
|
|
65167
65243
|
let current = error;
|
|
65168
|
-
for (let depth = 0;current !== undefined && depth <
|
|
65244
|
+
for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH3 && !visited.has(current); depth++) {
|
|
65169
65245
|
visited.add(current);
|
|
65170
65246
|
const message = current instanceof Error ? current.message : String(current);
|
|
65171
65247
|
if (!messages.includes(message))
|
|
@@ -65174,7 +65250,7 @@ function describeErrorWithCauses(error) {
|
|
|
65174
65250
|
}
|
|
65175
65251
|
return messages.join(": ");
|
|
65176
65252
|
}
|
|
65177
|
-
var
|
|
65253
|
+
var MAX_CAUSE_DEPTH3 = 5;
|
|
65178
65254
|
|
|
65179
65255
|
// dist/builtin/workflows/src/shared/returned-run-status.ts
|
|
65180
65256
|
function normalizeReturnedWorkflowStatus(status) {
|
|
@@ -66699,7 +66775,7 @@ function recordedOwners(boundary, reason) {
|
|
|
66699
66775
|
const pending = [{ value: reason, depth: 0 }];
|
|
66700
66776
|
while (pending.length > 0) {
|
|
66701
66777
|
const { value: value2, depth } = pending.pop();
|
|
66702
|
-
if (depth >
|
|
66778
|
+
if (depth > MAX_CAUSE_DEPTH4)
|
|
66703
66779
|
continue;
|
|
66704
66780
|
if (isPrimitive(value2)) {
|
|
66705
66781
|
if (depth === 0 || value2 !== undefined && value2 !== null) {
|
|
@@ -67021,7 +67097,7 @@ function containUiRejections(ui, scope) {
|
|
|
67021
67097
|
custom: (factory, options) => scope.watch(ui.custom(factory, options))
|
|
67022
67098
|
};
|
|
67023
67099
|
}
|
|
67024
|
-
var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections",
|
|
67100
|
+
var EVENT = "unhandledRejection", BOUNDARY_KEY, FLAG = "--unhandled-rejections", MAX_CAUSE_DEPTH4 = 8, MAX_PRIMITIVES_PER_RUN = 64, MAX_STOP_STRINGS = 64, ENDED_RUN_GRACE_MS = 30000, NATIVE_REPORTING_MODES, WATCHED_STAGE_METHODS;
|
|
67025
67101
|
var init_run_rejection_boundary = __esm(() => {
|
|
67026
67102
|
init_prompt_callsite();
|
|
67027
67103
|
init_workflow_source();
|
|
@@ -72912,27 +72988,6 @@ var init_runtime = __esm(() => {
|
|
|
72912
72988
|
init_intercom_group();
|
|
72913
72989
|
});
|
|
72914
72990
|
|
|
72915
|
-
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
72916
|
-
import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
|
|
72917
|
-
function reportsClosedSession(error) {
|
|
72918
|
-
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError2(error);
|
|
72919
|
-
}
|
|
72920
|
-
function isSessionClosedError(error) {
|
|
72921
|
-
let current = error;
|
|
72922
|
-
for (let depth = 0;depth < MAX_CAUSE_DEPTH4 && current !== undefined; depth++) {
|
|
72923
|
-
try {
|
|
72924
|
-
if (reportsClosedSession(current))
|
|
72925
|
-
return true;
|
|
72926
|
-
current = current.cause instanceof Error ? current.cause : undefined;
|
|
72927
|
-
} catch {
|
|
72928
|
-
return false;
|
|
72929
|
-
}
|
|
72930
|
-
}
|
|
72931
|
-
return false;
|
|
72932
|
-
}
|
|
72933
|
-
var MAX_CAUSE_DEPTH4 = 8;
|
|
72934
|
-
var init_session_closed_error = () => {};
|
|
72935
|
-
|
|
72936
72991
|
// dist/builtin/workflows/src/engine/workflow-activity.ts
|
|
72937
72992
|
import { runCallback as runCallback4 } from "@bastani/atomic";
|
|
72938
72993
|
function nextEventLoopTurn() {
|