Merge pull request #701 from SuanmoSuanyangTechnology/feature/ui_upgrade_zy
Feature/UI upgrade zy
This commit is contained in:
@@ -2163,6 +2163,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
|||||||
'memory-write': 'Memory Storage',
|
'memory-write': 'Memory Storage',
|
||||||
unknown: 'Unknown Node',
|
unknown: 'Unknown Node',
|
||||||
notes: 'Sticky Note',
|
notes: 'Sticky Note',
|
||||||
|
'document-extractor': 'Document Extractor',
|
||||||
|
|
||||||
clickToConfigure: 'Click to configure node parameters',
|
clickToConfigure: 'Click to configure node parameters',
|
||||||
nodeProperties: 'Node Properties',
|
nodeProperties: 'Node Properties',
|
||||||
@@ -2361,6 +2362,9 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
|||||||
placeholder: 'Enter note...',
|
placeholder: 'Enter note...',
|
||||||
removeLink: 'Remove Link',
|
removeLink: 'Remove Link',
|
||||||
},
|
},
|
||||||
|
'document-extractor': {
|
||||||
|
file_selector: 'Input Variable',
|
||||||
|
},
|
||||||
name: 'Key',
|
name: 'Key',
|
||||||
type: 'Type',
|
type: 'Type',
|
||||||
value: 'Value',
|
value: 'Value',
|
||||||
|
|||||||
@@ -2160,6 +2160,7 @@ export const zh = {
|
|||||||
'memory-write': '记忆储存',
|
'memory-write': '记忆储存',
|
||||||
unknown: '未知节点',
|
unknown: '未知节点',
|
||||||
notes: '便签',
|
notes: '便签',
|
||||||
|
'document-extractor': '文档提取器',
|
||||||
|
|
||||||
clickToConfigure: '点击配置节点参数',
|
clickToConfigure: '点击配置节点参数',
|
||||||
nodeProperties: '节点属性',
|
nodeProperties: '节点属性',
|
||||||
@@ -2361,6 +2362,9 @@ export const zh = {
|
|||||||
placeholder: '输入注释...',
|
placeholder: '输入注释...',
|
||||||
removeLink: '取消链接',
|
removeLink: '取消链接',
|
||||||
},
|
},
|
||||||
|
'document-extractor': {
|
||||||
|
file_selector: '输入变量',
|
||||||
|
},
|
||||||
name: '键',
|
name: '键',
|
||||||
type: '类型',
|
type: '类型',
|
||||||
value: '值',
|
value: '值',
|
||||||
|
|||||||
@@ -161,10 +161,12 @@ const Neo4j: FC = () => {
|
|||||||
<RelationshipNetwork />
|
<RelationshipNetwork />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<EndUserProfile ref={ref} onDataLoaded={handleNameUpdate} className={selectedKey === 'userProfile' ? 'rb:block!' : 'rb:hidden!'} />
|
<div onClick={(e) => e.stopPropagation()}>
|
||||||
<AboutMe ref={aboutMeRef} className={selectedKey === 'aboutMe' ? 'rb:block!' : 'rb:hidden!'} />
|
<EndUserProfile ref={ref} onDataLoaded={handleNameUpdate} className={selectedKey === 'userProfile' ? 'rb:block!' : 'rb:hidden!'} />
|
||||||
<InterestDistribution className={selectedKey === 'interestDistribution' ? 'rb:block!' : 'rb:hidden!'} />
|
<AboutMe ref={aboutMeRef} className={selectedKey === 'aboutMe' ? 'rb:block!' : 'rb:hidden!'} />
|
||||||
<MemoryInsight ref={memoryInsightRef} className={selectedKey === 'memoryInsight' ? 'rb:block!' : 'rb:hidden!'} />
|
<InterestDistribution className={selectedKey === 'interestDistribution' ? 'rb:block!' : 'rb:hidden!'} />
|
||||||
|
<MemoryInsight ref={memoryInsightRef} className={selectedKey === 'memoryInsight' ? 'rb:block!' : 'rb:hidden!'} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options
|
|||||||
const root = $getRoot();
|
const root = $getRoot();
|
||||||
root.clear();
|
root.clear();
|
||||||
|
|
||||||
const parts = value.split(/(\{\{[^}]+\}\})/);
|
const parts = value.split(/(\{\{[^}]+\}\}|\n)/);
|
||||||
|
|
||||||
if (enableLineNumbers) {
|
if (enableLineNumbers) {
|
||||||
const lines = value.split('\n');
|
const lines = value.split('\n');
|
||||||
@@ -63,8 +63,14 @@ const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options
|
|||||||
root.append(paragraph);
|
root.append(paragraph);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const paragraph = $createParagraphNode();
|
let paragraph = $createParagraphNode();
|
||||||
|
|
||||||
parts.forEach(part => {
|
parts.forEach(part => {
|
||||||
|
if (part === '\n') {
|
||||||
|
root.append(paragraph);
|
||||||
|
paragraph = $createParagraphNode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const match = part.match(/^\{\{([^.]+)\.([^}]+)\}\}$/);
|
const match = part.match(/^\{\{([^.]+)\.([^}]+)\}\}$/);
|
||||||
const contextMatch = part.match(/^\{\{context\}\}$/);
|
const contextMatch = part.match(/^\{\{context\}\}$/);
|
||||||
const conversationMatch = part.match(/^\{\{conv\.([^}]+)\}\}$/);
|
const conversationMatch = part.match(/^\{\{conv\.([^}]+)\}\}$/);
|
||||||
@@ -78,10 +84,10 @@ const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversationMatch) {
|
if (conversationMatch) {
|
||||||
const [_, variableName] = conversationMatch;
|
const [_, variableName] = conversationMatch;
|
||||||
const conversationSuggestion = optionsRef.current.find(s =>
|
const conversationSuggestion = optionsRef.current.find(s =>
|
||||||
s.group === 'CONVERSATION' && s.label === variableName
|
s.group === 'CONVERSATION' && s.label === variableName
|
||||||
);
|
);
|
||||||
if (conversationSuggestion) {
|
if (conversationSuggestion) {
|
||||||
@@ -91,7 +97,7 @@ const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const [_, nodeId, label] = match;
|
const [_, nodeId, label] = match;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { type FC } from 'react'
|
import { type FC, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Form, Select, Input, Button, InputNumber, Flex } from 'antd'
|
import { Form, Select, Input, Button, InputNumber, Flex } from 'antd'
|
||||||
|
|
||||||
import VariableSelect from '../VariableSelect'
|
import VariableSelect from '../VariableSelect'
|
||||||
import type { Suggestion } from '../../Editor/plugin/AutocompletePlugin'
|
import type { Suggestion } from '../../Editor/plugin/AutocompletePlugin'
|
||||||
import RadioGroupBtn from '../RadioGroupBtn'
|
import RadioGroupBtn from '../RadioGroupBtn'
|
||||||
|
import { getChildNodeVariables } from '../hooks/useVariableList'
|
||||||
|
|
||||||
interface CycleVar {
|
interface CycleVar {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -44,40 +45,14 @@ const CycleVarsList: FC<CycleVarsListProps> = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
|
|
||||||
// 获取循环节点的子节点变量
|
const availableOptions = useMemo(() => {
|
||||||
const getChildNodeVariables = () => {
|
|
||||||
if (!selectedNode || !graphRef?.current || selectedNode.getData()?.type !== 'loop') {
|
if (!selectedNode || !graphRef?.current || selectedNode.getData()?.type !== 'loop') {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
const childVars = getChildNodeVariables(selectedNode, graphRef);
|
||||||
|
|
||||||
const loopNodeId = selectedNode.getData()?.id;
|
return options.filter(option => !childVars.some(item => item.value === option.value))
|
||||||
const childNodes = graphRef.current.getNodes().filter((node: any) =>
|
}, [options, selectedNode, graphRef]);
|
||||||
node.getData()?.cycle === loopNodeId
|
|
||||||
);
|
|
||||||
|
|
||||||
const childVariables: Suggestion[] = [];
|
|
||||||
childNodes.forEach((childNode: any) => {
|
|
||||||
const childData = childNode.getData();
|
|
||||||
if (childData?.config) {
|
|
||||||
Object.keys(childData.config).forEach(key => {
|
|
||||||
if (childData.config[key]?.defaultValue) {
|
|
||||||
childVariables.push({
|
|
||||||
key: `${childData.id}.${key}`,
|
|
||||||
label: `${childData.name || childData.type}.${key}`,
|
|
||||||
type: 'output',
|
|
||||||
dataType: 'string',
|
|
||||||
value: `${childData.id}.${key}`,
|
|
||||||
nodeData: childData
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...options, ...childVariables];
|
|
||||||
};
|
|
||||||
|
|
||||||
const availableOptions = getChildNodeVariables();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.List name={parentName}>
|
<Form.List name={parentName}>
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ const NODE_VARIABLES = {
|
|||||||
'memory-read': [
|
'memory-read': [
|
||||||
{ label: 'answer', dataType: 'string', field: 'answer' },
|
{ label: 'answer', dataType: 'string', field: 'answer' },
|
||||||
{ label: 'intermediate_outputs', dataType: 'array[object]', field: 'intermediate_outputs' }
|
{ label: 'intermediate_outputs', dataType: 'array[object]', field: 'intermediate_outputs' }
|
||||||
|
],
|
||||||
|
'document-extractor': [
|
||||||
|
{ label: 'text', dataType: 'string', field: 'text' },
|
||||||
]
|
]
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -177,7 +180,8 @@ const hasOutputNodeTypes = [
|
|||||||
'var-aggregator',
|
'var-aggregator',
|
||||||
'http-request',
|
'http-request',
|
||||||
'tool',
|
'tool',
|
||||||
'jinja-render'
|
'jinja-render',
|
||||||
|
'document-extractor'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -636,6 +636,8 @@ const Properties: FC<PropertiesProps> = ({
|
|||||||
size="small"
|
size="small"
|
||||||
parentName={key}
|
parentName={key}
|
||||||
options={getFilteredVariableList(selectedNode?.data?.type, key)}
|
options={getFilteredVariableList(selectedNode?.data?.type, key)}
|
||||||
|
selectedNode={selectedNode}
|
||||||
|
graphRef={graphRef}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -473,6 +473,16 @@ export const nodeLibrary: NodeLibrary[] = [
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "document-extractor", icon: codeExecutionIcon,
|
||||||
|
config: {
|
||||||
|
file_selector: {
|
||||||
|
type: 'variableList',
|
||||||
|
placeholder: 'common.pleaseSelect',
|
||||||
|
onFilterVariableNames: ['sys.files']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -858,100 +868,6 @@ export interface OutputVariable {
|
|||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Output variable definitions for each node type
|
|
||||||
* Specifies what variables each node produces
|
|
||||||
*/
|
|
||||||
export const outputVariable: { [key: string]: OutputVariable } = {
|
|
||||||
start: {
|
|
||||||
sys: [
|
|
||||||
{ name: "message", type: "string" },
|
|
||||||
{ name: "conversation_id", type: "string" },
|
|
||||||
{ name: "execution_id", type: "string", },
|
|
||||||
{ name: "workspace_id", type: "string" },
|
|
||||||
{ name: "user_id", type: "string" },
|
|
||||||
],
|
|
||||||
define: ['variables']
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
},
|
|
||||||
llm: {
|
|
||||||
default: [
|
|
||||||
{ name: "output", type: "string" },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'knowledge-retrieval': {
|
|
||||||
default: [
|
|
||||||
{ name: "output", type: "array[object]" },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'parameter-extractor': {
|
|
||||||
default: [
|
|
||||||
{ name: "__is_success", type: "number" },
|
|
||||||
{ name: "__reason", type: "string" },
|
|
||||||
],
|
|
||||||
define: ['params']
|
|
||||||
},
|
|
||||||
'memory-read': {
|
|
||||||
default: [
|
|
||||||
{ name: "answer", type: "string" },
|
|
||||||
{ name: "intermediate_outputs", type: "array[object]" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'memory-write': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'if-else': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'question-classifier': {
|
|
||||||
default: [
|
|
||||||
{ name: "class_name", type: "string" },
|
|
||||||
// { name: "output", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'iteration': {
|
|
||||||
default: [
|
|
||||||
// { name: "item", type: "string" }, // 仅内部使用
|
|
||||||
{ name: "output", type: "array[string]" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'loop': {
|
|
||||||
define: ['cycle_vars']
|
|
||||||
},
|
|
||||||
'cycle-start': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'break': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'var-aggregator': {
|
|
||||||
// default: [
|
|
||||||
// { name: "output", type: "string" },
|
|
||||||
// ],
|
|
||||||
define: ['group_variables']
|
|
||||||
},
|
|
||||||
'assigner': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'http-request': {
|
|
||||||
default: [
|
|
||||||
{ name: "body", type: "string" },
|
|
||||||
{ name: "status_code", type: "number" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'tool': {
|
|
||||||
default: [
|
|
||||||
{ name: "data", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'jinja-render': {
|
|
||||||
default: [
|
|
||||||
{ name: "output", type: "string" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default edge attributes configuration
|
* Default edge attributes configuration
|
||||||
* Defines visual styling for edges/connections
|
* Defines visual styling for edges/connections
|
||||||
|
|||||||
Reference in New Issue
Block a user