mirror of
https://github.com/langgenius/dify.git
synced 2026-01-04 13:37:22 +00:00
feat: support string num seletor to single run debug
This commit is contained in:
@@ -60,7 +60,7 @@ const ConfigModal: FC<IConfigModalProps> = ({
|
||||
Toast.notify({ type: 'error', message: t('appDebug.variableConig.errorMsg.labelNameRequired') })
|
||||
return
|
||||
}
|
||||
if (isStringInput) {
|
||||
if (isStringInput || type === InputVarType.number) {
|
||||
onConfirm(tempPayload)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -39,7 +39,7 @@ const Form: FC<Props> = ({
|
||||
draft[key].push(RETRIEVAL_OUTPUT_STRUCT)
|
||||
})
|
||||
onChange(newValues)
|
||||
}, [values, onChange])
|
||||
}, [values, onChange, inputs])
|
||||
return (
|
||||
<div className={cn(className, 'space-y-2')}>
|
||||
{label && (
|
||||
|
||||
@@ -55,6 +55,10 @@ const formatItem = (item: any, isChatMode: boolean, filterVar: (payload: Var, se
|
||||
return {
|
||||
variable: v.variable,
|
||||
type: inputVarTypeToVarType(v.type),
|
||||
isParagraph: v.type === InputVarType.paragraph,
|
||||
isSelect: v.type === InputVarType.select,
|
||||
options: v.options,
|
||||
required: v.required,
|
||||
}
|
||||
})
|
||||
if (isChatMode) {
|
||||
|
||||
@@ -93,7 +93,7 @@ const VarReferencePicker: FC<Props> = ({
|
||||
const isLast = i === value.length - 2
|
||||
curr = curr.find((v: any) => v.variable === key)
|
||||
if (isLast) {
|
||||
type = curr.type
|
||||
type = curr?.type
|
||||
}
|
||||
else {
|
||||
if (curr.type === VarType.object)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNodeDataUpdate } from '@/app/components/workflow/hooks'
|
||||
import type { CheckValidRes, CommonNodeType, InputVar, Variable } from '@/app/components/workflow/types'
|
||||
import { BlockEnum, InputVarType, NodeRunningStatus } from '@/app/components/workflow/types'
|
||||
import {
|
||||
useIsChatMode,
|
||||
useNodeDataUpdate,
|
||||
useWorkflow,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
import { toNodeOutputVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||
|
||||
import type { CheckValidRes, CommonNodeType, InputVar, ValueSelector, Var, Variable } from '@/app/components/workflow/types'
|
||||
import { BlockEnum, InputVarType, NodeRunningStatus, VarType } from '@/app/components/workflow/types'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { singleNodeRun } from '@/service/workflow'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
@@ -22,6 +28,27 @@ type Params<T> = {
|
||||
beforeRunCheckValid?: () => CheckValidRes
|
||||
}
|
||||
|
||||
const varTypeToInputVarType = (type: VarType, {
|
||||
isSelect,
|
||||
isParagraph,
|
||||
}: {
|
||||
isSelect: boolean
|
||||
isParagraph: boolean
|
||||
}) => {
|
||||
if (isSelect)
|
||||
return InputVarType.select
|
||||
if (isParagraph)
|
||||
return InputVarType.paragraph
|
||||
if (type === VarType.number)
|
||||
return InputVarType.number
|
||||
if ([VarType.object, VarType.array, VarType.arrayNumber, VarType.arrayString, VarType.arrayObject].includes(type))
|
||||
return InputVarType.json
|
||||
if (type === VarType.arrayFile)
|
||||
return InputVarType.files
|
||||
|
||||
return InputVarType.textInput
|
||||
}
|
||||
|
||||
const useOneStepRun = <T>({
|
||||
id,
|
||||
data,
|
||||
@@ -29,6 +56,32 @@ const useOneStepRun = <T>({
|
||||
beforeRunCheckValid = () => ({ isValid: true }),
|
||||
}: Params<T>) => {
|
||||
const { t } = useTranslation()
|
||||
const { getBeforeNodesInSameBranch } = useWorkflow()
|
||||
const isChatMode = useIsChatMode()
|
||||
|
||||
const allOutputVars = toNodeOutputVars(getBeforeNodesInSameBranch(id), isChatMode)
|
||||
const getVar = (valueSelector: ValueSelector): Var | undefined => {
|
||||
let res: Var | undefined
|
||||
const targetVar = allOutputVars.find(v => v.nodeId === valueSelector[0])
|
||||
if (!targetVar)
|
||||
return undefined
|
||||
|
||||
let curr: any = targetVar.vars
|
||||
valueSelector.slice(1).forEach((key, i) => {
|
||||
const isLast = i === valueSelector.length - 2
|
||||
curr = curr.find((v: any) => v.variable === key)
|
||||
if (isLast) {
|
||||
res = curr
|
||||
}
|
||||
else {
|
||||
if (curr.type === VarType.object)
|
||||
curr = curr.children
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
const checkValid = checkValidFns[data.type]
|
||||
const appId = useAppStore.getState().appDetail?.id
|
||||
const [runInputData, setRunInputData] = useState<Record<string, any>>(defaultRunInputData || {})
|
||||
@@ -91,10 +144,6 @@ const useOneStepRun = <T>({
|
||||
throw new Error(res.error)
|
||||
}
|
||||
catch (e: any) {
|
||||
// Toast.notify({
|
||||
// type: 'error',
|
||||
// message: e.toString(),
|
||||
// })
|
||||
handleNodeDataUpdate({
|
||||
id,
|
||||
data: {
|
||||
@@ -133,14 +182,25 @@ const useOneStepRun = <T>({
|
||||
if (!variables)
|
||||
return []
|
||||
|
||||
const varInputs = variables.map((item, i) => {
|
||||
const allVarTypes = [InputVarType.textInput, InputVarType.paragraph, InputVarType.number, InputVarType.select, InputVarType.files]
|
||||
const varInputs = variables.map((item) => {
|
||||
const originalVar = getVar(item.value_selector)
|
||||
if (!originalVar) {
|
||||
return {
|
||||
label: item.variable,
|
||||
variable: item.variable,
|
||||
type: InputVarType.textInput,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
return {
|
||||
label: item.variable,
|
||||
variable: item.variable,
|
||||
type: allVarTypes[i % allVarTypes.length], // TODO: dynamic get var type
|
||||
required: true, // TODO
|
||||
options: ['a', 'b', 'c'], // TODO
|
||||
type: varTypeToInputVarType(originalVar.type, {
|
||||
isSelect: !!originalVar.isSelect,
|
||||
isParagraph: !!originalVar.isParagraph,
|
||||
}),
|
||||
required: item.required !== false,
|
||||
options: originalVar.options,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ const useConfig = (id: string, payload: LLMNodeType) => {
|
||||
})
|
||||
|
||||
// context
|
||||
const handleContextVarChange = useCallback((newVar: ValueSelector) => {
|
||||
const handleContextVarChange = useCallback((newVar: ValueSelector | string) => {
|
||||
const newInputs = produce(inputs, (draft) => {
|
||||
draft.context.variable_selector = newVar
|
||||
draft.context.variable_selector = newVar as ValueSelector
|
||||
})
|
||||
setInputs(newInputs)
|
||||
}, [inputs, setInputs])
|
||||
|
||||
@@ -61,6 +61,9 @@ export type Variable = {
|
||||
value_selector: ValueSelector
|
||||
variable_type?: VarKindType
|
||||
value?: string
|
||||
options?: string[]
|
||||
required?: boolean
|
||||
isParagraph?: boolean
|
||||
}
|
||||
|
||||
export type VariableWithValue = {
|
||||
@@ -75,6 +78,7 @@ export enum InputVarType {
|
||||
number = 'number',
|
||||
url = 'url',
|
||||
files = 'files',
|
||||
json = 'json', // obj, array
|
||||
contexts = 'contexts', // knowledge retrieval
|
||||
}
|
||||
|
||||
@@ -141,6 +145,10 @@ export type Var = {
|
||||
variable: string
|
||||
type: VarType
|
||||
children?: Var[] // if type is obj, has the children struct
|
||||
isParagraph?: boolean
|
||||
isSelect?: boolean
|
||||
options?: string[]
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
export type NodeOutPutVar = {
|
||||
|
||||
Reference in New Issue
Block a user