Skip to content

Commit c41a6c3

Browse files
authored
fix: tools call available dropdown (#5222)
1 parent 919b667 commit c41a6c3

File tree

4 files changed

+66
-50
lines changed

4 files changed

+66
-50
lines changed

web-app/src/containers/ChatInput.tsx

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ const ChatInput = ({
6464
const { selectedModel } = useModelProvider()
6565
const { sendMessage } = useChat()
6666
const [message, setMessage] = useState('')
67+
const [dropdownToolsAvailable, setDropdownToolsAvailable] = useState(false)
68+
const [tooltipToolsAvailable, setTooltipToolsAvailable] = useState(false)
6769
const [uploadedFiles, setUploadedFiles] = useState<
6870
Array<{
6971
name: string
@@ -407,7 +409,6 @@ const ChatInput = ({
407409
useLastUsedModel={initialMessage}
408410
/>
409411
)}
410-
411412
{/* File attachment - always available */}
412413
<div
413414
className="h-6 hidden p-1 items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1"
@@ -421,16 +422,14 @@ const ChatInput = ({
421422
onChange={handleFileChange}
422423
/>
423424
</div>
424-
425425
{/* Microphone - always available - Temp Hide */}
426426
{/* <div className="h-6 p-1 flex items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1">
427427
<IconMicrophone size={18} className="text-main-view-fg/50" />
428428
</div> */}
429-
430429
{selectedModel?.capabilities?.includes('vision') && (
431430
<TooltipProvider>
432431
<Tooltip>
433-
<TooltipTrigger asChild>
432+
<TooltipTrigger disabled={dropdownToolsAvailable}>
434433
<div className="h-6 p-1 flex items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1">
435434
<IconEye size={18} className="text-main-view-fg/50" />
436435
</div>
@@ -441,7 +440,6 @@ const ChatInput = ({
441440
</Tooltip>
442441
</TooltipProvider>
443442
)}
444-
445443
{selectedModel?.capabilities?.includes('embeddings') && (
446444
<TooltipProvider>
447445
<Tooltip>
@@ -463,32 +461,49 @@ const ChatInput = ({
463461
{selectedModel?.capabilities?.includes('tools') &&
464462
hasActiveMCPServers && (
465463
<TooltipProvider>
466-
<Tooltip>
467-
<TooltipTrigger asChild>
468-
<div>
464+
<Tooltip
465+
open={tooltipToolsAvailable}
466+
onOpenChange={setTooltipToolsAvailable}
467+
>
468+
<TooltipTrigger
469+
asChild
470+
disabled={dropdownToolsAvailable}
471+
>
472+
<div
473+
onClick={(e) => {
474+
setDropdownToolsAvailable(false)
475+
e.stopPropagation()
476+
}}
477+
>
469478
<DropdownToolsAvailable
470479
initialMessage={initialMessage}
471480
>
472-
{(isOpen, toolsCount) => (
473-
<div
474-
className={cn(
475-
'h-6 p-1 flex items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1 cursor-pointer relative',
476-
isOpen && 'bg-main-view-fg/10'
477-
)}
478-
>
479-
<IconTool
480-
size={18}
481-
className="text-main-view-fg/50"
482-
/>
483-
{toolsCount > 0 && (
484-
<div className="absolute -top-1 -right-1.5 bg-accent text-accent-fg text-xs rounded-full size-4 flex items-center justify-center font-medium">
485-
<span className="leading-0">
486-
{toolsCount > 99 ? '99+' : toolsCount}
487-
</span>
488-
</div>
489-
)}
490-
</div>
491-
)}
481+
{(isOpen, toolsCount) => {
482+
setDropdownToolsAvailable(isOpen)
483+
if (tooltipToolsAvailable && isOpen) {
484+
setTooltipToolsAvailable(false)
485+
}
486+
return (
487+
<div
488+
className={cn(
489+
'h-6 p-1 flex items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1 cursor-pointer relative',
490+
isOpen && 'bg-main-view-fg/10'
491+
)}
492+
>
493+
<IconTool
494+
size={18}
495+
className="text-main-view-fg/50"
496+
/>
497+
{toolsCount > 0 && (
498+
<div className="absolute -top-2 -right-2 bg-accent text-accent-fg text-xs rounded-full size-5 flex items-center justify-center font-medium">
499+
<span className="leading-0 text-xs">
500+
{toolsCount > 99 ? '99+' : toolsCount}
501+
</span>
502+
</div>
503+
)}
504+
</div>
505+
)
506+
}}
492507
</DropdownToolsAvailable>
493508
</div>
494509
</TooltipTrigger>
@@ -498,7 +513,6 @@ const ChatInput = ({
498513
</Tooltip>
499514
</TooltipProvider>
500515
)}
501-
502516
{selectedModel?.capabilities?.includes('web_search') && (
503517
<TooltipProvider>
504518
<Tooltip>
@@ -516,7 +530,6 @@ const ChatInput = ({
516530
</Tooltip>
517531
</TooltipProvider>
518532
)}
519-
520533
{selectedModel?.capabilities?.includes('reasoning') && (
521534
<TooltipProvider>
522535
<Tooltip>

web-app/src/containers/DropdownToolsAvailable.tsx

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,36 +99,34 @@ export default function DropdownToolsAvailable({
9999
<DropdownMenu onOpenChange={setIsOpen}>
100100
<DropdownMenuTrigger asChild>{renderTrigger()}</DropdownMenuTrigger>
101101

102-
<DropdownMenuContent
103-
side="top"
104-
align="start"
105-
className="max-w-64 max-h-64 "
106-
>
102+
<DropdownMenuContent side="top" align="start" className="max-w-64">
107103
<DropdownMenuLabel className="flex items-center gap-2 sticky -top-1 z-10 bg-main-view px-4 pl-2 py-2">
108104
Available Tools
109105
</DropdownMenuLabel>
110106
<DropdownMenuSeparator />
111-
<div>
107+
<div className="max-h-64 overflow-y-auto">
112108
{tools.map((tool) => {
113109
const isChecked = isToolChecked(tool.name)
114110
return (
115111
<div
116112
key={tool.name}
117-
className="px-2 py-2 hover:bg-main-view-fg/5 rounded-sm"
113+
className="py-2 hover:bg-main-view-fg/5 rounded-sm px-2 mx-auto w-full"
118114
>
119-
<div className="flex items-start justify-between gap-3">
120-
<div className="flex-1 min-w-0">
121-
<div className="flex items-start justify-between gap-4">
122-
<div>
123-
<h4 className="text-sm font-medium line-clamp-1">
115+
<div className="flex items-start justify-center gap-3">
116+
<div className="flex items-start justify-between gap-4 w-full">
117+
<div className="overflow-hidden w-full flex flex-col ">
118+
<div className="truncate">
119+
<span className="text-sm font-medium" title={tool.name}>
124120
{tool.name}
125-
</h4>
126-
{tool.description && (
127-
<p className="text-xs text-main-view-fg/70 mt-1 line-clamp-2">
128-
{tool.description}
129-
</p>
130-
)}
121+
</span>
131122
</div>
123+
{tool.description && (
124+
<p className="text-xs text-main-view-fg/70 mt-1 line-clamp-2">
125+
{tool.description}
126+
</p>
127+
)}
128+
</div>
129+
<div className="shrink-0 mx-auto">
132130
<Switch
133131
checked={isChecked}
134132
onCheckedChange={(checked) =>

web-app/src/containers/ProvidersMenu.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ const ProvidersMenu = ({
9696
}
9797
>
9898
<ProvidersAvatar provider={provider} />
99-
<span>{getProviderTitle(provider.provider)}</span>
99+
<div className="truncate">
100+
<span>{getProviderTitle(provider.provider)}</span>
101+
</div>
100102
</div>
101103
</div>
102104
)

web-app/src/containers/RenderMarkdown.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ function RenderMarkdownComponent({
8080
{getReadableLanguageName(language)}
8181
</span>
8282
<button
83-
onClick={() => handleCopy(code, codeId)}
83+
onClick={(e) => {
84+
e.stopPropagation()
85+
handleCopy(code, codeId)
86+
}}
8487
className="flex items-center gap-1 text-xs font-sans transition-colors cursor-pointer"
8588
>
8689
{copiedId === codeId ? (

0 commit comments

Comments
 (0)