From b9052bc244952b6c89ab066dfa79b64d292992ac Mon Sep 17 00:00:00 2001 From: zhsama Date: Wed, 14 Jan 2026 03:22:42 +0800 Subject: [PATCH] feat: add sub-graph config panel with variable selection and null handling --- .../sub-graph/components/config-panel.tsx | 219 +++++++++++++----- .../components/sub-graph-children.tsx | 84 +++++-- .../sub-graph/components/sub-graph-main.tsx | 23 +- web/app/components/sub-graph/index.tsx | 31 ++- web/app/components/sub-graph/types.ts | 3 + .../tool/components/sub-graph-modal/index.tsx | 65 +++++- .../sub-graph-modal/sub-graph-canvas.tsx | 4 + .../tool/components/sub-graph-modal/types.ts | 3 + web/i18n/en-US/workflow.json | 4 + web/i18n/ja-JP/workflow.json | 4 + web/i18n/zh-Hans/workflow.json | 4 + web/i18n/zh-Hant/workflow.json | 4 + 12 files changed, 351 insertions(+), 97 deletions(-) diff --git a/web/app/components/sub-graph/components/config-panel.tsx b/web/app/components/sub-graph/components/config-panel.tsx index 9f0245c23d..0b8674ffe4 100644 --- a/web/app/components/sub-graph/components/config-panel.tsx +++ b/web/app/components/sub-graph/components/config-panel.tsx @@ -1,85 +1,178 @@ 'use client' import type { FC } from 'react' -import type { WhenOutputNoneOption } from '../types' -import { memo, useCallback, useState } from 'react' +import type { Item } from '@/app/components/base/select' +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' +import type { Node, NodeOutPutVar, ValueSelector } from '@/app/components/workflow/types' +import { RiCheckLine } from '@remixicon/react' +import { memo, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import { SimpleSelect } from '@/app/components/base/select' +import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import Field from '@/app/components/workflow/nodes/_base/components/field' +import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' +import Tab, { TabType } from '@/app/components/workflow/nodes/_base/components/workflow-panel/tab' +import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { cn } from '@/utils/classnames' type ConfigPanelProps = { - toolNodeId: string - paramKey: string - activeTab: 'settings' | 'lastRun' - onTabChange: (tab: 'settings' | 'lastRun') => void + agentName: string + extractorNodeId: string + mentionConfig: MentionConfig + availableNodes: Node[] + availableVars: NodeOutPutVar[] + onMentionConfigChange: (config: MentionConfig) => void } -const outputVariables = [ - { name: 'text', type: 'string' }, - { name: 'structured_output', type: 'object' }, -] - const ConfigPanel: FC = ({ - toolNodeId: _toolNodeId, - paramKey: _paramKey, - activeTab, + agentName, + extractorNodeId, + mentionConfig, + availableNodes, + availableVars, + onMentionConfigChange, }) => { const { t } = useTranslation() - const [whenOutputNone, setWhenOutputNone] = useState('default') + const [tabType, setTabType] = useState(TabType.settings) - const handleWhenOutputNoneChange = useCallback((e: React.ChangeEvent) => { - setWhenOutputNone(e.target.value as WhenOutputNoneOption) - }, []) + const resolvedExtractorId = mentionConfig.extractor_node_id || extractorNodeId - if (activeTab === 'lastRun') { - return ( -
-
+ const selectedOutput = useMemo(() => { + if (!resolvedExtractorId || !mentionConfig.output_selector?.length) + return [] + + return [resolvedExtractorId, ...(mentionConfig.output_selector || [])] + }, [mentionConfig.output_selector, resolvedExtractorId]) + + const handleOutputVarChange = useCallback((value: ValueSelector | string) => { + const selector = Array.isArray(value) ? value : [] + const nextExtractorId = selector[0] || resolvedExtractorId + const nextOutputSelector = selector.length > 1 ? selector.slice(1) : [] + + onMentionConfigChange({ + ...mentionConfig, + extractor_node_id: nextExtractorId, + output_selector: nextOutputSelector, + }) + }, [mentionConfig, onMentionConfigChange, resolvedExtractorId]) + + const whenOutputNoneOptions = useMemo(() => ([ + { + value: 'raise_error', + name: t('subGraphModal.whenOutputNone.error', { ns: 'workflow' }), + description: t('subGraphModal.whenOutputNone.errorDesc', { ns: 'workflow' }), + }, + { + value: 'use_default', + name: t('subGraphModal.whenOutputNone.default', { ns: 'workflow' }), + description: t('subGraphModal.whenOutputNone.defaultDesc', { ns: 'workflow' }), + }, + ]), [t]) + + const handleNullStrategyChange = useCallback((item: Item) => { + if (typeof item.value !== 'string') + return + onMentionConfigChange({ + ...mentionConfig, + null_strategy: item.value as MentionConfig['null_strategy'], + }) + }, [mentionConfig, onMentionConfigChange]) + + const handleDefaultValueChange = useCallback((value: string) => { + const trimmed = value.trim() + let nextValue: unknown = value + if ((trimmed.startsWith('{') && trimmed.endsWith('}')) || (trimmed.startsWith('[') && trimmed.endsWith(']'))) { + try { + nextValue = JSON.parse(trimmed) + } + catch { + nextValue = value + } + } + + onMentionConfigChange({ + ...mentionConfig, + default_value: nextValue, + }) + }, [mentionConfig, onMentionConfigChange]) + + return ( +
+
+
+ {t('subGraphModal.internalStructure', { ns: 'workflow' })} +
+
+ {t('subGraphModal.internalStructureDesc', { ns: 'workflow', name: agentName })} +
+
+
+ +
+ {tabType === TabType.lastRun && ( +

{t('subGraphModal.noRunHistory', { ns: 'workflow' })}

-
- ) - } - - return ( -
- -
- {outputVariables.map(variable => ( -
- {variable.name} - {variable.type} -
- ))} + )} + {tabType === TabType.settings && ( +
+
+ + + +
+
+ + ( +
+
+ {selected && ( + + )} +
+
+
{item.name}
+
{item.description}
+
+
+ )} + /> +
+ {mentionConfig.null_strategy === 'use_default' && ( +
+
+ {t('subGraphModal.defaultValueHint', { ns: 'workflow' })} +
+
+ +
+
+ )} +
- - - - - + )}
) } diff --git a/web/app/components/sub-graph/components/sub-graph-children.tsx b/web/app/components/sub-graph/components/sub-graph-children.tsx index c9cb989f53..618d0c9e20 100644 --- a/web/app/components/sub-graph/components/sub-graph-children.tsx +++ b/web/app/components/sub-graph/components/sub-graph-children.tsx @@ -1,36 +1,72 @@ import type { FC } from 'react' -import type { SubGraphConfig } from '../types' +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' +import type { NodeOutPutVar } from '@/app/components/workflow/types' import { memo, useMemo } from 'react' import { useStore as useReactFlowStore } from 'reactflow' import { useShallow } from 'zustand/react/shallow' +import { useIsChatMode, useWorkflowVariables } from '@/app/components/workflow/hooks' import { Panel as NodePanel } from '@/app/components/workflow/nodes' +import { useStore } from '@/app/components/workflow/store' import { BlockEnum } from '@/app/components/workflow/types' +import ConfigPanel from './config-panel' type SubGraphChildrenProps = { - toolNodeId: string - paramKey: string - onConfigChange: (config: Partial) => void + agentName: string + extractorNodeId: string + mentionConfig: MentionConfig + onMentionConfigChange: (config: MentionConfig) => void } const SubGraphChildren: FC = ({ - toolNodeId: _toolNodeId, - paramKey: _paramKey, - onConfigChange: _onConfigChange, + agentName, + extractorNodeId, + mentionConfig, + onMentionConfigChange, }) => { - const selectedNode = useReactFlowStore(useShallow((s) => { + const { getNodeAvailableVars } = useWorkflowVariables() + const isChatMode = useIsChatMode() + const nodePanelWidth = useStore(s => s.nodePanelWidth) + + const { selectedNode, nodes } = useReactFlowStore(useShallow((s) => { const nodes = s.getNodes() const currentNode = nodes.find(node => node.data.selected) if (currentNode?.data.type === BlockEnum.LLM) { return { - id: currentNode.id, - type: currentNode.type, - data: currentNode.data, + selectedNode: { + id: currentNode.id, + type: currentNode.type, + data: currentNode.data, + }, + nodes, } } - return null + return { + selectedNode: null, + nodes, + } })) + const extractorNode = useMemo(() => { + return nodes.find(node => node.data.type === BlockEnum.LLM) + }, [nodes]) + + const availableNodes = useMemo(() => { + return extractorNode ? [extractorNode] : [] + }, [extractorNode]) + + const availableVars = useMemo(() => { + if (!extractorNode) + return [] + + const vars = getNodeAvailableVars({ + beforeNodes: [extractorNode], + isChatMode, + filterVar: () => true, + }) + return vars.filter(item => item.nodeId === extractorNode.id) + }, [extractorNode, getNodeAvailableVars, isChatMode]) + const nodePanel = useMemo(() => { if (!selectedNode) return null @@ -46,11 +82,25 @@ const SubGraphChildren: FC = ({ return (
- {nodePanel && ( -
- {nodePanel} -
- )} +
+ {nodePanel || ( +
+
+ +
+
+ )} +
) } diff --git a/web/app/components/sub-graph/components/sub-graph-main.tsx b/web/app/components/sub-graph/components/sub-graph-main.tsx index 727693162c..c9e1c93428 100644 --- a/web/app/components/sub-graph/components/sub-graph-main.tsx +++ b/web/app/components/sub-graph/components/sub-graph-main.tsx @@ -1,18 +1,21 @@ import type { FC } from 'react' import type { Viewport } from 'reactflow' +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' import type { Edge, Node } from '@/app/components/workflow/types' import { useCallback, useMemo } from 'react' import { useStoreApi } from 'reactflow' import { WorkflowWithInnerContext } from '@/app/components/workflow' -import { useAvailableNodesMetaData, useSubGraphPersistence } from '../hooks' +import { useAvailableNodesMetaData } from '../hooks' import SubGraphChildren from './sub-graph-children' type SubGraphMainProps = { nodes: Node[] edges: Edge[] viewport: Viewport - toolNodeId: string - paramKey: string + agentName: string + extractorNodeId: string + mentionConfig: MentionConfig + onMentionConfigChange: (config: MentionConfig) => void onSave?: (nodes: Node[], edges: Edge[]) => void } @@ -20,13 +23,14 @@ const SubGraphMain: FC = ({ nodes, edges, viewport, - toolNodeId, - paramKey, + agentName, + extractorNodeId, + mentionConfig, + onMentionConfigChange, onSave, }) => { const reactFlowStore = useStoreApi() const availableNodesMetaData = useAvailableNodesMetaData() - const { updateSubGraphConfig } = useSubGraphPersistence({ toolNodeId, paramKey }) const handleSyncSubGraphDraft = useCallback(() => { const { getNodes, edges } = reactFlowStore.getState() @@ -53,9 +57,10 @@ const SubGraphMain: FC = ({ interactionMode="subgraph" > ) diff --git a/web/app/components/sub-graph/index.tsx b/web/app/components/sub-graph/index.tsx index c7ec066108..79f13f0161 100644 --- a/web/app/components/sub-graph/index.tsx +++ b/web/app/components/sub-graph/index.tsx @@ -5,16 +5,27 @@ import type { InjectWorkflowStoreSliceFn } from '@/app/components/workflow/store import type { PromptItem } from '@/app/components/workflow/types' import { memo, useMemo } from 'react' import WorkflowWithDefaultContext from '@/app/components/workflow' +import { NODE_WIDTH_X_OFFSET, START_INITIAL_POSITION } from '@/app/components/workflow/constants' import { WorkflowContextProvider } from '@/app/components/workflow/context' import { BlockEnum, EditionType, PromptRole } from '@/app/components/workflow/types' import SubGraphMain from './components/sub-graph-main' import { useSubGraphNodes } from './hooks' import { createSubGraphSlice } from './store' +const SUB_GRAPH_EDGE_GAP = 180 +const SUB_GRAPH_ENTRY_POSITION = { + x: START_INITIAL_POSITION.x, + y: 150, +} +const SUB_GRAPH_LLM_POSITION = { + x: SUB_GRAPH_ENTRY_POSITION.x + NODE_WIDTH_X_OFFSET - SUB_GRAPH_EDGE_GAP, + y: SUB_GRAPH_ENTRY_POSITION.y, +} + const defaultViewport: Viewport = { - x: 50, + x: SUB_GRAPH_EDGE_GAP, y: 50, - zoom: 1, + zoom: 1.3, } const SubGraph: FC = (props) => { @@ -23,6 +34,8 @@ const SubGraph: FC = (props) => { paramKey, agentName, agentNodeId, + mentionConfig, + onMentionConfigChange, extractorNode, toolParamValue, onSave, @@ -41,7 +54,7 @@ const SubGraph: FC = (props) => { return { id: 'subgraph-source', type: 'custom', - position: { x: 100, y: 150 }, + position: SUB_GRAPH_ENTRY_POSITION, data: { type: BlockEnum.Start, title: agentName, @@ -50,8 +63,10 @@ const SubGraph: FC = (props) => { _connectedTargetHandleIds: [], _subGraphEntry: true, _iconTypeOverride: BlockEnum.Agent, + selected: false, variables: [], }, + selected: false, selectable: false, draggable: false, connectable: false, @@ -110,9 +125,11 @@ const SubGraph: FC = (props) => { return { ...extractorNode, hidden: false, - position: { x: 320, y: 150 }, + selected: false, + position: SUB_GRAPH_LLM_POSITION, data: { ...extractorNode.data, + selected: false, prompt_template: nextPromptTemplate, }, } @@ -159,8 +176,10 @@ const SubGraph: FC = (props) => { nodes={nodes} edges={edges} viewport={defaultViewport} - toolNodeId={toolNodeId} - paramKey={paramKey} + agentName={agentName} + extractorNodeId={`${toolNodeId}_ext_${paramKey}`} + mentionConfig={mentionConfig} + onMentionConfigChange={onMentionConfigChange} onSave={onSave} /> diff --git a/web/app/components/sub-graph/types.ts b/web/app/components/sub-graph/types.ts index 957acba417..587ed9e451 100644 --- a/web/app/components/sub-graph/types.ts +++ b/web/app/components/sub-graph/types.ts @@ -1,4 +1,5 @@ import type { StateCreator } from 'zustand' +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types' import type { Edge, Node, NodeOutPutVar, ValueSelector, VarType } from '@/app/components/workflow/types' @@ -26,6 +27,8 @@ export type SubGraphProps = { sourceVariable: ValueSelector agentNodeId: string agentName: string + mentionConfig: MentionConfig + onMentionConfigChange: (config: MentionConfig) => void extractorNode?: Node toolParamValue?: string onSave?: (nodes: Node[], edges: Edge[]) => void diff --git a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx index ea539b5d5c..373b3153a1 100644 --- a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx +++ b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/index.tsx @@ -1,17 +1,19 @@ 'use client' import type { FC } from 'react' import type { SubGraphModalProps } from './types' +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types' import type { ToolNodeType } from '@/app/components/workflow/nodes/tool/types' import type { Node, PromptItem } from '@/app/components/workflow/types' import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react' import { RiCloseLine } from '@remixicon/react' import { noop } from 'es-toolkit/function' -import { Fragment, memo, useCallback, useMemo } from 'react' +import { Fragment, memo, useCallback, useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { useStoreApi } from 'reactflow' import { Agent } from '@/app/components/base/icons/src/vender/workflow' import { useNodesSyncDraft } from '@/app/components/workflow/hooks' +import { VarKindType } from '@/app/components/workflow/nodes/_base/types' import { useStore } from '@/app/components/workflow/store' import { EditionType, PromptRole } from '@/app/components/workflow/types' import SubGraphCanvas from './sub-graph-canvas' @@ -38,7 +40,64 @@ const SubGraphModal: FC = ({ const toolNode = useMemo(() => { return workflowNodes.find(node => node.id === toolNodeId) }, [toolNodeId, workflowNodes]) - const toolParamValue = (toolNode?.data as ToolNodeType | undefined)?.tool_parameters?.[paramKey]?.value as string | undefined + const toolParam = (toolNode?.data as ToolNodeType | undefined)?.tool_parameters?.[paramKey] + const toolParamValue = toolParam?.value as string | undefined + + const mentionConfig = useMemo(() => { + const current = toolParam?.mention_config + const rawSelector = Array.isArray(current?.output_selector) ? current!.output_selector : [] + const outputSelector = rawSelector[0] === extractorNodeId ? rawSelector.slice(1) : rawSelector + return { + extractor_node_id: current?.extractor_node_id || extractorNodeId, + output_selector: outputSelector, + null_strategy: current?.null_strategy || 'use_default', + default_value: current?.default_value ?? '', + } + }, [extractorNodeId, toolParam?.mention_config]) + + const handleMentionConfigChange = useCallback((config: MentionConfig) => { + const { getNodes, setNodes } = reactflowStore.getState() + const nextNodes = getNodes().map((node) => { + if (node.id !== toolNodeId) + return node + + const toolData = node.data as ToolNodeType + const currentParam = toolData.tool_parameters?.[paramKey] + if (!currentParam) + return node + + return { + ...node, + data: { + ...toolData, + tool_parameters: { + ...toolData.tool_parameters, + [paramKey]: { + ...currentParam, + type: currentParam.type || VarKindType.mention, + mention_config: config, + }, + }, + }, + } + }) + setNodes(nextNodes) + handleSyncWorkflowDraft(true) + }, [handleSyncWorkflowDraft, paramKey, reactflowStore, toolNodeId]) + + useEffect(() => { + if (!toolParam || (toolParam.type && toolParam.type !== VarKindType.mention)) + return + + const current = toolParam.mention_config + const needsExtractor = !current?.extractor_node_id + const needsNullStrategy = !current?.null_strategy + const needsOutputSelector = !Array.isArray(current?.output_selector) + const needsDefaultValue = current?.default_value === undefined + + if (needsExtractor || needsNullStrategy || needsOutputSelector || needsDefaultValue) + handleMentionConfigChange(mentionConfig) + }, [handleMentionConfigChange, mentionConfig, toolParam]) const getUserPromptText = useCallback((promptTemplate?: PromptItem[] | PromptItem) => { if (!promptTemplate) @@ -147,6 +206,8 @@ const SubGraphModal: FC = ({ sourceVariable={sourceVariable} agentNodeId={agentNodeId} agentName={agentName} + mentionConfig={mentionConfig} + onMentionConfigChange={handleMentionConfigChange} extractorNode={extractorNode} toolParamValue={toolParamValue} onSave={handleSave} diff --git a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/sub-graph-canvas.tsx b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/sub-graph-canvas.tsx index 120015e189..e838ddbceb 100644 --- a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/sub-graph-canvas.tsx +++ b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/sub-graph-canvas.tsx @@ -10,6 +10,8 @@ const SubGraphCanvas: FC = ({ sourceVariable, agentNodeId, agentName, + mentionConfig, + onMentionConfigChange, extractorNode, toolParamValue, onSave, @@ -22,6 +24,8 @@ const SubGraphCanvas: FC = ({ sourceVariable={sourceVariable} agentNodeId={agentNodeId} agentName={agentName} + mentionConfig={mentionConfig} + onMentionConfigChange={onMentionConfigChange} extractorNode={extractorNode} toolParamValue={toolParamValue} onSave={onSave} diff --git a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/types.ts b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/types.ts index 4023b258c7..b4e3dada85 100644 --- a/web/app/components/workflow/nodes/tool/components/sub-graph-modal/types.ts +++ b/web/app/components/workflow/nodes/tool/components/sub-graph-modal/types.ts @@ -1,3 +1,4 @@ +import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types' import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types' import type { Edge as WorkflowEdge, Node as WorkflowNode } from '@/app/components/workflow/types' @@ -19,6 +20,8 @@ export type SubGraphCanvasProps = { sourceVariable: WorkflowValueSelector agentNodeId: string agentName: string + mentionConfig: MentionConfig + onMentionConfigChange: (config: MentionConfig) => void extractorNode?: WorkflowNode toolParamValue?: string onSave?: (nodes: WorkflowNode[], edges: WorkflowEdge[]) => void diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 686fe3f7cc..ec2e838feb 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -989,7 +989,9 @@ "singleRun.testRunIteration": "Test Run Iteration", "singleRun.testRunLoop": "Test Run Loop", "subGraphModal.canvasPlaceholder": "Click to configure the internal structure", + "subGraphModal.defaultValueHint": "Returns the value below", "subGraphModal.internalStructure": "Internal structure", + "subGraphModal.internalStructureDesc": "Internal structure of @{{name}}", "subGraphModal.lastRun": "LAST RUN", "subGraphModal.noRunHistory": "No run history yet", "subGraphModal.outputVariables": "OUTPUT VARIABLES", @@ -998,7 +1000,9 @@ "subGraphModal.title": "INTERNAL STRUCTURE", "subGraphModal.whenOutputIsNone": "WHEN OUTPUT IS NONE", "subGraphModal.whenOutputNone.default": "Use default value", + "subGraphModal.whenOutputNone.defaultDesc": "Continue with a default value", "subGraphModal.whenOutputNone.error": "Raise an error", + "subGraphModal.whenOutputNone.errorDesc": "Pass the error to the outer workflow", "subGraphModal.whenOutputNone.skip": "Skip this step", "tabs.-": "Default", "tabs.addAll": "Add all", diff --git a/web/i18n/ja-JP/workflow.json b/web/i18n/ja-JP/workflow.json index 1435f672e8..555867256d 100644 --- a/web/i18n/ja-JP/workflow.json +++ b/web/i18n/ja-JP/workflow.json @@ -986,7 +986,9 @@ "singleRun.testRunIteration": "テスト実行(イテレーション)", "singleRun.testRunLoop": "テスト実行ループ", "subGraphModal.canvasPlaceholder": "クリックして内部構造を設定", + "subGraphModal.defaultValueHint": "以下の値を返す", "subGraphModal.internalStructure": "内部構造", + "subGraphModal.internalStructureDesc": "@{{name}} の内部構造", "subGraphModal.lastRun": "前回の実行", "subGraphModal.noRunHistory": "実行履歴がありません", "subGraphModal.outputVariables": "出力変数", @@ -995,7 +997,9 @@ "subGraphModal.title": "内部構造", "subGraphModal.whenOutputIsNone": "出力が空の場合", "subGraphModal.whenOutputNone.default": "デフォルト値を使用", + "subGraphModal.whenOutputNone.defaultDesc": "デフォルト値で続行", "subGraphModal.whenOutputNone.error": "エラーを発生させる", + "subGraphModal.whenOutputNone.errorDesc": "エラーを外部ワークフローに渡す", "subGraphModal.whenOutputNone.skip": "このステップをスキップ", "tabs.-": "デフォルト", "tabs.addAll": "すべてを追加する", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 2b863487b0..cebe1cede5 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -987,7 +987,9 @@ "singleRun.testRunIteration": "测试运行迭代", "singleRun.testRunLoop": "测试运行循环", "subGraphModal.canvasPlaceholder": "点击配置内部结构", + "subGraphModal.defaultValueHint": "返回以下值", "subGraphModal.internalStructure": "内部结构", + "subGraphModal.internalStructureDesc": "@{{name}} 的内部结构", "subGraphModal.lastRun": "上次运行", "subGraphModal.noRunHistory": "暂无运行记录", "subGraphModal.outputVariables": "输出变量", @@ -996,7 +998,9 @@ "subGraphModal.title": "内部结构", "subGraphModal.whenOutputIsNone": "当输出为空时", "subGraphModal.whenOutputNone.default": "使用默认值", + "subGraphModal.whenOutputNone.defaultDesc": "使用默认值继续执行", "subGraphModal.whenOutputNone.error": "抛出错误", + "subGraphModal.whenOutputNone.errorDesc": "将错误传递给外部工作流", "subGraphModal.whenOutputNone.skip": "跳过此步骤", "tabs.-": "默认", "tabs.addAll": "添加全部", diff --git a/web/i18n/zh-Hant/workflow.json b/web/i18n/zh-Hant/workflow.json index 11e91a7a9d..0d181bb69b 100644 --- a/web/i18n/zh-Hant/workflow.json +++ b/web/i18n/zh-Hant/workflow.json @@ -986,7 +986,9 @@ "singleRun.testRunIteration": "測試運行迭代", "singleRun.testRunLoop": "測試運行循環", "subGraphModal.canvasPlaceholder": "點擊配置內部結構", + "subGraphModal.defaultValueHint": "返回以下值", "subGraphModal.internalStructure": "內部結構", + "subGraphModal.internalStructureDesc": "@{{name}} 的內部結構", "subGraphModal.lastRun": "上次執行", "subGraphModal.noRunHistory": "暫無執行記錄", "subGraphModal.outputVariables": "輸出變數", @@ -995,7 +997,9 @@ "subGraphModal.title": "內部結構", "subGraphModal.whenOutputIsNone": "當輸出為空時", "subGraphModal.whenOutputNone.default": "使用預設值", + "subGraphModal.whenOutputNone.defaultDesc": "使用預設值繼續執行", "subGraphModal.whenOutputNone.error": "拋出錯誤", + "subGraphModal.whenOutputNone.errorDesc": "將錯誤傳遞給外部工作流程", "subGraphModal.whenOutputNone.skip": "跳過此步驟", "tabs.-": "預設", "tabs.addAll": "全部新增",