@arhen/pi-core-subagent 1.3.53 → 1.3.54
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/package.json +1 -1
- package/src/format.ts +15 -10
- package/src/index.ts +1 -0
- package/src/manager.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arhen/pi-core-subagent",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "pi extension: fast in-process subagents with a dependency-graph scheduler (needs edges gate tasks and carry upstream output into dependent prompts), plus background runs, intercom and agent-to-agent mailbox. Leader defines agents inline.",
|
|
6
6
|
"license": "MIT",
|
package/src/format.ts
CHANGED
|
@@ -114,7 +114,8 @@ export function compactLines(run: RunSnapshot): string[] {
|
|
|
114
114
|
if (run.tasks.length > MAX_TASKS) lines.push(`… +${run.tasks.length - MAX_TASKS} more`);
|
|
115
115
|
return lines;
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
// header + 4 task rows; live tasks are ordered first, so the cap only ever hides finished work
|
|
118
|
+
const WIDGET_MAX_LINES = 5;
|
|
118
119
|
|
|
119
120
|
export class SubagentsWidget implements Component {
|
|
120
121
|
constructor(
|
|
@@ -139,17 +140,21 @@ export class SubagentsWidget implements Component {
|
|
|
139
140
|
),
|
|
140
141
|
];
|
|
141
142
|
const budget = WIDGET_MAX_LINES - 1;
|
|
143
|
+
// live tasks first so the budget never hides work in progress
|
|
144
|
+
const all = runs.flatMap((run) => run.tasks);
|
|
145
|
+
const ordered = [
|
|
146
|
+
...all.filter((t) => !TERMINAL.includes(t.status)),
|
|
147
|
+
...all.filter((t) => TERMINAL.includes(t.status)),
|
|
148
|
+
];
|
|
142
149
|
let shown = 0;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const activity = task.lastActivity ? `${this.theme.fg("dim", `→ ${task.lastActivity}`)} · ` : "";
|
|
150
|
+
for (const task of ordered) {
|
|
151
|
+
if (shown >= budget) break;
|
|
152
|
+
shown += 1;
|
|
153
|
+
const activity = task.lastActivity ? `${this.theme.fg("dim", `→ ${task.lastActivity}`)} · ` : "";
|
|
148
154
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
155
|
+
lines.push(
|
|
156
|
+
truncateToWidth(`${this.theme.fg("dim", "├─")} ${themedTaskLine(task, this.theme, activity)}`, width, "…"),
|
|
157
|
+
);
|
|
153
158
|
}
|
|
154
159
|
const hidden = total - shown;
|
|
155
160
|
if (hidden > 0) {
|
package/src/index.ts
CHANGED
|
@@ -140,6 +140,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
140
140
|
"Define each agent inline: invented name, focused system prompt, read-only by default (write:true to edit). A matched agent file takes over (see description); matching is by description, not name — name the agent whatever fits the goal.",
|
|
141
141
|
"Right after spawning, call subagent_status(runId) ONCE before any other work — a child that died on spawn (or never started) is invisible until far later otherwise. If it shows a task failed/never started, fix or respawn immediately.",
|
|
142
142
|
"Never block with nothing to do: if you have no work left after spawning, end your turn — completion notifies you and wakes a fresh turn with the results. await_subagent/autoAwait while idle only burns time and tokens.",
|
|
143
|
+
"A failed task interrupts you immediately as a steering message — handle it in the same turn (resume, swap model, re-dispatch) instead of finishing the plan on a broken intermediate result. Completes and aborts queue as follow-ups.",
|
|
143
144
|
"autoAwait:true only when this SAME turn must consume the result immediately. await_subagent is for syncing with your own parallel work — not the default follow-up to a spawn.",
|
|
144
145
|
"A task that failed mid-work (provider error, rate limit, timeout) keeps its session file and branch: resume_subagent(runId, taskId, model?) revives it with full context — prefer that over respawning. Respawn only when it never started (no session file).",
|
|
145
146
|
],
|
package/src/manager.ts
CHANGED
|
@@ -437,7 +437,9 @@ export class SubagentManager {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
private deliverMode(kind: string, task: TaskSnapshot): "steer" | "followUp" {
|
|
440
|
-
|
|
440
|
+
// failures interrupt the leader's turn: it must decide immediately (resume, swap model, respawn)
|
|
441
|
+
// instead of finding out after its own turn ended. Aborts are user-initiated, so they queue.
|
|
442
|
+
return kind === "failed" || isStartupFailure(task, kind) ? "steer" : "followUp";
|
|
441
443
|
}
|
|
442
444
|
|
|
443
445
|
private notifyTask(run: RunSnapshot, task: TaskSnapshot, kind: "completed" | "failed" | "aborted"): void {
|
|
@@ -470,7 +472,7 @@ export class SubagentManager {
|
|
|
470
472
|
? `A subagent is asking you a question (task ${extra?.taskId}): ${extra?.question ?? ""}\nReply with reply_subagent(runId: "${run.id}", taskId: "${extra?.taskId}", message: ...).`
|
|
471
473
|
: makeNotice(run, kind);
|
|
472
474
|
try {
|
|
473
|
-
this.pi.sendUserMessage(body, { deliverAs: "followUp" });
|
|
475
|
+
this.pi.sendUserMessage(body, { deliverAs: kind === "failed" ? "steer" : "followUp" });
|
|
474
476
|
} catch {}
|
|
475
477
|
this.emit("subagent:notification", { runId: run.id, kind, body });
|
|
476
478
|
}
|