feat: add context missing warning (#1384)

Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
This commit is contained in:
Joel 2023-10-19 17:52:14 +08:00 committed by GitHub
parent ff527a0190
commit 08aa367892
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 57 deletions

View File

@ -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,

View File

@ -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)}
/>
)
}

View File

@ -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,

View File

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

View File

@ -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 && (

View File

@ -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]' />,

View File

@ -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',

View File

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

View File

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