@bastani/atomic 0.9.44-alpha.2 → 0.9.44-alpha.3
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 +15 -0
- package/dist/builtin/intercom/CHANGELOG.md +7 -0
- package/dist/builtin/intercom/broker/framing.ts +18 -1
- package/dist/builtin/intercom/index.bundle.mjs +19 -4
- 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/index.bundle.mjs +2510 -1308
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +7 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +313 -76
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +313 -76
- package/dist/builtin/workflows/src/index.js +313 -76
- package/dist/builtin/workflows/src/local-worker-entry.mjs +313 -76
- package/examples/extensions/gondolin/package-lock.json +3 -3
- package/npm-shrinkwrap.json +67 -51
- package/package.json +4 -4
|
@@ -9870,12 +9870,16 @@ function removeProcessExitCleanup(cleanup) {
|
|
|
9870
9870
|
if (processExitCleanups.delete(cleanup) && processExitCleanups.size === 0)
|
|
9871
9871
|
process.off("exit", runProcessExitCleanups);
|
|
9872
9872
|
}
|
|
9873
|
+
function writtenHandle(event) {
|
|
9874
|
+
if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
|
|
9875
|
+
return event.payload.handle;
|
|
9876
|
+
if (event.type === RUN_EVENT_TYPES.checkpointRecorded || event.type === RUN_EVENT_TYPES.messageSettled || event.type === RUN_EVENT_TYPES.messageDelivered)
|
|
9877
|
+
return;
|
|
9878
|
+
return event.payload;
|
|
9879
|
+
}
|
|
9873
9880
|
function snapshotNeedsHistory(tail) {
|
|
9874
|
-
const
|
|
9875
|
-
|
|
9876
|
-
return false;
|
|
9877
|
-
const payload = event.payload;
|
|
9878
|
-
return hasPendingStageDeliveryDelta(payload.pendingStageMessages);
|
|
9881
|
+
const handle = writtenHandle(tail.snapshot.event);
|
|
9882
|
+
return handle !== undefined && (handle.pendingStageMessageChange !== undefined || hasPendingStageDeliveryDelta(handle.pendingStageMessages));
|
|
9879
9883
|
}
|
|
9880
9884
|
function* invoke(action) {
|
|
9881
9885
|
try {
|
|
@@ -9989,14 +9993,11 @@ class JournalDurableBackend {
|
|
|
9989
9993
|
const payload = event.payload;
|
|
9990
9994
|
this.projection.archivePendingStageDeliveryReceipt(entry.runId, payload.messageId, payload.delivery, payload.accounting);
|
|
9991
9995
|
} else if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased) {
|
|
9992
|
-
this.projection.applyWorkflowSnapshot(event.payload.handle);
|
|
9996
|
+
this.projection.applyWorkflowSnapshot(decodeHandle(event.payload.handle, this.projection.getWorkflow(entry.runId)?.pendingStageMessages));
|
|
9993
9997
|
this.prompts.set(entry.runId, new PromptReservationState(event.payload.handle.pendingPrompts, event.payload.prompts));
|
|
9994
9998
|
} else {
|
|
9995
9999
|
const previous = this.projection.getWorkflow(entry.runId);
|
|
9996
|
-
const handle =
|
|
9997
|
-
...event.payload,
|
|
9998
|
-
pendingStageMessages: decodePendingStageDeliveries(previous?.pendingStageMessages ?? [], event.payload.pendingStageMessages ?? [])
|
|
9999
|
-
} : event.payload;
|
|
10000
|
+
const handle = decodeHandle(event.payload, previous?.pendingStageMessages);
|
|
10000
10001
|
this.projection.applyWorkflowSnapshot(handle);
|
|
10001
10002
|
if (event.type === RUN_EVENT_TYPES.runStarted || previous?.pendingPrompts !== handle.pendingPrompts)
|
|
10002
10003
|
this.prompts.delete(entry.runId);
|
|
@@ -10116,6 +10117,20 @@ class JournalDurableBackend {
|
|
|
10116
10117
|
}
|
|
10117
10118
|
*append(runId, event, options) {
|
|
10118
10119
|
const lease = yield* this.ownership(runId);
|
|
10120
|
+
const base = this.sequences.get(runId);
|
|
10121
|
+
const pinned = options?.expectSeq;
|
|
10122
|
+
const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
|
|
10123
|
+
if (encoded !== undefined) {
|
|
10124
|
+
try {
|
|
10125
|
+
return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
|
|
10126
|
+
} catch (error) {
|
|
10127
|
+
if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
|
|
10128
|
+
throw error;
|
|
10129
|
+
}
|
|
10130
|
+
}
|
|
10131
|
+
yield* this.write(runId, lease, event, options);
|
|
10132
|
+
}
|
|
10133
|
+
*write(runId, lease, event, options) {
|
|
10119
10134
|
try {
|
|
10120
10135
|
const outcome = yield* invoke(() => this.journal.append(lease, event, options));
|
|
10121
10136
|
const nextSeq = (this.sequences.get(runId) ?? 0) + 1;
|
|
@@ -10297,17 +10312,6 @@ class JournalDurableBackend {
|
|
|
10297
10312
|
pendingStageMessages: replacePendingStageMessagesForRun(handle.pendingStageMessages ?? [], logicalRunId, messages),
|
|
10298
10313
|
updatedAt: Math.max(Date.now(), handle.updatedAt + 1)
|
|
10299
10314
|
};
|
|
10300
|
-
const encoded = encodePendingStageDeliveries(handle.pendingStageMessages ?? [], next.pendingStageMessages ?? []);
|
|
10301
|
-
const base = this.sequences.get(runId);
|
|
10302
|
-
if (encoded !== undefined && base !== undefined) {
|
|
10303
|
-
try {
|
|
10304
|
-
yield* this.append(runId, { type: RUN_EVENT_TYPES.messageQueued, payload: { ...next, pendingStageMessages: encoded } }, { expectSeq: base });
|
|
10305
|
-
return true;
|
|
10306
|
-
} catch (error) {
|
|
10307
|
-
if (!(error instanceof JournalCasConflictError))
|
|
10308
|
-
throw error;
|
|
10309
|
-
}
|
|
10310
|
-
}
|
|
10311
10315
|
yield* this.snapshot(next, RUN_EVENT_TYPES.messageQueued);
|
|
10312
10316
|
return true;
|
|
10313
10317
|
}
|
|
@@ -10647,31 +10651,143 @@ function uniqueByIdentity(messages) {
|
|
|
10647
10651
|
function isDeltaEncoded(message) {
|
|
10648
10652
|
return message.deliveryDelta !== undefined;
|
|
10649
10653
|
}
|
|
10650
|
-
function
|
|
10651
|
-
const
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
return message;
|
|
10659
|
-
const drop = [];
|
|
10660
|
-
let kept = 0;
|
|
10661
|
-
base.forEach((delivery, index) => {
|
|
10662
|
-
if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
|
|
10663
|
-
kept++;
|
|
10664
|
-
else
|
|
10665
|
-
drop.push(index);
|
|
10666
|
-
});
|
|
10667
|
-
const add = deliveries.slice(kept);
|
|
10668
|
-
if (drop.length + add.length >= deliveries.length)
|
|
10669
|
-
return message;
|
|
10670
|
-
encodedAny = true;
|
|
10671
|
-
const { deliveries: _full, ...rest } = message;
|
|
10672
|
-
return { ...rest, deliveryDelta: drop.length === 0 ? { add } : { drop, add } };
|
|
10654
|
+
function deliveryDelta(base, deliveries) {
|
|
10655
|
+
const drop = [];
|
|
10656
|
+
let kept = 0;
|
|
10657
|
+
base.forEach((delivery, index) => {
|
|
10658
|
+
if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
|
|
10659
|
+
kept++;
|
|
10660
|
+
else
|
|
10661
|
+
drop.push(index);
|
|
10673
10662
|
});
|
|
10674
|
-
|
|
10663
|
+
const add = deliveries.slice(kept);
|
|
10664
|
+
return drop.length === 0 ? { add } : { drop, add };
|
|
10665
|
+
}
|
|
10666
|
+
function pendingStageFields(message) {
|
|
10667
|
+
return Object.keys(message);
|
|
10668
|
+
}
|
|
10669
|
+
function copyField(target, source, key) {
|
|
10670
|
+
target[key] = source[key];
|
|
10671
|
+
}
|
|
10672
|
+
function isRemovedField(message, key) {
|
|
10673
|
+
return message[key] === undefined;
|
|
10674
|
+
}
|
|
10675
|
+
function json(message) {
|
|
10676
|
+
let text = entryJson.get(message);
|
|
10677
|
+
if (text === undefined) {
|
|
10678
|
+
text = JSON.stringify(message);
|
|
10679
|
+
entryJson.set(message, text);
|
|
10680
|
+
}
|
|
10681
|
+
return text;
|
|
10682
|
+
}
|
|
10683
|
+
function patchEntry(index, base, message) {
|
|
10684
|
+
const set = {};
|
|
10685
|
+
const unset = pendingStageFields(base).filter((key) => base[key] !== undefined && isRemovedField(message, key));
|
|
10686
|
+
for (const key of pendingStageFields(message)) {
|
|
10687
|
+
if (message[key] === undefined || key === "deliveries")
|
|
10688
|
+
continue;
|
|
10689
|
+
if (JSON.stringify(message[key]) !== JSON.stringify(base[key]))
|
|
10690
|
+
copyField(set, message, key);
|
|
10691
|
+
}
|
|
10692
|
+
let delta;
|
|
10693
|
+
if (message.deliveries !== undefined) {
|
|
10694
|
+
if (base.deliveries === undefined)
|
|
10695
|
+
set.deliveries = message.deliveries;
|
|
10696
|
+
else if (JSON.stringify(base.deliveries) !== JSON.stringify(message.deliveries))
|
|
10697
|
+
delta = deliveryDelta(base.deliveries, message.deliveries);
|
|
10698
|
+
}
|
|
10699
|
+
return {
|
|
10700
|
+
patch: index,
|
|
10701
|
+
...Object.keys(set).length === 0 ? {} : { set },
|
|
10702
|
+
...unset.length === 0 ? {} : { unset },
|
|
10703
|
+
...delta === undefined ? {} : { deliveryDelta: delta }
|
|
10704
|
+
};
|
|
10705
|
+
}
|
|
10706
|
+
function encodePendingStageList(previous, next) {
|
|
10707
|
+
const positions = new Map;
|
|
10708
|
+
const repeated = new Set;
|
|
10709
|
+
previous.forEach((message, index) => {
|
|
10710
|
+
const key = identity(message);
|
|
10711
|
+
if (positions.has(key))
|
|
10712
|
+
repeated.add(key);
|
|
10713
|
+
positions.set(key, index);
|
|
10714
|
+
});
|
|
10715
|
+
for (const key of repeated)
|
|
10716
|
+
positions.delete(key);
|
|
10717
|
+
const items = [];
|
|
10718
|
+
let reused = 0;
|
|
10719
|
+
for (const message of next) {
|
|
10720
|
+
const index = positions.get(identity(message));
|
|
10721
|
+
const base = index === undefined ? undefined : previous[index];
|
|
10722
|
+
if (base === undefined) {
|
|
10723
|
+
items.push(message);
|
|
10724
|
+
continue;
|
|
10725
|
+
}
|
|
10726
|
+
reused++;
|
|
10727
|
+
const patched = base === message || json(base) === json(message) ? undefined : patchEntry(index, base, message);
|
|
10728
|
+
if (patched === undefined || Object.keys(patched).length === 1) {
|
|
10729
|
+
const last = items.at(-1);
|
|
10730
|
+
if (Array.isArray(last) && last[0] + last[1] === index)
|
|
10731
|
+
last[1]++;
|
|
10732
|
+
else
|
|
10733
|
+
items.push([index, 1]);
|
|
10734
|
+
continue;
|
|
10735
|
+
}
|
|
10736
|
+
items.push(JSON.stringify(patched).length < json(message).length ? patched : message);
|
|
10737
|
+
}
|
|
10738
|
+
return reused > 0 ? items : undefined;
|
|
10739
|
+
}
|
|
10740
|
+
function decodePendingStageList(previous, items) {
|
|
10741
|
+
const base = (index) => {
|
|
10742
|
+
if (!Number.isInteger(index) || index < 0 || index >= previous.length)
|
|
10743
|
+
throw new Error(`atomic-workflows: journal pending-stage change names missing entry ${index}`);
|
|
10744
|
+
return previous[index];
|
|
10745
|
+
};
|
|
10746
|
+
const result = [];
|
|
10747
|
+
for (const item of items) {
|
|
10748
|
+
if (Array.isArray(item)) {
|
|
10749
|
+
const [start, count] = item;
|
|
10750
|
+
for (let index = start;index < start + count; index++)
|
|
10751
|
+
result.push(base(index));
|
|
10752
|
+
} else if (typeof item.patch === "number") {
|
|
10753
|
+
const { patch, set, unset, deliveryDelta: delta } = item;
|
|
10754
|
+
const entry = { ...base(patch), ...set };
|
|
10755
|
+
for (const key of unset ?? [])
|
|
10756
|
+
delete entry[key];
|
|
10757
|
+
if (delta !== undefined) {
|
|
10758
|
+
const dropped = new Set(delta.drop ?? []);
|
|
10759
|
+
const deliveries = base(patch).deliveries ?? [];
|
|
10760
|
+
entry.deliveries = [...deliveries.filter((_, index) => !dropped.has(index)), ...delta.add];
|
|
10761
|
+
}
|
|
10762
|
+
result.push(entry);
|
|
10763
|
+
} else
|
|
10764
|
+
result.push(item);
|
|
10765
|
+
}
|
|
10766
|
+
return result;
|
|
10767
|
+
}
|
|
10768
|
+
function encodeHandleEvent(event, previous) {
|
|
10769
|
+
const handle = writtenHandle(event);
|
|
10770
|
+
if (handle?.pendingStageMessages === undefined || previous === undefined)
|
|
10771
|
+
return;
|
|
10772
|
+
const change = encodePendingStageList(previous, handle.pendingStageMessages);
|
|
10773
|
+
if (change === undefined)
|
|
10774
|
+
return;
|
|
10775
|
+
const { pendingStageMessages: _full, ...rest } = handle;
|
|
10776
|
+
const encoded = { ...rest, pendingStageMessageChange: change };
|
|
10777
|
+
if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
|
|
10778
|
+
return { ...event, payload: { ...event.payload, handle: encoded } };
|
|
10779
|
+
return { ...event, payload: encoded };
|
|
10780
|
+
}
|
|
10781
|
+
function decodeHandle(handle, previous) {
|
|
10782
|
+
const { pendingStageMessageChange: change, ...rest } = handle;
|
|
10783
|
+
if (change !== undefined)
|
|
10784
|
+
return { ...rest, pendingStageMessages: decodePendingStageList(previous ?? [], change) };
|
|
10785
|
+
if (!hasPendingStageDeliveryDelta(handle.pendingStageMessages))
|
|
10786
|
+
return handle;
|
|
10787
|
+
return {
|
|
10788
|
+
...handle,
|
|
10789
|
+
pendingStageMessages: decodePendingStageDeliveries(previous ?? [], handle.pendingStageMessages ?? [])
|
|
10790
|
+
};
|
|
10675
10791
|
}
|
|
10676
10792
|
function decodePendingStageDeliveries(previous, messages) {
|
|
10677
10793
|
if (!messages.some(isDeltaEncoded))
|
|
@@ -10691,7 +10807,7 @@ function decodePendingStageDeliveries(previous, messages) {
|
|
|
10691
10807
|
function hasPendingStageDeliveryDelta(messages) {
|
|
10692
10808
|
return messages?.some(isDeltaEncoded) === true;
|
|
10693
10809
|
}
|
|
10694
|
-
var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError;
|
|
10810
|
+
var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
10695
10811
|
var init_journal_backend = __esm(() => {
|
|
10696
10812
|
init_workflow_instance_ownership_error();
|
|
10697
10813
|
init_backend();
|
|
@@ -10749,6 +10865,7 @@ var init_journal_backend = __esm(() => {
|
|
|
10749
10865
|
this.name = "JournalMessageScopeError";
|
|
10750
10866
|
}
|
|
10751
10867
|
};
|
|
10868
|
+
entryJson = new WeakMap;
|
|
10752
10869
|
});
|
|
10753
10870
|
|
|
10754
10871
|
// dist/builtin/workflows/src/durable/factory.ts
|
|
@@ -58215,7 +58332,20 @@ function createWorkflowBoundarySegmentsResolver(runs) {
|
|
|
58215
58332
|
};
|
|
58216
58333
|
}
|
|
58217
58334
|
function workflowBoundaryHops(runs, runId) {
|
|
58335
|
+
return boundaryHopsFrom(new Map(runs.map((run) => [run.id, run])), runId);
|
|
58336
|
+
}
|
|
58337
|
+
function createWorkflowBoundaryHopsResolver(runs) {
|
|
58218
58338
|
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
58339
|
+
const cache = new Map;
|
|
58340
|
+
return (runId) => {
|
|
58341
|
+
if (cache.has(runId))
|
|
58342
|
+
return cache.get(runId);
|
|
58343
|
+
const hops = boundaryHopsFrom(runById, runId);
|
|
58344
|
+
cache.set(runId, hops);
|
|
58345
|
+
return hops;
|
|
58346
|
+
};
|
|
58347
|
+
}
|
|
58348
|
+
function boundaryHopsFrom(runById, runId) {
|
|
58219
58349
|
const hops = [];
|
|
58220
58350
|
let current = runById.get(runId);
|
|
58221
58351
|
while (current !== undefined && current.parentRunId !== undefined) {
|
|
@@ -58241,6 +58371,35 @@ function workflowStagePathVariants(hops, stageSegments) {
|
|
|
58241
58371
|
function stageMatchesPathPattern(patternSegments, hops, stageSegments) {
|
|
58242
58372
|
return workflowStagePathVariants(hops, stageSegments).some((candidate) => matchStagePathSegments(patternSegments, candidate));
|
|
58243
58373
|
}
|
|
58374
|
+
function createStagePathPatternIndex(patterns) {
|
|
58375
|
+
const byFirstSegment = new Map;
|
|
58376
|
+
const globFirst = [];
|
|
58377
|
+
patterns.forEach((pattern, index) => {
|
|
58378
|
+
const first = pattern[0];
|
|
58379
|
+
if (first === undefined || first.includes("*")) {
|
|
58380
|
+
globFirst.push(index);
|
|
58381
|
+
return;
|
|
58382
|
+
}
|
|
58383
|
+
const bucket = byFirstSegment.get(first);
|
|
58384
|
+
if (bucket === undefined)
|
|
58385
|
+
byFirstSegment.set(first, [index]);
|
|
58386
|
+
else
|
|
58387
|
+
bucket.push(index);
|
|
58388
|
+
});
|
|
58389
|
+
return {
|
|
58390
|
+
matching(hops, stageSegments) {
|
|
58391
|
+
if (patterns.length === 0)
|
|
58392
|
+
return [];
|
|
58393
|
+
const variants = workflowStagePathVariants(hops, stageSegments);
|
|
58394
|
+
const candidates = new Set(globFirst);
|
|
58395
|
+
for (const variant of variants) {
|
|
58396
|
+
for (const index of byFirstSegment.get(variant[0]) ?? [])
|
|
58397
|
+
candidates.add(index);
|
|
58398
|
+
}
|
|
58399
|
+
return [...candidates].sort((left, right) => left - right).filter((index) => variants.some((variant) => matchStagePathSegments(patterns[index], variant)));
|
|
58400
|
+
}
|
|
58401
|
+
};
|
|
58402
|
+
}
|
|
58244
58403
|
var init_pending_stage_status = __esm(() => {
|
|
58245
58404
|
init_store_internal();
|
|
58246
58405
|
init_workflow_stage_target();
|
|
@@ -58251,24 +58410,63 @@ function stickyStageDeliveryStatuses(runs, rootRunId, availableBackend) {
|
|
|
58251
58410
|
const root = runs.find((run) => run.id === rootRunId);
|
|
58252
58411
|
const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
|
|
58253
58412
|
const result = [];
|
|
58413
|
+
const patternByTarget = new Map;
|
|
58414
|
+
const patterns = [];
|
|
58415
|
+
const entriesByPattern = [];
|
|
58416
|
+
const ownEntries = [];
|
|
58417
|
+
entries.forEach((entry, index) => {
|
|
58418
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
58419
|
+
let pattern = patternByTarget.get(target);
|
|
58420
|
+
if (pattern === undefined) {
|
|
58421
|
+
const parsed = parseWorkflowStageTarget(target);
|
|
58422
|
+
pattern = parsed?.rootRunId === rootRunId ? patterns.push(parsed.segments) - 1 : -1;
|
|
58423
|
+
if (pattern >= 0)
|
|
58424
|
+
entriesByPattern.push([]);
|
|
58425
|
+
patternByTarget.set(target, pattern);
|
|
58426
|
+
}
|
|
58427
|
+
if (pattern < 0)
|
|
58428
|
+
return;
|
|
58429
|
+
entriesByPattern[pattern].push(index);
|
|
58430
|
+
ownEntries.push(index);
|
|
58431
|
+
});
|
|
58432
|
+
if (ownEntries.length === 0)
|
|
58433
|
+
return result;
|
|
58434
|
+
const patternIndex = createStagePathPatternIndex(patterns);
|
|
58435
|
+
const deliveriesByEntry = new Map;
|
|
58436
|
+
const entryReceipts = (index, runId, stageId) => {
|
|
58437
|
+
let byStage = deliveriesByEntry.get(index);
|
|
58438
|
+
if (byStage === undefined) {
|
|
58439
|
+
byStage = new Map;
|
|
58440
|
+
for (const delivery of entries[index].deliveries ?? []) {
|
|
58441
|
+
const key = `${delivery.runId}\x00${delivery.stageId}`;
|
|
58442
|
+
const list = byStage.get(key);
|
|
58443
|
+
if (list === undefined)
|
|
58444
|
+
byStage.set(key, [delivery]);
|
|
58445
|
+
else
|
|
58446
|
+
list.push(delivery);
|
|
58447
|
+
}
|
|
58448
|
+
deliveriesByEntry.set(index, byStage);
|
|
58449
|
+
}
|
|
58450
|
+
return byStage.get(`${runId}\x00${stageId}`) ?? [];
|
|
58451
|
+
};
|
|
58254
58452
|
availableBackend = availableRunDurableBackend(runs, rootRunId) ?? availableBackend;
|
|
58255
58453
|
const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, runs, rootRunId);
|
|
58454
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
58455
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
58256
58456
|
for (const run of runs) {
|
|
58257
|
-
|
|
58457
|
+
const durableRootRunId = reciprocalWorkflowRootRunId(runById, run.id);
|
|
58458
|
+
if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunId !== rootRunId)
|
|
58258
58459
|
continue;
|
|
58259
|
-
const resolved =
|
|
58260
|
-
const hops =
|
|
58460
|
+
const resolved = durableRootRunId === rootRunId;
|
|
58461
|
+
const hops = hopsFor(run.id);
|
|
58261
58462
|
for (const stage of run.stages) {
|
|
58262
58463
|
if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
|
|
58263
58464
|
continue;
|
|
58264
|
-
|
|
58465
|
+
const matchedEntries = resolved && hops ? patternIndex.matching(hops, [stage.id, stage.name]).flatMap((pattern) => entriesByPattern[pattern]).sort((left, right) => left - right) : ownEntries;
|
|
58466
|
+
for (const index of matchedEntries) {
|
|
58467
|
+
const entry = entries[index];
|
|
58265
58468
|
const target = entry.targetPath ?? entry.stageKey;
|
|
58266
|
-
const
|
|
58267
|
-
if (!parsed || parsed.rootRunId !== rootRunId)
|
|
58268
|
-
continue;
|
|
58269
|
-
if (resolved && hops && !stageMatchesPathPattern(parsed.segments, hops, [stage.id, stage.name]))
|
|
58270
|
-
continue;
|
|
58271
|
-
const receipts = (entry.deliveries ?? []).filter((delivery) => delivery.runId === run.id && delivery.stageId === stage.id);
|
|
58469
|
+
const receipts = entryReceipts(index, run.id, stage.id);
|
|
58272
58470
|
const delivered = backend?.hasCachedPendingStageDeliveryReceipt?.(rootRunId, entry.id, {
|
|
58273
58471
|
runId: run.id,
|
|
58274
58472
|
stageId: stage.id,
|
|
@@ -58586,20 +58784,27 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
|
|
|
58586
58784
|
if (isTerminalRunStatus(rootRun.status))
|
|
58587
58785
|
return [];
|
|
58588
58786
|
const stickyQueued = (rootRun.pendingStageMessages ?? []).filter((entry) => entry.sticky === true && entry.status === "queued");
|
|
58787
|
+
const segmentsByTarget = new Map;
|
|
58589
58788
|
const stickySegments = (entry) => {
|
|
58590
|
-
const
|
|
58591
|
-
|
|
58789
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
58790
|
+
if (segmentsByTarget.has(target))
|
|
58791
|
+
return segmentsByTarget.get(target);
|
|
58792
|
+
const parsed = parseWorkflowStageTarget(target);
|
|
58793
|
+
const segments = parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
|
|
58794
|
+
segmentsByTarget.set(target, segments);
|
|
58795
|
+
return segments;
|
|
58592
58796
|
};
|
|
58593
58797
|
const scanEntries = stickyQueued.filter((entry) => {
|
|
58594
58798
|
const segments = stickySegments(entry);
|
|
58595
58799
|
return !(segments !== undefined && segments.length === 1 && segments[0] === "**");
|
|
58596
58800
|
});
|
|
58801
|
+
const liveStageMatches = materializedStageMatcher(runs, rootRunId);
|
|
58597
58802
|
const rows = [];
|
|
58598
58803
|
for (const scanEntry of rootRun.possibleStages ?? []) {
|
|
58599
58804
|
const rowSegments = splitStagePathSegments(scanEntry);
|
|
58600
58805
|
if (rowSegments.length === 0 || rowSegments.some((segment) => segment.length === 0))
|
|
58601
58806
|
continue;
|
|
58602
|
-
if (!rowSegments.some((segment) => segment.includes("*")) &&
|
|
58807
|
+
if (!rowSegments.some((segment) => segment.includes("*")) && liveStageMatches(rowSegments)) {
|
|
58603
58808
|
continue;
|
|
58604
58809
|
}
|
|
58605
58810
|
rows.push({
|
|
@@ -58620,28 +58825,43 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
|
|
|
58620
58825
|
}).length
|
|
58621
58826
|
});
|
|
58622
58827
|
const statuses = stickyStageDeliveryStatuses(runs, rootRunId, backend);
|
|
58623
|
-
|
|
58624
|
-
|
|
58828
|
+
const statusesByTarget = new Map;
|
|
58829
|
+
for (const status of statuses) {
|
|
58830
|
+
const forTarget = statusesByTarget.get(status.target);
|
|
58831
|
+
if (forTarget === undefined)
|
|
58832
|
+
statusesByTarget.set(status.target, [status]);
|
|
58833
|
+
else
|
|
58834
|
+
forTarget.push(status);
|
|
58835
|
+
}
|
|
58836
|
+
const queuedByTarget = new Map;
|
|
58837
|
+
for (const entry of stickyQueued) {
|
|
58838
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
58839
|
+
queuedByTarget.set(target, (queuedByTarget.get(target) ?? 0) + 1);
|
|
58840
|
+
}
|
|
58841
|
+
const rowTargets = new Set(rows.map((row) => row.target));
|
|
58842
|
+
for (const target of statusesByTarget.keys()) {
|
|
58843
|
+
if (rowTargets.has(target))
|
|
58625
58844
|
continue;
|
|
58626
|
-
|
|
58627
|
-
|
|
58628
|
-
queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
|
|
58629
|
-
deliveryOnly: true
|
|
58630
|
-
});
|
|
58845
|
+
rowTargets.add(target);
|
|
58846
|
+
rows.push({ target, queuedCount: queuedByTarget.get(target) ?? 0, deliveryOnly: true });
|
|
58631
58847
|
}
|
|
58632
58848
|
for (let index = 0;index < rows.length; index++) {
|
|
58633
58849
|
const row = rows[index];
|
|
58634
|
-
const deliveryStates =
|
|
58635
|
-
if (deliveryStates
|
|
58850
|
+
const deliveryStates = statusesByTarget.get(row.target);
|
|
58851
|
+
if (deliveryStates !== undefined)
|
|
58636
58852
|
rows[index] = { ...row, deliveryStates };
|
|
58637
58853
|
}
|
|
58638
58854
|
return rows;
|
|
58639
58855
|
}
|
|
58640
|
-
function
|
|
58641
|
-
|
|
58642
|
-
|
|
58643
|
-
|
|
58644
|
-
|
|
58856
|
+
function materializedStageMatcher(runs, rootRunId) {
|
|
58857
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
58858
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
58859
|
+
const invocationRuns = runs.filter((run) => reciprocalWorkflowRootRunId(runById, run.id) === rootRunId);
|
|
58860
|
+
return (entrySegments) => materializedStageMatches(invocationRuns, hopsFor, entrySegments);
|
|
58861
|
+
}
|
|
58862
|
+
function materializedStageMatches(invocationRuns, hopsFor, entrySegments) {
|
|
58863
|
+
for (const run of invocationRuns) {
|
|
58864
|
+
const hops = hopsFor(run.id);
|
|
58645
58865
|
if (hops === undefined)
|
|
58646
58866
|
continue;
|
|
58647
58867
|
for (const stage of run.stages) {
|
|
@@ -58916,10 +59136,12 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
|
|
|
58916
59136
|
}
|
|
58917
59137
|
function matchingLiveStages(runs, rootRunId, patternSegments) {
|
|
58918
59138
|
const matches = [];
|
|
59139
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
59140
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
58919
59141
|
for (const run of runs) {
|
|
58920
|
-
if (
|
|
59142
|
+
if (reciprocalWorkflowRootRunId(runById, run.id) !== rootRunId)
|
|
58921
59143
|
continue;
|
|
58922
|
-
const hops =
|
|
59144
|
+
const hops = hopsFor(run.id);
|
|
58923
59145
|
if (hops === undefined)
|
|
58924
59146
|
continue;
|
|
58925
59147
|
for (const stage of run.stages) {
|
|
@@ -59055,11 +59277,26 @@ function writeMessage(socket, msg, callback) {
|
|
|
59055
59277
|
}
|
|
59056
59278
|
function createMessageReader(onMessage, onError) {
|
|
59057
59279
|
let buffer = Buffer.alloc(0);
|
|
59280
|
+
let pending = [];
|
|
59281
|
+
let pendingLength = 0;
|
|
59282
|
+
let awaitedLength = 0;
|
|
59058
59283
|
return (data) => {
|
|
59059
|
-
|
|
59284
|
+
if (pendingLength + data.length < awaitedLength) {
|
|
59285
|
+
pending.push(data);
|
|
59286
|
+
pendingLength += data.length;
|
|
59287
|
+
return;
|
|
59288
|
+
}
|
|
59289
|
+
buffer = pending.length === 0 ? Buffer.concat([buffer, data]) : Buffer.concat([...pending, data]);
|
|
59290
|
+
pending = [];
|
|
59291
|
+
pendingLength = 0;
|
|
59292
|
+
awaitedLength = 0;
|
|
59060
59293
|
while (buffer.length >= 4) {
|
|
59061
59294
|
const length = buffer.readUInt32BE(0);
|
|
59062
59295
|
if (buffer.length < 4 + length) {
|
|
59296
|
+
pending = [buffer];
|
|
59297
|
+
pendingLength = buffer.length;
|
|
59298
|
+
awaitedLength = 4 + length;
|
|
59299
|
+
buffer = Buffer.alloc(0);
|
|
59063
59300
|
break;
|
|
59064
59301
|
}
|
|
59065
59302
|
const payload = buffer.subarray(4, 4 + length);
|