oira666_pi-subagent 0.2.26 → 0.2.28

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.
Files changed (5) hide show
  1. package/index.ts +61 -4
  2. package/package.json +1 -1
  3. package/runner.ts +1202 -1089
  4. package/tree.ts +67 -4
  5. package/types.ts +474 -319
package/index.ts CHANGED
@@ -43,12 +43,19 @@ import {
43
43
  type SingleResult,
44
44
  type SubagentDetails,
45
45
  DEFAULT_DELEGATION_MODE,
46
+ buildLiveSubagentDetails,
46
47
  buildSubagentDetails,
47
48
  getFinalOutput,
48
49
  getNestedSubagentResults,
49
50
  isResultError,
50
51
  isSubagentDetails,
52
+ emptyUsage,
53
+ addUsage,
54
+ emptyUsageSummary,
55
+ addUsageSummary,
56
+ usageSummaryToUsageStats,
51
57
  } from "./types.js";
58
+ import { formatCombinedUsageStatusLine } from "./tree.js";
52
59
 
53
60
  // ---------------------------------------------------------------------------
54
61
  // Limits
@@ -294,15 +301,51 @@ function makeDetailsFactory(
294
301
  projectAgentsDir: string | null,
295
302
  delegationMode: DelegationMode,
296
303
  ) {
297
- return (mode: "single" | "parallel") =>
298
- (results: SingleResult[]): SubagentDetails =>
304
+ return (mode: "single" | "parallel") => {
305
+ const makeDetails = (results: SingleResult[]): SubagentDetails =>
299
306
  buildSubagentDetails(mode, delegationMode, projectAgentsDir, results);
307
+ makeDetails.live = (results: SingleResult[]): SubagentDetails =>
308
+ buildLiveSubagentDetails(mode, delegationMode, projectAgentsDir, results);
309
+ return makeDetails;
310
+ };
300
311
  }
301
312
 
302
313
  function formatAgentNames(agents: AgentConfig[]): string {
303
314
  return agents.map((a) => `${a.name} (${a.source})`).join(", ") || "none";
304
315
  }
305
316
 
317
+ function collectCombinedUsageStatusLine(ctx: any): string | undefined {
318
+ const entries = typeof ctx?.sessionManager?.getEntries === "function" || typeof ctx?.sessionManager?.getBranch === "function"
319
+ ? branchEntries(ctx)
320
+ : [];
321
+ if (entries.length === 0) return undefined;
322
+
323
+ const parentUsage = emptyUsage();
324
+ const subagents = emptyUsageSummary();
325
+ for (const entry of entries as any[]) {
326
+ if (entry?.type !== "message") continue;
327
+ const msg = entry.message;
328
+ if (!msg) continue;
329
+ if (msg.role === "assistant" && msg.provider !== RESUME_PROVIDER) {
330
+ const usage = msg.usage;
331
+ if (usage) {
332
+ parentUsage.input += usage.input || 0;
333
+ parentUsage.output += usage.output || 0;
334
+ parentUsage.cacheRead += usage.cacheRead || 0;
335
+ parentUsage.cacheWrite += usage.cacheWrite || 0;
336
+ parentUsage.cost += usage.cost?.total || 0;
337
+ parentUsage.turns += 1;
338
+ }
339
+ }
340
+ if (msg.role === "toolResult" && msg.toolName === "subagent" && isSubagentDetails(msg.details)) {
341
+ addUsageSummary(subagents, msg.details.usageSummary ?? emptyUsageSummary());
342
+ }
343
+ }
344
+ const subagentUsage = usageSummaryToUsageStats(subagents) ?? emptyUsage();
345
+ addUsage(parentUsage, subagentUsage);
346
+ return formatCombinedUsageStatusLine(parentUsage, subagents.subagentCount);
347
+ }
348
+
306
349
  function getCycleViolations(
307
350
  requestedNames: Set<string>,
308
351
  ancestorAgentStack: string[],
@@ -1006,6 +1049,20 @@ export default function (pi: ExtensionAPI) {
1006
1049
  }
1007
1050
  }
1008
1051
 
1052
+ // If the host exposes a status-line extension point, add a second line under
1053
+ // the normal session stats with parent + active-branch subagent totals. Older
1054
+ // Pi versions simply won't have this API, so keep this best-effort.
1055
+ try {
1056
+ const statusProvider = (ctx: any) => collectCombinedUsageStatusLine(ctx ?? latestSessionCtx);
1057
+ if (typeof pi.registerStatusLine === "function") {
1058
+ pi.registerStatusLine({ id: "subagent-combined-usage", placement: "after-session-stats", render: statusProvider });
1059
+ } else if (typeof pi.addStatusLine === "function") {
1060
+ pi.addStatusLine(statusProvider, { id: "subagent-combined-usage", placement: "after-session-stats" });
1061
+ }
1062
+ } catch (err) {
1063
+ console.error("[pi-subagent] Failed to register combined subagent status line:", err);
1064
+ }
1065
+
1009
1066
  // Auto-discover agents on session start
1010
1067
  pi.on("session_start", async (event, ctx) => {
1011
1068
  latestSessionCtx = ctx;
@@ -1466,7 +1523,7 @@ This guard prevents self-recursion and cyclic handoffs (for example A -> B -> A)
1466
1523
  const errorMsg =
1467
1524
  result.errorMessage ||
1468
1525
  result.stderr ||
1469
- getFinalOutput(result.messages) ||
1526
+ getFinalOutput(result.messages, result.finalOutput) ||
1470
1527
  "(no output)";
1471
1528
  return {
1472
1529
  content: [
@@ -1483,7 +1540,7 @@ This guard prevents self-recursion and cyclic handoffs (for example A -> B -> A)
1483
1540
  content: [
1484
1541
  {
1485
1542
  type: "text" as const,
1486
- text: getFinalOutput(result.messages) || "(no output)",
1543
+ text: getFinalOutput(result.messages, result.finalOutput) || "(no output)",
1487
1544
  },
1488
1545
  ],
1489
1546
  details: makeDetails("single")([result]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oira666_pi-subagent",
3
- "version": "0.2.26",
3
+ "version": "0.2.28",
4
4
  "description": "Subagent extension for Pi coding agent. Delegate tasks to specialized agents.",
5
5
  "type": "module",
6
6
  "main": "index.ts",