@duckmind/dm-windows-x64 0.60.6 → 0.60.8
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +70 -123
- package/extensions/dm-9router-ext/src/index.js +410 -5
- package/extensions/dm-caveman/extensions/caveman.js +283 -12
- package/extensions/dm-cliproxy/index.js +182 -2
- package/extensions/dm-cliproxy/scripts/check-config-migration.js +66 -8
- package/extensions/dm-cliproxy/src/apply.js +228 -1
- package/extensions/dm-cliproxy/src/cache.js +42 -1
- package/extensions/dm-cliproxy/src/commands.js +50 -2
- package/extensions/dm-cliproxy/src/compat.js +81 -1
- package/extensions/dm-cliproxy/src/config.js +192 -2
- package/extensions/dm-cliproxy/src/conflicts.js +46 -1
- package/extensions/dm-cliproxy/src/fetch-models.js +190 -1
- package/extensions/dm-cliproxy/src/fetch-usage.js +41 -1
- package/extensions/dm-cliproxy/src/log.js +23 -1
- package/extensions/dm-cliproxy/src/status-quota.js +77 -1
- package/extensions/dm-cliproxy/src/ui-frame.js +50 -1
- package/extensions/dm-cliproxy/src/ui-hub/hub.js +199 -2
- package/extensions/dm-cliproxy/src/ui-hub/index.js +26 -2
- package/extensions/dm-cliproxy/src/ui-hub/shell.js +46 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-diagnostics.js +69 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-models.js +379 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-usage.js +106 -1
- package/extensions/dm-cliproxy/src/ui-picker/catalog.js +41 -1
- package/extensions/dm-cliproxy/src/ui-picker/mutate.js +115 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-confirm.js +35 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-name.js +62 -1
- package/extensions/dm-cliproxy/src/ui-picker/providers.js +45 -1
- package/extensions/dm-cliproxy/src/ui-picker/render-text.js +34 -1
- package/extensions/dm-cliproxy/src/ui-picker/rows.js +57 -1
- package/extensions/dm-cliproxy/src/ui-setup.js +260 -2
- package/extensions/dm-cliproxy/src/ui-usage.js +151 -1
- package/extensions/dm-cliproxy/src/usage-shared-cache.js +97 -1
- package/extensions/dm-context/src/context.js +144 -1
- package/extensions/dm-context/src/index.js +339 -7
- package/extensions/dm-context/src/utils.js +9 -1
- package/extensions/dm-cua/bin/browser-cua.mjs +73 -8
- package/extensions/dm-cua/index.js +75 -6
- package/extensions/dm-cua/src/browser-cua-lib.mjs +490 -6
- package/extensions/dm-cua/src/browser-install.mjs +331 -2
- package/extensions/dm-fff/src/index.js +688 -12
- package/extensions/dm-fff/src/query.js +60 -1
- package/extensions/dm-goal/src/goal.js +894 -23
- package/extensions/dm-image2/index.js +103 -9
- package/extensions/dm-image2/src/image-lib.mjs +1275 -8
- package/extensions/dm-subagents/install.mjs +62 -8
- package/extensions/dm-subagents/src/agents/agent-management.js +1190 -36
- package/extensions/dm-subagents/src/agents/agent-memory.js +216 -6
- package/extensions/dm-subagents/src/agents/agent-scope.js +5 -1
- package/extensions/dm-subagents/src/agents/agent-selection.js +20 -1
- package/extensions/dm-subagents/src/agents/agent-serializer.js +120 -5
- package/extensions/dm-subagents/src/agents/agents.js +1139 -11
- package/extensions/dm-subagents/src/agents/chain-serializer.js +299 -11
- package/extensions/dm-subagents/src/agents/frontmatter.js +65 -6
- package/extensions/dm-subagents/src/agents/identity.js +29 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +141 -1
- package/extensions/dm-subagents/src/agents/skills.js +614 -6
- package/extensions/dm-subagents/src/extension/config.js +35 -2
- package/extensions/dm-subagents/src/extension/control-notices.js +69 -4
- package/extensions/dm-subagents/src/extension/doctor.js +172 -15
- package/extensions/dm-subagents/src/extension/fanout-child.js +158 -231
- package/extensions/dm-subagents/src/extension/index.js +521 -359
- package/extensions/dm-subagents/src/extension/rpc.js +266 -7
- package/extensions/dm-subagents/src/extension/schemas.js +275 -1
- package/extensions/dm-subagents/src/extension/tool-description.js +111 -6
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +126 -4
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +452 -5
- package/extensions/dm-subagents/src/intercom/result-intercom.js +319 -3
- package/extensions/dm-subagents/src/profiles/profiles.js +458 -3
- package/extensions/dm-subagents/src/runs/background/async-execution.js +834 -40
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +435 -14
- package/extensions/dm-subagents/src/runs/background/async-resume.js +334 -8
- package/extensions/dm-subagents/src/runs/background/async-status.js +313 -12
- package/extensions/dm-subagents/src/runs/background/chain-append.js +245 -2
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +136 -1
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +94 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +54 -1
- package/extensions/dm-subagents/src/runs/background/control-channel.js +190 -1
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +483 -17
- package/extensions/dm-subagents/src/runs/background/notify.js +129 -3
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +34 -1
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +236 -6
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +76 -4
- package/extensions/dm-subagents/src/runs/background/run-status.js +427 -23
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +487 -4
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +306 -9
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +2849 -73
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +5 -1
- package/extensions/dm-subagents/src/runs/background/wait.js +206 -11
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +1013 -12
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +980 -101
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1165 -45
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +3157 -222
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +835 -3
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +104 -1
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +116 -3
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +208 -1
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +90 -1
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +282 -1
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +148 -1
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +305 -1
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +194 -1
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +65 -1
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +851 -8
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +41 -1
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +105 -1
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +81 -4
- package/extensions/dm-subagents/src/runs/shared/run-history.js +51 -4
- package/extensions/dm-subagents/src/runs/shared/single-output.js +149 -8
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +58 -1
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +166 -5
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +329 -13
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +73 -1
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +47 -4
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +196 -1
- package/extensions/dm-subagents/src/runs/shared/worktree.js +435 -3
- package/extensions/dm-subagents/src/shared/artifacts.js +92 -2
- package/extensions/dm-subagents/src/shared/atomic-json.js +55 -1
- package/extensions/dm-subagents/src/shared/child-transcript.js +167 -5
- package/extensions/dm-subagents/src/shared/file-coalescer.js +25 -1
- package/extensions/dm-subagents/src/shared/fork-context.js +147 -4
- package/extensions/dm-subagents/src/shared/formatters.js +98 -7
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +56 -2
- package/extensions/dm-subagents/src/shared/model-info.js +62 -1
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +68 -1
- package/extensions/dm-subagents/src/shared/session-identity.js +6 -1
- package/extensions/dm-subagents/src/shared/session-tokens.js +39 -2
- package/extensions/dm-subagents/src/shared/settings.js +198 -11
- package/extensions/dm-subagents/src/shared/status-format.js +53 -1
- package/extensions/dm-subagents/src/shared/types.js +184 -6
- package/extensions/dm-subagents/src/shared/utils.js +462 -2
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +288 -1
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +297 -7
- package/extensions/dm-subagents/src/slash/slash-bridge.js +118 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +1287 -31
- package/extensions/dm-subagents/src/slash/slash-live-state.js +240 -4
- package/extensions/dm-subagents/src/tui/render-helpers.js +64 -1
- package/extensions/dm-subagents/src/tui/render.js +1542 -4
- package/extensions/dm-usage/index.js +1294 -9
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +40 -9
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp.mjs +896 -30
- package/extensions/greedysearch-dm/bin/gschrome.mjs +30 -2
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +7 -2
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +13 -2
- package/extensions/greedysearch-dm/bin/launch.mjs +282 -10
- package/extensions/greedysearch-dm/bin/mcp.mjs +386 -361
- package/extensions/greedysearch-dm/bin/search.mjs +620 -540
- package/extensions/greedysearch-dm/bin/visible.mjs +22 -2
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +329 -579
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +301 -583
- package/extensions/greedysearch-dm/extractors/common.mjs +408 -32
- package/extensions/greedysearch-dm/extractors/consensus.mjs +376 -365
- package/extensions/greedysearch-dm/extractors/consent.mjs +303 -14
- package/extensions/greedysearch-dm/extractors/gemini.mjs +228 -592
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +78 -499
- package/extensions/greedysearch-dm/extractors/logically.mjs +270 -347
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +243 -581
- package/extensions/greedysearch-dm/extractors/selectors.mjs +32 -1
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +130 -317
- package/extensions/greedysearch-dm/index.js +123 -23
- package/extensions/greedysearch-dm/src/fetcher.mjs +576 -2
- package/extensions/greedysearch-dm/src/formatters/results.js +95 -10
- package/extensions/greedysearch-dm/src/formatters/sources.js +57 -1
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +49 -1
- package/extensions/greedysearch-dm/src/github.mjs +222 -7
- package/extensions/greedysearch-dm/src/reddit.mjs +145 -14
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +340 -9
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +112 -4
- package/extensions/greedysearch-dm/src/search/chrome.mjs +486 -285
- package/extensions/greedysearch-dm/src/search/constants.mjs +109 -8
- package/extensions/greedysearch-dm/src/search/defaults.mjs +10 -1
- package/extensions/greedysearch-dm/src/search/engines.mjs +79 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +441 -349
- package/extensions/greedysearch-dm/src/search/file-sources.mjs +29 -7
- package/extensions/greedysearch-dm/src/search/minimize.mjs +86 -1
- package/extensions/greedysearch-dm/src/search/output.mjs +51 -5
- package/extensions/greedysearch-dm/src/search/paths.mjs +48 -1
- package/extensions/greedysearch-dm/src/search/pdf.mjs +63 -2
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +69 -1
- package/extensions/greedysearch-dm/src/search/progress.mjs +109 -2
- package/extensions/greedysearch-dm/src/search/query.mjs +21 -1
- package/extensions/greedysearch-dm/src/search/recovery.mjs +49 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +2227 -458
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +61 -11
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +396 -805
- package/extensions/greedysearch-dm/src/search/sources.mjs +412 -1
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +127 -12
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +202 -12
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +209 -23
- package/extensions/greedysearch-dm/src/tools/shared.js +226 -10
- package/extensions/greedysearch-dm/src/utils/content.mjs +35 -4
- package/extensions/greedysearch-dm/src/utils/helpers.js +22 -1
- package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +10 -1
- package/extensions/greedysearch-dm/src/utils/system-cmds.mjs +61 -1
- package/package.json +1 -1
|
@@ -1,102 +1,981 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { ChainClarifyComponent } from "./chain-clarify.js";
|
|
4
|
+
import { toModelInfo } from "../../shared/model-info.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveChainTemplates,
|
|
7
|
+
createChainDir,
|
|
8
|
+
removeChainDir,
|
|
9
|
+
resolveStepBehavior,
|
|
10
|
+
resolveParallelBehaviors,
|
|
11
|
+
buildChainInstructions,
|
|
12
|
+
writeInitialProgressFile,
|
|
13
|
+
createParallelDirs,
|
|
14
|
+
suppressProgressForReadOnlyTask,
|
|
15
|
+
aggregateParallelOutputs,
|
|
16
|
+
isDynamicParallelStep,
|
|
17
|
+
isParallelStep
|
|
18
|
+
} from "../../shared/settings.js";
|
|
19
|
+
import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skills.js";
|
|
20
|
+
import { INTERCOM_BRIDGE_MARKER } from "../../intercom/intercom-bridge.js";
|
|
21
|
+
import { runSync } from "./execution.js";
|
|
22
|
+
import { buildChainSummary } from "../../shared/formatters.js";
|
|
23
|
+
import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
|
|
24
|
+
import { DEFAULT_GLOBAL_CONCURRENCY_LIMIT, Semaphore } from "../shared/parallel-utils.js";
|
|
25
|
+
import { recordRun } from "../shared/run-history.js";
|
|
26
|
+
import {
|
|
27
|
+
cleanupWorktrees,
|
|
28
|
+
createWorktrees,
|
|
29
|
+
diffWorktrees,
|
|
30
|
+
findWorktreeTaskCwdConflict,
|
|
31
|
+
formatWorktreeDiffSummary,
|
|
32
|
+
formatWorktreeTaskCwdConflict
|
|
33
|
+
} from "../shared/worktree.js";
|
|
34
|
+
import {
|
|
35
|
+
MAX_CONCURRENCY,
|
|
36
|
+
resolveChildMaxSubagentDepth
|
|
37
|
+
} from "../../shared/types.js";
|
|
38
|
+
import { resolveSubagentModelOverride } from "../shared/model-fallback.js";
|
|
39
|
+
import { validateFileOnlyOutputMode } from "../shared/single-output.js";
|
|
40
|
+
import { buildWorkflowGraphSnapshot } from "../shared/workflow-graph.js";
|
|
41
|
+
import { ChainOutputValidationError, outputEntryFromResult, resolveOutputReferences, validateChainOutputBindings } from "../shared/chain-outputs.js";
|
|
42
|
+
import { createStructuredOutputRuntime } from "../shared/structured-output.js";
|
|
43
|
+
import { collectDynamicResults, DynamicFanoutError, materializeDynamicParallelStep, validateDynamicCollection } from "../shared/dynamic-fanout.js";
|
|
44
|
+
import { acceptanceFailureMessage, aggregateAcceptanceReport, evaluateAcceptance, resolveEffectiveAcceptance } from "../shared/acceptance.js";
|
|
45
|
+
import { validateToolBudgetConfig } from "../shared/tool-budget.js";
|
|
46
|
+
function buildChainExecutionDetails(input) {
|
|
47
|
+
return compactForegroundDetails({
|
|
48
|
+
mode: "chain",
|
|
49
|
+
results: input.results,
|
|
50
|
+
progress: input.includeProgress ? input.allProgress : undefined,
|
|
51
|
+
artifacts: input.allArtifactPaths.length ? { dir: input.artifactsDir, files: input.allArtifactPaths } : undefined,
|
|
52
|
+
chainAgents: input.chainAgents,
|
|
53
|
+
totalSteps: input.totalSteps,
|
|
54
|
+
currentStepIndex: input.currentStepIndex,
|
|
55
|
+
outputs: input.outputs,
|
|
56
|
+
totalChildUsage: sumResultsUsage(input.results),
|
|
57
|
+
totalCost: sumResultsCost(input.results),
|
|
58
|
+
workflowGraph: buildWorkflowGraphSnapshot({
|
|
59
|
+
runId: input.runId,
|
|
60
|
+
mode: "chain",
|
|
61
|
+
steps: input.chainSteps,
|
|
62
|
+
results: input.results,
|
|
63
|
+
currentStepIndex: input.currentStepIndex,
|
|
64
|
+
currentFlatIndex: input.currentFlatIndex,
|
|
65
|
+
dynamicChildren: input.dynamicChildren,
|
|
66
|
+
dynamicGroupStatuses: input.dynamicGroupStatuses
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function buildChainExecutionErrorResult(message, input) {
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: "text", text: message }],
|
|
73
|
+
isError: true,
|
|
74
|
+
details: buildChainExecutionDetails(input)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function ensureParallelProgressFile(chainDir, progressCreated, parallelBehaviors) {
|
|
78
|
+
if (progressCreated || !parallelBehaviors.some((behavior) => behavior.progress)) {
|
|
79
|
+
return progressCreated;
|
|
80
|
+
}
|
|
81
|
+
writeInitialProgressFile(chainDir);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function appendParallelWorktreeSummary(output, worktreeSetup, diffsDir, agents) {
|
|
85
|
+
if (!worktreeSetup)
|
|
86
|
+
return output;
|
|
87
|
+
const diffs = diffWorktrees(worktreeSetup, agents, diffsDir);
|
|
88
|
+
const diffSummary = formatWorktreeDiffSummary(diffs);
|
|
89
|
+
if (!diffSummary)
|
|
90
|
+
return output;
|
|
91
|
+
return `${output}
|
|
14
92
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
`;if(J+G+Buffer.byteLength(V,"utf-8")>X){U();return}try{z0.appendFileSync($.transcriptPath,q,"utf-8"),J+=G}catch(z){Z=`Failed to write child transcript '${$.transcriptPath}': ${d1(z)}`}};try{z0.mkdirSync(O2.dirname($.transcriptPath),{recursive:!0}),z0.writeFileSync($.transcriptPath,"","utf-8")}catch(H){Z=`Failed to initialize child transcript '${$.transcriptPath}': ${d1(H)}`}let W=(H,q)=>{let G=N0(q.content);B({...Y("message"),sourceEventType:H,role:q.role,...G?{text:G}:{},...q.model?{model:q.model}:{},...q.stopReason?{stopReason:q.stopReason}:{},...q.errorMessage?{errorMessage:q.errorMessage}:{},...q.usage?{usage:B4(q.usage)}:{},message:q})};return{path:$.transcriptPath,writeInitialUserMessage(H){B({...Y("message"),sourceEventType:"initial_prompt",role:"user",text:H,message:{role:"user",content:[{type:"text",text:H}]}})},writeChildEvent(H){if((H.type==="message_end"||H.type==="tool_result_end")&&H.message){W(H.type,H.message);return}if(H.type==="tool_execution_start"&&H.toolName){let q=H4(H);B({...Y("tool_start"),sourceEventType:H.type,toolName:H.toolName,...Object.keys(q).length>0?{argsPreview:W1(q)}:{}});return}if(H.type==="tool_execution_end")B({...Y("tool_end"),sourceEventType:H.type,...H.toolName?{toolName:H.toolName}:{}})},writeStdoutLine(H){if(!H.trim())return;B({...Y("stdout"),text:H})},writeStderrLine(H){if(!H.trim())return;B({...Y("stderr"),text:H})},writeStderrText(H){for(let q of H.split(/\r?\n/))this.writeStderrLine(q)},getError(){return Z}}}var W4=["event","async","intercom"],q4=["active_long_running","needs_attention"],M2={enabled:!0,needsAttentionAfterMs:60000,activeNoticeAfterMs:240000,failedToolAttemptsBeforeAttention:3,notifyOn:q4,notifyChannels:W4};function E2($){if(!$.config.enabled)return;let J=$.now??Date.now(),Z=$.lastActivityAt??$.startedAt;return Math.max(0,J-Z)>$.config.needsAttentionAfterMs?"needs_attention":void 0}function K1($){let J=$.ts??Date.now(),Z=$.type??($.to==="active_long_running"?"active_long_running":"needs_attention"),Q=$.elapsedMs??($.lastActivityAt?Math.max(0,J-$.lastActivityAt):void 0),X=Q!==void 0?Math.floor(Q/1000):void 0,Y=$.message??(Z==="active_long_running"?`${$.agent} is still active but long-running`:X!==void 0?`${$.agent} needs attention (no observed activity for ${X}s)`:`${$.agent} needs attention`);return{type:Z,...$.from?{from:$.from}:{},to:$.to,ts:J,runId:$.runId,agent:$.agent,...$.index!==void 0?{index:$.index}:{},message:Y,reason:$.reason??(Z==="active_long_running"?"active_long_running":"idle"),...$.turns!==void 0?{turns:$.turns}:{},...$.tokens!==void 0?{tokens:$.tokens}:{},...$.toolCount!==void 0?{toolCount:$.toolCount}:{},...$.currentTool?{currentTool:$.currentTool}:{},...$.currentToolDurationMs!==void 0?{currentToolDurationMs:$.currentToolDurationMs}:{},...$.currentPath?{currentPath:$.currentPath}:{},...Q!==void 0?{elapsedMs:Q}:{},...$.recentFailureSummary?{recentFailureSummary:$.recentFailureSummary}:{}}}function p1($,J){return $.enabled&&$.notifyOn.includes(J.type)}function V4($,J){return`${J??($.index!==void 0?`${$.runId}:${$.index}`:$.runId)}:${$.type}:${$.reason??"idle"}`}function R2($,J,Z,Q){if(!p1($,J))return!1;let X=V4(J,Q);if(Z.has(X))return!1;return Z.add(X),!0}import*as Y$ from"node:fs";import*as z$ from"node:path";import*as U0 from"node:fs";import*as g$ from"node:path";import{fileURLToPath as $6}from"node:url";import*as d$ from"node:fs";import*as T2 from"node:os";import*as p0 from"node:path";import{Compile as z4}from"typebox/compile";var S2="DM_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA",w2="DM_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE";function j4($,J="outputSchema"){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${J} must be a JSON Schema object.`)}function o1($,J){j4($);let Z=J??T2.tmpdir();d$.mkdirSync(Z,{recursive:!0});let Q=d$.mkdtempSync(p0.join(Z,"dm-subagent-structured-")),X=p0.join(Q,"schema.json"),Y=p0.join(Q,"output.json");return d$.writeFileSync(X,JSON.stringify($),{mode:384}),{schema:$,schemaPath:X,outputPath:Y}}function l1($,J){let Z;try{Z=z4($)}catch(X){return{status:"invalid",message:`invalid outputSchema: ${X instanceof Error?X.message:String(X)}`}}if(Z.Check(J))return{status:"valid"};return{status:"invalid",message:[...Z.Errors(J)].slice(0,8).map((X)=>{return`${X.instancePath?X.instancePath.replace(/^\//,"").replace(/\//g,"."):"root"}: ${X.message}`}).join("; ")||"schema validation failed"}}function y2($){if(!d$.existsSync($.outputPath))return{error:"Missing structured_output call; this step has outputSchema and must finish by calling structured_output."};let J;try{J=JSON.parse(d$.readFileSync($.outputPath,"utf-8"))}catch(Q){return{error:`Failed to read structured output: ${Q instanceof Error?Q.message:String(Q)}`}}let Z=l1($.schema,J);if(Z.status==="invalid")return{error:`Structured output validation failed: ${Z.message}`};return{value:J}}class b extends Error{}var K4=/^[A-Za-z_][A-Za-z0-9_]*$/,_4=/^[A-Za-z_][A-Za-z0-9_]*$/,l0=/\{([A-Za-z_][A-Za-z0-9_]*)(?:\.([^{}]+))?\}/g,A4=new Set(["task","previous","chain_dir","outputs"]),b2=new Set(["expand","parallel","collect","concurrency","failFast","phase","label","acceptance"]),N4=new Set([...b2,"effectiveAcceptance","sessionFiles","thinkingOverrides"]),F4=new Set(["from","item","key","maxItems","onEmpty"]),O4=new Set(["output","path"]),f2=new Set(["agent","task","phase","label","outputSchema","cwd","output","outputMode","reads","progress","skill","model","toolBudget","acceptance"]),L4=new Set([...f2,"outputName","structured","inheritProjectContext","inheritSkills","skills","outputPath","maxSubagentDepth","structuredOutput","structuredOutputSchema","tools","extensions","subagentOnlyExtensions","mcpDirectTools","completionGuard","systemPrompt","systemPromptMode","thinking","modelCandidates","sessionFile","effectiveAcceptance","parentSessionId"]),M4=new Set(["as","outputSchema"]);function D2($){return K4.test($)}function n1($,J){if($==="")return;if(!$.startsWith("/"))throw new b(`${J} must be a JSON Pointer starting with '/'.`);for(let Z of $.slice(1).split("/"))if(/~(?![01])/.test(Z))throw new b(`${J} contains invalid JSON Pointer escape.`)}function E4($){return $.replace(/~1/g,"/").replace(/~0/g,"~")}function s1($,J,Z){if(n1(J,Z),J==="")return $;let Q=$;for(let X of J.slice(1).split("/")){let Y=E4(X);if(Array.isArray(Q)){if(!/^(0|[1-9][0-9]*)$/.test(Y))throw new b(`${Z} segment '${Y}' does not address an array index.`);let B=Number(Y);if(B>=Q.length)throw new b(`${Z} does not exist.`);Q=Q[B];continue}if(!Q||typeof Q!=="object")throw new b(`${Z} does not exist.`);let U=Q;if(!Object.prototype.hasOwnProperty.call(U,Y))throw new b(`${Z} does not exist.`);Q=U[Y]}return Q}function R4($,J){if(typeof $==="string"||typeof $==="number"||typeof $==="boolean"){let Z=String($);if(!Z.trim())throw new b(`${J} resolved to an empty key.`);if(/[\u0000-\u001F\u007F]/.test(Z))throw new b(`${J} resolved to an unsafe key.`);if(Z.length>200)throw new b(`${J} resolved to a key longer than 200 characters.`);return Z}throw new b(`${J} must resolve to a string, number, or boolean.`)}function C4($){return $.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"item"}function T4($,J){if($===void 0)throw new b(`Unresolved item reference '${J}'.`);if(typeof $==="string")return $;if(typeof $==="number"||typeof $==="boolean"||$===null)return String($);return JSON.stringify($)}function S4($,J,Z){if(!J)return $;let Q=`/${J.split(".").map((X)=>X.replace(/~/g,"~0").replace(/\//g,"~1")).join("/")}`;return s1($,Q,Z)}function I2($,J,Z){return $.replace(l0,(Q,X,Y)=>{if(X!==J)return Q;if(Y!==void 0&&(!Y.trim()||Y.includes("..")))throw new b(`Invalid item reference '${Q}'.`);return T4(S4(Z,Y,Q),Q)})}function o0($,J,Z){if(!$||typeof $!=="object"||Array.isArray($))throw new b(`${Z} must be an object.`);for(let Q of Object.keys($))if(!J.has(Q))throw new b(`${Z} does not support field '${Q}'.`)}function w4($,J,Z){for(let Q of $.matchAll(/\{([^{}]*)\}/g)){let X=Q[0],Y=Q[1];if(Y===J||Y.startsWith(`${J}.`)){if(!l0.test(X)||Y===`${J}.`||Y.includes(".."))throw new b(`Invalid item reference '${X}' in ${Z}.`);l0.lastIndex=0;continue}l0.lastIndex=0;let U=Y.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];if(U===J)throw new b(`Invalid item reference '${X}' in ${Z}.`);if(U&&A4.has(U))continue;if(U)throw new b(`Unsupported template reference '${X}' in ${Z}.`)}if(l0.lastIndex=0,$.includes(`{${J}.}`)||new RegExp(`\\{${J}(?:\\.|$)[^}]*$`).test($))throw new b(`Invalid item reference in ${Z}.`)}function P2($){return!!$&&typeof $==="object"&&!Array.isArray($)&&(Object.prototype.hasOwnProperty.call($,"expand")||Object.prototype.hasOwnProperty.call($,"collect"))}function i1($,J,Z={}){let Q=`Dynamic chain step ${J+1}`;if(o0($,Z.allowRunnerFields?N4:b2,Q),!$.expand||!$.expand.from)throw new b(`${Q} requires expand.from.`);if(o0($.expand,F4,`${Q} expand`),o0($.expand.from,O4,`${Q} expand.from`),!D2($.expand.from.output))throw new b(`${Q} has invalid expand.from.output '${$.expand.from.output}'.`);if(n1($.expand.from.path,`${Q} expand.from.path`),$.expand.key!==void 0)n1($.expand.key,`${Q} expand.key`);let X=$.expand.item??"item";if(!_4.test(X))throw new b(`${Q} has invalid expand.item '${X}'.`);if($.expand.maxItems===void 0&&Z.maxItems===void 0)throw new b(`${Q} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`);if($.expand.maxItems!==void 0&&(!Number.isInteger($.expand.maxItems)||$.expand.maxItems<0))throw new b(`${Q} expand.maxItems must be an integer >= 0.`);if(Z.maxItems!==void 0&&(!Number.isInteger(Z.maxItems)||Z.maxItems<0))throw new b("config.chain.dynamicFanout.maxItems must be an integer >= 0.");if(!$.parallel||Array.isArray($.parallel))throw new b(`${Q} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`);if(o0($.parallel,Z.allowRunnerFields?L4:f2,`${Q} parallel`),"expand"in $.parallel)throw new b(`${Q} does not support nested dynamic fanout.`);if(!$.parallel.agent)throw new b(`${Q} parallel.agent is required.`);if(!$.collect?.as||!D2($.collect.as))throw new b(`${Q} requires collect.as with a safe output name.`);o0($.collect,M4,`${Q} collect`);for(let[Y,U]of[["parallel.task",$.parallel.task],["parallel.label",$.parallel.label]])if(U)w4(U,X,`${Q} ${Y}`)}function y4($,J,Z,Q={}){i1($,Z,Q);let X=$.expand.from.output,Y=J[X];if(!Y)throw new b(`Dynamic chain step ${Z+1} references unknown output '${X}'.`);if(Y.structured===void 0)throw new b(`Dynamic chain step ${Z+1} requires structured output '${X}'.`);let U=s1(Y.structured,$.expand.from.path,`Dynamic chain step ${Z+1} expand.from.path`);if(!Array.isArray(U))throw new b(`Dynamic chain step ${Z+1} expand.from.path must resolve to an array.`);let B=$.expand.maxItems??Q.maxItems;if(B===void 0)throw new b(`Dynamic chain step ${Z+1} requires an effective maxItems.`);if(U.length>B)throw new b(`Dynamic chain step ${Z+1} resolved ${U.length} items, exceeding maxItems ${B}.`);let W=new Set,H=new Set;return U.map((q,G)=>{let V=$.expand.key===void 0?String(G):R4(s1(q,$.expand.key,`Dynamic chain step ${Z+1} expand.key`),`Dynamic chain step ${Z+1} expand.key`);if(W.has(V))throw new b(`Dynamic chain step ${Z+1} produced duplicate item key '${V}'.`);W.add(V);let z=C4(V);if(H.has(z))throw new b(`Dynamic chain step ${Z+1} produced colliding item id '${z}'.`);return H.add(z),{index:G,key:V,idKey:z,item:q}})}function k2($,J,Z,Q={}){let X=y4($,J,Z,Q);if(X.length===0){if(($.expand.onEmpty??"skip")==="fail")throw new b(`Dynamic chain step ${Z+1} source array is empty.`);return{items:X,parallel:[],collectedOnEmpty:[]}}let Y=$.expand.item??"item",U=X.map((B)=>{let W=I2($.parallel.task??"{previous}",Y,B.item),H=$.parallel.label?I2($.parallel.label,Y,B.item):void 0;return{...$.parallel,task:W,...H!==void 0?{label:H}:{}}});return{items:X,parallel:U}}function x2($,J,Z){return J.map((Q,X)=>{let Y=Z[X],U=Y?"output"in Y&&typeof Y.output==="string"?Y.output:Q0(Y):"";return{key:Q.key,index:Q.index,item:Q.item,agent:Y?.agent??$.parallel.agent,exitCode:Y?.exitCode??null,text:U,...Y?.structuredOutput!==void 0?{structured:Y.structuredOutput}:{},...Y?.error?{error:Y.error}:{},...Y?.timedOut?{timedOut:!0}:{},...Y?.savedOutputPath?{outputPath:Y.savedOutputPath}:{},...Y?.artifactPaths?{artifactPaths:Y.artifactPaths}:{}}})}function r1($,J){if(!$)return;let Z=l1($,J);if(Z.status==="invalid")throw new b(`Collected output validation failed: ${Z.message}`)}var g2=/\{outputs\.([^}]*)\}/g,a1=/^[A-Za-z_][A-Za-z0-9_]*$/;class b$ extends Error{}function h2($){if(T$($))return $.parallel.map((Z)=>Z.as).filter((Z)=>Boolean(Z));if(S$($))return[$.collect.as];let J=$.as;return J?[J]:[]}function D4($){if(T$($))return $.parallel.map((J)=>J.task??"{previous}");if(S$($))return[$.parallel.task??"{previous}",$.parallel.label??""].filter(Boolean);return[$.task??"{previous}"]}function t1($,J={}){I4($,J)}function I4($,J={},Z={}){let Q=[...Z.priorOutputNames??[]],X=new Set(Q),Y=new Set(Q);for(let U=0;U<$.length;U++){let B=(Z.startStepIndex??0)+U+1,W=$[U];if(P2(W)){if(!S$(W))throw new b$(`Dynamic chain step ${B} requires expand, a single parallel template object, and collect; dynamic expand/collect cannot be mixed with static parallel arrays.`);try{i1(W,B-1,J)}catch(H){if(H instanceof b)throw new b$(H.message);throw H}if(!X.has(W.expand.from.output))throw new b$(`Dynamic chain step ${B} references unknown output '${W.expand.from.output}'. Named outputs are only available after producing step/group completes.`)}for(let H of h2(W)){if(!a1.test(H))throw new b$(`Invalid chain output name '${H}' at step ${B}. Use /^[A-Za-z_][A-Za-z0-9_]*$/.`);if(Y.has(H))throw new b$(`Duplicate chain output name '${H}'. Each as name must be unique.`);Y.add(H)}for(let H of D4(W))for(let q of H.matchAll(g2)){let G=q[0],V=q[1];if(!a1.test(V))throw new b$(`Invalid chain output reference '${G}' at step ${B}. Use {outputs.name} with /^[A-Za-z_][A-Za-z0-9_]*$/ names.`);if(!X.has(V))throw new b$(`Unknown chain output reference '${G}' at step ${B}. Named outputs are only available after producing step/group completes.`)}for(let H of h2(W))X.add(H)}}function e1($,J){return $.replace(g2,(Z,Q)=>{if(!a1.test(Q))throw new b$(`Invalid chain output reference '${Z}'. Use {outputs.name} with /^[A-Za-z_][A-Za-z0-9_]*$/ names.`);let X=J[Q];if(!X)throw new b$(`Unknown chain output reference '${Z}'.`);return X.text})}function b4($){return JSON.stringify($)}function $J($,J){return{text:$.structuredOutput!==void 0?b4($.structuredOutput):Q0($),...$.structuredOutput!==void 0?{structured:$.structuredOutput}:{},agent:$.agent,stepIndex:J}}import{spawn as f4}from"node:child_process";import{spawnSync as P4}from"node:child_process";import*as m2 from"node:path";var C0={none:0,attested:1,checked:2,verified:3,reviewed:4};var k4=new Set(["changed-files","tests-added","commands-run","validation-output","residual-risks","no-staged-files","diff-summary","review-findings","manual-notes"]);function x4($){return $??"auto"}function c2($){return[...new Set($)]}function JJ($){switch($){case"none":return[];case"attested":return["manual-notes","residual-risks"];case"checked":return["changed-files","tests-added","commands-run","residual-risks","no-staged-files"];case"verified":case"reviewed":return["changed-files","tests-added","commands-run","validation-output","residual-risks","no-staged-files"]}}function h4($){let J=$.agentName.toLowerCase(),Z=$.task?.toLowerCase()??"",Q=[],X=/\b(?:reviewer|scout|context-builder|researcher|analyst)\b/.test(J),Y=/\b(?:read[- ]only|review[- ]only|do not edit|don't edit|no edits|without edits|inspect|summari[sz]e)\b/.test(Z),U=/\b(?:fix|implement|update|write|edit|modify|migrate|release|security|delete|remove|refactor|commit)\b/.test(Z)||/\bworker\b/.test(J);if(Boolean($.async&&U)||Boolean($.dynamic)||Boolean($.dynamicGroup)||/\b(?:release|migration|migrate|security|data[- ]loss|destructive|post-review|fix pass)\b/.test(Z)){if(Q.push($.async?"async write-capable or risky run":"risky write-capable run"),$.dynamic||$.dynamicGroup)Q.push("dynamic fanout context");return{level:"reviewed",reasons:Q,criteria:["Implement the requested change without widening scope","Return evidence sufficient for an independent acceptance review"],evidence:JJ("reviewed"),review:{agent:"reviewer",required:!0}}}if(U&&!Y)return Q.push("write-capable worker/task"),{level:"checked",reasons:Q,criteria:["Implement the requested change without widening scope"],evidence:JJ("checked")};if(X||Y)return Q.push(X?"read-only/reviewer-style agent":"read-only task wording"),{level:"attested",reasons:Q,criteria:["Return concrete findings with file paths and severity when applicable"],evidence:["review-findings","residual-risks"]};return Q.push("default lightweight attestation"),{level:"attested",reasons:Q,criteria:["Return a concise result and residual risks when applicable"],evidence:["manual-notes","residual-risks"]}}function g4($){if($===void 0||$==="auto")return{level:"auto"};if($===!1)return{level:"none",reason:"disabled by deprecated false shorthand"};if(typeof $==="string")return{level:$};return{...$}}function v4($){return $.level==="none"&&typeof $.reason==="string"&&$.reason.trim().length>0}function m4($,J){return($??[]).map((Z,Q)=>{if(typeof Z==="string")return{id:`criterion-${Q+1}`,must:Z,evidence:J,severity:"required"};return{id:Z.id?.trim()||`criterion-${Q+1}`,must:Z.must??"",evidence:Z.evidence?.filter((X)=>k4.has(X))??J,severity:Z.severity??"required"}}).filter((Z)=>Z.must.trim())}function r0($){let J=g4($.explicit),Z=h4($),Q=x4(J.level),X=v4(J)?"none":Q==="auto"?Z.level:C0[Q]>=C0[Z.level]?Q:Z.level,Y=c2([...X===Z.level?Z.evidence:JJ(X),...J.evidence??[]]),U=m4(J.criteria?.length?J.criteria:Z.criteria,Y),B=J.review!==void 0?J.review:Z.review;if(X==="reviewed"&&Q!=="auto"&&Q!=="reviewed"&&J.review===void 0&&B&&B!==!1)B={...B,required:!1};return{level:X,explicit:$.explicit!==void 0,inferredReason:Z.reasons,criteria:U,evidence:Y,verify:J.verify??[],review:B,stopRules:J.stopRules??[],reason:J.reason}}function u2($){if($.level==="none")return"";let J=["","## Acceptance Contract",`Acceptance level: ${$.level}`,"Completion is not accepted from prose alone. End with a structured acceptance report.","","Criteria:",...$.criteria.length?$.criteria.map((Z)=>`- ${Z.id}: ${Z.must}`):["- Return the requested result."],"",`Required evidence: ${$.evidence.join(", ")||"none"}`];if($.verify.length>0){J.push("","Runtime verification commands configured by parent:");for(let Z of $.verify)J.push(`- ${Z.id}: ${Z.command}`)}if($.review&&$.review!==!1){if(J.push("",`Review gate: ${$.review.required===!1?"optional":"required"}${$.review.agent?` by ${$.review.agent}`:""}.`),$.review.focus)J.push(`Review focus: ${$.review.focus}`)}if($.stopRules.length>0)J.push("","Stop rules:",...$.stopRules.map((Z)=>`- ${Z}`));return J.push("","Finish with a fenced JSON block tagged `acceptance-report` in this shape:","Use empty arrays when no items apply; array fields contain strings unless object entries are shown.","```acceptance-report",JSON.stringify({criteriaSatisfied:[{id:"criterion-1",status:"satisfied",evidence:"specific proof"}],changedFiles:["src/file.ts"],testsAddedOrUpdated:["test/file.test.ts"],commandsRun:[{command:"command",result:"passed",summary:"short result"}],validationOutput:["validation output or concise summary"],residualRisks:["none"],noStagedFiles:!0,diffSummary:"short description of the diff",reviewFindings:["blocker: file.ts:12 - issue found, or no blockers"],manualNotes:"anything else the parent should know"},null,2),"```"),J.join(`
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
`,G=Buffer.byteLength(q,"utf-8");if(B+G>W)return;try{let V=X.write(q);if(B+=G,!V&&!Y)Y=!0,J.pause(),X.once("drain",()=>{if(Y=!1,!U)J.resume()})}catch{}},async close(){if(!X||U)return;U=!0;let H=X;X=void 0,await new Promise((q)=>H.end(()=>q()))}}}function p$($,J){try{return $.kill(J)}catch{return!1}}function A8($,J){let{idleMs:Z,hardMs:Q}=J,X=!1,Y=!1,U=!1,B,W,H=()=>{if(!Y)try{$.stdout?.destroy()}catch{}if(!U)try{$.stderr?.destroy()}catch{}},q=()=>{if(B)clearTimeout(B),B=void 0;if(W)clearTimeout(W),W=void 0},G=()=>{if(!X)return;if(B)clearTimeout(B);B=setTimeout(H,Z),B.unref?.()};return $.stdout?.on("data",G),$.stderr?.on("data",G),$.stdout?.on("end",()=>{if(Y=!0,Y&&U)q()}),$.stderr?.on("end",()=>{if(U=!0,Y&&U)q()}),$.on("exit",()=>{if(X=!0,G(),W)return;W=setTimeout(H,Q),W.unref?.()}),$.on("close",q),$.on("error",q),q}import*as P$ from"node:fs";import*as _J from"node:os";import*as j$ from"node:path";import{fileURLToPath as v8}from"node:url";import*as O8 from"node:path";var y6=128,D6=4;function I6($){return typeof $==="string"&&$.length>0&&$.length<=y6&&!O8.isAbsolute($)&&!$.includes("/")&&!$.includes("\\")&&!$.includes("..")}function N8($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function F8($,J){return typeof $==="string"&&$.length>0?$.slice(0,J):void 0}function L8($){if(!Array.isArray($))return[];return $.map((J)=>{if(!J||typeof J!=="object")return;let Z=J;if(!I6(Z.runId))return;return{runId:Z.runId,...N8(Z.stepIndex)!==void 0?{stepIndex:N8(Z.stepIndex)}:{},...F8(Z.agent,128)?{agent:F8(Z.agent,128)}:{}}}).filter((J)=>Boolean(J)).slice(0,D6)}function M8($){if(!$)return[];try{return L8(JSON.parse($))}catch{return[]}}function E8($){let J=L8($);return J.length?JSON.stringify(J):""}import{createHash as b6}from"node:crypto";import*as T0 from"node:fs";import*as o$ from"node:os";import*as F$ from"node:path";var f6=1,P6=604800000,R8=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),C8=F$.join(o$.homedir(),".config","mcp","mcp.json"),w8={cursor:[F$.join(o$.homedir(),".cursor","mcp.json")],"claude-code":[F$.join(o$.homedir(),".claude","mcp.json"),F$.join(o$.homedir(),".claude.json"),F$.join(o$.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[F$.join(o$.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[F$.join(o$.homedir(),".codex","config.json")],windsurf:[F$.join(o$.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};function y8($,J=process.cwd()){if(!$?.length)return[];try{let Z=x6(J),Q=k6();if(!Q)return[];return p6(Z,Q,s6(Z.settings?.toolPrefix),$)}catch{return[]}}function k6(){let $=F$.join(h$(),"mcp-cache.json"),J;try{J=JSON.parse(T0.readFileSync($,"utf-8"))}catch{return null}if(!J||typeof J!=="object")return null;let Z=J;if(Z.version!==f6||!Z.servers||typeof Z.servers!=="object"||Array.isArray(Z.servers))return null;return Z}function x6($){let J={mcpServers:{}};for(let Z of h6($)){let Q=g6(Z);if(!Q)continue;J=m6(J,c6(Q,$))}return J}function h6($){let J=F$.join(h$(),"mcp.json"),Z=F$.resolve($,".mcp.json"),Q=F$.resolve(x$($),"mcp.json"),X=[];if(C8!==J)X.push(C8);if(X.push(J),Z!==J)X.push(Z);if(Q!==J&&Q!==Z)X.push(Q);return X}function g6($){let J;try{J=JSON.parse(T0.readFileSync($,"utf-8"))}catch{return null}return v6(J)}function v6($){if(!$||typeof $!=="object"||Array.isArray($))return{mcpServers:{}};let J=$,Z=J.mcpServers??J["mcp-servers"]??{};return{mcpServers:Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{},imports:Array.isArray(J.imports)?J.imports.filter((Q)=>i6(Q)):void 0,settings:J.settings&&typeof J.settings==="object"&&!Array.isArray(J.settings)?J.settings:void 0}}function m6($,J){let Z=[...$.imports??[],...J.imports??[]];return{mcpServers:{...$.mcpServers,...J.mcpServers},imports:Z.length?[...new Set(Z)]:void 0,settings:J.settings?{...$.settings,...J.settings}:$.settings}}function c6($,J){if(!$.imports?.length)return $;let Z={};for(let Q of $.imports){let X=u6(Q,J);if(!X)continue;let Y;try{Y=JSON.parse(T0.readFileSync(X,"utf-8"))}catch{continue}for(let[U,B]of Object.entries(d6(Y,Q)))if(!Z[U])Z[U]=B}return{imports:$.imports,settings:$.settings,mcpServers:{...Z,...$.mcpServers}}}function u6($,J){for(let Z of w8[$]){let Q=Z.startsWith(".")?F$.resolve(J,Z):Z;if(T0.existsSync(Q))return Q}return null}function d6($,J){if(!$||typeof $!=="object"||Array.isArray($))return{};let Z=$,Q=J==="cursor"||J==="windsurf"||J==="vscode"?Z.mcpServers??Z["mcp-servers"]:Z.mcpServers;return Q&&typeof Q==="object"&&!Array.isArray(Q)?Q:{}}function p6($,J,Z,Q){let X=[],Y=new Set,{servers:U,tools:B}=o6(Q);for(let[W,H]of Object.entries($.mcpServers)){let q=J.servers[W];if(!l6(q,H))continue;let G=U.has(W)?!0:B.get(W);if(!G)continue;for(let V of Array.isArray(q.tools)?q.tools:[]){if(typeof V?.name!=="string"||!V.name)continue;if(G!==!0&&!G.has(V.name))continue;if(T8(V.name,W,Z,H.excludeTools))continue;let z=J1(V.name,W,Z);if(R8.has(z)||Y.has(z))continue;Y.add(z),X.push(z)}if(H.exposeResources===!1)continue;for(let V of Array.isArray(q.resources)?q.resources:[]){if(typeof V?.name!=="string"||!V.name||typeof V.uri!=="string"||!V.uri)continue;let z=`get_${a6(V.name)}`;if(G!==!0&&!G.has(z))continue;if(T8(z,W,Z,H.excludeTools))continue;let _=J1(z,W,Z);if(R8.has(_)||Y.has(_))continue;Y.add(_),X.push(_)}}return X}function o6($){let J=new Set,Z=new Map;for(let Q of $)if(Q=Q.replace(/\/+$/,""),Q.includes("/")){let[X,Y]=Q.split("/",2);if(X&&Y){if(!Z.has(X))Z.set(X,new Set);Z.get(X).add(Y)}else if(X)J.add(X)}else if(Q)J.add(Q);return{servers:J,tools:Z}}function l6($,J){if(!$||$.configHash!==n6(J))return!1;if(!$.cachedAt||typeof $.cachedAt!=="number")return!1;return Date.now()-$.cachedAt<=P6}function n6($){let J={command:$.command,args:$.args,env:S8($.env),cwd:t6($.cwd),url:$.url,headers:S8($.headers),auth:$.auth,bearerToken:e6($),bearerTokenEnv:$.bearerTokenEnv,exposeResources:$.exposeResources,excludeTools:$.excludeTools};return b6("sha256").update(qJ(J)).digest("hex")}function s6($){return $==="none"||$==="short"||$==="server"?$:"server"}function i6($){return typeof $==="string"&&Object.hasOwn(w8,$)}function r6($,J){if(J==="none")return"";if(J==="short")return $.replace(/-?mcp$/i,"").replace(/-/g,"_")||"mcp";return $.replace(/-/g,"_")}function J1($,J,Z){let Q=r6(J,Z);return Q?`${Q}_${$}`:$}function T8($,J,Z,Q){if(!Array.isArray(Q)||Q.length===0)return!1;let X=new Set([$1($),$1(J1($,J,Z)),$1(J1($,J,"server")),$1(J1($,J,"short"))]);return Q.some((Y)=>typeof Y==="string"&&X.has($1(Y)))}function $1($){return $.replace(/-/g,"_")}function a6($){let J=$.replace(/[^a-zA-Z0-9]/g,"_").replace(/_+/g,"_").replace(/^_+/,"").replace(/_+$/,"").toLowerCase();if(!J||/^\d/.test(J))J=`resource${J?`_${J}`:""}`;return J}function S8($){if(!$||typeof $!=="object"||Array.isArray($))return;let J={};for(let[Z,Q]of Object.entries($))if(typeof Q==="string")J[Z]=VJ(Q);return J}function VJ($){return $.replace(/\$\{(\w+)\}/g,(J,Z)=>process.env[Z]??"").replace(/\$env:(\w+)/g,(J,Z)=>process.env[Z]??"")}function t6($){if(typeof $!=="string")return;let J=VJ($);if(J==="~")return o$.homedir();if(J.startsWith("~/")||J.startsWith("~\\"))return F$.join(o$.homedir(),J.slice(2));return J}function e6($){if(typeof $.bearerToken==="string")return VJ($.bearerToken);return typeof $.bearerTokenEnv==="string"?process.env[$.bearerTokenEnv]:void 0}function qJ($){if($===null||$===void 0||typeof $!=="object"){let Z=JSON.stringify($);return Z===void 0?"undefined":Z}if(Array.isArray($))return`[${$.map((Z)=>qJ(Z)).join(",")}]`;let J=$;return`{${Object.keys(J).sort().map((Z)=>`${JSON.stringify(Z)}:${qJ(J[Z])}`).join(",")}}`}var $Z=["off","minimal","low","medium","high","xhigh"],JZ=8000;function m8($,J){let Z=v8($),Q=j$.extname(Z),X=[".js",".mjs",".cjs",".ts",".mts",".cts"].includes(Q)?Q:".ts";return j$.join(j$.dirname(Z),`${J}${X}`)}function c8($){return j$.basename(v8($)).startsWith("dm-args.")}function ZZ($=import.meta.url){let J=c8($)?"subagent-prompt-runtime":j$.join("..","runs","shared","subagent-prompt-runtime");return m8($,J)}function QZ($=import.meta.url){let J=c8($)?j$.join("..","..","extension","fanout-child"):"fanout-child";return m8($,J)}var D8=ZZ(),XZ=QZ(),YZ="DM_SUBAGENT_CHILD",UZ="DM_SUBAGENT_ORCHESTRATOR_TARGET",GZ="DM_SUBAGENT_ORCHESTRATOR_SESSION_ID",BZ="DM_SUBAGENT_SUPERVISOR_CHANNEL_DIR",I8="DM_SUBAGENT_RUN_ID",HZ="DM_SUBAGENT_CHILD_AGENT",WZ="DM_SUBAGENT_CHILD_INDEX",qZ="DM_SUBAGENT_FANOUT_CHILD",zJ="DM_SUBAGENT_PARENT_EVENT_SINK",b8="DM_SUBAGENT_PARENT_CONTROL_INBOX",jJ="DM_SUBAGENT_PARENT_ROOT_RUN_ID",f8="DM_SUBAGENT_PARENT_RUN_ID",P8="DM_SUBAGENT_PARENT_CHILD_INDEX",k8="DM_SUBAGENT_PARENT_DEPTH",x8="DM_SUBAGENT_PARENT_PATH",KJ="DM_SUBAGENT_PARENT_CAPABILITY_TOKEN",h8="DM_SUBAGENT_PARENT_SESSION",VZ="DM_SUBAGENT_STEER_INBOX";function g8($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function zZ($,J,Z){return j$.join(R0,"supervisor-channels",`${g8($)}-${g8(J)}-${Z}`)}function AJ($,J,Z=!1){if(!$||!J)return $;let Q=$.lastIndexOf(":");if(Q!==-1&&$Z.includes($.substring(Q+1)))return Z?`${$.slice(0,Q)}:${J}`:$;return`${$}:${J}`}function u8($){let J=[...$.baseArgs];if($.sessionFile)P$.mkdirSync(j$.dirname($.sessionFile),{recursive:!0}),J.push("--session",$.sessionFile);else{if(!$.sessionEnabled)J.push("--no-session");if($.sessionDir)P$.mkdirSync($.sessionDir,{recursive:!0}),J.push("--session-dir",$.sessionDir)}let Z=AJ($.model,$.thinking);if(Z)J.push("--model",Z);let Q=$.tools?.filter((O)=>!(O.includes("/")||O.endsWith(".ts")||O.endsWith(".js")))??[],X=$.requireReadTool&&$.tools?.length&&!Q.includes("read")?["read",...Q]:Q,Y=X.includes("subagent"),U=[];if($.tools?.length){let O=[...X];for(let D of $.tools)if(!X.includes(D)&&(D.includes("/")||D.endsWith(".ts")||D.endsWith(".js")))U.push(D);if(O.length>0){if($.mcpDirectTools?.length)O.push(...y8($.mcpDirectTools,$.cwd));J.push("--tools",O.join(","))}}let B=Y?[D8,XZ]:[D8];if($.extensions!==void 0){J.push("--no-extensions");for(let O of[...new Set([...B,...U,...$.extensions,...$.subagentOnlyExtensions??[]])])J.push("--extension",O)}else for(let O of[...new Set([...B,...U,...$.subagentOnlyExtensions??[]])])J.push("--extension",O);if(!$.inheritSkills)J.push("--no-skills");let W;if($.systemPrompt!==void 0&&$.systemPrompt!==null){W=P$.mkdtempSync(j$.join(_J.tmpdir(),"dm-subagent-"));let O=($.promptFileStem??"prompt").replace(/[^\w.-]/g,"_"),D=j$.join(W,`${O}.md`);P$.writeFileSync(D,$.systemPrompt,{mode:384}),J.push($.systemPromptMode==="replace"?"--system-prompt":"--append-system-prompt",D)}if($.task.length>JZ){if(!W)W=P$.mkdtempSync(j$.join(_J.tmpdir(),"dm-subagent-"));let O=j$.join(W,"task.md");P$.writeFileSync(O,`Task: ${$.task}`,{mode:384}),J.push(`@${O}`)}else J.push(`Task: ${$.task}`);let H={};H[YZ]="1",H[qZ]=Y?"1":"0";let q=Boolean(process.env[zJ]&&process.env[jJ]&&process.env[KJ]),G=$.parentRunId??$.runId??(q?process.env[I8]:void 0)??process.env[f8]??"",V=$.parentChildIndex!==void 0?String($.parentChildIndex):$.childIndex!==void 0?String($.childIndex):process.env[P8]??"",z=Number(process.env[k8]),_=$.parentDepth??(q&&Number.isFinite(z)?z+1:1),A=$.parentPath??[...M8(process.env[x8]),...G?[{runId:G,...V&&/^\d+$/.test(V)?{stepIndex:Number(V)}:{},...$.childAgentName?{agent:$.childAgentName}:{}}]:[]];if(H[zJ]=Y?$.parentEventSink??process.env[zJ]??"":"",H[b8]=Y?$.parentControlInbox??process.env[b8]??"":"",H[jJ]=Y?$.parentRootRunId??process.env[jJ]??$.runId??"":"",H[f8]=Y?G:"",H[P8]=Y?V:"",H[k8]=Y?String(_):"",H[x8]=Y?E8(A):"",H[KJ]=Y?$.parentCapabilityToken??process.env[KJ]??"":"",H.DM_SUBAGENT_INHERIT_PROJECT_CONTEXT=$.inheritProjectContext?"1":"0",H.DM_SUBAGENT_INHERIT_SKILLS=$.inheritSkills?"1":"0",$.intercomSessionName)H.DM_SUBAGENT_INTERCOM_SESSION_NAME=$.intercomSessionName;if($.orchestratorIntercomTarget)H[UZ]=$.orchestratorIntercomTarget;if($.parentSessionId)H[GZ]=$.parentSessionId;if($.orchestratorIntercomTarget&&$.parentSessionId&&$.runId&&$.childAgentName){let O=$.childIndex??0,D=zZ($.runId,$.childAgentName,O);P$.mkdirSync(j$.join(D,"requests"),{recursive:!0}),P$.mkdirSync(j$.join(D,"replies"),{recursive:!0}),H[BZ]=D}if($.runId)H[I8]=$.runId;if($.childAgentName)H[HZ]=$.childAgentName;if($.childIndex!==void 0)H[WZ]=String($.childIndex);if($.mcpDirectTools?.length)H.MCP_DIRECT_TOOLS=$.mcpDirectTools.join(",");else H.MCP_DIRECT_TOOLS="__none__";if($.structuredOutput)H[w2]=$.structuredOutput.outputPath,H[S2]=$.structuredOutput.schemaPath;if($.steerInboxDir)H[VZ]=$.steerInboxDir;let M=i2($.toolBudget);if(M)H[n2]=M;return H[h8]=$.parentSessionId??process.env[h8]??"",{args:J,env:H,tempDir:W}}function NJ($){if(!$)return;try{P$.rmSync($,{recursive:!0,force:!0})}catch{}}import*as $0 from"node:fs";import*as Z1 from"node:path";function jZ($){return[`Write your findings to exactly this path: ${$}`,"This path is authoritative for this run.","Ignore any other output filename or output path mentioned elsewhere, including output destinations in the base agent prompt, system prompt, or task instructions."].join(`
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
${Y}`}function V9($){if($.stepBudget!==void 0){let Z=e0($.stepBudget,"toolBudget");return{toolBudget:Z.budget,error:Z.error}}if($.runBudget!==void 0)return{toolBudget:$.runBudget};if($.agentBudget!==void 0){let Z=e0($.agentBudget,"agent.toolBudget");return{toolBudget:Z.budget,error:Z.error}}let J=e0($.configBudget,"config.toolBudget");return{toolBudget:J.budget,error:J.error}}async function q9($){let J=$.step.concurrency??H2,Z=$.step.failFast??!1,Q=!1;return await y1($.step.parallel,J,async(Y,U)=>{if(Q&&Z)return{agent:Y.agent,task:"(skipped)",exitCode:-1,messages:[],usage:{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,turns:0},error:"Skipped due to fail-fast"};let B=$.parallelTemplates[U]??"{previous}",W=d0($.parallelBehaviors[U],B,$.originalTask),H=B.includes("{previous}"),{prefix:q,suffix:G}=v1(W,$.chainDir,!1,H?void 0:$.prev),V=e1(B,$.outputs);V=V.replace(/\{task\}/g,$.originalTask),V=V.replace(/\{previous\}/g,$.prev),V=V.replace(/\{chain_dir\}/g,$.chainDir);let z=V;V=q+V+G;let _=$.agents.find((X$)=>X$.name===Y.agent),A=R1(Y.model??_?.model,$.ctx.model,$.availableModels,$.ctx.model?.provider,{scope:$.modelScope,source:Y.model?"explicit":"inherited"}),M=x1($.maxSubagentDepth,_?.maxSubagentDepth),O=V9({stepBudget:Y.toolBudget,runBudget:$.toolBudget,agentBudget:_?.toolBudget,configBudget:$.configToolBudget});if(O.error)throw Error(O.error);let D=$.worktreeSetup?$.worktreeSetup.worktrees[U].agentCwd:H1($.cwd??$.ctx.cwd,Y.cwd),j=typeof W.output==="string"?A$.isAbsolute(W.output)?W.output:A$.join($.chainDir,W.output):void 0,c=new AbortController;if($.foregroundControl)$.foregroundControl.currentAgent=Y.agent,$.foregroundControl.currentIndex=$.globalTaskIndex+U,$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),$.foregroundControl.interrupt=()=>{if(c.signal.aborted)return!1;return c.abort(),$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),!0};let q$=Y.outputSchema?o1(Y.outputSchema,A$.join($.chainDir,"structured-output")):void 0,I=await TJ($.ctx.cwd,$.agents,Y.agent,V,{parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,cwd:D,signal:$.signal,interruptSignal:c.signal,allowIntercomDetach:_?.systemPrompt?.includes(u1)===!0,intercomEvents:$.intercomEvents,runId:$.runId,index:$.globalTaskIndex+U,sessionDir:$.sessionDirForIndex($.globalTaskIndex+U),sessionFile:$.sessionFileForTask?.(Y.agent,$.globalTaskIndex+U)??$.sessionFileForIndex?.($.globalTaskIndex+U),thinkingOverride:$.thinkingOverrideForTask?.(Y.agent,$.globalTaskIndex+U),share:$.shareEnabled,artifactsDir:$.artifactConfig.enabled?$.artifactsDir:void 0,artifactConfig:$.artifactConfig,outputPath:j,outputMode:W.outputMode,maxSubagentDepth:M,controlConfig:$.controlConfig,onControlEvent:$.onControlEvent,intercomSessionName:$.childIntercomTarget?.(Y.agent,$.globalTaskIndex+U),orchestratorIntercomTarget:$.orchestratorIntercomTarget,nestedRoute:$.nestedRoute,modelOverride:A,availableModels:$.availableModels,preferredModelProvider:$.ctx.model?.provider,modelScope:$.modelScope,skills:W.skills===!1?[]:W.skills,structuredOutput:q$,acceptance:Y.acceptance,acceptanceContext:{mode:"chain"},timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,turnBudget:$.turnBudget,onDetachedExit:$.onDetachedExit?(X$)=>$.onDetachedExit?.($.globalTaskIndex+U,X$):void 0,toolBudget:O.toolBudget,onUpdate:$.onUpdate?(X$)=>{let I$=X$.details?.results||[],m=X$.details?.progress||[];if($.foregroundControl&&m.length>0){let H$=m[0];$.foregroundControl.currentAgent=Y.agent,$.foregroundControl.currentIndex=$.globalTaskIndex+U,$.foregroundControl.currentActivityState=H$?.activityState,$.foregroundControl.lastActivityAt=H$?.lastActivityAt,$.foregroundControl.currentTool=H$?.currentTool,$.foregroundControl.currentToolStartedAt=H$?.currentToolStartedAt,$.foregroundControl.currentPath=H$?.currentPath,$.foregroundControl.turnCount=H$?.turnCount,$.foregroundControl.tokens=H$?.tokens,$.foregroundControl.toolCount=H$?.toolCount,$.foregroundControl.updatedAt=Date.now()}$.onUpdate?.({...X$,details:{mode:"chain",results:$.results.concat(I$),progress:$.allProgress.concat(m),controlEvents:X$.details?.controlEvents,chainAgents:$.chainAgents,totalSteps:$.totalSteps,currentStepIndex:$.stepIndex,outputs:$.outputs,workflowGraph:F1({runId:$.runId,mode:"chain",steps:$.chainSteps,results:$.results.concat(I$),currentStepIndex:$.stepIndex,currentFlatIndex:$.globalTaskIndex+U,dynamicChildren:$.dynamicChildren,dynamicGroupStatuses:$.dynamicGroupStatuses})}})}:void 0});if($.foregroundControl?.currentIndex===$.globalTaskIndex+U)$.foregroundControl.interrupt=void 0,$.foregroundControl.updatedAt=Date.now();if(I.exitCode!==0&&Z)Q=!0;return SJ(Y.agent,z,I.exitCode,I.progressSummary?.durationMs??0),I},$.globalSemaphore)}async function h7($){let{chain:J,agents:Z,ctx:Q,signal:X,runId:Y,cwd:U,shareEnabled:B,sessionDirForIndex:W,sessionFileForIndex:H,sessionFileForTask:q,thinkingOverrideForTask:G,artifactsDir:V,artifactConfig:z,includeProgress:_,clarify:A,onUpdate:M,onControlEvent:O,controlConfig:D,onDetachedExit:j,childIntercomTarget:c,orchestratorIntercomTarget:q$,foregroundControl:I,intercomEvents:X$,chainSkills:I$,chainDir:m,modelScope:H$}=$,C=I$??[],e=[],P={},E={},i={},S=[],d=[],r=J.map((K)=>T$(K)?`[${K.parallel.map((T)=>T.agent).join("+")}]`:S$(K)?`expand:${K.parallel.agent}`:K.agent),s=J.length,v=(K={})=>({results:e,..._!==void 0?{includeProgress:_}:{},allProgress:S,allArtifactPaths:d,artifactsDir:V,chainAgents:r,chainSteps:J,totalSteps:s,runId:Y,outputs:P,dynamicChildren:E,dynamicGroupStatuses:i,...K}),v$=J[0],E$=$.task??(T$(v$)?v$.parallel[0].task:S$(v$)?v$.parallel.task:v$.task);try{t1(J,{maxItems:$.dynamicFanoutMaxItems})}catch(K){if(K instanceof b$)return{content:[{type:"text",text:K.message}],isError:!0,details:O$(v())};throw K}let n=j2(Y,m),B0=J.some((K)=>T$(K)||S$(K)),r$=K2(J),H0=A===!0&&Q.hasUI&&!B0,y0,m$=Q.modelRegistry.getAvailable().map(bJ),W0=Y2(U??Q.cwd);if(H0){let K=J,T=[];for(let f of K){let u=Z.find((h)=>h.name===f.agent);if(!u)return u0(n),{content:[{type:"text",text:`Unknown agent: ${f.agent}`}],isError:!0,details:O$(v({currentStepIndex:K.indexOf(f)}))};T.push(u)}let c$=K.map((f)=>({output:f.output,outputMode:f.outputMode,reads:f.reads,progress:f.progress,skills:L0(f.skill),model:f.model})),k=T.map((f,u)=>g1(f,c$[u],C)),K$=r$,o=await Q.ui.custom((f,u,h,l)=>new T1(f,u,T,K$,E$,n,k,m$,Q.model?.provider,W0,l),{overlay:!0,overlayOptions:{anchor:"center",width:84,maxHeight:"80%"}});if(!o||!o.confirmed)return u0(n),{content:[{type:"text",text:"Chain cancelled"}],details:O$(v())};if(o.runInBackground){u0(n);let f=J.map((u,h)=>{if(T$(u))return u;let l=o.behaviorOverrides[h];return{...u,task:o.templates[h],...l?.model?{model:l.model}:{},...l?.output!==void 0?{output:l.output}:{},..."outputMode"in u&&u.outputMode!==void 0?{outputMode:u.outputMode}:{},...l?.reads!==void 0?{reads:l.reads}:{},...l?.progress!==void 0?{progress:l.progress}:{},...l?.skills!==void 0?{skill:l.skills}:{}}});return{content:[{type:"text",text:"Launching in background..."}],details:O$(v()),requestedAsync:{chain:f,chainSkills:C}}}r$=o.templates,y0=o.behaviorOverrides}let D0=$.deadlineAt??($.timeoutMs!==void 0?Date.now()+$.timeoutMs:void 0),I0=new w1($.globalConcurrencyLimit??pJ),R$="",$$=0,J0=!1;for(let K=0;K<J.length;K++){let T=J[K],c$=r$[K];if(T$(T)){let k=c$,K$=H1(U??Q.cwd,T.cwd),o;if(T.worktree){let f=Q9(T.parallel,K$);if(f)return l$(`parallel chain step ${K+1}: ${X9(f,K$)}`,v({currentStepIndex:K,currentFlatIndex:$$}));try{o=U9(K$,`${Y}-s${K}`,T.parallel.length,{agents:T.parallel.map((u)=>u.agent),setupHook:$.worktreeSetupHook?{hookPath:$.worktreeSetupHook,timeoutMs:$.worktreeSetupHookTimeoutMs}:void 0,baseDir:$.worktreeBaseDir})}catch(u){let h=u instanceof Error?u.message:String(u);return l$(h,v({currentStepIndex:K,currentFlatIndex:$$}))}}try{let f=T.parallel.map((w)=>w.agent),u=m1(T.parallel,Z,K,C).map((w,J$)=>d0(w,k[J$]??T.parallel[J$]?.task,E$));for(let w=0;w<T.parallel.length;w++){let J$=u[w],N$=typeof J$.output==="string"?A$.isAbsolute(J$.output)?J$.output:A$.join(n,J$.output):void 0,G$=S0(J$.outputMode,N$,`Parallel chain step ${K+1} task ${w+1} (${T.parallel[w].agent})`);if(G$)return l$(G$,v({currentStepIndex:K,currentFlatIndex:$$+w}))}J0=W9(n,J0,u),c1(n,K,T.parallel.length,f);let h=await q9({step:T,parallelTemplates:k,parallelBehaviors:u,agents:Z,stepIndex:K,availableModels:m$,modelScope:H$,chainDir:n,prev:R$,originalTask:E$,ctx:Q,intercomEvents:X$,cwd:U,runId:Y,globalTaskIndex:$$,sessionDirForIndex:W,sessionFileForIndex:H,sessionFileForTask:q,thinkingOverrideForTask:G,shareEnabled:B,artifactConfig:z,artifactsDir:V,signal:X,onUpdate:M,results:e,allProgress:S,outputs:P,chainAgents:r,chainSteps:J,totalSteps:s,dynamicChildren:E,dynamicGroupStatuses:i,controlConfig:D,onControlEvent:O,childIntercomTarget:c,orchestratorIntercomTarget:q$,foregroundControl:I,nestedRoute:$.nestedRoute,worktreeSetup:o,maxSubagentDepth:$.maxSubagentDepth,timeoutMs:$.timeoutMs,deadlineAt:D0,turnBudget:$.turnBudget,onDetachedExit:j,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalSemaphore:I0});$$+=T.parallel.length;for(let w of h){if(e.push(w),w.progress)S.push(w.progress);if(w.artifactPaths)d.push(w.artifactPaths)}let l=h.findIndex((w)=>w.interrupted),L$=l>=0?h[l]:void 0;if(L$)return{content:[{type:"text",text:`Chain paused after interrupt at step ${K+1} (${L$.agent}). Waiting for explicit next action.`}],details:O$(v({currentStepIndex:K,currentFlatIndex:$$-T.parallel.length+l}))};let C$=h.findIndex((w)=>w.detached),a$=C$>=0?h[C$]:void 0;if(a$)return{content:[{type:"text",text:`Chain detached for intercom coordination at step ${K+1} (${a$.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.`}],details:O$(v({currentStepIndex:K,currentFlatIndex:$$-T.parallel.length+C$}))};let U$=h.map((w,J$)=>({...w,originalIndex:J$})).filter((w)=>w.exitCode!==0&&w.exitCode!==-1);if(U$.length>0){let w=U$.map((G$)=>`- Task ${G$.originalIndex+1} (${G$.agent}): ${G$.error||"failed"}`).join(`
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
${diffSummary}`;
|
|
94
|
+
}
|
|
95
|
+
function resolveChainToolBudget(input) {
|
|
96
|
+
if (input.stepBudget !== undefined) {
|
|
97
|
+
const resolved = validateToolBudgetConfig(input.stepBudget, "toolBudget");
|
|
98
|
+
return { toolBudget: resolved.budget, error: resolved.error };
|
|
99
|
+
}
|
|
100
|
+
if (input.runBudget !== undefined)
|
|
101
|
+
return { toolBudget: input.runBudget };
|
|
102
|
+
if (input.agentBudget !== undefined) {
|
|
103
|
+
const resolved = validateToolBudgetConfig(input.agentBudget, "agent.toolBudget");
|
|
104
|
+
return { toolBudget: resolved.budget, error: resolved.error };
|
|
105
|
+
}
|
|
106
|
+
const resolved = validateToolBudgetConfig(input.configBudget, "config.toolBudget");
|
|
107
|
+
return { toolBudget: resolved.budget, error: resolved.error };
|
|
108
|
+
}
|
|
109
|
+
async function runParallelChainTasks(input) {
|
|
110
|
+
const concurrency = input.step.concurrency ?? MAX_CONCURRENCY;
|
|
111
|
+
const failFast = input.step.failFast ?? false;
|
|
112
|
+
let aborted = false;
|
|
113
|
+
const parallelResults = await mapConcurrent(input.step.parallel, concurrency, async (task, taskIndex) => {
|
|
114
|
+
if (aborted && failFast) {
|
|
115
|
+
return {
|
|
116
|
+
agent: task.agent,
|
|
117
|
+
task: "(skipped)",
|
|
118
|
+
exitCode: -1,
|
|
119
|
+
messages: [],
|
|
120
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 },
|
|
121
|
+
error: "Skipped due to fail-fast"
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const taskTemplate = input.parallelTemplates[taskIndex] ?? "{previous}";
|
|
125
|
+
const behavior = suppressProgressForReadOnlyTask(input.parallelBehaviors[taskIndex], taskTemplate, input.originalTask);
|
|
126
|
+
const templateHasPrevious = taskTemplate.includes("{previous}");
|
|
127
|
+
const { prefix, suffix } = buildChainInstructions(behavior, input.chainDir, false, templateHasPrevious ? undefined : input.prev);
|
|
128
|
+
let taskStr = resolveOutputReferences(taskTemplate, input.outputs);
|
|
129
|
+
taskStr = taskStr.replace(/\{task\}/g, input.originalTask);
|
|
130
|
+
taskStr = taskStr.replace(/\{previous\}/g, input.prev);
|
|
131
|
+
taskStr = taskStr.replace(/\{chain_dir\}/g, input.chainDir);
|
|
132
|
+
const cleanTask = taskStr;
|
|
133
|
+
taskStr = prefix + taskStr + suffix;
|
|
134
|
+
const taskAgentConfig = input.agents.find((agent) => agent.name === task.agent);
|
|
135
|
+
const effectiveModel = resolveSubagentModelOverride(task.model ?? taskAgentConfig?.model, input.ctx.model, input.availableModels, input.ctx.model?.provider, { scope: input.modelScope, source: task.model ? "explicit" : "inherited" });
|
|
136
|
+
const maxSubagentDepth = resolveChildMaxSubagentDepth(input.maxSubagentDepth, taskAgentConfig?.maxSubagentDepth);
|
|
137
|
+
const toolBudget = resolveChainToolBudget({ stepBudget: task.toolBudget, runBudget: input.toolBudget, agentBudget: taskAgentConfig?.toolBudget, configBudget: input.configToolBudget });
|
|
138
|
+
if (toolBudget.error)
|
|
139
|
+
throw new Error(toolBudget.error);
|
|
140
|
+
const taskCwd = input.worktreeSetup ? input.worktreeSetup.worktrees[taskIndex].agentCwd : resolveChildCwd(input.cwd ?? input.ctx.cwd, task.cwd);
|
|
141
|
+
const outputPath = typeof behavior.output === "string" ? path.isAbsolute(behavior.output) ? behavior.output : path.join(input.chainDir, behavior.output) : undefined;
|
|
142
|
+
const interruptController = new AbortController;
|
|
143
|
+
if (input.foregroundControl) {
|
|
144
|
+
input.foregroundControl.currentAgent = task.agent;
|
|
145
|
+
input.foregroundControl.currentIndex = input.globalTaskIndex + taskIndex;
|
|
146
|
+
input.foregroundControl.currentActivityState = undefined;
|
|
147
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
148
|
+
input.foregroundControl.interrupt = () => {
|
|
149
|
+
if (interruptController.signal.aborted)
|
|
150
|
+
return false;
|
|
151
|
+
interruptController.abort();
|
|
152
|
+
input.foregroundControl.currentActivityState = undefined;
|
|
153
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
154
|
+
return true;
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const structuredRuntime = task.outputSchema ? createStructuredOutputRuntime(task.outputSchema, path.join(input.chainDir, "structured-output")) : undefined;
|
|
158
|
+
const result = await runSync(input.ctx.cwd, input.agents, task.agent, taskStr, {
|
|
159
|
+
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
160
|
+
cwd: taskCwd,
|
|
161
|
+
signal: input.signal,
|
|
162
|
+
interruptSignal: interruptController.signal,
|
|
163
|
+
allowIntercomDetach: taskAgentConfig?.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
164
|
+
intercomEvents: input.intercomEvents,
|
|
165
|
+
runId: input.runId,
|
|
166
|
+
index: input.globalTaskIndex + taskIndex,
|
|
167
|
+
sessionDir: input.sessionDirForIndex(input.globalTaskIndex + taskIndex),
|
|
168
|
+
sessionFile: input.sessionFileForTask?.(task.agent, input.globalTaskIndex + taskIndex) ?? input.sessionFileForIndex?.(input.globalTaskIndex + taskIndex),
|
|
169
|
+
thinkingOverride: input.thinkingOverrideForTask?.(task.agent, input.globalTaskIndex + taskIndex),
|
|
170
|
+
share: input.shareEnabled,
|
|
171
|
+
artifactsDir: input.artifactConfig.enabled ? input.artifactsDir : undefined,
|
|
172
|
+
artifactConfig: input.artifactConfig,
|
|
173
|
+
outputPath,
|
|
174
|
+
outputMode: behavior.outputMode,
|
|
175
|
+
maxSubagentDepth,
|
|
176
|
+
controlConfig: input.controlConfig,
|
|
177
|
+
onControlEvent: input.onControlEvent,
|
|
178
|
+
intercomSessionName: input.childIntercomTarget?.(task.agent, input.globalTaskIndex + taskIndex),
|
|
179
|
+
orchestratorIntercomTarget: input.orchestratorIntercomTarget,
|
|
180
|
+
nestedRoute: input.nestedRoute,
|
|
181
|
+
modelOverride: effectiveModel,
|
|
182
|
+
availableModels: input.availableModels,
|
|
183
|
+
preferredModelProvider: input.ctx.model?.provider,
|
|
184
|
+
modelScope: input.modelScope,
|
|
185
|
+
skills: behavior.skills === false ? [] : behavior.skills,
|
|
186
|
+
structuredOutput: structuredRuntime,
|
|
187
|
+
acceptance: task.acceptance,
|
|
188
|
+
acceptanceContext: { mode: "chain" },
|
|
189
|
+
timeoutMs: input.timeoutMs,
|
|
190
|
+
deadlineAt: input.deadlineAt,
|
|
191
|
+
turnBudget: input.turnBudget,
|
|
192
|
+
onDetachedExit: input.onDetachedExit ? (result) => input.onDetachedExit?.(input.globalTaskIndex + taskIndex, result) : undefined,
|
|
193
|
+
toolBudget: toolBudget.toolBudget,
|
|
194
|
+
onUpdate: input.onUpdate ? (progressUpdate) => {
|
|
195
|
+
const stepResults = progressUpdate.details?.results || [];
|
|
196
|
+
const stepProgress = progressUpdate.details?.progress || [];
|
|
197
|
+
if (input.foregroundControl && stepProgress.length > 0) {
|
|
198
|
+
const current = stepProgress[0];
|
|
199
|
+
input.foregroundControl.currentAgent = task.agent;
|
|
200
|
+
input.foregroundControl.currentIndex = input.globalTaskIndex + taskIndex;
|
|
201
|
+
input.foregroundControl.currentActivityState = current?.activityState;
|
|
202
|
+
input.foregroundControl.lastActivityAt = current?.lastActivityAt;
|
|
203
|
+
input.foregroundControl.currentTool = current?.currentTool;
|
|
204
|
+
input.foregroundControl.currentToolStartedAt = current?.currentToolStartedAt;
|
|
205
|
+
input.foregroundControl.currentPath = current?.currentPath;
|
|
206
|
+
input.foregroundControl.turnCount = current?.turnCount;
|
|
207
|
+
input.foregroundControl.tokens = current?.tokens;
|
|
208
|
+
input.foregroundControl.toolCount = current?.toolCount;
|
|
209
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
210
|
+
}
|
|
211
|
+
input.onUpdate?.({
|
|
212
|
+
...progressUpdate,
|
|
213
|
+
details: {
|
|
214
|
+
mode: "chain",
|
|
215
|
+
results: input.results.concat(stepResults),
|
|
216
|
+
progress: input.allProgress.concat(stepProgress),
|
|
217
|
+
controlEvents: progressUpdate.details?.controlEvents,
|
|
218
|
+
chainAgents: input.chainAgents,
|
|
219
|
+
totalSteps: input.totalSteps,
|
|
220
|
+
currentStepIndex: input.stepIndex,
|
|
221
|
+
outputs: input.outputs,
|
|
222
|
+
workflowGraph: buildWorkflowGraphSnapshot({
|
|
223
|
+
runId: input.runId,
|
|
224
|
+
mode: "chain",
|
|
225
|
+
steps: input.chainSteps,
|
|
226
|
+
results: input.results.concat(stepResults),
|
|
227
|
+
currentStepIndex: input.stepIndex,
|
|
228
|
+
currentFlatIndex: input.globalTaskIndex + taskIndex,
|
|
229
|
+
dynamicChildren: input.dynamicChildren,
|
|
230
|
+
dynamicGroupStatuses: input.dynamicGroupStatuses
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
} : undefined
|
|
235
|
+
});
|
|
236
|
+
if (input.foregroundControl?.currentIndex === input.globalTaskIndex + taskIndex) {
|
|
237
|
+
input.foregroundControl.interrupt = undefined;
|
|
238
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
239
|
+
}
|
|
240
|
+
if (result.exitCode !== 0 && failFast) {
|
|
241
|
+
aborted = true;
|
|
242
|
+
}
|
|
243
|
+
recordRun(task.agent, cleanTask, result.exitCode, result.progressSummary?.durationMs ?? 0);
|
|
244
|
+
return result;
|
|
245
|
+
}, input.globalSemaphore);
|
|
246
|
+
return parallelResults;
|
|
247
|
+
}
|
|
248
|
+
export async function executeChain(params) {
|
|
249
|
+
const {
|
|
250
|
+
chain: chainSteps,
|
|
251
|
+
agents,
|
|
252
|
+
ctx,
|
|
253
|
+
signal,
|
|
254
|
+
runId,
|
|
255
|
+
cwd,
|
|
256
|
+
shareEnabled,
|
|
257
|
+
sessionDirForIndex,
|
|
258
|
+
sessionFileForIndex,
|
|
259
|
+
sessionFileForTask,
|
|
260
|
+
thinkingOverrideForTask,
|
|
261
|
+
artifactsDir,
|
|
262
|
+
artifactConfig,
|
|
263
|
+
includeProgress,
|
|
264
|
+
clarify,
|
|
265
|
+
onUpdate,
|
|
266
|
+
onControlEvent,
|
|
267
|
+
controlConfig,
|
|
268
|
+
onDetachedExit,
|
|
269
|
+
childIntercomTarget,
|
|
270
|
+
orchestratorIntercomTarget,
|
|
271
|
+
foregroundControl,
|
|
272
|
+
intercomEvents,
|
|
273
|
+
chainSkills: chainSkillsParam,
|
|
274
|
+
chainDir: chainDirBase,
|
|
275
|
+
modelScope
|
|
276
|
+
} = params;
|
|
277
|
+
const chainSkills = chainSkillsParam ?? [];
|
|
278
|
+
const results = [];
|
|
279
|
+
const outputs = {};
|
|
280
|
+
const dynamicChildren = {};
|
|
281
|
+
const dynamicGroupStatuses = {};
|
|
282
|
+
const allProgress = [];
|
|
283
|
+
const allArtifactPaths = [];
|
|
284
|
+
const chainAgents = chainSteps.map((step) => isParallelStep(step) ? `[${step.parallel.map((t) => t.agent).join("+")}]` : isDynamicParallelStep(step) ? `expand:${step.parallel.agent}` : step.agent);
|
|
285
|
+
const totalSteps = chainSteps.length;
|
|
286
|
+
const makeDetailsInput = (overrides = {}) => ({
|
|
287
|
+
results,
|
|
288
|
+
...includeProgress !== undefined ? { includeProgress } : {},
|
|
289
|
+
allProgress,
|
|
290
|
+
allArtifactPaths,
|
|
291
|
+
artifactsDir,
|
|
292
|
+
chainAgents,
|
|
293
|
+
chainSteps,
|
|
294
|
+
totalSteps,
|
|
295
|
+
runId,
|
|
296
|
+
outputs,
|
|
297
|
+
dynamicChildren,
|
|
298
|
+
dynamicGroupStatuses,
|
|
299
|
+
...overrides
|
|
300
|
+
});
|
|
301
|
+
const firstStep = chainSteps[0];
|
|
302
|
+
const originalTask = params.task ?? (isParallelStep(firstStep) ? firstStep.parallel[0].task : isDynamicParallelStep(firstStep) ? firstStep.parallel.task : firstStep.task);
|
|
303
|
+
try {
|
|
304
|
+
validateChainOutputBindings(chainSteps, { maxItems: params.dynamicFanoutMaxItems });
|
|
305
|
+
} catch (error) {
|
|
306
|
+
if (error instanceof ChainOutputValidationError) {
|
|
307
|
+
return {
|
|
308
|
+
content: [{ type: "text", text: error.message }],
|
|
309
|
+
isError: true,
|
|
310
|
+
details: buildChainExecutionDetails(makeDetailsInput())
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
const chainDir = createChainDir(runId, chainDirBase);
|
|
316
|
+
const hasParallelSteps = chainSteps.some((step) => isParallelStep(step) || isDynamicParallelStep(step));
|
|
317
|
+
let templates = resolveChainTemplates(chainSteps);
|
|
318
|
+
const shouldClarify = clarify === true && ctx.hasUI && !hasParallelSteps;
|
|
319
|
+
let tuiBehaviorOverrides;
|
|
320
|
+
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
321
|
+
const availableSkills = discoverAvailableSkills(cwd ?? ctx.cwd);
|
|
322
|
+
if (shouldClarify) {
|
|
323
|
+
const seqSteps = chainSteps;
|
|
324
|
+
const agentConfigs = [];
|
|
325
|
+
for (const step of seqSteps) {
|
|
326
|
+
const config = agents.find((a) => a.name === step.agent);
|
|
327
|
+
if (!config) {
|
|
328
|
+
removeChainDir(chainDir);
|
|
329
|
+
return {
|
|
330
|
+
content: [{ type: "text", text: `Unknown agent: ${step.agent}` }],
|
|
331
|
+
isError: true,
|
|
332
|
+
details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: seqSteps.indexOf(step) }))
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
agentConfigs.push(config);
|
|
336
|
+
}
|
|
337
|
+
const stepOverrides = seqSteps.map((step) => ({
|
|
338
|
+
output: step.output,
|
|
339
|
+
outputMode: step.outputMode,
|
|
340
|
+
reads: step.reads,
|
|
341
|
+
progress: step.progress,
|
|
342
|
+
skills: normalizeSkillInput(step.skill),
|
|
343
|
+
model: step.model
|
|
344
|
+
}));
|
|
345
|
+
const resolvedBehaviors = agentConfigs.map((config, i) => resolveStepBehavior(config, stepOverrides[i], chainSkills));
|
|
346
|
+
const flatTemplates = templates;
|
|
347
|
+
const result = await ctx.ui.custom((tui, theme, _kb, done) => new ChainClarifyComponent(tui, theme, agentConfigs, flatTemplates, originalTask, chainDir, resolvedBehaviors, availableModels, ctx.model?.provider, availableSkills, done), {
|
|
348
|
+
overlay: true,
|
|
349
|
+
overlayOptions: { anchor: "center", width: 84, maxHeight: "80%" }
|
|
350
|
+
});
|
|
351
|
+
if (!result || !result.confirmed) {
|
|
352
|
+
removeChainDir(chainDir);
|
|
353
|
+
return {
|
|
354
|
+
content: [{ type: "text", text: "Chain cancelled" }],
|
|
355
|
+
details: buildChainExecutionDetails(makeDetailsInput())
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (result.runInBackground) {
|
|
359
|
+
removeChainDir(chainDir);
|
|
360
|
+
const updatedChain = chainSteps.map((step, i) => {
|
|
361
|
+
if (isParallelStep(step))
|
|
362
|
+
return step;
|
|
363
|
+
const override = result.behaviorOverrides[i];
|
|
364
|
+
return {
|
|
365
|
+
...step,
|
|
366
|
+
task: result.templates[i],
|
|
367
|
+
...override?.model ? { model: override.model } : {},
|
|
368
|
+
...override?.output !== undefined ? { output: override.output } : {},
|
|
369
|
+
..."outputMode" in step && step.outputMode !== undefined ? { outputMode: step.outputMode } : {},
|
|
370
|
+
...override?.reads !== undefined ? { reads: override.reads } : {},
|
|
371
|
+
...override?.progress !== undefined ? { progress: override.progress } : {},
|
|
372
|
+
...override?.skills !== undefined ? { skill: override.skills } : {}
|
|
373
|
+
};
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
content: [{ type: "text", text: "Launching in background..." }],
|
|
377
|
+
details: buildChainExecutionDetails(makeDetailsInput()),
|
|
378
|
+
requestedAsync: { chain: updatedChain, chainSkills }
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
templates = result.templates;
|
|
382
|
+
tuiBehaviorOverrides = result.behaviorOverrides;
|
|
383
|
+
}
|
|
384
|
+
const deadlineAt = params.deadlineAt ?? (params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined);
|
|
385
|
+
const globalSemaphore = new Semaphore(params.globalConcurrencyLimit ?? DEFAULT_GLOBAL_CONCURRENCY_LIMIT);
|
|
386
|
+
let prev = "";
|
|
387
|
+
let globalTaskIndex = 0;
|
|
388
|
+
let progressCreated = false;
|
|
389
|
+
for (let stepIndex = 0;stepIndex < chainSteps.length; stepIndex++) {
|
|
390
|
+
const step = chainSteps[stepIndex];
|
|
391
|
+
const stepTemplates = templates[stepIndex];
|
|
392
|
+
if (isParallelStep(step)) {
|
|
393
|
+
const parallelTemplates = stepTemplates;
|
|
394
|
+
const parallelCwd = resolveChildCwd(cwd ?? ctx.cwd, step.cwd);
|
|
395
|
+
let worktreeSetup;
|
|
396
|
+
if (step.worktree) {
|
|
397
|
+
const worktreeTaskCwdConflict = findWorktreeTaskCwdConflict(step.parallel, parallelCwd);
|
|
398
|
+
if (worktreeTaskCwdConflict) {
|
|
399
|
+
return buildChainExecutionErrorResult(`parallel chain step ${stepIndex + 1}: ${formatWorktreeTaskCwdConflict(worktreeTaskCwdConflict, parallelCwd)}`, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
400
|
+
}
|
|
401
|
+
try {
|
|
402
|
+
worktreeSetup = createWorktrees(parallelCwd, `${runId}-s${stepIndex}`, step.parallel.length, {
|
|
403
|
+
agents: step.parallel.map((task) => task.agent),
|
|
404
|
+
setupHook: params.worktreeSetupHook ? { hookPath: params.worktreeSetupHook, timeoutMs: params.worktreeSetupHookTimeoutMs } : undefined,
|
|
405
|
+
baseDir: params.worktreeBaseDir
|
|
406
|
+
});
|
|
407
|
+
} catch (error) {
|
|
408
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
409
|
+
return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
const agentNames = step.parallel.map((task) => task.agent);
|
|
414
|
+
const parallelBehaviors = resolveParallelBehaviors(step.parallel, agents, stepIndex, chainSkills).map((behavior, taskIndex) => suppressProgressForReadOnlyTask(behavior, parallelTemplates[taskIndex] ?? step.parallel[taskIndex]?.task, originalTask));
|
|
415
|
+
for (let taskIndex = 0;taskIndex < step.parallel.length; taskIndex++) {
|
|
416
|
+
const behavior = parallelBehaviors[taskIndex];
|
|
417
|
+
const outputPath = typeof behavior.output === "string" ? path.isAbsolute(behavior.output) ? behavior.output : path.join(chainDir, behavior.output) : undefined;
|
|
418
|
+
const validationError = validateFileOnlyOutputMode(behavior.outputMode, outputPath, `Parallel chain step ${stepIndex + 1} task ${taskIndex + 1} (${step.parallel[taskIndex].agent})`);
|
|
419
|
+
if (validationError)
|
|
420
|
+
return buildChainExecutionErrorResult(validationError, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex + taskIndex }));
|
|
421
|
+
}
|
|
422
|
+
progressCreated = ensureParallelProgressFile(chainDir, progressCreated, parallelBehaviors);
|
|
423
|
+
createParallelDirs(chainDir, stepIndex, step.parallel.length, agentNames);
|
|
424
|
+
const parallelResults = await runParallelChainTasks({
|
|
425
|
+
step,
|
|
426
|
+
parallelTemplates,
|
|
427
|
+
parallelBehaviors,
|
|
428
|
+
agents,
|
|
429
|
+
stepIndex,
|
|
430
|
+
availableModels,
|
|
431
|
+
modelScope,
|
|
432
|
+
chainDir,
|
|
433
|
+
prev,
|
|
434
|
+
originalTask,
|
|
435
|
+
ctx,
|
|
436
|
+
intercomEvents,
|
|
437
|
+
cwd,
|
|
438
|
+
runId,
|
|
439
|
+
globalTaskIndex,
|
|
440
|
+
sessionDirForIndex,
|
|
441
|
+
sessionFileForIndex,
|
|
442
|
+
sessionFileForTask,
|
|
443
|
+
thinkingOverrideForTask,
|
|
444
|
+
shareEnabled,
|
|
445
|
+
artifactConfig,
|
|
446
|
+
artifactsDir,
|
|
447
|
+
signal,
|
|
448
|
+
onUpdate,
|
|
449
|
+
results,
|
|
450
|
+
allProgress,
|
|
451
|
+
outputs,
|
|
452
|
+
chainAgents,
|
|
453
|
+
chainSteps,
|
|
454
|
+
totalSteps,
|
|
455
|
+
dynamicChildren,
|
|
456
|
+
dynamicGroupStatuses,
|
|
457
|
+
controlConfig,
|
|
458
|
+
onControlEvent,
|
|
459
|
+
childIntercomTarget,
|
|
460
|
+
orchestratorIntercomTarget,
|
|
461
|
+
foregroundControl,
|
|
462
|
+
nestedRoute: params.nestedRoute,
|
|
463
|
+
worktreeSetup,
|
|
464
|
+
maxSubagentDepth: params.maxSubagentDepth,
|
|
465
|
+
timeoutMs: params.timeoutMs,
|
|
466
|
+
deadlineAt,
|
|
467
|
+
turnBudget: params.turnBudget,
|
|
468
|
+
onDetachedExit,
|
|
469
|
+
toolBudget: params.toolBudget,
|
|
470
|
+
configToolBudget: params.configToolBudget,
|
|
471
|
+
globalSemaphore
|
|
472
|
+
});
|
|
473
|
+
globalTaskIndex += step.parallel.length;
|
|
474
|
+
for (const result of parallelResults) {
|
|
475
|
+
results.push(result);
|
|
476
|
+
if (result.progress)
|
|
477
|
+
allProgress.push(result.progress);
|
|
478
|
+
if (result.artifactPaths)
|
|
479
|
+
allArtifactPaths.push(result.artifactPaths);
|
|
480
|
+
}
|
|
481
|
+
const interruptedIndexInStep = parallelResults.findIndex((result) => result.interrupted);
|
|
482
|
+
const interrupted = interruptedIndexInStep >= 0 ? parallelResults[interruptedIndexInStep] : undefined;
|
|
483
|
+
if (interrupted) {
|
|
484
|
+
return {
|
|
485
|
+
content: [{ type: "text", text: `Chain paused after interrupt at step ${stepIndex + 1} (${interrupted.agent}). Waiting for explicit next action.` }],
|
|
486
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
487
|
+
currentStepIndex: stepIndex,
|
|
488
|
+
currentFlatIndex: globalTaskIndex - step.parallel.length + interruptedIndexInStep
|
|
489
|
+
}))
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
const detachedIndexInStep = parallelResults.findIndex((result) => result.detached);
|
|
493
|
+
const detached = detachedIndexInStep >= 0 ? parallelResults[detachedIndexInStep] : undefined;
|
|
494
|
+
if (detached) {
|
|
495
|
+
return {
|
|
496
|
+
content: [{ type: "text", text: `Chain detached for intercom coordination at step ${stepIndex + 1} (${detached.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
|
|
497
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
498
|
+
currentStepIndex: stepIndex,
|
|
499
|
+
currentFlatIndex: globalTaskIndex - step.parallel.length + detachedIndexInStep
|
|
500
|
+
}))
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
const failures = parallelResults.map((result, originalIndex) => ({ ...result, originalIndex })).filter((result) => result.exitCode !== 0 && result.exitCode !== -1);
|
|
504
|
+
if (failures.length > 0) {
|
|
505
|
+
const failureSummary = failures.map((failure) => `- Task ${failure.originalIndex + 1} (${failure.agent}): ${failure.error || "failed"}`).join(`
|
|
506
|
+
`);
|
|
507
|
+
const errorMsg = `Parallel step ${stepIndex + 1} failed:
|
|
508
|
+
${failureSummary}`;
|
|
509
|
+
const summary = buildChainSummary(chainSteps, results, chainDir, "failed", {
|
|
510
|
+
index: stepIndex,
|
|
511
|
+
error: errorMsg
|
|
512
|
+
});
|
|
513
|
+
return {
|
|
514
|
+
content: [{ type: "text", text: summary }],
|
|
515
|
+
isError: true,
|
|
516
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
517
|
+
currentStepIndex: stepIndex,
|
|
518
|
+
currentFlatIndex: globalTaskIndex - step.parallel.length + failures[0].originalIndex
|
|
519
|
+
}))
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
for (let taskIndex = 0;taskIndex < parallelResults.length; taskIndex++) {
|
|
523
|
+
const outputName = step.parallel[taskIndex]?.as;
|
|
524
|
+
if (outputName)
|
|
525
|
+
outputs[outputName] = outputEntryFromResult(parallelResults[taskIndex], stepIndex);
|
|
526
|
+
}
|
|
527
|
+
const taskResults = parallelResults.map((result, i) => {
|
|
528
|
+
const outputTarget = parallelBehaviors[i]?.output;
|
|
529
|
+
const outputTargetPath = typeof outputTarget === "string" ? path.isAbsolute(outputTarget) ? outputTarget : path.join(chainDir, outputTarget) : undefined;
|
|
530
|
+
return {
|
|
531
|
+
agent: result.agent,
|
|
532
|
+
taskIndex: i,
|
|
533
|
+
output: getSingleResultOutput(result),
|
|
534
|
+
exitCode: result.exitCode,
|
|
535
|
+
error: result.error,
|
|
536
|
+
timedOut: result.timedOut,
|
|
537
|
+
outputTargetPath,
|
|
538
|
+
outputTargetExists: outputTargetPath ? fs.existsSync(outputTargetPath) : undefined
|
|
539
|
+
};
|
|
540
|
+
});
|
|
541
|
+
prev = aggregateParallelOutputs(taskResults);
|
|
542
|
+
prev = appendParallelWorktreeSummary(prev, worktreeSetup, path.join(chainDir, "worktree-diffs", `step-${stepIndex}`), agentNames);
|
|
543
|
+
} finally {
|
|
544
|
+
if (worktreeSetup)
|
|
545
|
+
cleanupWorktrees(worktreeSetup);
|
|
546
|
+
}
|
|
547
|
+
} else if (isDynamicParallelStep(step)) {
|
|
548
|
+
const dynamicStartIndex = globalTaskIndex;
|
|
549
|
+
const reservedDynamicItems = step.expand.maxItems ?? params.dynamicFanoutMaxItems ?? 0;
|
|
550
|
+
let materialized;
|
|
551
|
+
try {
|
|
552
|
+
materialized = materializeDynamicParallelStep(step, outputs, stepIndex, { maxItems: params.dynamicFanoutMaxItems });
|
|
553
|
+
} catch (error) {
|
|
554
|
+
const message = error instanceof DynamicFanoutError ? error.message : error instanceof Error ? error.message : String(error);
|
|
555
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: message };
|
|
556
|
+
return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
557
|
+
}
|
|
558
|
+
dynamicChildren[stepIndex] = materialized.items.map((item, itemIndex) => ({
|
|
559
|
+
agent: step.parallel.agent,
|
|
560
|
+
label: materialized.parallel[itemIndex]?.label,
|
|
561
|
+
flatIndex: globalTaskIndex + itemIndex,
|
|
562
|
+
itemKey: item.key,
|
|
563
|
+
structured: Boolean(step.parallel.outputSchema)
|
|
564
|
+
}));
|
|
565
|
+
if (materialized.parallel.length === 0) {
|
|
566
|
+
const collection = [];
|
|
567
|
+
try {
|
|
568
|
+
validateDynamicCollection(step.collect.outputSchema, collection);
|
|
569
|
+
} catch (error) {
|
|
570
|
+
const message = error instanceof DynamicFanoutError ? error.message : error instanceof Error ? error.message : String(error);
|
|
571
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: message };
|
|
572
|
+
return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
573
|
+
}
|
|
574
|
+
outputs[step.collect.as] = {
|
|
575
|
+
text: JSON.stringify(collection),
|
|
576
|
+
structured: collection,
|
|
577
|
+
agent: step.parallel.agent,
|
|
578
|
+
stepIndex
|
|
579
|
+
};
|
|
580
|
+
dynamicGroupStatuses[stepIndex] = { status: "completed" };
|
|
581
|
+
if (step.acceptance !== undefined) {
|
|
582
|
+
const effectiveGroupAcceptance = resolveEffectiveAcceptance({
|
|
583
|
+
explicit: step.acceptance,
|
|
584
|
+
agentName: step.parallel.agent,
|
|
585
|
+
task: step.parallel.task ?? originalTask,
|
|
586
|
+
mode: "chain",
|
|
587
|
+
dynamicGroup: true
|
|
588
|
+
});
|
|
589
|
+
const groupAcceptance = await evaluateAcceptance({
|
|
590
|
+
acceptance: effectiveGroupAcceptance,
|
|
591
|
+
output: "",
|
|
592
|
+
report: aggregateAcceptanceReport({
|
|
593
|
+
results: [],
|
|
594
|
+
notes: "Dynamic fanout produced 0 results."
|
|
595
|
+
}),
|
|
596
|
+
cwd: cwd ?? ctx.cwd
|
|
597
|
+
});
|
|
598
|
+
dynamicGroupStatuses[stepIndex].acceptance = groupAcceptance;
|
|
599
|
+
const groupAcceptanceFailure = acceptanceFailureMessage(groupAcceptance);
|
|
600
|
+
if (groupAcceptanceFailure) {
|
|
601
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: groupAcceptanceFailure, acceptance: groupAcceptance };
|
|
602
|
+
return buildChainExecutionErrorResult(groupAcceptanceFailure, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
prev = "Dynamic fanout produced 0 results.";
|
|
606
|
+
globalTaskIndex = dynamicStartIndex + reservedDynamicItems;
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
const dynamicParallelStep = {
|
|
610
|
+
parallel: materialized.parallel,
|
|
611
|
+
concurrency: step.concurrency,
|
|
612
|
+
failFast: step.failFast
|
|
613
|
+
};
|
|
614
|
+
const parallelTemplates = materialized.parallel.map((task) => task.task ?? "{previous}");
|
|
615
|
+
const parallelBehaviors = resolveParallelBehaviors(dynamicParallelStep.parallel, agents, stepIndex, chainSkills).map((behavior, taskIndex) => suppressProgressForReadOnlyTask(behavior, parallelTemplates[taskIndex] ?? dynamicParallelStep.parallel[taskIndex]?.task, originalTask));
|
|
616
|
+
for (let taskIndex = 0;taskIndex < dynamicParallelStep.parallel.length; taskIndex++) {
|
|
617
|
+
const behavior = parallelBehaviors[taskIndex];
|
|
618
|
+
const outputPath = typeof behavior.output === "string" ? path.isAbsolute(behavior.output) ? behavior.output : path.join(chainDir, behavior.output) : undefined;
|
|
619
|
+
const validationError = validateFileOnlyOutputMode(behavior.outputMode, outputPath, `Dynamic chain step ${stepIndex + 1} item ${taskIndex + 1} (${dynamicParallelStep.parallel[taskIndex].agent})`);
|
|
620
|
+
if (validationError) {
|
|
621
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: validationError };
|
|
622
|
+
return buildChainExecutionErrorResult(validationError, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex + taskIndex }));
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
progressCreated = ensureParallelProgressFile(chainDir, progressCreated, parallelBehaviors);
|
|
626
|
+
createParallelDirs(chainDir, stepIndex, dynamicParallelStep.parallel.length, dynamicParallelStep.parallel.map((task) => task.agent));
|
|
627
|
+
const parallelResults = await runParallelChainTasks({
|
|
628
|
+
step: dynamicParallelStep,
|
|
629
|
+
parallelTemplates,
|
|
630
|
+
parallelBehaviors,
|
|
631
|
+
agents,
|
|
632
|
+
stepIndex,
|
|
633
|
+
availableModels,
|
|
634
|
+
modelScope,
|
|
635
|
+
chainDir,
|
|
636
|
+
prev,
|
|
637
|
+
originalTask,
|
|
638
|
+
ctx,
|
|
639
|
+
intercomEvents,
|
|
640
|
+
cwd,
|
|
641
|
+
runId,
|
|
642
|
+
globalTaskIndex,
|
|
643
|
+
sessionDirForIndex,
|
|
644
|
+
sessionFileForIndex,
|
|
645
|
+
sessionFileForTask,
|
|
646
|
+
thinkingOverrideForTask,
|
|
647
|
+
shareEnabled,
|
|
648
|
+
artifactConfig,
|
|
649
|
+
artifactsDir,
|
|
650
|
+
signal,
|
|
651
|
+
onUpdate,
|
|
652
|
+
results,
|
|
653
|
+
allProgress,
|
|
654
|
+
outputs,
|
|
655
|
+
chainAgents,
|
|
656
|
+
chainSteps,
|
|
657
|
+
totalSteps,
|
|
658
|
+
dynamicChildren,
|
|
659
|
+
dynamicGroupStatuses,
|
|
660
|
+
controlConfig,
|
|
661
|
+
onControlEvent,
|
|
662
|
+
childIntercomTarget,
|
|
663
|
+
orchestratorIntercomTarget,
|
|
664
|
+
foregroundControl,
|
|
665
|
+
nestedRoute: params.nestedRoute,
|
|
666
|
+
maxSubagentDepth: params.maxSubagentDepth,
|
|
667
|
+
timeoutMs: params.timeoutMs,
|
|
668
|
+
deadlineAt,
|
|
669
|
+
turnBudget: params.turnBudget,
|
|
670
|
+
onDetachedExit,
|
|
671
|
+
toolBudget: params.toolBudget,
|
|
672
|
+
configToolBudget: params.configToolBudget,
|
|
673
|
+
globalSemaphore
|
|
674
|
+
});
|
|
675
|
+
globalTaskIndex = dynamicStartIndex + reservedDynamicItems;
|
|
676
|
+
for (const result of parallelResults) {
|
|
677
|
+
results.push(result);
|
|
678
|
+
if (result.progress)
|
|
679
|
+
allProgress.push(result.progress);
|
|
680
|
+
if (result.artifactPaths)
|
|
681
|
+
allArtifactPaths.push(result.artifactPaths);
|
|
682
|
+
}
|
|
683
|
+
const collected = collectDynamicResults(step, materialized.items, parallelResults);
|
|
684
|
+
const interruptedIndexInStep = parallelResults.findIndex((result) => result.interrupted);
|
|
685
|
+
const interrupted = interruptedIndexInStep >= 0 ? parallelResults[interruptedIndexInStep] : undefined;
|
|
686
|
+
if (interrupted) {
|
|
687
|
+
return {
|
|
688
|
+
content: [{ type: "text", text: `Chain paused after interrupt at step ${stepIndex + 1} (${interrupted.agent}). Waiting for explicit next action.` }],
|
|
689
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
690
|
+
currentStepIndex: stepIndex,
|
|
691
|
+
currentFlatIndex: dynamicStartIndex + interruptedIndexInStep
|
|
692
|
+
}))
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
const detachedIndexInStep = parallelResults.findIndex((result) => result.detached);
|
|
696
|
+
const detached = detachedIndexInStep >= 0 ? parallelResults[detachedIndexInStep] : undefined;
|
|
697
|
+
if (detached) {
|
|
698
|
+
return {
|
|
699
|
+
content: [{ type: "text", text: `Chain detached for intercom coordination at step ${stepIndex + 1} (${detached.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
|
|
700
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
701
|
+
currentStepIndex: stepIndex,
|
|
702
|
+
currentFlatIndex: dynamicStartIndex + detachedIndexInStep
|
|
703
|
+
}))
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
const failures = parallelResults.map((result, originalIndex) => ({ ...result, originalIndex })).filter((result) => result.exitCode !== 0 && result.exitCode !== -1);
|
|
707
|
+
if (failures.length > 0) {
|
|
708
|
+
const failureSummary = failures.map((failure) => `- Item ${failure.originalIndex + 1} (${failure.agent}, key ${materialized.items[failure.originalIndex]?.key ?? failure.originalIndex}): ${failure.error || "failed"}`).join(`
|
|
709
|
+
`);
|
|
710
|
+
const errorMsg = `Dynamic step ${stepIndex + 1} failed:
|
|
711
|
+
${failureSummary}`;
|
|
712
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: errorMsg };
|
|
713
|
+
const summary = buildChainSummary(chainSteps, results, chainDir, "failed", {
|
|
714
|
+
index: stepIndex,
|
|
715
|
+
error: errorMsg
|
|
716
|
+
});
|
|
717
|
+
return {
|
|
718
|
+
content: [{ type: "text", text: summary }],
|
|
719
|
+
isError: true,
|
|
720
|
+
details: buildChainExecutionDetails(makeDetailsInput({
|
|
721
|
+
currentStepIndex: stepIndex,
|
|
722
|
+
currentFlatIndex: dynamicStartIndex + failures[0].originalIndex
|
|
723
|
+
}))
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
try {
|
|
727
|
+
validateDynamicCollection(step.collect.outputSchema, collected);
|
|
728
|
+
} catch (error) {
|
|
729
|
+
const message = error instanceof DynamicFanoutError ? error.message : error instanceof Error ? error.message : String(error);
|
|
730
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: message };
|
|
731
|
+
return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: dynamicStartIndex }));
|
|
732
|
+
}
|
|
733
|
+
outputs[step.collect.as] = {
|
|
734
|
+
text: JSON.stringify(collected),
|
|
735
|
+
structured: collected,
|
|
736
|
+
agent: step.parallel.agent,
|
|
737
|
+
stepIndex
|
|
738
|
+
};
|
|
739
|
+
dynamicGroupStatuses[stepIndex] = { status: "completed" };
|
|
740
|
+
const effectiveGroupAcceptance = resolveEffectiveAcceptance({
|
|
741
|
+
explicit: step.acceptance,
|
|
742
|
+
agentName: step.parallel.agent,
|
|
743
|
+
task: step.parallel.task ?? originalTask,
|
|
744
|
+
mode: "chain",
|
|
745
|
+
dynamicGroup: true
|
|
746
|
+
});
|
|
747
|
+
const groupAcceptance = await evaluateAcceptance({
|
|
748
|
+
acceptance: effectiveGroupAcceptance,
|
|
749
|
+
output: "",
|
|
750
|
+
report: aggregateAcceptanceReport({
|
|
751
|
+
results: parallelResults,
|
|
752
|
+
notes: `Dynamic fanout collected ${collected.length} result(s) into ${step.collect.as}.`
|
|
753
|
+
}),
|
|
754
|
+
cwd: cwd ?? ctx.cwd
|
|
755
|
+
});
|
|
756
|
+
dynamicGroupStatuses[stepIndex].acceptance = groupAcceptance;
|
|
757
|
+
const groupAcceptanceFailure = acceptanceFailureMessage(groupAcceptance);
|
|
758
|
+
if (groupAcceptanceFailure) {
|
|
759
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: groupAcceptanceFailure, acceptance: groupAcceptance };
|
|
760
|
+
return buildChainExecutionErrorResult(groupAcceptanceFailure, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex - dynamicParallelStep.parallel.length }));
|
|
761
|
+
}
|
|
762
|
+
const taskResults = parallelResults.map((result, i) => ({
|
|
763
|
+
agent: result.agent,
|
|
764
|
+
taskIndex: i,
|
|
765
|
+
output: getSingleResultOutput(result),
|
|
766
|
+
exitCode: result.exitCode,
|
|
767
|
+
error: result.error,
|
|
768
|
+
timedOut: result.timedOut
|
|
769
|
+
}));
|
|
770
|
+
prev = aggregateParallelOutputs(taskResults, (i, agent) => `=== Dynamic Item ${i + 1} (${agent}, key ${materialized.items[i]?.key ?? i}) ===`);
|
|
771
|
+
} else {
|
|
772
|
+
const seqStep = step;
|
|
773
|
+
const stepTemplate = stepTemplates;
|
|
774
|
+
const agentConfig = agents.find((a) => a.name === seqStep.agent);
|
|
775
|
+
if (!agentConfig) {
|
|
776
|
+
removeChainDir(chainDir);
|
|
777
|
+
return {
|
|
778
|
+
content: [{ type: "text", text: `Unknown agent: ${seqStep.agent}` }],
|
|
779
|
+
isError: true,
|
|
780
|
+
details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }))
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
const tuiOverride = tuiBehaviorOverrides?.[stepIndex];
|
|
784
|
+
const stepOverride = {
|
|
785
|
+
output: tuiOverride?.output !== undefined ? tuiOverride.output : seqStep.output,
|
|
786
|
+
outputMode: seqStep.outputMode,
|
|
787
|
+
reads: tuiOverride?.reads !== undefined ? tuiOverride.reads : seqStep.reads,
|
|
788
|
+
progress: tuiOverride?.progress !== undefined ? tuiOverride.progress : seqStep.progress,
|
|
789
|
+
skills: tuiOverride?.skills !== undefined ? tuiOverride.skills : normalizeSkillInput(seqStep.skill)
|
|
790
|
+
};
|
|
791
|
+
const behavior = suppressProgressForReadOnlyTask(resolveStepBehavior(agentConfig, stepOverride, chainSkills), stepTemplate, originalTask);
|
|
792
|
+
const isFirstProgress = behavior.progress && !progressCreated;
|
|
793
|
+
if (isFirstProgress) {
|
|
794
|
+
progressCreated = true;
|
|
795
|
+
}
|
|
796
|
+
const templateHasPrevious = stepTemplate.includes("{previous}");
|
|
797
|
+
const { prefix, suffix } = buildChainInstructions(behavior, chainDir, isFirstProgress, templateHasPrevious ? undefined : prev);
|
|
798
|
+
let stepTask = resolveOutputReferences(stepTemplate, outputs);
|
|
799
|
+
stepTask = stepTask.replace(/\{task\}/g, originalTask);
|
|
800
|
+
stepTask = stepTask.replace(/\{previous\}/g, prev);
|
|
801
|
+
stepTask = stepTask.replace(/\{chain_dir\}/g, chainDir);
|
|
802
|
+
const cleanTask = stepTask;
|
|
803
|
+
stepTask = prefix + stepTask + suffix;
|
|
804
|
+
const explicitStepModel = tuiOverride?.model ?? seqStep.model;
|
|
805
|
+
const effectiveModel = resolveSubagentModelOverride(explicitStepModel ?? agentConfig.model, ctx.model, availableModels, ctx.model?.provider, { scope: modelScope, source: explicitStepModel ? "explicit" : "inherited" });
|
|
806
|
+
const outputPath = typeof behavior.output === "string" ? path.isAbsolute(behavior.output) ? behavior.output : path.join(chainDir, behavior.output) : undefined;
|
|
807
|
+
const validationError = validateFileOnlyOutputMode(behavior.outputMode, outputPath, `Chain step ${stepIndex + 1} (${seqStep.agent})`);
|
|
808
|
+
if (validationError) {
|
|
809
|
+
return buildChainExecutionErrorResult(validationError, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
810
|
+
}
|
|
811
|
+
const maxSubagentDepth = resolveChildMaxSubagentDepth(params.maxSubagentDepth, agentConfig.maxSubagentDepth);
|
|
812
|
+
const childIndex = globalTaskIndex;
|
|
813
|
+
const interruptController = new AbortController;
|
|
814
|
+
if (foregroundControl) {
|
|
815
|
+
foregroundControl.currentAgent = seqStep.agent;
|
|
816
|
+
foregroundControl.currentIndex = childIndex;
|
|
817
|
+
foregroundControl.currentActivityState = undefined;
|
|
818
|
+
foregroundControl.updatedAt = Date.now();
|
|
819
|
+
foregroundControl.interrupt = () => {
|
|
820
|
+
if (interruptController.signal.aborted)
|
|
821
|
+
return false;
|
|
822
|
+
interruptController.abort();
|
|
823
|
+
foregroundControl.currentActivityState = undefined;
|
|
824
|
+
foregroundControl.updatedAt = Date.now();
|
|
825
|
+
return true;
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
const structuredRuntime = seqStep.outputSchema ? createStructuredOutputRuntime(seqStep.outputSchema, path.join(chainDir, "structured-output")) : undefined;
|
|
829
|
+
const toolBudget = resolveChainToolBudget({ stepBudget: seqStep.toolBudget, runBudget: params.toolBudget, agentBudget: agentConfig?.toolBudget, configBudget: params.configToolBudget });
|
|
830
|
+
if (toolBudget.error)
|
|
831
|
+
return buildChainExecutionErrorResult(toolBudget.error, {
|
|
832
|
+
results,
|
|
833
|
+
includeProgress,
|
|
834
|
+
allProgress,
|
|
835
|
+
allArtifactPaths,
|
|
836
|
+
artifactsDir: params.artifactsDir,
|
|
837
|
+
chainAgents,
|
|
838
|
+
chainSteps,
|
|
839
|
+
totalSteps,
|
|
840
|
+
currentStepIndex: stepIndex,
|
|
841
|
+
runId: params.runId,
|
|
842
|
+
outputs,
|
|
843
|
+
currentFlatIndex: globalTaskIndex,
|
|
844
|
+
dynamicChildren,
|
|
845
|
+
dynamicGroupStatuses
|
|
846
|
+
});
|
|
847
|
+
const r = await runSync(ctx.cwd, agents, seqStep.agent, stepTask, {
|
|
848
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
849
|
+
cwd: resolveChildCwd(cwd ?? ctx.cwd, seqStep.cwd),
|
|
850
|
+
signal,
|
|
851
|
+
interruptSignal: interruptController.signal,
|
|
852
|
+
allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
853
|
+
intercomEvents,
|
|
854
|
+
runId,
|
|
855
|
+
index: childIndex,
|
|
856
|
+
sessionDir: sessionDirForIndex(childIndex),
|
|
857
|
+
sessionFile: sessionFileForTask?.(seqStep.agent, childIndex) ?? sessionFileForIndex?.(childIndex),
|
|
858
|
+
thinkingOverride: thinkingOverrideForTask?.(seqStep.agent, childIndex),
|
|
859
|
+
share: shareEnabled,
|
|
860
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
861
|
+
artifactConfig,
|
|
862
|
+
outputPath,
|
|
863
|
+
outputMode: behavior.outputMode,
|
|
864
|
+
maxSubagentDepth,
|
|
865
|
+
controlConfig,
|
|
866
|
+
onControlEvent,
|
|
867
|
+
intercomSessionName: childIntercomTarget?.(seqStep.agent, childIndex),
|
|
868
|
+
orchestratorIntercomTarget,
|
|
869
|
+
nestedRoute: params.nestedRoute,
|
|
870
|
+
modelOverride: effectiveModel,
|
|
871
|
+
availableModels,
|
|
872
|
+
preferredModelProvider: ctx.model?.provider,
|
|
873
|
+
modelScope,
|
|
874
|
+
skills: behavior.skills === false ? [] : behavior.skills,
|
|
875
|
+
structuredOutput: structuredRuntime,
|
|
876
|
+
acceptance: seqStep.acceptance,
|
|
877
|
+
acceptanceContext: { mode: "chain" },
|
|
878
|
+
timeoutMs: params.timeoutMs,
|
|
879
|
+
deadlineAt,
|
|
880
|
+
turnBudget: params.turnBudget,
|
|
881
|
+
onDetachedExit: onDetachedExit ? (result) => onDetachedExit(childIndex, result) : undefined,
|
|
882
|
+
toolBudget: toolBudget.toolBudget,
|
|
883
|
+
onUpdate: onUpdate ? (p) => {
|
|
884
|
+
const stepResults = p.details?.results || [];
|
|
885
|
+
const stepProgress = p.details?.progress || [];
|
|
886
|
+
if (foregroundControl && stepProgress.length > 0) {
|
|
887
|
+
const current = stepProgress[0];
|
|
888
|
+
foregroundControl.currentAgent = seqStep.agent;
|
|
889
|
+
foregroundControl.currentIndex = childIndex;
|
|
890
|
+
foregroundControl.currentActivityState = current?.activityState;
|
|
891
|
+
foregroundControl.lastActivityAt = current?.lastActivityAt;
|
|
892
|
+
foregroundControl.currentTool = current?.currentTool;
|
|
893
|
+
foregroundControl.currentToolStartedAt = current?.currentToolStartedAt;
|
|
894
|
+
foregroundControl.currentPath = current?.currentPath;
|
|
895
|
+
foregroundControl.turnCount = current?.turnCount;
|
|
896
|
+
foregroundControl.tokens = current?.tokens;
|
|
897
|
+
foregroundControl.toolCount = current?.toolCount;
|
|
898
|
+
foregroundControl.updatedAt = Date.now();
|
|
899
|
+
}
|
|
900
|
+
onUpdate({
|
|
901
|
+
...p,
|
|
902
|
+
details: {
|
|
903
|
+
mode: "chain",
|
|
904
|
+
results: results.concat(stepResults),
|
|
905
|
+
progress: allProgress.concat(stepProgress),
|
|
906
|
+
controlEvents: p.details?.controlEvents,
|
|
907
|
+
chainAgents,
|
|
908
|
+
totalSteps,
|
|
909
|
+
currentStepIndex: stepIndex,
|
|
910
|
+
outputs,
|
|
911
|
+
workflowGraph: buildWorkflowGraphSnapshot({
|
|
912
|
+
runId,
|
|
913
|
+
mode: "chain",
|
|
914
|
+
steps: chainSteps,
|
|
915
|
+
results: results.concat(stepResults),
|
|
916
|
+
currentStepIndex: stepIndex,
|
|
917
|
+
currentFlatIndex: childIndex,
|
|
918
|
+
dynamicChildren,
|
|
919
|
+
dynamicGroupStatuses
|
|
920
|
+
})
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
} : undefined
|
|
924
|
+
});
|
|
925
|
+
if (foregroundControl?.currentIndex === childIndex) {
|
|
926
|
+
foregroundControl.interrupt = undefined;
|
|
927
|
+
foregroundControl.updatedAt = Date.now();
|
|
928
|
+
}
|
|
929
|
+
recordRun(seqStep.agent, cleanTask, r.exitCode, r.progressSummary?.durationMs ?? 0);
|
|
930
|
+
globalTaskIndex++;
|
|
931
|
+
results.push(r);
|
|
932
|
+
if (r.progress)
|
|
933
|
+
allProgress.push(r.progress);
|
|
934
|
+
if (r.artifactPaths)
|
|
935
|
+
allArtifactPaths.push(r.artifactPaths);
|
|
936
|
+
if (r.interrupted) {
|
|
937
|
+
return {
|
|
938
|
+
content: [{ type: "text", text: `Chain paused after interrupt at step ${stepIndex + 1} (${r.agent}). Waiting for explicit next action.` }],
|
|
939
|
+
details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex }))
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
if (r.detached) {
|
|
943
|
+
return {
|
|
944
|
+
content: [{ type: "text", text: `Chain detached for intercom coordination at step ${stepIndex + 1} (${r.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
|
|
945
|
+
details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex }))
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
if (r.exitCode !== 0) {
|
|
949
|
+
const summary = buildChainSummary(chainSteps, results, chainDir, "failed", {
|
|
950
|
+
index: stepIndex,
|
|
951
|
+
error: r.error || "Chain failed"
|
|
952
|
+
});
|
|
953
|
+
return {
|
|
954
|
+
content: [{ type: "text", text: summary }],
|
|
955
|
+
details: buildChainExecutionDetails(makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: childIndex })),
|
|
956
|
+
isError: true
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
if (behavior.output) {
|
|
960
|
+
try {
|
|
961
|
+
const expectedPath = path.isAbsolute(behavior.output) ? behavior.output : path.join(chainDir, behavior.output);
|
|
962
|
+
if (!fs.existsSync(expectedPath)) {
|
|
963
|
+
const dirFiles = fs.readdirSync(chainDir);
|
|
964
|
+
const mdFiles = dirFiles.filter((file) => file.endsWith(".md") && file !== "progress.md");
|
|
965
|
+
const warning = mdFiles.length > 0 ? `Agent wrote to different file(s): ${mdFiles.join(", ")} instead of ${behavior.output}` : `Agent did not create expected output file: ${behavior.output}`;
|
|
966
|
+
r.error = r.error ? `${r.error}
|
|
967
|
+
${warning}` : warning;
|
|
968
|
+
}
|
|
969
|
+
} catch {}
|
|
970
|
+
}
|
|
971
|
+
if (seqStep.as)
|
|
972
|
+
outputs[seqStep.as] = outputEntryFromResult(r, stepIndex);
|
|
973
|
+
prev = getSingleResultOutput(r);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
const summary = buildChainSummary(chainSteps, results, chainDir, "completed");
|
|
977
|
+
return {
|
|
978
|
+
content: [{ type: "text", text: summary }],
|
|
979
|
+
details: buildChainExecutionDetails(makeDetailsInput())
|
|
980
|
+
};
|
|
981
|
+
}
|