Bash 工具执行时不实时展示输出 / Bash tool output is not shown in real time
问题描述 / Description
执行 Bash 工具时,即使命令需要较长时间运行并持续输出,UI 中不会实时显示命令的 stdout,只有等命令执行结束拿到最终结果后内容才一次性出现。后台其实已经在流式推送输出,但渲染层没有把它展示出来。
When a Bash tool call runs a long-running command that emits output, PI-Desktop does not display the command's stdout live. The output only appears once the command finishes. The backend already streams the output, but the rendering layer never surfaces it.
复现步骤 / Steps to reproduce
- 新建/打开一个会话,向 agent 发起一个会持续输出且耗时较长的 Bash 命令,例如:
- Open a session and ask the agent to run a long-running command that keeps printing, e.g.:
# for i in $(seq 1 60); do echo "tick $i"; sleep 1; done
- 观察工具行:命令开始后只显示"运行中"和命令摘要,没有任何输出滚动。只有命令结束后才显示完整 stdout。
- Observe the tool row: while the command runs you only see a "running" label plus the command summary; no output scrolls by. The full stdout only appears after the command finishes.
当前实现现状 / Current implementation state
代码链路其实是通的,问题出在 UI 呈现:
- Rust 宿主(
crates/host-core/src/tools/mod.rs)通过 OutputNotifier 每约 100ms 把 stdout/stderr 增量以 tools.output 通知推送给客户端(crates/host-core/src/rpc/mod.rs 里 output_tx 已接线)。
- agent-runtime(
packages/agent-runtime/src/runtime.ts)订阅 tools.output,累积成进度并节流地以 onUpdate({details:{output}}) 上报,最终转成 tool_update 事件(字段 partialResult = { details: { output } })。
- 主进程
electron/main/index.ts 把 agent.event(含 tool_update)转发给渲染进程;渲染侧 apps/desktop/src/stores/app-store.ts 在 tool_update 分支把它写进工具的 content/toolResult。
但 UI 上有两个问题导致"看不到实时输出":
- 运行中的 Bash 行默认是折叠的且不渲染输出正文:
apps/desktop/src/components/ChatTranscript.tsx 中 ToolRow 的正文只在 open && hasDetails 时构建(而 open 默认仅在失败时才为 true);未展开时活动组头部只显示"状态 + 命令摘要"(activityItemSummary),不含实时输出。
- 流式字段键与展示字段不一致:流式 partialResult 的键是
details.output,而展示层 apps/desktop/src/lib/tool-presentation.ts 的 run 分支只读取 details.stdout / details.stderr。因此即使展开运行中的行,流式的 output 也不会被渲染为 stdout 文本;要等 Bash 结束后返回的最终 details.stdout 才可见。
预期行为 / Expected behavior
- 运行中的 Bash 工具行应能实时/近乎实时地展示正在滚动输出的 stdout(最好自动展开或提供可见的滚动输出区)。
- 流式期间的
details.output 应与最终 details.stdout 保持一致渲染(键统一,或展示层兼容 output)。
环境 / Environment
- App: PI-Desktop
- Platform: Windows (Windows PowerShell shell)
- 复现方式:通过 agent 发起长耗时 Bash 命令
Bash 工具执行时不实时展示输出 / Bash tool output is not shown in real time
问题描述 / Description
执行 Bash 工具时,即使命令需要较长时间运行并持续输出,UI 中不会实时显示命令的 stdout,只有等命令执行结束拿到最终结果后内容才一次性出现。后台其实已经在流式推送输出,但渲染层没有把它展示出来。
When a Bash tool call runs a long-running command that emits output, PI-Desktop does not display the command's stdout live. The output only appears once the command finishes. The backend already streams the output, but the rendering layer never surfaces it.
复现步骤 / Steps to reproduce
# for i in $(seq 1 60); do echo "tick $i"; sleep 1; done当前实现现状 / Current implementation state
代码链路其实是通的,问题出在 UI 呈现:
crates/host-core/src/tools/mod.rs)通过OutputNotifier每约 100ms 把 stdout/stderr 增量以tools.output通知推送给客户端(crates/host-core/src/rpc/mod.rs里output_tx已接线)。packages/agent-runtime/src/runtime.ts)订阅tools.output,累积成进度并节流地以onUpdate({details:{output}})上报,最终转成tool_update事件(字段partialResult = { details: { output } })。electron/main/index.ts把agent.event(含tool_update)转发给渲染进程;渲染侧apps/desktop/src/stores/app-store.ts在tool_update分支把它写进工具的content/toolResult。但 UI 上有两个问题导致"看不到实时输出":
apps/desktop/src/components/ChatTranscript.tsx中ToolRow的正文只在open && hasDetails时构建(而open默认仅在失败时才为 true);未展开时活动组头部只显示"状态 + 命令摘要"(activityItemSummary),不含实时输出。details.output,而展示层apps/desktop/src/lib/tool-presentation.ts的run分支只读取details.stdout/details.stderr。因此即使展开运行中的行,流式的output也不会被渲染为 stdout 文本;要等 Bash 结束后返回的最终details.stdout才可见。预期行为 / Expected behavior
details.output应与最终details.stdout保持一致渲染(键统一,或展示层兼容output)。环境 / Environment