diff options
| author | Igor Soarez <igor@soarez.org> | 2026-11-06 13:58:14 +0200 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-11-06 13:58:14 +0200 |
| commit | 3cfe984ab7e26aaad4a2442501526b6a2f232bc0 (patch) | |
| tree | 2fa210e3631a955d4f51a72adb7b06498bada917 | |
| parent | 6c96aca6839ce75e380321bb861452bc987e06c3 (diff) | |
pi forum: fold long messages in the transcript, whole on expand
A message of up to 4000 characters printed in full in both panes; show
its first 10 lines, or 1000 characters, and how much more there is,
as pi does for tool output. The model still gets the whole text.
| -rw-r--r-- | config/pi/extensions/forum.ts | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/config/pi/extensions/forum.ts b/config/pi/extensions/forum.ts index 010e1b8..05d5edc 100644 --- a/config/pi/extensions/forum.ts +++ b/config/pi/extensions/forum.ts @@ -84,7 +84,7 @@ import net from "node:net"; import { homedir } from "node:os"; import { join } from "node:path"; import { StringEnum } from "@earendil-works/pi-ai"; -import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent"; +import { type ExtensionAPI, type ExtensionContext, keyHint } from "@earendil-works/pi-coding-agent"; import { Box, Text } from "@earendil-works/pi-tui"; import { type Static, Type } from "typebox"; @@ -98,6 +98,9 @@ const MAX_PIN = 200; const READ_DEFAULT = 20; const READ_MAX = 50; const READ_MAX_CHARS = 30_000; +// A message folded in the transcript: at most this many lines, or characters. +const FOLD_LINES = 10; +const FOLD_CHARS = 1000; const TICK_MS = 2000; const LABEL_EVERY_MS = 15_000; const REQUEST_TIMEOUT_MS = 3000; @@ -329,6 +332,20 @@ function clip(s: string, n: number): string { const who = (s: Sender) => `${s.label} [${s.id}]`; +// A message for the transcript: whole when expanded, otherwise its first +// FOLD_LINES lines (FOLD_CHARS at most, for one long line) and how much more +// there is. Display only: the model always has the whole text. +function fold(text: string, expanded: boolean): string { + if (expanded) return text; + let shown = text.split("\n").slice(0, FOLD_LINES).join("\n"); + if (shown.length > FOLD_CHARS) shown = shown.slice(0, FOLD_CHARS); + if (shown.length === text.length) return text; + const rest = text.slice(shown.length); + const lines = rest.split("\n").length - (rest.startsWith("\n") ? 1 : 0); + const more = lines > 1 ? `${lines} more lines` : `${rest.length} more characters`; + return `${shown}…\n(${more}, ${keyHint("app.tools.expand", "to expand")})`; +} + // --- labels ---------------------------------------------------------------- function run(cmd: string, args: string[]): Promise<string | undefined> { @@ -1050,13 +1067,18 @@ export default function (pi: ExtensionAPI) { return { content: [{ type: "text", text }], details: undefined }; }, - renderCall(args, theme) { + renderCall(args, theme, context) { let head = theme.fg("toolTitle", theme.bold("forum ")) + theme.fg("muted", args.action); if (args.forum) head += ` ${theme.fg("accent", args.forum)}`; if (args.to) head += ` ${theme.fg("accent", `→ ${args.to}`)}`; if (args.mention?.length) head += ` ${theme.fg("accent", args.mention.map((m: string) => `@${m}`).join(" "))}`; if (args.from !== undefined) head += theme.fg("dim", ` from #${args.from}`); - const body = args.text && args.action !== "pin" ? `\n${args.text}` : args.text ? ` ${theme.fg("dim", `"${args.text}"`)}` : ""; + const body = + args.text && args.action !== "pin" + ? `\n${fold(args.text, context.expanded)}` + : args.text + ? ` ${theme.fg("dim", `"${args.text}"`)}` + : ""; return new Text(head + body, 0, 0); }, }); @@ -1196,7 +1218,7 @@ export default function (pi: ExtensionAPI) { : `Forum · ${d.forumName} #${d.postNo} · ${d.all ? "@all" : "@you"} from ${who(d.from)}` : "Forum message"; const sub = theme.fg("dim", " another agent, not typed by you"); - const body = expanded || !d ? String(message.content) : d.text; + const body = expanded || !d ? String(message.content) : fold(d.text, false); const box = new Box(outputPad, 1, (t) => theme.bg("customMessageBg", t)); box.addChild(new Text(`${theme.fg("warning", theme.bold(head))}${sub}\n${body}`, 0, 0)); return box; |
