@bastani/atomic 0.8.24-alpha.2 → 0.8.24-alpha.4
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 +12 -0
- package/README.md +2 -1
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +16 -0
- package/dist/builtin/subagents/README.md +132 -21
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/prompts/parallel-context-build.md +4 -2
- package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +3 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +49 -11
- package/dist/builtin/subagents/src/agents/agent-management.ts +79 -16
- package/dist/builtin/subagents/src/agents/agents.ts +47 -16
- package/dist/builtin/subagents/src/agents/chain-serializer.ts +114 -0
- package/dist/builtin/subagents/src/extension/schemas.ts +139 -3
- package/dist/builtin/subagents/src/runs/background/async-execution.ts +92 -6
- package/dist/builtin/subagents/src/runs/background/async-status.ts +11 -1
- package/dist/builtin/subagents/src/runs/background/run-status.ts +4 -1
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +529 -32
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +361 -118
- package/dist/builtin/subagents/src/runs/foreground/execution.ts +75 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +33 -0
- package/dist/builtin/subagents/src/runs/shared/acceptance.ts +611 -0
- package/dist/builtin/subagents/src/runs/shared/chain-outputs.ts +101 -0
- package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +293 -0
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +29 -1
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +11 -0
- package/dist/builtin/subagents/src/runs/shared/structured-output.ts +79 -0
- package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +52 -2
- package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +206 -0
- package/dist/builtin/subagents/src/shared/formatters.ts +2 -2
- package/dist/builtin/subagents/src/shared/settings.ts +53 -4
- package/dist/builtin/subagents/src/shared/types.ts +226 -0
- package/dist/builtin/subagents/src/shared/utils.ts +2 -1
- package/dist/builtin/subagents/src/slash/slash-commands.ts +41 -3
- package/dist/builtin/subagents/src/tui/render.ts +152 -34
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/create-spec/SKILL.md +1 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +0 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +4 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/usage.md +1 -0
- package/docs/workflows.md +173 -0
- package/node_modules/@earendil-works/pi-tui/README.md +779 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +54 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +632 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +22 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js +104 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +22 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js +35 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +249 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +1857 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js +89 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +37 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js +378 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +31 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +69 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +96 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +644 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +159 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +185 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +12 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js +23 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +19 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js +89 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +13 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js +51 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +39 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +16 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +110 -0
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +23 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js +32 -0
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +193 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +174 -0
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts +184 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.js +1173 -0
- package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts +28 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js +44 -0
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +3 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +53 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +50 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +361 -0
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +90 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +366 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +113 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +472 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +227 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +1106 -0
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts +17 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js +25 -0
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +84 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +1029 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +25 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +96 -0
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/package.json +47 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/marked/LICENSE.md +44 -0
- package/node_modules/marked/README.md +106 -0
- package/node_modules/marked/bin/main.js +282 -0
- package/node_modules/marked/bin/marked.js +15 -0
- package/node_modules/marked/lib/marked.cjs +2211 -0
- package/node_modules/marked/lib/marked.cjs.map +7 -0
- package/node_modules/marked/lib/marked.d.cts +728 -0
- package/node_modules/marked/lib/marked.d.ts +728 -0
- package/node_modules/marked/lib/marked.esm.js +2189 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +2213 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +111 -0
- package/node_modules/marked/man/marked.1.md +92 -0
- package/node_modules/marked/marked.min.js +69 -0
- package/node_modules/marked/package.json +111 -0
- package/package.json +9 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
6
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
7
7
|
import type { Message } from "@earendil-works/pi-ai";
|
|
8
8
|
import type { CodexFastModeResolvedSettings, CodexFastModeScope } from "@bastani/atomic";
|
|
9
9
|
import type { AgentConfig } from "../../agents/agents.ts";
|
|
@@ -47,6 +47,7 @@ import { getPiSpawnCommand } from "../shared/pi-spawn.ts";
|
|
|
47
47
|
import { createJsonlWriter } from "../../shared/jsonl-writer.ts";
|
|
48
48
|
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.ts";
|
|
49
49
|
import { applyThinkingSuffix, buildPiArgs, cleanupTempDir } from "../shared/pi-args.ts";
|
|
50
|
+
import { readStructuredOutput } from "../shared/structured-output.ts";
|
|
50
51
|
import { captureSingleOutputSnapshot, formatSavedOutputReference, resolveSingleOutput, validateFileOnlyOutputMode, type SingleOutputSnapshot } from "../shared/single-output.ts";
|
|
51
52
|
import {
|
|
52
53
|
buildModelCandidates,
|
|
@@ -70,8 +71,10 @@ import {
|
|
|
70
71
|
resolveSubagentModelFastMode,
|
|
71
72
|
} from "../../shared/fast-mode.ts";
|
|
72
73
|
import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
74
|
+
import { acceptanceFailureMessage, evaluateAcceptance, formatAcceptancePrompt, resolveEffectiveAcceptance, stripAcceptanceReport } from "../shared/acceptance.ts";
|
|
73
75
|
|
|
74
76
|
const artifactOutputByResult = new WeakMap<SingleResult, string>();
|
|
77
|
+
const acceptanceOutputByResult = new WeakMap<SingleResult, string>();
|
|
75
78
|
|
|
76
79
|
function emptyUsage(): Usage {
|
|
77
80
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
@@ -94,6 +97,17 @@ function appendRecentOutput(progress: AgentProgress, lines: string[]): void {
|
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
|
|
100
|
+
function stripAcceptanceReportsFromMessages(messages: Message[] | undefined): void {
|
|
101
|
+
for (const message of messages ?? []) {
|
|
102
|
+
if (message.role !== "assistant" || !Array.isArray(message.content)) continue;
|
|
103
|
+
for (const part of message.content) {
|
|
104
|
+
if (part.type === "text" && "text" in part && typeof part.text === "string") {
|
|
105
|
+
part.text = stripAcceptanceReport(part.text);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
97
111
|
function snapshotProgress(progress: AgentProgress): AgentProgress {
|
|
98
112
|
return {
|
|
99
113
|
...progress,
|
|
@@ -142,6 +156,7 @@ async function runSingleAttempt(
|
|
|
142
156
|
outputSnapshot?: SingleOutputSnapshot;
|
|
143
157
|
fastModeSettings: CodexFastModeResolvedSettings;
|
|
144
158
|
fastModeScope: CodexFastModeScope;
|
|
159
|
+
originalTask?: string;
|
|
145
160
|
},
|
|
146
161
|
): Promise<SingleResult> {
|
|
147
162
|
const modelArg = applyThinkingSuffix(model, agent.thinking);
|
|
@@ -180,11 +195,12 @@ async function runSingleAttempt(
|
|
|
180
195
|
parentCapabilityToken: options.nestedRoute?.capabilityToken,
|
|
181
196
|
codexFastModeSettings: shared.fastModeSettings,
|
|
182
197
|
codexFastModeScope: shared.fastModeScope,
|
|
198
|
+
structuredOutput: options.structuredOutput,
|
|
183
199
|
});
|
|
184
200
|
|
|
185
201
|
const result: SingleResult = {
|
|
186
202
|
agent: agent.name,
|
|
187
|
-
task,
|
|
203
|
+
task: shared.originalTask ?? task,
|
|
188
204
|
exitCode: 0,
|
|
189
205
|
messages: [],
|
|
190
206
|
usage: emptyUsage(),
|
|
@@ -195,6 +211,13 @@ async function runSingleAttempt(
|
|
|
195
211
|
skillsWarning: shared.skillsWarning,
|
|
196
212
|
};
|
|
197
213
|
const startTime = Date.now();
|
|
214
|
+
if (options.structuredOutput) {
|
|
215
|
+
try {
|
|
216
|
+
if (existsSync(options.structuredOutput.outputPath)) unlinkSync(options.structuredOutput.outputPath);
|
|
217
|
+
} catch {
|
|
218
|
+
// Missing/stale structured-output files are handled after the child exits.
|
|
219
|
+
}
|
|
220
|
+
}
|
|
198
221
|
const controlConfig = options.controlConfig ?? DEFAULT_CONTROL_CONFIG;
|
|
199
222
|
let interruptedByControl = false;
|
|
200
223
|
const allControlEvents: ControlEvent[] = [];
|
|
@@ -680,6 +703,21 @@ async function runSingleAttempt(
|
|
|
680
703
|
: `${errInfo.errorType} failed with exit code ${errInfo.exitCode}`;
|
|
681
704
|
}
|
|
682
705
|
}
|
|
706
|
+
if (options.structuredOutput && result.exitCode === 0 && !result.error) {
|
|
707
|
+
const structured = readStructuredOutput({
|
|
708
|
+
schema: options.structuredOutput.schema,
|
|
709
|
+
schemaPath: options.structuredOutput.schemaPath,
|
|
710
|
+
outputPath: options.structuredOutput.outputPath,
|
|
711
|
+
});
|
|
712
|
+
result.structuredOutputSchemaPath = options.structuredOutput.schemaPath;
|
|
713
|
+
result.structuredOutputPath = options.structuredOutput.outputPath;
|
|
714
|
+
if (structured.error) {
|
|
715
|
+
result.exitCode = 1;
|
|
716
|
+
result.error = structured.error;
|
|
717
|
+
} else {
|
|
718
|
+
result.structuredOutput = structured.value;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
683
721
|
|
|
684
722
|
progress.status = result.exitCode === 0 ? "completed" : "failed";
|
|
685
723
|
progress.durationMs = Date.now() - startTime;
|
|
@@ -696,11 +734,12 @@ async function runSingleAttempt(
|
|
|
696
734
|
durationMs: progress.durationMs,
|
|
697
735
|
};
|
|
698
736
|
|
|
699
|
-
|
|
737
|
+
const acceptanceOutput = getFinalOutput(result.messages ?? []);
|
|
738
|
+
let fullOutput = stripAcceptanceReport(acceptanceOutput);
|
|
700
739
|
const completionGuard = result.exitCode === 0 && !result.error && agent.completionGuard !== false
|
|
701
740
|
? evaluateCompletionMutationGuard({
|
|
702
741
|
agent: agent.name,
|
|
703
|
-
task,
|
|
742
|
+
task: shared.originalTask ?? task,
|
|
704
743
|
messages: result.messages ?? [],
|
|
705
744
|
tools: agent.tools,
|
|
706
745
|
mcpDirectTools: agent.mcpDirectTools,
|
|
@@ -724,7 +763,7 @@ async function runSingleAttempt(
|
|
|
724
763
|
}
|
|
725
764
|
if (options.outputPath && result.exitCode === 0) {
|
|
726
765
|
const resolvedOutput = resolveSingleOutput(options.outputPath, fullOutput, shared.outputSnapshot);
|
|
727
|
-
fullOutput = resolvedOutput.fullOutput;
|
|
766
|
+
fullOutput = stripAcceptanceReport(resolvedOutput.fullOutput);
|
|
728
767
|
result.savedOutputPath = resolvedOutput.savedPath;
|
|
729
768
|
result.outputSaveError = resolvedOutput.saveError;
|
|
730
769
|
if (resolvedOutput.savedPath) {
|
|
@@ -732,6 +771,7 @@ async function runSingleAttempt(
|
|
|
732
771
|
}
|
|
733
772
|
}
|
|
734
773
|
artifactOutputByResult.set(result, fullOutput);
|
|
774
|
+
acceptanceOutputByResult.set(result, acceptanceOutput);
|
|
735
775
|
result.outputMode = options.outputMode ?? "inline";
|
|
736
776
|
result.finalOutput = options.outputMode === "file-only" && result.savedOutputPath && result.outputReference
|
|
737
777
|
? result.outputReference.message
|
|
@@ -789,6 +829,17 @@ export async function runSync(
|
|
|
789
829
|
}
|
|
790
830
|
|
|
791
831
|
const shareEnabled = options.share === true;
|
|
832
|
+
const effectiveAcceptance = resolveEffectiveAcceptance({
|
|
833
|
+
explicit: options.acceptance,
|
|
834
|
+
agentName,
|
|
835
|
+
task,
|
|
836
|
+
mode: options.acceptanceContext?.mode ?? "single",
|
|
837
|
+
async: options.acceptanceContext?.async,
|
|
838
|
+
dynamic: options.acceptanceContext?.dynamic,
|
|
839
|
+
dynamicGroup: options.acceptanceContext?.dynamicGroup,
|
|
840
|
+
});
|
|
841
|
+
const acceptancePrompt = formatAcceptancePrompt(effectiveAcceptance);
|
|
842
|
+
const taskWithAcceptance = acceptancePrompt ? `${task}\n${acceptancePrompt}` : task;
|
|
792
843
|
const sessionEnabled = Boolean(options.sessionFile || options.sessionDir) || shareEnabled;
|
|
793
844
|
const skillNames = options.skills ?? agent.skills ?? [];
|
|
794
845
|
const skillCwd = options.cwd ?? runtimeCwd;
|
|
@@ -833,7 +884,7 @@ export async function runSync(
|
|
|
833
884
|
artifactPathsResult = getArtifactPaths(options.artifactsDir, options.runId, agentName, options.index);
|
|
834
885
|
ensureArtifactsDir(options.artifactsDir);
|
|
835
886
|
if (options.artifactConfig?.includeInput !== false) {
|
|
836
|
-
|
|
887
|
+
writeArtifact(artifactPathsResult.inputPath, `# Task for ${agentName}\n\n${taskWithAcceptance}`);
|
|
837
888
|
}
|
|
838
889
|
if (options.artifactConfig?.includeJsonl !== false) {
|
|
839
890
|
jsonlPath = artifactPathsResult.jsonlPath;
|
|
@@ -846,7 +897,7 @@ export async function runSync(
|
|
|
846
897
|
const candidate = modelsToTry[i];
|
|
847
898
|
if (candidate) attemptedModels.push(candidate);
|
|
848
899
|
const outputSnapshot = captureSingleOutputSnapshot(options.outputPath);
|
|
849
|
-
const result = await runSingleAttempt(runtimeCwd, agent,
|
|
900
|
+
const result = await runSingleAttempt(runtimeCwd, agent, taskWithAcceptance, candidate, options, {
|
|
850
901
|
sessionEnabled,
|
|
851
902
|
systemPrompt,
|
|
852
903
|
resolvedSkillNames: resolvedSkills.length > 0 ? resolvedSkills.map((skill) => skill.name) : undefined,
|
|
@@ -857,6 +908,7 @@ export async function runSync(
|
|
|
857
908
|
outputSnapshot,
|
|
858
909
|
fastModeSettings,
|
|
859
910
|
fastModeScope,
|
|
911
|
+
originalTask: task,
|
|
860
912
|
});
|
|
861
913
|
lastResult = result;
|
|
862
914
|
sumUsage(aggregateUsage, result.usage);
|
|
@@ -949,5 +1001,21 @@ export async function runSync(
|
|
|
949
1001
|
if (sessionFile) result.sessionFile = sessionFile;
|
|
950
1002
|
}
|
|
951
1003
|
|
|
1004
|
+
result.acceptance = await evaluateAcceptance({
|
|
1005
|
+
acceptance: effectiveAcceptance,
|
|
1006
|
+
output: acceptanceOutputByResult.get(result) ?? result.finalOutput ?? "",
|
|
1007
|
+
cwd: options.cwd ?? runtimeCwd,
|
|
1008
|
+
});
|
|
1009
|
+
const acceptanceFailure = acceptanceFailureMessage(result.acceptance);
|
|
1010
|
+
stripAcceptanceReportsFromMessages(result.messages);
|
|
1011
|
+
if (acceptanceFailure && result.acceptance.explicit && result.exitCode === 0 && !result.detached && !result.interrupted) {
|
|
1012
|
+
result.exitCode = 1;
|
|
1013
|
+
result.error = result.error ? `${result.error}\n${acceptanceFailure}` : acceptanceFailure;
|
|
1014
|
+
if (result.progress) {
|
|
1015
|
+
result.progress.status = "failed";
|
|
1016
|
+
result.progress.error = result.error;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
952
1020
|
return result;
|
|
953
1021
|
}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
writeInitialProgressFile,
|
|
22
22
|
getStepAgents,
|
|
23
23
|
isParallelStep,
|
|
24
|
+
isDynamicParallelStep,
|
|
24
25
|
resolveStepBehavior,
|
|
25
26
|
suppressProgressForReadOnlyTask,
|
|
26
27
|
taskDisallowsFileUpdates,
|
|
@@ -63,6 +64,7 @@ import {
|
|
|
63
64
|
} from "../shared/worktree.ts";
|
|
64
65
|
import {
|
|
65
66
|
type AgentProgress,
|
|
67
|
+
type AcceptanceInput,
|
|
66
68
|
type ArtifactConfig,
|
|
67
69
|
type ArtifactPaths,
|
|
68
70
|
type ControlConfig,
|
|
@@ -107,6 +109,7 @@ interface TaskParam {
|
|
|
107
109
|
progress?: boolean;
|
|
108
110
|
model?: string;
|
|
109
111
|
skill?: string | string[] | boolean;
|
|
112
|
+
acceptance?: AcceptanceInput;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
export interface SubagentParamsLike {
|
|
@@ -140,6 +143,7 @@ export interface SubagentParamsLike {
|
|
|
140
143
|
outputMode?: "inline" | "file-only";
|
|
141
144
|
agentScope?: string;
|
|
142
145
|
chainDir?: string;
|
|
146
|
+
acceptance?: AcceptanceInput;
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
export interface SubagentExecutorRuntimeDeps {
|
|
@@ -858,6 +862,12 @@ function validateExecutionInput(
|
|
|
858
862
|
details: { mode: "chain" as const, results: [] },
|
|
859
863
|
};
|
|
860
864
|
}
|
|
865
|
+
} else if (isDynamicParallelStep(firstStep)) {
|
|
866
|
+
return {
|
|
867
|
+
content: [{ type: "text", text: "First step in chain cannot be dynamic fanout; expand.from requires a prior structured named output" }],
|
|
868
|
+
isError: true,
|
|
869
|
+
details: { mode: "chain" as const, results: [] },
|
|
870
|
+
};
|
|
861
871
|
} else if (!(firstStep as SequentialStep).task && !params.task && !allowClarifyTaskPrompt) {
|
|
862
872
|
return {
|
|
863
873
|
content: [{ type: "text", text: "First step in chain must have a task" }],
|
|
@@ -1019,6 +1029,10 @@ function collectChainSessionFiles(
|
|
|
1019
1029
|
}
|
|
1020
1030
|
continue;
|
|
1021
1031
|
}
|
|
1032
|
+
if (isDynamicParallelStep(step)) {
|
|
1033
|
+
sessionFiles.push(undefined);
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1022
1036
|
sessionFiles.push(sessionFileForIndex(flatIndex));
|
|
1023
1037
|
flatIndex++;
|
|
1024
1038
|
}
|
|
@@ -1037,6 +1051,15 @@ function wrapChainTasksForFork(chain: ChainStep[], context: SubagentParamsLike["
|
|
|
1037
1051
|
})),
|
|
1038
1052
|
};
|
|
1039
1053
|
}
|
|
1054
|
+
if (isDynamicParallelStep(step)) {
|
|
1055
|
+
return {
|
|
1056
|
+
...step,
|
|
1057
|
+
parallel: {
|
|
1058
|
+
...step.parallel,
|
|
1059
|
+
task: wrapForkTask(step.parallel.task ?? "{previous}"),
|
|
1060
|
+
},
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1040
1063
|
const sequential = step as SequentialStep;
|
|
1041
1064
|
return {
|
|
1042
1065
|
...sequential,
|
|
@@ -1127,6 +1150,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ResolvedExecutorDeps): S
|
|
|
1127
1150
|
...(task.outputMode !== undefined ? { outputMode: task.outputMode } : {}),
|
|
1128
1151
|
...(task.reads !== undefined && task.reads !== true ? { reads: task.reads } : {}),
|
|
1129
1152
|
...(task.progress !== undefined ? { progress: task.progress } : {}),
|
|
1153
|
+
...(task.acceptance !== undefined ? { acceptance: task.acceptance } : {}),
|
|
1130
1154
|
}));
|
|
1131
1155
|
return deps.runtime.executeAsyncChain(id, {
|
|
1132
1156
|
chain: [{
|
|
@@ -1175,6 +1199,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ResolvedExecutorDeps): S
|
|
|
1175
1199
|
sessionRoot,
|
|
1176
1200
|
chainSkills,
|
|
1177
1201
|
sessionFilesByFlatIndex: collectChainSessionFiles(chain, sessionFileForIndex),
|
|
1202
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1178
1203
|
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1179
1204
|
workflowStageSubagentGuard,
|
|
1180
1205
|
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
@@ -1227,6 +1252,7 @@ function runAsyncPath(data: ExecutionContextData, deps: ResolvedExecutorDeps): S
|
|
|
1227
1252
|
controlIntercomTarget,
|
|
1228
1253
|
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(agent, index) : undefined,
|
|
1229
1254
|
nestedRoute,
|
|
1255
|
+
acceptance: params.acceptance,
|
|
1230
1256
|
});
|
|
1231
1257
|
}
|
|
1232
1258
|
|
|
@@ -1284,6 +1310,7 @@ async function runChainPath(data: ExecutionContextData, deps: ResolvedExecutorDe
|
|
|
1284
1310
|
nestedRoute: foregroundControl?.nestedRoute,
|
|
1285
1311
|
chainSkills,
|
|
1286
1312
|
chainDir: params.chainDir,
|
|
1313
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1287
1314
|
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1288
1315
|
workflowStageSubagentGuard,
|
|
1289
1316
|
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
@@ -1322,6 +1349,7 @@ async function runChainPath(data: ExecutionContextData, deps: ResolvedExecutorDe
|
|
|
1322
1349
|
sessionRoot,
|
|
1323
1350
|
chainSkills: chainResult.requestedAsync.chainSkills,
|
|
1324
1351
|
sessionFilesByFlatIndex: collectChainSessionFiles(asyncChain, sessionFileForIndex),
|
|
1352
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1325
1353
|
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1326
1354
|
workflowStageSubagentGuard,
|
|
1327
1355
|
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
@@ -1549,6 +1577,8 @@ async function runForegroundParallelTasks(input: ForegroundParallelRunInput): Pr
|
|
|
1549
1577
|
preferredModelProvider: input.ctx.model?.provider,
|
|
1550
1578
|
currentModel: currentModelFullId(input.ctx.model),
|
|
1551
1579
|
skills: effectiveSkills === false ? [] : effectiveSkills,
|
|
1580
|
+
acceptance: task.acceptance,
|
|
1581
|
+
acceptanceContext: { mode: "parallel" },
|
|
1552
1582
|
onUpdate: input.onUpdate
|
|
1553
1583
|
? (progressUpdate) => {
|
|
1554
1584
|
const stepResults = progressUpdate.details?.results || [];
|
|
@@ -1741,6 +1771,7 @@ async function runParallelPath(data: ExecutionContextData, deps: ResolvedExecuto
|
|
|
1741
1771
|
...(behaviorOverrides[i]?.outputMode !== undefined ? { outputMode: behaviorOverrides[i]!.outputMode } : {}),
|
|
1742
1772
|
...(behaviorOverrides[i]?.reads !== undefined ? { reads: behaviorOverrides[i]!.reads } : {}),
|
|
1743
1773
|
...(progress !== undefined ? { progress } : {}),
|
|
1774
|
+
...(t.acceptance !== undefined ? { acceptance: t.acceptance } : {}),
|
|
1744
1775
|
};
|
|
1745
1776
|
});
|
|
1746
1777
|
return deps.runtime.executeAsyncChain(id, {
|
|
@@ -2123,6 +2154,8 @@ async function runSinglePath(data: ExecutionContextData, deps: ResolvedExecutorD
|
|
|
2123
2154
|
preferredModelProvider: currentProvider,
|
|
2124
2155
|
currentModel: currentModelFullId(ctx.model),
|
|
2125
2156
|
skills: effectiveSkills,
|
|
2157
|
+
acceptance: params.acceptance,
|
|
2158
|
+
acceptanceContext: { mode: "single" },
|
|
2126
2159
|
});
|
|
2127
2160
|
if (foregroundControl?.currentIndex === 0) {
|
|
2128
2161
|
foregroundControl.interrupt = undefined;
|