@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,228 +1,3163 @@
|
|
|
1
|
-
import{randomUUID
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { getArtifactsDir, getProjectChainRunsDir } from "../../shared/artifacts.js";
|
|
5
|
+
import { ChainClarifyComponent } from "./chain-clarify.js";
|
|
6
|
+
import { toModelInfo } from "../../shared/model-info.js";
|
|
7
|
+
import { executeChain } from "./chain-execution.js";
|
|
8
|
+
import { resolveExecutionAgentScope } from "../../agents/agent-scope.js";
|
|
9
|
+
import { handleManagementAction } from "../../agents/agent-management.js";
|
|
10
|
+
import { buildDoctorReport } from "../../extension/doctor.js";
|
|
11
|
+
import { clearPendingForegroundControlNotices } from "../../extension/control-notices.js";
|
|
12
|
+
import { runSync } from "./execution.js";
|
|
13
|
+
import { resolveSubagentModelOverride } from "../shared/model-fallback.js";
|
|
14
|
+
import { aggregateParallelOutputs } from "../shared/parallel-utils.js";
|
|
15
|
+
import { recordRun } from "../shared/run-history.js";
|
|
16
|
+
import {
|
|
17
|
+
buildChainInstructions,
|
|
18
|
+
writeInitialProgressFile,
|
|
19
|
+
getStepAgents,
|
|
20
|
+
isParallelStep,
|
|
21
|
+
isDynamicParallelStep,
|
|
22
|
+
resolveStepBehavior,
|
|
23
|
+
suppressProgressForReadOnlyTask,
|
|
24
|
+
taskDisallowsFileUpdates
|
|
25
|
+
} from "../../shared/settings.js";
|
|
26
|
+
import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skills.js";
|
|
27
|
+
import { buildAsyncRunnerSteps, executeAsyncChain, executeAsyncSingle, formatAsyncStartedMessage, isAsyncAvailable } from "../background/async-execution.js";
|
|
28
|
+
import { enqueueChainAppendRequest, readPendingChainAppendRequests, runnerStepOutputNames } from "../background/chain-append.js";
|
|
29
|
+
import { ChainOutputValidationError, validateChainOutputBindingsWithContext } from "../shared/chain-outputs.js";
|
|
30
|
+
import { validateAcceptanceInput } from "../shared/acceptance.js";
|
|
31
|
+
import { createForkContextResolver } from "../../shared/fork-context.js";
|
|
32
|
+
import { resolveCurrentSessionId } from "../../shared/session-identity.js";
|
|
33
|
+
import { applyIntercomBridgeToAgent, INTERCOM_BRIDGE_MARKER, resolveIntercomBridge, resolveIntercomSessionTarget, resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.js";
|
|
34
|
+
import { formatControlIntercomMessage, formatControlNoticeMessage, resolveControlConfig, shouldNotifyControlEvent } from "../shared/subagent-control.js";
|
|
35
|
+
import { DEFAULT_TURN_BUDGET_GRACE_TURNS } from "../shared/turn-budget.js";
|
|
36
|
+
import { validateToolBudgetConfig } from "../shared/tool-budget.js";
|
|
37
|
+
import { finalizeSingleOutput, injectSingleOutputInstruction, normalizeSingleOutputOverride, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
|
|
38
|
+
import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, readStatus, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.js";
|
|
39
|
+
import { DEFAULT_GLOBAL_CONCURRENCY_LIMIT, Semaphore } from "../shared/parallel-utils.js";
|
|
40
|
+
import {
|
|
41
|
+
attachNestedChildrenToResultChildren,
|
|
42
|
+
buildSubagentResultIntercomPayload,
|
|
43
|
+
deliverSubagentIntercomMessageEvent,
|
|
44
|
+
deliverSubagentResultIntercomEvent,
|
|
45
|
+
formatSubagentResultReceipt,
|
|
46
|
+
resolveSubagentResultStatus,
|
|
47
|
+
stripDetailsOutputsForIntercomReceipt
|
|
48
|
+
} from "../../intercom/result-intercom.js";
|
|
49
|
+
import { buildRevivedAsyncTask, interruptLiveAsyncResumeTarget, resolveAsyncResumeTarget, resolveAsyncRunLocation } from "../background/async-resume.js";
|
|
50
|
+
import { deliverInterruptRequest, requestAsyncSteer } from "../background/control-channel.js";
|
|
51
|
+
import { reconcileAsyncRun } from "../background/stale-run-reconciler.js";
|
|
52
|
+
import { resolveAsyncRootResultPath } from "../background/chain-root-attachment.js";
|
|
53
|
+
import { attachRootChildrenToSteps, createNestedRoute, readNestedControlResults, resolveInheritedNestedRouteFromEnv, resolveNestedAsyncDir, resolveNestedParentAddressFromEnv, updateForegroundNestedProjection, writeNestedControlRequest, writeNestedEvent } from "../shared/nested-events.js";
|
|
54
|
+
import { resolveSubagentRunId } from "../background/run-id-resolver.js";
|
|
55
|
+
import { formatNestedRunStatusLines } from "../shared/nested-render.js";
|
|
56
|
+
import { inspectSubagentStatus } from "../background/run-status.js";
|
|
57
|
+
import { applyForceTopLevelAsyncOverride } from "../background/top-level-async.js";
|
|
58
|
+
import {
|
|
59
|
+
cleanupWorktrees,
|
|
60
|
+
createWorktrees,
|
|
61
|
+
diffWorktrees,
|
|
62
|
+
findWorktreeTaskCwdConflict,
|
|
63
|
+
formatWorktreeDiffSummary,
|
|
64
|
+
formatWorktreeTaskCwdConflict
|
|
65
|
+
} from "../shared/worktree.js";
|
|
66
|
+
import {
|
|
67
|
+
ASYNC_DIR,
|
|
68
|
+
DEFAULT_ARTIFACT_CONFIG,
|
|
69
|
+
RESULTS_DIR,
|
|
70
|
+
SUBAGENT_ACTIONS,
|
|
71
|
+
SUBAGENT_CONTROL_EVENT,
|
|
72
|
+
SUBAGENT_CONTROL_INTERCOM_EVENT,
|
|
73
|
+
checkSubagentDepth,
|
|
74
|
+
resolveMaxSubagentSpawnsPerSession,
|
|
75
|
+
resolveTopLevelParallelConcurrency,
|
|
76
|
+
resolveTopLevelParallelMaxTasks,
|
|
77
|
+
resolveChildMaxSubagentDepth,
|
|
78
|
+
resolveCurrentMaxSubagentDepth,
|
|
79
|
+
wrapForkTask
|
|
80
|
+
} from "../../shared/types.js";
|
|
81
|
+
const MUTATING_MANAGEMENT_ACTIONS = new Set(["create", "update", "delete", "eject", "disable", "enable", "reset"]);
|
|
82
|
+
function resolveRequestedCwd(runtimeCwd, requestedCwd) {
|
|
83
|
+
return requestedCwd ? path.resolve(runtimeCwd, requestedCwd) : runtimeCwd;
|
|
84
|
+
}
|
|
85
|
+
function getForegroundControl(state, runId) {
|
|
86
|
+
if (runId)
|
|
87
|
+
return state.foregroundControls.get(runId);
|
|
88
|
+
if (state.lastForegroundControlId) {
|
|
89
|
+
const latest = state.foregroundControls.get(state.lastForegroundControlId);
|
|
90
|
+
if (latest)
|
|
91
|
+
return latest;
|
|
92
|
+
}
|
|
93
|
+
let newest;
|
|
94
|
+
for (const control of state.foregroundControls.values()) {
|
|
95
|
+
if (!newest || control.updatedAt > newest.updatedAt)
|
|
96
|
+
newest = control;
|
|
97
|
+
}
|
|
98
|
+
return newest;
|
|
99
|
+
}
|
|
100
|
+
function formatForegroundActivity(control) {
|
|
101
|
+
const facts = [];
|
|
102
|
+
if (control.currentTool && control.currentToolStartedAt)
|
|
103
|
+
facts.push(`tool ${control.currentTool} for ${Math.floor(Math.max(0, Date.now() - control.currentToolStartedAt) / 1000)}s`);
|
|
104
|
+
else if (control.currentTool)
|
|
105
|
+
facts.push(`tool ${control.currentTool}`);
|
|
106
|
+
if (control.currentPath)
|
|
107
|
+
facts.push(`path ${control.currentPath}`);
|
|
108
|
+
if (control.turnCount !== undefined)
|
|
109
|
+
facts.push(`${control.turnCount} turns`);
|
|
110
|
+
if (control.tokens !== undefined)
|
|
111
|
+
facts.push(`${control.tokens} tokens`);
|
|
112
|
+
if (control.toolCount !== undefined)
|
|
113
|
+
facts.push(`${control.toolCount} tools`);
|
|
114
|
+
if (!control.lastActivityAt) {
|
|
115
|
+
if (control.currentActivityState === "needs_attention")
|
|
116
|
+
return ["needs attention", ...facts].join(" | ");
|
|
117
|
+
if (control.currentActivityState === "active_long_running")
|
|
118
|
+
return ["active but long-running", ...facts].join(" | ");
|
|
119
|
+
return facts.length ? facts.join(" | ") : undefined;
|
|
120
|
+
}
|
|
121
|
+
const seconds = Math.floor(Math.max(0, Date.now() - control.lastActivityAt) / 1000);
|
|
122
|
+
if (control.currentActivityState === "needs_attention")
|
|
123
|
+
return [`no activity for ${seconds}s`, ...facts].join(" | ");
|
|
124
|
+
if (control.currentActivityState === "active_long_running")
|
|
125
|
+
return [`active but long-running; last activity ${seconds}s ago`, ...facts].join(" | ");
|
|
126
|
+
return [`active ${seconds}s ago`, ...facts].join(" | ");
|
|
127
|
+
}
|
|
128
|
+
function nestedResolutionScopeForExecutor(deps) {
|
|
129
|
+
if (deps.allowMutatingManagementActions !== false)
|
|
130
|
+
return;
|
|
131
|
+
const route = resolveInheritedNestedRouteFromEnv();
|
|
132
|
+
const address = route ? resolveNestedParentAddressFromEnv() : undefined;
|
|
133
|
+
return {
|
|
134
|
+
routes: route ? [route] : [],
|
|
135
|
+
...address ? { descendantOf: { parentRunId: address.parentRunId, ...address.parentStepIndex !== undefined ? { parentStepIndex: address.parentStepIndex } : {} } } : {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function trustedSessionRootsForStatus(ctx, deps) {
|
|
139
|
+
const roots = deps.config.defaultSessionDir ? [path.resolve(deps.expandTilde(deps.config.defaultSessionDir))] : [];
|
|
140
|
+
const parentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
|
|
141
|
+
if (parentSessionFile)
|
|
142
|
+
roots.push(deps.getSubagentSessionRoot(parentSessionFile));
|
|
143
|
+
return [...new Set(roots)];
|
|
144
|
+
}
|
|
145
|
+
function reserveSubagentSpawns(input) {
|
|
146
|
+
if (input.requested <= 0)
|
|
147
|
+
return;
|
|
148
|
+
if (input.state.subagentSpawns?.sessionId !== input.sessionId) {
|
|
149
|
+
input.state.subagentSpawns = { sessionId: input.sessionId, count: 0 };
|
|
150
|
+
}
|
|
151
|
+
const maxSpawns = resolveMaxSubagentSpawnsPerSession(input.config.maxSubagentSpawnsPerSession);
|
|
152
|
+
const used = input.state.subagentSpawns.count;
|
|
153
|
+
if (used + input.requested > maxSpawns) {
|
|
154
|
+
return {
|
|
155
|
+
content: [{ type: "text", text: `Subagent spawn limit reached for this session (${used}/${maxSpawns} used, ${input.requested} requested). Complete the work directly or start a new session.` }],
|
|
156
|
+
isError: true,
|
|
157
|
+
details: { mode: input.mode, results: [] }
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
input.state.subagentSpawns.count = used + input.requested;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
function countRequestedSubagentSpawns(params, config) {
|
|
164
|
+
if (params.tasks)
|
|
165
|
+
return params.tasks.length;
|
|
166
|
+
if (params.chain) {
|
|
167
|
+
return params.chain.reduce((total, step) => {
|
|
168
|
+
if (isDynamicParallelStep(step))
|
|
169
|
+
return total + (step.expand.maxItems ?? config.chain?.dynamicFanout?.maxItems ?? 0);
|
|
170
|
+
return total + getStepAgents(step).length;
|
|
171
|
+
}, 0);
|
|
172
|
+
}
|
|
173
|
+
return params.agent ? 1 : 0;
|
|
174
|
+
}
|
|
175
|
+
function foregroundStatusResult(control) {
|
|
176
|
+
let nestedWarning;
|
|
177
|
+
try {
|
|
178
|
+
updateForegroundNestedProjection(control);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
nestedWarning = `Nested status unavailable: ${error instanceof Error ? error.message : String(error)}`;
|
|
181
|
+
}
|
|
182
|
+
const activity = formatForegroundActivity(control);
|
|
183
|
+
const lines = [
|
|
184
|
+
`Run: ${control.runId}`,
|
|
185
|
+
"State: running",
|
|
186
|
+
`Mode: ${control.mode}`,
|
|
187
|
+
control.currentAgent ? `Current: ${control.currentAgent}${control.currentIndex !== undefined ? ` step ${control.currentIndex + 1}` : ""}` : undefined,
|
|
188
|
+
activity ? `Activity: ${activity}` : undefined
|
|
189
|
+
].filter((line) => Boolean(line));
|
|
190
|
+
lines.push(...formatNestedRunStatusLines(control.nestedChildren, { indent: "", commandHints: true, maxLines: 20 }));
|
|
191
|
+
if (nestedWarning)
|
|
192
|
+
lines.push(`Warning: ${nestedWarning}`);
|
|
193
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
194
|
+
`) }], details: { mode: "management", results: [] } };
|
|
195
|
+
}
|
|
196
|
+
function trimRememberedForegroundRuns(state) {
|
|
197
|
+
if (!state.foregroundRuns)
|
|
198
|
+
return;
|
|
199
|
+
while (state.foregroundRuns.size > 50) {
|
|
200
|
+
const oldest = [...state.foregroundRuns.values()].sort((left, right) => left.updatedAt - right.updatedAt)[0];
|
|
201
|
+
if (!oldest)
|
|
202
|
+
break;
|
|
203
|
+
state.foregroundRuns.delete(oldest.runId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function rememberForegroundRun(state, input) {
|
|
207
|
+
state.foregroundRuns ??= new Map;
|
|
208
|
+
const previous = state.foregroundRuns.get(input.runId);
|
|
209
|
+
const updatedAt = Date.now();
|
|
210
|
+
state.foregroundRuns.set(input.runId, {
|
|
211
|
+
runId: input.runId,
|
|
212
|
+
mode: input.mode,
|
|
213
|
+
cwd: input.cwd,
|
|
214
|
+
updatedAt,
|
|
215
|
+
children: input.results.map((result, index) => {
|
|
216
|
+
const child = {
|
|
217
|
+
agent: result.agent,
|
|
218
|
+
index,
|
|
219
|
+
status: resolveSubagentResultStatus({ exitCode: result.exitCode, interrupted: result.interrupted, detached: result.detached }),
|
|
220
|
+
updatedAt,
|
|
221
|
+
...result.exitCode !== undefined ? { exitCode: result.exitCode } : {},
|
|
222
|
+
...result.finalOutput ? { finalOutput: result.finalOutput } : {},
|
|
223
|
+
...result.sessionFile ? { sessionFile: result.sessionFile } : {},
|
|
224
|
+
...result.artifactPaths ? { artifactPaths: result.artifactPaths } : {},
|
|
225
|
+
...result.transcriptPath ? { transcriptPath: result.transcriptPath } : {},
|
|
226
|
+
...result.transcriptError ? { transcriptError: result.transcriptError } : {},
|
|
227
|
+
...result.detachedReason ? { detachedReason: result.detachedReason } : {}
|
|
228
|
+
};
|
|
229
|
+
const recovered = previous?.children[index];
|
|
230
|
+
return child.status === "detached" && recovered && recovered.status !== "detached" ? recovered : child;
|
|
231
|
+
})
|
|
232
|
+
});
|
|
233
|
+
trimRememberedForegroundRuns(state);
|
|
234
|
+
}
|
|
235
|
+
function updateRememberedForegroundChild(state, input) {
|
|
236
|
+
state.foregroundRuns ??= new Map;
|
|
237
|
+
const updatedAt = Date.now();
|
|
238
|
+
let run = state.foregroundRuns.get(input.runId);
|
|
239
|
+
if (!run) {
|
|
240
|
+
run = { runId: input.runId, mode: input.mode, cwd: input.cwd, updatedAt, children: [] };
|
|
241
|
+
state.foregroundRuns.set(input.runId, run);
|
|
242
|
+
}
|
|
243
|
+
run.updatedAt = updatedAt;
|
|
244
|
+
const child = run.children[input.index] ?? { agent: input.result.agent, index: input.index, status: "detached" };
|
|
245
|
+
run.children[input.index] = {
|
|
246
|
+
...child,
|
|
247
|
+
agent: input.result.agent,
|
|
248
|
+
index: input.index,
|
|
249
|
+
status: resolveSubagentResultStatus({ exitCode: input.result.exitCode, interrupted: input.result.interrupted, detached: false }),
|
|
250
|
+
updatedAt,
|
|
251
|
+
...input.result.exitCode !== undefined ? { exitCode: input.result.exitCode } : {},
|
|
252
|
+
...input.result.finalOutput ? { finalOutput: input.result.finalOutput } : {},
|
|
253
|
+
...input.result.sessionFile ? { sessionFile: input.result.sessionFile } : {},
|
|
254
|
+
...input.result.artifactPaths ? { artifactPaths: input.result.artifactPaths } : {},
|
|
255
|
+
...input.result.transcriptPath ? { transcriptPath: input.result.transcriptPath } : {},
|
|
256
|
+
...input.result.transcriptError ? { transcriptError: input.result.transcriptError } : {},
|
|
257
|
+
...input.result.detachedReason ? { detachedReason: input.result.detachedReason } : {}
|
|
258
|
+
};
|
|
259
|
+
trimRememberedForegroundRuns(state);
|
|
260
|
+
}
|
|
261
|
+
function resolveForegroundResumeTarget(params, state) {
|
|
262
|
+
const requested = (params.id ?? params.runId)?.trim();
|
|
263
|
+
if (!requested || !state.foregroundRuns?.size)
|
|
264
|
+
return;
|
|
265
|
+
const direct = state.foregroundRuns.get(requested);
|
|
266
|
+
const matches = direct ? [direct] : [...state.foregroundRuns.values()].filter((run) => run.runId.startsWith(requested));
|
|
267
|
+
if (matches.length === 0)
|
|
268
|
+
return;
|
|
269
|
+
if (matches.length > 1)
|
|
270
|
+
throw new Error(`Ambiguous foreground run id prefix '${requested}' matched: ${matches.map((run) => run.runId).join(", ")}. Provide a longer id.`);
|
|
271
|
+
const run = matches[0];
|
|
272
|
+
if (run.children.length > 1 && params.index === undefined)
|
|
273
|
+
throw new Error(`Foreground run '${run.runId}' has ${run.children.length} children. Provide index to choose one.`);
|
|
274
|
+
const index = params.index ?? 0;
|
|
275
|
+
if (!Number.isInteger(index))
|
|
276
|
+
throw new Error(`Foreground run '${run.runId}' index must be an integer.`);
|
|
277
|
+
if (index < 0 || index >= run.children.length)
|
|
278
|
+
throw new Error(`Foreground run '${run.runId}' has ${run.children.length} children. Index ${index} is out of range.`);
|
|
279
|
+
const child = run.children[index];
|
|
280
|
+
if (child.status === "detached")
|
|
281
|
+
throw new Error(`Foreground run '${run.runId}' child ${index} is detached for intercom coordination and cannot be revived safely from the remembered foreground state. Reply to the supervisor request first; after the child exits, start a fresh follow-up if needed.`);
|
|
282
|
+
if (!child.sessionFile)
|
|
283
|
+
throw new Error(`Foreground run '${run.runId}' child ${index} does not have a persisted session file to resume from.`);
|
|
284
|
+
if (path.extname(child.sessionFile) !== ".jsonl")
|
|
285
|
+
throw new Error(`Foreground run '${run.runId}' child ${index} session file must be a .jsonl file: ${child.sessionFile}`);
|
|
286
|
+
const sessionFile = path.resolve(child.sessionFile);
|
|
287
|
+
if (!fs.existsSync(sessionFile))
|
|
288
|
+
throw new Error(`Foreground run '${run.runId}' child ${index} session file does not exist: ${child.sessionFile}`);
|
|
289
|
+
return { runId: run.runId, mode: run.mode, state: "complete", agent: child.agent, index, intercomTarget: resolveSubagentIntercomTarget(run.runId, child.agent, index), cwd: run.cwd, sessionFile };
|
|
290
|
+
}
|
|
291
|
+
function isAsyncRunNotFound(error) {
|
|
292
|
+
return error instanceof Error && error.message.startsWith("Async run not found.");
|
|
293
|
+
}
|
|
294
|
+
function isResumeAmbiguity(error) {
|
|
295
|
+
return error instanceof Error && /Ambiguous .*run id prefix/.test(error.message);
|
|
296
|
+
}
|
|
297
|
+
function resumeTargetExact(target, requested) {
|
|
298
|
+
return target?.runId === requested;
|
|
299
|
+
}
|
|
300
|
+
function escapeRegExp(value) {
|
|
301
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
302
|
+
}
|
|
303
|
+
function isExactResumeError(error, source, requested) {
|
|
304
|
+
if (!(error instanceof Error) || !requested)
|
|
305
|
+
return false;
|
|
306
|
+
return new RegExp(`\\b${source} run '${escapeRegExp(requested)}'`, "i").test(error.message);
|
|
307
|
+
}
|
|
308
|
+
function resolveResumeTarget(params, state, options = {}) {
|
|
309
|
+
const requested = (params.id ?? params.runId)?.trim() ?? "";
|
|
310
|
+
let foregroundTarget;
|
|
311
|
+
let foregroundError;
|
|
312
|
+
let asyncTarget;
|
|
313
|
+
let asyncError;
|
|
314
|
+
try {
|
|
315
|
+
const target = resolveForegroundResumeTarget(params, state);
|
|
316
|
+
if (target)
|
|
317
|
+
foregroundTarget = { kind: "revive", source: "foreground", ...target };
|
|
318
|
+
} catch (error) {
|
|
319
|
+
foregroundError = error;
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
asyncTarget = { source: "async", ...resolveAsyncResumeTarget(params, {}, { requireSessionFile: options.asyncRequireSessionFile }) };
|
|
323
|
+
} catch (error) {
|
|
324
|
+
asyncError = error;
|
|
325
|
+
}
|
|
326
|
+
if (foregroundTarget && asyncTarget) {
|
|
327
|
+
const foregroundExact = resumeTargetExact(foregroundTarget, requested);
|
|
328
|
+
const asyncExact = resumeTargetExact(asyncTarget, requested);
|
|
329
|
+
if (foregroundExact && !asyncExact)
|
|
330
|
+
return foregroundTarget;
|
|
331
|
+
if (asyncExact && !foregroundExact)
|
|
332
|
+
return asyncTarget;
|
|
333
|
+
throw new Error(`Resume id '${requested}' is ambiguous between foreground run '${foregroundTarget.runId}' and async run '${asyncTarget.runId}'. Provide a full run id.`);
|
|
334
|
+
}
|
|
335
|
+
if (foregroundTarget) {
|
|
336
|
+
if (isExactResumeError(asyncError, "async", requested))
|
|
337
|
+
throw asyncError;
|
|
338
|
+
if (isResumeAmbiguity(asyncError) && !resumeTargetExact(foregroundTarget, requested))
|
|
339
|
+
throw asyncError;
|
|
340
|
+
return foregroundTarget;
|
|
341
|
+
}
|
|
342
|
+
if (asyncTarget) {
|
|
343
|
+
if (isExactResumeError(foregroundError, "foreground", requested))
|
|
344
|
+
throw foregroundError;
|
|
345
|
+
if (isResumeAmbiguity(foregroundError) && !resumeTargetExact(asyncTarget, requested))
|
|
346
|
+
throw foregroundError;
|
|
347
|
+
return asyncTarget;
|
|
348
|
+
}
|
|
349
|
+
if (foregroundError && !isAsyncRunNotFound(asyncError))
|
|
350
|
+
throw foregroundError;
|
|
351
|
+
if (foregroundError)
|
|
352
|
+
throw foregroundError;
|
|
353
|
+
if (asyncError)
|
|
354
|
+
throw asyncError;
|
|
355
|
+
throw new Error("Run not found. Provide id or runId.");
|
|
356
|
+
}
|
|
357
|
+
function getAsyncInterruptTarget(state, runId, location) {
|
|
358
|
+
if (location?.asyncDir) {
|
|
359
|
+
return {
|
|
360
|
+
asyncId: location.resolvedId ?? runId ?? path.basename(location.asyncDir),
|
|
361
|
+
asyncDir: location.asyncDir
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
if (runId) {
|
|
365
|
+
const direct = state.asyncJobs.get(runId);
|
|
366
|
+
if (direct)
|
|
367
|
+
return { asyncId: direct.asyncId, asyncDir: direct.asyncDir };
|
|
368
|
+
}
|
|
369
|
+
let newest;
|
|
370
|
+
for (const job of state.asyncJobs.values()) {
|
|
371
|
+
if (job.status !== "running")
|
|
372
|
+
continue;
|
|
373
|
+
if (!newest || (job.updatedAt ?? 0) > newest.updatedAt) {
|
|
374
|
+
newest = { asyncId: job.asyncId, asyncDir: job.asyncDir, updatedAt: job.updatedAt ?? 0 };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return newest ? { asyncId: newest.asyncId, asyncDir: newest.asyncDir } : undefined;
|
|
378
|
+
}
|
|
379
|
+
function emitControlNotification(input) {
|
|
380
|
+
if (!shouldNotifyControlEvent(input.controlConfig, input.event))
|
|
381
|
+
return;
|
|
382
|
+
const childIntercomTarget = input.intercomBridge.active ? resolveSubagentIntercomTarget(input.event.runId, input.event.agent, input.event.index) : undefined;
|
|
383
|
+
const payload = {
|
|
384
|
+
event: input.event,
|
|
385
|
+
source: "foreground",
|
|
386
|
+
childIntercomTarget,
|
|
387
|
+
noticeText: formatControlNoticeMessage(input.event, childIntercomTarget)
|
|
388
|
+
};
|
|
389
|
+
if (input.controlConfig.notifyChannels.includes("event")) {
|
|
390
|
+
input.pi.events.emit(SUBAGENT_CONTROL_EVENT, payload);
|
|
391
|
+
}
|
|
392
|
+
if (input.event.type !== "active_long_running" && input.controlConfig.notifyChannels.includes("intercom") && input.intercomBridge.active && input.intercomBridge.orchestratorTarget) {
|
|
393
|
+
input.pi.events.emit(SUBAGENT_CONTROL_INTERCOM_EVENT, {
|
|
394
|
+
...payload,
|
|
395
|
+
to: input.intercomBridge.orchestratorTarget,
|
|
396
|
+
message: formatControlIntercomMessage(input.event, childIntercomTarget)
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function interruptAsyncRun(state, runId, kill, location) {
|
|
401
|
+
const target = getAsyncInterruptTarget(state, runId, location);
|
|
402
|
+
if (!target)
|
|
403
|
+
return null;
|
|
404
|
+
const status = reconcileAsyncRun(target.asyncDir, { kill }).status;
|
|
405
|
+
if (!status || status.state !== "running" || typeof status.pid !== "number") {
|
|
406
|
+
return {
|
|
407
|
+
content: [{ type: "text", text: `No running async run with an interrupt-capable pid was found for '${runId ?? "current"}'.` }],
|
|
408
|
+
isError: true,
|
|
409
|
+
details: { mode: "management", results: [] }
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
deliverInterruptRequest({ asyncDir: target.asyncDir, pid: status.pid, kill, source: "interrupt-action" });
|
|
414
|
+
const tracked = state.asyncJobs.get(target.asyncId);
|
|
415
|
+
if (tracked) {
|
|
416
|
+
tracked.activityState = undefined;
|
|
417
|
+
tracked.updatedAt = Date.now();
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
content: [{ type: "text", text: `Interrupt requested for async run ${target.asyncId}.` }],
|
|
421
|
+
details: { mode: "management", results: [] }
|
|
422
|
+
};
|
|
423
|
+
} catch (error) {
|
|
424
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
425
|
+
return {
|
|
426
|
+
content: [{ type: "text", text: `Failed to interrupt async run ${target.asyncId}: ${message}` }],
|
|
427
|
+
isError: true,
|
|
428
|
+
details: { mode: "management", results: [] }
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function steerAsyncRun(input) {
|
|
433
|
+
if (!input.location.asyncDir) {
|
|
434
|
+
return {
|
|
435
|
+
content: [{ type: "text", text: `Async run '${input.runId}' has no live run directory to steer.` }],
|
|
436
|
+
isError: true,
|
|
437
|
+
details: { mode: "management", results: [] }
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
const status = reconcileAsyncRun(input.location.asyncDir, { kill: input.kill }).status;
|
|
441
|
+
if (!status || status.state !== "running" && status.state !== "queued") {
|
|
442
|
+
return {
|
|
443
|
+
content: [{ type: "text", text: `Async run '${input.runId}' is not running or queued and cannot be steered.` }],
|
|
444
|
+
isError: true,
|
|
445
|
+
details: { mode: "management", results: [] }
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
const steps = status.steps ?? [];
|
|
449
|
+
if (input.index !== undefined) {
|
|
450
|
+
if (input.index < 0 || input.index >= steps.length) {
|
|
451
|
+
return {
|
|
452
|
+
content: [{ type: "text", text: `Async run '${status.runId}' has ${steps.length} children. Index ${input.index} is out of range.` }],
|
|
453
|
+
isError: true,
|
|
454
|
+
details: { mode: "management", results: [] }
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
const targetStep = steps[input.index];
|
|
458
|
+
if (targetStep && targetStep.status !== "running" && targetStep.status !== "pending") {
|
|
459
|
+
return {
|
|
460
|
+
content: [{ type: "text", text: `Async run '${status.runId}' child ${input.index} is ${targetStep.status} and cannot be steered.` }],
|
|
461
|
+
isError: true,
|
|
462
|
+
details: { mode: "management", results: [] }
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
const running = steps.filter((step) => step.status === "running");
|
|
467
|
+
if (running.length === 0 && steps.length > 1) {
|
|
468
|
+
return {
|
|
469
|
+
content: [{ type: "text", text: `Async run '${status.runId}' has no running child yet. Provide index to steer a queued child.` }],
|
|
470
|
+
isError: true,
|
|
471
|
+
details: { mode: "management", results: [] }
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
requestAsyncSteer(input.location.asyncDir, { message: input.message, targetIndex: input.index, source: "steer-action" });
|
|
476
|
+
const tracked = input.state.asyncJobs.get(status.runId);
|
|
477
|
+
if (tracked)
|
|
478
|
+
tracked.updatedAt = Date.now();
|
|
479
|
+
const childText = input.index !== undefined ? ` child ${input.index}` : " running child";
|
|
480
|
+
return {
|
|
481
|
+
content: [{ type: "text", text: `Steering queued for async run ${status.runId}${childText}. Delivery requires a live DM child session that supports mid-run steering.` }],
|
|
482
|
+
details: { mode: "management", results: [] }
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function duplicateNames(names) {
|
|
486
|
+
const seen = new Set;
|
|
487
|
+
const duplicates = new Set;
|
|
488
|
+
for (const name of names) {
|
|
489
|
+
if (seen.has(name))
|
|
490
|
+
duplicates.add(name);
|
|
491
|
+
else
|
|
492
|
+
seen.add(name);
|
|
493
|
+
}
|
|
494
|
+
return [...duplicates];
|
|
495
|
+
}
|
|
496
|
+
function appendStepToAsyncChain(input) {
|
|
497
|
+
const targetRunId = input.params.id ?? input.params.runId;
|
|
498
|
+
if (!targetRunId) {
|
|
499
|
+
return {
|
|
500
|
+
content: [{ type: "text", text: "action='append-step' requires id." }],
|
|
501
|
+
isError: true,
|
|
502
|
+
details: { mode: "management", results: [] }
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
if (!input.params.chain || input.params.chain.length !== 1) {
|
|
506
|
+
return {
|
|
507
|
+
content: [{ type: "text", text: "action='append-step' requires chain with exactly one step." }],
|
|
508
|
+
isError: true,
|
|
509
|
+
details: { mode: "management", results: [] }
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
const acceptanceErrors = validateExecutionAcceptance(input.params);
|
|
513
|
+
if (acceptanceErrors.length > 0) {
|
|
514
|
+
return {
|
|
515
|
+
content: [{ type: "text", text: `Cannot append step: ${acceptanceErrors.join(" ")}` }],
|
|
516
|
+
isError: true,
|
|
517
|
+
details: { mode: "management", results: [] }
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
let resolved;
|
|
521
|
+
try {
|
|
522
|
+
resolved = resolveSubagentRunId(targetRunId, { state: input.deps.state, nested: nestedResolutionScopeForExecutor(input.deps) });
|
|
523
|
+
} catch (error) {
|
|
524
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
525
|
+
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
526
|
+
}
|
|
527
|
+
if (!resolved) {
|
|
528
|
+
return {
|
|
529
|
+
content: [{ type: "text", text: `No async chain run found for '${targetRunId}'.` }],
|
|
530
|
+
isError: true,
|
|
531
|
+
details: { mode: "management", results: [] }
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
if (resolved.kind !== "async" || !resolved.location.asyncDir) {
|
|
535
|
+
return {
|
|
536
|
+
content: [{ type: "text", text: `Run '${resolved.id}' is not an append-capable async chain run.` }],
|
|
537
|
+
isError: true,
|
|
538
|
+
details: { mode: "management", results: [] }
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
const status = readStatus(resolved.location.asyncDir);
|
|
542
|
+
if (!status) {
|
|
543
|
+
return {
|
|
544
|
+
content: [{ type: "text", text: `No async run status found for '${resolved.id}'.` }],
|
|
545
|
+
isError: true,
|
|
546
|
+
details: { mode: "management", results: [] }
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
if (status.mode !== "chain") {
|
|
550
|
+
return {
|
|
551
|
+
content: [{ type: "text", text: `Run '${resolved.id}' is ${status.mode}; only active chain runs accept appended steps.` }],
|
|
552
|
+
isError: true,
|
|
553
|
+
details: { mode: "management", results: [] }
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
if (status.state !== "running") {
|
|
557
|
+
return {
|
|
558
|
+
content: [{ type: "text", text: `Run '${resolved.id}' is ${status.state}; only running chain runs accept appended steps.` }],
|
|
559
|
+
isError: true,
|
|
560
|
+
details: { mode: "management", results: [] }
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
const stillInProgress = (status.steps ?? []).some((step) => step.status === "running" || step.status === "pending") || (status.pendingAppends ?? 0) > 0;
|
|
564
|
+
if (!stillInProgress) {
|
|
565
|
+
return {
|
|
566
|
+
content: [{ type: "text", text: `Run '${resolved.id}' has no running or pending chain steps left; append-step must target an in-progress chain.` }],
|
|
567
|
+
isError: true,
|
|
568
|
+
details: { mode: "management", results: [] }
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
const pendingAppendRequests = readPendingChainAppendRequests(resolved.location.asyncDir);
|
|
572
|
+
const reservedOutputNames = new Set([
|
|
573
|
+
...Object.keys(status.outputs ?? {}),
|
|
574
|
+
...(status.steps ?? []).map((step) => step.outputName).filter((name) => Boolean(name)),
|
|
575
|
+
...pendingAppendRequests.flatMap((request) => runnerStepOutputNames(request.steps))
|
|
576
|
+
]);
|
|
577
|
+
try {
|
|
578
|
+
validateChainOutputBindingsWithContext(input.params.chain, { maxItems: input.deps.config.chain?.dynamicFanout?.maxItems }, {
|
|
579
|
+
priorOutputNames: reservedOutputNames,
|
|
580
|
+
startStepIndex: status.chainStepCount ?? status.steps?.length ?? 0
|
|
581
|
+
});
|
|
582
|
+
} catch (error) {
|
|
583
|
+
if (!(error instanceof ChainOutputValidationError))
|
|
584
|
+
throw error;
|
|
585
|
+
return {
|
|
586
|
+
content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': ${error.message}` }],
|
|
587
|
+
isError: true,
|
|
588
|
+
details: { mode: "management", results: [] }
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
const scope = resolveExecutionAgentScope(input.params.agentScope);
|
|
592
|
+
const discoveredForAppend = input.deps.discoverAgents(input.requestCwd, scope);
|
|
593
|
+
const agents = discoveredForAppend.agents;
|
|
594
|
+
const contextPolicy = resolveExplicitContextPolicy(input.params);
|
|
595
|
+
const chainSkillInput = normalizeSkillInput(input.params.skill);
|
|
596
|
+
const chainSkills = chainSkillInput === false ? [] : chainSkillInput ?? [];
|
|
597
|
+
const asyncCtx = {
|
|
598
|
+
pi: input.deps.pi,
|
|
599
|
+
cwd: input.ctx.cwd,
|
|
600
|
+
currentSessionId: resolveCurrentSessionId(input.ctx.sessionManager),
|
|
601
|
+
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
602
|
+
currentModelProvider: input.ctx.model?.provider,
|
|
603
|
+
currentModel: input.ctx.model,
|
|
604
|
+
modelScope: discoveredForAppend.modelScope
|
|
605
|
+
};
|
|
606
|
+
const built = buildAsyncRunnerSteps(resolved.id, {
|
|
607
|
+
chain: wrapChainTasksForFork(input.params.chain, contextPolicy),
|
|
608
|
+
task: input.params.task,
|
|
609
|
+
resultMode: "chain",
|
|
610
|
+
agents,
|
|
611
|
+
ctx: asyncCtx,
|
|
612
|
+
availableModels: input.ctx.modelRegistry.getAvailable().map(toModelInfo),
|
|
613
|
+
cwd: status.cwd ?? input.requestCwd,
|
|
614
|
+
chainSkills,
|
|
615
|
+
dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
|
|
616
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
617
|
+
asyncDir: resolved.location.asyncDir,
|
|
618
|
+
validateOutputBindings: false
|
|
619
|
+
});
|
|
620
|
+
if ("error" in built) {
|
|
621
|
+
return {
|
|
622
|
+
content: [{ type: "text", text: built.error }],
|
|
623
|
+
isError: true,
|
|
624
|
+
details: { mode: "management", results: [] }
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
const appendedOutputNames = runnerStepOutputNames(built.steps);
|
|
628
|
+
const duplicateAppendedOutputs = duplicateNames(appendedOutputNames);
|
|
629
|
+
if (duplicateAppendedOutputs.length > 0) {
|
|
630
|
+
return {
|
|
631
|
+
content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': duplicate output name in appended step: ${duplicateAppendedOutputs.join(", ")}.` }],
|
|
632
|
+
isError: true,
|
|
633
|
+
details: { mode: "management", results: [] }
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const pendingOutputNames = new Set(pendingAppendRequests.flatMap((request) => runnerStepOutputNames(request.steps)));
|
|
637
|
+
const pendingDuplicateOutputs = appendedOutputNames.filter((name) => pendingOutputNames.has(name));
|
|
638
|
+
if (pendingDuplicateOutputs.length > 0) {
|
|
639
|
+
return {
|
|
640
|
+
content: [{ type: "text", text: `Cannot append step to run '${resolved.id}': output name already belongs to a pending append: ${pendingDuplicateOutputs.join(", ")}.` }],
|
|
641
|
+
isError: true,
|
|
642
|
+
details: { mode: "management", results: [] }
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
try {
|
|
646
|
+
const result = enqueueChainAppendRequest({
|
|
647
|
+
asyncDir: resolved.location.asyncDir,
|
|
648
|
+
runId: resolved.id,
|
|
649
|
+
steps: built.steps
|
|
650
|
+
});
|
|
651
|
+
const stepText = built.steps.length === 1 ? "step" : "steps";
|
|
652
|
+
return {
|
|
653
|
+
content: [{
|
|
654
|
+
type: "text",
|
|
655
|
+
text: `Append queued for chain run ${resolved.id}: ${built.steps.length} ${stepText}. It becomes eligible after the chain's already-queued steps finish. Pending appends: ${result.pendingCount}.`
|
|
656
|
+
}],
|
|
657
|
+
details: { mode: "management", results: [], asyncId: resolved.id, asyncDir: resolved.location.asyncDir }
|
|
658
|
+
};
|
|
659
|
+
} catch (error) {
|
|
660
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
661
|
+
return {
|
|
662
|
+
content: [{ type: "text", text: `Failed to append step to chain run ${resolved.id}: ${message}` }],
|
|
663
|
+
isError: true,
|
|
664
|
+
details: { mode: "management", results: [] }
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
function nestedRunSessionFile(run) {
|
|
669
|
+
return run.sessionFile ?? (run.steps?.length === 1 ? run.steps[0]?.sessionFile : undefined);
|
|
670
|
+
}
|
|
671
|
+
function nestedRunAgent(run) {
|
|
672
|
+
return run.agent ?? run.agents?.[0] ?? (run.steps?.length === 1 ? run.steps[0]?.agent : undefined);
|
|
673
|
+
}
|
|
674
|
+
function pathWithin(base, candidate) {
|
|
675
|
+
const resolvedBase = path.resolve(base);
|
|
676
|
+
const resolvedCandidate = path.resolve(candidate);
|
|
677
|
+
return resolvedCandidate === resolvedBase || resolvedCandidate.startsWith(`${resolvedBase}${path.sep}`);
|
|
678
|
+
}
|
|
679
|
+
function validateNestedSessionFile(run, trustedSessionRoots) {
|
|
680
|
+
const sessionFile = nestedRunSessionFile(run);
|
|
681
|
+
if (!sessionFile)
|
|
682
|
+
throw new Error(`Nested run '${run.id}' does not have a persisted session file to resume from.`);
|
|
683
|
+
if (path.extname(sessionFile) !== ".jsonl")
|
|
684
|
+
throw new Error(`Nested run '${run.id}' session file must be a .jsonl file: ${sessionFile}`);
|
|
685
|
+
const resolved = path.resolve(sessionFile);
|
|
686
|
+
if (!path.isAbsolute(sessionFile))
|
|
687
|
+
throw new Error(`Nested run '${run.id}' session file must be absolute: ${sessionFile}`);
|
|
688
|
+
if (!fs.existsSync(resolved))
|
|
689
|
+
throw new Error(`Nested run '${run.id}' session file does not exist: ${sessionFile}`);
|
|
690
|
+
const stat = fs.lstatSync(resolved);
|
|
691
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
692
|
+
throw new Error(`Nested run '${run.id}' session file is not a regular file: ${sessionFile}`);
|
|
693
|
+
const realSessionFile = fs.realpathSync(resolved);
|
|
694
|
+
const trustedRoots = trustedSessionRoots.filter((root) => fs.existsSync(root)).map((root) => fs.realpathSync(root));
|
|
695
|
+
if (!trustedRoots.some((root) => pathWithin(root, realSessionFile))) {
|
|
696
|
+
throw new Error(`Nested run '${run.id}' session file is outside trusted nested session roots: ${sessionFile}`);
|
|
697
|
+
}
|
|
698
|
+
if (!realSessionFile.split(path.sep).includes(run.id)) {
|
|
699
|
+
throw new Error(`Nested run '${run.id}' session file is not under that nested run's session directory: ${sessionFile}`);
|
|
700
|
+
}
|
|
701
|
+
return realSessionFile;
|
|
702
|
+
}
|
|
703
|
+
function resolveNestedResumeTarget(match, trustedSessionRoots) {
|
|
704
|
+
const run = match.match.run;
|
|
705
|
+
if (run.state === "running" || run.state === "queued")
|
|
706
|
+
throw new Error(`Nested run '${run.id}' is live; route the follow-up to the owner process instead.`);
|
|
707
|
+
const agent = nestedRunAgent(run);
|
|
708
|
+
if (!agent)
|
|
709
|
+
throw new Error(`Could not determine child agent for nested run '${run.id}'.`);
|
|
710
|
+
const state = run.state === "complete" || run.state === "failed" || run.state === "paused" ? run.state : "failed";
|
|
711
|
+
const asyncDir = resolveNestedAsyncDir(match.match.rootRunId, run);
|
|
712
|
+
return {
|
|
713
|
+
kind: "revive",
|
|
714
|
+
source: "nested",
|
|
715
|
+
runId: run.id,
|
|
716
|
+
state,
|
|
717
|
+
agent,
|
|
718
|
+
index: 0,
|
|
719
|
+
intercomTarget: resolveSubagentIntercomTarget(run.id, agent, 0),
|
|
720
|
+
cwd: asyncDir ? path.dirname(asyncDir) : undefined,
|
|
721
|
+
sessionFile: validateNestedSessionFile(run, trustedSessionRoots)
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
async function waitForNestedControlResult(target, requestId, timeoutMs = 1000) {
|
|
725
|
+
const deadline = Date.now() + timeoutMs;
|
|
726
|
+
while (Date.now() < deadline) {
|
|
727
|
+
const result = readNestedControlResults(target.match.route).find((candidate) => candidate.requestId === requestId && candidate.targetRunId === target.match.run.id);
|
|
728
|
+
if (result)
|
|
729
|
+
return result;
|
|
730
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
731
|
+
}
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
async function sendNestedControlRequest(target, action, message) {
|
|
735
|
+
const requestId = randomUUID();
|
|
736
|
+
writeNestedControlRequest(target.match.route, {
|
|
737
|
+
ts: Date.now(),
|
|
738
|
+
requestId,
|
|
739
|
+
targetRunId: target.match.run.id,
|
|
740
|
+
action,
|
|
741
|
+
...message ? { message } : {}
|
|
742
|
+
});
|
|
743
|
+
return waitForNestedControlResult(target, requestId);
|
|
744
|
+
}
|
|
745
|
+
function directNestedAsyncInterrupt(target) {
|
|
746
|
+
const run = target.match.run;
|
|
747
|
+
const asyncDir = resolveNestedAsyncDir(target.match.rootRunId, run);
|
|
748
|
+
if (!asyncDir)
|
|
749
|
+
return;
|
|
750
|
+
const status = reconcileAsyncRun(asyncDir, { resultsDir: path.join(RESULTS_DIR, "nested", target.match.rootRunId) }).status;
|
|
751
|
+
const pid = typeof status?.pid === "number" && status.pid > 0 ? status.pid : run.pid;
|
|
752
|
+
if (!status || status.state !== "running" || typeof pid !== "number" || pid <= 0)
|
|
753
|
+
return;
|
|
754
|
+
try {
|
|
755
|
+
deliverInterruptRequest({ asyncDir, pid, source: "nested-interrupt" });
|
|
756
|
+
return { content: [{ type: "text", text: `Interrupt requested for nested async run ${run.id}.` }], details: { mode: "management", results: [] } };
|
|
757
|
+
} catch (error) {
|
|
758
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
759
|
+
return { content: [{ type: "text", text: `Failed to interrupt nested async run ${run.id}: ${message}` }], isError: true, details: { mode: "management", results: [] } };
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
function directNestedAsyncSteer(input) {
|
|
763
|
+
const run = input.target.match.run;
|
|
764
|
+
const asyncDir = resolveNestedAsyncDir(input.target.match.rootRunId, run);
|
|
765
|
+
if (!asyncDir)
|
|
766
|
+
return;
|
|
767
|
+
const status = reconcileAsyncRun(asyncDir, { resultsDir: path.join(RESULTS_DIR, "nested", input.target.match.rootRunId) }).status;
|
|
768
|
+
if (!status || status.state !== "running" && status.state !== "queued")
|
|
769
|
+
return;
|
|
770
|
+
const steps = status.steps ?? [];
|
|
771
|
+
if (input.index !== undefined) {
|
|
772
|
+
if (input.index < 0 || input.index >= steps.length)
|
|
773
|
+
return { content: [{ type: "text", text: `Nested async run ${run.id} has ${steps.length} children. Index ${input.index} is out of range.` }], isError: true, details: { mode: "management", results: [] } };
|
|
774
|
+
const step = steps[input.index];
|
|
775
|
+
if (step && step.status !== "running" && step.status !== "pending")
|
|
776
|
+
return { content: [{ type: "text", text: `Nested async run ${run.id} child ${input.index} is ${step.status} and cannot be steered.` }], isError: true, details: { mode: "management", results: [] } };
|
|
777
|
+
}
|
|
778
|
+
requestAsyncSteer(asyncDir, { message: input.message, targetIndex: input.index, source: "nested-steer" });
|
|
779
|
+
return { content: [{ type: "text", text: `Steering queued for nested async run ${run.id}. Delivery requires a live DM child session that supports mid-run steering.` }], details: { mode: "management", results: [] } };
|
|
780
|
+
}
|
|
781
|
+
async function interruptNestedRun(target) {
|
|
782
|
+
const run = target.match.run;
|
|
783
|
+
if (run.state === "complete")
|
|
784
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} is already complete and cannot be interrupted.` }], isError: true, details: { mode: "management", results: [] } };
|
|
785
|
+
if (run.state === "failed")
|
|
786
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} has failed and cannot be interrupted.` }], isError: true, details: { mode: "management", results: [] } };
|
|
787
|
+
if (run.state === "paused")
|
|
788
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} is already paused.` }], isError: true, details: { mode: "management", results: [] } };
|
|
789
|
+
const result = await sendNestedControlRequest(target, "interrupt");
|
|
790
|
+
if (result)
|
|
791
|
+
return { content: [{ type: "text", text: result.message }], isError: result.ok ? undefined : true, details: { mode: "management", results: [] } };
|
|
792
|
+
const direct = directNestedAsyncInterrupt(target);
|
|
793
|
+
if (direct)
|
|
794
|
+
return direct;
|
|
795
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} owner is not reachable and no safe direct async interrupt fallback is available.` }], isError: true, details: { mode: "management", results: [] } };
|
|
796
|
+
}
|
|
797
|
+
async function resumeLiveNestedRun(input) {
|
|
798
|
+
const run = input.target.match.run;
|
|
799
|
+
const result = await sendNestedControlRequest(input.target, "resume", input.message);
|
|
800
|
+
if (result)
|
|
801
|
+
return { content: [{ type: "text", text: result.message }], isError: result.ok ? undefined : true, details: { mode: "management", results: [] } };
|
|
802
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} appears live but its owner route is not reachable. Wait for completion, then retry action='resume'.` }], isError: true, details: { mode: "management", results: [] } };
|
|
803
|
+
}
|
|
804
|
+
function steerNestedRun(input) {
|
|
805
|
+
const run = input.target.match.run;
|
|
806
|
+
if (run.state !== "running" && run.state !== "queued")
|
|
807
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} is ${run.state} and cannot be steered.` }], isError: true, details: { mode: "management", results: [] } };
|
|
808
|
+
const direct = directNestedAsyncSteer(input);
|
|
809
|
+
if (direct)
|
|
810
|
+
return direct;
|
|
811
|
+
return { content: [{ type: "text", text: `Nested run ${run.id} is not a live async DM child session with a steering inbox. action='steer' cannot target foreground nested runs.` }], isError: true, details: { mode: "management", results: [] } };
|
|
812
|
+
}
|
|
813
|
+
async function resumeAsyncRun(input) {
|
|
814
|
+
const followUp = (input.params.message ?? input.params.task ?? "").trim();
|
|
815
|
+
const attachChain = (input.params.chain?.length ?? 0) > 0 ? input.params.chain : undefined;
|
|
816
|
+
if (!followUp && !attachChain) {
|
|
817
|
+
return {
|
|
818
|
+
content: [{ type: "text", text: "action='resume' requires message." }],
|
|
819
|
+
isError: true,
|
|
820
|
+
details: { mode: "management", results: [] }
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
let target;
|
|
824
|
+
const parentSessionFile = input.ctx.sessionManager.getSessionFile() ?? null;
|
|
825
|
+
try {
|
|
826
|
+
const requestedId = input.params.id ?? input.params.runId;
|
|
827
|
+
let resolved;
|
|
828
|
+
try {
|
|
829
|
+
resolved = requestedId ? resolveSubagentRunId(requestedId, { state: input.deps.state, nested: nestedResolutionScopeForExecutor(input.deps) }) : undefined;
|
|
830
|
+
} catch (error) {
|
|
831
|
+
const message = error instanceof Error ? error.message : "";
|
|
832
|
+
const asyncMatches = message.match(/async:/g)?.length ?? 0;
|
|
833
|
+
if (!isResumeAmbiguity(error) || !message.includes("foreground:") || asyncMatches !== 1)
|
|
834
|
+
throw error;
|
|
835
|
+
}
|
|
836
|
+
if (resolved?.kind === "nested") {
|
|
837
|
+
if (attachChain) {
|
|
838
|
+
return {
|
|
839
|
+
content: [{ type: "text", text: "Attaching a running subagent as a chain root is currently available for top-level async runs only." }],
|
|
840
|
+
isError: true,
|
|
841
|
+
details: { mode: "management", results: [] }
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
if (resolved.match.run.state === "running" || resolved.match.run.state === "queued") {
|
|
845
|
+
return resumeLiveNestedRun({ target: resolved, message: followUp });
|
|
846
|
+
}
|
|
847
|
+
const trustedSessionRoots = [
|
|
848
|
+
...input.deps.config.defaultSessionDir ? [path.resolve(input.deps.expandTilde(input.deps.config.defaultSessionDir))] : [],
|
|
849
|
+
...parentSessionFile ? [input.deps.getSubagentSessionRoot(parentSessionFile)] : []
|
|
850
|
+
];
|
|
851
|
+
target = resolveNestedResumeTarget(resolved, trustedSessionRoots);
|
|
852
|
+
} else {
|
|
853
|
+
target = resolveResumeTarget(input.params, input.deps.state, { asyncRequireSessionFile: !attachChain });
|
|
854
|
+
}
|
|
855
|
+
} catch (error) {
|
|
856
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
857
|
+
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
858
|
+
}
|
|
859
|
+
if (target.kind === "live" && !attachChain) {
|
|
860
|
+
const interrupt = interruptLiveAsyncResumeTarget({
|
|
861
|
+
target,
|
|
862
|
+
state: input.deps.state,
|
|
863
|
+
kill: input.deps.kill,
|
|
864
|
+
resultsDir: RESULTS_DIR
|
|
865
|
+
});
|
|
866
|
+
if (!interrupt.ok) {
|
|
867
|
+
return {
|
|
868
|
+
content: [{ type: "text", text: interrupt.message }],
|
|
869
|
+
isError: true,
|
|
870
|
+
details: { mode: "management", results: [] }
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
const delivered = await deliverSubagentIntercomMessageEvent(input.deps.pi.events, target.intercomTarget, `Follow-up for async run ${target.runId} (${target.agent}):
|
|
2
874
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`)
|
|
14
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`),B=z.match(/^([ \t]+)/m)?.[1]??"",K=B?z.replace(new RegExp(`^${C5(B)}`,"gm"),"").replace(/^\n/,""):z;J[j]=K}return{frontmatter:J,body:Y}}import*as m0 from"node:fs";import*as R5 from"node:os";import*as iJ from"node:path";import{Compile as JX}from"typebox/compile";var y5="DM_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA",f5="DM_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE";function ZX($,J="outputSchema"){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${J} must be a JSON Schema object.`)}function rJ($,J){ZX($);let Z=J??R5.tmpdir();m0.mkdirSync(Z,{recursive:!0});let Q=m0.mkdtempSync(iJ.join(Z,"dm-subagent-structured-")),X=iJ.join(Q,"schema.json"),Y=iJ.join(Q,"output.json");return m0.writeFileSync(X,JSON.stringify($),{mode:384}),{schema:$,schemaPath:X,outputPath:Y}}function k4($,J){let Z;try{Z=JX($)}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 D5($){if(!m0.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(m0.readFileSync($.outputPath,"utf-8"))}catch(Q){return{error:`Failed to read structured output: ${Q instanceof Error?Q.message:String(Q)}`}}let Z=k4($.schema,J);if(Z.status==="invalid")return{error:`Structured output validation failed: ${Z.message}`};return{value:J}}class V$ extends Error{}var QX=/^[A-Za-z_][A-Za-z0-9_]*$/,XX=/^[A-Za-z_][A-Za-z0-9_]*$/,aJ=/\{([A-Za-z_][A-Za-z0-9_]*)(?:\.([^{}]+))?\}/g,YX=new Set(["task","previous","chain_dir","outputs"]),I5=new Set(["expand","parallel","collect","concurrency","failFast","phase","label","acceptance"]),HX=new Set([...I5,"effectiveAcceptance","sessionFiles","thinkingOverrides"]),jX=new Set(["from","item","key","maxItems","onEmpty"]),UX=new Set(["output","path"]),k5=new Set(["agent","task","phase","label","outputSchema","cwd","output","outputMode","reads","progress","skill","model","toolBudget","acceptance"]),VX=new Set([...k5,"outputName","structured","inheritProjectContext","inheritSkills","skills","outputPath","maxSubagentDepth","structuredOutput","structuredOutputSchema","tools","extensions","subagentOnlyExtensions","mcpDirectTools","completionGuard","systemPrompt","systemPromptMode","thinking","modelCandidates","sessionFile","effectiveAcceptance","parentSessionId"]),zX=new Set(["as","outputSchema"]);function b5($){return QX.test($)}function P4($,J){if($==="")return;if(!$.startsWith("/"))throw new V$(`${J} must be a JSON Pointer starting with '/'.`);for(let Z of $.slice(1).split("/"))if(/~(?![01])/.test(Z))throw new V$(`${J} contains invalid JSON Pointer escape.`)}function GX($){return $.replace(/~1/g,"/").replace(/~0/g,"~")}function x4($,J,Z){if(P4(J,Z),J==="")return $;let Q=$;for(let X of J.slice(1).split("/")){let Y=GX(X);if(Array.isArray(Q)){if(!/^(0|[1-9][0-9]*)$/.test(Y))throw new V$(`${Z} segment '${Y}' does not address an array index.`);let j=Number(Y);if(j>=Q.length)throw new V$(`${Z} does not exist.`);Q=Q[j];continue}if(!Q||typeof Q!=="object")throw new V$(`${Z} does not exist.`);let H=Q;if(!Object.prototype.hasOwnProperty.call(H,Y))throw new V$(`${Z} does not exist.`);Q=H[Y]}return Q}function BX($,J){if(typeof $==="string"||typeof $==="number"||typeof $==="boolean"){let Z=String($);if(!Z.trim())throw new V$(`${J} resolved to an empty key.`);if(/[\u0000-\u001F\u007F]/.test(Z))throw new V$(`${J} resolved to an unsafe key.`);if(Z.length>200)throw new V$(`${J} resolved to a key longer than 200 characters.`);return Z}throw new V$(`${J} must resolve to a string, number, or boolean.`)}function KX($){return $.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"item"}function WX($,J){if($===void 0)throw new V$(`Unresolved item reference '${J}'.`);if(typeof $==="string")return $;if(typeof $==="number"||typeof $==="boolean"||$===null)return String($);return JSON.stringify($)}function _X($,J,Z){if(!J)return $;let Q=`/${J.split(".").map((X)=>X.replace(/~/g,"~0").replace(/\//g,"~1")).join("/")}`;return x4($,Q,Z)}function w5($,J,Z){return $.replace(aJ,(Q,X,Y)=>{if(X!==J)return Q;if(Y!==void 0&&(!Y.trim()||Y.includes("..")))throw new V$(`Invalid item reference '${Q}'.`);return WX(_X(Z,Y,Q),Q)})}function sJ($,J,Z){if(!$||typeof $!=="object"||Array.isArray($))throw new V$(`${Z} must be an object.`);for(let Q of Object.keys($))if(!J.has(Q))throw new V$(`${Z} does not support field '${Q}'.`)}function AX($,J,Z){for(let Q of $.matchAll(/\{([^{}]*)\}/g)){let X=Q[0],Y=Q[1];if(Y===J||Y.startsWith(`${J}.`)){if(!aJ.test(X)||Y===`${J}.`||Y.includes(".."))throw new V$(`Invalid item reference '${X}' in ${Z}.`);aJ.lastIndex=0;continue}aJ.lastIndex=0;let H=Y.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];if(H===J)throw new V$(`Invalid item reference '${X}' in ${Z}.`);if(H&&YX.has(H))continue;if(H)throw new V$(`Unsupported template reference '${X}' in ${Z}.`)}if(aJ.lastIndex=0,$.includes(`{${J}.}`)||new RegExp(`\\{${J}(?:\\.|$)[^}]*$`).test($))throw new V$(`Invalid item reference in ${Z}.`)}function P5($){return!!$&&typeof $==="object"&&!Array.isArray($)&&(Object.prototype.hasOwnProperty.call($,"expand")||Object.prototype.hasOwnProperty.call($,"collect"))}function v4($,J,Z={}){let Q=`Dynamic chain step ${J+1}`;if(sJ($,Z.allowRunnerFields?HX:I5,Q),!$.expand||!$.expand.from)throw new V$(`${Q} requires expand.from.`);if(sJ($.expand,jX,`${Q} expand`),sJ($.expand.from,UX,`${Q} expand.from`),!b5($.expand.from.output))throw new V$(`${Q} has invalid expand.from.output '${$.expand.from.output}'.`);if(P4($.expand.from.path,`${Q} expand.from.path`),$.expand.key!==void 0)P4($.expand.key,`${Q} expand.key`);let X=$.expand.item??"item";if(!XX.test(X))throw new V$(`${Q} has invalid expand.item '${X}'.`);if($.expand.maxItems===void 0&&Z.maxItems===void 0)throw new V$(`${Q} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`);if($.expand.maxItems!==void 0&&(!Number.isInteger($.expand.maxItems)||$.expand.maxItems<0))throw new V$(`${Q} expand.maxItems must be an integer >= 0.`);if(Z.maxItems!==void 0&&(!Number.isInteger(Z.maxItems)||Z.maxItems<0))throw new V$("config.chain.dynamicFanout.maxItems must be an integer >= 0.");if(!$.parallel||Array.isArray($.parallel))throw new V$(`${Q} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`);if(sJ($.parallel,Z.allowRunnerFields?VX:k5,`${Q} parallel`),"expand"in $.parallel)throw new V$(`${Q} does not support nested dynamic fanout.`);if(!$.parallel.agent)throw new V$(`${Q} parallel.agent is required.`);if(!$.collect?.as||!b5($.collect.as))throw new V$(`${Q} requires collect.as with a safe output name.`);sJ($.collect,zX,`${Q} collect`);for(let[Y,H]of[["parallel.task",$.parallel.task],["parallel.label",$.parallel.label]])if(H)AX(H,X,`${Q} ${Y}`)}function qX($,J,Z,Q={}){v4($,Z,Q);let X=$.expand.from.output,Y=J[X];if(!Y)throw new V$(`Dynamic chain step ${Z+1} references unknown output '${X}'.`);if(Y.structured===void 0)throw new V$(`Dynamic chain step ${Z+1} requires structured output '${X}'.`);let H=x4(Y.structured,$.expand.from.path,`Dynamic chain step ${Z+1} expand.from.path`);if(!Array.isArray(H))throw new V$(`Dynamic chain step ${Z+1} expand.from.path must resolve to an array.`);let j=$.expand.maxItems??Q.maxItems;if(j===void 0)throw new V$(`Dynamic chain step ${Z+1} requires an effective maxItems.`);if(H.length>j)throw new V$(`Dynamic chain step ${Z+1} resolved ${H.length} items, exceeding maxItems ${j}.`);let U=new Set,G=new Set;return H.map((z,V)=>{let B=$.expand.key===void 0?String(V):BX(x4(z,$.expand.key,`Dynamic chain step ${Z+1} expand.key`),`Dynamic chain step ${Z+1} expand.key`);if(U.has(B))throw new V$(`Dynamic chain step ${Z+1} produced duplicate item key '${B}'.`);U.add(B);let K=KX(B);if(G.has(K))throw new V$(`Dynamic chain step ${Z+1} produced colliding item id '${K}'.`);return G.add(K),{index:V,key:B,idKey:K,item:z}})}function x5($,J,Z,Q={}){let X=qX($,J,Z,Q);if(X.length===0){if(($.expand.onEmpty??"skip")==="fail")throw new V$(`Dynamic chain step ${Z+1} source array is empty.`);return{items:X,parallel:[],collectedOnEmpty:[]}}let Y=$.expand.item??"item",H=X.map((j)=>{let U=w5($.parallel.task??"{previous}",Y,j.item),G=$.parallel.label?w5($.parallel.label,Y,j.item):void 0;return{...$.parallel,task:U,...G!==void 0?{label:G}:{}}});return{items:X,parallel:H}}function v5($,J,Z){return J.map((Q,X)=>{let Y=Z[X],H=Y?"output"in Y&&typeof Y.output==="string"?Y.output:f0(Y):"";return{key:Q.key,index:Q.index,item:Q.item,agent:Y?.agent??$.parallel.agent,exitCode:Y?.exitCode??null,text:H,...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 h4($,J){if(!$)return;let Z=k4($,J);if(Z.status==="invalid")throw new V$(`Collected output validation failed: ${Z.message}`)}var g5=/\{outputs\.([^}]*)\}/g,g4=/^[A-Za-z_][A-Za-z0-9_]*$/;class a$ extends Error{}function h5($){if(E$($))return $.parallel.map((Z)=>Z.as).filter((Z)=>Boolean(Z));if(C$($))return[$.collect.as];let J=$.as;return J?[J]:[]}function OX($){if(E$($))return $.parallel.map((J)=>J.task??"{previous}");if(C$($))return[$.parallel.task??"{previous}",$.parallel.label??""].filter(Boolean);return[$.task??"{previous}"]}function BJ($,J={}){J8($,J)}function J8($,J={},Z={}){let Q=[...Z.priorOutputNames??[]],X=new Set(Q),Y=new Set(Q);for(let H=0;H<$.length;H++){let j=(Z.startStepIndex??0)+H+1,U=$[H];if(P5(U)){if(!C$(U))throw new a$(`Dynamic chain step ${j} requires expand, a single parallel template object, and collect; dynamic expand/collect cannot be mixed with static parallel arrays.`);try{v4(U,j-1,J)}catch(G){if(G instanceof V$)throw new a$(G.message);throw G}if(!X.has(U.expand.from.output))throw new a$(`Dynamic chain step ${j} references unknown output '${U.expand.from.output}'. Named outputs are only available after producing step/group completes.`)}for(let G of h5(U)){if(!g4.test(G))throw new a$(`Invalid chain output name '${G}' at step ${j}. Use /^[A-Za-z_][A-Za-z0-9_]*$/.`);if(Y.has(G))throw new a$(`Duplicate chain output name '${G}'. Each as name must be unique.`);Y.add(G)}for(let G of OX(U))for(let z of G.matchAll(g5)){let V=z[0],B=z[1];if(!g4.test(B))throw new a$(`Invalid chain output reference '${V}' at step ${j}. Use {outputs.name} with /^[A-Za-z_][A-Za-z0-9_]*$/ names.`);if(!X.has(B))throw new a$(`Unknown chain output reference '${V}' at step ${j}. Named outputs are only available after producing step/group completes.`)}for(let G of h5(U))X.add(G)}}function m4($,J){return $.replace(g5,(Z,Q)=>{if(!g4.test(Q))throw new a$(`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 a$(`Unknown chain output reference '${Z}'.`);return X.text})}function FX($){return JSON.stringify($)}function c4($,J){return{text:$.structuredOutput!==void 0?FX($.structuredOutput):f0($),...$.structuredOutput!==void 0?{structured:$.structuredOutput}:{},agent:$.agent,stepIndex:J}}import{spawn as LX}from"node:child_process";import{spawnSync as MX}from"node:child_process";import*as u5 from"node:path";var KJ={none:0,attested:1,checked:2,verified:3,reviewed:4},m5=new Set(["auto","none","attested","checked","verified","reviewed"]),u4=new Set(["changed-files","tests-added","commands-run","validation-output","residual-risks","no-staged-files","diff-summary","review-findings","manual-notes"]),NX=new Set(["level","criteria","evidence","verify","review","stopRules","reason"]),EX=new Set(["id","must","evidence","severity"]),TX=new Set(["id","command","timeoutMs","cwd","env","allowFailure"]),SX=new Set(["agent","focus","required"]);function CX($){return $??"auto"}function d5($){return[...new Set($)]}function d4($){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 RX($){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),H=/\b(?:fix|implement|update|write|edit|modify|migrate|release|security|delete|remove|refactor|commit)\b/.test(Z)||/\bworker\b/.test(J);if(Boolean($.async&&H)||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:d4("reviewed"),review:{agent:"reviewer",required:!0}}}if(H&&!Y)return Q.push("write-capable worker/task"),{level:"checked",reasons:Q,criteria:["Implement the requested change without widening scope"],evidence:d4("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 yX($){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 fX($){return $.level==="none"&&typeof $.reason==="string"&&$.reason.trim().length>0}function $1($,J="acceptance"){let Z=[];if($===void 0)return Z;if($===!1)return Z;if(typeof $==="string"){if(!m5.has($))Z.push(`${J} has invalid level '${$}'.`);return Z}if(!$||typeof $!=="object"||Array.isArray($))return Z.push(`${J} must be a string level, false, or an object.`),Z;let Q=$;for(let X of Object.keys(Q))if(!NX.has(X))Z.push(`${J}.${X} is not supported.`);if(Q.level!==void 0&&(typeof Q.level!=="string"||!m5.has(Q.level)))Z.push(`${J}.level must be one of auto, none, attested, checked, verified, reviewed.`);if(Q.level==="none"&&(typeof Q.reason!=="string"||!Q.reason.trim()))Z.push(`${J}.reason is required when level is none.`);if(Q.reason!==void 0&&typeof Q.reason!=="string")Z.push(`${J}.reason must be a string.`);if(Q.criteria!==void 0&&!Array.isArray(Q.criteria))Z.push(`${J}.criteria must be an array.`);if(Array.isArray(Q.criteria))for(let[X,Y]of Q.criteria.entries()){if(typeof Y==="string")continue;let H=`${J}.criteria[${X}]`;if(!Y||typeof Y!=="object"||Array.isArray(Y)){Z.push(`${H} must be a string or an object.`);continue}let j=Y;for(let U of Object.keys(j))if(!EX.has(U))Z.push(`${H}.${U} is not supported.`);if(typeof j.id!=="string"||!j.id.trim())Z.push(`${H}.id is required.`);if(typeof j.must!=="string"||!j.must.trim())Z.push(`${H}.must is required.`);if(j.evidence!==void 0&&!Array.isArray(j.evidence))Z.push(`${H}.evidence must be an array.`);if(Array.isArray(j.evidence)){for(let[U,G]of j.evidence.entries())if(typeof G!=="string"||!u4.has(G))Z.push(`${H}.evidence[${U}] is not a supported evidence kind.`)}if(j.severity!==void 0&&j.severity!=="required"&&j.severity!=="recommended")Z.push(`${H}.severity must be required or recommended.`)}if(Array.isArray(Q.evidence)){for(let[X,Y]of Q.evidence.entries())if(typeof Y!=="string"||!u4.has(Y))Z.push(`${J}.evidence[${X}] is not a supported evidence kind.`)}else if(Q.evidence!==void 0)Z.push(`${J}.evidence must be an array.`);if(Q.verify!==void 0&&!Array.isArray(Q.verify))Z.push(`${J}.verify must be an array.`);if(Array.isArray(Q.verify))for(let[X,Y]of Q.verify.entries()){if(!Y||typeof Y!=="object"||Array.isArray(Y)){Z.push(`${J}.verify[${X}] must be an object.`);continue}let H=Y;for(let j of Object.keys(H))if(!TX.has(j))Z.push(`${J}.verify[${X}].${j} is not supported.`);if(typeof H.id!=="string"||!H.id.trim())Z.push(`${J}.verify[${X}].id is required.`);if(typeof H.command!=="string"||!H.command.trim())Z.push(`${J}.verify[${X}].command is required.`);if(H.timeoutMs!==void 0&&(typeof H.timeoutMs!=="number"||!Number.isInteger(H.timeoutMs)||H.timeoutMs<1))Z.push(`${J}.verify[${X}].timeoutMs must be an integer >= 1.`);if(H.cwd!==void 0&&typeof H.cwd!=="string")Z.push(`${J}.verify[${X}].cwd must be a string.`);if(H.env!==void 0){if(!H.env||typeof H.env!=="object"||Array.isArray(H.env))Z.push(`${J}.verify[${X}].env must be an object.`);else for(let[j,U]of Object.entries(H.env))if(typeof U!=="string")Z.push(`${J}.verify[${X}].env.${j} must be a string.`)}if(H.allowFailure!==void 0&&typeof H.allowFailure!=="boolean")Z.push(`${J}.verify[${X}].allowFailure must be a boolean.`)}if(Q.review!==void 0&&Q.review!==!1)if(!Q.review||typeof Q.review!=="object"||Array.isArray(Q.review))Z.push(`${J}.review must be false or an object.`);else{let X=Q.review;for(let Y of Object.keys(X))if(!SX.has(Y))Z.push(`${J}.review.${Y} is not supported.`);if(X.agent!==void 0&&typeof X.agent!=="string")Z.push(`${J}.review.agent must be a string.`);if(X.focus!==void 0&&typeof X.focus!=="string")Z.push(`${J}.review.focus must be a string.`);if(X.required!==void 0&&typeof X.required!=="boolean")Z.push(`${J}.review.required must be a boolean.`)}if(Q.stopRules!==void 0&&!Array.isArray(Q.stopRules))Z.push(`${J}.stopRules must be an array.`);if(Array.isArray(Q.stopRules)){for(let[X,Y]of Q.stopRules.entries())if(typeof Y!=="string")Z.push(`${J}.stopRules[${X}] must be a string.`)}return Z}function DX($,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)=>u4.has(X))??J,severity:Z.severity??"required"}}).filter((Z)=>Z.must.trim())}function z1($){let J=yX($.explicit),Z=RX($),Q=CX(J.level),X=fX(J)?"none":Q==="auto"?Z.level:KJ[Q]>=KJ[Z.level]?Q:Z.level,Y=d5([...X===Z.level?Z.evidence:d4(X),...J.evidence??[]]),H=DX(J.criteria?.length?J.criteria:Z.criteria,Y),j=J.review!==void 0?J.review:Z.review;if(X==="reviewed"&&Q!=="auto"&&Q!=="reviewed"&&J.review===void 0&&j&&j!==!1)j={...j,required:!1};return{level:X,explicit:$.explicit!==void 0,inferredReason:Z.reasons,criteria:H,evidence:Y,verify:J.verify??[],review:j,stopRules:J.stopRules??[],reason:J.reason}}function o5($){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(`
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`,"utf-8")}function Q8($,J){if($===void 0)return;if($===!1)return!1;if(!Array.isArray($))throw Error(`Builtin override '${J.name}' in '${J.filePath}' has invalid '${J.field}'; expected an array of strings or false.`);let Z=[];for(let Q of $){if(typeof Q!=="string")throw Error(`Builtin override '${J.name}' in '${J.filePath}' has invalid '${J.field}'; expected an array of strings or false.`);let X=Q.trim();if(X)Z.push(X)}return Z}function QY($,J,Z){if(!J||typeof J!=="object"||Array.isArray(J))throw Error(`Builtin override '${$}' in '${Z}' must be an object.`);let Q=J,X={};if("model"in Q)if(typeof Q.model==="string"||Q.model===!1)X.model=Q.model;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'model'; expected a string or false.`);if("thinking"in Q)if(typeof Q.thinking==="string"||Q.thinking===!1)X.thinking=Q.thinking;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'thinking'; expected a string or false.`);if("systemPromptMode"in Q)if(Q.systemPromptMode==="append"||Q.systemPromptMode==="replace")X.systemPromptMode=Q.systemPromptMode;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`);if("inheritProjectContext"in Q)if(typeof Q.inheritProjectContext==="boolean")X.inheritProjectContext=Q.inheritProjectContext;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'inheritProjectContext'; expected a boolean.`);if("inheritSkills"in Q)if(typeof Q.inheritSkills==="boolean")X.inheritSkills=Q.inheritSkills;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'inheritSkills'; expected a boolean.`);if("defaultContext"in Q)if(Q.defaultContext==="fresh"||Q.defaultContext==="fork"||Q.defaultContext===!1)X.defaultContext=Q.defaultContext;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`);if("disabled"in Q)if(typeof Q.disabled==="boolean")X.disabled=Q.disabled;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'disabled'; expected a boolean.`);if("completionGuard"in Q)if(typeof Q.completionGuard==="boolean")X.completionGuard=Q.completionGuard;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'completionGuard'; expected a boolean.`);if("toolBudget"in Q)if(Q.toolBudget===!1)X.toolBudget=!1;else if(Q.toolBudget&&typeof Q.toolBudget==="object"&&!Array.isArray(Q.toolBudget))X.toolBudget=Q.toolBudget;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'toolBudget'; expected an object or false.`);if("systemPrompt"in Q)if(typeof Q.systemPrompt==="string")X.systemPrompt=Q.systemPrompt;else throw Error(`Builtin override '${$}' in '${Z}' has invalid 'systemPrompt'; expected a string.`);let Y=Q8(Q.fallbackModels,{filePath:Z,name:$,field:"fallbackModels"});if(Y!==void 0)X.fallbackModels=Y;let H=Q8(Q.skills,{filePath:Z,name:$,field:"skills"});if(H!==void 0)X.skills=H;let j=Q8(Q.tools,{filePath:Z,name:$,field:"tools"});if(j!==void 0)X.tools=j;let U=Q8(Q.subagentOnlyExtensions,{filePath:Z,name:$,field:"subagentOnlyExtensions"});if(U!==void 0)X.subagentOnlyExtensions=U;return Object.keys(X).length>0?X:void 0}function XZ($){if(!$)return JZ;let Z=G8($).subagents;if(!Z||typeof Z!=="object"||Array.isArray(Z))return JZ;let Q=Z,X;if("disableBuiltins"in Q)if(typeof Q.disableBuiltins==="boolean")X=Q.disableBuiltins;else throw Error(`Subagent settings in '${$}' have invalid 'disableBuiltins'; expected a boolean.`);let Y;if("disableThinking"in Q)if(typeof Q.disableThinking==="boolean")Y=Q.disableThinking;else throw Error(`Subagent settings in '${$}' have invalid 'disableThinking'; expected a boolean.`);let H;if("defaultModel"in Q)if(typeof Q.defaultModel==="string"&&Q.defaultModel.trim())H=Q.defaultModel.trim();else throw Error(`Subagent settings in '${$}' have invalid 'defaultModel'; expected a non-empty string.`);let j=Q5(Q.modelScope,{filePath:$}),U={},G=Q.agentOverrides;if(!G||typeof G!=="object"||Array.isArray(G))return{overrides:U,defaultModel:H,disableBuiltins:X,disableThinking:Y,modelScope:j};for(let[z,V]of Object.entries(G)){let B=QY(z,V,$);if(B)U[z]=B}return{overrides:U,defaultModel:H,disableBuiltins:X,disableThinking:Y,modelScope:j}}function XY($,J,Z,Q){if(Q&&J.defaultModel!==void 0)return{type:"subagents.defaultModel",scope:"project",path:Q,model:J.defaultModel};return $.defaultModel!==void 0?{type:"subagents.defaultModel",scope:"user",path:Z,model:$.defaultModel}:void 0}function X8($,J){if(!J)return $;return $.map((Z)=>{if(Z.model!==void 0)return Z;let Q={...Z,model:J.model,modelSource:J},X=j8.get(Z);if(X)j8.set(Q,X);return Q})}function Y8($,J,Z){let Q={...$,override:{...Z,base:Q6($)}};if(J.model!==void 0)Q.model=J.model===!1?void 0:J.model;if(J.fallbackModels!==void 0)Q.fallbackModels=J.fallbackModels===!1?void 0:[...J.fallbackModels];if(J.thinking!==void 0)Q.thinking=J.thinking===!1?void 0:J.thinking;if(J.systemPromptMode!==void 0)Q.systemPromptMode=J.systemPromptMode;if(J.inheritProjectContext!==void 0)Q.inheritProjectContext=J.inheritProjectContext;if(J.inheritSkills!==void 0)Q.inheritSkills=J.inheritSkills;if(J.defaultContext!==void 0)Q.defaultContext=J.defaultContext===!1?void 0:J.defaultContext;if(J.disabled!==void 0)Q.disabled=J.disabled;if(J.systemPrompt!==void 0)Q.systemPrompt=J.systemPrompt;if(J.skills!==void 0)Q.skills=J.skills===!1?void 0:[...J.skills];if(J.tools!==void 0){let{tools:X,mcpDirectTools:Y}=jZ(J.tools===!1?[]:J.tools);Q.tools=X,Q.mcpDirectTools=Y}if(J.subagentOnlyExtensions!==void 0)Q.subagentOnlyExtensions=J.subagentOnlyExtensions===!1?void 0:[...J.subagentOnlyExtensions];if(J.completionGuard!==void 0)Q.completionGuard=J.completionGuard;if(J.toolBudget!==void 0)Q.toolBudget=J.toolBudget===!1?void 0:J.toolBudget;return Q}function YY($,J){if($.thinking===void 0)return $;return{...$,thinking:void 0,override:$.override??{...J,base:Q6($)}}}function HY($,J,Z,Q,X){let Y=Z.disableBuiltins===!0&&X!==null,H=Z.disableBuiltins===void 0&&J.disableBuiltins===!0,j=Z.disableThinking!==void 0&&X!==null,U=j?Z.disableThinking===!0:J.disableThinking===!0,G=j?{scope:"project",path:X}:{scope:"user",path:Q},z=(V,B)=>{if(!U||B)return V;return YY(V,G)};return $.map((V)=>{let B=Z.overrides[V.name];if(B&&X)return z(Y8(V,B,{scope:"project",path:X}),B.thinking!==void 0);if(Y&&X)return z(Y8(V,{disabled:!0},{scope:"project",path:X}),!1);let K=J.overrides[V.name];if(K)return z(Y8(V,K,{scope:"user",path:Q}),!j&&K.thinking!==void 0);if(H)return z(Y8(V,{disabled:!0},{scope:"user",path:Q}),!1);return z(V,!1)})}function YZ($,...J){let Z=j8.get($);return Z?J.some((Q)=>Z.has(Q)):!1}function HZ($,J,Z){let Q,X=!1,Y=()=>{return Q??={...$},Q},H=(j,U,G)=>{if(YZ($,...U))return;Y()[j]=G,X=!0};if(J.model!==void 0)H("model",["model"],J.model===!1?void 0:J.model);if(J.fallbackModels!==void 0)H("fallbackModels",["fallbackModels"],J.fallbackModels===!1?void 0:[...J.fallbackModels]);if(J.thinking!==void 0)H("thinking",["thinking"],J.thinking===!1?void 0:J.thinking);if(J.systemPromptMode!==void 0)H("systemPromptMode",["systemPromptMode"],J.systemPromptMode);if(J.inheritProjectContext!==void 0)H("inheritProjectContext",["inheritProjectContext"],J.inheritProjectContext);if(J.inheritSkills!==void 0)H("inheritSkills",["inheritSkills"],J.inheritSkills);if(J.defaultContext!==void 0)H("defaultContext",["defaultContext"],J.defaultContext===!1?void 0:J.defaultContext);if(J.disabled!==void 0&&$.disabled===void 0)Y().disabled=J.disabled,X=!0;if(J.skills!==void 0)H("skills",["skill","skills"],J.skills===!1?void 0:[...J.skills]);if(J.tools!==void 0&&!YZ($,"tools")){let{tools:j,mcpDirectTools:U}=jZ(J.tools===!1?[]:J.tools),G=Y();G.tools=j,G.mcpDirectTools=U,X=!0}if(J.subagentOnlyExtensions!==void 0)H("subagentOnlyExtensions",["subagentOnlyExtensions"],J.subagentOnlyExtensions===!1?void 0:[...J.subagentOnlyExtensions]);if(J.completionGuard!==void 0)H("completionGuard",["completionGuard"],J.completionGuard);if(J.toolBudget!==void 0)H("toolBudget",["toolBudget"],J.toolBudget===!1?void 0:J.toolBudget);if(!X||!Q)return $;return Q.override={...Z,base:Q6($)},Q}function a4($,J,Z,Q,X){return $.map((Y)=>{let H=Z.overrides[Y.name];if(H&&X)return HZ(Y,H,{scope:"project",path:X});let j=J.overrides[Y.name];if(j)return HZ(Y,j,{scope:"user",path:Q});return Y})}function UZ($,J,Z){let Q=Z==="project"?z8($):V8();if(!Q)throw Error("Project override is not available here. No project config root was found.");if(!x$.existsSync(Q))return{path:Q,removed:!1};let X=G8(Q),Y=X.subagents;if(!Y||typeof Y!=="object"||Array.isArray(Y))return{path:Q,removed:!1};let H={...Y},j=H.agentOverrides;if(!j||typeof j!=="object"||Array.isArray(j))return{path:Q,removed:!1};let U={...j};if(!Object.prototype.hasOwnProperty.call(U,J))return{path:Q,removed:!1};if(delete U[J],Object.keys(U).length>0)H.agentOverrides=U;else delete H.agentOverrides;if(Object.keys(H).length>0)X.subagents=H;else delete X.subagents;return X6(Q,X),{path:Q,removed:!0}}function VZ($,J,Z,Q){let X=Z==="project"?z8($):V8();if(!X)throw Error("Project override is not available here. No project config root was found.");let Y=G8(X),H=Y.subagents&&typeof Y.subagents==="object"&&!Array.isArray(Y.subagents)?{...Y.subagents}:{},j=H.agentOverrides&&typeof H.agentOverrides==="object"&&!Array.isArray(H.agentOverrides)?{...H.agentOverrides}:{},U=j[J],G=U&&typeof U==="object"&&!Array.isArray(U)?U:{};return j[J]={...G,...ZY(Q)},H.agentOverrides=j,Y.subagents=H,X6(X,Y),X}function zZ($,J,Z,Q){let X=Z==="project"?z8($):V8();if(!X)throw Error("Project override is not available here. No project config root was found.");if(!x$.existsSync(X))return{path:X,removed:!1};let Y=G8(X),H=Y.subagents;if(!H||typeof H!=="object"||Array.isArray(H))return{path:X,removed:!1};let j=H.agentOverrides;if(!j||typeof j!=="object"||Array.isArray(j))return{path:X,removed:!1};let U=j[J];if(!U||typeof U!=="object"||Array.isArray(U))return{path:X,removed:!1};let G={...U},z=!1;for(let B of Q)if(Object.prototype.hasOwnProperty.call(G,B))delete G[B],z=!0;if(!z)return{path:X,removed:!1};let V={...H};if(Object.keys(G).length>0)V.agentOverrides[J]=G;else{let B={...j};if(delete B[J],Object.keys(B).length>0)V.agentOverrides=B;else delete V.agentOverrides}if(Object.keys(V).length>0)Y.subagents=V;else delete Y.subagents;return X6(X,Y),{path:X,removed:!0}}function Y6($,J){let Z=[];if(!x$.existsSync($))return Z;let Q;try{Q=x$.readdirSync($,{withFileTypes:!0}).sort((X,Y)=>X.name.localeCompare(Y.name))}catch{return Z}for(let X of Q){let Y=B$.join($,X.name);if(X.isDirectory()){Z.push(...Y6(Y,J));continue}if(!X.isFile()&&!X.isSymbolicLink())continue;if(!J(X.name))continue;Z.push(Y)}return Z}function jY($,J){let Q=B$.relative($,J).split(B$.sep).map((X)=>X.toLowerCase());if(B$.basename($).toLowerCase()===".agents")Q.unshift(".agents");return Q.some((X,Y)=>X===".agents"&&Q[Y+1]==="skills")}function WJ($,J){let Z=[];for(let Q of Y6($,(X)=>X.endsWith(".md")&&!X.endsWith(".chain.md"))){if(jY($,Q))continue;let X;try{X=x$.readFileSync(Q,"utf-8")}catch{continue}let{frontmatter:Y,body:H}=GJ(X);if(!Y.name||!Y.description)continue;let j=Y.name,U=S1(Y.package,`Agent '${j}' package`);if(U.error)continue;let G=U.packageName,z=t0(j,G),V=Y.tools?.split(",").map((N)=>N.trim()).filter(Boolean),B=[],K=[];if(V)for(let N of V)if(N.startsWith("mcp:"))B.push(N.slice(4));else K.push(N);let W=Y.defaultReads?.split(",").map((N)=>N.trim()).filter(Boolean),F=(Y.skill||Y.skills)?.split(",").map((N)=>N.trim()).filter(Boolean),_=Y.fallbackModels?.split(",").map((N)=>N.trim()).filter(Boolean),f=Y.systemPromptMode==="replace"?"replace":Y.systemPromptMode==="append"?"append":$6(j),O=Y.inheritProjectContext==="true"?!0:Y.inheritProjectContext==="false"?!1:J6(j),y=Y.inheritSkills==="true"?!0:Y.inheritSkills==="false"?!1:Z6(),C=Y.defaultContext==="fork"?"fork":Y.defaultContext==="fresh"?"fresh":void 0,T;if(Y.extensions!==void 0)T=Y.extensions.split(",").map((N)=>N.trim()).filter(Boolean);let h;if(Y.subagentOnlyExtensions!==void 0)h=Y.subagentOnlyExtensions.split(",").map((N)=>N.trim()).filter(Boolean);let b={};for(let[N,E]of Object.entries(Y))if(!w4.has(N))b[N]=E;let w=Number(Y.maxSubagentDepth),q;if(Y.toolBudget!==void 0&&Y.toolBudget.trim()){let N=JSON.parse(Y.toolBudget);if(!N||typeof N!=="object"||Array.isArray(N))throw Error(`Agent '${j}' has invalid toolBudget frontmatter; expected a JSON object.`);q=N}let S=Y.completionGuard==="false"?!1:Y.completionGuard==="true"?!0:void 0,M={name:z,localName:j,packageName:G,description:Y.description,tools:K.length>0?K:void 0,mcpDirectTools:B.length>0?B:void 0,model:Y.model,fallbackModels:_&&_.length>0?_:void 0,thinking:Y.thinking,systemPromptMode:f,inheritProjectContext:O,inheritSkills:y,defaultContext:C,systemPrompt:H,source:J,filePath:Q,skills:F&&F.length>0?F:void 0,extensions:T,subagentOnlyExtensions:h,output:Y.output,defaultReads:W&&W.length>0?W:void 0,defaultProgress:Y.defaultProgress==="true",interactive:Y.interactive==="true",maxSubagentDepth:Number.isInteger(w)&&w>=0?w:void 0,completionGuard:S,toolBudget:q,memory:GZ(Y.memory),extraFields:Object.keys(b).length>0?b:void 0};j8.set(M,new Set(Object.keys(Y))),Z.push(M)}return Z}function t4($,J){let Z=new Map,Q=[];for(let X of Y6($,(Y)=>Y.endsWith(".chain.md")||Y.endsWith(".chain.json"))){let Y;try{Y=x$.readFileSync(X,"utf-8")}catch{continue}try{let H=X.endsWith(".chain.json")?e5(Y,J,X):t5(Y,J,X),j=Z.get(H.name);if(j&&j.filePath.endsWith(".chain.json")&&X.endsWith(".chain.md"))continue;Z.set(H.name,H)}catch(H){Q.push({source:J,filePath:X,error:H instanceof Error?H.message:String(H)});continue}}return{chains:Array.from(Z.values()),diagnostics:Q}}function X2($){try{return x$.statSync($).isDirectory()}catch{return!1}}function UY($){let J=_J($);if(!J)return{readDirs:[],preferredDir:null};let Z=B$.join(J,".agents"),Q=B$.join(s$(J),"agents"),X=[];if(X2(Z))X.push(Z);if(X2(Q))X.push(Q);return{readDirs:X,preferredDir:Q}}function VY($){let J=_J($);if(!J)return{readDirs:[],preferredDir:null};let Z=B$.join(s$(J),"chains");return{readDirs:X2(Z)?[Z]:[],preferredDir:Z}}var zY=B$.resolve(B$.dirname(lX(import.meta.url)),"..","..","agents"),GY="DM_SUBAGENT_EXTRA_AGENT_DIRS";function BY(){let $=process.env[GY];if(!$)return[];return $.split(B$.delimiter).map((J)=>J.trim()).filter((J)=>J.length>0)}function t$($){let J=B$.join(Y0(),"agents"),Z=B$.join(H8.homedir(),".agents"),Q=nX(),{readDirs:X,preferredDir:Y}=UY($),{readDirs:H,preferredDir:j}=VY($),U=V8(),G=z8($),z=XZ(U),V=XZ(G),B=XY(z,V,U,G),K=JY($),W=HY(X8(WJ(zY,"builtin"),B),z,V,U,G),A=a4(X8([...BY().flatMap((M)=>WJ(M,"user")),...WJ(J,"user"),...WJ(Z,"user")],B),z,V,U,G),F=new Map;for(let M of K.agents)for(let N of WJ(M,"package"))if(!F.has(N.name))F.set(N.name,N);let _=a4(X8(Array.from(F.values()),B),z,V,U,G),f=new Map;for(let M of X)for(let N of WJ(M,"project"))f.set(N.name,N);let O=a4(X8(Array.from(f.values()),B),z,V,U,G),y=new Map,C=[],T=new Map;for(let M of K.chains){let N=t4(M,"package");C.push(...N.diagnostics);for(let E of N.chains)if(!T.has(E.name))T.set(E.name,E)}let h=[];for(let M of H){let N=t4(M,"project");h.push(...N.diagnostics);for(let E of N.chains)y.set(E.name,E)}let b=t4(Q,"user"),w=[...Array.from(T.values()),...b.chains,...Array.from(y.values())],q=[...C,...b.diagnostics,...h],S=process.env.DM_CODING_AGENT_DIR?J:x$.existsSync(Z)?Z:J;return{builtin:W,package:_,user:A,project:O,chains:w,chainDiagnostics:q,userDir:S,projectDir:Y,userChainDir:Q,projectChainDir:j,userSettingsPath:U,projectSettingsPath:G}}var BZ="agent-memory",H6="MEMORY.md",j6=200,u1=16384,KY=new Set(["edit","write","bash"]);function KZ($){let J=$.trim();if(J.startsWith('"')&&J.endsWith('"')||J.startsWith("'")&&J.endsWith("'"))return J.slice(1,-1);return J}function GZ($){if(!$)return;let J=new Map,Q=$.trim().match(/^\{(.*)\}$/s);if(Q)for(let H of Q[1].split(",")){let j=H.trim().match(/^([\w-]+)\s*:\s*(.*)$/);if(!j)continue;J.set(j[1],KZ(j[2]))}else for(let H of $.split(`
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`,V=Buffer.byteLength(z,"utf-8");if(j+V>U)return;try{let B=X.write(z);if(j+=V,!B&&!Y)Y=!0,J.pause(),X.once("drain",()=>{if(Y=!1,!H)J.resume()})}catch{}},async close(){if(!X||H)return;H=!0;let G=X;X=void 0,await new Promise((z)=>G.end(()=>z()))}}}function c0($,J){try{return $.kill(J)}catch{return!1}}function fZ($,J){let{idleMs:Z,hardMs:Q}=J,X=!1,Y=!1,H=!1,j,U,G=()=>{if(!Y)try{$.stdout?.destroy()}catch{}if(!H)try{$.stderr?.destroy()}catch{}},z=()=>{if(j)clearTimeout(j),j=void 0;if(U)clearTimeout(U),U=void 0},V=()=>{if(!X)return;if(j)clearTimeout(j);j=setTimeout(G,Z),j.unref?.()};return $.stdout?.on("data",V),$.stderr?.on("data",V),$.stdout?.on("end",()=>{if(Y=!0,Y&&H)z()}),$.stderr?.on("end",()=>{if(H=!0,Y&&H)z()}),$.on("exit",()=>{if(X=!0,V(),U)return;U=setTimeout(G,Q),U.unref?.()}),$.on("close",z),$.on("error",z),z}import*as S0 from"node:fs";import*as _6 from"node:os";import*as Z0 from"node:path";import{fileURLToPath as oZ}from"node:url";import*as wZ from"node:path";var mY=128,cY=4;function B6($){return typeof $==="string"&&$.length>0&&$.length<=mY&&!wZ.isAbsolute($)&&!$.includes("/")&&!$.includes("\\")&&!$.includes("..")}function DZ($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function bZ($,J){return typeof $==="string"&&$.length>0?$.slice(0,J):void 0}function B8($){if(!Array.isArray($))return[];return $.map((J)=>{if(!J||typeof J!=="object")return;let Z=J;if(!B6(Z.runId))return;return{runId:Z.runId,...DZ(Z.stepIndex)!==void 0?{stepIndex:DZ(Z.stepIndex)}:{},...bZ(Z.agent,128)?{agent:bZ(Z.agent,128)}:{}}}).filter((J)=>Boolean(J)).slice(0,cY)}function K8($){if(!$)return[];try{return B8(JSON.parse($))}catch{return[]}}function IZ($){let J=B8($);return J.length?JSON.stringify(J):""}import{createHash as uY}from"node:crypto";import*as AJ from"node:fs";import*as u0 from"node:os";import*as K0 from"node:path";var dY=1,oY=604800000,kZ=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),PZ=K0.join(u0.homedir(),".config","mcp","mcp.json"),hZ={cursor:[K0.join(u0.homedir(),".cursor","mcp.json")],"claude-code":[K0.join(u0.homedir(),".claude","mcp.json"),K0.join(u0.homedir(),".claude.json"),K0.join(u0.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[K0.join(u0.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[K0.join(u0.homedir(),".codex","config.json")],windsurf:[K0.join(u0.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};function gZ($,J=process.cwd()){if(!$?.length)return[];try{let Z=nY(J),Q=lY();if(!Q)return[];return $H(Z,Q,XH(Z.settings?.toolPrefix),$)}catch{return[]}}function lY(){let $=K0.join(Y0(),"mcp-cache.json"),J;try{J=JSON.parse(AJ.readFileSync($,"utf-8"))}catch{return null}if(!J||typeof J!=="object")return null;let Z=J;if(Z.version!==dY||!Z.servers||typeof Z.servers!=="object"||Array.isArray(Z.servers))return null;return Z}function nY($){let J={mcpServers:{}};for(let Z of pY($)){let Q=iY(Z);if(!Q)continue;J=sY(J,aY(Q,$))}return J}function pY($){let J=K0.join(Y0(),"mcp.json"),Z=K0.resolve($,".mcp.json"),Q=K0.resolve(s$($),"mcp.json"),X=[];if(PZ!==J)X.push(PZ);if(X.push(J),Z!==J)X.push(Z);if(Q!==J&&Q!==Z)X.push(Q);return X}function iY($){let J;try{J=JSON.parse(AJ.readFileSync($,"utf-8"))}catch{return null}return rY(J)}function rY($){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)=>YH(Q)):void 0,settings:J.settings&&typeof J.settings==="object"&&!Array.isArray(J.settings)?J.settings:void 0}}function sY($,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 aY($,J){if(!$.imports?.length)return $;let Z={};for(let Q of $.imports){let X=tY(Q,J);if(!X)continue;let Y;try{Y=JSON.parse(AJ.readFileSync(X,"utf-8"))}catch{continue}for(let[H,j]of Object.entries(eY(Y,Q)))if(!Z[H])Z[H]=j}return{imports:$.imports,settings:$.settings,mcpServers:{...Z,...$.mcpServers}}}function tY($,J){for(let Z of hZ[$]){let Q=Z.startsWith(".")?K0.resolve(J,Z):Z;if(AJ.existsSync(Q))return Q}return null}function eY($,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 $H($,J,Z,Q){let X=[],Y=new Set,{servers:H,tools:j}=JH(Q);for(let[U,G]of Object.entries($.mcpServers)){let z=J.servers[U];if(!ZH(z,G))continue;let V=H.has(U)?!0:j.get(U);if(!V)continue;for(let B of Array.isArray(z.tools)?z.tools:[]){if(typeof B?.name!=="string"||!B.name)continue;if(V!==!0&&!V.has(B.name))continue;if(xZ(B.name,U,Z,G.excludeTools))continue;let K=j2(B.name,U,Z);if(kZ.has(K)||Y.has(K))continue;Y.add(K),X.push(K)}if(G.exposeResources===!1)continue;for(let B of Array.isArray(z.resources)?z.resources:[]){if(typeof B?.name!=="string"||!B.name||typeof B.uri!=="string"||!B.uri)continue;let K=`get_${jH(B.name)}`;if(V!==!0&&!V.has(K))continue;if(xZ(K,U,Z,G.excludeTools))continue;let W=j2(K,U,Z);if(kZ.has(W)||Y.has(W))continue;Y.add(W),X.push(W)}}return X}function JH($){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 ZH($,J){if(!$||$.configHash!==QH(J))return!1;if(!$.cachedAt||typeof $.cachedAt!=="number")return!1;return Date.now()-$.cachedAt<=oY}function QH($){let J={command:$.command,args:$.args,env:vZ($.env),cwd:UH($.cwd),url:$.url,headers:vZ($.headers),auth:$.auth,bearerToken:VH($),bearerTokenEnv:$.bearerTokenEnv,exposeResources:$.exposeResources,excludeTools:$.excludeTools};return uY("sha256").update(K6(J)).digest("hex")}function XH($){return $==="none"||$==="short"||$==="server"?$:"server"}function YH($){return typeof $==="string"&&Object.hasOwn(hZ,$)}function HH($,J){if(J==="none")return"";if(J==="short")return $.replace(/-?mcp$/i,"").replace(/-/g,"_")||"mcp";return $.replace(/-/g,"_")}function j2($,J,Z){let Q=HH(J,Z);return Q?`${Q}_${$}`:$}function xZ($,J,Z,Q){if(!Array.isArray(Q)||Q.length===0)return!1;let X=new Set([H2($),H2(j2($,J,Z)),H2(j2($,J,"server")),H2(j2($,J,"short"))]);return Q.some((Y)=>typeof Y==="string"&&X.has(H2(Y)))}function H2($){return $.replace(/-/g,"_")}function jH($){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 vZ($){if(!$||typeof $!=="object"||Array.isArray($))return;let J={};for(let[Z,Q]of Object.entries($))if(typeof Q==="string")J[Z]=W6(Q);return J}function W6($){return $.replace(/\$\{(\w+)\}/g,(J,Z)=>process.env[Z]??"").replace(/\$env:(\w+)/g,(J,Z)=>process.env[Z]??"")}function UH($){if(typeof $!=="string")return;let J=W6($);if(J==="~")return u0.homedir();if(J.startsWith("~/")||J.startsWith("~\\"))return K0.join(u0.homedir(),J.slice(2));return J}function VH($){if(typeof $.bearerToken==="string")return W6($.bearerToken);return typeof $.bearerTokenEnv==="string"?process.env[$.bearerTokenEnv]:void 0}function K6($){if($===null||$===void 0||typeof $!=="object"){let Z=JSON.stringify($);return Z===void 0?"undefined":Z}if(Array.isArray($))return`[${$.map((Z)=>K6(Z)).join(",")}]`;let J=$;return`{${Object.keys(J).sort().map((Z)=>`${JSON.stringify(Z)}:${K6(J[Z])}`).join(",")}}`}var zH=["off","minimal","low","medium","high","xhigh"],GH=8000;function F8($,J){let Z=oZ($),Q=Z0.extname(Z),X=[".js",".mjs",".cjs",".ts",".mts",".cts"].includes(Q)?Q:".ts";return Z0.join(Z0.dirname(Z),`${J}${X}`)}function lZ($){return Z0.basename(oZ($)).startsWith("dm-args.")}function BH($=import.meta.url){let J=lZ($)?"subagent-prompt-runtime":Z0.join("..","runs","shared","subagent-prompt-runtime");return F8($,J)}function KH($=import.meta.url){let J=lZ($)?Z0.join("..","..","extension","fanout-child"):"fanout-child";return F8($,J)}var mZ=BH(),WH=KH(),_H="DM_SUBAGENT_CHILD",AH="DM_SUBAGENT_ORCHESTRATOR_TARGET",qH="DM_SUBAGENT_ORCHESTRATOR_SESSION_ID",OH="DM_SUBAGENT_SUPERVISOR_CHANNEL_DIR",cZ="DM_SUBAGENT_RUN_ID",FH="DM_SUBAGENT_CHILD_AGENT",LH="DM_SUBAGENT_CHILD_INDEX",MH="DM_SUBAGENT_FANOUT_CHILD",U2="DM_SUBAGENT_PARENT_EVENT_SINK",W8="DM_SUBAGENT_PARENT_CONTROL_INBOX",V2="DM_SUBAGENT_PARENT_ROOT_RUN_ID",_8="DM_SUBAGENT_PARENT_RUN_ID",A8="DM_SUBAGENT_PARENT_CHILD_INDEX",q8="DM_SUBAGENT_PARENT_DEPTH",O8="DM_SUBAGENT_PARENT_PATH",z2="DM_SUBAGENT_PARENT_CAPABILITY_TOKEN",uZ="DM_SUBAGENT_PARENT_SESSION",NH="DM_SUBAGENT_STEER_INBOX";function dZ($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function EH($,J,Z){return Z0.join(G0,"supervisor-channels",`${dZ($)}-${dZ(J)}-${Z}`)}function R1($,J,Z=!1){if(!$||!J)return $;let Q=$.lastIndexOf(":");if(Q!==-1&&zH.includes($.substring(Q+1)))return Z?`${$.slice(0,Q)}:${J}`:$;return`${$}:${J}`}function nZ($){let J=[...$.baseArgs];if($.sessionFile)S0.mkdirSync(Z0.dirname($.sessionFile),{recursive:!0}),J.push("--session",$.sessionFile);else{if(!$.sessionEnabled)J.push("--no-session");if($.sessionDir)S0.mkdirSync($.sessionDir,{recursive:!0}),J.push("--session-dir",$.sessionDir)}let Z=R1($.model,$.thinking);if(Z)J.push("--model",Z);let Q=$.tools?.filter((_)=>!(_.includes("/")||_.endsWith(".ts")||_.endsWith(".js")))??[],X=$.requireReadTool&&$.tools?.length&&!Q.includes("read")?["read",...Q]:Q,Y=X.includes("subagent"),H=[];if($.tools?.length){let _=[...X];for(let f of $.tools)if(!X.includes(f)&&(f.includes("/")||f.endsWith(".ts")||f.endsWith(".js")))H.push(f);if(_.length>0){if($.mcpDirectTools?.length)_.push(...gZ($.mcpDirectTools,$.cwd));J.push("--tools",_.join(","))}}let j=Y?[mZ,WH]:[mZ];if($.extensions!==void 0){J.push("--no-extensions");for(let _ of[...new Set([...j,...H,...$.extensions,...$.subagentOnlyExtensions??[]])])J.push("--extension",_)}else for(let _ of[...new Set([...j,...H,...$.subagentOnlyExtensions??[]])])J.push("--extension",_);if(!$.inheritSkills)J.push("--no-skills");let U;if($.systemPrompt!==void 0&&$.systemPrompt!==null){U=S0.mkdtempSync(Z0.join(_6.tmpdir(),"dm-subagent-"));let _=($.promptFileStem??"prompt").replace(/[^\w.-]/g,"_"),f=Z0.join(U,`${_}.md`);S0.writeFileSync(f,$.systemPrompt,{mode:384}),J.push($.systemPromptMode==="replace"?"--system-prompt":"--append-system-prompt",f)}if($.task.length>GH){if(!U)U=S0.mkdtempSync(Z0.join(_6.tmpdir(),"dm-subagent-"));let _=Z0.join(U,"task.md");S0.writeFileSync(_,`Task: ${$.task}`,{mode:384}),J.push(`@${_}`)}else J.push(`Task: ${$.task}`);let G={};G[_H]="1",G[MH]=Y?"1":"0";let z=Boolean(process.env[U2]&&process.env[V2]&&process.env[z2]),V=$.parentRunId??$.runId??(z?process.env[cZ]:void 0)??process.env[_8]??"",B=$.parentChildIndex!==void 0?String($.parentChildIndex):$.childIndex!==void 0?String($.childIndex):process.env[A8]??"",K=Number(process.env[q8]),W=$.parentDepth??(z&&Number.isFinite(K)?K+1:1),A=$.parentPath??[...K8(process.env[O8]),...V?[{runId:V,...B&&/^\d+$/.test(B)?{stepIndex:Number(B)}:{},...$.childAgentName?{agent:$.childAgentName}:{}}]:[]];if(G[U2]=Y?$.parentEventSink??process.env[U2]??"":"",G[W8]=Y?$.parentControlInbox??process.env[W8]??"":"",G[V2]=Y?$.parentRootRunId??process.env[V2]??$.runId??"":"",G[_8]=Y?V:"",G[A8]=Y?B:"",G[q8]=Y?String(W):"",G[O8]=Y?IZ(A):"",G[z2]=Y?$.parentCapabilityToken??process.env[z2]??"":"",G.DM_SUBAGENT_INHERIT_PROJECT_CONTEXT=$.inheritProjectContext?"1":"0",G.DM_SUBAGENT_INHERIT_SKILLS=$.inheritSkills?"1":"0",$.intercomSessionName)G.DM_SUBAGENT_INTERCOM_SESSION_NAME=$.intercomSessionName;if($.orchestratorIntercomTarget)G[AH]=$.orchestratorIntercomTarget;if($.parentSessionId)G[qH]=$.parentSessionId;if($.orchestratorIntercomTarget&&$.parentSessionId&&$.runId&&$.childAgentName){let _=$.childIndex??0,f=EH($.runId,$.childAgentName,_);S0.mkdirSync(Z0.join(f,"requests"),{recursive:!0}),S0.mkdirSync(Z0.join(f,"replies"),{recursive:!0}),G[OH]=f}if($.runId)G[cZ]=$.runId;if($.childAgentName)G[FH]=$.childAgentName;if($.childIndex!==void 0)G[LH]=String($.childIndex);if($.mcpDirectTools?.length)G.MCP_DIRECT_TOOLS=$.mcpDirectTools.join(",");else G.MCP_DIRECT_TOOLS="__none__";if($.structuredOutput)G[f5]=$.structuredOutput.outputPath,G[y5]=$.structuredOutput.schemaPath;if($.steerInboxDir)G[NH]=$.steerInboxDir;let F=a5($.toolBudget);if(F)G[r5]=F;return G[uZ]=$.parentSessionId??process.env[uZ]??"",{args:J,env:G,tempDir:U}}function A6($){if(!$)return;try{S0.rmSync($,{recursive:!0,force:!0})}catch{}}import*as G1 from"node:fs";import*as J1 from"node:path";function qJ($,J){if($===!1||$==="false")return!1;if($===!0||$==="true")return J;if(typeof $==="string"&&$.length>0)return $;return}function y1($,J,Z,Q){if(typeof $!=="string"||!$||$==="false"||$==="true")return;if(J1.isAbsolute($))return $;if(Q)return J1.resolve(Q,$);let X=Z?J1.isAbsolute(Z)?Z:J1.resolve(J,Z):J;return J1.resolve(X,$)}function pZ($){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(`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
${
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
${J}`:$}function B2($){return{...$,outcome:"within-budget",turnCount:0}}function L6($,J,Z){return{...$,turnCount:J,outcome:Z?"exceeded":"wrap-up-requested",wrapUpRequestedAtTurn:$.maxTurns,...Z?{exceededAtTurn:J}:{}}}function $3($,J,Z){let Q=$.maxTurns+$.graceTurns;if(J<Q)return!1;if(J>Q)return!0;return!Z}var Z3=new WeakMap,Q3=new WeakMap;function FJ(){return{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,turns:0}}function fH($,J){$.input+=J.input,$.output+=J.output,$.cacheRead+=J.cacheRead,$.cacheWrite+=J.cacheWrite,$.cost+=J.cost,$.turns+=J.turns}function X3($){return`Subagent timed out after ${$}ms.`}function DH($){if($.timeoutMs===void 0)return;let J=$.deadlineAt??Date.now()+$.timeoutMs;return{timeoutMs:$.timeoutMs,remainingMs:Math.max(0,J-Date.now()),message:X3($.timeoutMs)}}function J3($,J){return{status:$.level==="none"?"not-required":"rejected",explicit:$.explicit,effectiveAcceptance:$,inferredReason:$.inferredReason,criteria:$.criteria,runtimeChecks:$.level==="none"?[]:[{id:J.id,status:"failed",message:J.message}],verifyRuns:[]}}function M6($,J){if(J.length===0)return;if($.recentOutput.push(...J.filter((Z)=>Z.trim())),$.recentOutput.length>50)$.recentOutput.splice(0,$.recentOutput.length-50)}function bH($){for(let J of $??[]){if(J.role!=="assistant"||!Array.isArray(J.content))continue;for(let Z of J.content)if(Z.type==="text"&&"text"in Z&&typeof Z.text==="string")Z.text=Z8(Z.text)}}function N6($){return{...$,skills:$.skills?[...$.skills]:void 0,recentTools:$.recentTools.map((J)=>({...J})),recentOutput:[...$.recentOutput]}}function E6($,J){return{...$,messages:$.outputMode==="file-only"&&$.savedOutputPath?void 0:$.messages?[...$.messages]:void 0,usage:{...$.usage},skills:$.skills?[...$.skills]:void 0,attemptedModels:$.attemptedModels?[...$.attemptedModels]:void 0,modelAttempts:$.modelAttempts?$.modelAttempts.map((Z)=>({...Z,usage:Z.usage?{...Z.usage}:void 0})):void 0,controlEvents:$.controlEvents?$.controlEvents.map((Z)=>({...Z})):void 0,progress:J,progressSummary:$.progressSummary?{...$.progressSummary}:void 0,artifactPaths:$.artifactPaths?{...$.artifactPaths}:void 0,truncation:$.truncation?{...$.truncation}:void 0,outputReference:$.outputReference?{...$.outputReference}:void 0}}async function wH($,J,Z,Q,X,Y){let H=X.thinkingOverride??J.thinking,j=R1(Q,H,X.thinkingOverride!==void 0),{args:U,env:G,tempDir:z}=nZ({baseArgs:["--mode","json","-p"],task:Z,sessionEnabled:Y.sessionEnabled,sessionDir:X.sessionDir,sessionFile:X.sessionFile,model:j,thinking:H,systemPromptMode:J.systemPromptMode,inheritProjectContext:J.inheritProjectContext,inheritSkills:J.inheritSkills,requireReadTool:Boolean(Y.resolvedSkillNames?.length),tools:J.tools,extensions:J.extensions,subagentOnlyExtensions:J.subagentOnlyExtensions,systemPrompt:tZ(Y.systemPrompt,X.turnBudget),mcpDirectTools:J.mcpDirectTools,cwd:X.cwd??$,promptFileStem:J.name,intercomSessionName:X.intercomSessionName,orchestratorIntercomTarget:X.orchestratorIntercomTarget,runId:X.runId,childAgentName:J.name,childIndex:X.index??0,parentEventSink:X.nestedRoute?.eventSink,parentControlInbox:X.nestedRoute?.controlInbox,parentRootRunId:X.nestedRoute?.rootRunId,parentCapabilityToken:X.nestedRoute?.capabilityToken,parentSessionId:X.parentSessionId,structuredOutput:X.structuredOutput,toolBudget:X.toolBudget}),V={agent:J.name,task:Y.originalTask??Z,exitCode:0,messages:[],usage:FJ(),model:j,artifactPaths:Y.artifactPaths,transcriptPath:Y.transcriptWriter?Y.artifactPaths?.transcriptPath:void 0,skills:Y.resolvedSkillNames,skillsWarning:Y.skillsWarning,...X.turnBudget?{turnBudget:B2(X.turnBudget)}:{},...X.toolBudget?{toolBudget:s5(X.toolBudget)}:{}},B=Date.now();if(X.structuredOutput)try{if(T6(X.structuredOutput.outputPath))yH(X.structuredOutput.outputPath)}catch{}let K=X.controlConfig??T1,W=!1,A=[],F=[],_=new Set,f=(S)=>{if(!pJ(K,S))return;if(!T5(K,S,_))return;A.push(S),F.push(S),X.onControlEvent?.(S)},O={index:X.index??0,agent:J.name,status:"running",task:Z,skills:Y.resolvedSkillNames,recentTools:[],recentOutput:[...Y.attemptNotes],toolCount:0,tokens:0,durationMs:0,lastActivityAt:B};V.progress=O;let y=DH(X);if(y?.remainingMs===0)return V.exitCode=1,V.timedOut=!0,V.error=y.message,V.finalOutput=y.message,O.status="failed",O.error=y.message,V.progressSummary={toolCount:O.toolCount,tokens:O.tokens,durationMs:O.durationMs},V;let C={...process.env,...G,...b9(X.maxSubagentDepth)},T=!1,h=await new Promise((S)=>{let M=CZ(U),N=RH(M.command,M.args,{cwd:X.cwd??$,env:C,stdio:["ignore","pipe","pipe"],windowsHide:!0}),E=yZ(Y.jsonlPath,N.stdout),n="",L=!1,k=!1,o=!1,g=!1,I,a,O$,P,w$,$$,l,v$=!1,c,H$,F$=()=>{if(c)clearTimeout(c),c=void 0;if(H$)clearTimeout(H$),H$=void 0},z$=()=>{if(w$)clearTimeout(w$),w$=void 0;if($$)clearTimeout($$),$$=void 0;if(l)clearTimeout(l),l=void 0},Y$=()=>{o=!0,L=!0,V.detached=!0,V.detachedReason="intercom coordination",O.status="detached",O.durationMs=Date.now()-B,V.progressSummary={toolCount:O.toolCount,tokens:O.tokens,durationMs:O.durationMs},A$(-2)},Z$=1000,K$=3000,_$=!1,R=!1,i=!1,n$,J$,c$=()=>{if(n$)clearTimeout(n$),n$=void 0;if(J$)clearTimeout(J$),J$=void 0},N$=()=>{if(_$||n$||k||L||o)return;n$=setTimeout(()=>{if(k||L||o)return;if(!c0(N,"SIGTERM"))return;if(R=!0,!i&&!I)V.error=V.error??`Subagent process did not exit within ${Z$}ms after its final message. Forcing termination.`;J$=setTimeout(()=>{if(k||L||o)return;R=c0(N,"SIGKILL")||R},K$),J$.unref?.()},Z$),n$.unref?.()},X$=X.intercomEvents?.on?.(M9,(v)=>{if(!X.allowIntercomDetach||o||L||!g)return;if(!v||typeof v!=="object")return;let d=v.requestId;if(typeof d!=="string"||d.length===0)return;X.intercomEvents?.emit(N9,{requestId:d,accepted:!0}),Y$()}),A$=(v)=>{if(k)return;if(k=!0,c$(),l$(),z$(),F$(),P)clearInterval(P),P=void 0;X$?.(),a?.(),O$?.(),S(v)},U$=()=>{if(F.length===0)return;let v=F;return F=[],v},m=!1,R$,i$=LZ(),s=300000,p=(v)=>O.currentToolStartedAt?Math.max(0,v-O.currentToolStartedAt):void 0,M$=(v,d={})=>{if(!K.enabled)return!1;let L$=O.activityState;O.activityState="needs_attention";let y$=e2({type:"needs_attention",from:L$,to:"needs_attention",runId:X.runId,agent:J.name,index:X.index,ts:v,lastActivityAt:O.lastActivityAt,message:d.message,reason:d.reason??"idle",turns:V.usage.turns,tokens:O.tokens,toolCount:O.toolCount,currentTool:d.currentTool??O.currentTool,currentToolDurationMs:d.currentToolDurationMs??p(v),currentPath:d.currentPath??O.currentPath,recentFailureSummary:d.recentFailureSummary});return f(y$),L$!=="needs_attention"},x=(v,d)=>{if(!K.enabled||m||O.activityState==="needs_attention")return!1;m=!0;let L$=O.activityState;return O.activityState="active_long_running",f(e2({type:"active_long_running",from:L$,to:"active_long_running",runId:X.runId,agent:J.name,index:X.index,ts:v,message:`${J.name} is still active but long-running`,reason:d,turns:V.usage.turns,tokens:O.tokens,toolCount:O.toolCount,currentTool:O.currentTool,currentToolDurationMs:p(v),currentPath:O.currentPath,elapsedMs:v-B})),!0},Q$=(v)=>{let d=X.turnBudget;if(!d||V.timedOut||V.turnBudgetExceeded||W||L||k||o)return;let L$=F6(d,v);V.turnBudgetExceeded=!0,V.wrapUpRequested=!0,V.turnBudget=L6(d,v,!0),V.error=L$,V.finalOutput=L$,O.status="failed",O.error=L$,O.durationMs=Date.now()-B,D(),c0(N,"SIGINT"),c=setTimeout(()=>{if(L||k||o||V.timedOut)return;c0(N,"SIGTERM")},1000),c.unref?.(),H$=setTimeout(()=>{if(L||k||o||V.timedOut)return;c0(N,"SIGKILL")},4000),H$.unref?.()},p$=(v,d)=>{let L$=X.turnBudget;if(!L$||V.timedOut||V.turnBudgetExceeded)return;if(v<L$.maxTurns){V.turnBudget={...L$,outcome:"within-budget",turnCount:v};return}if(!v$)v$=!0,V.wrapUpRequested=!0,M6(O,[O6(L$,v)]);if(V.turnBudget=L6(L$,v,!1),$3(L$,v,d))Q$(v)},I$=(v)=>{if(!K.enabled)return!1;if(N5({config:K,startedAt:B,lastActivityAt:O.lastActivityAt,now:v})==="needs_attention")return O.activityState==="needs_attention"?!1:M$(v);let L$=OZ(K,{startedAt:B,now:v,turns:V.usage.turns,tokens:O.tokens});return L$?x(v,L$):!1},F1=(v)=>{if(!X.onUpdate||L)return;let d=N6(O),L$=E6(V,d),y$=U$();X.onUpdate({content:[{type:"text",text:v}],details:{mode:"single",results:[L$],progress:[d],controlEvents:y$}})},D=()=>{if(!X.onUpdate||L)return;O.durationMs=Date.now()-B;let v=(V.timedOut||V.turnBudgetExceeded)&&V.finalOutput?V.finalOutput:YJ(V.messages);F1(v||"(running...)")},G$=(v)=>{if(!v.trim())return;E.writeLine(v);let d;try{d=JSON.parse(v)}catch{Y.transcriptWriter?.writeStdoutLine(v);return}Y.transcriptWriter?.writeChildEvent(d);let L$=Date.now();if(O.durationMs=L$-B,O.lastActivityAt=L$,I$(L$),d.type==="tool_execution_start"){let y$=d.args&&typeof d.args==="object"&&!Array.isArray(d.args)?d.args:{},D$=!1;if(X.allowIntercomDetach&&(d.toolName==="intercom"||d.toolName==="contact_supervisor"))g=!0,D$=d.toolName==="intercom"&&y$.action==="ask"||d.toolName==="contact_supervisor"&&(y$.reason==="need_decision"||y$.reason==="interview_request");if(O.toolCount++,X.toolBudget)V.toolBudget=p4(X.toolBudget,O.toolCount);O.currentTool=d.toolName,O.currentToolArgs=l2(y$),O.currentToolStartedAt=L$,O.currentPath=_Z(d.toolName,y$);let p0=AZ(d.toolName,y$);if(T=T||p0,R$={tool:d.toolName??"tool",path:O.currentPath,mutates:p0,startedAt:L$},D(),D$&&!o&&!L)Y$()}if(d.type==="tool_execution_end"){if(O.currentTool)O.recentTools.push({tool:O.currentTool,args:O.currentToolArgs||"",endMs:L$});O.currentTool=void 0,O.currentToolArgs=void 0,O.currentToolStartedAt=void 0,O.currentPath=void 0,D()}if(d.type==="message_end"&&d.message){if(V.messages.push(d.message),d.message.role==="assistant"){V.usage.turns++,O.turnCount=V.usage.turns;let y$=d.message.stopReason,D$=Array.isArray(d.message.content)&&d.message.content.some((a7)=>a7.type==="toolCall"),p0=y$==="stop"&&!D$;p$(V.usage.turns,p0);let t1=d.message.usage;if(t1)V.usage.input+=t1.input||0,V.usage.output+=t1.output||0,V.usage.cacheRead+=t1.cacheRead||0,V.usage.cacheWrite+=t1.cacheWrite||0,V.usage.cost+=t1.cost?.total||0,O.tokens=V.usage.input+V.usage.output;if(!V.model&&d.message.model)V.model=d.message.model;if(d.message.errorMessage)I=d.message.errorMessage;let O9=UJ(d.message.content);if(M6(O,O9.split(`
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
${Y}`}function _3($){if($.stepBudget!==void 0){let Z=O0($.stepBudget,"toolBudget");return{toolBudget:Z.budget,error:Z.error}}if($.runBudget!==void 0)return{toolBudget:$.runBudget};if($.agentBudget!==void 0){let Z=O0($.agentBudget,"agent.toolBudget");return{toolBudget:Z.budget,error:Z.error}}let J=O0($.configBudget,"config.toolBudget");return{toolBudget:J.budget,error:J.error}}async function W3($){let J=$.step.concurrency??X4,Z=$.step.failFast??!1,Q=!1;return await vJ($.step.parallel,J,async(Y,H)=>{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 j=$.parallelTemplates[H]??"{previous}",U=x0($.parallelBehaviors[H],j,$.originalTask),G=j.includes("{previous}"),{prefix:z,suffix:V}=H1(U,$.chainDir,!1,G?void 0:$.prev),B=m4(j,$.outputs);B=B.replace(/\{task\}/g,$.originalTask),B=B.replace(/\{previous\}/g,$.prev),B=B.replace(/\{chain_dir\}/g,$.chainDir);let K=B;B=z+B+V;let W=$.agents.find((h)=>h.name===Y.agent),A=B0(Y.model??W?.model,$.ctx.model,$.availableModels,$.ctx.model?.provider,{scope:$.modelScope,source:Y.model?"explicit":"inherited"}),F=s0($.maxSubagentDepth,W?.maxSubagentDepth),_=_3({stepBudget:Y.toolBudget,runBudget:$.toolBudget,agentBudget:W?.toolBudget,configBudget:$.configToolBudget});if(_.error)throw Error(_.error);let f=$.worktreeSetup?$.worktreeSetup.worktrees[H].agentCwd:v0($.cwd??$.ctx.cwd,Y.cwd),O=typeof U.output==="string"?V0.isAbsolute(U.output)?U.output:V0.join($.chainDir,U.output):void 0,y=new AbortController;if($.foregroundControl)$.foregroundControl.currentAgent=Y.agent,$.foregroundControl.currentIndex=$.globalTaskIndex+H,$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),$.foregroundControl.interrupt=()=>{if(y.signal.aborted)return!1;return y.abort(),$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),!0};let C=Y.outputSchema?rJ(Y.outputSchema,V0.join($.chainDir,"structured-output")):void 0,T=await LJ($.ctx.cwd,$.agents,Y.agent,B,{parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,cwd:f,signal:$.signal,interruptSignal:y.signal,allowIntercomDetach:W?.systemPrompt?.includes(V1)===!0,intercomEvents:$.intercomEvents,runId:$.runId,index:$.globalTaskIndex+H,sessionDir:$.sessionDirForIndex($.globalTaskIndex+H),sessionFile:$.sessionFileForTask?.(Y.agent,$.globalTaskIndex+H)??$.sessionFileForIndex?.($.globalTaskIndex+H),thinkingOverride:$.thinkingOverrideForTask?.(Y.agent,$.globalTaskIndex+H),share:$.shareEnabled,artifactsDir:$.artifactConfig.enabled?$.artifactsDir:void 0,artifactConfig:$.artifactConfig,outputPath:O,outputMode:U.outputMode,maxSubagentDepth:F,controlConfig:$.controlConfig,onControlEvent:$.onControlEvent,intercomSessionName:$.childIntercomTarget?.(Y.agent,$.globalTaskIndex+H),orchestratorIntercomTarget:$.orchestratorIntercomTarget,nestedRoute:$.nestedRoute,modelOverride:A,availableModels:$.availableModels,preferredModelProvider:$.ctx.model?.provider,modelScope:$.modelScope,skills:U.skills===!1?[]:U.skills,structuredOutput:C,acceptance:Y.acceptance,acceptanceContext:{mode:"chain"},timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,turnBudget:$.turnBudget,onDetachedExit:$.onDetachedExit?(h)=>$.onDetachedExit?.($.globalTaskIndex+H,h):void 0,toolBudget:_.toolBudget,onUpdate:$.onUpdate?(h)=>{let b=h.details?.results||[],w=h.details?.progress||[];if($.foregroundControl&&w.length>0){let q=w[0];$.foregroundControl.currentAgent=Y.agent,$.foregroundControl.currentIndex=$.globalTaskIndex+H,$.foregroundControl.currentActivityState=q?.activityState,$.foregroundControl.lastActivityAt=q?.lastActivityAt,$.foregroundControl.currentTool=q?.currentTool,$.foregroundControl.currentToolStartedAt=q?.currentToolStartedAt,$.foregroundControl.currentPath=q?.currentPath,$.foregroundControl.turnCount=q?.turnCount,$.foregroundControl.tokens=q?.tokens,$.foregroundControl.toolCount=q?.toolCount,$.foregroundControl.updatedAt=Date.now()}$.onUpdate?.({...h,details:{mode:"chain",results:$.results.concat(b),progress:$.allProgress.concat(w),controlEvents:h.details?.controlEvents,chainAgents:$.chainAgents,totalSteps:$.totalSteps,currentStepIndex:$.stepIndex,outputs:$.outputs,workflowGraph:NJ({runId:$.runId,mode:"chain",steps:$.chainSteps,results:$.results.concat(b),currentStepIndex:$.stepIndex,currentFlatIndex:$.globalTaskIndex+H,dynamicChildren:$.dynamicChildren,dynamicGroupStatuses:$.dynamicGroupStatuses})}})}:void 0});if($.foregroundControl?.currentIndex===$.globalTaskIndex+H)$.foregroundControl.interrupt=void 0,$.foregroundControl.updatedAt=Date.now();if(T.exitCode!==0&&Z)Q=!0;return MJ(Y.agent,K,T.exitCode,T.progressSummary?.durationMs??0),T},$.globalSemaphore)}async function A3($){let{chain:J,agents:Z,ctx:Q,signal:X,runId:Y,cwd:H,shareEnabled:j,sessionDirForIndex:U,sessionFileForIndex:G,sessionFileForTask:z,thinkingOverrideForTask:V,artifactsDir:B,artifactConfig:K,includeProgress:W,clarify:A,onUpdate:F,onControlEvent:_,controlConfig:f,onDetachedExit:O,childIntercomTarget:y,orchestratorIntercomTarget:C,foregroundControl:T,intercomEvents:h,chainSkills:b,chainDir:w,modelScope:q}=$,S=b??[],M=[],N={},E={},n={},L=[],k=[],o=J.map((R)=>E$(R)?`[${R.parallel.map((i)=>i.agent).join("+")}]`:C$(R)?`expand:${R.parallel.agent}`:R.agent),g=J.length,I=(R={})=>({results:M,...W!==void 0?{includeProgress:W}:{},allProgress:L,allArtifactPaths:k,artifactsDir:B,chainAgents:o,chainSteps:J,totalSteps:g,runId:Y,outputs:N,dynamicChildren:E,dynamicGroupStatuses:n,...R}),a=J[0],O$=$.task??(E$(a)?a.parallel[0].task:C$(a)?a.parallel.task:a.task);try{BJ(J,{maxItems:$.dynamicFanoutMaxItems})}catch(R){if(R instanceof a$)return{content:[{type:"text",text:R.message}],isError:!0,details:W0(I())};throw R}let P=m9(Y,w),w$=J.some((R)=>E$(R)||C$(R)),$$=c9(J),l=A===!0&&Q.hasUI&&!w$,v$,c=Q.modelRegistry.getAvailable().map(y0),H$=I0(H??Q.cwd);if(l){let R=J,i=[];for(let X$ of R){let A$=Z.find((U$)=>U$.name===X$.agent);if(!A$)return hJ(P),{content:[{type:"text",text:`Unknown agent: ${X$.agent}`}],isError:!0,details:W0(I({currentStepIndex:R.indexOf(X$)}))};i.push(A$)}let n$=R.map((X$)=>({output:X$.output,outputMode:X$.outputMode,reads:X$.reads,progress:X$.progress,skills:X0(X$.skill),model:X$.model})),J$=i.map((X$,A$)=>P0(X$,n$[A$],S)),c$=$$,N$=await Q.ui.custom((X$,A$,U$,m)=>new VJ(X$,A$,i,c$,O$,P,J$,c,Q.model?.provider,H$,m),{overlay:!0,overlayOptions:{anchor:"center",width:84,maxHeight:"80%"}});if(!N$||!N$.confirmed)return hJ(P),{content:[{type:"text",text:"Chain cancelled"}],details:W0(I())};if(N$.runInBackground){hJ(P);let X$=J.map((A$,U$)=>{if(E$(A$))return A$;let m=N$.behaviorOverrides[U$];return{...A$,task:N$.templates[U$],...m?.model?{model:m.model}:{},...m?.output!==void 0?{output:m.output}:{},..."outputMode"in A$&&A$.outputMode!==void 0?{outputMode:A$.outputMode}:{},...m?.reads!==void 0?{reads:m.reads}:{},...m?.progress!==void 0?{progress:m.progress}:{},...m?.skills!==void 0?{skill:m.skills}:{}}});return{content:[{type:"text",text:"Launching in background..."}],details:W0(I()),requestedAsync:{chain:X$,chainSkills:S}}}$$=N$.templates,v$=N$.behaviorOverrides}let F$=$.deadlineAt??($.timeoutMs!==void 0?Date.now()+$.timeoutMs:void 0),z$=new xJ($.globalConcurrencyLimit??u2),Y$="",Z$=0,K$=!1;for(let R=0;R<J.length;R++){let i=J[R],n$=$$[R];if(E$(i)){let J$=n$,c$=v0(H??Q.cwd,i.cwd),N$;if(i.worktree){let X$=W2(i.parallel,c$);if(X$)return d0(`parallel chain step ${R+1}: ${_2(X$,c$)}`,I({currentStepIndex:R,currentFlatIndex:Z$}));try{N$=N8(c$,`${Y}-s${R}`,i.parallel.length,{agents:i.parallel.map((A$)=>A$.agent),setupHook:$.worktreeSetupHook?{hookPath:$.worktreeSetupHook,timeoutMs:$.worktreeSetupHookTimeoutMs}:void 0,baseDir:$.worktreeBaseDir})}catch(A$){let U$=A$ instanceof Error?A$.message:String(A$);return d0(U$,I({currentStepIndex:R,currentFlatIndex:Z$}))}}try{let X$=i.parallel.map((x)=>x.agent),A$=_4(i.parallel,Z,R,S).map((x,Q$)=>x0(x,J$[Q$]??i.parallel[Q$]?.task,O$));for(let x=0;x<i.parallel.length;x++){let Q$=A$[x],p$=typeof Q$.output==="string"?V0.isAbsolute(Q$.output)?Q$.output:V0.join(P,Q$.output):void 0,I$=b0(Q$.outputMode,p$,`Parallel chain step ${R+1} task ${x+1} (${i.parallel[x].agent})`);if(I$)return d0(I$,I({currentStepIndex:R,currentFlatIndex:Z$+x}))}K$=K3(P,K$,A$),A4(P,R,i.parallel.length,X$);let U$=await W3({step:i,parallelTemplates:J$,parallelBehaviors:A$,agents:Z,stepIndex:R,availableModels:c,modelScope:q,chainDir:P,prev:Y$,originalTask:O$,ctx:Q,intercomEvents:h,cwd:H,runId:Y,globalTaskIndex:Z$,sessionDirForIndex:U,sessionFileForIndex:G,sessionFileForTask:z,thinkingOverrideForTask:V,shareEnabled:j,artifactConfig:K,artifactsDir:B,signal:X,onUpdate:F,results:M,allProgress:L,outputs:N,chainAgents:o,chainSteps:J,totalSteps:g,dynamicChildren:E,dynamicGroupStatuses:n,controlConfig:f,onControlEvent:_,childIntercomTarget:y,orchestratorIntercomTarget:C,foregroundControl:T,nestedRoute:$.nestedRoute,worktreeSetup:N$,maxSubagentDepth:$.maxSubagentDepth,timeoutMs:$.timeoutMs,deadlineAt:F$,turnBudget:$.turnBudget,onDetachedExit:O,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalSemaphore:z$});Z$+=i.parallel.length;for(let x of U$){if(M.push(x),x.progress)L.push(x.progress);if(x.artifactPaths)k.push(x.artifactPaths)}let m=U$.findIndex((x)=>x.interrupted),R$=m>=0?U$[m]:void 0;if(R$)return{content:[{type:"text",text:`Chain paused after interrupt at step ${R+1} (${R$.agent}). Waiting for explicit next action.`}],details:W0(I({currentStepIndex:R,currentFlatIndex:Z$-i.parallel.length+m}))};let i$=U$.findIndex((x)=>x.detached),s=i$>=0?U$[i$]:void 0;if(s)return{content:[{type:"text",text:`Chain detached for intercom coordination at step ${R+1} (${s.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.`}],details:W0(I({currentStepIndex:R,currentFlatIndex:Z$-i.parallel.length+i$}))};let p=U$.map((x,Q$)=>({...x,originalIndex:Q$})).filter((x)=>x.exitCode!==0&&x.exitCode!==-1);if(p.length>0){let x=p.map((I$)=>`- Task ${I$.originalIndex+1} (${I$.agent}): ${I$.error||"failed"}`).join(`
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
${D$}`:D$}}catch{}if(J$.as)N[J$.as]=c4(v,R);Y$=f0(v)}}return{content:[{type:"text",text:gJ(J,M,P,"completed")}],details:W0(I())}}function S8($){if($==="user"||$==="project"||$==="both")return $;return"both"}import*as o$ from"node:fs";import*as B1 from"node:path";var Qj=["reviewer","context-builder","delegate"];function q3($){if(typeof $!=="number")return;if(!Number.isInteger($)||!Number.isFinite($)||$<1)return;return $}function F3($){if($===!1)return{enabled:!1,minReferences:2,maxRecommendations:3,preferredAgent:"reviewer"};let J=q3($?.maxRecommendations)??3;return{enabled:$?.enabled??!0,minReferences:q3($?.minReferences)??2,maxRecommendations:Math.min(J,5),preferredAgent:typeof $?.preferredAgent==="string"&&$.preferredAgent.trim()?$.preferredAgent.trim():"reviewer"}}function Xj($){if($===!1||$===!0||$===void 0||$===null)return[];if(Array.isArray($))return[...new Set($.filter((J)=>typeof J==="string").map((J)=>J.trim()).filter(Boolean))];if(typeof $==="string")return[...new Set($.split(",").map((J)=>J.trim()).filter(Boolean))];return[]}function R6($,J){for(let Q of Xj($.skills??$.skill))J.add(Q);let Z=$.parallel;if(!Z)return;if(Array.isArray(Z)){for(let Q of Z)if(Q&&typeof Q==="object"&&!Array.isArray(Q))R6(Q,J);return}if(typeof Z==="object")R6(Z,J)}function Yj($,J){let Z=$.filter((Q)=>!Q.disabled);if(Z.some((Q)=>Q.name===J))return J;for(let Q of Qj)if(Z.some((X)=>X.name===Q))return Q;return Z[0]?.name}function O3($,J,Z){if(J==="dm-subagents")return;let Q=$.get(J)??new Set;Q.add(Z),$.set(J,Q)}function Hj($){let J=F3($.config);if(!J.enabled)return[];let Z=Yj($.agents,J.preferredAgent);if(!Z)return[];let Q=$.availableSkills?new Map($.availableSkills.map((Y)=>[Y.name,Y])):void 0,X=new Map;for(let Y of $.agents){if(Y.disabled)continue;for(let H of Y.skills??[])O3(X,H,`agent:${Y.name}`)}for(let Y of $.chains??[]){let H=new Set;for(let j of Y.steps)R6(j,H);for(let j of H)O3(X,j,`chain:${Y.name}`)}return[...X.entries()].filter(([Y,H])=>H.size>=J.minReferences&&(!Q||Q.has(Y))).map(([Y,H])=>({skill:Y,agent:Z,references:H.size,sources:[...H].sort((j,U)=>j.localeCompare(U)),description:Q?.get(Y)?.description,reason:`referenced by ${H.size} configured agents/chains`})).sort((Y,H)=>H.references-Y.references||Y.skill.localeCompare(H.skill)).slice(0,J.maxRecommendations)}function jj($){if($.length===0)return[];return["Proactive skill subagent suggestions:",...$.map((J)=>{let Z=J.sources.slice(0,3).join(", "),Q=J.sources.length>3?`, +${J.sources.length-3} more`:"",X=J.description?` - ${J.description}`:"";return`- ${J.skill} via ${J.agent} (${J.reason}; ${Z}${Q})${X}`}),"Guardrails: use these for broad tasks where a skill-specialist pass is useful; keep fanout small, use fresh context unless private/session context is explicitly needed, and skip when the user asks for a direct answer."]}function L3($){if(!F3($.config).enabled)return[];let J;try{J=$.discoverAvailableSkills()}catch{J=[]}return jj(Hj({agents:$.agents,chains:$.chains,availableSkills:J,config:$.config}))}function u($,J=!1){return{content:[{type:"text",text:$}],isError:J,details:{mode:"management",results:[]}}}function EJ($){return[...new Set($.split(",").map((J)=>J.trim()).filter(Boolean))]}function T3($){let J=$;if(typeof J==="string")try{J=JSON.parse(J)}catch(Z){return{error:`config must be valid JSON: ${Z instanceof Error?Z.message:String(Z)}`}}if(!J||typeof J!=="object"||Array.isArray(J))return{};return{value:J}}function r($,J){return Object.prototype.hasOwnProperty.call($,J)}function O2($){if($==="user"||$==="project")return $;return}function y8($,J){if($===void 0)return{scope:"user"};let Z=O2($);return Z?{scope:Z}:{error:u(`agentScope must be 'user' or 'project' for ${J}.`,!0)}}function Uj($){if($===void 0)return"both";if($==="user"||$==="project"||$==="both")return $;return}function f1($){return $.toLowerCase().trim().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function y6($){return S1($,"config.package")}function F2($){return[...$.builtin,...$.package,...$.user,...$.project]}function o1($,J){let Z=t$($),Q=J==="agent"?F2(Z):Z.chains;return[...new Set(Q.map((X)=>X.name))].sort((X,Y)=>X.localeCompare(Y))}function f6($,J,Z="both"){let Q=t$(J),X=$.trim(),Y=f1(X);return F2(Q).filter((H)=>(Z==="both"||H.source===Z)&&(H.name===X||H.name===Y)).sort((H,j)=>H.source.localeCompare(j.source))}function D6($,J,Z="both"){let Q=$.trim(),X=f1(Q);return t$(J).chains.filter((Y)=>(Z==="both"||Y.source===Z)&&(Y.name===Q||Y.name===X)).sort((Y,H)=>Y.source.localeCompare(H.source))}var M3={builtin:0,package:1,user:2,project:3};function C8($,J){let Z=J.trim(),Q=f1(Z),X=F2($).filter((Y)=>Y.name===Z||Y.name===Q);if(X.length===0)return;return X.reduce((Y,H)=>M3[H.source]>M3[Y.source]?H:Y)}function b6($,J,Z,Q){let X=t$($);for(let Y of J==="user"?X.user:X.project)if(Y.name===Z&&Y.filePath!==Q)return!0;for(let Y of X.chains)if(Y.source===J&&Y.name===Z&&Y.filePath!==Q)return!0;return!1}function Vj($){return $==="user"||$==="project"}function S3($,J){let Z=t$($),Q=new Set(F2(Z).map((X)=>X.name));return[...new Set(J.map((X)=>X.agent).filter((X)=>!Q.has(X)))].sort((X,Y)=>X.localeCompare(Y))}function C3($,J){let Z=[],Q=new Set(I0($.cwd).map((X)=>X.name));for(let X=0;X<J.length;X++){let Y=J[X];if(Y.model){if(!$.modelRegistry.getAvailable().some((j)=>`${j.provider}/${j.id}`===Y.model||j.id===Y.model))Z.push(`Warning: step ${X+1} (${Y.agent}): model '${Y.model}' is not in the current model registry.`)}if(Array.isArray(Y.skills)&&Y.skills.length>0){let H=Y.skills.filter((j)=>!Q.has(j));if(H.length)Z.push(`Warning: step ${X+1} (${Y.agent}): skills not found: ${H.join(", ")}.`)}}return Z}function R3($,J){if(!J)return;return $.modelRegistry.getAvailable().some((Q)=>`${Q.provider}/${Q.id}`===J||Q.id===J)?void 0:`Warning: model '${J}' is not in the current model registry.`}function y3($,J){if(!J||J.length===0)return;let Z=new Set($.modelRegistry.getAvailable().flatMap((X)=>[`${X.provider}/${X.id}`,X.id])),Q=J.filter((X)=>!Z.has(X));return Q.length?`Warning: fallback models not in the current model registry: ${Q.join(", ")}.`:void 0}function f3($,J){if(!J||J.length===0)return;let Z=new Set(I0($).map((X)=>X.name)),Q=J.filter((X)=>!Z.has(X));return Q.length?`Warning: skills not found: ${Q.join(", ")}.`:void 0}function zj($){let J=$.override?.base;if(!J)return{...$};return{...$,model:J.model,fallbackModels:J.fallbackModels?[...J.fallbackModels]:void 0,thinking:J.thinking,systemPromptMode:J.systemPromptMode,inheritProjectContext:J.inheritProjectContext,inheritSkills:J.inheritSkills,defaultContext:J.defaultContext,disabled:J.disabled,systemPrompt:J.systemPrompt,skills:J.skills?[...J.skills]:void 0,tools:J.tools?[...J.tools]:void 0,mcpDirectTools:J.mcpDirectTools?[...J.mcpDirectTools]:void 0,subagentOnlyExtensions:J.subagentOnlyExtensions?[...J.subagentOnlyExtensions]:void 0,completionGuard:J.completionGuard,override:void 0}}function Gj($){try{let{frontmatter:J}=GJ(o$.readFileSync($,"utf-8"));return new Set(Object.keys(J))}catch{return new Set}}function Bj($,J){let Z=Gj($.filePath),Q=(...X)=>{for(let Y of X)Z.delete(Y)};if(r(J,"name"))Q("name");if(r(J,"package"))Q("package");if(r(J,"description"))Q("description");if(r(J,"systemPrompt"))Q("systemPrompt");if(r(J,"model"))Q("model");if(r(J,"fallbackModels"))Q("fallbackModels");if(r(J,"tools"))Q("tools");if(r(J,"skills"))Q("skill","skills");if(r(J,"extensions"))Q("extensions");if(r(J,"subagentOnlyExtensions"))Q("subagentOnlyExtensions");if(r(J,"thinking")){if(Q("thinking"),J.thinking==="off")Z.add("thinking")}if(r(J,"systemPromptMode"))Q("systemPromptMode"),Z.add("systemPromptMode");if(r(J,"inheritProjectContext"))Q("inheritProjectContext"),Z.add("inheritProjectContext");if(r(J,"inheritSkills"))Q("inheritSkills"),Z.add("inheritSkills");if(r(J,"defaultContext"))Q("defaultContext");if(r(J,"output"))Q("output");if(r(J,"reads"))Q("defaultReads");if(r(J,"progress"))Q("defaultProgress");if(r(J,"maxSubagentDepth"))Q("maxSubagentDepth");if(r(J,"completionGuard")){if(Q("completionGuard"),J.completionGuard===!0)Z.add("completionGuard")}if(r(J,"toolBudget"))Q("toolBudget");return Z}function D3($){if(!Array.isArray($))return{error:"config.steps must be an array."};if($.length===0)return{error:"config.steps must include at least one step."};let J=[];for(let Z=0;Z<$.length;Z++){let Q=$[Z];if(!Q||typeof Q!=="object"||Array.isArray(Q))return{error:`config.steps[${Z}] must be an object.`};let X=Q;if(typeof X.agent!=="string"||!X.agent.trim())return{error:`config.steps[${Z}].agent must be a non-empty string.`};let Y={agent:X.agent.trim(),task:typeof X.task==="string"?X.task:""};if(r(X,"phase"))if(typeof X.phase==="string")Y.phase=X.phase;else return{error:`config.steps[${Z}].phase must be a string.`};if(r(X,"label"))if(typeof X.label==="string")Y.label=X.label;else return{error:`config.steps[${Z}].label must be a string.`};if(r(X,"as"))if(typeof X.as==="string")Y.as=X.as;else return{error:`config.steps[${Z}].as must be a string.`};if(r(X,"outputSchema"))if(typeof X.outputSchema==="string")Y.outputSchema=X.outputSchema;else return{error:`config.steps[${Z}].outputSchema must be a schema file path string for saved chains.`};if(r(X,"output"))if(X.output===!1)Y.output=!1;else if(typeof X.output==="string")Y.output=X.output;else return{error:`config.steps[${Z}].output must be a string or false.`};if(r(X,"outputMode"))if(X.outputMode==="inline"||X.outputMode==="file-only")Y.outputMode=X.outputMode;else return{error:`config.steps[${Z}].outputMode must be 'inline' or 'file-only'.`};if(r(X,"reads"))if(X.reads===!1)Y.reads=!1;else if(Array.isArray(X.reads))Y.reads=X.reads.filter((H)=>typeof H==="string").map((H)=>H.trim()).filter(Boolean);else return{error:`config.steps[${Z}].reads must be an array or false.`};if(r(X,"model"))if(typeof X.model==="string")Y.model=X.model;else return{error:`config.steps[${Z}].model must be a string.`};if(r(X,"skills"))if(X.skills===!1)Y.skills=!1;else if(Array.isArray(X.skills))Y.skills=X.skills.filter((H)=>typeof H==="string").map((H)=>H.trim()).filter(Boolean);else return{error:`config.steps[${Z}].skills must be an array or false.`};if(r(X,"progress"))if(typeof X.progress==="boolean")Y.progress=X.progress;else return{error:`config.steps[${Z}].progress must be a boolean.`};if(r(X,"toolBudget")){let H=O0(X.toolBudget,`config.steps[${Z}].toolBudget`);if(H.error)return{error:H.error};Y.toolBudget=X.toolBudget}J.push(Y)}return{steps:J}}function Kj($){let J=[],Z=[];for(let Q of EJ($))if(Q.startsWith("mcp:")){let X=Q.slice(4).trim();if(X)Z.push(X)}else J.push(Q);return{tools:J.length?J:void 0,mcpDirectTools:Z.length?Z:void 0}}function b3($,J){if(r(J,"systemPrompt"))if(J.systemPrompt===!1||J.systemPrompt==="")$.systemPrompt="";else if(typeof J.systemPrompt==="string")$.systemPrompt=J.systemPrompt;else return"config.systemPrompt must be a string or false when provided.";if(r(J,"model"))if(J.model===!1||J.model==="")$.model=void 0;else if(typeof J.model==="string")$.model=J.model.trim()||void 0;else return"config.model must be a string or false when provided.";if(r(J,"fallbackModels"))if(J.fallbackModels===!1||J.fallbackModels==="")$.fallbackModels=void 0;else if(typeof J.fallbackModels==="string"){let Z=EJ(J.fallbackModels);$.fallbackModels=Z.length?Z:void 0}else if(Array.isArray(J.fallbackModels)){let Z=J.fallbackModels.filter((Q)=>typeof Q==="string").map((Q)=>Q.trim()).filter(Boolean);$.fallbackModels=Z.length?[...new Set(Z)]:void 0}else return"config.fallbackModels must be a comma-separated string, string array, or false when provided.";if(r(J,"tools"))if(J.tools===!1||J.tools==="")$.tools=void 0,$.mcpDirectTools=void 0;else if(typeof J.tools==="string"){let Z=Kj(J.tools);$.tools=Z.tools,$.mcpDirectTools=Z.mcpDirectTools}else return"config.tools must be a comma-separated string or false when provided.";if(r(J,"skills"))if(J.skills===!1||J.skills==="")$.skills=void 0;else if(typeof J.skills==="string"){let Z=EJ(J.skills);$.skills=Z.length?Z:void 0}else return"config.skills must be a comma-separated string or false when provided.";if(r(J,"extensions"))if(J.extensions===!1)$.extensions=void 0;else if(J.extensions==="")$.extensions=[];else if(typeof J.extensions==="string")$.extensions=EJ(J.extensions);else return"config.extensions must be a comma-separated string, empty string, or false when provided.";if(r(J,"subagentOnlyExtensions"))if(J.subagentOnlyExtensions===!1)$.subagentOnlyExtensions=void 0;else if(J.subagentOnlyExtensions==="")$.subagentOnlyExtensions=[];else if(typeof J.subagentOnlyExtensions==="string")$.subagentOnlyExtensions=EJ(J.subagentOnlyExtensions);else return"config.subagentOnlyExtensions must be a comma-separated string, empty string, or false when provided.";if(r(J,"thinking"))if(J.thinking===!1||J.thinking==="")$.thinking=void 0;else if(typeof J.thinking==="string")$.thinking=J.thinking.trim()||void 0;else return"config.thinking must be a string or false when provided.";if(r(J,"systemPromptMode"))if(J.systemPromptMode==="append"||J.systemPromptMode==="replace")$.systemPromptMode=J.systemPromptMode;else return"config.systemPromptMode must be 'append' or 'replace' when provided.";if(r(J,"inheritProjectContext")){if(typeof J.inheritProjectContext!=="boolean")return"config.inheritProjectContext must be a boolean when provided.";$.inheritProjectContext=J.inheritProjectContext}if(r(J,"inheritSkills")){if(typeof J.inheritSkills!=="boolean")return"config.inheritSkills must be a boolean when provided.";$.inheritSkills=J.inheritSkills}if(r(J,"defaultContext"))if(J.defaultContext===!1||J.defaultContext==="")$.defaultContext=void 0;else if(J.defaultContext==="fresh"||J.defaultContext==="fork")$.defaultContext=J.defaultContext;else return"config.defaultContext must be 'fresh', 'fork', or false when provided.";if(r(J,"output"))if(J.output===!1||J.output==="")$.output=void 0;else if(typeof J.output==="string")$.output=J.output;else return"config.output must be a string or false when provided.";if(r(J,"reads"))if(J.reads===!1||J.reads==="")$.defaultReads=void 0;else if(typeof J.reads==="string"){let Z=EJ(J.reads);$.defaultReads=Z.length?Z:void 0}else return"config.reads must be a comma-separated string or false when provided.";if(r(J,"progress")){if(typeof J.progress!=="boolean")return"config.progress must be a boolean when provided.";$.defaultProgress=J.progress}if(r(J,"maxSubagentDepth"))if(J.maxSubagentDepth===!1||J.maxSubagentDepth==="")$.maxSubagentDepth=void 0;else if(typeof J.maxSubagentDepth==="number"&&Number.isInteger(J.maxSubagentDepth)&&J.maxSubagentDepth>=0)$.maxSubagentDepth=J.maxSubagentDepth;else return"config.maxSubagentDepth must be an integer >= 0 or false when provided.";if(r(J,"completionGuard")){if(typeof J.completionGuard!=="boolean")return"config.completionGuard must be a boolean when provided.";$.completionGuard=J.completionGuard}if(r(J,"toolBudget"))if(J.toolBudget===!1||J.toolBudget==="")$.toolBudget=void 0;else{let Z=O0(J.toolBudget,"config.toolBudget");if(Z.error)return Z.error;$.toolBudget=J.toolBudget}return}function R8($,J,Z,Q,X){let Y=Z.filter((U)=>Vj(U.source));if(Y.length===0){if(Z.length>0)return u(`${$==="agent"?"Agent":"Chain"} '${J}' is read-only and cannot be modified. Create a same-named ${$} in user or project scope to override it.`,!0);let U=o1(Q,$);return u(`${$==="agent"?"Agent":"Chain"} '${J}' not found. Available: ${U.join(", ")||"none"}.`,!0)}if(Y.length===1)return Y[0];let H=O2(X);if(!H){let U=Y.map((G)=>`${G.source}: ${G.filePath}`).join(`
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
`
|
|
161
|
-
`
|
|
162
|
-
`
|
|
163
|
-
`
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
`)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
${J$}`:J$}let l=Y2(L,g);if(l)$$=$$?`${$$}
|
|
176
|
-
|
|
177
|
-
${l}`:l;let v$=H1({...a,output:!1,progress:!1},I,!1),c=a.progress&&!N&&!C;if(a.progress)C=!0;let H$=H1({...a,output:!1,reads:!1},F,c),F$=y1(a.output,X.cwd,I,V);$$=G2($$,F$);let z$=b0(a.outputMode,F$,`Async step (${q.agent})`);if(z$)throw new x8(z$);let Y$=q.task??"{previous}";Y$=Y$.replace(/\{task\}/g,O??""),Y$=Y$.replace(/\{chain_dir\}/g,A);let Z$=OJ(`${v$.prefix}${Y$}${H$.suffix}`,F$),K$=a.model??L.model,_$=B0(K$,X.currentModel,W,X.currentModelProvider,{scope:X.modelScope,source:a.model?"explicit":"inherited"}),R=n===void 0?void 0:j?.[n],i=R??L.thinking,n$=R1(_$,i,R!==void 0);return{parentSessionId:X.parentSessionId??X.currentSessionId,agent:q.agent,task:Z$,phase:q.phase,label:q.label,outputName:q.as,structured:Boolean(q.outputSchema),cwd:g,model:n$,thinking:q4(n$,i),modelCandidates:dJ(_$,L.fallbackModels,W,X.currentModelProvider,{scope:X.modelScope}).map((J$)=>R1(J$,i,R!==void 0)),tools:L.tools,extensions:L.extensions,subagentOnlyExtensions:L.subagentOnlyExtensions,mcpDirectTools:L.mcpDirectTools,completionGuard:L.completionGuard,systemPrompt:$$,systemPromptMode:L.systemPromptMode,inheritProjectContext:L.inheritProjectContext,inheritSkills:L.inheritSkills,skills:P.map((J$)=>J$.name),outputPath:F$,outputMode:a.outputMode,sessionFile:S,maxSubagentDepth:s0(U,L.maxSubagentDepth),effectiveAcceptance:z1({explicit:q.acceptance,agentName:q.agent,task:q.task,mode:B,async:!0,dynamic:!1}),...q.outputSchema?{structuredOutputSchema:q.outputSchema}:{},...q.outputSchema?{structuredOutput:rJ(q.outputSchema,b$.join(z,"structured-output"))}:{},...o.budget?{toolBudget:o.budget}:{}}},b=0,w=()=>{let q=b,S=H?.[b],M=j?.[b];return b++,{index:q,...S?{sessionFile:S}:{},...M?{thinkingOverride:M}:{}}};try{let q=Z.map((M,N)=>{if(E$(M)){let n=M.parallel.map((k)=>{let o=Q.find((g)=>g.name===k.agent);return x0(P0(o,T(k),K),k.task,O)}),L=n.some((k)=>k.progress);if(L){if(!M.worktree||J.progressDir)v1(F);C=!0}return{parallel:M.parallel.map((k,o)=>{let g;if(M.worktree)try{g=z3(A,`${$}-s${N}`,o,G)}catch{g=void 0}let I=w();return h(k,I.sessionFile,g,L,n[o],I.index)}),concurrency:M.concurrency,failFast:M.failFast,worktree:M.worktree}}if(C$(M)){let n=Q.find((I)=>I.name===M.parallel.agent),L=x0(P0(n,T(M.parallel),K),M.parallel.task,O),k=L.progress;if(k)v1(F),C=!0;let o=M.expand.maxItems??J.dynamicFanoutMaxItems??0,g=Array.from({length:o},()=>w());return{expand:M.expand,parallel:h(M.parallel,void 0,void 0,k,L),collect:M.collect,concurrency:M.concurrency,failFast:M.failFast,phase:M.phase,label:M.label,sessionFiles:g.map((I)=>I.sessionFile),thinkingOverrides:g.map((I)=>I.thinkingOverride),effectiveAcceptance:z1({explicit:M.acceptance,agentName:M.parallel.agent,task:M.parallel.task,mode:B,async:!0,dynamicGroup:!0})}}let E=w();return h(M,E.sessionFile,void 0,!1,void 0,E.index)});return{steps:J.attachRoot?[{agent:J.attachRoot.agent,task:"",label:J.attachRoot.label??`Attached root ${J.attachRoot.runId}`,outputName:J.attachRoot.outputName,importAsyncRoot:{runId:J.attachRoot.runId,asyncDir:J.attachRoot.asyncDir,resultPath:J.attachRoot.resultPath,index:J.attachRoot.index},inheritProjectContext:!1,inheritSkills:!1},...q]:q,runnerCwd:A,workflowGraph:y,eventChain:_,...O!==void 0?{originalTask:O}:{}}}catch(q){if(q instanceof u6||q instanceof x8)return{error:q.message};throw q}}function yJ($,J){let{chain:Z,agents:Q,ctx:X,cwd:Y,maxOutput:H,artifactsDir:j,artifactConfig:U,shareEnabled:G,sessionRoot:z,sessionFilesByFlatIndex:V,thinkingOverridesByFlatIndex:B,maxSubagentDepth:K,worktreeSetupHook:W,worktreeSetupHookTimeoutMs:A,worktreeBaseDir:F,controlConfig:_,controlIntercomTarget:f,childIntercomTarget:O,nestedRoute:y}=J,C=J.resultMode??"chain",T=SJ(),h=T?CJ():void 0,b=T?b$.join(G0,"nested-subagent-runs",T.rootRunId,$):b$.join(Q0,$);try{f$.mkdirSync(b,{recursive:!0})}catch(I){let a=I instanceof Error?I.message:String(I);return{content:[{type:"text",text:`Failed to create async run directory '${b}': ${a}`}],isError:!0,details:{mode:C,results:[]}}}let w=d6($,{chain:Z,task:J.task,attachRoot:J.attachRoot,resultMode:C,agents:Q,ctx:X,availableModels:J.availableModels,cwd:Y,chainSkills:J.chainSkills,sessionFilesByFlatIndex:V,thinkingOverridesByFlatIndex:B,progressDir:J.progressDir??(j?b$.join(j,"progress",$):C==="parallel"?b$.join(b,"progress"):void 0),outputBaseDir:j?b$.join(j,"outputs",$):void 0,dynamicFanoutMaxItems:J.dynamicFanoutMaxItems,maxSubagentDepth:K,worktreeBaseDir:F,asyncDir:b,toolBudget:J.toolBudget,configToolBudget:J.configToolBudget});if("error"in w){try{f$.rmSync(b,{recursive:!0,force:!0})}catch{}return b1(C,w.error)}let{steps:q,runnerCwd:S,workflowGraph:M,eventChain:N}=w,E=J.timeoutMs!==void 0?Date.now()+J.timeoutMs:void 0,n=J.turnBudget?B2(J.turnBudget):void 0,L=0,k=O?q.flatMap((I)=>{if(!("parallel"in I)&&I.importAsyncRoot)return L++,[void 0];if("parallel"in I){if(!Array.isArray(I.parallel))return L++,[void 0];return I.parallel.map((a)=>O(a.agent,L++))}return[O(I.agent,L++)]}):void 0,o={};try{o=l3({id:$,steps:q,resultPath:T?g6(T.rootRunId,$):b$.join(h$,`${$}.json`),cwd:S,placeholder:"{previous}",maxOutput:H,artifactsDir:U.enabled?j:void 0,artifactConfig:U,share:G,sessionDir:z?b$.join(z,`async-${$}`):void 0,asyncDir:b,sessionId:X.currentSessionId,piPackageRoot:w1,piArgv1:process.argv[1],worktreeSetupHook:W,worktreeSetupHookTimeoutMs:A,worktreeBaseDir:F,controlConfig:_,turnBudget:J.turnBudget,toolBudget:J.toolBudget,controlIntercomTarget:f,childIntercomTargets:k,resultMode:C,dynamicFanoutMaxItems:J.dynamicFanoutMaxItems,timeoutMs:J.timeoutMs,deadlineAt:E,globalConcurrencyLimit:J.globalConcurrencyLimit,workflowGraph:M,nestedRoute:y??T,nestedSelf:T&&h?{parentRunId:h.parentRunId,parentStepIndex:h.parentStepIndex,depth:h.depth,path:h.path}:void 0},$,S)}catch(I){let a=I instanceof Error?I.message:String(I);return b1(C,`Failed to start async ${C} '${$}': ${a}`)}if(o.error)return b1(C,`Failed to start async ${C} '${$}': ${o.error}`);if(o.pid){let I=N[0],a=E$(I)?I.parallel.map(($$)=>$$.agent):C$(I)?[I.parallel.agent]:[I.agent],O$=[],P=[],w$=0;for(let $$=0;$$<N.length;$$++){let l=N[$$];if(E$(l))O$.push({start:w$,count:l.parallel.length,stepIndex:$$}),P.push(...l.parallel.map((v$)=>v$.agent)),w$+=l.parallel.length;else if(C$(l))O$.push({start:w$,count:1,stepIndex:$$}),P.push(l.parallel.agent),w$++;else P.push(l.agent),w$++}if(T&&h){let $$=Date.now();try{p1(T,{type:"subagent.nested.started",ts:$$,parentRunId:h.parentRunId,parentStepIndex:h.parentStepIndex,child:{id:$,parentRunId:h.parentRunId,parentStepIndex:h.parentStepIndex,depth:h.depth,path:h.path,asyncDir:b,pid:o.pid,ownerIntercomTarget:process.env.DM_SUBAGENT_INTERCOM_SESSION_NAME,leafIntercomTarget:k?.[0],intercomTarget:k?.[0],ownerState:"live",mode:C,state:"running",agent:a[0],agents:P,chainStepCount:N.length,parallelGroups:O$,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:E}:{},...n?{turnBudget:n}:{},startedAt:$$,lastUpdate:$$}})}catch(l){console.error("Failed to emit nested async start event:",l)}}X.pi.events.emit(Z4,{lifecycleArtifactVersion:J4,id:$,pid:o.pid,sessionId:X.currentSessionId,mode:C,agent:a[0],agents:P,task:E$(I)?I.parallel[0]?.task?.slice(0,50):C$(I)?I.parallel.task?.slice(0,50):I.task?.slice(0,50),chain:N.map(($$)=>E$($$)?`[${$$.parallel.map((l)=>l.agent).join("+")}]`:C$($$)?`expand:${$$.parallel.agent}`:$$.agent),chainStepCount:N.length,parallelGroups:O$,workflowGraph:M,cwd:S,asyncDir:b,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:E}:{},...n?{turnBudget:n}:{},nestedRoute:y})}let g=Z.map((I)=>E$(I)?`[${I.parallel.map((a)=>a.agent).join("+")}]`:C$(I)?`expand:${I.parallel.agent}`:I.agent).join(" -> ");return{content:[{type:"text",text:N2(`Async ${C}: ${g} [${$}]`)}],details:{mode:C,runId:$,results:[],asyncId:$,asyncDir:b,workflowGraph:M,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:E}:{},...J.turnBudget?{turnBudget:J.turnBudget}:{},...J.toolBudget?{toolBudget:J.toolBudget}:{}}}}function v8($,J){let{agent:Z,agentConfig:Q,ctx:X,cwd:Y,maxOutput:H,artifactsDir:j,artifactConfig:U,shareEnabled:G,sessionRoot:z,sessionFile:V,maxSubagentDepth:B,worktreeSetupHook:K,worktreeSetupHookTimeoutMs:W,worktreeBaseDir:A,controlConfig:F,controlIntercomTarget:_,childIntercomTarget:f,nestedRoute:O}=J,y=J.task??"",C=v0(X.cwd,Y),T=J.skills??Q.skills??[],h=J.availableModels,{resolved:b,missing:w}=kJ(T,C,X.cwd);if(w.includes("dm-subagents"))return b1("single",n3);let q=Q.systemPrompt?.trim()??"";if(b.length>0){let c=PJ(b);q=q?`${q}
|
|
178
|
-
|
|
179
|
-
${c}`:c}let S=Y2(Q,C);if(S)q=q?`${q}
|
|
180
|
-
|
|
181
|
-
${S}`:S;let M=SJ(),N=M?CJ():void 0,E=M?b$.join(G0,"nested-subagent-runs",M.rootRunId,$):b$.join(Q0,$);try{f$.mkdirSync(E,{recursive:!0})}catch(c){let H$=c instanceof Error?c.message:String(c);return{content:[{type:"text",text:`Failed to create async run directory '${E}': ${H$}`}],isError:!0,details:{mode:"single",results:[]}}}let n=qJ(J.output,Q.output),L=y1(n,X.cwd,C,J.outputBaseDir??(j?b$.join(j,"outputs",$):void 0));q=G2(q,L);let k=J.outputMode??"inline",o=b0(k,L,`Async single run (${Z})`);if(o)return b1("single",o);let g=OJ(y,L),I=B0(J.modelOverride??Q.model,X.currentModel,h,X.currentModelProvider),a=J.thinkingOverride??Q.thinking,O$=R1(I,a,J.thinkingOverride!==void 0),P=J.toolBudget??Q.toolBudget??J.configToolBudget,w$=O0(P,J.toolBudget?"toolBudget":Q.toolBudget?"agent.toolBudget":"config.toolBudget");if(w$.error)return b1("single",w$.error);let $$=J.timeoutMs!==void 0?Date.now()+J.timeoutMs:void 0,l=J.turnBudget?B2(J.turnBudget):void 0,v$={};try{v$=l3({id:$,steps:[{parentSessionId:X.parentSessionId??X.currentSessionId,agent:Z,task:g,cwd:C,model:O$,thinking:q4(O$,a),modelCandidates:dJ(I,Q.fallbackModels,h,X.currentModelProvider,{scope:X.modelScope}).map((c)=>R1(c,a,J.thinkingOverride!==void 0)),tools:Q.tools,extensions:Q.extensions,subagentOnlyExtensions:Q.subagentOnlyExtensions,mcpDirectTools:Q.mcpDirectTools,completionGuard:Q.completionGuard,systemPrompt:q,systemPromptMode:Q.systemPromptMode,inheritProjectContext:Q.inheritProjectContext,inheritSkills:Q.inheritSkills,skills:b.map((c)=>c.name),outputPath:L,outputMode:k,sessionFile:V,maxSubagentDepth:s0(B,Q.maxSubagentDepth),effectiveAcceptance:z1({explicit:J.acceptance,agentName:Z,task:y,mode:"single",async:!0}),...w$.budget?{toolBudget:w$.budget}:{}}],resultPath:M?g6(M.rootRunId,$):b$.join(h$,`${$}.json`),cwd:C,placeholder:"{previous}",maxOutput:H,artifactsDir:U.enabled?j:void 0,artifactConfig:U,share:G,sessionDir:z?b$.join(z,`async-${$}`):void 0,asyncDir:E,sessionId:X.currentSessionId,piPackageRoot:w1,piArgv1:process.argv[1],worktreeSetupHook:K,worktreeSetupHookTimeoutMs:W,worktreeBaseDir:A,controlConfig:F,timeoutMs:J.timeoutMs,deadlineAt:$$,turnBudget:J.turnBudget,toolBudget:J.toolBudget,controlIntercomTarget:_,childIntercomTargets:f?[f(Z,0)]:void 0,resultMode:"single",nestedRoute:O??M,nestedSelf:M&&N?{parentRunId:N.parentRunId,parentStepIndex:N.parentStepIndex,depth:N.depth,path:N.path}:void 0},$,C)}catch(c){let H$=c instanceof Error?c.message:String(c);return b1("single",`Failed to start async run '${$}': ${H$}`)}if(v$.error)return b1("single",`Failed to start async run '${$}': ${v$.error}`);if(v$.pid){if(M&&N){let c=Date.now();try{p1(M,{type:"subagent.nested.started",ts:c,parentRunId:N.parentRunId,parentStepIndex:N.parentStepIndex,child:{id:$,parentRunId:N.parentRunId,parentStepIndex:N.parentStepIndex,depth:N.depth,path:N.path,asyncDir:E,pid:v$.pid,ownerIntercomTarget:process.env.DM_SUBAGENT_INTERCOM_SESSION_NAME,leafIntercomTarget:f?.(Z,0),intercomTarget:f?.(Z,0),ownerState:"live",mode:"single",state:"running",agent:Z,agents:[Z],chainStepCount:1,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:$$}:{},...l?{turnBudget:l}:{},startedAt:c,lastUpdate:c}})}catch(H$){console.error("Failed to emit nested async start event:",H$)}}X.pi.events.emit(Z4,{lifecycleArtifactVersion:J4,id:$,pid:v$.pid,sessionId:X.currentSessionId,mode:"single",agent:Z,task:y?.slice(0,50),cwd:C,asyncDir:E,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:$$}:{},...l?{turnBudget:l}:{},nestedRoute:O})}return{content:[{type:"text",text:N2(`Async: ${Z} [${$}]`)}],details:{mode:"single",runId:$,results:[],asyncId:$,asyncDir:E,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs,deadlineAt:$$}:{},...J.turnBudget?{turnBudget:J.turnBudget}:{},...J.toolBudget?{toolBudget:J.toolBudget}:{}}}}var QU={tempRootDir:G0,asyncDir:Q0,resultsDir:h$,chainRunsDir:m2},XU={isAsyncAvailable:I1,discoverAgentsAll:t$,discoverAvailableSkills:I0,diagnoseIntercomBridge:O5};function i3($){return $ instanceof Error?`${$.name}: ${$.message}`:String($)}function T2($,J){try{return J()}catch(Z){return`- ${$}: failed — ${i3(Z)}`}}function h8($,J){try{if(!q1.existsSync(J))return`- ${$}: missing (${J})`;if(!q1.statSync(J).isDirectory())throw Error(`not a directory: ${J}`);return q1.accessSync(J,q1.constants.R_OK|q1.constants.W_OK),`- ${$}: ok (${J})`}catch(Z){return`- ${$}: failed (${J}) — ${i3(Z)}`}}function p3($){return`builtin ${$.builtin}, package ${$.package}, user ${$.user}, project ${$.project}`}function YU($){let J=new Map;for(let X of $)J.set(X.source,(J.get(X.source)??0)+1);let Q=["project","project-settings","project-package","user","user-settings","user-package","extension","builtin","unknown"].map((X)=>`${X} ${J.get(X)??0}`).filter((X)=>!X.endsWith(" 0"));return Q.length>0?Q.join(", "):"none"}function HU($){if($.requestedSessionDir)return E2.resolve($.expandTilde?.($.requestedSessionDir)??$.requestedSessionDir);if($.config.defaultSessionDir)return E2.resolve($.expandTilde?.($.config.defaultSessionDir)??$.config.defaultSessionDir);return"not configured"}function jU($){let J=$.currentSessionFile??null,Z=[T2("configured session dir",()=>`- configured session dir: ${HU($)}`),`- current session file: ${J??"not available"}`,`- current session dir: ${J?E2.dirname(J):"not available"}`,`- current session id: ${$.currentSessionId??$.state.currentSessionId??"not available"}`];if($.sessionError)Z.push(`- session manager: failed — ${$.sessionError}`);return Z}function UU($,J){return[T2("agents/chains",()=>{let Z=J.discoverAgentsAll($.cwd),Q={builtin:Z.builtin.length,package:Z.package?.length??0,user:Z.user.length,project:Z.project.length},X=Z.chains.reduce((Y,H)=>{return Y[H.source]+=1,Y},{builtin:0,package:0,user:0,project:0});return[`- agents: total ${Q.builtin+Q.package+Q.user+Q.project} (${p3(Q)})`,`- chains: total ${Z.chains.length} (${p3(X)})`].join(`
|
|
182
|
-
`)}),T2("skills",()=>{let Z=J.discoverAvailableSkills($.cwd);return`- skills: total ${Z.length} (${YU(Z)})`})]}function VU($,J){return[`- bridge: ${$.active?"active":"inactive"}${$.reason?` (${$.reason})`:""}`,`- mode: ${$.mode}; context: ${J??"unspecified"}`,`- orchestrator target: ${$.orchestratorTarget??"not available"}`,`- supervisor channel: ${$.supervisorChannelAvailable?"available":"unavailable"} (${$.extensionDir})`]}function zU(){let $=[],Z=(process.env.DM_SUBAGENT_PARENT_SESSION??"").trim();if(Z)$.push(`- parent session: set (${Z})`);else $.push("- parent session: not set — ask forwarding from subprocess children will not reach a parent UI");let Q=process.env.DM_SUBAGENT_CHILD==="1";return $.push(`- subagent process: ${Q?"yes (DM_SUBAGENT_CHILD=1)":"no"}`),$}function r3($){let J=$.paths??QU,Z={...XU,...$.deps};return["Subagents doctor report","","Runtime",`- cwd: ${$.cwd}`,T2("async support",()=>`- async support: ${Z.isAsyncAvailable()?"available":"unavailable"}`),...jU($),"","Filesystem",h8("temp root",J.tempRootDir),h8("async runs",J.asyncDir),h8("results",J.resultsDir),h8("chain runs",J.chainRunsDir),"","Discovery",...UU($,Z),"","Permission system",...zU(),"","Intercom bridge",...T2("intercom bridge",()=>VU(Z.diagnoseIntercomBridge({config:$.config.intercomBridge,context:$.context,orchestratorTarget:$.orchestratorTarget,cwd:$.cwd}),$.context).join(`
|
|
183
|
-
`)).split(`
|
|
184
|
-
`)].join(`
|
|
185
|
-
`)}function s3($,J){let Z=$.pendingForegroundControlNotices;if(!Z)return;for(let[Q,X]of Z){if(J!==void 0&&!Q.startsWith(`${J}:`))continue;clearTimeout(X),Z.delete(Q)}}import{randomUUID as GU}from"node:crypto";import*as r1 from"node:fs";import*as fJ from"node:path";var BU="append-requests";function o6($){return fJ.join($,BU)}function KU($,J){return fJ.join(o6($),`${J.createdAt}-${J.id}.json`)}function a3($){let J=o6($);try{return r1.readdirSync(J).filter((Z)=>Z.endsWith(".json")).map((Z)=>fJ.join(J,Z)).sort()}catch(Z){if(Z.code==="ENOENT")return[];throw Z}}function WU($){return a3($).length}function g8($){let J=[];for(let Z of $)if(v9(Z))J.push(...Z.parallel.map((Q)=>Q.outputName).filter((Q)=>Boolean(Q)));else if(h9(Z)){if(Z.collect.as)J.push(Z.collect.as)}else if(Z.outputName)J.push(Z.outputName);return J}function t3($){let J=j1($.asyncDir);if(!J)throw Error(`No async run status found for '${$.runId}'.`);if(J.runId!==$.runId)throw Error(`Async run id mismatch: expected '${$.runId}', found '${J.runId}'.`);if(J.mode!=="chain")throw Error(`Run '${$.runId}' is ${J.mode}; only active chain runs accept appended steps.`);if(J.state!=="running")throw Error(`Run '${$.runId}' is ${J.state}; only running chain runs accept appended steps.`);if(!((J.steps??[]).some((j)=>j.status==="running"||j.status==="pending")||(J.pendingAppends??0)>0))throw Error(`Run '${$.runId}' has no running or pending chain steps left; append-step must target an in-progress chain.`);if($.steps.length===0)throw Error("append-step requires one chain step.");let Q={id:GU(),createdAt:$.now??Date.now(),steps:$.steps};r1.mkdirSync(o6($.asyncDir),{recursive:!0}),w0(KU($.asyncDir,Q),Q);let X=WU($.asyncDir),Y=fJ.join($.asyncDir,"status.json"),H={...J,pendingAppends:X,lastUpdate:Q.createdAt};return w0(Y,H),J5(fJ.join($.asyncDir,"events.jsonl"),JSON.stringify({type:"subagent.chain.append.requested",ts:Q.createdAt,runId:$.runId,requestId:Q.id,stepCount:$.steps.length,pendingAppends:X})),{request:Q,pendingCount:X}}function _U($){let J=JSON.parse(r1.readFileSync($,"utf-8"));if(!J.id||typeof J.id!=="string")return;if(!Number.isFinite(J.createdAt))return;if(!Array.isArray(J.steps)||J.steps.length===0)return;return{id:J.id,createdAt:J.createdAt,steps:J.steps}}function e3($){return a3($).map((J)=>_U(J)).filter((J)=>Boolean(J)).sort((J,Z)=>J.createdAt-Z.createdAt||J.id.localeCompare(Z.id))}import{randomUUID as $7}from"node:crypto";import*as Z1 from"node:fs";import*as Z7 from"node:path";import{SessionManager as AU}from"@duckmind/dm-coding-agent";function qU($){return $==="fork"?"fork":"fresh"}function OU($,J){if(!$||!J||typeof J!=="object"||!("type"in J))return!1;let Z=typeof $.provider==="string"?$.provider.toLowerCase():"",Q=typeof $.api==="string"?$.api.toLowerCase():"",X=typeof $.model==="string"?$.model.toLowerCase():"",Y=Z==="anthropic"||Q==="anthropic-messages"||X.startsWith("anthropic/");if(J.type==="redacted_thinking")return!0;if(J.type!=="thinking"||!Y)return!1;let H="thinkingSignature"in J?J.thinkingSignature:("signature"in J)?J.signature:void 0;return J.redacted===!0||typeof H==="string"&&H.length>0}function FU($){let J=new Set($.map((Z)=>Z.id).filter((Z)=>typeof Z==="string"));for(let Z=0;Z<100;Z++){let Q=$7().slice(0,8);if(!J.has(Q))return Q}return $7()}function LU($){let J=$[$.length-1];if(J?.type==="thinking_level_change"&&J.thinkingLevel==="off")return;let Z=[...$].reverse().find((Q)=>typeof Q.id==="string");$.push({type:"thinking_level_change",id:FU($),parentId:Z?.id??null,timestamp:new Date().toISOString(),thinkingLevel:"off"})}function J7($){let J=!1;for(let Z of $){if(Z.type!=="message"||Z.message?.role!=="assistant"||!Array.isArray(Z.message.content))continue;let Q=Z.message.content.filter((X)=>!OU(Z.message,X));if(Q.length===Z.message.content.length)continue;Z.message.content=Q,J=!0}if(J)LU($);return J}function MU($){return Z1.readFileSync($,"utf-8").split(`
|
|
186
|
-
`).filter((Z)=>Z.trim().length>0).map((Z,Q)=>{try{return JSON.parse(Z)}catch(X){let Y=X instanceof Error?X:Error(String(X));throw Error(`Unable to inspect forked session ${$}: invalid JSONL on line ${Q+1}: ${Y.message}`,{cause:Y})}})}function Q7($,J,Z={}){if(qU(J)!=="fork")return{sessionFileForIndex:()=>{return},thinkingOverrideForIndex:()=>{return}};let Q=$.getSessionFile();if(!Q)throw Error("Forked subagent context requires a persisted parent session.");let X=$.getLeafId();if(!X)throw Error("Forked subagent context requires a current leaf to fork from.");let H=Z.openSession??$.openSession??((z,V)=>AU.open(z,V)),j=$.getSessionDir?.(),U=new Map,G=(z=0)=>{let V=U.get(z);if(V)return V;try{if(!Z1.existsSync(Q))throw Error(`Parent session file does not exist: ${Q}. DM has not persisted enough history to fork yet.`);let B;try{let K=typeof $.createDetachedBranchedSession==="function"?$.createDetachedBranchedSession(X):(B=H(Q,j)).createBranchedSession(X);if(!K)throw Error("Session manager did not return a forked session file.");let W;if(!Z1.existsSync(K)){let F=B?.getHeader?.(),_=B?.getEntries?.();if(!F||!_)throw Error(`Session manager returned a forked session file that does not exist and cannot be persisted by fallback: ${K}`);if(J7(_))W="off";Z1.mkdirSync(Z7.dirname(K),{recursive:!0}),Z1.writeFileSync(K,`${[F,..._].map((f)=>JSON.stringify(f)).join(`
|
|
187
|
-
`)}
|
|
188
|
-
`,"utf-8")}else{let F=MU(K);if(J7(F))W="off",Z1.writeFileSync(K,`${F.map((_)=>JSON.stringify(_)).join(`
|
|
189
|
-
`)}
|
|
190
|
-
`,"utf-8")}let A={sessionFile:K,...W?{thinkingOverride:W}:{}};return U.set(z,A),A}finally{B?.dispose?.()}}catch(B){let K=B instanceof Error?B:Error(String(B));throw Error(`Failed to create forked subagent session: ${K.message}`,{cause:K})}};return{sessionFileForIndex(z=0){return G(z).sessionFile},thinkingOverrideForIndex(z=0){return G(z).thinkingOverride}}}function m8($){let J=$.getSessionFile()??$.getSessionId();if(!J)throw Error("Current session identity is unavailable.");return J}import{randomUUID as NU}from"node:crypto";import*as X7 from"node:fs";function u8($){if($.detached)return"detached";if($.interrupted||$.state==="paused")return"paused";if(typeof $.success==="boolean")return $.success?"completed":"failed";if($.state==="complete")return"completed";if($.state==="failed")return"failed";if(typeof $.exitCode==="number")return $.exitCode===0?"completed":"failed";return"failed"}function d8($){let J={completed:0,failed:0,paused:0,detached:0};for(let Z of $)J[Z.status]+=1;return J}function n6($){let J=[$.completed?`${$.completed} completed`:void 0,$.failed?`${$.failed} failed`:void 0,$.paused?`${$.paused} paused`:void 0,$.detached?`${$.detached} detached`:void 0].filter((Z)=>Boolean(Z));return J.length?J.join(", "):"0 results"}function EU($){let J=d8($);if(J.failed>0)return"failed";if(J.paused>0)return"paused";if(J.completed>0)return"completed";if(J.detached>0)return"detached";return"failed"}function l6($,J=0){return{id:$.id,parentRunId:$.parentRunId,...$.parentStepIndex!==void 0?{parentStepIndex:$.parentStepIndex}:{},...$.parentAgent?{parentAgent:$.parentAgent}:{},depth:$.depth,path:$.path.slice(0,4).map((Z)=>({runId:Z.runId,...Z.stepIndex!==void 0?{stepIndex:Z.stepIndex}:{},...Z.agent?{agent:Z.agent}:{}})),...$.asyncDir?{asyncDir:$.asyncDir}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.sessionFile?{sessionFile:$.sessionFile}:{},...$.intercomTarget?{intercomTarget:$.intercomTarget}:{},...$.ownerIntercomTarget?{ownerIntercomTarget:$.ownerIntercomTarget}:{},...$.leafIntercomTarget?{leafIntercomTarget:$.leafIntercomTarget}:{},...$.ownerState?{ownerState:$.ownerState}:{},...$.mode?{mode:$.mode}:{},state:$.state,...$.agent?{agent:$.agent}:{},...$.agents?.length?{agents:$.agents.slice(0,12)}:{},...$.currentStep!==void 0?{currentStep:$.currentStep}:{},...$.chainStepCount!==void 0?{chainStepCount:$.chainStepCount}:{},...$.parallelGroups?.length?{parallelGroups:$.parallelGroups.slice(0,8)}:{},...$.activityState?{activityState:$.activityState}:{},...$.lastActivityAt!==void 0?{lastActivityAt:$.lastActivityAt}:{},...$.currentTool?{currentTool:$.currentTool}:{},...$.currentToolStartedAt!==void 0?{currentToolStartedAt:$.currentToolStartedAt}:{},...$.currentPath?{currentPath:$.currentPath}:{},...$.turnCount!==void 0?{turnCount:$.turnCount}:{},...$.toolCount!==void 0?{toolCount:$.toolCount}:{},...$.totalTokens?{totalTokens:$.totalTokens}:{},...$.startedAt!==void 0?{startedAt:$.startedAt}:{},...$.endedAt!==void 0?{endedAt:$.endedAt}:{},...$.lastUpdate!==void 0?{lastUpdate:$.lastUpdate}:{},...$.error?{error:$.error}:{},...$.steps?.length?{steps:$.steps.slice(0,12).map((Z)=>({agent:Z.agent,status:Z.status,...Z.sessionFile?{sessionFile:Z.sessionFile}:{},...Z.activityState?{activityState:Z.activityState}:{},...Z.lastActivityAt!==void 0?{lastActivityAt:Z.lastActivityAt}:{},...Z.currentTool?{currentTool:Z.currentTool}:{},...Z.currentToolStartedAt!==void 0?{currentToolStartedAt:Z.currentToolStartedAt}:{},...Z.currentPath?{currentPath:Z.currentPath}:{},...Z.turnCount!==void 0?{turnCount:Z.turnCount}:{},...Z.toolCount!==void 0?{toolCount:Z.toolCount}:{},...Z.startedAt!==void 0?{startedAt:Z.startedAt}:{},...Z.endedAt!==void 0?{endedAt:Z.endedAt}:{},...Z.error?{error:Z.error}:{},...J<2&&Z.children?.length?{children:Z.children.slice(0,8).map((Q)=>l6(Q,J+1))}:{}}))}:{},...J<2&&$.children?.length?{children:$.children.slice(0,8).map((Z)=>l6(Z,J+1))}:{}}}function c8($){if(!$?.length)return;return $.slice(0,16).map((J)=>l6(J))}function Y7($,J,Z){let Q=c8(Z);if(!Q?.length)return J.map((X)=>({...X,children:c8(X.children)}));return J.map((X,Y)=>{let H=X.index??Y,j=new Set(X.children?.map((V)=>V.id)??[]),U=Q.filter((V)=>V.parentRunId===$&&V.parentStepIndex===H&&!j.has(V.id)),G=J.length===1?Q.filter((V)=>V.parentRunId===$&&V.parentStepIndex===void 0&&!j.has(V.id)):[],z=c8([...X.children??[],...U,...G]);return z?.length?{...X,children:z}:{...X,children:void 0}})}function TU($){if(!$?.length)return[];let J=["Nested subagents:"],Z=10,Q=(X,Y)=>{for(let H of X??[]){if(Z<=0){J.push(`${Y}↳ +more nested runs; inspect status for full tree`);return}Z--;let j=H.agent??H.agents?.join("+")??H.id;if(J.push(`${Y}↳ ${j} — ${H.state} [${H.id}]`),H.sessionFile)J.push(`${Y} Session: ${H.sessionFile}`);Q(H.children,`${Y} `);for(let U of H.steps??[])Q(U.children,`${Y} `)}};return Q($,""),J}function SU($){if($.source!=="async"||!$.asyncId)return;let J=$.children.filter((Z)=>typeof Z.sessionPath==="string"&&X7.existsSync(Z.sessionPath));if($.children.length===1&&J.length===1)return`Revive: subagent({ action: "resume", id: "${$.asyncId}", message: "..." })`;if(J.length>0){let Z=J[0]?.index??$.children.indexOf(J[0]);return`Revive child: subagent({ action: "resume", id: "${$.asyncId}", index: ${Z}, message: "..." })`}return"Resume: unavailable; no child session file was persisted."}function CU($){let J=d8($.children),Z=["subagent results","",`Run: ${$.runId}`,`Mode: ${$.mode}`,`Status: ${$.status}`,`Children: ${n6(J)}`];if($.mode==="chain"&&typeof $.chainSteps==="number")Z.push(`Chain steps: ${$.chainSteps}`);if($.asyncId)Z.push(`Async id: ${$.asyncId}`);if($.asyncDir)Z.push(`Async dir: ${$.asyncDir}`);let Q=SU($);if(Q)Z.push(Q);if($.children.some((X)=>X.intercomTarget))Z.push(""),Z.push($.source==="async"?"Previous intercom targets below identify child sessions used while they were running. Inspect artifacts or session logs if resume is unavailable.":"Intercom targets below identify child sessions used while they were running; completed child sessions may no longer be reachable. Inspect artifacts or session logs for follow-up.");for(let X=0;X<$.children.length;X++){let Y=$.children[X];if(Z.push(""),Z.push(`${X+1}. ${Y.agent} — ${Y.status}`),Y.intercomTarget)Z.push(`${$.source==="async"?"Previous intercom target":"Run intercom target"}: ${Y.intercomTarget}`);if(Y.artifactPath)Z.push(`Output artifact: ${Y.artifactPath}`);if(Y.sessionPath)Z.push(`Session: ${Y.sessionPath}`);Z.push(...TU(Y.children)),Z.push("Summary:"),Z.push(Y.summary)}return Z.join(`
|
|
191
|
-
`)}function H7($){let J=$.children.map((H)=>({...H,summary:H.summary.trim()||"(no output)",children:c8(H.children)})),Z=EU(J),Q=n6(d8(J)),X=J[0],Y={to:$.to,runId:$.runId,mode:$.mode,status:Z,summary:Q,source:$.source,children:J,...$.asyncId?{asyncId:$.asyncId}:{},...$.asyncDir?{asyncDir:$.asyncDir}:{},...typeof $.chainSteps==="number"?{chainSteps:$.chainSteps}:{},...X?.agent?{agent:X.agent}:{},...X?.index!==void 0?{index:X.index}:{},...X?.artifactPath?{artifactPath:X.artifactPath}:{},...X?.sessionPath?{sessionPath:X.sessionPath}:{},message:""};return Y.message=CU(Y),Y}async function j7($,J,Z=500){return p6($,J.to,J.message,Z,J)}async function p6($,J,Z,Q=500,X={}){if(typeof $.on!=="function"||typeof $.emit!=="function")return!1;let Y=typeof X.requestId==="string"?X.requestId:NU();return new Promise((H)=>{let j=!1,U,G,z=(V)=>{if(j)return;if(j=!0,G)clearTimeout(G);U?.(),H(V)};U=$.on(C9,(V)=>{if(!V||typeof V!=="object")return;let B=V;if(B.requestId!==Y)return;z(B.delivered===!0)}),G=setTimeout(()=>z(!1),Q);try{$.emit(S9,{...X,to:J,message:Z,requestId:Y})}catch{z(!1)}})}function RU($){return{...$,messages:void 0,finalOutput:void 0,truncation:void 0}}function U7($){return{...$,results:$.results.map(RU)}}function V7($){let J=d8($.payload.children),Q=[`Delivered ${$.mode==="single"?"single subagent result":$.mode==="parallel"?"parallel subagent results":"chain subagent results"} via intercom.`,`Run: ${$.runId}`,`Children: ${n6(J)}`],X=$.payload.children.filter((j)=>typeof j.artifactPath==="string");if(X.length>0){Q.push("Artifacts:");for(let j of X)Q.push(`- ${j.agent} [${j.status}]: ${j.artifactPath}`)}let Y=$.payload.children.filter((j)=>typeof j.intercomTarget==="string");if(Y.length>0){Q.push("Run intercom targets (may be inactive after completion):");for(let j of Y)Q.push(`- ${j.agent} [${j.status}]: ${j.intercomTarget}`)}let H=$.payload.children.filter((j)=>typeof j.sessionPath==="string");if(H.length>0){Q.push("Sessions:");for(let j of H)Q.push(`- ${j.agent} [${j.status}]: ${j.sessionPath}`)}return Q.push("Full grouped output was sent over intercom."),Q.join(`
|
|
192
|
-
`)}import*as o0 from"node:fs";import*as P$ from"node:path";import{randomUUID as yU}from"node:crypto";import*as z7 from"node:fs";import*as S2 from"node:path";var fU=process.platform==="win32"?"SIGBREAK":"SIGUSR2",DU="steer-requests";function G7($){return S2.join($,"control")}function bU($){return S2.join(G7($),"interrupt.json")}function wU($){return S2.join(G7($),DU)}function IU($){return`${String($.ts).padStart(13,"0")}-${Buffer.from($.id).toString("base64url")}.json`}function kU($,J){let Z=S2.join($,IU(J));return w0(Z,J),Z}function PU($,J={},Z={}){let Q=bU($),X={...J,ts:J.ts??Z.now?.()??Date.now(),type:"interrupt"};return w0(Q,X),Q}function i6($,J,Z={}){let Q=J.message.trim();if(!Q)throw Error("steer message must not be empty.");if(J.targetIndex!==void 0&&(!Number.isInteger(J.targetIndex)||J.targetIndex<0))throw Error("steer targetIndex must be a non-negative integer.");let X={type:"steer",id:J.id??Z.randomId?.()??yU(),ts:J.ts??Z.now?.()??Date.now(),message:Q,...J.targetIndex!==void 0?{targetIndex:J.targetIndex}:{},...J.source?{source:J.source}:{}};return kU(wU($),X)}function C2($){let J=PU($.asyncDir,$.source?{source:$.source}:{},{now:$.now});if(typeof $.pid==="number"&&$.pid>0)try{($.kill??process.kill)($.pid,$.signal??fU)}catch(Z){if(Z?.code==="ENOSYS")return;try{z7.rmSync(J,{force:!0})}catch{}throw Z}}import*as z0 from"node:fs";import*as N0 from"node:path";function xU($,J,Z){if(typeof $!=="object"||$===null)return!1;let{start:Q,count:X,stepIndex:Y}=$;return typeof Q==="number"&&typeof X==="number"&&typeof Y==="number"&&Number.isInteger(Q)&&Number.isInteger(X)&&Number.isInteger(Y)&&Q>=0&&X>0&&Y>=0&&Y<Z&&Q+X<=J}function s1($,J,Z){if(!Array.isArray($))return[];return $.filter((Q)=>xU(Q,J,Z)).sort((Q,X)=>Q.stepIndex-X.stepIndex||Q.start-X.start)}function o8($,J,Z){let Q=0,X=0;for(let Y of Z){while(X<Y.start&&Q<J){if(X===$)return Q;X++,Q++}if($>=Y.start&&$<Y.start+Y.count)return Y.stepIndex;X=Y.start+Y.count,Q=Y.stepIndex+1}while(X<=$&&Q<J){if(X===$)return Q;X++,Q++}return Math.max(0,J-1)}function r6($){return $ instanceof Error?$.message:String($)}function vU($){let J=N0.join($,"runner.stderr.log"),Z=65536,Q;try{let Y=z0.statSync(J);if(Y.size<=0)return;let H=z0.openSync(J,"r");try{let j=Math.min(Y.size,65536),U=Math.max(0,Y.size-j),G=Buffer.alloc(j);z0.readSync(H,G,0,j,U),Q=G.toString("utf-8").trim()}finally{z0.closeSync(H)}}catch{return}if(!Q)return;let X=Q.split(/\r?\n/).slice(-30).join(`
|
|
193
|
-
`);return X.length>4000?`${X.slice(-4000)}
|
|
194
|
-
[stderr tail truncated]`:X}function W7($){return typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT"}function hU($,J){try{z0.mkdirSync(N0.dirname($),{recursive:!0}),z0.appendFileSync($,`${JSON.stringify(J)}
|
|
195
|
-
`,"utf-8")}catch{}}function gU($){let J=N0.join($,"status.json"),Z;try{Z=z0.readFileSync(J,"utf-8")}catch(Q){if(W7(Q))return null;throw Error(`Failed to read async status file '${J}': ${r6(Q)}`,{cause:Q instanceof Error?Q:void 0})}try{return JSON.parse(Z)}catch(Q){throw Error(`Failed to parse async status file '${J}': ${r6(Q)}`,{cause:Q instanceof Error?Q:void 0})}}function mU($){try{let J=JSON.parse(z0.readFileSync($,"utf-8"));return{state:J.success?"complete":J.state==="paused"||J.exitCode===0?"paused":"failed",...Array.isArray(J.results)?{results:J.results}:{}}}catch(J){if(W7(J))return;throw Error(`Failed to read async result file '${$}': ${r6(J)}`,{cause:J instanceof Error?J:void 0})}}function cU($,J){if(J?.success===!0)return"complete";if(J?.success===!1)return"failed";return $}function uU($,J,Z){let Q=mU(J);if(!Q)return;let X=($.steps??[]).map((Y,H)=>{if(Y.status!=="running"&&Y.status!=="pending")return Y;let j=Q.results?.[H],U=cU(Q.state,j);return{...Y,status:U==="complete"?"complete":U,endedAt:Y.endedAt??Z,durationMs:Y.startedAt!==void 0&&Y.durationMs===void 0?Math.max(0,Z-Y.startedAt):Y.durationMs,exitCode:Y.exitCode??(U==="complete"||U==="paused"?0:1),error:U==="failed"?Y.error??j?.error:Y.error,sessionFile:Y.sessionFile??j?.sessionFile,model:Y.model??j?.model,attemptedModels:Y.attemptedModels??j?.attemptedModels,modelAttempts:Y.modelAttempts??j?.modelAttempts}});return{...$,state:Q.state,activityState:void 0,lastUpdate:Z,endedAt:$.endedAt??Z,steps:X}}function dU($,J,Z){let Q=J.startedAt??Z,X=J.agents?.length?J.agents:["subagent"],Y=J.chainStepCount,H=Y!==void 0?s1(J.parallelGroups,X.length,Y):[];return{runId:J.runId||N0.basename($),...J.sessionId?{sessionId:J.sessionId}:{},mode:J.mode??"single",state:"running",pid:J.pid,startedAt:Q,lastUpdate:Z,currentStep:0,...Y!==void 0?{chainStepCount:Y}:{},...H.length?{parallelGroups:H}:{},steps:X.map((j)=>({agent:j,status:"running",startedAt:Q})),...J.sessionFile?{sessionFile:J.sessionFile}:{}}}function oU($,J,Z,Q){let X=$.runId||N0.basename(J),Y=typeof $.pid==="number"?$.pid:"unknown",H=Q??`Async runner process ${Y} exited or disappeared before writing a result. Marked run failed by stale-run reconciliation.`,j=vU(J),U=j?`${H}
|
|
196
|
-
|
|
197
|
-
Runner stderr tail:
|
|
198
|
-
${j}`:H,z=(($.steps?.length)?$.steps:[{agent:"subagent",status:"running"}]).map((K)=>K.status==="running"||K.status==="pending"?{...K,status:"failed",activityState:void 0,endedAt:K.endedAt??Z,durationMs:K.startedAt!==void 0&&K.durationMs===void 0?Math.max(0,Z-K.startedAt):K.durationMs,exitCode:K.exitCode??1,error:K.error??U}:K),V={...$,state:"failed",activityState:void 0,lastUpdate:Z,endedAt:Z,steps:z},B=z[$.currentStep??0]?.agent??z[0]?.agent??"subagent";return{status:V,message:U,result:{id:X,agent:B,mode:$.mode,success:!1,state:"failed",summary:U,results:z.map((K)=>({agent:K.agent,output:K.status==="complete"||K.status==="completed"?"":U,error:K.status==="complete"||K.status==="completed"?void 0:K.error??U,success:K.status==="complete"||K.status==="completed",model:K.model,attemptedModels:K.attemptedModels,modelAttempts:K.modelAttempts,sessionFile:K.sessionFile})),exitCode:1,timestamp:Z,durationMs:Math.max(0,Z-$.startedAt),asyncDir:J,sessionId:$.sessionId,sessionFile:$.sessionFile}}}function B7($,J,Z,Q,X){let Y=oU(J,$,Q,X);return w0(Z,Y.result),w0(N0.join($,"status.json"),Y.status),hU(N0.join($,"events.jsonl"),{type:"subagent.run.repaired_stale",ts:Q,runId:Y.status.runId,pid:J.pid,resultPath:Z,message:Y.message}),{status:Y.status,repaired:!0,resultPath:Z,message:Y.message}}function K7($){return $==="complete"||$==="failed"||$==="paused"}function*s6($){for(let J of $??[])yield J,yield*s6(J.children),yield*s6(J.steps?.flatMap((Z)=>Z.children??[]))}function R2($,J={}){let Z=n1($);for(let Q of s6(Z.children)){if(Q.state!=="running"&&Q.state!=="queued")continue;let X=RJ($.rootRunId,Q);if(!X)continue;let Y=C0(X,{...J,resultsDir:N0.join(J.resultsDir??h$,"nested",$.rootRunId)}),H=Y.status;if(!H)continue;if(!Y.repaired&&!K7(H.state))continue;let j=J.now?.()??Date.now();p1($,{type:K7(H.state)?"subagent.nested.completed":"subagent.nested.updated",ts:j,parentRunId:Q.parentRunId,parentStepIndex:Q.parentStepIndex,child:o3(H,X,{id:Q.id,parentRunId:Q.parentRunId,parentStepIndex:Q.parentStepIndex,depth:Q.depth,path:Q.path,mode:Q.mode,ts:j})})}}function lU($,J=process.kill){try{return J($,0),"alive"}catch(Z){let Q=typeof Z==="object"&&Z!==null&&"code"in Z?Z.code:void 0;if(Q==="ESRCH")return"dead";if(Q==="EPERM")return"unknown";return"unknown"}}function C0($,J={}){let Z=J.now?.()??Date.now(),Q=gU($),X=!Q&&J.startedRun?dU($,J.startedRun,Z):void 0,Y=Q??X;if(!Y)return{status:null,repaired:!1};let H=Y.runId||N0.basename($),j=N0.join(J.resultsDir??h$,`${H}.json`);if(z0.existsSync(j)){let G=Y.state==="running"||Y.state==="queued"?uU(Y,j,Z):void 0;if(G)return w0(N0.join($,"status.json"),G),{status:G,repaired:!0,resultPath:j,message:"Existing async result file was used to repair stale running status."};return{status:Y,repaired:!1,resultPath:j}}if(Y.state!=="running"||typeof Y.pid!=="number")return{status:Q??null,repaired:!1,resultPath:j};if(!Q){let G=J.startedRun?.startedAt??Y.startedAt;if(Z-G<(J.missingStatusGraceMs??1000))return{status:null,repaired:!1,resultPath:j}}if(lU(Y.pid,J.kill)!=="dead"){let G=J.staleAlivePidMs??86400000,z=Y.lastUpdate??Y.startedAt;if(Z-z<=G)return{status:Q??null,repaired:!1,resultPath:j};let V=`Async runner process ${Y.pid} still has a live PID, but status has not updated for ${Z-z}ms. Marked run failed by stale-run reconciliation because PID ownership cannot be verified.`;return B7($,Y,j,Z,V)}return B7($,Y,j,Z)}var nU=process.platform==="win32"?"SIGBREAK":"SIGUSR2";function O7($){let J=$.target.runId;if(!$.target.asyncDir)return{ok:!1,message:`Async run ${J} is live but does not have an async directory to interrupt.`};let Z=C0($.target.asyncDir,{resultsDir:$.resultsDir,kill:$.kill,now:$.now}).status;if(!Z||Z.state!=="running"||typeof Z.pid!=="number")return{ok:!1,message:`Async run ${J} is live but no interrupt-capable runner pid was found.`};try{C2({asyncDir:$.target.asyncDir,pid:Z.pid,kill:$.kill,signal:nU,now:$.now,source:"async-resume"});let Q=$.state?.asyncJobs.get(J);if(Q)Q.activityState=void 0,Q.updatedAt=$.now?.()??Date.now();return{ok:!0,asyncId:J}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return{ok:!1,message:`Failed to interrupt async run ${J}: ${X}`}}}function _7($){return $ instanceof Error?$.message:String($)}function A7($,J){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`Async result file '${J}' must contain a JSON object.`);return $}function Q1($,J,Z,Q=J){let X=$[J];if(X===void 0)return;if(typeof X!=="string")throw Error(`Invalid async result file '${Z}': ${Q} must be a string.`);return X}function pU($,J){let Z=A7($,J),Q=Z.results,X;if(Q!==void 0){if(!Array.isArray(Q))throw Error(`Invalid async result file '${J}': results must be an array.`);X=Q.map((H,j)=>{let U=A7(H,`${J} results[${j}]`),G=Q1(U,"agent",J,`results[${j}].agent`),z=Q1(U,"sessionFile",J,`results[${j}].sessionFile`),V=Q1(U,"intercomTarget",J,`results[${j}].intercomTarget`),B=U.success;if(B!==void 0&&typeof B!=="boolean")throw Error(`Invalid async result file '${J}': results[${j}].success must be a boolean.`);return{agent:G,sessionFile:z,intercomTarget:V,...typeof B==="boolean"?{success:B}:{}}})}let Y=Z.success;if(Y!==void 0&&typeof Y!=="boolean")throw Error(`Invalid async result file '${J}': success must be a boolean.`);return{id:Q1(Z,"id",J),runId:Q1(Z,"runId",J),agent:Q1(Z,"agent",J),mode:Q1(Z,"mode",J),state:Q1(Z,"state",J),cwd:Q1(Z,"cwd",J),sessionFile:Q1(Z,"sessionFile",J),...typeof Y==="boolean"?{success:Y}:{},...X?{results:X}:{}}}function iU($){let J;try{J=o0.readFileSync($,"utf-8")}catch(Z){throw Error(`Failed to read async result file '${$}': ${_7(Z)}`,{cause:Z instanceof Error?Z:void 0})}try{return pU(JSON.parse(J),$)}catch(Z){if(Z instanceof SyntaxError)throw Error(`Failed to parse async result file '${$}': ${_7(Z)}`,{cause:Z});throw Z}}function a6($,J){if($===void 0)return;if($.trim()==="")throw Error(`${J} must not be empty.`);if(P$.isAbsolute($)||/[\\/]/.test($)||$.includes(".."))throw Error(`${J} must be an async run id or prefix, not a path.`);return $}function l8($,J,Z){let Q=P$.resolve($),X=P$.resolve(J),Y=P$.relative(Q,X);if(Y===""||!Y.startsWith("..")&&!P$.isAbsolute(Y))return;throw Error(`${Z} must be inside ${Q}.`)}function q7($,J,Z=""){if(!o0.existsSync($))return[];return o0.readdirSync($).filter((Q)=>Q.startsWith(J)&&(!Z||Q.endsWith(Z))).map((Q)=>Z?Q.slice(0,-Z.length):Q).sort()}function t6($,J){let Z=P$.join($,`${J}.json`);return l8($,Z,"Async result file"),o0.existsSync(Z)?Z:null}function e6($,J,Z){let Q=a6($,"id");if(!Q)return[];let X=P$.resolve(J),Y=P$.resolve(Z);return[...new Set([...q7(X,Q),...q7(Y,Q,".json")])].sort().map((j)=>{let U=P$.join(X,j);return l8(X,U,"Async run directory"),{id:j,location:{asyncDir:o0.existsSync(U)?U:null,resultPath:t6(Y,j),resolvedId:j}}})}function y2($,J,Z){let Q=P$.resolve(J),X=P$.resolve(Z),Y=a6($.id,"id")??a6($.runId,"runId");if($.dir){let G=P$.resolve($.dir);l8(Q,G,"Async run directory");let z=Y??P$.basename(G);if(Y&&Y!==P$.basename(G))throw Error(`Async run id '${Y}' does not match directory '${P$.basename(G)}'.`);return{asyncDir:G,resultPath:t6(X,z),resolvedId:z}}if(!Y)return{asyncDir:null,resultPath:null};let H=P$.join(Q,Y);l8(Q,H,"Async run directory");let j=t6(X,Y);if(o0.existsSync(H)||j)return{asyncDir:o0.existsSync(H)?H:null,resultPath:j,resolvedId:Y};let U=e6(Y,Q,X);if(U.length===0)return{asyncDir:null,resultPath:null,resolvedId:Y};if(U.length>1)throw Error(`Ambiguous async run id prefix '${Y}' matched: ${U.map((G)=>G.id).join(", ")}. Provide a longer id.`);return U[0].location}function rU($){if($.state==="complete"||$.state==="failed"||$.state==="paused"||$.state==="running"||$.state==="queued")return $.state;return $.success?"complete":"failed"}function sU($,J){if(!$)return;if(typeof $.runId!=="string")throw Error(`Invalid async status '${J}': runId must be a string.`);if($.sessionId!==void 0&&typeof $.sessionId!=="string")throw Error(`Invalid async status '${J}': sessionId must be a string.`);if($.cwd!==void 0&&typeof $.cwd!=="string")throw Error(`Invalid async status '${J}': cwd must be a string.`);if($.sessionFile!==void 0&&typeof $.sessionFile!=="string")throw Error(`Invalid async status '${J}': sessionFile must be a string.`);if($.steps!==void 0){if(!Array.isArray($.steps))throw Error(`Invalid async status '${J}': steps must be an array.`);$.steps.forEach((Z,Q)=>{if(!Z||typeof Z!=="object"||Array.isArray(Z))throw Error(`Invalid async status '${J}': steps[${Q}] must be an object.`);if(typeof Z.agent!=="string")throw Error(`Invalid async status '${J}': steps[${Q}].agent must be a string.`);if(Z.sessionFile!==void 0&&typeof Z.sessionFile!=="string")throw Error(`Invalid async status '${J}': steps[${Q}].sessionFile must be a string.`)})}}function aU($,J){if(P$.extname(J)!==".jsonl")throw Error(`Async run '${$}' session file must be a .jsonl file: ${J}`);let Z=P$.resolve(J);if(!o0.existsSync(Z))throw Error(`Async run '${$}' session file does not exist: ${J}`);return Z}function F7($,J={},Z={}){let Q=J.asyncDirRoot??Q0,X=J.resultsDir??h$,Y=Z.requireSessionFile??!0,H=y2($,Q,X);if(!H.asyncDir&&!H.resultPath)throw Error("Async run not found. Provide id or dir.");let U=(H.asyncDir?C0(H.asyncDir,{resultsDir:X,kill:J.kill,now:J.now}):void 0)?.status??null;sU(U,H.asyncDir?P$.join(H.asyncDir,"status.json"):"status.json");let G=H.resultPath?iU(H.resultPath):void 0,z=U?.runId??G?.runId??G?.id??H.resolvedId??(H.asyncDir?P$.basename(H.asyncDir):"unknown"),V=U?.state??(G?rU(G):void 0);if(!V)throw Error(`Status file not found for async run '${z}'.`);let B=U?.steps??[],K=G?.results??[],W=B.length||K.length||(G?.agent?1:0),A=$.index;if(A!==void 0&&!Number.isInteger(A))throw Error(`Async run '${z}' index must be an integer.`);let F=new Set(["complete","completed","failed","paused"]);if(V==="running")if(A!==void 0){if(A<0||A>=W)throw Error(`Async run '${z}' has ${W} children. Index ${A} is out of range.`);let C=B[A];if(C?.status==="running")return{kind:"live",runId:z,asyncDir:H.asyncDir??void 0,state:V,agent:C.agent,index:A,intercomTarget:u$(z,C.agent,A),cwd:U?.cwd??G?.cwd,sessionFile:C.sessionFile??U?.sessionFile??G?.sessionFile};if(C?.status==="pending")throw Error(`Async run '${z}' child ${A} is pending and has not started yet. Wait for it to run or complete before resuming.`);if(C&&!F.has(C.status))throw Error(`Async run '${z}' child ${A} is ${C.status} and cannot be revived yet.`)}else{let C=B.map((h,b)=>({step:h,index:b})).filter(({step:h})=>h.status==="running"),T=C.length===1?C[0]:void 0;if(!T)throw Error(`Async run '${z}' has ${C.length} running children. Provide index to choose one.`);return{kind:"live",runId:z,asyncDir:H.asyncDir??void 0,state:V,agent:T.step.agent,index:T.index,intercomTarget:u$(z,T.step.agent,T.index),cwd:U?.cwd??G?.cwd,sessionFile:T.step.sessionFile??U?.sessionFile??G?.sessionFile}}if(W>1&&A===void 0)throw Error(`Async run '${z}' has ${W} children. Provide index to choose one.`);let _=A??0;if(!Number.isInteger(_))throw Error(`Async run '${z}' index must be an integer.`);if(_<0||_>=W)throw Error(`Async run '${z}' has ${W} children. Index ${_} is out of range.`);let f=B[_]?.agent??K[_]?.agent??G?.agent;if(!f)throw Error(`Could not determine child agent for async run '${z}'.`);let O=B[_]?.sessionFile??K[_]?.sessionFile??(W===1?U?.sessionFile??G?.sessionFile:void 0);if(!O&&Y)throw Error(`Async run '${z}' child ${_} does not have a persisted session file to resume from.`);let y=O?aU(z,O):void 0;return{kind:"revive",runId:z,asyncDir:H.asyncDir??void 0,state:V,agent:f,index:_,intercomTarget:u$(z,f,_),cwd:U?.cwd??G?.cwd,...y?{sessionFile:y}:{}}}function L7($,J){return["You are reviving a previous subagent conversation.","",`Original run: ${$.runId}`,`Original agent: ${$.agent}`,$.sessionFile?`Original session file: ${$.sessionFile}`:void 0,"","Use the stored session context as background. Answer the orchestrator's follow-up below. Do not assume the original child process is still alive.","","Follow-up:",J].filter((Z)=>Z!==void 0).join(`
|
|
199
|
-
`)}import*as M7 from"node:path";function N7($,J){return M7.join($,`${J}.json`)}import*as f2 from"node:fs";import*as $9 from"node:path";function tU($,J,Z){let Q=$9.join(J,$),X=$9.join(Z,`${$}.json`);if(!f2.existsSync(Q)&&!f2.existsSync(X))return;return{asyncDir:f2.existsSync(Q)?Q:null,resultPath:f2.existsSync(X)?X:null,resolvedId:$}}function eU($){if(!$)return[];return[...new Set([...$.foregroundControls.keys(),...$.foregroundRuns?.keys()??[]])]}function $V($){if(!$)return;let J=[],Z=new Set,Q=(X)=>{if(!X)return;let Y=`${X.rootRunId}:${X.eventSink}:${X.controlInbox}`;if(Z.has(Y))return;Z.add(Y),J.push(X)};for(let X of $.foregroundControls.values())Q(X.nestedRoute);for(let X of $.asyncJobs.values())Q(X.nestedRoute);return{routes:J}}function JV($,J,Z){return e6($,J,Z)}function O1($,J={}){P6("id",$);let Z=J.asyncDirRoot??Q0,Q=J.resultsDir??h$,X=J.nested??$V(J.state);if(J.state?.foregroundControls.has($)||J.state?.foregroundRuns?.has($))return{kind:"foreground",id:$};let Y=tU($,Z,Q);if(Y)return{kind:"async",id:$,location:Y};let H=h6($,X?{scope:X}:{});if(H.length>1)throw Error(`Nested run id '${$}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);if(H[0])return{kind:"nested",id:$,match:H[0]};let j=[];for(let z of eU(J.state).filter((V)=>V.startsWith($)))j.push({kind:"foreground",id:z});for(let z of JV($,Z,Q))j.push({kind:"async",id:z.id,location:z.location});for(let z of h6($,X?{prefix:!0,scope:X}:{prefix:!0}))j.push({kind:"nested",id:z.run.id,match:z});let G=[...new Map(j.map((z)=>[`${z.kind}:${z.id}`,z])).values()];if(G.length>1)throw Error(`Ambiguous subagent run id prefix '${$}' matched: ${G.map((z)=>`${z.kind}:${z.id}`).join(", ")}. Provide a longer id.`);return G[0]}function ZV($){if($<1000)return"now";if($<60000)return`${Math.floor($/1000)}s`;return`${Math.floor($/60000)}m`}function l0($,J,Z=Date.now()){if($===void 0){if(J==="needs_attention")return"needs attention";if(J==="active_long_running")return"active but long-running";return}let Q=ZV(Math.max(0,Z-$));if(J==="needs_attention")return`no activity for ${Q}`;if(J==="active_long_running")return`active but long-running · last activity ${Q} ago`;return Q==="now"?"active now":`active ${Q} ago`}function QV($){return $==="complete"||$==="completed"}function XV($){return $===1?"1 agent running":`${$} agents running`}function J9($,J,Z={}){let Q=$.filter((U)=>U.status==="running").length,X=$.filter((U)=>QV(U.status)).length,Y=$.filter((U)=>U.status==="failed").length,H=$.filter((U)=>U.status==="paused").length,j=[`${X}/${J} done`];if(Z.showRunning!==!1&&Q>0)j.unshift(XV(Q));if(Y>0)j.push(`${Y} failed`);if(H>0)j.push(`${H} paused`);return j.join(" · ")}function T7($){let J={total:0,running:0,paused:0,complete:0,failed:0,queued:0};for(let Z of $??[]){J.total++,J[Z.state]++;let Q=T7([...Z.children??[],...Z.steps?.flatMap((X)=>X.children??[])??[]]);J.total+=Q.total,J.running+=Q.running,J.paused+=Q.paused,J.complete+=Q.complete,J.failed+=Q.failed,J.queued+=Q.queued}return J}function Z9($){let J=T7($);if(J.total===0)return;let Z=[J.running>0?`${J.running} running`:"",J.paused>0?`${J.paused} paused`:"",J.failed>0?`${J.failed} failed`:"",J.complete>0?`${J.complete} complete`:"",J.queued>0?`${J.queued} queued`:""].filter(Boolean);return`+${J.total} nested run${J.total===1?"":"s"}${Z.length?` (${Z.join(", ")})`:""}`}function YV($){if($.agent)return $.agent;if($.agents?.length)return $.agents.length===1?$.agents[0]:`${$.agents.slice(0,2).join(", ")}${$.agents.length>2?` +${$.agents.length-2}`:""}`;return $.id}function E7($){let J=[];if($.currentTool&&$.currentToolStartedAt!==void 0)J.push(`tool ${$.currentTool} ${M1(Math.max(0,Date.now()-$.currentToolStartedAt))}`);else if($.currentTool)J.push(`tool ${$.currentTool}`);if($.currentPath)J.push(H0($.currentPath));if($.turnCount!==void 0)J.push(`${$.turnCount} turns`);if($.toolCount!==void 0)J.push(`${$.toolCount} tools`);if($.totalTokens)J.push(`${XJ($.totalTokens.total)} tok`);let Z=l0($.lastActivityAt,$.activityState);return Z||J.length?[Z,...J].filter(Boolean).join(" | "):void 0}function HV($,J){let Z=[],Q=(X,Y,H)=>{if(!X?.length||Z.length>=J.maxLines)return;if(Y>J.maxDepth){let j=Z9(X);if(j&&Z.length<J.maxLines)Z.push(`${H}↳ ${j}`);return}for(let j=0;j<X.length;j++){let U=X[j];if(Z.length>=J.maxLines){let V=Z9(X.slice(j));if(V)Z[Z.length-1]=`${H}↳ ${V}`;return}let G=U.state==="running"?E7(U):void 0,z=U.error?` | error: ${U.error}`:"";if(Z.push(`${H}↳ ${YV(U)} [${U.id}] ${U.state}${G?` | ${G}`:""}${z}`),J.commandHints&&Z.length<J.maxLines)Z.push(`${H} Status: subagent({ action: "status", id: "${U.id}" })`);if(Y===J.maxDepth){let V=Z9([...U.steps?.flatMap((B)=>B.children??[])??[],...U.children??[]]);if(V&&Z.length<J.maxLines)Z.push(`${H} ↳ ${V}`);continue}for(let[V,B]of(U.steps??[]).entries()){if(Z.length>=J.maxLines)return;let K=B.status==="running"?E7(B):void 0;Z.push(`${H} ${V+1}. ${B.agent} ${B.status}${K?` | ${K}`:""}${B.error?` | error: ${B.error}`:""}`),Q(B.children,Y+1,`${H} `)}Q(U.children,Y+1,`${H} `)}};return Q($,0,J.indent),Z}function E0($,J={}){return HV($,{indent:J.indent??" ",maxDepth:J.maxDepth??2,maxLines:J.maxLines??40,commandHints:J.commandHints??!1})}import*as X1 from"node:fs";import*as s8 from"node:path";import*as b2 from"node:fs";import*as R0 from"node:path";function D2($){return $ instanceof Error?$.message:String($)}function Q9($){return typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT"}function jV($,J){let Z=R0.join($,J);try{return b2.statSync(Z).isDirectory()}catch(Q){if(Q9(Q))return!1;throw Error(`Failed to inspect async run path '${Z}': ${D2(Q)}`,{cause:Q instanceof Error?Q:void 0})}}function UV($){if(!$)return;try{return b2.statSync($).mtimeMs}catch(J){if(Q9(J))return;throw Error(`Failed to inspect async output file '${$}': ${D2(J)}`,{cause:J instanceof Error?J:void 0})}}function VV($,J){if(J.state!=="running")return{activityState:J.activityState,lastActivityAt:J.lastActivityAt};let Z=J.outputFile?R0.isAbsolute(J.outputFile)?J.outputFile:R0.join($,J.outputFile):void 0,Q=typeof J.currentStep==="number"?J.steps?.[J.currentStep]:void 0;return{activityState:J.activityState,lastActivityAt:J.lastActivityAt??UV(Z)??Q?.lastActivityAt??Q?.startedAt??J.startedAt}}function zV($,J,Z=[],Q){if(J.sessionId!==void 0&&typeof J.sessionId!=="string")throw Error(`Invalid async status '${R0.join($,"status.json")}': sessionId must be a string.`);let{activityState:X,lastActivityAt:Y}=VV($,J),H=J.steps??[],j=J.chainStepCount??H.length,U=s1(J.parallelGroups,H.length,j),G=[];if(Z.length===0&&Q)try{G=n1(Q)?.children??[]}catch(V){Z.push(`Nested status unavailable: ${D2(V)}`)}let z=H.map((V,B)=>{let{activityState:K,lastActivityAt:W}=V;return{index:B,agent:V.agent,...V.label?{label:V.label}:{},...V.phase?{phase:V.phase}:{},...V.outputName?{outputName:V.outputName}:{},...V.structured?{structured:V.structured}:{},status:V.status,...K?{activityState:K}:{},...W?{lastActivityAt:W}:{},...V.currentTool?{currentTool:V.currentTool}:{},...V.currentToolArgs?{currentToolArgs:V.currentToolArgs}:{},...V.currentToolStartedAt?{currentToolStartedAt:V.currentToolStartedAt}:{},...V.currentPath?{currentPath:V.currentPath}:{},...V.recentTools?{recentTools:V.recentTools.map((A)=>({...A}))}:{},...V.recentOutput?{recentOutput:[...V.recentOutput]}:{},...V.turnCount!==void 0?{turnCount:V.turnCount}:{},...V.toolCount!==void 0?{toolCount:V.toolCount}:{},...V.steerCount!==void 0?{steerCount:V.steerCount}:{},...V.lastSteerAt!==void 0?{lastSteerAt:V.lastSteerAt}:{},...V.durationMs!==void 0?{durationMs:V.durationMs}:{},...V.tokens?{tokens:V.tokens}:{},...V.totalCost?{totalCost:V.totalCost}:{},...V.skills?{skills:V.skills}:{},...V.model?{model:V.model}:{},...V.thinking?{thinking:V.thinking}:{},...V.attemptedModels?{attemptedModels:V.attemptedModels}:{},...V.error?{error:V.error}:{},...V.timedOut!==void 0?{timedOut:V.timedOut}:{},...V.turnBudget?{turnBudget:V.turnBudget}:{},...V.turnBudgetExceeded!==void 0?{turnBudgetExceeded:V.turnBudgetExceeded}:{},...V.wrapUpRequested!==void 0?{wrapUpRequested:V.wrapUpRequested}:{},...V.children?.length?{children:V.children}:{}}});return D1(J.runId||R0.basename($),z,G),{id:J.runId||R0.basename($),asyncDir:$,...J.sessionId?{sessionId:J.sessionId}:{},state:J.state,...J.error?{error:J.error}:{},activityState:X,lastActivityAt:Y,currentTool:J.currentTool,currentToolStartedAt:J.currentToolStartedAt,currentPath:J.currentPath,turnCount:J.turnCount,toolCount:J.toolCount,steerCount:J.steerCount,lastSteerAt:J.lastSteerAt,mode:J.mode,cwd:J.cwd,startedAt:J.startedAt,lastUpdate:J.lastUpdate,endedAt:J.endedAt,...J.timeoutMs!==void 0?{timeoutMs:J.timeoutMs}:{},...J.deadlineAt!==void 0?{deadlineAt:J.deadlineAt}:{},...J.timedOut!==void 0?{timedOut:J.timedOut}:{},...J.turnBudget?{turnBudget:J.turnBudget}:{},...J.turnBudgetExceeded!==void 0?{turnBudgetExceeded:J.turnBudgetExceeded}:{},...J.wrapUpRequested!==void 0?{wrapUpRequested:J.wrapUpRequested}:{},currentStep:J.currentStep,...J.chainStepCount!==void 0?{chainStepCount:J.chainStepCount}:{},...J.pendingAppends!==void 0?{pendingAppends:J.pendingAppends}:{},...U.length?{parallelGroups:U}:{},steps:z,...G.length?{nestedChildren:G}:{},...Z.length?{nestedWarnings:Z}:{},...J.sessionDir?{sessionDir:J.sessionDir}:{},...J.outputFile?{outputFile:J.outputFile}:{},...J.totalTokens?{totalTokens:J.totalTokens}:{},...J.totalCost?{totalCost:J.totalCost}:{},...J.sessionFile?{sessionFile:J.sessionFile}:{}}}function GV($){let J=(Z)=>{switch(Z){case"running":return 0;case"queued":return 1;case"failed":return 2;case"paused":return 2;case"complete":return 3}};return[...$].sort((Z,Q)=>{let X=J(Z.state)-J(Q.state);if(X!==0)return X;let Y=Z.lastUpdate??Z.endedAt??Z.startedAt;return(Q.lastUpdate??Q.endedAt??Q.startedAt)-Y})}function n8($,J={}){let Z;try{Z=b2.readdirSync($).filter((U)=>jV($,U))}catch(U){if(Q9(U))return[];throw Error(`Failed to list async runs in '${$}': ${D2(U)}`,{cause:U instanceof Error?U:void 0})}let Q=J.states?new Set(J.states):void 0,X=[],Y,H=(U)=>{if(!Y)Y=g3();return Y.get(U)};for(let U of Z){let G=R0.join($,U),V=(J.reconcile===!1?void 0:C0(G,{resultsDir:J.resultsDir,kill:J.kill,now:J.now}))?.status??j1(G);if(!V)continue;if(Q&&!Q.has(V.state))continue;if(J.sessionId&&V.sessionId!==J.sessionId)continue;let B=[],K;try{if(K=H(V.runId||R0.basename(G)),K)R2(K,{resultsDir:J.resultsDir,kill:J.kill,now:J.now})}catch(A){B.push(`Nested status unavailable: ${D2(A)}`)}let W=zV(G,V,B,K);X.push(W)}let j=GV(X);return J.limit!==void 0?j.slice(0,J.limit):j}function S7($){let J=[];if($.currentTool&&$.currentToolStartedAt!==void 0)J.push(`tool ${$.currentTool} ${M1(Math.max(0,Date.now()-$.currentToolStartedAt))}`);else if($.currentTool)J.push(`tool ${$.currentTool}`);if($.currentPath)J.push(H0($.currentPath));if($.turnCount!==void 0)J.push(`${$.turnCount} turns`);if($.turnBudgetExceeded&&$.turnBudget)J.push(`turn budget exceeded ${$.turnBudget.turnCount}/${$.turnBudget.maxTurns}+${$.turnBudget.graceTurns}`);else if($.wrapUpRequested&&$.turnBudget)J.push(`wrap-up requested ${$.turnBudget.turnCount}/${$.turnBudget.maxTurns}`);else if($.turnBudget)J.push(`turn budget ${$.turnBudget.turnCount}/${$.turnBudget.maxTurns}+${$.turnBudget.graceTurns}`);if($.toolCount!==void 0)J.push(`${$.toolCount} tools`);if($.steerCount!==void 0)J.push(`${$.steerCount} steers`);if(typeof $.lastSteerAt==="number"&&Number.isFinite($.lastSteerAt))J.push(`last steer ${new Date($.lastSteerAt).toISOString()}`);let Z=l0($.lastActivityAt,$.activityState);return Z||J.length?[Z,...J].filter(Boolean).join(" | "):void 0}function BV($){let J=$.label?`${$.label} (${$.agent})`:$.agent,Z=$.phase?`[${$.phase}] `:"",Q=[`${$.index+1}. ${Z}${J}`,$.status],X=S7($);if(X)Q.push(X);let Y=g1($.model,$.thinking);if(Y)Q.push(Y);if($.durationMs!==void 0)Q.push(M1($.durationMs));if($.tokens)Q.push(`${XJ($.tokens.total)} tok`);return Q.join(" | ")}function w2($){if(!$.outputFile)return;return R0.isAbsolute($.outputFile)?$.outputFile:R0.join($.asyncDir,$.outputFile)}function I2($){let J=$.steps.length||1,Z=$.chainStepCount??J,Q=s1($.parallelGroups,$.steps.length,Z),X=$.currentStep!==void 0?Q.find((Y)=>$.currentStep>=Y.start&&$.currentStep<Y.start+Y.count):void 0;if(X){let Y=$.steps.slice(X.start,X.start+X.count),H=J9(Y,X.count,{showRunning:$.state==="running"});if($.mode==="parallel")return H;return`step ${X.stepIndex+1}/${Z} · parallel group: ${H}`}if($.mode==="parallel")return J9($.steps,J,{showRunning:$.state==="running"});if($.mode==="chain"&&$.currentStep!==void 0&&Q.length>0)return`step ${o8($.currentStep,Z,Q)+1}/${Z}`;return $.currentStep!==void 0?`step ${$.currentStep+1}/${J}`:`steps ${J}`}function KV($){let J=I2($),Z=$.cwd?H0($.cwd):H0($.asyncDir),Q=S7($),X=$.pendingAppends?` | ${$.pendingAppends} pending append${$.pendingAppends===1?"":"s"}`:"";return`${$.id} | ${$.state}${Q?` | ${Q}`:""} | ${$.mode} | ${J}${X} | ${Z}`}function C7($,J="Active async runs"){if($.length===0)return`No ${J.toLowerCase()}.`;let Z=[`${J}: ${$.length}`,""];for(let Q of $){Z.push(`- ${KV(Q)}`);for(let j of Q.steps)Z.push(` ${BV(j)}`),Z.push(...E0(j.children,{indent:" ",maxLines:12}));let X=new Set(Q.steps.flatMap((j)=>j.children?.map((U)=>U.id)??[])),Y=Q.nestedChildren?.filter((j)=>!X.has(j.id))??[];if(Z.push(...E0(Y,{indent:" ",maxLines:12})),Q.error)Z.push(` Error: ${Q.error}`);for(let j of Q.nestedWarnings??[])Z.push(` Warning: ${j}`);let H=w2(Q);if(H)Z.push(` output: ${H0(H)}`);if(Q.sessionFile)Z.push(` session: ${H0(Q.sessionFile)}`);Z.push("")}return Z.join(`
|
|
200
|
-
`).trimEnd()}import*as e$ from"node:fs";import*as _0 from"node:path";var R7=80,WV=500,_V=262144;function Y9($){if($===void 0)return R7;if(!Number.isFinite($))return R7;return Math.max(1,Math.min(WV,Math.trunc($)))}function y7($){let J=new Set,Z=[];for(let Q of $){if(!Q||J.has(Q))continue;J.add(Q),Z.push(Q)}return Z}function AV($,J){if(!J)return;return _0.resolve($,J)}function f7($,J){let Z=_0.resolve($),Q=_0.resolve(J);return Q===Z||Q.startsWith(`${Z}${_0.sep}`)}function p8($){return $ instanceof Error?$.message:String($)}function D7($){return typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT"}function qV($,J){let Z;try{Z=e$.statSync($)}catch(X){if(D7(X))return{path:$,lines:[],truncated:!1};return{path:$,lines:[],truncated:!1,error:p8(X)}}if(Z.size===0)return{path:$,lines:[],truncated:!1};let Q;try{let X=Math.min(Z.size,_V),Y=Z.size-X,H=Buffer.alloc(X);Q=e$.openSync($,"r");let j=e$.readSync(Q,H,0,X,Y),G=H.subarray(0,j).toString("utf-8").split(/\r?\n/);if(Y>0&&G.length>0)G=G.slice(1);if(G.at(-1)==="")G=G.slice(0,-1);return{path:$,lines:G.slice(-J),truncated:Y>0||G.length>J}}catch(X){return{path:$,lines:[],truncated:!1,error:p8(X)}}finally{if(Q!==void 0)e$.closeSync(Q)}}function b7($,J,Z,Q){if(Z.length===0)return{path:$,lines:[],truncated:!1,error:`Refusing to read ${Q} transcript path without a trusted root: ${$}`};let X=_0.resolve($);if(!Z.some((U)=>f7(U,X)))return{path:$,lines:[],truncated:!1,error:`Refusing to read ${Q} transcript path outside trusted roots: ${$}`};let Y;try{Y=e$.lstatSync(X)}catch(U){if(D7(U))return{path:$,lines:[],truncated:!1};return{path:$,lines:[],truncated:!1,error:p8(U)}}if(Y.isSymbolicLink())return{path:$,lines:[],truncated:!1,error:`Refusing to read symlink ${Q} transcript path: ${$}`};if(!Y.isFile())return{path:$,lines:[],truncated:!1,error:`Refusing to read non-file ${Q} transcript path: ${$}`};let H,j;try{H=e$.realpathSync(X),j=Z.filter((U)=>e$.existsSync(U)).map((U)=>e$.realpathSync(U))}catch(U){return{path:$,lines:[],truncated:!1,error:p8(U)}}if(!j.some((U)=>f7(U,H)))return{path:$,lines:[],truncated:!1,error:`Refusing to read ${Q} transcript path outside trusted roots: ${$}`};return qV(X,J)}function X9($,J=240){let Z;if(typeof $==="string")Z=$;else Z=JSON.stringify($);return Z.length>J?`${Z.slice(0,J)}…`:Z}function OV($){if(typeof $==="string")return $;if(!Array.isArray($))return"";return $.map((J)=>{if(!J||typeof J!=="object")return"";let Z=J;if(typeof Z.text==="string")return Z.text;if(Z.type==="toolCall"||Z.type==="tool_call")return`[tool: ${typeof Z.name==="string"?Z.name:typeof Z.toolName==="string"?Z.toolName:"tool"}${Z.args===void 0?"":` ${X9(Z.args)}`}]`;if(Z.type==="toolResult"||Z.type==="tool_result")return`[tool result${Z.result===void 0?"":`: ${X9(Z.result)}`}]`;if(Z.content!==void 0)return X9(Z.content);return""}).filter(Boolean).join(`
|
|
201
|
-
`)}function FV($){if(!$||typeof $!=="object")return;let J=$,Z=J.message&&typeof J.message==="object"?J.message:J,Q=typeof Z.role==="string"?Z.role:void 0;if(!Q)return;let X=OV(Z.content).trim();if(!X)return;return`${Q}: ${X}`}function w7($,J,Z){let Q=b7($,Math.max(J*4,J),Z,"session"),X=[];if(Q.error)X.push(`Session read failed for ${$}: ${Q.error}`);let Y=[],H=0;for(let j of Q.lines){if(!j.trim())continue;try{let U=JSON.parse(j),G=FV(U);if(G)Y.push(G)}catch{H++}}if(H>0)X.push(`Skipped ${H} malformed session tail line${H===1?"":"s"}.`);return{lines:Y.slice(-J),warnings:X}}function i8($){let J=[];if($.currentTool&&$.currentToolStartedAt!==void 0)J.push(`tool ${$.currentTool} ${M1(Math.max(0,Date.now()-$.currentToolStartedAt))}`);else if($.currentTool)J.push(`tool ${$.currentTool}`);if($.currentPath)J.push(H0($.currentPath));if($.turnCount!==void 0)J.push(`${$.turnCount} turns`);if($.toolCount!==void 0)J.push(`${$.toolCount} tools`);if($.tokens?.total)J.push(`${XJ($.tokens.total)} tok`);let Z=l0($.lastActivityAt,$.activityState);return Z||J.length?[Z,...J].filter(Boolean).join(" | "):void 0}function LV($){if($.mode==="single"&&$.currentAgent)return $.currentAgent;return $.mode}function MV($){if($.length===0)return[];let J=["Foreground runs:"],Z=[...$].sort((Q,X)=>X.updatedAt-Q.updatedAt);for(let Q of Z){let X=i8({activityState:Q.currentActivityState,lastActivityAt:Q.lastActivityAt,currentTool:Q.currentTool,currentToolStartedAt:Q.currentToolStartedAt,currentPath:Q.currentPath,turnCount:Q.turnCount,toolCount:Q.toolCount,...Q.tokens!==void 0?{tokens:{total:Q.tokens}}:{}}),Y=Q.currentAgent?` | ${Q.currentAgent}${Q.currentIndex!==void 0?` #${Q.currentIndex}`:""}`:"";J.push(`- ${Q.runId} | running | ${LV(Q)}${Y}${X?` | ${X}`:""}`),J.push(` status: subagent({ action: "status", id: "${Q.runId}" })`),J.push(" transcript: live in the expanded foreground result; persisted session transcript appears after completion when sessions are enabled."),J.push(...E0(Q.nestedChildren,{indent:" ",commandHints:!0,maxLines:12}))}return J}function NV($){if($.length===0)return[];let J=["Async runs:"];for(let Z of $){let Q=I2(Z),X=i8(Z),Y=Z.cwd?H0(Z.cwd):H0(Z.asyncDir),H=Z.pendingAppends?` | ${Z.pendingAppends} pending append${Z.pendingAppends===1?"":"s"}`:"";J.push(`- ${Z.id} | ${Z.state}${X?` | ${X}`:""} | ${Z.mode} | ${Q}${H} | ${Y}`),J.push(` status: subagent({ action: "status", id: "${Z.id}" })`),J.push(` transcript: subagent({ action: "status", id: "${Z.id}", view: "transcript" })`);for(let z of Z.steps){let V=z.label?`${z.label} (${z.agent})`:z.agent,B=z.phase?`[${z.phase}] `:"",K=i8(z),W=g1(z.model,z.thinking),A=[`${z.index}. ${B}${V}`,z.status,K,W].filter(Boolean);J.push(` ${A.join(" | ")}`);let F=_0.join(Z.asyncDir,`output-${z.index}.log`);if(e$.existsSync(F))J.push(` output: ${H0(F)}`);if(z.sessionFile)J.push(` session: ${H0(z.sessionFile)}`);if(z.status==="running"||z.recentOutput?.length||e$.existsSync(F))J.push(` transcript: subagent({ action: "status", id: "${Z.id}", index: ${z.index}, view: "transcript" })`);J.push(...E0(z.children,{indent:" ",commandHints:!0,maxLines:12}))}let j=new Set(Z.steps.flatMap((z)=>z.children?.map((V)=>V.id)??[])),U=Z.nestedChildren?.filter((z)=>!j.has(z.id))??[];if(J.push(...E0(U,{indent:" ",commandHints:!0,maxLines:12})),Z.error)J.push(` error: ${Z.error}`);for(let z of Z.nestedWarnings??[])J.push(` warning: ${z}`);let G=w2(Z);if(G)J.push(` output: ${H0(G)}`);if(Z.sessionFile)J.push(` session: ${H0(Z.sessionFile)}`)}return J}function I7($,J={}){if(J.childSafe)return{content:[{type:"text",text:'Child-safe subagent fleet view is unavailable without an explicit run id. Use subagent({ action: "status", id: "..." }) for the delegated run you can see.'}],isError:!0,details:{mode:"management",results:[]}};let Z;try{Z=n8(J.asyncDirRoot??Q0,{states:["queued","running"],sessionId:J.state?.currentSessionId??void 0,resultsDir:J.resultsDir??h$,kill:J.kill,now:J.now})}catch(U){return{content:[{type:"text",text:U instanceof Error?U.message:String(U)}],isError:!0,details:{mode:"management",results:[]}}}let Q=J.state?[...J.state.foregroundControls.values()]:[],X=Q.length+Z.length;if(X===0)return{content:[{type:"text",text:'No active subagent fleet. Background runs that already finished are available through completion notifications or subagent({ action: "status", id: "..." }).'}],details:{mode:"management",results:[]}};let Y=[`Subagent fleet: ${X} active`,""],H=MV(Q);if(H.length)Y.push(...H,"");let j=NV(Z);if(j.length)Y.push(...j,"");return Y.push("Commands:"),Y.push(' Refresh fleet: subagent({ action: "status", view: "fleet" })'),Y.push(' Tail run transcript: subagent({ action: "status", id: "<run-id>", view: "transcript" })'),Y.push(' Tail child transcript: subagent({ action: "status", id: "<run-id>", index: 0, view: "transcript" })'),{content:[{type:"text",text:Y.join(`
|
|
202
|
-
`).trimEnd()}],details:{mode:"management",results:[]}}}function EV($,J){if($===void 0)return;if(!Number.isInteger($))throw Error("Transcript index must be an integer.");if($<0||$>=J.length)throw Error(`Transcript index ${$} is out of range for ${J.length} child step${J.length===1?"":"s"}.`);return $}function TV($,J){let Z=$.steps??[],Q=EV(J.index,Z);if(Q===void 0){if($.state==="running"&&typeof $.currentStep==="number"&&$.currentStep>=0&&$.currentStep<Z.length)Q=$.currentStep;else if(Z.length===1)Q=0}let X=Q!==void 0?Z[Q]:void 0,Y=J.index===void 0&&Z.length>1?`Tip: pass index to inspect a specific child transcript (${Z.map((H,j)=>`${j}=${H.agent}`).join(", ")}).`:void 0;return{index:Q,step:X,hint:Y}}function SV($,J,Z){if(J===void 0||!Z)return;let Q=g1(Z.model,Z.thinking);return[`${$==="parallel"?"Agent":"Step"}: ${J} (${Z.agent})`,Z.status,i8(Z),Q,Z.error?`error: ${Z.error}`:void 0].filter(Boolean).join(" | ")}function H9($,J){let Z=[];for(let Q of J.outputPaths)Z.push(`Output: ${Q}`);if(J.sessionFile)Z.push(`Session: ${J.sessionFile}`);if(J.eventsPath)Z.push(`Events: ${J.eventsPath}`);if(J.logPath)Z.push(`Log: ${J.logPath}`);if(J.resultPath)Z.push(`Result: ${J.resultPath}`);if(!Z.length)return;$.push("Artifacts:");for(let Q of Z)$.push(` ${Q}`)}function r8($,J,Z,Q){if($.push(`${J}${Q?" (tail truncated)":""}:`),Z.length===0){$.push(" (no transcript lines available yet)");return}for(let X of Z)$.push(` ${X}`)}function j9($,J,Z={}){let Q=Y9(Z.lines),X=TV($,Z),Y=X.index!==void 0?_0.join(J,`output-${X.index}.log`):void 0,H=AV(J,$.outputFile),j=_0.join(J,`subagent-log-${$.runId}.md`),U=X.index!==void 0?y7([Y,H&&Y&&_0.resolve(H)===_0.resolve(Y)?H:void 0]):y7([H]),G=X.index!==void 0?X.step?.sessionFile:$.sessionFile,z=_0.join(J,"events.jsonl"),V=[`Run: ${$.runId}`,`State: ${$.state}`,`Mode: ${$.mode}`,SV($.mode,X.index,X.step),X.hint].filter((F)=>Boolean(F));H9(V,{outputPaths:U,sessionFile:G,eventsPath:e$.existsSync(z)?z:void 0,logPath:e$.existsSync(j)?j:void 0});let B=[],K=[],W="Transcript tail",A=!1;for(let F of U){let _=b7(F,Q,[J],"output");if(_.error)B.push(`Output read failed for ${_.path}: ${_.error}`);if(_.lines.length===0)continue;K=_.lines,W=`Transcript tail from ${_.path}`,A=_.truncated;break}if(K.length===0&&X.step?.recentOutput?.length)K=X.step.recentOutput.slice(-Q),W="Recent output from status.json";if(K.length===0&&G){let F=w7(G,Q,Z.sessionRoots??[]);if(K=F.lines,B.push(...F.warnings),K.length>0)W=`Session transcript tail from ${G}`}if(B.length){V.push("Warnings:");for(let F of B)V.push(` ${F}`)}return r8(V,W,K,A),V.join(`
|
|
203
|
-
`)}function k7($,J={}){if($.asyncDir){let Y=j1($.asyncDir);if(Y)return j9(Y,$.asyncDir,J)}let Z=Y9(J.lines),Q=[`Nested run: ${$.id}`,`State: ${$.state}`,$.mode?`Mode: ${$.mode}`:void 0,$.agent?`Agent: ${$.agent}`:$.agents?.length?`Agents: ${$.agents.join(", ")}`:void 0].filter((Y)=>Boolean(Y));if(H9(Q,{outputPaths:[],sessionFile:$.sessionFile}),!$.sessionFile)return r8(Q,"Transcript tail",[],!1),Q.join(`
|
|
204
|
-
`);let X=w7($.sessionFile,Z,J.sessionRoots??[]);if(X.warnings.length){Q.push("Warnings:");for(let Y of X.warnings)Q.push(` ${Y}`)}return r8(Q,`Session transcript tail from ${$.sessionFile}`,X.lines,!1),Q.join(`
|
|
205
|
-
`)}function P7($,J,Z={}){let Q=Y9(Z.lines),X=$.runId??$.id??_0.basename(J,".json"),Y=Array.isArray($.results)?$.results:$.agent?[{agent:$.agent,output:$.output,summary:$.summary,sessionFile:$.sessionFile,state:$.state,success:$.success,exitCode:$.exitCode}]:[],H=Z.index;if(H!==void 0&&!Number.isInteger(H))throw Error("Transcript index must be an integer.");if(H===void 0&&Y.length===1)H=0;if(H!==void 0&&(H<0||H>=Y.length))throw Error(`Transcript index ${H} is out of range for ${Y.length} result child${Y.length===1?"":"ren"}.`);let j=H!==void 0?Y[H]:void 0,U=H!==void 0?j?.output??j?.summary??(Y.length===1?$.output??$.summary:void 0)??"":$.output??$.summary??"",G=U.split(/\r?\n/).slice(-Q),z=j?.sessionFile??$.sessionFile,V=[`Run: ${X}`,`State: ${$.state??($.success?"complete":"failed")}`,H!==void 0&&j?`Child: ${H} (${j.agent??"subagent"})`:void 0,H===void 0&&Y.length>1?`Tip: pass index to inspect a specific child transcript (${Y.map((B,K)=>`${K}=${B.agent??"subagent"}`).join(", ")}).`:void 0].filter((B)=>Boolean(B));return H9(V,{outputPaths:[],sessionFile:z,resultPath:J}),r8(V,"Result transcript tail",G.filter((B)=>B.trim()),U.split(/\r?\n/).length>Q),V.join(`
|
|
206
|
-
`)}function U9($){return typeof $==="string"&&X1.existsSync($)}function x7($,J,Z){let Q=J.map((H,j)=>({child:H,index:j})).filter(({child:H})=>typeof H.agent==="string");if(!$||Q.length===0)return"Resume: unavailable; no child session file was persisted.";let X=Q[0]?.child.sessionFile??Z;if(J.length===1&&Q.length===1&&U9(X))return`Revive: subagent({ action: "resume", id: "${$}", message: "..." })`;let Y=Q.find(({child:H})=>U9(H.sessionFile));if(Y)return`Revive child: subagent({ action: "resume", id: "${$}", index: ${Y.index}, message: "..." })`;return"Resume: unavailable; no child session file was persisted."}function CV($,J){let Z=$.steps??[];if($.mode==="parallel")return`Agent ${J+1}/${Z.length||1}`;if($.mode==="chain"){let Q=$.chainStepCount??(Z.length||1),X=s1($.parallelGroups,Z.length,Q),Y=X.find((H)=>J>=H.start&&J<H.start+H.count);if(Y)return`Step ${Y.stepIndex+1}/${Q} Agent ${J-Y.start+1}/${Y.count}`;return`Step ${o8(J,Q,X)+1}/${Q}`}return`Step ${J+1}`}function RV($){if($.agent)return $.agent;if($.agents?.length)return $.agents.join(", ");return $.id}function v7($){let J=[];if($.steerCount!==void 0)J.push(`${$.steerCount} steer${$.steerCount===1?"":"s"}`);if(typeof $.lastSteerAt==="number"&&Number.isFinite($.lastSteerAt))J.push(`last ${new Date($.lastSteerAt).toISOString()}`);return J.length?J.join(", "):void 0}function h7($){let J=$.artifactPaths?.outputPath;if(J&&X1.existsSync(J))try{let Z=X1.readFileSync(J,"utf-8").trim();if(Z)return Z}catch{}return $.finalOutput??""}function yV($){let J=[`Run: ${$.runId}`,"State: remembered foreground",`Mode: ${$.mode}`,`Updated: ${new Date($.updatedAt).toISOString()}`,`Cwd: ${$.cwd}`];for(let Q of $.children){let X=h7(Q).trim().split(/\r?\n/).find((H)=>H.trim()),Y=[`${Q.index+1}. ${Q.agent} ${Q.status}`,Q.exitCode!==void 0?`exit ${Q.exitCode}`:void 0,Q.detachedReason?`detached: ${Q.detachedReason}`:void 0,X?`output: ${X.slice(0,160)}`:void 0].filter(Boolean);if(J.push(Y.join(", ")),Q.sessionFile)J.push(` Session: ${Q.sessionFile}`);if(Q.transcriptPath)J.push(` Transcript: ${Q.transcriptPath}`);if(Q.artifactPaths?.outputPath)J.push(` Output: ${Q.artifactPaths.outputPath}`);if(Q.transcriptError)J.push(` Transcript warning: ${Q.transcriptError}`)}if(J.push("",`Status: subagent({ action: "status", id: "${$.runId}" })`),$.children.length===1)J.push(`Transcript: subagent({ action: "status", id: "${$.runId}", view: "transcript" })`);else J.push(`Transcript: subagent({ action: "status", id: "${$.runId}", index: 0, view: "transcript" })`);let Z=$.children.find((Q)=>Q.status!=="detached"&&U9(Q.sessionFile));if(Z)J.push($.children.length===1?`Revive: subagent({ action: "resume", id: "${$.runId}", message: "..." })`:`Revive child: subagent({ action: "resume", id: "${$.runId}", index: ${Z.index}, message: "..." })`);else if($.children.some((Q)=>Q.status==="detached"))J.push("Recovery: child detached for intercom coordination; status will show recovered output after the child exits when DM can observe it.");else J.push("Resume: unavailable; no child session file was persisted.");return J.join(`
|
|
207
|
-
`)}function fV($,J){let Z=J.index;if(Z!==void 0&&!Number.isInteger(Z))throw Error("Transcript index must be an integer.");if(Z===void 0&&$.children.length===1)Z=0;if(Z===void 0)return`Transcript view requires index for foreground run '${$.runId}' with ${$.children.length} children.`;if(Z<0||Z>=$.children.length)throw Error(`Transcript index ${Z} is out of range for ${$.children.length} foreground children.`);let Q=$.children[Z],X=Math.max(1,Math.min(J.lines??80,1000)),Y=h7(Q).split(/\r?\n/).filter((j)=>j.trim()).slice(-X),H=[`Run: ${$.runId}`,`State: ${Q.status}`,`Child: ${Z} (${Q.agent})`,Q.sessionFile?`Session: ${Q.sessionFile}`:void 0,Q.transcriptPath?`Transcript: ${Q.transcriptPath}`:void 0,Q.artifactPaths?.outputPath?`Output: ${Q.artifactPaths.outputPath}`:void 0].filter((j)=>Boolean(j));if(H.push("Result transcript tail:"),Y.length===0)H.push(" (no recovered final output available yet)");else for(let j of Y)H.push(` ${j}`);return H.join(`
|
|
208
|
-
`)}function DV($,J){let Z=[`Nested run: ${J.id}`,`Root: ${$}`,`Parent: ${J.parentRunId}${J.parentStepIndex!==void 0?` step ${J.parentStepIndex+1}`:""}`,`State: ${J.state}`,J.activityState||J.lastActivityAt?`Activity: ${l0(J.lastActivityAt,J.activityState)}`:void 0,J.mode?`Mode: ${J.mode}`:void 0,`Agent: ${RV(J)}`,J.currentStep!==void 0?`Progress: step ${J.currentStep+1}/${J.chainStepCount??J.steps?.length??1}`:void 0,J.turnBudget?`Turn budget: ${J.turnBudget.turnCount}/${J.turnBudget.maxTurns}+${J.turnBudget.graceTurns} (${J.turnBudget.outcome})`:void 0,J.asyncDir?`Dir: ${J.asyncDir}`:void 0,J.sessionFile?`Session: ${J.sessionFile}`:void 0,J.error?`Error: ${J.error}`:void 0].filter((Q)=>Boolean(Q));if(J.path.length)Z.push(`Path: ${J.path.map((Q)=>`${Q.runId}${Q.stepIndex!==void 0?`:${Q.stepIndex+1}`:""}${Q.agent?`:${Q.agent}`:""}`).join(" > ")} > ${J.id}`);if(J.steps?.length){Z.push("Steps:");for(let[Q,X]of J.steps.entries()){let Y=X.status==="running"?l0(X.lastActivityAt,X.activityState):void 0,H=X.turnBudget?`, turn budget: ${X.turnBudget.turnCount}/${X.turnBudget.maxTurns}+${X.turnBudget.graceTurns} (${X.turnBudget.outcome})`:"";Z.push(` ${Q+1}. ${X.agent} ${X.status}${Y?`, ${Y}`:""}${H}${X.error?`, error: ${X.error}`:""}`),Z.push(...E0(X.children,{indent:" ",commandHints:!0}))}}return Z.push(...E0(J.children,{indent:" ",commandHints:!0})),Z.push("Commands:",` Status: subagent({ action: "status", id: "${J.id}" })`,` Interrupt: subagent({ action: "interrupt", id: "${J.id}" })`,` Resume: subagent({ action: "resume", id: "${J.id}", message: "..." })`,` Steer: subagent({ action: "steer", id: "${J.id}", message: "..." })`,` Root status: subagent({ action: "status", id: "${$}" })`),Z.join(`
|
|
209
|
-
`)}function a8($,J={}){let Z=J.asyncDirRoot??Q0,Q=J.resultsDir??h$,X=J.state?.currentSessionId??void 0;if($.view&&$.view!=="fleet"&&$.view!=="transcript")return{content:[{type:"text",text:`Unknown status view: ${$.view}. Valid: fleet, transcript.`}],isError:!0,details:{mode:"single",results:[]}};if($.view==="fleet")return I7($,{asyncDirRoot:Z,resultsDir:Q,kill:J.kill,now:J.now,state:J.state,childSafe:Boolean(J.nested)});if(!$.id&&!$.runId&&!$.dir){if(J.nested)return{content:[{type:"text",text:"Child-safe subagent status requires an id when no foreground run is active."}],isError:!0,details:{mode:"single",results:[]}};try{let G=n8(Z,{states:["queued","running"],sessionId:X,resultsDir:Q,kill:J.kill,now:J.now});if($.view==="transcript"){if(G.length===1)return a8({...$,id:G[0].id},J);return{content:[{type:"text",text:G.length===0?"No active async run transcript is available.":`Transcript view requires an id when ${G.length} active async runs exist. Use subagent({ action: "status", view: "fleet" }) to choose one.`}],isError:!0,details:{mode:"single",results:[]}}}return{content:[{type:"text",text:C7(G)}],details:{mode:"single",results:[]}}}catch(G){return{content:[{type:"text",text:G instanceof Error?G.message:String(G)}],isError:!0,details:{mode:"single",results:[]}}}}let Y;try{let G=$.id??$.runId;if(!$.dir&&G){let z=O1(G,{asyncDirRoot:Z,resultsDir:Q,state:J.state,nested:J.nested});if(z?.kind==="foreground"){let V=J.state?.foregroundRuns?.get(z.id);if(V)try{return{content:[{type:"text",text:$.view==="transcript"?fV(V,{index:$.index,lines:$.lines}):yV(V)}],details:{mode:"single",results:[]}}}catch(B){return{content:[{type:"text",text:B instanceof Error?B.message:String(B)}],isError:!0,details:{mode:"single",results:[]}}}}if(z?.kind==="nested"){R2(z.match.route,{resultsDir:Q,kill:J.kill,now:J.now});let V=O1(G,{asyncDirRoot:Z,resultsDir:Q,state:J.state,nested:J.nested}),B=V?.kind==="nested"?V:z;if($.view==="transcript")try{return{content:[{type:"text",text:k7(B.match.run,{index:$.index,lines:$.lines,sessionRoots:J.sessionRoots})}],details:{mode:"single",results:[]}}}catch(K){return{content:[{type:"text",text:K instanceof Error?K.message:String(K)}],isError:!0,details:{mode:"single",results:[]}}}return{content:[{type:"text",text:DV(B.match.rootRunId,B.match.run)}],details:{mode:"single",results:[]}}}if(z?.kind==="async")Y=z.location;else Y={asyncDir:null,resultPath:null,resolvedId:G}}else Y=y2($,Z,Q)}catch(G){return{content:[{type:"text",text:G instanceof Error?G.message:String(G)}],isError:!0,details:{mode:"single",results:[]}}}let{asyncDir:H,resultPath:j,resolvedId:U}=Y;if(!H&&!j)return{content:[{type:"text",text:"Async run not found. Provide id or dir."}],isError:!0,details:{mode:"single",results:[]}};if(H){let G;try{G=C0(H,{resultsDir:Q,kill:J.kill,now:J.now})}catch(W){return{content:[{type:"text",text:W instanceof Error?W.message:String(W)}],isError:!0,details:{mode:"single",results:[]}}}let z=G.status,V=z?.runId??U??"unknown",B=s8.join(H,`subagent-log-${V}.md`),K=s8.join(H,"events.jsonl");if(z){if($.view==="transcript"){if(X&&z.sessionId!==X)return{content:[{type:"text",text:"Transcript view is only available for async runs owned by the current session."}],isError:!0,details:{mode:"single",results:[]}};try{return{content:[{type:"text",text:j9(z,H,{index:$.index,lines:$.lines,sessionRoots:J.sessionRoots})}],details:{mode:"single",results:[]}}}catch(w){return{content:[{type:"text",text:w instanceof Error?w.message:String(w)}],isError:!0,details:{mode:"single",results:[]}}}}let W=[],A;try{let w=v6(z.runId);if(w)R2(w,{resultsDir:Q,kill:J.kill,now:J.now});W=m3(z.runId)?.children??[],D1(z.runId,z.steps,W)}catch(w){A=`Nested status unavailable: ${w instanceof Error?w.message:String(w)}`}let F=w2({asyncDir:H,outputFile:z.outputFile}),_=I2({mode:z.mode,state:z.state,currentStep:z.currentStep,chainStepCount:z.chainStepCount,parallelGroups:z.parallelGroups,steps:(z.steps??[]).map((w,q)=>({index:q,agent:w.agent,status:w.status}))}),f=new Date(z.startedAt).toISOString(),O=z.lastUpdate?new Date(z.lastUpdate).toISOString():"n/a",y=z.state==="running"?l0(z.lastActivityAt,z.activityState):void 0,C=v7(z),T=[`Run: ${z.runId}`,`State: ${z.state}`,z.error?`Error: ${z.error}`:void 0,y?`Activity: ${y}`:void 0,C?`Steering: ${C}`:void 0,`Mode: ${z.mode}`,`Progress: ${_}`,z.pendingAppends?`Pending appends: ${z.pendingAppends}`:void 0,`Started: ${f}`,`Updated: ${O}`,z.turnBudget?`Turn budget: ${z.turnBudget.turnCount}/${z.turnBudget.maxTurns}+${z.turnBudget.graceTurns} (${z.turnBudget.outcome})`:void 0,`Dir: ${H}`,F?`Output: ${F}`:void 0,G.message?`Diagnosis: ${G.message}`:void 0,G.resultPath&&X1.existsSync(G.resultPath)?`Result: ${G.resultPath}`:void 0].filter((w)=>Boolean(w));for(let[w,q]of(z.steps??[]).entries()){let S=q.status==="running"?l0(q.lastActivityAt,q.activityState):void 0,M=g1(q.model,q.thinking),N=M?` (${M})`:"",E=v7(q),n=E?`, steering: ${E}`:"",L=q.error?`, error: ${q.error}`:"",k=q.acceptance?.status?`, acceptance: ${q.acceptance.status}`:"",o=q.turnBudget?`, turn budget: ${q.turnBudget.turnCount}/${q.turnBudget.maxTurns}+${q.turnBudget.graceTurns} (${q.turnBudget.outcome})`:"",g=q.label?`${q.label} (${q.agent})`:q.agent,I=q.phase?`[${q.phase}] `:"";T.push(`${CV(z,w)}: ${I}${g} ${q.status}${N}${S?`, ${S}`:""}${n}${k}${o}${L}`),T.push(...E0(q.children,{indent:" ",commandHints:!0,maxLines:20}));let a=s8.join(H,`output-${w}.log`);if(a!==F&&X1.existsSync(a))T.push(` Output: ${a}`);if(q.status==="running")T.push(` Intercom target: ${u$(z.runId,q.agent,w)} (if registered)`),T.push(` Steer: subagent({ action: "steer", id: "${z.runId}", index: ${w}, message: "..." })`)}let h=new Set((z.steps??[]).flatMap((w)=>w.children?.map((q)=>q.id)??[])),b=W.filter((w)=>!h.has(w.id));if(T.push(...E0(b,{indent:"",commandHints:!0,maxLines:20})),A)T.push(`Warning: ${A}`);if(z.sessionFile)T.push(`Session: ${z.sessionFile}`);if(z.state==="running")T.push(`Steer running child: subagent({ action: "steer", id: "${z.runId}", message: "..." })`);if(z.state!=="running")T.push(x7(z.runId,z.steps??[],z.sessionFile));if(X1.existsSync(B))T.push(`Log: ${B}`);if(X1.existsSync(K))T.push(`Events: ${K}`);return{content:[{type:"text",text:T.join(`
|
|
210
|
-
`)}],details:{mode:"single",results:[]}}}}if(j)try{let G=X1.readFileSync(j,"utf-8"),z=JSON.parse(G);if($.view==="transcript")try{return{content:[{type:"text",text:P7(z,j,{index:$.index,lines:$.lines})}],details:{mode:"single",results:[]}}}catch(A){return{content:[{type:"text",text:A instanceof Error?A.message:String(A)}],isError:!0,details:{mode:"single",results:[]}}}let V=z.success?"complete":z.state==="paused"||z.exitCode===0?"paused":"failed",B=z.runId??z.id??U,K=[`Run: ${B}`,`State: ${V}`,`Result: ${j}`],W=Array.isArray(z.results)?z.results:z.agent?[{agent:z.agent,sessionFile:z.sessionFile}]:[];if(K.push(x7(B,W,z.sessionFile)),z.summary)K.push("",z.summary);return{content:[{type:"text",text:K.join(`
|
|
211
|
-
`)}],details:{mode:"single",results:[]}}}catch(G){return{content:[{type:"text",text:`Failed to read async result file: ${G instanceof Error?G.message:String(G)}`}],isError:!0,details:{mode:"single",results:[]}}}return{content:[{type:"text",text:"Status file not found."}],isError:!0,details:{mode:"single",results:[]}}}function g7($,J,Z){if(!(J===0&&Z))return $;return{...$,async:!0,clarify:!1}}var bV=new Set(["create","update","delete","eject","disable","enable","reset"]);function wV($,J){return J?T$.resolve($,J):$}function V9($,J){if(J)return $.foregroundControls.get(J);if($.lastForegroundControlId){let Q=$.foregroundControls.get($.lastForegroundControlId);if(Q)return Q}let Z;for(let Q of $.foregroundControls.values())if(!Z||Q.updatedAt>Z.updatedAt)Z=Q;return Z}function IV($){let J=[];if($.currentTool&&$.currentToolStartedAt)J.push(`tool ${$.currentTool} for ${Math.floor(Math.max(0,Date.now()-$.currentToolStartedAt)/1000)}s`);else if($.currentTool)J.push(`tool ${$.currentTool}`);if($.currentPath)J.push(`path ${$.currentPath}`);if($.turnCount!==void 0)J.push(`${$.turnCount} turns`);if($.tokens!==void 0)J.push(`${$.tokens} tokens`);if($.toolCount!==void 0)J.push(`${$.toolCount} tools`);if(!$.lastActivityAt){if($.currentActivityState==="needs_attention")return["needs attention",...J].join(" | ");if($.currentActivityState==="active_long_running")return["active but long-running",...J].join(" | ");return J.length?J.join(" | "):void 0}let Z=Math.floor(Math.max(0,Date.now()-$.lastActivityAt)/1000);if($.currentActivityState==="needs_attention")return[`no activity for ${Z}s`,...J].join(" | ");if($.currentActivityState==="active_long_running")return[`active but long-running; last activity ${Z}s ago`,...J].join(" | ");return[`active ${Z}s ago`,...J].join(" | ")}function P2($){if($.allowMutatingManagementActions!==!1)return;let J=SJ(),Z=J?CJ():void 0;return{routes:J?[J]:[],...Z?{descendantOf:{parentRunId:Z.parentRunId,...Z.parentStepIndex!==void 0?{parentStepIndex:Z.parentStepIndex}:{}}}:{}}}function kV($,J){let Z=J.config.defaultSessionDir?[T$.resolve(J.expandTilde(J.config.defaultSessionDir))]:[],Q=$.sessionManager.getSessionFile()??null;if(Q)Z.push(J.getSubagentSessionRoot(Q));return[...new Set(Z)]}function PV($){if($.requested<=0)return;if($.state.subagentSpawns?.sessionId!==$.sessionId)$.state.subagentSpawns={sessionId:$.sessionId,count:0};let J=w9($.config.maxSubagentSpawnsPerSession),Z=$.state.subagentSpawns.count;if(Z+$.requested>J)return{content:[{type:"text",text:`Subagent spawn limit reached for this session (${Z}/${J} used, ${$.requested} requested). Complete the work directly or start a new session.`}],isError:!0,details:{mode:$.mode,results:[]}};$.state.subagentSpawns.count=Z+$.requested;return}function xV($,J){if($.tasks)return $.tasks.length;if($.chain)return $.chain.reduce((Z,Q)=>{if(C$(Q))return Z+(Q.expand.maxItems??J.chain?.dynamicFanout?.maxItems??0);return Z+o2(Q).length},0);return $.agent?1:0}function m7($){let J;try{i1($)}catch(X){J=`Nested status unavailable: ${X instanceof Error?X.message:String(X)}`}let Z=IV($),Q=[`Run: ${$.runId}`,"State: running",`Mode: ${$.mode}`,$.currentAgent?`Current: ${$.currentAgent}${$.currentIndex!==void 0?` step ${$.currentIndex+1}`:""}`:void 0,Z?`Activity: ${Z}`:void 0].filter((X)=>Boolean(X));if(Q.push(...E0($.nestedChildren,{indent:"",commandHints:!0,maxLines:20})),J)Q.push(`Warning: ${J}`);return{content:[{type:"text",text:Q.join(`
|
|
212
|
-
`)}],details:{mode:"management",results:[]}}}function o7($){if(!$.foregroundRuns)return;while($.foregroundRuns.size>50){let J=[...$.foregroundRuns.values()].sort((Z,Q)=>Z.updatedAt-Q.updatedAt)[0];if(!J)break;$.foregroundRuns.delete(J.runId)}}function G9($,J){$.foregroundRuns??=new Map;let Z=$.foregroundRuns.get(J.runId),Q=Date.now();$.foregroundRuns.set(J.runId,{runId:J.runId,mode:J.mode,cwd:J.cwd,updatedAt:Q,children:J.results.map((X,Y)=>{let H={agent:X.agent,index:Y,status:u8({exitCode:X.exitCode,interrupted:X.interrupted,detached:X.detached}),updatedAt:Q,...X.exitCode!==void 0?{exitCode:X.exitCode}:{},...X.finalOutput?{finalOutput:X.finalOutput}:{},...X.sessionFile?{sessionFile:X.sessionFile}:{},...X.artifactPaths?{artifactPaths:X.artifactPaths}:{},...X.transcriptPath?{transcriptPath:X.transcriptPath}:{},...X.transcriptError?{transcriptError:X.transcriptError}:{},...X.detachedReason?{detachedReason:X.detachedReason}:{}},j=Z?.children[Y];return H.status==="detached"&&j&&j.status!=="detached"?j:H})}),o7($)}function B9($,J){$.foregroundRuns??=new Map;let Z=Date.now(),Q=$.foregroundRuns.get(J.runId);if(!Q)Q={runId:J.runId,mode:J.mode,cwd:J.cwd,updatedAt:Z,children:[]},$.foregroundRuns.set(J.runId,Q);Q.updatedAt=Z;let X=Q.children[J.index]??{agent:J.result.agent,index:J.index,status:"detached"};Q.children[J.index]={...X,agent:J.result.agent,index:J.index,status:u8({exitCode:J.result.exitCode,interrupted:J.result.interrupted,detached:!1}),updatedAt:Z,...J.result.exitCode!==void 0?{exitCode:J.result.exitCode}:{},...J.result.finalOutput?{finalOutput:J.result.finalOutput}:{},...J.result.sessionFile?{sessionFile:J.result.sessionFile}:{},...J.result.artifactPaths?{artifactPaths:J.result.artifactPaths}:{},...J.result.transcriptPath?{transcriptPath:J.result.transcriptPath}:{},...J.result.transcriptError?{transcriptError:J.result.transcriptError}:{},...J.result.detachedReason?{detachedReason:J.result.detachedReason}:{}},o7($)}function vV($,J){let Z=($.id??$.runId)?.trim();if(!Z||!J.foregroundRuns?.size)return;let Q=J.foregroundRuns.get(Z),X=Q?[Q]:[...J.foregroundRuns.values()].filter((G)=>G.runId.startsWith(Z));if(X.length===0)return;if(X.length>1)throw Error(`Ambiguous foreground run id prefix '${Z}' matched: ${X.map((G)=>G.runId).join(", ")}. Provide a longer id.`);let Y=X[0];if(Y.children.length>1&&$.index===void 0)throw Error(`Foreground run '${Y.runId}' has ${Y.children.length} children. Provide index to choose one.`);let H=$.index??0;if(!Number.isInteger(H))throw Error(`Foreground run '${Y.runId}' index must be an integer.`);if(H<0||H>=Y.children.length)throw Error(`Foreground run '${Y.runId}' has ${Y.children.length} children. Index ${H} is out of range.`);let j=Y.children[H];if(j.status==="detached")throw Error(`Foreground run '${Y.runId}' child ${H} is detached for intercom coordination and cannot be revived safely from the remembered foreground state. Reply to the supervisor request first; after the child exits, start a fresh follow-up if needed.`);if(!j.sessionFile)throw Error(`Foreground run '${Y.runId}' child ${H} does not have a persisted session file to resume from.`);if(T$.extname(j.sessionFile)!==".jsonl")throw Error(`Foreground run '${Y.runId}' child ${H} session file must be a .jsonl file: ${j.sessionFile}`);let U=T$.resolve(j.sessionFile);if(!n0.existsSync(U))throw Error(`Foreground run '${Y.runId}' child ${H} session file does not exist: ${j.sessionFile}`);return{runId:Y.runId,mode:Y.mode,state:"complete",agent:j.agent,index:H,intercomTarget:u$(Y.runId,j.agent,H),cwd:Y.cwd,sessionFile:U}}function hV($){return $ instanceof Error&&$.message.startsWith("Async run not found.")}function z9($){return $ instanceof Error&&/Ambiguous .*run id prefix/.test($.message)}function t8($,J){return $?.runId===J}function gV($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function c7($,J,Z){if(!($ instanceof Error)||!Z)return!1;return new RegExp(`\\b${J} run '${gV(Z)}'`,"i").test($.message)}function mV($,J,Z={}){let Q=($.id??$.runId)?.trim()??"",X,Y,H,j;try{let U=vV($,J);if(U)X={kind:"revive",source:"foreground",...U}}catch(U){Y=U}try{H={source:"async",...F7($,{},{requireSessionFile:Z.asyncRequireSessionFile})}}catch(U){j=U}if(X&&H){let U=t8(X,Q),G=t8(H,Q);if(U&&!G)return X;if(G&&!U)return H;throw Error(`Resume id '${Q}' is ambiguous between foreground run '${X.runId}' and async run '${H.runId}'. Provide a full run id.`)}if(X){if(c7(j,"async",Q))throw j;if(z9(j)&&!t8(X,Q))throw j;return X}if(H){if(c7(Y,"foreground",Q))throw Y;if(z9(Y)&&!t8(H,Q))throw Y;return H}if(Y&&!hV(j))throw Y;if(Y)throw Y;if(j)throw j;throw Error("Run not found. Provide id or runId.")}function cV($,J,Z){if(Z?.asyncDir)return{asyncId:Z.resolvedId??J??T$.basename(Z.asyncDir),asyncDir:Z.asyncDir};if(J){let X=$.asyncJobs.get(J);if(X)return{asyncId:X.asyncId,asyncDir:X.asyncDir}}let Q;for(let X of $.asyncJobs.values()){if(X.status!=="running")continue;if(!Q||(X.updatedAt??0)>Q.updatedAt)Q={asyncId:X.asyncId,asyncDir:X.asyncDir,updatedAt:X.updatedAt??0}}return Q?{asyncId:Q.asyncId,asyncDir:Q.asyncDir}:void 0}function uV($){if(!pJ($.controlConfig,$.event))return;let J=$.intercomBridge.active?u$($.event.runId,$.event.agent,$.event.index):void 0,Z={event:$.event,source:"foreground",childIntercomTarget:J,noticeText:$8($.event,J)};if($.controlConfig.notifyChannels.includes("event"))$.pi.events.emit(E9,Z);if($.event.type!=="active_long_running"&&$.controlConfig.notifyChannels.includes("intercom")&&$.intercomBridge.active&&$.intercomBridge.orchestratorTarget)$.pi.events.emit(T9,{...Z,to:$.intercomBridge.orchestratorTarget,message:S5($.event,J)})}function dV($,J,Z,Q){let X=cV($,J,Q);if(!X)return null;let Y=C0(X.asyncDir,{kill:Z}).status;if(!Y||Y.state!=="running"||typeof Y.pid!=="number")return{content:[{type:"text",text:`No running async run with an interrupt-capable pid was found for '${J??"current"}'.`}],isError:!0,details:{mode:"management",results:[]}};try{C2({asyncDir:X.asyncDir,pid:Y.pid,kill:Z,source:"interrupt-action"});let H=$.asyncJobs.get(X.asyncId);if(H)H.activityState=void 0,H.updatedAt=Date.now();return{content:[{type:"text",text:`Interrupt requested for async run ${X.asyncId}.`}],details:{mode:"management",results:[]}}}catch(H){let j=H instanceof Error?H.message:String(H);return{content:[{type:"text",text:`Failed to interrupt async run ${X.asyncId}: ${j}`}],isError:!0,details:{mode:"management",results:[]}}}}function u7($){if(!$.location.asyncDir)return{content:[{type:"text",text:`Async run '${$.runId}' has no live run directory to steer.`}],isError:!0,details:{mode:"management",results:[]}};let J=C0($.location.asyncDir,{kill:$.kill}).status;if(!J||J.state!=="running"&&J.state!=="queued")return{content:[{type:"text",text:`Async run '${$.runId}' is not running or queued and cannot be steered.`}],isError:!0,details:{mode:"management",results:[]}};let Z=J.steps??[];if($.index!==void 0){if($.index<0||$.index>=Z.length)return{content:[{type:"text",text:`Async run '${J.runId}' has ${Z.length} children. Index ${$.index} is out of range.`}],isError:!0,details:{mode:"management",results:[]}};let Y=Z[$.index];if(Y&&Y.status!=="running"&&Y.status!=="pending")return{content:[{type:"text",text:`Async run '${J.runId}' child ${$.index} is ${Y.status} and cannot be steered.`}],isError:!0,details:{mode:"management",results:[]}}}else if(Z.filter((H)=>H.status==="running").length===0&&Z.length>1)return{content:[{type:"text",text:`Async run '${J.runId}' has no running child yet. Provide index to steer a queued child.`}],isError:!0,details:{mode:"management",results:[]}};i6($.location.asyncDir,{message:$.message,targetIndex:$.index,source:"steer-action"});let Q=$.state.asyncJobs.get(J.runId);if(Q)Q.updatedAt=Date.now();let X=$.index!==void 0?` child ${$.index}`:" running child";return{content:[{type:"text",text:`Steering queued for async run ${J.runId}${X}. Delivery requires a live DM child session that supports mid-run steering.`}],details:{mode:"management",results:[]}}}function oV($){let J=new Set,Z=new Set;for(let Q of $)if(J.has(Q))Z.add(Q);else J.add(Q);return[...Z]}function lV($){let J=$.params.id??$.params.runId;if(!J)return{content:[{type:"text",text:"action='append-step' requires id."}],isError:!0,details:{mode:"management",results:[]}};if(!$.params.chain||$.params.chain.length!==1)return{content:[{type:"text",text:"action='append-step' requires chain with exactly one step."}],isError:!0,details:{mode:"management",results:[]}};let Z=n7($.params);if(Z.length>0)return{content:[{type:"text",text:`Cannot append step: ${Z.join(" ")}`}],isError:!0,details:{mode:"management",results:[]}};let Q;try{Q=O1(J,{state:$.deps.state,nested:P2($.deps)})}catch(y){return{content:[{type:"text",text:y instanceof Error?y.message:String(y)}],isError:!0,details:{mode:"management",results:[]}}}if(!Q)return{content:[{type:"text",text:`No async chain run found for '${J}'.`}],isError:!0,details:{mode:"management",results:[]}};if(Q.kind!=="async"||!Q.location.asyncDir)return{content:[{type:"text",text:`Run '${Q.id}' is not an append-capable async chain run.`}],isError:!0,details:{mode:"management",results:[]}};let X=j1(Q.location.asyncDir);if(!X)return{content:[{type:"text",text:`No async run status found for '${Q.id}'.`}],isError:!0,details:{mode:"management",results:[]}};if(X.mode!=="chain")return{content:[{type:"text",text:`Run '${Q.id}' is ${X.mode}; only active chain runs accept appended steps.`}],isError:!0,details:{mode:"management",results:[]}};if(X.state!=="running")return{content:[{type:"text",text:`Run '${Q.id}' is ${X.state}; only running chain runs accept appended steps.`}],isError:!0,details:{mode:"management",results:[]}};if(!((X.steps??[]).some((y)=>y.status==="running"||y.status==="pending")||(X.pendingAppends??0)>0))return{content:[{type:"text",text:`Run '${Q.id}' has no running or pending chain steps left; append-step must target an in-progress chain.`}],isError:!0,details:{mode:"management",results:[]}};let H=e3(Q.location.asyncDir),j=new Set([...Object.keys(X.outputs??{}),...(X.steps??[]).map((y)=>y.outputName).filter((y)=>Boolean(y)),...H.flatMap((y)=>g8(y.steps))]);try{J8($.params.chain,{maxItems:$.deps.config.chain?.dynamicFanout?.maxItems},{priorOutputNames:j,startStepIndex:X.chainStepCount??X.steps?.length??0})}catch(y){if(!(y instanceof a$))throw y;return{content:[{type:"text",text:`Cannot append step to run '${Q.id}': ${y.message}`}],isError:!0,details:{mode:"management",results:[]}}}let U=S8($.params.agentScope),G=$.deps.discoverAgents($.requestCwd,U),z=G.agents,V=A9($.params),B=X0($.params.skill),K=B===!1?[]:B??[],W={pi:$.deps.pi,cwd:$.ctx.cwd,currentSessionId:m8($.ctx.sessionManager),parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,currentModelProvider:$.ctx.model?.provider,currentModel:$.ctx.model,modelScope:G.modelScope},A=d6(Q.id,{chain:v2($.params.chain,V),task:$.params.task,resultMode:"chain",agents:z,ctx:W,availableModels:$.ctx.modelRegistry.getAvailable().map(y0),cwd:X.cwd??$.requestCwd,chainSkills:K,dynamicFanoutMaxItems:$.deps.config.chain?.dynamicFanout?.maxItems,maxSubagentDepth:r0($.deps.config.maxSubagentDepth),asyncDir:Q.location.asyncDir,validateOutputBindings:!1});if("error"in A)return{content:[{type:"text",text:A.error}],isError:!0,details:{mode:"management",results:[]}};let F=g8(A.steps),_=oV(F);if(_.length>0)return{content:[{type:"text",text:`Cannot append step to run '${Q.id}': duplicate output name in appended step: ${_.join(", ")}.`}],isError:!0,details:{mode:"management",results:[]}};let f=new Set(H.flatMap((y)=>g8(y.steps))),O=F.filter((y)=>f.has(y));if(O.length>0)return{content:[{type:"text",text:`Cannot append step to run '${Q.id}': output name already belongs to a pending append: ${O.join(", ")}.`}],isError:!0,details:{mode:"management",results:[]}};try{let y=t3({asyncDir:Q.location.asyncDir,runId:Q.id,steps:A.steps}),C=A.steps.length===1?"step":"steps";return{content:[{type:"text",text:`Append queued for chain run ${Q.id}: ${A.steps.length} ${C}. It becomes eligible after the chain's already-queued steps finish. Pending appends: ${y.pendingCount}.`}],details:{mode:"management",results:[],asyncId:Q.id,asyncDir:Q.location.asyncDir}}}catch(y){let C=y instanceof Error?y.message:String(y);return{content:[{type:"text",text:`Failed to append step to chain run ${Q.id}: ${C}`}],isError:!0,details:{mode:"management",results:[]}}}}function nV($){return $.sessionFile??($.steps?.length===1?$.steps[0]?.sessionFile:void 0)}function pV($){return $.agent??$.agents?.[0]??($.steps?.length===1?$.steps[0]?.agent:void 0)}function iV($,J){let Z=T$.resolve($),Q=T$.resolve(J);return Q===Z||Q.startsWith(`${Z}${T$.sep}`)}function rV($,J){let Z=nV($);if(!Z)throw Error(`Nested run '${$.id}' does not have a persisted session file to resume from.`);if(T$.extname(Z)!==".jsonl")throw Error(`Nested run '${$.id}' session file must be a .jsonl file: ${Z}`);let Q=T$.resolve(Z);if(!T$.isAbsolute(Z))throw Error(`Nested run '${$.id}' session file must be absolute: ${Z}`);if(!n0.existsSync(Q))throw Error(`Nested run '${$.id}' session file does not exist: ${Z}`);let X=n0.lstatSync(Q);if(!X.isFile()||X.isSymbolicLink())throw Error(`Nested run '${$.id}' session file is not a regular file: ${Z}`);let Y=n0.realpathSync(Q);if(!J.filter((j)=>n0.existsSync(j)).map((j)=>n0.realpathSync(j)).some((j)=>iV(j,Y)))throw Error(`Nested run '${$.id}' session file is outside trusted nested session roots: ${Z}`);if(!Y.split(T$.sep).includes($.id))throw Error(`Nested run '${$.id}' session file is not under that nested run's session directory: ${Z}`);return Y}function sV($,J){let Z=$.match.run;if(Z.state==="running"||Z.state==="queued")throw Error(`Nested run '${Z.id}' is live; route the follow-up to the owner process instead.`);let Q=pV(Z);if(!Q)throw Error(`Could not determine child agent for nested run '${Z.id}'.`);let X=Z.state==="complete"||Z.state==="failed"||Z.state==="paused"?Z.state:"failed",Y=RJ($.match.rootRunId,Z);return{kind:"revive",source:"nested",runId:Z.id,state:X,agent:Q,index:0,intercomTarget:u$(Z.id,Q,0),cwd:Y?T$.dirname(Y):void 0,sessionFile:rV(Z,J)}}async function aV($,J,Z=1000){let Q=Date.now()+Z;while(Date.now()<Q){let X=d3($.match.route).find((Y)=>Y.requestId===J&&Y.targetRunId===$.match.run.id);if(X)return X;await new Promise((Y)=>setTimeout(Y,50))}return}async function l7($,J,Z){let Q=P1();return u3($.match.route,{ts:Date.now(),requestId:Q,targetRunId:$.match.run.id,action:J,...Z?{message:Z}:{}}),aV($,Q)}function tV($){let J=$.match.run,Z=RJ($.match.rootRunId,J);if(!Z)return;let Q=C0(Z,{resultsDir:T$.join(h$,"nested",$.match.rootRunId)}).status,X=typeof Q?.pid==="number"&&Q.pid>0?Q.pid:J.pid;if(!Q||Q.state!=="running"||typeof X!=="number"||X<=0)return;try{return C2({asyncDir:Z,pid:X,source:"nested-interrupt"}),{content:[{type:"text",text:`Interrupt requested for nested async run ${J.id}.`}],details:{mode:"management",results:[]}}}catch(Y){let H=Y instanceof Error?Y.message:String(Y);return{content:[{type:"text",text:`Failed to interrupt nested async run ${J.id}: ${H}`}],isError:!0,details:{mode:"management",results:[]}}}}function eV($){let J=$.target.match.run,Z=RJ($.target.match.rootRunId,J);if(!Z)return;let Q=C0(Z,{resultsDir:T$.join(h$,"nested",$.target.match.rootRunId)}).status;if(!Q||Q.state!=="running"&&Q.state!=="queued")return;let X=Q.steps??[];if($.index!==void 0){if($.index<0||$.index>=X.length)return{content:[{type:"text",text:`Nested async run ${J.id} has ${X.length} children. Index ${$.index} is out of range.`}],isError:!0,details:{mode:"management",results:[]}};let Y=X[$.index];if(Y&&Y.status!=="running"&&Y.status!=="pending")return{content:[{type:"text",text:`Nested async run ${J.id} child ${$.index} is ${Y.status} and cannot be steered.`}],isError:!0,details:{mode:"management",results:[]}}}return i6(Z,{message:$.message,targetIndex:$.index,source:"nested-steer"}),{content:[{type:"text",text:`Steering queued for nested async run ${J.id}. Delivery requires a live DM child session that supports mid-run steering.`}],details:{mode:"management",results:[]}}}async function $z($){let J=$.match.run;if(J.state==="complete")return{content:[{type:"text",text:`Nested run ${J.id} is already complete and cannot be interrupted.`}],isError:!0,details:{mode:"management",results:[]}};if(J.state==="failed")return{content:[{type:"text",text:`Nested run ${J.id} has failed and cannot be interrupted.`}],isError:!0,details:{mode:"management",results:[]}};if(J.state==="paused")return{content:[{type:"text",text:`Nested run ${J.id} is already paused.`}],isError:!0,details:{mode:"management",results:[]}};let Z=await l7($,"interrupt");if(Z)return{content:[{type:"text",text:Z.message}],isError:Z.ok?void 0:!0,details:{mode:"management",results:[]}};let Q=tV($);if(Q)return Q;return{content:[{type:"text",text:`Nested run ${J.id} owner is not reachable and no safe direct async interrupt fallback is available.`}],isError:!0,details:{mode:"management",results:[]}}}async function Jz($){let J=$.target.match.run,Z=await l7($.target,"resume",$.message);if(Z)return{content:[{type:"text",text:Z.message}],isError:Z.ok?void 0:!0,details:{mode:"management",results:[]}};return{content:[{type:"text",text:`Nested run ${J.id} appears live but its owner route is not reachable. Wait for completion, then retry action='resume'.`}],isError:!0,details:{mode:"management",results:[]}}}function Zz($){let J=$.target.match.run;if(J.state!=="running"&&J.state!=="queued")return{content:[{type:"text",text:`Nested run ${J.id} is ${J.state} and cannot be steered.`}],isError:!0,details:{mode:"management",results:[]}};let Z=eV($);if(Z)return Z;return{content:[{type:"text",text:`Nested run ${J.id} is not a live async DM child session with a steering inbox. action='steer' cannot target foreground nested runs.`}],isError:!0,details:{mode:"management",results:[]}}}async function Qz($){let J=($.params.message??$.params.task??"").trim(),Z=($.params.chain?.length??0)>0?$.params.chain:void 0;if(!J&&!Z)return{content:[{type:"text",text:"action='resume' requires message."}],isError:!0,details:{mode:"management",results:[]}};let Q,X=$.ctx.sessionManager.getSessionFile()??null;try{let q=$.params.id??$.params.runId,S;try{S=q?O1(q,{state:$.deps.state,nested:P2($.deps)}):void 0}catch(M){let N=M instanceof Error?M.message:"",E=N.match(/async:/g)?.length??0;if(!z9(M)||!N.includes("foreground:")||E!==1)throw M}if(S?.kind==="nested"){if(Z)return{content:[{type:"text",text:"Attaching a running subagent as a chain root is currently available for top-level async runs only."}],isError:!0,details:{mode:"management",results:[]}};if(S.match.run.state==="running"||S.match.run.state==="queued")return Jz({target:S,message:J});let M=[...$.deps.config.defaultSessionDir?[T$.resolve($.deps.expandTilde($.deps.config.defaultSessionDir))]:[],...X?[$.deps.getSubagentSessionRoot(X)]:[]];Q=sV(S,M)}else Q=mV($.params,$.deps.state,{asyncRequireSessionFile:!Z})}catch(q){return{content:[{type:"text",text:q instanceof Error?q.message:String(q)}],isError:!0,details:{mode:"management",results:[]}}}if(Q.kind==="live"&&!Z){let q=O7({target:Q,state:$.deps.state,kill:$.deps.kill,resultsDir:h$});if(!q.ok)return{content:[{type:"text",text:q.message}],isError:!0,details:{mode:"management",results:[]}};if(await p6($.deps.pi.events,Q.intercomTarget,`Follow-up for async run ${Q.runId} (${Q.agent}):
|
|
213
|
-
|
|
214
|
-
${J}`,500,{source:"async-resume",runId:Q.runId,agent:Q.agent,index:Q.index}))return{content:[{type:"text",text:["Interrupted live async child, then delivered follow-up.",`Run: ${Q.runId}`,`Intercom target: ${Q.intercomTarget}`].join(`
|
|
215
|
-
`)}],details:{mode:"management",results:[]}};return{content:[{type:"text",text:["Async child appears live but its intercom target is not registered.",`Run: ${Q.runId}`,`Intercom target: ${Q.intercomTarget}`,"Wait for completion, then retry action='resume'."].join(`
|
|
216
|
-
`)}],isError:!0,details:{mode:"management",results:[]}}}let{blocked:Y,depth:H,maxDepth:j}=U4($.deps.config.maxSubagentDepth);if(Y)return{content:[{type:"text",text:`Nested subagent resume blocked (depth=${H}, max=${j}). Complete the follow-up directly instead.`}],isError:!0,details:{mode:"management",results:[]}};$.deps.state.currentSessionId=m8($.ctx.sessionManager);let U=Q.cwd??$.requestCwd,G=S8($.params.agentScope),z=$.deps.discoverAgents(U,G),V=z.agents,B=z.modelScope,K=s2($.deps.pi.getSessionName(),$.ctx.sessionManager.getSessionId()),W=y4({config:$.deps.config.intercomBridge,context:$.params.context,orchestratorTarget:K}),A=W.active?V.map((q)=>f4(q,W)):V,F=A.find((q)=>q.name===Q.agent);if(!F)return{content:[{type:"text",text:`Unknown agent for resume: ${Q.agent}`}],isError:!0,details:{mode:"management",results:[]}};if(Z){if(Q.source!=="async")return{content:[{type:"text",text:"Attaching a running subagent as a chain root is currently available for async runs only."}],isError:!0,details:{mode:"management",results:[]}};if(!I1())return{content:[{type:"text",text:"Async mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed."}],isError:!0,details:{mode:"chain",results:[]}};let q=P1().slice(0,8),S={...g2,enabled:$.params.artifacts!==!1},M=$.ctx.modelRegistry.getAvailable().map(y0),N=A9($.params),E=v2(Z,N),n=X0($.params.skill),L=yJ(q,{chain:E,task:($.params.task??J)||void 0,attachRoot:{runId:Q.runId,asyncDir:Q.asyncDir??T$.join(Q0,Q.runId),resultPath:N7(h$,Q.runId),index:Q.index,agent:Q.agent,label:`Attached ${Q.runId}`},agents:A,ctx:{pi:$.deps.pi,cwd:$.requestCwd,currentSessionId:$.deps.state.currentSessionId,parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,currentModelProvider:$.ctx.model?.provider,currentModel:$.ctx.model,modelScope:B},availableModels:M,cwd:U,maxOutput:$.params.maxOutput,artifactsDir:n2(X,U),artifactConfig:S,shareEnabled:$.params.share===!0,sessionRoot:$.deps.getSubagentSessionRoot(X),chainSkills:n===!1?[]:n??[],dynamicFanoutMaxItems:$.deps.config.chain?.dynamicFanout?.maxItems,maxSubagentDepth:r0($.deps.config.maxSubagentDepth),worktreeSetupHook:$.deps.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:$.deps.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:$.deps.config.worktreeBaseDir,controlConfig:t2($.deps.config.control,$.params.control),controlIntercomTarget:W.active?W.orchestratorTarget:void 0,childIntercomTarget:W.active?(g,I)=>u$(q,g,I):void 0,globalConcurrencyLimit:$.deps.config.globalConcurrencyLimit});if(L.isError)return L;let k=L.details.asyncId??q,o=[`Attached async subagent ${Q.runId} as the first step of a new chain.`,`Chain run: ${k}`,`Root: ${Q.agent} (step ${Q.index+1})`,L.details.asyncDir?`Async dir: ${L.details.asyncDir}`:void 0,`Status if needed: subagent({ action: "status", id: "${k}" })`].filter((g)=>Boolean(g));return{content:[{type:"text",text:N2(o.join(`
|
|
217
|
-
`))}],details:L.details}}let _=P1().slice(0,8),f={...g2,enabled:$.params.artifacts!==!1},O=n2(X,U),y=$.ctx.modelRegistry.getAvailable().map(y0),C=v8(_,{agent:Q.agent,task:L7(Q,J),agentConfig:F,ctx:{pi:$.deps.pi,cwd:$.requestCwd,currentSessionId:$.deps.state.currentSessionId,parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,currentModelProvider:$.ctx.model?.provider,currentModel:$.ctx.model,modelScope:B},cwd:U,maxOutput:$.params.maxOutput,artifactsDir:O,artifactConfig:f,shareEnabled:$.params.share===!0,sessionRoot:$.deps.getSubagentSessionRoot(X),sessionFile:Q.sessionFile,outputBaseDir:e8($.deps,O,_),maxSubagentDepth:r0($.deps.config.maxSubagentDepth),worktreeSetupHook:$.deps.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:$.deps.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:$.deps.config.worktreeBaseDir,controlConfig:t2($.deps.config.control,$.params.control),controlIntercomTarget:W.active?W.orchestratorTarget:void 0,childIntercomTarget:W.active?(q,S)=>u$(_,q,S):void 0,availableModels:y});if(C.isError)return C;let T=C.details.asyncId??_,h=W.active?u$(T,Q.agent,0):void 0,w=[`Revived ${Q.source} subagent from ${Q.runId}.`,`Revived run: ${T}`,`Agent: ${Q.agent}`,`Session: ${Q.sessionFile}`,C.details.asyncDir?`Async dir: ${C.details.asyncDir}`:void 0,h?`Intercom target: ${h} (if registered)`:void 0,`Status if needed: subagent({ action: "status", id: "${T}" })`].filter((q)=>Boolean(q));return{content:[{type:"text",text:N2(w.join(`
|
|
218
|
-
`))}],details:C.details}}function Xz($){let J=f0($);if($.exitCode!==0&&$.error)return J?`${$.error}
|
|
875
|
+
${followUp}`, 500, { source: "async-resume", runId: target.runId, agent: target.agent, index: target.index });
|
|
876
|
+
if (delivered) {
|
|
877
|
+
return {
|
|
878
|
+
content: [{ type: "text", text: [`Interrupted live async child, then delivered follow-up.`, `Run: ${target.runId}`, `Intercom target: ${target.intercomTarget}`].join(`
|
|
879
|
+
`) }],
|
|
880
|
+
details: { mode: "management", results: [] }
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
return {
|
|
884
|
+
content: [{ type: "text", text: [`Async child appears live but its intercom target is not registered.`, `Run: ${target.runId}`, `Intercom target: ${target.intercomTarget}`, `Wait for completion, then retry action='resume'.`].join(`
|
|
885
|
+
`) }],
|
|
886
|
+
isError: true,
|
|
887
|
+
details: { mode: "management", results: [] }
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
const { blocked, depth, maxDepth } = checkSubagentDepth(input.deps.config.maxSubagentDepth);
|
|
891
|
+
if (blocked) {
|
|
892
|
+
return {
|
|
893
|
+
content: [{ type: "text", text: `Nested subagent resume blocked (depth=${depth}, max=${maxDepth}). Complete the follow-up directly instead.` }],
|
|
894
|
+
isError: true,
|
|
895
|
+
details: { mode: "management", results: [] }
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
input.deps.state.currentSessionId = resolveCurrentSessionId(input.ctx.sessionManager);
|
|
899
|
+
const effectiveCwd = target.cwd ?? input.requestCwd;
|
|
900
|
+
const scope = resolveExecutionAgentScope(input.params.agentScope);
|
|
901
|
+
const discovered = input.deps.discoverAgents(effectiveCwd, scope);
|
|
902
|
+
const discoveredAgents = discovered.agents;
|
|
903
|
+
const modelScope = discovered.modelScope;
|
|
904
|
+
const sessionName = resolveIntercomSessionTarget(input.deps.pi.getSessionName(), input.ctx.sessionManager.getSessionId());
|
|
905
|
+
const intercomBridge = resolveIntercomBridge({
|
|
906
|
+
config: input.deps.config.intercomBridge,
|
|
907
|
+
context: input.params.context,
|
|
908
|
+
orchestratorTarget: sessionName
|
|
909
|
+
});
|
|
910
|
+
const agents = intercomBridge.active ? discoveredAgents.map((agent) => applyIntercomBridgeToAgent(agent, intercomBridge)) : discoveredAgents;
|
|
911
|
+
const agentConfig = agents.find((agent) => agent.name === target.agent);
|
|
912
|
+
if (!agentConfig) {
|
|
913
|
+
return {
|
|
914
|
+
content: [{ type: "text", text: `Unknown agent for resume: ${target.agent}` }],
|
|
915
|
+
isError: true,
|
|
916
|
+
details: { mode: "management", results: [] }
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
if (attachChain) {
|
|
920
|
+
if (target.source !== "async") {
|
|
921
|
+
return {
|
|
922
|
+
content: [{ type: "text", text: "Attaching a running subagent as a chain root is currently available for async runs only." }],
|
|
923
|
+
isError: true,
|
|
924
|
+
details: { mode: "management", results: [] }
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
if (!isAsyncAvailable()) {
|
|
928
|
+
return {
|
|
929
|
+
content: [{ type: "text", text: "Async mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed." }],
|
|
930
|
+
isError: true,
|
|
931
|
+
details: { mode: "chain", results: [] }
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
const runId = randomUUID().slice(0, 8);
|
|
935
|
+
const artifactConfig = { ...DEFAULT_ARTIFACT_CONFIG, enabled: input.params.artifacts !== false };
|
|
936
|
+
const availableModels = input.ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
937
|
+
const contextPolicy = resolveExplicitContextPolicy(input.params);
|
|
938
|
+
const chain = wrapChainTasksForFork(attachChain, contextPolicy);
|
|
939
|
+
const normalized = normalizeSkillInput(input.params.skill);
|
|
940
|
+
const result = executeAsyncChain(runId, {
|
|
941
|
+
chain,
|
|
942
|
+
task: (input.params.task ?? followUp) || undefined,
|
|
943
|
+
attachRoot: {
|
|
944
|
+
runId: target.runId,
|
|
945
|
+
asyncDir: target.asyncDir ?? path.join(ASYNC_DIR, target.runId),
|
|
946
|
+
resultPath: resolveAsyncRootResultPath(RESULTS_DIR, target.runId),
|
|
947
|
+
index: target.index,
|
|
948
|
+
agent: target.agent,
|
|
949
|
+
label: `Attached ${target.runId}`
|
|
950
|
+
},
|
|
951
|
+
agents,
|
|
952
|
+
ctx: {
|
|
953
|
+
pi: input.deps.pi,
|
|
954
|
+
cwd: input.requestCwd,
|
|
955
|
+
currentSessionId: input.deps.state.currentSessionId,
|
|
956
|
+
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
957
|
+
currentModelProvider: input.ctx.model?.provider,
|
|
958
|
+
currentModel: input.ctx.model,
|
|
959
|
+
modelScope
|
|
960
|
+
},
|
|
961
|
+
availableModels,
|
|
962
|
+
cwd: effectiveCwd,
|
|
963
|
+
maxOutput: input.params.maxOutput,
|
|
964
|
+
artifactsDir: getArtifactsDir(parentSessionFile, effectiveCwd),
|
|
965
|
+
artifactConfig,
|
|
966
|
+
shareEnabled: input.params.share === true,
|
|
967
|
+
sessionRoot: input.deps.getSubagentSessionRoot(parentSessionFile),
|
|
968
|
+
chainSkills: normalized === false ? [] : normalized ?? [],
|
|
969
|
+
dynamicFanoutMaxItems: input.deps.config.chain?.dynamicFanout?.maxItems,
|
|
970
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
971
|
+
worktreeSetupHook: input.deps.config.worktreeSetupHook,
|
|
972
|
+
worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
|
|
973
|
+
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
974
|
+
controlConfig: resolveControlConfig(input.deps.config.control, input.params.control),
|
|
975
|
+
controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
|
|
976
|
+
childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
|
|
977
|
+
globalConcurrencyLimit: input.deps.config.globalConcurrencyLimit
|
|
978
|
+
});
|
|
979
|
+
if (result.isError)
|
|
980
|
+
return result;
|
|
981
|
+
const attachedId = result.details.asyncId ?? runId;
|
|
982
|
+
const lines = [
|
|
983
|
+
`Attached async subagent ${target.runId} as the first step of a new chain.`,
|
|
984
|
+
`Chain run: ${attachedId}`,
|
|
985
|
+
`Root: ${target.agent} (step ${target.index + 1})`,
|
|
986
|
+
result.details.asyncDir ? `Async dir: ${result.details.asyncDir}` : undefined,
|
|
987
|
+
`Status if needed: subagent({ action: "status", id: "${attachedId}" })`
|
|
988
|
+
].filter((line) => Boolean(line));
|
|
989
|
+
return { content: [{ type: "text", text: formatAsyncStartedMessage(lines.join(`
|
|
990
|
+
`)) }], details: result.details };
|
|
991
|
+
}
|
|
992
|
+
const runId = randomUUID().slice(0, 8);
|
|
993
|
+
const artifactConfig = { ...DEFAULT_ARTIFACT_CONFIG, enabled: input.params.artifacts !== false };
|
|
994
|
+
const artifactsDir = getArtifactsDir(parentSessionFile, effectiveCwd);
|
|
995
|
+
const availableModels = input.ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
996
|
+
const result = executeAsyncSingle(runId, {
|
|
997
|
+
agent: target.agent,
|
|
998
|
+
task: buildRevivedAsyncTask(target, followUp),
|
|
999
|
+
agentConfig,
|
|
1000
|
+
ctx: {
|
|
1001
|
+
pi: input.deps.pi,
|
|
1002
|
+
cwd: input.requestCwd,
|
|
1003
|
+
currentSessionId: input.deps.state.currentSessionId,
|
|
1004
|
+
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
1005
|
+
currentModelProvider: input.ctx.model?.provider,
|
|
1006
|
+
currentModel: input.ctx.model,
|
|
1007
|
+
modelScope
|
|
1008
|
+
},
|
|
1009
|
+
cwd: effectiveCwd,
|
|
1010
|
+
maxOutput: input.params.maxOutput,
|
|
1011
|
+
artifactsDir,
|
|
1012
|
+
artifactConfig,
|
|
1013
|
+
shareEnabled: input.params.share === true,
|
|
1014
|
+
sessionRoot: input.deps.getSubagentSessionRoot(parentSessionFile),
|
|
1015
|
+
sessionFile: target.sessionFile,
|
|
1016
|
+
outputBaseDir: resolveSingleRunOutputBaseDir(input.deps, artifactsDir, runId),
|
|
1017
|
+
maxSubagentDepth: resolveCurrentMaxSubagentDepth(input.deps.config.maxSubagentDepth),
|
|
1018
|
+
worktreeSetupHook: input.deps.config.worktreeSetupHook,
|
|
1019
|
+
worktreeSetupHookTimeoutMs: input.deps.config.worktreeSetupHookTimeoutMs,
|
|
1020
|
+
worktreeBaseDir: input.deps.config.worktreeBaseDir,
|
|
1021
|
+
controlConfig: resolveControlConfig(input.deps.config.control, input.params.control),
|
|
1022
|
+
controlIntercomTarget: intercomBridge.active ? intercomBridge.orchestratorTarget : undefined,
|
|
1023
|
+
childIntercomTarget: intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(runId, agent, index) : undefined,
|
|
1024
|
+
availableModels
|
|
1025
|
+
});
|
|
1026
|
+
if (result.isError)
|
|
1027
|
+
return result;
|
|
1028
|
+
const revivedId = result.details.asyncId ?? runId;
|
|
1029
|
+
const revivedTarget = intercomBridge.active ? resolveSubagentIntercomTarget(revivedId, target.agent, 0) : undefined;
|
|
1030
|
+
const sourceLabel = target.source;
|
|
1031
|
+
const lines = [
|
|
1032
|
+
`Revived ${sourceLabel} subagent from ${target.runId}.`,
|
|
1033
|
+
`Revived run: ${revivedId}`,
|
|
1034
|
+
`Agent: ${target.agent}`,
|
|
1035
|
+
`Session: ${target.sessionFile}`,
|
|
1036
|
+
result.details.asyncDir ? `Async dir: ${result.details.asyncDir}` : undefined,
|
|
1037
|
+
revivedTarget ? `Intercom target: ${revivedTarget} (if registered)` : undefined,
|
|
1038
|
+
`Status if needed: subagent({ action: "status", id: "${revivedId}" })`
|
|
1039
|
+
].filter((line) => Boolean(line));
|
|
1040
|
+
return { content: [{ type: "text", text: formatAsyncStartedMessage(lines.join(`
|
|
1041
|
+
`)) }], details: result.details };
|
|
1042
|
+
}
|
|
1043
|
+
function resultSummaryForIntercom(result) {
|
|
1044
|
+
const output = getSingleResultOutput(result);
|
|
1045
|
+
if (result.exitCode !== 0 && result.error) {
|
|
1046
|
+
return output ? `${result.error}
|
|
219
1047
|
|
|
220
1048
|
Output:
|
|
221
|
-
${
|
|
222
|
-
`)}function K9($,J){return(Z)=>uV({pi:J.pi,controlConfig:$.controlConfig,intercomBridge:$.intercomBridge,event:Z})}async function Hz($){if(!$.intercomBridge.active||!$.intercomBridge.orchestratorTarget)return null;let J=$.results.flatMap((X,Y)=>X.detached?[]:[{agent:X.agent,status:u8({exitCode:X.exitCode,interrupted:X.interrupted,detached:X.detached}),summary:Xz(X),index:Y,artifactPath:X.artifactPaths?.outputPath,sessionPath:X.sessionFile,intercomTarget:u$($.runId,X.agent,Y)}]);if(J.length===0)return null;let Z=H7({to:$.intercomBridge.orchestratorTarget,runId:$.runId,mode:$.mode,source:"foreground",children:Y7($.runId,J,$.nestedChildren),...typeof $.chainSteps==="number"?{chainSteps:$.chainSteps}:{}});if(!await j7($.pi.events,Z))return null;return Z}async function W9($){let J=await Hz({pi:$.pi,intercomBridge:$.intercomBridge,runId:$.runId,mode:$.mode,results:$.details.results,...typeof $.details.totalSteps==="number"?{chainSteps:$.details.totalSteps}:{},...$.nestedChildren?.length?{nestedChildren:$.nestedChildren}:{}});if(!J)return null;return{text:V7({mode:$.mode,runId:$.runId,payload:J}),details:U7($.details)}}function jz($,J,Z,Q,X,Y){if(Number(Z)+Number(Q)+Number(X)!==1)return{content:[{type:"text",text:`Provide exactly one mode. Agents: ${J.map((j)=>j.name).join(", ")||"none"}`}],isError:!0,details:{mode:"single",results:[]}};let H=n7($);if(H.length>0)return{content:[{type:"text",text:H.join(" ")}],isError:!0,details:{mode:_9($),results:[]}};if(X&&$.agent&&!J.find((j)=>j.name===$.agent))return{content:[{type:"text",text:`Unknown agent: ${$.agent}`}],isError:!0,details:{mode:"single",results:[]}};if(Q&&$.tasks)for(let j=0;j<$.tasks.length;j++){let U=$.tasks[j];if(!J.find((G)=>G.name===U.agent))return{content:[{type:"text",text:`Unknown agent: ${U.agent} (task ${j+1})`}],isError:!0,details:{mode:"parallel",results:[]}}}if(Z&&$.chain){if($.chain.length===0)return{content:[{type:"text",text:"Chain must have at least one step"}],isError:!0,details:{mode:"chain",results:[]}};let j=$.chain[0];if(E$(j)){let U=j.parallel.findIndex((G)=>!G.task);if(U!==-1)return{content:[{type:"text",text:`First parallel step: task ${U+1} must have a task (no previous output to reference)`}],isError:!0,details:{mode:"chain",results:[]}}}else if(C$(j))return{content:[{type:"text",text:"First step in chain cannot be dynamic fanout; expand.from requires a prior structured named output"}],isError:!0,details:{mode:"chain",results:[]}};else if(!j.task&&!$.task&&!Y)return{content:[{type:"text",text:"First step in chain must have a task"}],isError:!0,details:{mode:"chain",results:[]}};for(let U=0;U<$.chain.length;U++){let G=$.chain[U],z=o2(G);for(let V of z)if(!J.find((B)=>B.name===V))return{content:[{type:"text",text:`Unknown agent: ${V} (step ${U+1})`}],isError:!0,details:{mode:"chain",results:[]}};if(E$(G)&&G.parallel.length===0)return{content:[{type:"text",text:`Parallel step ${U+1} must have at least one task`}],isError:!0,details:{mode:"chain",results:[]}}}}return null}function Uz($,J){if(($.chain?.length??0)===0)return null;try{J8($.chain,{maxItems:J})}catch(Z){if(Z instanceof a$)return{content:[{type:"text",text:Z.message}],isError:!0,details:{mode:"chain",results:[]}};throw Z}return null}function n7($){let J=[];J.push(...$1($.acceptance,"acceptance"));for(let[Z,Q]of($.tasks??[]).entries())J.push(...$1(Q.acceptance,`tasks[${Z}].acceptance`));for(let[Z,Q]of($.chain??[]).entries())if(J.push(...$1(Q.acceptance,`chain[${Z}].acceptance`)),E$(Q))for(let[X,Y]of Q.parallel.entries())J.push(...$1(Y.acceptance,`chain[${Z}].parallel[${X}].acceptance`));else if(C$(Q))J.push(...$1(Q.parallel.acceptance,`chain[${Z}].parallel.acceptance`));return J}function _9($){if(($.chain?.length??0)>0)return"chain";if(($.tasks?.length??0)>0)return"parallel";if($.agent)return"single";return"single"}function Vz($,J){if($.context!==void 0)return A9($);let Z=new Map(J.map((Y)=>[Y.name,Y])),Q=(Y)=>Z.get(Y)?.defaultContext==="fork"?"fork":"fresh",X=zz($).some((Y)=>Q(Y)==="fork");return{params:X?{...$,context:"fork"}:$,contextForAgent:Q,usesFork:X}}function A9($){let J=$.context==="fork"?"fork":"fresh";return{params:$,contextForAgent:()=>J,usesFork:J==="fork"}}function zz($){let J=[];if($.agent)J.push($.agent);for(let Z of $.tasks??[])J.push(Z.agent);for(let Z of $.chain??[])J.push(...o2(Z));return J}function A0($,J){return $.contextForAgent(J)==="fork"}function DJ($,J){return k1({content:[{type:"text",text:J}],isError:!0,details:{mode:_9($),results:[]}},$.context)}function Gz($){let{timeoutMs:J,maxRuntimeMs:Z}=$;if(J===void 0&&Z===void 0)return{};for(let[Q,X]of[["timeoutMs",J],["maxRuntimeMs",Z]]){if(X===void 0)continue;if(typeof X!=="number"||!Number.isInteger(X)||X<=0)return{error:`${Q} must be a positive integer.`}}if(J!==void 0&&Z!==void 0&&J!==Z)return{error:"timeoutMs and maxRuntimeMs are aliases; provide only one value or use the same value for both."};return{timeoutMs:J??Z}}function Bz($,J){let Z=$.turnBudget??J.turnBudget;if(Z===void 0)return{};if(!Z||typeof Z!=="object"||Array.isArray(Z))return{error:"turnBudget must be an object with maxTurns and optional graceTurns."};if(typeof Z.maxTurns!=="number"||!Number.isInteger(Z.maxTurns)||Z.maxTurns<1)return{error:"turnBudget.maxTurns must be an integer >= 1."};let Q=Z.graceTurns??aZ;if(typeof Q!=="number"||!Number.isInteger(Q)||Q<0)return{error:"turnBudget.graceTurns must be an integer >= 0."};return{turnBudget:{maxTurns:Z.maxTurns,graceTurns:Q}}}function x2($,J="toolBudget"){let Z=O0($,J);return{toolBudget:Z.budget,error:Z.error}}function p7($){if($.stepBudget!==void 0)return x2($.stepBudget,"toolBudget");if($.runBudget!==void 0)return{toolBudget:$.runBudget};if($.agentBudget!==void 0)return x2($.agentBudget,"agent.toolBudget");return x2($.configBudget,"config.toolBudget")}function Kz($){let J=[];for(let Z=0;Z<$.length;Z++){let Q=$[Z],X=Q.count;if(X!==void 0&&(typeof X!=="number"||!Number.isInteger(X)||X<1))return{error:`tasks[${Z}].count must be an integer >= 1`};let{count:Y,...H}=Q;for(let j=0;j<(X??1);j++)J.push({...H})}return{tasks:J}}function Wz($){let J=[];for(let Z=0;Z<$.length;Z++){let Q=$[Z];if(!E$(Q)){J.push(Q);continue}let X=[];for(let Y=0;Y<Q.parallel.length;Y++){let H=Q.parallel[Y],j=H.count;if(j!==void 0&&(typeof j!=="number"||!Number.isInteger(j)||j<1))return{error:`chain[${Z}].parallel[${Y}].count must be an integer >= 1`};let{count:U,...G}=H;for(let z=0;z<(j??1);z++)X.push({...G})}J.push({...Q,parallel:X})}return{chain:J}}function _z($){if($.tasks){let J=Kz($.tasks);if(J.error)return{error:DJ($,J.error)};return{params:{...$,tasks:J.tasks}}}if($.chain){let J=Wz($.chain);if(J.error)return{error:DJ($,J.error)};return{params:{...$,chain:J.chain}}}return{params:$}}function k1($,J){if(J!=="fork"||!$.details)return $;return{...$,details:{...$.details,context:"fork"}}}function k2($,J){let Z=J instanceof Error?J.message:String(J);return k1({content:[{type:"text",text:Z}],isError:!0,details:{mode:_9($),results:[]}},$.context)}function i7($,J,Z){let Q=[],X=0;for(let Y of $){if(E$(Y)){for(let H of Y.parallel)Q.push(J(H.agent,X)),X++;continue}if(C$(Y)){let H=Y.expand.maxItems??Z??0;for(let j=0;j<H;j++)Q.push(J(Y.parallel.agent,X)),X++;continue}Q.push(J(Y.agent,X)),X++}return Q}function r7($,J,Z){let Q=[],X=0;for(let Y of $){if(E$(Y)){for(let H of Y.parallel)Q.push(J(H.agent,X)),X++;continue}if(C$(Y)){let H=Y.expand.maxItems??Z??0;for(let j=0;j<H;j++)Q.push(J(Y.parallel.agent,X)),X++;continue}Q.push(J(Y.agent,X)),X++}return Q}function v2($,J){return $.map((Z,Q)=>{if(E$(Z))return{...Z,parallel:Z.parallel.map((Y)=>({...Y,task:A0(J,Y.agent)?i0(Y.task??"{previous}"):Y.task}))};if(C$(Z))return{...Z,parallel:{...Z.parallel,task:A0(J,Z.parallel.agent)?i0(Z.parallel.task??"{previous}"):Z.parallel.task}};let X=Z;return{...X,task:A0(J,X.agent)?i0(X.task??(Q===0?"{task}":"{previous}")):X.task}})}function Az($,J,Z,Q){if(!J.usesFork)return;if($.agent){if(A0(J,$.agent))Z($.agent,0);return}if($.tasks){$.tasks.forEach((Y,H)=>{if(A0(J,Y.agent))Z(Y.agent,H)});return}if(!$.chain?.length)return;let X=0;for(let Y of $.chain){if(E$(Y)){for(let j of Y.parallel){if(A0(J,j.agent))Z(j.agent,X);X++}continue}if(C$(Y)){let j=Y.expand.maxItems??Q??0;if(A0(J,Y.parallel.agent))for(let U=0;U<j;U++)Z(Y.parallel.agent,X+U);X+=j;continue}let H=Y;if(A0(J,H.agent))Z(H.agent,X);X++}}function qz($,J){let{params:Z,effectiveCwd:Q,agents:X,ctx:Y,shareEnabled:H,sessionRoot:j,sessionFileForIndex:U,sessionFileForTask:G,thinkingOverrideForTask:z,artifactConfig:V,artifactsDir:B,effectiveAsync:K,controlConfig:W,intercomBridge:A,nestedRoute:F,contextPolicy:_}=$,f=(Z.chain?.length??0)>0,O=(Z.tasks?.length??0)>0,y=!f&&!O&&Boolean(Z.agent);if(!K)return null;if(f&&Z.chain){let M=Lz(Z.chain,Q);if(M)return{content:[{type:"text",text:M}],isError:!0,details:{mode:"chain",results:[]}}}if(O&&Z.tasks){let M=H4(J.config.parallel?.maxTasks);if(Z.tasks.length>M)return a1(`Max ${M} tasks`);if(Z.worktree){let N=s7(Z.tasks,Q);if(N)return a1(N)}}if(!I1())return{content:[{type:"text",text:"Async mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed."}],isError:!0,details:{mode:"single",results:[]}};let C=P1(),T={pi:J.pi,cwd:Y.cwd,currentSessionId:J.state.currentSessionId,parentSessionId:Y.sessionManager.getSessionId()??void 0,currentModelProvider:Y.model?.provider,currentModel:Y.model,modelScope:$.modelScope},h=Y.modelRegistry.getAvailable().map(y0),b=r0(J.config.maxSubagentDepth),w=Y.model?.provider,q=A.active?A.orchestratorTarget:void 0,S=A.active?(M,N)=>u$(C,M,N):void 0;if(O&&Z.tasks){let M=Z.tasks.map((L)=>X.find((k)=>k.name===L.agent)),N=Z.tasks.map((L,k)=>B0(L.model??M[k]?.model,Y.model,h,w,{scope:$.modelScope,source:L.model?"explicit":"inherited"})),E=Z.tasks.map((L)=>X0(L.skill)),n=Z.tasks.map((L,k)=>({agent:L.agent,task:A0(_,L.agent)?i0(L.task):L.task,cwd:L.cwd,...N[k]?{model:N[k]}:{},...E[k]!==void 0?{skill:E[k]}:{},...L.output===!0?M[k]?.output?{output:M[k].output}:{}:L.output!==void 0?{output:L.output}:{},...L.outputMode!==void 0?{outputMode:L.outputMode}:{},...L.reads!==void 0&&L.reads!==!0?{reads:L.reads}:{},...L.progress!==void 0?{progress:L.progress}:{},...L.toolBudget!==void 0?{toolBudget:L.toolBudget}:{},...L.acceptance!==void 0?{acceptance:L.acceptance}:{}}));return yJ(C,{chain:[{parallel:n,concurrency:j4(Z.concurrency,J.config.parallel?.concurrency),worktree:Z.worktree}],resultMode:"parallel",agents:X,ctx:T,availableModels:h,cwd:Q,maxOutput:Z.maxOutput,artifactsDir:V.enabled?B:void 0,artifactConfig:V,shareEnabled:H,sessionRoot:j,chainSkills:[],sessionFilesByFlatIndex:Z.tasks.map((L,k)=>G(L.agent,k)),thinkingOverridesByFlatIndex:Z.tasks.map((L,k)=>z(L.agent,k)),maxSubagentDepth:b,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:W,controlIntercomTarget:q,childIntercomTarget:S,nestedRoute:F,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalConcurrencyLimit:J.config.globalConcurrencyLimit})}if(f&&Z.chain){let M=X0(Z.skill),N=M===!1?[]:M??[],E=v2(Z.chain,_);return yJ(C,{chain:E,task:Z.task,agents:X,ctx:T,availableModels:h,cwd:Q,maxOutput:Z.maxOutput,artifactsDir:V.enabled?B:void 0,artifactConfig:V,shareEnabled:H,sessionRoot:j,chainSkills:N,sessionFilesByFlatIndex:i7(E,G,J.config.chain?.dynamicFanout?.maxItems),thinkingOverridesByFlatIndex:r7(E,z,J.config.chain?.dynamicFanout?.maxItems),dynamicFanoutMaxItems:J.config.chain?.dynamicFanout?.maxItems,maxSubagentDepth:b,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:W,controlIntercomTarget:q,childIntercomTarget:S,nestedRoute:F,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalConcurrencyLimit:J.config.globalConcurrencyLimit})}if(y){let M=X.find((I)=>I.name===Z.agent);if(!M)return{content:[{type:"text",text:`Unknown agent: ${Z.agent}`}],isError:!0,details:{mode:"single",results:[]}};let N=Z.output!==void 0?Z.output:M.output,E=qJ(N,M.output),n=Z.outputMode??"inline",L=X0(Z.skill),k=L===!1?[]:L,o=s0(b,M.maxSubagentDepth),g=B0(Z.model??M.model,Y.model,h,w,{scope:$.modelScope,source:Z.model?"explicit":"inherited"});return v8(C,{agent:Z.agent,task:A0(_,Z.agent)?i0(Z.task??""):Z.task??"",agentConfig:M,ctx:T,availableModels:h,cwd:Q,maxOutput:Z.maxOutput,artifactsDir:V.enabled?B:void 0,artifactConfig:V,shareEnabled:H,sessionRoot:j,sessionFile:G(Z.agent,0),skills:k,output:E,outputMode:n,outputBaseDir:e8(J,B,C),modelOverride:g,thinkingOverride:z(Z.agent,0),maxSubagentDepth:o,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:W,controlIntercomTarget:q,childIntercomTarget:S?(I,a)=>S(I,a):void 0,nestedRoute:F,acceptance:Z.acceptance,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget})}return null}async function Oz($,J){let{params:Z,effectiveCwd:Q,agents:X,ctx:Y,signal:H,runId:j,shareEnabled:U,sessionDirForIndex:G,sessionFileForIndex:z,sessionFileForTask:V,thinkingOverrideForTask:B,artifactsDir:K,artifactConfig:W,onUpdate:A,sessionRoot:F,controlConfig:_,contextPolicy:f}=$,O=K9($,J),y=$.intercomBridge.active?u$:void 0,C=J.state.foregroundControls.get(j),T=X0(Z.skill),h=T===!1?[]:T??[],b=v2(Z.chain,f),w=r0(J.config.maxSubagentDepth),q=await A3({chain:b,task:Z.task,agents:X,ctx:Y,modelScope:$.modelScope,intercomEvents:J.pi.events,signal:H,runId:j,cwd:Q,shareEnabled:U,sessionDirForIndex:G,sessionFileForIndex:z,sessionFileForTask:V,thinkingOverrideForTask:B,artifactsDir:K,artifactConfig:W,includeProgress:Z.includeProgress,clarify:Z.clarify,onUpdate:A,onControlEvent:O,controlConfig:_,childIntercomTarget:y?(E,n)=>y(j,E,n):void 0,orchestratorIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,foregroundControl:C,nestedRoute:C?.nestedRoute,chainSkills:h,chainDir:Z.chainDir??a9(Q),dynamicFanoutMaxItems:J.config.chain?.dynamicFanout?.maxItems,maxSubagentDepth:w,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,turnBudget:$.turnBudget,onDetachedExit:(E,n)=>B9(J.state,{runId:j,mode:"chain",cwd:Q,index:E,result:n}),toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalConcurrencyLimit:J.config.globalConcurrencyLimit});if(q.requestedAsync){if(!I1())return{content:[{type:"text",text:"Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed."}],isError:!0,details:{mode:"chain",results:[]}};let E=P1(),n={pi:J.pi,cwd:Y.cwd,currentSessionId:J.state.currentSessionId,parentSessionId:Y.sessionManager.getSessionId()??void 0,currentModelProvider:Y.model?.provider,currentModel:Y.model,modelScope:$.modelScope},L=v2(q.requestedAsync.chain,f);return yJ(E,{chain:L,task:Z.task,agents:X,ctx:n,availableModels:Y.modelRegistry.getAvailable().map(y0),cwd:Q,maxOutput:Z.maxOutput,artifactsDir:W.enabled?K:void 0,artifactConfig:W,shareEnabled:U,sessionRoot:F,chainSkills:q.requestedAsync.chainSkills,sessionFilesByFlatIndex:i7(L,V,J.config.chain?.dynamicFanout?.maxItems),thinkingOverridesByFlatIndex:r7(L,B,J.config.chain?.dynamicFanout?.maxItems),dynamicFanoutMaxItems:J.config.chain?.dynamicFanout?.maxItems,maxSubagentDepth:w,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:_,controlIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,childIntercomTarget:$.intercomBridge.active?(k,o)=>u$(E,k,o):void 0,nestedRoute:$.nestedRoute,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,toolBudget:$.toolBudget,configToolBudget:$.configToolBudget,globalConcurrencyLimit:J.config.globalConcurrencyLimit})}let S=q.details?{...q.details,runId:j}:void 0;if(C&&S)i1(C),D1(j,S.results,C.nestedChildren),S.totalCost=HJ(S.results);let M=S?jJ(S):void 0;if(M)G9(J.state,{runId:j,mode:"chain",cwd:Q,results:M.results});let N=M&&!M.results.some((E)=>E.interrupted||E.detached)?await W9({pi:J.pi,intercomBridge:$.intercomBridge,runId:j,mode:"chain",details:M,...C?.nestedChildren?.length?{nestedChildren:C.nestedChildren}:{}}):null;if(N)return{...q,content:[{type:"text",text:N.text}],details:N.details};return M?{...q,details:M}:q}function a1($){return{content:[{type:"text",text:$}],isError:!0,details:{mode:"parallel",results:[]}}}function Fz($,J,Z,Q,X,Y,H){if(!$)return{};try{return{setup:N8(J,Z,Q.length,{agents:Q.map((j)=>j.agent),setupHook:X?{hookPath:X,timeoutMs:Y}:void 0,baseDir:H})}}catch(j){let U=j instanceof Error?j.message:String(j);return{errorResult:a1(U)}}}function s7($,J){let Z=W2($,J);if(!Z)return;return _2(Z,J)}function e8($,J,Z){return $.config.singleRunOutputBaseDir?T$.resolve($.expandTilde($.config.singleRunOutputBaseDir)):T$.join(J,"outputs",Z)}function Lz($,J){for(let Z=0;Z<$.length;Z++){let Q=$[Z];if(!E$(Q)||!Q.worktree)continue;let X=v0(J,Q.cwd),Y=W2(Q.parallel,X);if(!Y)continue;let H=_2(Y,X);return`parallel chain step ${Z+1}: ${H}`}return}function q9($,J,Z,Q){if(Z)return Z.worktrees[Q].agentCwd;return v0(J,$.cwd)}function Mz($,J,Z){if(!$)return"";let Q=T$.join(J,"worktree-diffs"),X=E8($,Z.map((Y)=>Y.agent),Q);return T8(X)}function Nz($){let J=new Map;for(let Z=0;Z<$.tasks.length;Z++){let Q=$.behaviors[Z];if(!Q?.output)continue;let X=$.tasks[Z],Y=q9(X,$.paramsCwd,$.worktreeSetup,Z),H=y1(Q.output,$.ctxCwd,Y,$.outputBaseDir);if(!H)continue;let j=J.get(H);if(j)return`Parallel tasks ${j.index+1} (${j.agent}) and ${Z+1} (${X.agent}) resolve output to the same path: ${H}. Use distinct output paths.`;J.set(H,{index:Z,agent:X.agent})}return}async function Ez($){for(let J=0;J<$.tasks.length;J++)$.sessionFileForIndex(J);return vJ($.tasks,$.concurrencyLimit,async(J,Z)=>{let Q=$.behaviors[Z],X=Q?.skills,Y=q9(J,$.paramsCwd,$.worktreeSetup,Z),H=Q?H1({...Q,output:!1,progress:!1},Y,!1):{prefix:"",suffix:""},j=Q?H1({...Q,output:!1,reads:!1},$.progressDir,Z===$.firstProgressIndex):{prefix:"",suffix:""},U=y1(Q?.output,$.ctx.cwd,Y,$.outputBaseDir),G=OJ(`${H.prefix}${$.taskTexts[Z]}${j.suffix}`,U),z=new AbortController;if($.foregroundControl)$.foregroundControl.currentAgent=J.agent,$.foregroundControl.currentIndex=Z,$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),$.foregroundControl.interrupt=()=>{if(z.signal.aborted)return!1;return z.abort(),$.foregroundControl.currentActivityState=void 0,$.foregroundControl.updatedAt=Date.now(),!0};let V=$.agents.find((B)=>B.name===J.agent);return LJ($.ctx.cwd,$.agents,J.agent,G,{parentSessionId:$.ctx.sessionManager.getSessionId()??void 0,cwd:Y,signal:$.signal,interruptSignal:z.signal,allowIntercomDetach:V?.systemPrompt?.includes(V1)===!0,intercomEvents:$.intercomEvents,runId:$.runId,index:Z,sessionDir:$.sessionDirForIndex(Z),sessionFile:$.sessionFileForTask(J.agent,Z),share:$.shareEnabled,artifactsDir:$.artifactConfig.enabled?$.artifactsDir:void 0,artifactConfig:$.artifactConfig,maxOutput:$.maxOutput,outputPath:U,outputMode:Q?.outputMode,maxSubagentDepth:$.maxSubagentDepths[Z],controlConfig:$.controlConfig,onControlEvent:$.onControlEvent,onDetachedExit:(B)=>B9($.state,{runId:$.runId,mode:"parallel",cwd:Y,index:Z,result:B}),intercomSessionName:$.childIntercomTarget?.(J.agent,Z),orchestratorIntercomTarget:$.orchestratorIntercomTarget,nestedRoute:$.foregroundControl?.nestedRoute,modelOverride:$.modelOverrides[Z],thinkingOverride:$.thinkingOverrideForTask(J.agent,Z),availableModels:$.availableModels,preferredModelProvider:$.ctx.model?.provider,modelScope:$.modelScope,skills:X===!1?[]:X,acceptance:J.acceptance,acceptanceContext:{mode:"parallel"},timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,turnBudget:$.turnBudget,toolBudget:$.toolBudgets[Z],onUpdate:$.onUpdate?(B)=>{let K=B.details?.results||[],W=B.details?.progress||[];if($.foregroundControl&&W.length>0){let _=W[0];$.foregroundControl.currentAgent=J.agent,$.foregroundControl.currentIndex=Z,$.foregroundControl.currentActivityState=_?.activityState,$.foregroundControl.lastActivityAt=_?.lastActivityAt,$.foregroundControl.currentTool=_?.currentTool,$.foregroundControl.currentToolStartedAt=_?.currentToolStartedAt,$.foregroundControl.currentPath=_?.currentPath,$.foregroundControl.turnCount=_?.turnCount,$.foregroundControl.tokens=_?.tokens,$.foregroundControl.toolCount=_?.toolCount,$.foregroundControl.updatedAt=Date.now()}if(K.length>0)$.liveResults[Z]=K[0];if(W.length>0)$.liveProgress[Z]=W[0];let A=$.liveResults.filter((_)=>_!==void 0),F=$.liveProgress.filter((_)=>_!==void 0);$.onUpdate?.({content:B.content,details:{mode:"parallel",results:A,progress:F,controlEvents:B.details?.controlEvents,totalSteps:$.tasks.length}})}:void 0}).finally(()=>{if($.foregroundControl?.currentIndex===Z)$.foregroundControl.interrupt=void 0,$.foregroundControl.updatedAt=Date.now()})},$.globalSemaphore)}async function Tz($,J){let{params:Z,effectiveCwd:Q,agents:X,ctx:Y,signal:H,runId:j,sessionDirForIndex:U,sessionFileForIndex:G,sessionFileForTask:z,thinkingOverrideForTask:V,shareEnabled:B,artifactConfig:K,artifactsDir:W,backgroundRequestedWhileClarifying:A,onUpdate:F,sessionRoot:_,controlConfig:f,contextPolicy:O}=$,y=K9($,J),C=$.intercomBridge.active?u$:void 0,T=[],h=[],b=Z.tasks,w=H4(J.config.parallel?.maxTasks),q=j4(Z.concurrency,J.config.parallel?.concurrency);if(b.length>w)return{content:[{type:"text",text:`Max ${w} tasks`}],isError:!0,details:{mode:"parallel",results:[]}};let S=[];for(let c of b){let H$=X.find((F$)=>F$.name===c.agent);if(!H$)return{content:[{type:"text",text:`Unknown agent: ${c.agent}`}],isError:!0,details:{mode:"parallel",results:[]}};S.push(H$)}let M=r0(J.config.maxSubagentDepth),N=S.map((c)=>s0(M,c.maxSubagentDepth)),E=[];for(let c=0;c<b.length;c++){let H$=p7({stepBudget:b[c]?.toolBudget,runBudget:$.toolBudget,agentBudget:S[c]?.toolBudget,configBudget:$.configToolBudget});if(H$.error)return a1(H$.error);E.push(H$.toolBudget)}if(Z.worktree){let c=s7(b,Q);if(c)return a1(c)}let n=Y.model?.provider,L=Y.modelRegistry.getAvailable().map(y0),k=b.map((c)=>c.task),o=b.map((c)=>X0(c.skill)),g=b.map((c,H$)=>({...c.output!==void 0?{output:c.output===!0?S[H$]?.output??!1:c.output}:{},...c.outputMode!==void 0?{outputMode:c.outputMode}:{},...c.reads!==void 0&&c.reads!==!0?{reads:c.reads}:{},...c.progress!==void 0?{progress:c.progress}:{},...o[H$]!==void 0?{skills:o[H$]}:{},...c.model?{model:c.model}:{}})),I=b.map((c,H$)=>B0(g[H$]?.model??S[H$]?.model,Y.model,L,n,{scope:$.modelScope,source:g[H$]?.model?"explicit":"inherited"}));if(Z.clarify===!0&&Y.hasUI){let c=S.map((z$,Y$)=>P0(z$,g[Y$])),H$=I0(Q),F$=await Y.ui.custom((z$,Y$,Z$,K$)=>new VJ(z$,Y$,S,k,"",void 0,c,L,n,H$,K$,"parallel"),{overlay:!0,overlayOptions:{anchor:"center",width:84,maxHeight:"80%"}});if(!F$||!F$.confirmed)return{content:[{type:"text",text:"Cancelled"}],details:{mode:"parallel",results:[]}};k=F$.templates;for(let z$=0;z$<F$.behaviorOverrides.length;z$++){let Y$=F$.behaviorOverrides[z$];if(Y$?.model)I[z$]=B0(Y$.model,Y.model,L,n,{scope:$.modelScope,source:"explicit"}),g[z$].model=Y$.model;if(Y$?.output!==void 0)g[z$].output=Y$.output;if(Y$?.reads!==void 0)g[z$].reads=Y$.reads;if(Y$?.progress!==void 0)g[z$].progress=Y$.progress;if(Y$?.skills!==void 0)o[z$]=Y$.skills,g[z$].skills=Y$.skills}if(F$.runInBackground){if(!I1())return{content:[{type:"text",text:"Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed."}],isError:!0,details:{mode:"parallel",results:[]}};let z$=P1(),Y$={pi:J.pi,cwd:Y.cwd,currentSessionId:J.state.currentSessionId,parentSessionId:Y.sessionManager.getSessionId()??void 0,currentModelProvider:Y.model?.provider,currentModel:Y.model,modelScope:$.modelScope},Z$=b.map((K$,_$)=>{let R=A0(O,K$.agent)?i0(k[_$]):k[_$],i=W4(R)?!1:g[_$]?.progress;return{agent:K$.agent,task:R,cwd:K$.cwd,...I[_$]?{model:I[_$]}:{},...o[_$]!==void 0?{skill:o[_$]}:{},...g[_$]?.output!==void 0?{output:g[_$].output}:{},...g[_$]?.outputMode!==void 0?{outputMode:g[_$].outputMode}:{},...g[_$]?.reads!==void 0?{reads:g[_$].reads}:{},...i!==void 0?{progress:i}:{},...K$.toolBudget!==void 0?{toolBudget:K$.toolBudget}:{},...K$.acceptance!==void 0?{acceptance:K$.acceptance}:{}}});return yJ(z$,{chain:[{parallel:Z$,concurrency:q,worktree:Z.worktree}],resultMode:"parallel",agents:X,ctx:Y$,availableModels:L,cwd:Q,maxOutput:Z.maxOutput,artifactsDir:K.enabled?W:void 0,artifactConfig:K,shareEnabled:B,sessionRoot:_,chainSkills:[],sessionFilesByFlatIndex:b.map((K$,_$)=>z(K$.agent,_$)),thinkingOverridesByFlatIndex:b.map((K$,_$)=>V(K$.agent,_$)),maxSubagentDepth:M,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:f,controlIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,childIntercomTarget:$.intercomBridge.active?(K$,_$)=>u$(z$,K$,_$):void 0,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,globalConcurrencyLimit:J.config.globalConcurrencyLimit})}}let a=S.map((c,H$)=>x0(P0(c,g[H$]),k[H$])),O$=a.findIndex((c)=>c.progress),P=Array(b.length).fill(void 0),w$=Array(b.length).fill(void 0),$$=J.state.foregroundControls.get(j),{setup:l,errorResult:v$}=Fz(Z.worktree,Q,j,b,J.config.worktreeSetupHook,J.config.worktreeSetupHookTimeoutMs,J.config.worktreeBaseDir);if(v$)return v$;try{let c=T$.join(W,"outputs",j),H$=Nz({tasks:b,behaviors:a,paramsCwd:Q,ctxCwd:Y.cwd,outputBaseDir:c,worktreeSetup:l});if(H$)return a1(H$);for(let m=0;m<b.length;m++){let R$=q9(b[m],Q,l,m),i$=y1(a[m]?.output,Y.cwd,R$,c),s=b0(a[m]?.outputMode,i$,`Parallel task ${m+1} (${b[m].agent})`);if(s)return a1(s)}let F$=O$!==-1,z$=T$.join(W,"progress",j);if(F$)v1(z$);for(let m=0;m<k.length;m++)if(A0(O,b[m].agent))k[m]=i0(k[m]);let Y$=$.deadlineAt??($.timeoutMs!==void 0?Date.now()+$.timeoutMs:void 0),Z$=await Ez({tasks:b,taskTexts:k,agents:X,ctx:Y,state:J.state,intercomEvents:J.pi.events,signal:H,runId:j,sessionDirForIndex:U,sessionFileForIndex:G,sessionFileForTask:z,thinkingOverrideForTask:V,shareEnabled:B,artifactConfig:K,artifactsDir:W,outputBaseDir:c,maxOutput:Z.maxOutput,paramsCwd:Q,progressDir:z$,availableModels:L,modelScope:$.modelScope,modelOverrides:I,behaviors:a,firstProgressIndex:F$?-1:O$,controlConfig:f,onControlEvent:y,childIntercomTarget:C?(m,R$)=>C(j,m,R$):void 0,orchestratorIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,foregroundControl:$$,concurrencyLimit:q,globalSemaphore:new xJ(J.config.globalConcurrencyLimit??u2),maxSubagentDepths:N,liveResults:P,liveProgress:w$,onUpdate:F,worktreeSetup:l,timeoutMs:$.timeoutMs,deadlineAt:Y$,turnBudget:$.turnBudget,toolBudgets:E});for(let m=0;m<Z$.length;m++){let R$=Z$[m];MJ(R$.agent,k[m],R$.exitCode,R$.progressSummary?.durationMs??0)}for(let m of Z$){if(m.progress)T.push(m.progress);if(m.artifactPaths)h.push(m.artifactPaths)}if($$)i1($$),D1(j,Z$,$$.nestedChildren);let K$=Z$.find((m)=>m.interrupted),_$=jJ({mode:"parallel",runId:j,results:Z$,progress:Z.includeProgress?T:void 0,artifacts:h.length?{dir:W,files:h}:void 0,totalChildUsage:uJ(Z$),totalCost:HJ(Z$)});if(G9(J.state,{runId:j,mode:"parallel",cwd:Q,results:_$.results}),K$)return{content:[{type:"text",text:`Parallel run paused after interrupt (${K$.agent}). Waiting for explicit next action.`}],details:_$};let R=Z$.findIndex((m)=>m.detached),i=R>=0?Z$[R]:void 0;if(i)return{content:[{type:"text",text:`Parallel run detached for intercom coordination (${i.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.`}],details:_$};if($$)i1($$);let n$=await W9({pi:J.pi,intercomBridge:$.intercomBridge,runId:j,mode:"parallel",details:_$,...$$?.nestedChildren?.length?{nestedChildren:$$.nestedChildren}:{}});if(n$)return{content:[{type:"text",text:n$.text}],details:n$.details};let J$=Mz(l,W,b),c$=Z$.filter((m)=>m.exitCode===0).length,N$=A?" (background requested, but clarify kept this run foreground)":"",X$=ZJ(Z$.map((m)=>({agent:m.agent,output:m.truncation?.text||f0(m),exitCode:m.exitCode,error:m.error,timedOut:m.timedOut})),(m,R$)=>`=== Task ${m+1}: ${R$} ===`),A$=`${c$}/${Z$.length} succeeded${N$}`;return{content:[{type:"text",text:J$?`${A$}
|
|
1049
|
+
${output}` : result.error;
|
|
1050
|
+
}
|
|
1051
|
+
return output || result.error || "(no output)";
|
|
1052
|
+
}
|
|
1053
|
+
function formatFailedSingleRunOutput(result, displayOutput) {
|
|
1054
|
+
const error = result.error || "Failed";
|
|
1055
|
+
const output = displayOutput.trim();
|
|
1056
|
+
const lines = [error];
|
|
1057
|
+
if (output && output !== error.trim()) {
|
|
1058
|
+
lines.push("", "Output:", output);
|
|
1059
|
+
}
|
|
1060
|
+
if (result.artifactPaths?.outputPath) {
|
|
1061
|
+
lines.push("", `Output artifact: ${result.artifactPaths.outputPath}`);
|
|
1062
|
+
}
|
|
1063
|
+
return lines.join(`
|
|
1064
|
+
`);
|
|
1065
|
+
}
|
|
1066
|
+
function createForegroundControlNotifier(data, deps) {
|
|
1067
|
+
return (event) => emitControlNotification({
|
|
1068
|
+
pi: deps.pi,
|
|
1069
|
+
controlConfig: data.controlConfig,
|
|
1070
|
+
intercomBridge: data.intercomBridge,
|
|
1071
|
+
event
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
async function emitForegroundResultIntercom(input) {
|
|
1075
|
+
if (!input.intercomBridge.active || !input.intercomBridge.orchestratorTarget)
|
|
1076
|
+
return null;
|
|
1077
|
+
const children = input.results.flatMap((result, index) => result.detached ? [] : [{
|
|
1078
|
+
agent: result.agent,
|
|
1079
|
+
status: resolveSubagentResultStatus({
|
|
1080
|
+
exitCode: result.exitCode,
|
|
1081
|
+
interrupted: result.interrupted,
|
|
1082
|
+
detached: result.detached
|
|
1083
|
+
}),
|
|
1084
|
+
summary: resultSummaryForIntercom(result),
|
|
1085
|
+
index,
|
|
1086
|
+
artifactPath: result.artifactPaths?.outputPath,
|
|
1087
|
+
sessionPath: result.sessionFile,
|
|
1088
|
+
intercomTarget: resolveSubagentIntercomTarget(input.runId, result.agent, index)
|
|
1089
|
+
}]);
|
|
1090
|
+
if (children.length === 0)
|
|
1091
|
+
return null;
|
|
1092
|
+
const payload = buildSubagentResultIntercomPayload({
|
|
1093
|
+
to: input.intercomBridge.orchestratorTarget,
|
|
1094
|
+
runId: input.runId,
|
|
1095
|
+
mode: input.mode,
|
|
1096
|
+
source: "foreground",
|
|
1097
|
+
children: attachNestedChildrenToResultChildren(input.runId, children, input.nestedChildren),
|
|
1098
|
+
...typeof input.chainSteps === "number" ? { chainSteps: input.chainSteps } : {}
|
|
1099
|
+
});
|
|
1100
|
+
const delivered = await deliverSubagentResultIntercomEvent(input.pi.events, payload);
|
|
1101
|
+
if (!delivered)
|
|
1102
|
+
return null;
|
|
1103
|
+
return payload;
|
|
1104
|
+
}
|
|
1105
|
+
async function maybeBuildForegroundIntercomReceipt(input) {
|
|
1106
|
+
const payload = await emitForegroundResultIntercom({
|
|
1107
|
+
pi: input.pi,
|
|
1108
|
+
intercomBridge: input.intercomBridge,
|
|
1109
|
+
runId: input.runId,
|
|
1110
|
+
mode: input.mode,
|
|
1111
|
+
results: input.details.results,
|
|
1112
|
+
...typeof input.details.totalSteps === "number" ? { chainSteps: input.details.totalSteps } : {},
|
|
1113
|
+
...input.nestedChildren?.length ? { nestedChildren: input.nestedChildren } : {}
|
|
1114
|
+
});
|
|
1115
|
+
if (!payload)
|
|
1116
|
+
return null;
|
|
1117
|
+
return {
|
|
1118
|
+
text: formatSubagentResultReceipt({ mode: input.mode, runId: input.runId, payload }),
|
|
1119
|
+
details: stripDetailsOutputsForIntercomReceipt(input.details)
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
function validateExecutionInput(params, agents, hasChain, hasTasks, hasSingle, allowClarifyTaskPrompt) {
|
|
1123
|
+
if (Number(hasChain) + Number(hasTasks) + Number(hasSingle) !== 1) {
|
|
1124
|
+
return {
|
|
1125
|
+
content: [
|
|
1126
|
+
{
|
|
1127
|
+
type: "text",
|
|
1128
|
+
text: `Provide exactly one mode. Agents: ${agents.map((a) => a.name).join(", ") || "none"}`
|
|
1129
|
+
}
|
|
1130
|
+
],
|
|
1131
|
+
isError: true,
|
|
1132
|
+
details: { mode: "single", results: [] }
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
const acceptanceErrors = validateExecutionAcceptance(params);
|
|
1136
|
+
if (acceptanceErrors.length > 0) {
|
|
1137
|
+
return {
|
|
1138
|
+
content: [{ type: "text", text: acceptanceErrors.join(" ") }],
|
|
1139
|
+
isError: true,
|
|
1140
|
+
details: { mode: getRequestedModeLabel(params), results: [] }
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
if (hasSingle && params.agent && !agents.find((agent) => agent.name === params.agent)) {
|
|
1144
|
+
return {
|
|
1145
|
+
content: [{ type: "text", text: `Unknown agent: ${params.agent}` }],
|
|
1146
|
+
isError: true,
|
|
1147
|
+
details: { mode: "single", results: [] }
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
if (hasTasks && params.tasks) {
|
|
1151
|
+
for (let i = 0;i < params.tasks.length; i++) {
|
|
1152
|
+
const task = params.tasks[i];
|
|
1153
|
+
if (!agents.find((agent) => agent.name === task.agent)) {
|
|
1154
|
+
return {
|
|
1155
|
+
content: [{ type: "text", text: `Unknown agent: ${task.agent} (task ${i + 1})` }],
|
|
1156
|
+
isError: true,
|
|
1157
|
+
details: { mode: "parallel", results: [] }
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
if (hasChain && params.chain) {
|
|
1163
|
+
if (params.chain.length === 0) {
|
|
1164
|
+
return {
|
|
1165
|
+
content: [{ type: "text", text: "Chain must have at least one step" }],
|
|
1166
|
+
isError: true,
|
|
1167
|
+
details: { mode: "chain", results: [] }
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
const firstStep = params.chain[0];
|
|
1171
|
+
if (isParallelStep(firstStep)) {
|
|
1172
|
+
const missingTaskIndex = firstStep.parallel.findIndex((t) => !t.task);
|
|
1173
|
+
if (missingTaskIndex !== -1) {
|
|
1174
|
+
return {
|
|
1175
|
+
content: [{ type: "text", text: `First parallel step: task ${missingTaskIndex + 1} must have a task (no previous output to reference)` }],
|
|
1176
|
+
isError: true,
|
|
1177
|
+
details: { mode: "chain", results: [] }
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
} else if (isDynamicParallelStep(firstStep)) {
|
|
1181
|
+
return {
|
|
1182
|
+
content: [{ type: "text", text: "First step in chain cannot be dynamic fanout; expand.from requires a prior structured named output" }],
|
|
1183
|
+
isError: true,
|
|
1184
|
+
details: { mode: "chain", results: [] }
|
|
1185
|
+
};
|
|
1186
|
+
} else if (!firstStep.task && !params.task && !allowClarifyTaskPrompt) {
|
|
1187
|
+
return {
|
|
1188
|
+
content: [{ type: "text", text: "First step in chain must have a task" }],
|
|
1189
|
+
isError: true,
|
|
1190
|
+
details: { mode: "chain", results: [] }
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
for (let i = 0;i < params.chain.length; i++) {
|
|
1194
|
+
const step = params.chain[i];
|
|
1195
|
+
const stepAgents = getStepAgents(step);
|
|
1196
|
+
for (const agentName of stepAgents) {
|
|
1197
|
+
if (!agents.find((a) => a.name === agentName)) {
|
|
1198
|
+
return {
|
|
1199
|
+
content: [{ type: "text", text: `Unknown agent: ${agentName} (step ${i + 1})` }],
|
|
1200
|
+
isError: true,
|
|
1201
|
+
details: { mode: "chain", results: [] }
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
if (isParallelStep(step) && step.parallel.length === 0) {
|
|
1206
|
+
return {
|
|
1207
|
+
content: [{ type: "text", text: `Parallel step ${i + 1} must have at least one task` }],
|
|
1208
|
+
isError: true,
|
|
1209
|
+
details: { mode: "chain", results: [] }
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
return null;
|
|
1215
|
+
}
|
|
1216
|
+
function validateExecutionChainBindings(params, dynamicFanoutMaxItems) {
|
|
1217
|
+
if ((params.chain?.length ?? 0) === 0)
|
|
1218
|
+
return null;
|
|
1219
|
+
try {
|
|
1220
|
+
validateChainOutputBindingsWithContext(params.chain, { maxItems: dynamicFanoutMaxItems });
|
|
1221
|
+
} catch (error) {
|
|
1222
|
+
if (error instanceof ChainOutputValidationError) {
|
|
1223
|
+
return {
|
|
1224
|
+
content: [{ type: "text", text: error.message }],
|
|
1225
|
+
isError: true,
|
|
1226
|
+
details: { mode: "chain", results: [] }
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
throw error;
|
|
1230
|
+
}
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
function validateExecutionAcceptance(params) {
|
|
1234
|
+
const errors = [];
|
|
1235
|
+
errors.push(...validateAcceptanceInput(params.acceptance, "acceptance"));
|
|
1236
|
+
for (const [index, task] of (params.tasks ?? []).entries()) {
|
|
1237
|
+
errors.push(...validateAcceptanceInput(task.acceptance, `tasks[${index}].acceptance`));
|
|
1238
|
+
}
|
|
1239
|
+
for (const [stepIndex, step] of (params.chain ?? []).entries()) {
|
|
1240
|
+
errors.push(...validateAcceptanceInput(step.acceptance, `chain[${stepIndex}].acceptance`));
|
|
1241
|
+
if (isParallelStep(step)) {
|
|
1242
|
+
for (const [taskIndex, task] of step.parallel.entries()) {
|
|
1243
|
+
errors.push(...validateAcceptanceInput(task.acceptance, `chain[${stepIndex}].parallel[${taskIndex}].acceptance`));
|
|
1244
|
+
}
|
|
1245
|
+
} else if (isDynamicParallelStep(step)) {
|
|
1246
|
+
errors.push(...validateAcceptanceInput(step.parallel.acceptance, `chain[${stepIndex}].parallel.acceptance`));
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
return errors;
|
|
1250
|
+
}
|
|
1251
|
+
function getRequestedModeLabel(params) {
|
|
1252
|
+
if ((params.chain?.length ?? 0) > 0)
|
|
1253
|
+
return "chain";
|
|
1254
|
+
if ((params.tasks?.length ?? 0) > 0)
|
|
1255
|
+
return "parallel";
|
|
1256
|
+
if (params.agent)
|
|
1257
|
+
return "single";
|
|
1258
|
+
return "single";
|
|
1259
|
+
}
|
|
1260
|
+
function resolveAgentDefaultContextPolicy(params, agents) {
|
|
1261
|
+
if (params.context !== undefined) {
|
|
1262
|
+
return resolveExplicitContextPolicy(params);
|
|
1263
|
+
}
|
|
1264
|
+
const byName = new Map(agents.map((agent) => [agent.name, agent]));
|
|
1265
|
+
const contextForAgent = (agentName) => byName.get(agentName)?.defaultContext === "fork" ? "fork" : "fresh";
|
|
1266
|
+
const usesFork = collectRequestedAgentNames(params).some((name) => contextForAgent(name) === "fork");
|
|
1267
|
+
return {
|
|
1268
|
+
params: usesFork ? { ...params, context: "fork" } : params,
|
|
1269
|
+
contextForAgent,
|
|
1270
|
+
usesFork
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
function resolveExplicitContextPolicy(params) {
|
|
1274
|
+
const context = params.context === "fork" ? "fork" : "fresh";
|
|
1275
|
+
return {
|
|
1276
|
+
params,
|
|
1277
|
+
contextForAgent: () => context,
|
|
1278
|
+
usesFork: context === "fork"
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
function collectRequestedAgentNames(params) {
|
|
1282
|
+
const names = [];
|
|
1283
|
+
if (params.agent)
|
|
1284
|
+
names.push(params.agent);
|
|
1285
|
+
for (const task of params.tasks ?? [])
|
|
1286
|
+
names.push(task.agent);
|
|
1287
|
+
for (const step of params.chain ?? [])
|
|
1288
|
+
names.push(...getStepAgents(step));
|
|
1289
|
+
return names;
|
|
1290
|
+
}
|
|
1291
|
+
function shouldForkAgent(contextPolicy, agentName) {
|
|
1292
|
+
return contextPolicy.contextForAgent(agentName) === "fork";
|
|
1293
|
+
}
|
|
1294
|
+
function buildRequestedModeError(params, message) {
|
|
1295
|
+
return withForkContext({
|
|
1296
|
+
content: [{ type: "text", text: message }],
|
|
1297
|
+
isError: true,
|
|
1298
|
+
details: { mode: getRequestedModeLabel(params), results: [] }
|
|
1299
|
+
}, params.context);
|
|
1300
|
+
}
|
|
1301
|
+
function resolveForegroundTimeout(params) {
|
|
1302
|
+
const rawTimeout = params.timeoutMs;
|
|
1303
|
+
const rawMaxRuntime = params.maxRuntimeMs;
|
|
1304
|
+
if (rawTimeout === undefined && rawMaxRuntime === undefined)
|
|
1305
|
+
return {};
|
|
1306
|
+
for (const [name, value] of [["timeoutMs", rawTimeout], ["maxRuntimeMs", rawMaxRuntime]]) {
|
|
1307
|
+
if (value === undefined)
|
|
1308
|
+
continue;
|
|
1309
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
1310
|
+
return { error: `${name} must be a positive integer.` };
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
if (rawTimeout !== undefined && rawMaxRuntime !== undefined && rawTimeout !== rawMaxRuntime) {
|
|
1314
|
+
return { error: "timeoutMs and maxRuntimeMs are aliases; provide only one value or use the same value for both." };
|
|
1315
|
+
}
|
|
1316
|
+
return { timeoutMs: rawTimeout ?? rawMaxRuntime };
|
|
1317
|
+
}
|
|
1318
|
+
function resolveTurnBudget(params, config) {
|
|
1319
|
+
const raw = params.turnBudget ?? config.turnBudget;
|
|
1320
|
+
if (raw === undefined)
|
|
1321
|
+
return {};
|
|
1322
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
1323
|
+
return { error: "turnBudget must be an object with maxTurns and optional graceTurns." };
|
|
1324
|
+
if (typeof raw.maxTurns !== "number" || !Number.isInteger(raw.maxTurns) || raw.maxTurns < 1) {
|
|
1325
|
+
return { error: "turnBudget.maxTurns must be an integer >= 1." };
|
|
1326
|
+
}
|
|
1327
|
+
const graceTurns = raw.graceTurns ?? DEFAULT_TURN_BUDGET_GRACE_TURNS;
|
|
1328
|
+
if (typeof graceTurns !== "number" || !Number.isInteger(graceTurns) || graceTurns < 0) {
|
|
1329
|
+
return { error: "turnBudget.graceTurns must be an integer >= 0." };
|
|
1330
|
+
}
|
|
1331
|
+
return { turnBudget: { maxTurns: raw.maxTurns, graceTurns } };
|
|
1332
|
+
}
|
|
1333
|
+
function resolveToolBudget(raw, label = "toolBudget") {
|
|
1334
|
+
const resolved = validateToolBudgetConfig(raw, label);
|
|
1335
|
+
return { toolBudget: resolved.budget, error: resolved.error };
|
|
1336
|
+
}
|
|
1337
|
+
function resolveEffectiveToolBudget(input) {
|
|
1338
|
+
if (input.stepBudget !== undefined)
|
|
1339
|
+
return resolveToolBudget(input.stepBudget, "toolBudget");
|
|
1340
|
+
if (input.runBudget !== undefined)
|
|
1341
|
+
return { toolBudget: input.runBudget };
|
|
1342
|
+
if (input.agentBudget !== undefined)
|
|
1343
|
+
return resolveToolBudget(input.agentBudget, "agent.toolBudget");
|
|
1344
|
+
return resolveToolBudget(input.configBudget, "config.toolBudget");
|
|
1345
|
+
}
|
|
1346
|
+
function expandTopLevelTaskCounts(tasks) {
|
|
1347
|
+
const expanded = [];
|
|
1348
|
+
for (let taskIndex = 0;taskIndex < tasks.length; taskIndex++) {
|
|
1349
|
+
const task = tasks[taskIndex];
|
|
1350
|
+
const rawCount = task.count;
|
|
1351
|
+
if (rawCount !== undefined && (typeof rawCount !== "number" || !Number.isInteger(rawCount) || rawCount < 1)) {
|
|
1352
|
+
return { error: `tasks[${taskIndex}].count must be an integer >= 1` };
|
|
1353
|
+
}
|
|
1354
|
+
const { count, ...concreteTask } = task;
|
|
1355
|
+
for (let repeat = 0;repeat < (rawCount ?? 1); repeat++) {
|
|
1356
|
+
expanded.push({ ...concreteTask });
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
return { tasks: expanded };
|
|
1360
|
+
}
|
|
1361
|
+
function expandChainParallelCounts(chain) {
|
|
1362
|
+
const expandedChain = [];
|
|
1363
|
+
for (let stepIndex = 0;stepIndex < chain.length; stepIndex++) {
|
|
1364
|
+
const step = chain[stepIndex];
|
|
1365
|
+
if (!isParallelStep(step)) {
|
|
1366
|
+
expandedChain.push(step);
|
|
1367
|
+
continue;
|
|
1368
|
+
}
|
|
1369
|
+
const expandedParallel = [];
|
|
1370
|
+
for (let taskIndex = 0;taskIndex < step.parallel.length; taskIndex++) {
|
|
1371
|
+
const task = step.parallel[taskIndex];
|
|
1372
|
+
const rawCount = task.count;
|
|
1373
|
+
if (rawCount !== undefined && (typeof rawCount !== "number" || !Number.isInteger(rawCount) || rawCount < 1)) {
|
|
1374
|
+
return { error: `chain[${stepIndex}].parallel[${taskIndex}].count must be an integer >= 1` };
|
|
1375
|
+
}
|
|
1376
|
+
const { count, ...concreteTask } = task;
|
|
1377
|
+
for (let repeat = 0;repeat < (rawCount ?? 1); repeat++) {
|
|
1378
|
+
expandedParallel.push({ ...concreteTask });
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
expandedChain.push({ ...step, parallel: expandedParallel });
|
|
1382
|
+
}
|
|
1383
|
+
return { chain: expandedChain };
|
|
1384
|
+
}
|
|
1385
|
+
function normalizeRepeatedParallelCounts(params) {
|
|
1386
|
+
if (params.tasks) {
|
|
1387
|
+
const expandedTasks = expandTopLevelTaskCounts(params.tasks);
|
|
1388
|
+
if (expandedTasks.error) {
|
|
1389
|
+
return { error: buildRequestedModeError(params, expandedTasks.error) };
|
|
1390
|
+
}
|
|
1391
|
+
return { params: { ...params, tasks: expandedTasks.tasks } };
|
|
1392
|
+
}
|
|
1393
|
+
if (params.chain) {
|
|
1394
|
+
const expandedChain = expandChainParallelCounts(params.chain);
|
|
1395
|
+
if (expandedChain.error) {
|
|
1396
|
+
return { error: buildRequestedModeError(params, expandedChain.error) };
|
|
1397
|
+
}
|
|
1398
|
+
return { params: { ...params, chain: expandedChain.chain } };
|
|
1399
|
+
}
|
|
1400
|
+
return { params };
|
|
1401
|
+
}
|
|
1402
|
+
function withForkContext(result, context) {
|
|
1403
|
+
if (context !== "fork" || !result.details)
|
|
1404
|
+
return result;
|
|
1405
|
+
return {
|
|
1406
|
+
...result,
|
|
1407
|
+
details: {
|
|
1408
|
+
...result.details,
|
|
1409
|
+
context: "fork"
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
function toExecutionErrorResult(params, error) {
|
|
1414
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1415
|
+
return withForkContext({
|
|
1416
|
+
content: [{ type: "text", text: message }],
|
|
1417
|
+
isError: true,
|
|
1418
|
+
details: { mode: getRequestedModeLabel(params), results: [] }
|
|
1419
|
+
}, params.context);
|
|
1420
|
+
}
|
|
1421
|
+
function collectChainSessionFiles(chain, sessionFileForTask, dynamicFanoutMaxItems) {
|
|
1422
|
+
const sessionFiles = [];
|
|
1423
|
+
let flatIndex = 0;
|
|
1424
|
+
for (const step of chain) {
|
|
1425
|
+
if (isParallelStep(step)) {
|
|
1426
|
+
for (const task of step.parallel) {
|
|
1427
|
+
sessionFiles.push(sessionFileForTask(task.agent, flatIndex));
|
|
1428
|
+
flatIndex++;
|
|
1429
|
+
}
|
|
1430
|
+
continue;
|
|
1431
|
+
}
|
|
1432
|
+
if (isDynamicParallelStep(step)) {
|
|
1433
|
+
const maxItems = step.expand.maxItems ?? dynamicFanoutMaxItems ?? 0;
|
|
1434
|
+
for (let itemIndex = 0;itemIndex < maxItems; itemIndex++) {
|
|
1435
|
+
sessionFiles.push(sessionFileForTask(step.parallel.agent, flatIndex));
|
|
1436
|
+
flatIndex++;
|
|
1437
|
+
}
|
|
1438
|
+
continue;
|
|
1439
|
+
}
|
|
1440
|
+
sessionFiles.push(sessionFileForTask(step.agent, flatIndex));
|
|
1441
|
+
flatIndex++;
|
|
1442
|
+
}
|
|
1443
|
+
return sessionFiles;
|
|
1444
|
+
}
|
|
1445
|
+
function collectChainThinkingOverrides(chain, thinkingOverrideForTask, dynamicFanoutMaxItems) {
|
|
1446
|
+
const thinkingOverrides = [];
|
|
1447
|
+
let flatIndex = 0;
|
|
1448
|
+
for (const step of chain) {
|
|
1449
|
+
if (isParallelStep(step)) {
|
|
1450
|
+
for (const task of step.parallel) {
|
|
1451
|
+
thinkingOverrides.push(thinkingOverrideForTask(task.agent, flatIndex));
|
|
1452
|
+
flatIndex++;
|
|
1453
|
+
}
|
|
1454
|
+
continue;
|
|
1455
|
+
}
|
|
1456
|
+
if (isDynamicParallelStep(step)) {
|
|
1457
|
+
const maxItems = step.expand.maxItems ?? dynamicFanoutMaxItems ?? 0;
|
|
1458
|
+
for (let itemIndex = 0;itemIndex < maxItems; itemIndex++) {
|
|
1459
|
+
thinkingOverrides.push(thinkingOverrideForTask(step.parallel.agent, flatIndex));
|
|
1460
|
+
flatIndex++;
|
|
1461
|
+
}
|
|
1462
|
+
continue;
|
|
1463
|
+
}
|
|
1464
|
+
thinkingOverrides.push(thinkingOverrideForTask(step.agent, flatIndex));
|
|
1465
|
+
flatIndex++;
|
|
1466
|
+
}
|
|
1467
|
+
return thinkingOverrides;
|
|
1468
|
+
}
|
|
1469
|
+
function wrapChainTasksForFork(chain, contextPolicy) {
|
|
1470
|
+
return chain.map((step, stepIndex) => {
|
|
1471
|
+
if (isParallelStep(step)) {
|
|
1472
|
+
return {
|
|
1473
|
+
...step,
|
|
1474
|
+
parallel: step.parallel.map((task) => ({
|
|
1475
|
+
...task,
|
|
1476
|
+
task: shouldForkAgent(contextPolicy, task.agent) ? wrapForkTask(task.task ?? "{previous}") : task.task
|
|
1477
|
+
}))
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
if (isDynamicParallelStep(step)) {
|
|
1481
|
+
return {
|
|
1482
|
+
...step,
|
|
1483
|
+
parallel: {
|
|
1484
|
+
...step.parallel,
|
|
1485
|
+
task: shouldForkAgent(contextPolicy, step.parallel.agent) ? wrapForkTask(step.parallel.task ?? "{previous}") : step.parallel.task
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
const sequential = step;
|
|
1490
|
+
return {
|
|
1491
|
+
...sequential,
|
|
1492
|
+
task: shouldForkAgent(contextPolicy, sequential.agent) ? wrapForkTask(sequential.task ?? (stepIndex === 0 ? "{task}" : "{previous}")) : sequential.task
|
|
1493
|
+
};
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
function preflightForkSessionsForStaticTasks(params, contextPolicy, sessionFileForTask, dynamicFanoutMaxItems) {
|
|
1497
|
+
if (!contextPolicy.usesFork)
|
|
1498
|
+
return;
|
|
1499
|
+
if (params.agent) {
|
|
1500
|
+
if (shouldForkAgent(contextPolicy, params.agent))
|
|
1501
|
+
sessionFileForTask(params.agent, 0);
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
if (params.tasks) {
|
|
1505
|
+
params.tasks.forEach((task, index) => {
|
|
1506
|
+
if (shouldForkAgent(contextPolicy, task.agent))
|
|
1507
|
+
sessionFileForTask(task.agent, index);
|
|
1508
|
+
});
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
if (!params.chain?.length)
|
|
1512
|
+
return;
|
|
1513
|
+
let flatIndex = 0;
|
|
1514
|
+
for (const step of params.chain) {
|
|
1515
|
+
if (isParallelStep(step)) {
|
|
1516
|
+
for (const task of step.parallel) {
|
|
1517
|
+
if (shouldForkAgent(contextPolicy, task.agent))
|
|
1518
|
+
sessionFileForTask(task.agent, flatIndex);
|
|
1519
|
+
flatIndex++;
|
|
1520
|
+
}
|
|
1521
|
+
continue;
|
|
1522
|
+
}
|
|
1523
|
+
if (isDynamicParallelStep(step)) {
|
|
1524
|
+
const maxItems = step.expand.maxItems ?? dynamicFanoutMaxItems ?? 0;
|
|
1525
|
+
if (shouldForkAgent(contextPolicy, step.parallel.agent)) {
|
|
1526
|
+
for (let itemIndex = 0;itemIndex < maxItems; itemIndex++)
|
|
1527
|
+
sessionFileForTask(step.parallel.agent, flatIndex + itemIndex);
|
|
1528
|
+
}
|
|
1529
|
+
flatIndex += maxItems;
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
const sequential = step;
|
|
1533
|
+
if (shouldForkAgent(contextPolicy, sequential.agent))
|
|
1534
|
+
sessionFileForTask(sequential.agent, flatIndex);
|
|
1535
|
+
flatIndex++;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
function runAsyncPath(data, deps) {
|
|
1539
|
+
const {
|
|
1540
|
+
params,
|
|
1541
|
+
effectiveCwd,
|
|
1542
|
+
agents,
|
|
1543
|
+
ctx,
|
|
1544
|
+
shareEnabled,
|
|
1545
|
+
sessionRoot,
|
|
1546
|
+
sessionFileForIndex,
|
|
1547
|
+
sessionFileForTask,
|
|
1548
|
+
thinkingOverrideForTask,
|
|
1549
|
+
artifactConfig,
|
|
1550
|
+
artifactsDir,
|
|
1551
|
+
effectiveAsync,
|
|
1552
|
+
controlConfig,
|
|
1553
|
+
intercomBridge,
|
|
1554
|
+
nestedRoute,
|
|
1555
|
+
contextPolicy
|
|
1556
|
+
} = data;
|
|
1557
|
+
const hasChain = (params.chain?.length ?? 0) > 0;
|
|
1558
|
+
const hasTasks = (params.tasks?.length ?? 0) > 0;
|
|
1559
|
+
const hasSingle = !hasChain && !hasTasks && Boolean(params.agent);
|
|
1560
|
+
if (!effectiveAsync)
|
|
1561
|
+
return null;
|
|
1562
|
+
if (hasChain && params.chain) {
|
|
1563
|
+
const chainWorktreeTaskCwdError = buildChainWorktreeTaskCwdError(params.chain, effectiveCwd);
|
|
1564
|
+
if (chainWorktreeTaskCwdError) {
|
|
1565
|
+
return {
|
|
1566
|
+
content: [{ type: "text", text: chainWorktreeTaskCwdError }],
|
|
1567
|
+
isError: true,
|
|
1568
|
+
details: { mode: "chain", results: [] }
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
if (hasTasks && params.tasks) {
|
|
1573
|
+
const maxParallelTasks = resolveTopLevelParallelMaxTasks(deps.config.parallel?.maxTasks);
|
|
1574
|
+
if (params.tasks.length > maxParallelTasks) {
|
|
1575
|
+
return buildParallelModeError(`Max ${maxParallelTasks} tasks`);
|
|
1576
|
+
}
|
|
1577
|
+
if (params.worktree) {
|
|
1578
|
+
const worktreeTaskCwdError = buildParallelWorktreeTaskCwdError(params.tasks, effectiveCwd);
|
|
1579
|
+
if (worktreeTaskCwdError)
|
|
1580
|
+
return buildParallelModeError(worktreeTaskCwdError);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
if (!isAsyncAvailable()) {
|
|
1584
|
+
return {
|
|
1585
|
+
content: [{ type: "text", text: "Async mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed." }],
|
|
1586
|
+
isError: true,
|
|
1587
|
+
details: { mode: "single", results: [] }
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
const id = randomUUID();
|
|
1591
|
+
const asyncCtx = {
|
|
1592
|
+
pi: deps.pi,
|
|
1593
|
+
cwd: ctx.cwd,
|
|
1594
|
+
currentSessionId: deps.state.currentSessionId,
|
|
1595
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
1596
|
+
currentModelProvider: ctx.model?.provider,
|
|
1597
|
+
currentModel: ctx.model,
|
|
1598
|
+
modelScope: data.modelScope
|
|
1599
|
+
};
|
|
1600
|
+
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
1601
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
1602
|
+
const currentProvider = ctx.model?.provider;
|
|
1603
|
+
const controlIntercomTarget = intercomBridge.active ? intercomBridge.orchestratorTarget : undefined;
|
|
1604
|
+
const childIntercomTarget = intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(id, agent, index) : undefined;
|
|
1605
|
+
if (hasTasks && params.tasks) {
|
|
1606
|
+
const agentConfigs = params.tasks.map((task) => agents.find((agent) => agent.name === task.agent));
|
|
1607
|
+
const modelOverrides = params.tasks.map((task, index) => resolveSubagentModelOverride(task.model ?? agentConfigs[index]?.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: task.model ? "explicit" : "inherited" }));
|
|
1608
|
+
const skillOverrides = params.tasks.map((task) => normalizeSkillInput(task.skill));
|
|
1609
|
+
const parallelTasks = params.tasks.map((task, index) => ({
|
|
1610
|
+
agent: task.agent,
|
|
1611
|
+
task: shouldForkAgent(contextPolicy, task.agent) ? wrapForkTask(task.task) : task.task,
|
|
1612
|
+
cwd: task.cwd,
|
|
1613
|
+
...modelOverrides[index] ? { model: modelOverrides[index] } : {},
|
|
1614
|
+
...skillOverrides[index] !== undefined ? { skill: skillOverrides[index] } : {},
|
|
1615
|
+
...task.output === true ? agentConfigs[index]?.output ? { output: agentConfigs[index].output } : {} : task.output !== undefined ? { output: task.output } : {},
|
|
1616
|
+
...task.outputMode !== undefined ? { outputMode: task.outputMode } : {},
|
|
1617
|
+
...task.reads !== undefined && task.reads !== true ? { reads: task.reads } : {},
|
|
1618
|
+
...task.progress !== undefined ? { progress: task.progress } : {},
|
|
1619
|
+
...task.toolBudget !== undefined ? { toolBudget: task.toolBudget } : {},
|
|
1620
|
+
...task.acceptance !== undefined ? { acceptance: task.acceptance } : {}
|
|
1621
|
+
}));
|
|
1622
|
+
return executeAsyncChain(id, {
|
|
1623
|
+
chain: [{
|
|
1624
|
+
parallel: parallelTasks,
|
|
1625
|
+
concurrency: resolveTopLevelParallelConcurrency(params.concurrency, deps.config.parallel?.concurrency),
|
|
1626
|
+
worktree: params.worktree
|
|
1627
|
+
}],
|
|
1628
|
+
resultMode: "parallel",
|
|
1629
|
+
agents,
|
|
1630
|
+
ctx: asyncCtx,
|
|
1631
|
+
availableModels,
|
|
1632
|
+
cwd: effectiveCwd,
|
|
1633
|
+
maxOutput: params.maxOutput,
|
|
1634
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
1635
|
+
artifactConfig,
|
|
1636
|
+
shareEnabled,
|
|
1637
|
+
sessionRoot,
|
|
1638
|
+
chainSkills: [],
|
|
1639
|
+
sessionFilesByFlatIndex: params.tasks.map((task, index) => sessionFileForTask(task.agent, index)),
|
|
1640
|
+
thinkingOverridesByFlatIndex: params.tasks.map((task, index) => thinkingOverrideForTask(task.agent, index)),
|
|
1641
|
+
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1642
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
1643
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
1644
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
1645
|
+
controlConfig,
|
|
1646
|
+
controlIntercomTarget,
|
|
1647
|
+
childIntercomTarget,
|
|
1648
|
+
nestedRoute,
|
|
1649
|
+
timeoutMs: data.timeoutMs,
|
|
1650
|
+
turnBudget: data.turnBudget,
|
|
1651
|
+
toolBudget: data.toolBudget,
|
|
1652
|
+
configToolBudget: data.configToolBudget,
|
|
1653
|
+
globalConcurrencyLimit: deps.config.globalConcurrencyLimit
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
if (hasChain && params.chain) {
|
|
1657
|
+
const normalized = normalizeSkillInput(params.skill);
|
|
1658
|
+
const chainSkills = normalized === false ? [] : normalized ?? [];
|
|
1659
|
+
const chain = wrapChainTasksForFork(params.chain, contextPolicy);
|
|
1660
|
+
return executeAsyncChain(id, {
|
|
1661
|
+
chain,
|
|
1662
|
+
task: params.task,
|
|
1663
|
+
agents,
|
|
1664
|
+
ctx: asyncCtx,
|
|
1665
|
+
availableModels,
|
|
1666
|
+
cwd: effectiveCwd,
|
|
1667
|
+
maxOutput: params.maxOutput,
|
|
1668
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
1669
|
+
artifactConfig,
|
|
1670
|
+
shareEnabled,
|
|
1671
|
+
sessionRoot,
|
|
1672
|
+
chainSkills,
|
|
1673
|
+
sessionFilesByFlatIndex: collectChainSessionFiles(chain, sessionFileForTask, deps.config.chain?.dynamicFanout?.maxItems),
|
|
1674
|
+
thinkingOverridesByFlatIndex: collectChainThinkingOverrides(chain, thinkingOverrideForTask, deps.config.chain?.dynamicFanout?.maxItems),
|
|
1675
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1676
|
+
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1677
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
1678
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
1679
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
1680
|
+
controlConfig,
|
|
1681
|
+
controlIntercomTarget,
|
|
1682
|
+
childIntercomTarget,
|
|
1683
|
+
nestedRoute,
|
|
1684
|
+
timeoutMs: data.timeoutMs,
|
|
1685
|
+
turnBudget: data.turnBudget,
|
|
1686
|
+
toolBudget: data.toolBudget,
|
|
1687
|
+
configToolBudget: data.configToolBudget,
|
|
1688
|
+
globalConcurrencyLimit: deps.config.globalConcurrencyLimit
|
|
1689
|
+
});
|
|
1690
|
+
}
|
|
1691
|
+
if (hasSingle) {
|
|
1692
|
+
const a = agents.find((x) => x.name === params.agent);
|
|
1693
|
+
if (!a) {
|
|
1694
|
+
return {
|
|
1695
|
+
content: [{ type: "text", text: `Unknown agent: ${params.agent}` }],
|
|
1696
|
+
isError: true,
|
|
1697
|
+
details: { mode: "single", results: [] }
|
|
1698
|
+
};
|
|
1699
|
+
}
|
|
1700
|
+
const rawOutput = params.output !== undefined ? params.output : a.output;
|
|
1701
|
+
const effectiveOutput = normalizeSingleOutputOverride(rawOutput, a.output);
|
|
1702
|
+
const effectiveOutputMode = params.outputMode ?? "inline";
|
|
1703
|
+
const normalizedSkills = normalizeSkillInput(params.skill);
|
|
1704
|
+
const skills = normalizedSkills === false ? [] : normalizedSkills;
|
|
1705
|
+
const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, a.maxSubagentDepth);
|
|
1706
|
+
const modelOverride = resolveSubagentModelOverride(params.model ?? a.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: params.model ? "explicit" : "inherited" });
|
|
1707
|
+
return executeAsyncSingle(id, {
|
|
1708
|
+
agent: params.agent,
|
|
1709
|
+
task: shouldForkAgent(contextPolicy, params.agent) ? wrapForkTask(params.task ?? "") : params.task ?? "",
|
|
1710
|
+
agentConfig: a,
|
|
1711
|
+
ctx: asyncCtx,
|
|
1712
|
+
availableModels,
|
|
1713
|
+
cwd: effectiveCwd,
|
|
1714
|
+
maxOutput: params.maxOutput,
|
|
1715
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
1716
|
+
artifactConfig,
|
|
1717
|
+
shareEnabled,
|
|
1718
|
+
sessionRoot,
|
|
1719
|
+
sessionFile: sessionFileForTask(params.agent, 0),
|
|
1720
|
+
skills,
|
|
1721
|
+
output: effectiveOutput,
|
|
1722
|
+
outputMode: effectiveOutputMode,
|
|
1723
|
+
outputBaseDir: resolveSingleRunOutputBaseDir(deps, artifactsDir, id),
|
|
1724
|
+
modelOverride,
|
|
1725
|
+
thinkingOverride: thinkingOverrideForTask(params.agent, 0),
|
|
1726
|
+
maxSubagentDepth,
|
|
1727
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
1728
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
1729
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
1730
|
+
controlConfig,
|
|
1731
|
+
controlIntercomTarget,
|
|
1732
|
+
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(agent, index) : undefined,
|
|
1733
|
+
nestedRoute,
|
|
1734
|
+
acceptance: params.acceptance,
|
|
1735
|
+
timeoutMs: data.timeoutMs,
|
|
1736
|
+
turnBudget: data.turnBudget,
|
|
1737
|
+
toolBudget: data.toolBudget,
|
|
1738
|
+
configToolBudget: data.configToolBudget
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1741
|
+
return null;
|
|
1742
|
+
}
|
|
1743
|
+
async function runChainPath(data, deps) {
|
|
1744
|
+
const {
|
|
1745
|
+
params,
|
|
1746
|
+
effectiveCwd,
|
|
1747
|
+
agents,
|
|
1748
|
+
ctx,
|
|
1749
|
+
signal,
|
|
1750
|
+
runId,
|
|
1751
|
+
shareEnabled,
|
|
1752
|
+
sessionDirForIndex,
|
|
1753
|
+
sessionFileForIndex,
|
|
1754
|
+
sessionFileForTask,
|
|
1755
|
+
thinkingOverrideForTask,
|
|
1756
|
+
artifactsDir,
|
|
1757
|
+
artifactConfig,
|
|
1758
|
+
onUpdate,
|
|
1759
|
+
sessionRoot,
|
|
1760
|
+
controlConfig,
|
|
1761
|
+
contextPolicy
|
|
1762
|
+
} = data;
|
|
1763
|
+
const onControlEvent = createForegroundControlNotifier(data, deps);
|
|
1764
|
+
const childIntercomTarget = data.intercomBridge.active ? resolveSubagentIntercomTarget : undefined;
|
|
1765
|
+
const foregroundControl = deps.state.foregroundControls.get(runId);
|
|
1766
|
+
const normalized = normalizeSkillInput(params.skill);
|
|
1767
|
+
const chainSkills = normalized === false ? [] : normalized ?? [];
|
|
1768
|
+
const chain = wrapChainTasksForFork(params.chain, contextPolicy);
|
|
1769
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
1770
|
+
const chainResult = await executeChain({
|
|
1771
|
+
chain,
|
|
1772
|
+
task: params.task,
|
|
1773
|
+
agents,
|
|
1774
|
+
ctx,
|
|
1775
|
+
modelScope: data.modelScope,
|
|
1776
|
+
intercomEvents: deps.pi.events,
|
|
1777
|
+
signal,
|
|
1778
|
+
runId,
|
|
1779
|
+
cwd: effectiveCwd,
|
|
1780
|
+
shareEnabled,
|
|
1781
|
+
sessionDirForIndex,
|
|
1782
|
+
sessionFileForIndex,
|
|
1783
|
+
sessionFileForTask,
|
|
1784
|
+
thinkingOverrideForTask,
|
|
1785
|
+
artifactsDir,
|
|
1786
|
+
artifactConfig,
|
|
1787
|
+
includeProgress: params.includeProgress,
|
|
1788
|
+
clarify: params.clarify,
|
|
1789
|
+
onUpdate,
|
|
1790
|
+
onControlEvent,
|
|
1791
|
+
controlConfig,
|
|
1792
|
+
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(runId, agent, index) : undefined,
|
|
1793
|
+
orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
1794
|
+
foregroundControl,
|
|
1795
|
+
nestedRoute: foregroundControl?.nestedRoute,
|
|
1796
|
+
chainSkills,
|
|
1797
|
+
chainDir: params.chainDir ?? getProjectChainRunsDir(effectiveCwd),
|
|
1798
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1799
|
+
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1800
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
1801
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
1802
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
1803
|
+
timeoutMs: data.timeoutMs,
|
|
1804
|
+
deadlineAt: data.deadlineAt,
|
|
1805
|
+
turnBudget: data.turnBudget,
|
|
1806
|
+
onDetachedExit: (index, result) => updateRememberedForegroundChild(deps.state, { runId, mode: "chain", cwd: effectiveCwd, index, result }),
|
|
1807
|
+
toolBudget: data.toolBudget,
|
|
1808
|
+
configToolBudget: data.configToolBudget,
|
|
1809
|
+
globalConcurrencyLimit: deps.config.globalConcurrencyLimit
|
|
1810
|
+
});
|
|
1811
|
+
if (chainResult.requestedAsync) {
|
|
1812
|
+
if (!isAsyncAvailable()) {
|
|
1813
|
+
return {
|
|
1814
|
+
content: [{ type: "text", text: "Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed." }],
|
|
1815
|
+
isError: true,
|
|
1816
|
+
details: { mode: "chain", results: [] }
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
const id = randomUUID();
|
|
1820
|
+
const asyncCtx = {
|
|
1821
|
+
pi: deps.pi,
|
|
1822
|
+
cwd: ctx.cwd,
|
|
1823
|
+
currentSessionId: deps.state.currentSessionId,
|
|
1824
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
1825
|
+
currentModelProvider: ctx.model?.provider,
|
|
1826
|
+
currentModel: ctx.model,
|
|
1827
|
+
modelScope: data.modelScope
|
|
1828
|
+
};
|
|
1829
|
+
const asyncChain = wrapChainTasksForFork(chainResult.requestedAsync.chain, contextPolicy);
|
|
1830
|
+
return executeAsyncChain(id, {
|
|
1831
|
+
chain: asyncChain,
|
|
1832
|
+
task: params.task,
|
|
1833
|
+
agents,
|
|
1834
|
+
ctx: asyncCtx,
|
|
1835
|
+
availableModels: ctx.modelRegistry.getAvailable().map(toModelInfo),
|
|
1836
|
+
cwd: effectiveCwd,
|
|
1837
|
+
maxOutput: params.maxOutput,
|
|
1838
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
1839
|
+
artifactConfig,
|
|
1840
|
+
shareEnabled,
|
|
1841
|
+
sessionRoot,
|
|
1842
|
+
chainSkills: chainResult.requestedAsync.chainSkills,
|
|
1843
|
+
sessionFilesByFlatIndex: collectChainSessionFiles(asyncChain, sessionFileForTask, deps.config.chain?.dynamicFanout?.maxItems),
|
|
1844
|
+
thinkingOverridesByFlatIndex: collectChainThinkingOverrides(asyncChain, thinkingOverrideForTask, deps.config.chain?.dynamicFanout?.maxItems),
|
|
1845
|
+
dynamicFanoutMaxItems: deps.config.chain?.dynamicFanout?.maxItems,
|
|
1846
|
+
maxSubagentDepth: currentMaxSubagentDepth,
|
|
1847
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
1848
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
1849
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
1850
|
+
controlConfig,
|
|
1851
|
+
controlIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
1852
|
+
childIntercomTarget: data.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(id, agent, index) : undefined,
|
|
1853
|
+
nestedRoute: data.nestedRoute,
|
|
1854
|
+
timeoutMs: data.timeoutMs,
|
|
1855
|
+
turnBudget: data.turnBudget,
|
|
1856
|
+
toolBudget: data.toolBudget,
|
|
1857
|
+
configToolBudget: data.configToolBudget,
|
|
1858
|
+
globalConcurrencyLimit: deps.config.globalConcurrencyLimit
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
const rawChainDetails = chainResult.details ? { ...chainResult.details, runId } : undefined;
|
|
1862
|
+
if (foregroundControl && rawChainDetails) {
|
|
1863
|
+
updateForegroundNestedProjection(foregroundControl);
|
|
1864
|
+
attachRootChildrenToSteps(runId, rawChainDetails.results, foregroundControl.nestedChildren);
|
|
1865
|
+
rawChainDetails.totalCost = sumResultsCost(rawChainDetails.results);
|
|
1866
|
+
}
|
|
1867
|
+
const chainDetails = rawChainDetails ? compactForegroundDetails(rawChainDetails) : undefined;
|
|
1868
|
+
if (chainDetails)
|
|
1869
|
+
rememberForegroundRun(deps.state, { runId, mode: "chain", cwd: effectiveCwd, results: chainDetails.results });
|
|
1870
|
+
const intercomReceipt = chainDetails && !chainDetails.results.some((result) => result.interrupted || result.detached) ? await maybeBuildForegroundIntercomReceipt({
|
|
1871
|
+
pi: deps.pi,
|
|
1872
|
+
intercomBridge: data.intercomBridge,
|
|
1873
|
+
runId,
|
|
1874
|
+
mode: "chain",
|
|
1875
|
+
details: chainDetails,
|
|
1876
|
+
...foregroundControl?.nestedChildren?.length ? { nestedChildren: foregroundControl.nestedChildren } : {}
|
|
1877
|
+
}) : null;
|
|
1878
|
+
if (intercomReceipt) {
|
|
1879
|
+
return {
|
|
1880
|
+
...chainResult,
|
|
1881
|
+
content: [{ type: "text", text: intercomReceipt.text }],
|
|
1882
|
+
details: intercomReceipt.details
|
|
1883
|
+
};
|
|
1884
|
+
}
|
|
1885
|
+
return chainDetails ? { ...chainResult, details: chainDetails } : chainResult;
|
|
1886
|
+
}
|
|
1887
|
+
function buildParallelModeError(message) {
|
|
1888
|
+
return {
|
|
1889
|
+
content: [{ type: "text", text: message }],
|
|
1890
|
+
isError: true,
|
|
1891
|
+
details: { mode: "parallel", results: [] }
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
function createParallelWorktreeSetup(enabled, cwd, runId, tasks, setupHook, setupHookTimeoutMs, baseDir) {
|
|
1895
|
+
if (!enabled)
|
|
1896
|
+
return {};
|
|
1897
|
+
try {
|
|
1898
|
+
return {
|
|
1899
|
+
setup: createWorktrees(cwd, runId, tasks.length, {
|
|
1900
|
+
agents: tasks.map((task) => task.agent),
|
|
1901
|
+
setupHook: setupHook ? { hookPath: setupHook, timeoutMs: setupHookTimeoutMs } : undefined,
|
|
1902
|
+
baseDir
|
|
1903
|
+
})
|
|
1904
|
+
};
|
|
1905
|
+
} catch (error) {
|
|
1906
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1907
|
+
return { errorResult: buildParallelModeError(message) };
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function buildParallelWorktreeTaskCwdError(tasks, sharedCwd) {
|
|
1911
|
+
const conflict = findWorktreeTaskCwdConflict(tasks, sharedCwd);
|
|
1912
|
+
if (!conflict)
|
|
1913
|
+
return;
|
|
1914
|
+
return formatWorktreeTaskCwdConflict(conflict, sharedCwd);
|
|
1915
|
+
}
|
|
1916
|
+
function resolveSingleRunOutputBaseDir(deps, artifactsDir, runId) {
|
|
1917
|
+
return deps.config.singleRunOutputBaseDir ? path.resolve(deps.expandTilde(deps.config.singleRunOutputBaseDir)) : path.join(artifactsDir, "outputs", runId);
|
|
1918
|
+
}
|
|
1919
|
+
function buildChainWorktreeTaskCwdError(chain, sharedCwd) {
|
|
1920
|
+
for (let stepIndex = 0;stepIndex < chain.length; stepIndex++) {
|
|
1921
|
+
const step = chain[stepIndex];
|
|
1922
|
+
if (!isParallelStep(step) || !step.worktree)
|
|
1923
|
+
continue;
|
|
1924
|
+
const stepCwd = resolveChildCwd(sharedCwd, step.cwd);
|
|
1925
|
+
const conflict = findWorktreeTaskCwdConflict(step.parallel, stepCwd);
|
|
1926
|
+
if (!conflict)
|
|
1927
|
+
continue;
|
|
1928
|
+
const detail = formatWorktreeTaskCwdConflict(conflict, stepCwd);
|
|
1929
|
+
return `parallel chain step ${stepIndex + 1}: ${detail}`;
|
|
1930
|
+
}
|
|
1931
|
+
return;
|
|
1932
|
+
}
|
|
1933
|
+
function resolveParallelTaskCwd(task, paramsCwd, worktreeSetup, index) {
|
|
1934
|
+
if (worktreeSetup)
|
|
1935
|
+
return worktreeSetup.worktrees[index].agentCwd;
|
|
1936
|
+
return resolveChildCwd(paramsCwd, task.cwd);
|
|
1937
|
+
}
|
|
1938
|
+
function buildParallelWorktreeSuffix(worktreeSetup, artifactsDir, tasks) {
|
|
1939
|
+
if (!worktreeSetup)
|
|
1940
|
+
return "";
|
|
1941
|
+
const diffsDir = path.join(artifactsDir, "worktree-diffs");
|
|
1942
|
+
const diffs = diffWorktrees(worktreeSetup, tasks.map((task) => task.agent), diffsDir);
|
|
1943
|
+
return formatWorktreeDiffSummary(diffs);
|
|
1944
|
+
}
|
|
1945
|
+
function findDuplicateParallelOutputPath(input) {
|
|
1946
|
+
const seen = new Map;
|
|
1947
|
+
for (let index = 0;index < input.tasks.length; index++) {
|
|
1948
|
+
const behavior = input.behaviors[index];
|
|
1949
|
+
if (!behavior?.output)
|
|
1950
|
+
continue;
|
|
1951
|
+
const task = input.tasks[index];
|
|
1952
|
+
const taskCwd = resolveParallelTaskCwd(task, input.paramsCwd, input.worktreeSetup, index);
|
|
1953
|
+
const outputPath = resolveSingleOutputPath(behavior.output, input.ctxCwd, taskCwd, input.outputBaseDir);
|
|
1954
|
+
if (!outputPath)
|
|
1955
|
+
continue;
|
|
1956
|
+
const previous = seen.get(outputPath);
|
|
1957
|
+
if (previous) {
|
|
1958
|
+
return `Parallel tasks ${previous.index + 1} (${previous.agent}) and ${index + 1} (${task.agent}) resolve output to the same path: ${outputPath}. Use distinct output paths.`;
|
|
1959
|
+
}
|
|
1960
|
+
seen.set(outputPath, { index, agent: task.agent });
|
|
1961
|
+
}
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
async function runForegroundParallelTasks(input) {
|
|
1965
|
+
for (let i = 0;i < input.tasks.length; i++) {
|
|
1966
|
+
input.sessionFileForIndex(i);
|
|
1967
|
+
}
|
|
1968
|
+
return mapConcurrent(input.tasks, input.concurrencyLimit, async (task, index) => {
|
|
1969
|
+
const behavior = input.behaviors[index];
|
|
1970
|
+
const effectiveSkills = behavior?.skills;
|
|
1971
|
+
const taskCwd = resolveParallelTaskCwd(task, input.paramsCwd, input.worktreeSetup, index);
|
|
1972
|
+
const readInstructions = behavior ? buildChainInstructions({ ...behavior, output: false, progress: false }, taskCwd, false) : { prefix: "", suffix: "" };
|
|
1973
|
+
const progressInstructions = behavior ? buildChainInstructions({ ...behavior, output: false, reads: false }, input.progressDir, index === input.firstProgressIndex) : { prefix: "", suffix: "" };
|
|
1974
|
+
const outputPath = resolveSingleOutputPath(behavior?.output, input.ctx.cwd, taskCwd, input.outputBaseDir);
|
|
1975
|
+
const taskText = injectSingleOutputInstruction(`${readInstructions.prefix}${input.taskTexts[index]}${progressInstructions.suffix}`, outputPath);
|
|
1976
|
+
const interruptController = new AbortController;
|
|
1977
|
+
if (input.foregroundControl) {
|
|
1978
|
+
input.foregroundControl.currentAgent = task.agent;
|
|
1979
|
+
input.foregroundControl.currentIndex = index;
|
|
1980
|
+
input.foregroundControl.currentActivityState = undefined;
|
|
1981
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
1982
|
+
input.foregroundControl.interrupt = () => {
|
|
1983
|
+
if (interruptController.signal.aborted)
|
|
1984
|
+
return false;
|
|
1985
|
+
interruptController.abort();
|
|
1986
|
+
input.foregroundControl.currentActivityState = undefined;
|
|
1987
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
1988
|
+
return true;
|
|
1989
|
+
};
|
|
1990
|
+
}
|
|
1991
|
+
const agentConfig = input.agents.find((agent) => agent.name === task.agent);
|
|
1992
|
+
return runSync(input.ctx.cwd, input.agents, task.agent, taskText, {
|
|
1993
|
+
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
1994
|
+
cwd: taskCwd,
|
|
1995
|
+
signal: input.signal,
|
|
1996
|
+
interruptSignal: interruptController.signal,
|
|
1997
|
+
allowIntercomDetach: agentConfig?.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
1998
|
+
intercomEvents: input.intercomEvents,
|
|
1999
|
+
runId: input.runId,
|
|
2000
|
+
index,
|
|
2001
|
+
sessionDir: input.sessionDirForIndex(index),
|
|
2002
|
+
sessionFile: input.sessionFileForTask(task.agent, index),
|
|
2003
|
+
share: input.shareEnabled,
|
|
2004
|
+
artifactsDir: input.artifactConfig.enabled ? input.artifactsDir : undefined,
|
|
2005
|
+
artifactConfig: input.artifactConfig,
|
|
2006
|
+
maxOutput: input.maxOutput,
|
|
2007
|
+
outputPath,
|
|
2008
|
+
outputMode: behavior?.outputMode,
|
|
2009
|
+
maxSubagentDepth: input.maxSubagentDepths[index],
|
|
2010
|
+
controlConfig: input.controlConfig,
|
|
2011
|
+
onControlEvent: input.onControlEvent,
|
|
2012
|
+
onDetachedExit: (result) => updateRememberedForegroundChild(input.state, { runId: input.runId, mode: "parallel", cwd: taskCwd, index, result }),
|
|
2013
|
+
intercomSessionName: input.childIntercomTarget?.(task.agent, index),
|
|
2014
|
+
orchestratorIntercomTarget: input.orchestratorIntercomTarget,
|
|
2015
|
+
nestedRoute: input.foregroundControl?.nestedRoute,
|
|
2016
|
+
modelOverride: input.modelOverrides[index],
|
|
2017
|
+
thinkingOverride: input.thinkingOverrideForTask(task.agent, index),
|
|
2018
|
+
availableModels: input.availableModels,
|
|
2019
|
+
preferredModelProvider: input.ctx.model?.provider,
|
|
2020
|
+
modelScope: input.modelScope,
|
|
2021
|
+
skills: effectiveSkills === false ? [] : effectiveSkills,
|
|
2022
|
+
acceptance: task.acceptance,
|
|
2023
|
+
acceptanceContext: { mode: "parallel" },
|
|
2024
|
+
timeoutMs: input.timeoutMs,
|
|
2025
|
+
deadlineAt: input.deadlineAt,
|
|
2026
|
+
turnBudget: input.turnBudget,
|
|
2027
|
+
toolBudget: input.toolBudgets[index],
|
|
2028
|
+
onUpdate: input.onUpdate ? (progressUpdate) => {
|
|
2029
|
+
const stepResults = progressUpdate.details?.results || [];
|
|
2030
|
+
const stepProgress = progressUpdate.details?.progress || [];
|
|
2031
|
+
if (input.foregroundControl && stepProgress.length > 0) {
|
|
2032
|
+
const current = stepProgress[0];
|
|
2033
|
+
input.foregroundControl.currentAgent = task.agent;
|
|
2034
|
+
input.foregroundControl.currentIndex = index;
|
|
2035
|
+
input.foregroundControl.currentActivityState = current?.activityState;
|
|
2036
|
+
input.foregroundControl.lastActivityAt = current?.lastActivityAt;
|
|
2037
|
+
input.foregroundControl.currentTool = current?.currentTool;
|
|
2038
|
+
input.foregroundControl.currentToolStartedAt = current?.currentToolStartedAt;
|
|
2039
|
+
input.foregroundControl.currentPath = current?.currentPath;
|
|
2040
|
+
input.foregroundControl.turnCount = current?.turnCount;
|
|
2041
|
+
input.foregroundControl.tokens = current?.tokens;
|
|
2042
|
+
input.foregroundControl.toolCount = current?.toolCount;
|
|
2043
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
2044
|
+
}
|
|
2045
|
+
if (stepResults.length > 0)
|
|
2046
|
+
input.liveResults[index] = stepResults[0];
|
|
2047
|
+
if (stepProgress.length > 0)
|
|
2048
|
+
input.liveProgress[index] = stepProgress[0];
|
|
2049
|
+
const mergedResults = input.liveResults.filter((result) => result !== undefined);
|
|
2050
|
+
const mergedProgress = input.liveProgress.filter((progress) => progress !== undefined);
|
|
2051
|
+
input.onUpdate?.({
|
|
2052
|
+
content: progressUpdate.content,
|
|
2053
|
+
details: {
|
|
2054
|
+
mode: "parallel",
|
|
2055
|
+
results: mergedResults,
|
|
2056
|
+
progress: mergedProgress,
|
|
2057
|
+
controlEvents: progressUpdate.details?.controlEvents,
|
|
2058
|
+
totalSteps: input.tasks.length
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
2061
|
+
} : undefined
|
|
2062
|
+
}).finally(() => {
|
|
2063
|
+
if (input.foregroundControl?.currentIndex === index) {
|
|
2064
|
+
input.foregroundControl.interrupt = undefined;
|
|
2065
|
+
input.foregroundControl.updatedAt = Date.now();
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
2068
|
+
}, input.globalSemaphore);
|
|
2069
|
+
}
|
|
2070
|
+
async function runParallelPath(data, deps) {
|
|
2071
|
+
const {
|
|
2072
|
+
params,
|
|
2073
|
+
effectiveCwd,
|
|
2074
|
+
agents,
|
|
2075
|
+
ctx,
|
|
2076
|
+
signal,
|
|
2077
|
+
runId,
|
|
2078
|
+
sessionDirForIndex,
|
|
2079
|
+
sessionFileForIndex,
|
|
2080
|
+
sessionFileForTask,
|
|
2081
|
+
thinkingOverrideForTask,
|
|
2082
|
+
shareEnabled,
|
|
2083
|
+
artifactConfig,
|
|
2084
|
+
artifactsDir,
|
|
2085
|
+
backgroundRequestedWhileClarifying,
|
|
2086
|
+
onUpdate,
|
|
2087
|
+
sessionRoot,
|
|
2088
|
+
controlConfig,
|
|
2089
|
+
contextPolicy
|
|
2090
|
+
} = data;
|
|
2091
|
+
const onControlEvent = createForegroundControlNotifier(data, deps);
|
|
2092
|
+
const childIntercomTarget = data.intercomBridge.active ? resolveSubagentIntercomTarget : undefined;
|
|
2093
|
+
const allProgress = [];
|
|
2094
|
+
const allArtifactPaths = [];
|
|
2095
|
+
const tasks = params.tasks;
|
|
2096
|
+
const maxParallelTasks = resolveTopLevelParallelMaxTasks(deps.config.parallel?.maxTasks);
|
|
2097
|
+
const parallelConcurrency = resolveTopLevelParallelConcurrency(params.concurrency, deps.config.parallel?.concurrency);
|
|
2098
|
+
if (tasks.length > maxParallelTasks)
|
|
2099
|
+
return {
|
|
2100
|
+
content: [{ type: "text", text: `Max ${maxParallelTasks} tasks` }],
|
|
2101
|
+
isError: true,
|
|
2102
|
+
details: { mode: "parallel", results: [] }
|
|
2103
|
+
};
|
|
2104
|
+
const agentConfigs = [];
|
|
2105
|
+
for (const t of tasks) {
|
|
2106
|
+
const config = agents.find((a) => a.name === t.agent);
|
|
2107
|
+
if (!config) {
|
|
2108
|
+
return {
|
|
2109
|
+
content: [{ type: "text", text: `Unknown agent: ${t.agent}` }],
|
|
2110
|
+
isError: true,
|
|
2111
|
+
details: { mode: "parallel", results: [] }
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
agentConfigs.push(config);
|
|
2115
|
+
}
|
|
2116
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
2117
|
+
const maxSubagentDepths = agentConfigs.map((config) => resolveChildMaxSubagentDepth(currentMaxSubagentDepth, config.maxSubagentDepth));
|
|
2118
|
+
const toolBudgets = [];
|
|
2119
|
+
for (let index = 0;index < tasks.length; index++) {
|
|
2120
|
+
const resolved = resolveEffectiveToolBudget({ stepBudget: tasks[index]?.toolBudget, runBudget: data.toolBudget, agentBudget: agentConfigs[index]?.toolBudget, configBudget: data.configToolBudget });
|
|
2121
|
+
if (resolved.error)
|
|
2122
|
+
return buildParallelModeError(resolved.error);
|
|
2123
|
+
toolBudgets.push(resolved.toolBudget);
|
|
2124
|
+
}
|
|
2125
|
+
if (params.worktree) {
|
|
2126
|
+
const worktreeTaskCwdError = buildParallelWorktreeTaskCwdError(tasks, effectiveCwd);
|
|
2127
|
+
if (worktreeTaskCwdError)
|
|
2128
|
+
return buildParallelModeError(worktreeTaskCwdError);
|
|
2129
|
+
}
|
|
2130
|
+
const currentProvider = ctx.model?.provider;
|
|
2131
|
+
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
2132
|
+
let taskTexts = tasks.map((t) => t.task);
|
|
2133
|
+
const skillOverrides = tasks.map((t) => normalizeSkillInput(t.skill));
|
|
2134
|
+
const behaviorOverrides = tasks.map((task, index) => ({
|
|
2135
|
+
...task.output !== undefined ? { output: task.output === true ? agentConfigs[index]?.output ?? false : task.output } : {},
|
|
2136
|
+
...task.outputMode !== undefined ? { outputMode: task.outputMode } : {},
|
|
2137
|
+
...task.reads !== undefined && task.reads !== true ? { reads: task.reads } : {},
|
|
2138
|
+
...task.progress !== undefined ? { progress: task.progress } : {},
|
|
2139
|
+
...skillOverrides[index] !== undefined ? { skills: skillOverrides[index] } : {},
|
|
2140
|
+
...task.model ? { model: task.model } : {}
|
|
2141
|
+
}));
|
|
2142
|
+
const modelOverrides = tasks.map((_, i) => resolveSubagentModelOverride(behaviorOverrides[i]?.model ?? agentConfigs[i]?.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: behaviorOverrides[i]?.model ? "explicit" : "inherited" }));
|
|
2143
|
+
if (params.clarify === true && ctx.hasUI) {
|
|
2144
|
+
const behaviors = agentConfigs.map((c, i) => resolveStepBehavior(c, behaviorOverrides[i]));
|
|
2145
|
+
const availableSkills = discoverAvailableSkills(effectiveCwd);
|
|
2146
|
+
const result = await ctx.ui.custom((tui, theme, _kb, done) => new ChainClarifyComponent(tui, theme, agentConfigs, taskTexts, "", undefined, behaviors, availableModels, currentProvider, availableSkills, done, "parallel"), { overlay: true, overlayOptions: { anchor: "center", width: 84, maxHeight: "80%" } });
|
|
2147
|
+
if (!result || !result.confirmed) {
|
|
2148
|
+
return { content: [{ type: "text", text: "Cancelled" }], details: { mode: "parallel", results: [] } };
|
|
2149
|
+
}
|
|
2150
|
+
taskTexts = result.templates;
|
|
2151
|
+
for (let i = 0;i < result.behaviorOverrides.length; i++) {
|
|
2152
|
+
const override = result.behaviorOverrides[i];
|
|
2153
|
+
if (override?.model) {
|
|
2154
|
+
modelOverrides[i] = resolveSubagentModelOverride(override.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: "explicit" });
|
|
2155
|
+
behaviorOverrides[i].model = override.model;
|
|
2156
|
+
}
|
|
2157
|
+
if (override?.output !== undefined)
|
|
2158
|
+
behaviorOverrides[i].output = override.output;
|
|
2159
|
+
if (override?.reads !== undefined)
|
|
2160
|
+
behaviorOverrides[i].reads = override.reads;
|
|
2161
|
+
if (override?.progress !== undefined)
|
|
2162
|
+
behaviorOverrides[i].progress = override.progress;
|
|
2163
|
+
if (override?.skills !== undefined) {
|
|
2164
|
+
skillOverrides[i] = override.skills;
|
|
2165
|
+
behaviorOverrides[i].skills = override.skills;
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
if (result.runInBackground) {
|
|
2169
|
+
if (!isAsyncAvailable()) {
|
|
2170
|
+
return {
|
|
2171
|
+
content: [{ type: "text", text: "Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed." }],
|
|
2172
|
+
isError: true,
|
|
2173
|
+
details: { mode: "parallel", results: [] }
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
const id = randomUUID();
|
|
2177
|
+
const asyncCtx = {
|
|
2178
|
+
pi: deps.pi,
|
|
2179
|
+
cwd: ctx.cwd,
|
|
2180
|
+
currentSessionId: deps.state.currentSessionId,
|
|
2181
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
2182
|
+
currentModelProvider: ctx.model?.provider,
|
|
2183
|
+
currentModel: ctx.model,
|
|
2184
|
+
modelScope: data.modelScope
|
|
2185
|
+
};
|
|
2186
|
+
const parallelTasks = tasks.map((t, i) => {
|
|
2187
|
+
const taskText = shouldForkAgent(contextPolicy, t.agent) ? wrapForkTask(taskTexts[i]) : taskTexts[i];
|
|
2188
|
+
const progress = taskDisallowsFileUpdates(taskText) ? false : behaviorOverrides[i]?.progress;
|
|
2189
|
+
return {
|
|
2190
|
+
agent: t.agent,
|
|
2191
|
+
task: taskText,
|
|
2192
|
+
cwd: t.cwd,
|
|
2193
|
+
...modelOverrides[i] ? { model: modelOverrides[i] } : {},
|
|
2194
|
+
...skillOverrides[i] !== undefined ? { skill: skillOverrides[i] } : {},
|
|
2195
|
+
...behaviorOverrides[i]?.output !== undefined ? { output: behaviorOverrides[i].output } : {},
|
|
2196
|
+
...behaviorOverrides[i]?.outputMode !== undefined ? { outputMode: behaviorOverrides[i].outputMode } : {},
|
|
2197
|
+
...behaviorOverrides[i]?.reads !== undefined ? { reads: behaviorOverrides[i].reads } : {},
|
|
2198
|
+
...progress !== undefined ? { progress } : {},
|
|
2199
|
+
...t.toolBudget !== undefined ? { toolBudget: t.toolBudget } : {},
|
|
2200
|
+
...t.acceptance !== undefined ? { acceptance: t.acceptance } : {}
|
|
2201
|
+
};
|
|
2202
|
+
});
|
|
2203
|
+
return executeAsyncChain(id, {
|
|
2204
|
+
chain: [{ parallel: parallelTasks, concurrency: parallelConcurrency, worktree: params.worktree }],
|
|
2205
|
+
resultMode: "parallel",
|
|
2206
|
+
agents,
|
|
2207
|
+
ctx: asyncCtx,
|
|
2208
|
+
availableModels,
|
|
2209
|
+
cwd: effectiveCwd,
|
|
2210
|
+
maxOutput: params.maxOutput,
|
|
2211
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
2212
|
+
artifactConfig,
|
|
2213
|
+
shareEnabled,
|
|
2214
|
+
sessionRoot,
|
|
2215
|
+
chainSkills: [],
|
|
2216
|
+
sessionFilesByFlatIndex: tasks.map((task, index) => sessionFileForTask(task.agent, index)),
|
|
2217
|
+
thinkingOverridesByFlatIndex: tasks.map((task, index) => thinkingOverrideForTask(task.agent, index)),
|
|
2218
|
+
maxSubagentDepth: currentMaxSubagentDepth,
|
|
2219
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
2220
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
2221
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
2222
|
+
controlConfig,
|
|
2223
|
+
controlIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
2224
|
+
childIntercomTarget: data.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(id, agent, index) : undefined,
|
|
2225
|
+
timeoutMs: data.timeoutMs,
|
|
2226
|
+
turnBudget: data.turnBudget,
|
|
2227
|
+
globalConcurrencyLimit: deps.config.globalConcurrencyLimit
|
|
2228
|
+
});
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
const behaviors = agentConfigs.map((config, index) => suppressProgressForReadOnlyTask(resolveStepBehavior(config, behaviorOverrides[index]), taskTexts[index]));
|
|
2232
|
+
const firstProgressIndex = behaviors.findIndex((behavior) => behavior.progress);
|
|
2233
|
+
const liveResults = new Array(tasks.length).fill(undefined);
|
|
2234
|
+
const liveProgress = new Array(tasks.length).fill(undefined);
|
|
2235
|
+
const foregroundControl = deps.state.foregroundControls.get(runId);
|
|
2236
|
+
const { setup: worktreeSetup, errorResult } = createParallelWorktreeSetup(params.worktree, effectiveCwd, runId, tasks, deps.config.worktreeSetupHook, deps.config.worktreeSetupHookTimeoutMs, deps.config.worktreeBaseDir);
|
|
2237
|
+
if (errorResult)
|
|
2238
|
+
return errorResult;
|
|
2239
|
+
try {
|
|
2240
|
+
const outputBaseDir = path.join(artifactsDir, "outputs", runId);
|
|
2241
|
+
const duplicateOutputError = findDuplicateParallelOutputPath({
|
|
2242
|
+
tasks,
|
|
2243
|
+
behaviors,
|
|
2244
|
+
paramsCwd: effectiveCwd,
|
|
2245
|
+
ctxCwd: ctx.cwd,
|
|
2246
|
+
outputBaseDir,
|
|
2247
|
+
worktreeSetup
|
|
2248
|
+
});
|
|
2249
|
+
if (duplicateOutputError)
|
|
2250
|
+
return buildParallelModeError(duplicateOutputError);
|
|
2251
|
+
for (let index = 0;index < tasks.length; index++) {
|
|
2252
|
+
const taskCwd = resolveParallelTaskCwd(tasks[index], effectiveCwd, worktreeSetup, index);
|
|
2253
|
+
const outputPath = resolveSingleOutputPath(behaviors[index]?.output, ctx.cwd, taskCwd, outputBaseDir);
|
|
2254
|
+
const validationError = validateFileOnlyOutputMode(behaviors[index]?.outputMode, outputPath, `Parallel task ${index + 1} (${tasks[index].agent})`);
|
|
2255
|
+
if (validationError)
|
|
2256
|
+
return buildParallelModeError(validationError);
|
|
2257
|
+
}
|
|
2258
|
+
const parallelProgressPrecreated = firstProgressIndex !== -1;
|
|
2259
|
+
const parallelProgressDir = path.join(artifactsDir, "progress", runId);
|
|
2260
|
+
if (parallelProgressPrecreated)
|
|
2261
|
+
writeInitialProgressFile(parallelProgressDir);
|
|
2262
|
+
for (let i = 0;i < taskTexts.length; i++) {
|
|
2263
|
+
if (shouldForkAgent(contextPolicy, tasks[i].agent))
|
|
2264
|
+
taskTexts[i] = wrapForkTask(taskTexts[i]);
|
|
2265
|
+
}
|
|
2266
|
+
const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
|
|
2267
|
+
const results = await runForegroundParallelTasks({
|
|
2268
|
+
tasks,
|
|
2269
|
+
taskTexts,
|
|
2270
|
+
agents,
|
|
2271
|
+
ctx,
|
|
2272
|
+
state: deps.state,
|
|
2273
|
+
intercomEvents: deps.pi.events,
|
|
2274
|
+
signal,
|
|
2275
|
+
runId,
|
|
2276
|
+
sessionDirForIndex,
|
|
2277
|
+
sessionFileForIndex,
|
|
2278
|
+
sessionFileForTask,
|
|
2279
|
+
thinkingOverrideForTask,
|
|
2280
|
+
shareEnabled,
|
|
2281
|
+
artifactConfig,
|
|
2282
|
+
artifactsDir,
|
|
2283
|
+
outputBaseDir,
|
|
2284
|
+
maxOutput: params.maxOutput,
|
|
2285
|
+
paramsCwd: effectiveCwd,
|
|
2286
|
+
progressDir: parallelProgressDir,
|
|
2287
|
+
availableModels,
|
|
2288
|
+
modelScope: data.modelScope,
|
|
2289
|
+
modelOverrides,
|
|
2290
|
+
behaviors,
|
|
2291
|
+
firstProgressIndex: parallelProgressPrecreated ? -1 : firstProgressIndex,
|
|
2292
|
+
controlConfig,
|
|
2293
|
+
onControlEvent,
|
|
2294
|
+
childIntercomTarget: childIntercomTarget ? (agent, index) => childIntercomTarget(runId, agent, index) : undefined,
|
|
2295
|
+
orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
2296
|
+
foregroundControl,
|
|
2297
|
+
concurrencyLimit: parallelConcurrency,
|
|
2298
|
+
globalSemaphore: new Semaphore(deps.config.globalConcurrencyLimit ?? DEFAULT_GLOBAL_CONCURRENCY_LIMIT),
|
|
2299
|
+
maxSubagentDepths,
|
|
2300
|
+
liveResults,
|
|
2301
|
+
liveProgress,
|
|
2302
|
+
onUpdate,
|
|
2303
|
+
worktreeSetup,
|
|
2304
|
+
timeoutMs: data.timeoutMs,
|
|
2305
|
+
deadlineAt,
|
|
2306
|
+
turnBudget: data.turnBudget,
|
|
2307
|
+
toolBudgets
|
|
2308
|
+
});
|
|
2309
|
+
for (let i = 0;i < results.length; i++) {
|
|
2310
|
+
const run = results[i];
|
|
2311
|
+
recordRun(run.agent, taskTexts[i], run.exitCode, run.progressSummary?.durationMs ?? 0);
|
|
2312
|
+
}
|
|
2313
|
+
for (const result of results) {
|
|
2314
|
+
if (result.progress)
|
|
2315
|
+
allProgress.push(result.progress);
|
|
2316
|
+
if (result.artifactPaths)
|
|
2317
|
+
allArtifactPaths.push(result.artifactPaths);
|
|
2318
|
+
}
|
|
2319
|
+
if (foregroundControl) {
|
|
2320
|
+
updateForegroundNestedProjection(foregroundControl);
|
|
2321
|
+
attachRootChildrenToSteps(runId, results, foregroundControl.nestedChildren);
|
|
2322
|
+
}
|
|
2323
|
+
const interrupted = results.find((result) => result.interrupted);
|
|
2324
|
+
const details = compactForegroundDetails({
|
|
2325
|
+
mode: "parallel",
|
|
2326
|
+
runId,
|
|
2327
|
+
results,
|
|
2328
|
+
progress: params.includeProgress ? allProgress : undefined,
|
|
2329
|
+
artifacts: allArtifactPaths.length ? { dir: artifactsDir, files: allArtifactPaths } : undefined,
|
|
2330
|
+
totalChildUsage: sumResultsUsage(results),
|
|
2331
|
+
totalCost: sumResultsCost(results)
|
|
2332
|
+
});
|
|
2333
|
+
rememberForegroundRun(deps.state, { runId, mode: "parallel", cwd: effectiveCwd, results: details.results });
|
|
2334
|
+
if (interrupted) {
|
|
2335
|
+
return {
|
|
2336
|
+
content: [{ type: "text", text: `Parallel run paused after interrupt (${interrupted.agent}). Waiting for explicit next action.` }],
|
|
2337
|
+
details
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
const detachedIndex = results.findIndex((result) => result.detached);
|
|
2341
|
+
const detached = detachedIndex >= 0 ? results[detachedIndex] : undefined;
|
|
2342
|
+
if (detached) {
|
|
2343
|
+
return {
|
|
2344
|
+
content: [{ type: "text", text: `Parallel run detached for intercom coordination (${detached.agent}). Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
|
|
2345
|
+
details
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
if (foregroundControl)
|
|
2349
|
+
updateForegroundNestedProjection(foregroundControl);
|
|
2350
|
+
const intercomReceipt = await maybeBuildForegroundIntercomReceipt({
|
|
2351
|
+
pi: deps.pi,
|
|
2352
|
+
intercomBridge: data.intercomBridge,
|
|
2353
|
+
runId,
|
|
2354
|
+
mode: "parallel",
|
|
2355
|
+
details,
|
|
2356
|
+
...foregroundControl?.nestedChildren?.length ? { nestedChildren: foregroundControl.nestedChildren } : {}
|
|
2357
|
+
});
|
|
2358
|
+
if (intercomReceipt) {
|
|
2359
|
+
return {
|
|
2360
|
+
content: [{ type: "text", text: intercomReceipt.text }],
|
|
2361
|
+
details: intercomReceipt.details
|
|
2362
|
+
};
|
|
2363
|
+
}
|
|
2364
|
+
const worktreeSuffix = buildParallelWorktreeSuffix(worktreeSetup, artifactsDir, tasks);
|
|
2365
|
+
const ok = results.filter((result) => result.exitCode === 0).length;
|
|
2366
|
+
const downgradeNote = backgroundRequestedWhileClarifying ? " (background requested, but clarify kept this run foreground)" : "";
|
|
2367
|
+
const aggregatedOutput = aggregateParallelOutputs(results.map((result) => ({
|
|
2368
|
+
agent: result.agent,
|
|
2369
|
+
output: result.truncation?.text || getSingleResultOutput(result),
|
|
2370
|
+
exitCode: result.exitCode,
|
|
2371
|
+
error: result.error,
|
|
2372
|
+
timedOut: result.timedOut
|
|
2373
|
+
})), (i, agent) => `=== Task ${i + 1}: ${agent} ===`);
|
|
2374
|
+
const summary = `${ok}/${results.length} succeeded${downgradeNote}`;
|
|
2375
|
+
const fullContent = worktreeSuffix ? `${summary}
|
|
223
2376
|
|
|
224
|
-
${
|
|
2377
|
+
${aggregatedOutput}
|
|
225
2378
|
|
|
226
|
-
${
|
|
2379
|
+
${worktreeSuffix}` : `${summary}
|
|
227
2380
|
|
|
228
|
-
${X$}`}],details:_$}}finally{if(l)A2(l)}}async function Sz($,J){let{params:Z,effectiveCwd:Q,agents:X,ctx:Y,signal:H,runId:j,sessionDirForIndex:U,sessionFileForTask:G,thinkingOverrideForTask:z,shareEnabled:V,artifactConfig:B,artifactsDir:K,onUpdate:W,sessionRoot:A,controlConfig:F,contextPolicy:_}=$,f=K9($,J),O=$.intercomBridge.active?u$(j,Z.agent,0):void 0,y=[],C=[],T=X.find((F$)=>F$.name===Z.agent);if(!T)return{content:[{type:"text",text:`Unknown agent: ${Z.agent}`}],isError:!0,details:{mode:"single",results:[]}};let h=p7({runBudget:$.toolBudget,agentBudget:T.toolBudget,configBudget:$.configToolBudget});if(h.error)return k2(Z,Error(h.error));let b=Y.model?.provider,w=Y.modelRegistry.getAvailable().map(y0),q=Z.task??"",S=B0(Z.model??T.model,Y.model,w,b,{scope:$.modelScope,source:Z.model?"explicit":"inherited"}),M=X0(Z.skill),N=Z.output!==void 0?Z.output:T.output,E=qJ(N,T.output),n=Z.outputMode??"inline",L=r0(J.config.maxSubagentDepth),k=s0(L,T.maxSubagentDepth);if(Z.clarify===!0&&Y.hasUI){let F$=P0(T,{output:E,skills:M}),z$=I0(Q),Y$=await Y.ui.custom((K$,_$,R,i)=>new VJ(K$,_$,[T],[q],q,void 0,[F$],w,b,z$,i,"single"),{overlay:!0,overlayOptions:{anchor:"center",width:84,maxHeight:"80%"}});if(!Y$||!Y$.confirmed)return{content:[{type:"text",text:"Cancelled"}],details:{mode:"single",results:[]}};q=Y$.templates[0];let Z$=Y$.behaviorOverrides[0];if(Z$?.model)S=B0(Z$.model,Y.model,w,b,{scope:$.modelScope,source:"explicit"});if(Z$?.output!==void 0)E=qJ(Z$.output,T.output);if(Z$?.skills!==void 0)M=Z$.skills;if(Y$.runInBackground){if(!I1())return{content:[{type:"text",text:"Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed."}],isError:!0,details:{mode:"single",results:[]}};let K$=P1(),_$={pi:J.pi,cwd:Y.cwd,currentSessionId:J.state.currentSessionId,parentSessionId:Y.sessionManager.getSessionId()??void 0,currentModelProvider:Y.model?.provider,currentModel:Y.model,modelScope:$.modelScope};return v8(K$,{agent:Z.agent,task:A0(_,Z.agent)?i0(q):q,agentConfig:T,ctx:_$,availableModels:w,cwd:Q,maxOutput:Z.maxOutput,artifactsDir:B.enabled?K:void 0,artifactConfig:B,shareEnabled:V,sessionRoot:A,sessionFile:G(Z.agent,0),skills:M===!1?[]:M,output:E,outputMode:n,outputBaseDir:e8(J,K,K$),modelOverride:S,thinkingOverride:z(Z.agent,0),maxSubagentDepth:k,worktreeSetupHook:J.config.worktreeSetupHook,worktreeSetupHookTimeoutMs:J.config.worktreeSetupHookTimeoutMs,worktreeBaseDir:J.config.worktreeBaseDir,controlConfig:F,controlIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,childIntercomTarget:$.intercomBridge.active?(R,i)=>u$(K$,R,i):void 0,timeoutMs:$.timeoutMs,turnBudget:$.turnBudget,toolBudget:h.toolBudget})}}if(A0(_,Z.agent))q=i0(q);let o=q,g=y1(E,Y.cwd,Q,e8(J,K,j)),I=b0(n,g,`Single run (${Z.agent})`);if(I)return{content:[{type:"text",text:I}],isError:!0,details:{mode:"single",results:[]}};q=OJ(q,g);let a;if(M===!1)a=[];else a=M;let O$=new AbortController,P=J.state.foregroundControls.get(j);if(P)P.currentAgent=Z.agent,P.currentIndex=0,P.currentActivityState=void 0,P.updatedAt=Date.now(),P.interrupt=()=>{if(O$.signal.aborted)return!1;return O$.abort(),P.currentActivityState=void 0,P.updatedAt=Date.now(),!0};let w$=W?(F$)=>{if(P){let z$=F$.details?.progress?.[0];P.currentAgent=Z.agent,P.currentIndex=z$?.index??0,P.currentActivityState=z$?.activityState,P.lastActivityAt=z$?.lastActivityAt,P.currentTool=z$?.currentTool,P.currentToolStartedAt=z$?.currentToolStartedAt,P.currentPath=z$?.currentPath,P.turnCount=z$?.turnCount,P.tokens=z$?.tokens,P.toolCount=z$?.toolCount,P.updatedAt=Date.now()}W(F$)}:void 0,$$=$.deadlineAt??($.timeoutMs!==void 0?Date.now()+$.timeoutMs:void 0),l=await LJ(Y.cwd,X,Z.agent,q,{parentSessionId:Y.sessionManager.getSessionId()??void 0,cwd:Q,signal:H,interruptSignal:O$.signal,allowIntercomDetach:T.systemPrompt?.includes(V1)===!0,intercomEvents:J.pi.events,runId:j,sessionDir:U(0),sessionFile:G(Z.agent,0),share:V,artifactsDir:B.enabled?K:void 0,artifactConfig:B,maxOutput:Z.maxOutput,outputPath:g,outputMode:n,maxSubagentDepth:k,onUpdate:w$,controlConfig:F,onControlEvent:f,intercomSessionName:O,orchestratorIntercomTarget:$.intercomBridge.active?$.intercomBridge.orchestratorTarget:void 0,nestedRoute:P?.nestedRoute,index:0,modelOverride:S,thinkingOverride:z(Z.agent,0),availableModels:w,preferredModelProvider:b,modelScope:$.modelScope,skills:a,acceptance:Z.acceptance,acceptanceContext:{mode:"single"},onDetachedExit:(F$)=>B9(J.state,{runId:j,mode:"single",cwd:Q,index:0,result:F$}),timeoutMs:$.timeoutMs,deadlineAt:$$,turnBudget:$.turnBudget,toolBudget:h.toolBudget});if(P?.currentIndex===0)P.interrupt=void 0,P.currentActivityState=l.progress?.activityState,P.lastActivityAt=l.progress?.lastActivityAt,P.currentTool=l.progress?.currentTool,P.currentToolStartedAt=l.progress?.currentToolStartedAt,P.currentPath=l.progress?.currentPath,P.turnCount=l.progress?.turnCount,P.tokens=l.progress?.tokens,P.toolCount=l.progress?.toolCount,P.updatedAt=Date.now();if(MJ(Z.agent,o,l.exitCode,l.progressSummary?.durationMs??0),l.progress)y.push(l.progress);if(l.artifactPaths)C.push(l.artifactPaths);let v$=f0(l),c=sZ({fullOutput:v$,truncatedOutput:l.truncation?.text,outputPath:g,outputMode:l.outputMode,exitCode:l.exitCode,savedPath:l.savedOutputPath,outputReference:l.outputReference,saveError:l.outputSaveError});if(P)i1(P),D1(j,[l],P.nestedChildren);let H$=jJ({mode:"single",runId:j,results:[l],...$.turnBudget?{turnBudget:$.turnBudget}:{},...h.toolBudget?{toolBudget:h.toolBudget}:{},progress:Z.includeProgress?y:void 0,artifacts:C.length?{dir:K,files:C}:void 0,truncation:l.truncation,totalChildUsage:uJ([l]),totalCost:HJ([l])});if(G9(J.state,{runId:j,mode:"single",cwd:Q,results:H$.results}),!l.detached&&!l.interrupted){if(P)i1(P);let F$=await W9({pi:J.pi,intercomBridge:$.intercomBridge,runId:j,mode:"single",details:H$,...P?.nestedChildren?.length?{nestedChildren:P.nestedChildren}:{}});if(F$)return{content:[{type:"text",text:F$.text}],details:F$.details,...l.exitCode!==0?{isError:!0}:{}}}if(l.detached)return{content:[{type:"text",text:`Detached for intercom coordination: ${Z.agent}. Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.`}],details:H$};if(l.interrupted)return{content:[{type:"text",text:`Run paused after interrupt (${Z.agent}). Waiting for explicit next action.`}],details:H$};if(l.exitCode!==0)return{content:[{type:"text",text:Yz(l,c.displayOutput)}],details:H$,isError:!0};return{content:[{type:"text",text:c.displayOutput||"(no output)"}],details:H$}}function Cz($){if(($.chain?.length??0)>0)return"chain";if(($.tasks?.length??0)>0)return"parallel";return"single"}function Rz($){return{content:[{type:"text",text:"Rejected: a subagent call is already in progress. Issue exactly ONE subagent call per turn."}],isError:!0,details:{mode:Cz($),results:[]}}}function d7($){let J=$.action?.toLowerCase();if(J==="single"&&($.agent!==void 0||$.task!==void 0)){let Z={...$};return delete Z.action,Z}if((J==="parallel"||J==="tasks")&&($.tasks?.length??0)>0){let Z={...$};return delete Z.action,Z}return $}function YA($){let J=async(Q,X,Y,H,j)=>{$.state.baseCwd=j.cwd,$.state.foregroundRuns??=new Map,$.state.foregroundControls??=new Map,$.state.lastForegroundControlId??=null;let U=d7(X),G=wV(j.cwd,U.cwd),z=U.cwd===void 0?U:{...U,cwd:G},V=z.action;if(V){if(V==="doctor"){let s=null,p=$.state.currentSessionId,M$;try{s=j.sessionManager.getSessionFile()??null,p=j.sessionManager.getSessionId()}catch(Q$){M$=Q$ instanceof Error?`${Q$.name}: ${Q$.message}`:String(Q$)}let x;try{x=s2($.pi.getSessionName(),j.sessionManager.getSessionId())}catch(Q$){if(!M$)M$=Q$ instanceof Error?`${Q$.name}: ${Q$.message}`:String(Q$)}return{content:[{type:"text",text:r3({cwd:G,config:$.config,state:$.state,context:z.context,requestedSessionDir:z.sessionDir,currentSessionFile:s,currentSessionId:p,orchestratorTarget:x,sessionError:M$,expandTilde:$.expandTilde})}],details:{mode:"management",results:[]}}}if(V==="status"){let s=z.id??z.runId,p=P2($),M$=kV(j,$);if(z.view==="fleet")return a8(z,{state:$.state,nested:p,sessionRoots:M$});if(s)try{let x=O1(s,{state:$.state,nested:p});if(x?.kind==="foreground"){let Q$=V9($.state,x.id);if(Q$){if(z.view==="transcript")return{content:[{type:"text",text:"Live foreground transcript is already visible in the expanded running subagent result. Persisted session transcript becomes inspectable after the foreground run completes when sessions are enabled."}],details:{mode:"management",results:[]}};return m7(Q$)}}}catch(x){return{content:[{type:"text",text:x instanceof Error?x.message:String(x)}],isError:!0,details:{mode:"management",results:[]}}}else{let x=V9($.state,void 0);if(x&&z.view!=="transcript")return m7(x);if(x&&z.view==="transcript")return{content:[{type:"text",text:"Live foreground transcript is already visible in the expanded running subagent result. Pass an async run id to inspect a background transcript."}],details:{mode:"management",results:[]}}}return a8(z,{state:$.state,nested:p,sessionRoots:M$})}if(V==="resume")return Qz({params:z,requestCwd:G,ctx:j,deps:$});if(V==="steer"){let s=(z.message??z.task??"").trim();if(!s)return{content:[{type:"text",text:"action='steer' requires message."}],isError:!0,details:{mode:"management",results:[]}};let p=z.runId??z.id;if(z.dir)try{let x=y2(z,Q0,h$),Q$=x.resolvedId??p??T$.basename(x.asyncDir??z.dir);return u7({state:$.state,runId:Q$,message:s,index:z.index,kill:$.kill,location:x})}catch(x){return{content:[{type:"text",text:x instanceof Error?x.message:String(x)}],isError:!0,details:{mode:"management",results:[]}}}if(!p)return{content:[{type:"text",text:"action='steer' requires id or dir."}],isError:!0,details:{mode:"management",results:[]}};let M$;try{M$=O1(p,{state:$.state,nested:P2($)})}catch(x){return{content:[{type:"text",text:x instanceof Error?x.message:String(x)}],isError:!0,details:{mode:"management",results:[]}}}if(M$?.kind==="nested")return Zz({target:M$,message:s,index:z.index});if(M$?.kind==="foreground")return{content:[{type:"text",text:"action='steer' currently supports live async DM child sessions only; use action='interrupt' or action='resume' for foreground runs."}],isError:!0,details:{mode:"management",results:[]}};if(M$?.kind!=="async")return{content:[{type:"text",text:`No async run found for '${p}'.`}],isError:!0,details:{mode:"management",results:[]}};return u7({state:$.state,runId:M$.id,message:s,index:z.index,kill:$.kill,location:M$.location})}if(V==="append-step")return lV({params:z,requestCwd:G,ctx:j,deps:$});if(V==="schedule"||V==="schedule-list"||V==="schedule-status"||V==="schedule-cancel"){if(!$.handleScheduledRunAction)return{content:[{type:"text",text:`Action '${V}' is not available in this subagent context.`}],isError:!0,details:{mode:"management",results:[]}};return $.handleScheduledRunAction(z,j)}if(V==="interrupt"){let s=z.runId??z.id,p;if(s)try{p=O1(s,{state:$.state,nested:P2($)})}catch(Q$){return{content:[{type:"text",text:Q$ instanceof Error?Q$.message:String(Q$)}],isError:!0,details:{mode:"management",results:[]}}}if(p?.kind==="nested")return $z(p);let M$=V9($.state,p?.kind==="foreground"?p.id:s);if(M$?.interrupt){if(M$.interrupt())return M$.updatedAt=Date.now(),M$.currentActivityState=void 0,{content:[{type:"text",text:`Interrupt requested for foreground run ${M$.runId}.`}],details:{mode:"management",results:[]}};return{content:[{type:"text",text:`Foreground run ${M$.runId} has no active child step to interrupt.`}],isError:!0,details:{mode:"management",results:[]}}}let x=dV($.state,p?.kind==="async"?p.id:s,$.kill,p?.kind==="async"?p.location:void 0);if(x)return x;return{content:[{type:"text",text:"No interrupt-capable run found in this session."}],isError:!0,details:{mode:"management",results:[]}}}if(!Y4.includes(V))return{content:[{type:"text",text:`Unknown action: ${V}. Valid: ${Y4.join(", ")}`}],isError:!0,details:{mode:"management",results:[]}};if($.allowMutatingManagementActions===!1&&bV.has(V))return{content:[{type:"text",text:`Action '${V}' is not available from child-safe subagent fanout mode.`}],isError:!0,details:{mode:"management",results:[]}};return w3(V,z,{...j,cwd:G,config:$.config})}let{blocked:B,depth:K,maxDepth:W}=U4($.config.maxSubagentDepth);if(B)return{content:[{type:"text",text:`Nested subagent call blocked (depth=${K}, max=${W}). You are running at the maximum subagent nesting depth. Complete your current task directly without delegating to further subagents.`}],isError:!0,details:{mode:"single",results:[]}};let A=_z(z);if(A.error)return A.error;let F=A.params,_=g7(F,K,$.config.forceTopLevelAsync===!0),f=Gz(_);if(f.error)return DJ(_,f.error);let O=Bz(_,$.config);if(O.error)return DJ(_,O.error);let y=x2(_.toolBudget,"toolBudget");if(y.error)return DJ(_,y.error);let C=x2($.config.toolBudget,"config.toolBudget");if(C.error)return DJ(_,C.error);let T=S8(_.agentScope),h=_.cwd??j.cwd,b=j.sessionManager.getSessionFile()??null;$.state.currentSessionId=m8(j.sessionManager);let w=$.discoverAgents(h,T),q=w.agents,S=w.modelScope,M=Vz(_,q);_=M.params;let N=s2($.pi.getSessionName(),j.sessionManager.getSessionId()),E=y4({config:$.config.intercomBridge,context:_.context,orchestratorTarget:N}),n=E.active?q.map((s)=>f4(s,E)):q,L=P1().slice(0,8),k=SJ(),o=k?CJ():void 0,g=k??v3(L),I=_.share===!0,a=(_.chain?.length??0)>0,O$=(_.tasks?.length??0)>0,P=!a&&!O$&&Boolean(_.agent),w$=a&&_.clarify===!0&&j.hasUI&&!(_.chain?.some(E$)??!1),$$=jz(_,n,a,O$,P,w$);if($$)return $$;let l=()=>{return},v$=()=>{return};try{let s=Q7(j.sessionManager,M.usesFork?"fork":void 0);l=s.sessionFileForIndex,v$=s.thinkingOverrideForIndex}catch(s){return k2(_,s)}let c=_.async??$.asyncByDefault,H$=(a||O$)&&c&&_.clarify===!0,F$=c&&_.clarify!==!0,z$=t2($.config.control,_.control),Y$={...g2,enabled:_.artifacts!==!1},Z$=n2(b,h),K$;if(_.sessionDir)K$=T$.resolve($.expandTilde(_.sessionDir));else{let s=$.config.defaultSessionDir?T$.resolve($.expandTilde($.config.defaultSessionDir)):$.getSubagentSessionRoot(b);K$=T$.join(s,L)}try{n0.mkdirSync(K$,{recursive:!0})}catch(s){let p=s instanceof Error?s.message:String(s);return k2(_,Error(`Failed to create session directory '${K$}': ${p}`))}let _$=(s)=>T$.join(K$,`run-${s??0}`),R=(s,p)=>A0(M,s)?l(p):void 0,i=(s,p)=>A0(M,s)?v$(p):void 0,n$=(s,p)=>R(s,p)??T$.join(_$(p),"session.jsonl"),J$=(s)=>T$.join(_$(s),"session.jsonl");try{Az(_,M,R,$.config.chain?.dynamicFanout?.maxItems)}catch(s){return k2(_,s)}let c$=Uz(_,$.config.chain?.dynamicFanout?.maxItems);if(c$)return c$;let N$=H?(s)=>H(k1(s,_.context)):void 0,X$=a?"chain":O$?"parallel":"single",A$=PV({state:$.state,config:$.config,sessionId:$.state.currentSessionId,requested:xV(_,$.config),mode:X$});if(A$)return A$;let U$={params:_,effectiveCwd:h,ctx:j,signal:Y,onUpdate:N$,agents:n,runId:L,shareEnabled:I,sessionRoot:K$,sessionDirForIndex:_$,sessionFileForIndex:J$,sessionFileForTask:n$,thinkingOverrideForTask:i,artifactConfig:Y$,artifactsDir:Z$,backgroundRequestedWhileClarifying:H$,effectiveAsync:F$,controlConfig:z$,intercomBridge:E,nestedRoute:g,timeoutMs:f.timeoutMs,turnBudget:O.turnBudget,toolBudget:y.toolBudget,configToolBudget:C.toolBudget,contextPolicy:M,modelScope:S},m=F$?void 0:{runId:L,mode:X$,startedAt:Date.now(),updatedAt:Date.now(),currentAgent:void 0,currentIndex:void 0,currentActivityState:void 0,nestedRoute:g,interrupt:void 0};if(m)$.state.foregroundControls.set(L,m),$.state.lastForegroundControlId=L;let R$=(s,p)=>{if(!k||!o)return;let M$=Date.now(),x=p?.details,Q$=s==="subagent.nested.started"?"running":p?.isError||x?.results.some((D)=>D.exitCode!==0)?"failed":x?.results.some((D)=>D.interrupted)?"paused":"complete",p$=p?.isError?p.content.find((D)=>D.type==="text")?.text:void 0,I$=O$&&_.tasks?_.tasks.map((D)=>D.agent):a&&_.chain?_.chain.flatMap((D)=>E$(D)?D.parallel.map((G$)=>G$.agent):[D.agent]):_.agent?[_.agent]:[],F1=E.active&&I$[0]?u$(L,I$[0],0):void 0;try{p1(k,{type:s,ts:M$,parentRunId:o.parentRunId,parentStepIndex:o.parentStepIndex,child:{id:L,parentRunId:o.parentRunId,parentStepIndex:o.parentStepIndex,depth:o.depth,path:o.path,ownerIntercomTarget:process.env.DM_SUBAGENT_INTERCOM_SESSION_NAME,leafIntercomTarget:F1,intercomTarget:F1,ownerState:Q$==="running"?"live":"gone",mode:X$,state:Q$,agent:I$[0],agents:I$,startedAt:m?.startedAt??M$,...Q$!=="running"?{endedAt:M$}:{},lastUpdate:M$,...x?.totalCost?{totalCost:x.totalCost}:{},...p$?{error:p$}:{},...x?.results.length?{steps:x.results.map((D)=>({agent:D.agent,status:D.interrupted?"paused":D.exitCode===0?"complete":"failed",...D.sessionFile?{sessionFile:D.sessionFile}:{},...D.error?{error:D.error}:{}}))}:{}}})}catch(D){console.error("Failed to emit nested foreground status event:",D)}},i$=!1;try{let s=qz(U$,$);if(s)return k1(s,_.context);if(m)R$("subagent.nested.started"),i$=!0;if(a&&_.chain){let p=await Oz(U$,$);return R$("subagent.nested.completed",p),k1(p,_.context)}if(O$&&_.tasks){let p=await Tz(U$,$);return R$("subagent.nested.completed",p),k1(p,_.context)}if(P){let p=await Sz(U$,$);return R$("subagent.nested.completed",p),k1(p,_.context)}}catch(s){let p=k2(_,s);if(i$)R$("subagent.nested.completed",p);return p}finally{if(m){if(s3($.state,L),$.state.foregroundControls.delete(L),$.state.lastForegroundControlId===L)$.state.lastForegroundControlId=null}}return k1({content:[{type:"text",text:"Invalid params"}],isError:!0,details:{mode:"single",results:[]}},_.context)};return{execute:async(Q,X,Y,H,j)=>{let U=d7(X);if(U.action)return J(Q,U,Y,H,j);if($.state.subagentInProgress===!0)return Rz(U);$.state.subagentInProgress=!0;try{return await J(Q,U,Y,H,j)}finally{$.state.subagentInProgress=!1}}}}export{YA as createSubagentExecutor};
|
|
2381
|
+
${aggregatedOutput}`;
|
|
2382
|
+
return {
|
|
2383
|
+
content: [{ type: "text", text: fullContent }],
|
|
2384
|
+
details
|
|
2385
|
+
};
|
|
2386
|
+
} finally {
|
|
2387
|
+
if (worktreeSetup)
|
|
2388
|
+
cleanupWorktrees(worktreeSetup);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
async function runSinglePath(data, deps) {
|
|
2392
|
+
const {
|
|
2393
|
+
params,
|
|
2394
|
+
effectiveCwd,
|
|
2395
|
+
agents,
|
|
2396
|
+
ctx,
|
|
2397
|
+
signal,
|
|
2398
|
+
runId,
|
|
2399
|
+
sessionDirForIndex,
|
|
2400
|
+
sessionFileForTask,
|
|
2401
|
+
thinkingOverrideForTask,
|
|
2402
|
+
shareEnabled,
|
|
2403
|
+
artifactConfig,
|
|
2404
|
+
artifactsDir,
|
|
2405
|
+
onUpdate,
|
|
2406
|
+
sessionRoot,
|
|
2407
|
+
controlConfig,
|
|
2408
|
+
contextPolicy
|
|
2409
|
+
} = data;
|
|
2410
|
+
const onControlEvent = createForegroundControlNotifier(data, deps);
|
|
2411
|
+
const childIntercomTarget = data.intercomBridge.active ? resolveSubagentIntercomTarget(runId, params.agent, 0) : undefined;
|
|
2412
|
+
const allProgress = [];
|
|
2413
|
+
const allArtifactPaths = [];
|
|
2414
|
+
const agentConfig = agents.find((a) => a.name === params.agent);
|
|
2415
|
+
if (!agentConfig) {
|
|
2416
|
+
return {
|
|
2417
|
+
content: [{ type: "text", text: `Unknown agent: ${params.agent}` }],
|
|
2418
|
+
isError: true,
|
|
2419
|
+
details: { mode: "single", results: [] }
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
const effectiveToolBudget = resolveEffectiveToolBudget({ runBudget: data.toolBudget, agentBudget: agentConfig.toolBudget, configBudget: data.configToolBudget });
|
|
2423
|
+
if (effectiveToolBudget.error)
|
|
2424
|
+
return toExecutionErrorResult(params, new Error(effectiveToolBudget.error));
|
|
2425
|
+
const currentProvider = ctx.model?.provider;
|
|
2426
|
+
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
2427
|
+
let task = params.task ?? "";
|
|
2428
|
+
let modelOverride = resolveSubagentModelOverride(params.model ?? agentConfig.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: params.model ? "explicit" : "inherited" });
|
|
2429
|
+
let skillOverride = normalizeSkillInput(params.skill);
|
|
2430
|
+
const rawOutput = params.output !== undefined ? params.output : agentConfig.output;
|
|
2431
|
+
let effectiveOutput = normalizeSingleOutputOverride(rawOutput, agentConfig.output);
|
|
2432
|
+
const effectiveOutputMode = params.outputMode ?? "inline";
|
|
2433
|
+
const currentMaxSubagentDepth = resolveCurrentMaxSubagentDepth(deps.config.maxSubagentDepth);
|
|
2434
|
+
const maxSubagentDepth = resolveChildMaxSubagentDepth(currentMaxSubagentDepth, agentConfig.maxSubagentDepth);
|
|
2435
|
+
if (params.clarify === true && ctx.hasUI) {
|
|
2436
|
+
const behavior = resolveStepBehavior(agentConfig, { output: effectiveOutput, skills: skillOverride });
|
|
2437
|
+
const availableSkills = discoverAvailableSkills(effectiveCwd);
|
|
2438
|
+
const result = await ctx.ui.custom((tui, theme, _kb, done) => new ChainClarifyComponent(tui, theme, [agentConfig], [task], task, undefined, [behavior], availableModels, currentProvider, availableSkills, done, "single"), { overlay: true, overlayOptions: { anchor: "center", width: 84, maxHeight: "80%" } });
|
|
2439
|
+
if (!result || !result.confirmed) {
|
|
2440
|
+
return { content: [{ type: "text", text: "Cancelled" }], details: { mode: "single", results: [] } };
|
|
2441
|
+
}
|
|
2442
|
+
task = result.templates[0];
|
|
2443
|
+
const override = result.behaviorOverrides[0];
|
|
2444
|
+
if (override?.model)
|
|
2445
|
+
modelOverride = resolveSubagentModelOverride(override.model, ctx.model, availableModels, currentProvider, { scope: data.modelScope, source: "explicit" });
|
|
2446
|
+
if (override?.output !== undefined)
|
|
2447
|
+
effectiveOutput = normalizeSingleOutputOverride(override.output, agentConfig.output);
|
|
2448
|
+
if (override?.skills !== undefined)
|
|
2449
|
+
skillOverride = override.skills;
|
|
2450
|
+
if (result.runInBackground) {
|
|
2451
|
+
if (!isAsyncAvailable()) {
|
|
2452
|
+
return {
|
|
2453
|
+
content: [{ type: "text", text: "Background mode requires upstream jiti for TypeScript execution but it could not be found. Ensure the dm-subagents package dependencies are installed." }],
|
|
2454
|
+
isError: true,
|
|
2455
|
+
details: { mode: "single", results: [] }
|
|
2456
|
+
};
|
|
2457
|
+
}
|
|
2458
|
+
const id = randomUUID();
|
|
2459
|
+
const asyncCtx = {
|
|
2460
|
+
pi: deps.pi,
|
|
2461
|
+
cwd: ctx.cwd,
|
|
2462
|
+
currentSessionId: deps.state.currentSessionId,
|
|
2463
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
2464
|
+
currentModelProvider: ctx.model?.provider,
|
|
2465
|
+
currentModel: ctx.model,
|
|
2466
|
+
modelScope: data.modelScope
|
|
2467
|
+
};
|
|
2468
|
+
return executeAsyncSingle(id, {
|
|
2469
|
+
agent: params.agent,
|
|
2470
|
+
task: shouldForkAgent(contextPolicy, params.agent) ? wrapForkTask(task) : task,
|
|
2471
|
+
agentConfig,
|
|
2472
|
+
ctx: asyncCtx,
|
|
2473
|
+
availableModels,
|
|
2474
|
+
cwd: effectiveCwd,
|
|
2475
|
+
maxOutput: params.maxOutput,
|
|
2476
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
2477
|
+
artifactConfig,
|
|
2478
|
+
shareEnabled,
|
|
2479
|
+
sessionRoot,
|
|
2480
|
+
sessionFile: sessionFileForTask(params.agent, 0),
|
|
2481
|
+
skills: skillOverride === false ? [] : skillOverride,
|
|
2482
|
+
output: effectiveOutput,
|
|
2483
|
+
outputMode: effectiveOutputMode,
|
|
2484
|
+
outputBaseDir: resolveSingleRunOutputBaseDir(deps, artifactsDir, id),
|
|
2485
|
+
modelOverride,
|
|
2486
|
+
thinkingOverride: thinkingOverrideForTask(params.agent, 0),
|
|
2487
|
+
maxSubagentDepth,
|
|
2488
|
+
worktreeSetupHook: deps.config.worktreeSetupHook,
|
|
2489
|
+
worktreeSetupHookTimeoutMs: deps.config.worktreeSetupHookTimeoutMs,
|
|
2490
|
+
worktreeBaseDir: deps.config.worktreeBaseDir,
|
|
2491
|
+
controlConfig,
|
|
2492
|
+
controlIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
2493
|
+
childIntercomTarget: data.intercomBridge.active ? (agent, index) => resolveSubagentIntercomTarget(id, agent, index) : undefined,
|
|
2494
|
+
timeoutMs: data.timeoutMs,
|
|
2495
|
+
turnBudget: data.turnBudget,
|
|
2496
|
+
toolBudget: effectiveToolBudget.toolBudget
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
if (shouldForkAgent(contextPolicy, params.agent)) {
|
|
2501
|
+
task = wrapForkTask(task);
|
|
2502
|
+
}
|
|
2503
|
+
const cleanTask = task;
|
|
2504
|
+
const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, effectiveCwd, resolveSingleRunOutputBaseDir(deps, artifactsDir, runId));
|
|
2505
|
+
const validationError = validateFileOnlyOutputMode(effectiveOutputMode, outputPath, `Single run (${params.agent})`);
|
|
2506
|
+
if (validationError) {
|
|
2507
|
+
return { content: [{ type: "text", text: validationError }], isError: true, details: { mode: "single", results: [] } };
|
|
2508
|
+
}
|
|
2509
|
+
task = injectSingleOutputInstruction(task, outputPath);
|
|
2510
|
+
let effectiveSkills;
|
|
2511
|
+
if (skillOverride === false) {
|
|
2512
|
+
effectiveSkills = [];
|
|
2513
|
+
} else {
|
|
2514
|
+
effectiveSkills = skillOverride;
|
|
2515
|
+
}
|
|
2516
|
+
const interruptController = new AbortController;
|
|
2517
|
+
const foregroundControl = deps.state.foregroundControls.get(runId);
|
|
2518
|
+
if (foregroundControl) {
|
|
2519
|
+
foregroundControl.currentAgent = params.agent;
|
|
2520
|
+
foregroundControl.currentIndex = 0;
|
|
2521
|
+
foregroundControl.currentActivityState = undefined;
|
|
2522
|
+
foregroundControl.updatedAt = Date.now();
|
|
2523
|
+
foregroundControl.interrupt = () => {
|
|
2524
|
+
if (interruptController.signal.aborted)
|
|
2525
|
+
return false;
|
|
2526
|
+
interruptController.abort();
|
|
2527
|
+
foregroundControl.currentActivityState = undefined;
|
|
2528
|
+
foregroundControl.updatedAt = Date.now();
|
|
2529
|
+
return true;
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
const forwardSingleUpdate = onUpdate ? (update) => {
|
|
2533
|
+
if (foregroundControl) {
|
|
2534
|
+
const firstProgress = update.details?.progress?.[0];
|
|
2535
|
+
foregroundControl.currentAgent = params.agent;
|
|
2536
|
+
foregroundControl.currentIndex = firstProgress?.index ?? 0;
|
|
2537
|
+
foregroundControl.currentActivityState = firstProgress?.activityState;
|
|
2538
|
+
foregroundControl.lastActivityAt = firstProgress?.lastActivityAt;
|
|
2539
|
+
foregroundControl.currentTool = firstProgress?.currentTool;
|
|
2540
|
+
foregroundControl.currentToolStartedAt = firstProgress?.currentToolStartedAt;
|
|
2541
|
+
foregroundControl.currentPath = firstProgress?.currentPath;
|
|
2542
|
+
foregroundControl.turnCount = firstProgress?.turnCount;
|
|
2543
|
+
foregroundControl.tokens = firstProgress?.tokens;
|
|
2544
|
+
foregroundControl.toolCount = firstProgress?.toolCount;
|
|
2545
|
+
foregroundControl.updatedAt = Date.now();
|
|
2546
|
+
}
|
|
2547
|
+
onUpdate(update);
|
|
2548
|
+
} : undefined;
|
|
2549
|
+
const deadlineAt = data.deadlineAt ?? (data.timeoutMs !== undefined ? Date.now() + data.timeoutMs : undefined);
|
|
2550
|
+
const r = await runSync(ctx.cwd, agents, params.agent, task, {
|
|
2551
|
+
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
2552
|
+
cwd: effectiveCwd,
|
|
2553
|
+
signal,
|
|
2554
|
+
interruptSignal: interruptController.signal,
|
|
2555
|
+
allowIntercomDetach: agentConfig.systemPrompt?.includes(INTERCOM_BRIDGE_MARKER) === true,
|
|
2556
|
+
intercomEvents: deps.pi.events,
|
|
2557
|
+
runId,
|
|
2558
|
+
sessionDir: sessionDirForIndex(0),
|
|
2559
|
+
sessionFile: sessionFileForTask(params.agent, 0),
|
|
2560
|
+
share: shareEnabled,
|
|
2561
|
+
artifactsDir: artifactConfig.enabled ? artifactsDir : undefined,
|
|
2562
|
+
artifactConfig,
|
|
2563
|
+
maxOutput: params.maxOutput,
|
|
2564
|
+
outputPath,
|
|
2565
|
+
outputMode: effectiveOutputMode,
|
|
2566
|
+
maxSubagentDepth,
|
|
2567
|
+
onUpdate: forwardSingleUpdate,
|
|
2568
|
+
controlConfig,
|
|
2569
|
+
onControlEvent,
|
|
2570
|
+
intercomSessionName: childIntercomTarget,
|
|
2571
|
+
orchestratorIntercomTarget: data.intercomBridge.active ? data.intercomBridge.orchestratorTarget : undefined,
|
|
2572
|
+
nestedRoute: foregroundControl?.nestedRoute,
|
|
2573
|
+
index: 0,
|
|
2574
|
+
modelOverride,
|
|
2575
|
+
thinkingOverride: thinkingOverrideForTask(params.agent, 0),
|
|
2576
|
+
availableModels,
|
|
2577
|
+
preferredModelProvider: currentProvider,
|
|
2578
|
+
modelScope: data.modelScope,
|
|
2579
|
+
skills: effectiveSkills,
|
|
2580
|
+
acceptance: params.acceptance,
|
|
2581
|
+
acceptanceContext: { mode: "single" },
|
|
2582
|
+
onDetachedExit: (result) => updateRememberedForegroundChild(deps.state, { runId, mode: "single", cwd: effectiveCwd, index: 0, result }),
|
|
2583
|
+
timeoutMs: data.timeoutMs,
|
|
2584
|
+
deadlineAt,
|
|
2585
|
+
turnBudget: data.turnBudget,
|
|
2586
|
+
toolBudget: effectiveToolBudget.toolBudget
|
|
2587
|
+
});
|
|
2588
|
+
if (foregroundControl?.currentIndex === 0) {
|
|
2589
|
+
foregroundControl.interrupt = undefined;
|
|
2590
|
+
foregroundControl.currentActivityState = r.progress?.activityState;
|
|
2591
|
+
foregroundControl.lastActivityAt = r.progress?.lastActivityAt;
|
|
2592
|
+
foregroundControl.currentTool = r.progress?.currentTool;
|
|
2593
|
+
foregroundControl.currentToolStartedAt = r.progress?.currentToolStartedAt;
|
|
2594
|
+
foregroundControl.currentPath = r.progress?.currentPath;
|
|
2595
|
+
foregroundControl.turnCount = r.progress?.turnCount;
|
|
2596
|
+
foregroundControl.tokens = r.progress?.tokens;
|
|
2597
|
+
foregroundControl.toolCount = r.progress?.toolCount;
|
|
2598
|
+
foregroundControl.updatedAt = Date.now();
|
|
2599
|
+
}
|
|
2600
|
+
recordRun(params.agent, cleanTask, r.exitCode, r.progressSummary?.durationMs ?? 0);
|
|
2601
|
+
if (r.progress)
|
|
2602
|
+
allProgress.push(r.progress);
|
|
2603
|
+
if (r.artifactPaths)
|
|
2604
|
+
allArtifactPaths.push(r.artifactPaths);
|
|
2605
|
+
const fullOutput = getSingleResultOutput(r);
|
|
2606
|
+
const finalizedOutput = finalizeSingleOutput({
|
|
2607
|
+
fullOutput,
|
|
2608
|
+
truncatedOutput: r.truncation?.text,
|
|
2609
|
+
outputPath,
|
|
2610
|
+
outputMode: r.outputMode,
|
|
2611
|
+
exitCode: r.exitCode,
|
|
2612
|
+
savedPath: r.savedOutputPath,
|
|
2613
|
+
outputReference: r.outputReference,
|
|
2614
|
+
saveError: r.outputSaveError
|
|
2615
|
+
});
|
|
2616
|
+
if (foregroundControl) {
|
|
2617
|
+
updateForegroundNestedProjection(foregroundControl);
|
|
2618
|
+
attachRootChildrenToSteps(runId, [r], foregroundControl.nestedChildren);
|
|
2619
|
+
}
|
|
2620
|
+
const details = compactForegroundDetails({
|
|
2621
|
+
mode: "single",
|
|
2622
|
+
runId,
|
|
2623
|
+
results: [r],
|
|
2624
|
+
...data.turnBudget ? { turnBudget: data.turnBudget } : {},
|
|
2625
|
+
...effectiveToolBudget.toolBudget ? { toolBudget: effectiveToolBudget.toolBudget } : {},
|
|
2626
|
+
progress: params.includeProgress ? allProgress : undefined,
|
|
2627
|
+
artifacts: allArtifactPaths.length ? { dir: artifactsDir, files: allArtifactPaths } : undefined,
|
|
2628
|
+
truncation: r.truncation,
|
|
2629
|
+
totalChildUsage: sumResultsUsage([r]),
|
|
2630
|
+
totalCost: sumResultsCost([r])
|
|
2631
|
+
});
|
|
2632
|
+
rememberForegroundRun(deps.state, { runId, mode: "single", cwd: effectiveCwd, results: details.results });
|
|
2633
|
+
if (!r.detached && !r.interrupted) {
|
|
2634
|
+
if (foregroundControl)
|
|
2635
|
+
updateForegroundNestedProjection(foregroundControl);
|
|
2636
|
+
const intercomReceipt = await maybeBuildForegroundIntercomReceipt({
|
|
2637
|
+
pi: deps.pi,
|
|
2638
|
+
intercomBridge: data.intercomBridge,
|
|
2639
|
+
runId,
|
|
2640
|
+
mode: "single",
|
|
2641
|
+
details,
|
|
2642
|
+
...foregroundControl?.nestedChildren?.length ? { nestedChildren: foregroundControl.nestedChildren } : {}
|
|
2643
|
+
});
|
|
2644
|
+
if (intercomReceipt) {
|
|
2645
|
+
return {
|
|
2646
|
+
content: [{ type: "text", text: intercomReceipt.text }],
|
|
2647
|
+
details: intercomReceipt.details,
|
|
2648
|
+
...r.exitCode !== 0 ? { isError: true } : {}
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
if (r.detached) {
|
|
2653
|
+
return {
|
|
2654
|
+
content: [{ type: "text", text: `Detached for intercom coordination: ${params.agent}. Reply to the supervisor request first. After the child exits, start a fresh follow-up if needed.` }],
|
|
2655
|
+
details
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
if (r.interrupted) {
|
|
2659
|
+
return {
|
|
2660
|
+
content: [{ type: "text", text: `Run paused after interrupt (${params.agent}). Waiting for explicit next action.` }],
|
|
2661
|
+
details
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
if (r.exitCode !== 0)
|
|
2665
|
+
return {
|
|
2666
|
+
content: [{ type: "text", text: formatFailedSingleRunOutput(r, finalizedOutput.displayOutput) }],
|
|
2667
|
+
details,
|
|
2668
|
+
isError: true
|
|
2669
|
+
};
|
|
2670
|
+
return {
|
|
2671
|
+
content: [{ type: "text", text: finalizedOutput.displayOutput || "(no output)" }],
|
|
2672
|
+
details
|
|
2673
|
+
};
|
|
2674
|
+
}
|
|
2675
|
+
function inferExecutionMode(params) {
|
|
2676
|
+
if ((params.chain?.length ?? 0) > 0)
|
|
2677
|
+
return "chain";
|
|
2678
|
+
if ((params.tasks?.length ?? 0) > 0)
|
|
2679
|
+
return "parallel";
|
|
2680
|
+
return "single";
|
|
2681
|
+
}
|
|
2682
|
+
function duplicateSubagentCallResult(params) {
|
|
2683
|
+
return {
|
|
2684
|
+
content: [{
|
|
2685
|
+
type: "text",
|
|
2686
|
+
text: "Rejected: a subagent call is already in progress. Issue exactly ONE subagent call per turn."
|
|
2687
|
+
}],
|
|
2688
|
+
isError: true,
|
|
2689
|
+
details: { mode: inferExecutionMode(params), results: [] }
|
|
2690
|
+
};
|
|
2691
|
+
}
|
|
2692
|
+
function omitExecutionModeActionAlias(params) {
|
|
2693
|
+
const action = params.action?.toLowerCase();
|
|
2694
|
+
if (action === "single" && (params.agent !== undefined || params.task !== undefined)) {
|
|
2695
|
+
const rest = { ...params };
|
|
2696
|
+
delete rest.action;
|
|
2697
|
+
return rest;
|
|
2698
|
+
}
|
|
2699
|
+
if ((action === "parallel" || action === "tasks") && (params.tasks?.length ?? 0) > 0) {
|
|
2700
|
+
const rest = { ...params };
|
|
2701
|
+
delete rest.action;
|
|
2702
|
+
return rest;
|
|
2703
|
+
}
|
|
2704
|
+
return params;
|
|
2705
|
+
}
|
|
2706
|
+
export function createSubagentExecutor(deps) {
|
|
2707
|
+
const execute = async (_id, params, signal, onUpdate, ctx) => {
|
|
2708
|
+
deps.state.baseCwd = ctx.cwd;
|
|
2709
|
+
deps.state.foregroundRuns ??= new Map;
|
|
2710
|
+
deps.state.foregroundControls ??= new Map;
|
|
2711
|
+
deps.state.lastForegroundControlId ??= null;
|
|
2712
|
+
const requestParams = omitExecutionModeActionAlias(params);
|
|
2713
|
+
const requestCwd = resolveRequestedCwd(ctx.cwd, requestParams.cwd);
|
|
2714
|
+
const paramsWithResolvedCwd = requestParams.cwd === undefined ? requestParams : { ...requestParams, cwd: requestCwd };
|
|
2715
|
+
const action = paramsWithResolvedCwd.action;
|
|
2716
|
+
if (action) {
|
|
2717
|
+
if (action === "doctor") {
|
|
2718
|
+
let currentSessionFile = null;
|
|
2719
|
+
let currentSessionId = deps.state.currentSessionId;
|
|
2720
|
+
let sessionError;
|
|
2721
|
+
try {
|
|
2722
|
+
currentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
|
|
2723
|
+
currentSessionId = ctx.sessionManager.getSessionId();
|
|
2724
|
+
} catch (error) {
|
|
2725
|
+
sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
2726
|
+
}
|
|
2727
|
+
let orchestratorTarget;
|
|
2728
|
+
try {
|
|
2729
|
+
orchestratorTarget = resolveIntercomSessionTarget(deps.pi.getSessionName(), ctx.sessionManager.getSessionId());
|
|
2730
|
+
} catch (error) {
|
|
2731
|
+
if (!sessionError)
|
|
2732
|
+
sessionError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
2733
|
+
}
|
|
2734
|
+
return {
|
|
2735
|
+
content: [{
|
|
2736
|
+
type: "text",
|
|
2737
|
+
text: buildDoctorReport({
|
|
2738
|
+
cwd: requestCwd,
|
|
2739
|
+
config: deps.config,
|
|
2740
|
+
state: deps.state,
|
|
2741
|
+
context: paramsWithResolvedCwd.context,
|
|
2742
|
+
requestedSessionDir: paramsWithResolvedCwd.sessionDir,
|
|
2743
|
+
currentSessionFile,
|
|
2744
|
+
currentSessionId,
|
|
2745
|
+
orchestratorTarget,
|
|
2746
|
+
sessionError,
|
|
2747
|
+
expandTilde: deps.expandTilde
|
|
2748
|
+
})
|
|
2749
|
+
}],
|
|
2750
|
+
details: { mode: "management", results: [] }
|
|
2751
|
+
};
|
|
2752
|
+
}
|
|
2753
|
+
if (action === "status") {
|
|
2754
|
+
const targetRunId = paramsWithResolvedCwd.id ?? paramsWithResolvedCwd.runId;
|
|
2755
|
+
const nestedScope = nestedResolutionScopeForExecutor(deps);
|
|
2756
|
+
const sessionRoots = trustedSessionRootsForStatus(ctx, deps);
|
|
2757
|
+
if (paramsWithResolvedCwd.view === "fleet") {
|
|
2758
|
+
return inspectSubagentStatus(paramsWithResolvedCwd, { state: deps.state, nested: nestedScope, sessionRoots });
|
|
2759
|
+
}
|
|
2760
|
+
if (targetRunId) {
|
|
2761
|
+
try {
|
|
2762
|
+
const resolved = resolveSubagentRunId(targetRunId, { state: deps.state, nested: nestedScope });
|
|
2763
|
+
if (resolved?.kind === "foreground") {
|
|
2764
|
+
const foreground = getForegroundControl(deps.state, resolved.id);
|
|
2765
|
+
if (foreground) {
|
|
2766
|
+
if (paramsWithResolvedCwd.view === "transcript") {
|
|
2767
|
+
return {
|
|
2768
|
+
content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Persisted session transcript becomes inspectable after the foreground run completes when sessions are enabled." }],
|
|
2769
|
+
details: { mode: "management", results: [] }
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
return foregroundStatusResult(foreground);
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
} catch (error) {
|
|
2776
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2777
|
+
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
2778
|
+
}
|
|
2779
|
+
} else {
|
|
2780
|
+
const foreground = getForegroundControl(deps.state, undefined);
|
|
2781
|
+
if (foreground && paramsWithResolvedCwd.view !== "transcript")
|
|
2782
|
+
return foregroundStatusResult(foreground);
|
|
2783
|
+
if (foreground && paramsWithResolvedCwd.view === "transcript") {
|
|
2784
|
+
return {
|
|
2785
|
+
content: [{ type: "text", text: "Live foreground transcript is already visible in the expanded running subagent result. Pass an async run id to inspect a background transcript." }],
|
|
2786
|
+
details: { mode: "management", results: [] }
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
return inspectSubagentStatus(paramsWithResolvedCwd, { state: deps.state, nested: nestedScope, sessionRoots });
|
|
2791
|
+
}
|
|
2792
|
+
if (action === "resume") {
|
|
2793
|
+
return resumeAsyncRun({ params: paramsWithResolvedCwd, requestCwd, ctx, deps });
|
|
2794
|
+
}
|
|
2795
|
+
if (action === "steer") {
|
|
2796
|
+
const message = (paramsWithResolvedCwd.message ?? paramsWithResolvedCwd.task ?? "").trim();
|
|
2797
|
+
if (!message)
|
|
2798
|
+
return { content: [{ type: "text", text: "action='steer' requires message." }], isError: true, details: { mode: "management", results: [] } };
|
|
2799
|
+
const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
|
|
2800
|
+
if (paramsWithResolvedCwd.dir) {
|
|
2801
|
+
try {
|
|
2802
|
+
const location = resolveAsyncRunLocation(paramsWithResolvedCwd, ASYNC_DIR, RESULTS_DIR);
|
|
2803
|
+
const runId = location.resolvedId ?? targetRunId ?? path.basename(location.asyncDir ?? paramsWithResolvedCwd.dir);
|
|
2804
|
+
return steerAsyncRun({ state: deps.state, runId, message, index: paramsWithResolvedCwd.index, kill: deps.kill, location });
|
|
2805
|
+
} catch (error) {
|
|
2806
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
2807
|
+
return { content: [{ type: "text", text }], isError: true, details: { mode: "management", results: [] } };
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
if (!targetRunId)
|
|
2811
|
+
return { content: [{ type: "text", text: "action='steer' requires id or dir." }], isError: true, details: { mode: "management", results: [] } };
|
|
2812
|
+
let resolved;
|
|
2813
|
+
try {
|
|
2814
|
+
resolved = resolveSubagentRunId(targetRunId, { state: deps.state, nested: nestedResolutionScopeForExecutor(deps) });
|
|
2815
|
+
} catch (error) {
|
|
2816
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
2817
|
+
return { content: [{ type: "text", text }], isError: true, details: { mode: "management", results: [] } };
|
|
2818
|
+
}
|
|
2819
|
+
if (resolved?.kind === "nested")
|
|
2820
|
+
return steerNestedRun({ target: resolved, message, index: paramsWithResolvedCwd.index });
|
|
2821
|
+
if (resolved?.kind === "foreground")
|
|
2822
|
+
return { content: [{ type: "text", text: "action='steer' currently supports live async DM child sessions only; use action='interrupt' or action='resume' for foreground runs." }], isError: true, details: { mode: "management", results: [] } };
|
|
2823
|
+
if (resolved?.kind !== "async")
|
|
2824
|
+
return { content: [{ type: "text", text: `No async run found for '${targetRunId}'.` }], isError: true, details: { mode: "management", results: [] } };
|
|
2825
|
+
return steerAsyncRun({ state: deps.state, runId: resolved.id, message, index: paramsWithResolvedCwd.index, kill: deps.kill, location: resolved.location });
|
|
2826
|
+
}
|
|
2827
|
+
if (action === "append-step") {
|
|
2828
|
+
return appendStepToAsyncChain({ params: paramsWithResolvedCwd, requestCwd, ctx, deps });
|
|
2829
|
+
}
|
|
2830
|
+
if (action === "schedule" || action === "schedule-list" || action === "schedule-status" || action === "schedule-cancel") {
|
|
2831
|
+
if (!deps.handleScheduledRunAction) {
|
|
2832
|
+
return {
|
|
2833
|
+
content: [{ type: "text", text: `Action '${action}' is not available in this subagent context.` }],
|
|
2834
|
+
isError: true,
|
|
2835
|
+
details: { mode: "management", results: [] }
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
return deps.handleScheduledRunAction(paramsWithResolvedCwd, ctx);
|
|
2839
|
+
}
|
|
2840
|
+
if (action === "interrupt") {
|
|
2841
|
+
const targetRunId = paramsWithResolvedCwd.runId ?? paramsWithResolvedCwd.id;
|
|
2842
|
+
let resolved;
|
|
2843
|
+
if (targetRunId) {
|
|
2844
|
+
try {
|
|
2845
|
+
resolved = resolveSubagentRunId(targetRunId, { state: deps.state, nested: nestedResolutionScopeForExecutor(deps) });
|
|
2846
|
+
} catch (error) {
|
|
2847
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2848
|
+
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
if (resolved?.kind === "nested")
|
|
2852
|
+
return interruptNestedRun(resolved);
|
|
2853
|
+
const foreground = getForegroundControl(deps.state, resolved?.kind === "foreground" ? resolved.id : targetRunId);
|
|
2854
|
+
if (foreground?.interrupt) {
|
|
2855
|
+
const interrupted = foreground.interrupt();
|
|
2856
|
+
if (interrupted) {
|
|
2857
|
+
foreground.updatedAt = Date.now();
|
|
2858
|
+
foreground.currentActivityState = undefined;
|
|
2859
|
+
return {
|
|
2860
|
+
content: [{ type: "text", text: `Interrupt requested for foreground run ${foreground.runId}.` }],
|
|
2861
|
+
details: { mode: "management", results: [] }
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
return {
|
|
2865
|
+
content: [{ type: "text", text: `Foreground run ${foreground.runId} has no active child step to interrupt.` }],
|
|
2866
|
+
isError: true,
|
|
2867
|
+
details: { mode: "management", results: [] }
|
|
2868
|
+
};
|
|
2869
|
+
}
|
|
2870
|
+
const asyncInterruptResult = interruptAsyncRun(deps.state, resolved?.kind === "async" ? resolved.id : targetRunId, deps.kill, resolved?.kind === "async" ? resolved.location : undefined);
|
|
2871
|
+
if (asyncInterruptResult)
|
|
2872
|
+
return asyncInterruptResult;
|
|
2873
|
+
return {
|
|
2874
|
+
content: [{ type: "text", text: "No interrupt-capable run found in this session." }],
|
|
2875
|
+
isError: true,
|
|
2876
|
+
details: { mode: "management", results: [] }
|
|
2877
|
+
};
|
|
2878
|
+
}
|
|
2879
|
+
if (!SUBAGENT_ACTIONS.includes(action)) {
|
|
2880
|
+
return {
|
|
2881
|
+
content: [{ type: "text", text: `Unknown action: ${action}. Valid: ${SUBAGENT_ACTIONS.join(", ")}` }],
|
|
2882
|
+
isError: true,
|
|
2883
|
+
details: { mode: "management", results: [] }
|
|
2884
|
+
};
|
|
2885
|
+
}
|
|
2886
|
+
if (deps.allowMutatingManagementActions === false && MUTATING_MANAGEMENT_ACTIONS.has(action)) {
|
|
2887
|
+
return {
|
|
2888
|
+
content: [{ type: "text", text: `Action '${action}' is not available from child-safe subagent fanout mode.` }],
|
|
2889
|
+
isError: true,
|
|
2890
|
+
details: { mode: "management", results: [] }
|
|
2891
|
+
};
|
|
2892
|
+
}
|
|
2893
|
+
return handleManagementAction(action, paramsWithResolvedCwd, {
|
|
2894
|
+
...ctx,
|
|
2895
|
+
cwd: requestCwd,
|
|
2896
|
+
config: deps.config
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
const { blocked, depth, maxDepth } = checkSubagentDepth(deps.config.maxSubagentDepth);
|
|
2900
|
+
if (blocked) {
|
|
2901
|
+
return {
|
|
2902
|
+
content: [
|
|
2903
|
+
{
|
|
2904
|
+
type: "text",
|
|
2905
|
+
text: `Nested subagent call blocked (depth=${depth}, max=${maxDepth}). ` + "You are running at the maximum subagent nesting depth. " + "Complete your current task directly without delegating to further subagents."
|
|
2906
|
+
}
|
|
2907
|
+
],
|
|
2908
|
+
isError: true,
|
|
2909
|
+
details: { mode: "single", results: [] }
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2912
|
+
const normalized = normalizeRepeatedParallelCounts(paramsWithResolvedCwd);
|
|
2913
|
+
if (normalized.error)
|
|
2914
|
+
return normalized.error;
|
|
2915
|
+
const normalizedParams = normalized.params;
|
|
2916
|
+
let effectiveParams = applyForceTopLevelAsyncOverride(normalizedParams, depth, deps.config.forceTopLevelAsync === true);
|
|
2917
|
+
const foregroundTimeout = resolveForegroundTimeout(effectiveParams);
|
|
2918
|
+
if (foregroundTimeout.error)
|
|
2919
|
+
return buildRequestedModeError(effectiveParams, foregroundTimeout.error);
|
|
2920
|
+
const turnBudget = resolveTurnBudget(effectiveParams, deps.config);
|
|
2921
|
+
if (turnBudget.error)
|
|
2922
|
+
return buildRequestedModeError(effectiveParams, turnBudget.error);
|
|
2923
|
+
const runToolBudget = resolveToolBudget(effectiveParams.toolBudget, "toolBudget");
|
|
2924
|
+
if (runToolBudget.error)
|
|
2925
|
+
return buildRequestedModeError(effectiveParams, runToolBudget.error);
|
|
2926
|
+
const configToolBudget = resolveToolBudget(deps.config.toolBudget, "config.toolBudget");
|
|
2927
|
+
if (configToolBudget.error)
|
|
2928
|
+
return buildRequestedModeError(effectiveParams, configToolBudget.error);
|
|
2929
|
+
const scope = resolveExecutionAgentScope(effectiveParams.agentScope);
|
|
2930
|
+
const effectiveCwd = effectiveParams.cwd ?? ctx.cwd;
|
|
2931
|
+
const parentSessionFile = ctx.sessionManager.getSessionFile() ?? null;
|
|
2932
|
+
deps.state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
|
|
2933
|
+
const discovered = deps.discoverAgents(effectiveCwd, scope);
|
|
2934
|
+
const discoveredAgents = discovered.agents;
|
|
2935
|
+
const modelScope = discovered.modelScope;
|
|
2936
|
+
const contextPolicy = resolveAgentDefaultContextPolicy(effectiveParams, discoveredAgents);
|
|
2937
|
+
effectiveParams = contextPolicy.params;
|
|
2938
|
+
const sessionName = resolveIntercomSessionTarget(deps.pi.getSessionName(), ctx.sessionManager.getSessionId());
|
|
2939
|
+
const intercomBridge = resolveIntercomBridge({
|
|
2940
|
+
config: deps.config.intercomBridge,
|
|
2941
|
+
context: effectiveParams.context,
|
|
2942
|
+
orchestratorTarget: sessionName
|
|
2943
|
+
});
|
|
2944
|
+
const agents = intercomBridge.active ? discoveredAgents.map((agent) => applyIntercomBridgeToAgent(agent, intercomBridge)) : discoveredAgents;
|
|
2945
|
+
const runId = randomUUID().slice(0, 8);
|
|
2946
|
+
const inheritedNestedRoute = resolveInheritedNestedRouteFromEnv();
|
|
2947
|
+
const nestedParentAddress = inheritedNestedRoute ? resolveNestedParentAddressFromEnv() : undefined;
|
|
2948
|
+
const nestedRoute = inheritedNestedRoute ?? createNestedRoute(runId);
|
|
2949
|
+
const shareEnabled = effectiveParams.share === true;
|
|
2950
|
+
const hasChain = (effectiveParams.chain?.length ?? 0) > 0;
|
|
2951
|
+
const hasTasks = (effectiveParams.tasks?.length ?? 0) > 0;
|
|
2952
|
+
const hasSingle = !hasChain && !hasTasks && Boolean(effectiveParams.agent);
|
|
2953
|
+
const allowClarifyTaskPrompt = hasChain && effectiveParams.clarify === true && ctx.hasUI && !(effectiveParams.chain?.some(isParallelStep) ?? false);
|
|
2954
|
+
const validationError = validateExecutionInput(effectiveParams, agents, hasChain, hasTasks, hasSingle, allowClarifyTaskPrompt);
|
|
2955
|
+
if (validationError)
|
|
2956
|
+
return validationError;
|
|
2957
|
+
let forkSessionFileForIndex = () => {
|
|
2958
|
+
return;
|
|
2959
|
+
};
|
|
2960
|
+
let forkThinkingOverrideForIndex = () => {
|
|
2961
|
+
return;
|
|
2962
|
+
};
|
|
2963
|
+
try {
|
|
2964
|
+
const forkContextResolver = createForkContextResolver(ctx.sessionManager, contextPolicy.usesFork ? "fork" : undefined);
|
|
2965
|
+
forkSessionFileForIndex = forkContextResolver.sessionFileForIndex;
|
|
2966
|
+
forkThinkingOverrideForIndex = forkContextResolver.thinkingOverrideForIndex;
|
|
2967
|
+
} catch (error) {
|
|
2968
|
+
return toExecutionErrorResult(effectiveParams, error);
|
|
2969
|
+
}
|
|
2970
|
+
const requestedAsync = effectiveParams.async ?? deps.asyncByDefault;
|
|
2971
|
+
const backgroundRequestedWhileClarifying = (hasChain || hasTasks) && requestedAsync && effectiveParams.clarify === true;
|
|
2972
|
+
const effectiveAsync = requestedAsync && effectiveParams.clarify !== true;
|
|
2973
|
+
const controlConfig = resolveControlConfig(deps.config.control, effectiveParams.control);
|
|
2974
|
+
const artifactConfig = {
|
|
2975
|
+
...DEFAULT_ARTIFACT_CONFIG,
|
|
2976
|
+
enabled: effectiveParams.artifacts !== false
|
|
2977
|
+
};
|
|
2978
|
+
const artifactsDir = getArtifactsDir(parentSessionFile, effectiveCwd);
|
|
2979
|
+
let sessionRoot;
|
|
2980
|
+
if (effectiveParams.sessionDir) {
|
|
2981
|
+
sessionRoot = path.resolve(deps.expandTilde(effectiveParams.sessionDir));
|
|
2982
|
+
} else {
|
|
2983
|
+
const baseSessionRoot = deps.config.defaultSessionDir ? path.resolve(deps.expandTilde(deps.config.defaultSessionDir)) : deps.getSubagentSessionRoot(parentSessionFile);
|
|
2984
|
+
sessionRoot = path.join(baseSessionRoot, runId);
|
|
2985
|
+
}
|
|
2986
|
+
try {
|
|
2987
|
+
fs.mkdirSync(sessionRoot, { recursive: true });
|
|
2988
|
+
} catch (error) {
|
|
2989
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2990
|
+
return toExecutionErrorResult(effectiveParams, new Error(`Failed to create session directory '${sessionRoot}': ${message}`));
|
|
2991
|
+
}
|
|
2992
|
+
const sessionDirForIndex = (idx) => path.join(sessionRoot, `run-${idx ?? 0}`);
|
|
2993
|
+
const forkSessionFileForTask = (agentName, idx) => shouldForkAgent(contextPolicy, agentName) ? forkSessionFileForIndex(idx) : undefined;
|
|
2994
|
+
const forkThinkingOverrideForTask = (agentName, idx) => shouldForkAgent(contextPolicy, agentName) ? forkThinkingOverrideForIndex(idx) : undefined;
|
|
2995
|
+
const childSessionFileForTask = (agentName, idx) => forkSessionFileForTask(agentName, idx) ?? path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
2996
|
+
const childSessionFileForIndex = (idx) => path.join(sessionDirForIndex(idx), "session.jsonl");
|
|
2997
|
+
try {
|
|
2998
|
+
preflightForkSessionsForStaticTasks(effectiveParams, contextPolicy, forkSessionFileForTask, deps.config.chain?.dynamicFanout?.maxItems);
|
|
2999
|
+
} catch (error) {
|
|
3000
|
+
return toExecutionErrorResult(effectiveParams, error);
|
|
3001
|
+
}
|
|
3002
|
+
const chainBindingsError = validateExecutionChainBindings(effectiveParams, deps.config.chain?.dynamicFanout?.maxItems);
|
|
3003
|
+
if (chainBindingsError)
|
|
3004
|
+
return chainBindingsError;
|
|
3005
|
+
const onUpdateWithContext = onUpdate ? (r) => onUpdate(withForkContext(r, effectiveParams.context)) : undefined;
|
|
3006
|
+
const foregroundMode = hasChain ? "chain" : hasTasks ? "parallel" : "single";
|
|
3007
|
+
const spawnLimitError = reserveSubagentSpawns({
|
|
3008
|
+
state: deps.state,
|
|
3009
|
+
config: deps.config,
|
|
3010
|
+
sessionId: deps.state.currentSessionId,
|
|
3011
|
+
requested: countRequestedSubagentSpawns(effectiveParams, deps.config),
|
|
3012
|
+
mode: foregroundMode
|
|
3013
|
+
});
|
|
3014
|
+
if (spawnLimitError)
|
|
3015
|
+
return spawnLimitError;
|
|
3016
|
+
const execData = {
|
|
3017
|
+
params: effectiveParams,
|
|
3018
|
+
effectiveCwd,
|
|
3019
|
+
ctx,
|
|
3020
|
+
signal,
|
|
3021
|
+
onUpdate: onUpdateWithContext,
|
|
3022
|
+
agents,
|
|
3023
|
+
runId,
|
|
3024
|
+
shareEnabled,
|
|
3025
|
+
sessionRoot,
|
|
3026
|
+
sessionDirForIndex,
|
|
3027
|
+
sessionFileForIndex: childSessionFileForIndex,
|
|
3028
|
+
sessionFileForTask: childSessionFileForTask,
|
|
3029
|
+
thinkingOverrideForTask: forkThinkingOverrideForTask,
|
|
3030
|
+
artifactConfig,
|
|
3031
|
+
artifactsDir,
|
|
3032
|
+
backgroundRequestedWhileClarifying,
|
|
3033
|
+
effectiveAsync,
|
|
3034
|
+
controlConfig,
|
|
3035
|
+
intercomBridge,
|
|
3036
|
+
nestedRoute,
|
|
3037
|
+
timeoutMs: foregroundTimeout.timeoutMs,
|
|
3038
|
+
turnBudget: turnBudget.turnBudget,
|
|
3039
|
+
toolBudget: runToolBudget.toolBudget,
|
|
3040
|
+
configToolBudget: configToolBudget.toolBudget,
|
|
3041
|
+
contextPolicy,
|
|
3042
|
+
modelScope
|
|
3043
|
+
};
|
|
3044
|
+
const foregroundControl = effectiveAsync ? undefined : {
|
|
3045
|
+
runId,
|
|
3046
|
+
mode: foregroundMode,
|
|
3047
|
+
startedAt: Date.now(),
|
|
3048
|
+
updatedAt: Date.now(),
|
|
3049
|
+
currentAgent: undefined,
|
|
3050
|
+
currentIndex: undefined,
|
|
3051
|
+
currentActivityState: undefined,
|
|
3052
|
+
nestedRoute,
|
|
3053
|
+
interrupt: undefined
|
|
3054
|
+
};
|
|
3055
|
+
if (foregroundControl) {
|
|
3056
|
+
deps.state.foregroundControls.set(runId, foregroundControl);
|
|
3057
|
+
deps.state.lastForegroundControlId = runId;
|
|
3058
|
+
}
|
|
3059
|
+
const writeNestedForegroundEvent = (type, result) => {
|
|
3060
|
+
if (!inheritedNestedRoute || !nestedParentAddress)
|
|
3061
|
+
return;
|
|
3062
|
+
const now = Date.now();
|
|
3063
|
+
const details = result?.details;
|
|
3064
|
+
const state = type === "subagent.nested.started" ? "running" : result?.isError || details?.results.some((child) => child.exitCode !== 0) ? "failed" : details?.results.some((child) => child.interrupted) ? "paused" : "complete";
|
|
3065
|
+
const errorText = result?.isError ? result.content.find((item) => item.type === "text")?.text : undefined;
|
|
3066
|
+
const agentsForSummary = hasTasks && effectiveParams.tasks ? effectiveParams.tasks.map((task) => task.agent) : hasChain && effectiveParams.chain ? effectiveParams.chain.flatMap((step) => isParallelStep(step) ? step.parallel.map((task) => task.agent) : [step.agent]) : effectiveParams.agent ? [effectiveParams.agent] : [];
|
|
3067
|
+
const leafIntercomTarget = intercomBridge.active && agentsForSummary[0] ? resolveSubagentIntercomTarget(runId, agentsForSummary[0], 0) : undefined;
|
|
3068
|
+
try {
|
|
3069
|
+
writeNestedEvent(inheritedNestedRoute, {
|
|
3070
|
+
type,
|
|
3071
|
+
ts: now,
|
|
3072
|
+
parentRunId: nestedParentAddress.parentRunId,
|
|
3073
|
+
parentStepIndex: nestedParentAddress.parentStepIndex,
|
|
3074
|
+
child: {
|
|
3075
|
+
id: runId,
|
|
3076
|
+
parentRunId: nestedParentAddress.parentRunId,
|
|
3077
|
+
parentStepIndex: nestedParentAddress.parentStepIndex,
|
|
3078
|
+
depth: nestedParentAddress.depth,
|
|
3079
|
+
path: nestedParentAddress.path,
|
|
3080
|
+
ownerIntercomTarget: process.env.DM_SUBAGENT_INTERCOM_SESSION_NAME,
|
|
3081
|
+
leafIntercomTarget,
|
|
3082
|
+
intercomTarget: leafIntercomTarget,
|
|
3083
|
+
ownerState: state === "running" ? "live" : "gone",
|
|
3084
|
+
mode: foregroundMode,
|
|
3085
|
+
state,
|
|
3086
|
+
agent: agentsForSummary[0],
|
|
3087
|
+
agents: agentsForSummary,
|
|
3088
|
+
startedAt: foregroundControl?.startedAt ?? now,
|
|
3089
|
+
...state !== "running" ? { endedAt: now } : {},
|
|
3090
|
+
lastUpdate: now,
|
|
3091
|
+
...details?.totalCost ? { totalCost: details.totalCost } : {},
|
|
3092
|
+
...errorText ? { error: errorText } : {},
|
|
3093
|
+
...details?.results.length ? { steps: details.results.map((child) => ({
|
|
3094
|
+
agent: child.agent,
|
|
3095
|
+
status: child.interrupted ? "paused" : child.exitCode === 0 ? "complete" : "failed",
|
|
3096
|
+
...child.sessionFile ? { sessionFile: child.sessionFile } : {},
|
|
3097
|
+
...child.error ? { error: child.error } : {}
|
|
3098
|
+
})) } : {}
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
} catch (error) {
|
|
3102
|
+
console.error("Failed to emit nested foreground status event:", error);
|
|
3103
|
+
}
|
|
3104
|
+
};
|
|
3105
|
+
let nestedForegroundStarted = false;
|
|
3106
|
+
try {
|
|
3107
|
+
const asyncResult = runAsyncPath(execData, deps);
|
|
3108
|
+
if (asyncResult)
|
|
3109
|
+
return withForkContext(asyncResult, effectiveParams.context);
|
|
3110
|
+
if (foregroundControl) {
|
|
3111
|
+
writeNestedForegroundEvent("subagent.nested.started");
|
|
3112
|
+
nestedForegroundStarted = true;
|
|
3113
|
+
}
|
|
3114
|
+
if (hasChain && effectiveParams.chain) {
|
|
3115
|
+
const result = await runChainPath(execData, deps);
|
|
3116
|
+
writeNestedForegroundEvent("subagent.nested.completed", result);
|
|
3117
|
+
return withForkContext(result, effectiveParams.context);
|
|
3118
|
+
}
|
|
3119
|
+
if (hasTasks && effectiveParams.tasks) {
|
|
3120
|
+
const result = await runParallelPath(execData, deps);
|
|
3121
|
+
writeNestedForegroundEvent("subagent.nested.completed", result);
|
|
3122
|
+
return withForkContext(result, effectiveParams.context);
|
|
3123
|
+
}
|
|
3124
|
+
if (hasSingle) {
|
|
3125
|
+
const result = await runSinglePath(execData, deps);
|
|
3126
|
+
writeNestedForegroundEvent("subagent.nested.completed", result);
|
|
3127
|
+
return withForkContext(result, effectiveParams.context);
|
|
3128
|
+
}
|
|
3129
|
+
} catch (error) {
|
|
3130
|
+
const errorResult = toExecutionErrorResult(effectiveParams, error);
|
|
3131
|
+
if (nestedForegroundStarted)
|
|
3132
|
+
writeNestedForegroundEvent("subagent.nested.completed", errorResult);
|
|
3133
|
+
return errorResult;
|
|
3134
|
+
} finally {
|
|
3135
|
+
if (foregroundControl) {
|
|
3136
|
+
clearPendingForegroundControlNotices(deps.state, runId);
|
|
3137
|
+
deps.state.foregroundControls.delete(runId);
|
|
3138
|
+
if (deps.state.lastForegroundControlId === runId) {
|
|
3139
|
+
deps.state.lastForegroundControlId = null;
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
return withForkContext({
|
|
3144
|
+
content: [{ type: "text", text: "Invalid params" }],
|
|
3145
|
+
isError: true,
|
|
3146
|
+
details: { mode: "single", results: [] }
|
|
3147
|
+
}, effectiveParams.context);
|
|
3148
|
+
};
|
|
3149
|
+
const executeWithSingleDispatchGuard = async (id, params, signal, onUpdate, ctx) => {
|
|
3150
|
+
const requestParams = omitExecutionModeActionAlias(params);
|
|
3151
|
+
if (requestParams.action)
|
|
3152
|
+
return execute(id, requestParams, signal, onUpdate, ctx);
|
|
3153
|
+
if (deps.state.subagentInProgress === true)
|
|
3154
|
+
return duplicateSubagentCallResult(requestParams);
|
|
3155
|
+
deps.state.subagentInProgress = true;
|
|
3156
|
+
try {
|
|
3157
|
+
return await execute(id, requestParams, signal, onUpdate, ctx);
|
|
3158
|
+
} finally {
|
|
3159
|
+
deps.state.subagentInProgress = false;
|
|
3160
|
+
}
|
|
3161
|
+
};
|
|
3162
|
+
return { execute: executeWithSingleDispatchGuard };
|
|
3163
|
+
}
|