@bastani/atomic 0.9.41-alpha.1 → 0.9.41-alpha.2
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 +25 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +3 -3
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +8 -0
- package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
- package/dist/builtin/workflows/builtin/{chunk-qjqn389g.js → chunk-2jfst7e4.js} +72 -10
- package/dist/builtin/workflows/builtin/{chunk-4bwtzyjq.js → chunk-49kkbdpr.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-qdd897wm.js → chunk-apagcs4r.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-454hz1qt.js → chunk-dcxscfnb.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-bjva9j5k.js → chunk-hx8v4p97.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-85mx6wcf.js → chunk-k5q3t7je.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-8kkv04hz.js → chunk-n2gkzkty.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-y45tkftg.js → chunk-txbc93t6.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-x0vvjyzg.js → chunk-w4xp1w1f.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-5eh0brtd.js → chunk-z3pajrfs.js} +1 -1
- package/dist/builtin/workflows/builtin/classify-and-act.js +2 -2
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +2 -2
- package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +10 -10
- package/dist/builtin/workflows/builtin/loop-until-done.js +2 -2
- package/dist/builtin/workflows/builtin/open-claude-design.js +2 -2
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/builtin/tournament.js +2 -2
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +511 -28
- package/dist/builtin/workflows/src/index.js +582 -99
- package/dist/core/model-config.d.ts +28 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/provider-composer-internal.d.ts +2 -1
- package/dist/core/provider-composer-internal.d.ts.map +1 -1
- package/dist/core/provider-composer-internal.js +8 -6
- package/dist/core/provider-composer-internal.js.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/docs/models-configuration.md +9 -0
- package/docs/models.md +3 -1
- package/docs/providers.md +1 -1
- package/docs/workflows/authoring.md +1 -1
- package/npm-shrinkwrap.json +67 -54
- package/package.json +6 -6
- package/schemas/models.schema.json +21 -0
|
@@ -52451,7 +52451,7 @@ function compareDraftSourceOrder(left, right) {
|
|
|
52451
52451
|
function runTopologyFor(drafts, tools) {
|
|
52452
52452
|
return drafts.find((draft) => draft.topology?.run !== undefined)?.topology?.run ?? tools.find((checkpoint) => checkpoint.topology?.run !== undefined)?.topology?.run;
|
|
52453
52453
|
}
|
|
52454
|
-
function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
52454
|
+
function validateRunGroups(grouped, rootRunId, tools, checkpoints, allowPendingChildren = false) {
|
|
52455
52455
|
const toolsFor = (runId) => tools.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
52456
52456
|
const owners = new Map;
|
|
52457
52457
|
const syntheticChildIds = new Set;
|
|
@@ -52463,6 +52463,11 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
|
52463
52463
|
if (childRunId === parentRunId || owners.has(childRunId))
|
|
52464
52464
|
return false;
|
|
52465
52465
|
if (!grouped.has(childRunId)) {
|
|
52466
|
+
if (allowPendingChildren && isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) && !childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId)) {
|
|
52467
|
+
syntheticChildIds.add(childRunId);
|
|
52468
|
+
owners.set(childRunId, draft);
|
|
52469
|
+
continue;
|
|
52470
|
+
}
|
|
52466
52471
|
if (!isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId))
|
|
52467
52472
|
return false;
|
|
52468
52473
|
syntheticChildIds.add(childRunId);
|
|
@@ -52495,6 +52500,10 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
|
52495
52500
|
}
|
|
52496
52501
|
return true;
|
|
52497
52502
|
}
|
|
52503
|
+
function isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) {
|
|
52504
|
+
const boundary = draft.topology?.boundary;
|
|
52505
|
+
return workflowChildFromDraft(draft) === undefined && boundary?.event === "start" && boundary.status === "running" && boundary.child.runId === childRunId && boundary.child.parentRunId === parentRunId && boundary.child.parentStageId === draft.topology?.stageId && boundary.child.rootRunId === rootRunId;
|
|
52506
|
+
}
|
|
52498
52507
|
function isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) {
|
|
52499
52508
|
const child = workflowChildFromDraft(draft);
|
|
52500
52509
|
const boundary = draft.topology?.boundary;
|
|
@@ -56014,6 +56023,20 @@ function resolve_budget(layers) {
|
|
|
56014
56023
|
var DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15;
|
|
56015
56024
|
var WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
|
|
56016
56025
|
|
|
56026
|
+
// dist/builtin/workflows/src/shared/workflow-source.ts
|
|
56027
|
+
var WORKFLOW_SOURCES = new WeakMap;
|
|
56028
|
+
var OWN_MODULE_PATH = normalizeStackPath(import.meta.url);
|
|
56029
|
+
function isWorkflowRuntimeModule(path) {
|
|
56030
|
+
const normalized = normalizeStackPath(path);
|
|
56031
|
+
return normalized === OWN_MODULE_PATH || isWorkflowRuntimeFrame(normalized);
|
|
56032
|
+
}
|
|
56033
|
+
function recordWorkflowSource(definition, path) {
|
|
56034
|
+
WORKFLOW_SOURCES.set(definition, path);
|
|
56035
|
+
}
|
|
56036
|
+
function workflowSource(definition) {
|
|
56037
|
+
return WORKFLOW_SOURCES.get(definition);
|
|
56038
|
+
}
|
|
56039
|
+
|
|
56017
56040
|
// dist/builtin/workflows/src/workflows/identity.ts
|
|
56018
56041
|
function normalizeWorkflowName(name) {
|
|
56019
56042
|
if (!name || typeof name !== "string") {
|
|
@@ -56061,8 +56084,10 @@ function isWorkflowAuthoringImplementationFrame(filePath) {
|
|
|
56061
56084
|
return false;
|
|
56062
56085
|
return normalized.includes("/packages/workflows/") || normalized.includes("/dist/builtin/workflows/") || normalized.includes("/.atomic/agent/extensions/workflows/");
|
|
56063
56086
|
}
|
|
56064
|
-
function
|
|
56065
|
-
const
|
|
56087
|
+
function callerSourcePath(entry) {
|
|
56088
|
+
const capture = new Error;
|
|
56089
|
+
Error.captureStackTrace(capture, entry);
|
|
56090
|
+
const stack = capture.stack;
|
|
56066
56091
|
if (stack === undefined)
|
|
56067
56092
|
return;
|
|
56068
56093
|
for (const line of stack.split(`
|
|
@@ -56072,14 +56097,18 @@ function workflowNameFromCaller() {
|
|
|
56072
56097
|
continue;
|
|
56073
56098
|
if (isWorkflowAuthoringImplementationFrame(filePath))
|
|
56074
56099
|
continue;
|
|
56075
|
-
|
|
56076
|
-
if (base.length > 0)
|
|
56077
|
-
return base;
|
|
56100
|
+
return isWorkflowRuntimeModule(filePath) ? undefined : filePath;
|
|
56078
56101
|
}
|
|
56079
56102
|
return;
|
|
56080
56103
|
}
|
|
56081
|
-
function
|
|
56082
|
-
|
|
56104
|
+
function workflowNameFromSourcePath(filePath) {
|
|
56105
|
+
if (filePath === undefined)
|
|
56106
|
+
return;
|
|
56107
|
+
const base = basename(filePath.replace(/\\/g, "/")).replace(/\.[cm]?[jt]sx?$/, "");
|
|
56108
|
+
return base.length > 0 ? base : undefined;
|
|
56109
|
+
}
|
|
56110
|
+
function resolveWorkflowName(name, sourcePath) {
|
|
56111
|
+
const resolved = name ?? workflowNameFromSourcePath(sourcePath);
|
|
56083
56112
|
if (resolved === undefined) {
|
|
56084
56113
|
throw new TypeError("workflow: name must be provided when caller filename cannot be inferred");
|
|
56085
56114
|
}
|
|
@@ -56115,7 +56144,8 @@ function workflow(spec) {
|
|
|
56115
56144
|
throw new TypeError("workflow: heartbeatIntervalMinutes must be a non-negative finite number");
|
|
56116
56145
|
}
|
|
56117
56146
|
assertWorkflowBudget(spec.budget, "workflow: budget");
|
|
56118
|
-
const
|
|
56147
|
+
const source = callerSourcePath(workflow);
|
|
56148
|
+
const name = resolveWorkflowName(spec.name, source);
|
|
56119
56149
|
const normalizedName = normalizeWorkflowName(name);
|
|
56120
56150
|
requireNonEmptyString(normalizedName, "normalized name");
|
|
56121
56151
|
const frozenInputs = freezeSchemaMap(spec.inputs ?? {});
|
|
@@ -56137,6 +56167,8 @@ function workflow(spec) {
|
|
|
56137
56167
|
run
|
|
56138
56168
|
};
|
|
56139
56169
|
const branded = stampWorkflowDefinition(definition);
|
|
56170
|
+
if (source !== undefined)
|
|
56171
|
+
recordWorkflowSource(branded, source);
|
|
56140
56172
|
return Object.freeze(branded);
|
|
56141
56173
|
}
|
|
56142
56174
|
|
|
@@ -63585,6 +63617,7 @@ function createWorkflowExitManager(input) {
|
|
|
63585
63617
|
...outputSnapshot !== undefined ? { outputSnapshot } : {},
|
|
63586
63618
|
...validationError !== undefined ? { validationError } : {}
|
|
63587
63619
|
}));
|
|
63620
|
+
input.onExitSelected?.(selectedExit);
|
|
63588
63621
|
input.controller.abort(selectedExit);
|
|
63589
63622
|
runWorkflowExitCleanups(reason);
|
|
63590
63623
|
throw selectedExit;
|
|
@@ -64854,6 +64887,402 @@ function deferStageUntilRunRelease(input) {
|
|
|
64854
64887
|
};
|
|
64855
64888
|
}
|
|
64856
64889
|
|
|
64890
|
+
// dist/builtin/workflows/src/engine/run-rejection-boundary.ts
|
|
64891
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
64892
|
+
import { inspect } from "node:util";
|
|
64893
|
+
var EVENT = "unhandledRejection";
|
|
64894
|
+
var BOUNDARY_KEY = Symbol.for("atomic-workflows/run-rejection-boundary@5");
|
|
64895
|
+
var FLAG = "--unhandled-rejections";
|
|
64896
|
+
var MAX_CAUSE_DEPTH2 = 8;
|
|
64897
|
+
var MAX_PRIMITIVES_PER_RUN = 64;
|
|
64898
|
+
var MAX_STOP_STRINGS = 64;
|
|
64899
|
+
var ENDED_RUN_GRACE_MS = 30000;
|
|
64900
|
+
var NATIVE_REPORTING_MODES = new Set(["throw", "warn-with-error-code"]);
|
|
64901
|
+
function boundaryBag() {
|
|
64902
|
+
return globalThis;
|
|
64903
|
+
}
|
|
64904
|
+
function sharedBoundary() {
|
|
64905
|
+
const bag = boundaryBag();
|
|
64906
|
+
const existing = bag[BOUNDARY_KEY];
|
|
64907
|
+
if (existing !== undefined && existing.version === 5)
|
|
64908
|
+
return existing;
|
|
64909
|
+
const created = {
|
|
64910
|
+
version: 5,
|
|
64911
|
+
store: new AsyncLocalStorage3,
|
|
64912
|
+
owners: new WeakMap,
|
|
64913
|
+
promises: new WeakMap,
|
|
64914
|
+
scopes: new Set,
|
|
64915
|
+
runs: new Map,
|
|
64916
|
+
ended: new Map,
|
|
64917
|
+
stops: new Set,
|
|
64918
|
+
listener: undefined
|
|
64919
|
+
};
|
|
64920
|
+
bag[BOUNDARY_KEY] = created;
|
|
64921
|
+
return created;
|
|
64922
|
+
}
|
|
64923
|
+
function isObject(value2) {
|
|
64924
|
+
return typeof value2 === "object" && value2 !== null || typeof value2 === "function";
|
|
64925
|
+
}
|
|
64926
|
+
function isPrimitive(value2) {
|
|
64927
|
+
return !isObject(value2);
|
|
64928
|
+
}
|
|
64929
|
+
function safeField3(value2, key) {
|
|
64930
|
+
try {
|
|
64931
|
+
return value2[key];
|
|
64932
|
+
} catch {
|
|
64933
|
+
return;
|
|
64934
|
+
}
|
|
64935
|
+
}
|
|
64936
|
+
function strongerEffect(left, right) {
|
|
64937
|
+
return left === "fail-run" || right === "fail-run" ? "fail-run" : "ignore";
|
|
64938
|
+
}
|
|
64939
|
+
function addAttribution(into, scope, effect) {
|
|
64940
|
+
into.set(scope, strongerEffect(into.get(scope), effect));
|
|
64941
|
+
}
|
|
64942
|
+
function recordedOwners(boundary, reason) {
|
|
64943
|
+
const owners = new Map;
|
|
64944
|
+
let stopped = false;
|
|
64945
|
+
const seen = new Set;
|
|
64946
|
+
const pending = [{ value: reason, depth: 0 }];
|
|
64947
|
+
while (pending.length > 0) {
|
|
64948
|
+
const { value: value2, depth } = pending.pop();
|
|
64949
|
+
if (depth > MAX_CAUSE_DEPTH2)
|
|
64950
|
+
continue;
|
|
64951
|
+
if (isPrimitive(value2)) {
|
|
64952
|
+
if (depth === 0 || value2 !== undefined && value2 !== null) {
|
|
64953
|
+
for (const scope of boundary.scopes) {
|
|
64954
|
+
const entry = scope.primitives.get(value2);
|
|
64955
|
+
if (entry !== undefined)
|
|
64956
|
+
addAttribution(owners, scope, entry.effect);
|
|
64957
|
+
}
|
|
64958
|
+
if (typeof value2 === "string" && boundary.stops.has(value2))
|
|
64959
|
+
stopped = true;
|
|
64960
|
+
}
|
|
64961
|
+
continue;
|
|
64962
|
+
}
|
|
64963
|
+
if (seen.has(value2))
|
|
64964
|
+
continue;
|
|
64965
|
+
seen.add(value2);
|
|
64966
|
+
for (const [scope, effect] of boundary.owners.get(value2) ?? [])
|
|
64967
|
+
addAttribution(owners, scope, effect);
|
|
64968
|
+
pending.push({ value: safeField3(value2, "cause"), depth: depth + 1 });
|
|
64969
|
+
const errors = safeField3(value2, "errors");
|
|
64970
|
+
if (Array.isArray(errors))
|
|
64971
|
+
for (const entry of errors)
|
|
64972
|
+
pending.push({ value: entry, depth: depth + 1 });
|
|
64973
|
+
}
|
|
64974
|
+
return { owners, stopped };
|
|
64975
|
+
}
|
|
64976
|
+
function pruneEndedSources(boundary) {
|
|
64977
|
+
const now = Date.now();
|
|
64978
|
+
for (const [source, trees] of boundary.ended) {
|
|
64979
|
+
for (const [rootRunId, endedAt] of trees)
|
|
64980
|
+
if (now - endedAt > ENDED_RUN_GRACE_MS)
|
|
64981
|
+
trees.delete(rootRunId);
|
|
64982
|
+
if (trees.size === 0)
|
|
64983
|
+
boundary.ended.delete(source);
|
|
64984
|
+
}
|
|
64985
|
+
}
|
|
64986
|
+
function recordEndedRun(boundary, scope) {
|
|
64987
|
+
if (scope.source === undefined)
|
|
64988
|
+
return;
|
|
64989
|
+
const trees = boundary.ended.get(scope.source) ?? new Map;
|
|
64990
|
+
trees.set(scope.rootRunId, Date.now());
|
|
64991
|
+
boundary.ended.set(scope.source, trees);
|
|
64992
|
+
}
|
|
64993
|
+
function endedInAnotherRunTree(boundary, source, live) {
|
|
64994
|
+
for (const endedRoot of boundary.ended.get(source)?.keys() ?? [])
|
|
64995
|
+
if (endedRoot !== live.rootRunId)
|
|
64996
|
+
return true;
|
|
64997
|
+
return false;
|
|
64998
|
+
}
|
|
64999
|
+
function recognizedSources(boundary) {
|
|
65000
|
+
pruneEndedSources(boundary);
|
|
65001
|
+
const sources = new Set(boundary.ended.keys());
|
|
65002
|
+
for (const scope of boundary.scopes)
|
|
65003
|
+
if (scope.live && scope.source !== undefined)
|
|
65004
|
+
sources.add(scope.source);
|
|
65005
|
+
return sources;
|
|
65006
|
+
}
|
|
65007
|
+
function authoringSource(reason, sources) {
|
|
65008
|
+
if (sources.size === 0 || !isObject(reason))
|
|
65009
|
+
return;
|
|
65010
|
+
const stack = safeField3(reason, "stack");
|
|
65011
|
+
if (typeof stack !== "string")
|
|
65012
|
+
return;
|
|
65013
|
+
for (const line of stack.split(`
|
|
65014
|
+
`)) {
|
|
65015
|
+
if (!line.trimStart().startsWith("at "))
|
|
65016
|
+
continue;
|
|
65017
|
+
const path = parsePromptStackFrame(line)?.normalizedPath;
|
|
65018
|
+
if (path === undefined)
|
|
65019
|
+
continue;
|
|
65020
|
+
if (isWorkflowRuntimeModule(path))
|
|
65021
|
+
return;
|
|
65022
|
+
if (/\/node_modules\//.test(path))
|
|
65023
|
+
continue;
|
|
65024
|
+
if (sources.has(path))
|
|
65025
|
+
return path;
|
|
65026
|
+
}
|
|
65027
|
+
return;
|
|
65028
|
+
}
|
|
65029
|
+
function hasAncestorIn(scope, candidates) {
|
|
65030
|
+
for (let ancestor = scope.parent;ancestor !== undefined; ancestor = ancestor.parent) {
|
|
65031
|
+
if (candidates.has(ancestor))
|
|
65032
|
+
return true;
|
|
65033
|
+
}
|
|
65034
|
+
return false;
|
|
65035
|
+
}
|
|
65036
|
+
function outermostLiveRuns(boundary, source) {
|
|
65037
|
+
const matching = new Set;
|
|
65038
|
+
for (const scope of boundary.scopes)
|
|
65039
|
+
if (scope.live && scope.source === source)
|
|
65040
|
+
matching.add(scope);
|
|
65041
|
+
const outermost = new Set;
|
|
65042
|
+
for (const scope of matching)
|
|
65043
|
+
if (!hasAncestorIn(scope, matching))
|
|
65044
|
+
outermost.add(scope);
|
|
65045
|
+
return outermost;
|
|
65046
|
+
}
|
|
65047
|
+
function runOfSource(boundary, source) {
|
|
65048
|
+
const [only, ...others] = outermostLiveRuns(boundary, source);
|
|
65049
|
+
if (only === undefined)
|
|
65050
|
+
return new Map;
|
|
65051
|
+
if (others.length > 0 || only.sharedSource)
|
|
65052
|
+
return;
|
|
65053
|
+
if (endedInAnotherRunTree(boundary, source, only))
|
|
65054
|
+
return;
|
|
65055
|
+
return new Map([[only, "fail-run"]]);
|
|
65056
|
+
}
|
|
65057
|
+
function markSharedSource(boundary, source) {
|
|
65058
|
+
const runs = outermostLiveRuns(boundary, source);
|
|
65059
|
+
if (runs.size > 1)
|
|
65060
|
+
for (const run of runs)
|
|
65061
|
+
run.sharedSource = true;
|
|
65062
|
+
}
|
|
65063
|
+
function rejectingRun(boundary, recorded, promise, scoped) {
|
|
65064
|
+
const tracked = promise === undefined ? undefined : boundary.promises.get(promise);
|
|
65065
|
+
if (tracked !== undefined && recorded.has(tracked))
|
|
65066
|
+
return tracked;
|
|
65067
|
+
if (scoped !== undefined && recorded.has(scoped))
|
|
65068
|
+
return scoped;
|
|
65069
|
+
return;
|
|
65070
|
+
}
|
|
65071
|
+
function attribute(boundary, reason, promise) {
|
|
65072
|
+
const { owners: recorded, stopped } = recordedOwners(boundary, reason);
|
|
65073
|
+
const scoped = boundary.store.getStore();
|
|
65074
|
+
if (recorded.size > 1) {
|
|
65075
|
+
const rejecting = rejectingRun(boundary, recorded, promise, scoped);
|
|
65076
|
+
if (rejecting !== undefined)
|
|
65077
|
+
return new Map([[rejecting, recorded.get(rejecting) ?? "fail-run"]]);
|
|
65078
|
+
}
|
|
65079
|
+
if (recorded.size > 0)
|
|
65080
|
+
return recorded;
|
|
65081
|
+
if (stopped)
|
|
65082
|
+
return new Map;
|
|
65083
|
+
if (scoped !== undefined && boundary.scopes.has(scoped))
|
|
65084
|
+
return new Map([[scoped, "fail-run"]]);
|
|
65085
|
+
const origin = authoringSource(reason, recognizedSources(boundary));
|
|
65086
|
+
if (origin === undefined)
|
|
65087
|
+
return;
|
|
65088
|
+
if (scoped !== undefined)
|
|
65089
|
+
return new Map([[scoped, "ignore"]]);
|
|
65090
|
+
return runOfSource(boundary, origin);
|
|
65091
|
+
}
|
|
65092
|
+
function unhandledRejectionError(reason) {
|
|
65093
|
+
return Object.assign(new Error("This error originated either by throwing inside of an async function without a catch block, " + `or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "${inspect(reason)}".`), { code: "ERR_UNHANDLED_REJECTION" });
|
|
65094
|
+
}
|
|
65095
|
+
function unhandledRejectionsMode() {
|
|
65096
|
+
const args = [...(process.env.NODE_OPTIONS ?? "").split(/\s+/), ...process.execArgv];
|
|
65097
|
+
let mode = "throw";
|
|
65098
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
65099
|
+
const arg = args[index] ?? "";
|
|
65100
|
+
if (arg.startsWith(`${FLAG}=`))
|
|
65101
|
+
mode = arg.slice(FLAG.length + 1);
|
|
65102
|
+
else if (arg === FLAG && args[index + 1] !== undefined)
|
|
65103
|
+
mode = args[index + 1] ?? mode;
|
|
65104
|
+
}
|
|
65105
|
+
return mode;
|
|
65106
|
+
}
|
|
65107
|
+
function surfaceNatively(boundary, reason) {
|
|
65108
|
+
const listener = boundary.listener;
|
|
65109
|
+
if (listener === undefined || process.listenerCount(EVENT) > 1)
|
|
65110
|
+
return;
|
|
65111
|
+
if (!NATIVE_REPORTING_MODES.has(unhandledRejectionsMode()))
|
|
65112
|
+
return;
|
|
65113
|
+
process.nextTick(() => {
|
|
65114
|
+
process.removeListener(EVENT, listener);
|
|
65115
|
+
Promise.reject(reason);
|
|
65116
|
+
setImmediate(() => {
|
|
65117
|
+
if (!process.listeners(EVENT).includes(listener))
|
|
65118
|
+
process.on(EVENT, listener);
|
|
65119
|
+
});
|
|
65120
|
+
});
|
|
65121
|
+
}
|
|
65122
|
+
function onUnhandledRejection(reason, promise) {
|
|
65123
|
+
const boundary = sharedBoundary();
|
|
65124
|
+
const owners = attribute(boundary, reason, promise);
|
|
65125
|
+
if (owners === undefined) {
|
|
65126
|
+
surfaceNatively(boundary, reason);
|
|
65127
|
+
return;
|
|
65128
|
+
}
|
|
65129
|
+
const error = isObject(reason) ? reason : unhandledRejectionError(reason);
|
|
65130
|
+
for (const [scope, effect] of owners) {
|
|
65131
|
+
if (effect !== "fail-run" || !scope.live)
|
|
65132
|
+
continue;
|
|
65133
|
+
try {
|
|
65134
|
+
scope.fail(error);
|
|
65135
|
+
} catch {}
|
|
65136
|
+
}
|
|
65137
|
+
}
|
|
65138
|
+
function ensureInstalled(boundary) {
|
|
65139
|
+
if (boundary.listener !== undefined)
|
|
65140
|
+
return;
|
|
65141
|
+
boundary.listener = onUnhandledRejection;
|
|
65142
|
+
process.on(EVENT, onUnhandledRejection);
|
|
65143
|
+
}
|
|
65144
|
+
function record(boundary, scope, reason, effect) {
|
|
65145
|
+
if (isPrimitive(reason)) {
|
|
65146
|
+
recordPrimitive(scope, reason, effect);
|
|
65147
|
+
return;
|
|
65148
|
+
}
|
|
65149
|
+
const owners = boundary.owners.get(reason);
|
|
65150
|
+
if (owners === undefined)
|
|
65151
|
+
boundary.owners.set(reason, new Map([[scope, effect]]));
|
|
65152
|
+
else
|
|
65153
|
+
addAttribution(owners, scope, effect);
|
|
65154
|
+
}
|
|
65155
|
+
function recordStop(boundary, reason) {
|
|
65156
|
+
boundary.stops.delete(reason);
|
|
65157
|
+
boundary.stops.add(reason);
|
|
65158
|
+
if (boundary.stops.size <= MAX_STOP_STRINGS)
|
|
65159
|
+
return;
|
|
65160
|
+
const oldest = boundary.stops.values().next();
|
|
65161
|
+
if (!oldest.done)
|
|
65162
|
+
boundary.stops.delete(oldest.value);
|
|
65163
|
+
}
|
|
65164
|
+
function recordPrimitive(scope, reason, effect) {
|
|
65165
|
+
if (!scope.live)
|
|
65166
|
+
return;
|
|
65167
|
+
if (scope.primitives.size >= MAX_PRIMITIVES_PER_RUN && !scope.primitives.has(reason)) {
|
|
65168
|
+
const oldest = scope.primitives.keys().next();
|
|
65169
|
+
if (!oldest.done)
|
|
65170
|
+
scope.primitives.delete(oldest.value);
|
|
65171
|
+
}
|
|
65172
|
+
scope.generation += 1;
|
|
65173
|
+
const generation = scope.generation;
|
|
65174
|
+
scope.primitives.set(reason, { effect: strongerEffect(scope.primitives.get(reason)?.effect, effect), generation });
|
|
65175
|
+
afterPendingRejectionReports().then(() => {
|
|
65176
|
+
if (scope.primitives.get(reason)?.generation === generation)
|
|
65177
|
+
scope.primitives.delete(reason);
|
|
65178
|
+
});
|
|
65179
|
+
}
|
|
65180
|
+
function discardFailure() {}
|
|
65181
|
+
function afterPendingRejectionReports() {
|
|
65182
|
+
return new Promise((resolve) => {
|
|
65183
|
+
const { port1, port2 } = new MessageChannel;
|
|
65184
|
+
port1.onmessage = () => {
|
|
65185
|
+
port1.close();
|
|
65186
|
+
port2.close();
|
|
65187
|
+
resolve();
|
|
65188
|
+
};
|
|
65189
|
+
port2.postMessage(undefined);
|
|
65190
|
+
});
|
|
65191
|
+
}
|
|
65192
|
+
function openRunRejectionScope(options) {
|
|
65193
|
+
const boundary = sharedBoundary();
|
|
65194
|
+
ensureInstalled(boundary);
|
|
65195
|
+
pruneEndedSources(boundary);
|
|
65196
|
+
const parent = options.parentRunId === undefined ? undefined : boundary.runs.get(options.parentRunId);
|
|
65197
|
+
const scope = {
|
|
65198
|
+
runId: options.runId,
|
|
65199
|
+
rootRunId: parent?.rootRunId ?? options.runId,
|
|
65200
|
+
source: options.source === undefined ? undefined : normalizeStackPath(options.source),
|
|
65201
|
+
parent,
|
|
65202
|
+
fail: options.fail,
|
|
65203
|
+
primitives: new Map,
|
|
65204
|
+
generation: 0,
|
|
65205
|
+
live: true,
|
|
65206
|
+
sharedSource: false
|
|
65207
|
+
};
|
|
65208
|
+
boundary.scopes.add(scope);
|
|
65209
|
+
boundary.runs.set(scope.runId, scope);
|
|
65210
|
+
if (scope.source !== undefined)
|
|
65211
|
+
markSharedSource(boundary, scope.source);
|
|
65212
|
+
return {
|
|
65213
|
+
run: (callback) => boundary.store.run(scope, callback),
|
|
65214
|
+
contain: (promise, effect = "fail-run") => {
|
|
65215
|
+
boundary.promises.set(promise, scope);
|
|
65216
|
+
promise.then(undefined, (reason) => record(boundary, scope, reason, effect));
|
|
65217
|
+
return promise;
|
|
65218
|
+
},
|
|
65219
|
+
watch: (promise) => {
|
|
65220
|
+
const watched = promise.then(undefined, (reason) => {
|
|
65221
|
+
record(boundary, scope, reason, "fail-run");
|
|
65222
|
+
throw reason;
|
|
65223
|
+
});
|
|
65224
|
+
boundary.promises.set(watched, scope);
|
|
65225
|
+
return watched;
|
|
65226
|
+
},
|
|
65227
|
+
ignore: (reason) => {
|
|
65228
|
+
if (typeof reason === "string")
|
|
65229
|
+
recordStop(boundary, reason);
|
|
65230
|
+
else
|
|
65231
|
+
record(boundary, scope, reason, "ignore");
|
|
65232
|
+
},
|
|
65233
|
+
settle: afterPendingRejectionReports,
|
|
65234
|
+
close: () => {
|
|
65235
|
+
scope.live = false;
|
|
65236
|
+
scope.fail = discardFailure;
|
|
65237
|
+
recordEndedRun(boundary, scope);
|
|
65238
|
+
afterPendingRejectionReports().then(() => {
|
|
65239
|
+
scope.primitives.clear();
|
|
65240
|
+
scope.parent = undefined;
|
|
65241
|
+
boundary.scopes.delete(scope);
|
|
65242
|
+
if (boundary.runs.get(scope.runId) === scope)
|
|
65243
|
+
boundary.runs.delete(scope.runId);
|
|
65244
|
+
});
|
|
65245
|
+
}
|
|
65246
|
+
};
|
|
65247
|
+
}
|
|
65248
|
+
var WATCHED_STAGE_METHODS = [
|
|
65249
|
+
"prompt",
|
|
65250
|
+
"complete",
|
|
65251
|
+
"sendUserMessage",
|
|
65252
|
+
"steer",
|
|
65253
|
+
"followUp",
|
|
65254
|
+
"setModel",
|
|
65255
|
+
"setThinkingLevel",
|
|
65256
|
+
"cycleModel",
|
|
65257
|
+
"cycleThinkingLevel",
|
|
65258
|
+
"navigateTree",
|
|
65259
|
+
"compact",
|
|
65260
|
+
"abort"
|
|
65261
|
+
];
|
|
65262
|
+
function containStageRejections(stage, scope) {
|
|
65263
|
+
const contained = Object.create(stage);
|
|
65264
|
+
const descriptors = {};
|
|
65265
|
+
for (const name of WATCHED_STAGE_METHODS) {
|
|
65266
|
+
descriptors[name] = {
|
|
65267
|
+
value: (...args) => {
|
|
65268
|
+
const result = Reflect.apply(stage[name], stage, args);
|
|
65269
|
+
return result instanceof Promise ? scope.watch(result) : result;
|
|
65270
|
+
}
|
|
65271
|
+
};
|
|
65272
|
+
}
|
|
65273
|
+
Object.defineProperties(contained, descriptors);
|
|
65274
|
+
return contained;
|
|
65275
|
+
}
|
|
65276
|
+
function containUiRejections(ui, scope) {
|
|
65277
|
+
return {
|
|
65278
|
+
input: (prompt) => scope.watch(ui.input(prompt)),
|
|
65279
|
+
confirm: (message) => scope.watch(ui.confirm(message)),
|
|
65280
|
+
select: (message, options) => scope.watch(ui.select(message, options)),
|
|
65281
|
+
editor: (initial) => scope.watch(ui.editor(initial)),
|
|
65282
|
+
custom: (factory, options) => scope.watch(ui.custom(factory, options))
|
|
65283
|
+
};
|
|
65284
|
+
}
|
|
65285
|
+
|
|
64857
65286
|
// dist/builtin/workflows/src/engine/run-returned-status.ts
|
|
64858
65287
|
function classifyReturnedRunStatus(result, runSnapshot) {
|
|
64859
65288
|
const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
|
|
@@ -70870,13 +71299,13 @@ class EngineRuntime {
|
|
|
70870
71299
|
|
|
70871
71300
|
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
70872
71301
|
import { isStaleExtensionContextError as isStaleExtensionContextError5 } from "@bastani/atomic";
|
|
70873
|
-
var
|
|
71302
|
+
var MAX_CAUSE_DEPTH3 = 8;
|
|
70874
71303
|
function reportsClosedSession(error) {
|
|
70875
71304
|
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError5(error);
|
|
70876
71305
|
}
|
|
70877
71306
|
function isSessionClosedError(error) {
|
|
70878
71307
|
let current = error;
|
|
70879
|
-
for (let depth = 0;depth <
|
|
71308
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH3 && current !== undefined; depth++) {
|
|
70880
71309
|
try {
|
|
70881
71310
|
if (reportsClosedSession(current))
|
|
70882
71311
|
return true;
|
|
@@ -70948,7 +71377,12 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
70948
71377
|
workflowObservationRuntime(activeStore).control(runId, "kill");
|
|
70949
71378
|
ownController.abort(callerSignal?.reason);
|
|
70950
71379
|
};
|
|
70951
|
-
const exit = createWorkflowExitManager({
|
|
71380
|
+
const exit = createWorkflowExitManager({
|
|
71381
|
+
runId,
|
|
71382
|
+
exitScope,
|
|
71383
|
+
controller: ownController,
|
|
71384
|
+
onExitSelected: (signal) => rejectionScope.ignore(signal)
|
|
71385
|
+
});
|
|
70952
71386
|
const sourceBackend = opts.durableBackend;
|
|
70953
71387
|
const backendView = sourceBackend;
|
|
70954
71388
|
const rootBackend = opts.durableRootBackend ?? backendView;
|
|
@@ -71462,6 +71896,22 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71462
71896
|
baseFromPromptNodes: getPromptNodeUi
|
|
71463
71897
|
});
|
|
71464
71898
|
let pausedExit;
|
|
71899
|
+
const authoredIn = workflowSource(def);
|
|
71900
|
+
const rejectionScope = openRunRejectionScope({
|
|
71901
|
+
runId,
|
|
71902
|
+
...opts.parentRun !== undefined ? { parentRunId: opts.parentRun.runId } : {},
|
|
71903
|
+
...authoredIn !== undefined ? { source: authoredIn } : {},
|
|
71904
|
+
fail: (error) => {
|
|
71905
|
+
if (findWorkflowGracefulQuit(error) !== undefined)
|
|
71906
|
+
return;
|
|
71907
|
+
const selected = terminalEvents.selectFailure(error);
|
|
71908
|
+
if (selected.kind === "failure" && !ownController.signal.aborted)
|
|
71909
|
+
ownController.abort(selected.error);
|
|
71910
|
+
}
|
|
71911
|
+
});
|
|
71912
|
+
ownController.signal.addEventListener("abort", () => rejectionScope.ignore(ownController.signal.reason), {
|
|
71913
|
+
once: true
|
|
71914
|
+
});
|
|
71465
71915
|
const ctx = {
|
|
71466
71916
|
inputs: resolvedInputs,
|
|
71467
71917
|
runId,
|
|
@@ -71472,28 +71922,30 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71472
71922
|
if (scheduler.isRunPaused()) {
|
|
71473
71923
|
pausedExit ??= whenRunning(async () => exit.exit(options));
|
|
71474
71924
|
pausedExit.catch(() => {});
|
|
71475
|
-
|
|
71925
|
+
const waiting = new Error("Workflow exit is waiting for explicit resume");
|
|
71926
|
+
rejectionScope.ignore(waiting);
|
|
71927
|
+
throw waiting;
|
|
71476
71928
|
}
|
|
71477
71929
|
return exit.exit(options);
|
|
71478
71930
|
},
|
|
71479
|
-
ui,
|
|
71931
|
+
ui: containUiRejections(ui, rejectionScope),
|
|
71480
71932
|
stage: (name, options) => {
|
|
71481
71933
|
ownController.signal.throwIfAborted();
|
|
71482
71934
|
if (!scheduler.isRunPaused())
|
|
71483
|
-
return durableStage(name, options);
|
|
71935
|
+
return containStageRejections(durableStage(name, options), rejectionScope);
|
|
71484
71936
|
const replayKey = stageReplayKeyGenerator(name);
|
|
71485
|
-
return deferStageUntilRunRelease({
|
|
71937
|
+
return containStageRejections(deferStageUntilRunRelease({
|
|
71486
71938
|
name,
|
|
71487
71939
|
create: () => durableStage(name, options, replayKey),
|
|
71488
71940
|
isPaused: scheduler.isRunPaused,
|
|
71489
71941
|
waitForRelease: waitForRunRelease,
|
|
71490
71942
|
signal: ownController.signal
|
|
71491
|
-
});
|
|
71943
|
+
}), rejectionScope);
|
|
71492
71944
|
},
|
|
71493
|
-
task: gatedTask,
|
|
71494
|
-
chain: (...args) => whenRunning(() => chain(...args)),
|
|
71495
|
-
parallel: (...args) => whenRunning(() => parallel(...args)),
|
|
71496
|
-
workflow: (...args) => whenRunning(() => {
|
|
71945
|
+
task: (...args) => rejectionScope.watch(gatedTask(...args)),
|
|
71946
|
+
chain: (...args) => rejectionScope.watch(whenRunning(() => chain(...args))),
|
|
71947
|
+
parallel: (...args) => rejectionScope.watch(whenRunning(() => parallel(...args))),
|
|
71948
|
+
workflow: (...args) => rejectionScope.watch(whenRunning(() => {
|
|
71497
71949
|
const pending = durableWorkflow(...args);
|
|
71498
71950
|
pendingChildWorkflows.add(pending);
|
|
71499
71951
|
const settled = () => {
|
|
@@ -71501,13 +71953,11 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71501
71953
|
};
|
|
71502
71954
|
pending.then(settled, settled);
|
|
71503
71955
|
return pending;
|
|
71504
|
-
}),
|
|
71956
|
+
})),
|
|
71505
71957
|
tool: (...args) => {
|
|
71506
71958
|
if (admittedTools.closed)
|
|
71507
|
-
return tool(...args);
|
|
71508
|
-
|
|
71509
|
-
pending.catch(() => {});
|
|
71510
|
-
return pending;
|
|
71959
|
+
return rejectionScope.contain(tool(...args), "ignore");
|
|
71960
|
+
return rejectionScope.contain(whenRunning(() => tool(...args)));
|
|
71511
71961
|
},
|
|
71512
71962
|
...opts.models !== undefined ? { models: opts.models } : {}
|
|
71513
71963
|
};
|
|
@@ -71659,7 +72109,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71659
72109
|
while (scheduler.isRunPaused())
|
|
71660
72110
|
await waitForRunRelease();
|
|
71661
72111
|
ownController.signal.throwIfAborted();
|
|
71662
|
-
const rawResult = await raceAbort(runWorkflowDefinitionCallback(def.name, runId, () => def.run(ctx)), ownController.signal);
|
|
72112
|
+
const rawResult = await raceAbort(runWorkflowDefinitionCallback(def.name, runId, () => rejectionScope.run(() => def.run(ctx))), ownController.signal);
|
|
71663
72113
|
await drainCachedStagePersistence();
|
|
71664
72114
|
while (scheduler.isRunPaused())
|
|
71665
72115
|
await waitForRunRelease();
|
|
@@ -71669,6 +72119,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71669
72119
|
if (pausedExit !== undefined)
|
|
71670
72120
|
await pausedExit;
|
|
71671
72121
|
budget.rethrowIfSystemOwnedStop(runSnapshot.stages.at(-1)?.name ?? startupFrontierStage);
|
|
72122
|
+
await rejectionScope.settle();
|
|
71672
72123
|
const normalTerminalEvent = terminalEvents.winner();
|
|
71673
72124
|
if (normalTerminalEvent?.kind === "cancellation") {
|
|
71674
72125
|
const gracefulQuit = findWorkflowGracefulQuit(normalTerminalEvent.reason);
|
|
@@ -71738,6 +72189,9 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71738
72189
|
}
|
|
71739
72190
|
if (ownerClosing && err instanceof Error && isSessionClosedError(err))
|
|
71740
72191
|
return await suspendForClosedSession(err);
|
|
72192
|
+
if (selectedTerminalEvent.kind === "failure" && pendingChildWorkflows.size > 0 && !ownController.signal.aborted) {
|
|
72193
|
+
ownController.abort(err);
|
|
72194
|
+
}
|
|
71741
72195
|
await admittedTools.closeAndDrain();
|
|
71742
72196
|
if (ownController.signal.aborted)
|
|
71743
72197
|
await Promise.allSettled([...pendingChildWorkflows]);
|
|
@@ -71812,6 +72266,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71812
72266
|
});
|
|
71813
72267
|
return failed;
|
|
71814
72268
|
} finally {
|
|
72269
|
+
rejectionScope.close();
|
|
71815
72270
|
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
71816
72271
|
workflowObservationRuntime(activeStore).finishRun(runId);
|
|
71817
72272
|
runtimeSettled.resolve();
|
|
@@ -72926,11 +73381,17 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
72926
73381
|
retainReachableRunGroups(grouped, rootRunId);
|
|
72927
73382
|
if (policy.failOnUnreachable && grouped.size !== groupedCount)
|
|
72928
73383
|
return [];
|
|
72929
|
-
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
|
|
73384
|
+
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints, policy.retainActive))
|
|
72930
73385
|
return [];
|
|
72931
73386
|
const syntheticChildren = [];
|
|
73387
|
+
const pendingChildren = [];
|
|
72932
73388
|
for (const [parentRunId, runDrafts] of grouped) {
|
|
72933
73389
|
for (const draft of runDrafts) {
|
|
73390
|
+
const pendingChildRunId = childRunIdFromDraft(draft);
|
|
73391
|
+
if (policy.retainActive && pendingChildRunId !== undefined && !grouped.has(pendingChildRunId) && isPendingChildBoundary(draft, parentRunId, pendingChildRunId, rootRunId)) {
|
|
73392
|
+
pendingChildren.push({ parentRunId, owner: draft });
|
|
73393
|
+
continue;
|
|
73394
|
+
}
|
|
72934
73395
|
const child = workflowChildFromDraft(draft);
|
|
72935
73396
|
if (child?.exited !== true || grouped.has(child.runId))
|
|
72936
73397
|
continue;
|
|
@@ -73039,6 +73500,28 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
73039
73500
|
resumable: false
|
|
73040
73501
|
});
|
|
73041
73502
|
}
|
|
73503
|
+
for (const { parentRunId, owner } of pendingChildren) {
|
|
73504
|
+
if (!emittedRunIds.has(parentRunId))
|
|
73505
|
+
return [];
|
|
73506
|
+
const topology = owner.topology;
|
|
73507
|
+
const boundary = topology.boundary;
|
|
73508
|
+
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
73509
|
+
if (parentStageId === undefined)
|
|
73510
|
+
return [];
|
|
73511
|
+
runs.push({
|
|
73512
|
+
id: boundary.child.runId,
|
|
73513
|
+
name: boundary.child.runName,
|
|
73514
|
+
inputs: {},
|
|
73515
|
+
status: "running",
|
|
73516
|
+
stages: [],
|
|
73517
|
+
toolNodes: [],
|
|
73518
|
+
startedAt: owner.startedAt ?? owner.firstCompletedAt,
|
|
73519
|
+
parentRunId,
|
|
73520
|
+
parentStageId,
|
|
73521
|
+
rootRunId: boundary.child.rootRunId,
|
|
73522
|
+
resumable: false
|
|
73523
|
+
});
|
|
73524
|
+
}
|
|
73042
73525
|
return runs;
|
|
73043
73526
|
}
|
|
73044
73527
|
function stageSnapshotFromDraft(draft, id, parentIds) {
|