Переглянути джерело

fix: can add a custom tool without a name (#6172)

非法操作 9 місяців тому
батько
коміт
27d72e30ad

+ 18 - 2
web/app/components/tools/edit-custom-collection-modal/index.tsx

@@ -17,6 +17,7 @@ import EmojiPicker from '@/app/components/base/emoji-picker'
 import AppIcon from '@/app/components/base/app-icon'
 import { parseParamsSchema } from '@/service/tools'
 import LabelSelector from '@/app/components/tools/labels/selector'
+import Toast from '@/app/components/base/toast'
 
 const fieldNameClassNames = 'py-2 leading-5 text-sm font-medium text-gray-900'
 type Props = {
@@ -136,6 +137,21 @@ const EditCustomCollectionModal: FC<Props> = ({
       draft.labels = labels
     })
 
+    let errorMessage = ''
+    if (!postData.provider)
+      errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') })
+
+    if (!postData.schema)
+      errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.schema') })
+
+    if (errorMessage) {
+      Toast.notify({
+        type: 'error',
+        message: errorMessage,
+      })
+      return
+    }
+
     if (isAdd) {
       onAdd?.(postData)
       return
@@ -175,7 +191,7 @@ const EditCustomCollectionModal: FC<Props> = ({
           <div className='flex flex-col h-full'>
             <div className='grow h-0 overflow-y-auto px-6 py-3 space-y-4'>
               <div>
-                <div className={fieldNameClassNames}>{t('tools.createTool.name')}</div>
+                <div className={fieldNameClassNames}>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
                 <div className='flex items-center justify-between gap-3'>
                   <AppIcon size='large' onClick={() => { setShowEmojiPicker(true) }} className='cursor-pointer' icon={emoji.content} background={emoji.background} />
                   <input
@@ -195,7 +211,7 @@ const EditCustomCollectionModal: FC<Props> = ({
               <div className='select-none'>
                 <div className='flex justify-between items-center'>
                   <div className='flex items-center'>
-                    <div className={fieldNameClassNames}>{t('tools.createTool.schema')}</div>
+                    <div className={fieldNameClassNames}>{t('tools.createTool.schema')}<span className='ml-1 text-red-500'>*</span></div>
                     <div className='mx-2 w-px h-3 bg-black/5'></div>
                     <a
                       href="https://swagger.io/specification/"

+ 23 - 19
web/app/components/tools/workflow-tool/index.tsx

@@ -63,28 +63,32 @@ const WorkflowToolAsModal: FC<Props> = ({
   const [showModal, setShowModal] = useState(false)
 
   const isNameValid = (name: string) => {
+    // when the user has not input anything, no need for a warning
+    if (name === '')
+      return true
+
     return /^[a-zA-Z0-9_]+$/.test(name)
   }
 
   const onConfirm = () => {
-    if (!label) {
-      return Toast.notify({
-        type: 'error',
-        message: 'Please enter the tool name',
-      })
-    }
-    if (!name) {
-      return Toast.notify({
-        type: 'error',
-        message: 'Please enter the name for tool call',
-      })
-    }
-    else if (!isNameValid(name)) {
-      return Toast.notify({
+    let errorMessage = ''
+    if (!label)
+      errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.name') })
+
+    if (!name)
+      errorMessage = t('common.errorMsg.fieldRequired', { field: t('tools.createTool.nameForToolCall') })
+
+    if (!isNameValid(name))
+      errorMessage = t('tools.createTool.nameForToolCall') + t('tools.createTool.nameForToolCallTip')
+
+    if (errorMessage) {
+      Toast.notify({
         type: 'error',
-        message: 'Name for tool call can only contain numbers, letters, and underscores',
+        message: errorMessage,
       })
+      return
     }
+
     const requestParams = {
       name,
       description,
@@ -127,7 +131,7 @@ const WorkflowToolAsModal: FC<Props> = ({
             <div className='grow h-0 overflow-y-auto px-6 py-3 space-y-4'>
               {/* name & icon */}
               <div>
-                <div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.name')}</div>
+                <div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
                 <div className='flex items-center justify-between gap-3'>
                   <AppIcon size='large' onClick={() => { setShowEmojiPicker(true) }} className='cursor-pointer' icon={emoji.content} background={emoji.background} />
                   <input
@@ -142,7 +146,7 @@ const WorkflowToolAsModal: FC<Props> = ({
               {/* name for tool call */}
               <div>
                 <div className='flex items-center py-2 leading-5 text-sm font-medium text-gray-900'>
-                  {t('tools.createTool.nameForToolCall')}
+                  {t('tools.createTool.nameForToolCall')} <span className='ml-1 text-red-500'>*</span>
                   <Tooltip
                     htmlContent={
                       <div className='w-[180px]'>
@@ -162,7 +166,7 @@ const WorkflowToolAsModal: FC<Props> = ({
                   onChange={e => setName(e.target.value)}
                 />
                 {!isNameValid(name) && (
-                  <div className='text-xs leading-[18px] text-[#DC6803]'>{t('tools.createTool.nameForToolCallTip')}</div>
+                  <div className='text-xs leading-[18px] text-red-500'>{t('tools.createTool.nameForToolCallTip')}</div>
                 )}
               </div>
               {/* description */}
@@ -248,7 +252,7 @@ const WorkflowToolAsModal: FC<Props> = ({
               )}
               <div className='flex space-x-2 '>
                 <Button onClick={onHide}>{t('common.operation.cancel')}</Button>
-                <Button disabled={!label || !name || !isNameValid(name)} variant='primary' onClick={() => {
+                <Button variant='primary' onClick={() => {
                   if (isAdd)
                     onConfirm()
                   else