From 7edb624bdc1fe40692561c97b6cdc98b0e3e7280 Mon Sep 17 00:00:00 2001 From: Yingjie He Date: Mon, 3 Mar 2025 13:42:49 -0800 Subject: [PATCH] feat: improve the allow tool ui (#1473) --- ui/desktop/src/components/GooseMessage.tsx | 12 ++- .../src/components/ToolCallConfirmation.tsx | 82 +++++++++++++------ ui/desktop/src/types/message.ts | 15 +--- 3 files changed, 72 insertions(+), 37 deletions(-) diff --git a/ui/desktop/src/components/GooseMessage.tsx b/ui/desktop/src/components/GooseMessage.tsx index 56ef805d..f41159ad 100644 --- a/ui/desktop/src/components/GooseMessage.tsx +++ b/ui/desktop/src/components/GooseMessage.tsx @@ -9,7 +9,7 @@ import { getTextContent, getToolRequests, getToolResponses, - getToolConfirmationRequestId, + getToolConfirmationContent, } from '../types/message'; import ToolCallConfirmation from './ToolCallConfirmation'; @@ -36,7 +36,8 @@ export default function GooseMessage({ message, metadata, messages, append }: Go const previousUrls = previousMessage ? extractUrls(getTextContent(previousMessage)) : []; const urls = toolRequests.length === 0 ? extractUrls(textContent, previousUrls) : []; - const [toolConfirmationId, hasToolConfirmation] = getToolConfirmationRequestId(message); + const toolConfirmationContent = getToolConfirmationContent(message); + const hasToolConfirmation = toolConfirmationContent !== undefined; // Find tool responses that correspond to the tool requests in this message const toolResponsesMap = useMemo(() => { @@ -72,7 +73,12 @@ export default function GooseMessage({ message, metadata, messages, append }: Go )} - {hasToolConfirmation && } + {hasToolConfirmation && ( + + )} {toolRequests.length > 0 && (
diff --git a/ui/desktop/src/components/ToolCallConfirmation.tsx b/ui/desktop/src/components/ToolCallConfirmation.tsx index 32418b83..1c3daa88 100644 --- a/ui/desktop/src/components/ToolCallConfirmation.tsx +++ b/ui/desktop/src/components/ToolCallConfirmation.tsx @@ -1,11 +1,15 @@ import React, { useState } from 'react'; import { ConfirmToolRequest } from '../utils/toolConfirm'; +import { snakeToTitleCase } from '../utils'; +import Box from './ui/Box'; -export default function ToolConfirmation({ toolConfirmationId }) { - const [disabled, setDisabled] = useState(false); +export default function ToolConfirmation({ toolConfirmationId, toolName }) { + const [clicked, setClicked] = useState(false); + const [status, setStatus] = useState(''); const handleButtonClick = (confirmed) => { - setDisabled(true); + setClicked(true); + setStatus(confirmed ? 'approved' : 'denied'); ConfirmToolRequest(toolConfirmationId, confirmed); }; @@ -14,26 +18,58 @@ export default function ToolConfirmation({ toolConfirmationId }) {
Goose would like to call the above tool. Allow?
-
- - -
+ {clicked ? ( +
+
+ {status === 'approved' && ( + + + + )} + {status === 'denied' && ( + + + + )} + + {snakeToTitleCase(toolName.substring(toolName.lastIndexOf('__') + 2))} is {status} + +
+
+ ) : ( +
+ + +
+ )} ); } diff --git a/ui/desktop/src/types/message.ts b/ui/desktop/src/types/message.ts index d03212bd..31e898aa 100644 --- a/ui/desktop/src/types/message.ts +++ b/ui/desktop/src/types/message.ts @@ -187,20 +187,13 @@ export function getToolResponses(message: Message): ToolResponseMessageContent[] ); } -export function getToolConfirmationRequestId(message: Message): [string, boolean] { - const hasToolConfirmationRequest = message.content.some( +export function getToolConfirmationContent( + message: Message +): ToolConfirmationRequestMessageContent { + return message.content.find( (content): content is ToolConfirmationRequestMessageContent => content.type === 'toolConfirmationRequest' ); - - const contentId = hasToolConfirmationRequest - ? message.content.find( - (content): content is ToolConfirmationRequestMessageContent => - content.type === 'toolConfirmationRequest' - )?.id || '' - : ''; - - return [contentId, hasToolConfirmationRequest]; } export function hasCompletedToolCalls(message: Message): boolean {