@astralyn/pi 0.84.4 → 0.84.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +5 -4
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/core/agent-session.d.ts +6 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +4 -0
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +29 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +4 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +2 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +4 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/project-trust.js +2 -2
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/sdk.d.ts +5 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.js +2 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +12 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +2 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +2 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -0
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/background/index.d.ts +74 -0
- package/dist/extensions/background/index.d.ts.map +1 -0
- package/dist/extensions/background/index.js +332 -0
- package/dist/extensions/background/index.js.map +1 -0
- package/dist/extensions/background/manager.d.ts +81 -0
- package/dist/extensions/background/manager.d.ts.map +1 -0
- package/dist/extensions/background/manager.js +320 -0
- package/dist/extensions/background/manager.js.map +1 -0
- package/dist/extensions/background/registry.d.ts +138 -0
- package/dist/extensions/background/registry.d.ts.map +1 -0
- package/dist/extensions/background/registry.js +358 -0
- package/dist/extensions/background/registry.js.map +1 -0
- package/dist/extensions/background/render.d.ts +26 -0
- package/dist/extensions/background/render.d.ts.map +1 -0
- package/dist/extensions/background/render.js +118 -0
- package/dist/extensions/background/render.js.map +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +0 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +2 -5
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
- package/dist/extensions/subagent/agents-command.js +308 -153
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts +3 -6
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js +22 -192
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +4 -5
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/constants.js +11 -7
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts +0 -3
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +56 -188
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts +1 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +208 -576
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts +2 -2
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js +23 -15
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +1 -2
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +109 -131
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/schema.d.ts +4 -10
- package/dist/extensions/subagent/schema.d.ts.map +1 -1
- package/dist/extensions/subagent/schema.js +8 -13
- package/dist/extensions/subagent/schema.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +9 -20
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts +2 -2
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +27 -14
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/text.d.ts +3 -0
- package/dist/extensions/subagent/text.d.ts.map +1 -0
- package/dist/extensions/subagent/text.js +16 -0
- package/dist/extensions/subagent/text.js.map +1 -0
- package/dist/extensions/subagent/types.d.ts +13 -35
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/subagent/ui/model-list.d.ts +4 -3
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +10 -4
- package/dist/extensions/subagent/ui/model-list.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +77 -25
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +36 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +2 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +23 -10
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +5 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +12 -2
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +4 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +5 -2
- package/dist/modes/json-event.js.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/create-harness.d.ts.map +1 -1
- package/dist/server/create-harness.js +2 -0
- package/dist/server/create-harness.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +10 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +14 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/bundled/README.md +1 -0
- package/docs/bundled/extensions/background.md +64 -0
- package/docs/bundled/extensions/subagent.md +83 -71
- package/docs/compaction.md +6 -6
- package/docs/custom-provider.md +1 -1
- package/docs/docs.json +4 -0
- package/docs/environment-variables.md +8 -2
- package/docs/extensions.md +6 -2
- package/docs/json.md +6 -4
- package/docs/keybindings.md +9 -2
- package/docs/rpc.md +15 -4
- package/docs/sdk.md +9 -0
- package/docs/settings.md +31 -0
- package/docs/terminal-setup.md +23 -2
- package/docs/themes.md +24 -3
- package/docs/tui.md +2 -2
- package/docs/usage.md +4 -3
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +0 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +170 -221
- package/package.json +6 -6
- package/dist/extensions/subagent/display-name.d.ts +0 -6
- package/dist/extensions/subagent/display-name.d.ts.map +0 -1
- package/dist/extensions/subagent/display-name.js +0 -13
- package/dist/extensions/subagent/display-name.js.map +0 -1
- package/dist/extensions/subagent/ui/profile-editor.d.ts +0 -54
- package/dist/extensions/subagent/ui/profile-editor.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/profile-editor.js +0 -154
- package/dist/extensions/subagent/ui/profile-editor.js.map +0 -1
- package/dist/extensions/subagent/ui/profile-picker.d.ts +0 -32
- package/dist/extensions/subagent/ui/profile-picker.d.ts.map +0 -1
- package/dist/extensions/subagent/ui/profile-picker.js +0 -149
- package/dist/extensions/subagent/ui/profile-picker.js.map +0 -1
- package/examples/extensions/subagent/README.md +0 -175
- package/examples/extensions/subagent/agents/planner.md +0 -37
- package/examples/extensions/subagent/agents/reviewer.md +0 -35
- package/examples/extensions/subagent/agents/scout.md +0 -50
- package/examples/extensions/subagent/agents/worker.md +0 -24
- package/examples/extensions/subagent/agents.ts +0 -126
- package/examples/extensions/subagent/index.ts +0 -1009
- package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/examples/extensions/subagent/prompts/implement.md +0 -10
- package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { relative } from "node:path";
|
|
2
2
|
import { isRetryableAssistantError } from "@earendil-works/pi-ai/compat";
|
|
3
3
|
import { sleep } from "../../utils/sleep.js";
|
|
4
|
-
import { boundText, emptyUsage, mergeUsage,
|
|
5
|
-
import { DETAILS_ACTIVITY_LIMIT, DETAILS_OUTPUT_LIMIT, ERROR_TEXT_LIMIT, MAX_CONCURRENCY, MAX_TASKS,
|
|
4
|
+
import { boundText, emptyUsage, mergeUsage, toNestedUsage } from "./activity.js";
|
|
5
|
+
import { DETAILS_ACTIVITY_LIMIT, DETAILS_OUTPUT_LIMIT, ERROR_TEXT_LIMIT, MAX_CONCURRENCY, MAX_TASKS, RETRY_ERROR_TEXT_LIMIT, TASK_OUTPUT_LIMIT, TASK_RETRY_BASE_DELAY_MS, TASK_RETRY_LIMIT, TOTAL_OUTPUT_LIMIT, } from "./constants.js";
|
|
6
6
|
import { resolveSubagentTask } from "./resolve.js";
|
|
7
7
|
import { beginSubagentRetry, clearSubagentRetry } from "./retry.js";
|
|
8
8
|
import { runSdkTask } from "./sdk-runner.js";
|
|
@@ -57,9 +57,7 @@ function createRun(task, index, parentCwd) {
|
|
|
57
57
|
return {
|
|
58
58
|
id: runId(index),
|
|
59
59
|
agent: task.agent.name,
|
|
60
|
-
agentSource: task.agent.source,
|
|
61
60
|
description: task.description,
|
|
62
|
-
prompt: task.prompt,
|
|
63
61
|
// Display-only relative path; the worker session itself uses the
|
|
64
62
|
// resolved absolute task.cwd. Empty means "same as the parent".
|
|
65
63
|
cwd: relative(parentCwd, task.cwd),
|
|
@@ -67,8 +65,7 @@ function createRun(task, index, parentCwd) {
|
|
|
67
65
|
thinking: task.thinking,
|
|
68
66
|
status: "queued",
|
|
69
67
|
activities: [],
|
|
70
|
-
|
|
71
|
-
finalOutput: "",
|
|
68
|
+
report: "",
|
|
72
69
|
usage: emptyUsage(),
|
|
73
70
|
};
|
|
74
71
|
}
|
|
@@ -83,12 +80,11 @@ function detailsSize(details) {
|
|
|
83
80
|
}
|
|
84
81
|
export function boundSubagentDetails(details) {
|
|
85
82
|
const perRunBudget = Math.max(1_024, Math.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)));
|
|
86
|
-
const
|
|
83
|
+
const reportLimit = Math.min(TASK_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));
|
|
87
84
|
const bounded = {
|
|
88
85
|
...details,
|
|
89
86
|
runs: details.runs.map((run) => ({
|
|
90
87
|
...run,
|
|
91
|
-
prompt: boundText(run.prompt, 1_024),
|
|
92
88
|
cwd: boundText(run.cwd, 1_024),
|
|
93
89
|
currentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,
|
|
94
90
|
retry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,
|
|
@@ -97,21 +93,13 @@ export function boundSubagentDetails(details) {
|
|
|
97
93
|
summary: boundText(activity.summary, 256),
|
|
98
94
|
resultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,
|
|
99
95
|
})),
|
|
100
|
-
|
|
101
|
-
// head, or the transcript's live tail would freeze at the 1KB mark.
|
|
102
|
-
liveText: tailText(run.liveText, 1_024),
|
|
103
|
-
finalOutput: boundText(run.finalOutput, outputLimit),
|
|
96
|
+
report: boundText(run.report, reportLimit),
|
|
104
97
|
error: run.error ? boundText(run.error, 1_024) : undefined,
|
|
105
98
|
})),
|
|
106
99
|
};
|
|
107
100
|
const fields = [];
|
|
108
101
|
for (const run of bounded.runs) {
|
|
109
102
|
fields.push({
|
|
110
|
-
get: () => run.prompt,
|
|
111
|
-
set: (value) => {
|
|
112
|
-
run.prompt = value;
|
|
113
|
-
},
|
|
114
|
-
}, {
|
|
115
103
|
get: () => run.cwd,
|
|
116
104
|
set: (value) => {
|
|
117
105
|
run.cwd = value;
|
|
@@ -122,14 +110,9 @@ export function boundSubagentDetails(details) {
|
|
|
122
110
|
run.currentActivity = value || undefined;
|
|
123
111
|
},
|
|
124
112
|
}, {
|
|
125
|
-
get: () => run.
|
|
113
|
+
get: () => run.report,
|
|
126
114
|
set: (value) => {
|
|
127
|
-
run.
|
|
128
|
-
},
|
|
129
|
-
}, {
|
|
130
|
-
get: () => run.finalOutput,
|
|
131
|
-
set: (value) => {
|
|
132
|
-
run.finalOutput = value;
|
|
115
|
+
run.report = value;
|
|
133
116
|
},
|
|
134
117
|
}, {
|
|
135
118
|
get: () => run.error ?? "",
|
|
@@ -163,30 +146,28 @@ export function boundSubagentDetails(details) {
|
|
|
163
146
|
return bounded;
|
|
164
147
|
}
|
|
165
148
|
function statusOf(runs) {
|
|
166
|
-
if (runs.
|
|
167
|
-
return "
|
|
168
|
-
|
|
169
|
-
|
|
149
|
+
if (runs.length === 0)
|
|
150
|
+
return "running";
|
|
151
|
+
// Active beats terminal: any queued or running run keeps the batch
|
|
152
|
+
// "running" regardless of what the others have settled to.
|
|
170
153
|
if (runs.some((run) => run.status === "queued" || run.status === "running"))
|
|
171
154
|
return "running";
|
|
172
|
-
|
|
155
|
+
if (runs.every((run) => run.status === "completed"))
|
|
156
|
+
return "completed";
|
|
157
|
+
if (runs.some((run) => run.status === "completed"))
|
|
158
|
+
return "partial";
|
|
159
|
+
if (runs.every((run) => run.status === "aborted"))
|
|
160
|
+
return "aborted";
|
|
161
|
+
return "failed";
|
|
173
162
|
}
|
|
174
163
|
function statusText(details) {
|
|
164
|
+
if (details.runs.length === 0)
|
|
165
|
+
return "Initializing…";
|
|
175
166
|
const running = details.runs.filter((run) => run.status === "running").length;
|
|
176
167
|
const queued = details.runs.filter((run) => run.status === "queued").length;
|
|
177
168
|
const completed = details.runs.filter((run) => run.status === "completed").length;
|
|
178
169
|
const failed = details.runs.filter((run) => run.status === "failed").length;
|
|
179
170
|
const aborted = details.runs.filter((run) => run.status === "aborted").length;
|
|
180
|
-
if (details.mode === "single") {
|
|
181
|
-
const run = details.runs[0];
|
|
182
|
-
if (run?.currentActivity)
|
|
183
|
-
return run.currentActivity;
|
|
184
|
-
if (!run ||
|
|
185
|
-
(run.status === "running" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)) {
|
|
186
|
-
return "Initializing…";
|
|
187
|
-
}
|
|
188
|
-
return run.status === "running" ? "Thinking…" : run.status;
|
|
189
|
-
}
|
|
190
171
|
const parts = [`${completed}/${details.runs.length} complete`];
|
|
191
172
|
if (running)
|
|
192
173
|
parts.push(`${running} running`);
|
|
@@ -198,9 +179,8 @@ function statusText(details) {
|
|
|
198
179
|
parts.push(`${aborted} aborted`);
|
|
199
180
|
return parts.join(" · ");
|
|
200
181
|
}
|
|
201
|
-
function emitDetails(
|
|
182
|
+
function emitDetails(runs, startedAt, onUpdate) {
|
|
202
183
|
const details = {
|
|
203
|
-
mode,
|
|
204
184
|
status: statusOf(runs),
|
|
205
185
|
runs: [...runs],
|
|
206
186
|
startedAt,
|
|
@@ -217,8 +197,14 @@ function validateTaskCount(tasks) {
|
|
|
217
197
|
}
|
|
218
198
|
async function resolveTasks(tasks, options) {
|
|
219
199
|
validateTaskCount(tasks);
|
|
200
|
+
// One config load and one resolution pass for the whole batch: every
|
|
201
|
+
// task/profile/cwd/model is settled before any run is created or any
|
|
202
|
+
// worker starts, so a failing task cannot strand half-initialized runs.
|
|
220
203
|
const config = await loadSubagentConfig(options.agentDir);
|
|
221
|
-
return Promise.all(tasks.map((task) => resolveSubagentTask(task, options.parentCwd, options.
|
|
204
|
+
return Promise.all(tasks.map((task, index) => resolveSubagentTask(task, options.parentCwd, options.parent, options.agentDir, config).catch((error) => {
|
|
205
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
206
|
+
throw new Error(`Subagent task tasks[${index}] failed to resolve: ${message}`);
|
|
207
|
+
})));
|
|
222
208
|
}
|
|
223
209
|
// Reuses pi-ai's provider-error classification by wrapping the stored error
|
|
224
210
|
// text in the assistant-message shape it inspects.
|
|
@@ -241,8 +227,7 @@ function resetRunForRetry(run, attempt, maxAttempts, delayMs) {
|
|
|
241
227
|
run.error = undefined;
|
|
242
228
|
run.startedAt = undefined;
|
|
243
229
|
run.endedAt = undefined;
|
|
244
|
-
run.
|
|
245
|
-
run.liveText = "";
|
|
230
|
+
run.report = "";
|
|
246
231
|
run.activities.length = 0;
|
|
247
232
|
run.usage = emptyUsage();
|
|
248
233
|
beginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });
|
|
@@ -264,19 +249,25 @@ async function waitForTaskRetry(delayMs, options) {
|
|
|
264
249
|
unregisterAbort?.();
|
|
265
250
|
}
|
|
266
251
|
}
|
|
252
|
+
// The gate slot is held only while a worker session actually runs. Backoff
|
|
253
|
+
// waits outside the slot (release, sleep, reacquire) so a retrying task
|
|
254
|
+
// cannot starve queued tasks, and aborting during the wait settles the run
|
|
255
|
+
// without occupying the gate.
|
|
267
256
|
async function runWithGate(task, run, options, onProgress) {
|
|
268
257
|
onProgress();
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
258
|
+
const baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;
|
|
259
|
+
for (let attempt = 0;; attempt++) {
|
|
260
|
+
clearSubagentRetry(run);
|
|
261
|
+
let release;
|
|
262
|
+
let delayMs = 0;
|
|
263
|
+
try {
|
|
264
|
+
release = await options.gate.acquire(options.signal);
|
|
265
|
+
if (options.signal?.aborted) {
|
|
266
|
+
run.status = "aborted";
|
|
267
|
+
run.error = "Subagent was aborted while queued.";
|
|
268
|
+
run.endedAt = Date.now();
|
|
269
|
+
return run;
|
|
270
|
+
}
|
|
280
271
|
const result = await runSdkTask({
|
|
281
272
|
task,
|
|
282
273
|
run,
|
|
@@ -289,77 +280,66 @@ async function runWithGate(task, run, options, onProgress) {
|
|
|
289
280
|
});
|
|
290
281
|
if (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result))
|
|
291
282
|
return result;
|
|
292
|
-
|
|
283
|
+
delayMs = baseDelayMs * 2 ** attempt;
|
|
293
284
|
resetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);
|
|
294
285
|
onProgress();
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
clearSubagentRetry(run);
|
|
289
|
+
run.status = options.signal?.aborted ? "aborted" : "failed";
|
|
290
|
+
run.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);
|
|
291
|
+
run.endedAt = Date.now();
|
|
292
|
+
onProgress();
|
|
293
|
+
return run;
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
release?.();
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
await waitForTaskRetry(delayMs, options);
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
clearSubagentRetry(run);
|
|
303
|
+
run.status = "aborted";
|
|
304
|
+
run.error = "Subagent was aborted while waiting to retry.";
|
|
305
|
+
run.endedAt = Date.now();
|
|
306
|
+
onProgress();
|
|
307
|
+
return run;
|
|
306
308
|
}
|
|
307
309
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
310
|
+
}
|
|
311
|
+
// Fair per-task report budget: the total cap is split evenly after reserving
|
|
312
|
+
// room for the numbered section headings and separators, capped per task.
|
|
313
|
+
function perTaskReportBudget(taskCount) {
|
|
314
|
+
const headingReserve = Math.min(256 * taskCount, Math.floor(TOTAL_OUTPUT_LIMIT / 4));
|
|
315
|
+
const fairShare = Math.floor((TOTAL_OUTPUT_LIMIT - headingReserve) / Math.max(1, taskCount));
|
|
316
|
+
return Math.min(TASK_OUTPUT_LIMIT, Math.max(2_048, fairShare));
|
|
317
|
+
}
|
|
318
|
+
function reportSectionTitle(run, index) {
|
|
319
|
+
return `### ${index + 1}. ${run.description} (${run.agent}) — ${run.status}`;
|
|
320
|
+
}
|
|
321
|
+
function reportSectionBody(run) {
|
|
322
|
+
if (run.status === "completed")
|
|
323
|
+
return run.report || EMPTY_OUTPUT;
|
|
324
|
+
if (run.status === "failed" || run.status === "aborted") {
|
|
325
|
+
const verdict = run.status === "aborted" ? "Subagent aborted" : "Subagent failed";
|
|
326
|
+
const cause = run.error ? `: ${run.error}` : ".";
|
|
327
|
+
const partial = run.report ? `\n\nPartial report:\n${run.report}` : "";
|
|
328
|
+
return `${verdict}${cause}${partial}`;
|
|
318
329
|
}
|
|
330
|
+
if (run.status === "queued")
|
|
331
|
+
return "Task was queued and never started.";
|
|
332
|
+
return "Task was still running when the batch settled.";
|
|
319
333
|
}
|
|
334
|
+
// Always ordered numbered sections, even for a single task, so the parent
|
|
335
|
+
// can reference results by number. Total cap with a fair per-task budget;
|
|
336
|
+
// empty, failed, aborted, and partial reports are labeled explicitly.
|
|
320
337
|
function resultContent(details) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return "Subagent produced no run.";
|
|
325
|
-
if (run.status === "failed" || run.status === "aborted") {
|
|
326
|
-
return boundText(`${run.status === "aborted" ? "Subagent aborted" : "Subagent failed"}: ${run.error ?? "unknown error"}${run.finalOutput ? `\n\nPartial response:\n${run.finalOutput}` : ""}`, SINGLE_OUTPUT_LIMIT);
|
|
327
|
-
}
|
|
328
|
-
return run.finalOutput || EMPTY_OUTPUT;
|
|
329
|
-
}
|
|
330
|
-
const sections = details.runs.map((run) => {
|
|
331
|
-
const output = run.finalOutput || run.error || EMPTY_OUTPUT;
|
|
332
|
-
return `### ${run.description} (${run.agent}) — ${run.status}\n\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;
|
|
338
|
+
const perTaskBudget = perTaskReportBudget(details.runs.length);
|
|
339
|
+
const sections = details.runs.map((run, index) => {
|
|
340
|
+
return `${reportSectionTitle(run, index)}\n\n${boundText(reportSectionBody(run), perTaskBudget)}`;
|
|
333
341
|
});
|
|
334
|
-
return boundText(sections.join("\n\n---\n\n"),
|
|
335
|
-
}
|
|
336
|
-
function invocationMode(params) {
|
|
337
|
-
const provided = [];
|
|
338
|
-
if (params.prompt != null)
|
|
339
|
-
provided.push("prompt");
|
|
340
|
-
if (params.tasks != null)
|
|
341
|
-
provided.push("tasks");
|
|
342
|
-
if (provided.length !== 1) {
|
|
343
|
-
throw new Error(provided.length === 0
|
|
344
|
-
? "Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided."
|
|
345
|
-
: `Provide exactly one subagent mode: received ${provided.join(", ")}. Keep one and set the unused mode fields to null or omit them.`);
|
|
346
|
-
}
|
|
347
|
-
if (params.tasks != null) {
|
|
348
|
-
return { mode: "parallel", tasks: params.tasks };
|
|
349
|
-
}
|
|
350
|
-
if (!params.description)
|
|
351
|
-
throw new Error("description is required for single mode.");
|
|
352
|
-
return {
|
|
353
|
-
mode: "single",
|
|
354
|
-
tasks: [
|
|
355
|
-
{
|
|
356
|
-
agent: params.agent,
|
|
357
|
-
description: params.description,
|
|
358
|
-
prompt: params.prompt,
|
|
359
|
-
cwd: params.cwd,
|
|
360
|
-
},
|
|
361
|
-
],
|
|
362
|
-
};
|
|
342
|
+
return boundText(sections.join("\n\n---\n\n"), TOTAL_OUTPUT_LIMIT);
|
|
363
343
|
}
|
|
364
344
|
// Cheap change detector: consecutive events that alter nothing user-visible
|
|
365
345
|
// skip the bounded-details serialization in emitDetails entirely. Every
|
|
@@ -378,9 +358,7 @@ export function progressKey(runs) {
|
|
|
378
358
|
run.retry?.maxAttempts ?? "",
|
|
379
359
|
run.retry?.deadline ?? "",
|
|
380
360
|
run.retry?.error ?? "",
|
|
381
|
-
run.
|
|
382
|
-
run.liveText.slice(-24),
|
|
383
|
-
run.finalOutput.length,
|
|
361
|
+
run.report.length,
|
|
384
362
|
run.usage.turns,
|
|
385
363
|
run.usage.toolUses,
|
|
386
364
|
run.usage.totalTokens,
|
|
@@ -397,26 +375,26 @@ export function isSubagentError(details) {
|
|
|
397
375
|
return !details.runs.some((run) => run.status === "completed");
|
|
398
376
|
}
|
|
399
377
|
export async function runSubagentInvocation(options) {
|
|
400
|
-
|
|
378
|
+
// Defensive count check: the schema already enforces 1..MAX_TASKS, but
|
|
379
|
+
// strict providers can bypass minItems, so validate before any work.
|
|
380
|
+
const tasks = options.params.tasks ?? [];
|
|
401
381
|
const resolved = await resolveTasks(tasks, options);
|
|
402
382
|
const runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));
|
|
403
383
|
const startedAt = Date.now();
|
|
404
|
-
let latestDetails = emitDetails(
|
|
384
|
+
let latestDetails = emitDetails(runs, startedAt, options.onUpdate);
|
|
405
385
|
let lastProgressKey = progressKey(runs);
|
|
406
386
|
const progress = () => {
|
|
407
387
|
const key = progressKey(runs);
|
|
408
388
|
if (key === lastProgressKey)
|
|
409
389
|
return;
|
|
410
390
|
lastProgressKey = key;
|
|
411
|
-
latestDetails = emitDetails(
|
|
391
|
+
latestDetails = emitDetails(runs, startedAt, options.onUpdate);
|
|
412
392
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
}
|
|
419
|
-
latestDetails = emitDetails(mode, runs, startedAt, undefined);
|
|
393
|
+
// Every task runs concurrently through the shared gate; Promise.all keeps
|
|
394
|
+
// result order identical to input order. There is no single-task branch:
|
|
395
|
+
// one task is just a batch of one.
|
|
396
|
+
await Promise.all(resolved.map((task, index) => runWithGate(task, runs[index], options, progress)));
|
|
397
|
+
latestDetails = emitDetails(runs, startedAt, undefined);
|
|
420
398
|
latestDetails.endedAt = Date.now();
|
|
421
399
|
// Error classification lives in the tool_result handler (index.ts), the
|
|
422
400
|
// only channel that reaches the session transcript and export.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,qBAAqB,EACrB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAA2B,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAUnD,MAAM,YAAY,GAAG,8CAA8C,CAAC;AASpE,MAAM,OAAO,eAAe;IAK3B,YAAY,KAAK,GAAG,eAAe;QAJ3B,WAAM,GAAG,CAAC,CAAC;QACF,YAAO,GAAa,EAAE,CAAC;QAIvC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,MAAoB;QAC3B,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC5F,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClD,MAAM,MAAM,GAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YACnD,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,aAAa,GAAG,GAAG,EAAE;oBAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBAC3C,IAAI,KAAK,IAAI,CAAC;wBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC9C,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;gBACzD,CAAC,CAAC;gBACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,OAAO;QACd,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAG,CAAC;YACrC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC5B,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;gBACzB,SAAS;YACV,CAAC;YACD,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,aAAc,CAAC,CAAC;YACnE,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACrC,OAAO;QACR,CAAC;IACF,CAAC;CACD;AAkBD,SAAS,KAAK,CAAC,KAAa;IAC3B,OAAO,YAAY,KAAK,GAAG,CAAC,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,SAAS,CAAC,IAA0B,EAAE,KAAa,EAAE,SAAiB;IAC9E,OAAO;QACN,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC;QAChB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;QACtB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;QAC9B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,iEAAiE;QACjE,gEAAgE;QAChE,GAAG,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC;QAClC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;QAChD,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;QACZ,WAAW,EAAE,EAAE;QACf,KAAK,EAAE,UAAU,EAAE;KACnB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAmC;IAC1D,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC;AACd,CAAC;AAOD,SAAS,WAAW,CAAC,OAAwB;IAC5C,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAwB;IAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC5B,KAAK,EACL,IAAI,CAAC,KAAK,CAAC,CAAC,oBAAoB,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAChF,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAoB;QAChC,GAAG,OAAO;QACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAChC,GAAG,GAAG;YACN,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;YACpC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;YAC9B,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;YACtF,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;YAC1G,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC5E,GAAG,QAAQ;gBACX,OAAO,EAAE,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;gBACzC,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;aAC1F,CAAC,CAAC;YACH,qEAAqE;YACrE,oEAAoE;YACpE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC;YACvC,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC;YACpD,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SAC1D,CAAC,CAAC;KACH,CAAC;IACF,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CACV;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM;YACrB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,CAAC;SACD,EACD;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG;YAClB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC;YACjB,CAAC;SACD,EACD;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE;YACpC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,eAAe,GAAG,KAAK,IAAI,SAAS,CAAC;YAC1C,CAAC;SACD,EACD;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ;YACvB,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,CAAC;SACD,EACD;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW;YAC1B,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,CAAC;SACD,EACD;YACC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,GAAG,CAAC,KAAK,GAAG,KAAK,IAAI,SAAS,CAAC;YAChC,CAAC;SACD,CACD,CAAC;QACF,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,CAAC,IAAI,CACV;gBACC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO;gBAC3B,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;oBACd,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC1B,CAAC;aACD,EACD;gBACC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE;gBACvC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;oBACd,QAAQ,CAAC,aAAa,GAAG,KAAK,IAAI,SAAS,CAAC;gBAC7C,CAAC;aACD,CACD,CAAC;QACH,CAAC;IACF,CAAC;IACD,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG,oBAAoB,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM;aACpB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;aACzE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM;QAC1C,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,oBAAoB,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmC;IACpD,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IACnE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9F,OAAO,WAAW,CAAC;AACpB,CAAC;AAED,SAAS,UAAU,CAAC,OAAwB;IAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IAC9E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC5E,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC5E,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IAC9E,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,GAAG,EAAE,eAAe;YAAE,OAAO,GAAG,CAAC,eAAe,CAAC;QACrD,IACC,CAAC,GAAG;YACJ,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,EAC3G,CAAC;YACF,OAAO,eAAe,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IAC5D,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC;IAC/D,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC;IAC9C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC;IAC3C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC;IAC3C,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CACnB,IAA6B,EAC7B,IAA0B,EAC1B,SAAiB,EACjB,QAA0D;IAE1D,MAAM,OAAO,GAAoB;QAChC,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;QACtB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,SAAS;QACT,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC;KAC3B,CAAC;IACF,QAAQ,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAA8B;IACxD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACjF,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,SAAS,SAAS,CAAC,CAAC;AACvG,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,KAA8B,EAC9B,OAAkC;IAElC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC,GAAG,CACjB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CACtG,CACD,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,mDAAmD;AACnD,SAAS,mBAAmB,CAAC,KAAyB;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;IAC3F,OAAO,yBAAyB,CAAC,KAAmE,CAAC,CAAC;AACvG,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,mBAAmB;AACnB,SAAS,eAAe,CAAC,GAAuB;IAC/C,OAAO,CACN,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAC9G,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAuB,EAAE,OAAe,EAAE,WAAmB,EAAE,OAAe;IACvG,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,+BAA+B,CAAC;IAC3D,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC;IACtB,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;IACtB,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;IACxB,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;IACrB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,GAAG,CAAC,KAAK,GAAG,UAAU,EAAE,CAAC;IACzB,kBAAkB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,OAAe,EACf,OAAoE;IAEpE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC5D,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,UAAU,CAAC,KAAK,EAAE,CAAC;;QAC3C,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC;QACJ,MAAM,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;YAAS,CAAC;QACV,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAC5D,eAAe,EAAE,EAAE,CAAC;IACrB,CAAC;AACF,CAAC;AAED,KAAK,UAAU,WAAW,CACzB,IAA0B,EAC1B,GAAuB,EACvB,OAAkC,EAClC,UAAsB;IAEtB,UAAU,EAAE,CAAC;IACb,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;YACvB,GAAG,CAAC,KAAK,GAAG,oCAAoC,CAAC;YACjD,OAAO,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,CAAC,oBAAoB,IAAI,wBAAwB,CAAC;QAC7E,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YACnC,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;gBAC/B,IAAI;gBACJ,GAAG;gBACH,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU;gBACV,aAAa,EAAE,OAAO,CAAC,aAAa;aACpC,CAAC,CAAC;YACH,IAAI,OAAO,IAAI,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;YACtG,MAAM,OAAO,GAAG,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC;YAC3C,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;YAC9D,UAAU,EAAE,CAAC;YACb,IAAI,CAAC;gBACJ,MAAM,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACR,kBAAkB,CAAC,GAAG,CAAC,CAAC;gBACxB,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC;gBACvB,GAAG,CAAC,KAAK,GAAG,8CAA8C,CAAC;gBAC3D,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACzB,UAAU,EAAE,CAAC;gBACb,OAAO,GAAG,CAAC;YACZ,CAAC;QACF,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACxB,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5D,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAChG,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,UAAU,EAAE,CAAC;QACb,OAAO,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACV,OAAO,EAAE,EAAE,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,OAAwB;IAC9C,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG;YAAE,OAAO,2BAA2B,CAAC;QAC7C,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACzD,OAAO,SAAS,CACf,GAAG,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,KAAK,GAAG,CAAC,KAAK,IAAI,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAC5K,mBAAmB,CACnB,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC,WAAW,IAAI,YAAY,CAAC;IACxC,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,KAAK,IAAI,YAAY,CAAC;QAC5D,OAAO,OAAO,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,MAAM,OAAO,SAAS,CAAC,MAAM,EAAE,0BAA0B,CAAC,EAAE,CAAC;IACpH,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,MAAsB;IAC7C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI;QAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;QAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACd,QAAQ,CAAC,MAAM,KAAK,CAAC;YACpB,CAAC,CAAC,uGAAuG;YACzG,CAAC,CAAC,+CAA+C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,iEAAiE,CACtI,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACrF,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE;YACN;gBACC,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,MAAM,EAAE,MAAM,CAAC,MAAO;gBACtB,GAAG,EAAE,MAAM,CAAC,GAAG;aACf;SACD;KACD,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,0EAA0E;AAC1E,0CAA0C;AAC1C,MAAM,UAAU,WAAW,CAAC,IAAmC;IAC9D,OAAO,IAAI;SACT,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACZ,OAAO;YACN,GAAG,CAAC,MAAM;YACV,GAAG,CAAC,eAAe,IAAI,EAAE;YACzB,GAAG,CAAC,UAAU,CAAC,MAAM;YACrB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAChG,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE;YACxB,GAAG,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE;YAC5B,GAAG,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE;YACzB,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YACtB,GAAG,CAAC,QAAQ,CAAC,MAAM;YACnB,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,WAAW,CAAC,MAAM;YACtB,GAAG,CAAC,KAAK,CAAC,KAAK;YACf,GAAG,CAAC,KAAK,CAAC,QAAQ;YAClB,GAAG,CAAC,KAAK,CAAC,WAAW;YACrB,GAAG,CAAC,KAAK,IAAI,EAAE;SACf,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAiD;IAChF,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9E,qEAAqE;IACrE,8DAA8D;IAC9D,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAkC;IAC7E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACtF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,aAAa,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,IAAI,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,EAAE;QACrB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,eAAe;YAAE,OAAO;QACpC,eAAe,GAAG,GAAG,CAAC;QACtB,aAAa,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtE,CAAC,CAAC;IAEF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACP,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtG,CAAC;IACD,aAAa,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9D,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,wEAAwE;IACxE,+DAA+D;IAC/D,OAAO;QACN,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC;QACrC,OAAO,EAAE,oBAAoB,CAAC,aAAa,CAAC;QAC5C,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC;KACzC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAwB;IACrD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, tailText, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tPARALLEL_OUTPUT_LIMIT,\n\tPARALLEL_TASK_OUTPUT_LIMIT,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tSINGLE_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport { beginSubagentRetry, clearSubagentRetry } from \"./retry.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tAgentDefinition,\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift()!;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tagents: readonly AgentDefinition[];\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tagentSource: task.agent.source,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\tliveText: \"\",\n\t\tfinalOutput: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst outputLimit = Math.min(SINGLE_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tprompt: boundText(run.prompt, 1_024),\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tretry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\t// liveText is a tail by construction: keep the newest lines, not the\n\t\t\t// head, or the transcript's live tail would freeze at the 1KB mark.\n\t\t\tliveText: tailText(run.liveText, 1_024),\n\t\t\tfinalOutput: boundText(run.finalOutput, outputLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.prompt,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.prompt = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.liveText,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.liveText = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.finalOutput,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.finalOutput = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.some((run) => run.status === \"aborted\")) return \"aborted\";\n\tif (runs.some((run) => run.status === \"failed\")) return \"failed\";\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\treturn \"completed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (run?.currentActivity) return run.currentActivity;\n\t\tif (\n\t\t\t!run ||\n\t\t\t(run.status === \"running\" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)\n\t\t) {\n\t\t\treturn \"Initializing…\";\n\t\t}\n\t\treturn run.status === \"running\" ? \"Thinking…\" : run.status;\n\t}\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\tmode: SubagentDetails[\"mode\"],\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tmode,\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.agents, options.parent, options.agentDir, config),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number, delayMs: number): void {\n\tconst error = run.error ?? \"Subagent failed before retry.\";\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.finalOutput = \"\";\n\trun.liveText = \"\";\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n\tbeginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });\n}\n\nasync function waitForTaskRetry(\n\tdelayMs: number,\n\toptions: Pick<SubagentInvocationOptions, \"signal\" | \"registerAbort\">,\n): Promise<void> {\n\tconst controller = new AbortController();\n\tconst abort = async (): Promise<void> => controller.abort();\n\tconst unregisterAbort = options.registerAbort?.(abort);\n\tconst abortListener = () => controller.abort();\n\tif (options.signal?.aborted) controller.abort();\n\telse options.signal?.addEventListener(\"abort\", abortListener, { once: true });\n\ttry {\n\t\tawait sleep(delayMs, controller.signal);\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", abortListener);\n\t\tunregisterAbort?.();\n\t}\n}\n\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tlet release: (() => void) | undefined;\n\ttry {\n\t\trelease = await options.gate.acquire(options.signal);\n\t\tif (options.signal?.aborted) {\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\treturn run;\n\t\t}\n\t\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tclearSubagentRetry(run);\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tconst delayMs = baseDelayMs * 2 ** attempt;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);\n\t\t\tonProgress();\n\t\t\ttry {\n\t\t\t\tawait waitForTaskRetry(delayMs, options);\n\t\t\t} catch {\n\t\t\t\tclearSubagentRetry(run);\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\tonProgress();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tclearSubagentRetry(run);\n\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\trun.endedAt = Date.now();\n\t\tonProgress();\n\t\treturn run;\n\t} finally {\n\t\trelease?.();\n\t}\n}\n\nfunction resultContent(details: SubagentDetails): string {\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (!run) return \"Subagent produced no run.\";\n\t\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\t\treturn boundText(\n\t\t\t\t`${run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\"}: ${run.error ?? \"unknown error\"}${run.finalOutput ? `\\n\\nPartial response:\\n${run.finalOutput}` : \"\"}`,\n\t\t\t\tSINGLE_OUTPUT_LIMIT,\n\t\t\t);\n\t\t}\n\t\treturn run.finalOutput || EMPTY_OUTPUT;\n\t}\n\tconst sections = details.runs.map((run) => {\n\t\tconst output = run.finalOutput || run.error || EMPTY_OUTPUT;\n\t\treturn `### ${run.description} (${run.agent}) — ${run.status}\\n\\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), PARALLEL_OUTPUT_LIMIT);\n}\n\nfunction invocationMode(params: SubagentParams): { mode: SubagentDetails[\"mode\"]; tasks: SubagentTask[] } {\n\tconst provided: string[] = [];\n\tif (params.prompt != null) provided.push(\"prompt\");\n\tif (params.tasks != null) provided.push(\"tasks\");\n\tif (provided.length !== 1) {\n\t\tthrow new Error(\n\t\t\tprovided.length === 0\n\t\t\t\t? \"Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided.\"\n\t\t\t\t: `Provide exactly one subagent mode: received ${provided.join(\", \")}. Keep one and set the unused mode fields to null or omit them.`,\n\t\t);\n\t}\n\tif (params.tasks != null) {\n\t\treturn { mode: \"parallel\", tasks: params.tasks };\n\t}\n\tif (!params.description) throw new Error(\"description is required for single mode.\");\n\treturn {\n\t\tmode: \"single\",\n\t\ttasks: [\n\t\t\t{\n\t\t\t\tagent: params.agent,\n\t\t\t\tdescription: params.description,\n\t\t\t\tprompt: params.prompt!,\n\t\t\t\tcwd: params.cwd,\n\t\t\t},\n\t\t],\n\t};\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely. Every\n// activity contributes its status, not just the last one: agent-core can end\n// parallel tool executions out of order, and a mid-list row settling then\n// would otherwise slip past the detector.\nexport function progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\trun.activities.map((activity) => `${activity.status}:${activity.resultSummary ?? \"\"}`).join(\",\"),\n\t\t\t\trun.retry?.attempt ?? \"\",\n\t\t\t\trun.retry?.maxAttempts ?? \"\",\n\t\t\t\trun.retry?.deadline ?? \"\",\n\t\t\t\trun.retry?.error ?? \"\",\n\t\t\t\trun.liveText.length,\n\t\t\t\trun.liveText.slice(-24),\n\t\t\t\trun.finalOutput.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\tconst { mode, tasks } = invocationMode(options.params);\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\t};\n\n\tif (mode === \"single\") {\n\t\tawait runWithGate(resolved[0]!, runs[0]!, options, progress);\n\t} else {\n\t\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\t}\n\tlatestDetails = emitDetails(mode, runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\t// Error classification lives in the tool_result handler (index.ts), the\n\t// only channel that reaches the session transcript and export.\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tTASK_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n\tTOTAL_OUTPUT_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport { beginSubagentRetry, clearSubagentRetry } from \"./retry.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift()!;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tdescription: task.description,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\treport: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst reportLimit = Math.min(TASK_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tretry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\treport: boundText(run.report, reportLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.report,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.report = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.length === 0) return \"running\";\n\t// Active beats terminal: any queued or running run keeps the batch\n\t// \"running\" regardless of what the others have settled to.\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\tif (runs.every((run) => run.status === \"completed\")) return \"completed\";\n\tif (runs.some((run) => run.status === \"completed\")) return \"partial\";\n\tif (runs.every((run) => run.status === \"aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tif (details.runs.length === 0) return \"Initializing…\";\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\t// One config load and one resolution pass for the whole batch: every\n\t// task/profile/cwd/model is settled before any run is created or any\n\t// worker starts, so a failing task cannot strand half-initialized runs.\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task, index) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.parent, options.agentDir, config).catch((error) => {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new Error(`Subagent task tasks[${index}] failed to resolve: ${message}`);\n\t\t\t}),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number, delayMs: number): void {\n\tconst error = run.error ?? \"Subagent failed before retry.\";\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.report = \"\";\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n\tbeginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });\n}\n\nasync function waitForTaskRetry(\n\tdelayMs: number,\n\toptions: Pick<SubagentInvocationOptions, \"signal\" | \"registerAbort\">,\n): Promise<void> {\n\tconst controller = new AbortController();\n\tconst abort = async (): Promise<void> => controller.abort();\n\tconst unregisterAbort = options.registerAbort?.(abort);\n\tconst abortListener = () => controller.abort();\n\tif (options.signal?.aborted) controller.abort();\n\telse options.signal?.addEventListener(\"abort\", abortListener, { once: true });\n\ttry {\n\t\tawait sleep(delayMs, controller.signal);\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", abortListener);\n\t\tunregisterAbort?.();\n\t}\n}\n\n// The gate slot is held only while a worker session actually runs. Backoff\n// waits outside the slot (release, sleep, reacquire) so a retrying task\n// cannot starve queued tasks, and aborting during the wait settles the run\n// without occupying the gate.\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\tfor (let attempt = 0; ; attempt++) {\n\t\tclearSubagentRetry(run);\n\t\tlet release: (() => void) | undefined;\n\t\tlet delayMs = 0;\n\t\ttry {\n\t\t\trelease = await options.gate.acquire(options.signal);\n\t\t\tif (options.signal?.aborted) {\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tdelayMs = baseDelayMs * 2 ** attempt;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);\n\t\t\tonProgress();\n\t\t} catch (error) {\n\t\t\tclearSubagentRetry(run);\n\t\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\t\trun.endedAt = Date.now();\n\t\t\tonProgress();\n\t\t\treturn run;\n\t\t} finally {\n\t\t\trelease?.();\n\t\t}\n\t\ttry {\n\t\t\tawait waitForTaskRetry(delayMs, options);\n\t\t} catch {\n\t\t\tclearSubagentRetry(run);\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\trun.endedAt = Date.now();\n\t\t\tonProgress();\n\t\t\treturn run;\n\t\t}\n\t}\n}\n\n// Fair per-task report budget: the total cap is split evenly after reserving\n// room for the numbered section headings and separators, capped per task.\nfunction perTaskReportBudget(taskCount: number): number {\n\tconst headingReserve = Math.min(256 * taskCount, Math.floor(TOTAL_OUTPUT_LIMIT / 4));\n\tconst fairShare = Math.floor((TOTAL_OUTPUT_LIMIT - headingReserve) / Math.max(1, taskCount));\n\treturn Math.min(TASK_OUTPUT_LIMIT, Math.max(2_048, fairShare));\n}\n\nfunction reportSectionTitle(run: SubagentRunDetails, index: number): string {\n\treturn `### ${index + 1}. ${run.description} (${run.agent}) — ${run.status}`;\n}\n\nfunction reportSectionBody(run: SubagentRunDetails): string {\n\tif (run.status === \"completed\") return run.report || EMPTY_OUTPUT;\n\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\tconst verdict = run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\";\n\t\tconst cause = run.error ? `: ${run.error}` : \".\";\n\t\tconst partial = run.report ? `\\n\\nPartial report:\\n${run.report}` : \"\";\n\t\treturn `${verdict}${cause}${partial}`;\n\t}\n\tif (run.status === \"queued\") return \"Task was queued and never started.\";\n\treturn \"Task was still running when the batch settled.\";\n}\n\n// Always ordered numbered sections, even for a single task, so the parent\n// can reference results by number. Total cap with a fair per-task budget;\n// empty, failed, aborted, and partial reports are labeled explicitly.\nfunction resultContent(details: SubagentDetails): string {\n\tconst perTaskBudget = perTaskReportBudget(details.runs.length);\n\tconst sections = details.runs.map((run, index) => {\n\t\treturn `${reportSectionTitle(run, index)}\\n\\n${boundText(reportSectionBody(run), perTaskBudget)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), TOTAL_OUTPUT_LIMIT);\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely. Every\n// activity contributes its status, not just the last one: agent-core can end\n// parallel tool executions out of order, and a mid-list row settling then\n// would otherwise slip past the detector.\nexport function progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\trun.activities.map((activity) => `${activity.status}:${activity.resultSummary ?? \"\"}`).join(\",\"),\n\t\t\t\trun.retry?.attempt ?? \"\",\n\t\t\t\trun.retry?.maxAttempts ?? \"\",\n\t\t\t\trun.retry?.deadline ?? \"\",\n\t\t\t\trun.retry?.error ?? \"\",\n\t\t\t\trun.report.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\t// Defensive count check: the schema already enforces 1..MAX_TASKS, but\n\t// strict providers can bypass minItems, so validate before any work.\n\tconst tasks = options.params.tasks ?? [];\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(runs, startedAt, options.onUpdate);\n\t};\n\n\t// Every task runs concurrently through the shared gate; Promise.all keeps\n\t// result order identical to input order. There is no single-task branch:\n\t// one task is just a batch of one.\n\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\tlatestDetails = emitDetails(runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\t// Error classification lives in the tool_result handler (index.ts), the\n\t// only channel that reaches the session transcript and export.\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
import { type Static, Type } from "typebox";
|
|
2
2
|
export declare const TaskSchema: Type.TObject<{
|
|
3
|
-
agent: Type.TOptional<Type.TUnion<[Type.
|
|
4
|
-
description: Type.TString;
|
|
3
|
+
agent: Type.TOptional<Type.TUnion<[Type.TUnsafe<"explorer" | "general">, Type.TNull]>>;
|
|
5
4
|
prompt: Type.TString;
|
|
6
5
|
cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
7
6
|
}>;
|
|
8
7
|
export declare const SubagentParamsSchema: Type.TObject<{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
prompt: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
12
|
-
cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
13
|
-
tasks: Type.TOptional<Type.TUnion<[Type.TArray<Type.TObject<{
|
|
14
|
-
agent: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
15
|
-
description: Type.TString;
|
|
8
|
+
tasks: Type.TArray<Type.TObject<{
|
|
9
|
+
agent: Type.TOptional<Type.TUnion<[Type.TUnsafe<"explorer" | "general">, Type.TNull]>>;
|
|
16
10
|
prompt: Type.TString;
|
|
17
11
|
cwd: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
18
|
-
}
|
|
12
|
+
}>>;
|
|
19
13
|
}>;
|
|
20
14
|
export type SubagentParams = Static<typeof SubagentParamsSchema>;
|
|
21
15
|
export type SubagentTask = Static<typeof TaskSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,IAAI,EAAE,MAAM,SAAS,CAAC;AAW1D,eAAO,MAAM,UAAU;;;;EAiBtB,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;EAShC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
+
import { StringEnum } from "@earendil-works/pi-ai";
|
|
1
2
|
import { Type } from "typebox";
|
|
2
|
-
import { MAX_TASKS } from "./constants.js";
|
|
3
|
+
import { MAX_CONCURRENCY, MAX_TASKS, SUBAGENT_AGENT_NAMES } from "./constants.js";
|
|
3
4
|
// Strict constrained-sampling providers treat every property as required
|
|
4
5
|
// and reject bare unions at the top level, so the schema is a flat
|
|
5
6
|
// `type: "object"` whose optional fields are also nullable: callers omit
|
|
6
7
|
// a field when the grammar allows it and send null when it does not.
|
|
7
|
-
// The exactly-one-mode rule is enforced at runtime in `invocationMode`.
|
|
8
8
|
function nullable(schema, description) {
|
|
9
9
|
return Type.Optional(Type.Union([schema, Type.Null()], { description }));
|
|
10
10
|
}
|
|
11
11
|
export const TaskSchema = Type.Object({
|
|
12
|
-
agent: nullable(
|
|
13
|
-
description: Type.String({
|
|
14
|
-
minLength: 1,
|
|
15
|
-
maxLength: 80,
|
|
16
|
-
description: "Concise 3-8 word UI label",
|
|
17
|
-
}),
|
|
12
|
+
agent: nullable(StringEnum(SUBAGENT_AGENT_NAMES, { description: "Which built-in profile runs this task" }), "Built-in profile; null or omit for explorer (the default)"),
|
|
18
13
|
prompt: Type.String({
|
|
19
14
|
minLength: 1,
|
|
20
15
|
maxLength: 50_000,
|
|
@@ -23,10 +18,10 @@ export const TaskSchema = Type.Object({
|
|
|
23
18
|
cwd: nullable(Type.String({ minLength: 1, maxLength: 4_096 }), "Relative or absolute directory inside the parent working directory; null or omit to inherit it"),
|
|
24
19
|
}, { additionalProperties: false });
|
|
25
20
|
export const SubagentParamsSchema = Type.Object({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
tasks: Type.Array(TaskSchema, {
|
|
22
|
+
minItems: 1,
|
|
23
|
+
maxItems: MAX_TASKS,
|
|
24
|
+
description: `Independent tasks run concurrently: at most ${MAX_CONCURRENCY} active at once, excess tasks queue, and results preserve input order`,
|
|
25
|
+
}),
|
|
31
26
|
}, { additionalProperties: false });
|
|
32
27
|
//# sourceMappingURL=schema.js.map
|