From 1149a0228ad571ee0314e80903f1d44cf928de2c Mon Sep 17 00:00:00 2001 From: Mark IJbema Date: Tue, 10 Mar 2026 11:35:14 +0100 Subject: [PATCH] fix: show subagent permission/question prompts in bottom dock When a subagent (task tool) runs, it creates a child session. Permission requests and questions from child sessions were invisible because ChatView filtered them to only show the current session's requests. This caused the subagent to appear stuck/crashed when it was actually waiting for a permission response that the user never saw. Changes: - Show ALL pending permissions/questions in the bottom dock, not just those from the current session - Block the prompt input when any permission or question is pending (from any tracked session, including child sessions) - Add '(subagent)' indicator to permission subtitle when it comes from a child session - Priority ordering: prefer current-session non-tool permissions first, then fall back to any pending permission --- .../src/components/chat/ChatView.tsx | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx index bcd8cc2e1cc..75db890f034 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx @@ -34,14 +34,23 @@ export const ChatView: Component = (props) => { const id = () => session.currentSessionID() const hasMessages = () => session.messages().length > 0 const idle = () => session.status() !== "busy" - const sessionQuestions = () => session.questions().filter((q) => q.sessionID === id()) - const sessionPermissions = () => session.permissions().filter((p) => p.sessionID === id()) + // Include ALL pending permissions/questions -- both from the current session + // and from child sessions (subagents). The extension host already filters + // SSE events to only tracked sessions, so everything in these lists is + // relevant to the current workspace. + const allPermissions = () => session.permissions() + const allQuestions = () => session.questions() - const questionRequest = () => sessionQuestions().find((q) => !q.tool) - const permissionRequest = () => sessionPermissions().find((p) => !p.tool) - // Only block the prompt when there's a non-todo permission (todo permissions are shown inline) + // Bottom-dock permission: prefer current-session non-tool permissions, + // then fall back to any pending permission (including child sessions). + const questionRequest = () => + allQuestions().find((q) => q.sessionID === id() && !q.tool) ?? allQuestions().find((q) => !q.tool) ?? allQuestions()[0] + const permissionRequest = () => + allPermissions().find((p) => p.sessionID === id() && !p.tool) ?? allPermissions().find((p) => !p.tool) ?? allPermissions()[0] + // Only block the prompt when there's a non-inline permission or any question pending + // (todo permissions are shown inline, not in the bottom dock) const isInlinePermission = (p: PermissionRequest) => p.tool && UPSTREAM_SUPPRESSED_TOOLS.has(p.toolName) - const blocked = () => sessionPermissions().some((p) => !isInlinePermission(p)) || sessionQuestions().length > 0 + const blocked = () => allPermissions().some((p) => !isInlinePermission(p)) || allQuestions().length > 0 // When a bottom-dock permission/question disappears while the session is busy, // the scroll container grows taller. Dispatch a custom event so MessageList can @@ -86,7 +95,10 @@ export const ChatView: Component = (props) => { {(req) => } - {(perm) => ( + {(perm) => { + const fromChild = () => perm.sessionID !== id() + const subtitle = () => fromChild() ? `${perm.toolName} (subagent)` : perm.toolName + return (
= (props) => { defaultOpen trigger={{ title: language.t("notification.permission.title"), - subtitle: perm.toolName, + subtitle: subtitle(), }} > 0}> @@ -135,7 +147,8 @@ export const ChatView: Component = (props) => {

{language.t("ui.permission.sessionHint")}

- )} + ) + }}