pi-agent-flow 0.4.2 → 0.4.4
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/render-utils.ts +15 -4
- package/render.ts +26 -17
package/package.json
CHANGED
package/render-utils.ts
CHANGED
|
@@ -87,6 +87,17 @@ export function getTruncationBudget(prefixLength: number): number {
|
|
|
87
87
|
return Math.max(width - prefixLength, 1);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
/** Fixed content budget for collapsed-line text (dir/exe/log). */
|
|
91
|
+
export const CONTENT_MAX = 40;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Compute how many visible chars of content fit after a prefix,
|
|
95
|
+
* using the fixed CONTENT_MAX budget. Floor of 8 to keep things readable.
|
|
96
|
+
*/
|
|
97
|
+
export function contentBudget(prefixVisibleLen: number): number {
|
|
98
|
+
return Math.max(CONTENT_MAX - prefixVisibleLen, 8);
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
/**
|
|
91
102
|
* Truncate an ANSI-colored string to at most `max` visible characters,
|
|
92
103
|
* preserving ANSI codes in the kept portions. Does not inject reset codes
|
|
@@ -95,14 +106,14 @@ export function getTruncationBudget(prefixLength: number): number {
|
|
|
95
106
|
function truncateAnsi(text: string, max: number): string {
|
|
96
107
|
if (visibleLength(text) <= max) return text;
|
|
97
108
|
|
|
98
|
-
if (max <
|
|
99
|
-
// Not enough room for
|
|
109
|
+
if (max < 3) {
|
|
110
|
+
// Not enough room for '…' — just truncate without ellipsis
|
|
100
111
|
const { raw } = takeVisible(text, max);
|
|
101
112
|
return raw;
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
const head = Math.ceil(max * 0.6);
|
|
105
|
-
const tail = max - head -
|
|
116
|
+
const tail = max - head - 1; // 1 = '…'.length
|
|
106
117
|
|
|
107
118
|
// Walk through the string, collecting raw chars until we've consumed
|
|
108
119
|
// `count` visible characters. ANSI sequences are copied through without
|
|
@@ -160,7 +171,7 @@ function truncateAnsi(text: string, max: number): string {
|
|
|
160
171
|
|
|
161
172
|
const tailRaw = takeVisibleFromEnd(text, tail);
|
|
162
173
|
|
|
163
|
-
return headResult.raw + "
|
|
174
|
+
return headResult.raw + "\u2026" + tailRaw;
|
|
164
175
|
}
|
|
165
176
|
|
|
166
177
|
export function truncateChars(text: string, max: number): string {
|
package/render.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import * as os from "node:os";
|
|
9
9
|
import { getMarkdownTheme } from "@mariozechner/pi-coding-agent";
|
|
10
|
-
import { Container, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
|
10
|
+
import { Container, Markdown, Spacer, Text, TruncatedText } from "@mariozechner/pi-tui";
|
|
11
11
|
import { getFlowSummaryText } from "./runner-events.js";
|
|
12
12
|
import {
|
|
13
13
|
type DisplayItem,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
isFlowError,
|
|
23
23
|
isFlowSuccess,
|
|
24
24
|
} from "./types.js";
|
|
25
|
-
import { formatFixedTokens, formatCompactStats, formatFlowTypeName, truncateChars,
|
|
25
|
+
import { formatFixedTokens, formatCompactStats, formatFlowTypeName, truncateChars, contentBudget } from "./render-utils.js";
|
|
26
26
|
|
|
27
27
|
function shortenPath(p: string): string {
|
|
28
28
|
const home = os.homedir();
|
|
@@ -231,29 +231,34 @@ function renderFlowCollapsed(
|
|
|
231
231
|
const typeName = formatFlowTypeName(r.type);
|
|
232
232
|
let header = `${theme.fg("accent", theme.bold(typeName))} ${theme.fg("dim", "─")} ${theme.fg("dim", stats)}`;
|
|
233
233
|
if (error && r.stopReason) header += ` ${theme.fg("error", `[${r.stopReason}]`)}`;
|
|
234
|
-
container.addChild(new
|
|
234
|
+
container.addChild(new TruncatedText(header, 0, 0));
|
|
235
235
|
|
|
236
236
|
// dir: line (intent/objective)
|
|
237
237
|
if (r.intent) {
|
|
238
|
-
|
|
238
|
+
const dirContent = truncateChars(r.intent, contentBudget(10));
|
|
239
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "├─ dir:")} ${theme.fg("dim", dirContent)}`, 0, 0));
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
// exe: line (last tool call)
|
|
242
243
|
const lastTool = getLastToolCall(r.messages);
|
|
243
244
|
if (lastTool) {
|
|
244
245
|
const exeStr = formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme));
|
|
245
|
-
|
|
246
|
+
const exeContent = truncateChars(exeStr, contentBudget(10));
|
|
247
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "├─ exe:")} ${exeContent}`, 0, 0));
|
|
246
248
|
}
|
|
247
249
|
|
|
248
250
|
// log: line (last assistant text or streaming)
|
|
249
251
|
if (flowOutput) {
|
|
250
|
-
|
|
252
|
+
const logContent = truncateChars(flowOutput, contentBudget(10));
|
|
253
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "└─ log:")} ${theme.fg("dim", logContent)}`, 0, 0));
|
|
251
254
|
} else if (streamingText) {
|
|
252
|
-
|
|
255
|
+
const logContent = truncateChars(streamingText, contentBudget(10));
|
|
256
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "└─ log:")} ${theme.fg("dim", logContent)}`, 0, 0));
|
|
253
257
|
} else if (error && r.errorMessage) {
|
|
254
|
-
|
|
258
|
+
const logContent = truncateChars(r.errorMessage, contentBudget(10));
|
|
259
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "└─ log:")} ${theme.fg("error", logContent)}`, 0, 0));
|
|
255
260
|
} else {
|
|
256
|
-
container.addChild(new
|
|
261
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", "└─ log:")} ${theme.fg("dim", "[n/a]")}`, 0, 0));
|
|
257
262
|
}
|
|
258
263
|
|
|
259
264
|
return container;
|
|
@@ -364,40 +369,44 @@ function renderActivityPanel(
|
|
|
364
369
|
if (error && r.stopReason) {
|
|
365
370
|
headerLine += ` ${theme.fg("error", `[${r.stopReason}]`)}`;
|
|
366
371
|
}
|
|
367
|
-
container.addChild(new
|
|
372
|
+
container.addChild(new TruncatedText(headerLine, 0, 0));
|
|
368
373
|
|
|
369
374
|
// Continuation indent for sub-lines
|
|
370
375
|
const indent = isLast ? " " : "│ ";
|
|
371
376
|
|
|
372
377
|
// dir: line (intent/objective)
|
|
373
378
|
if (r.intent) {
|
|
374
|
-
|
|
379
|
+
const dirContent = truncateChars(r.intent, contentBudget(10));
|
|
380
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", indent + "├─ dir:")} ${theme.fg("dim", dirContent)}`, 0, 0));
|
|
375
381
|
}
|
|
376
382
|
|
|
377
383
|
// exe: line (last tool call)
|
|
378
384
|
const lastTool = getLastToolCall(r.messages);
|
|
379
385
|
if (lastTool) {
|
|
380
386
|
const exeStr = formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme));
|
|
381
|
-
|
|
387
|
+
const exeContent = truncateChars(exeStr, contentBudget(10));
|
|
388
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", indent + "├─ exe:")} ${exeContent}`, 0, 0));
|
|
382
389
|
}
|
|
383
390
|
|
|
384
391
|
// log: line (last assistant text)
|
|
385
392
|
const lastText = getLastAssistantText(r.messages);
|
|
386
393
|
if (lastText) {
|
|
387
|
-
|
|
394
|
+
const logContent = truncateChars(lastText, contentBudget(10));
|
|
395
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", indent + "└─ log:")} ${theme.fg("dim", logContent)}`, 0, 0));
|
|
388
396
|
} else if (error && r.errorMessage) {
|
|
389
|
-
|
|
397
|
+
const logContent = truncateChars(r.errorMessage, contentBudget(10));
|
|
398
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", indent + "└─ log:")} ${theme.fg("error", logContent)}`, 0, 0));
|
|
390
399
|
} else {
|
|
391
|
-
container.addChild(new
|
|
400
|
+
container.addChild(new TruncatedText(`${theme.fg("dim", indent + "└─ log:")} ${theme.fg("dim", "[n/a]")}`, 0, 0));
|
|
392
401
|
}
|
|
393
402
|
|
|
394
403
|
// Add blank line separator between flows (with continuation pipe)
|
|
395
404
|
if (!isLast) {
|
|
396
|
-
container.addChild(new
|
|
405
|
+
container.addChild(new TruncatedText(theme.fg("dim", "│"), 0, 0));
|
|
397
406
|
}
|
|
398
407
|
}
|
|
399
408
|
|
|
400
|
-
container.addChild(new
|
|
409
|
+
container.addChild(new TruncatedText(theme.fg("muted", "(Ctrl+O to expand tool traces)"), 0, 0));
|
|
401
410
|
|
|
402
411
|
return container;
|
|
403
412
|
}
|