From 8c6c3405d82abfb5b68c6e87547c64f387a7e7d3 Mon Sep 17 00:00:00 2001 From: ramnique <30795890+ramnique@users.noreply.github.com> Date: Thu, 23 Jan 2025 08:19:04 +0530 Subject: [PATCH] rowboat: tool call ui improvements --- .../[projectId]/playground/messages.tsx | 149 ++++++++---------- 1 file changed, 66 insertions(+), 83 deletions(-) diff --git a/apps/rowboat/app/projects/[projectId]/playground/messages.tsx b/apps/rowboat/app/projects/[projectId]/playground/messages.tsx index f91415ec..13035bbe 100644 --- a/apps/rowboat/app/projects/[projectId]/playground/messages.tsx +++ b/apps/rowboat/app/projects/[projectId]/playground/messages.tsx @@ -1,6 +1,6 @@ 'use client'; import { Button, Spinner, Textarea } from "@nextui-org/react"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import z from "zod"; import { GetInformationToolResult, WebpageCrawlResponse, Workflow, WorkflowTool } from "@/app/lib/types"; import { executeClientTool, getInformationTool, scrapeWebpage, suggestToolResponse } from "@/app/actions"; @@ -8,7 +8,7 @@ import MarkdownContent from "@/app/lib/components/markdown-content"; import Link from "next/link"; import { apiV1 } from "rowboat-shared"; import { EditableField } from "@/app/lib/components/editable-field"; -import { MessageSquareIcon, EllipsisIcon } from "lucide-react"; +import { MessageSquareIcon, EllipsisIcon, CircleCheckIcon, ChevronsDownIcon, ChevronsRightIcon, ChevronRightIcon, ChevronDownIcon, ExternalLinkIcon, XIcon } from "lucide-react"; function UserMessage({ content }: { content: string }) { return
@@ -37,9 +37,7 @@ function InternalAssistantMessage({ content, sender, latency }: { content: strin {sender ?? 'Assistant'}
@@ -206,6 +204,24 @@ function ToolCall({ } } +function ToolCallHeader({ + toolCall, + result, +}: { + toolCall: z.infer['tool_calls'][number]; + result: z.infer | undefined; +}) { + return
+
+ {!result && } + {result && } +
+ Function Call: {toolCall.function.name} +
+
+
; +} + function GetInformationToolCall({ toolCall, result: availableResult, @@ -269,17 +285,7 @@ function GetInformationToolCall({ return
{sender &&
{sender}
}
-
- {!result && } - - {result && } - -
- Function Call: {toolCall.function.name} -
-
+
{result ? 'Fetched' : 'Fetch'} information for question: {args['question']} @@ -357,17 +363,7 @@ function RetrieveUrlInfoToolCall({ return
{sender &&
{sender}
}
-
- {!result && } - - {result && } - -
- Function Call: {toolCall.function.name} -
-
+
@@ -375,15 +371,13 @@ function RetrieveUrlInfoToolCall({ {args.url} - +
{result && ( )} @@ -479,20 +473,11 @@ function ClientToolCall({ return
{sender &&
{sender}
}
-
- {!result && } + - {result && } - -
- Function Call: {toolCall.function.name} -
-
- - {result && } + + {result && }
; @@ -546,22 +531,15 @@ function MockToolCall({ } let ignore = false; - function process() { + async function process() { setGeneratingResponse(true); - suggestToolResponse(toolCall.id, projectId, messages) - .then((object) => { - if (ignore) { - return; - } - setResponse(JSON.stringify(object)); - }) - .finally(() => { - if (ignore) { - return; - } - setGeneratingResponse(false); - }) + const response = await suggestToolResponse(toolCall.id, projectId, messages); + if (ignore) { + return; + } + setResponse(response); + setGeneratingResponse(false); } process(); @@ -584,24 +562,16 @@ function MockToolCall({ }, [autoSubmit, response, handleSubmit, result]); return
- {sender &&
{sender}
} + {sender &&
{sender}
}
-
- {!result && } + - {result && } - -
- Function Call: {toolCall.function.name} -
-
- - {result && } + + {result && }
- {!result &&
+ + {!result && !autoSubmit &&
Response:
@@ -631,28 +603,39 @@ function ExpandableContent({ expanded = false }: { label: string, - content: string + content: string | object | undefined, expanded?: boolean }) { const [isExpanded, setIsExpanded] = useState(expanded); + const formattedContent = useMemo(() => { + if (typeof content === 'string') { + try { + const parsed = JSON.parse(content); + return JSON.stringify(parsed, null, 2); + } catch (e) { + return content; + } + } + if (typeof content === 'object') { + return JSON.stringify(content, null, 2); + } + return 'undefined'; + }, [content]); + function toggleExpanded() { setIsExpanded(!isExpanded); } return
-
- {!isExpanded && } - {isExpanded && } -
{label}
+
+ {!isExpanded && } + {isExpanded && } +
{label}
- {isExpanded &&
- {content} -
} + {isExpanded &&
+            {formattedContent}
+        
}
; }