Skip to content

Commit 8057b2a

Browse files
authored
Merge pull request #5339 from continuedev/dallin/tool-policies-UI
Tool policies UI improvements
2 parents fb1935d + c5fc405 commit 8057b2a

File tree

3 files changed

+123
-63
lines changed

3 files changed

+123
-63
lines changed

gui/src/components/mainInput/Lump/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function Lump() {
3737

3838
return (
3939
<LumpDiv>
40-
<div className="mt-0.5 px-2">
40+
<div className="xs:px-2 mt-0.5 px-1">
4141
<LumpToolbar />
4242

4343
<ContentDiv

gui/src/components/mainInput/Lump/sections/tool-policies/ToolPoliciesSection.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const ToolPoliciesSection = () => {
5959
size={10}
6060
/>
6161
</div>
62-
<div className="relative flex flex-col p-1">
62+
<div className={`relative flex flex-col p-1`}>
6363
{tools.map((tool) => (
6464
<ToolPolicyItem
6565
key={tool.uri + tool.function.name}
@@ -68,9 +68,6 @@ export const ToolPoliciesSection = () => {
6868
excluded={toolGroupSettings[groupName] === "exclude"}
6969
/>
7070
))}
71-
{toolGroupSettings[groupName] === "exclude" && (
72-
<div className="absolute right-0 top-0 h-full w-full cursor-not-allowed"></div>
73-
)}
7471
</div>
7572
</div>
7673
))}

gui/src/components/mainInput/Lump/sections/tool-policies/ToolPolicyItem.tsx

Lines changed: 121 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import { InformationCircleIcon } from "@heroicons/react/24/outline";
1+
import {
2+
ChevronRightIcon,
3+
InformationCircleIcon,
4+
} from "@heroicons/react/24/outline";
25
import { Tool } from "core";
3-
import { useEffect } from "react";
6+
import { useEffect, useMemo, useState } from "react";
47
import { useDispatch } from "react-redux";
58
import { useAppSelector } from "../../../../../redux/hooks";
69
import {
710
addTool,
811
toggleToolSetting,
912
} from "../../../../../redux/slices/uiSlice";
10-
import { fontSize } from "../../../../../util";
1113
import { ToolTip } from "../../../../gui/Tooltip";
14+
import { useFontSize } from "../../../../ui/font";
1215

1316
interface ToolDropdownItemProps {
1417
tool: Tool;
@@ -21,81 +24,141 @@ function ToolPolicyItem(props: ToolDropdownItemProps) {
2124
const policy = useAppSelector(
2225
(state) => state.ui.toolSettings[props.tool.function.name],
2326
);
27+
const [isExpanded, setIsExpanded] = useState(false);
2428

2529
useEffect(() => {
2630
if (!policy) {
2731
dispatch(addTool(props.tool));
2832
}
2933
}, [props.tool.function.name, policy]);
3034

35+
const parameters = useMemo(() => {
36+
if (props.tool.function.parameters?.properties) {
37+
return Object.entries(props.tool.function.parameters.properties).map(
38+
([name, schema]) =>
39+
[name, schema] as [string, { description: string; type: string }],
40+
);
41+
}
42+
return undefined;
43+
}, [props.tool.function.parameters]);
44+
45+
const fontSize = useFontSize(-2);
46+
3147
if (!policy) {
3248
return null;
3349
}
3450

3551
return (
3652
<div
37-
className="hover:bg-list-active hover:text-list-active-foreground -mx-2 flex cursor-pointer items-center justify-between gap-2 rounded-md px-2 py-0.5"
53+
className="flex flex-col"
3854
style={{
39-
fontSize: fontSize(-3),
40-
}}
41-
data-testid={`tool-policy-item-${props.tool.function.name}`}
42-
onClick={(e) => {
43-
dispatch(toggleToolSetting(props.tool.function.name));
44-
e.stopPropagation();
45-
e.preventDefault();
55+
fontSize,
4656
}}
4757
>
48-
<div className="flex flex-1 flex-row items-center gap-1">
49-
{props.duplicatesDetected ? (
50-
<>
51-
<div>
52-
<InformationCircleIcon
53-
data-tooltip-id={props.tool.displayTitle + "-duplicate-warning"}
54-
className="h-3 w-3 cursor-help text-yellow-500"
58+
<div className="flex flex-row items-center">
59+
<div
60+
className={`hover:bg-list-active hover:text-list-active-foreground xs:gap-1.5 flex flex-1 cursor-pointer flex-row items-center gap-1 py-0.5 pl-1 pr-2`}
61+
onClick={() => setIsExpanded((val) => !val)}
62+
>
63+
<ChevronRightIcon
64+
className={`xs:flex hidden h-3 w-3 flex-shrink-0 transition-all duration-200 ${isExpanded ? "rotate-90" : ""}`}
65+
/>
66+
67+
<div
68+
className={`flex items-center gap-1 rounded-md`}
69+
style={{
70+
fontSize,
71+
}}
72+
>
73+
{props.duplicatesDetected ? (
74+
<>
75+
<InformationCircleIcon
76+
data-tooltip-id={
77+
props.tool.displayTitle + "-duplicate-warning"
78+
}
79+
className="h-3 w-3 flex-shrink-0 cursor-help text-yellow-500"
80+
/>
81+
<ToolTip
82+
id={props.tool.displayTitle + "-duplicate-warning"}
83+
place="bottom"
84+
className="flex flex-wrap items-center"
85+
>
86+
<p className="m-0 p-0">
87+
<span>Duplicate tool name</span>{" "}
88+
<code>{props.tool.function.name}</code>{" "}
89+
<span>
90+
detected. Permissions will conflict and usage may be
91+
unpredictable
92+
</span>
93+
</p>
94+
</ToolTip>
95+
</>
96+
) : null}
97+
{props.tool.faviconUrl && (
98+
<img
99+
src={props.tool.faviconUrl}
100+
alt={props.tool.displayTitle}
101+
className="h-3 w-3 flex-shrink-0"
55102
/>
56-
</div>
57-
<ToolTip
58-
id={props.tool.displayTitle + "-duplicate-warning"}
59-
place="bottom"
60-
className="flex flex-wrap items-center"
61-
>
62-
<p className="m-0 p-0">
63-
<span>Duplicate tool name</span>{" "}
64-
<code>{props.tool.function.name}</code>{" "}
65-
<span>
66-
detected. Permissions will conflict and usage may be
67-
unpredictable
68-
</span>
69-
</p>
70-
</ToolTip>
103+
)}
104+
<span className="line-clamp-1 break-all">
105+
{props.tool.function.name}
106+
</span>
107+
</div>
108+
</div>
109+
<div
110+
className={`flex w-8 flex-row items-center justify-end gap-2 px-2 py-0.5 sm:w-16 ${props.excluded ? "cursor-not-allowed" : "hover:bg-list-active hover:text-list-active-foreground cursor-pointer"}`}
111+
data-testid={`tool-policy-item-${props.tool.function.name}`}
112+
onClick={(e) => {
113+
dispatch(toggleToolSetting(props.tool.function.name));
114+
e.stopPropagation();
115+
e.preventDefault();
116+
}}
117+
>
118+
{props.excluded || policy === "disabled" ? (
119+
<>
120+
<span className="text-lightgray sm:hidden">Off</span>
121+
<span className="text-lightgray hidden sm:inline-block">
122+
Excluded
123+
</span>
124+
</>
125+
) : policy === "allowedWithoutPermission" ? (
126+
<>
127+
<span className="text-green-500 sm:hidden">Auto</span>
128+
<span className="hidden text-green-500 sm:inline-block">
129+
Automatic
130+
</span>
131+
</>
132+
) : (
133+
// allowedWithPermission
134+
<>
135+
<span className="text-yellow-500 sm:hidden">Ask</span>
136+
<span className="hidden text-yellow-500 sm:inline-block">
137+
Ask First
138+
</span>
139+
</>
140+
)}
141+
</div>
142+
</div>
143+
<div
144+
className={`flex flex-col overflow-hidden ${isExpanded ? "h-min" : "h-0 opacity-0"} gap-x-1 gap-y-2 pl-2 transition-all`}
145+
>
146+
<span className="mt-1.5 text-xs font-bold">Description:</span>
147+
<span className="italic">{props.tool.function.description}</span>
148+
{parameters ? (
149+
<>
150+
<span className="text-xs font-bold">Arguments:</span>
151+
{parameters.map((param) => (
152+
<div className="block">
153+
<code className="">{param[0]}</code>
154+
<span className="ml-1">{`(${param[1].type}):`}</span>
155+
<span className="ml-1 italic">{param[1].description}</span>
156+
</div>
157+
))}
71158
</>
72159
) : null}
73-
<span className="line-clamp-1 flex items-center gap-1">
74-
{props.tool.faviconUrl && (
75-
<img
76-
src={props.tool.faviconUrl}
77-
alt={props.tool.displayTitle}
78-
className="h-4 w-4"
79-
/>
80-
)}
81-
<pre className="my-0.5 text-[11px]">{props.tool.function.name}</pre>
82-
</span>
160+
<div className="h-1"></div>
83161
</div>
84-
{props.excluded ? (
85-
<span className="text-lightgray">Excluded</span>
86-
) : (
87-
<div className="flex cursor-pointer gap-2">
88-
{(policy === "allowedWithPermission" || policy === undefined) && (
89-
<span className="text-yellow-500">Ask First</span>
90-
)}
91-
{policy === "allowedWithoutPermission" && (
92-
<span className="text-green-500">Automatic</span>
93-
)}
94-
{policy === "disabled" && (
95-
<span className="text-lightgray">Excluded</span>
96-
)}
97-
</div>
98-
)}
99162
</div>
100163
);
101164
}

0 commit comments

Comments
 (0)