Merge pull request #114 from SuanmoSuanyangTechnology/fix/workflow_zy

Fix/workflow zy
This commit is contained in:
yingzhao
2026-01-14 16:57:46 +08:00
committed by GitHub
12 changed files with 153 additions and 43 deletions

View File

@@ -1265,6 +1265,7 @@ export const en = {
emotionLine: 'Emotion Changes Over Time',
interaction: 'Interaction Frequency & Relationship Stages',
timelines_memory: 'All',
Chunk: 'Chunk',
MemorySummary: 'Long-term Accumulation',
Statement: 'Emotional Memory',
ExtractedEntity: 'Episodic Memory',
@@ -1786,6 +1787,9 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
temperature: 'Temperature',
max_tokens: 'Max Tokens',
context: 'Context',
memory: 'Memory',
enable_window: 'Memory Window',
inner: 'Built-in',
},
start: {
variables: 'Input Fields',

View File

@@ -1343,6 +1343,7 @@ export const zh = {
emotionLine: '情绪随时间变化',
interaction: '互动频率 & 关系阶段',
timelines_memory: '全部',
Chunk: '工作记忆',
MemorySummary: '长期沉淀',
Statement: '情绪记忆',
ExtractedEntity: '情景记忆',
@@ -1883,6 +1884,9 @@ export const zh = {
temperature: '温度',
max_tokens: '最大令牌数',
context: '上下文',
memory: '记忆',
enable_window: '记忆窗口',
inner: '内置',
},
start: {
variables: '输入字段',

View File

@@ -176,6 +176,9 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
if (response?.knowledge_retrieval?.knowledge_bases?.length) {
getDefaultKnowledgeList(response)
}
if (response?.tools?.length) {
setToolList(response?.tools)
}
}).finally(() => {
setLoading(false)
})

View File

@@ -79,8 +79,6 @@ const ToolList: FC<{ data: ToolOption[]; onUpdate: (config: ToolOption[]) => voi
}
}, [data])
console.log('toolList', toolList)
const handleAddTool = () => {
toolModalRef.current?.handleOpen()
}

View File

@@ -1,6 +1,5 @@
import React, { useState, useImperativeHandle, forwardRef, useRef } from 'react';
import { Button, Input, Space, Typography, Tooltip, message, List } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { useState, useImperativeHandle, forwardRef, useRef } from 'react';
import { Button, Space, List } from 'antd';
import { useTranslation } from 'react-i18next';
import type { ChatVariable, AddChatVariableRef } from '../../types';
import type { ChatVariableModalRef } from './types'

View File

@@ -131,7 +131,7 @@ const EditableTable: React.FC<EditableTableProps> = ({
const AddButton = ({ block = false }: { block?: boolean }) => (
<Button
type={block ? "dashed" : "text"}
icon={<PlusOutlined />}
icon={block ? undefined : <PlusOutlined />}
onClick={() => add(createNewRow())}
size="small"
block={block}

View File

@@ -0,0 +1,69 @@
import { type FC } from "react";
import { useTranslation } from 'react-i18next'
import { Form, Row, Col, Divider, Switch, Slider } from 'antd'
import type { Suggestion } from '../../Editor/plugin/AutocompletePlugin'
import MessageEditor from '../MessageEditor'
const MemoryConfig: FC<{ options: Suggestion[]; parentName: string; }> = ({
options,
parentName
}) => {
const { t } = useTranslation()
const form = Form.useFormInstance();
const values = Form.useWatch([], form) || {}
console.log('MemoryConfig', values)
const handleChangeEnable = (value: boolean) => {
if (value) {
form.setFieldsValue({
memory: {
...form.getFieldValue(parentName),
enable_window: false,
window_size: 20,
messages: "{{sys.message}}"
}
})
}
}
return (
<>
{values?.memory?.enable && <>
<div className="rb:flex rb:items-center rb:justify-between rb:py-1.5 rb:px-2 rb:bg-[#F6F8FC] rb:rounded-md rb:mb-2">
{t('workflow.config.llm.memory')}
<span>{t('workflow.config.llm.inner')}</span>
</div>
<Form.Item layout="horizontal" name={[parentName, 'messages']}>
<MessageEditor
title="USER"
isArray={false}
parentName={[parentName, 'messages']}
options={options}
/>
</Form.Item>
<Divider />
</>}
<Form.Item layout="horizontal" name={[parentName, 'enable']} label={t('workflow.config.llm.memory')}>
<Switch onChange={handleChangeEnable} />
</Form.Item>
{values?.memory?.enable && <>
<Row className="rb:mb-3">
<Col span={10}>
<Form.Item layout="horizontal" name={[parentName, 'enable_window']} noStyle>
<Switch />
</Form.Item>
<span className="rb:ml-2">{t('workflow.config.llm.enable_window')}</span>
</Col>
<Col span={14}>
<Form.Item layout="horizontal" name={[parentName, 'window_size']} noStyle>
<Slider min={1} max={100} step={1} className="rb:my-0!" disabled={!values?.memory?.enable_window} />
</Form.Item>
</Col>
</Row>
</>}
</>
);
};
export default MemoryConfig;

View File

@@ -127,7 +127,7 @@ const MessageEditor: FC<MessageEditor> = ({
</Space>
);
})}
<Form.Item>
<Form.Item noStyle>
<Button type="dashed" onClick={() => handleAdd(add)} block>
+{t('workflow.addMessage')}
</Button>

View File

@@ -22,6 +22,7 @@ import ConditionList from './ConditionList'
import CycleVarsList from './CycleVarsList'
import AssignmentList from './AssignmentList'
import ToolConfig from './ToolConfig'
import MemoryConfig from './MemoryConfig'
// import { calculateVariableList } from './utils/variableListCalculator'
interface PropertiesProps {
@@ -1230,6 +1231,20 @@ const Properties: FC<PropertiesProps> = ({
</Form.Item>
)
}
if (config.type === 'memoryConfig') {
return (
<Form.Item
key={key}
name={key}
noStyle
>
<MemoryConfig
parentName={key}
options={getFilteredVariableList('llm')}
/>
</Form.Item>
)
}
return (
<Form.Item

View File

@@ -135,6 +135,14 @@ export const nodeLibrary: NodeLibrary[] = [
readonly: true
},
]
},
memory: {
type: 'memoryConfig',
defaultValue: {
enable: false,
enable_window: false,
window_size: 20
}
}
}
},
@@ -750,10 +758,6 @@ export const outputVariable: { [key: string]: OutputVariable } = {
{ name: "body", type: "string" },
{ name: "status_code", type: "number" },
],
error: [
{ name: "error_message", type: "string" },
{ name: "error_type", type: "string" },
]
},
'tool': {
default: [

View File

@@ -6,7 +6,7 @@ import { Graph, Node, MiniMap, Snapline, Clipboard, Keyboard, type Edge } from '
import { register } from '@antv/x6-react-shape';
import { nodeRegisterLibrary, graphNodeLibrary, nodeLibrary, portMarkup, portAttrs } from '../constant';
import type { WorkflowConfig, NodeProperties } from '../types';
import type { WorkflowConfig, NodeProperties, ChatVariable } from '../types';
import { getWorkflowConfig, saveWorkflowConfig } from '@/api/application'
import type { PortMetadata } from '@antv/x6/lib/model/port';
@@ -35,6 +35,8 @@ export interface UseWorkflowGraphReturn {
copyEvent: () => boolean | void;
parseEvent: () => boolean | void;
handleSave: (flag?: boolean) => Promise<unknown>;
chatVariables: ChatVariable[];
setChatVariables: React.Dispatch<React.SetStateAction<ChatVariable[]>>;
}
export const edge_color = '#155EEF';
@@ -54,6 +56,7 @@ export const useWorkflowGraph = ({
const [canRedo, setCanRedo] = useState(false);
const [isHandMode, setIsHandMode] = useState(false);
const [config, setConfig] = useState<WorkflowConfig | null>(null);
const [chatVariables, setChatVariables] = useState<ChatVariable[]>([])
useEffect(() => {
getConfig()
@@ -63,16 +66,15 @@ export const useWorkflowGraph = ({
getWorkflowConfig(id)
.then(res => {
const { variables, ...rest } = res as WorkflowConfig
setConfig({
...rest,
variables: variables.map(v => {
const { default: _, ...cleanV } = v
return {
...cleanV,
defaultValue: v.default ?? ''
}
})
const initChatVariables = variables.map(v => {
const { default: _, ...cleanV } = v
return {
...cleanV,
defaultValue: v.default ?? ''
}
})
setChatVariables(initChatVariables)
setConfig({ ...rest, variables: initChatVariables })
})
}
@@ -94,7 +96,17 @@ export const useWorkflowGraph = ({
if (nodeLibraryConfig?.config) {
Object.keys(nodeLibraryConfig.config).forEach(key => {
if (key === 'knowledge_retrieval' && nodeLibraryConfig.config && nodeLibraryConfig.config[key]) {
if (key === 'memory' && nodeLibraryConfig.config && nodeLibraryConfig.config[key]) {
const { memory, messages } = config as any;
if (memory?.enable && messages && messages.length > 0) {
const lastMessage = messages[messages.length - 1]
nodeLibraryConfig.config[key].defaultValue = {
...memory,
messages: lastMessage.content
}
nodeLibraryConfig.config.messages.defaultValue.splice(-1, 1)
}
} else if (key === 'knowledge_retrieval' && nodeLibraryConfig.config && nodeLibraryConfig.config[key]) {
const { query, ...rest } = config
nodeLibraryConfig.config[key].defaultValue = {
...rest
@@ -917,13 +929,13 @@ export const useWorkflowGraph = ({
const params = {
...config,
variables: config.variables.map(v => {
const { defaultValue, ...cleanV } = v
return {
...cleanV,
default: defaultValue ?? ''
}
}),
variables: chatVariables.map(v => {
const { defaultValue, ...cleanV } = v
return {
...cleanV,
default: defaultValue ?? ''
}
}),
nodes: nodes.map((node: Node) => {
const data = node.getData();
const position = node.getPosition();
@@ -931,7 +943,15 @@ export const useWorkflowGraph = ({
if (data.config) {
Object.keys(data.config).forEach(key => {
if (data.config[key] && 'defaultValue' in data.config[key] && key === 'group_variables') {
if (key === 'memory' && data.config[key] && 'defaultValue' in data.config[key]) {
const { messages, ...rest } = data.config[key].defaultValue
let memoryMessage = { role: 'USER', content: data.config[key].defaultValue.messages }
itemConfig = {
...itemConfig,
messages: rest.enable ? [...itemConfig.messages, memoryMessage] : itemConfig.messages,
memory: { ...rest },
}
} else if (data.config[key] && 'defaultValue' in data.config[key] && key === 'group_variables') {
let group_variables = data.config.group.defaultValue ? {} : data.config[key].defaultValue
if (data.config.group.defaultValue) {
data.config[key].defaultValue.map((vo: any) => {
@@ -1077,5 +1097,7 @@ export const useWorkflowGraph = ({
copyEvent,
parseEvent,
handleSave,
chatVariables,
setChatVariables
};
};

View File

@@ -8,7 +8,7 @@ import PortClickHandler from './components/PortClickHandler';
import { useWorkflowGraph } from './hooks/useWorkflowGraph';
import type { WorkflowRef } from '@/views/ApplicationConfig/types'
import Chat from './components/Chat/Chat';
import type { ChatRef, AddChatVariableRef, ChatVariable } from './types'
import type { ChatRef, AddChatVariableRef } from './types'
import arrowIcon from '@/assets/images/workflow/arrow.png'
import AddChatVariable from './components/AddChatVariable';
@@ -21,7 +21,6 @@ const Workflow = forwardRef<WorkflowRef>((_props, ref) => {
// 使用自定义Hook初始化工作流图
const {
config,
setConfig,
graphRef,
selectedNode,
setSelectedNode,
@@ -38,6 +37,8 @@ const Workflow = forwardRef<WorkflowRef>((_props, ref) => {
copyEvent,
parseEvent,
handleSave,
chatVariables,
setChatVariables
} = useWorkflowGraph({ containerRef, miniMapRef });
const onDragOver = (event: React.DragEvent) => {
@@ -52,15 +53,6 @@ const Workflow = forwardRef<WorkflowRef>((_props, ref) => {
const addVariable = () => {
addChatVariableRef.current?.handleOpen()
}
const handleUpdateChatVariable = (variables: ChatVariable[]) => {
setConfig(prev => {
if (!prev) return null
return {
...prev,
variables
}
})
}
useImperativeHandle(ref, () => ({
handleSave,
@@ -125,8 +117,8 @@ const Workflow = forwardRef<WorkflowRef>((_props, ref) => {
<AddChatVariable
ref={addChatVariableRef}
variables={config?.variables}
onChange={handleUpdateChatVariable}
variables={chatVariables}
onChange={setChatVariables}
/>
</div>
);