chore: enchance auto generate prompt (#6564)

This commit is contained in:
Joel
2024-07-23 19:51:38 +08:00
committed by GitHub
parent 2bc0632d0d
commit 0f6a064c08
24 changed files with 565 additions and 293 deletions

View File

@@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { BlockEnum, EditionType } from '../../../../types'
import type {
ModelConfig,
Node,
NodeOutPutVar,
Variable,
@@ -16,6 +17,7 @@ import type {
import Wrap from '../editor/wrap'
import { CodeLanguage } from '../../../code/types'
import PromptGeneratorBtn from '../../../llm/components/prompt-generator-btn'
import cn from '@/utils/classnames'
import ToggleExpandBtn from '@/app/components/workflow/nodes/_base/components/toggle-expand-btn'
import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend'
@@ -55,6 +57,9 @@ type Props = {
}
nodesOutputVars?: NodeOutPutVar[]
availableNodes?: Node[]
isSupportPromptGenerator?: boolean
onGenerated?: (prompt: string) => void
modelConfig?: ModelConfig
// for jinja
isSupportJinja?: boolean
editionType?: EditionType
@@ -80,11 +85,14 @@ const Editor: FC<Props> = ({
hasSetBlockStatus,
nodesOutputVars,
availableNodes = [],
isSupportPromptGenerator,
isSupportJinja,
editionType,
onEditionTypeChange,
varList = [],
handleAddVariable,
onGenerated,
modelConfig,
}) => {
const { t } = useTranslation()
const { eventEmitter } = useEventEmitterContextContext()
@@ -124,6 +132,10 @@ const Editor: FC<Props> = ({
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
<div className='flex items-center'>
<div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div>
{isSupportPromptGenerator && (
<PromptGeneratorBtn className='ml-[5px]' onGenerated={onGenerated} modelConfig={modelConfig} />
)}
<div className='w-px h-3 ml-2 mr-2 bg-gray-200'></div>
{/* Operations */}
<div className='flex items-center space-x-2'>

View File

@@ -1,11 +1,12 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import React, { useCallback, useEffect, useState } from 'react'
import { uniqueId } from 'lodash-es'
import { useTranslation } from 'react-i18next'
import { RiQuestionLine } from '@remixicon/react'
import type { PromptItem, Variable } from '../../../types'
import type { ModelConfig, PromptItem, Variable } from '../../../types'
import { EditionType } from '../../../types'
import { useWorkflowStore } from '../../../store'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
import TooltipPlus from '@/app/components/base/tooltip-plus'
@@ -37,6 +38,7 @@ type Props = {
availableNodes: any
varList: Variable[]
handleAddVariable: (payload: any) => void
modelConfig?: ModelConfig
}
const roleOptions = [
@@ -76,13 +78,23 @@ const ConfigPromptItem: FC<Props> = ({
availableNodes,
varList,
handleAddVariable,
modelConfig,
}) => {
const { t } = useTranslation()
const workflowStore = useWorkflowStore()
const {
setControlPromptEditorRerenderKey,
} = workflowStore.getState()
const [instanceId, setInstanceId] = useState(uniqueId())
useEffect(() => {
setInstanceId(`${id}-${uniqueId()}`)
}, [id])
const handleGenerated = useCallback((prompt: string) => {
onPromptChange(prompt)
setTimeout(() => setControlPromptEditorRerenderKey(Date.now()))
}, [onPromptChange, setControlPromptEditorRerenderKey])
return (
<Editor
className={className}
@@ -126,6 +138,9 @@ const ConfigPromptItem: FC<Props> = ({
hasSetBlockStatus={hasSetBlockStatus}
nodesOutputVars={availableVars}
availableNodes={availableNodes}
isSupportPromptGenerator={payload.role === PromptRole.system}
onGenerated={handleGenerated}
modelConfig={modelConfig}
isSupportJinja
editionType={payload.edition_type}
onEditionTypeChange={onEditionTypeChange}

View File

@@ -5,9 +5,10 @@ import { useTranslation } from 'react-i18next'
import produce from 'immer'
import { ReactSortable } from 'react-sortablejs'
import { v4 as uuid4 } from 'uuid'
import type { PromptItem, ValueSelector, Var, Variable } from '../../../types'
import type { ModelConfig, PromptItem, ValueSelector, Var, Variable } from '../../../types'
import { EditionType, PromptRole } from '../../../types'
import useAvailableVarList from '../../_base/hooks/use-available-var-list'
import { useWorkflowStore } from '../../../store'
import ConfigPromptItem from './config-prompt-item'
import cn from '@/utils/classnames'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
@@ -32,6 +33,7 @@ type Props = {
}
varList?: Variable[]
handleAddVariable: (payload: any) => void
modelConfig: ModelConfig
}
const ConfigPrompt: FC<Props> = ({
@@ -46,8 +48,13 @@ const ConfigPrompt: FC<Props> = ({
hasSetBlockStatus,
varList = [],
handleAddVariable,
modelConfig,
}) => {
const { t } = useTranslation()
const workflowStore = useWorkflowStore()
const {
setControlPromptEditorRerenderKey,
} = workflowStore.getState()
const payloadWithIds = (isChatModel && Array.isArray(payload))
? payload.map((item) => {
const id = uuid4()
@@ -124,6 +131,11 @@ const ConfigPrompt: FC<Props> = ({
onChange(newPrompt)
}, [onChange, payload])
const handleGenerated = useCallback((prompt: string) => {
handleCompletionPromptChange(prompt)
setTimeout(() => setControlPromptEditorRerenderKey(Date.now()))
}, [handleCompletionPromptChange, setControlPromptEditorRerenderKey])
const handleCompletionEditionTypeChange = useCallback((editionType: EditionType) => {
const newPrompt = produce(payload as PromptItem, (draft) => {
draft.edition_type = editionType
@@ -189,12 +201,11 @@ const ConfigPrompt: FC<Props> = ({
availableNodes={availableNodesWithParent}
varList={varList}
handleAddVariable={handleAddVariable}
modelConfig={modelConfig}
/>
</div>
)
})
}
</ReactSortable>
</div>
@@ -219,11 +230,14 @@ const ConfigPrompt: FC<Props> = ({
hasSetBlockStatus={hasSetBlockStatus}
nodesOutputVars={availableVars}
availableNodes={availableNodesWithParent}
isSupportPromptGenerator
isSupportJinja
editionType={(payload as PromptItem).edition_type}
varList={varList}
onEditionTypeChange={handleCompletionEditionTypeChange}
handleAddVariable={handleAddVariable}
onGenerated={handleGenerated}
modelConfig={modelConfig}
/>
</div>
)}

View File

@@ -0,0 +1,48 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useBoolean } from 'ahooks'
import cn from 'classnames'
import { Generator } from '@/app/components/base/icons/src/vender/other'
import GetAutomaticResModal from '@/app/components/app/configuration/config/automatic/get-automatic-res'
import { AppType } from '@/types/app'
import type { AutomaticRes } from '@/service/debug'
import type { ModelConfig } from '@/app/components/workflow/types'
import type { Model } from '@/types/app'
type Props = {
className?: string
onGenerated?: (prompt: string) => void
modelConfig?: ModelConfig
}
const PromptGeneratorBtn: FC<Props> = ({
className,
onGenerated,
modelConfig,
}) => {
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
const handleAutomaticRes = useCallback((res: AutomaticRes) => {
onGenerated?.(res.prompt)
showAutomaticFalse()
}, [onGenerated, showAutomaticFalse])
return (
<div className={cn(className)}>
<div className='p-[5px] rounded-md hover:bg-[#155EEF]/8 cursor-pointer' onClick={showAutomaticTrue}>
<Generator className='w-3.5 h-3.5 text-primary-600' />
</div>
{showAutomatic && (
<GetAutomaticResModal
mode={AppType.chat}
isShow={showAutomatic}
onClose={showAutomaticFalse}
onFinished={handleAutomaticRes}
model={modelConfig as Model}
isInLLMNode
/>
)}
</div>
)
}
export default React.memo(PromptGeneratorBtn)

View File

@@ -178,6 +178,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
hasSetBlockStatus={hasSetBlockStatus}
varList={inputs.prompt_config?.jinja2_variables || []}
handleAddVariable={handleAddVariable}
modelConfig={model}
/>
)}