mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-18 05:15:56 +08:00
feat: support var show
This commit is contained in:
parent
e624bf381b
commit
6a76e27b05
@ -3,7 +3,7 @@ import { isArray, uniq } from 'lodash-es'
|
||||
import type { CodeNodeType } from '../../../code/types'
|
||||
import type { EndNodeType } from '../../../end/types'
|
||||
import type { AnswerNodeType } from '../../../answer/types'
|
||||
import type { LLMNodeType } from '../../../llm/types'
|
||||
import type { LLMNodeType, StructuredOutput } from '../../../llm/types'
|
||||
import type { KnowledgeRetrievalNodeType } from '../../../knowledge-retrieval/types'
|
||||
import type { IfElseNodeType } from '../../../if-else/types'
|
||||
import type { TemplateTransformNodeType } from '../../../template-transform/types'
|
||||
@ -20,6 +20,8 @@ import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/type
|
||||
import type { StartNodeType } from '@/app/components/workflow/nodes/start/types'
|
||||
import type { ConversationVariable, EnvironmentVariable, Node, NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types'
|
||||
import type { VariableAssignerNodeType } from '@/app/components/workflow/nodes/variable-assigner/types'
|
||||
import mockStructData from '@/app/components/workflow/nodes/llm/mock-struct-data'
|
||||
|
||||
import {
|
||||
HTTP_REQUEST_OUTPUT_STRUCT,
|
||||
KNOWLEDGE_RETRIEVAL_OUTPUT_STRUCT,
|
||||
@ -59,15 +61,18 @@ const findExceptVarInObject = (obj: any, filterVar: (payload: Var, selector: Val
|
||||
const res: Var = {
|
||||
variable: obj.variable,
|
||||
type: isFile ? VarType.file : VarType.object,
|
||||
children: children.filter((item: Var) => {
|
||||
children: children.length > 0 ? children.filter((item: Var) => {
|
||||
const { children } = item
|
||||
const isStructuredOutput = !!(children as StructuredOutput)?.schema
|
||||
if (!isStructuredOutput) {
|
||||
const currSelector = [...value_selector, item.variable]
|
||||
if (!children)
|
||||
return filterVar(item, currSelector)
|
||||
|
||||
const obj = findExceptVarInObject(item, filterVar, currSelector, false) // File doesn't contains file children
|
||||
return obj.children && obj.children?.length > 0
|
||||
}),
|
||||
return obj.children && (obj.children as Var[])?.length > 0
|
||||
}
|
||||
return true // TODO: handle structured output
|
||||
}) : (children || []),
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -138,7 +143,14 @@ const formatItem = (
|
||||
}
|
||||
|
||||
case BlockEnum.LLM: {
|
||||
res.vars = LLM_OUTPUT_STRUCT
|
||||
res.vars = [
|
||||
...LLM_OUTPUT_STRUCT,
|
||||
{
|
||||
variable: 'structured_output',
|
||||
type: VarType.object,
|
||||
children: mockStructData,
|
||||
},
|
||||
]
|
||||
break
|
||||
}
|
||||
|
||||
@ -404,7 +416,7 @@ const formatItem = (
|
||||
return false
|
||||
|
||||
const obj = findExceptVarInObject(isFile ? { ...v, children } : v, filterVar, selector, isFile)
|
||||
return obj?.children && obj?.children.length > 0
|
||||
return obj?.children && ((obj?.children as Var[]).length > 0 || Object.keys((obj?.children as StructuredOutput)?.schema?.properties || {}).length > 0)
|
||||
}).map((v) => {
|
||||
const isFile = v.type === VarType.file
|
||||
|
||||
@ -428,6 +440,9 @@ const formatItem = (
|
||||
return findExceptVarInObject(isFile ? { ...v, children } : v, filterVar, selector, isFile)
|
||||
})
|
||||
|
||||
if (res.nodeId === 'llm')
|
||||
console.log(res)
|
||||
|
||||
return res
|
||||
}
|
||||
export const toNodeOutputVars = (
|
||||
@ -527,8 +542,7 @@ export const getVarType = ({
|
||||
isConstant,
|
||||
environmentVariables = [],
|
||||
conversationVariables = [],
|
||||
}:
|
||||
{
|
||||
}: {
|
||||
valueSelector: ValueSelector
|
||||
parentNode?: Node | null
|
||||
isIterationItem?: boolean
|
||||
@ -1094,12 +1108,14 @@ const varToValueSelectorList = (v: Var, parentValueSelector: ValueSelector, res:
|
||||
return
|
||||
|
||||
res.push([...parentValueSelector, v.variable])
|
||||
|
||||
if (v.children && v.children.length > 0) {
|
||||
v.children.forEach((child) => {
|
||||
if (v.children) {
|
||||
if ((v.children as Var[])?.length > 0) {
|
||||
(v.children as Var[]).forEach((child) => {
|
||||
varToValueSelectorList(child, [...parentValueSelector, v.variable], res)
|
||||
})
|
||||
}
|
||||
// TODO: handle structured output
|
||||
}
|
||||
}
|
||||
|
||||
const varsToValueSelectorList = (vars: Var | Var[], parentValueSelector: ValueSelector, res: ValueSelector[]) => {
|
||||
|
@ -16,8 +16,10 @@ import Input from '@/app/components/base/input'
|
||||
import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
|
||||
import { checkKeys } from '@/utils/var'
|
||||
import { FILE_STRUCT } from '@/app/components/workflow/constants'
|
||||
import type { StructuredOutput } from '../../../llm/types'
|
||||
import PickerStructurePanel from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker'
|
||||
|
||||
interface ObjectChildrenProps {
|
||||
type ObjectChildrenProps = {
|
||||
nodeId: string
|
||||
title: string
|
||||
data: Var[]
|
||||
@ -28,7 +30,7 @@ interface ObjectChildrenProps {
|
||||
isSupportFileVar?: boolean
|
||||
}
|
||||
|
||||
interface ItemProps {
|
||||
type ItemProps = {
|
||||
nodeId: string
|
||||
title: string
|
||||
objPath: string[]
|
||||
@ -51,8 +53,9 @@ const Item: FC<ItemProps> = ({
|
||||
isSupportFileVar,
|
||||
isException,
|
||||
}) => {
|
||||
const isFile = itemData.type === VarType.file
|
||||
const isObj = ([VarType.object, VarType.file].includes(itemData.type) && itemData.children && itemData.children.length > 0)
|
||||
const isStructureOutput = itemData.type === VarType.object && (itemData.children as StructuredOutput)?.schema?.properties
|
||||
const isFile = itemData.type === VarType.file && !isStructureOutput
|
||||
const isObj = ([VarType.object, VarType.file].includes(itemData.type) && itemData.children && (itemData.children as Var[]).length > 0)
|
||||
const isSys = itemData.variable.startsWith('sys.')
|
||||
const isEnv = itemData.variable.startsWith('env.')
|
||||
const isChatVar = itemData.variable.startsWith('conversation.')
|
||||
@ -77,7 +80,7 @@ const Item: FC<ItemProps> = ({
|
||||
})
|
||||
const [isChildrenHovering, setIsChildrenHovering] = useState(false)
|
||||
const isHovering = isItemHovering || isChildrenHovering
|
||||
const open = isObj && isHovering
|
||||
const open = (isObj || isStructureOutput) && isHovering
|
||||
useEffect(() => {
|
||||
onHovering && onHovering(isHovering)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@ -125,7 +128,7 @@ const Item: FC<ItemProps> = ({
|
||||
)}
|
||||
</div>
|
||||
<div className='ml-1 shrink-0 text-xs font-normal text-text-tertiary capitalize'>{itemData.type}</div>
|
||||
{isObj && (
|
||||
{(isObj || isStructureOutput) && (
|
||||
<ChevronRight className={cn('ml-0.5 w-3 h-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />
|
||||
)}
|
||||
</div>
|
||||
@ -133,6 +136,9 @@ const Item: FC<ItemProps> = ({
|
||||
<PortalToFollowElemContent style={{
|
||||
zIndex: 100,
|
||||
}}>
|
||||
{isStructureOutput && (
|
||||
<PickerStructurePanel root={{ attrName: itemData.variable }} payload={itemData.children as StructuredOutput} />
|
||||
)}
|
||||
{(isObj && !isFile) && (
|
||||
// eslint-disable-next-line ts/no-use-before-define
|
||||
<ObjectChildren
|
||||
@ -226,7 +232,7 @@ const ObjectChildren: FC<ObjectChildrenProps> = ({
|
||||
)
|
||||
}
|
||||
|
||||
interface Props {
|
||||
type Props = {
|
||||
hideSearch?: boolean
|
||||
searchBoxClassName?: string
|
||||
vars: NodeOutPutVar[]
|
||||
@ -322,7 +328,7 @@ const VarReferenceVars: FC<Props> = ({
|
||||
}
|
||||
</div>
|
||||
: <div className='pl-3 leading-[18px] text-xs font-medium text-gray-500 uppercase'>{t('workflow.common.noVar')}</div>}
|
||||
</ >
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default React.memo(VarReferenceVars)
|
||||
|
@ -14,6 +14,7 @@ import type {
|
||||
ErrorHandleTypeEnum,
|
||||
} from '@/app/components/workflow/nodes/_base/components/error-handle/types'
|
||||
import type { WorkflowRetryConfig } from '@/app/components/workflow/nodes/_base/components/retry/types'
|
||||
import type { StructuredOutput } from './nodes/llm/types'
|
||||
|
||||
export enum BlockEnum {
|
||||
Start = 'start',
|
||||
@ -250,7 +251,7 @@ export enum VarType {
|
||||
export type Var = {
|
||||
variable: string
|
||||
type: VarType
|
||||
children?: Var[] // if type is obj, has the children struct
|
||||
children?: Var[] | StructuredOutput // if type is obj, has the children struct
|
||||
isParagraph?: boolean
|
||||
isSelect?: boolean
|
||||
options?: string[]
|
||||
|
Loading…
x
Reference in New Issue
Block a user