From 14bcebee2a04e346a205d28c6b2d27bec4e8a7b0 Mon Sep 17 00:00:00 2001 From: Jiayuan Date: Sat, 31 Jan 2026 18:28:58 +0800 Subject: [PATCH] feat(agent): add real-time streaming updates to exec tool Utilize the onUpdate callback from pi-agent-core's AgentTool interface to stream output updates in real-time while commands are executing. - Accept onUpdate as 4th parameter in execute function - Emit tailBuffer updates on each stdout/stderr data event - Stop emitting updates once command is backgrounded (yielded) This enables UI to show live command output progress via the tool_execution_update agent event. Co-Authored-By: Claude Opus 4.5 --- src/agent/tools/exec.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/agent/tools/exec.ts b/src/agent/tools/exec.ts index 11338593..cf77d83f 100644 --- a/src/agent/tools/exec.ts +++ b/src/agent/tools/exec.ts @@ -47,7 +47,7 @@ export function createExecTool(defaultCwd?: string): AgentTool' to check output, 'process status ' to check status, 'process stop ' to terminate.", parameters: ExecSchema, - execute: async (_toolCallId, args, signal) => { + execute: async (_toolCallId, args, signal, onUpdate) => { const { command, cwd, timeoutMs, yieldMs = DEFAULT_YIELD_MS } = args as ExecArgs; const effectiveCwd = cwd || defaultCwd; @@ -67,6 +67,29 @@ export function createExecTool(defaultCwd?: string): AgentTool { + if (!onUpdate || yielded) return; + const entry = PROCESS_REGISTRY.get(processId); + if (!entry) return; + onUpdate({ + content: [{ type: "text", text: entry.tailBuffer || "(running...)" }], + details: { + output: entry.tailBuffer, + exitCode: null, + truncated: false, + processId, + }, + }); + }; + + // Listen to stdout/stderr to trigger onUpdate (data collection is handled by registerProcess) + if (onUpdate) { + child.stdout?.on("data", emitUpdate); + child.stderr?.on("data", emitUpdate); + } + // Timeout handling (hard kill) if (timeoutMs && timeoutMs > 0) { timeout = setTimeout(() => {