node var list

pull/21369/head
jZonG 1 year ago
parent 85c98dd20a
commit 24f02f0166

@ -1,6 +1,7 @@
import { fetchNodeInspectVars } from '@/service/workflow' import { fetchNodeInspectVars } from '@/service/workflow'
import { useWorkflowStore } from '../store' import { useWorkflowStore } from '../store'
import type { ValueSelector } from '../types' import type { ValueSelector } from '../types'
import { VarInInspectType } from '@/types/workflow'
import { import {
useConversationVarValues, useConversationVarValues,
useDeleteAllInspectorVars, useDeleteAllInspectorVars,
@ -82,7 +83,8 @@ const useInspectVarsCrud = () => {
varId, varId,
value, value,
}) })
setInspectVarValue(nodeId, varId, value) if (nodeId !== VarInInspectType.conversation && nodeId !== VarInInspectType.system)
setInspectVarValue(nodeId, varId, value)
}, [doEditInspectorVar, setInspectVarValue]) }, [doEditInspectorVar, setInspectVarValue])
const [currNodeId, setCurrNodeId] = useState<string | null>(null) const [currNodeId, setCurrNodeId] = useState<string | null>(null)

@ -6,13 +6,23 @@ export const vars: VarInInspect[] = [
{ {
id: 'xxx', id: 'xxx',
type: VarInInspectType.node, type: VarInInspectType.node,
name: 'llm 2', name: 'text',
description: '', description: '',
selector: ['1745476079387', 'text'], selector: ['1745476079387', 'text'],
value_type: VarType.string, value_type: VarType.string,
value: 'text value...', value: 'text value...',
edited: false, edited: false,
}, },
{
id: 'fdklajljgldjglkagjlk',
type: VarInInspectType.node,
name: 'text',
description: '',
selector: ['1712386917734', 'text'],
value_type: VarType.string,
value: 'made zhizhang',
edited: false,
},
] ]
export const conversationVars: VarInInspect[] = [ export const conversationVars: VarInInspect[] = [

@ -2,14 +2,15 @@ import { useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import {
RiArrowRightSLine, RiArrowRightSLine,
RiDeleteBinLine,
RiFileList3Line,
RiLoader2Line,
// RiErrorWarningFill, // RiErrorWarningFill,
// RiLoader2Line,
} from '@remixicon/react' } from '@remixicon/react'
// import { BlockEnum } from '../types'
// import Button from '@/app/components/base/button' // import Button from '@/app/components/base/button'
// import ActionButton from '@/app/components/base/action-button' import ActionButton from '@/app/components/base/action-button'
// import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
// import BlockIcon from '@/app/components/workflow/block-icon' import BlockIcon from '@/app/components/workflow/block-icon'
import { import {
BubbleX, BubbleX,
Env, Env,
@ -17,21 +18,27 @@ import {
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import type { currentVarType } from './panel' import type { currentVarType } from './panel'
import { VarInInspectType } from '@/types/workflow' import { VarInInspectType } from '@/types/workflow'
import type { VarInInspect } from '@/types/workflow' import type { NodeWithVar, VarInInspect } from '@/types/workflow'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
type Props = { type Props = {
nodeData?: NodeWithVar
currentVar?: currentVarType currentVar?: currentVarType
varType: VarInInspectType varType: VarInInspectType
varList: VarInInspect[] varList: VarInInspect[]
handleSelect: (state: any) => void handleSelect: (state: any) => void
handleView?: () => void
handleClear?: () => void
} }
const Group = ({ const Group = ({
nodeData,
currentVar, currentVar,
varType, varType,
varList, varList,
handleSelect, handleSelect,
handleView,
handleClear,
}: Props) => { }: Props) => {
const { t } = useTranslation() const { t } = useTranslation()
const [isCollapsed, setIsCollapsed] = useState(false) const [isCollapsed, setIsCollapsed] = useState(false)
@ -43,8 +50,8 @@ const Group = ({
const handleSelectVar = (varItem: any, type?: string) => { const handleSelectVar = (varItem: any, type?: string) => {
if (type === VarInInspectType.environment) { if (type === VarInInspectType.environment) {
handleSelect({ handleSelect({
nodeId: 'env', nodeId: VarInInspectType.environment,
nodeTitle: 'env', title: VarInInspectType.environment,
nodeType: VarInInspectType.environment, nodeType: VarInInspectType.environment,
var: { var: {
...varItem, ...varItem,
@ -56,9 +63,9 @@ const Group = ({
} }
if (type === VarInInspectType.conversation) { if (type === VarInInspectType.conversation) {
handleSelect({ handleSelect({
nodeId: 'conversation', nodeId: VarInInspectType.conversation,
nodeTitle: 'conversation',
nodeType: VarInInspectType.conversation, nodeType: VarInInspectType.conversation,
title: VarInInspectType.conversation,
var: { var: {
...varItem, ...varItem,
type: VarInInspectType.conversation, type: VarInInspectType.conversation,
@ -68,9 +75,9 @@ const Group = ({
} }
if (type === VarInInspectType.system) { if (type === VarInInspectType.system) {
handleSelect({ handleSelect({
nodeId: 'sys', nodeId: VarInInspectType.system,
nodeTitle: 'sys',
nodeType: VarInInspectType.system, nodeType: VarInInspectType.system,
title: VarInInspectType.system,
var: { var: {
...varItem, ...varItem,
type: VarInInspectType.system, type: VarInInspectType.system,
@ -78,29 +85,61 @@ const Group = ({
}) })
return return
} }
if (!nodeData) return
handleSelect({ handleSelect({
nodeId: varItem.nodeId, nodeId: nodeData.nodeId,
nodeTitle: varItem.nodeTitle, nodeType: nodeData.nodeType,
nodeType: varItem.nodeType, title: nodeData.title,
var: varItem.var, var: varItem,
}) })
} }
return ( return (
<div className='p-0.5'> <div className='p-0.5'>
{/* node item */} {/* node item */}
<div className='flex h-6 items-center gap-0.5'> <div className='group flex h-6 items-center gap-0.5'>
<RiArrowRightSLine className={cn('h-3 w-3 text-text-tertiary', !isCollapsed && 'rotate-90')} /> {nodeData?.isSingRunRunning && (
<RiLoader2Line className='h-3 w-3 animate-spin text-text-accent' />
)}
{(!nodeData || !nodeData.isSingRunRunning) && (
<RiArrowRightSLine className={cn('h-3 w-3 text-text-tertiary', !isCollapsed && 'rotate-90')} onClick={() => setIsCollapsed(!isCollapsed)} />
)}
<div className='flex grow cursor-pointer items-center gap-1' onClick={() => setIsCollapsed(!isCollapsed)}> <div className='flex grow cursor-pointer items-center gap-1' onClick={() => setIsCollapsed(!isCollapsed)}>
<div className='system-xs-medium-uppercase truncate text-text-tertiary'> {nodeData && (
{isEnv && t('workflow.debug.variableInspect.envNode')} <>
{isChatVar && t('workflow.debug.variableInspect.chatNode')} <BlockIcon
{isSystem && t('workflow.debug.variableInspect.systemNode')} className='shrink-0'
</div> type={nodeData.nodeType}
size='xs'
/>
<div className='system-xs-medium-uppercase truncate text-text-tertiary'>{nodeData.title}</div>
</>
)}
{!nodeData && (
<div className='system-xs-medium-uppercase truncate text-text-tertiary'>
{isEnv && t('workflow.debug.variableInspect.envNode')}
{isChatVar && t('workflow.debug.variableInspect.chatNode')}
{isSystem && t('workflow.debug.variableInspect.systemNode')}
</div>
)}
</div> </div>
{nodeData && !nodeData.isSingRunRunning && (
<div className='hidden shrink-0 items-center group-hover:flex'>
<Tooltip popupContent={t('workflow.debug.variableInspect.view')}>
<ActionButton onClick={handleView}>
<RiFileList3Line className='h-4 w-4' />
</ActionButton>
</Tooltip>
<Tooltip popupContent={t('workflow.debug.variableInspect.clearNode')}>
<ActionButton onClick={handleClear}>
<RiDeleteBinLine className='h-4 w-4' />
</ActionButton>
</Tooltip>
</div>
)}
</div> </div>
{/* var item list */} {/* var item list */}
{!isCollapsed && ( {!isCollapsed && !nodeData?.isSingRunRunning && (
<div className='px-0.5'> <div className='px-0.5'>
{varList.length > 0 && varList.map(varItem => ( {varList.length > 0 && varList.map(varItem => (
<div <div
@ -113,7 +152,7 @@ const Group = ({
> >
{isEnv && <Env className='h-4 w-4 shrink-0 text-util-colors-violet-violet-600' />} {isEnv && <Env className='h-4 w-4 shrink-0 text-util-colors-violet-violet-600' />}
{isChatVar && <BubbleX className='h-4 w-4 shrink-0 text-util-colors-teal-teal-700' />} {isChatVar && <BubbleX className='h-4 w-4 shrink-0 text-util-colors-teal-teal-700' />}
{isSystem && <Variable02 className='h-4 w-4 shrink-0 text-text-accent' />} {(isSystem || nodeData) && <Variable02 className='h-4 w-4 shrink-0 text-text-accent' />}
<div className='system-sm-medium grow truncate text-text-secondary'>{varItem.name}</div> <div className='system-sm-medium grow truncate text-text-secondary'>{varItem.name}</div>
<div className='system-xs-regular shrink-0 text-text-tertiary'>{varItem.value_type}</div> <div className='system-xs-regular shrink-0 text-text-tertiary'>{varItem.value_type}</div>
</div> </div>

@ -1,19 +1,13 @@
// import { useState } from 'react' // import { useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import {
RiArrowRightSLine,
RiErrorWarningFill,
RiLoader2Line,
} from '@remixicon/react'
import { useStore } from '../store' import { useStore } from '../store'
import { BlockEnum } from '../types'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
// import ActionButton from '@/app/components/base/action-button' // import ActionButton from '@/app/components/base/action-button'
// import Tooltip from '@/app/components/base/tooltip' // import Tooltip from '@/app/components/base/tooltip'
import BlockIcon from '@/app/components/workflow/block-icon'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import Group from './group' import Group from './group'
import useCurrentVars from '../hooks/use-inspect-vars-crud' import useCurrentVars from '../hooks/use-inspect-vars-crud'
import { useNodesInteractions } from '../hooks/use-nodes-interactions'
import type { currentVarType } from './panel' import type { currentVarType } from './panel'
import type { VarInInspect } from '@/types/workflow' import type { VarInInspect } from '@/types/workflow'
import { VarInInspectType } from '@/types/workflow' import { VarInInspectType } from '@/types/workflow'
@ -36,13 +30,12 @@ const Left = ({
systemVars, systemVars,
nodesWithInspectVars, nodesWithInspectVars,
deleteAllInspectorVars, deleteAllInspectorVars,
deleteNodeInspectorVars,
} = useCurrentVars() } = useCurrentVars()
const { handleNodeSelect } = useNodesInteractions()
const showDivider = environmentVariables.length > 0 || conversationVars.length > 0 || systemVars.length > 0 const showDivider = environmentVariables.length > 0 || conversationVars.length > 0 || systemVars.length > 0
// TODO node selection
const selectedNode = 3 < 4
return ( return (
<div className={cn('flex h-full flex-col')}> <div className={cn('flex h-full flex-col')}>
{/* header */} {/* header */}
@ -86,64 +79,18 @@ const Left = ({
</div> </div>
)} )}
{/* group nodes */} {/* group nodes */}
<div className='p-0.5'> {nodesWithInspectVars.length > 0 && nodesWithInspectVars.map(group => (
{/* node item */} <Group
<div className='flex h-6 items-center gap-0.5'> key={group.nodeId}
<RiArrowRightSLine className='h-3 w-3 rotate-90 text-text-tertiary' /> varType={VarInInspectType.node}
<div className='flex grow cursor-pointer items-center gap-1'> varList={group.vars}
<BlockIcon nodeData={group}
className='shrink-0' currentVar={currentNodeVar}
type={BlockEnum.LLM} handleSelect={handleVarSelect}
size='xs' handleView={() => handleNodeSelect(group.nodeId)}
/> handleClear={() => deleteNodeInspectorVars(group.nodeId)}
<div className='system-xs-medium-uppercase truncate text-text-tertiary'>LLM</div> />
</div> ))}
</div>
{/* var item list */}
<div className='px-0.5'>
<div className={cn('relative flex cursor-pointer items-center gap-1 rounded-md px-3 py-1 hover:bg-state-base-hover')}>
<Variable02 className='h-4 w-4 text-text-accent' />
<div className='system-sm-medium grow truncate text-text-secondary'>chat_history</div>
<div className='system-xs-regular shrink-0 text-text-tertiary'>array</div>
</div>
<div className={cn('relative flex cursor-pointer items-center gap-1 rounded-md px-3 py-1 hover:bg-state-base-hover')}>
{selectedNode && <span className='absolute left-1.5 top-[10.5px] h-[3px] w-[3px] rounded-full bg-text-accent-secondary'></span>}
<Variable02 className='h-4 w-4 text-text-warning' />
<div className='system-sm-medium grow truncate text-text-secondary'>custom_chat_history</div>
<div className='system-xs-regular shrink-0 text-text-tertiary'>array</div>
</div>
</div>
</div>
{/* group nodes */}
<div className='p-0.5'>
{/* node item */}
<div className='flex h-6 items-center gap-0.5'>
<RiLoader2Line className='h-3 w-3 text-text-accent' />
<div className='flex grow cursor-pointer items-center gap-1'>
<BlockIcon
className='shrink-0'
type={BlockEnum.QuestionClassifier}
size='xs'
/>
<div className='system-xs-medium-uppercase truncate text-text-tertiary'>Question Classifier</div>
</div>
</div>
</div>
{/* group nodes */}
<div className='p-0.5'>
{/* node item */}
<div className='flex h-6 items-center gap-0.5'>
<RiErrorWarningFill className='h-3 w-3 text-text-destructive' />
<div className='flex grow cursor-pointer items-center gap-1'>
<BlockIcon
className='shrink-0'
type={BlockEnum.HttpRequest}
size='xs'
/>
<div className='system-xs-medium-uppercase truncate text-text-tertiary'>HTTP Request</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
) )

@ -15,8 +15,8 @@ import cn from '@/utils/classnames'
export type currentVarType = { export type currentVarType = {
nodeId: string nodeId: string
nodeTitle: string
nodeType: string nodeType: string
title: string
var: VarInInspect var: VarInInspect
} }
@ -37,7 +37,7 @@ const Panel: FC = () => {
const isEmpty = useMemo(() => { const isEmpty = useMemo(() => {
const allVars = [...environmentVariables, ...conversationVars, ...systemVars, ...nodesWithInspectVars] const allVars = [...environmentVariables, ...conversationVars, ...systemVars, ...nodesWithInspectVars]
return allVars.length === 0 return allVars.length === 0
}, [conversationVars, systemVars, nodesWithInspectVars]) }, [environmentVariables, conversationVars, systemVars, nodesWithInspectVars])
if (isEmpty) { if (isEmpty) {
return ( return (

@ -77,7 +77,7 @@ const Right = ({
type={currentNodeVar.nodeType as BlockEnum} type={currentNodeVar.nodeType as BlockEnum}
size='xs' size='xs'
/> />
<div className='system-sm-regular shrink-0 text-text-secondary'>{currentNodeVar.nodeTitle}</div> <div className='system-sm-regular shrink-0 text-text-secondary'>{currentNodeVar.title}</div>
<div className='system-sm-regular shrink-0 text-text-quaternary'>/</div> <div className='system-sm-regular shrink-0 text-text-quaternary'>/</div>
</> </>
)} )}

@ -40,7 +40,6 @@ const ValueContent = ({
const textEditorDisabled = currentVar.type === VarInInspectType.environment || (currentVar.type === VarInInspectType.system && currentVar.name !== 'query') const textEditorDisabled = currentVar.type === VarInInspectType.environment || (currentVar.type === VarInInspectType.system && currentVar.name !== 'query')
const [value, setValue] = useState<any>() const [value, setValue] = useState<any>()
const [jsonSchema, setJsonSchema] = useState()
const [json, setJson] = useState('') const [json, setJson] = useState('')
const [parseError, setParseError] = useState<Error | null>(null) const [parseError, setParseError] = useState<Error | null>(null)
const [validationError, setValidationError] = useState<string>('') const [validationError, setValidationError] = useState<string>('')
@ -57,7 +56,6 @@ const ValueContent = ({
// update default value when id changed // update default value when id changed
useEffect(() => { useEffect(() => {
console.log('currentVar', currentVar)
if (showTextEditor) { if (showTextEditor) {
if (!currentVar.value) if (!currentVar.value)
return setValue('') return setValue('')
@ -65,10 +63,9 @@ const ValueContent = ({
return setValue(JSON.stringify(currentVar.value)) return setValue(JSON.stringify(currentVar.value))
setValue(currentVar.value) setValue(currentVar.value)
} }
if (showJSONEditor) { if (showJSONEditor)
setJsonSchema(currentVar.value || null)
setJson(currentVar.value ? JSON.stringify(currentVar.value, null, 2) : '') setJson(currentVar.value ? JSON.stringify(currentVar.value, null, 2) : '')
}
if (showFileEditor) { if (showFileEditor) {
setFileValue(currentVar.value_type === 'array[file]' setFileValue(currentVar.value_type === 'array[file]'
? currentVar.value || [] ? currentVar.value || []
@ -130,16 +127,11 @@ const ValueContent = ({
setJson(value) setJson(value)
if (jsonValueValidate(value, currentVar.value_type)) { if (jsonValueValidate(value, currentVar.value_type)) {
const parsed = JSON.parse(value) const parsed = JSON.parse(value)
setJsonSchema(parsed)
debounceValueChange(currentVar.id, parsed) debounceValueChange(currentVar.id, parsed)
} }
} }
const fileValueValidate = (fileList: any[]) => { const fileValueValidate = (fileList: any[]) => fileList.every(file => file.upload_file_id)
if (fileList.every(file => file.upload_file_id))
return true
return false
}
const handleFileChange = (value: any[]) => { const handleFileChange = (value: any[]) => {
setFileValue(value) setFileValue(value)
@ -168,7 +160,7 @@ const ValueContent = ({
errorMessageObserver.disconnect() errorMessageObserver.disconnect()
} }
} }
}, [errorMessageRef.current, setEditorHeight]) }, [setEditorHeight])
return ( return (
<div <div

Loading…
Cancel
Save