* perf: some log, chatTest histories slice; http request failed tip

* fix: ssr render

* perf: if else node ui and fix value type select
This commit is contained in:
Archer
2024-05-07 15:27:05 +08:00
committed by GitHub
parent 2053bbdb1b
commit 8f9203c053
21 changed files with 164 additions and 137 deletions

View File

@@ -17,13 +17,13 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { getFileAndOpen } from '@/web/core/dataset/utils';
import { MARKDOWN_QUOTE_SIGN } from '@fastgpt/global/core/chat/constants';
const CodeLight = dynamic(() => import('./CodeLight'));
const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'));
const MdImage = dynamic(() => import('./img/Image'));
const EChartsCodeBlock = dynamic(() => import('./img/EChartsCodeBlock'));
const CodeLight = dynamic(() => import('./CodeLight'), { ssr: false });
const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'), { ssr: false });
const MdImage = dynamic(() => import('./img/Image'), { ssr: false });
const EChartsCodeBlock = dynamic(() => import('./img/EChartsCodeBlock'), { ssr: false });
const ChatGuide = dynamic(() => import('./chat/Guide'));
const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'));
const ChatGuide = dynamic(() => import('./chat/Guide'), { ssr: false });
const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'), { ssr: false });
export enum CodeClassName {
guide = 'guide',

View File

@@ -65,7 +65,7 @@ const ChatTest = (
}
});
});
const history = chatList.slice(-historyMaxLen - 2, -2);
const history = chatList.slice(-(historyMaxLen * 2) - 2, -2);
// 流请求,获取数据
const { responseText, responseData, newVariables } = await streamFetch({

View File

@@ -24,6 +24,7 @@ import MyInput from '@/components/MyInput';
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
import { SourceHandle } from '../render/Handle';
import { Position, useReactFlow } from 'reactflow';
import { getReferenceDataValueType } from '@/web/core/workflow/utils';
const ListItem = ({
provided,
@@ -305,19 +306,17 @@ const ConditionSelect = ({
variable?: ReferenceValueProps;
onSelect: (e: VariableConditionEnum) => void;
}) => {
const { t } = useTranslation();
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
// get condition type
const valueType = useMemo(() => {
if (!variable) return;
const node = nodeList.find((node) => node.nodeId === variable[0]);
if (!node) return WorkflowIOValueTypeEnum.any;
const output = node.outputs.find((item) => item.id === variable[1]);
if (!output) return WorkflowIOValueTypeEnum.any;
return output.valueType;
}, [nodeList, variable]);
return getReferenceDataValueType({
variable,
nodeList,
t
});
}, [nodeList, t, variable]);
const conditionList = useMemo(() => {
if (valueType === WorkflowIOValueTypeEnum.string) return stringConditionList;

View File

@@ -30,7 +30,7 @@ import { SmallAddIcon } from '@chakra-ui/icons';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
import { ReferSelector, useReference } from './render/RenderInput/templates/Reference';
import { getWorkflowGlobalVariables } from '@/web/core/workflow/utils';
import { getReferenceDataValueType } from '@/web/core/workflow/utils';
import { isReferenceValue } from '@fastgpt/global/core/workflow/utils';
const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
@@ -82,19 +82,11 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) =>
return (
<>
{updateList.map((updateItem, index) => {
const valueType = (() => {
const variable = updateItem.variable;
const variableNodeId = variable?.[0];
const variableNode = nodeList.find((node) => node.nodeId === variableNodeId);
const systemVariables = getWorkflowGlobalVariables(nodeList, t);
const variableInput = !variableNode
? systemVariables.find((item) => item.key === variable?.[1])
: variableNode.outputs.find((output) => output.id === variable?.[1]);
if (!variableInput) return WorkflowIOValueTypeEnum.any;
return variableInput.valueType;
})();
const valueType = getReferenceDataValueType({
variable: updateItem.variable,
nodeList,
t
});
const renderTypeData = menuList.find((item) => item.renderType === updateItem.renderType);
const handleUpdate = (newValue: ReferenceValueProps | string) => {

View File

@@ -79,7 +79,6 @@ const NodeCard = (props: Props) => {
return (
<Box position={'relative'}>
{/* debug */}
<NodeDebugResponse nodeId={nodeId} debugResult={debugResult} />
<Box className="custom-drag-handle" px={4} py={3}>
{/* tool target handle */}
{showToolHandle && <ToolTargetHandle nodeId={nodeId} />}
@@ -134,7 +133,6 @@ const NodeCard = (props: Props) => {
);
}, [
nodeId,
debugResult,
showToolHandle,
avatar,
t,
@@ -179,6 +177,7 @@ const NodeCard = (props: Props) => {
borderColor: selected ? 'primary.600' : 'borderColor.base'
})}
>
<NodeDebugResponse nodeId={nodeId} debugResult={debugResult} />
{Header}
{children}
<ConnectionSourceHandle nodeId={nodeId} />
@@ -259,6 +258,22 @@ const MenuRender = React.memo(function MenuRender({
},
[setEdges, setNodes]
);
const onclickSyncVersion = useCallback(async () => {
if (!pluginId) return;
try {
setLoading(true);
onResetNode({
id: nodeId,
node: await getPreviewPluginModule(pluginId)
});
} catch (e) {
return toast({
status: 'error',
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
});
}
setLoading(false);
}, [nodeId, onResetNode, pluginId, setLoading, t, toast]);
const Render = useMemo(() => {
const menuList = [
@@ -288,25 +303,7 @@ const MenuRender = React.memo(function MenuRender({
icon: 'common/refreshLight',
label: t('plugin.Synchronous version'),
variant: 'whiteBase',
onClick: () => {
if (!pluginId) return;
onOpenConfirmSync(async () => {
try {
setLoading(true);
const pluginModule = await getPreviewPluginModule(pluginId);
onResetNode({
id: nodeId,
module: pluginModule
});
} catch (e) {
return toast({
status: 'error',
title: getErrText(e, t('plugin.Get Plugin Module Detail Failed'))
});
}
setLoading(false);
})();
}
onClick: onOpenConfirmSync(onclickSyncVersion)
}
]
: []),
@@ -370,12 +367,9 @@ const MenuRender = React.memo(function MenuRender({
onDelNode,
onOpenConfirmDeleteNode,
onOpenConfirmSync,
onResetNode,
onclickSyncVersion,
openDebugNode,
pluginId,
setLoading,
t,
toast
t
]);
return Render;
@@ -530,7 +524,8 @@ const NodeDebugResponse = React.memo(function NodeDebugResponse({
top={0}
zIndex={10}
w={'420px'}
maxH={'540px'}
maxH={'100%'}
minH={'300px'}
overflowY={'auto'}
border={'base'}
>

View File

@@ -55,7 +55,7 @@ type WorkflowContextType = {
hoverNodeId?: string;
setHoverNodeId: React.Dispatch<React.SetStateAction<string | undefined>>;
onUpdateNodeError: (node: string, isError: Boolean) => void;
onResetNode: (e: { id: string; module: FlowNodeTemplateType }) => void;
onResetNode: (e: { id: string; node: FlowNodeTemplateType }) => void;
onChangeNode: (e: FlowNodeChangeProps) => void;
// edges
@@ -159,7 +159,7 @@ export const WorkflowContext = createContext<WorkflowContextType>({
onEdgesChange: function (changes: EdgeChange[]): void {
throw new Error('Function not implemented.');
},
onResetNode: function (e: { id: string; module: FlowNodeTemplateType }): void {
onResetNode: function (e: { id: string; node: FlowNodeTemplateType }): void {
throw new Error('Function not implemented.');
},
onDelEdge: function (e: {
@@ -279,31 +279,30 @@ const WorkflowContextProvider = ({
});
// reset a node data. delete edge and replace it
const onResetNode = useMemoizedFn(
({ id, module }: { id: string; module: FlowNodeTemplateType }) => {
setNodes((state) =>
state.map((node) => {
if (node.id === id) {
// delete edge
node.data.inputs.forEach((item) => {
onDelEdge({ nodeId: id, targetHandle: item.key });
});
node.data.outputs.forEach((item) => {
onDelEdge({ nodeId: id, sourceHandle: item.key });
});
return {
const onResetNode = useMemoizedFn(({ id, node }: { id: string; node: FlowNodeTemplateType }) => {
setNodes((state) =>
state.map((item) => {
if (item.id === id) {
return {
...item,
data: {
...item.data,
...node,
data: {
...node.data,
...module
}
};
}
return node;
})
);
}
);
inputs: node.inputs.map((input) => {
const value =
item.data.inputs.find((i) => i.key === input.key)?.value ?? input.value;
return {
...input,
value
};
})
}
};
}
return item;
})
);
});
const onChangeNode = useMemoizedFn((props: FlowNodeChangeProps) => {
const { nodeId, type } = props;
@@ -431,7 +430,6 @@ const WorkflowContextProvider = ({
const initData = useMemoizedFn(
async (e: { nodes: StoreNodeItemType[]; edges: StoreEdgeItemType[] }) => {
setNodes(e.nodes?.map((item) => storeNode2FlowNode({ item })));
setEdges(e.edges?.map((item) => storeEdgesRenderEdge({ edge: item })));
}
);

View File

@@ -53,10 +53,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
appId,
runtimeNodes: nodes,
runtimeEdges: edges,
variables: {
...variables,
userChatInput: ''
},
variables,
query: [],
histories: [],
stream: false,

View File

@@ -75,6 +75,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
WorkflowContext,
(v) => v.setIsShowVersionHistories
);
const workflowDebugData = useContextSelector(WorkflowContext, (v) => v.workflowDebugData);
const flowData2StoreDataAndCheck = useCallback(async () => {
const { nodes } = await getWorkflowStore();
@@ -93,35 +94,40 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
}
}, [edges, onUpdateNodeError, t, toast]);
const onclickSave = useCallback(async () => {
if (isShowVersionHistories) return;
const { nodes } = await getWorkflowStore();
const onclickSave = useCallback(
async (forbid?: boolean) => {
// version preview / debug mode, not save
if (isShowVersionHistories || forbid) return;
if (nodes.length === 0) return null;
setIsSaving(true);
const { nodes } = await getWorkflowStore();
const storeWorkflow = flowNode2StoreNodes({ nodes, edges });
if (nodes.length === 0) return null;
setIsSaving(true);
try {
await updateAppDetail(app._id, {
...storeWorkflow,
type: AppTypeEnum.advanced,
//@ts-ignore
version: 'v2'
});
const storeWorkflow = flowNode2StoreNodes({ nodes, edges });
setSaveLabel(
t('core.app.Auto Save time', {
time: formatTime2HM()
})
);
// ChatTestRef.current?.resetChatTest();
} catch (error) {}
try {
await updateAppDetail(app._id, {
...storeWorkflow,
type: AppTypeEnum.advanced,
//@ts-ignore
version: 'v2'
});
setIsSaving(false);
setSaveLabel(
t('core.app.Auto Save time', {
time: formatTime2HM()
})
);
// ChatTestRef.current?.resetChatTest();
} catch (error) {}
return null;
}, [isShowVersionHistories, edges, updateAppDetail, app._id, t]);
setIsSaving(false);
return null;
},
[isShowVersionHistories, edges, updateAppDetail, app._id, t]
);
const onclickPublish = useCallback(async () => {
setIsSaving(true);
@@ -182,7 +188,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
useInterval(() => {
if (!app._id) return;
onclickSave();
onclickSave(!!workflowDebugData);
}, 20000);
const Render = useMemo(() => {
@@ -221,7 +227,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
display={'inline-block'}
borderRadius={'xs'}
cursor={'pointer'}
onClick={onclickSave}
onClick={() => onclickSave()}
color={'myGray.500'}
>
{saveLabel}

View File

@@ -62,7 +62,7 @@ const ChatTest = ({
}
});
});
const history = chatList.slice(-historyMaxLen - 2, -2);
const history = chatList.slice(-(historyMaxLen * 2) - 2, -2);
// 流请求,获取数据
const { responseText, responseData } = await streamFetch({

View File

@@ -24,6 +24,7 @@ import {
} from '@fastgpt/global/core/workflow/utils';
import { getSystemVariables } from '../app/utils';
import { TFunction } from 'next-i18next';
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
export const nodeTemplate2FlowNode = ({
template,
@@ -140,6 +141,26 @@ export const computedNodeInputReference = ({
return sourceNodes;
};
export const getReferenceDataValueType = ({
variable,
nodeList,
t
}: {
variable?: ReferenceValueProps;
nodeList: FlowNodeItemType[];
t: TFunction;
}) => {
if (!variable) return WorkflowIOValueTypeEnum.any;
const node = nodeList.find((node) => node.nodeId === variable[0]);
const systemVariables = getWorkflowGlobalVariables(nodeList, t);
if (!node) return systemVariables.find((item) => item.key === variable?.[1])?.valueType;
const output = node.outputs.find((item) => item.id === variable[1]);
if (!output) return WorkflowIOValueTypeEnum.any;
return output.valueType;
};
/* Connection rules */
export const checkWorkflowNodeAndConnection = ({