@bastani/atomic 0.9.19-alpha.5 → 0.9.19-alpha.7
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 +32 -0
- package/README.md +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/broker/client.ts +19 -1
- package/dist/builtin/intercom/index.bundle.mjs +8 -1
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/README.md +3 -1
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +7 -7
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +3 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +2 -1
- package/dist/builtin/web-access/CHANGELOG.md +13 -0
- package/dist/builtin/web-access/README.md +31 -24
- package/dist/builtin/web-access/index.bundle.mjs +16121 -80
- package/dist/builtin/web-access/package.json +2 -1
- package/dist/builtin/workflows/CHANGELOG.md +15 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
- package/dist/builtin/workflows/builtin/{chunk-vhmnzdj9.js → chunk-1jth021m.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-p8jjwfg6.js → chunk-2377r57g.js} +4 -2
- package/dist/builtin/workflows/builtin/{chunk-hbnwv56f.js → chunk-31j2gs7h.js} +2 -2
- package/dist/builtin/workflows/builtin/{chunk-n8zysf1t.js → chunk-ngkqkzej.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-1nbq96fh.js → chunk-nkrafh9s.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-1kx4aggw.js → chunk-wf741bv3.js} +2 -2
- package/dist/builtin/workflows/builtin/{chunk-t6x2d78s.js → chunk-z29qbehr.js} +1 -1
- package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
- package/dist/builtin/workflows/builtin/goal.js +3 -3
- package/dist/builtin/workflows/builtin/index.js +7 -7
- package/dist/builtin/workflows/builtin/ralph.js +3 -3
- package/dist/builtin/workflows/builtin/tournament.js +2 -2
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +339 -31
- package/dist/builtin/workflows/src/index.js +67 -19
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -0
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +10 -0
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +3 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +91 -12
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-coordinator.d.ts +255 -0
- package/dist/core/tools/file-mutation-coordinator.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-coordinator.js +300 -0
- package/dist/core/tools/file-mutation-coordinator.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +14 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +15 -3
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/hashline.d.ts +9 -0
- package/dist/core/tools/hashline.d.ts.map +1 -1
- package/dist/core/tools/hashline.js +12 -1
- package/dist/core/tools/hashline.js.map +1 -1
- package/dist/core/tools/index.d.ts +9 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +67 -12
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/non-minting-snapshot-store.d.ts +49 -0
- package/dist/core/tools/non-minting-snapshot-store.d.ts.map +1 -0
- package/dist/core/tools/non-minting-snapshot-store.js +64 -0
- package/dist/core/tools/non-minting-snapshot-store.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +2 -2
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +2 -5
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/read-document-extract.js.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts +30 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +97 -8
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/task-live-transcript.d.ts +1 -1
- package/dist/modes/interactive/components/task-live-transcript.d.ts.map +1 -1
- package/dist/modes/interactive/components/task-live-transcript.js +19 -11
- package/dist/modes/interactive/components/task-live-transcript.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +3 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +28 -4
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +3 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive-engine/activity-watchdog.d.ts +2 -2
- package/dist/modes/interactive-engine/activity-watchdog.d.ts.map +1 -1
- package/dist/modes/interactive-engine/activity-watchdog.js.map +1 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.d.ts +3 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.js +11 -0
- package/dist/modes/interactive-engine/engine-diagnostic-view.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +2 -1
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/rpc/rpc-client-process.d.ts +2 -0
- package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-process.js +23 -1
- package/dist/modes/rpc/rpc-client-process.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +20 -3
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/utils/markit.d.ts +2 -0
- package/dist/utils/markit.d.ts.map +1 -1
- package/dist/utils/markit.js +65 -5
- package/dist/utils/markit.js.map +1 -1
- package/docs/background-tasks.md +15 -11
- package/docs/build.md +51 -0
- package/docs/changelog.mdx +8 -8
- package/docs/compaction/reference.md +267 -0
- package/docs/compaction.md +36 -219
- package/docs/computer-use.md +35 -0
- package/docs/containerization.md +9 -5
- package/docs/custom-provider/api-reference.md +145 -0
- package/docs/custom-provider/oauth.md +131 -0
- package/docs/custom-provider/override.md +34 -0
- package/docs/custom-provider/registration.md +163 -0
- package/docs/custom-provider/streaming.md +214 -0
- package/docs/custom-provider.md +43 -607
- package/docs/development.md +87 -0
- package/docs/docs.json +199 -76
- package/docs/environment-variables.md +1 -1
- package/docs/extensions/api-reference.md +1001 -0
- package/docs/extensions/authoring.md +676 -0
- package/docs/extensions/events.md +793 -0
- package/docs/extensions/examples.md +94 -0
- package/docs/extensions/ui.md +470 -0
- package/docs/extensions.md +270 -2768
- package/docs/getting-started/authentication.md +55 -0
- package/docs/getting-started/first-session.md +172 -0
- package/docs/getting-started/installation.md +154 -0
- package/docs/getting-started/project-instructions.md +43 -0
- package/docs/guides/configuration.md +65 -0
- package/docs/guides/intercom.md +24 -0
- package/docs/guides/non-interactive.md +33 -0
- package/docs/guides/subagents.md +24 -0
- package/docs/guides/workflows.md +27 -0
- package/docs/guides.md +41 -0
- package/docs/index.md +13 -45
- package/docs/intercom/operations.md +178 -0
- package/docs/intercom/reference.md +146 -0
- package/docs/intercom.md +54 -259
- package/docs/json.md +17 -0
- package/docs/llama-cpp.md +5 -0
- package/docs/models/artificial-analysis-index.md +89 -0
- package/docs/models/evals.md +2 -2
- package/docs/models/model-selection.md +3 -3
- package/docs/models/pareto-efficiency.md +2 -2
- package/docs/models/reference.md +601 -0
- package/docs/models.md +45 -550
- package/docs/packages/authoring.md +88 -0
- package/docs/packages/reference.md +43 -0
- package/docs/packages.md +28 -107
- package/docs/programmatic.md +29 -0
- package/docs/prompt-templates.md +11 -0
- package/docs/providers/reference.md +23 -0
- package/docs/providers.md +10 -15
- package/docs/quickstart.md +44 -238
- package/docs/reference/cli.md +252 -0
- package/docs/reference.md +52 -0
- package/docs/rpc/examples.md +64 -0
- package/docs/rpc/extension-ui.md +198 -0
- package/docs/rpc/protocol.md +1341 -0
- package/docs/rpc.md +109 -1346
- package/docs/sdk/reference.md +1090 -0
- package/docs/sdk.md +56 -1002
- package/docs/session-format.md +2 -0
- package/docs/sessions.md +6 -10
- package/docs/settings.md +6 -45
- package/docs/skills/authoring.md +95 -0
- package/docs/skills/reference.md +60 -0
- package/docs/skills.md +20 -122
- package/docs/subagents/authoring.md +37 -0
- package/docs/subagents/reference.md +60 -0
- package/docs/subagents.md +42 -96
- package/docs/terminal-setup.md +1 -1
- package/docs/themes/reference.md +176 -0
- package/docs/themes.md +21 -135
- package/docs/tmux.md +5 -0
- package/docs/tools/edit.md +5 -0
- package/docs/tools.md +31 -0
- package/docs/tui/reference.md +343 -0
- package/docs/tui.md +23 -286
- package/docs/usage.md +26 -209
- package/docs/web-access.md +40 -0
- package/docs/windows.md +2 -1
- package/docs/workflows/api-reference.md +11 -4
- package/docs/workflows/authoring.md +4 -2
- package/docs/workflows/builtins.md +2 -2
- package/docs/workflows/operations.md +11 -7
- package/docs/workflows/reliable-design.md +21 -3
- package/docs/workflows/verification.md +8 -0
- package/examples/extensions/gondolin/index.ts +116 -148
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/ssh.ts +56 -34
- package/npm-shrinkwrap.json +33 -33
- package/package.json +4 -4
|
@@ -76420,6 +76420,7 @@ class StageUiBroker {
|
|
|
76420
76420
|
};
|
|
76421
76421
|
}
|
|
76422
76422
|
requestCustomUi(runId, stageId, factory, options, signal) {
|
|
76423
|
+
signal = options?.signal ? signal ? AbortSignal.any([signal, options.signal]) : options.signal : signal;
|
|
76423
76424
|
if (signal?.aborted) {
|
|
76424
76425
|
return Promise.reject(signal.reason ?? new Error("atomic-workflows: stage UI request aborted"));
|
|
76425
76426
|
}
|
|
@@ -82123,6 +82124,108 @@ function collectDefinitionName(tokens, localValues, workflowNames) {
|
|
|
82123
82124
|
}
|
|
82124
82125
|
return;
|
|
82125
82126
|
}
|
|
82127
|
+
function discoveryField(object) {
|
|
82128
|
+
if (object?.[0]?.value !== "{" || object.at(-1)?.value !== "}")
|
|
82129
|
+
return;
|
|
82130
|
+
let value2;
|
|
82131
|
+
for (const field of arrayElements(object)) {
|
|
82132
|
+
let key = field;
|
|
82133
|
+
while (["get", "set", "async", "*"].includes(key[0]?.value ?? ""))
|
|
82134
|
+
key = key.slice(1);
|
|
82135
|
+
if (key[0]?.value === "[" || key !== field && key[0]?.value === "possibleStageNames")
|
|
82136
|
+
return;
|
|
82137
|
+
if (field[0]?.value === ".") {
|
|
82138
|
+
if (value2 !== undefined)
|
|
82139
|
+
return;
|
|
82140
|
+
continue;
|
|
82141
|
+
}
|
|
82142
|
+
if (field[0]?.value !== "possibleStageNames")
|
|
82143
|
+
continue;
|
|
82144
|
+
if (value2 !== undefined || field[1]?.value !== ":")
|
|
82145
|
+
return;
|
|
82146
|
+
value2 = field.slice(2);
|
|
82147
|
+
}
|
|
82148
|
+
return value2;
|
|
82149
|
+
}
|
|
82150
|
+
function literalDiscoveryNames(value2) {
|
|
82151
|
+
if (value2?.[0]?.value !== "[" || value2.at(-1)?.value !== "]")
|
|
82152
|
+
return;
|
|
82153
|
+
const names = [];
|
|
82154
|
+
for (const element of arrayElements(value2)) {
|
|
82155
|
+
if (element.length !== 1 || element[0]?.kind !== "string")
|
|
82156
|
+
return;
|
|
82157
|
+
names.push(element[0].value);
|
|
82158
|
+
}
|
|
82159
|
+
return names.length > 0 ? names : undefined;
|
|
82160
|
+
}
|
|
82161
|
+
function discoveryHelpers(tokens) {
|
|
82162
|
+
const helpers = [];
|
|
82163
|
+
for (let index = 0;index < tokens.length; index += 1) {
|
|
82164
|
+
if (tokens[index]?.value !== "function" || tokens[index + 1]?.kind !== "ident")
|
|
82165
|
+
continue;
|
|
82166
|
+
let open = index + 2;
|
|
82167
|
+
if (tokens[open]?.value === "<")
|
|
82168
|
+
open = (matchBracket(tokens, open, "<", ">") ?? tokens.length) + 1;
|
|
82169
|
+
if (tokens[open]?.value !== "(")
|
|
82170
|
+
continue;
|
|
82171
|
+
const close = matchBracket(tokens, open, "(", ")");
|
|
82172
|
+
if (close === undefined)
|
|
82173
|
+
continue;
|
|
82174
|
+
let bodyOpen = close + 1;
|
|
82175
|
+
while (bodyOpen < tokens.length && tokens[bodyOpen]?.value !== "{")
|
|
82176
|
+
bodyOpen += 1;
|
|
82177
|
+
const bodyClose = matchBracket(tokens, bodyOpen, "{", "}");
|
|
82178
|
+
if (bodyClose === undefined)
|
|
82179
|
+
continue;
|
|
82180
|
+
const preceding = tokens[index - (tokens[index - 1]?.value === "async" ? 2 : 1)]?.value;
|
|
82181
|
+
helpers.push({
|
|
82182
|
+
name: tokens[index + 1].value,
|
|
82183
|
+
nameIndex: index + 1,
|
|
82184
|
+
params: splitTopLevelArguments({ method: "parallel", argsOpen: open }, tokens),
|
|
82185
|
+
bodyOpen,
|
|
82186
|
+
bodyClose,
|
|
82187
|
+
declaration: preceding === undefined || ["export", ";", "{", "}"].includes(preceding)
|
|
82188
|
+
});
|
|
82189
|
+
}
|
|
82190
|
+
return helpers;
|
|
82191
|
+
}
|
|
82192
|
+
function hasDiscoveryDestructuringWrite(tokens, parameter) {
|
|
82193
|
+
for (let index = 0;index < tokens.length; index += 1) {
|
|
82194
|
+
const open = tokens[index]?.value;
|
|
82195
|
+
if (open !== "[" && open !== "{")
|
|
82196
|
+
continue;
|
|
82197
|
+
const close = matchBracket(tokens, index, open, open === "[" ? "]" : "}");
|
|
82198
|
+
if (close === undefined || !["=", "of", "in"].includes(tokens[close + 1]?.value ?? ""))
|
|
82199
|
+
continue;
|
|
82200
|
+
if (tokens.slice(index + 1, close).some((token) => token.kind === "ident" && token.value === parameter))
|
|
82201
|
+
return true;
|
|
82202
|
+
}
|
|
82203
|
+
return false;
|
|
82204
|
+
}
|
|
82205
|
+
function discoveryCalls(tokens, name, declaration) {
|
|
82206
|
+
const calls = [];
|
|
82207
|
+
for (let index = 0;index < tokens.length; index += 1) {
|
|
82208
|
+
if (tokens[index]?.value === "import") {
|
|
82209
|
+
while (index < tokens.length && tokens[index]?.kind !== "string")
|
|
82210
|
+
index += 1;
|
|
82211
|
+
continue;
|
|
82212
|
+
}
|
|
82213
|
+
if (tokens[index]?.value === "export" && tokens[index + 1]?.value === "{") {
|
|
82214
|
+
const close = matchBracket(tokens, index + 1, "{", "}") ?? tokens.length;
|
|
82215
|
+
const exported = tokens.slice(index + 2, close);
|
|
82216
|
+
if (exported.some((token, offset) => token.value === name && (declaration === undefined || exported[offset + 1]?.value === "as")))
|
|
82217
|
+
return;
|
|
82218
|
+
index = close;
|
|
82219
|
+
continue;
|
|
82220
|
+
}
|
|
82221
|
+
if (tokens[index]?.kind !== "ident" || tokens[index]?.value !== name || index === declaration)
|
|
82222
|
+
continue;
|
|
82223
|
+
if (tokens[index + 1]?.value !== "(" || [".", "?.", "function"].includes(tokens[index - 1]?.value ?? ""))
|
|
82224
|
+
return;
|
|
82225
|
+
calls.push(index + 1);
|
|
82226
|
+
}
|
|
82227
|
+
return calls;
|
|
82228
|
+
}
|
|
82126
82229
|
|
|
82127
82230
|
class PossibleStagesScanner {
|
|
82128
82231
|
stages = new Set;
|
|
@@ -82131,6 +82234,7 @@ class PossibleStagesScanner {
|
|
|
82131
82234
|
maxDepth;
|
|
82132
82235
|
units = new Map;
|
|
82133
82236
|
aliasPool = new Set;
|
|
82237
|
+
closure = [];
|
|
82134
82238
|
constructor(maxDepth) {
|
|
82135
82239
|
this.maxDepth = maxDepth;
|
|
82136
82240
|
}
|
|
@@ -82166,11 +82270,17 @@ class PossibleStagesScanner {
|
|
|
82166
82270
|
this.aliasPool.add(alias);
|
|
82167
82271
|
}
|
|
82168
82272
|
}
|
|
82169
|
-
|
|
82170
|
-
|
|
82171
|
-
|
|
82172
|
-
|
|
82173
|
-
|
|
82273
|
+
const previousClosure = this.closure;
|
|
82274
|
+
this.closure = ordered;
|
|
82275
|
+
try {
|
|
82276
|
+
for (const path of ordered) {
|
|
82277
|
+
const unit = this.units.get(path);
|
|
82278
|
+
if (unit === undefined)
|
|
82279
|
+
continue;
|
|
82280
|
+
this.scanUnit(unit, path, boundaryPrefix, depth, ancestorStack);
|
|
82281
|
+
}
|
|
82282
|
+
} finally {
|
|
82283
|
+
this.closure = previousClosure;
|
|
82174
82284
|
}
|
|
82175
82285
|
}
|
|
82176
82286
|
unitFor(path) {
|
|
@@ -82284,7 +82394,127 @@ class PossibleStagesScanner {
|
|
|
82284
82394
|
}
|
|
82285
82395
|
return resolveRelativeSpecifier(specifier, importingFile);
|
|
82286
82396
|
}
|
|
82397
|
+
hasDataOnlyDiscoveryOptions(argument) {
|
|
82398
|
+
if (argument?.[0]?.value !== "{" || argument.at(-1)?.value !== "}")
|
|
82399
|
+
return false;
|
|
82400
|
+
return arrayElements(argument).every((field) => (field[0]?.kind === "ident" || field[0]?.kind === "string") && field[0].value !== "__proto__" && field[1]?.value === ":");
|
|
82401
|
+
}
|
|
82402
|
+
discoveryNames(call, unit, path) {
|
|
82403
|
+
if (call.method !== "parallel")
|
|
82404
|
+
return;
|
|
82405
|
+
const value2 = discoveryField(splitTopLevelArguments(call, unit.tokens)[1]);
|
|
82406
|
+
const literal = literalDiscoveryNames(value2);
|
|
82407
|
+
if (literal !== undefined)
|
|
82408
|
+
return literal;
|
|
82409
|
+
if (value2?.length !== 3 || value2[0]?.kind !== "ident" || value2[1]?.value !== "." || value2[2]?.value !== "possibleStageNames")
|
|
82410
|
+
return;
|
|
82411
|
+
const owner = discoveryHelpers(unit.tokens).filter((helper) => helper.bodyOpen < call.argsOpen && helper.bodyClose > call.argsOpen).at(-1);
|
|
82412
|
+
if (owner === undefined || !owner.declaration)
|
|
82413
|
+
return;
|
|
82414
|
+
const parameter = owner.params.findIndex((param) => param[0]?.value === value2[0]?.value);
|
|
82415
|
+
if (parameter < 0)
|
|
82416
|
+
return;
|
|
82417
|
+
for (const param of owner.params) {
|
|
82418
|
+
if (param[0]?.kind !== "ident")
|
|
82419
|
+
return;
|
|
82420
|
+
const assignment = param.findIndex((token) => token.value === "=");
|
|
82421
|
+
if (assignment < 0)
|
|
82422
|
+
continue;
|
|
82423
|
+
const initial = param.slice(assignment + 1);
|
|
82424
|
+
const emptyObject = initial.length === 2 && initial[0]?.value === "{" && initial[1]?.value === "}";
|
|
82425
|
+
const scalar = initial.length === 1 && (initial[0]?.kind === "string" || ["true", "false", "null", "undefined"].includes(initial[0]?.value ?? ""));
|
|
82426
|
+
if (!emptyObject && !scalar)
|
|
82427
|
+
return;
|
|
82428
|
+
}
|
|
82429
|
+
const body = unit.tokens.slice(owner.bodyOpen, owner.bodyClose);
|
|
82430
|
+
if (body.some((token) => token.kind === "ident" && token.value === "arguments"))
|
|
82431
|
+
return;
|
|
82432
|
+
if (hasDiscoveryDestructuringWrite(body, value2[0].value))
|
|
82433
|
+
return;
|
|
82434
|
+
const forwarded = new Set;
|
|
82435
|
+
const spreadOptions = new Set;
|
|
82436
|
+
for (let index = 0;index < body.length; index += 1) {
|
|
82437
|
+
const parallel = matchCtxCall(body, index, this.aliasPool);
|
|
82438
|
+
if (parallel?.method !== "parallel")
|
|
82439
|
+
continue;
|
|
82440
|
+
const parallelOptions = splitTopLevelArguments(parallel, body)[1];
|
|
82441
|
+
const field = discoveryField(parallelOptions);
|
|
82442
|
+
if (parallelOptions?.[0]?.value === "{") {
|
|
82443
|
+
for (const entry of arrayElements(parallelOptions)) {
|
|
82444
|
+
if (entry.length === 4 && entry.slice(0, 3).every((token) => token.value === "."))
|
|
82445
|
+
spreadOptions.add(entry[3]);
|
|
82446
|
+
}
|
|
82447
|
+
}
|
|
82448
|
+
if (field?.length === 3 && field[0]?.value === value2[0].value && field[1]?.value === "." && field[2]?.value === "possibleStageNames")
|
|
82449
|
+
forwarded.add(field[0]);
|
|
82450
|
+
}
|
|
82451
|
+
for (let index = 0;index < body.length; index += 1) {
|
|
82452
|
+
if (body[index]?.value !== value2[0]?.value)
|
|
82453
|
+
continue;
|
|
82454
|
+
if (body[index + 2]?.value === "possibleStageNames" && !forwarded.has(body[index]))
|
|
82455
|
+
return;
|
|
82456
|
+
const destructured = body[index - 2]?.value === "}" && body[index - 1]?.value === "=" && body[index + 1]?.value === ";";
|
|
82457
|
+
if (destructured) {
|
|
82458
|
+
let matched = false;
|
|
82459
|
+
for (let open = 0;open < index - 2; open += 1) {
|
|
82460
|
+
if (body[open]?.value !== "{" || matchBracket(body, open, "{", "}") !== index - 2)
|
|
82461
|
+
continue;
|
|
82462
|
+
if (body[open - 1]?.value !== "const")
|
|
82463
|
+
return;
|
|
82464
|
+
matched = true;
|
|
82465
|
+
for (const entry of arrayElements(body.slice(open, index - 1))) {
|
|
82466
|
+
if (entry.length === 1 && entry[0]?.kind === "ident" && entry[0].value !== "possibleStageNames")
|
|
82467
|
+
continue;
|
|
82468
|
+
if (entry.length !== 4 || !entry.slice(0, 3).every((token) => token.value === ".") || entry[3]?.kind !== "ident")
|
|
82469
|
+
return;
|
|
82470
|
+
const rest = entry[3];
|
|
82471
|
+
for (let use = 0;use < body.length; use += 1) {
|
|
82472
|
+
const token = body[use];
|
|
82473
|
+
if (token?.kind !== "ident" || token.value !== rest.value || token === rest)
|
|
82474
|
+
continue;
|
|
82475
|
+
if (spreadOptions.has(token))
|
|
82476
|
+
continue;
|
|
82477
|
+
if (body[use - 3]?.value === "const" && body[use - 2]?.kind === "ident" && body[use - 1]?.value === "=" && body[use + 1]?.value === "." && body[use + 2]?.value === "concurrency" && body[use + 3]?.value === ";")
|
|
82478
|
+
continue;
|
|
82479
|
+
return;
|
|
82480
|
+
}
|
|
82481
|
+
}
|
|
82482
|
+
}
|
|
82483
|
+
if (!matched)
|
|
82484
|
+
return;
|
|
82485
|
+
}
|
|
82486
|
+
if (!destructured && !forwarded.has(body[index]))
|
|
82487
|
+
return;
|
|
82488
|
+
}
|
|
82489
|
+
const names = [];
|
|
82490
|
+
for (const callerPath of this.closure) {
|
|
82491
|
+
const caller = this.units.get(callerPath);
|
|
82492
|
+
if (caller === undefined)
|
|
82493
|
+
continue;
|
|
82494
|
+
if ([...caller.imports.values()].some((binding) => binding.importedName === undefined && resolveRelativeSpecifier(binding.specifier, callerPath) === path))
|
|
82495
|
+
return;
|
|
82496
|
+
const references = callerPath === path ? [owner.name] : [...caller.imports].filter(([, binding]) => binding.importedName === owner.name && resolveRelativeSpecifier(binding.specifier, callerPath) === path).map(([local]) => local);
|
|
82497
|
+
for (const reference of references) {
|
|
82498
|
+
const calls = discoveryCalls(caller.tokens, reference, callerPath === path ? owner.nameIndex : undefined);
|
|
82499
|
+
if (calls === undefined)
|
|
82500
|
+
return;
|
|
82501
|
+
for (const argsOpen of calls) {
|
|
82502
|
+
const argument = splitTopLevelArguments({ method: "parallel", argsOpen }, caller.tokens)[parameter];
|
|
82503
|
+
if (!this.hasDataOnlyDiscoveryOptions(argument))
|
|
82504
|
+
return;
|
|
82505
|
+
const declared = literalDiscoveryNames(discoveryField(argument));
|
|
82506
|
+
if (declared === undefined)
|
|
82507
|
+
return;
|
|
82508
|
+
names.push(...declared);
|
|
82509
|
+
}
|
|
82510
|
+
}
|
|
82511
|
+
}
|
|
82512
|
+
return names.length > 0 || this.closure[0] !== path ? names : undefined;
|
|
82513
|
+
}
|
|
82287
82514
|
stepNamesForStepsCall(call, unit, path) {
|
|
82515
|
+
const declared = this.discoveryNames(call, unit, path);
|
|
82516
|
+
if (declared !== undefined)
|
|
82517
|
+
return declared;
|
|
82288
82518
|
const first = firstArgumentTokens(call, unit.tokens);
|
|
82289
82519
|
if (first === undefined || first.length === 0)
|
|
82290
82520
|
return [];
|
|
@@ -90858,7 +91088,8 @@ async function warm_first_fan_out(ctx, steps, prefixKeyOf, options = {}) {
|
|
|
90858
91088
|
const warmResults = await ctx.parallel(warmSteps, {
|
|
90859
91089
|
...parallelOptions,
|
|
90860
91090
|
concurrency: boundedConcurrency(warmSteps.length, warmConcurrency ?? DEFAULT_WARM_CONCURRENCY, inheritedConcurrency),
|
|
90861
|
-
failFast: false
|
|
91091
|
+
failFast: false,
|
|
91092
|
+
possibleStageNames: options.possibleStageNames
|
|
90862
91093
|
});
|
|
90863
91094
|
for (const [resultIndex, result] of warmResults.entries()) {
|
|
90864
91095
|
const originalIndex = warmIndices[resultIndex];
|
|
@@ -90873,7 +91104,8 @@ async function warm_first_fan_out(ctx, steps, prefixKeyOf, options = {}) {
|
|
|
90873
91104
|
const restSteps = restIndices.map((index) => steps[index]);
|
|
90874
91105
|
const restResults = await ctx.parallel(restSteps, {
|
|
90875
91106
|
...parallelOptions,
|
|
90876
|
-
concurrency: boundedConcurrency(restSteps.length, undefined, inheritedConcurrency)
|
|
91107
|
+
concurrency: boundedConcurrency(restSteps.length, undefined, inheritedConcurrency),
|
|
91108
|
+
possibleStageNames: options.possibleStageNames
|
|
90877
91109
|
});
|
|
90878
91110
|
for (const [resultIndex, result] of restResults.entries()) {
|
|
90879
91111
|
const originalIndex = restIndices[resultIndex];
|
|
@@ -91082,7 +91314,7 @@ async function runAdversarialVerification(ctx) {
|
|
|
91082
91314
|
const runWave = async (pending, reaskWave) => {
|
|
91083
91315
|
if (pending.length === 0)
|
|
91084
91316
|
return { valid: [], invalid: [], results: [] };
|
|
91085
|
-
const reports = await warm_first_fan_out(ctx, pending.map((cell) => scoreStep(cell, reaskWave, scoringHead, criteriaPath)), () => scoringHead, { concurrency: Math.min(pending.length, 4), failFast: false });
|
|
91317
|
+
const reports = await warm_first_fan_out(ctx, pending.map((cell) => scoreStep(cell, reaskWave, scoringHead, criteriaPath)), () => scoringHead, { concurrency: Math.min(pending.length, 4), failFast: false, possibleStageNames: ["verifier-*-*-*", "verifier-*-*-*-reask-*"] });
|
|
91086
91318
|
const byName = new Map;
|
|
91087
91319
|
for (const report of reports) {
|
|
91088
91320
|
const name = report.name ?? report.stageName;
|
|
@@ -96470,7 +96702,7 @@ async function runTournament(ctx) {
|
|
|
96470
96702
|
if (stages.length === 0)
|
|
96471
96703
|
return { preferences: [], results: [] };
|
|
96472
96704
|
executed += stages.length;
|
|
96473
|
-
const results = await warm_first_fan_out(ctx, stages.map((stage) => stage.step), (_step, index) => `${stages[index].slot1}:${stages[index].slot2}`, { concurrency: maxConcurrency, failFast: false });
|
|
96705
|
+
const results = await warm_first_fan_out(ctx, stages.map((stage) => stage.step), (_step, index) => `${stages[index].slot1}:${stages[index].slot2}`, { concurrency: maxConcurrency, failFast: false, possibleStageNames: ["judge-*-*-*-r*"] });
|
|
96474
96706
|
const phaseResults = [...results];
|
|
96475
96707
|
for (const stage of stages) {
|
|
96476
96708
|
let report = judgeReport(resultFor(results, stage.name)?.structured);
|
|
@@ -104255,21 +104487,17 @@ function throwFinalizationError(error) {
|
|
|
104255
104487
|
function createTrackedStageCaller(input) {
|
|
104256
104488
|
const { runtime } = input;
|
|
104257
104489
|
const readinessGateEnabled = runtime.opts.confirmStageReadiness !== undefined || runtime.opts.usePromptNodesForUi === true;
|
|
104258
|
-
const confirmReadiness = async () => {
|
|
104259
|
-
|
|
104260
|
-
|
|
104261
|
-
|
|
104262
|
-
|
|
104263
|
-
|
|
104264
|
-
|
|
104265
|
-
|
|
104266
|
-
|
|
104267
|
-
|
|
104268
|
-
|
|
104269
|
-
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, runtime.signal);
|
|
104270
|
-
} catch {
|
|
104271
|
-
return { action: "advance" };
|
|
104272
|
-
}
|
|
104490
|
+
const confirmReadiness = async (signal) => {
|
|
104491
|
+
if (runtime.opts.confirmStageReadiness !== undefined) {
|
|
104492
|
+
const ready = await raceAbort(runtime.opts.confirmStageReadiness({
|
|
104493
|
+
runId: runtime.runId,
|
|
104494
|
+
stageId: runtime.stageId,
|
|
104495
|
+
stageName: runtime.name,
|
|
104496
|
+
signal
|
|
104497
|
+
}), signal);
|
|
104498
|
+
return ready ? { action: "advance" } : { action: "stay" };
|
|
104499
|
+
}
|
|
104500
|
+
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, signal);
|
|
104273
104501
|
};
|
|
104274
104502
|
const suppressReadinessForCurrentTurn = () => {
|
|
104275
104503
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
@@ -104423,9 +104651,35 @@ function createTrackedStageCaller(input) {
|
|
|
104423
104651
|
});
|
|
104424
104652
|
try {
|
|
104425
104653
|
while (runtime.state.askUserQuestionObservedThisTurn || repeatReadinessAfterChatTurn) {
|
|
104426
|
-
|
|
104654
|
+
runtime.signal.throwIfAborted();
|
|
104655
|
+
if (runtime.stageSnapshot.status === "paused" || runtime.stageSnapshot.status === "blocked") {
|
|
104656
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
104657
|
+
continue;
|
|
104658
|
+
}
|
|
104659
|
+
const controller = new AbortController;
|
|
104660
|
+
runtime.state.readinessController = controller;
|
|
104661
|
+
let decision;
|
|
104662
|
+
try {
|
|
104663
|
+
decision = await confirmReadiness(AbortSignal.any([runtime.signal, controller.signal]));
|
|
104664
|
+
if (decision.action === "advance" || decision.message !== undefined) {
|
|
104665
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
104666
|
+
}
|
|
104667
|
+
runtime.signal.throwIfAborted();
|
|
104668
|
+
if (controller.signal.aborted) {
|
|
104669
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
104670
|
+
continue;
|
|
104671
|
+
}
|
|
104672
|
+
} catch (error) {
|
|
104673
|
+
runtime.signal.throwIfAborted();
|
|
104674
|
+
if (controller.signal.aborted) {
|
|
104675
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
104676
|
+
continue;
|
|
104677
|
+
}
|
|
104678
|
+
throw error;
|
|
104679
|
+
}
|
|
104427
104680
|
if (decision.action === "advance")
|
|
104428
104681
|
break;
|
|
104682
|
+
delete runtime.state.readinessController;
|
|
104429
104683
|
if (runtime.signal.aborted)
|
|
104430
104684
|
break;
|
|
104431
104685
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
@@ -104568,9 +104822,17 @@ function createTrackedStageCaller(input) {
|
|
|
104568
104822
|
const failure = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
104569
104823
|
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
104570
104824
|
}
|
|
104571
|
-
if (!runtime.state.stageFinalized)
|
|
104572
|
-
applyTerminalStageState?.();
|
|
104573
104825
|
try {
|
|
104826
|
+
if (terminalStateIsSuccess && runtime.state.readinessController !== undefined) {
|
|
104827
|
+
let pauseVersion;
|
|
104828
|
+
do {
|
|
104829
|
+
pauseVersion = runtime.state.readinessPauseVersion;
|
|
104830
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
104831
|
+
} while (pauseVersion !== runtime.state.readinessPauseVersion);
|
|
104832
|
+
runtime.signal.throwIfAborted();
|
|
104833
|
+
}
|
|
104834
|
+
if (!runtime.state.stageFinalized)
|
|
104835
|
+
applyTerminalStageState?.();
|
|
104574
104836
|
await runtime.finalizeStageSnapshot();
|
|
104575
104837
|
} catch (err) {
|
|
104576
104838
|
finalizationError ??= { thrown: true, error: err };
|
|
@@ -104588,6 +104850,9 @@ function createTrackedStageCaller(input) {
|
|
|
104588
104850
|
input.limiter.release();
|
|
104589
104851
|
if (finalizationError !== undefined)
|
|
104590
104852
|
throwFinalizationError(finalizationError.error);
|
|
104853
|
+
delete runtime.state.readinessController;
|
|
104854
|
+
if (terminalStateIsSuccess && readinessGateEnabled)
|
|
104855
|
+
runtime.signal.throwIfAborted();
|
|
104591
104856
|
}
|
|
104592
104857
|
};
|
|
104593
104858
|
}
|
|
@@ -104908,12 +105173,26 @@ function createStageControlHandle(runtime) {
|
|
|
104908
105173
|
async pause() {
|
|
104909
105174
|
runtime.throwIfStageMutationBlocked();
|
|
104910
105175
|
const statusBeforePause = runtime.stageSnapshot.status;
|
|
105176
|
+
let readinessPauseVersion;
|
|
105177
|
+
if (runtime.state.readinessController !== undefined) {
|
|
105178
|
+
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
105179
|
+
readinessPauseVersion = (runtime.state.readinessPauseVersion ?? 0) + 1;
|
|
105180
|
+
runtime.state.readinessPauseVersion = readinessPauseVersion;
|
|
105181
|
+
}
|
|
104911
105182
|
if (statusBeforePause === "pending" || statusBeforePause === "running" || runtime.innerCtx.isStreaming) {
|
|
104912
|
-
|
|
105183
|
+
try {
|
|
105184
|
+
await runtime.innerCtx.__requestPause();
|
|
105185
|
+
} catch (error) {
|
|
105186
|
+
if (readinessPauseVersion !== undefined && runtime.state.readinessPauseVersion === readinessPauseVersion && runtime.stageSnapshot.status !== "paused" && runtime.stageSnapshot.status !== "blocked" && !runtime.scheduler.hasCascadePauseOwners(runtime.stageId)) {
|
|
105187
|
+
runtime.scheduler.releaseStageBarrier(runtime.stageId);
|
|
105188
|
+
}
|
|
105189
|
+
throw error;
|
|
105190
|
+
}
|
|
104913
105191
|
}
|
|
104914
105192
|
const changed = runtime.activeStore.recordStagePaused(runtime.runId, runtime.stageId);
|
|
104915
105193
|
if (changed) {
|
|
104916
105194
|
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
105195
|
+
runtime.state.readinessController?.abort(new Error("atomic-workflows: readiness paused"));
|
|
104917
105196
|
await runtime.scheduler.cascadePauseFrom(runtime.stageId);
|
|
104918
105197
|
const run = runtime.activeStore.runs().find((candidate) => candidate.id === runtime.runId);
|
|
104919
105198
|
const stillActive = run?.stages.some((stage) => stage.status === "running" && stage.id !== runtime.stageId) ?? false;
|
|
@@ -112462,21 +112741,24 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
112462
112741
|
pi.events?.emit?.(PENDING_STAGE_UNDELIVERABLE_EVENT, payload);
|
|
112463
112742
|
return payload.handled && await payload.completion === true;
|
|
112464
112743
|
};
|
|
112744
|
+
const announcedRoutes = new Map;
|
|
112465
112745
|
const announceRoutes = () => {
|
|
112466
112746
|
if (disposed)
|
|
112467
112747
|
return;
|
|
112748
|
+
const ownedRunIds = new Set;
|
|
112468
112749
|
const runs = activeStore.runs();
|
|
112469
112750
|
for (const run of runs) {
|
|
112470
112751
|
const rootRunId = durableRootRunIdForRun(runs, run.id);
|
|
112471
112752
|
if (rootRunId === undefined)
|
|
112472
112753
|
continue;
|
|
112754
|
+
ownedRunIds.add(run.id);
|
|
112473
112755
|
const parentRun = runs.find((candidate) => candidate.id === run.parentRunId);
|
|
112474
112756
|
const boundary = parentRun?.stages.find((stage) => stage.id === run.parentStageId);
|
|
112475
112757
|
const parent = parentRun === undefined || boundary === undefined ? undefined : {
|
|
112476
112758
|
runId: parentRun.id,
|
|
112477
112759
|
stageKeys: [boundary.id, boundary.name].filter((key) => resolveChildRun(runs, parentRun, key)?.id === run.id)
|
|
112478
112760
|
};
|
|
112479
|
-
|
|
112761
|
+
const announcement = {
|
|
112480
112762
|
runId: run.id,
|
|
112481
112763
|
group: workflowInvocationIntercomGroup(rootRunId),
|
|
112482
112764
|
capability: workflowPendingStageRouteCapability(activeStore, run.id),
|
|
@@ -112501,7 +112783,32 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
112501
112783
|
}))
|
|
112502
112784
|
],
|
|
112503
112785
|
...run.id === rootRunId ? { possibleStages: possibleStageRows(runs, rootRunId, run) } : {}
|
|
112504
|
-
}
|
|
112786
|
+
};
|
|
112787
|
+
const signature = JSON.stringify(announcement);
|
|
112788
|
+
if (announcedRoutes.get(run.id)?.signature === signature)
|
|
112789
|
+
continue;
|
|
112790
|
+
const entry = { signature };
|
|
112791
|
+
announcedRoutes.set(run.id, entry);
|
|
112792
|
+
try {
|
|
112793
|
+
pi.events?.emit?.(PENDING_STAGE_ROUTE_EVENT, announcement);
|
|
112794
|
+
} catch (error) {
|
|
112795
|
+
if (announcedRoutes.get(run.id) === entry)
|
|
112796
|
+
announcedRoutes.delete(run.id);
|
|
112797
|
+
throw error;
|
|
112798
|
+
}
|
|
112799
|
+
const completion = announcement.completion;
|
|
112800
|
+
if (completion === undefined) {
|
|
112801
|
+
announcedRoutes.delete(run.id);
|
|
112802
|
+
} else {
|
|
112803
|
+
completion.catch(() => {
|
|
112804
|
+
if (announcedRoutes.get(run.id) === entry)
|
|
112805
|
+
announcedRoutes.delete(run.id);
|
|
112806
|
+
});
|
|
112807
|
+
}
|
|
112808
|
+
}
|
|
112809
|
+
for (const runId of announcedRoutes.keys()) {
|
|
112810
|
+
if (!ownedRunIds.has(runId))
|
|
112811
|
+
announcedRoutes.delete(runId);
|
|
112505
112812
|
}
|
|
112506
112813
|
sweepPromise = sweepPromise.then(() => settleUndeliverablePendingStageMessages(activeStore, notifyUndeliverable)).then(() => {
|
|
112507
112814
|
return;
|
|
@@ -112586,6 +112893,7 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
112586
112893
|
subscription();
|
|
112587
112894
|
if (typeof stickySubscription === "function")
|
|
112588
112895
|
stickySubscription();
|
|
112896
|
+
announcedRoutes.clear();
|
|
112589
112897
|
};
|
|
112590
112898
|
pi.on?.("session_shutdown", dispose);
|
|
112591
112899
|
return dispose;
|
|
@@ -117150,7 +117458,7 @@ var DEFAULT_PROMPT_GUIDANCE = [
|
|
|
117150
117458
|
- After creating and reloading a newly authored custom workflow, close the loop by stating the folder containing the workflow file just written, for example \`.atomic/workflows/\`, in this shape: \`Custom workflow created. You can inspect its code at: <workflow-folder-path>\`. Do this only for newly created custom workflows, never builtin or pre-existing workflows.
|
|
117151
117459
|
- Keep a small, readable workflow in one entry file and write it for human maintainers. Keep the graph and control flow visible in the top-level workflow entry file, use stage names that state each stage's responsibility, and make its inputs, outputs, evidence, and success contract explicit. A developer reading the entry file from top to bottom should be able to identify the graph, branches, gates, artifacts, and stop conditions. Avoid both monolithic prompt blobs and gratuitous fragmentation. Do not split short one-use prompts, create one file per stage, add wrapper-only modules, hide the graph across files, or use line counts alone as a module boundary.
|
|
117152
117460
|
- When a meaningful source boundary improves clarity, reuse, ownership, or testability, keep the graph and control flow in the top-level workflow entry file and extract cohesive concerns such as long or reused prompt builders, shared TypeBox schemas and workflow-specific types, model-policy constants shared by several stages, deterministic helpers with their own testable behavior, or reusable child workflow definitions into a subdirectory below the top-level discovery directory — either one owned by a single workflow or a shared support directory. Project and user discovery scans only top-level \`.ts\`/\`.js\`/\`.mjs\`/\`.cjs\` files in the workflow directory, so those support modules are not scanned as extra top-level workflow candidates; use \`.js\` import extensions from TypeScript source.
|
|
117153
|
-
- Evaluate Atomic extension hooks when a workflow needs fine-grained, cross-cutting tool or session event control. Workflow TypeScript owns the inspectable DAG, stages, handoffs, durable \`ctx.tool\` side effects, and gates; extension hooks own cross-cutting session and model-tool policy such as \`tool_call\` interception, input mutation, or blocking, \`tool_result\` transformation, context and provider hooks, lifecycle observation, or reusable custom tools. Use hooks only when cross-stage or cross-workflow event control is materially clearer than embedding the policy in each stage; do not prescribe a companion extension for ordinary workflow logic. Consult \`packages/coding-agent/docs/extensions.md#events\` for the authoritative hook contracts.
|
|
117461
|
+
- Evaluate Atomic extension hooks when a workflow needs fine-grained, cross-cutting tool or session event control. Workflow TypeScript owns the inspectable DAG, stages, handoffs, durable \`ctx.tool\` side effects, and gates; extension hooks own cross-cutting session and model-tool policy such as \`tool_call\` interception, input mutation, or blocking, \`tool_result\` transformation, context and provider hooks, lifecycle observation, or reusable custom tools. Use hooks only when cross-stage or cross-workflow event control is materially clearer than embedding the policy in each stage; do not prescribe a companion extension for ordinary workflow logic. Consult \`packages/coding-agent/docs/extensions/events.md#events\` for the authoritative hook contracts.
|
|
117154
117462
|
- When a workflow depends on a companion extension, make the dependency explicit, package and document it with the workflow, include any extension-provided custom tools in stage \`tools\` allowlists, and document hook-driven behavior so the workflow remains inspectable.
|
|
117155
117463
|
- When creating or editing a workflow that pins an explicit stage \`model\` or \`fallbackModels\`, consult \`packages/coding-agent/docs/models/model-selection.md\` for role-based recommendations and \`packages/coding-agent/docs/models/evals.md\` for the measured per-evaluation scores behind them (its task-type picker maps each stage type to the eval that measures it), treating benchmark thinking levels as measurement configurations rather than universal workflow defaults, then call \`workflow({ action: "models" })\` to see the models actually present in the user's configured catalog. Use only the catalog's returned \`fullId\` values as model strings, and append a thinking suffix only when that exact level appears in the entry's \`availableThinkingLevels\`; apply the stage role and failure-cost policy independently to the primary and every fallback; treat an absent or empty \`availableThinkingLevels\` as no suffix support rather than inferring one. If a guide-recommended model for the role is unavailable, try another guide-recommended model that is present in the catalog. If the selected model does not support the role's level, choose another catalog model that does or leave the stage unpinned rather than inventing or silently promoting a level. An explicit user request for a level overrides the role default, but never fabricate an unsupported catalog level. If no recommendation intersects with the catalog, leave the stage unpinned rather than inventing a substitute, and mention the limitation, asking the user only if the workflow requires an explicit model choice. If the catalog is empty, continue with unpinned stages, state that no configured models were returned, and do not fabricate model IDs. Do not inspect or infer credentials, environment variables, auth files, token validity, entitlements, or the reason a model is absent; \`isCurrent\` marks the active selection, not a quality recommendation.
|
|
117156
117464
|
- Consult docs/workflows/reliable-design.md and its starter patterns (Classify-and-act, Fan-out-and-synthesize, Adversarial verification, Generate-and-filter, Tournament, Loop until done, and Stacked implementation slices) when designing a stage graph.
|
|
@@ -3156,6 +3156,7 @@ class StageUiBroker {
|
|
|
3156
3156
|
};
|
|
3157
3157
|
}
|
|
3158
3158
|
requestCustomUi(runId, stageId, factory, options, signal) {
|
|
3159
|
+
signal = options?.signal ? signal ? AbortSignal.any([signal, options.signal]) : options.signal : signal;
|
|
3159
3160
|
if (signal?.aborted) {
|
|
3160
3161
|
return Promise.reject(signal.reason ?? new Error("atomic-workflows: stage UI request aborted"));
|
|
3161
3162
|
}
|
|
@@ -13429,21 +13430,17 @@ function throwFinalizationError(error) {
|
|
|
13429
13430
|
function createTrackedStageCaller(input) {
|
|
13430
13431
|
const { runtime } = input;
|
|
13431
13432
|
const readinessGateEnabled = runtime.opts.confirmStageReadiness !== undefined || runtime.opts.usePromptNodesForUi === true;
|
|
13432
|
-
const confirmReadiness = async () => {
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, runtime.signal);
|
|
13444
|
-
} catch {
|
|
13445
|
-
return { action: "advance" };
|
|
13446
|
-
}
|
|
13433
|
+
const confirmReadiness = async (signal) => {
|
|
13434
|
+
if (runtime.opts.confirmStageReadiness !== undefined) {
|
|
13435
|
+
const ready = await raceAbort(runtime.opts.confirmStageReadiness({
|
|
13436
|
+
runId: runtime.runId,
|
|
13437
|
+
stageId: runtime.stageId,
|
|
13438
|
+
stageName: runtime.name,
|
|
13439
|
+
signal
|
|
13440
|
+
}), signal);
|
|
13441
|
+
return ready ? { action: "advance" } : { action: "stay" };
|
|
13442
|
+
}
|
|
13443
|
+
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, signal);
|
|
13447
13444
|
};
|
|
13448
13445
|
const suppressReadinessForCurrentTurn = () => {
|
|
13449
13446
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
@@ -13597,9 +13594,35 @@ function createTrackedStageCaller(input) {
|
|
|
13597
13594
|
});
|
|
13598
13595
|
try {
|
|
13599
13596
|
while (runtime.state.askUserQuestionObservedThisTurn || repeatReadinessAfterChatTurn) {
|
|
13600
|
-
|
|
13597
|
+
runtime.signal.throwIfAborted();
|
|
13598
|
+
if (runtime.stageSnapshot.status === "paused" || runtime.stageSnapshot.status === "blocked") {
|
|
13599
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13600
|
+
continue;
|
|
13601
|
+
}
|
|
13602
|
+
const controller = new AbortController;
|
|
13603
|
+
runtime.state.readinessController = controller;
|
|
13604
|
+
let decision;
|
|
13605
|
+
try {
|
|
13606
|
+
decision = await confirmReadiness(AbortSignal.any([runtime.signal, controller.signal]));
|
|
13607
|
+
if (decision.action === "advance" || decision.message !== undefined) {
|
|
13608
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13609
|
+
}
|
|
13610
|
+
runtime.signal.throwIfAborted();
|
|
13611
|
+
if (controller.signal.aborted) {
|
|
13612
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13613
|
+
continue;
|
|
13614
|
+
}
|
|
13615
|
+
} catch (error) {
|
|
13616
|
+
runtime.signal.throwIfAborted();
|
|
13617
|
+
if (controller.signal.aborted) {
|
|
13618
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13619
|
+
continue;
|
|
13620
|
+
}
|
|
13621
|
+
throw error;
|
|
13622
|
+
}
|
|
13601
13623
|
if (decision.action === "advance")
|
|
13602
13624
|
break;
|
|
13625
|
+
delete runtime.state.readinessController;
|
|
13603
13626
|
if (runtime.signal.aborted)
|
|
13604
13627
|
break;
|
|
13605
13628
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
@@ -13742,9 +13765,17 @@ function createTrackedStageCaller(input) {
|
|
|
13742
13765
|
const failure = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
13743
13766
|
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
13744
13767
|
}
|
|
13745
|
-
if (!runtime.state.stageFinalized)
|
|
13746
|
-
applyTerminalStageState?.();
|
|
13747
13768
|
try {
|
|
13769
|
+
if (terminalStateIsSuccess && runtime.state.readinessController !== undefined) {
|
|
13770
|
+
let pauseVersion;
|
|
13771
|
+
do {
|
|
13772
|
+
pauseVersion = runtime.state.readinessPauseVersion;
|
|
13773
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13774
|
+
} while (pauseVersion !== runtime.state.readinessPauseVersion);
|
|
13775
|
+
runtime.signal.throwIfAborted();
|
|
13776
|
+
}
|
|
13777
|
+
if (!runtime.state.stageFinalized)
|
|
13778
|
+
applyTerminalStageState?.();
|
|
13748
13779
|
await runtime.finalizeStageSnapshot();
|
|
13749
13780
|
} catch (err) {
|
|
13750
13781
|
finalizationError ??= { thrown: true, error: err };
|
|
@@ -13762,6 +13793,9 @@ function createTrackedStageCaller(input) {
|
|
|
13762
13793
|
input.limiter.release();
|
|
13763
13794
|
if (finalizationError !== undefined)
|
|
13764
13795
|
throwFinalizationError(finalizationError.error);
|
|
13796
|
+
delete runtime.state.readinessController;
|
|
13797
|
+
if (terminalStateIsSuccess && readinessGateEnabled)
|
|
13798
|
+
runtime.signal.throwIfAborted();
|
|
13765
13799
|
}
|
|
13766
13800
|
};
|
|
13767
13801
|
}
|
|
@@ -14122,12 +14156,26 @@ function createStageControlHandle(runtime) {
|
|
|
14122
14156
|
async pause() {
|
|
14123
14157
|
runtime.throwIfStageMutationBlocked();
|
|
14124
14158
|
const statusBeforePause = runtime.stageSnapshot.status;
|
|
14159
|
+
let readinessPauseVersion;
|
|
14160
|
+
if (runtime.state.readinessController !== undefined) {
|
|
14161
|
+
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
14162
|
+
readinessPauseVersion = (runtime.state.readinessPauseVersion ?? 0) + 1;
|
|
14163
|
+
runtime.state.readinessPauseVersion = readinessPauseVersion;
|
|
14164
|
+
}
|
|
14125
14165
|
if (statusBeforePause === "pending" || statusBeforePause === "running" || runtime.innerCtx.isStreaming) {
|
|
14126
|
-
|
|
14166
|
+
try {
|
|
14167
|
+
await runtime.innerCtx.__requestPause();
|
|
14168
|
+
} catch (error) {
|
|
14169
|
+
if (readinessPauseVersion !== undefined && runtime.state.readinessPauseVersion === readinessPauseVersion && runtime.stageSnapshot.status !== "paused" && runtime.stageSnapshot.status !== "blocked" && !runtime.scheduler.hasCascadePauseOwners(runtime.stageId)) {
|
|
14170
|
+
runtime.scheduler.releaseStageBarrier(runtime.stageId);
|
|
14171
|
+
}
|
|
14172
|
+
throw error;
|
|
14173
|
+
}
|
|
14127
14174
|
}
|
|
14128
14175
|
const changed = runtime.activeStore.recordStagePaused(runtime.runId, runtime.stageId);
|
|
14129
14176
|
if (changed) {
|
|
14130
14177
|
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
14178
|
+
runtime.state.readinessController?.abort(new Error("atomic-workflows: readiness paused"));
|
|
14131
14179
|
await runtime.scheduler.cascadePauseFrom(runtime.stageId);
|
|
14132
14180
|
const run = runtime.activeStore.runs().find((candidate) => candidate.id === runtime.runId);
|
|
14133
14181
|
const stillActive = run?.stages.some((stage) => stage.status === "running" && stage.id !== runtime.stageId) ?? false;
|
|
@@ -358,6 +358,8 @@ export interface WorkflowChainOptions extends WorkflowSharedTaskDefaults {
|
|
|
358
358
|
export interface WorkflowParallelOptions extends WorkflowSharedTaskDefaults {
|
|
359
359
|
readonly concurrency?: number;
|
|
360
360
|
readonly failFast?: boolean;
|
|
361
|
+
/** Static discovery only: literal conservative stage names/globs for an otherwise opaque step array. */
|
|
362
|
+
readonly possibleStageNames?: readonly string[];
|
|
361
363
|
}
|
|
362
364
|
export type WorkflowTaskSessionOptions = StageOptions & WorkflowTaskSessionFields;
|
|
363
365
|
export interface WorkflowRunChildOptions<TInputs extends WorkflowInputValues = WorkflowInputValues> {
|