diff --git a/web/src/views/ApplicationConfig/Cluster.tsx b/web/src/views/ApplicationConfig/Cluster.tsx index c452eef0..cfb5597f 100644 --- a/web/src/views/ApplicationConfig/Cluster.tsx +++ b/web/src/views/ApplicationConfig/Cluster.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:29:33 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-27 18:14:25 + * @Last Modified time: 2026-04-07 20:37:43 */ import { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react' import { useTranslation } from 'react-i18next' @@ -115,7 +115,8 @@ const Cluster = forwardRef item.agent_id) }) getApplicationList({ ids: sub_agents?.map(item => item.agent_id).join(',')}) .then(res => { - const applicationList = (res as Application[]) || [] + const applicationList = ((res as { items: Application[] }).items) || [] + setSubAgents(sub_agents.map(vo => { const filterVO = applicationList.find(item => item.id === vo.agent_id) if (filterVO) { @@ -194,6 +195,9 @@ const Cluster = forwardRef {loading && } diff --git a/web/src/views/ApplicationConfig/TestChat/index.tsx b/web/src/views/ApplicationConfig/TestChat/index.tsx index ede83fd8..427acc0b 100644 --- a/web/src/views/ApplicationConfig/TestChat/index.tsx +++ b/web/src/views/ApplicationConfig/TestChat/index.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-03-13 17:27:52 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-04-07 18:08:18 + * @Last Modified time: 2026-04-07 20:25:45 */ import { type FC, useState, useRef, useEffect } from 'react' import { useTranslation } from 'react-i18next' @@ -109,7 +109,7 @@ const TestChat: FC = ({ setFeatures(config?.features || {} as FeaturesConfigForm) - if (config?.features?.opening_statement.enabled && config?.features?.opening_statement?.statement && config?.features?.opening_statement?.statement.trim() !== '') { + if (config?.features?.opening_statement?.enabled && config?.features?.opening_statement?.statement && config?.features?.opening_statement?.statement.trim() !== '') { setChatList(prev => [...prev, { role: 'assistant', created_at: Date.now(), diff --git a/web/src/views/KnowledgeBase/index.tsx b/web/src/views/KnowledgeBase/index.tsx index 9e1a63ce..8c16d7a7 100644 --- a/web/src/views/KnowledgeBase/index.tsx +++ b/web/src/views/KnowledgeBase/index.tsx @@ -562,83 +562,88 @@ const KnowledgeBaseManagement: FC = () => { {data.length === 0 && !loading ? ( ) : ( -
- {data.map((item) => { - const modelInfo = modelMenus[item.id]; - const hasModelInfo = modelInfo && modelInfo.menu.length > 1; - return ( -
- e.stopPropagation()}> - -
e.stopPropagation()} className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]">
-
-
- } - > -
handleToDetail(item)}> -
- {/*
{t('knowledgeBase.description')}
*/} - -
{(item.description && item.description != '') ? item.description : t('knowledgeBase.noDescription')}
-
-
- - {item.descriptionItems?.map((description: Record) => ( -
-
{(description.label as string)}
-
{(description.children as string)}
-
- ))} -
- {hasModelInfo && ( -
e.stopPropagation()}> -
{ - setData(prev => prev.map(d => d.id === item.id ? { ...d, _expanded: !d._expanded } : d)); - }} - > - {/* {t('knowledgeBase.models')}: */} - - {modelInfo.summary[0].split(':')[0]}:{modelInfo.summary[0].split(':').slice(1).join(':')} - - - {item._expanded ? : } - -
- {item._expanded && ( -
- {modelInfo.summary.slice(1).map((text, idx) => { - const [label, value] = text.split(':'); - return ( -
- {label}:{value} -
- ); - })} + + {[0, 1, 2].map(colIdx => ( +
+ {data.filter((_, i) => i % 3 === colIdx).map((item) => { + const modelInfo = modelMenus[item.id]; + const hasModelInfo = modelInfo && modelInfo.menu.length > 1; + return ( +
+ e.stopPropagation()}> + +
e.stopPropagation()} className="rb:cursor-pointer rb:size-5.5 rb:bg-[url('@/assets/images/common/more.svg')] rb:hover:bg-[url('@/assets/images/common/more_hover.svg')]">
+
- )} -
- )} -
- + } + > +
handleToDetail(item)}> +
+ {/*
{t('knowledgeBase.description')}
*/} + +
{(item.description && item.description != '') ? item.description : t('knowledgeBase.noDescription')}
+
+
+ + {item.descriptionItems?.map((description: Record) => ( +
+
{(description.label as string)}
+
{(description.children as string)}
+
+ ))} +
+ {hasModelInfo && ( +
e.stopPropagation()}> +
{ + setData(prev => prev.map(d => d.id === item.id ? { ...d, _expanded: !d._expanded } : d)); + }} + > + {/* {t('knowledgeBase.models')}: */} + + {modelInfo.summary[0].split(':')[0]}:{modelInfo.summary[0].split(':').slice(1).join(':')} + + + {item._expanded ? : } + +
+ {item._expanded && ( +
+ {modelInfo.summary.slice(1).map((text, idx) => { + const [label, value] = text.split(':'); + return ( +
+ {label}:{value} +
+ ); + })} +
+ )} +
+ )} +
+ +
+ ) + })}
- )})} -
+ ))} + )} diff --git a/web/src/views/Workflow/components/AddChatVariable/ChatVariableModal.tsx b/web/src/views/Workflow/components/AddChatVariable/ChatVariableModal.tsx index 69ce73bd..b09802da 100644 --- a/web/src/views/Workflow/components/AddChatVariable/ChatVariableModal.tsx +++ b/web/src/views/Workflow/components/AddChatVariable/ChatVariableModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2025-12-30 13:59:36 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-04-02 19:01:12 + * @Last Modified time: 2026-04-07 20:17:59 */ import { forwardRef, useImperativeHandle, useState, useRef, useMemo } from 'react'; import { Form, Input, Select, InputNumber, Button, Row, Col, Flex, Spin } from 'antd'; @@ -135,7 +135,10 @@ const ChatVariableModal = forwardRef { form.validateFields().then((values) => { - refresh({ ...values, default: values.defaultValue }, editIndex); + const defaultValue = Array.isArray(values.defaultValue) + ? values.defaultValue.filter((v: any) => v !== undefined && v !== null && v !== '') + : values.defaultValue; + refresh({ ...values, defaultValue }, editIndex); handleClose(); }); }; diff --git a/web/src/views/Workflow/components/Properties/VariableSelect.tsx b/web/src/views/Workflow/components/Properties/VariableSelect.tsx index 38c48dba..4fd01363 100644 --- a/web/src/views/Workflow/components/Properties/VariableSelect.tsx +++ b/web/src/views/Workflow/components/Properties/VariableSelect.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 15:40:13 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-04-03 20:19:34 + * @Last Modified time: 2026-04-07 19:40:27 */ import { useState, useRef, useEffect, useLayoutEffect, type FC } from 'react' import { createPortal } from 'react-dom' @@ -232,15 +232,16 @@ const VariableSelect: FC = ({ {placeholder} ) ) : selectedSuggestion ? ( - - +
+ {!isConversation && nodeData?.icon &&
} - {!isConversation && nodeData?.name && {nodeData.name}{sep}} - + {!isConversation && nodeData?.name && {nodeData.name}} + {!isConversation && nodeData?.name && {sep}} + {parentOfSelected ? <>{parentOfSelected.label}{sep}{selectedSuggestion.label} : selectedSuggestion.label} - +
) : ( {placeholder} )} @@ -264,7 +265,7 @@ const VariableSelect: FC = ({ {open && createPortal(
@@ -272,8 +273,8 @@ const VariableSelect: FC = ({ const nd = suggestions[0].nodeData; return (
- - {nd.icon &&
} + + {nd.icon &&
} {nd.name} {suggestions.map(s => { @@ -286,14 +287,15 @@ const VariableSelect: FC = ({ { if (el) itemRefs.current.set(s.key, el); }} - className="rb:mx-3! rb:pl-3! rb:pr-3! rb:py-1.5! rb:rounded-lg!" + className={clsx("rb:pl-6! rb:pr-3! rb:py-1.25! rb:rounded-lg!", { + 'rb:bg-[#e6f4ff]': isSelected || isExpanded, + 'rb:bg-white rb:hover:bg-[#F6F6F6]!': !(isSelected || isExpanded), + 'rb:opacity-60': s.disabled, + 'rb:cursor-not-allowed': s.disabled, + 'rb:cursor-pointer': !s.disabled, + })} align="center" justify="space-between" - style={{ - cursor: s.disabled ? 'not-allowed' : 'pointer', - background: isSelected || isExpanded ? '#f0f8ff' : 'white', - opacity: s.disabled ? 0.5 : 1, - }} onClick={() => { if (s.disabled) return; if (hasChildren) { diff --git a/web/src/views/Workflow/components/Properties/hooks/useVariableList.ts b/web/src/views/Workflow/components/Properties/hooks/useVariableList.ts index 0c09136d..98494531 100644 --- a/web/src/views/Workflow/components/Properties/hooks/useVariableList.ts +++ b/web/src/views/Workflow/components/Properties/hooks/useVariableList.ts @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-01-19 17:00:26 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-04-02 16:58:40 + * @Last Modified time: 2026-04-07 20:33:26 */ /** * useVariableList Hook @@ -125,7 +125,7 @@ const processNodeVariables = ( if (type in NODE_VARIABLES) { if (type === 'list-operator') { // Determine output type from the first variable in config - const variableValue = config?.variable; + const variableValue = config?.input_list?.defaultValue; let itemType = 'string'; if (variableValue) { const refVar = variableList.find(v => `{{${v.value}}}` === variableValue); @@ -321,7 +321,6 @@ export const getChildNodeVariables = ( if (p?.name) addVariable(list, keys, `${nodeId}_${p.name}`, p.name, p.type || 'string', `${nodeId}.${p.name}`, nodeData); }); } - // Add code node variables if (type === 'code') { (nodeData.config?.output_variables?.defaultValue || []).forEach((p: any) => { @@ -393,8 +392,18 @@ export const useVariableList = ( // Add chat variables chatVariables?.forEach(v => addVariable(list, keys, `CONVERSATION_${v.name}`, v.name, v.type, `conv.${v.name}`, { type: 'CONVERSATION', name: 'CONVERSATION', icon: '' }, { group: 'CONVERSATION' })); - // Process each relevant node + // Process each relevant node: non-list-operator first, then list-operator + const listOperatorIds: string[] = []; relevantIds.forEach(id => { + const node = nodes.find(n => n.id === id); + if (!node) return; + if (node.getData()?.type === 'list-operator') { + listOperatorIds.push(id); + } else { + processNodeVariables(node.getData(), node.getData().id, list, keys); + } + }); + listOperatorIds.forEach(id => { const node = nodes.find(n => n.id === id); if (node) processNodeVariables(node.getData(), node.getData().id, list, keys); }); diff --git a/web/src/views/Workflow/constant.ts b/web/src/views/Workflow/constant.ts index 9621d968..67553555 100644 --- a/web/src/views/Workflow/constant.ts +++ b/web/src/views/Workflow/constant.ts @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 15:06:18 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-04-03 20:28:08 + * @Last Modified time: 2026-04-07 19:56:56 */ import LoopNode from './components/Nodes/LoopNode'; import NormalNode from './components/Nodes/NormalNode'; @@ -579,7 +579,7 @@ export const noteNode = { export const nodeWidth = 240; -export const conditionNodePortItemArgsY = 60; +export const conditionNodePortItemArgsY = 56.5; export const conditionNodeItemHeight = 26; export const conditionNodeHeight = 110; /** @@ -703,7 +703,7 @@ export const portTextAttrs = { fontSize: 12, fill: '#5B6167' } /** * Port position arguments */ -export const portItemArgsY = 26; +export const portItemArgsY = 26.5; export const portArgs = { x: nodeWidth, y: portItemArgsY } const defaultPortGroup = { diff --git a/web/src/views/Workflow/types.ts b/web/src/views/Workflow/types.ts index 9ae198b1..a6dc9813 100644 --- a/web/src/views/Workflow/types.ts +++ b/web/src/views/Workflow/types.ts @@ -108,7 +108,7 @@ export interface ChatVariable { required: boolean; description: string; default?: string; - defaultValue: string; + defaultValue: string | any[]; } export interface AddChatVariableRef { handleOpen: (value?: ChatVariable) => void;