mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
feat(tools): added reordering of tool calls in agent tool input (#629)
* added tool re-ordering in agent block * styling
This commit is contained in:
+83
-2
@@ -347,6 +347,8 @@ export function ToolInput({
|
||||
const [customToolModalOpen, setCustomToolModalOpen] = useState(false)
|
||||
const [editingToolIndex, setEditingToolIndex] = useState<number | null>(null)
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [draggedIndex, setDraggedIndex] = useState<number | null>(null)
|
||||
const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)
|
||||
const isWide = useWorkflowStore((state) => state.blocks[blockId]?.isWide)
|
||||
const customTools = useCustomToolsStore((state) => state.getAllTools())
|
||||
const subBlockStore = useSubBlockStore()
|
||||
@@ -668,6 +670,46 @@ export function ToolInput({
|
||||
)
|
||||
}
|
||||
|
||||
const handleDragStart = (e: React.DragEvent, index: number) => {
|
||||
if (isPreview || disabled) return
|
||||
setDraggedIndex(index)
|
||||
e.dataTransfer.effectAllowed = 'move'
|
||||
e.dataTransfer.setData('text/html', '')
|
||||
}
|
||||
|
||||
const handleDragOver = (e: React.DragEvent, index: number) => {
|
||||
if (isPreview || disabled || draggedIndex === null) return
|
||||
e.preventDefault()
|
||||
e.dataTransfer.dropEffect = 'move'
|
||||
setDragOverIndex(index)
|
||||
}
|
||||
|
||||
const handleDragEnd = () => {
|
||||
setDraggedIndex(null)
|
||||
setDragOverIndex(null)
|
||||
}
|
||||
|
||||
const handleDrop = (e: React.DragEvent, dropIndex: number) => {
|
||||
if (isPreview || disabled || draggedIndex === null || draggedIndex === dropIndex) return
|
||||
e.preventDefault()
|
||||
|
||||
const newTools = [...selectedTools]
|
||||
const draggedTool = newTools[draggedIndex]
|
||||
|
||||
newTools.splice(draggedIndex, 1)
|
||||
|
||||
if (dropIndex === selectedTools.length) {
|
||||
newTools.push(draggedTool)
|
||||
} else {
|
||||
const adjustedDropIndex = draggedIndex < dropIndex ? dropIndex - 1 : dropIndex
|
||||
newTools.splice(adjustedDropIndex, 0, draggedTool)
|
||||
}
|
||||
|
||||
setStoreValue(newTools)
|
||||
setDraggedIndex(null)
|
||||
setDragOverIndex(null)
|
||||
}
|
||||
|
||||
const IconComponent = ({ icon: Icon, className }: { icon: any; className?: string }) => {
|
||||
if (!Icon) return null
|
||||
return <Icon className={className} />
|
||||
@@ -827,9 +869,34 @@ export function ToolInput({
|
||||
return (
|
||||
<div
|
||||
key={`${tool.type}-${toolIndex}`}
|
||||
className={cn('group flex flex-col', isWide ? 'w-[calc(50%-0.25rem)]' : 'w-full')}
|
||||
className={cn(
|
||||
'group relative flex flex-col transition-all duration-200 ease-in-out',
|
||||
isWide ? 'w-[calc(50%-0.25rem)]' : 'w-full',
|
||||
draggedIndex === toolIndex ? 'scale-95 opacity-40' : '',
|
||||
dragOverIndex === toolIndex && draggedIndex !== toolIndex && draggedIndex !== null
|
||||
? 'translate-y-1 transform'
|
||||
: '',
|
||||
selectedTools.length > 1 && !isPreview && !disabled
|
||||
? 'cursor-grab active:cursor-grabbing'
|
||||
: ''
|
||||
)}
|
||||
draggable={!isPreview && !disabled}
|
||||
onDragStart={(e) => handleDragStart(e, toolIndex)}
|
||||
onDragOver={(e) => handleDragOver(e, toolIndex)}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDrop={(e) => handleDrop(e, toolIndex)}
|
||||
>
|
||||
<div className='flex flex-col overflow-visible rounded-md border bg-card'>
|
||||
{/* Subtle drop indicator - use border highlight instead of separate line */}
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col overflow-visible rounded-md border bg-card',
|
||||
dragOverIndex === toolIndex &&
|
||||
draggedIndex !== toolIndex &&
|
||||
draggedIndex !== null
|
||||
? 'border-t-2 border-t-muted-foreground/40'
|
||||
: ''
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'flex items-center justify-between bg-accent/50 p-2',
|
||||
@@ -1091,6 +1158,20 @@ export function ToolInput({
|
||||
)
|
||||
})}
|
||||
|
||||
{/* Drop zone for the end of the list */}
|
||||
{selectedTools.length > 0 && draggedIndex !== null && (
|
||||
<div
|
||||
className={cn(
|
||||
'h-2 w-full rounded transition-all duration-200 ease-in-out',
|
||||
dragOverIndex === selectedTools.length
|
||||
? 'border-b-2 border-b-muted-foreground/40'
|
||||
: ''
|
||||
)}
|
||||
onDragOver={(e) => handleDragOver(e, selectedTools.length)}
|
||||
onDrop={(e) => handleDrop(e, selectedTools.length)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user