Skip to content

feat(user-input-fold): 超长用户输入在 transcript 里折叠显示 - #42

Merged
tt-a1i merged 5 commits into
mainfrom
user-input-fold
Aug 22, 2026
Merged

feat(user-input-fold): 超长用户输入在 transcript 里折叠显示#42
tt-a1i merged 5 commits into
mainfrom
user-input-fold

Conversation

@tt-a1i

@tt-a1i tt-a1i commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Closes #40

用户粘贴几百行日志/堆栈/整个文件发送后,pi 把它作为普通用户消息全文渲染,直接刷掉好几屏。而工具输出、子代理结果在本包里都早有折叠,用户消息是唯一没有折叠机制的 transcript 内容——偏偏它可能是最长的。

机制:registerMarkdownTransformer,display-only

pi 的这个 hook 文档明确写了「the original message remains unchanged in the session and model context」。所以:折叠只改 TUI 显示,session 文件和模型上下文里永远是完整原文。这是本 PR 的红线,写进了模块头,并有纯函数测试保证 foldUserMessage 不修改输入。

顺带确认:copy-all 读的是 sessionManager.getBranch()(session 真相源),不受折叠影响,复制出去的仍是完整原文。

折叠规则

  • 触发:> 20 行 或 > 1,200 字符
  • 预览:散文保留 12 行(另有 1,200 字符预算);每个 ``` 代码块保留「开栏 + 语言标记 + 前 4 行 + + 闭栏」——整块折叠,绝不在行中间切,fence 始终闭合
  • 最小收益门槛:只有当折叠能隐藏 ≥ 8 行时才折。少于 8 行就原样渲染
  • marker… folded N lines · full content was sent to the model —— 措辞必须让用户知道模型收到的是完整内容,否则会以为被截断而重复粘贴

那条最小收益门槛是 review 时实测发现的:openpi 自己注入的 /openpi-setup 提示(16 行、因一条极长的 guidance 行而超字符阈值)原本只折掉 4 行,净省 3 行屏幕,代价却是隐藏了 Agent role models / Intercom 这两行用户本来要读的配置摘要。而且字符触发的折叠对「行少但行长」的消息几乎没有屏幕收益——剩下的长行照样换行占多行。折叠必须自己挣回成本。

实测

500 行日志 → 13 行;300 行代码块 → 保留块头 4 行且 fence 闭合(实测 ``` 计数为偶数);setup 提示 → 原样保留

边界与兜底

覆盖并测试:阈值上下各一(19 行隐藏 7 行 → 不折;20 行隐藏 8 行 → 折)、单个巨型代码块、多代码块夹散文、CRLF、结尾换行、阈值下含代码块、空/纯空白、未闭合 fence(保守按文本折)、纯函数性、短消息逐字节一致。transformer 外层有 try/catch——折叠出 bug 也只是退回原文,绝不弄坏渲染。

验证

  • bun run test758 + 29 全绿(基线 739 + 29,新增 19 个测试)
  • bun run check 退出 0(仅剩 file-search/binaries.ts 既存 warning)

tt-a1i added 5 commits August 21, 2026 01:09
Register a display-only markdown transformer that folds finalized user
messages over 20 lines or 1,200 characters into a short preview (12 prose
lines, first 4 content lines per fenced code block) plus a marker stating
how many lines were folded and that the full content was still sent to the
model. The session and model context keep the original message untouched.

Closes #40.
… itself

A char-triggered fold on a message with few but very long lines (e.g. the
/openpi-setup prompt) hid only a handful of lines while saving almost no
screen rows, because the remaining long lines still wrap. Gate folding on
hiding at least 8 lines; below that the message renders byte-identical in
full. Thresholds, preview budgets, marker wording, and the display-only
contract are unchanged.

Refs #40.
@tt-a1i

tt-a1i commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

合并前补充审查:原实现对每个 fenced code block 单独应用预览上限,大量短代码块会绕过折叠预算,极端情况下折叠后反而比原文更长。现已改为所有 prose/code block 共享 20 行全局预览预算,并补充多块与 700 行压力回归。当前分支验证:783 Node tests + 30 Vitest;bun run check 通过。最新 Node 22/24 CI 全绿。

@tt-a1i
tt-a1i merged commit 2b35548 into main Aug 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

超长用户输入发送后全文展开刷屏,应折叠显示(display-only)

1 participant