diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index 5b16efe461..0f9a3d36ae 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -1,4 +1,5 @@ import produce from 'immer' +import { isArray } from 'lodash-es' import type { CodeNodeType } from '../../../code/types' import type { EndNodeType } from '../../../end/types' import type { AnswerNodeType } from '../../../answer/types' @@ -177,6 +178,12 @@ export const isSystemVar = (valueSelector: ValueSelector) => { return valueSelector[0] === 'sys' || valueSelector[1] === 'sys' } +export const getNodeInfoById = (nodes: any, id: string) => { + if (!isArray(nodes)) + return + return nodes.find((node: any) => node.id === id) +} + export const getVarType = (value: ValueSelector, availableNodes: any[], isChatMode: boolean): VarType | undefined => { const isSystem = isSystemVar(value) const startNode = availableNodes.find((node: any) => { diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx index e4b336f6b9..c96727c255 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx @@ -3,10 +3,9 @@ import type { FC } from 'react' import React, { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import cn from 'classnames' -import { isArray } from 'lodash-es' import produce from 'immer' import VarReferencePopup from './var-reference-popup' -import { isSystemVar, toNodeOutputVars } from './utils' +import { getNodeInfoById, isSystemVar, toNodeOutputVars } from './utils' import type { ValueSelector, Var } from '@/app/components/workflow/types' import { BlockEnum, VarType } from '@/app/components/workflow/types' import { VarBlockIcon } from '@/app/components/workflow/block-icon' @@ -42,12 +41,6 @@ type Props = { filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean } -const getNodeInfoById = (nodes: any, id: string) => { - if (!isArray(nodes)) - return - return nodes.find((node: any) => node.id === id) -} - const VarReferencePicker: FC = ({ nodeId, readonly, diff --git a/web/app/components/workflow/nodes/llm/use-config.ts b/web/app/components/workflow/nodes/llm/use-config.ts index 7e083e307d..0748927de3 100644 --- a/web/app/components/workflow/nodes/llm/use-config.ts +++ b/web/app/components/workflow/nodes/llm/use-config.ts @@ -1,5 +1,6 @@ import { useCallback, useEffect, useRef, useState } from 'react' import produce from 'immer' +import { flatten, uniqBy } from 'lodash' import useVarList from '../_base/hooks/use-var-list' import { VarType } from '../../types' import type { Memory, ValueSelector, Var } from '../../types' @@ -7,7 +8,9 @@ import { useStore } from '../../store' import { useIsChatMode, useNodesReadOnly, + useWorkflow, } from '../../hooks' +import { getNodeInfoById } from '../_base/components/variable/utils' import type { LLMNodeType } from './types' import { Resolution } from '@/types/app' import { useModelListAndDefaultModelAndCurrentProviderAndModel, useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks' @@ -16,11 +19,14 @@ import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-cr import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run' import type { PromptItem } from '@/models/debug' import { RETRIEVAL_OUTPUT_STRUCT } from '@/app/components/workflow/constants' -import { checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants' +import { checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock, getInputVars } from '@/app/components/base/prompt-editor/constants' const useConfig = (id: string, payload: LLMNodeType) => { const { nodesReadOnly: readOnly } = useNodesReadOnly() const isChatMode = useIsChatMode() + const { getBeforeNodesInSameBranch } = useWorkflow() + + const availableNodes = getBeforeNodesInSameBranch(id) const defaultConfig = useStore(s => s.nodesDefaultConfigs)[payload.type] const [defaultRolePrefix, setDefaultRolePrefix] = useState<{ user: string; assistant: string }>({ user: '', assistant: '' }) @@ -262,8 +268,32 @@ const useConfig = (id: string, payload: LLMNodeType) => { '#files#': newFiles, }) }, [runInputData, setRunInputData]) + const variables = (() => { + let valueSelectors: ValueSelector[] = [] + if (isChatModel) { + valueSelectors = flatten( + (inputs.prompt_template as PromptItem[]) + .map(item => getInputVars(item.text)), + ) + } + else { + valueSelectors = getInputVars((inputs.prompt_template as PromptItem).text) + } - const varInputs = toVarInputs(inputs.variables) + const variables = uniqBy(valueSelectors, item => item.join('.')).map((item) => { + const varInfo = getNodeInfoById(availableNodes, item[0])?.data + const variable = [...item] + variable[0] = varInfo?.title || availableNodes[0]?.data.title // default start node title + + return { + variable: variable.join('/'), + value_selector: item, + } + }) + + return variables + })() + const varInputs = toVarInputs(variables) return { readOnly,