@hheei/pi-subagents 0.5.1 → 0.5.3

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 (2) hide show
  1. package/dist/extension.js +21 -4
  2. package/package.json +2 -2
package/dist/extension.js CHANGED
@@ -1,4 +1,4 @@
1
- import { errorMessage, getBackgroundDelivery, registerExtensionLifecycle, } from "@hheei/pi-ext-core";
1
+ import { createRenderThrottle, DEFAULT_MAX_BYTES, errorMessage, fitsOutputBudget, getBackgroundDelivery, registerExtensionLifecycle, truncateWithSpill, } from "@hheei/pi-ext-core";
2
2
  import { discoverAgents } from "./agent-resolver.js";
3
3
  import { registerChildBridge } from "./child-bridge.js";
4
4
  import { registerParentCommands } from "./commands.js";
@@ -90,7 +90,9 @@ export function createParentChannel(pi, deps) {
90
90
  async deliver(report) {
91
91
  if (disposed)
92
92
  throw new Error("Parent report channel is disposed");
93
- held.push(report);
93
+ // A report that already fits stays on the synchronous path: a batch is flushed in the same
94
+ // microtask, and awaiting a spill that will not happen would delay every ordinary report.
95
+ held.push(fitsOutputBudget(report.message, REPORT_LIMITS) ? report : await cappedReport(report));
94
96
  registration.request();
95
97
  },
96
98
  dispose() {
@@ -114,6 +116,16 @@ export function skillCatalogFromLoaded(skills) {
114
116
  function reportText(report) {
115
117
  return `[Subagent ${report.agent} ${report.childId}: ${report.reason}]\n${report.message}`;
116
118
  }
119
+ /**
120
+ * A child's final answer is a result the parent reads, so it obeys the shared budget. It is stored
121
+ * as plain text rather than pointing back at the child's transcript: a transcript is JSONL that must
122
+ * be parsed to find the one message, which costs more than the copy.
123
+ */
124
+ const REPORT_LIMITS = { maxBytes: DEFAULT_MAX_BYTES, maxLines: Number.POSITIVE_INFINITY };
125
+ async function cappedReport(report) {
126
+ const spilled = await truncateWithSpill(report.message, `sub-${report.childId}`, REPORT_LIMITS);
127
+ return spilled.truncated ? { ...report, message: spilled.text } : report;
128
+ }
117
129
  export default function piSubagentsExtension(pi) {
118
130
  const child = childIdentityFromEnv(process.env);
119
131
  if (child !== undefined) {
@@ -302,7 +314,10 @@ export default function piSubagentsExtension(pi) {
302
314
  registerParentCommands(pi, manager);
303
315
  const status = createSubagentStatus(context.ui, runtime.signal);
304
316
  let refreshVersion = 0;
305
- const refreshStatus = () => {
317
+ // The manager notifies on every lifecycle transition, and each notification costs an async
318
+ // list plus a full footer rebuild. The footer follows the shared streaming window instead;
319
+ // the first change still paints immediately and the last state is never dropped.
320
+ const repaintStatus = createRenderThrottle(() => {
306
321
  if (runtime.signal.aborted)
307
322
  return;
308
323
  const version = ++refreshVersion;
@@ -314,11 +329,13 @@ export default function piSubagentsExtension(pi) {
314
329
  status.refresh(children);
315
330
  })
316
331
  .catch((error) => diagnose(`Subagent status failed: ${errorMessage(error)}`));
317
- };
332
+ });
333
+ const refreshStatus = () => repaintStatus.request();
318
334
  const unsubscribe = manager.onChange(refreshStatus);
319
335
  refreshStatus();
320
336
  runtime.resources.add("subagent-status", () => {
321
337
  unsubscribe();
338
+ repaintStatus.dispose();
322
339
  status.dispose();
323
340
  });
324
341
  runtime.resources.add("subagent-manager", () => manager.closeLocalConnections());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hheei/pi-subagents",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Independent background Pi subagent sessions with durable identity and RPC control.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "access": "public"
36
36
  },
37
37
  "dependencies": {
38
- "@hheei/pi-ext-core": "^0.6.0"
38
+ "@hheei/pi-ext-core": "^0.6.2"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@earendil-works/pi-coding-agent": ">=1.3.0",