Files
my-pi/pi-overflow/README.md
T
云服务部-叶林立andDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 2a6bf8c929 feat(pi-overflow): 新增统一的新工具结果展示截断扩展
此前截断分散在多层且互相冲突:Pi bash 保留尾部 50KB,RTK 兜底截断又只留
开头 12000 字符(砍掉报错与完整输出路径),pi-chrome 截开头 30K,web_fetch
各 provider 不一致。新扩展统一负责"新结果给模型看多少":
- capture.ts 最先加载暂存原文,index.ts 最后加载(system-prompt 之前)
- 超过 24K 字符时原文落盘 <agentDir>/my-pi/pi-overflow/(700/600、原子写),
  优先取 bash fullOutputPath 完整文件;模型看到 头 + 中段信号行 + 尾 的有界
  视图,行号基于落盘原文、结尾永远可见
- overflow_query:按 id 正则搜索、行区间、jsonPath 只读查询,id 校验防穿越
- 收编:RTK truncate 默认关闭、删除 pi-chrome truncateText、web_fetch 默认
  每页 20000(上限 100000)、web_search max_results 限定 1–20
- pi-compaction 遮蔽带 details.overflow.id 的结果时在占位符提示 overflow_query
- 登记 tools.jsonc / routing / 权限 allow / tool-search 常驻与分组

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-21 20:25:44 -07:00

3.0 KiB

pi-overflow

Bounded display for oversized tool results. When a tool result exceeds thresholdChars, pi-overflow persists the full original to disk and shows the model a deterministic view — head lines, signal lines (error/fail/warn/…), and tail lines — plus an overflow_query tool to search or read the stored original by id.

Two-stage load order

  • capture.ts — first in pi.extensions. A tool_result handler that never modifies anything; it stashes the untouched original text in globalThis[Symbol.for("my-pi.pi-overflow.stash.v1")] (capacity 64) so the bound stage can still reach the pre-RTK original.
  • index.ts — last content extension, right before system-prompt.ts. Its tool_result handler sees the final text after every other handler (RTK semantic compaction included) has run, then:
    • resolves the original: details.fullOutputPath file (streamed, capped at maxEntryBytes head+tail) → stashed raw text → current text;
    • if the current text still exceeds thresholdChars, replaces it with the bounded view built from the stored file — line numbers and totals in the view are exactly what overflow_query will read, even when RTK or bash already cut the in-context text (file sources are scanned line-by-line in a stream, never held in memory);
    • if the current text fits but the original did not (an earlier extension already cut it), keeps the text and appends a one-line [pi-overflow id=…] recovery marker;
    • preserves image parts and structuredContent, and merges details.overflow = { id, totalLines, totalBytes, truncated } into the existing details.
  • Exempt tools (read, edit, write, overflow_query, ask_user_question) and nested calls (parentToolCallId) are never touched.

Stored originals

<agentDir>/my-pi/pi-overflow/<id>.txt + <id>.json metadata, where id = sha1(sessionId + "\0" + toolCallId)[0:12]. Directories are 0700, files 0600, writes are atomic. session_start cleans entries older than retentionDays and evicts oldest-first past maxStoreBytes.

overflow_query

  • id (required, ^[0-9a-f]{12}$ — path traversal safe)
  • search — case-insensitive regex; hits come back with context lines and adjacent hits merge; capped by maxResults
  • lines: { start, end } — 1-based inclusive line range
  • jsonPath — dot/bracket path into stored JSON (a.b[3].c)
  • No selector → metadata + first-screen view. Output is always bounded by thresholdChars and reports whether it was truncated.

Configuration

config/pi-overflow.json inside the installed bundle. Every field is validated independently and falls back to its default; an uncompilable signalPattern falls back to the default pattern (case-insensitive).

Development

npm test        # node --test test/*.test.ts
npm run check   # strip-types syntax check + tests

Tests inject a temporary store root — they never write to a real agent directory.