Commit b1aafde7 by Archer Committed by GitHub

4.8.1 test-fix (#1561)

parent 87e4afe8
...@@ -25,6 +25,8 @@ weight: 350 ...@@ -25,6 +25,8 @@ weight: 350
curl --location --request GET 'http://localhost:3000/api/core/chat/inputGuide/query?appId=663c75302caf8315b1c00194&searchKey=你' curl --location --request GET 'http://localhost:3000/api/core/chat/inputGuide/query?appId=663c75302caf8315b1c00194&searchKey=你'
``` ```
其中 `appId` 为应用ID,`searchKey` 为搜索关键字,最多是50个字符。
**响应** **响应**
```json ```json
...@@ -43,6 +45,8 @@ curl --location --request GET 'http://localhost:3000/api/core/chat/inputGuide/qu ...@@ -43,6 +45,8 @@ curl --location --request GET 'http://localhost:3000/api/core/chat/inputGuide/qu
} }
``` ```
data是一个数组,包含了搜索到的问题,最多只需要返回5个问题。
**参数说明:** **参数说明:**
......
...@@ -118,6 +118,7 @@ export enum NodeOutputKeyEnum { ...@@ -118,6 +118,7 @@ export enum NodeOutputKeyEnum {
answerText = 'answerText', // module answer. the value will be show and save to history answerText = 'answerText', // module answer. the value will be show and save to history
success = 'success', success = 'success',
failed = 'failed', failed = 'failed',
error = 'error',
text = 'system_text', text = 'system_text',
addOutputParam = 'system_addOutputParam', addOutputParam = 'system_addOutputParam',
......
...@@ -89,6 +89,7 @@ export const AiChatModule: FlowNodeTemplateType = { ...@@ -89,6 +89,7 @@ export const AiChatModule: FlowNodeTemplateType = {
{ {
id: NodeOutputKeyEnum.history, id: NodeOutputKeyEnum.history,
key: NodeOutputKeyEnum.history, key: NodeOutputKeyEnum.history,
required: true,
label: 'core.module.output.label.New context', label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context', description: 'core.module.output.description.New context',
valueType: WorkflowIOValueTypeEnum.chatHistory, valueType: WorkflowIOValueTypeEnum.chatHistory,
...@@ -97,6 +98,7 @@ export const AiChatModule: FlowNodeTemplateType = { ...@@ -97,6 +98,7 @@ export const AiChatModule: FlowNodeTemplateType = {
{ {
id: NodeOutputKeyEnum.answerText, id: NodeOutputKeyEnum.answerText,
key: NodeOutputKeyEnum.answerText, key: NodeOutputKeyEnum.answerText,
required: true,
label: 'core.module.output.label.Ai response content', label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content', description: 'core.module.output.description.Ai response content',
valueType: WorkflowIOValueTypeEnum.string, valueType: WorkflowIOValueTypeEnum.string,
......
...@@ -24,6 +24,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = { ...@@ -24,6 +24,7 @@ export const AssignedAnswerModule: FlowNodeTemplateType = {
key: NodeInputKeyEnum.answerText, key: NodeInputKeyEnum.answerText,
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference], renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.any, valueType: WorkflowIOValueTypeEnum.any,
required: true,
label: 'core.module.input.label.Response content', label: 'core.module.input.label.Response content',
description: 'core.module.input.description.Response content', description: 'core.module.input.description.Response content',
placeholder: 'core.module.input.description.Response content' placeholder: 'core.module.input.description.Response content'
......
...@@ -68,6 +68,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = { ...@@ -68,6 +68,7 @@ export const ClassifyQuestionModule: FlowNodeTemplateType = {
{ {
id: NodeOutputKeyEnum.cqResult, id: NodeOutputKeyEnum.cqResult,
key: NodeOutputKeyEnum.cqResult, key: NodeOutputKeyEnum.cqResult,
required: true,
label: '分类结果', label: '分类结果',
valueType: WorkflowIOValueTypeEnum.string, valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static type: FlowNodeOutputTypeEnum.static
......
...@@ -60,25 +60,20 @@ export const ContextExtractModule: FlowNodeTemplateType = { ...@@ -60,25 +60,20 @@ export const ContextExtractModule: FlowNodeTemplateType = {
} }
], ],
outputs: [ outputs: [
// { {
// id: NodeOutputKeyEnum.success, id: NodeOutputKeyEnum.success,
// key: NodeOutputKeyEnum.success, key: NodeOutputKeyEnum.success,
// label: '字段完全提取', label: '字段完全提取',
// valueType: WorkflowIOValueTypeEnum.boolean, required: true,
// type: FlowNodeOutputTypeEnum.source description: '提取字段全部填充时返回 true (模型提取或使用默认值均属于成功)',
// }, valueType: WorkflowIOValueTypeEnum.boolean,
// { type: FlowNodeOutputTypeEnum.static
// id: NodeOutputKeyEnum.failed, },
// key: NodeOutputKeyEnum.failed,
// label: '提取字段缺失',
// description: '存在一个或多个字段未提取成功。尽管使用了默认值也算缺失。',
// valueType: WorkflowIOValueTypeEnum.boolean,
// type: FlowNodeOutputTypeEnum.source
// },
{ {
id: NodeOutputKeyEnum.contextExtractFields, id: NodeOutputKeyEnum.contextExtractFields,
key: NodeOutputKeyEnum.contextExtractFields, key: NodeOutputKeyEnum.contextExtractFields,
label: '完整提取结果', label: '完整提取结果',
required: true,
description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}', description: '一个 JSON 字符串,例如:{"name:":"YY","Time":"2023/7/2 18:00"}',
valueType: WorkflowIOValueTypeEnum.string, valueType: WorkflowIOValueTypeEnum.string,
type: FlowNodeOutputTypeEnum.static type: FlowNodeOutputTypeEnum.static
......
...@@ -82,9 +82,18 @@ export const HttpModule468: FlowNodeTemplateType = { ...@@ -82,9 +82,18 @@ export const HttpModule468: FlowNodeTemplateType = {
outputs: [ outputs: [
Output_Template_AddOutput, Output_Template_AddOutput,
{ {
id: NodeOutputKeyEnum.error,
key: NodeOutputKeyEnum.error,
label: '请求错误',
description: 'HTTP请求错误信息,成功时返回空',
valueType: WorkflowIOValueTypeEnum.object,
type: FlowNodeOutputTypeEnum.static
},
{
id: NodeOutputKeyEnum.httpRawResponse, id: NodeOutputKeyEnum.httpRawResponse,
key: NodeOutputKeyEnum.httpRawResponse, key: NodeOutputKeyEnum.httpRawResponse,
label: '原始响应', label: '原始响应',
required: true,
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。', description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
valueType: WorkflowIOValueTypeEnum.any, valueType: WorkflowIOValueTypeEnum.any,
type: FlowNodeOutputTypeEnum.static type: FlowNodeOutputTypeEnum.static
......
...@@ -43,6 +43,7 @@ export const RunAppModule: FlowNodeTemplateType = { ...@@ -43,6 +43,7 @@ export const RunAppModule: FlowNodeTemplateType = {
label: '新的上下文', label: '新的上下文',
description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回', description: '将该应用回复内容拼接到历史记录中,作为新的上下文返回',
valueType: WorkflowIOValueTypeEnum.chatHistory, valueType: WorkflowIOValueTypeEnum.chatHistory,
required: true,
type: FlowNodeOutputTypeEnum.static type: FlowNodeOutputTypeEnum.static
}, },
{ {
......
export const chatNodeSystemPromptTip = 'core.app.tip.chatNodeSystemPromptTip'; 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 = ( ...@@ -175,7 +175,7 @@ export const pluginData2FlowNodeIO = (
}; };
export const formatEditorVariablePickerIcon = ( export const formatEditorVariablePickerIcon = (
variables: { key: string; label: string; type?: `${VariableInputEnum}` }[] variables: { key: string; label: string; type?: `${VariableInputEnum}`; required?: boolean }[]
): EditorVariablePickerType[] => { ): EditorVariablePickerType[] => {
return variables.map((item) => ({ return variables.map((item) => ({
...item, ...item,
......
...@@ -39,6 +39,10 @@ export async function connectMongo({ ...@@ -39,6 +39,10 @@ export async function connectMongo({
global.mongodb?.disconnect(); global.mongodb?.disconnect();
global.mongodb = undefined; global.mongodb = undefined;
}); });
mongoose.connection.on('disconnected', () => {
console.log('mongo disconnected');
global.mongodb = undefined;
});
console.log('mongo connected'); console.log('mongo connected');
......
...@@ -32,3 +32,5 @@ export const systemStartCb = () => { ...@@ -32,3 +32,5 @@ export const systemStartCb = () => {
// process.exit(1); // 退出进程 // process.exit(1); // 退出进程
}); });
}; };
export const surrenderProcess = () => new Promise((resolve) => setImmediate(resolve));
...@@ -132,15 +132,17 @@ export const embeddingRecall = async ( ...@@ -132,15 +132,17 @@ export const embeddingRecall = async (
): Promise<{ ): Promise<{
results: EmbeddingRecallItemType[]; results: EmbeddingRecallItemType[];
}> => { }> => {
const { datasetIds, vectors, limit, retry = 2 } = props; const { teamId, datasetIds, vectors, limit, retry = 2 } = props;
try { try {
const results: any = await PgClient.query( const results: any = await PgClient.query(
`BEGIN; `
BEGIN;
SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100}; SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
select id, collection_id, vector <#> '[${vectors[0]}]' AS score select id, collection_id, vector <#> '[${vectors[0]}]' AS score
from ${PgDatasetTableName} 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}; order by score limit ${limit};
COMMIT;` COMMIT;`
); );
......
...@@ -35,8 +35,7 @@ type Props = ModuleDispatchProps<{ ...@@ -35,8 +35,7 @@ type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.aiModel]: string; [NodeInputKeyEnum.aiModel]: string;
}>; }>;
type Response = DispatchNodeResultType<{ type Response = DispatchNodeResultType<{
[NodeOutputKeyEnum.success]?: boolean; [NodeOutputKeyEnum.success]: boolean;
[NodeOutputKeyEnum.failed]?: boolean;
[NodeOutputKeyEnum.contextExtractFields]: string; [NodeOutputKeyEnum.contextExtractFields]: string;
}>; }>;
...@@ -119,9 +118,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> { ...@@ -119,9 +118,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
}); });
return { return {
// [DispatchNodeResponseKeyEnum.skipHandleId]: success [NodeOutputKeyEnum.success]: success,
// ? [getHandleId(nodeId, 'source', NodeOutputKeyEnum.failed)]
// : [getHandleId(nodeId, 'source', NodeOutputKeyEnum.success)],
[NodeOutputKeyEnum.contextExtractFields]: JSON.stringify(arg), [NodeOutputKeyEnum.contextExtractFields]: JSON.stringify(arg),
...arg, ...arg,
[DispatchNodeResponseKeyEnum.nodeResponse]: { [DispatchNodeResponseKeyEnum.nodeResponse]: {
......
import { NextApiResponse } from 'next'; 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 { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import type { ChatDispatchProps } from '@fastgpt/global/core/workflow/type/index.d'; import type { ChatDispatchProps } from '@fastgpt/global/core/workflow/type/index.d';
...@@ -45,6 +45,7 @@ import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime ...@@ -45,6 +45,7 @@ import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime
import { dispatchSystemConfig } from './init/systemConfig'; import { dispatchSystemConfig } from './init/systemConfig';
import { dispatchUpdateVariable } from './tools/runUpdateVar'; import { dispatchUpdateVariable } from './tools/runUpdateVar';
import { addLog } from '../../../common/system/log'; import { addLog } from '../../../common/system/log';
import { surrenderProcess } from '../../../common/system/tools';
const callbackMap: Record<FlowNodeTypeEnum, Function> = { const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart, [FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
...@@ -206,25 +207,34 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons ...@@ -206,25 +207,34 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
} }
function checkNodeCanRun(nodes: RuntimeNodeItemType[] = []): Promise<any> { function checkNodeCanRun(nodes: RuntimeNodeItemType[] = []): Promise<any> {
return Promise.all( return Promise.all(
nodes.map((node) => { nodes.map(async (node) => {
const status = checkNodeRunStatus({ const status = checkNodeRunStatus({
node, node,
runtimeEdges runtimeEdges
}); });
if (res?.closed || props.maxRunTimes <= 0) return;
props.maxRunTimes--;
console.log(props.maxRunTimes, user._id);
await surrenderProcess();
if (status === 'run') { if (status === 'run') {
addLog.info(`[dispatchWorkFlow] nodeRunWithActive: ${node.name}`); addLog.info(`[dispatchWorkFlow] nodeRunWithActive: ${node.name}`);
return nodeRunWithActive(node); return nodeRunWithActive(node);
} }
if (status === 'skip') { if (status === 'skip') {
addLog.info(`[dispatchWorkFlow] nodeRunWithActive: ${node.name}`); addLog.info(`[dispatchWorkFlow] nodeRunWithSkip: ${node.name}`);
return nodeRunWithSkip(node); return nodeRunWithSkip(node);
} }
return []; return;
}) })
).then((result) => { ).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; if (flat.length === 0) return;
// Update the node output at the end of the run and get the next nodes // 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 ...@@ -267,7 +277,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
return params; return params;
} }
async function nodeRunWithActive(node: RuntimeNodeItemType) { async function nodeRunWithActive(node: RuntimeNodeItemType) {
if (res?.closed || props.maxRunTimes <= 0) return [];
// push run status messages // push run status messages
if (res && stream && detail && node.showStatus) { if (res && stream && detail && node.showStatus) {
responseStatus({ responseStatus({
...@@ -277,8 +286,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons ...@@ -277,8 +286,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
}); });
} }
props.maxRunTimes--;
// get node running params // get node running params
const params = getNodeRunParams(node); const params = getNodeRunParams(node);
......
...@@ -33,7 +33,7 @@ type HttpRequestProps = ModuleDispatchProps<{ ...@@ -33,7 +33,7 @@ type HttpRequestProps = ModuleDispatchProps<{
[key: string]: any; [key: string]: any;
}>; }>;
type HttpResponse = DispatchNodeResultType<{ type HttpResponse = DispatchNodeResultType<{
[NodeOutputKeyEnum.failed]?: boolean; [NodeOutputKeyEnum.error]?: object;
[key: string]: any; [key: string]: any;
}>; }>;
...@@ -159,11 +159,9 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H ...@@ -159,11 +159,9 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
} catch (error) { } catch (error) {
addLog.error('Http request error', error); addLog.error('Http request error', error);
if (isToolCall) {
return { return {
[NodeOutputKeyEnum.failed]: true, [NodeOutputKeyEnum.error]: formatHttpError(error),
[DispatchNodeResponseKeyEnum.nodeResponse]: { [DispatchNodeResponseKeyEnum.nodeResponse]: {
totalPoints: 0,
params: Object.keys(params).length > 0 ? params : undefined, params: Object.keys(params).length > 0 ? params : undefined,
body: Object.keys(requestBody).length > 0 ? requestBody : undefined, body: Object.keys(requestBody).length > 0 ? requestBody : undefined,
headers: Object.keys(headers).length > 0 ? headers : undefined, headers: Object.keys(headers).length > 0 ? headers : undefined,
...@@ -172,8 +170,6 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H ...@@ -172,8 +170,6 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
[NodeOutputKeyEnum.httpRawResponse]: getErrText(error) [NodeOutputKeyEnum.httpRawResponse]: getErrText(error)
}; };
} }
return Promise.reject(error);
}
}; };
async function fetchData({ async function fetchData({
......
...@@ -170,10 +170,7 @@ export async function parseHeaderCert({ ...@@ -170,10 +170,7 @@ export async function parseHeaderCert({
/* set cookie */ /* set cookie */
export const setCookie = (res: NextApiResponse, token: string) => { export const setCookie = (res: NextApiResponse, token: string) => {
res.setHeader( res.setHeader('Set-Cookie', `token=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict;`);
'Set-Cookie',
`token=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict; Secure;`
);
}; };
/* clear cookie */ /* clear cookie */
export const clearCookie = (res: NextApiResponse) => { export const clearCookie = (res: NextApiResponse) => {
......
...@@ -67,7 +67,12 @@ const MyRightDrawer = ({ ...@@ -67,7 +67,12 @@ const MyRightDrawer = ({
<DrawerCloseButton position={'relative'} fontSize={'sm'} top={0} right={0} /> <DrawerCloseButton position={'relative'} fontSize={'sm'} top={0} right={0} />
</Flex> </Flex>
<DrawerBody overflow={'hidden'} px={props?.px}> <DrawerBody
overflowY={props?.overflowY || 'auto'}
display={'flex'}
flexDirection={'column'}
px={props?.px ?? 4}
>
{children} {children}
<Loading loading={isLoading} fixed={false} /> <Loading loading={isLoading} fixed={false} />
</DrawerBody> </DrawerBody>
......
...@@ -98,6 +98,7 @@ const MySelect = ( ...@@ -98,6 +98,7 @@ const MySelect = (
</MenuButton> </MenuButton>
<MenuList <MenuList
className={props.className}
minW={(() => { minW={(() => {
const w = ref.current?.clientWidth; const w = ref.current?.clientWidth;
if (w) { if (w) {
......
...@@ -3,12 +3,12 @@ import MyTooltip from '.'; ...@@ -3,12 +3,12 @@ import MyTooltip from '.';
import { IconProps, QuestionOutlineIcon } from '@chakra-ui/icons'; import { IconProps, QuestionOutlineIcon } from '@chakra-ui/icons';
type Props = IconProps & { type Props = IconProps & {
label?: string; label?: string | React.ReactNode;
}; };
const QuestionTip = ({ label, ...props }: Props) => { const QuestionTip = ({ label, maxW, ...props }: Props) => {
return ( return (
<MyTooltip label={label}> <MyTooltip label={label} maxW={maxW}>
<QuestionOutlineIcon {...props} /> <QuestionOutlineIcon {...props} />
</MyTooltip> </MyTooltip>
); );
......
...@@ -3,6 +3,7 @@ import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants ...@@ -3,6 +3,7 @@ import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants
export type EditorVariablePickerType = { export type EditorVariablePickerType = {
key: string; key: string;
label: string; label: string;
required?: boolean;
icon?: string; icon?: string;
valueType?: WorkflowIOValueTypeEnum; valueType?: WorkflowIOValueTypeEnum;
}; };
import { useBoolean } from 'ahooks';
export const useRefresh = () => {
const [_, { toggle }] = useBoolean();
return {
refresh: toggle
};
};
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" rx="6" fill="#F0EEFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 10.7886C8 9.684 8.89543 8.78857 10 8.78857H26C27.1046 8.78857 28 9.684 28 10.7886V18.5718C28 19.6764 27.1046 20.5718 26 20.5718H10C8.89543 20.5718 8 19.6764 8 18.5718V10.7886ZM10.8 11.4928C10.3582 11.4928 10 11.851 10 12.2928C10 12.7347 10.3582 13.0928 10.8 13.0928H16.3812C16.823 13.0928 17.1812 12.7347 17.1812 12.2928C17.1812 11.851 16.823 11.4928 16.3812 11.4928H10.8ZM10.8 14.6802C10.3582 14.6802 10 15.0383 10 15.4802C10 15.922 10.3582 16.2802 10.8 16.2802H20.4092C20.8511 16.2802 21.2092 15.922 21.2092 15.4802C21.2092 15.0383 20.8511 14.6802 20.4092 14.6802H10.8ZM8 23.4807C8 22.7076 8.6268 22.0807 9.4 22.0807H26.6C27.3732 22.0807 28 22.7076 28 23.4807V25.8114C28 26.5846 27.3732 27.2114 26.6 27.2114H9.4C8.6268 27.2114 8 26.5846 8 25.8114V23.4807ZM24.745 23.7461C24.8601 23.5468 25.1479 23.5468 25.263 23.7461L26.243 25.4436C26.3696 25.6629 26.1835 25.9304 25.9339 25.888L25.0541 25.7384C25.021 25.7328 24.9871 25.7328 24.9539 25.7384L24.0741 25.888C23.8245 25.9304 23.6384 25.6629 23.765 25.4436L24.745 23.7461Z" fill="#8774EE"/>
</svg>
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" rx="6" fill="#FFF1F6"/>
<path d="M16.9567 8.4704C16.9567 7.89425 17.4238 7.42719 17.9999 7.42719C18.5761 7.42719 19.0432 7.89425 19.0432 8.4704V9.86377C19.0432 10.4399 18.5761 10.907 17.9999 10.907C17.4238 10.907 16.9567 10.4399 16.9567 9.86377V8.4704Z" fill="#F9518E"/>
<path d="M10.0569 17.0231C10.633 17.0231 11.1001 17.4901 11.1001 18.0663C11.1001 18.6424 10.633 19.1095 10.0569 19.1095H8.66797C8.09182 19.1095 7.62476 18.6424 7.62476 18.0663C7.62476 17.4901 8.09182 17.0231 8.66797 17.0231H10.0569Z" fill="#F9518E"/>
<path d="M27.332 17.0231C27.9081 17.0231 28.3752 17.4901 28.3752 18.0663C28.3752 18.6424 27.9081 19.1095 27.332 19.1095H25.9372C25.361 19.1095 24.894 18.6424 24.894 18.0663C24.894 17.4901 25.361 17.0231 25.9372 17.0231H27.332Z" fill="#F9518E"/>
<path d="M20.3526 24.6161C20.811 24.6161 21.1826 24.9878 21.1826 25.4461C21.1826 25.9045 20.811 26.2761 20.3526 26.2761H15.6229C15.1645 26.2761 14.7929 25.9045 14.7929 25.4461C14.7929 24.9878 15.1645 24.6161 15.6229 24.6161H20.3526Z" fill="#F9518E"/>
<path d="M19.169 27.1129C19.5722 27.1129 19.899 27.4397 19.899 27.8429C19.899 28.246 19.5722 28.5729 19.169 28.5729H16.8064C16.4032 28.5729 16.0764 28.246 16.0764 27.8429C16.0764 27.4397 16.4032 27.1129 16.8064 27.1129H19.169Z" fill="#F9518E"/>
<path d="M23.8047 17.8024C23.8047 21.0082 21.2058 23.6071 18 23.6071C14.7941 23.6071 12.1953 21.0082 12.1953 17.8024C12.1953 14.5965 14.7941 11.9977 18 11.9977C21.2058 11.9977 23.8047 14.5965 23.8047 17.8024Z" fill="#F9518E"/>
<path d="M24.3817 12.9573C23.9743 13.3647 23.3138 13.3647 22.9064 12.9573C22.499 12.5499 22.499 11.8894 22.9064 11.482L23.8909 10.4975C24.2983 10.0901 24.9588 10.0901 25.3662 10.4975C25.7736 10.9049 25.7736 11.5654 25.3662 11.9728L24.3817 12.9573Z" fill="#F9518E"/>
<path d="M11.6182 12.9619C12.0256 13.3693 12.6861 13.3693 13.0935 12.9619C13.5009 12.5545 13.5009 11.894 13.0935 11.4866L12.1091 10.5022C11.7017 10.0948 11.0411 10.0948 10.6337 10.5022C10.2263 10.9096 10.2263 11.5701 10.6337 11.9775L11.6182 12.9619Z" fill="#F9518E"/>
</svg>
<svg width="36" height="37" viewBox="0 0 36 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="0.230957" width="36" height="36" rx="6" fill="#F0F4FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6371 10.4538C12.0276 10.8443 12.0277 11.4774 11.6373 11.868C9.95004 13.5558 9.0022 15.8445 9.0022 18.231C9.0022 20.6175 9.95004 22.9063 11.6373 24.594C12.0277 24.9846 12.0276 25.6178 11.6371 26.0082C11.2465 26.3987 10.6133 26.3986 10.2228 26.008C8.16067 23.9452 7.0022 21.1478 7.0022 18.231C7.0022 15.3142 8.16067 12.5168 10.2228 10.454C10.6133 10.0634 11.2465 10.0633 11.6371 10.4538ZM24.3631 10.4538C24.7536 10.0633 25.3868 10.0634 25.7773 10.454C27.8395 12.5168 28.9979 15.3142 28.9979 18.231C28.9979 21.1478 27.8395 23.9452 25.7773 26.008C25.3868 26.3986 24.7536 26.3987 24.3631 26.0082C23.9725 25.6178 23.9724 24.9846 24.3628 24.594C26.0501 22.9063 26.9979 20.6175 26.9979 18.231C26.9979 15.8445 26.0501 13.5558 24.3628 11.868C23.9724 11.4774 23.9725 10.8443 24.3631 10.4538ZM14.4676 13.2743C14.8579 13.665 14.8575 14.2982 14.4668 14.6885C14.0019 15.1529 13.6331 15.7043 13.3815 16.3113C13.1299 16.9183 13.0003 17.5689 13.0003 18.226C13.0003 18.8831 13.1299 19.5337 13.3815 20.1407C13.6331 20.7477 14.0019 21.2991 14.4668 21.7635C14.8575 22.1538 14.8579 22.787 14.4676 23.1777C14.0773 23.5685 13.4441 23.5688 13.0533 23.1785C12.4025 22.5284 11.8862 21.7564 11.5339 20.9066C11.1817 20.0568 11.0003 19.1459 11.0003 18.226C11.0003 17.3061 11.1817 16.3952 11.5339 15.5454C11.8862 14.6956 12.4025 13.9236 13.0533 13.2735C13.4441 12.8832 14.0773 12.8836 14.4676 13.2743ZM21.5326 13.2843C21.9229 12.8936 22.556 12.8932 22.9468 13.2835C23.5976 13.9336 24.1139 14.7056 24.4662 15.5554C24.8185 16.4052 24.9998 17.3161 24.9998 18.236C24.9998 19.1559 24.8185 20.0668 24.4662 20.9166C24.1139 21.7664 23.5976 22.5384 22.9468 23.1885C22.556 23.5788 21.9229 23.5785 21.5326 23.1877C21.1423 22.797 21.1426 22.1638 21.5333 21.7735C21.9982 21.3091 22.367 20.7577 22.6186 20.1507C22.8703 19.5437 22.9998 18.8931 22.9998 18.236C22.9998 17.5789 22.8703 16.9283 22.6186 16.3213C22.367 15.7143 21.9982 15.1629 21.5333 14.6985C21.1426 14.3082 21.1423 13.675 21.5326 13.2843ZM18.0001 17.231C17.4478 17.231 17.0001 17.6787 17.0001 18.231C17.0001 18.7833 17.4478 19.231 18.0001 19.231C18.5523 19.231 19.0001 18.7833 19.0001 18.231C19.0001 17.6787 18.5523 17.231 18.0001 17.231ZM15.0001 18.231C15.0001 16.5742 16.3432 15.231 18.0001 15.231C19.6569 15.231 21.0001 16.5742 21.0001 18.231C21.0001 19.8879 19.6569 21.231 18.0001 21.231C16.3432 21.231 15.0001 19.8879 15.0001 18.231Z" fill="#3370FF"/>
</svg>
<svg width="36" height="37" viewBox="0 0 36 37" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="0.230957" width="36" height="36" rx="6" fill="#F0FBFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5797 27.1461C11.794 27.1461 11.9676 26.9724 11.9676 26.7582V24.9462C11.9676 24.7319 11.794 24.5583 11.5797 24.5583C11.3078 24.5583 11.1752 24.4712 11.0932 24.3431C10.9906 24.1753 10.907 23.8212 10.907 23.2019V21.2155C10.907 20.4008 10.82 19.7102 10.6307 19.1588C10.5034 18.7878 10.3258 18.4692 10.0894 18.2208C10.6742 17.6081 10.907 16.5688 10.907 15.2658V13.2018C10.907 12.6679 10.9932 12.3336 11.1126 12.1438C11.213 11.9842 11.3491 11.9036 11.5797 11.9036C11.794 11.9036 11.9676 11.73 11.9676 11.5157V9.70369C11.9676 9.48946 11.794 9.3158 11.5797 9.3158C10.5397 9.3158 9.70222 9.60765 9.16921 10.2748C8.64853 10.9201 8.43413 11.9701 8.43413 13.3181V15.479C8.43413 16.0734 8.35105 16.4582 8.22944 16.6816C8.17182 16.7874 8.11057 16.8478 8.0527 16.8833C7.99573 16.9182 7.92089 16.9419 7.81441 16.9419C7.60018 16.9419 7.42651 17.1155 7.42651 17.3298V19.1127C7.42651 19.327 7.60018 19.5006 7.81441 19.5006C8.00762 19.5006 8.13191 19.5715 8.23242 19.7493C8.35131 19.9597 8.43413 20.3252 8.43413 20.8957V23.2213C8.43413 24.5622 8.6503 25.6053 9.18226 26.2336C9.72059 26.8695 10.5522 27.1461 11.5797 27.1461Z" fill="#009BDE"/>
<path d="M24.0326 26.7582C24.0326 26.9724 24.2062 27.1461 24.4205 27.1461C25.448 27.1461 26.2796 26.8695 26.8179 26.2336C27.3499 25.6053 27.5661 24.5622 27.5661 23.2213V20.8957C27.5661 20.3252 27.6489 19.9597 27.7678 19.7493C27.8683 19.5715 27.9926 19.5006 28.1858 19.5006C28.4 19.5006 28.5737 19.327 28.5737 19.1127V17.3298C28.5737 17.1155 28.4 16.9419 28.1858 16.9419C28.0793 16.9419 28.0045 16.9182 27.9475 16.8833C27.8896 16.8478 27.8284 16.7874 27.7707 16.6816C27.6491 16.4582 27.5661 16.0734 27.5661 15.479V13.3181C27.5661 11.97 27.3516 10.92 26.8309 10.2747C26.2979 9.60761 25.4604 9.3158 24.4205 9.3158C24.2062 9.3158 24.0326 9.48946 24.0326 9.70369V11.5157C24.0326 11.73 24.2062 11.9036 24.4205 11.9036C24.6511 11.9036 24.7872 11.9842 24.8876 12.1438C25.007 12.3336 25.0932 12.6679 25.0932 13.2018V15.2658C25.0932 16.5688 25.326 17.6081 25.9108 18.2208C25.6744 18.4692 25.4968 18.7878 25.3694 19.1588C25.1802 19.7102 25.0932 20.4008 25.0932 21.2155V23.2019C25.0932 23.8212 25.0096 24.1753 24.907 24.3432C24.825 24.4712 24.6923 24.5583 24.4205 24.5583C24.2062 24.5583 24.0326 24.7319 24.0326 24.9462V26.7582Z" fill="#009BDE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.8173 15.5567C13.4007 15.1401 13.4007 14.4647 13.8173 14.0481C14.2339 13.6315 14.9093 13.6315 15.3258 14.0481L18.0001 16.7224L20.6744 14.0481C21.0909 13.6315 21.7663 13.6315 22.1829 14.0481C22.5995 14.4647 22.5995 15.1401 22.1829 15.5567L19.5087 18.2309L22.1829 20.9052C22.5995 21.3218 22.5995 21.9972 22.1829 22.4138C21.7663 22.8303 21.0909 22.8303 20.6744 22.4138L18.0001 19.7395L15.3258 22.4138C14.9093 22.8303 14.2339 22.8303 13.8173 22.4138C13.4007 21.9972 13.4007 21.3218 13.8173 20.9052L16.4915 18.2309L13.8173 15.5567Z" fill="#009BDE"/>
</svg>
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="36" height="36" rx="6" fill="#FFF1F6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 18C28 23.5228 23.5228 28 18 28C16.3347 28 14.7645 27.5929 13.3834 26.8729H10.2223C9.5596 26.8729 9.02234 26.3356 9.02234 25.6729V22.4098C8.3677 21.0796 8 19.5827 8 18C8 12.4772 12.4772 8 18 8C23.5228 8 28 12.4772 28 18ZM14.5962 18C14.5962 18.7028 14.0265 19.2726 13.3237 19.2726C12.6209 19.2726 12.0511 18.7028 12.0511 18C12.0511 17.2972 12.6209 16.7275 13.3237 16.7275C14.0265 16.7275 14.5962 17.2972 14.5962 18ZM19.1724 18C19.1724 18.7028 18.6027 19.2726 17.8999 19.2726C17.1971 19.2726 16.6273 18.7028 16.6273 18C16.6273 17.2972 17.1971 16.7275 17.8999 16.7275C18.6027 16.7275 19.1724 17.2972 19.1724 18ZM23.7485 18C23.7485 18.7028 23.1788 19.2726 22.476 19.2726C21.7732 19.2726 21.2034 18.7028 21.2034 18C21.2034 17.2972 21.7732 16.7275 22.476 16.7275C23.1788 16.7275 23.7485 17.2972 23.7485 18Z" fill="#F9518E"/>
</svg>
...@@ -30,7 +30,7 @@ export default function InputGuideBox({ ...@@ -30,7 +30,7 @@ export default function InputGuideBox({
return await queryChatInputGuideList( return await queryChatInputGuideList(
{ {
appId, appId,
searchKey: text searchKey: text.slice(0, 50)
}, },
chatInputGuide.customUrl ? chatInputGuide.customUrl : undefined chatInputGuide.customUrl ? chatInputGuide.customUrl : undefined
); );
......
...@@ -9,6 +9,7 @@ import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants'; ...@@ -9,6 +9,7 @@ import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import { ChatBoxInputFormType } from '../type.d'; import { ChatBoxInputFormType } from '../type.d';
import { useRefresh } from '@fastgpt/web/hooks/useRefresh';
const VariableInput = ({ const VariableInput = ({
appAvatar, appAvatar,
...@@ -25,6 +26,7 @@ const VariableInput = ({ ...@@ -25,6 +26,7 @@ const VariableInput = ({
const { register, setValue, handleSubmit: handleSubmitChat, watch } = chatForm; const { register, setValue, handleSubmit: handleSubmitChat, watch } = chatForm;
const variables = watch('variables'); const variables = watch('variables');
const chatStarted = watch('chatStarted'); const chatStarted = watch('chatStarted');
const { refresh } = useRefresh();
return ( return (
<Box py={3}> <Box py={3}>
...@@ -86,6 +88,7 @@ const VariableInput = ({ ...@@ -86,6 +88,7 @@ const VariableInput = ({
})} })}
value={variables[item.key]} value={variables[item.key]}
onchange={(e) => { onchange={(e) => {
refresh();
setValue(`variables.${item.key}`, e); setValue(`variables.${item.key}`, e);
}} }}
/> />
......
...@@ -21,7 +21,6 @@ import { getErrText } from '@fastgpt/global/common/error/utils'; ...@@ -21,7 +21,6 @@ import { getErrText } from '@fastgpt/global/common/error/utils';
import { Box, Flex, Checkbox } from '@chakra-ui/react'; import { Box, Flex, Checkbox } from '@chakra-ui/react';
import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus'; import { EventNameEnum, eventBus } from '@/web/common/utils/eventbus';
import { chats2GPTMessages } from '@fastgpt/global/core/chat/adapt'; import { chats2GPTMessages } from '@fastgpt/global/core/chat/adapt';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants'; import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
......
...@@ -37,6 +37,7 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; ...@@ -37,6 +37,7 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useRequest } from 'ahooks'; import { useRequest } from 'ahooks';
import HighlightText from '@fastgpt/web/components/common/String/HighlightText'; import HighlightText from '@fastgpt/web/components/common/String/HighlightText';
import { defaultChatInputGuideConfig } from '@fastgpt/global/core/app/constants'; import { defaultChatInputGuideConfig } from '@fastgpt/global/core/app/constants';
import ChatFunctionTip from './Tip';
const csvTemplate = `"第一列内容" const csvTemplate = `"第一列内容"
"只会将第一列内容导入,其余列会被忽略" "只会将第一列内容导入,其余列会被忽略"
...@@ -86,7 +87,7 @@ const InputGuideConfig = ({ ...@@ -86,7 +87,7 @@ const InputGuideConfig = ({
<MyIcon name={'core/app/inputGuides'} mr={2} w={'20px'} /> <MyIcon name={'core/app/inputGuides'} mr={2} w={'20px'} />
<HStack> <HStack>
<Box>{chatT('Input guide')}</Box> <Box>{chatT('Input guide')}</Box>
<QuestionTip label={chatT('Input guide tip')} /> <ChatFunctionTip type={'inputGuide'} />
</HStack> </HStack>
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={chatT('Config input guide')}> <MyTooltip label={chatT('Config input guide')}>
......
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { Box, Flex, Switch, type SwitchProps } from '@chakra-ui/react'; import { Box, Flex, Switch, type SwitchProps } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import ChatFunctionTip from './Tip';
// question generator switch // question generator switch
const QGSwitch = (props: SwitchProps) => { const QGSwitch = (props: SwitchProps) => {
...@@ -12,9 +11,7 @@ const QGSwitch = (props: SwitchProps) => { ...@@ -12,9 +11,7 @@ const QGSwitch = (props: SwitchProps) => {
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/chat/QGFill'} mr={2} w={'20px'} /> <MyIcon name={'core/chat/QGFill'} mr={2} w={'20px'} />
<Box fontWeight={'medium'}>{t('core.app.Question Guide')}</Box> <Box fontWeight={'medium'}>{t('core.app.Question Guide')}</Box>
<MyTooltip label={t('core.app.Question Guide Tip')} forceShow> <ChatFunctionTip type={'nextQuestion'} />
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
<Box flex={1} /> <Box flex={1} />
<Switch {...props} /> <Switch {...props} />
</Flex> </Flex>
......
...@@ -8,7 +8,6 @@ import { AppScheduledTriggerConfigType } from '@fastgpt/global/core/app/type'; ...@@ -8,7 +8,6 @@ import { AppScheduledTriggerConfigType } from '@fastgpt/global/core/app/type';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import type { MultipleSelectProps } from '@fastgpt/web/components/common/MySelect/type.d'; import type { MultipleSelectProps } from '@fastgpt/web/components/common/MySelect/type.d';
import { useForm } from 'react-hook-form';
import { cronParser2Fields } from '@fastgpt/global/common/string/time'; import { cronParser2Fields } from '@fastgpt/global/common/string/time';
import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect'; import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect';
......
import MyIcon from '@fastgpt/web/components/common/Icon'; import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@/components/MyTooltip';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/react'; import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/react';
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
...@@ -12,6 +11,7 @@ import MyModal from '@fastgpt/web/components/common/MyModal'; ...@@ -12,6 +11,7 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
import MySlider from '@/components/Slider'; import MySlider from '@/components/Slider';
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import { defaultTTSConfig } from '@fastgpt/global/core/app/constants'; import { defaultTTSConfig } from '@fastgpt/global/core/app/constants';
import ChatFunctionTip from './Tip';
const TTSSelect = ({ const TTSSelect = ({
value = defaultTTSConfig, value = defaultTTSConfig,
...@@ -82,9 +82,7 @@ const TTSSelect = ({ ...@@ -82,9 +82,7 @@ const TTSSelect = ({
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/tts'} mr={2} w={'20px'} /> <MyIcon name={'core/app/simpleMode/tts'} mr={2} w={'20px'} />
<Box fontWeight={'medium'}>{t('core.app.TTS')}</Box> <Box fontWeight={'medium'}>{t('core.app.TTS')}</Box>
<MyTooltip label={t('core.app.TTS Tip')} forceShow> <ChatFunctionTip type={'tts'} />
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
<Box flex={1} /> <Box flex={1} />
<MyTooltip label={t('core.app.Select TTS')}> <MyTooltip label={t('core.app.Select TTS')}>
<Button <Button
......
import { useI18n } from '@/web/context/I18n';
import { Box, Flex, Image } from '@chakra-ui/react';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { useTranslation } from 'next-i18next';
import React, { useRef } from 'react';
enum FnTypeEnum {
inputGuide = 'inputGuide',
nextQuestion = 'nextQuestion',
tts = 'tts',
variable = 'variable',
welcome = 'welcome'
}
const ChatFunctionTip = ({ type }: { type: `${FnTypeEnum}` }) => {
const { t } = useTranslation();
const { chatT } = useI18n();
const map = useRef({
[FnTypeEnum.inputGuide]: {
icon: '/imgs/app/inputGuide-icon.svg',
title: chatT('Input guide'),
desc: chatT('Input guide tip'),
imgUrl: '/imgs/app/inputGuide.svg'
},
[FnTypeEnum.nextQuestion]: {
icon: '/imgs/app/nextQuestion-icon.svg',
title: t('core.app.Question Guide'),
desc: t('core.app.Question Guide Tip'),
imgUrl: '/imgs/app/nextQuestion.svg'
},
[FnTypeEnum.tts]: {
icon: '/imgs/app/tts-icon.svg',
title: t('core.app.TTS'),
desc: t('core.app.TTS Tip'),
imgUrl: '/imgs/app/tts.svg'
},
[FnTypeEnum.variable]: {
icon: '/imgs/app/variable-icon.svg',
title: t('core.module.Variable'),
desc: t('core.app.tip.variableTip'),
imgUrl: '/imgs/app/variable.svg'
},
[FnTypeEnum.welcome]: {
icon: '/imgs/app/welcome-icon.svg',
title: t('core.app.Welcome Text'),
desc: t('core.app.tip.welcomeTextTip'),
imgUrl: '/imgs/app/welcome.svg'
}
});
const data = map.current[type];
return (
<QuestionTip
maxW={'420px'}
ml={1}
label={
<Box>
<Flex>
<Image src={data.icon} w={'36px'} alt={''} />
<Box ml={3}>
<Box fontWeight="bold">{data.title}</Box>
<Box fontSize={'xs'} color={'myGray.500'}>
{data.desc}
</Box>
</Box>
</Flex>
<Image src={data.imgUrl} w={'100%'} minH={['auto', '200px']} mt={2} alt={''} />
</Box>
}
/>
);
};
export default ChatFunctionTip;
...@@ -32,11 +32,11 @@ import { customAlphabet } from 'nanoid'; ...@@ -32,11 +32,11 @@ import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6); const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import MyTooltip from '@/components/MyTooltip'; import MyTooltip from '@/components/MyTooltip';
import { variableTip } from '@fastgpt/global/core/workflow/template/tip';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import MyRadio from '@/components/common/MyRadio'; import MyRadio from '@/components/common/MyRadio';
import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils'; import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/workflow/utils';
import ChatFunctionTip from './Tip';
const VariableEdit = ({ const VariableEdit = ({
variables = [], variables = [],
...@@ -96,12 +96,11 @@ const VariableEdit = ({ ...@@ -96,12 +96,11 @@ const VariableEdit = ({
<Box> <Box>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/variable'} w={'20px'} /> <MyIcon name={'core/app/simpleMode/variable'} w={'20px'} />
<Box ml={2} flex={1} fontWeight={'medium'}> <Box ml={2} fontWeight={'medium'}>
{t('core.module.Variable')} {t('core.module.Variable')}
<MyTooltip label={t(variableTip)} forceShow>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Box> </Box>
<ChatFunctionTip type={'variable'} />
<Box flex={1} />
<Button <Button
variant={'transparentBase'} variant={'transparentBase'}
leftIcon={<SmallAddIcon />} leftIcon={<SmallAddIcon />}
......
import { Box, Flex, TextareaProps } from '@chakra-ui/react';
import React from 'react';
import MyIcon from '@fastgpt/web/components/common/Icon';
import ChatFunctionTip from './Tip';
import MyTextarea from '@/components/common/Textarea/MyTextarea';
import { useTranslation } from 'next-i18next';
const WelcomeTextConfig = (props: TextareaProps) => {
const { t } = useTranslation();
return (
<>
<Flex alignItems={'center'}>
<MyIcon name={'core/app/simpleMode/chat'} w={'20px'} />
<Box ml={2}>{t('core.app.Welcome Text')}</Box>
<ChatFunctionTip type={'welcome'} />
</Flex>
<MyTextarea
mt={2}
bg={'myWhite.400'}
rows={6}
fontSize={'sm'}
placeholder={t('core.app.tip.welcomeTextTip')}
{...props}
/>
</>
);
};
export default WelcomeTextConfig;
...@@ -19,26 +19,26 @@ const scoreTheme: Record< ...@@ -19,26 +19,26 @@ const scoreTheme: Record<
color: string; color: string;
bg: string; bg: string;
borderColor: string; borderColor: string;
colorSchema: string; colorScheme: string;
} }
> = { > = {
'0': { '0': {
color: '#6F5DD7', color: '#6F5DD7',
bg: '#F0EEFF', bg: '#F0EEFF',
borderColor: '#D3CAFF', borderColor: '#D3CAFF',
colorSchema: 'purple' colorScheme: 'purple'
}, },
'1': { '1': {
color: '#9E53C1', color: '#9E53C1',
bg: '#FAF1FF', bg: '#FAF1FF',
borderColor: '#ECF', borderColor: '#ECF',
colorSchema: 'pink' colorScheme: 'pink'
}, },
'2': { '2': {
color: '#0884DD', color: '#0884DD',
bg: '#F0FBFF', bg: '#F0FBFF',
borderColor: '#BCE7FF', borderColor: '#BCE7FF',
colorSchema: 'blue' colorScheme: 'blue'
} }
}; };
...@@ -184,7 +184,7 @@ const QuoteItem = ({ ...@@ -184,7 +184,7 @@ const QuoteItem = ({
size="sm" size="sm"
borderRadius={'20px'} borderRadius={'20px'}
{...(scoreTheme[i] && { {...(scoreTheme[i] && {
colorScheme: scoreTheme[i].colorSchema colorScheme: scoreTheme[i].colorScheme
})} })}
bg="#E8EBF0" bg="#E8EBF0"
/> />
......
...@@ -165,7 +165,6 @@ export const useDebug = () => { ...@@ -165,7 +165,6 @@ export const useDebug = () => {
maxW={['90vw', '35vw']} maxW={['90vw', '35vw']}
px={0} px={0}
> >
<Flex flexDirection={'column'} h={'100%'} overflowY={'auto'}>
<Box flex={'1 0 0'} overflow={'auto'} px={6}> <Box flex={'1 0 0'} overflow={'auto'} px={6}>
{renderInputs.map((input) => { {renderInputs.map((input) => {
const required = input.required || false; const required = input.required || false;
...@@ -240,10 +239,9 @@ export const useDebug = () => { ...@@ -240,10 +239,9 @@ export const useDebug = () => {
) : null; ) : null;
})} })}
</Box> </Box>
<Flex py={2} justifyContent={'flex-end'}> <Flex py={2} justifyContent={'flex-end'} px={6}>
<Button onClick={handleSubmit(onclickRun)}>运行</Button> <Button onClick={handleSubmit(onclickRun)}>运行</Button>
</Flex> </Flex>
</Flex>
</MyRightDrawer> </MyRightDrawer>
); );
}, [onStartNodeDebug, runtimeEdges, runtimeNodeId, runtimeNodes, t]); }, [onStartNodeDebug, runtimeEdges, runtimeNodeId, runtimeNodes, t]);
......
...@@ -280,7 +280,7 @@ export function RenderHttpProps({ ...@@ -280,7 +280,7 @@ export function RenderHttpProps({
); );
return [...moduleVariables, ...globalVariables]; return [...moduleVariables, ...globalVariables];
}, [inputs, nodeList, t]); }, [appDetail.chatConfig, inputs, nodeList, t]);
const variableText = useMemo(() => { const variableText = useMemo(() => {
return variables return variables
......
...@@ -28,7 +28,7 @@ import MyInput from '@/components/MyInput'; ...@@ -28,7 +28,7 @@ import MyInput from '@/components/MyInput';
import { getElseIFLabel, getHandleId } from '@fastgpt/global/core/workflow/utils'; import { getElseIFLabel, getHandleId } from '@fastgpt/global/core/workflow/utils';
import { SourceHandle } from '../render/Handle'; import { SourceHandle } from '../render/Handle';
import { Position, useReactFlow } from 'reactflow'; import { Position, useReactFlow } from 'reactflow';
import { getReferenceDataValueType } from '@/web/core/workflow/utils'; import { getRefData } from '@/web/core/workflow/utils';
import DragIcon from '@fastgpt/web/components/common/DndDrag/DragIcon'; import DragIcon from '@fastgpt/web/components/common/DndDrag/DragIcon';
import { AppContext } from '@/web/core/app/context/appContext'; import { AppContext } from '@/web/core/app/context/appContext';
...@@ -346,8 +346,8 @@ const ConditionSelect = ({ ...@@ -346,8 +346,8 @@ const ConditionSelect = ({
const appDetail = useContextSelector(AppContext, (v) => v.appDetail); const appDetail = useContextSelector(AppContext, (v) => v.appDetail);
// get condition type // get condition type
const valueType = useMemo(() => { const { valueType, required } = useMemo(() => {
return getReferenceDataValueType({ return getRefData({
variable, variable,
nodeList, nodeList,
chatConfig: appDetail.chatConfig, chatConfig: appDetail.chatConfig,
...@@ -376,11 +376,22 @@ const ConditionSelect = ({ ...@@ -376,11 +376,22 @@ const ConditionSelect = ({
return []; return [];
}, [valueType]); }, [valueType]);
const filterQuiredConditionList = useMemo(() => {
if (required) {
return conditionList.filter(
(item) =>
item.value !== VariableConditionEnum.isEmpty &&
item.value !== VariableConditionEnum.isNotEmpty
);
}
return conditionList;
}, [conditionList, required]);
return ( return (
<MySelect <MySelect
className="nowheel"
w={'100%'} w={'100%'}
list={conditionList} list={filterQuiredConditionList}
value={condition} value={condition}
onchange={onSelect} onchange={onSelect}
placeholder="选择条件" placeholder="选择条件"
......
import React, { Dispatch, useMemo, useTransition } from 'react'; import React, { Dispatch, useMemo, useTransition } from 'react';
import { NodeProps } from 'reactflow'; import { NodeProps } from 'reactflow';
import { Box, Flex, Textarea, useTheme } from '@chakra-ui/react'; import { Box, useTheme } from '@chakra-ui/react';
import { QuestionOutlineIcon } from '@chakra-ui/icons';
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d'; import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import { welcomeTextTip } from '@fastgpt/global/core/workflow/template/tip';
import QGSwitch from '@/components/core/app/QGSwitch'; import QGSwitch from '@/components/core/app/QGSwitch';
import TTSSelect from '@/components/core/app/TTSSelect'; import TTSSelect from '@/components/core/app/TTSSelect';
import WhisperConfig from '@/components/core/app/WhisperConfig'; import WhisperConfig from '@/components/core/app/WhisperConfig';
import InputGuideConfig from '@/components/core/chat/appConfig/InputGuideConfig'; import InputGuideConfig from '@/components/core/app/InputGuideConfig';
import { getAppChatConfig } from '@fastgpt/global/core/workflow/utils'; import { getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { TTSTypeEnum } from '@/web/core/app/constants'; import { TTSTypeEnum } from '@/web/core/app/constants';
import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@/components/MyTooltip';
import NodeCard from './render/NodeCard'; import NodeCard from './render/NodeCard';
import ScheduledTriggerConfig from '@/components/core/app/ScheduledTriggerConfig'; import ScheduledTriggerConfig from '@/components/core/app/ScheduledTriggerConfig';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
...@@ -22,6 +18,7 @@ import { AppChatConfigType, AppDetailType, VariableItemType } from '@fastgpt/glo ...@@ -22,6 +18,7 @@ import { AppChatConfigType, AppDetailType, VariableItemType } from '@fastgpt/glo
import { useMemoizedFn } from 'ahooks'; import { useMemoizedFn } from 'ahooks';
import VariableEdit from '@/components/core/app/VariableEdit'; import VariableEdit from '@/components/core/app/VariableEdit';
import { AppContext } from '@/web/core/app/context/appContext'; import { AppContext } from '@/web/core/app/context/appContext';
import WelcomeTextConfig from '@/components/core/app/WelcomeTextConfig';
type ComponentProps = { type ComponentProps = {
chatConfig: AppChatConfigType; chatConfig: AppChatConfigType;
...@@ -94,22 +91,10 @@ function WelcomeText({ chatConfig: { welcomeText }, setAppDetail }: ComponentPro ...@@ -94,22 +91,10 @@ function WelcomeText({ chatConfig: { welcomeText }, setAppDetail }: ComponentPro
const [, startTst] = useTransition(); const [, startTst] = useTransition();
return ( return (
<> <Box className="nodrag">
<Flex mb={1} alignItems={'center'}> <WelcomeTextConfig
<MyIcon name={'core/modules/welcomeText'} mr={2} w={'14px'} color={'#E74694'} />
<Box fontWeight={'medium'}>{t('core.app.Welcome Text')}</Box>
<MyTooltip label={t(welcomeTextTip)} forceShow>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</MyTooltip>
</Flex>
<Textarea
className="nodrag"
rows={6}
fontSize={'12px'}
resize={'both'} resize={'both'}
defaultValue={welcomeText} defaultValue={welcomeText}
bg={'myWhite.500'}
placeholder={t(welcomeTextTip)}
onChange={(e) => { onChange={(e) => {
startTst(() => { startTst(() => {
setAppDetail((state) => ({ setAppDetail((state) => ({
...@@ -122,7 +107,7 @@ function WelcomeText({ chatConfig: { welcomeText }, setAppDetail }: ComponentPro ...@@ -122,7 +107,7 @@ function WelcomeText({ chatConfig: { welcomeText }, setAppDetail }: ComponentPro
}); });
}} }}
/> />
</> </Box>
); );
} }
......
...@@ -30,7 +30,7 @@ import { SmallAddIcon } from '@chakra-ui/icons'; ...@@ -30,7 +30,7 @@ import { SmallAddIcon } from '@chakra-ui/icons';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io'; import { ReferenceValueProps } from '@fastgpt/global/core/workflow/type/io';
import { ReferSelector, useReference } from './render/RenderInput/templates/Reference'; import { ReferSelector, useReference } from './render/RenderInput/templates/Reference';
import { getReferenceDataValueType } from '@/web/core/workflow/utils'; import { getRefData } from '@/web/core/workflow/utils';
import { isReferenceValue } from '@fastgpt/global/core/workflow/utils'; import { isReferenceValue } from '@fastgpt/global/core/workflow/utils';
import { AppContext } from '@/web/core/app/context/appContext'; import { AppContext } from '@/web/core/app/context/appContext';
...@@ -84,7 +84,7 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) => ...@@ -84,7 +84,7 @@ const NodeVariableUpdate = ({ data, selected }: NodeProps<FlowNodeItemType>) =>
return ( return (
<> <>
{updateList.map((updateItem, index) => { {updateList.map((updateItem, index) => {
const valueType = getReferenceDataValueType({ const { valueType } = getRefData({
variable: updateItem.variable, variable: updateItem.variable,
nodeList, nodeList,
chatConfig: appDetail.chatConfig, chatConfig: appDetail.chatConfig,
......
...@@ -32,6 +32,7 @@ const NodeStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => { ...@@ -32,6 +32,7 @@ const NodeStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
id: item.key, id: item.key,
type: FlowNodeOutputTypeEnum.static, type: FlowNodeOutputTypeEnum.static,
key: item.key, key: item.key,
required: item.required,
valueType: item.valueType || WorkflowIOValueTypeEnum.any, valueType: item.valueType || WorkflowIOValueTypeEnum.any,
label: item.label label: item.label
})); }));
......
...@@ -171,6 +171,11 @@ const RenderOutput = ({ ...@@ -171,6 +171,11 @@ const RenderOutput = ({
{renderOutputs.map((output) => { {renderOutputs.map((output) => {
return output.label ? ( return output.label ? (
<Box key={output.key} _notLast={{ mb: 5 }} position={'relative'}> <Box key={output.key} _notLast={{ mb: 5 }} position={'relative'}>
{output.required && (
<Box position={'absolute'} left={'-6px'} top={-1} color={'red.600'}>
*
</Box>
)}
<OutputLabel nodeId={nodeId} output={output} /> <OutputLabel nodeId={nodeId} output={output} />
</Box> </Box>
) : null; ) : null;
......
...@@ -47,6 +47,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) { ...@@ -47,6 +47,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
const { teamId, tmbId, dataset } = await authDataset({ const { teamId, tmbId, dataset } = await authDataset({
req, req,
authToken: true,
authApiKey: true, authApiKey: true,
per: 'w', per: 'w',
datasetId: data.datasetId datasetId: data.datasetId
......
...@@ -163,8 +163,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ...@@ -163,8 +163,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return authHeaderRequest({ return authHeaderRequest({
req, req,
appId, appId,
chatId, chatId
detail
}); });
})(); })();
...@@ -292,18 +291,20 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ...@@ -292,18 +291,20 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
data: '[DONE]' data: '[DONE]'
}); });
if (responseDetail && detail) { if (detail) {
responseWrite({ responseWrite({
res, res,
event: SseResponseEventEnum.updateVariables, event: SseResponseEventEnum.updateVariables,
data: JSON.stringify(newVariables) data: JSON.stringify(newVariables)
}); });
if (responseDetail) {
responseWrite({ responseWrite({
res, res,
event: SseResponseEventEnum.flowResponses, event: SseResponseEventEnum.flowResponses,
data: JSON.stringify(feResponseData) data: JSON.stringify(feResponseData)
}); });
} }
}
res.end(); res.end();
} else { } else {
...@@ -443,13 +444,11 @@ const authTeamSpaceChat = async ({ ...@@ -443,13 +444,11 @@ const authTeamSpaceChat = async ({
const authHeaderRequest = async ({ const authHeaderRequest = async ({
req, req,
appId, appId,
chatId, chatId
detail
}: { }: {
req: NextApiRequest; req: NextApiRequest;
appId?: string; appId?: string;
chatId?: string; chatId?: string;
detail?: boolean;
}): Promise<AuthResponseType> => { }): Promise<AuthResponseType> => {
const { const {
appId: apiKeyAppId, appId: apiKeyAppId,
...@@ -517,7 +516,7 @@ const authHeaderRequest = async ({ ...@@ -517,7 +516,7 @@ const authHeaderRequest = async ({
tmbId, tmbId,
user, user,
app, app,
responseDetail: detail, responseDetail: true,
apikey, apikey,
authType, authType,
canWrite canWrite
......
...@@ -4,7 +4,6 @@ import { AddIcon, QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons'; ...@@ -4,7 +4,6 @@ import { AddIcon, QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
import { useFieldArray, UseFormReturn } from 'react-hook-form'; import { useFieldArray, UseFormReturn } from 'react-hook-form';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d'; import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
import { welcomeTextTip } from '@fastgpt/global/core/workflow/template/tip';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
...@@ -42,14 +41,16 @@ const ToolSelectModal = dynamic(() => import('./ToolSelectModal'), { ssr: false ...@@ -42,14 +41,16 @@ const ToolSelectModal = dynamic(() => import('./ToolSelectModal'), { ssr: false
const TTSSelect = dynamic(() => import('@/components/core/app/TTSSelect'), { ssr: false }); const TTSSelect = dynamic(() => import('@/components/core/app/TTSSelect'), { ssr: false });
const QGSwitch = dynamic(() => import('@/components/core/app/QGSwitch'), { ssr: false }); const QGSwitch = dynamic(() => import('@/components/core/app/QGSwitch'), { ssr: false });
const WhisperConfig = dynamic(() => import('@/components/core/app/WhisperConfig'), { ssr: false }); const WhisperConfig = dynamic(() => import('@/components/core/app/WhisperConfig'), { ssr: false });
const InputGuideConfig = dynamic( const InputGuideConfig = dynamic(() => import('@/components/core/app/InputGuideConfig'), {
() => import('@/components/core/chat/appConfig/InputGuideConfig'), ssr: false
{ ssr: false } });
);
const ScheduledTriggerConfig = dynamic( const ScheduledTriggerConfig = dynamic(
() => import('@/components/core/app/ScheduledTriggerConfig'), () => import('@/components/core/app/ScheduledTriggerConfig'),
{ ssr: false } { ssr: false }
); );
const WelcomeTextConfig = dynamic(() => import('@/components/core/app/WelcomeTextConfig'), {
ssr: false
});
const BoxStyles: BoxProps = { const BoxStyles: BoxProps = {
px: 5, px: 5,
...@@ -409,18 +410,7 @@ const EditForm = ({ ...@@ -409,18 +410,7 @@ const EditForm = ({
{/* welcome */} {/* welcome */}
<Box {...BoxStyles}> <Box {...BoxStyles}>
<Flex alignItems={'center'}> <WelcomeTextConfig
<MyIcon name={'core/app/simpleMode/chat'} w={'20px'} />
<Box mx={2}>{t('core.app.Welcome Text')}</Box>
<MyTooltip label={t(welcomeTextTip)} forceShow>
<QuestionOutlineIcon />
</MyTooltip>
</Flex>
<MyTextarea
mt={2}
bg={'myWhite.400'}
rows={5}
placeholder={t(welcomeTextTip)}
defaultValue={getValues('chatConfig.welcomeText')} defaultValue={getValues('chatConfig.welcomeText')}
onBlur={(e) => { onBlur={(e) => {
setValue('chatConfig.welcomeText', e.target.value || ''); setValue('chatConfig.welcomeText', e.target.value || '');
......
...@@ -83,7 +83,6 @@ const PreviewChunks = ({ ...@@ -83,7 +83,6 @@ const PreviewChunks = ({
isLoading={isLoading} isLoading={isLoading}
maxW={['90vw', '40vw']} maxW={['90vw', '40vw']}
> >
<Flex flexDirection={'column'} height={'100%'} overflowY={'auto'}>
{data.map((item, index) => ( {data.map((item, index) => (
<Box <Box
key={index} key={index}
...@@ -104,7 +103,6 @@ const PreviewChunks = ({ ...@@ -104,7 +103,6 @@ const PreviewChunks = ({
<Box color={'myGray.500'}>{item.a}</Box> <Box color={'myGray.500'}>{item.a}</Box>
</Box> </Box>
))} ))}
</Flex>
</MyRightDrawer> </MyRightDrawer>
); );
}; };
......
...@@ -33,8 +33,8 @@ import ParentPaths from '@/components/common/ParentPaths'; ...@@ -33,8 +33,8 @@ import ParentPaths from '@/components/common/ParentPaths';
import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag'; import DatasetTypeTag from '@/components/core/dataset/DatasetTypeTag';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import { getErrText } from '@fastgpt/global/common/error/utils'; import { getErrText } from '@fastgpt/global/common/error/utils';
import { xmlDownloadFetch } from '@/web/common/api/xmlFetch';
import { useDatasetStore } from '@/web/core/dataset/store/dataset'; import { useDatasetStore } from '@/web/core/dataset/store/dataset';
import { downloadFetch } from '@/web/common/system/utils';
const CreateModal = dynamic(() => import('./component/CreateModal'), { ssr: false }); const CreateModal = dynamic(() => import('./component/CreateModal'), { ssr: false });
const MoveModal = dynamic(() => import('./component/MoveModal'), { ssr: false }); const MoveModal = dynamic(() => import('./component/MoveModal'), { ssr: false });
...@@ -93,7 +93,7 @@ const Dataset = () => { ...@@ -93,7 +93,7 @@ const Dataset = () => {
setLoading(true); setLoading(true);
await checkTeamExportDatasetLimit(dataset._id); await checkTeamExportDatasetLimit(dataset._id);
await xmlDownloadFetch({ await downloadFetch({
url: `/api/core/dataset/exportAll?datasetId=${dataset._id}`, url: `/api/core/dataset/exportAll?datasetId=${dataset._id}`,
filename: `${dataset.name}.csv` filename: `${dataset.name}.csv`
}); });
......
...@@ -51,18 +51,14 @@ const Render = ({ pluginId }: Props) => { ...@@ -51,18 +51,14 @@ const Render = ({ pluginId }: Props) => {
}); });
useEffect(() => { useEffect(() => {
if (isV2Workflow) {
initData(JSON.parse(workflowStringData));
}
}, [initData, isV2Workflow, workflowStringData]);
useEffect(() => {
if (!isV2Workflow && pluginDetail) { if (!isV2Workflow && pluginDetail) {
openConfirm(() => { openConfirm(() => {
initData(JSON.parse(JSON.stringify(v1Workflow2V2((pluginDetail.modules || []) as any)))); initData(JSON.parse(JSON.stringify(v1Workflow2V2((pluginDetail.modules || []) as any))));
})(); })();
} else {
initData(JSON.parse(workflowStringData));
} }
}, [initData, isV2Workflow, openConfirm, pluginDetail]); }, [pluginDetail]);
useBeforeunload({ useBeforeunload({
tip: t('core.common.tip.leave page') tip: t('core.common.tip.leave page')
......
...@@ -2,7 +2,6 @@ import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/cons ...@@ -2,7 +2,6 @@ import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/cons
import { getErrText } from '@fastgpt/global/common/error/utils'; import { getErrText } from '@fastgpt/global/common/error/utils';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d'; import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
import type { StartChatFnProps } from '@/components/ChatBox/type.d'; import type { StartChatFnProps } from '@/components/ChatBox/type.d';
import { getToken } from '@/web/support/user/auth';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { import {
...@@ -117,8 +116,7 @@ export const streamFetch = ({ ...@@ -117,8 +116,7 @@ export const streamFetch = ({
const requestData = { const requestData = {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
token: getToken()
}, },
signal: abortCtrl.signal, signal: abortCtrl.signal,
body: JSON.stringify({ body: JSON.stringify({
......
...@@ -4,7 +4,7 @@ import axios, { ...@@ -4,7 +4,7 @@ import axios, {
AxiosResponse, AxiosResponse,
AxiosProgressEvent AxiosProgressEvent
} from 'axios'; } from 'axios';
import { clearToken, getToken } from '@/web/support/user/auth'; import { clearToken } from '@/web/support/user/auth';
import { TOKEN_ERROR_CODE } from '@fastgpt/global/common/error/errorCode'; import { TOKEN_ERROR_CODE } from '@fastgpt/global/common/error/errorCode';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { useSystemStore } from '../system/useSystemStore'; import { useSystemStore } from '../system/useSystemStore';
...@@ -15,6 +15,7 @@ interface ConfigType { ...@@ -15,6 +15,7 @@ interface ConfigType {
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
cancelToken?: AbortController; cancelToken?: AbortController;
maxQuantity?: number; maxQuantity?: number;
withCredentials?: boolean;
} }
interface ResponseDataType { interface ResponseDataType {
code: number; code: number;
...@@ -61,7 +62,6 @@ function requestFinish({ url }: { url: string }) { ...@@ -61,7 +62,6 @@ function requestFinish({ url }: { url: string }) {
*/ */
function startInterceptors(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig { function startInterceptors(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
if (config.headers) { if (config.headers) {
config.headers.token = getToken();
} }
return config; return config;
...@@ -138,7 +138,7 @@ instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err) ...@@ -138,7 +138,7 @@ instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err)
function request( function request(
url: string, url: string,
data: any, data: any,
{ cancelToken, maxQuantity, ...config }: ConfigType, { cancelToken, maxQuantity, withCredentials, ...config }: ConfigType,
method: Method method: Method
): any { ): any {
/* 去空 */ /* 去空 */
...@@ -158,6 +158,7 @@ function request( ...@@ -158,6 +158,7 @@ function request(
data: ['POST', 'PUT'].includes(method) ? data : null, data: ['POST', 'PUT'].includes(method) ? data : null,
params: !['POST', 'PUT'].includes(method) ? data : null, params: !['POST', 'PUT'].includes(method) ? data : null,
signal: cancelToken?.signal, signal: cancelToken?.signal,
withCredentials,
...config // 用户自定义配置,可以覆盖前面的配置 ...config // 用户自定义配置,可以覆盖前面的配置
}) })
.then((res) => checkRes(res.data)) .then((res) => checkRes(res.data))
......
import { getToken } from '@/web/support/user/auth';
import { hasHttps } from '@fastgpt/web/common/system/utils';
export const xmlDownloadFetch = async ({ url, filename }: { url: string; filename: string }) => {
if (hasHttps()) {
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
} else {
const response = await fetch(url, {
headers: {
token: `${getToken()}`
}
});
if (!response.ok) throw new Error('Network response was not ok.');
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none'; // 隐藏<a>元素
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click(); // 模拟用户点击
document.body.removeChild(a);
window.URL.revokeObjectURL(downloadUrl); // 清理生成的URL
}
};
export const downloadFetch = async ({ url, filename }: { url: string; filename: string }) => {
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
...@@ -5,7 +5,6 @@ import type { AppTTSConfigType } from '@fastgpt/global/core/app/type.d'; ...@@ -5,7 +5,6 @@ import type { AppTTSConfigType } from '@fastgpt/global/core/app/type.d';
import { TTSTypeEnum } from '@/web/core/app/constants'; import { TTSTypeEnum } from '@/web/core/app/constants';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat.d'; import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat.d';
import { getToken } from '@/web/support/user/auth';
import { useMount } from 'ahooks'; import { useMount } from 'ahooks';
const contentType = 'audio/mpeg'; const contentType = 'audio/mpeg';
...@@ -41,8 +40,7 @@ export const useAudioPlay = (props?: OutLinkChatAuthProps & { ttsConfig?: AppTTS ...@@ -41,8 +40,7 @@ export const useAudioPlay = (props?: OutLinkChatAuthProps & { ttsConfig?: AppTTS
const response = await fetch('/api/core/chat/item/getSpeech', { const response = await fetch('/api/core/chat/item/getSpeech', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
token: getToken()
}, },
signal: audioController.current.signal, signal: audioController.current.signal,
body: JSON.stringify({ body: JSON.stringify({
......
...@@ -701,6 +701,7 @@ export const getSystemVariables = (t: TFunction): EditorVariablePickerType[] => ...@@ -701,6 +701,7 @@ export const getSystemVariables = (t: TFunction): EditorVariablePickerType[] =>
{ {
key: 'appId', key: 'appId',
label: t('core.module.http.AppId'), label: t('core.module.http.AppId'),
required: true,
valueType: WorkflowIOValueTypeEnum.string valueType: WorkflowIOValueTypeEnum.string
}, },
{ {
...@@ -716,11 +717,13 @@ export const getSystemVariables = (t: TFunction): EditorVariablePickerType[] => ...@@ -716,11 +717,13 @@ export const getSystemVariables = (t: TFunction): EditorVariablePickerType[] =>
{ {
key: 'histories', key: 'histories',
label: t('core.module.http.Histories'), label: t('core.module.http.Histories'),
required: true,
valueType: WorkflowIOValueTypeEnum.chatHistory valueType: WorkflowIOValueTypeEnum.chatHistory
}, },
{ {
key: 'cTime', key: 'cTime',
label: t('core.module.http.Current time'), label: t('core.module.http.Current time'),
required: true,
valueType: WorkflowIOValueTypeEnum.string valueType: WorkflowIOValueTypeEnum.string
} }
]; ];
......
...@@ -26,10 +26,11 @@ export const getCountChatInputGuideTotal = (data: countChatInputGuideTotalQuery) ...@@ -26,10 +26,11 @@ export const getCountChatInputGuideTotal = (data: countChatInputGuideTotalQuery)
export const getChatInputGuideList = (data: ChatInputGuideProps) => export const getChatInputGuideList = (data: ChatInputGuideProps) =>
GET<ChatInputGuideResponse>(`/core/chat/inputGuide/list`, data); GET<ChatInputGuideResponse>(`/core/chat/inputGuide/list`, data);
export const queryChatInputGuideList = ( export const queryChatInputGuideList = (data: QueryChatInputGuideProps, url?: string) => {
data: QueryChatInputGuideProps, return GET<QueryChatInputGuideResponse>(url ?? `/core/chat/inputGuide/query`, data, {
url = `/core/chat/inputGuide/query` withCredentials: !url
) => GET<QueryChatInputGuideResponse>(url, data); });
};
export const postChatInputGuides = (data: createInputGuideBody) => export const postChatInputGuides = (data: createInputGuideBody) =>
POST<createInputGuideResponse>(`/core/chat/inputGuide/create`, data); POST<createInputGuideResponse>(`/core/chat/inputGuide/create`, data);
......
...@@ -428,7 +428,7 @@ export const v1Workflow2V2 = ( ...@@ -428,7 +428,7 @@ export const v1Workflow2V2 = (
pluginId, pluginId,
pluginType: node.pluginType, pluginType: node.pluginType,
parentId: node.parentId, parentId: node.parentId,
version: 'v2.0', version: '481',
inputs, inputs,
outputs outputs
......
...@@ -157,7 +157,7 @@ export const computedNodeInputReference = ({ ...@@ -157,7 +157,7 @@ export const computedNodeInputReference = ({
return sourceNodes; return sourceNodes;
}; };
export const getReferenceDataValueType = ({ export const getRefData = ({
variable, variable,
nodeList, nodeList,
chatConfig, chatConfig,
...@@ -168,16 +168,34 @@ export const getReferenceDataValueType = ({ ...@@ -168,16 +168,34 @@ export const getReferenceDataValueType = ({
chatConfig: AppChatConfigType; chatConfig: AppChatConfigType;
t: TFunction; t: TFunction;
}) => { }) => {
if (!variable) return WorkflowIOValueTypeEnum.any; if (!variable)
return {
valueType: WorkflowIOValueTypeEnum.any,
required: false
};
const node = nodeList.find((node) => node.nodeId === variable[0]); const node = nodeList.find((node) => node.nodeId === variable[0]);
const systemVariables = getWorkflowGlobalVariables({ nodes: nodeList, chatConfig, t }); const systemVariables = getWorkflowGlobalVariables({ nodes: nodeList, chatConfig, t });
if (!node) return systemVariables.find((item) => item.key === variable?.[1])?.valueType; if (!node) {
const globalVariable = systemVariables.find((item) => item.key === variable?.[1]);
return {
valueType: globalVariable?.valueType || WorkflowIOValueTypeEnum.any,
required: !!globalVariable?.required
};
}
const output = node.outputs.find((item) => item.id === variable[1]); const output = node.outputs.find((item) => item.id === variable[1]);
if (!output) return WorkflowIOValueTypeEnum.any; if (!output)
return output.valueType; return {
valueType: WorkflowIOValueTypeEnum.any,
required: false
};
return {
valueType: output.valueType,
required: !!output.required
};
}; };
/* Connection rules */ /* Connection rules */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment