feat: agent node toolbox
This commit is contained in:
parent
0c5101fb3c
commit
a5509fbe5a
@ -1,30 +1,40 @@
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
import classNames from '@/utils/classnames'
|
||||
import { useRef } from 'react'
|
||||
import { useMemo, useRef } from 'react'
|
||||
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools'
|
||||
|
||||
export type ToolIconProps = {
|
||||
src: string
|
||||
alt?: string
|
||||
status?: 'error' | 'warning'
|
||||
tooltip?: string
|
||||
providerName: string
|
||||
}
|
||||
|
||||
export const ToolIcon = ({ src, status, tooltip, alt }: ToolIconProps) => {
|
||||
export const ToolIcon = ({ status, tooltip, providerName }: ToolIconProps) => {
|
||||
const indicator = status === 'error' ? 'red' : status === 'warning' ? 'yellow' : undefined
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const notSuccess = (['error', 'warning'] as Array<ToolIconProps['status']>).includes(status)
|
||||
const { data: buildInTools } = useAllBuiltInTools()
|
||||
const { data: customTools } = useAllCustomTools()
|
||||
const { data: workflowTools } = useAllWorkflowTools()
|
||||
const currentProvider = useMemo(() => {
|
||||
const mergedTools = [...(buildInTools || []), ...(customTools || []), ...(workflowTools || [])]
|
||||
return mergedTools.find((toolWithProvider) => {
|
||||
return toolWithProvider.name === providerName
|
||||
})
|
||||
}, [providerName, buildInTools, customTools, workflowTools])
|
||||
return <Tooltip triggerMethod='hover' popupContent={tooltip} disabled={!notSuccess}>
|
||||
<div className={classNames(
|
||||
'size-5 border-[0.5px] border-components-panel-border-subtle bg-background-default-dodge relative',
|
||||
'size-5 border-[0.5px] border-components-panel-border-subtle bg-background-default-dodge relative flex items-center justify-center rounded-[6px]',
|
||||
)}
|
||||
ref={containerRef}
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={src}
|
||||
alt={alt}
|
||||
src={currentProvider?.icon as string}
|
||||
alt='tool icon'
|
||||
className={classNames(
|
||||
'w-full h-full max-w-5 max-h-5 object-cover rounded-[6px]',
|
||||
'w-full h-full size-3.5 object-cover',
|
||||
notSuccess && 'opacity-50',
|
||||
)}
|
||||
/>
|
||||
|
@ -8,13 +8,11 @@ import type { ToolIconProps } from './components/tool-icon'
|
||||
import { ToolIcon } from './components/tool-icon'
|
||||
import useConfig from './use-config'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useInstalledPluginList } from '@/service/use-plugins'
|
||||
import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
|
||||
const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||
const { inputs, currentStrategy } = useConfig(props.id, props.data)
|
||||
const { t } = useTranslation()
|
||||
const pluginList = useInstalledPluginList()
|
||||
// TODO: Implement models
|
||||
const models = useMemo(() => {
|
||||
if (!inputs) return []
|
||||
@ -41,17 +39,28 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||
const tools = useMemo(() => {
|
||||
const tools: Array<ToolIconProps> = []
|
||||
currentStrategy?.parameters.forEach((param) => {
|
||||
if (['array[tool]', 'tool'].includes(param.type)) {
|
||||
const vari = inputs.agent_parameters?.[param.name]
|
||||
if (!vari) return
|
||||
if (Array.isArray(vari.value)) {
|
||||
// TODO: Implement array of tools
|
||||
if (param.type === FormTypeEnum.toolSelector) {
|
||||
const field = param.name
|
||||
const value = inputs.agent_parameters?.[field]
|
||||
if (value) {
|
||||
tools.push({
|
||||
providerName: value.provider_name,
|
||||
})
|
||||
}
|
||||
else {
|
||||
// TODO: Implement single tool
|
||||
}
|
||||
if (param.type === FormTypeEnum.multiToolSelector) {
|
||||
const field = param.name
|
||||
const value = inputs.agent_parameters?.[field]
|
||||
if (value) {
|
||||
(value as any[]).forEach((item) => {
|
||||
tools.push({
|
||||
providerName: item.provider_name,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
return tools
|
||||
}, [currentStrategy, inputs.agent_parameters])
|
||||
return <div className='mb-1 px-3 py-1 space-y-1'>
|
||||
{inputs.agent_strategy_name
|
||||
@ -89,19 +98,7 @@ const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||
{t('workflow.nodes.agent.toolbox')}
|
||||
</GroupLabel>}>
|
||||
<div className='grid grid-cols-10 gap-0.5'>
|
||||
<ToolIcon src='/logo/logo.png' />
|
||||
<ToolIcon
|
||||
src='/logo/logo.png'
|
||||
status='error'
|
||||
tooltip={t('workflow.nodes.agent.toolNotInstallTooltip', {
|
||||
tool: 'Gmail Sender',
|
||||
})} />
|
||||
<ToolIcon
|
||||
src='/logo/logo.png'
|
||||
status='warning'
|
||||
tooltip={t('workflow.nodes.agent.toolNotAuthorizedTooltip', {
|
||||
tool: 'DuckDuckGo AI Search',
|
||||
})} />
|
||||
{tools.map(tool => <ToolIcon {...tool} key={Math.random()} />)}
|
||||
</div>
|
||||
</Group>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user