fix: tools call available dropdown (#5222)

This commit is contained in:
Faisal Amir 2025-06-09 20:58:09 +07:00 committed by GitHub
parent 919b6671a1
commit c41a6c3899
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 66 additions and 50 deletions

View File

@ -64,6 +64,8 @@ const ChatInput = ({
const { selectedModel } = useModelProvider()
const { sendMessage } = useChat()
const [message, setMessage] = useState('')
const [dropdownToolsAvailable, setDropdownToolsAvailable] = useState(false)
const [tooltipToolsAvailable, setTooltipToolsAvailable] = useState(false)
const [uploadedFiles, setUploadedFiles] = useState<
Array<{
name: string
@ -407,7 +409,6 @@ const ChatInput = ({
useLastUsedModel={initialMessage}
/>
)}
{/* File attachment - always available */}
<div
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 = ({
onChange={handleFileChange}
/>
</div>
{/* Microphone - always available - Temp Hide */}
{/* <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">
<IconMicrophone size={18} className="text-main-view-fg/50" />
</div> */}
{selectedModel?.capabilities?.includes('vision') && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<TooltipTrigger disabled={dropdownToolsAvailable}>
<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">
<IconEye size={18} className="text-main-view-fg/50" />
</div>
@ -441,7 +440,6 @@ const ChatInput = ({
</Tooltip>
</TooltipProvider>
)}
{selectedModel?.capabilities?.includes('embeddings') && (
<TooltipProvider>
<Tooltip>
@ -463,32 +461,49 @@ const ChatInput = ({
{selectedModel?.capabilities?.includes('tools') &&
hasActiveMCPServers && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div>
<Tooltip
open={tooltipToolsAvailable}
onOpenChange={setTooltipToolsAvailable}
>
<TooltipTrigger
asChild
disabled={dropdownToolsAvailable}
>
<div
onClick={(e) => {
setDropdownToolsAvailable(false)
e.stopPropagation()
}}
>
<DropdownToolsAvailable
initialMessage={initialMessage}
>
{(isOpen, toolsCount) => (
<div
className={cn(
'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',
isOpen && 'bg-main-view-fg/10'
)}
>
<IconTool
size={18}
className="text-main-view-fg/50"
/>
{toolsCount > 0 && (
<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">
<span className="leading-0">
{toolsCount > 99 ? '99+' : toolsCount}
</span>
</div>
)}
</div>
)}
{(isOpen, toolsCount) => {
setDropdownToolsAvailable(isOpen)
if (tooltipToolsAvailable && isOpen) {
setTooltipToolsAvailable(false)
}
return (
<div
className={cn(
'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',
isOpen && 'bg-main-view-fg/10'
)}
>
<IconTool
size={18}
className="text-main-view-fg/50"
/>
{toolsCount > 0 && (
<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">
<span className="leading-0 text-xs">
{toolsCount > 99 ? '99+' : toolsCount}
</span>
</div>
)}
</div>
)
}}
</DropdownToolsAvailable>
</div>
</TooltipTrigger>
@ -498,7 +513,6 @@ const ChatInput = ({
</Tooltip>
</TooltipProvider>
)}
{selectedModel?.capabilities?.includes('web_search') && (
<TooltipProvider>
<Tooltip>
@ -516,7 +530,6 @@ const ChatInput = ({
</Tooltip>
</TooltipProvider>
)}
{selectedModel?.capabilities?.includes('reasoning') && (
<TooltipProvider>
<Tooltip>

View File

@ -99,36 +99,34 @@ export default function DropdownToolsAvailable({
<DropdownMenu onOpenChange={setIsOpen}>
<DropdownMenuTrigger asChild>{renderTrigger()}</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="start"
className="max-w-64 max-h-64 "
>
<DropdownMenuContent side="top" align="start" className="max-w-64">
<DropdownMenuLabel className="flex items-center gap-2 sticky -top-1 z-10 bg-main-view px-4 pl-2 py-2">
Available Tools
</DropdownMenuLabel>
<DropdownMenuSeparator />
<div>
<div className="max-h-64 overflow-y-auto">
{tools.map((tool) => {
const isChecked = isToolChecked(tool.name)
return (
<div
key={tool.name}
className="px-2 py-2 hover:bg-main-view-fg/5 rounded-sm"
className="py-2 hover:bg-main-view-fg/5 rounded-sm px-2 mx-auto w-full"
>
<div className="flex items-start justify-between gap-3">
<div className="flex-1 min-w-0">
<div className="flex items-start justify-between gap-4">
<div>
<h4 className="text-sm font-medium line-clamp-1">
<div className="flex items-start justify-center gap-3">
<div className="flex items-start justify-between gap-4 w-full">
<div className="overflow-hidden w-full flex flex-col ">
<div className="truncate">
<span className="text-sm font-medium" title={tool.name}>
{tool.name}
</h4>
{tool.description && (
<p className="text-xs text-main-view-fg/70 mt-1 line-clamp-2">
{tool.description}
</p>
)}
</span>
</div>
{tool.description && (
<p className="text-xs text-main-view-fg/70 mt-1 line-clamp-2">
{tool.description}
</p>
)}
</div>
<div className="shrink-0 mx-auto">
<Switch
checked={isChecked}
onCheckedChange={(checked) =>

View File

@ -96,7 +96,9 @@ const ProvidersMenu = ({
}
>
<ProvidersAvatar provider={provider} />
<span>{getProviderTitle(provider.provider)}</span>
<div className="truncate">
<span>{getProviderTitle(provider.provider)}</span>
</div>
</div>
</div>
)

View File

@ -80,7 +80,10 @@ function RenderMarkdownComponent({
{getReadableLanguageName(language)}
</span>
<button
onClick={() => handleCopy(code, codeId)}
onClick={(e) => {
e.stopPropagation()
handleCopy(code, codeId)
}}
className="flex items-center gap-1 text-xs font-sans transition-colors cursor-pointer"
>
{copiedId === codeId ? (