@bastani/atomic 0.9.44-alpha.1 → 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 +31 -0
- package/dist/builtin/intercom/CHANGELOG.md +17 -0
- package/dist/builtin/intercom/broker/client-message-validation.ts +6 -0
- package/dist/builtin/intercom/broker/client.ts +4 -0
- package/dist/builtin/intercom/broker/framing.ts +18 -1
- package/dist/builtin/intercom/broker/send-signature.ts +4 -1
- package/dist/builtin/intercom/index.bundle.mjs +101 -18
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/skills/intercom/SKILL.md +1 -0
- package/dist/builtin/intercom/types.ts +8 -0
- 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 +13 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +363 -37
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +363 -37
- package/dist/builtin/workflows/src/index.js +363 -37
- package/dist/builtin/workflows/src/local-worker-entry.mjs +363 -37
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +59 -0
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +1 -0
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts +4 -0
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +10 -2
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +9 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/builtin-packages.d.ts.map +1 -1
- package/dist/core/builtin-packages.js +13 -13
- package/dist/core/builtin-packages.js.map +1 -1
- package/docs/intercom/operations.md +1 -1
- package/docs/intercom.md +11 -1
- package/docs/subagents.md +9 -1
- package/examples/extensions/gondolin/package-lock.json +3 -3
- package/npm-shrinkwrap.json +67 -51
- package/package.json +4 -4
|
@@ -1661,6 +1661,17 @@ function removeProcessExitCleanup(cleanup) {
|
|
|
1661
1661
|
if (processExitCleanups.delete(cleanup) && processExitCleanups.size === 0)
|
|
1662
1662
|
process.off("exit", runProcessExitCleanups);
|
|
1663
1663
|
}
|
|
1664
|
+
function writtenHandle(event) {
|
|
1665
|
+
if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
|
|
1666
|
+
return event.payload.handle;
|
|
1667
|
+
if (event.type === RUN_EVENT_TYPES.checkpointRecorded || event.type === RUN_EVENT_TYPES.messageSettled || event.type === RUN_EVENT_TYPES.messageDelivered)
|
|
1668
|
+
return;
|
|
1669
|
+
return event.payload;
|
|
1670
|
+
}
|
|
1671
|
+
function snapshotNeedsHistory(tail) {
|
|
1672
|
+
const handle = writtenHandle(tail.snapshot.event);
|
|
1673
|
+
return handle !== undefined && (handle.pendingStageMessageChange !== undefined || hasPendingStageDeliveryDelta(handle.pendingStageMessages));
|
|
1674
|
+
}
|
|
1664
1675
|
function* invoke(action) {
|
|
1665
1676
|
try {
|
|
1666
1677
|
const result = action();
|
|
@@ -1773,11 +1784,11 @@ class JournalDurableBackend {
|
|
|
1773
1784
|
const payload = event.payload;
|
|
1774
1785
|
this.projection.archivePendingStageDeliveryReceipt(entry.runId, payload.messageId, payload.delivery, payload.accounting);
|
|
1775
1786
|
} else if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased) {
|
|
1776
|
-
this.projection.applyWorkflowSnapshot(event.payload.handle);
|
|
1787
|
+
this.projection.applyWorkflowSnapshot(decodeHandle(event.payload.handle, this.projection.getWorkflow(entry.runId)?.pendingStageMessages));
|
|
1777
1788
|
this.prompts.set(entry.runId, new PromptReservationState(event.payload.handle.pendingPrompts, event.payload.prompts));
|
|
1778
1789
|
} else {
|
|
1779
|
-
const handle = event.payload;
|
|
1780
1790
|
const previous = this.projection.getWorkflow(entry.runId);
|
|
1791
|
+
const handle = decodeHandle(event.payload, previous?.pendingStageMessages);
|
|
1781
1792
|
this.projection.applyWorkflowSnapshot(handle);
|
|
1782
1793
|
if (event.type === RUN_EVENT_TYPES.runStarted || previous?.pendingPrompts !== handle.pendingPrompts)
|
|
1783
1794
|
this.prompts.delete(entry.runId);
|
|
@@ -1897,6 +1908,20 @@ class JournalDurableBackend {
|
|
|
1897
1908
|
}
|
|
1898
1909
|
*append(runId, event, options) {
|
|
1899
1910
|
const lease = yield* this.ownership(runId);
|
|
1911
|
+
const base = this.sequences.get(runId);
|
|
1912
|
+
const pinned = options?.expectSeq;
|
|
1913
|
+
const encoded = base !== undefined && (pinned === undefined || pinned === base) && event.type !== RUN_EVENT_TYPES.runStarted ? encodeHandleEvent(event, this.projection.getWorkflow(runId)?.pendingStageMessages) : undefined;
|
|
1914
|
+
if (encoded !== undefined) {
|
|
1915
|
+
try {
|
|
1916
|
+
return yield* this.write(runId, lease, encoded, { ...options, expectSeq: base });
|
|
1917
|
+
} catch (error) {
|
|
1918
|
+
if (!(error instanceof JournalCasConflictError) || pinned !== undefined)
|
|
1919
|
+
throw error;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
yield* this.write(runId, lease, event, options);
|
|
1923
|
+
}
|
|
1924
|
+
*write(runId, lease, event, options) {
|
|
1900
1925
|
try {
|
|
1901
1926
|
const outcome = yield* invoke(() => this.journal.append(lease, event, options));
|
|
1902
1927
|
const nextSeq = (this.sequences.get(runId) ?? 0) + 1;
|
|
@@ -2073,11 +2098,12 @@ class JournalDurableBackend {
|
|
|
2073
2098
|
for (const message of messages)
|
|
2074
2099
|
if (message.runId !== logicalRunId)
|
|
2075
2100
|
throw new JournalMessageScopeError(logicalRunId, message.runId);
|
|
2076
|
-
|
|
2101
|
+
const next = {
|
|
2077
2102
|
...handle,
|
|
2078
2103
|
pendingStageMessages: replacePendingStageMessagesForRun(handle.pendingStageMessages ?? [], logicalRunId, messages),
|
|
2079
2104
|
updatedAt: Math.max(Date.now(), handle.updatedAt + 1)
|
|
2080
|
-
}
|
|
2105
|
+
};
|
|
2106
|
+
yield* this.snapshot(next, RUN_EVENT_TYPES.messageQueued);
|
|
2081
2107
|
return true;
|
|
2082
2108
|
}
|
|
2083
2109
|
async archivePendingStageMessage(runId, message) {
|
|
@@ -2171,7 +2197,7 @@ class JournalDurableBackend {
|
|
|
2171
2197
|
if (summarized !== undefined && summarized.seq === version.seq && summarized.at === version.at)
|
|
2172
2198
|
return;
|
|
2173
2199
|
const tail = yield* invoke(() => journal.snapshotTail(runId));
|
|
2174
|
-
if (tail !== undefined)
|
|
2200
|
+
if (tail !== undefined && !snapshotNeedsHistory(tail))
|
|
2175
2201
|
return this.summarize(runId, tail);
|
|
2176
2202
|
if (summarized === undefined && version.seq === 0)
|
|
2177
2203
|
return;
|
|
@@ -2397,7 +2423,182 @@ class JournalDurableBackend {
|
|
|
2397
2423
|
}
|
|
2398
2424
|
}
|
|
2399
2425
|
}
|
|
2400
|
-
|
|
2426
|
+
function identity(message) {
|
|
2427
|
+
return JSON.stringify([message.runId, message.id]);
|
|
2428
|
+
}
|
|
2429
|
+
function uniqueByIdentity(messages) {
|
|
2430
|
+
const result = new Map;
|
|
2431
|
+
const repeated = new Set;
|
|
2432
|
+
for (const message of messages) {
|
|
2433
|
+
const key = identity(message);
|
|
2434
|
+
if (result.has(key))
|
|
2435
|
+
repeated.add(key);
|
|
2436
|
+
result.set(key, message);
|
|
2437
|
+
}
|
|
2438
|
+
for (const key of repeated)
|
|
2439
|
+
result.delete(key);
|
|
2440
|
+
return result;
|
|
2441
|
+
}
|
|
2442
|
+
function isDeltaEncoded(message) {
|
|
2443
|
+
return message.deliveryDelta !== undefined;
|
|
2444
|
+
}
|
|
2445
|
+
function deliveryDelta(base, deliveries) {
|
|
2446
|
+
const drop = [];
|
|
2447
|
+
let kept = 0;
|
|
2448
|
+
base.forEach((delivery, index) => {
|
|
2449
|
+
if (kept < deliveries.length && JSON.stringify(delivery) === JSON.stringify(deliveries[kept]))
|
|
2450
|
+
kept++;
|
|
2451
|
+
else
|
|
2452
|
+
drop.push(index);
|
|
2453
|
+
});
|
|
2454
|
+
const add = deliveries.slice(kept);
|
|
2455
|
+
return drop.length === 0 ? { add } : { drop, add };
|
|
2456
|
+
}
|
|
2457
|
+
function pendingStageFields(message) {
|
|
2458
|
+
return Object.keys(message);
|
|
2459
|
+
}
|
|
2460
|
+
function copyField(target, source, key) {
|
|
2461
|
+
target[key] = source[key];
|
|
2462
|
+
}
|
|
2463
|
+
function isRemovedField(message, key) {
|
|
2464
|
+
return message[key] === undefined;
|
|
2465
|
+
}
|
|
2466
|
+
function json(message) {
|
|
2467
|
+
let text = entryJson.get(message);
|
|
2468
|
+
if (text === undefined) {
|
|
2469
|
+
text = JSON.stringify(message);
|
|
2470
|
+
entryJson.set(message, text);
|
|
2471
|
+
}
|
|
2472
|
+
return text;
|
|
2473
|
+
}
|
|
2474
|
+
function patchEntry(index, base, message) {
|
|
2475
|
+
const set = {};
|
|
2476
|
+
const unset = pendingStageFields(base).filter((key) => base[key] !== undefined && isRemovedField(message, key));
|
|
2477
|
+
for (const key of pendingStageFields(message)) {
|
|
2478
|
+
if (message[key] === undefined || key === "deliveries")
|
|
2479
|
+
continue;
|
|
2480
|
+
if (JSON.stringify(message[key]) !== JSON.stringify(base[key]))
|
|
2481
|
+
copyField(set, message, key);
|
|
2482
|
+
}
|
|
2483
|
+
let delta;
|
|
2484
|
+
if (message.deliveries !== undefined) {
|
|
2485
|
+
if (base.deliveries === undefined)
|
|
2486
|
+
set.deliveries = message.deliveries;
|
|
2487
|
+
else if (JSON.stringify(base.deliveries) !== JSON.stringify(message.deliveries))
|
|
2488
|
+
delta = deliveryDelta(base.deliveries, message.deliveries);
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
patch: index,
|
|
2492
|
+
...Object.keys(set).length === 0 ? {} : { set },
|
|
2493
|
+
...unset.length === 0 ? {} : { unset },
|
|
2494
|
+
...delta === undefined ? {} : { deliveryDelta: delta }
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
function encodePendingStageList(previous, next) {
|
|
2498
|
+
const positions = new Map;
|
|
2499
|
+
const repeated = new Set;
|
|
2500
|
+
previous.forEach((message, index) => {
|
|
2501
|
+
const key = identity(message);
|
|
2502
|
+
if (positions.has(key))
|
|
2503
|
+
repeated.add(key);
|
|
2504
|
+
positions.set(key, index);
|
|
2505
|
+
});
|
|
2506
|
+
for (const key of repeated)
|
|
2507
|
+
positions.delete(key);
|
|
2508
|
+
const items = [];
|
|
2509
|
+
let reused = 0;
|
|
2510
|
+
for (const message of next) {
|
|
2511
|
+
const index = positions.get(identity(message));
|
|
2512
|
+
const base = index === undefined ? undefined : previous[index];
|
|
2513
|
+
if (base === undefined) {
|
|
2514
|
+
items.push(message);
|
|
2515
|
+
continue;
|
|
2516
|
+
}
|
|
2517
|
+
reused++;
|
|
2518
|
+
const patched = base === message || json(base) === json(message) ? undefined : patchEntry(index, base, message);
|
|
2519
|
+
if (patched === undefined || Object.keys(patched).length === 1) {
|
|
2520
|
+
const last = items.at(-1);
|
|
2521
|
+
if (Array.isArray(last) && last[0] + last[1] === index)
|
|
2522
|
+
last[1]++;
|
|
2523
|
+
else
|
|
2524
|
+
items.push([index, 1]);
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
items.push(JSON.stringify(patched).length < json(message).length ? patched : message);
|
|
2528
|
+
}
|
|
2529
|
+
return reused > 0 ? items : undefined;
|
|
2530
|
+
}
|
|
2531
|
+
function decodePendingStageList(previous, items) {
|
|
2532
|
+
const base = (index) => {
|
|
2533
|
+
if (!Number.isInteger(index) || index < 0 || index >= previous.length)
|
|
2534
|
+
throw new Error(`atomic-workflows: journal pending-stage change names missing entry ${index}`);
|
|
2535
|
+
return previous[index];
|
|
2536
|
+
};
|
|
2537
|
+
const result = [];
|
|
2538
|
+
for (const item of items) {
|
|
2539
|
+
if (Array.isArray(item)) {
|
|
2540
|
+
const [start, count] = item;
|
|
2541
|
+
for (let index = start;index < start + count; index++)
|
|
2542
|
+
result.push(base(index));
|
|
2543
|
+
} else if (typeof item.patch === "number") {
|
|
2544
|
+
const { patch, set, unset, deliveryDelta: delta } = item;
|
|
2545
|
+
const entry = { ...base(patch), ...set };
|
|
2546
|
+
for (const key of unset ?? [])
|
|
2547
|
+
delete entry[key];
|
|
2548
|
+
if (delta !== undefined) {
|
|
2549
|
+
const dropped = new Set(delta.drop ?? []);
|
|
2550
|
+
const deliveries = base(patch).deliveries ?? [];
|
|
2551
|
+
entry.deliveries = [...deliveries.filter((_, index) => !dropped.has(index)), ...delta.add];
|
|
2552
|
+
}
|
|
2553
|
+
result.push(entry);
|
|
2554
|
+
} else
|
|
2555
|
+
result.push(item);
|
|
2556
|
+
}
|
|
2557
|
+
return result;
|
|
2558
|
+
}
|
|
2559
|
+
function encodeHandleEvent(event, previous) {
|
|
2560
|
+
const handle = writtenHandle(event);
|
|
2561
|
+
if (handle?.pendingStageMessages === undefined || previous === undefined)
|
|
2562
|
+
return;
|
|
2563
|
+
const change = encodePendingStageList(previous, handle.pendingStageMessages);
|
|
2564
|
+
if (change === undefined)
|
|
2565
|
+
return;
|
|
2566
|
+
const { pendingStageMessages: _full, ...rest } = handle;
|
|
2567
|
+
const encoded = { ...rest, pendingStageMessageChange: change };
|
|
2568
|
+
if (event.type === RUN_EVENT_TYPES.promptAsked || event.type === RUN_EVENT_TYPES.promptReleased)
|
|
2569
|
+
return { ...event, payload: { ...event.payload, handle: encoded } };
|
|
2570
|
+
return { ...event, payload: encoded };
|
|
2571
|
+
}
|
|
2572
|
+
function decodeHandle(handle, previous) {
|
|
2573
|
+
const { pendingStageMessageChange: change, ...rest } = handle;
|
|
2574
|
+
if (change !== undefined)
|
|
2575
|
+
return { ...rest, pendingStageMessages: decodePendingStageList(previous ?? [], change) };
|
|
2576
|
+
if (!hasPendingStageDeliveryDelta(handle.pendingStageMessages))
|
|
2577
|
+
return handle;
|
|
2578
|
+
return {
|
|
2579
|
+
...handle,
|
|
2580
|
+
pendingStageMessages: decodePendingStageDeliveries(previous ?? [], handle.pendingStageMessages ?? [])
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
function decodePendingStageDeliveries(previous, messages) {
|
|
2584
|
+
if (!messages.some(isDeltaEncoded))
|
|
2585
|
+
return messages;
|
|
2586
|
+
const bases = uniqueByIdentity(previous);
|
|
2587
|
+
return messages.map((message) => {
|
|
2588
|
+
if (!isDeltaEncoded(message))
|
|
2589
|
+
return message;
|
|
2590
|
+
const base = bases.get(identity(message))?.deliveries;
|
|
2591
|
+
if (base === undefined)
|
|
2592
|
+
throw new Error(`atomic-workflows: journal delivery change for ${identity(message)} has no base entry`);
|
|
2593
|
+
const { deliveryDelta, ...rest } = message;
|
|
2594
|
+
const dropped = new Set(deliveryDelta.drop ?? []);
|
|
2595
|
+
return { ...rest, deliveries: [...base.filter((_, index) => !dropped.has(index)), ...deliveryDelta.add] };
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2598
|
+
function hasPendingStageDeliveryDelta(messages) {
|
|
2599
|
+
return messages?.some(isDeltaEncoded) === true;
|
|
2600
|
+
}
|
|
2601
|
+
var PROCESS_HOLDER_ID, processExitCleanups, JournalOwnershipError, JournalBackendClosedError, JournalOperationAbortedError, JournalExecutionRetiredError, JournalMessageScopeError, entryJson;
|
|
2401
2602
|
var init_journal_backend = __esm(() => {
|
|
2402
2603
|
init_workflow_instance_ownership_error();
|
|
2403
2604
|
init_backend();
|
|
@@ -2455,6 +2656,7 @@ var init_journal_backend = __esm(() => {
|
|
|
2455
2656
|
this.name = "JournalMessageScopeError";
|
|
2456
2657
|
}
|
|
2457
2658
|
};
|
|
2659
|
+
entryJson = new WeakMap;
|
|
2458
2660
|
});
|
|
2459
2661
|
|
|
2460
2662
|
// dist/builtin/workflows/src/durable/journal/legacy-journal-tables.ts
|
|
@@ -57447,7 +57649,20 @@ function createWorkflowBoundarySegmentsResolver(runs) {
|
|
|
57447
57649
|
};
|
|
57448
57650
|
}
|
|
57449
57651
|
function workflowBoundaryHops(runs, runId) {
|
|
57652
|
+
return boundaryHopsFrom(new Map(runs.map((run) => [run.id, run])), runId);
|
|
57653
|
+
}
|
|
57654
|
+
function createWorkflowBoundaryHopsResolver(runs) {
|
|
57450
57655
|
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
57656
|
+
const cache = new Map;
|
|
57657
|
+
return (runId) => {
|
|
57658
|
+
if (cache.has(runId))
|
|
57659
|
+
return cache.get(runId);
|
|
57660
|
+
const hops = boundaryHopsFrom(runById, runId);
|
|
57661
|
+
cache.set(runId, hops);
|
|
57662
|
+
return hops;
|
|
57663
|
+
};
|
|
57664
|
+
}
|
|
57665
|
+
function boundaryHopsFrom(runById, runId) {
|
|
57451
57666
|
const hops = [];
|
|
57452
57667
|
let current = runById.get(runId);
|
|
57453
57668
|
while (current !== undefined && current.parentRunId !== undefined) {
|
|
@@ -57473,6 +57688,35 @@ function workflowStagePathVariants(hops, stageSegments) {
|
|
|
57473
57688
|
function stageMatchesPathPattern(patternSegments, hops, stageSegments) {
|
|
57474
57689
|
return workflowStagePathVariants(hops, stageSegments).some((candidate) => matchStagePathSegments(patternSegments, candidate));
|
|
57475
57690
|
}
|
|
57691
|
+
function createStagePathPatternIndex(patterns) {
|
|
57692
|
+
const byFirstSegment = new Map;
|
|
57693
|
+
const globFirst = [];
|
|
57694
|
+
patterns.forEach((pattern, index) => {
|
|
57695
|
+
const first = pattern[0];
|
|
57696
|
+
if (first === undefined || first.includes("*")) {
|
|
57697
|
+
globFirst.push(index);
|
|
57698
|
+
return;
|
|
57699
|
+
}
|
|
57700
|
+
const bucket = byFirstSegment.get(first);
|
|
57701
|
+
if (bucket === undefined)
|
|
57702
|
+
byFirstSegment.set(first, [index]);
|
|
57703
|
+
else
|
|
57704
|
+
bucket.push(index);
|
|
57705
|
+
});
|
|
57706
|
+
return {
|
|
57707
|
+
matching(hops, stageSegments) {
|
|
57708
|
+
if (patterns.length === 0)
|
|
57709
|
+
return [];
|
|
57710
|
+
const variants = workflowStagePathVariants(hops, stageSegments);
|
|
57711
|
+
const candidates = new Set(globFirst);
|
|
57712
|
+
for (const variant of variants) {
|
|
57713
|
+
for (const index of byFirstSegment.get(variant[0]) ?? [])
|
|
57714
|
+
candidates.add(index);
|
|
57715
|
+
}
|
|
57716
|
+
return [...candidates].sort((left, right) => left - right).filter((index) => variants.some((variant) => matchStagePathSegments(patterns[index], variant)));
|
|
57717
|
+
}
|
|
57718
|
+
};
|
|
57719
|
+
}
|
|
57476
57720
|
var init_pending_stage_status = __esm(() => {
|
|
57477
57721
|
init_store_internal();
|
|
57478
57722
|
init_workflow_stage_target();
|
|
@@ -57483,24 +57727,63 @@ function stickyStageDeliveryStatuses(runs, rootRunId, availableBackend) {
|
|
|
57483
57727
|
const root = runs.find((run) => run.id === rootRunId);
|
|
57484
57728
|
const entries = (root?.pendingStageMessages ?? []).filter((entry) => entry.sticky === true);
|
|
57485
57729
|
const result = [];
|
|
57730
|
+
const patternByTarget = new Map;
|
|
57731
|
+
const patterns = [];
|
|
57732
|
+
const entriesByPattern = [];
|
|
57733
|
+
const ownEntries = [];
|
|
57734
|
+
entries.forEach((entry, index) => {
|
|
57735
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
57736
|
+
let pattern = patternByTarget.get(target);
|
|
57737
|
+
if (pattern === undefined) {
|
|
57738
|
+
const parsed = parseWorkflowStageTarget(target);
|
|
57739
|
+
pattern = parsed?.rootRunId === rootRunId ? patterns.push(parsed.segments) - 1 : -1;
|
|
57740
|
+
if (pattern >= 0)
|
|
57741
|
+
entriesByPattern.push([]);
|
|
57742
|
+
patternByTarget.set(target, pattern);
|
|
57743
|
+
}
|
|
57744
|
+
if (pattern < 0)
|
|
57745
|
+
return;
|
|
57746
|
+
entriesByPattern[pattern].push(index);
|
|
57747
|
+
ownEntries.push(index);
|
|
57748
|
+
});
|
|
57749
|
+
if (ownEntries.length === 0)
|
|
57750
|
+
return result;
|
|
57751
|
+
const patternIndex = createStagePathPatternIndex(patterns);
|
|
57752
|
+
const deliveriesByEntry = new Map;
|
|
57753
|
+
const entryReceipts = (index, runId, stageId) => {
|
|
57754
|
+
let byStage = deliveriesByEntry.get(index);
|
|
57755
|
+
if (byStage === undefined) {
|
|
57756
|
+
byStage = new Map;
|
|
57757
|
+
for (const delivery of entries[index].deliveries ?? []) {
|
|
57758
|
+
const key = `${delivery.runId}\x00${delivery.stageId}`;
|
|
57759
|
+
const list = byStage.get(key);
|
|
57760
|
+
if (list === undefined)
|
|
57761
|
+
byStage.set(key, [delivery]);
|
|
57762
|
+
else
|
|
57763
|
+
list.push(delivery);
|
|
57764
|
+
}
|
|
57765
|
+
deliveriesByEntry.set(index, byStage);
|
|
57766
|
+
}
|
|
57767
|
+
return byStage.get(`${runId}\x00${stageId}`) ?? [];
|
|
57768
|
+
};
|
|
57486
57769
|
availableBackend = availableRunDurableBackend(runs, rootRunId) ?? availableBackend;
|
|
57487
57770
|
const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, runs, rootRunId);
|
|
57771
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
57772
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
57488
57773
|
for (const run of runs) {
|
|
57489
|
-
|
|
57774
|
+
const durableRootRunId = reciprocalWorkflowRootRunId(runById, run.id);
|
|
57775
|
+
if (run.id !== rootRunId && run.rootRunId !== rootRunId && durableRootRunId !== rootRunId)
|
|
57490
57776
|
continue;
|
|
57491
|
-
const resolved =
|
|
57492
|
-
const hops =
|
|
57777
|
+
const resolved = durableRootRunId === rootRunId;
|
|
57778
|
+
const hops = hopsFor(run.id);
|
|
57493
57779
|
for (const stage of run.stages) {
|
|
57494
57780
|
if (stage.nodeKind === "tool" || stage.replayKey?.startsWith("prompt:") === true || stage.replayKey?.startsWith("workflow:") === true || stage.workflowChildRun !== undefined || stage.workflowChild !== undefined)
|
|
57495
57781
|
continue;
|
|
57496
|
-
|
|
57782
|
+
const matchedEntries = resolved && hops ? patternIndex.matching(hops, [stage.id, stage.name]).flatMap((pattern) => entriesByPattern[pattern]).sort((left, right) => left - right) : ownEntries;
|
|
57783
|
+
for (const index of matchedEntries) {
|
|
57784
|
+
const entry = entries[index];
|
|
57497
57785
|
const target = entry.targetPath ?? entry.stageKey;
|
|
57498
|
-
const
|
|
57499
|
-
if (!parsed || parsed.rootRunId !== rootRunId)
|
|
57500
|
-
continue;
|
|
57501
|
-
if (resolved && hops && !stageMatchesPathPattern(parsed.segments, hops, [stage.id, stage.name]))
|
|
57502
|
-
continue;
|
|
57503
|
-
const receipts = (entry.deliveries ?? []).filter((delivery) => delivery.runId === run.id && delivery.stageId === stage.id);
|
|
57786
|
+
const receipts = entryReceipts(index, run.id, stage.id);
|
|
57504
57787
|
const delivered = backend?.hasCachedPendingStageDeliveryReceipt?.(rootRunId, entry.id, {
|
|
57505
57788
|
runId: run.id,
|
|
57506
57789
|
stageId: stage.id,
|
|
@@ -57818,20 +58101,27 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
|
|
|
57818
58101
|
if (isTerminalRunStatus(rootRun.status))
|
|
57819
58102
|
return [];
|
|
57820
58103
|
const stickyQueued = (rootRun.pendingStageMessages ?? []).filter((entry) => entry.sticky === true && entry.status === "queued");
|
|
58104
|
+
const segmentsByTarget = new Map;
|
|
57821
58105
|
const stickySegments = (entry) => {
|
|
57822
|
-
const
|
|
57823
|
-
|
|
58106
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
58107
|
+
if (segmentsByTarget.has(target))
|
|
58108
|
+
return segmentsByTarget.get(target);
|
|
58109
|
+
const parsed = parseWorkflowStageTarget(target);
|
|
58110
|
+
const segments = parsed?.rootRunId === rootRunId ? parsed.segments : undefined;
|
|
58111
|
+
segmentsByTarget.set(target, segments);
|
|
58112
|
+
return segments;
|
|
57824
58113
|
};
|
|
57825
58114
|
const scanEntries = stickyQueued.filter((entry) => {
|
|
57826
58115
|
const segments = stickySegments(entry);
|
|
57827
58116
|
return !(segments !== undefined && segments.length === 1 && segments[0] === "**");
|
|
57828
58117
|
});
|
|
58118
|
+
const liveStageMatches = materializedStageMatcher(runs, rootRunId);
|
|
57829
58119
|
const rows = [];
|
|
57830
58120
|
for (const scanEntry of rootRun.possibleStages ?? []) {
|
|
57831
58121
|
const rowSegments = splitStagePathSegments(scanEntry);
|
|
57832
58122
|
if (rowSegments.length === 0 || rowSegments.some((segment) => segment.length === 0))
|
|
57833
58123
|
continue;
|
|
57834
|
-
if (!rowSegments.some((segment) => segment.includes("*")) &&
|
|
58124
|
+
if (!rowSegments.some((segment) => segment.includes("*")) && liveStageMatches(rowSegments)) {
|
|
57835
58125
|
continue;
|
|
57836
58126
|
}
|
|
57837
58127
|
rows.push({
|
|
@@ -57852,28 +58142,43 @@ function possibleStageRows(runs, rootRunId, rootRun, backend) {
|
|
|
57852
58142
|
}).length
|
|
57853
58143
|
});
|
|
57854
58144
|
const statuses = stickyStageDeliveryStatuses(runs, rootRunId, backend);
|
|
57855
|
-
|
|
57856
|
-
|
|
58145
|
+
const statusesByTarget = new Map;
|
|
58146
|
+
for (const status of statuses) {
|
|
58147
|
+
const forTarget = statusesByTarget.get(status.target);
|
|
58148
|
+
if (forTarget === undefined)
|
|
58149
|
+
statusesByTarget.set(status.target, [status]);
|
|
58150
|
+
else
|
|
58151
|
+
forTarget.push(status);
|
|
58152
|
+
}
|
|
58153
|
+
const queuedByTarget = new Map;
|
|
58154
|
+
for (const entry of stickyQueued) {
|
|
58155
|
+
const target = entry.targetPath ?? entry.stageKey;
|
|
58156
|
+
queuedByTarget.set(target, (queuedByTarget.get(target) ?? 0) + 1);
|
|
58157
|
+
}
|
|
58158
|
+
const rowTargets = new Set(rows.map((row) => row.target));
|
|
58159
|
+
for (const target of statusesByTarget.keys()) {
|
|
58160
|
+
if (rowTargets.has(target))
|
|
57857
58161
|
continue;
|
|
57858
|
-
|
|
57859
|
-
|
|
57860
|
-
queuedCount: stickyQueued.filter((entry) => (entry.targetPath ?? entry.stageKey) === target).length,
|
|
57861
|
-
deliveryOnly: true
|
|
57862
|
-
});
|
|
58162
|
+
rowTargets.add(target);
|
|
58163
|
+
rows.push({ target, queuedCount: queuedByTarget.get(target) ?? 0, deliveryOnly: true });
|
|
57863
58164
|
}
|
|
57864
58165
|
for (let index = 0;index < rows.length; index++) {
|
|
57865
58166
|
const row = rows[index];
|
|
57866
|
-
const deliveryStates =
|
|
57867
|
-
if (deliveryStates
|
|
58167
|
+
const deliveryStates = statusesByTarget.get(row.target);
|
|
58168
|
+
if (deliveryStates !== undefined)
|
|
57868
58169
|
rows[index] = { ...row, deliveryStates };
|
|
57869
58170
|
}
|
|
57870
58171
|
return rows;
|
|
57871
58172
|
}
|
|
57872
|
-
function
|
|
57873
|
-
|
|
57874
|
-
|
|
57875
|
-
|
|
57876
|
-
|
|
58173
|
+
function materializedStageMatcher(runs, rootRunId) {
|
|
58174
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
58175
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
58176
|
+
const invocationRuns = runs.filter((run) => reciprocalWorkflowRootRunId(runById, run.id) === rootRunId);
|
|
58177
|
+
return (entrySegments) => materializedStageMatches(invocationRuns, hopsFor, entrySegments);
|
|
58178
|
+
}
|
|
58179
|
+
function materializedStageMatches(invocationRuns, hopsFor, entrySegments) {
|
|
58180
|
+
for (const run of invocationRuns) {
|
|
58181
|
+
const hops = hopsFor(run.id);
|
|
57877
58182
|
if (hops === undefined)
|
|
57878
58183
|
continue;
|
|
57879
58184
|
for (const stage of run.stages) {
|
|
@@ -58148,10 +58453,12 @@ async function recordConfirmedStickyDeliveries(activeStore, event) {
|
|
|
58148
58453
|
}
|
|
58149
58454
|
function matchingLiveStages(runs, rootRunId, patternSegments) {
|
|
58150
58455
|
const matches = [];
|
|
58456
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
58457
|
+
const hopsFor = createWorkflowBoundaryHopsResolver(runs);
|
|
58151
58458
|
for (const run of runs) {
|
|
58152
|
-
if (
|
|
58459
|
+
if (reciprocalWorkflowRootRunId(runById, run.id) !== rootRunId)
|
|
58153
58460
|
continue;
|
|
58154
|
-
const hops =
|
|
58461
|
+
const hops = hopsFor(run.id);
|
|
58155
58462
|
if (hops === undefined)
|
|
58156
58463
|
continue;
|
|
58157
58464
|
for (const stage of run.stages) {
|
|
@@ -58287,11 +58594,26 @@ function writeMessage(socket, msg, callback) {
|
|
|
58287
58594
|
}
|
|
58288
58595
|
function createMessageReader(onMessage, onError) {
|
|
58289
58596
|
let buffer = Buffer.alloc(0);
|
|
58597
|
+
let pending = [];
|
|
58598
|
+
let pendingLength = 0;
|
|
58599
|
+
let awaitedLength = 0;
|
|
58290
58600
|
return (data) => {
|
|
58291
|
-
|
|
58601
|
+
if (pendingLength + data.length < awaitedLength) {
|
|
58602
|
+
pending.push(data);
|
|
58603
|
+
pendingLength += data.length;
|
|
58604
|
+
return;
|
|
58605
|
+
}
|
|
58606
|
+
buffer = pending.length === 0 ? Buffer.concat([buffer, data]) : Buffer.concat([...pending, data]);
|
|
58607
|
+
pending = [];
|
|
58608
|
+
pendingLength = 0;
|
|
58609
|
+
awaitedLength = 0;
|
|
58292
58610
|
while (buffer.length >= 4) {
|
|
58293
58611
|
const length = buffer.readUInt32BE(0);
|
|
58294
58612
|
if (buffer.length < 4 + length) {
|
|
58613
|
+
pending = [buffer];
|
|
58614
|
+
pendingLength = buffer.length;
|
|
58615
|
+
awaitedLength = 4 + length;
|
|
58616
|
+
buffer = Buffer.alloc(0);
|
|
58295
58617
|
break;
|
|
58296
58618
|
}
|
|
58297
58619
|
const payload = buffer.subarray(4, 4 + length);
|
|
@@ -58403,7 +58725,8 @@ function buildSendSignature(to, options) {
|
|
|
58403
58725
|
attachments: canonicalizeAttachmentsForSendSignature(options.attachments) ?? [],
|
|
58404
58726
|
replyTo: options.replyTo ?? null,
|
|
58405
58727
|
expectsReply: options.expectsReply ?? false,
|
|
58406
|
-
replyError: options.replyError ?? null
|
|
58728
|
+
replyError: options.replyError ?? null,
|
|
58729
|
+
...options.delivery === undefined || options.delivery === "steer" ? {} : { delivery: options.delivery }
|
|
58407
58730
|
});
|
|
58408
58731
|
}
|
|
58409
58732
|
|
|
@@ -58589,6 +58912,8 @@ function isMessage(value2) {
|
|
|
58589
58912
|
return false;
|
|
58590
58913
|
if (message.expectsReply !== undefined && typeof message.expectsReply !== "boolean")
|
|
58591
58914
|
return false;
|
|
58915
|
+
if (message.delivery !== undefined && message.delivery !== "steer" && message.delivery !== "followUp" && message.delivery !== "interrupt")
|
|
58916
|
+
return false;
|
|
58592
58917
|
if (message.replyError !== undefined && typeof message.replyError !== "string")
|
|
58593
58918
|
return false;
|
|
58594
58919
|
if (message.source !== undefined && !isMessageSource(message.source))
|
|
@@ -59798,6 +60123,7 @@ var init_client = __esm(() => {
|
|
|
59798
60123
|
timestamp: Date.now(),
|
|
59799
60124
|
replyTo: options.replyTo,
|
|
59800
60125
|
expectsReply: options.expectsReply,
|
|
60126
|
+
...options.delivery === undefined || options.delivery === "steer" ? {} : { delivery: options.delivery },
|
|
59801
60127
|
replyError: options.replyError,
|
|
59802
60128
|
source: this._messageSource,
|
|
59803
60129
|
content: { text: options.text, attachments: options.attachments }
|