Skip to content

fix(pi): 修复长首轮 prompt 投递 - #564

Merged
deepcoldy merged 2 commits into
deepcoldy:masterfrom
Justin1989:wt/claude-botmux-pi-prompt
Jul 23, 2026
Merged

fix(pi): 修复长首轮 prompt 投递#564
deepcoldy merged 2 commits into
deepcoldy:masterfrom
Justin1989:wt/claude-botmux-pi-prompt

Conversation

@Justin1989

Copy link
Copy Markdown

改动

  • Pi 首轮长 prompt 超过 4096 bytes 时不再回退到 TUI paste,而是写入 session 数据目录下的 UTF-8 prompt 文件,并以 @/path/to/*.prompt.md positional 参数启动 Pi。
  • 保留短 prompt 直接作为 positional message 的行为;长 prompt 缺少 SESSION_DATA_DIR 时 fail closed,避免退回 paste 导致上下文刷屏。
  • worker 在 buildArgs() 前执行 adapter 级首轮 prompt 预处理,并把 prompt 文件目录加入 Linux sandbox readonly roots;session 清理时 best-effort 删除生成文件。
  • 在 botmux routing/system prompt 中补充隐藏运行上下文防线:静默读取 XML/配置块,不回复/确认/记录,只处理 <user_message>
  • 增加 focused 回归测试覆盖 Pi @file 投递、adapter args、no TUI queue fallback、短 prompt 行为和 routing 防御文案。

为什么

Pi TUI 在长多行首轮 prompt 通过 paste + Enter 投递时会把 botmux 启动上下文拆成多轮 user message,模型会把 botmux_routingidentity、builtin skills 等隐藏上下文碎片误判为真实请求并连续回复“已了解/已补充”。Pi 支持 pi [options] [@files...] [messages...],因此长 prompt 用 @file 可以保持单个完整初始 user turn。

影响面

  • 主要影响 Pi adapter 和 worker 首轮启动参数构造。
  • 短 prompt 行为保持不变;其它 CLI 未接入新的 prepareInitialPromptArg hook,启动方式不变。
  • Linux sandbox 下新增只读暴露 Pi prompt 文件目录,避免 .botmux 隐藏策略遮住 @file
  • prompt 防御同时影响 inline routing 和 injectsSessionContext CLIs 的 system prompt 文案,只增加“隐藏上下文静默遵守”约束。

验证

  • pnpm vitest run --project unit test/pi-initial-prompt.test.ts test/startup-commands.test.ts test/prompt-builder.test.ts:69 passed
  • pnpm build:通过
  • 已执行 pnpm switch:here && pnpm daemon:restart,用当前 checkout 部署 live daemon 后在飞书 @pi 做长 prompt 回归验证:Pi 返回唯一 marker pi-long-prompt-single-turn-ok-20260723,未出现“已了解/已补充”等隐藏上下文确认噪音。
  • 检查 Pi session jsonl:user_turn_count = 1,首轮 user turn 约 38863 bytes,包含完整 prompt;没有单独以 - botmux-* / <identity> / <routing_rules> 开头的碎片 user turn。

备注

  • 完整 pnpm test 在当前 macOS 环境仍有与本改动无关的既有/环境型失败(例如部分测试里 rmSync 对目录、git clone hardlink、端口竞争、v3 distillation 环境凭据隔离测试)。本 PR 相关 focused 回归和 build 均已通过。
  • live daemon / 全局 shim 当前曾为验证切到本 checkout;合并/测试结束后需切回 canonical checkout。

🤖 Generated with Claude Code

@Justin1989
Justin1989 requested a review from deepcoldy as a code owner July 23, 2026 02:04
长首轮 prompt 改用 @file positional 参数传给 Pi,避免 TUI paste 拆成多轮 user message。

同时补充隐藏运行上下文防线与 focused 回归测试。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Justin1989
Justin1989 force-pushed the wt/claude-botmux-pi-prompt branch from 02950e8 to efd8d85 Compare July 23, 2026 02:13

Copy link
Copy Markdown
Owner

已修复独立复核发现的两个阻塞项,提交:0870ef26

修复摘要

  1. 首轮 prompt 读隔离

    • 存储改为 pi-initial-prompts/<sessionId>/initial.prompt.md,沙箱只挂当前 session 子目录。
    • macOS Seatbelt / Linux bwrap 都先 deny/mask 共享 pi-initial-prompts 根,再仅 carve out 当前 session 目录。
    • prompt 文件仍为 0600,session 目录为 0700;结束时先删文件,再非递归清理 session 目录。
  2. startupCommands / durable cold-start 不再退回 TUI 长文本粘贴

    • 长 prompt 的 defer 路径改为向 Pi TUI 发送一次性短命令 /botmux-initial-prompt
    • 该命令由 session-scoped Pi extension 从 worker 固定注入的文件路径读取全文,并通过 Pi 原生 sendUserMessage() 作为单个 user turn 提交;路径不接受用户参数。
    • 队列保留原始 prompt 作为 logicalContent,用于 transcript bridge 指纹、错误提示与崩溃重放;实际 PTY 只收到短命令。
    • extension 参数、环境变量、只读根和 prompt 文件在 owned restart(preservePending)期间保留,最终结束时清理。

验证

  • 相关回归:115/115 通过。
  • 完整 unit suite:TZ=Asia/Shanghai pnpm test,9983/9983 通过。
  • pnpm build 通过(含 public-domain audit / dist audit)。
  • git diff --check 通过。
  • 默认宿主时区下仅有仓库已有的 3 个 scheduler 本地时区断言失败;固定为测试约定时区后全绿,与本改动无关。

代码已推送到 PR head 分支;未合码。

deepcoldy commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Pi 独立三审与合并结果(head 0870ef26

结论:可合码,无阻塞项。PR 已合并。

Pi 0.80.6 以干净、只读、无扩展/技能/上下文文件模式独立复核了 origin/master...0870ef26,重点确认:

  • 每 session 独立 prompt 子目录,以及 session ID 路径安全;
  • macOS Seatbelt / Linux bwrap 对共享根 deny、仅对当前 session carveout;
  • startupCommands / durable cold-start defer 分支通过 extension + sendUserMessage 单轮投递,不回退到 TUI paste;
  • extension/env 注入边界、0o700/0o600 权限与 env 一次性消费;
  • preservePending restart/cleanup 语义;
  • logicalContent 的 bridge 指纹、crash replay 与禁止 queue merge。

非阻塞观察:尚缺真实 Seatbelt/bwrap 端到端、preservePending=true replay、isIdle()=false follow-up、owned restart 状态保留等专项测试;module-level extension/env 状态若未来出现“同会话后续 spawn 配置发生变化”需要主动清空;macOS 父目录 traverse 与 cleanup 数组去重可后续加强。以上在当前 worker 生命周期和现有测试覆盖下不构成合码阻塞。

此前验证仍有效:相关测试 459/459、完整测试 9983/9983、tsc --noEmit / build / audits / diff check 均通过;合并前工作树干净,PR head 未变化。

合并记录

  • 合并方式:merge commit(与仓库近期 PR 惯例一致)
  • 合并提交:cb556211c7aee3c2de5f5bc8717db930fb04d3d0
  • GitHub 确认:merged: true,PR 状态 MERGED
  • 合并时间:2026-07-23 09:31:41 UTC
  • 未删除贡献者分支

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.

2 participants