From 4ac0b528822749e28cbdf10ebfa3f5f47ed25847 Mon Sep 17 00:00:00 2001 From: Dark aura Date: Wed, 6 May 2026 04:57:18 +0100 Subject: [PATCH] redesign: compact tool display and anchored permission prompt - Replace heavy card layout with compact inline tool calls - Move permission prompt near input box (only shows when needed) - Add request_permission tool to tool catalog for frontend display - Create CompactToolCall component with expandable details - Fix TypeScript errors (removed unused props, simplified icons) - Preserve showAssistantDetails filter for non-request_permission tools --- web/backend/api/tools.go | 6 ++ .../src/components/chat/assistant-message.tsx | 69 ++------------- .../src/components/chat/chat-page.tsx | 24 ++--- .../src/components/chat/compact-tool-call.tsx | 88 +++++++++++++++++++ 4 files changed, 114 insertions(+), 73 deletions(-) create mode 100644 web/frontend/src/components/chat/compact-tool-call.tsx diff --git a/web/backend/api/tools.go b/web/backend/api/tools.go index 289ea5035..629d5f43d 100644 --- a/web/backend/api/tools.go +++ b/web/backend/api/tools.go @@ -193,6 +193,12 @@ var toolCatalog = []toolCatalogEntry{ Category: "discovery", ConfigKey: "mcp.discovery.use_bm25", }, + { + Name: "request_permission", + Description: "Request user permission for accessing paths outside workspace.", + Category: "system", + ConfigKey: "request_permission", + }, } func (h *Handler) registerToolRoutes(mux *http.ServeMux) { diff --git a/web/frontend/src/components/chat/assistant-message.tsx b/web/frontend/src/components/chat/assistant-message.tsx index 07a3c0abc..4ca1167c7 100644 --- a/web/frontend/src/components/chat/assistant-message.tsx +++ b/web/frontend/src/components/chat/assistant-message.tsx @@ -23,6 +23,7 @@ import { type ChatAttachment, type ChatToolCall, } from "@/store/chat" +import { CompactToolCall } from "@/components/chat/compact-tool-call" interface AssistantMessageProps { content: string @@ -114,71 +115,17 @@ export function AssistantMessage({ )} {(!isCollapsedBlock || isExpanded) && isToolCalls && hasToolCalls && ( -
+
{toolCalls.map((toolCall, index) => { - const explanation = - toolCall.extraContent?.toolFeedbackExplanation?.trim() ?? "" const toolName = toolCall.function?.name?.trim() ?? "" - const toolArguments = toolCall.function?.arguments?.trim() ?? "" - const hasFunctionSummary = toolName || toolArguments - - if (!explanation && !hasFunctionSummary) { - return null - } - + const isRequestPermission = toolName === "request_permission" + return ( -
0 && "border-border/20 border-t pt-3", - )} - > - {explanation && ( -
-
- {t("chat.toolCallExplanationLabel")} -
-
- - {explanation} - -
-
- )} - - {hasFunctionSummary && ( -
-
- {t("chat.toolCallFunctionLabel")} -
-
- {toolName && ( -
- {toolName} -
- )} - {toolArguments && ( -
-                              {toolArguments}
-                            
- )} -
-
- )} -
+ toolCall={toolCall} + isRequestPermission={isRequestPermission} + /> ) })}
diff --git a/web/frontend/src/components/chat/chat-page.tsx b/web/frontend/src/components/chat/chat-page.tsx index aa479d776..3031e9c9e 100644 --- a/web/frontend/src/components/chat/chat-page.tsx +++ b/web/frontend/src/components/chat/chat-page.tsx @@ -369,18 +369,6 @@ export function ChatPage() { /> )} - {permissionRequest && ( -
- -
- )} - {messages.map((msg) => { if ( !showAssistantDetails && @@ -421,6 +409,18 @@ export function ChatPage() { onChange={handleImageSelection} /> + {permissionRequest && ( +
+ +
+ )} + | null = null + if (toolArguments) { + try { + parsedArgs = JSON.parse(toolArguments) + } catch { + // ignore + } + } + + // Status icon + const isError = explanation.toLowerCase().includes("error") || explanation.toLowerCase().includes("denied") + + return ( +
+ + + {isExpanded && (explanation || toolArguments) && ( +
+ {explanation && ( +
+ {explanation} +
+ )} + {toolArguments && ( +
+
{toolArguments}
+
+ )} +
+ )} +
+ ) +}