Bladeren bron

fix: tool params not work as expected when develop a tool (#6550)

非法操作 9 maanden geleden
bovenliggende
commit
c0ada940bd

+ 1 - 1
api/core/tools/utils/tool_parameter_converter.py

@@ -53,7 +53,7 @@ class ToolParameterConverter:
                 case ToolParameter.ToolParameterType.NUMBER:
                     if isinstance(value, int) | isinstance(value, float):
                         return value
-                    elif isinstance(value, str):
+                    elif isinstance(value, str) and value != '':
                         if '.' in value:
                             return float(value)
                         else:

+ 62 - 0
web/app/components/workflow/nodes/_base/components/variable/constant-field.tsx

@@ -0,0 +1,62 @@
+'use client'
+import type { FC } from 'react'
+import React, { useCallback } from 'react'
+import type { CredentialFormSchema, CredentialFormSchemaNumberInput, CredentialFormSchemaSelect } 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 { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
+import type { Var } from '@/app/components/workflow/types'
+import { SimpleSelect } from '@/app/components/base/select'
+
+type Props = {
+  schema: CredentialFormSchema
+  readonly: boolean
+  value: string
+  onChange: (value: string | number, varKindType: VarKindType, varInfo?: Var) => void
+}
+
+const ConstantField: FC<Props> = ({
+  schema,
+  readonly,
+  value,
+  onChange,
+}) => {
+  const language = useLanguage()
+  const placeholder = (schema as CredentialFormSchemaSelect).placeholder
+  const handleStaticChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
+    const value = e.target.value === '' ? '' : parseFloat(e.target.value)
+    onChange(value, VarKindType.constant)
+  }, [onChange])
+  const handleSelectChange = useCallback((value: string | number) => {
+    value = value === null ? '' : value
+    onChange(value as string, VarKindType.constant)
+  }, [onChange])
+
+  return (
+    <>
+      {schema.type === FormTypeEnum.select && (
+        <SimpleSelect
+          wrapperClassName='w-full !h-8'
+          className='flex items-center'
+          disabled={readonly}
+          items={(schema as CredentialFormSchemaSelect).options.map(option => ({ value: option.value, name: option.label[language] || option.label.en_US }))}
+          onSelect={item => handleSelectChange(item.value)}
+          placeholder={placeholder?.[language] || placeholder?.en_US}
+        />
+      )}
+      {schema.type === FormTypeEnum.textNumber && (
+        <input
+          type='number'
+          className='w-full h-8 leading-8 pl-0.5 bg-transparent text-[13px] font-normal text-gray-900 placeholder:text-gray-400 focus:outline-none overflow-hidden'
+          value={value}
+          onChange={handleStaticChange}
+          readOnly={readonly}
+          placeholder={placeholder?.[language] || placeholder?.en_US}
+          min={(schema as CredentialFormSchemaNumberInput).min}
+          max={(schema as CredentialFormSchemaNumberInput).max}
+        />
+      )}
+    </>
+  )
+}
+export default React.memo(ConstantField)

+ 9 - 12
web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx

@@ -10,8 +10,10 @@ import produce from 'immer'
 import { useStoreApi } from 'reactflow'
 import VarReferencePopup from './var-reference-popup'
 import { getNodeInfoById, isENV, isSystemVar } from './utils'
+import ConstantField from './constant-field'
 import cn from '@/utils/classnames'
 import type { Node, NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
+import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations'
 import { BlockEnum } from '@/app/components/workflow/types'
 import { VarBlockIcon } from '@/app/components/workflow/block-icon'
 import { Line3 } from '@/app/components/base/icons/src/public/common'
@@ -47,6 +49,7 @@ type Props = {
   availableNodes?: Node[]
   availableVars?: NodeOutPutVar[]
   isAddBtnTrigger?: boolean
+  schema?: CredentialFormSchema
 }
 
 const VarReferencePicker: FC<Props> = ({
@@ -64,6 +67,7 @@ const VarReferencePicker: FC<Props> = ({
   availableNodes: passedInAvailableNodes,
   availableVars,
   isAddBtnTrigger,
+  schema,
 }) => {
   const { t } = useTranslation()
   const store = useStoreApi()
@@ -192,10 +196,6 @@ const VarReferencePicker: FC<Props> = ({
     setOpen(false)
   }, [onChange, varKindType])
 
-  const handleStaticChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
-    onChange(e.target.value as string, varKindType)
-  }, [onChange, varKindType])
-
   const handleClearVar = useCallback(() => {
     if (varKindType === VarKindType.constant)
       onChange('', varKindType)
@@ -265,14 +265,11 @@ const VarReferencePicker: FC<Props> = ({
                 </div>)}
               {isConstant
                 ? (
-                  <input
-                    type='text'
-                    className='w-full h-8 leading-8 pl-0.5 bg-transparent text-[13px] font-normal text-gray-900 placeholder:text-gray-400 focus:outline-none overflow-hidden'
-                    value={isConstant ? value : ''}
-                    onChange={handleStaticChange}
-                    onFocus={() => setIsFocus(true)}
-                    onBlur={() => setIsFocus(false)}
-                    readOnly={readonly}
+                  <ConstantField
+                    value={value as string}
+                    onChange={onChange as ((value: string | number, varKindType: VarKindType, varInfo?: Var) => void)}
+                    schema={schema as CredentialFormSchema}
+                    readonly={readonly}
                   />
                 )
                 : (

+ 16 - 10
web/app/components/workflow/nodes/tool/components/input-var-list.tsx

@@ -48,6 +48,8 @@ const InputVarList: FC<Props> = ({
       return 'Number'
     else if (type === FormTypeEnum.files)
       return 'Files'
+    else if (type === FormTypeEnum.select)
+      return 'Options'
     else
       return 'String'
   }
@@ -114,17 +116,19 @@ const InputVarList: FC<Props> = ({
   return (
     <div className='space-y-3'>
       {
-        schema.map(({
-          variable,
-          label,
-          type,
-          required,
-          tooltip,
-        }, index) => {
+        schema.map((schema, index) => {
+          const {
+            variable,
+            label,
+            type,
+            required,
+            tooltip,
+          } = schema
           const varInput = value[variable]
           const isNumber = type === FormTypeEnum.textNumber
+          const isSelect = type === FormTypeEnum.select
           const isFile = type === FormTypeEnum.files
-          const isString = type !== FormTypeEnum.textNumber && type !== FormTypeEnum.files
+          const isString = type !== FormTypeEnum.textNumber && type !== FormTypeEnum.files && type !== FormTypeEnum.select
           return (
             <div key={variable} className='space-y-1'>
               <div className='flex items-center h-[18px] space-x-2'>
@@ -145,7 +149,7 @@ const InputVarList: FC<Props> = ({
                   placeholderClassName='!leading-[21px]'
                 />
               )}
-              {isNumber && (
+              {(isNumber || isSelect) && (
                 <VarReferencePicker
                   readonly={readOnly}
                   isShowNodeName
@@ -155,7 +159,9 @@ const InputVarList: FC<Props> = ({
                   onOpen={handleOpen(index)}
                   isSupportConstantValue={isSupportConstantValue}
                   defaultVarKindType={varInput?.type}
-                  filterVar={filterVar}
+                  filterVar={isNumber ? filterVar : undefined}
+                  availableVars={isSelect ? availableVars : undefined}
+                  schema={schema}
                 />
               )}
               {isFile && (