Skip to content

Commit fcc3427

Browse files
committed
add args to simple tool call ui
1 parent 590b738 commit fcc3427

File tree

4 files changed

+103
-67
lines changed

4 files changed

+103
-67
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
2+
import { ContextItemWithId, Tool, ToolCallState } from "core";
3+
import { ComponentType, useMemo, useState } from "react";
4+
import { ContextItemsPeekItem } from "../../../components/mainInput/belowMainInput/ContextItemsPeek";
5+
import { ArgsItems, ArgsToggleIcon } from "./ToolCallArgs";
6+
import { ToolCallStatusMessage } from "./ToolCallStatusMessage";
7+
8+
interface SimpleToolCallUIProps {
9+
toolCallState: ToolCallState;
10+
tool: Tool | undefined;
11+
contextItems: ContextItemWithId[];
12+
icon?: ComponentType<React.SVGProps<SVGSVGElement>>;
13+
}
14+
15+
export function SimpleToolCallUI({
16+
contextItems,
17+
icon: Icon,
18+
toolCallState,
19+
tool,
20+
}: SimpleToolCallUIProps) {
21+
const ctxItems = useMemo(() => {
22+
return contextItems?.filter((ctxItem) => !ctxItem.hidden) ?? [];
23+
}, [contextItems]);
24+
25+
const [open, setOpen] = useState(false);
26+
const [isHovered, setIsHovered] = useState(false);
27+
28+
const [showingArgs, setShowingArgs] = useState(false);
29+
30+
const args: [string, any][] = useMemo(() => {
31+
return Object.entries(toolCallState.parsedArgs);
32+
}, [toolCallState.parsedArgs]);
33+
34+
return (
35+
<div className={`flex flex-1 flex-col px-2 pt-2`}>
36+
<div className="flex flex-row justify-between">
37+
<div
38+
className="flex cursor-pointer items-center justify-start text-xs text-gray-300"
39+
onClick={() => setOpen((prev) => !prev)}
40+
onMouseEnter={() => setIsHovered(true)}
41+
onMouseLeave={() => setIsHovered(false)}
42+
data-testid="context-items-peek"
43+
>
44+
<div className="relative mr-1 h-4 w-4">
45+
{Icon && !isHovered && !open ? (
46+
<Icon className={`absolute h-4 w-4 text-gray-400`} />
47+
) : (
48+
<>
49+
<ChevronRightIcon
50+
className={`absolute h-4 w-4 text-gray-400 transition-all duration-200 ease-in-out ${
51+
open ? "rotate-90 opacity-0" : "rotate-0 opacity-100"
52+
}`}
53+
/>
54+
<ChevronDownIcon
55+
className={`absolute h-4 w-4 text-gray-400 transition-all duration-200 ease-in-out ${
56+
open ? "rotate-0 opacity-100" : "-rotate-90 opacity-0"
57+
}`}
58+
/>
59+
</>
60+
)}
61+
</div>
62+
<span
63+
className="ml-1 text-xs text-gray-400 transition-colors duration-200"
64+
data-testid="toggle-div-title"
65+
>
66+
<ToolCallStatusMessage tool={tool} toolCallState={toolCallState} />
67+
</span>
68+
</div>
69+
<div>
70+
{args.length > 0 ? (
71+
<ArgsToggleIcon
72+
isShowing={showingArgs}
73+
setIsShowing={setShowingArgs}
74+
toolCallId={toolCallState.toolCallId}
75+
/>
76+
) : null}
77+
</div>
78+
</div>
79+
<ArgsItems args={args} isShowing={showingArgs} />
80+
<div
81+
className={`mt-2 overflow-y-auto transition-all duration-300 ease-in-out ${
82+
open ? "max-h-[50vh] opacity-100" : "max-h-0 opacity-0"
83+
}`}
84+
>
85+
{ctxItems.length ? (
86+
ctxItems.map((contextItem, idx) => (
87+
<ContextItemsPeekItem key={idx} contextItem={contextItem} />
88+
))
89+
) : (
90+
<div className="pl-2 text-xs italic text-gray-400">
91+
No tool call output
92+
</div>
93+
)}
94+
</div>
95+
</div>
96+
);
97+
}

gui/src/pages/gui/ToolCallDiv/ToolCallArgs.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { CodeBracketIcon } from "@heroicons/react/24/outline";
12
import { useMemo } from "react";
23
import { ToolTip } from "../../../components/gui/Tooltip";
34

@@ -24,9 +25,10 @@ export const ArgsToggleIcon = ({
2425
e.stopPropagation();
2526
setIsShowing(!isShowing);
2627
}}
27-
className={`hover:bg-vsc-input-background select-none px-1 py-0.5 hover:opacity-80 ${isShowing ? "bg-vsc-input-background" : "bg-transparent"}`}
28+
className={`cursor-pointer select-none rounded-sm px-1 py-0.5 hover:bg-gray-400/40 hover:opacity-80 ${isShowing ? "bg-gray-400/40" : "bg-transparent"}`}
2829
>
29-
{`{}`}
30+
<CodeBracketIcon className="h-3 w-3 flex-shrink-0" />
31+
{/* {`{}`} */}
3032
</div>
3133
<ToolTip id={argsTooltipId}>
3234
{isShowing ? "Hide args" : "Show args"}

gui/src/pages/gui/ToolCallDiv/ToolOutput.tsx

-63
This file was deleted.

gui/src/pages/gui/ToolCallDiv/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import { vscButtonBackground } from "../../../components";
2525
import Spinner from "../../../components/gui/Spinner";
2626
import { useAppSelector } from "../../../redux/hooks";
2727
import FunctionSpecificToolCallDiv from "./FunctionSpecificToolCallDiv";
28+
import { SimpleToolCallUI } from "./SimpleToolCallUI";
2829
import { ToolCallDisplay } from "./ToolCall";
29-
import { SimpleToolCallUI } from "./ToolOutput";
3030

3131
interface ToolCallDivProps {
3232
toolCall: ToolCallDelta;
@@ -80,7 +80,7 @@ export function ToolCallDiv(props: ToolCallDivProps) {
8080

8181
if (icon) {
8282
return (
83-
<div className="ml-4 mt-2">
83+
<div className="ml-4 mt-2 flex">
8484
<SimpleToolCallUI
8585
tool={tool}
8686
toolCallState={props.toolCallState}

0 commit comments

Comments
 (0)