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 /config | |
| 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.
Diffstat (limited to 'config')
| -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; |
