4.8.1 test-fix (#1561)
This commit is contained in:
@@ -118,6 +118,7 @@ export enum NodeOutputKeyEnum {
|
||||
answerText = 'answerText', // module answer. the value will be show and save to history
|
||||
success = 'success',
|
||||
failed = 'failed',
|
||||
error = 'error',
|
||||
text = 'system_text',
|
||||
addOutputParam = 'system_addOutputParam',
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.history,
|
||||
key: NodeOutputKeyEnum.history,
|
||||
required: true,
|
||||
label: 'core.module.output.label.New context',
|
||||
description: 'core.module.output.description.New context',
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
@@ -97,6 +98,7 @@ export const AiChatModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.answerText,
|
||||
key: NodeOutputKeyEnum.answerText,
|
||||
required: true,
|
||||
label: 'core.module.output.label.Ai response content',
|
||||
description: 'core.module.output.description.Ai response content',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
|
||||
@@ -24,6 +24,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
|
||||
key: NodeInputKeyEnum.answerText,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
required: true,
|
||||
label: 'core.module.input.label.Response content',
|
||||
description: 'core.module.input.description.Response content',
|
||||
placeholder: 'core.module.input.description.Response content'
|
||||
|
||||
@@ -68,6 +68,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
|
||||
{
|
||||
id: NodeOutputKeyEnum.cqResult,
|
||||
key: NodeOutputKeyEnum.cqResult,
|
||||
required: true,
|
||||
label: '分类结果',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
|
||||
@@ -60,25 +60,20 @@ export const ContextExtractModule: FlowNodeTemplateType = {
|
||||
}
|
||||
],
|
||||
outputs: [
|
||||
// {
|
||||
// id: NodeOutputKeyEnum.success,
|
||||
// key: NodeOutputKeyEnum.success,
|
||||
// label: '字段完全提取',
|
||||
// valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
// type: FlowNodeOutputTypeEnum.source
|
||||
// },
|
||||
// {
|
||||
// id: NodeOutputKeyEnum.failed,
|
||||
// key: NodeOutputKeyEnum.failed,
|
||||
// label: '提取字段缺失',
|
||||
// description: '存在一个或多个字段未提取成功。尽管使用了默认值也算缺失。',
|
||||
// valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
// type: FlowNodeOutputTypeEnum.source
|
||||
// },
|
||||
{
|
||||
id: NodeOutputKeyEnum.success,
|
||||
key: NodeOutputKeyEnum.success,
|
||||
label: '字段完全提取',
|
||||
required: true,
|
||||
description: '提取字段全部填充时返回 true (模型提取或使用默认值均属于成功)',
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.contextExtractFields,
|
||||
key: NodeOutputKeyEnum.contextExtractFields,
|
||||
label: '完整提取结果',
|
||||
required: true,
|
||||
description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}',
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
|
||||
@@ -81,10 +81,19 @@ export const HttpModule468: FlowNodeTemplateType = {
|
||||
],
|
||||
outputs: [
|
||||
Output_Template_AddOutput,
|
||||
{
|
||||
id: NodeOutputKeyEnum.error,
|
||||
key: NodeOutputKeyEnum.error,
|
||||
label: '请求错误',
|
||||
description: 'HTTP请求错误信息,成功时返回空',
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
id: NodeOutputKeyEnum.httpRawResponse,
|
||||
key: NodeOutputKeyEnum.httpRawResponse,
|
||||
label: '原始响应',
|
||||
required: true,
|
||||
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
|
||||
valueType: WorkflowIOValueTypeEnum.any,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
|
||||
@@ -43,6 +43,7 @@ export const RunAppModule: FlowNodeTemplateType = {
|
||||
label: '新的上下文',
|
||||
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
|
||||
valueType: WorkflowIOValueTypeEnum.chatHistory,
|
||||
required: true,
|
||||
type: FlowNodeOutputTypeEnum.static
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
export const chatNodeSystemPromptTip = 'core.app.tip.chatNodeSystemPromptTip';
|
||||
export const welcomeTextTip = 'core.app.tip.welcomeTextTip';
|
||||
export const variableTip = 'core.app.tip.variableTip';
|
||||
|
||||
@@ -175,7 +175,7 @@ export const pluginData2FlowNodeIO = (
|
||||
};
|
||||
|
||||
export const formatEditorVariablePickerIcon = (
|
||||
variables: { key: string; label: string; type?: `${VariableInputEnum}` }[]
|
||||
variables: { key: string; label: string; type?: `${VariableInputEnum}`; required?: boolean }[]
|
||||
): EditorVariablePickerType[] => {
|
||||
return variables.map((item) => ({
|
||||
...item,
|
||||
|
||||
@@ -39,6 +39,10 @@ export async function connectMongo({
|
||||
global.mongodb?.disconnect();
|
||||
global.mongodb = undefined;
|
||||
});
|
||||
mongoose.connection.on('disconnected', () => {
|
||||
console.log('mongo disconnected');
|
||||
global.mongodb = undefined;
|
||||
});
|
||||
|
||||
console.log('mongo connected');
|
||||
|
||||
|
||||
@@ -32,3 +32,5 @@ export const systemStartCb = () => {
|
||||
// process.exit(1); // 退出进程
|
||||
});
|
||||
};
|
||||
|
||||
export const surrenderProcess = () => new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
@@ -132,17 +132,19 @@ export const embeddingRecall = async (
|
||||
): Promise<{
|
||||
results: EmbeddingRecallItemType[];
|
||||
}> => {
|
||||
const { datasetIds, vectors, limit, retry = 2 } = props;
|
||||
const { teamId, datasetIds, vectors, limit, retry = 2 } = props;
|
||||
|
||||
try {
|
||||
const results: any = await PgClient.query(
|
||||
`BEGIN;
|
||||
`
|
||||
BEGIN;
|
||||
SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
|
||||
select id, collection_id, vector <#> '[${vectors[0]}]' AS score
|
||||
from ${PgDatasetTableName}
|
||||
where dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
||||
where team_id='${teamId}'
|
||||
AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
||||
order by score limit ${limit};
|
||||
COMMIT;`
|
||||
COMMIT;`
|
||||
);
|
||||
|
||||
const rows = results?.[2]?.rows as PgSearchRawType[];
|
||||
|
||||
@@ -35,8 +35,7 @@ type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.aiModel]: string;
|
||||
}>;
|
||||
type Response = DispatchNodeResultType<{
|
||||
[NodeOutputKeyEnum.success]?: boolean;
|
||||
[NodeOutputKeyEnum.failed]?: boolean;
|
||||
[NodeOutputKeyEnum.success]: boolean;
|
||||
[NodeOutputKeyEnum.contextExtractFields]: string;
|
||||
}>;
|
||||
|
||||
@@ -119,9 +118,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
});
|
||||
|
||||
return {
|
||||
// [DispatchNodeResponseKeyEnum.skipHandleId]: success
|
||||
// ? [getHandleId(nodeId, 'source', NodeOutputKeyEnum.failed)]
|
||||
// : [getHandleId(nodeId, 'source', NodeOutputKeyEnum.success)],
|
||||
[NodeOutputKeyEnum.success]: success,
|
||||
[NodeOutputKeyEnum.contextExtractFields]: JSON.stringify(arg),
|
||||
...arg,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NextApiResponse } from 'next';
|
||||
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { ChatDispatchProps } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
@@ -45,6 +45,7 @@ import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime
|
||||
import { dispatchSystemConfig } from './init/systemConfig';
|
||||
import { dispatchUpdateVariable } from './tools/runUpdateVar';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { surrenderProcess } from '../../../common/system/tools';
|
||||
|
||||
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
|
||||
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
|
||||
@@ -206,25 +207,34 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
}
|
||||
function checkNodeCanRun(nodes: RuntimeNodeItemType[] = []): Promise<any> {
|
||||
return Promise.all(
|
||||
nodes.map((node) => {
|
||||
nodes.map(async (node) => {
|
||||
const status = checkNodeRunStatus({
|
||||
node,
|
||||
runtimeEdges
|
||||
});
|
||||
|
||||
if (res?.closed || props.maxRunTimes <= 0) return;
|
||||
props.maxRunTimes--;
|
||||
console.log(props.maxRunTimes, user._id);
|
||||
|
||||
await surrenderProcess();
|
||||
|
||||
if (status === 'run') {
|
||||
addLog.info(`[dispatchWorkFlow] nodeRunWithActive: ${node.name}`);
|
||||
return nodeRunWithActive(node);
|
||||
}
|
||||
if (status === 'skip') {
|
||||
addLog.info(`[dispatchWorkFlow] nodeRunWithActive: ${node.name}`);
|
||||
addLog.info(`[dispatchWorkFlow] nodeRunWithSkip: ${node.name}`);
|
||||
return nodeRunWithSkip(node);
|
||||
}
|
||||
|
||||
return [];
|
||||
return;
|
||||
})
|
||||
).then((result) => {
|
||||
const flat = result.flat();
|
||||
const flat = result.flat().filter(Boolean) as unknown as {
|
||||
node: RuntimeNodeItemType;
|
||||
result: Record<string, any>;
|
||||
}[];
|
||||
if (flat.length === 0) return;
|
||||
|
||||
// Update the node output at the end of the run and get the next nodes
|
||||
@@ -267,7 +277,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
return params;
|
||||
}
|
||||
async function nodeRunWithActive(node: RuntimeNodeItemType) {
|
||||
if (res?.closed || props.maxRunTimes <= 0) return [];
|
||||
// push run status messages
|
||||
if (res && stream && detail && node.showStatus) {
|
||||
responseStatus({
|
||||
@@ -277,8 +286,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
});
|
||||
}
|
||||
|
||||
props.maxRunTimes--;
|
||||
|
||||
// get node running params
|
||||
const params = getNodeRunParams(node);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ type HttpRequestProps = ModuleDispatchProps<{
|
||||
[key: string]: any;
|
||||
}>;
|
||||
type HttpResponse = DispatchNodeResultType<{
|
||||
[NodeOutputKeyEnum.failed]?: boolean;
|
||||
[NodeOutputKeyEnum.error]?: object;
|
||||
[key: string]: any;
|
||||
}>;
|
||||
|
||||
@@ -159,20 +159,16 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
||||
} catch (error) {
|
||||
addLog.error('Http request error', 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);
|
||||
return {
|
||||
[NodeOutputKeyEnum.error]: formatHttpError(error),
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
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)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -170,10 +170,7 @@ export async function parseHeaderCert({
|
||||
|
||||
/* set cookie */
|
||||
export const setCookie = (res: NextApiResponse, token: string) => {
|
||||
res.setHeader(
|
||||
'Set-Cookie',
|
||||
`token=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict; Secure;`
|
||||
);
|
||||
res.setHeader('Set-Cookie', `token=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict;`);
|
||||
};
|
||||
/* clear cookie */
|
||||
export const clearCookie = (res: NextApiResponse) => {
|
||||
|
||||
@@ -67,7 +67,12 @@ const MyRightDrawer = ({
|
||||
<DrawerCloseButton position={'relative'} fontSize={'sm'} top={0} right={0} />
|
||||
</Flex>
|
||||
|
||||
<DrawerBody overflow={'hidden'} px={props?.px}>
|
||||
<DrawerBody
|
||||
overflowY={props?.overflowY || 'auto'}
|
||||
display={'flex'}
|
||||
flexDirection={'column'}
|
||||
px={props?.px ?? 4}
|
||||
>
|
||||
{children}
|
||||
<Loading loading={isLoading} fixed={false} />
|
||||
</DrawerBody>
|
||||
|
||||
@@ -98,6 +98,7 @@ const MySelect = (
|
||||
</MenuButton>
|
||||
|
||||
<MenuList
|
||||
className={props.className}
|
||||
minW={(() => {
|
||||
const w = ref.current?.clientWidth;
|
||||
if (w) {
|
||||
|
||||
@@ -3,12 +3,12 @@ import MyTooltip from '.';
|
||||
import { IconProps, QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
|
||||
type Props = IconProps & {
|
||||
label?: string;
|
||||
label?: string | React.ReactNode;
|
||||
};
|
||||
|
||||
const QuestionTip = ({ label, ...props }: Props) => {
|
||||
const QuestionTip = ({ label, maxW, ...props }: Props) => {
|
||||
return (
|
||||
<MyTooltip label={label}>
|
||||
<MyTooltip label={label} maxW={maxW}>
|
||||
<QuestionOutlineIcon {...props} />
|
||||
</MyTooltip>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants
|
||||
export type EditorVariablePickerType = {
|
||||
key: string;
|
||||
label: string;
|
||||
required?: boolean;
|
||||
icon?: string;
|
||||
valueType?: WorkflowIOValueTypeEnum;
|
||||
};
|
||||
|
||||
9
packages/web/hooks/useRefresh.ts
Normal file
9
packages/web/hooks/useRefresh.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { useBoolean } from 'ahooks';
|
||||
|
||||
export const useRefresh = () => {
|
||||
const [_, { toggle }] = useBoolean();
|
||||
|
||||
return {
|
||||
refresh: toggle
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user