@tt-a1i/openpi 0.1.1 → 0.3.0
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/README.md +65 -28
- package/SETUP.md +8 -6
- package/extensions/ask-user/handoff.ts +5 -1
- package/extensions/ask-user/index.ts +44 -0
- package/extensions/background-terminals/index.ts +118 -29
- package/extensions/background-terminals/src/domain.ts +5 -1
- package/extensions/background-terminals/src/manager.ts +2 -1
- package/extensions/background-terminals/src/prompt.ts +35 -0
- package/extensions/background-terminals/src/result-delivery.ts +76 -3
- package/extensions/background-terminals/src/ui/tool-result.ts +52 -1
- package/extensions/capabilities/index.ts +198 -0
- package/extensions/context-pivot/index.ts +21 -0
- package/extensions/cron/index.ts +42 -15
- package/extensions/execution-convergence/active-evidence.ts +129 -0
- package/extensions/execution-convergence/index.ts +442 -0
- package/extensions/execution-convergence/workspace-provenance.ts +338 -0
- package/extensions/file-search/index.ts +8 -1
- package/extensions/file-search/src/binaries.ts +2 -1
- package/extensions/git-info/src/runtime.ts +1 -1
- package/extensions/goal/controller.ts +2 -1
- package/extensions/goal/index.ts +20 -1
- package/extensions/plan-mode/bash-policy.ts +219 -42
- package/extensions/plan-mode/index.ts +56 -19
- package/extensions/setup/index.ts +96 -10
- package/extensions/shared/child-session.ts +40 -4
- package/extensions/shared/editor-layers.ts +150 -0
- package/extensions/shared/setup-config.ts +26 -15
- package/extensions/shared/setup-episode-state.ts +7 -0
- package/extensions/shared/tool-surface.ts +435 -0
- package/extensions/subagents/index.ts +179 -96
- package/extensions/subagents/src/manager.ts +13 -11
- package/extensions/subagents/src/prompt.ts +7 -7
- package/extensions/subagents/src/ui/takeover.ts +231 -133
- package/extensions/subagents/src/ui/transcript.ts +252 -37
- package/extensions/subagents/src/ui/wait-result.ts +6 -19
- package/extensions/suggestions/index.ts +27 -18
- package/extensions/tasks/index.ts +63 -18
- package/extensions/ui-customization/footer.ts +65 -11
- package/extensions/workflows/graph-projection.ts +6 -4
- package/extensions/workflows/index.ts +44 -21
- package/extensions/workflows/invocation-ledger.ts +8 -2
- package/extensions/workflows/model.ts +5 -1
- package/extensions/workflows/prompt.ts +10 -40
- package/extensions/workflows/replay-safety.ts +9 -8
- package/package.json +10 -10
- package/skills/subagents/SKILL.md +7 -1
- package/skills/workflows/EXAMPLES.md +58 -0
- package/skills/workflows/REFERENCE.md +44 -0
- package/skills/workflows/SKILL.md +39 -0
|
@@ -31,9 +31,9 @@ import type {
|
|
|
31
31
|
ExtensionCommandContext,
|
|
32
32
|
ExtensionContext,
|
|
33
33
|
ExtensionUIContext,
|
|
34
|
+
MessageRenderer,
|
|
34
35
|
} from "@earendil-works/pi-coding-agent";
|
|
35
36
|
import {
|
|
36
|
-
CustomEditor,
|
|
37
37
|
DEFAULT_MAX_BYTES,
|
|
38
38
|
DEFAULT_MAX_LINES,
|
|
39
39
|
defineTool,
|
|
@@ -65,6 +65,14 @@ import {
|
|
|
65
65
|
hasActivity,
|
|
66
66
|
unreadActivityCounts,
|
|
67
67
|
} from "../shared/activity-status.ts";
|
|
68
|
+
import {
|
|
69
|
+
OPENPI_TOOL_SURFACE,
|
|
70
|
+
patchOwnedTools,
|
|
71
|
+
} from "../shared/tool-surface.ts";
|
|
72
|
+
import {
|
|
73
|
+
registerEditorLayer,
|
|
74
|
+
removeEditorLayer,
|
|
75
|
+
} from "../shared/editor-layers.ts";
|
|
68
76
|
import { formatContextUtilization } from "./src/format.ts";
|
|
69
77
|
import { SubagentManager, type SubagentManagerShape } from "./src/manager.ts";
|
|
70
78
|
import {
|
|
@@ -121,6 +129,7 @@ import {
|
|
|
121
129
|
} from "./navigation.ts";
|
|
122
130
|
import { openSubagentPicker, openSubagentTakeover } from "./src/ui/takeover.ts";
|
|
123
131
|
import {
|
|
132
|
+
buildWaitResultPreview,
|
|
124
133
|
renderWaitResult,
|
|
125
134
|
type WaitResultDetails,
|
|
126
135
|
} from "./src/ui/wait-result.ts";
|
|
@@ -144,6 +153,23 @@ interface SubagentFinishedData {
|
|
|
144
153
|
readonly elapsed: string;
|
|
145
154
|
}
|
|
146
155
|
|
|
156
|
+
interface SubagentResultDetails {
|
|
157
|
+
readonly id?: string;
|
|
158
|
+
readonly title?: string;
|
|
159
|
+
readonly status?: SubagentSnapshot["status"];
|
|
160
|
+
readonly count?: number;
|
|
161
|
+
readonly results?: ReadonlyArray<{
|
|
162
|
+
readonly id: string;
|
|
163
|
+
readonly title: string;
|
|
164
|
+
readonly status: SubagentSnapshot["status"];
|
|
165
|
+
}>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface SubagentResultEntryData {
|
|
169
|
+
readonly content: string;
|
|
170
|
+
readonly details: SubagentResultDetails;
|
|
171
|
+
}
|
|
172
|
+
|
|
147
173
|
interface BtwResultData {
|
|
148
174
|
readonly id: string;
|
|
149
175
|
readonly title: string;
|
|
@@ -180,6 +206,104 @@ function truncatedOutput(
|
|
|
180
206
|
return text;
|
|
181
207
|
}
|
|
182
208
|
|
|
209
|
+
export function createSubagentResultDispatcher(
|
|
210
|
+
pi: ExtensionAPI,
|
|
211
|
+
outputFor: (snap: SubagentSnapshot) => string = truncatedOutput,
|
|
212
|
+
) {
|
|
213
|
+
return (snaps: readonly SubagentSnapshot[], wake: boolean) => {
|
|
214
|
+
if (snaps.length === 0) return;
|
|
215
|
+
const content = snaps
|
|
216
|
+
.map((snap) =>
|
|
217
|
+
buildSubagentResultMessage({
|
|
218
|
+
id: snap.id,
|
|
219
|
+
title: snap.title,
|
|
220
|
+
status: snap.status,
|
|
221
|
+
errorText: snap.errorText,
|
|
222
|
+
output: outputFor(snap),
|
|
223
|
+
}),
|
|
224
|
+
)
|
|
225
|
+
.join("\n\n");
|
|
226
|
+
const details: SubagentResultDetails =
|
|
227
|
+
snaps.length === 1
|
|
228
|
+
? {
|
|
229
|
+
id: snaps[0]!.id,
|
|
230
|
+
title: snaps[0]!.title,
|
|
231
|
+
status: snaps[0]!.status,
|
|
232
|
+
}
|
|
233
|
+
: {
|
|
234
|
+
count: snaps.length,
|
|
235
|
+
results: snaps.map((snap) => ({
|
|
236
|
+
id: snap.id,
|
|
237
|
+
title: snap.title,
|
|
238
|
+
status: snap.status,
|
|
239
|
+
})),
|
|
240
|
+
};
|
|
241
|
+
pi.appendEntry<SubagentResultEntryData>("subagent-result", {
|
|
242
|
+
content,
|
|
243
|
+
details,
|
|
244
|
+
});
|
|
245
|
+
pi.sendMessage(
|
|
246
|
+
{
|
|
247
|
+
customType: "subagent-result",
|
|
248
|
+
content,
|
|
249
|
+
display: false,
|
|
250
|
+
details,
|
|
251
|
+
},
|
|
252
|
+
resultDeliveryOptions(wake),
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
type SubagentResultTheme = Parameters<MessageRenderer>[2];
|
|
258
|
+
|
|
259
|
+
function renderSubagentResult(
|
|
260
|
+
content: string,
|
|
261
|
+
details: SubagentResultDetails,
|
|
262
|
+
expanded: boolean,
|
|
263
|
+
theme: SubagentResultTheme,
|
|
264
|
+
) {
|
|
265
|
+
if (!expanded && loadSetupConfig().ui.subagentResultDisplay === "compact") {
|
|
266
|
+
const results = details.results?.length
|
|
267
|
+
? details.results
|
|
268
|
+
: details.id
|
|
269
|
+
? [
|
|
270
|
+
{
|
|
271
|
+
id: details.id,
|
|
272
|
+
title: details.title,
|
|
273
|
+
status: details.status,
|
|
274
|
+
},
|
|
275
|
+
]
|
|
276
|
+
: [];
|
|
277
|
+
return new Text(buildWaitResultPreview(content, { results }, theme), 0, 0);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const failed = details.status === "error";
|
|
281
|
+
const icon = failed ? theme.fg("error", "x") : theme.fg("success", "■");
|
|
282
|
+
const header =
|
|
283
|
+
`${icon} ` +
|
|
284
|
+
theme.fg("accent", theme.bold(`subagent ${details.id ?? "?"}`)) +
|
|
285
|
+
theme.fg(
|
|
286
|
+
"muted",
|
|
287
|
+
` · ${details.title ?? ""} · ${failed ? "failed" : "finished"}`,
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
// Remove only the summary line. The following Error line (when present)
|
|
291
|
+
// is part of the actual result and must remain visible.
|
|
292
|
+
const body = content.split("\n").slice(1).join("\n").trim();
|
|
293
|
+
const md = new Markdown(body, 0, 0, getMarkdownTheme());
|
|
294
|
+
const container = new Text(header, 0, 0);
|
|
295
|
+
return {
|
|
296
|
+
render: (width: number) => [
|
|
297
|
+
...container.render(width),
|
|
298
|
+
...md.render(width),
|
|
299
|
+
],
|
|
300
|
+
invalidate: () => {
|
|
301
|
+
container.invalidate();
|
|
302
|
+
md.invalidate();
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
183
307
|
export default function (pi: ExtensionAPI) {
|
|
184
308
|
let runtime: SubagentRuntime | undefined;
|
|
185
309
|
let managerPromise: Promise<SubagentManagerShape> | undefined;
|
|
@@ -196,8 +320,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
196
320
|
let navigationManager: SubagentManagerShape | undefined;
|
|
197
321
|
let widgetVisible = false;
|
|
198
322
|
let requestWidgetRender: (() => void) | undefined;
|
|
323
|
+
let navigationLayerRegistered = false;
|
|
199
324
|
let dashboardOpen = false;
|
|
200
325
|
const resultDelivery = createDeferredResultDelivery<SubagentSnapshot>();
|
|
326
|
+
const dispatchResults = createSubagentResultDispatcher(pi);
|
|
327
|
+
const hideLifecycleTools = () =>
|
|
328
|
+
patchOwnedTools(pi, "subagents", {
|
|
329
|
+
disable: OPENPI_TOOL_SURFACE.subagents.deferred,
|
|
330
|
+
});
|
|
331
|
+
const showLifecycleTools = () =>
|
|
332
|
+
patchOwnedTools(pi, "subagents", {
|
|
333
|
+
enable: OPENPI_TOOL_SURFACE.subagents.deferred,
|
|
334
|
+
});
|
|
201
335
|
|
|
202
336
|
const getRuntime = () => (runtime ??= createSubagentRuntime());
|
|
203
337
|
|
|
@@ -280,26 +414,26 @@ export default function (pi: ExtensionAPI) {
|
|
|
280
414
|
|
|
281
415
|
const installSubagentNavigation = (ctx: ExtensionContext) => {
|
|
282
416
|
if (ctx.mode !== "tui") return;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
new
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
);
|
|
417
|
+
registerEditorLayer(pi, ctx, {
|
|
418
|
+
id: "subagents",
|
|
419
|
+
order: 100,
|
|
420
|
+
wrap: (base, tui, _theme, keybindings) =>
|
|
421
|
+
new BelowEditorNavigationEditor(
|
|
422
|
+
base,
|
|
423
|
+
keybindings,
|
|
424
|
+
stripState,
|
|
425
|
+
() => Boolean(stripEntry()),
|
|
426
|
+
() => {
|
|
427
|
+
const entry = stripEntry();
|
|
428
|
+
if (entry) void openDashboard(ctx, entry.snapshot.id);
|
|
429
|
+
},
|
|
430
|
+
() => {
|
|
431
|
+
requestWidgetRender?.();
|
|
432
|
+
tui.requestRender();
|
|
433
|
+
},
|
|
434
|
+
),
|
|
302
435
|
});
|
|
436
|
+
navigationLayerRegistered = true;
|
|
303
437
|
};
|
|
304
438
|
|
|
305
439
|
/**
|
|
@@ -314,41 +448,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
314
448
|
snaps: readonly SubagentSnapshot[],
|
|
315
449
|
wake: boolean,
|
|
316
450
|
) => {
|
|
317
|
-
|
|
318
|
-
pi.sendMessage(
|
|
319
|
-
{
|
|
320
|
-
customType: "subagent-result",
|
|
321
|
-
// One message per flush, not per subagent.
|
|
322
|
-
content: snaps
|
|
323
|
-
.map((snap) =>
|
|
324
|
-
buildSubagentResultMessage({
|
|
325
|
-
id: snap.id,
|
|
326
|
-
title: snap.title,
|
|
327
|
-
status: snap.status,
|
|
328
|
-
errorText: snap.errorText,
|
|
329
|
-
output: truncatedOutput(snap),
|
|
330
|
-
}),
|
|
331
|
-
)
|
|
332
|
-
.join("\n\n"),
|
|
333
|
-
display: true,
|
|
334
|
-
details:
|
|
335
|
-
snaps.length === 1
|
|
336
|
-
? {
|
|
337
|
-
id: snaps[0]!.id,
|
|
338
|
-
title: snaps[0]!.title,
|
|
339
|
-
status: snaps[0]!.status,
|
|
340
|
-
}
|
|
341
|
-
: {
|
|
342
|
-
count: snaps.length,
|
|
343
|
-
results: snaps.map((snap) => ({
|
|
344
|
-
id: snap.id,
|
|
345
|
-
title: snap.title,
|
|
346
|
-
status: snap.status,
|
|
347
|
-
})),
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
resultDeliveryOptions(wake),
|
|
351
|
-
);
|
|
451
|
+
dispatchResults(snaps, wake);
|
|
352
452
|
};
|
|
353
453
|
|
|
354
454
|
const flushResults = (wake: boolean) => {
|
|
@@ -408,6 +508,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
408
508
|
|
|
409
509
|
pi.on("session_start", (_event, ctx) => {
|
|
410
510
|
refreshAgentTypes(ctx.cwd, ctx.isProjectTrusted());
|
|
511
|
+
hideLifecycleTools();
|
|
411
512
|
sessionContext = ctx;
|
|
412
513
|
settledAcknowledgedAt = 0;
|
|
413
514
|
if (ctx.hasUI) ui = ctx.ui;
|
|
@@ -434,6 +535,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
434
535
|
pi.on("agent_settled", () => flushResults(false));
|
|
435
536
|
|
|
436
537
|
pi.on("session_shutdown", async () => {
|
|
538
|
+
if (navigationLayerRegistered) {
|
|
539
|
+
removeEditorLayer(pi, "subagents");
|
|
540
|
+
navigationLayerRegistered = false;
|
|
541
|
+
}
|
|
437
542
|
resultDelivery.clear();
|
|
438
543
|
unsubStatus?.();
|
|
439
544
|
unsubStatus = undefined;
|
|
@@ -681,6 +786,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
681
786
|
throw error;
|
|
682
787
|
}
|
|
683
788
|
|
|
789
|
+
showLifecycleTools();
|
|
790
|
+
|
|
684
791
|
return {
|
|
685
792
|
content: [
|
|
686
793
|
{
|
|
@@ -1036,52 +1143,28 @@ export default function (pi: ExtensionAPI) {
|
|
|
1036
1143
|
pi.registerMessageRenderer(
|
|
1037
1144
|
"subagent-result",
|
|
1038
1145
|
(message, { expanded }, theme) => {
|
|
1039
|
-
const details = (message.details ?? {}) as {
|
|
1040
|
-
id?: string;
|
|
1041
|
-
title?: string;
|
|
1042
|
-
status?: string;
|
|
1043
|
-
};
|
|
1044
|
-
const failed = details.status === "error";
|
|
1045
|
-
const icon = failed ? theme.fg("error", "x") : theme.fg("success", "■");
|
|
1046
|
-
const header =
|
|
1047
|
-
`${icon} ` +
|
|
1048
|
-
theme.fg("accent", theme.bold(`subagent ${details.id ?? "?"}`)) +
|
|
1049
|
-
theme.fg(
|
|
1050
|
-
"muted",
|
|
1051
|
-
` · ${details.title ?? ""} · ${failed ? "failed" : "finished"}`,
|
|
1052
|
-
);
|
|
1053
|
-
|
|
1054
1146
|
const content =
|
|
1055
1147
|
typeof message.content === "string" ? message.content : "";
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const container = new Text(header, 0, 0);
|
|
1063
|
-
return {
|
|
1064
|
-
render: (width: number) => [
|
|
1065
|
-
...container.render(width),
|
|
1066
|
-
...md.render(width),
|
|
1067
|
-
],
|
|
1068
|
-
invalidate: () => {
|
|
1069
|
-
container.invalidate();
|
|
1070
|
-
md.invalidate();
|
|
1071
|
-
},
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
const previewLines = body.split("\n").slice(0, 8);
|
|
1076
|
-
let text = header;
|
|
1077
|
-
for (const line of previewLines)
|
|
1078
|
-
text += `\n${theme.fg("toolOutput", line)}`;
|
|
1079
|
-
if (body.split("\n").length > 8)
|
|
1080
|
-
text += `\n${theme.fg("dim", `... (${keyHint("app.tools.expand", "to expand")})`)}`;
|
|
1081
|
-
return new Text(text, 0, 0);
|
|
1148
|
+
return renderSubagentResult(
|
|
1149
|
+
content,
|
|
1150
|
+
(message.details ?? {}) as SubagentResultDetails,
|
|
1151
|
+
expanded,
|
|
1152
|
+
theme,
|
|
1153
|
+
);
|
|
1082
1154
|
},
|
|
1083
1155
|
);
|
|
1084
1156
|
|
|
1157
|
+
pi.registerEntryRenderer<SubagentResultEntryData>(
|
|
1158
|
+
"subagent-result",
|
|
1159
|
+
(entry, { expanded }, theme) =>
|
|
1160
|
+
renderSubagentResult(
|
|
1161
|
+
entry.data?.content ?? "",
|
|
1162
|
+
entry.data?.details ?? {},
|
|
1163
|
+
expanded,
|
|
1164
|
+
theme,
|
|
1165
|
+
),
|
|
1166
|
+
);
|
|
1167
|
+
|
|
1085
1168
|
pi.registerEntryRenderer<SubagentFinishedData>(
|
|
1086
1169
|
"subagent-finished",
|
|
1087
1170
|
(entry, _options, theme) => {
|
|
@@ -205,7 +205,8 @@ const makeManager = Effect.gen(function* () {
|
|
|
205
205
|
let reservedBtw = 0;
|
|
206
206
|
let disposed = false;
|
|
207
207
|
let onSettled:
|
|
208
|
-
((snap: SubagentSnapshot, consumed: boolean) => void)
|
|
208
|
+
| ((snap: SubagentSnapshot, consumed: boolean) => void)
|
|
209
|
+
| undefined;
|
|
209
210
|
|
|
210
211
|
const notify = (id?: string) => {
|
|
211
212
|
const waiters = changeWaiters;
|
|
@@ -636,16 +637,17 @@ const makeManager = Effect.gen(function* () {
|
|
|
636
637
|
pruneSettled();
|
|
637
638
|
}),
|
|
638
639
|
),
|
|
639
|
-
Effect.map(
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
640
|
+
Effect.map(
|
|
641
|
+
(): ReadonlyArray<CancelResult> =>
|
|
642
|
+
unique.map((id) => {
|
|
643
|
+
const snapshot = entries.get(id)?.snapshot;
|
|
644
|
+
return {
|
|
645
|
+
id,
|
|
646
|
+
title: snapshot?.title ?? "?",
|
|
647
|
+
status: snapshot?.status ?? "error",
|
|
648
|
+
cancelled: runningIds.includes(id),
|
|
649
|
+
};
|
|
650
|
+
}),
|
|
649
651
|
),
|
|
650
652
|
);
|
|
651
653
|
});
|
|
@@ -8,7 +8,7 @@ import { MAX_RUNNING } from "./manager.ts";
|
|
|
8
8
|
|
|
9
9
|
/** Describes subagent_spawn, including the fixed concurrency cap. */
|
|
10
10
|
export const SUBAGENT_SPAWN_TOOL_DESCRIPTION =
|
|
11
|
-
"Spawn a background subagent: a fully autonomous, headless pi session with its own context window, this environment's tools and config, and normal host permissions. Fire-and-forget: this returns immediately with an id
|
|
11
|
+
"Spawn a background subagent: a fully autonomous, headless pi session with its own context window, this environment's tools and config, and normal host permissions. Fire-and-forget: this returns immediately with an id, and the subagent's final output is automatically queued back to you as a message when it settles. In an interactive session, keep working or end your turn so the user remains able to interact; do not block merely because a later step depends on the result. Children cannot orchestrate more agents/workflows or ask the user, and cannot see this conversation, so the prompt must be self-contained. Only use trusted working directories. " +
|
|
12
12
|
`Max ${MAX_RUNNING} subagents can be running at once.`;
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -62,7 +62,7 @@ export const SUBAGENT_SPAWN_PROMPT_SNIPPET =
|
|
|
62
62
|
/** Guides the parent model to delegate standalone tasks and avoid unnecessary blocking waits. */
|
|
63
63
|
export const SUBAGENT_SPAWN_PROMPT_GUIDELINES = [
|
|
64
64
|
"Reserve subagent_spawn for substantial, self-contained work; give it a complete, standalone prompt. For a single lookup or edit you can do inline, just do it — each subagent spends a fresh context window and cannot see this conversation.",
|
|
65
|
-
"After subagent_spawn, keep working on
|
|
65
|
+
"After subagent_spawn, keep working on independent work. If none remains in an interactive session, briefly tell the user the subagent is running in the background and end your turn; its result arrives automatically and you are re-invoked when it settles. Do not poll with subagent_check. Do not call subagent_wait merely because your next step depends on the result or because you have nothing else to do. Block only when the user explicitly asks you to keep the current response open for these results, or when a non-interactive automation must return them in the same invocation. Never answer from a guessed result before it arrives.",
|
|
66
66
|
];
|
|
67
67
|
|
|
68
68
|
/** Model-facing schema descriptions for subagent_spawn task and execution options. */
|
|
@@ -75,7 +75,7 @@ export const SUBAGENT_SPAWN_PARAMETER_DESCRIPTIONS = {
|
|
|
75
75
|
workingDir:
|
|
76
76
|
"Trusted working directory for the autonomous child (default: current working directory)",
|
|
77
77
|
isolation:
|
|
78
|
-
'Set to "worktree"
|
|
78
|
+
'Set to "worktree" for concurrent writers and tell the child to commit. Requires Git and a clean checkout. Read the subagents Skill for lifecycle, merge location, and costs.',
|
|
79
79
|
model:
|
|
80
80
|
'Optional model override, as "provider/model-id" or a bare id resolved against the current provider. Precedence: explicit spawn model > selected type file model > configured built-in role model > parent model. Never guess a model name.',
|
|
81
81
|
reasoningEffort:
|
|
@@ -113,14 +113,14 @@ export function buildSubagentSpawnResult(options: {
|
|
|
113
113
|
: "";
|
|
114
114
|
return (
|
|
115
115
|
`Spawned subagent ${options.id} "${options.title}" (${options.harness}: ${options.modelLabel}, ${options.cwd}).${typeNote}${toolNote}${worktreeNote}\n` +
|
|
116
|
-
`It runs in the background — keep working on
|
|
117
|
-
`
|
|
116
|
+
`It runs in the background — keep working on independent work. If none remains in an interactive session, briefly tell the user it is still running and end your turn; its result is delivered automatically and you are automatically re-invoked when it finishes. Do not poll or call subagent_wait merely because a later step depends on it. ` +
|
|
117
|
+
`Use subagent_wait(ids: ["${options.id}"]) only if the user explicitly asked you to keep the current response open for this result, or a non-interactive automation must return it in the same invocation; subagent_cancel stops it, subagent_check peeks at a running one, subagent_list shows all.`
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/** Describes explicit blocking collection of one or more subagent results. */
|
|
122
122
|
export const SUBAGENT_WAIT_TOOL_DESCRIPTION =
|
|
123
|
-
"Block until all listed subagents have settled, then return their final outputs. This is
|
|
123
|
+
"Block until all listed subagents have settled, then return their final outputs. This is an explicit synchronous barrier, not the default. In an interactive session, call it only when the user explicitly asks you to keep the current response open for these results. A dependent next step or having nothing else to do is not sufficient: end your turn and let automatic result delivery re-invoke you while the user remains free to interact. In a non-interactive automation, use it only when the same invocation must return the completed results. Never poll for completion and never answer from a guessed result before it arrives.";
|
|
124
124
|
|
|
125
125
|
/** Model-facing schema description for the subagent ids to await. */
|
|
126
126
|
export const SUBAGENT_WAIT_PARAMETER_DESCRIPTIONS = {
|
|
@@ -154,7 +154,7 @@ export function buildSubagentSendResult(options: {
|
|
|
154
154
|
}) {
|
|
155
155
|
return options.wasRunning
|
|
156
156
|
? `Steered ${options.id} "${options.title}". It is queued into the active run; the result is delivered when it settles.`
|
|
157
|
-
: `Restarted ${options.id} "${options.title}" for another turn on its existing transcript. The result is delivered when it settles
|
|
157
|
+
: `Restarted ${options.id} "${options.title}" for another turn on its existing transcript. The result is delivered automatically when it settles.`;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/** Describes nonblocking inspection of a subagent without consuming its result. */
|