From bd294ffe0d68695d7d952eaf6042686d70b50582 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 27 Aug 2025 16:07:31 +0800 Subject: [PATCH] feat: file schem file replace --- .../workflow/hooks/use-workflow-variables.ts | 6 +++++- .../nodes/_base/components/variable/utils.ts | 15 ++++++++++++--- .../workflow/nodes/data-source/default.ts | 11 ++++++----- .../components/condition-list/condition-item.tsx | 3 +++ web/app/components/workflow/nodes/tool/default.ts | 11 ++++++----- web/app/components/workflow/types.ts | 2 +- web/app/components/workflow/utils/tool.ts | 12 ------------ 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/web/app/components/workflow/hooks/use-workflow-variables.ts b/web/app/components/workflow/hooks/use-workflow-variables.ts index 429aaef73e..d5eebfde77 100644 --- a/web/app/components/workflow/hooks/use-workflow-variables.ts +++ b/web/app/components/workflow/hooks/use-workflow-variables.ts @@ -11,10 +11,12 @@ import type { import { useIsChatMode } from './use-workflow' import { useStoreApi } from 'reactflow' import type { Type } from '../nodes/llm/types' +import useMatchSchemaType from '../nodes/_base/components/variable/use-match-schema-type' export const useWorkflowVariables = () => { const { t } = useTranslation() const workflowStore = useWorkflowStore() + const { getMatchedSchemaType } = useMatchSchemaType() const getNodeAvailableVars = useCallback(({ parentNode, @@ -57,8 +59,9 @@ export const useWorkflowVariables = () => { mcpTools, dataSourceList: dataSourceList ?? [], }, + getMatchedSchemaType, }) - }, [t, workflowStore]) + }, [t, workflowStore, getMatchedSchemaType]) const getCurrentVariableType = useCallback(({ parentNode, @@ -105,6 +108,7 @@ export const useWorkflowVariables = () => { mcpTools, dataSourceList: dataSourceList ?? [], }, + getMatchedSchemaType, }) }, [workflowStore]) 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 f03f819afd..5324e94f48 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -233,6 +233,7 @@ const formatItem = ( filterVar: (payload: Var, selector: ValueSelector) => boolean, allPluginInfoList: Record, ragVars?: Var[], + getMatchedSchemaType = (_obj: any) => '', ): NodeOutPutVar => { const { id, data } = item @@ -414,7 +415,7 @@ const formatItem = ( } case BlockEnum.Tool: { - const toolOutputVars = ToolNodeDefault.getOutputVars?.(data as ToolNodeType, allPluginInfoList) || [] + const toolOutputVars = ToolNodeDefault.getOutputVars?.(data as ToolNodeType, allPluginInfoList, [], { getMatchedSchemaType }) || [] res.vars = toolOutputVars break } @@ -510,7 +511,7 @@ const formatItem = ( case BlockEnum.DataSource: { const payload = data as DataSourceNodeType - const dataSourceVars = DataSourceNodeDefault.getOutputVars?.(payload, allPluginInfoList, ragVars) || [] + const dataSourceVars = DataSourceNodeDefault.getOutputVars?.(payload, allPluginInfoList, ragVars, { getMatchedSchemaType }) || [] res.vars = dataSourceVars break } @@ -640,6 +641,7 @@ export const toNodeOutputVars = ( conversationVariables: ConversationVariable[] = [], ragVariables: RAGPipelineVariable[] = [], allPluginInfoList: Record, + getMatchedSchemaType = (_obj: any) => '', ): NodeOutPutVar[] => { // ENV_NODE data format const ENV_NODE = { @@ -697,7 +699,7 @@ export const toNodeOutputVars = ( description: ragVariable.label, isRagVariable: true, } as Var), - )), + ), getMatchedSchemaType), isStartNode: node.data.type === BlockEnum.Start, } }).filter(item => item.vars.length > 0) @@ -822,6 +824,7 @@ export const getVarType = ({ conversationVariables = [], ragVariables = [], allPluginInfoList, + getMatchedSchemaType, }: { valueSelector: ValueSelector parentNode?: Node | null @@ -834,6 +837,7 @@ export const getVarType = ({ conversationVariables?: ConversationVariable[] ragVariables?: RAGPipelineVariable[] allPluginInfoList: Record + getMatchedSchemaType: (obj: any) => string }): VarType => { if (isConstant) return VarType.string @@ -846,6 +850,7 @@ export const getVarType = ({ conversationVariables, ragVariables, allPluginInfoList, + getMatchedSchemaType, ) const isIterationInnerVar = parentNode?.data.type === BlockEnum.Iteration @@ -972,6 +977,7 @@ export const toNodeAvailableVars = ({ ragVariables, filterVar, allPluginInfoList, + getMatchedSchemaType, }: { parentNode?: Node | null t?: any @@ -986,6 +992,7 @@ export const toNodeAvailableVars = ({ ragVariables?: RAGPipelineVariable[] filterVar: (payload: Var, selector: ValueSelector) => boolean allPluginInfoList: Record + getMatchedSchemaType: (obj: any) => string }): NodeOutPutVar[] => { const beforeNodesOutputVars = toNodeOutputVars( beforeNodes, @@ -995,6 +1002,7 @@ export const toNodeAvailableVars = ({ conversationVariables, ragVariables, allPluginInfoList, + getMatchedSchemaType, ) const isInIteration = parentNode?.data.type === BlockEnum.Iteration if (isInIteration) { @@ -1008,6 +1016,7 @@ export const toNodeAvailableVars = ({ environmentVariables, conversationVariables, allPluginInfoList, + getMatchedSchemaType, }) const itemChildren = itemType === VarType.file ? { diff --git a/web/app/components/workflow/nodes/data-source/default.ts b/web/app/components/workflow/nodes/data-source/default.ts index 6e7d4cd2de..f7ddaf4178 100644 --- a/web/app/components/workflow/nodes/data-source/default.ts +++ b/web/app/components/workflow/nodes/data-source/default.ts @@ -8,7 +8,7 @@ import { LOCAL_FILE_OUTPUT, } from './constants' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' -import { getOutputVariableAlias } from '@/app/components/workflow/utils/tool' +import type { AnyObj } from '../_base/components/variable/match-schema-type' const i18nPrefix = 'workflow.errorMsg' @@ -54,12 +54,13 @@ const nodeDefault: NodeDefault = { errorMessage, } }, - getOutputVars(payload, allPluginInfoList, ragVars = []) { + getOutputVars(payload, allPluginInfoList, ragVars = [], { getMatchedSchemaType } = { getMatchedSchemaType: (_obj: AnyObj) => '' }) { const { plugin_id, datasource_name, provider_type, } = payload + const isLocalFile = provider_type === DataSourceClassification.localFile const currentDataSource = allPluginInfoList.dataSourceList?.find((ds: any) => ds.plugin_id === plugin_id) const currentDataSourceItem = currentDataSource?.tools?.find((tool: any) => tool.name === datasource_name) @@ -70,19 +71,19 @@ const nodeDefault: NodeDefault = { Object.keys(output_schema.properties).forEach((outputKey) => { const output = output_schema.properties[outputKey] const dataType = output.type - const alias = getOutputVariableAlias(output.properties) let type = dataType === 'array' ? `array[${output.items?.type.slice(0, 1).toLocaleLowerCase()}${output.items?.type.slice(1)}]` : `${dataType.slice(0, 1).toLocaleLowerCase()}${dataType.slice(1)}` + const schemaType = getMatchedSchemaType?.(output) - if (type === 'object' && alias === 'file') + if (type === 'object' && schemaType === 'file') type = 'file' dynamicOutputSchema.push({ variable: outputKey, type, description: output.description, - alias, + schemaType, children: output.type === 'object' ? { schema: { type: 'object', diff --git a/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx b/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx index 0c23139a28..1a76622c57 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx @@ -41,6 +41,7 @@ import { Variable02 } from '@/app/components/base/icons/src/vender/solid/develop import BoolValue from '@/app/components/workflow/panel/chat-variable-panel/components/bool-value' import { getVarType } from '@/app/components/workflow/nodes/_base/components/variable/utils' import { useIsChatMode } from '@/app/components/workflow/hooks/use-workflow' +import useMatchSchemaType from '../../../_base/components/variable/use-match-schema-type' const optionNameI18NPrefix = 'workflow.nodes.ifElse.optionName' type ConditionItemProps = { @@ -208,6 +209,7 @@ const ConditionItem = ({ onRemoveCondition?.(caseId, condition.id) }, [caseId, condition, conditionId, isSubVariableKey, onRemoveCondition, onRemoveSubVariableCondition]) + const { getMatchedSchemaType } = useMatchSchemaType() const handleVarChange = useCallback((valueSelector: ValueSelector, _varItem: Var) => { const { conversationVariables, @@ -224,6 +226,7 @@ const ConditionItem = ({ workflowTools, dataSourceList: dataSourceList ?? [], }, + getMatchedSchemaType, }) const newCondition = produce(condition, (draft) => { diff --git a/web/app/components/workflow/nodes/tool/default.ts b/web/app/components/workflow/nodes/tool/default.ts index bfe7d8fdd8..f201147f5a 100644 --- a/web/app/components/workflow/nodes/tool/default.ts +++ b/web/app/components/workflow/nodes/tool/default.ts @@ -1,4 +1,4 @@ -import { genNodeMetaData, getOutputVariableAlias } from '@/app/components/workflow/utils' +import { genNodeMetaData } from '@/app/components/workflow/utils' import { BlockEnum, VarType } from '@/app/components/workflow/types' import type { NodeDefault, ToolWithProvider } from '../../types' import type { ToolNodeType } from './types' @@ -6,6 +6,7 @@ import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/typ import { TOOL_OUTPUT_STRUCT } from '../../constants' import { CollectionType } from '@/app/components/tools/types' import { canFindTool } from '@/utils' +import type { AnyObj } from '../_base/components/variable/match-schema-type' const i18nPrefix = 'workflow.errorMsg' @@ -65,7 +66,7 @@ const nodeDefault: NodeDefault = { errorMessage: errorMessages, } }, - getOutputVars(payload: ToolNodeType, allPluginInfoList: Record) { + getOutputVars(payload: ToolNodeType, allPluginInfoList: Record, _ragVars: any, { getMatchedSchemaType } = { getMatchedSchemaType: (_obj: AnyObj) => '' }) { const { provider_id, provider_type } = payload let currentTools: ToolWithProvider[] = [] switch (provider_type) { @@ -96,19 +97,19 @@ const nodeDefault: NodeDefault = { Object.keys(output_schema.properties).forEach((outputKey) => { const output = output_schema.properties[outputKey] const dataType = output.type - const alias = getOutputVariableAlias(output.properties) + const schemaType = getMatchedSchemaType?.(output.value) let type = dataType === 'array' ? `array[${output.items?.type.slice(0, 1).toLocaleLowerCase()}${output.items?.type.slice(1)}]` : `${output.type.slice(0, 1).toLocaleLowerCase()}${output.type.slice(1)}` - if (type === VarType.object && alias === 'file') + if (type === VarType.object && schemaType === 'file') type = VarType.file outputSchema.push({ variable: outputKey, type, description: output.description, - alias, + schemaType, children: output.type === 'object' ? { schema: { type: 'object', diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index 593e8c1af3..4d2af1c28a 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -333,7 +333,7 @@ export type NodeDefault = { defaultValue: Partial defaultRunInputData?: Record checkValid: (payload: T, t: any, moreDataForCheckValid?: any) => { isValid: boolean; errorMessage?: string } - getOutputVars?: (payload: T, allPluginInfoList: Record, ragVariables?: Var[]) => Var[] + getOutputVars?: (payload: T, allPluginInfoList: Record, ragVariables?: Var[], utils?: { getMatchedSchemaType: (obj: any) => string }) => Var[] } export type OnSelectBlock = (type: BlockEnum, toolDefaultValue?: ToolDefaultValue | DataSourceDefaultValue) => void diff --git a/web/app/components/workflow/utils/tool.ts b/web/app/components/workflow/utils/tool.ts index ca92c5079d..1c3b792d9e 100644 --- a/web/app/components/workflow/utils/tool.ts +++ b/web/app/components/workflow/utils/tool.ts @@ -50,18 +50,6 @@ export const CHUNK_TYPE_MAP = { qa_chunks: 'QAStructureChunk', } -// deprecated, use schemaType in llm/types.ts instead -export const getOutputVariableAlias = (variable: Record) => { - if (variable?.general_chunks) - return CHUNK_TYPE_MAP.general_chunks - if (variable?.parent_child_chunks) - return CHUNK_TYPE_MAP.parent_child_chunks - if (variable?.qa_chunks) - return CHUNK_TYPE_MAP.qa_chunks - if (variable?.file_type) - return 'file' -} - export const wrapStructuredVarItem = (outputItem: any, matchedSchemaType: string): StructuredOutput => { const dataType = Type.object return {