浏览代码

feat: add context missing warning (#1384)

Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
Joel 1 年之前
父节点
当前提交
08aa367892

+ 61 - 35
web/app/components/app/configuration/config-prompt/advanced-prompt-input.tsx

@@ -18,6 +18,7 @@ import PromptEditor from '@/app/components/base/prompt-editor'
 import ConfigContext from '@/context/debug-configuration'
 import { getNewVar, getVars } from '@/utils/var'
 import { AppType } from '@/types/app'
+import { AlertCircle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
 
 type Props = {
   type: PromptRole
@@ -28,6 +29,8 @@ type Props = {
   canDelete: boolean
   onDelete: () => void
   promptVariables: PromptVariable[]
+  isContextMissing: boolean
+  onHideContextMissingTip: () => void
 }
 
 const AdvancedPromptInput: FC<Props> = ({
@@ -39,6 +42,8 @@ const AdvancedPromptInput: FC<Props> = ({
   canDelete,
   onDelete,
   promptVariables,
+  isContextMissing,
+  onHideContextMissingTip,
 }) => {
   const { t } = useTranslation()
 
@@ -91,50 +96,71 @@ const AdvancedPromptInput: FC<Props> = ({
   }
 
   const editorHeight = isChatMode ? 'h-[200px]' : 'h-[508px]'
-
+  const contextMissing = (
+    <div
+      className='flex justify-between items-center h-11 pt-2 pr-3 pb-1 pl-4 rounded-tl-xl rounded-tr-xl'
+      style={{
+        background: 'linear-gradient(180deg, #FEF0C7 0%, rgba(254, 240, 199, 0) 100%)',
+      }}
+    >
+      <div className='flex items-center pr-2' >
+        <AlertCircle className='mr-1 w-4 h-4 text-[#F79009]'/>
+        <div className='leading-[18px] text-[13px] font-medium text-[#DC6803]'>{t('appDebug.promptMode.contextMissing')}</div>
+      </div>
+      <div
+        className='flex items-center h-6 px-2 rounded-md bg-[#fff] border border-gray-200 shadow-xs text-xs font-medium text-primary-600 cursor-pointer'
+        onClick={onHideContextMissingTip}
+      >{t('common.operation.ok')}</div>
+    </div>
+  )
   return (
-    <div className={`relative ${s.gradientBorder}`}>
+    <div className={`relative ${!isContextMissing ? s.gradientBorder : s.warningBorder}`}>
       <div className='rounded-xl bg-white'>
-        <div className={cn(s.boxHeader, 'flex justify-between items-center h-11 pt-2 pr-3 pb-1 pl-4 rounded-tl-xl rounded-tr-xl bg-white hover:shadow-xs')}>
-          {isChatMode
-            ? (
-              <MessageTypeSelector value={type} onChange={onTypeChange} />
-            )
-            : (
-              <div className='flex items-center space-x-1'>
+        {isContextMissing
+          ? contextMissing
+          : (
+            <div className={cn(s.boxHeader, 'flex justify-between items-center h-11 pt-2 pr-3 pb-1 pl-4 rounded-tl-xl rounded-tr-xl bg-white hover:shadow-xs')}>
+              {isChatMode
+                ? (
+                  <MessageTypeSelector value={type} onChange={onTypeChange} />
+                )
+                : (
+                  <div className='flex items-center space-x-1'>
 
-                <div className='text-sm font-semibold uppercase text-indigo-800'>{t('appDebug.pageTitle.line1')}
-                </div>
-                <Tooltip
-                  htmlContent={<div className='w-[180px]'>
-                    {t('appDebug.promptTip')}
-                  </div>}
-                  selector='config-prompt-tooltip'>
-                  <HelpCircle className='w-[14px] h-[14px] text-indigo-400' />
-                </Tooltip>
-              </div>)}
-          <div className={cn(s.optionWrap, 'items-center space-x-1')}>
-            {canDelete && (
-              <Trash03 onClick={onDelete} className='h-6 w-6 p-1 text-gray-500 cursor-pointer' />
-            )}
-            {!isCopied
-              ? (
-                <Clipboard className='h-6 w-6 p-1 text-gray-500 cursor-pointer' onClick={() => {
-                  copy(value)
-                  setIsCopied(true)
-                }} />
-              )
-              : (
-                <ClipboardCheck className='h-6 w-6 p-1 text-gray-500' />
-              )}
+                    <div className='text-sm font-semibold uppercase text-indigo-800'>{t('appDebug.pageTitle.line1')}
+                    </div>
+                    <Tooltip
+                      htmlContent={<div className='w-[180px]'>
+                        {t('appDebug.promptTip')}
+                      </div>}
+                      selector='config-prompt-tooltip'>
+                      <HelpCircle className='w-[14px] h-[14px] text-indigo-400' />
+                    </Tooltip>
+                  </div>)}
+              <div className={cn(s.optionWrap, 'items-center space-x-1')}>
+                {canDelete && (
+                  <Trash03 onClick={onDelete} className='h-6 w-6 p-1 text-gray-500 cursor-pointer' />
+                )}
+                {!isCopied
+                  ? (
+                    <Clipboard className='h-6 w-6 p-1 text-gray-500 cursor-pointer' onClick={() => {
+                      copy(value)
+                      setIsCopied(true)
+                    }} />
+                  )
+                  : (
+                    <ClipboardCheck className='h-6 w-6 p-1 text-gray-500' />
+                  )}
+              </div>
+            </div>
+          )}
 
-          </div>
-        </div>
         <div className={cn(editorHeight, 'px-4 min-h-[102px] overflow-y-auto text-sm text-gray-700')}>
           <PromptEditor
             className={editorHeight}
             value={value}
             contextBlock={{
+              show: true,
               selectable: !hasSetBlockStatus.context,
               datasets: dataSets.map(item => ({
                 id: item.id,

+ 9 - 0
web/app/components/app/configuration/config-prompt/index.tsx

@@ -34,6 +34,8 @@ const Prompt: FC<IPromptProps> = ({
     currentAdvancedPrompt,
     setCurrentAdvancedPrompt,
     modelModeType,
+    dataSets,
+    hasSetBlockStatus,
   } = useContext(ConfigContext)
 
   const handleMessageTypeChange = (index: number, role: PromptRole) => {
@@ -84,6 +86,9 @@ const Prompt: FC<IPromptProps> = ({
     setCurrentAdvancedPrompt(newPrompt)
   }
 
+  const isContextMissing = dataSets.length > 0 && !hasSetBlockStatus.context
+  const [isHideContextMissTip, setIsHideContextMissTip] = React.useState(false)
+
   if (!isAdvancedMode) {
     return (
       <SimplePromptInput
@@ -112,6 +117,8 @@ const Prompt: FC<IPromptProps> = ({
                 onDelete={() => handlePromptDelete(index)}
                 onChange={value => handleValueChange(value, index)}
                 promptVariables={promptVariables}
+                isContextMissing={isContextMissing && !isHideContextMissTip}
+                onHideContextMissingTip={() => setIsHideContextMissTip(true)}
               />
             ))
           )
@@ -125,6 +132,8 @@ const Prompt: FC<IPromptProps> = ({
               onDelete={() => handlePromptDelete(0)}
               onChange={value => handleValueChange(value)}
               promptVariables={promptVariables}
+              isContextMissing={isContextMissing && !isHideContextMissTip}
+              onHideContextMissingTip={() => setIsHideContextMissTip(true)}
             />
           )
         }

+ 1 - 0
web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx

@@ -113,6 +113,7 @@ const Prompt: FC<ISimplePromptInput> = ({
             className='min-h-[210px]'
             value={promptTemplate}
             contextBlock={{
+              show: false,
               selectable: !hasSetBlockStatus.context,
               datasets: dataSets.map(item => ({
                 id: item.id,

+ 5 - 0
web/app/components/app/configuration/config-prompt/style.module.css

@@ -14,6 +14,11 @@
   box-sizing: border-box;
 }
 
+.warningBorder {
+  border: 2px solid #F79009;
+  border-radius: 12px;
+}
+
 .optionWrap {
   display: none;
 }

+ 20 - 11
web/app/components/base/prompt-editor/index.tsx

@@ -49,6 +49,7 @@ export type PromptEditorProps = {
   onChange?: (text: string) => void
   onBlur?: () => void
   contextBlock?: {
+    show?: boolean
     selectable?: boolean
     datasets: Dataset[]
     onInsert?: () => void
@@ -82,6 +83,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
   onChange,
   onBlur,
   contextBlock = {
+    show: true,
     selectable: true,
     datasets: [],
     onAddContext: () => {},
@@ -158,23 +160,30 @@ const PromptEditor: FC<PromptEditorProps> = ({
         />
         <ComponentPicker
           contextDisabled={!contextBlock.selectable}
+          contextShow={contextBlock.show}
           historyDisabled={!historyBlock.selectable}
           historyShow={historyBlock.show}
           queryDisabled={!queryBlock.selectable}
           queryShow={queryBlock.show}
         />
         <VariablePicker items={variableBlock.variables} />
-        <ContextBlock
-          datasets={contextBlock.datasets}
-          onAddContext={contextBlock.onAddContext}
-          onInsert={contextBlock.onInsert}
-          onDelete={contextBlock.onDelete}
-        />
-        <ContextBlockReplacementBlock
-          datasets={contextBlock.datasets}
-          onAddContext={contextBlock.onAddContext}
-          onInsert={contextBlock.onInsert}
-        />
+        {
+          contextBlock.show && (
+            <>
+              <ContextBlock
+                datasets={contextBlock.datasets}
+                onAddContext={contextBlock.onAddContext}
+                onInsert={contextBlock.onInsert}
+                onDelete={contextBlock.onDelete}
+              />
+              <ContextBlockReplacementBlock
+                datasets={contextBlock.datasets}
+                onAddContext={contextBlock.onAddContext}
+                onInsert={contextBlock.onInsert}
+              />
+            </>
+          )
+        }
         <VariableBlock />
         {
           historyBlock.show && (

+ 16 - 10
web/app/components/base/prompt-editor/plugins/component-picker.tsx

@@ -93,6 +93,7 @@ type ComponentPickerProps = {
   contextDisabled?: boolean
   historyDisabled?: boolean
   queryDisabled?: boolean
+  contextShow?: boolean
   historyShow?: boolean
   queryShow?: boolean
 }
@@ -100,6 +101,7 @@ const ComponentPicker: FC<ComponentPickerProps> = ({
   contextDisabled,
   historyDisabled,
   queryDisabled,
+  contextShow,
   historyShow,
   queryShow,
 }) => {
@@ -111,16 +113,20 @@ const ComponentPicker: FC<ComponentPickerProps> = ({
   })
 
   const options = [
-    new ComponentPickerOption(t('common.promptEditor.context.item.title'), {
-      desc: t('common.promptEditor.context.item.desc'),
-      icon: <File05 className='w-4 h-4 text-[#6938EF]' />,
-      onSelect: () => {
-        if (contextDisabled)
-          return
-        editor.dispatchCommand(INSERT_CONTEXT_BLOCK_COMMAND, undefined)
-      },
-      disabled: contextDisabled,
-    }),
+    ...contextShow
+      ? [
+        new ComponentPickerOption(t('common.promptEditor.context.item.title'), {
+          desc: t('common.promptEditor.context.item.desc'),
+          icon: <File05 className='w-4 h-4 text-[#6938EF]' />,
+          onSelect: () => {
+            if (contextDisabled)
+              return
+            editor.dispatchCommand(INSERT_CONTEXT_BLOCK_COMMAND, undefined)
+          },
+          disabled: contextDisabled,
+        }),
+      ]
+      : [],
     new ComponentPickerOption(t('common.promptEditor.variable.item.title'), {
       desc: t('common.promptEditor.variable.item.desc'),
       icon: <Variable className='w-4 h-4 text-[#2970FF]' />,

+ 1 - 0
web/i18n/lang/app-debug.en.ts

@@ -16,6 +16,7 @@ const translation = {
     operation: {
       addMessage: 'Add Message',
     },
+    contextMissing: 'Context component missed, the effectiveness of the prompt may not be good.',
   },
   operation: {
     applyConfig: 'Publish',

+ 1 - 0
web/i18n/lang/app-debug.zh.ts

@@ -16,6 +16,7 @@ const translation = {
     operation: {
       addMessage: '添加消息',
     },
+    contextMissing: '上下文内容块缺失,提示词的有效性可能不好。',
   },
   operation: {
     applyConfig: '发布',

+ 1 - 1
web/i18n/lang/common.zh.ts

@@ -136,7 +136,7 @@ const translation = {
     owner: '所有者',
     admin: '管理员',
     adminTip: '能够建立应用程序和管理团队设置',
-    normal: '正常人',
+    normal: '成员',
     normalTip: '只能使用应用程序,不能建立应用程序',
     inviteTeamMember: '添加团队成员',
     inviteTeamMemberTip: '对方在登录后可以访问你的团队数据。',