pi-agent-flow 2.0.7 → 2.0.9
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/agents/audit.md +2 -2
- package/agents/trace.md +3 -17
- package/dist/batch/execute.d.ts.map +1 -1
- package/dist/batch/execute.js +8 -0
- package/dist/batch/execute.js.map +1 -1
- package/dist/batch/render.js +3 -3
- package/dist/batch/render.js.map +1 -1
- package/dist/flow/agents.d.ts.map +1 -1
- package/dist/flow/agents.js +1 -0
- package/dist/flow/agents.js.map +1 -1
- package/dist/flow/runner.d.ts.map +1 -1
- package/dist/flow/runner.js +2 -0
- package/dist/flow/runner.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -16
- package/dist/index.js.map +1 -1
- package/dist/steering/sliding-prompt.d.ts.map +1 -1
- package/dist/steering/sliding-prompt.js +4 -3
- package/dist/steering/sliding-prompt.js.map +1 -1
- package/dist/tools/trace.d.ts +25 -16
- package/dist/tools/trace.d.ts.map +1 -1
- package/dist/tools/trace.js +195 -130
- package/dist/tools/trace.js.map +1 -1
- package/dist/tui/flow-colors.d.ts +6 -1
- package/dist/tui/flow-colors.d.ts.map +1 -1
- package/dist/tui/flow-colors.js +1 -0
- package/dist/tui/flow-colors.js.map +1 -1
- package/dist/tui/render.d.ts +0 -8
- package/dist/tui/render.d.ts.map +1 -1
- package/dist/tui/render.js +49 -166
- package/dist/tui/render.js.map +1 -1
- package/dist/tui/scramble/algorithm.d.ts.map +1 -1
- package/dist/tui/scramble/algorithm.js +9 -12
- package/dist/tui/scramble/algorithm.js.map +1 -1
- package/dist/tui/scramble/constants.d.ts +3 -3
- package/dist/tui/scramble/constants.js +2 -2
- package/dist/types/ui.d.ts +4 -0
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/ui.js +41 -0
- package/dist/types/ui.js.map +1 -1
- package/package.json +1 -1
package/dist/tui/render.js
CHANGED
|
@@ -24,6 +24,14 @@ function getAnonymousFlowId() {
|
|
|
24
24
|
export function resetAnonymousFlowIdCounter() {
|
|
25
25
|
anonFlowIdCounter = 0;
|
|
26
26
|
}
|
|
27
|
+
function getContentRole(baseRole, text, useError) {
|
|
28
|
+
if (useError)
|
|
29
|
+
return "msgError";
|
|
30
|
+
if (["[awaiting...]", "[n/a]", "[skipped]", "[approved]", "[finished]"].includes(text)) {
|
|
31
|
+
return "placeholder";
|
|
32
|
+
}
|
|
33
|
+
return baseRole;
|
|
34
|
+
}
|
|
27
35
|
function getLiveTextWithFallback(id) {
|
|
28
36
|
const value = getLiveText(id);
|
|
29
37
|
if (value !== undefined)
|
|
@@ -31,7 +39,7 @@ function getLiveTextWithFallback(id) {
|
|
|
31
39
|
const fallbackId = id.includes("#") ? "collapsed" + id.slice(id.indexOf("#")) : "collapsed";
|
|
32
40
|
return getLiveText(fallbackId);
|
|
33
41
|
}
|
|
34
|
-
import { formatCompactStats, formatFlowTypeName, lowerFirstWord, truncateChars, tailText, getTruncationBudget, visibleLength, stripAnsi, formatModelLabel, formatContextLabel, formatTps
|
|
42
|
+
import { formatCompactStats, formatFlowTypeName, lowerFirstWord, truncateChars, tailText, getTruncationBudget, visibleLength, stripAnsi, formatModelLabel, formatContextLabel, formatTps } from "./render-utils.js";
|
|
35
43
|
function shortenPath(p) {
|
|
36
44
|
const home = os.homedir();
|
|
37
45
|
return p.startsWith(home) ? `~${p.slice(home.length)}` : p;
|
|
@@ -395,12 +403,14 @@ export function renderFlowResult(result, expanded, theme, args, config) {
|
|
|
395
403
|
type: flowRequest.type || "unknown",
|
|
396
404
|
agentSource: "user",
|
|
397
405
|
intent: flowRequest.intent || "Processing...",
|
|
398
|
-
aim: flowRequest.aim
|
|
406
|
+
aim: flowRequest.aim ?? flowRequest.intent ?? "Processing...",
|
|
399
407
|
acceptance: flowRequest.acceptance,
|
|
400
408
|
exitCode: -1, // In progress
|
|
401
409
|
messages: [],
|
|
402
410
|
stderr: "",
|
|
403
411
|
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0, toolCalls: 0 },
|
|
412
|
+
...(flowRequest.model ? { model: flowRequest.model } : {}),
|
|
413
|
+
...(flowRequest.maxContextTokens !== undefined ? { maxContextTokens: flowRequest.maxContextTokens } : {}),
|
|
404
414
|
};
|
|
405
415
|
const ghostId = resolvedToolCallId || 'ghost';
|
|
406
416
|
if (expanded) {
|
|
@@ -473,140 +483,6 @@ export function renderFlowResult(result, expanded, theme, args, config) {
|
|
|
473
483
|
return container;
|
|
474
484
|
}
|
|
475
485
|
// ---------------------------------------------------------------------------
|
|
476
|
-
// Trace rendering — simplified, no model, inline stats
|
|
477
|
-
// ---------------------------------------------------------------------------
|
|
478
|
-
export function renderTraceCall(_args, _theme, _config) {
|
|
479
|
-
// Trace call frame is invisible — the result frame shows 'trace <aim>'.
|
|
480
|
-
// Returning an empty Container avoids a duplicate 'trace' line.
|
|
481
|
-
return new Container();
|
|
482
|
-
}
|
|
483
|
-
export function renderTraceResult(result, expanded, theme, args, config) {
|
|
484
|
-
const details = result.details;
|
|
485
|
-
const streamingText = result.content?.[0]?.type === "text" ? result.content[0].text : undefined;
|
|
486
|
-
// Resolve id (same pattern as renderFlowResult)
|
|
487
|
-
let resolvedToolCallId;
|
|
488
|
-
if (args?.state) {
|
|
489
|
-
const s = args.state;
|
|
490
|
-
resolvedToolCallId = s.__widgetId;
|
|
491
|
-
if (!resolvedToolCallId) {
|
|
492
|
-
resolvedToolCallId = result._toolCallId || args?.toolCallId || args?.id;
|
|
493
|
-
if (!resolvedToolCallId) {
|
|
494
|
-
resolvedToolCallId = getAnonymousFlowId();
|
|
495
|
-
}
|
|
496
|
-
s.__widgetId = resolvedToolCallId;
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
else {
|
|
500
|
-
resolvedToolCallId = result._toolCallId || args?.toolCallId || args?.id;
|
|
501
|
-
}
|
|
502
|
-
const id = resolvedToolCallId || "trace";
|
|
503
|
-
const now = Date.now();
|
|
504
|
-
let container = new Container();
|
|
505
|
-
// Get the SingleResult
|
|
506
|
-
let r;
|
|
507
|
-
if (details?.results && details.results.length > 0) {
|
|
508
|
-
r = details.results[0];
|
|
509
|
-
}
|
|
510
|
-
const isComplete = r ? isFlowStatusComplete(r) : false;
|
|
511
|
-
// Header line: ● trace · <aim> · <stats>
|
|
512
|
-
const typeName = formatFlowTypeName("trace");
|
|
513
|
-
const aimText = r?.aim || r?.intent || streamingText || "trace";
|
|
514
|
-
const initialDot = r ? flowStatusIcon(r, theme) : theme.fg("success", "●");
|
|
515
|
-
const dotPlaceholder = stripAnsi(initialDot) + " ";
|
|
516
|
-
const statsParts = [];
|
|
517
|
-
if (r) {
|
|
518
|
-
if (r.maxContextTokens !== undefined || r.usage.contextTokens > 0) {
|
|
519
|
-
statsParts.push(formatContextLabel(r.usage.contextTokens, r.maxContextTokens));
|
|
520
|
-
}
|
|
521
|
-
statsParts.push(formatTps(r.usage.smoothedTps));
|
|
522
|
-
}
|
|
523
|
-
const displayStats = statsParts.length > 0 ? " · " + statsParts.join(" · ") : "";
|
|
524
|
-
const statsPlain = stripAnsi(displayStats);
|
|
525
|
-
const headerPlain = `${dotPlaceholder}${typeName}${statsPlain}`;
|
|
526
|
-
const headerSegments = [
|
|
527
|
-
{ text: dotPlaceholder, style: (_s) => (r ? getScintillatingStatusDot(r, theme, Date.now(), id) : initialDot) + " " },
|
|
528
|
-
{ text: typeName, style: (s) => applyRole("flowName", s, theme, config) },
|
|
529
|
-
];
|
|
530
|
-
if (statsPlain) {
|
|
531
|
-
headerSegments.push({ text: displayStats, style: (s) => applyRole("stats", s, theme, config) });
|
|
532
|
-
}
|
|
533
|
-
container.addChild(new DynamicScrambleText(`${initialDot} ${applyRole("flowName", typeName, theme, config)}${applyRole("stats", displayStats, theme, config)}`, () => {
|
|
534
|
-
const now2 = Date.now();
|
|
535
|
-
const result2 = scrambleManager.updateText(id, "header", headerPlain, now2, isComplete, true);
|
|
536
|
-
return reconstructHeader(result2.content, headerSegments);
|
|
537
|
-
}, true));
|
|
538
|
-
// Cmd line: └─ cmd ▸ <last tool call>
|
|
539
|
-
const actTree = "└─";
|
|
540
|
-
const actLabel = ` cmd ▸ `;
|
|
541
|
-
if (r?.messages && r.messages.length > 0) {
|
|
542
|
-
const lastTool = getLastToolCall(r.messages);
|
|
543
|
-
const actStr = lastTool ? formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme)) : "[n/a]";
|
|
544
|
-
const actFullText = stripAnsi(lowerFirstWord(actStr));
|
|
545
|
-
const actInitial = `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole("actContent", italic(actFullText), theme, config)}`;
|
|
546
|
-
container.addChild(new DynamicScrambleText(actInitial, () => {
|
|
547
|
-
const now2 = Date.now();
|
|
548
|
-
const freshAct = lastTool ? formatFlowToolCall(lastTool.name, lastTool.args, theme.fg.bind(theme)) : "[n/a]";
|
|
549
|
-
const freshPlain = stripAnsi(lowerFirstWord(freshAct));
|
|
550
|
-
const result2 = scrambleManager.updateAct(id, freshPlain, now2, isComplete, true);
|
|
551
|
-
const content = result2.content;
|
|
552
|
-
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole("actContent", italic(content), theme, config)}`;
|
|
553
|
-
}, true));
|
|
554
|
-
}
|
|
555
|
-
else {
|
|
556
|
-
// No messages yet — show awaiting
|
|
557
|
-
const actInitial = `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole("prefixLabel", "[awaiting...]", theme, config)}`;
|
|
558
|
-
container.addChild(new DynamicScrambleText(actInitial, () => {
|
|
559
|
-
const now2 = Date.now();
|
|
560
|
-
const plain = "[awaiting...]";
|
|
561
|
-
const result2 = scrambleManager.updateAct(id, plain, now2, isComplete, true);
|
|
562
|
-
const content = result2.content;
|
|
563
|
-
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole((r && isFlowAwaiting(r)) ? "prefixLabel" : "actContent", italic(content), theme, config)}`;
|
|
564
|
-
}, true));
|
|
565
|
-
}
|
|
566
|
-
// Expanded view: add full output
|
|
567
|
-
if (expanded) {
|
|
568
|
-
const flowOutput = streamingText;
|
|
569
|
-
if (flowOutput) {
|
|
570
|
-
container.addChild(new Spacer(1));
|
|
571
|
-
container.addChild(new Markdown(flowOutput, 0, 0, getMarkdownTheme()));
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
// In-place mutation pattern (same as renderFlowResult)
|
|
575
|
-
if (args?.state) {
|
|
576
|
-
const s = args.state;
|
|
577
|
-
if (!s.__rootContainer) {
|
|
578
|
-
if (container instanceof Container) {
|
|
579
|
-
s.__rootContainer = container;
|
|
580
|
-
}
|
|
581
|
-
else {
|
|
582
|
-
const root = new Container();
|
|
583
|
-
root.addChild(container);
|
|
584
|
-
s.__rootContainer = root;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
else if (container !== s.__rootContainer) {
|
|
588
|
-
const root = s.__rootContainer;
|
|
589
|
-
root.clear();
|
|
590
|
-
if (container instanceof Container) {
|
|
591
|
-
const children = [...container.children];
|
|
592
|
-
for (const child of children) {
|
|
593
|
-
root.addChild(child);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
root.addChild(container);
|
|
598
|
-
}
|
|
599
|
-
root.invalidate();
|
|
600
|
-
container = root;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
if (isComplete) {
|
|
604
|
-
scrambleManager.completeFlow(id);
|
|
605
|
-
}
|
|
606
|
-
runScrambleTimer(args, id);
|
|
607
|
-
return container;
|
|
608
|
-
}
|
|
609
|
-
// ---------------------------------------------------------------------------
|
|
610
486
|
// Single flow result
|
|
611
487
|
// ---------------------------------------------------------------------------
|
|
612
488
|
export function renderSingleFlowResult(r, expanded, theme, streamingText, toolCallId, config) {
|
|
@@ -735,16 +611,17 @@ function renderFlowExpanded(r, icon, error, displayItems, flowOutput, theme, id,
|
|
|
735
611
|
}
|
|
736
612
|
// Output: animate streaming text; show clean markdown when complete
|
|
737
613
|
if (isFlowAwaiting(r)) {
|
|
738
|
-
container.addChild(new Text(applyRole("
|
|
614
|
+
container.addChild(new Text(applyRole("placeholder", "[awaiting...]", theme, config), 0, 0));
|
|
739
615
|
}
|
|
740
616
|
else if (!isComplete && streamingText != null) {
|
|
741
617
|
const msgBudget = getTruncationBudget(0);
|
|
742
618
|
const displayMsg = tailText(stripAnsi(streamingText), msgBudget);
|
|
743
|
-
container.addChild(new DynamicScrambleText(displayMsg, () => {
|
|
619
|
+
container.addChild(new DynamicScrambleText(applyRole("msgContent", displayMsg, theme, config), () => {
|
|
744
620
|
const budget = getTruncationBudget(0);
|
|
745
621
|
const freshStreamingText = getLiveTextWithFallback(id) ?? streamingText;
|
|
746
622
|
const text = tailText(stripAnsi(freshStreamingText), budget);
|
|
747
|
-
|
|
623
|
+
const result = scrambleManager.updateMsg(id, text, Date.now(), isComplete, undefined, true);
|
|
624
|
+
return result.isAnimating ? applyRole("msgContent", result.content, theme, config) : applyRole("msgContent", text, theme, config);
|
|
748
625
|
}));
|
|
749
626
|
}
|
|
750
627
|
else if (flowOutput) {
|
|
@@ -798,12 +675,13 @@ function renderFlowCollapsed(r, icon, error, flowOutput, theme, streamingText, t
|
|
|
798
675
|
const ctxLabel = formatContextLabel(r.usage.contextTokens, r.maxContextTokens);
|
|
799
676
|
statsParts.push(ctxLabel);
|
|
800
677
|
}
|
|
801
|
-
const tpsFormatted = formatTps(r.usage.smoothedTps);
|
|
802
|
-
statsParts.push(tpsFormatted);
|
|
803
678
|
let displayStats = statsParts.join(" · ");
|
|
804
|
-
// Flash TPS value when it changes
|
|
805
|
-
const tpsNum = tpsFormatted.slice(0, -4); // remove " t/s" suffix
|
|
806
679
|
if (r.usage.smoothedTps && r.usage.smoothedTps > 0) {
|
|
680
|
+
const tpsFormatted = formatTps(r.usage.smoothedTps);
|
|
681
|
+
statsParts.push(tpsFormatted);
|
|
682
|
+
displayStats = statsParts.join(" · ");
|
|
683
|
+
// Flash TPS value when it changes
|
|
684
|
+
const tpsNum = tpsFormatted.slice(0, -4); // remove " t/s" suffix
|
|
807
685
|
const scrambledTps = scrambleManager.updateTps(id, tpsNum, now, isComplete, true);
|
|
808
686
|
if (scrambledTps !== tpsNum) {
|
|
809
687
|
displayStats = displayStats.replace(`${tpsNum} t/s`, `${scrambledTps} t/s`);
|
|
@@ -833,20 +711,20 @@ function renderFlowCollapsed(r, icon, error, flowOutput, theme, streamingText, t
|
|
|
833
711
|
return reconstructHeader(result.content, headerSegments);
|
|
834
712
|
}, true));
|
|
835
713
|
// aim: line — glitch on text change
|
|
836
|
-
if (r.aim) {
|
|
714
|
+
if (r.aim && r.type !== "trace") {
|
|
837
715
|
const aimTree = "├─";
|
|
838
716
|
const aimLabel = ` aim ▸ `;
|
|
839
717
|
const aimPrefix = `${aimTree}${aimLabel}`;
|
|
840
718
|
const budget = getTruncationBudget(visibleLength(aimPrefix));
|
|
841
719
|
const displayAim = isFlowAwaiting(r) ? "[awaiting...]" : truncateChars(lowerFirstWord(r.aim), budget);
|
|
842
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", aimLabel, theme, config)}${applyRole(
|
|
720
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", aimLabel, theme, config)}${applyRole(getContentRole("aimContent", displayAim), displayAim, theme, config)}`, () => {
|
|
843
721
|
const now = Date.now();
|
|
844
722
|
const freshAimLabel = ` aim ▸ `;
|
|
845
723
|
const freshAimPrefix = `${aimTree}${freshAimLabel}`;
|
|
846
724
|
const freshBudget = getTruncationBudget(visibleLength(freshAimPrefix));
|
|
847
725
|
const freshText = isFlowAwaiting(r) ? "[awaiting...]" : truncateChars(lowerFirstWord(r.aim), freshBudget);
|
|
848
726
|
const result = scrambleManager.updateAim(id, freshText, now, isComplete, true);
|
|
849
|
-
return `${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", freshAimLabel, theme, config)}${applyRole(
|
|
727
|
+
return `${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", freshAimLabel, theme, config)}${applyRole(getContentRole("aimContent", freshText), result.content, theme, config)}`;
|
|
850
728
|
}, true));
|
|
851
729
|
}
|
|
852
730
|
// act: line (last tool call with count)
|
|
@@ -859,14 +737,14 @@ function renderFlowCollapsed(r, icon, error, flowOutput, theme, streamingText, t
|
|
|
859
737
|
const budget = getTruncationBudget(visibleLength(prefixStub));
|
|
860
738
|
const actFullText = stripAnsi(lowerFirstWord(actStr));
|
|
861
739
|
const initialActContent = isFlowAwaiting(r) ? "[n/a]" : (actFullText.length > budget ? tailText(actFullText, budget) : actFullText);
|
|
862
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(
|
|
740
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(getContentRole("actContent", initialActContent), initialActContent, theme, config)}`, () => {
|
|
863
741
|
const now = Date.now();
|
|
864
742
|
const actLabel = ` cmd ▸ `;
|
|
865
743
|
const actPrefix = `${actTree}${actLabel}`;
|
|
866
744
|
const freshBudget = getTruncationBudget(visibleLength(actPrefix));
|
|
867
745
|
const displayAct = isFlowAwaiting(r) ? "[n/a]" : tailText(actFullText, freshBudget);
|
|
868
746
|
const actContent = scrambleManager.updateAct(id, displayAct, now, isComplete, true).content;
|
|
869
|
-
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(
|
|
747
|
+
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(getContentRole("actContent", displayAct), actContent, theme, config)}`;
|
|
870
748
|
}, true));
|
|
871
749
|
// msg: line (last assistant text or streaming) — full mode only
|
|
872
750
|
if (!isLite) {
|
|
@@ -910,7 +788,7 @@ function renderFlowCollapsed(r, icon, error, flowOutput, theme, streamingText, t
|
|
|
910
788
|
const msgTree = "└─";
|
|
911
789
|
const msgLabel = ` msg ▸ `;
|
|
912
790
|
const initialMsgPrefix = `${msgTree}${msgLabel}`;
|
|
913
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(
|
|
791
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(getContentRole("msgContent", initialMsgContent, useError), initialMsgContent, theme, config)}`, () => {
|
|
914
792
|
const now = Date.now();
|
|
915
793
|
const msgLabel = ` msg ▸ `;
|
|
916
794
|
const msgPrefix = `${msgTree}${msgLabel}`;
|
|
@@ -931,7 +809,7 @@ function renderFlowCollapsed(r, icon, error, flowOutput, theme, streamingText, t
|
|
|
931
809
|
}
|
|
932
810
|
const displayMsg = needsTail ? tailText(freshRawMsg, msgBudget) : truncateChars(freshRawMsg, msgBudget);
|
|
933
811
|
const result = scrambleManager.updateMsg(id, displayMsg, now, isComplete, undefined, true);
|
|
934
|
-
return `${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(
|
|
812
|
+
return `${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(getContentRole("msgContent", freshRawMsg, useError), result.content, theme, config)}`;
|
|
935
813
|
}, true));
|
|
936
814
|
}
|
|
937
815
|
if (isComplete) {
|
|
@@ -1003,17 +881,18 @@ function renderMultiFlowExpanded(results, successCount, icon, theme, baseId, now
|
|
|
1003
881
|
}
|
|
1004
882
|
// Output: animate streaming text; show clean markdown when complete
|
|
1005
883
|
if (isFlowAwaiting(r)) {
|
|
1006
|
-
container.addChild(new Text(applyRole("
|
|
884
|
+
container.addChild(new Text(applyRole("placeholder", "[awaiting...]", theme, config), 0, 0));
|
|
1007
885
|
}
|
|
1008
886
|
else if (!isComplete && r.streamingText != null) {
|
|
1009
887
|
const streamingRaw = r.streamingText;
|
|
1010
888
|
const msgBudget = getTruncationBudget(0);
|
|
1011
889
|
const displayMsg = tailText(stripAnsi(streamingRaw), msgBudget);
|
|
1012
|
-
container.addChild(new DynamicScrambleText(displayMsg, () => {
|
|
890
|
+
container.addChild(new DynamicScrambleText(applyRole("msgContent", displayMsg, theme, config), () => {
|
|
1013
891
|
const budget = getTruncationBudget(0);
|
|
1014
892
|
const freshStreamingText = getLiveTextWithFallback(flowId) ?? streamingRaw;
|
|
1015
893
|
const text = tailText(stripAnsi(freshStreamingText), budget);
|
|
1016
|
-
|
|
894
|
+
const result = scrambleManager.updateMsg(flowId, text, Date.now(), isComplete, undefined, true);
|
|
895
|
+
return result.isAnimating ? applyRole("msgContent", result.content, theme, config) : applyRole("msgContent", text, theme, config);
|
|
1017
896
|
}));
|
|
1018
897
|
}
|
|
1019
898
|
else if (flowOutput) {
|
|
@@ -1168,17 +1047,18 @@ function renderFlowHeader(container, r, flowId, headerPrefix, theme, now, config
|
|
|
1168
1047
|
const ctxLabel = formatContextLabel(r.usage.contextTokens, r.maxContextTokens);
|
|
1169
1048
|
statsParts.push(ctxLabel);
|
|
1170
1049
|
}
|
|
1171
|
-
const tpsFormatted = formatTps(r.usage.smoothedTps);
|
|
1172
|
-
statsParts.push(tpsFormatted);
|
|
1173
1050
|
let displayStats = statsParts.join(" · ");
|
|
1174
|
-
const tpsNum = tpsFormatted.slice(0, -4); // remove " t/s" suffix
|
|
1175
1051
|
if (r.usage.smoothedTps && r.usage.smoothedTps > 0) {
|
|
1052
|
+
const tpsFormatted = formatTps(r.usage.smoothedTps);
|
|
1053
|
+
statsParts.push(tpsFormatted);
|
|
1054
|
+
displayStats = statsParts.join(" · ");
|
|
1055
|
+
const tpsNum = tpsFormatted.slice(0, -4); // remove " t/s" suffix
|
|
1176
1056
|
const scrambledTps = scrambleManager.updateTps(flowId, tpsNum, now, flowComplete, true);
|
|
1177
1057
|
if (scrambledTps !== tpsNum) {
|
|
1178
1058
|
displayStats = displayStats.replace(`${tpsNum} t/s`, `${scrambledTps} t/s`);
|
|
1179
1059
|
}
|
|
1180
1060
|
}
|
|
1181
|
-
const modelSegment = modelLabel ? `
|
|
1061
|
+
const modelSegment = modelLabel ? ` ${modelLabel}` : "";
|
|
1182
1062
|
const statsSegment = ` · ${displayStats}`;
|
|
1183
1063
|
const statsPlain = stripAnsi(statsSegment);
|
|
1184
1064
|
headerLine = `${applyRole("treeChars", headerPrefix, theme, config)} ${initialDot} ${applyRole("flowName", typeName, theme, config)}${applyRole("modelName", modelSegment, theme, config)}${applyRole("stats", statsSegment, theme, config)}`;
|
|
@@ -1201,20 +1081,20 @@ function renderFlowBody(container, r, flowId, indent, theme, now, config) {
|
|
|
1201
1081
|
const isComplete = isFlowStatusComplete(r);
|
|
1202
1082
|
const flowComplete = isComplete;
|
|
1203
1083
|
// aim: line — glitch on text change
|
|
1204
|
-
if (r.aim) {
|
|
1084
|
+
if (r.aim && r.type !== "trace") {
|
|
1205
1085
|
const aimTree = indent + "├─";
|
|
1206
1086
|
const aimLabel = ` aim ▸ `;
|
|
1207
1087
|
const aimPrefix = `${aimTree}${aimLabel}`;
|
|
1208
1088
|
const budget = getTruncationBudget(visibleLength(aimPrefix));
|
|
1209
1089
|
const displayAim = isFlowAwaiting(r) ? "[awaiting...]" : truncateChars(lowerFirstWord(r.aim), budget);
|
|
1210
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", aimLabel, theme, config)}${applyRole(
|
|
1090
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", aimLabel, theme, config)}${applyRole(getContentRole("aimContent", displayAim), displayAim, theme, config)}`, () => {
|
|
1211
1091
|
const now = Date.now();
|
|
1212
1092
|
const freshAimLabel = ` aim ▸ `;
|
|
1213
1093
|
const freshAimPrefix = `${aimTree}${freshAimLabel}`;
|
|
1214
1094
|
const freshBudget = getTruncationBudget(visibleLength(freshAimPrefix));
|
|
1215
1095
|
const freshText = isFlowAwaiting(r) ? "[awaiting...]" : truncateChars(lowerFirstWord(r.aim), freshBudget);
|
|
1216
1096
|
const result = scrambleManager.updateAim(flowId, freshText, now, flowComplete, true);
|
|
1217
|
-
return `${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", freshAimLabel, theme, config)}${applyRole(
|
|
1097
|
+
return `${applyRole("treeChars", aimTree, theme, config)}${applyRole("prefixLabel", freshAimLabel, theme, config)}${applyRole(getContentRole("aimContent", freshText), result.content, theme, config)}`;
|
|
1218
1098
|
}, true));
|
|
1219
1099
|
}
|
|
1220
1100
|
// act: line (last tool call with count)
|
|
@@ -1227,14 +1107,14 @@ function renderFlowBody(container, r, flowId, indent, theme, now, config) {
|
|
|
1227
1107
|
const budget = getTruncationBudget(visibleLength(prefixStub));
|
|
1228
1108
|
const actFullText = stripAnsi(lowerFirstWord(actStr));
|
|
1229
1109
|
const initialActContent = isFlowAwaiting(r) ? "[n/a]" : (actFullText.length > budget ? tailText(actFullText, budget) : actFullText);
|
|
1230
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(
|
|
1110
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(getContentRole("actContent", initialActContent), initialActContent, theme, config)}`, () => {
|
|
1231
1111
|
const now = Date.now();
|
|
1232
1112
|
const actLabel = ` cmd ▸ `;
|
|
1233
1113
|
const actPrefix = `${actTree}${actLabel}`;
|
|
1234
1114
|
const freshBudget = getTruncationBudget(visibleLength(actPrefix));
|
|
1235
1115
|
const displayAct = isFlowAwaiting(r) ? "[n/a]" : tailText(actFullText, freshBudget);
|
|
1236
1116
|
const actContent = scrambleManager.updateAct(flowId, displayAct, now, flowComplete, true).content;
|
|
1237
|
-
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(
|
|
1117
|
+
return `${applyRole("treeChars", actTree, theme, config)}${applyRole("prefixLabel", actLabel, theme, config)}${applyRole(getContentRole("actContent", displayAct), actContent, theme, config)}`;
|
|
1238
1118
|
}, true));
|
|
1239
1119
|
// msg: line (live streaming text or last assistant text) — full mode only
|
|
1240
1120
|
if (!isLite) {
|
|
@@ -1255,12 +1135,15 @@ function renderFlowBody(container, r, flowId, indent, theme, now, config) {
|
|
|
1255
1135
|
rawMsg = stripAnsi(r.errorMessage);
|
|
1256
1136
|
useError = true;
|
|
1257
1137
|
}
|
|
1258
|
-
else if (r.pingPongMeta
|
|
1138
|
+
else if ((r.pingPongMeta?.finalVerdict === "pass" || r.structuredOutput?.verdict === "pass") && r.type === "audit") {
|
|
1259
1139
|
rawMsg = "[approved]";
|
|
1260
1140
|
}
|
|
1261
|
-
else {
|
|
1141
|
+
else if (r.type === "audit" && !r.structuredOutput?.summary && !getFlowOutput(r.messages)) {
|
|
1262
1142
|
rawMsg = "[finished]";
|
|
1263
1143
|
}
|
|
1144
|
+
else {
|
|
1145
|
+
rawMsg = stripAnsi(r.structuredOutput?.summary ?? getFlowOutput(r.messages) ?? getFlowSummaryText(r)) || "[n/a]";
|
|
1146
|
+
}
|
|
1264
1147
|
}
|
|
1265
1148
|
else {
|
|
1266
1149
|
const liveMsgText = isFlowRunning(r) ? getLiveTextWithFallback(flowId) : undefined;
|
|
@@ -1290,7 +1173,7 @@ function renderFlowBody(container, r, flowId, indent, theme, now, config) {
|
|
|
1290
1173
|
}
|
|
1291
1174
|
const initialNeedsTail = !isFlowAwaiting(r) && isFlowRunning(r) && (r.streamingText != null || getLiveTextWithFallback(flowId) != null);
|
|
1292
1175
|
const initialDisplayMsg = initialNeedsTail ? tailText(rawMsg, msgBudget) : truncateChars(rawMsg, msgBudget);
|
|
1293
|
-
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(
|
|
1176
|
+
container.addChild(new DynamicScrambleText(`${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(getContentRole("msgContent", initialDisplayMsg, useError), initialDisplayMsg, theme, config)}`, () => {
|
|
1294
1177
|
const now = Date.now();
|
|
1295
1178
|
const msgLabel = ` msg ▸ `;
|
|
1296
1179
|
const msgPrefix = `${msgTree}${msgLabel}`;
|
|
@@ -1311,7 +1194,7 @@ function renderFlowBody(container, r, flowId, indent, theme, now, config) {
|
|
|
1311
1194
|
}
|
|
1312
1195
|
const displayMsg = needsTail ? tailText(freshRawMsg, msgBudget) : truncateChars(freshRawMsg, msgBudget);
|
|
1313
1196
|
const result = scrambleManager.updateMsg(flowId, displayMsg, now, flowComplete, undefined, true);
|
|
1314
|
-
return `${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(
|
|
1197
|
+
return `${applyRole("treeChars", msgTree, theme, config)}${applyRole("prefixLabel", msgLabel, theme, config)}${applyRole(getContentRole("msgContent", freshRawMsg, useError), result.content, theme, config)}`;
|
|
1315
1198
|
}, true));
|
|
1316
1199
|
}
|
|
1317
1200
|
}
|