diff --git a/packages/pi-agent-core/src/agent-loop.ts b/packages/pi-agent-core/src/agent-loop.ts index ff2bab0f9..a544b58c1 100644 --- a/packages/pi-agent-core/src/agent-loop.ts +++ b/packages/pi-agent-core/src/agent-loop.ts @@ -234,8 +234,9 @@ async function runLoop( const toolResults: ToolResultMessage[] = []; if (hasMoreToolCalls && config.externalToolExecution) { - // External execution mode: tools were handled by the provider (e.g., Claude Code SDK). - // Emit synthetic tool events for TUI rendering but skip local dispatch. + // External execution mode: tools were handled by the provider + // (e.g., Claude Code SDK). Emit tool_execution events for each + // tool call. The TUI adds these as components after the message. for (const tc of toolCalls as AgentToolCall[]) { stream.push({ type: "tool_execution_start", diff --git a/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts b/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts index 7f9fe7044..f9f7a5c79 100644 --- a/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +++ b/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts @@ -210,7 +210,18 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & { host.ui, ); component.setExpanded(host.toolOutputExpanded); - host.chatContainer.addChild(component); + + // For external tool execution: insert tool components before the + // last message component so tools render above the text response. + // The last child is the message that just finished streaming. + const children = host.chatContainer.children; + const lastChild = children.length > 0 ? children[children.length - 1] : undefined; + if (lastChild instanceof AssistantMessageComponent && !host.streamingComponent) { + host.chatContainer.insertChildBefore(component, lastChild); + } else { + host.chatContainer.addChild(component); + } + host.pendingTools.set(event.toolCallId, component); host.ui.requestRender(); } diff --git a/packages/pi-tui/src/components/box.ts b/packages/pi-tui/src/components/box.ts index c99b8600b..9dd692750 100644 --- a/packages/pi-tui/src/components/box.ts +++ b/packages/pi-tui/src/components/box.ts @@ -31,6 +31,16 @@ export class Box implements Component { this.invalidateCache(); } + insertChildBefore(component: Component, before: Component): void { + const index = this.children.indexOf(before); + if (index !== -1) { + this.children.splice(index, 0, component); + } else { + this.children.push(component); + } + this.invalidateCache(); + } + removeChild(component: Component): void { const index = this.children.indexOf(component); if (index !== -1) {