From e54c9844e896bb15e16d0ec2efeeb7e5dabc3faf Mon Sep 17 00:00:00 2001 From: weishu Date: Sun, 21 Dec 2025 23:59:50 +0800 Subject: [PATCH] feat(web): separate pending permissions from task details in tool messages Add helper functions to identify and split task children into pending permission blocks and other details, allowing permission prompts to display immediately while keeping other task details collapsible. --- .../AssistantChat/messages/ToolMessage.tsx | 71 ++++++++++++++----- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/web/src/components/AssistantChat/messages/ToolMessage.tsx b/web/src/components/AssistantChat/messages/ToolMessage.tsx index e8a54e3b..e1804c41 100644 --- a/web/src/components/AssistantChat/messages/ToolMessage.tsx +++ b/web/src/components/AssistantChat/messages/ToolMessage.tsx @@ -39,6 +39,25 @@ function isToolCallBlock(value: unknown): value is ToolCallBlock { return true } +function isPendingPermissionBlock(block: ChatBlock): boolean { + return block.kind === 'tool-call' && block.tool.permission?.status === 'pending' +} + +function splitTaskChildren(block: ToolCallBlock): { pending: ChatBlock[]; rest: ChatBlock[] } { + const pending: ChatBlock[] = [] + const rest: ChatBlock[] = [] + + for (const child of block.children) { + if (isPendingPermissionBlock(child)) { + pending.push(child) + } else { + rest.push(child) + } + } + + return { pending, rest } +} + function HappyNestedBlockList(props: { blocks: ChatBlock[] }) { @@ -104,6 +123,7 @@ function HappyNestedBlockList(props: { if (block.kind === 'tool-call') { const isTask = block.tool.name === 'Task' + const taskChildren = isTask ? splitTaskChildren(block) : null return (
@@ -117,14 +137,23 @@ function HappyNestedBlockList(props: { /> {block.children.length > 0 ? ( isTask ? ( -
- - Task details ({block.children.length}) - -
- -
-
+ <> + {taskChildren && taskChildren.pending.length > 0 ? ( +
+ +
+ ) : null} + {taskChildren && taskChildren.rest.length > 0 ? ( +
+ + Task details ({taskChildren.rest.length}) + +
+ +
+
+ ) : null} + ) : (
@@ -184,6 +213,7 @@ export function HappyToolMessage(props: ToolCallMessagePartProps) { const block = artifact const isTask = block.tool.name === 'Task' + const taskChildren = isTask ? splitTaskChildren(block) : null return (
@@ -197,14 +227,23 @@ export function HappyToolMessage(props: ToolCallMessagePartProps) { /> {block.children.length > 0 ? ( isTask ? ( -
- - Task details ({block.children.length}) - -
- -
-
+ <> + {taskChildren && taskChildren.pending.length > 0 ? ( +
+ +
+ ) : null} + {taskChildren && taskChildren.rest.length > 0 ? ( +
+ + Task details ({taskChildren.rest.length}) + +
+ +
+
+ ) : null} + ) : (