mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
4.8 test (#1382)
* 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:
@@ -46,7 +46,7 @@ export const IfElseNode: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.ifElseResult,
|
||||
key: NodeOutputKeyEnum.ifElseResult,
|
||||
label: 'IF ELSE',
|
||||
label: '判断结果',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ export type FlowNodeCommonType = {
|
||||
};
|
||||
|
||||
export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
id: string; // module id, unique
|
||||
id: string; // node id, unique
|
||||
templateType: `${FlowNodeTemplateTypeEnum}`;
|
||||
|
||||
// show handle
|
||||
@@ -132,11 +132,12 @@ export type ChatDispatchProps = {
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
histories: ChatItemType[];
|
||||
variables: Record<string, any>;
|
||||
query: UserChatItemValueItemType[];
|
||||
variables: Record<string, any>; // global variable
|
||||
query: UserChatItemValueItemType[]; // trigger query
|
||||
stream: boolean;
|
||||
detail: boolean; // response detail
|
||||
maxRunTimes: number;
|
||||
isToolCall?: boolean;
|
||||
};
|
||||
|
||||
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { POST } from '../../../common/api/serverRequest';
|
||||
|
||||
type PostReRankResponse = {
|
||||
@@ -38,7 +39,7 @@ export function reRankRecall({
|
||||
}
|
||||
)
|
||||
.then((data) => {
|
||||
console.log('rerank time:', Date.now() - start);
|
||||
addLog.info('ReRank finish:', { time: Date.now() - start });
|
||||
|
||||
return data?.results?.map((item) => ({
|
||||
id: documents[item.index].id,
|
||||
@@ -46,7 +47,7 @@ export function reRankRecall({
|
||||
}));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('rerank error:', err);
|
||||
addLog.error('rerank error', err);
|
||||
|
||||
return [];
|
||||
});
|
||||
|
@@ -161,6 +161,7 @@ export const runToolWithFunctionCall = async (
|
||||
|
||||
const toolRunResponse = await dispatchWorkFlow({
|
||||
...props,
|
||||
isToolCall: true,
|
||||
runtimeNodes: runtimeNodes.map((item) =>
|
||||
item.nodeId === toolNode.nodeId
|
||||
? {
|
||||
|
@@ -185,6 +185,7 @@ export const runToolWithPromptCall = async (
|
||||
|
||||
const moduleRunResponse = await dispatchWorkFlow({
|
||||
...props,
|
||||
isToolCall: true,
|
||||
runtimeNodes: runtimeNodes.map((item) =>
|
||||
item.nodeId === toolNode.nodeId
|
||||
? {
|
||||
|
@@ -182,6 +182,7 @@ export const runToolWithToolChoice = async (
|
||||
|
||||
const toolRunResponse = await dispatchWorkFlow({
|
||||
...props,
|
||||
isToolCall: true,
|
||||
runtimeNodes: runtimeNodes.map((item) =>
|
||||
item.nodeId === toolNode.nodeId
|
||||
? {
|
||||
|
@@ -8,12 +8,15 @@ export type UserChatInputProps = ModuleDispatchProps<{
|
||||
}>;
|
||||
|
||||
export const dispatchWorkflowStart = (props: Record<string, any>) => {
|
||||
const { query } = props as UserChatInputProps;
|
||||
const {
|
||||
query,
|
||||
params: { userChatInput }
|
||||
} = props as UserChatInputProps;
|
||||
|
||||
const { text, files } = chatValue2RuntimePrompt(query);
|
||||
|
||||
return {
|
||||
[NodeInputKeyEnum.userChatInput]: text,
|
||||
[NodeInputKeyEnum.userChatInput]: text || userChatInput,
|
||||
[NodeInputKeyEnum.inputFiles]: files
|
||||
};
|
||||
};
|
||||
|
@@ -49,6 +49,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
||||
variables,
|
||||
node: { outputs },
|
||||
histories,
|
||||
isToolCall,
|
||||
params: {
|
||||
system_httpMethod: httpMethod = 'POST',
|
||||
system_httpReqUrl: httpReqUrl,
|
||||
@@ -156,17 +157,21 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
||||
};
|
||||
} catch (error) {
|
||||
addLog.error('Http request error', error);
|
||||
return {
|
||||
[NodeOutputKeyEnum.failed]: true,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: 0,
|
||||
params: Object.keys(params).length > 0 ? params : undefined,
|
||||
body: Object.keys(requestBody).length > 0 ? requestBody : undefined,
|
||||
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
||||
httpResult: { error: formatHttpError(error) }
|
||||
},
|
||||
[NodeOutputKeyEnum.httpRawResponse]: getErrText(error)
|
||||
};
|
||||
|
||||
if (isToolCall) {
|
||||
return {
|
||||
[NodeOutputKeyEnum.failed]: true,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: 0,
|
||||
params: Object.keys(params).length > 0 ? params : undefined,
|
||||
body: Object.keys(requestBody).length > 0 ? requestBody : undefined,
|
||||
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
||||
httpResult: { error: formatHttpError(error) }
|
||||
},
|
||||
[NodeOutputKeyEnum.httpRawResponse]: getErrText(error)
|
||||
};
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { VariableConditionEnum } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
|
||||
@@ -15,6 +15,9 @@ type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.condition]: IfElseConditionType;
|
||||
[NodeInputKeyEnum.ifElseList]: IfElseListItemType[];
|
||||
}>;
|
||||
type Response = DispatchNodeResultType<{
|
||||
[NodeOutputKeyEnum.ifElseResult]: string;
|
||||
}>;
|
||||
|
||||
function checkCondition(condition: VariableConditionEnum, variableValue: any, value: string) {
|
||||
const operations = {
|
||||
@@ -63,7 +66,7 @@ function getResult(
|
||||
return condition === 'AND' ? listResult.every(Boolean) : listResult.some(Boolean);
|
||||
}
|
||||
|
||||
export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultType<{}>> => {
|
||||
export const dispatchIfElse = async (props: Props): Promise<Response> => {
|
||||
const {
|
||||
params,
|
||||
runtimeNodes,
|
||||
@@ -88,6 +91,7 @@ export const dispatchIfElse = async (props: Props): Promise<DispatchNodeResultTy
|
||||
});
|
||||
|
||||
return {
|
||||
[NodeOutputKeyEnum.ifElseResult]: res,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: 0,
|
||||
ifElseResult: res
|
||||
|
@@ -14,7 +14,9 @@ export const useBeforeunload = (props?: { callback?: () => any; tip?: string })
|
||||
e.returnValue = tip;
|
||||
callback?.();
|
||||
}
|
||||
: () => {};
|
||||
: () => {
|
||||
callback?.();
|
||||
};
|
||||
window.addEventListener('beforeunload', listen);
|
||||
|
||||
return () => {
|
||||
|
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@@ -1,4 +1,4 @@
|
||||
lockfileVersion: '6.0'
|
||||
lockfileVersion: '6.1'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
|
@@ -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',
|
||||
|
@@ -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({
|
||||
|
@@ -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;
|
||||
|
@@ -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) => {
|
||||
|
@@ -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'}
|
||||
>
|
||||
|
@@ -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 })));
|
||||
}
|
||||
);
|
||||
|
@@ -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,
|
||||
|
@@ -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}
|
||||
|
@@ -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({
|
||||
|
@@ -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 = ({
|
||||
|
Reference in New Issue
Block a user