@yusukeshib/pi-babysit 0.6.11 → 0.6.13
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 +6 -2
- package/index.ts +36 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,8 +88,12 @@ ten per page; `< 1/4 >` shows the current/total page when needed. Click the
|
|
|
88
88
|
arrows to page. Collapsed rows occupy one line, previewing the command for
|
|
89
89
|
processes and the task for agents (with `…` when clipped). Click a row for the
|
|
90
90
|
complete wrapped command or task; agent rows also show their RPC worker launch
|
|
91
|
-
argv (bold, readable text rather than a copy-paste shell command), and up to
|
|
92
|
-
output lines.
|
|
91
|
+
argv (bold, readable text rather than a copy-paste shell command), and up to 50
|
|
92
|
+
output lines. Agent output retains recent RPC text, tool calls, and tool results
|
|
93
|
+
in chronological order instead of showing only the latest message. Blank lines
|
|
94
|
+
and surrounding whitespace are preserved. Expanded output lines wrap without a
|
|
95
|
+
100-character cutoff.
|
|
96
|
+
Opening another row closes the previous
|
|
93
97
|
one. A session with no available output shows an explicit placeholder when
|
|
94
98
|
expanded. Mouse clicks
|
|
95
99
|
require fullscreen mode; `/babysit` works in regular mode. The displayed `age`
|
package/index.ts
CHANGED
|
@@ -1556,6 +1556,8 @@ export interface Progress {
|
|
|
1556
1556
|
finalText: string;
|
|
1557
1557
|
/** Best-effort text from the currently streaming assistant message. */
|
|
1558
1558
|
streamingText: string;
|
|
1559
|
+
/** Recent readable RPC output, independent of the latest assistant message. */
|
|
1560
|
+
logText: string;
|
|
1559
1561
|
/** Context size reported by the most recent assistant response. */
|
|
1560
1562
|
tokens?: number;
|
|
1561
1563
|
/** Cumulative model usage for the current subagent task. */
|
|
@@ -1616,6 +1618,7 @@ function emptyProgress(): Progress {
|
|
|
1616
1618
|
toolCallCount: 0,
|
|
1617
1619
|
finalText: "",
|
|
1618
1620
|
streamingText: "",
|
|
1621
|
+
logText: "",
|
|
1619
1622
|
modelCalls: 0,
|
|
1620
1623
|
usageTokens: 0,
|
|
1621
1624
|
inputTokens: 0,
|
|
@@ -1713,6 +1716,12 @@ function updateProgressState(progress: Progress): Progress {
|
|
|
1713
1716
|
return progress;
|
|
1714
1717
|
}
|
|
1715
1718
|
|
|
1719
|
+
function appendProgressLog(progress: Progress, text: string, separate = false): void {
|
|
1720
|
+
if (!text) return;
|
|
1721
|
+
const separator = separate && progress.logText && !progress.logText.endsWith("\n") ? "\n" : "";
|
|
1722
|
+
progress.logText = (progress.logText + separator + text).split("\n").slice(-50).join("\n");
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1716
1725
|
function parseEventLine(progress: Progress, raw: string): void {
|
|
1717
1726
|
const line = raw.replace(/\r$/, "").trim();
|
|
1718
1727
|
if (!line.startsWith("{")) return;
|
|
@@ -1732,12 +1741,14 @@ function parseEventLine(progress: Progress, raw: string): void {
|
|
|
1732
1741
|
| { type?: string; delta?: string }
|
|
1733
1742
|
| undefined;
|
|
1734
1743
|
if (update?.type === "text_delta" && typeof update.delta === "string") {
|
|
1744
|
+
appendProgressLog(progress, update.delta, !progress.streamingText);
|
|
1735
1745
|
progress.streamingText = clip(progress.streamingText + update.delta, ANSWER_MAX_BYTES);
|
|
1736
1746
|
}
|
|
1737
1747
|
break;
|
|
1738
1748
|
}
|
|
1739
1749
|
case "tool_execution_start": {
|
|
1740
1750
|
const name = String(event.toolName ?? "tool");
|
|
1751
|
+
appendProgressLog(progress, summarizeToolCall(name, (event.args as Record<string, unknown>) ?? {}), true);
|
|
1741
1752
|
progress.toolCallCount++;
|
|
1742
1753
|
progress.toolCalls.push({
|
|
1743
1754
|
name,
|
|
@@ -1771,12 +1782,22 @@ function parseEventLine(progress: Progress, raw: string): void {
|
|
|
1771
1782
|
};
|
|
1772
1783
|
}
|
|
1773
1784
|
| undefined;
|
|
1785
|
+
// Compact RPC logs omit successful tool_execution_end payloads, but
|
|
1786
|
+
// retain the corresponding toolResult message once.
|
|
1787
|
+
if (message?.role === "toolResult") {
|
|
1788
|
+
for (const block of message.content ?? []) {
|
|
1789
|
+
if (block.type === "text" && block.text) appendProgressLog(progress, block.text, true);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1774
1792
|
if (message?.role === "assistant") {
|
|
1775
1793
|
const text = (message.content ?? [])
|
|
1776
1794
|
.filter((content) => content.type === "text" && content.text)
|
|
1777
1795
|
.map((content) => content.text)
|
|
1778
1796
|
.join("");
|
|
1779
|
-
if (text.trim())
|
|
1797
|
+
if (text.trim()) {
|
|
1798
|
+
if (!progress.streamingText) appendProgressLog(progress, text, true);
|
|
1799
|
+
progress.finalText = clip(text, ANSWER_MAX_BYTES);
|
|
1800
|
+
}
|
|
1780
1801
|
if (message.stopReason === "error") {
|
|
1781
1802
|
progress.errorMsg = message.errorMessage || "subagent model request failed";
|
|
1782
1803
|
}
|
|
@@ -2368,8 +2389,7 @@ function renderWidgetSessionHeader(
|
|
|
2368
2389
|
|
|
2369
2390
|
// How many trailing output lines to show per session in the widget.
|
|
2370
2391
|
const WIDGET_COLLAPSED_TAIL_LINES = 1;
|
|
2371
|
-
const WIDGET_EXPANDED_TAIL_LINES =
|
|
2372
|
-
const WIDGET_TAIL_WIDTH = 100;
|
|
2392
|
+
const WIDGET_EXPANDED_TAIL_LINES = 50;
|
|
2373
2393
|
const WIDGET_SESSION_PAGE_SIZE = 10;
|
|
2374
2394
|
|
|
2375
2395
|
export interface WidgetSessionListState {
|
|
@@ -2422,14 +2442,14 @@ export function createWidgetComponent(
|
|
|
2422
2442
|
);
|
|
2423
2443
|
const target = session.expandable ? { type: "session" as const, id: session.id } : undefined;
|
|
2424
2444
|
const details = session.details ?? [];
|
|
2425
|
-
const
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
} else {
|
|
2430
|
-
push(` ${text}`, target);
|
|
2445
|
+
const pushWrapped = (text: string) => {
|
|
2446
|
+
const indent = width > 6 ? " " : "";
|
|
2447
|
+
for (const line of wrapTextWithAnsi(text, Math.max(1, width - indent.length))) {
|
|
2448
|
+
push(`${indent}${line}`, target);
|
|
2431
2449
|
}
|
|
2432
2450
|
};
|
|
2451
|
+
const pushDetail = (detail: string) =>
|
|
2452
|
+
pushWrapped(detail.startsWith("task: ") ? detail.slice(6) : detail);
|
|
2433
2453
|
if (!expanded && details.length) {
|
|
2434
2454
|
const preview = details[0].startsWith("task: ") ? details[0].slice(6) : details[0];
|
|
2435
2455
|
push(`${session.header} ${preview}`, target, "…");
|
|
@@ -2438,7 +2458,7 @@ export function createWidgetComponent(
|
|
|
2438
2458
|
} else {
|
|
2439
2459
|
push(session.header, target);
|
|
2440
2460
|
for (const detail of details) pushDetail(detail);
|
|
2441
|
-
for (const line of tail)
|
|
2461
|
+
for (const line of tail) pushWrapped(line);
|
|
2442
2462
|
if (expanded && tail.length === 0) push(" (no output available)", target);
|
|
2443
2463
|
}
|
|
2444
2464
|
};
|
|
@@ -2524,7 +2544,7 @@ function sanitizeTailLine(s: string): string {
|
|
|
2524
2544
|
.replace(/\x1b[@-Z\\-_]|\x1b\[[0-?]*[ -/]*[@-~]/g, "")
|
|
2525
2545
|
// remaining non-printable control chars (keep tab)
|
|
2526
2546
|
.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
|
|
2527
|
-
return clean
|
|
2547
|
+
return clean;
|
|
2528
2548
|
}
|
|
2529
2549
|
|
|
2530
2550
|
function readTailLines(file: string, lines: number, maxBytes = 64_000): string[] {
|
|
@@ -2566,10 +2586,12 @@ export function widgetTail(
|
|
|
2566
2586
|
raw = readTailLines(logPath(id), lines);
|
|
2567
2587
|
} else {
|
|
2568
2588
|
const progress = subagentProgress ?? taskProgressOf(id).progress;
|
|
2569
|
-
if (progress.
|
|
2570
|
-
raw = progress.
|
|
2589
|
+
if (progress.logText) {
|
|
2590
|
+
raw = progress.logText.split("\n");
|
|
2591
|
+
} else if (progress.streamingText.trim()) {
|
|
2592
|
+
raw = progress.streamingText.split("\n");
|
|
2571
2593
|
} else if (progress.finalText.trim()) {
|
|
2572
|
-
raw = progress.finalText.
|
|
2594
|
+
raw = progress.finalText.split("\n");
|
|
2573
2595
|
} else if (progress.toolCalls.length > 0) {
|
|
2574
2596
|
raw = progress.toolCalls.map((tool) => tool.summary);
|
|
2575
2597
|
} else {
|
|
@@ -2578,7 +2600,6 @@ export function widgetTail(
|
|
|
2578
2600
|
}
|
|
2579
2601
|
return raw
|
|
2580
2602
|
.map(sanitizeTailLine)
|
|
2581
|
-
.filter((line) => line.trim().length > 0)
|
|
2582
2603
|
.slice(-lines);
|
|
2583
2604
|
}
|
|
2584
2605
|
|