@arhen/pi-core-subagent 1.3.57 → 1.3.58
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 +7 -0
- package/src/index.ts +2 -1
- package/src/manager.ts +36 -21
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.58",
|
|
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
|
@@ -111,10 +111,17 @@ export function isTalking(task: TaskSnapshot): boolean {
|
|
|
111
111
|
return TALK_TOOLS.some((t) => a.startsWith(t));
|
|
112
112
|
}
|
|
113
113
|
let pulsePhase = 0;
|
|
114
|
+
const NOTE_CAP = 240;
|
|
115
|
+
function noteSnippet(note: string): string {
|
|
116
|
+
return note.length > NOTE_CAP ? `${note.slice(0, NOTE_CAP)}…` : note;
|
|
117
|
+
}
|
|
114
118
|
export function compactLines(run: RunSnapshot): string[] {
|
|
115
119
|
const lines: string[] = [];
|
|
116
120
|
for (const task of run.tasks.slice(0, MAX_TASKS)) {
|
|
117
121
|
lines.push(taskLine(task));
|
|
122
|
+
// a swapped model or toolset changes what the task did, so it cannot stay out of the status view
|
|
123
|
+
if (task.modelNote) lines.push(` ↳ Model: ${noteSnippet(task.modelNote)}`);
|
|
124
|
+
if (task.toolsNote) lines.push(` ↳ Tools: ${noteSnippet(task.toolsNote)}`);
|
|
118
125
|
}
|
|
119
126
|
if (run.tasks.length > MAX_TASKS) lines.push(`… +${run.tasks.length - MAX_TASKS} more`);
|
|
120
127
|
return lines;
|
package/src/index.ts
CHANGED
|
@@ -299,7 +299,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
299
299
|
? `\nApplied IN PLACE (no branch) — ${t.isolationReason ?? "worktree unavailable"}. The changes are already in your working tree.`
|
|
300
300
|
: "";
|
|
301
301
|
const wtErr = t.worktreeError ? `\nWorktree: ${t.worktreeError}` : "";
|
|
302
|
-
|
|
302
|
+
const modelNote = t.modelNote ? `\nModel: ${t.modelNote}` : "";
|
|
303
|
+
return `\n## ${t.agent} ${statusIcon(t.status)}\nGoal: ${truncateText(t.task, 300)}\n${t.error ? `Error: ${t.error}` : t.finalText || "(no output yet)"}${wt}${wtErr}${modelNote}\n${formatUsage(t.usage)}`;
|
|
303
304
|
}),
|
|
304
305
|
].join("\n");
|
|
305
306
|
return { content: [{ type: "text", text: truncateText(text) }], details: { run: cloneRun(run) } };
|
package/src/manager.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync
|
|
|
2
2
|
import { rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, join, relative, sep } from "node:path";
|
|
4
4
|
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
5
|
-
import
|
|
5
|
+
import {
|
|
6
|
+
type Api,
|
|
7
|
+
type AssistantMessage,
|
|
8
|
+
clampThinkingLevel,
|
|
9
|
+
getSupportedThinkingLevels,
|
|
10
|
+
type Model,
|
|
11
|
+
} from "@earendil-works/pi-ai";
|
|
6
12
|
import {
|
|
7
13
|
type AgentSessionEvent,
|
|
8
14
|
createAgentSession,
|
|
@@ -160,21 +166,19 @@ export function resolveChildModel(ctx: ExtensionContext, explicit: string | unde
|
|
|
160
166
|
const PROBE_THINKING_LEVELS: ThinkingLevel[] = ["low", "minimal", "medium", "high", "xhigh", "max"];
|
|
161
167
|
|
|
162
168
|
/**
|
|
163
|
-
* Thinking level for the usability probe:
|
|
164
|
-
* the model accepts
|
|
165
|
-
*
|
|
166
|
-
* make every preflight fail and fall
|
|
169
|
+
* Thinking level for the usability probe: exactly what the child session will send — the clamped
|
|
170
|
+
* requested level, or the cheapest the model accepts when none was requested. Probing without a
|
|
171
|
+
* level makes adaptive-thinking providers reject the request (9router claude models answer
|
|
172
|
+
* "thinking.type.disabled is not supported"), which used to make every preflight fail and fall
|
|
173
|
+
* back to the session model.
|
|
167
174
|
*/
|
|
168
175
|
function probeThinking(model: Model<Api>, thinking?: string): ThinkingLevel | undefined {
|
|
169
|
-
if (thinking && thinking !== "off") return thinking as ThinkingLevel;
|
|
170
176
|
if (!model.reasoning) return undefined;
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
return undefined;
|
|
177
|
+
const supported = getSupportedThinkingLevels(model);
|
|
178
|
+
if (thinking && thinking !== "off") return clampThinkingLevel(model, thinking as ThinkingLevel);
|
|
179
|
+
// the child clamps an unsupported "off" up to its cheapest level, so probe that instead
|
|
180
|
+
if (thinking === "off") return supported.includes("off") ? undefined : supported[0];
|
|
181
|
+
return PROBE_THINKING_LEVELS.find((level) => supported.includes(level));
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
async function probeModel(
|
|
@@ -325,10 +329,10 @@ export class SubagentManager {
|
|
|
325
329
|
return false;
|
|
326
330
|
}
|
|
327
331
|
|
|
328
|
-
clearWidget(ctx
|
|
332
|
+
clearWidget(ctx?: ExtensionContext): void {
|
|
329
333
|
this.widgetRuns = [];
|
|
330
334
|
this.widgetTui = null;
|
|
331
|
-
if (ctx
|
|
335
|
+
if (ctx?.hasUI) {
|
|
332
336
|
try {
|
|
333
337
|
ctx.ui.setWidget("subagents", undefined);
|
|
334
338
|
} catch {}
|
|
@@ -506,8 +510,14 @@ export class SubagentManager {
|
|
|
506
510
|
}
|
|
507
511
|
|
|
508
512
|
private widgetTui: TUI | null = null;
|
|
513
|
+
|
|
514
|
+
/** Settled runs are history (subagent_status/result still reach them) — the widget shows live work only. */
|
|
515
|
+
private pruneSettledWidget(): void {
|
|
516
|
+
this.widgetRuns = this.widgetRuns.filter((r) => !TERMINAL.includes(r.status));
|
|
517
|
+
}
|
|
509
518
|
private upsertWidgetRun(run: RunSnapshot | undefined): void {
|
|
510
|
-
|
|
519
|
+
this.pruneSettledWidget();
|
|
520
|
+
if (!run || TERMINAL.includes(run.status)) return;
|
|
511
521
|
const idx = this.widgetRuns.findIndex((r) => r.id === run.id);
|
|
512
522
|
if (idx >= 0) this.widgetRuns[idx] = run;
|
|
513
523
|
else this.widgetRuns.push(run);
|
|
@@ -547,12 +557,17 @@ export class SubagentManager {
|
|
|
547
557
|
this.widgetTimers.delete(run.id);
|
|
548
558
|
}
|
|
549
559
|
}
|
|
550
|
-
|
|
551
|
-
if (
|
|
552
|
-
this.
|
|
553
|
-
|
|
560
|
+
this.pruneSettledWidget();
|
|
561
|
+
if (this.widgetRuns.length === 0) {
|
|
562
|
+
if (this.widgetTui) this.clearWidget(ctx);
|
|
563
|
+
} else {
|
|
564
|
+
if (ctx?.hasUI) {
|
|
565
|
+
this.ensureWidget(ctx);
|
|
566
|
+
this.widgetTui?.requestRender();
|
|
567
|
+
}
|
|
568
|
+
this.maybePulse(ctx);
|
|
554
569
|
}
|
|
555
|
-
|
|
570
|
+
if (!run) return;
|
|
556
571
|
|
|
557
572
|
onUpdate?.({
|
|
558
573
|
content: [
|