@pi-kaush/pi-tool-call-markers 0.2.1 → 0.2.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.
- package/CHANGELOG.md +1 -0
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/index.ts +243 -36
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Compact multiline singleton calls into one width-safe summary after settlement, including timeout metadata, while preserving the full native call under Ctrl+O.
|
|
5
6
|
- Compose capped in-progress rows before the Box paints its background, fixing elapsed tails leaking outside the tool background and restoring the block's bottom padding.
|
|
6
7
|
|
|
7
8
|
- Render in-progress calls as a single header line (elapsed time inline for `bash`) that settles into the final summary at the same height, so the transcript flows downwards without jumping.
|
package/README.md
CHANGED
|
@@ -12,9 +12,9 @@ When several tool calls run in a row, Pi normally renders each one as its own ex
|
|
|
12
12
|
- **One-line, width-safe summaries.** Long targets truncate before their useful outcome tail instead of wrapping into taller blocks.
|
|
13
13
|
- **Running calls group immediately.** Adjacent calls become bullets as they appear, and each pending marker or elapsed `bash` time updates to the final outcome in place. Successful settlement does not shrink the block, so the transcript only grows downwards.
|
|
14
14
|
- **Sequential calls merge across quiet turns.** A later call joins the existing group immediately when no visible prose or thinking separates it; visible assistant content remains a hard boundary.
|
|
15
|
-
- **Self-rendered tools
|
|
15
|
+
- **Self-rendered tools get the same treatment.** Tools that own their framing (e.g. MCP adapter rows) collapse to the same one-line summary — args label plus outcome — with pending, success, and error backgrounds; expanding restores their full custom render.
|
|
16
16
|
- **Image results stay visible.** Image-bearing results are not collapsed into text-only groups. Partial text output is held back while a call runs and surfaces through the final summary.
|
|
17
|
-
- **Errors stay compact and visibly failed.** A failed call keeps
|
|
17
|
+
- **Errors stay compact and visibly failed.** A failed call keeps an error-colored block: native collapsed detail for built-in tools, or a one-line summary with the first error line for self-rendered tools.
|
|
18
18
|
- **Ctrl+O restores full blocks.** Expanding tools (`setToolsExpanded(true)`) brings back Pi's individual full blocks, including complete error details and successful results.
|
|
19
19
|
|
|
20
20
|
## Bundled thinking-block extension
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -51,7 +51,11 @@ type ToolExecutionRow = {
|
|
|
51
51
|
content?: Array<{ type?: unknown; text?: unknown }>;
|
|
52
52
|
details?: Record<string, unknown>;
|
|
53
53
|
};
|
|
54
|
-
rendererState?: {
|
|
54
|
+
rendererState?: {
|
|
55
|
+
startedAt?: unknown;
|
|
56
|
+
endedAt?: unknown;
|
|
57
|
+
compactTitle?: unknown;
|
|
58
|
+
};
|
|
55
59
|
contentBox?: ComponentContainer;
|
|
56
60
|
contentText?: TextComponent;
|
|
57
61
|
selfRenderContainer?: ComponentContainer;
|
|
@@ -68,7 +72,6 @@ type PresentationPatchState = {
|
|
|
68
72
|
theme?: ThemeLike;
|
|
69
73
|
collapseParallel: boolean;
|
|
70
74
|
groupCache: WeakMap<ToolExecutionRow, GroupRenderCache>;
|
|
71
|
-
liveRenderedRows: WeakSet<ToolExecutionRow>;
|
|
72
75
|
rowVersions: WeakMap<ToolExecutionRow, number>;
|
|
73
76
|
rowGroups: WeakMap<ToolExecutionRow, ToolExecutionRow[]>;
|
|
74
77
|
rowSignatures: WeakMap<ToolExecutionRow, string>;
|
|
@@ -208,12 +211,20 @@ function collapseSuccessfulResult(
|
|
|
208
211
|
row.expanded !== false ||
|
|
209
212
|
row.isPartial !== false ||
|
|
210
213
|
!row.result ||
|
|
211
|
-
row
|
|
212
|
-
hasImageResult(row) ||
|
|
213
|
-
row.getRenderShell?.() === "self"
|
|
214
|
+
hasImageResult(row)
|
|
214
215
|
)
|
|
215
216
|
return;
|
|
216
217
|
|
|
218
|
+
if (row.getRenderShell?.() === "self") {
|
|
219
|
+
collapseSelfRenderedRow(row, theme);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Default-shell failures keep Pi's native error render, which already
|
|
224
|
+
// applies the error background. rowHasFailed also catches MCP tools that
|
|
225
|
+
// use the default shell (e.g. mcpScript) and report via details.error.
|
|
226
|
+
if (rowHasFailed(row)) return;
|
|
227
|
+
|
|
217
228
|
const collapsed = row.hasRendererDefinition?.()
|
|
218
229
|
? removeResultComponent(row.contentBox)
|
|
219
230
|
: collapseGenericResult(row);
|
|
@@ -223,6 +234,193 @@ function collapseSuccessfulResult(
|
|
|
223
234
|
}
|
|
224
235
|
}
|
|
225
236
|
|
|
237
|
+
// Self-rendered tools (e.g. MCP adapter rows) own their framing, so there is
|
|
238
|
+
// no result component to trim. Swap the whole container for a single summary
|
|
239
|
+
// line in the same style as collapsed default-shell rows. Pi rebuilds the
|
|
240
|
+
// container on every updateDisplay, so this never corrupts expanded renders.
|
|
241
|
+
// Failures collapse too, with the error background and the first error line,
|
|
242
|
+
// since MCP error output tends to be a huge markdown blob.
|
|
243
|
+
function collapseSelfRenderedRow(
|
|
244
|
+
row: ToolExecutionRow,
|
|
245
|
+
theme?: ThemeLike,
|
|
246
|
+
): void {
|
|
247
|
+
const container = row.selfRenderContainer;
|
|
248
|
+
if (!theme || !container || !Array.isArray(container.children)) return;
|
|
249
|
+
|
|
250
|
+
const failed = rowHasFailed(row);
|
|
251
|
+
const tail = failed
|
|
252
|
+
? renderedErrorOutcome(row, theme)
|
|
253
|
+
: (renderedOutcome(row, theme) ?? renderedGenericOutcome(theme));
|
|
254
|
+
const box = new Box(1, 1, (text) =>
|
|
255
|
+
theme.bg(failed ? "toolErrorBg" : "toolSuccessBg", text),
|
|
256
|
+
);
|
|
257
|
+
box.addChild(
|
|
258
|
+
selfRenderedSummaryComponent(row, theme, tail, failed ? 0.5 : 1),
|
|
259
|
+
);
|
|
260
|
+
container.children = [box];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// The MCP adapter reports outcomes in details.error but only promotes
|
|
264
|
+
// tool_error/call_failed to result.isError (see its toolErrorOverride);
|
|
265
|
+
// remaining codes are informational guidance (ambiguous, no_instructions,
|
|
266
|
+
// auth flows, ...). Keep the failure code list here so every presentation
|
|
267
|
+
// decision — singletons and groups — shares one classification.
|
|
268
|
+
const MCP_FAILURE_ERROR_CODES: ReadonlySet<string> = new Set([
|
|
269
|
+
"tool_error",
|
|
270
|
+
"call_failed",
|
|
271
|
+
"tool_not_found",
|
|
272
|
+
"tool_not_found_after_reconnect",
|
|
273
|
+
"connect_failed",
|
|
274
|
+
"not_found",
|
|
275
|
+
"server_not_found",
|
|
276
|
+
"server_disabled",
|
|
277
|
+
"server_backoff",
|
|
278
|
+
"server_not_connected",
|
|
279
|
+
"init_failed",
|
|
280
|
+
"init_timeout",
|
|
281
|
+
"not_initialized",
|
|
282
|
+
"server_unavailable",
|
|
283
|
+
"not_connected",
|
|
284
|
+
"timeout",
|
|
285
|
+
"script_error",
|
|
286
|
+
]);
|
|
287
|
+
|
|
288
|
+
function rowHasFailed(row: ToolExecutionRow): boolean {
|
|
289
|
+
if (row.result?.isError) return true;
|
|
290
|
+
const code = row.result?.details?.error;
|
|
291
|
+
return typeof code === "string" && MCP_FAILURE_ERROR_CODES.has(code);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function renderedErrorOutcome(row: ToolExecutionRow, theme: ThemeLike): string {
|
|
295
|
+
const firstLine =
|
|
296
|
+
resultText(row)
|
|
297
|
+
.split("\n")
|
|
298
|
+
.map((line) => line.trim())
|
|
299
|
+
.find((line) => line.length > 0) ?? "error";
|
|
300
|
+
return `${theme.fg("muted", "→")} ${theme.fg("error", firstLine)}`;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function selfRenderedSummaryComponent(
|
|
304
|
+
row: ToolExecutionRow,
|
|
305
|
+
theme: ThemeLike,
|
|
306
|
+
tail: string,
|
|
307
|
+
maxTailShare = 1,
|
|
308
|
+
): ComponentLike {
|
|
309
|
+
return {
|
|
310
|
+
render(width: number): string[] {
|
|
311
|
+
const budget = Math.max(1, width - BADGE_WIDTH - 2);
|
|
312
|
+
const summary = selfRenderedSummary(row, budget);
|
|
313
|
+
// Long error lines would otherwise evict the call summary entirely;
|
|
314
|
+
// cap the tail's share so the label always survives.
|
|
315
|
+
const cappedTail =
|
|
316
|
+
maxTailShare >= 1
|
|
317
|
+
? tail
|
|
318
|
+
: capFailureTail(tail, Math.floor(budget * maxTailShare), theme);
|
|
319
|
+
return [fitSummaryTail(summary, cappedTail, budget)];
|
|
320
|
+
},
|
|
321
|
+
invalidate() {},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Trim a failure tail to its quota of the budget, counting the appended
|
|
326
|
+
// ellipsis inside the cap, so the call label keeps the leftover columns
|
|
327
|
+
// plus the joining space instead of being truncated to nothing.
|
|
328
|
+
function capFailureTail(tail: string, cap: number, theme: ThemeLike): string {
|
|
329
|
+
const tailWidth = visibleWidth(tail);
|
|
330
|
+
if (tailWidth <= cap) return tail;
|
|
331
|
+
const ellipsis = theme.fg("muted", "…");
|
|
332
|
+
return `${sliceByColumn(tail, 0, Math.max(0, cap - visibleWidth(ellipsis)), true)}${ellipsis}`;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function renderedGenericOutcome(theme: ThemeLike): string {
|
|
336
|
+
return `${theme.fg("muted", "→")} ${theme.fg("success", "done")}`;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// The MCP adapter stashes its call's first line in renderer state before
|
|
340
|
+
// collapsing to an empty component, so prefer it over re-rendering the call.
|
|
341
|
+
function selfRenderedCallTitle(row: ToolExecutionRow): string | undefined {
|
|
342
|
+
const title = row.rendererState?.compactTitle;
|
|
343
|
+
return typeof title === "string" && title.trim().length > 0
|
|
344
|
+
? title.trim()
|
|
345
|
+
: undefined;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// The MCP proxy passes tool arguments as a JSON-encoded string; parse and
|
|
349
|
+
// re-stringify so the summary shows compact JSON instead of escaped quotes.
|
|
350
|
+
function squashJsonish(value: unknown): string {
|
|
351
|
+
if (typeof value === "string") {
|
|
352
|
+
const trimmed = value.trim();
|
|
353
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
354
|
+
try {
|
|
355
|
+
const compact = JSON.stringify(JSON.parse(trimmed));
|
|
356
|
+
return compact === "{}" ? "" : compact;
|
|
357
|
+
} catch {
|
|
358
|
+
return flattenNewlines(trimmed);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return flattenNewlines(value);
|
|
362
|
+
}
|
|
363
|
+
return compactArgs(value);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// String fallbacks still feed the one-line "tool {args}" summary label;
|
|
367
|
+
// normalize embedded line breaks so a multiline argument cannot split it.
|
|
368
|
+
function flattenNewlines(text: string): string {
|
|
369
|
+
return text.replace(/[\r\n]+/g, " ");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Builds a one-line "tool {args}" label from the call arguments. The
|
|
373
|
+
// adapter's own title drops the arguments and its pretty-printed JSON spans
|
|
374
|
+
// many lines, so squash the JSON ourselves to keep the row at one line.
|
|
375
|
+
function selfRenderedCallLabel(row: ToolExecutionRow): string {
|
|
376
|
+
const token = row.toolName ?? "tool";
|
|
377
|
+
const args = row.args;
|
|
378
|
+
// Only the adapter's "mcp" proxy tool uses these action shapes. Build the
|
|
379
|
+
// label from the args: the adapter's own compactTitle drops parameters
|
|
380
|
+
// (limit/offset) and can misname the action, so it is not trusted here.
|
|
381
|
+
if (
|
|
382
|
+
token === "mcp" &&
|
|
383
|
+
args &&
|
|
384
|
+
typeof args === "object" &&
|
|
385
|
+
!Array.isArray(args)
|
|
386
|
+
) {
|
|
387
|
+
const record = args as Record<string, unknown>;
|
|
388
|
+
if (typeof record.tool === "string") {
|
|
389
|
+
const inner = squashJsonish(record.args);
|
|
390
|
+
const target =
|
|
391
|
+
typeof record.server === "string"
|
|
392
|
+
? `${record.tool} @ ${record.server}`
|
|
393
|
+
: record.tool;
|
|
394
|
+
return inner ? `${target} ${inner}` : target;
|
|
395
|
+
}
|
|
396
|
+
for (const key of ["search", "connect", "describe", "action"] as const) {
|
|
397
|
+
const value = record[key];
|
|
398
|
+
if (typeof value !== "string" || value.length === 0) continue;
|
|
399
|
+
const rest: Record<string, unknown> = { ...record };
|
|
400
|
+
delete rest[key];
|
|
401
|
+
let label = key === "action" ? `mcp ${value}` : `mcp ${key} ${value}`;
|
|
402
|
+
if (typeof rest.server === "string") {
|
|
403
|
+
label += ` @ ${rest.server}`;
|
|
404
|
+
delete rest.server;
|
|
405
|
+
}
|
|
406
|
+
const restJson = squashJsonish(rest);
|
|
407
|
+
return restJson ? `${label} ${restJson}` : label;
|
|
408
|
+
}
|
|
409
|
+
if (typeof record.server === "string") return `mcp list ${record.server}`;
|
|
410
|
+
}
|
|
411
|
+
const title = selfRenderedCallTitle(row);
|
|
412
|
+
const json = squashJsonish(args);
|
|
413
|
+
// Proxy actions format nicer in the adapter's own title ("mcp search …");
|
|
414
|
+
// direct tools put only the bare name there, so append the args ourselves.
|
|
415
|
+
if (title && title !== token) return title;
|
|
416
|
+
if (json) return `${token} ${json}`;
|
|
417
|
+
return title ?? token;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function selfRenderedSummary(row: ToolExecutionRow, width: number): string {
|
|
421
|
+
return fitSummary(selfRenderedCallLabel(row), width);
|
|
422
|
+
}
|
|
423
|
+
|
|
226
424
|
function isToolExecutionRow(
|
|
227
425
|
component: unknown,
|
|
228
426
|
): component is ToolExecutionRow & ComponentLike {
|
|
@@ -270,7 +468,6 @@ function isLiveRow(row: ToolExecutionRow): boolean {
|
|
|
270
468
|
return (
|
|
271
469
|
row.expanded === false &&
|
|
272
470
|
(row.isPartial !== false || !row.result) &&
|
|
273
|
-
row.getRenderShell?.() !== "self" &&
|
|
274
471
|
!hasImageResult(row)
|
|
275
472
|
);
|
|
276
473
|
}
|
|
@@ -310,6 +507,18 @@ function fitLiveHeader(
|
|
|
310
507
|
// cap is composed before the Box applies background and padding, so the live
|
|
311
508
|
// line keeps the tool background edge to edge and the block's bottom padding.
|
|
312
509
|
function capLiveRowDisplay(row: ToolExecutionRow, theme?: ThemeLike): void {
|
|
510
|
+
// Pin live self-rendered rows (e.g. MCP calls) to the same one-line summary
|
|
511
|
+
// they settle into, so the block never grows and hops on completion.
|
|
512
|
+
if (row.getRenderShell?.() === "self") {
|
|
513
|
+
const container = row.selfRenderContainer;
|
|
514
|
+
if (!theme || !container || !Array.isArray(container.children)) return;
|
|
515
|
+
const box = new Box(1, 1, (text) => theme.bg("toolPendingBg", text));
|
|
516
|
+
box.addChild(
|
|
517
|
+
selfRenderedSummaryComponent(row, theme, theme.fg("muted", "…")),
|
|
518
|
+
);
|
|
519
|
+
container.children = [box];
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
313
522
|
if (row.hasRendererDefinition?.()) {
|
|
314
523
|
const container = row.contentBox;
|
|
315
524
|
if (!container || !Array.isArray(container.children)) return;
|
|
@@ -353,15 +562,11 @@ function isCollapsibleSuccess(row: ToolExecutionRow): boolean {
|
|
|
353
562
|
row.expanded === false &&
|
|
354
563
|
row.isPartial === false &&
|
|
355
564
|
!!row.result &&
|
|
356
|
-
!row
|
|
565
|
+
!rowHasFailed(row) &&
|
|
357
566
|
!hasImageResult(row)
|
|
358
567
|
);
|
|
359
568
|
}
|
|
360
569
|
|
|
361
|
-
function isSettledToolRow(row: ToolExecutionRow): boolean {
|
|
362
|
-
return row.isPartial === false && !!row.result;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
570
|
function hasToolSiblingInAssistantBatch(
|
|
366
571
|
children: unknown[],
|
|
367
572
|
index: number,
|
|
@@ -390,10 +595,6 @@ function isGroupableToolRow(
|
|
|
390
595
|
state: PresentationPatchState,
|
|
391
596
|
): boolean {
|
|
392
597
|
if (!isLiveRow(row) && !isCollapsibleSuccess(row)) return false;
|
|
393
|
-
// Self-rendered tools can change height while active. Keep live instances
|
|
394
|
-
// individual so settling never collapses an already-painted preview.
|
|
395
|
-
if (row.getRenderShell?.() === "self" && state.liveRenderedRows.has(row))
|
|
396
|
-
return false;
|
|
397
598
|
return (
|
|
398
599
|
state.collapseParallel ||
|
|
399
600
|
!hasToolSiblingInAssistantBatch(children, index, renderAt)
|
|
@@ -532,9 +733,14 @@ function renderedGroupedOutcome(
|
|
|
532
733
|
): string | undefined {
|
|
533
734
|
const outcome = renderedOutcome(row, theme);
|
|
534
735
|
if (outcome) return outcome;
|
|
535
|
-
if (
|
|
536
|
-
|
|
537
|
-
|
|
736
|
+
if (isLiveRow(row)) {
|
|
737
|
+
const elapsed = liveElapsedText(row);
|
|
738
|
+
return theme.fg("muted", elapsed ? `· ${elapsed}` : "…");
|
|
739
|
+
}
|
|
740
|
+
// Self-rendered tools have no per-tool outcome summary; keep the group's
|
|
741
|
+
// settled tail consistent with collapsed singletons.
|
|
742
|
+
if (row.getRenderShell?.() === "self") return renderedGenericOutcome(theme);
|
|
743
|
+
return undefined;
|
|
538
744
|
}
|
|
539
745
|
|
|
540
746
|
function truncatePlain(text: string, width: number, suffix = "…"): string {
|
|
@@ -574,17 +780,17 @@ function decorateSuccessfulCall(
|
|
|
574
780
|
row.contentBox.children[0] = {
|
|
575
781
|
render(width: number): string[] {
|
|
576
782
|
const lines = original.render(width);
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
const line = lines[lineIndex];
|
|
783
|
+
const visibleLines = lines.filter(hasVisibleContent);
|
|
784
|
+
const line = visibleLines[0];
|
|
580
785
|
if (line === undefined) return lines;
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
786
|
+
|
|
787
|
+
const rendered = visibleLines.slice(0, 3).map(trimRenderedLine);
|
|
788
|
+
if (visibleLines.length > rendered.length)
|
|
789
|
+
rendered.push(theme.fg("muted", "…"));
|
|
790
|
+
const summary = rendered.join(theme.fg("muted", " · "));
|
|
791
|
+
return [
|
|
792
|
+
fitSummaryTail(summary, outcome, Math.max(1, width - BADGE_WIDTH)),
|
|
793
|
+
];
|
|
588
794
|
},
|
|
589
795
|
invalidate() {
|
|
590
796
|
original.invalidate();
|
|
@@ -620,17 +826,20 @@ function renderedCallSummary(
|
|
|
620
826
|
width: number,
|
|
621
827
|
theme: ThemeLike,
|
|
622
828
|
): string {
|
|
829
|
+
// Self-rendered call components change shape across the live/settled
|
|
830
|
+
// boundary (the adapter's call disappears once settled), so always build
|
|
831
|
+
// the summary from the stable args label instead of scraping the preview.
|
|
832
|
+
if (row.getRenderShell?.() === "self") return selfRenderedSummary(row, width);
|
|
833
|
+
|
|
623
834
|
let component = row.callRendererComponent;
|
|
624
835
|
if (!component && Array.isArray(row.contentBox?.children)) {
|
|
625
836
|
component = row.contentBox.children[0] as ComponentLike | undefined;
|
|
626
837
|
}
|
|
627
|
-
|
|
628
|
-
const selfRendered = row.getRenderShell?.() === "self";
|
|
629
838
|
if (component && typeof component.render === "function") {
|
|
630
839
|
const visibleLines = component
|
|
631
840
|
.render(Math.max(1, width))
|
|
632
841
|
.filter(hasVisibleContent);
|
|
633
|
-
const rendered = visibleLines.slice(0,
|
|
842
|
+
const rendered = visibleLines.slice(0, 3);
|
|
634
843
|
const line = rendered[0];
|
|
635
844
|
if (line) {
|
|
636
845
|
const first = trimRenderedLine(line);
|
|
@@ -666,8 +875,6 @@ function renderedCallSummary(
|
|
|
666
875
|
}
|
|
667
876
|
}
|
|
668
877
|
|
|
669
|
-
if (selfRendered) return theme.fg("muted", "(details omitted)");
|
|
670
|
-
|
|
671
878
|
const fallback = compactArgs(row.args);
|
|
672
879
|
return fallback
|
|
673
880
|
? theme.fg("accent", fallback)
|
|
@@ -820,7 +1027,9 @@ function renderGroupedToolRows(
|
|
|
820
1027
|
width,
|
|
821
1028
|
theme,
|
|
822
1029
|
);
|
|
823
|
-
const box = new Box(1, 1, (text) =>
|
|
1030
|
+
const box = new Box(1, 1, (text) =>
|
|
1031
|
+
theme.bg(hasLiveMembers ? "toolPendingBg" : "toolSuccessBg", text),
|
|
1032
|
+
);
|
|
824
1033
|
box.addChild(summary);
|
|
825
1034
|
lines = renderWithTemporaryChild(container, box, () =>
|
|
826
1035
|
state.originalRender.call(row, width),
|
|
@@ -1018,7 +1227,6 @@ function installPresentationPatch(): PresentationPatchState | undefined {
|
|
|
1018
1227
|
const state: PresentationPatchState = {
|
|
1019
1228
|
collapseParallel: envEnabled(COLLAPSE_PARALLEL_ENV, true),
|
|
1020
1229
|
groupCache: new WeakMap(),
|
|
1021
|
-
liveRenderedRows: new WeakSet(),
|
|
1022
1230
|
rowVersions: new WeakMap(),
|
|
1023
1231
|
rowGroups: new WeakMap(),
|
|
1024
1232
|
rowSignatures: new WeakMap(),
|
|
@@ -1052,7 +1260,6 @@ function installPresentationPatch(): PresentationPatchState | undefined {
|
|
|
1052
1260
|
this: ToolExecutionRow,
|
|
1053
1261
|
width: number,
|
|
1054
1262
|
): string[] {
|
|
1055
|
-
if (!isSettledToolRow(this)) state.liveRenderedRows.add(this);
|
|
1056
1263
|
const lines = state.originalRender.call(this, width);
|
|
1057
1264
|
try {
|
|
1058
1265
|
return decorateHeader(this, lines, width, state.theme);
|