Skip to content

fix(pi): 工具调用展示按 harness 归一化,不再只显示裸工具名 - #1437

Merged
MagicLizi merged 3 commits into
mainfrom
pi-tool-display
Aug 3, 2026
Merged

fix(pi): 工具调用展示按 harness 归一化,不再只显示裸工具名#1437
MagicLizi merged 3 commits into
mainfrom
pi-tool-display

Conversation

@zqchris

@zqchris zqchris commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

PI harness 会话里的工具调用在界面上只显示裸工具名(每行都是「调用 bash」「调用 read」),
看不到命令原文、文件名和搜索模式,可读性明显低于 Claude Code 与 Codex 会话。

根因不在 PI 事件层——translator.ts 已经把 toolName + input 原样发成 tool_use 事件;
问题在展示层的共享解析器 describeToolUse:它的 switch 只认 Claude Code 的大写工具名
Bash/Read/Edit…)和 Codex 的名字(exec/file_change…),而 PI 内置工具名全小写
bash/read/edit/write/grep/find/ls)、文件参数字段是 path 而不是 file_path
对不上就全部落进 generic 分支,行级动词兜底成「调用」,参数位只剩工具名。

本 PR 把 PI 内置工具接进同一条展示产线,不再为 PI 单开一套渲染。

顺带说明:权限弹窗那侧早就踩过并修过同一个坑(PermissionPrompt.formatToolInput 专门做了
harness 无关归一化,docs/dev-rules/pi-harness.md 维护不变量第 6 条还明文要求它 harness 无关),
只是这条归一化当时没有推广到聊天流的工具行展示层。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:无(使用 PI 会话时发现)
  • 本 PR 包含:把 PI 内置工具名与参数字段接入现有工具调用展示产线(解析、动词、diff 统计、
    行内详情与 diff 预览、最近一轮改动路径、mobile payload 六处消费端同一口径);其中 PI edit
    的两种入参形态由新增的共享归一化器 piEditReplacements 统一处理,三处 diff 消费端共用它
  • 明确不包含:不改 PI 事件翻译层,不改权限弹窗,不新增任何 UI 组件、样式、token 或 i18n 文案,
    不动 Claude Code / Codex 既有行为
  • 用户可见变化:PI 会话的工具行从「调用 bash」变成与其它 harness 一致的人话摘要——
    bash 走意图解析(git status → 「查看 git 状态」,无法分类时「运行」+ 命令原文)、
    read/ls → 「读取」+ 文件 chip、edit/write → 「编辑」/「创建」+ +N -N 与 diff 预览、
    grep/find → 「搜索」+ 搜索目标;灵动岛与手机端同款收益
  • 是否存在 breaking change:无

PI edit 的两种入参形态(review 中确认的关键事实)

pi v0.83.0 的 packages/coding-agent/src/core/tools/edit.ts 同时存在两种形态,展示层必须
都认,只认一种会让另一种退化成空 diff 与 +0 -0

  • 声明 schema(editSchema,模型被要求产出的形态):{ path, edits: [{ oldText, newText }] }
  • legacy 顶层单段(LegacyEditToolInput,pi 自己仍接受):{ path, oldText, newText }

pi 的 normalizeEditInput 在顶层两侧都是字符串时,把它作为最后一段追加到 edits[] 之后。
piEditReplacements 严格对齐这个顺序,避免展示层与 pi 自身的解释产生分歧。

UI 变化

PI 会话工具行的文案与参数位内容变化(见上方「用户可见变化」);行的布局、颜色、间距、
圆角、动效一律不变,复用现有 AgentActionRow 组件与现有 i18n key,未新增任何字符串或样式。

  • 引用的设计规范:docs/design-rules/DESIGN.md §3 Typography(层级由字号+字重承担)与
    §7 Do「Use monospace for terminal commands and code — it's primary content, not decoration」——
    PI 的命令原文现在和 CC/Codex 一样进入既有等宽命令区展示,而不是以裸工具名混在正文里;
    §2 调色板与 §5 间距未触及,无新增 token。双模式交付门槛不触发:本 PR 不含任何新样式或
    颜色分支,PI 行走的就是 CC/Codex 行已通过双模式的同一套 themed 样式。

怎么验证的

自动验证

在合入最新 upstream/main 后的最终树上执行:

pnpm test:unit
结果:通过(EXIT=0)

pnpm --filter @cindy/maker-shared test
结果:52 文件 / 772 用例 全部通过

pnpm --filter desktop test
结果:1654 文件 / 20161 用例通过、2 skipped(首轮全量;二轮定向跑受影响的 3 个文件 57 用例全通过)

pnpm --filter @cindy/maker-shared run --if-present typecheck
结果:通过

pnpm --filter desktop run --if-present typecheck
结果:通过(需 NODE_OPTIONS=--max-old-space-size=8192;见下方「未执行的验证」)

pnpm check:dco
结果:通过

pnpm check:i18n-glossary
结果:en / zh-CN / ja / ko 无新增违规(本 PR 未新增 UI 文案)

新增回归覆盖:

  • packages/maker-shared/src/__tests__/toolUseDescriptor.test.ts:PI 小写工具名 → 各 descriptor
    形态(bash 意图解析、path 取文件名、find 归 glob 模式、ls 无 path 时降级 generic);
    另有 piEditReplacements 专项:edits[] 形态、legacy 顶层形态、两者并存时的追加顺序、
    纯增/纯删单段保留、残缺输入不抛异常
  • apps/desktop/src/renderer/__tests__/diffStats.test.ts:PI edit 两种形态的统计(顶层形态
    必须给出真实 +1 -2 而不是 +0 -0)、并存时顶层段计入、无可用段返回 +0 -0
  • apps/desktop/src/renderer/__tests__/verbAggregator.test.ts:PI 工具的行级动词映射
  • apps/desktop/src/renderer/__tests__/agentActionRowRendering.test.ts:7 条 DOM 级断言,
    直接验证 PI 行渲染出的用户可见文案与交互(动词 label、文件 chip、+N -N、点击进 diff
    lightbox),含 legacy 顶层形态显式断死不出现 "diffs":[]
  • packages/maker-shared/src/__tests__/payloadSummary.test.ts:mobile payload 侧两种 edit
    形态与 write 的 diff 段落

手工验证

未在实机 PI 会话中目检。本次改动是工具名/字段的映射,无视觉与布局变化,因此改用上面的
DOM 级渲染断言直接验证用户可见输出(动词文案、文件 chip、diff 统计、点击后的 diff 预览
内容),比肉眼看单行文案更能锁住回归。

未执行的验证

  • 实机 PI 会话目检:未做,理由同上(无视觉变化 + 已有 DOM 级断言覆盖用户可见输出)。
    复核步骤很短:开一个 PI 会话,让它跑一次 bash、读一个文件、改一个文件,确认工具行显示
    人话摘要而不是「调用 bash」,且编辑行能点开非空 diff。
  • 手机端实机:未做。mobile 侧改动只有 payloadSummary.ts 的 PI write/edit diff 与
    工具摘要取值,与桌面端共用同一份 describeToolUse / piEditReplacements,由上述单测覆盖。
  • desktop typecheck 的默认堆pnpm --filter desktop typecheck 在本机默认 Node 堆
    (~4GB)下 OOM,抬到 8GB 后通过。这是仓库规模的既有容量问题,不是本 PR 引入(本 PR 只改
    11 个文件),未在本 PR 内改动任何工程配置去处理它。

关于 Windows CI 红(非本 PR 引入,已定位)

首轮 head 上的 Windows unit tests 失败共三处,全部与本 PR 无关,已逐个定性:

失败 定性 证据
voice-input/__tests__/VoiceInputSection.recordingGate.test.ts 源码正则断言 main 基线稳定失败,已有 issue #1448,修复 PR #1440 已并入 main main 自己的 client-ci(head 227dabf8)以同一用例、同一断言失败;本 PR 未触碰 voice-input/**
maker-host/__tests__/grokOauthCallbackListener.test.tslisten EACCES 127.0.0.1:56121 Windows runner 端口权限 flake 零代码改动重跑后该 shard 转绿
packages/device-link/src/__tests__/client.test.ts:2835(8ms ping 周期计时断言) 计时 flake 同上,零改动重跑转绿

处理方式:没有在本 PR 内改这三个文件(均属其它模块,改进来只会扩大本 PR 的评审面)。
本轮已合入最新 upstream/main,带上 #1440 的 CRLF 断言修复,基线那条随之解决。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 影响范围:纯展示层。只新增小写工具名分支,Claude Code / Codex 的既有分支一字未改,
    历史消息也只是渲染路径变化(数据未迁移、未改写)。新增分支只在工具名精确等于 PI 内置
    名时命中:MCP / dynamic / collab 工具在 switch 之前就已按命名空间前缀解析掉,不受影响。
    最坏情况是某个非 PI harness 恰好也用同名小写工具但字段语义不同——此时降级表现与今天
    一致(走 generic 兜底),不会报错或丢信息。
  • 回滚 / 降级方式:git revert 功能提交即可完全恢复原展示行为,无数据或配置残留。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

PI 内置工具名全小写(bash/read/edit/write/grep/find/ls)、文件参数字段为
path,而展示层的 describeToolUse 只认 Claude Code 大写名与 Codex 名,PI
的调用一律落进 generic 分支 —— 行级动词兜底成「调用」,参数位只剩裸工具
名,命令原文、文件名、搜索模式全部看不见。

把 PI 内置工具接进同一条展示产线:

- describeToolUse 补小写分支(bash→command 走 intent 解析,read/ls→file
  read,edit/write→file edit/create,grep/find→search);不用无脑
  toLowerCase 统一,因为 CC 的 Bash 带模型写的 description 而 PI 无此
  字段,展示策略不同。
- 行级动词映射补小写条目,「调用」变回「运行 / 读取 / 编辑 / 搜索」。
- diff 统计与 diff lightbox 认 PI 的 edits[].oldText/newText 与
  write.content,PI 编辑行恢复 +N -N 与 diff 预览。
- 展开详情、文件 chip 与 Read lightbox、最近一轮改动路径、mobile payload
  diff 同步认小写名与 path 字段。

灵动岛(agent-island/toolDetail)与 mobile 消息投影本就由 describeToolUse
驱动,随本次修复一并受益。

Signed-off-by: Chris <zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 04:37
@zqchris
zqchris requested a review from a team as a code owner August 3, 2026 04:37
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 将 PI harness 的小写内置工具调用接入现有的跨 harness 展示链路。

  • bashreadeditwritegrepfindls 增加统一的描述符与动词映射。
  • 在桌面端与移动端补充 PI 文件路径、diff 内容、变更统计及最近修改文件的解析。
  • 兼容 PI edit 的批量替换与 legacy 顶层替换参数,并增加相应的单元测试和 DOM 渲染测试。

Confidence Score: 5/5

此 PR 看起来可以安全合并。

当前没有仍需阻止合并的故障。

Important Files Changed

Filename Overview
packages/maker-shared/src/toolUseDescriptor.ts 增加 PI 小写工具描述符映射及 edit 替换参数归一化,相关输入形态已有针对性测试。
packages/maker-shared/src/payloadSummary.ts 移动 payload 摘要与 diff 构造现在识别 PI 的工具名、路径字段和编辑内容。
apps/desktop/src/renderer/components/chat/AgentActionRow.tsx 桌面工具行新增 PI 文件工具交互、命令详情及 diff lightbox 数据构造。
apps/desktop/src/renderer/lib/agent-actions/diffStats.ts 变更统计覆盖 PI write 和两种 edit 输入形态。
apps/desktop/src/renderer/features/right-sidebar/lib/lastTurnChangedFiles.ts 最近一轮变更文件提取支持 PI 小写编辑工具及 path 字段。

Reviews (2): Last reviewed commit: "fix: address review — pi edit 两种入参形态归一化,..." | Re-trigger Greptile

Copilot AI previously approved these changes Aug 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

变更集中在展示层归一化与测试补齐,逻辑闭环且覆盖到桌面端与共享层的关键消费点。

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

本 PR 修复 PI harness 会话中工具调用展示信息过少的问题:通过在共享解析/展示链路里支持 PI 内置小写工具名与 path 字段,将 PI 的工具行渲染归一化到与 Claude Code / Codex 同一套 descriptor 产线,从而在 UI 中展示更可读的动词、参数与 diff/预览信息。

Changes:

  • describeToolUse 中加入 PI 内置小写工具(bash/read/edit/write/grep/find/ls)的归一化解析,并复用既有命令意图/文件/搜索 descriptor。
  • 桌面端展示链路补齐 PI 工具的动词聚合、diff 统计、文件路径提取与行内详情展示(含 diff lightbox)。
  • 补充 maker-shared 与 desktop renderer 的单测/DOM 渲染断言,覆盖 PI 小写工具名与 path 字段路径。
File summaries
File Description
packages/maker-shared/src/toolUseDescriptor.ts 扩展 descriptor 解析以支持 PI 小写工具名与 path 字段,并将 bash/grep/find/ls 等映射到既有展示模型
packages/maker-shared/src/payloadSummary.ts 增强 mobile payload 的工具摘要与 diff 构建逻辑,支持 PI write/edit 等输入形态
packages/maker-shared/src/tests/toolUseDescriptor.test.ts 新增 PI 内置工具归一化解析的单测覆盖
apps/desktop/src/renderer/lib/agent-actions/verbAggregator.ts 补齐 PI 小写工具到行级动词的映射
apps/desktop/src/renderer/lib/agent-actions/diffStats.ts 支持 PI edit/write 的 diff 统计计算
apps/desktop/src/renderer/features/right-sidebar/lib/lastTurnChangedFiles.ts 右侧栏“最近一轮改动文件”提取逻辑兼容 PI path 字段与小写工具名
apps/desktop/src/renderer/components/chat/AgentActionRow.tsx 行渲染与展开/预览逻辑兼容 PI 小写工具名、grep/find/ls 的行内输入展示与 diff lightbox
apps/desktop/src/renderer/tests/verbAggregator.test.ts 新增 PI 工具动词映射的测试
apps/desktop/src/renderer/tests/diffStats.test.ts 新增 PI edit/write 统计与只读工具保持 null 的测试
apps/desktop/src/renderer/tests/agentActionRowRendering.test.ts 新增 PI 工具行的 DOM 级渲染断言(动词、chip、diff 统计与 lightbox 内容)
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread apps/desktop/src/renderer/components/chat/AgentActionRow.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d1a9c618f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/components/chat/AgentActionRow.tsx Outdated
@MagicLizi

Copy link
Copy Markdown
Contributor

@zqchris 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/renderer/components/chat/AgentActionRow.tsx),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added status:threads-open 还有未 resolve 的评审讨论(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) labels Aug 3, 2026
zqchris added 2 commits August 3, 2026 13:27
Codex P2:pi edit 的 diff 只按 edits[] 解析,真实事件会拿到空 diff 与 +0 -0。
核对 pi v0.83.0 的 core/tools/edit.ts 后确认它有**两种**入参形态:声明 schema
是 { path, edits: [{oldText,newText}] },同时 LegacyEditToolInput 仍接受顶层
{ path, oldText, newText } 并由 normalizeEditInput 归一化。只认任一种都会让
另一种退化成空 diff,因此改为两种都认。

- maker-shared 新增共享归一化器 piEditReplacements:先取 edits[],再把顶层
  oldText/newText(两侧都是字符串才认)作为最后一段追加,顺序与 pi 的
  normalizeEditInput 一致;单段内只有一侧是字符串时另一侧按空串,纯增/纯删
  不会被丢掉。
- AgentActionRow(diff lightbox)、diffStats(行内 +N -N)、payloadSummary
  (mobile payload)三处消费端改为共用它,消除各自解析导致的漂移。
- 测试补齐真实形态:两种入参各自的 diff/统计/渲染断言,含顶层形态必须给出
  非空 diff(断死不出现 "diffs":[])与真实 +1 -2。

Copilot:补 FILE_PATH_TOOLS 注释说明它不是「所有 kind='file' 描述符」的集合
—— pi 的 ls 归一化成 kind='file' 并渲染文件 chip,但刻意不入列(目标是目录,
开 lightbox 无意义),点击仍走命令类就地展开;新增工具按「点击后该看到什么」
判断是否入列。

同时合入最新 upstream/main(带上 #1440 的 VoiceInputSection CRLF 断言修复),
本 PR 的 Windows CI 红是该基线问题所致(issue #1448),非本 PR 引入。

Signed-off-by: Chris <zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 05:32
Copilot AI dismissed their stale review, a newer Copilot review was requested August 3, 2026 05:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

变更聚焦于展示层归一化且已在共享层与桌面渲染侧补齐覆盖 PI 工具形态的单测与 DOM 级回归断言,未发现会破坏既有 Claude Code/Codex 路径的风险点。

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details
  • Files reviewed: 11/11 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@MagicLizi MagicLizi added touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) and removed status:threads-open 还有未 resolve 的评审讨论(review-pr 自动维护,仅展示) labels Aug 3, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

💡 本 PR 命中 UI 路径但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范。

此条仅为建议提醒,不阻断合并。

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码审查通过,无 P0/P1 问题。

实现规范:PI 工具名归一化逻辑完善,piEditReplacements 正确处理两种输入形态,六个消费点的分支守卫清晰,测试覆盖全面(含 DOM 级断言验证端到端输出)。

@MagicLizi
MagicLizi merged commit 4c9e656 into main Aug 3, 2026
17 checks passed
@MagicLizi
MagicLizi deleted the pi-tool-display branch August 3, 2026 06:01
@MagicLizi

Copy link
Copy Markdown
Contributor

把 PI 的裸工具名真正接入了已有的渲染管线,六处消费点一个不漏——侧边栏改动列表、diff 弹窗、行内 stats 全对齐了,用户再也不用面对一堆 bash / edit 的字面文本猜动作。piEditReplacements 的双形态抽象干净利落。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants