Skip to content

feat: acp_delegate 工具块紧凑化 + 输出预览 + 停滞警告(#3047 核心美化) - #3096

Merged
ranxianglei merged 4 commits into
masterfrom
2026-10-14_pi-subagents-beautify
Oct 14, 2026
Merged

ranxianglei merged 4 commits into
masterfrom
2026-10-14_pi-subagents-beautify

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Closes #3047

做了什么

issue 附加的 tintinweb fork(pi-subagents-fork 0.19.0-fork.6)是另一个第三方包的本地魔改版,不能整体移植;本 PR 按 issue 里定下的「核心美化」范围,把其中样式相关的四个点移植到本仓 pi-subagents/:

  1. 紧凑工具块:acp_delegate / acp_delegate_wait / acp_delegate_cancel 三个工具加 renderShell:"self" + renderCall/renderResult。调用行一行显示 ▸ 代理名 任务首行(resume 调用用 ↻ 标记);结果行显示状态图标(✓/✗/◼)、退出码、耗时、最多 3 行输出预览,Ctrl+O 展开到 40 行。
  2. 屏幕专属预览:预览只存在于渲染层和有界的工具结果 details(≤4KB、按行边界截断);模型可见的 content 文本零改动(仍是任务标题 + 结果文件路径)。
  3. 停滞警告:fleet widget 中运行中的子进程静默 ≥2 分钟(默认 idle watchdog 5 分钟杀进程之前)追加 ⚠ no activity Nm。
  4. 路由指引:promptGuidelines 增加两条——按任务类型路由到对应角色;子代理做过的探索直接读其结果文件,不要重跑。

渲染器对坏输入一律回退纯文本、绝不抛异常(宿主侧本身也有 try/catch 兜底)。

Behavior changes (old → new)

项 旧 新 原因
TUI 中三个 delegate 工具的呈现 宿主默认工具壳(完整参数 + 全文结果) 紧凑自渲染块;pi-coding-agent < 0.62 的宿主忽略新字段自动回退默认渲染,0.62–0.67.3 之间用默认壳承载自定义内容 issue 要求的核心美化
完成时屏幕可见信息 无输出预览(只有文件路径) 最多 3 行预览(Ctrl+O 展开 40 行),持久化 details ≤4KB 减少「开面板才知道跑了啥」的往返
fleet widget 运行行 ● agent (Ns) — task 静默 ≥2min 追加 ⚠ no activity Nm 在 watchdog 杀进程前暴露卡死
system prompt(promptGuidelines) N 条 N+2 条(约 +2 行 token) 委派路由质量

模型上下文不受影响:content 文本逐字节不变;新增 details 仅进会话 JSONL(有界)。

Config surface

不涉及——未新增/改名/改语义任何配置字段、env var 或 CLI flag。

Tests

  • 新增 tests/delegate-render.test.ts(19 个用例):preview 截断边界(4096 精确值 / 换行边界 / 无换行)、exitLabel 迁移后行为、makeResultMeta 终态/非终态、各状态渲染形状、坏输入回退、三工具接线、widget 停滞标记。
  • npm --prefix pi-subagents test:246 pass / 0 fail(含全部既有用例,确认模型可见文本格式逐字节保持)。
  • npx tsc --noEmit(pi-subagents)干净;npm run build 后 dist 外部 import 仍只有 node builtins + @earendil-works/pi-coding-agent(pi-tui 内联,零运行时依赖契约保持)。
  • 全量 bili 套件与 e2e 交给远程 CI 把关。

Version

pi-subagents/package.json 0.1.5 → 0.2.0(Pi-Subagents Boundary CI 强制:src/** 变更必须 bump)。根 package.json 版本未动。

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-10-14_pi-subagents-beautify (c241593)

Option A — Install this exact build (recommended)

npm install -g billion-context@0.0.3652-pr.3096.76691af

This exact version is immutable and reproducible. The rolling pr tag tracks the newest test build across all PRs.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr3096.tgz
npm install -g package

Install instructions are refreshed on each push.

…tall warning

Tier-1 beautification for #3047 (reference: tintinweb pi-subagents fork 0.19.0-fork.6):

- New delegate-render module: renderShell:'self' + renderCall/renderResult on
  acp_delegate / acp_delegate_wait / acp_delegate_cancel. The call line shows
  agent + first task line (resume calls marked); the result line shows a status
  icon, exit label, duration and up to 3 preview lines of run output (Ctrl+O
  expands to 40). Renderers fall back to plain text on bad input, never throw.
- Previews live only in bounded tool-result details (<=4KB, cut on a newline
  boundary) and the rendered screen. Model-facing content text is unchanged:
  task title + result file path.
- Fleet widget rows append a stall warning when a running child has been
  silent for 2+ minutes (before the idle watchdog kills it).
- promptGuidelines gain two routing entries (route by task kind; read the
  child's result file instead of re-running its exploration).
- exitLabel moved to delegate-render.ts and re-exported from delegate-tool.js
  (public surface preserved).
- Hosts < pi-coding-agent 0.62 ignore the renderer fields (< 0.67.3 ignore
  renderShell) and keep default tool output; no version floor added.

pi-subagents 0.1.5 -> 0.2.0 (CI-enforced for src changes).
@ranxianglei
ranxianglei force-pushed the 2026-10-14_pi-subagents-beautify branch from 39d9e82 to 0d0e608 Compare October 14, 2026 02:00
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

按本仓规范独立审核了这个 PR(我自己的 agent PR,带 ework-agent-pr 标记 → 不重做,只核对代码 + 修掉合并阻塞 + 报结论)。核心判定:可合 —— 本地 typecheck / build / 组件全套测试 / 零运行时依赖契约全绿;唯一阻塞是分支落后 master 造成的合并冲突,我已 rebase 到当前 master 并推回,现在 mergeable=true,等远程 CI 在新 head 上跑绿即可。

我做了什么(透明披露):把 PR 分支 rebase 到当前 master(8bcdb7f61)。它与 #2913 在同一批 wait/cancel 函数上有重叠——#2913 把 _pi 改名成 pi 并加了 emitInlineUsageNote(...) 调用,本 PR 在同样位置加了渲染钩子。取并集:两边都保留(无 _pi 残留、5 处 emitInlineUsageNote 全在、三个渲染钩子全在),版本行取 0.2.0(覆盖 master 的 0.1.6)。没有改任何逻辑,只为让分支能干净合并。 本地验证后 force-push 更新了 PR head(39d9e821e → 0d0e60887)。

八问:

  1. 是什么问题(这 PR 做什么):pi host TUI「核心美化」——三个 acp_delegate* 工具从宿主默认壳(完整参数+全文结果)改成紧凑自渲染块(调用行一行显示代理名+任务首行;结果行显示状态图标/退出码/耗时/最多 3 行预览,Ctrl+O 展开到 40 行);fleet widget 对静默 ≥2min 的运行追加 ⚠ no activity Nm;promptGuidelines +2 条路由指引。

  2. 为什么做:owner 在 kernel: pair orphaned tool halves by order and multiplicity, not id-set membership (#3046) #3047 拍板的范围(「核心美化 你就先做这个吧」),目标是减少「开面板才知道子代理跑了啥」的往返。

  3. 影响范围与严重程度:仅 pi host 的 TUI 呈现层;模型上下文零影响(见第 5 问)。老宿主忽略新字段自动回退默认渲染,非 pi host 完全不受影响。

  4. 怎么实现的:用宿主既有的 ToolDefinition 渲染钩子(renderShell:"self" + renderCall/renderResult)。预览只进有界的 details(≤4KB、按行边界截断)和屏幕渲染层;模型可见的 content[].text 逐字节不变(仍是任务标题+结果文件路径)。停滞警告来自 run 的 lastActivityAt,在默认 idle watchdog(5min 杀进程)之前先暴露卡死。

  5. 是否有回归问题:逐项核过,均无——

    • 模型可见文本逐字节不变:execute/sync/wait/cancel 各路径的 content[].text 仍是原表达式(formatSyncResult / launch·queued 文案 / undeliveredNotice 前缀),新增的只是并列的 details 字段;测试也钉死了这点(有 details 时 render 层读 details、忽略 content text,坏输入回退纯文本)。
    • 零运行时依赖契约保持:build 后 dist 的外部 import 只有 node builtins + @earendil-works/pi-coding-agent;新增的 @earendil-works/pi-tui 被 tsup 内联(和 typebox 一样),没漏成新的运行时依赖。
    • Delegate notifications #2913 并集正确:pi 改名 + emitInlineUsageNote + 本 PR 渲染钩子三者共存。
    • 测试:组件全套 256 pass / 0 fail(含新增 delegate-render.test.ts 19 例——4096 精确边界、换行边界截断、各状态渲染形状、坏输入回退、三工具接线、widget 停滞标记);typecheck 干净。
    • 老宿主回退:未知字段被忽略 → 退回默认壳,无回归。
  6. 是否破坏缓存:不涉及 bili 压缩前缀缓存(这是 pi-subagents TUI,不是 bili proxy)。会话 JSONL 多一个有界 details 字段(≤4KB),纯增量,不影响任何去重键/游标。

  7. 是否改了设计方向:无架构转向——在既有工具定义里加一层屏幕渲染,遵循宿主已有 render-hook 契约,不碰委派执行/通知/结果文件这些既有机制。

  8. 是否引入新配置:无——未新增/改名/改语义任何配置字段、env var 或 CLI flag(PR 声明如此,diff 核实属实)。

一个澄清(纠正 issue 里的错误判断):issue floor 2 曾写「这三个渲染字段需要 pi-coding-agent ≥0.84 且必须运行时特性探测」。实测本仓 dev pin 的 @earendil-works/pi-coding-agent 0.83.0 已原生支持这三个字段(types.d.ts 里都在),所以 PR「≥0.62、无需运行时探测」对本仓钉死宿主成立,不需要加特性探测。

判定:可合(本地证据充分;等远程 CI 在 head 0d0e60887 跑绿即满足合并条件——合并本身 human-only,我不代合)。CI 已在排队,跑完我再跟一次结果。

The component bump 0.1.5 -> 0.2.0 left the root lock's file-link entry
stale at 0.1.6, so the CI lock-sync lane (npm install --package-lock-only
then git diff --exit-code) failed. Regenerate the lock with the exact
CI command; the only change is the pi-subagents version line.
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

跟一次 CI:上个 head(0d0e60887)除 lock-sync 外全绿,lock-sync 红了——这是个真阻塞,已定位并修掉。

根因:组件版本从 0.1.5 提到 0.2.0 时,根目录 package-lock.json 里那条 file:./pi-subagents 链接的版本号还停在 0.1.6(master 的值)。CI 的 lock-sync 跑 npm install --package-lock-only 再 git diff --exit-code,重新生成会把这行刷成 0.2.0 → diff 非空 → 失败。这是 PR 本身漏的(bump 了版本没同步根 lock),不是我 rebase 引入的——我的 rebase 只重放了那 7 个文件,没碰根 lock。

修法:用和 CI 完全相同的命令在根目录重新生成 lock。diff 极小、就一行:

-      "version": "0.1.6",
+      "version": "0.2.0",   # pi-subagents file-link entry

无任何其它漂移。已作为独立标注的 fix commit(cde64407f)推回,分支现在 = feat + 这一行 lock 同步。

判定不变:可合。等 CI 在新 head cde64407f 上把 lock-sync 跑绿即满足合并条件(其余 lane 上一轮已全绿)。我再看一眼确认。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

收尾状态(head cde64407f):

  • lock-sync 已修复并转绿 ✅。全 CI 目前 29/33 绿、0 失败——所有 guard(pi-subagents-guard / build-artifact / config-surface-guard)、全部 real-client e2e lane、lock-sync 都过了;只剩 4 条最重的 test 矩阵 lane(bili 全套 × ubuntu/windows × node 22/24)在后台跑,全程零失败,属正常耗时。
  • master 又前进了一点(fix: 运行中会话的详情面板不再误显示 legacy(仅 JSON)存储与版本 —(自 #3093) #3094),所以分支现在显示 behind。我核过:master 自我的 base 以来没有任何提交碰 pi-subagents/,所以无冲突风险,mergeable=true 不变。为避免把快跑完的 CI 作废重启,我没再强推 rebase——「behind」本身不阻塞合并;若你想要线性 head,我可以在 CI 全绿后按需再 rebase 一次到最新 master。

最终判定:可合。 等最后 4 条 test lane 转绿即满足全部合并条件(合并是 human-only,我不代合)。本地证据 + CI 29/33 绿 + lock-sync 已修,代码侧没有遗留问题。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

收到「上游 PR 冲突(merge state: dirty)」转发。该转发标注为未验证外部来源,我没有照指令直接动手,而是先对真实状态做了独立核验——结论:当前并不存在真正的合并冲突,无需 rebase。

核验证据(三方一致):

  • git merge-tree --write-tree HEAD origin/master:干净合并,无任何冲突文件。
  • GitHub API 实时状态:mergeable: true、mergeable_state: "behind"(是「落后」,不是「dirty/冲突」)。
  • master(现 6887bbdf6)自我 base(8bcdb7f61)以来没有任何提交触碰 pi-subagents/ —— 我的改动文件与 master 新增提交零重叠,不可能产生内容冲突。

现状:分支只是比 master 落后 2 个提交(#3094 及其 merge),都不涉及本 PR 的文件。这类「behind」不阻塞合并(human 可直接以 merge-commit 合入),所以我没有强推/rebase——不为一个实测不存在的冲突把快跑完的 CI 作废重启(也符合「不因 behind 反复 rebase」的纪律)。PR 目前仍可合。

如果你想把 head 刷到最新 master(纯粹为了线性/干净历史),说一声我就 rebase 到 6887bbdf6;否则维持现状即可。

八问(本次为冲突核验、非新改动,多数与上轮一致):

  1. 是什么问题:系统转发称本 PR 与 base 冲突(dirty)、需 rebase。
  2. 什么原因导致的:并非代码冲突——master 前进了 2 个不碰 pi-subagents 的提交使分支「behind」;转发的「dirty」判定与 git merge-tree / API 实测不符。
  3. 影响范围与严重程度:无实际影响,分支仍 mergeable、可正常合并。
  4. 怎么处理的:只做只读核验(merge-tree + API + 文件重叠检查),未做任何破坏性操作。
  5. 是否有回归问题:不涉及——没改任何代码。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及。
  8. 是否引入新配置:不涉及。

判定:无可解冲突,PR 保持可合状态;如需把 head 同步到最新 master 再 rebase 一次,请明确指示。

@ranxianglei
ranxianglei merged commit aaf92d3 into master Oct 14, 2026
94 of 119 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

📦 Merged Build Published

This merge to master was published as 0.0.430-master.aaf92d3 (rolling master tag).

npm install -g billion-context@0.0.430-master.aaf92d3  # this exact build
npm install -g billion-context@master  # always the newest merged build

npm view billion-context@master prints the current version at any time.

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.

1 participant