Commit f51f4a58 authored by Joel's avatar Joel

feat: tool inputs

parent b5f3bbea
......@@ -31,7 +31,7 @@ const Filed: FC<Props> = ({
<div className={cn(inline && 'flex justify-between items-center')}>
<div className='flex justify-between items-center'>
<div className='flex items-center h-6'>
<div className='text-xs font-medium text-gray-700 uppercase'>{title}</div>
<div className='text-[13px] font-medium text-gray-700 uppercase'>{title}</div>
{tooltip && (
<TooltipPlus popupContent={
<div className='w-[120px]'>
......
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import produce from 'immer'
import type { ToolVarInput } from '../types'
import { VarType } from '../types'
import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
type Props = {
readOnly: boolean
schema: CredentialFormSchema[]
value: ToolVarInput[]
onChange: (value: ToolVarInput[]) => void
}
const InputVarList: FC<Props> = ({
readOnly,
schema,
value,
onChange,
}) => {
const language = useLanguage()
const keyValues = (() => {
const res: Record<string, ToolVarInput> = {}
value.forEach((item) => {
res[item.variable] = item
})
return res
})()
const handleChange = useCallback((variable: string) => {
return (varValue: any) => {
const newValue = produce(value, (draft: ToolVarInput[]) => {
const target = draft.find(item => item.variable === variable)
if (target) {
target.value_selector = varValue // TODO: support constant value
}
else {
draft.push({
variable,
variable_type: VarType.selector, // TODO: support constant value
value_selector: varValue,
})
}
})
onChange(newValue)
}
}, [value, onChange])
return (
<div className='space-y-3'>
{
schema.map(({
variable,
label,
type,
required,
tooltip,
}) => {
const varInput = keyValues[variable]
return (
<div key={variable} className='space-y-1'>
<div className='flex items-center h-[18px] space-x-2'>
<span className='text-[13px] font-medium text-gray-900'>{label[language] || label.en_US}</span>
<span className='text-xs font-normal text-gray-500'>{type === FormTypeEnum.textNumber ? 'Number' : 'String'}</span>
{required && <span className='leading-[18px] text-xs font-normal text-[#EC4A0A]'>Required</span>}
</div>
<VarReferencePicker
readonly={readOnly}
isShowNodeName
value={varInput?.value_selector || []} // TODO: support constant value
onChange={handleChange(variable)}
/>
{tooltip && <div className='leading-[18px] text-xs font-normal text-gray-600'>{tooltip[language] || tooltip.en_US}</div>}
</div>
)
})
}
</div>
)
}
export default React.memo(InputVarList)
......@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
import Split from '../_base/components/split'
import type { ToolNodeType } from './types'
import useConfig from './use-config'
import InputVarList from './components/input-var-list'
import Button from '@/app/components/base/button'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import type { NodePanelProps } from '@/app/components/workflow/types'
......@@ -20,6 +21,8 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
const {
inputs,
toolInputVarSchema,
setInputVar,
toolSettingSchema,
toolSettingValue,
setToolSettingValue,
......@@ -41,12 +44,22 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
)}
<div className='px-4 pb-4 space-y-4'>
<Field
title={t(`${i18nPrefix}.inputVars`)}
>
inputVars
</Field>
<Split />
{toolInputVarSchema.length > 0 && (
<>
<Field
title={t(`${i18nPrefix}.inputVars`)}
>
<InputVarList
readOnly={readOnly}
schema={toolInputVarSchema as any}
value={inputs.tool_inputs}
onChange={setInputVar}
/>
</Field>
<Split />
</>
)}
<Form
className='space-y-4'
itemClassName='!py-0'
......
import { useCallback, useEffect, useState } from 'react'
import type { ToolNodeType } from './types'
import type { ToolNodeType, ToolVarInput } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import { fetchBuiltInToolList, fetchCustomToolList } from '@/service/tools'
import type { Tool } from '@/app/components/tools/types'
......@@ -9,7 +9,7 @@ import { CollectionType } from '@/app/components/tools/types'
const useConfig = (id: string, payload: ToolNodeType) => {
const { inputs, setInputs } = useNodeCrud<ToolNodeType>(id, payload)
const { provider_id, provider_type, tool_name, tool_parameters } = inputs
const { provider_id, provider_name, provider_type, tool_name, tool_parameters } = inputs
const isBuiltIn = provider_type === CollectionType.builtIn
const [currTool, setCurrTool] = useState<Tool | null>(null)
const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : []
......@@ -26,21 +26,30 @@ const useConfig = (id: string, payload: ToolNodeType) => {
}, [inputs, setInputs])
// setting when call
const toolInputSchema = formSchemas.filter((item: any) => item.form === 'llm')
const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm')
const setInputVar = useCallback((value: ToolVarInput[]) => {
setInputs({
...inputs,
tool_inputs: value,
})
}, [inputs, setInputs])
useEffect(() => {
(async () => {
const list = isBuiltIn ? await fetchBuiltInToolList(provider_id) : await fetchCustomToolList(provider_id)
const list = isBuiltIn ? await fetchBuiltInToolList(provider_name || provider_id) : await fetchCustomToolList(provider_name)
const currTool = list.find(tool => tool.name === tool_name)
if (currTool)
setCurrTool(currTool)
})()
}, [provider_id])
}, [provider_name])
return {
inputs,
currTool,
toolSettingSchema,
toolSettingValue,
setToolSettingValue,
toolInputVarSchema,
setInputVar,
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment