4.8.6 merge (#1943)

* Dataset collection forbid (#1885)

* perf: tool call support same id

* feat: collection forbid

* feat: collection forbid

* Inheritance Permission for apps (#1897)

* feat: app schema define

chore: references of authapp

* feat: authApp method inheritance

* feat: create and update api

* feat: update

* feat: inheritance Permission controller for app.

* feat: abstract version of inheritPermission

* feat: ancestorId for apps

* chore: update app

* fix: inheritPermission abstract version

* feat: update folder defaultPermission

* feat: app update api

* chore: inheritance frontend

* chore: app list api

* feat: update defaultPermission in app deatil

* feat: backend api finished

* feat: app inheritance permission fe

* fix: app update defaultpermission causes collaborator miss

* fix: ts error

* chore: adjust the codes

* chore: i18n

chore: i18n

* chore: fe adjust and i18n

* chore: adjust the code

* feat: resume api;
chore: rewrite update api and inheritPermission methods

* chore: something

* chore: fe code adjusting

* feat: frontend adjusting

* chore: fe code adjusting

* chore: adjusting the code

* perf: fe loading

* format

* Inheritance fix (#1908)

* fix: SlideCard

* fix: authapp did not return parent app for inheritance app

* fix: fe adjusting

* feat: fe adjusing

* perf: inherit per ux

* doc

* fix: ts errors (#1916)

* perf: inherit permission

* fix: permission inherit

* Workflow type (#1938)

* perf: workflow type

tmp workflow

perf: workflow type

feat: custom field config

* perf: dynamic input

* perf: node classify

* perf: node classify

* perf: node classify

* perf: node classify

* fix: workflow custom input

* feat: text editor and customFeedback move to basic nodes

* feat: community system plugin

* fix: ts

* feat: exprEval plugin

* perf: workflow type

* perf: plugin important

* fix: default templates

* perf: markdown hr css

* lock

* perf: fetch url

* perf: new plugin version

* fix: chat histories update

* fix: collection paths invalid

* perf: app card ui

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
This commit is contained in:
Archer
2024-07-04 17:42:09 +08:00
committed by GitHub
parent babf03c218
commit a9cdece341
303 changed files with 18883 additions and 13149 deletions

View File

@@ -11,6 +11,7 @@ import {
} from '@fortaine/fetch-event-source';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { useSystemStore } from '../system/useSystemStore';
import { formatTime2YMDHMW } from '@fastgpt/global/common/string/time';
type StreamFetchProps = {
url?: string;
@@ -108,7 +109,7 @@ export const streamFetch = ({
try {
// auto complete variables
const variables = data?.variables || {};
variables.cTime = dayjs().format('YYYY-MM-DD HH:mm:ss dddd');
variables.cTime = formatTime2YMDHMW();
const requestData = {
method: 'POST',

View File

@@ -1,16 +0,0 @@
import { useState } from 'react';
export const useDrag = () => {
const [moveDataId, setMoveDataId] = useState<string>();
const [dragStartId, setDragStartId] = useState<string>();
const [dragTargetId, setDragTargetId] = useState<string>();
return {
moveDataId,
setMoveDataId,
dragStartId,
setDragStartId,
dragTargetId,
setDragTargetId
};
};

View File

@@ -3,6 +3,7 @@ import { ModalFooter, ModalBody, Input, useDisclosure, Button, Box } from '@chak
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useTranslation } from 'next-i18next';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
export const useEditTitle = ({
title,
@@ -70,7 +71,7 @@ export const useEditTitle = ({
} catch (err) {
onErrorCb.current?.(err);
}
}, [canEmpty, onClose]);
}, [canEmpty, onClose, toast, valueRule]);
// eslint-disable-next-line react/display-name
const EditModal = useCallback(
@@ -82,34 +83,40 @@ export const useEditTitle = ({
maxLength?: number;
iconSrc?: string;
closeBtnText?: string;
}) => (
<MyModal isOpen={isOpen} onClose={onClose} iconSrc={iconSrc} title={title} maxW={'500px'}>
<ModalBody>
{!!tip && (
<Box mb={2} color={'myGray.500'} fontSize={'sm'}>
{tip}
</Box>
)}
}) => {
const { runAsync, loading } = useRequest2(onclickConfirm);
<Input
ref={inputRef}
defaultValue={defaultValue.current}
placeholder={placeholder}
autoFocus
maxLength={maxLength}
/>
</ModalBody>
<ModalFooter>
{!!closeBtnText && (
<Button mr={3} variant={'whiteBase'} onClick={onClose}>
{closeBtnText}
return (
<MyModal isOpen={isOpen} onClose={onClose} iconSrc={iconSrc} title={title} maxW={'500px'}>
<ModalBody>
{!!tip && (
<Box mb={2} color={'myGray.500'} fontSize={'sm'}>
{tip}
</Box>
)}
<Input
ref={inputRef}
defaultValue={defaultValue.current}
placeholder={placeholder}
autoFocus
maxLength={maxLength}
/>
</ModalBody>
<ModalFooter>
{!!closeBtnText && (
<Button mr={3} variant={'whiteBase'} onClick={onClose}>
{closeBtnText}
</Button>
)}
<Button onClick={runAsync} isLoading={loading}>
{t('common.Confirm')}
</Button>
)}
<Button onClick={onclickConfirm}>{t('common.Confirm')}</Button>
</ModalFooter>
</MyModal>
),
[isOpen, onClose, onclickConfirm, placeholder, tip, title]
</ModalFooter>
</MyModal>
);
},
[isOpen, onClose, onclickConfirm, placeholder, t, tip, title]
);
return {

View File

@@ -34,3 +34,6 @@ export const putAppById = (id: string, data: AppUpdateParams) =>
// =================== chat logs
export const getAppChatLogs = (data: GetAppChatLogsParams) => POST(`/core/app/getChatLogs`, data);
export const resumeInheritPer = (appId: string) =>
GET(`/core/app/resumeInheritPermission`, { appId });

View File

@@ -1,34 +1,37 @@
import { DELETE, GET, POST } from '@/web/common/api/request';
import type { createHttpPluginBody } from '@/pages/api/core/app/httpPlugin/create';
import type { UpdateHttpPluginBody } from '@/pages/api/core/app/httpPlugin/update';
import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type';
import type {
FlowNodeTemplateType,
NodeTemplateListItemType
} from '@fastgpt/global/core/workflow/type/node';
import { getMyApps } from '../api';
import type { ListAppBody } from '@/pages/api/core/app/list';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
import type { GetPreviewNodeQuery } from '@/pages/api/core/app/plugin/getPreviewNode';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
/* ============ team plugin ============== */
export const getTeamPlugTemplates = (data?: ListAppBody) =>
getMyApps(data).then((res) =>
res.map<FlowNodeTemplateType>((app) => ({
res.map<NodeTemplateListItemType>((app) => ({
id: app._id,
pluginId: app._id,
pluginType: app.type,
templateType: FlowNodeTemplateTypeEnum.personalPlugin,
isFolder: app.type === AppTypeEnum.folder || app.type === AppTypeEnum.httpPlugin,
templateType: FlowNodeTemplateTypeEnum.teamApp,
flowNodeType: FlowNodeTypeEnum.pluginModule,
avatar: app.avatar,
name: app.name,
intro: app.intro,
showStatus: false,
version: app.pluginData?.nodeVersion || '481',
inputs: [],
outputs: []
isTool: true
}))
);
export const getSystemPlugTemplates = () =>
GET<FlowNodeTemplateType[]>('/core/app/plugin/getSystemPluginTemplates');
GET<NodeTemplateListItemType[]>('/core/app/plugin/getSystemPluginTemplates');
export const getPreviewPluginNode = (data: GetPreviewNodeQuery) =>
GET<FlowNodeTemplateType>('/core/app/plugin/getPreviewNode', data);

View File

@@ -19,7 +19,8 @@ export const defaultApp: AppDetailType = {
edges: [],
version: 'v2',
defaultPermission: NullPermission,
permission: new AppPermission()
permission: new AppPermission(),
inheritPermission: false
};
export const defaultOutLinkForm: OutLinkEditType = {

View File

@@ -879,7 +879,7 @@ export const simpleBotTemplates: TemplateType = [
},
{
nodeId: 'jrWPV9',
name: '工具调用(实验)',
name: '工具调用',
intro: '通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。',
avatar: '/imgs/workflow/tool.svg',
flowNodeType: FlowNodeTypeEnum.tools,
@@ -982,7 +982,7 @@ export const simpleBotTemplates: TemplateType = [
description: ''
}
],
pluginId: 'community-getCurrentTime'
pluginId: 'community-getTime'
}
],
edges: [
@@ -1106,8 +1106,8 @@ export const workflowTemplates: TemplateType = [
id: 'userChatInput',
key: 'userChatInput',
label: 'core.module.input.label.user question',
valueType: 'string',
type: 'static'
type: 'static',
valueType: 'string'
}
]
},
@@ -1189,7 +1189,7 @@ export const workflowTemplates: TemplateType = [
description: '最多携带多少轮对话记录',
required: true,
min: 0,
max: 30,
max: 50,
value: 6
},
{
@@ -1199,7 +1199,7 @@ export const workflowTemplates: TemplateType = [
label: '用户问题',
required: true,
toolDescription: '用户问题',
value: ['k2QsBOBmH9Xu', 'text']
value: ['gBDvemE4FBhp', 'system_text']
},
{
key: 'quoteQA',
@@ -1214,99 +1214,23 @@ export const workflowTemplates: TemplateType = [
{
id: 'history',
key: 'history',
required: true,
label: 'core.module.output.label.New context',
description: 'core.module.output.description.New context',
valueType: 'chatHistory',
type: 'static',
required: true
type: 'static'
},
{
id: 'answerText',
key: 'answerText',
required: true,
label: 'core.module.output.label.Ai response content',
description: 'core.module.output.description.Ai response content',
valueType: 'string',
type: 'static',
required: true
type: 'static'
}
]
},
{
nodeId: 'k2QsBOBmH9Xu',
name: '原文声明',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
avatar: '/imgs/workflow/textEditor.svg',
flowNodeType: 'pluginModule',
showStatus: false,
position: {
x: 1000.9259923224292,
y: 3.3737410194846404
},
version: '481',
inputs: [
{
key: 'system_addInputParam',
valueType: 'dynamic',
label: '动态外部数据',
renderTypeList: ['addInputParam'],
required: false,
description: '',
canEdit: false,
value: '',
editField: {
key: true
},
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
}
},
{
key: 'q',
valueType: 'string',
label: 'q',
renderTypeList: ['reference'],
required: true,
description: '',
canEdit: true,
editField: {
key: true
},
value: ['448745', 'userChatInput']
},
{
key: '文本',
valueType: 'string',
label: '文本',
renderTypeList: ['textarea'],
required: true,
description: '',
canEdit: false,
value: '原文:\n"""\n{{q}}\n"""',
editField: {
key: true
},
maxLength: '',
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
}
}
],
outputs: [
{
id: 'text',
type: 'static',
key: 'text',
valueType: 'string',
label: 'text',
description: ''
}
],
pluginId: 'community-textEditor'
},
{
nodeId: 'w0oBbQ3YJHye',
name: '代码运行',
@@ -1330,8 +1254,41 @@ export const workflowTemplates: TemplateType = [
editField: {
key: true,
valueType: true
},
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: true
}
},
{
key: 'codeType',
renderTypeList: ['hidden'],
label: '',
value: 'js'
},
{
key: 'code',
renderTypeList: ['custom'],
label: '',
value:
"function main({data1}) {\n const codeBlocks = data1.match(/```[\\s\\S]*?```/g);\n\n if (codeBlocks && codeBlocks.length > 0) {\n const lastCodeBlock = codeBlocks[codeBlocks.length - 1];\n const cleanedCodeBlock = lastCodeBlock.replace(/```[a-zA-Z]*|```/g, '').trim();\n \n return {\n result: cleanedCodeBlock\n };\n }\n\n return {\n result: '未截取到代码块内容'\n };\n}\n"
},
{
key: 'data1',
valueType: 'string',
@@ -1344,19 +1301,6 @@ export const workflowTemplates: TemplateType = [
valueType: true
},
value: ['loOvhld2ZTKa', 'answerText']
},
{
key: 'codeType',
renderTypeList: ['hidden'],
label: '',
value: 'js'
},
{
key: 'code',
renderTypeList: ['custom'],
label: '',
value:
'function main({data1}){\n const result = data1.split("```").filter(item => !!item.trim())\n\n if(result[result.length-1]) {\n return {\n result: result[result.length-1]\n }\n }\n\n return {\n result: \'未截取到翻译内容\'\n }\n}'
}
],
outputs: [
@@ -1366,10 +1310,6 @@ export const workflowTemplates: TemplateType = [
type: 'dynamic',
valueType: 'dynamic',
label: '',
editField: {
key: true,
valueType: true
},
description: '将代码中 return 的对象作为输出,传递给后续的节点'
},
{
@@ -1393,6 +1333,13 @@ export const workflowTemplates: TemplateType = [
key: 'result',
valueType: 'string',
label: 'result'
},
{
id: 'gR0mkQpJ4Og8',
type: 'dynamic',
key: 'data2',
valueType: 'string',
label: 'data2'
}
]
},
@@ -1418,101 +1365,191 @@ export const workflowTemplates: TemplateType = [
description: 'core.module.input.description.Response content',
placeholder: 'core.module.input.description.Response content',
selectedTypeIndex: 1,
value: ['v9ijHqeA2NY2', 'text']
value: ['bcqtxqxE2R6o', 'system_text']
}
],
outputs: []
},
{
nodeId: 'v9ijHqeA2NY2',
name: '合并输出结果',
nodeId: 'gBDvemE4FBhp',
name: '文本拼接',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
avatar: '/imgs/workflow/textEditor.svg',
flowNodeType: 'pluginModule',
showStatus: false,
flowNodeType: 'textEditor',
position: {
x: 3083.567683275386,
y: 60.05513835086097
x: 1031.371061396644,
y: 38.65839420088383
},
version: '481',
version: '486',
inputs: [
{
key: 'system_addInputParam',
valueType: 'dynamic',
label: '动态外部数据',
renderTypeList: ['addInputParam'],
valueType: 'dynamic',
label: '',
required: false,
description: '',
canEdit: false,
value: '',
editField: {
key: true
},
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
description: '可以引用其他节点的输出,作为文本拼接的变量,通过 {{字段名}} 来引用变量',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
}
},
{
key: 'result',
valueType: 'string',
label: 'result',
renderTypeList: ['reference'],
required: true,
description: '',
canEdit: true,
editField: {
key: true
},
value: ['w0oBbQ3YJHye', 'qLUQfhG0ILRX']
},
{
key: '文本',
valueType: 'string',
label: '文本',
key: 'system_textareaInput',
renderTypeList: ['textarea'],
valueType: 'string',
required: true,
description: '',
canEdit: false,
value: '------\n\n最终翻译结果如下: \n\n```\n{{result}}\n```',
editField: {
key: true
label: '拼接文本',
placeholder: '可通过 {{字段名}} 来引用变量',
value: '原文:\n"""\n{{q}}\n"""'
},
{
renderTypeList: ['reference'],
valueType: 'string',
canEdit: true,
key: 'q',
label: 'q',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
},
maxLength: '',
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
}
required: true,
value: ['448745', 'userChatInput']
}
],
outputs: [
{
id: 'text',
id: 'system_text',
key: 'system_text',
label: '拼接结果',
type: 'static',
key: 'text',
valueType: 'string'
}
]
},
{
nodeId: 'bcqtxqxE2R6o',
name: '合并输出结果',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
avatar: '/imgs/workflow/textEditor.svg',
flowNodeType: 'textEditor',
position: {
x: 3113.6227559936665,
y: 12.909197647746709
},
version: '486',
inputs: [
{
key: 'system_addInputParam',
renderTypeList: ['addInputParam'],
valueType: 'dynamic',
label: '',
required: false,
description: '可以引用其他节点的输出,作为文本拼接的变量,通过 {{字段名}} 来引用变量',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
}
},
{
key: 'system_textareaInput',
renderTypeList: ['textarea'],
valueType: 'string',
label: 'text',
description: ''
required: true,
label: '拼接文本',
placeholder: '可通过 {{字段名}} 来引用变量',
value: '****** \n\n最终翻译结果如下: \n\n```\n{{result}}\n```'
},
{
renderTypeList: ['reference'],
valueType: 'string',
canEdit: true,
key: 'result',
label: 'result',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
},
required: true,
value: ['w0oBbQ3YJHye', 'qLUQfhG0ILRX']
}
],
pluginId: 'community-textEditor'
outputs: [
{
id: 'system_text',
key: 'system_text',
label: '拼接结果',
type: 'static',
valueType: 'string'
}
]
}
],
edges: [
{
source: '448745',
target: 'k2QsBOBmH9Xu',
sourceHandle: '448745-source-right',
targetHandle: 'k2QsBOBmH9Xu-target-left'
},
{
source: 'k2QsBOBmH9Xu',
target: 'loOvhld2ZTKa',
sourceHandle: 'k2QsBOBmH9Xu-source-right',
targetHandle: 'loOvhld2ZTKa-target-left'
},
{
source: 'loOvhld2ZTKa',
target: 'w0oBbQ3YJHye',
@@ -1520,15 +1557,27 @@ export const workflowTemplates: TemplateType = [
targetHandle: 'w0oBbQ3YJHye-target-left'
},
{
source: 'w0oBbQ3YJHye',
target: 'v9ijHqeA2NY2',
sourceHandle: 'w0oBbQ3YJHye-source-right',
targetHandle: 'v9ijHqeA2NY2-target-left'
source: '448745',
target: 'gBDvemE4FBhp',
sourceHandle: '448745-source-right',
targetHandle: 'gBDvemE4FBhp-target-left'
},
{
source: 'v9ijHqeA2NY2',
source: 'gBDvemE4FBhp',
target: 'loOvhld2ZTKa',
sourceHandle: 'gBDvemE4FBhp-source-right',
targetHandle: 'loOvhld2ZTKa-target-left'
},
{
source: 'w0oBbQ3YJHye',
target: 'bcqtxqxE2R6o',
sourceHandle: 'w0oBbQ3YJHye-source-right',
targetHandle: 'bcqtxqxE2R6o-target-left'
},
{
source: 'bcqtxqxE2R6o',
target: 'foO69L5FOmDQ',
sourceHandle: 'v9ijHqeA2NY2-source-right',
sourceHandle: 'bcqtxqxE2R6o-source-right',
targetHandle: 'foO69L5FOmDQ-target-left'
}
]
@@ -1636,7 +1685,7 @@ export const workflowTemplates: TemplateType = [
},
{
nodeId: 'NOgbnBzUwDgT',
name: '工具调用(实验)',
name: '工具调用',
intro: '通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。',
avatar: '/imgs/workflow/tool.svg',
flowNodeType: 'tools',
@@ -1735,11 +1784,7 @@ export const workflowTemplates: TemplateType = [
valueType: 'dynamic',
label: '',
required: false,
description: 'core.module.input.description.HTTP Dynamic Input',
editField: {
key: true,
valueType: true
}
description: 'core.module.input.description.HTTP Dynamic Input'
},
{
valueType: 'string',
@@ -1993,6 +2038,7 @@ export const workflowTemplates: TemplateType = [
x: 531.2422736065552,
y: -486.7611729549753
},
version: '481',
inputs: [
{
key: 'welcomeText',
@@ -2055,6 +2101,7 @@ export const workflowTemplates: TemplateType = [
x: 532.1275542407774,
y: 46.03775600322817
},
version: '481',
inputs: [
{
key: 'userChatInput',
@@ -2070,8 +2117,8 @@ export const workflowTemplates: TemplateType = [
id: 'userChatInput',
key: 'userChatInput',
label: 'core.module.input.label.user question',
valueType: 'string',
type: 'static'
type: 'static',
valueType: 'string'
}
]
},
@@ -2083,9 +2130,10 @@ export const workflowTemplates: TemplateType = [
flowNodeType: 'httpRequest468',
showStatus: true,
position: {
x: 921.2377506442713,
y: -483.94114977914256
x: 931.6784209157559,
y: -162.36850541742047
},
version: '486',
inputs: [
{
key: 'system_addInputParam',
@@ -2094,23 +2142,30 @@ export const workflowTemplates: TemplateType = [
label: '',
required: false,
description: 'core.module.input.description.HTTP Dynamic Input',
editField: {
key: true,
valueType: true
}
},
{
key: 'prompt',
valueType: 'string',
label: 'prompt',
renderTypeList: ['reference'],
description: '',
canEdit: true,
editField: {
key: true,
valueType: true
},
value: ['448745', 'userChatInput']
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: true
}
},
{
key: 'system_httpMethod',
@@ -2162,6 +2217,19 @@ export const workflowTemplates: TemplateType = [
'{\n "model": "dall-e-3",\n "prompt": "{{prompt}}",\n "n": 1,\n "size": "1024x1024"\n}',
label: '',
required: false
},
{
key: 'prompt',
valueType: 'string',
label: 'prompt',
renderTypeList: ['reference'],
description: '',
canEdit: true,
editField: {
key: true,
valueType: true
},
value: ['448745', 'userChatInput']
}
],
outputs: [
@@ -2171,15 +2239,40 @@ export const workflowTemplates: TemplateType = [
type: 'dynamic',
valueType: 'dynamic',
label: '',
editField: {
key: true,
valueType: true
customFieldConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: true
}
},
{
id: 'error',
key: 'error',
label: '请求错误',
description: 'HTTP请求错误信息成功时返回空',
valueType: 'object',
type: 'static'
},
{
id: 'httpRawResponse',
key: 'httpRawResponse',
label: '原始响应',
required: true,
description: 'HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。',
valueType: 'any',
type: 'static'
@@ -2193,81 +2286,6 @@ export const workflowTemplates: TemplateType = [
}
]
},
{
nodeId: 'CO3POL8svbbi',
name: '文本加工',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
avatar: '/imgs/workflow/textEditor.svg',
flowNodeType: 'pluginModule',
showStatus: false,
position: {
x: 1417.5940290051137,
y: -478.81889618104356
},
inputs: [
{
key: 'system_addInputParam',
valueType: 'dynamic',
label: '动态外部数据',
renderTypeList: ['addInputParam'],
required: false,
description: '',
canEdit: false,
value: '',
editField: {
key: true
},
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
}
},
{
key: 'url',
valueType: 'string',
label: 'url',
renderTypeList: ['reference'],
required: true,
description: '',
canEdit: true,
editField: {
key: true
},
value: ['tMyUnRL5jIrC', 'DeKGGioBwaMf']
},
{
key: '文本',
valueType: 'string',
label: '文本',
renderTypeList: ['textarea'],
required: true,
description: '',
canEdit: false,
value: '![]({{url}})',
editField: {
key: true
},
maxLength: '',
dynamicParamDefaultValue: {
inputType: 'reference',
valueType: 'string',
required: true
}
}
],
outputs: [
{
id: 'text',
type: 'static',
key: 'text',
valueType: 'string',
label: 'text',
description: ''
}
],
pluginId: 'community-textEditor'
},
{
nodeId: '7mapnCgHfKW6',
name: '指定回复',
@@ -2276,22 +2294,113 @@ export const workflowTemplates: TemplateType = [
avatar: '/imgs/workflow/reply.png',
flowNodeType: 'answerNode',
position: {
x: 1922.5628399315042,
y: -471.67391598231796
x: 2204.4609372615846,
y: 163.11883652393863
},
version: '481',
inputs: [
{
key: 'text',
renderTypeList: ['textarea', 'reference'],
valueType: 'string',
valueType: 'any',
label: 'core.module.input.label.Response content',
description: 'core.module.input.description.Response content',
placeholder: 'core.module.input.description.Response content',
selectedTypeIndex: 1,
value: ['CO3POL8svbbi', 'text']
value: ['vEXJF8pQ8eOv', 'system_text'],
required: true
}
],
outputs: []
},
{
nodeId: 'vEXJF8pQ8eOv',
name: '文本拼接',
intro: '可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。',
avatar: '/imgs/workflow/textEditor.svg',
flowNodeType: 'textEditor',
position: {
x: 1544.8821308368042,
y: -27.22950739442814
},
version: '486',
inputs: [
{
key: 'system_addInputParam',
renderTypeList: ['addInputParam'],
valueType: 'dynamic',
label: '',
required: false,
description: '可以引用其他节点的输出,作为文本拼接的变量,通过 {{字段名}} 来引用变量',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
}
},
{
key: 'system_textareaInput',
renderTypeList: ['textarea'],
valueType: 'string',
required: true,
label: '拼接文本',
placeholder: '可通过 {{字段名}} 来引用变量',
value: '![]({{url}})'
},
{
renderTypeList: ['reference'],
valueType: 'string',
canEdit: true,
key: 'url',
label: 'url',
customInputConfig: {
selectValueTypeList: [
'string',
'number',
'boolean',
'object',
'arrayString',
'arrayNumber',
'arrayBoolean',
'arrayObject',
'any',
'chatHistory',
'datasetQuote',
'dynamic',
'selectApp',
'selectDataset'
],
showDescription: false,
showDefaultValue: false
},
required: true,
value: ['tMyUnRL5jIrC', 'DeKGGioBwaMf']
}
],
outputs: [
{
id: 'system_text',
key: 'system_text',
label: '拼接结果',
type: 'static',
valueType: 'string'
}
]
}
],
edges: [
@@ -2303,14 +2412,14 @@ export const workflowTemplates: TemplateType = [
},
{
source: 'tMyUnRL5jIrC',
target: 'CO3POL8svbbi',
target: 'vEXJF8pQ8eOv',
sourceHandle: 'tMyUnRL5jIrC-source-right',
targetHandle: 'CO3POL8svbbi-target-left'
targetHandle: 'vEXJF8pQ8eOv-target-left'
},
{
source: 'CO3POL8svbbi',
source: 'vEXJF8pQ8eOv',
target: '7mapnCgHfKW6',
sourceHandle: 'CO3POL8svbbi-source-right',
sourceHandle: 'vEXJF8pQ8eOv-source-right',
targetHandle: '7mapnCgHfKW6-target-left'
}
]
@@ -2921,11 +3030,7 @@ export const pluginTemplates: TemplateType = [
valueType: 'dynamic',
label: '',
required: false,
description: 'core.module.input.description.HTTP Dynamic Input',
editField: {
key: true,
valueType: true
}
description: 'core.module.input.description.HTTP Dynamic Input'
},
{
key: 'text',

View File

@@ -4,7 +4,7 @@ import {
AppSchema,
AppSimpleEditFormType
} from '@fastgpt/global/core/app/type';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
import {
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
@@ -602,7 +602,7 @@ export function form2AppWorkflow(data: AppSimpleEditFormType): WorkflowType & {
nodes: [
{
nodeId: toolNodeId,
name: '工具调用(实验)',
name: '工具调用',
intro: '通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。',
avatar: '/imgs/workflow/tool.svg',
flowNodeType: FlowNodeTypeEnum.tools,

View File

@@ -110,7 +110,8 @@ const ChatContextProvider = ({
const { runAsync: onUpdateHistory, loading: isUpdatingHistory } = useRequest2(putChatHistory, {
onSuccess() {
loadHistories();
}
},
errorToast: undefined
});
const { runAsync: onDelHistory, loading: isDeletingHistory } = useRequest2(delChatHistoryById, {
onSuccess() {

View File

@@ -1,5 +1,5 @@
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/index.d';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';

View File

@@ -8,11 +8,7 @@ import type {
DatasetListItemType,
DatasetSimpleItemType
} from '@fastgpt/global/core/dataset/type.d';
import type {
GetDatasetCollectionsProps,
GetDatasetDataListProps,
UpdateDatasetCollectionParams
} from '@/global/core/api/datasetReq.d';
import type { GetDatasetCollectionsProps } from '@/global/core/api/datasetReq.d';
import type {
CreateDatasetCollectionParams,
CsvTableCreateDatasetCollectionParams,
@@ -29,16 +25,9 @@ import type {
SearchTestProps,
SearchTestResponse
} from '@/global/core/dataset/api.d';
import type {
UpdateDatasetDataProps,
CreateDatasetParams,
InsertOneDatasetDataProps
} from '@/global/core/dataset/api.d';
import type { CreateDatasetParams, InsertOneDatasetDataProps } from '@/global/core/dataset/api.d';
import type { DatasetCollectionItemType } from '@fastgpt/global/core/dataset/type';
import {
DatasetCollectionSyncResultEnum,
DatasetTypeEnum
} from '@fastgpt/global/core/dataset/constants';
import { DatasetCollectionSyncResultEnum } from '@fastgpt/global/core/dataset/constants';
import type { DatasetDataItemType } from '@fastgpt/global/core/dataset/type';
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
import { PagingData } from '@/types';
@@ -50,6 +39,9 @@ import type {
} from '@/pages/api/core/dataset/file/getPreviewChunks';
import type { readCollectionSourceResponse } from '@/pages/api/core/dataset/collection/read';
import type { GetDatasetListBody } from '@/pages/api/core/dataset/list';
import type { UpdateDatasetCollectionParams } from '@/pages/api/core/dataset/collection/update';
import type { GetDatasetDataListProps } from '@/pages/api/core/dataset/data/list';
import type { UpdateDatasetDataProps } from '@fastgpt/global/core/dataset/controller';
/* ======================== dataset ======================= */
export const getDatasets = (data: GetDatasetListBody) =>

View File

@@ -45,7 +45,6 @@ export const defaultCollectionDetail: DatasetCollectionItemType = {
name: '',
intro: '',
status: 'active',
permission: new DatasetPermission(),
vectorModel: defaultVectorModels[0].model,
agentModel: defaultQAModels[0].model,
defaultPermission: DatasetDefaultPermissionVal

View File

@@ -10,11 +10,8 @@ import {
FlowNodeTypeEnum
} from '@fastgpt/global/core/workflow/node/constant';
import { getHandleConfig } from '@fastgpt/global/core/workflow/template/utils';
import {
FlowNodeItemType,
FlowNodeTemplateType,
StoreNodeItemType
} from '@fastgpt/global/core/workflow/type';
import { FlowNodeItemType, StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
import type { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node';
import { VARIABLE_NODE_ID } from '@fastgpt/global/core/workflow/constants';
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
@@ -321,16 +318,6 @@ export const v1Workflow2V2 = (
step: input.step,
max: input.max,
min: input.min,
editField: input.editField,
dynamicParamDefaultValue: input.defaultEditField
? {
inputType: input.defaultEditField.inputType
? inputTypeMap[input.defaultEditField.inputType]
: undefined,
valueType: input.defaultEditField.valueType,
required: input.defaultEditField.required
}
: undefined,
llmModelType: input.llmModelType
};
@@ -407,12 +394,7 @@ export const v1Workflow2V2 = (
valueType: output.valueType,
renderTypeList: [FlowNodeInputTypeEnum.reference],
label: output.key,
canEdit: true,
editField: {
key: true,
description: true,
valueType: true
}
canEdit: true
});
});
}

View File

@@ -1,102 +1,16 @@
import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants';
export const FlowValueTypeMap = {
[WorkflowIOValueTypeEnum.string]: {
label: 'string',
value: WorkflowIOValueTypeEnum.string,
description: ''
},
[WorkflowIOValueTypeEnum.number]: {
label: 'number',
value: WorkflowIOValueTypeEnum.number,
description: ''
},
[WorkflowIOValueTypeEnum.boolean]: {
label: 'boolean',
value: WorkflowIOValueTypeEnum.boolean,
description: ''
},
[WorkflowIOValueTypeEnum.object]: {
label: 'object',
value: WorkflowIOValueTypeEnum.object,
description: ''
},
[WorkflowIOValueTypeEnum.arrayString]: {
label: 'array<string>',
value: WorkflowIOValueTypeEnum.arrayString,
description: ''
},
[WorkflowIOValueTypeEnum.arrayNumber]: {
label: 'array<number>',
value: WorkflowIOValueTypeEnum.arrayNumber,
description: ''
},
[WorkflowIOValueTypeEnum.arrayBoolean]: {
label: 'array<boolean>',
value: WorkflowIOValueTypeEnum.arrayBoolean,
description: ''
},
[WorkflowIOValueTypeEnum.arrayObject]: {
label: 'array<object>',
value: WorkflowIOValueTypeEnum.arrayObject,
description: ''
},
[WorkflowIOValueTypeEnum.chatHistory]: {
label: '历史记录',
value: WorkflowIOValueTypeEnum.chatHistory,
description: `{
obj: System | Human | AI;
value: string;
}[]`
},
[WorkflowIOValueTypeEnum.datasetQuote]: {
label: '知识库引用',
value: WorkflowIOValueTypeEnum.datasetQuote,
description: `{
id: string;
datasetId: string;
collectionId: string;
sourceName: string;
sourceId?: string;
q: string;
a: string
}[]`
},
[WorkflowIOValueTypeEnum.selectApp]: {
label: '选择应用',
value: WorkflowIOValueTypeEnum.selectApp,
description: ''
},
[WorkflowIOValueTypeEnum.selectDataset]: {
label: '选择知识库',
value: WorkflowIOValueTypeEnum.selectDataset,
description: `{
datasetId: string;
}`
},
[WorkflowIOValueTypeEnum.any]: {
label: 'any',
value: WorkflowIOValueTypeEnum.any,
description: ''
},
[WorkflowIOValueTypeEnum.dynamic]: {
label: '动态数据',
value: WorkflowIOValueTypeEnum.any,
description: ''
}
};
export const fnValueTypeSelect = [
{
label: 'String',
value: 'string'
label: WorkflowIOValueTypeEnum.string,
value: WorkflowIOValueTypeEnum.string
},
{
label: 'Number',
value: 'number'
label: WorkflowIOValueTypeEnum.number,
value: WorkflowIOValueTypeEnum.number
},
{
label: 'Boolean',
value: 'boolean'
label: WorkflowIOValueTypeEnum.boolean,
value: WorkflowIOValueTypeEnum.boolean
}
];

View File

@@ -1,14 +1,15 @@
import type {
StoreNodeItemType,
FlowNodeItemType,
FlowNodeTemplateType
} from '@fastgpt/global/core/workflow/type/index.d';
FlowNodeItemType
} from '@fastgpt/global/core/workflow/type/node.d';
import type { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node';
import type { Edge, Node, XYPosition } from 'reactflow';
import { moduleTemplatesFlat } from '@fastgpt/global/core/workflow/template/constants';
import {
EDGE_TYPE,
FlowNodeInputTypeEnum,
FlowNodeTypeEnum
FlowNodeTypeEnum,
defaultNodeVersion
} from '@fastgpt/global/core/workflow/node/constant';
import { EmptyNode } from '@fastgpt/global/core/workflow/template/system/emptyNode';
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
@@ -70,39 +71,55 @@ export const storeNode2FlowNode = ({
EmptyNode;
// replace item data
const moduleItem: FlowNodeItemType = {
const nodeItem: FlowNodeItemType = {
...template,
...storeNode,
avatar: storeNode?.avatar || template?.avatar,
inputs: storeNode.inputs
.map((storeInput) => {
const templateInput =
template.inputs.find((item) => item.key === storeInput.key) || storeInput;
version: storeNode.version ?? template.version ?? defaultNodeVersion,
inputs: template.inputs
.map<FlowNodeInputItemType>((templateInput) => {
const storeInput =
storeNode.inputs.find((item) => item.key === templateInput.key) || templateInput;
return {
...templateInput,
...storeInput,
renderTypeList: templateInput.renderTypeList
...templateInput,
selectedTypeIndex: storeInput.selectedTypeIndex ?? templateInput.selectedTypeIndex,
value: storeInput.value ?? templateInput.value,
label: storeInput.label ?? templateInput.label
};
})
.concat(
template.inputs.filter((item) => !storeNode.inputs.some((input) => input.key === item.key))
/*
1. Plugin input
2. Old version adapt: Dynamic input will be added to the node inputs.
*/
storeNode.inputs.filter((item) => !template.inputs.find((input) => input.key === item.key))
),
outputs: storeNode.outputs.map((storeOutput) => {
const templateOutput =
template.outputs.find((item) => item.key === storeOutput.key) || storeOutput;
return {
...storeOutput,
...templateOutput,
value: storeOutput.value
};
}),
version: storeNode.version || '481'
outputs: template.outputs
.map<FlowNodeOutputItemType>((templateOutput) => {
const storeOutput =
template.outputs.find((item) => item.key === templateOutput.key) || templateOutput;
return {
...storeOutput,
...templateOutput,
id: storeOutput.id ?? templateOutput.id,
value: storeOutput.value ?? templateOutput.value
};
})
.concat(
storeNode.outputs.filter(
(item) => !template.outputs.find((output) => output.key === item.key)
)
)
};
return {
id: storeNode.nodeId,
type: storeNode.flowNodeType,
data: moduleItem,
data: nodeItem,
selected,
position: storeNode.position || { x: 0, y: 0 }
};

View File

@@ -6,7 +6,7 @@ import type { BillSchemaType } from '@fastgpt/global/support/wallet/bill/type.d'
export const getBills = (
data: RequestPaging & {
type?: `${BillTypeEnum}`;
type?: BillTypeEnum;
}
) => POST<BillSchemaType[]>(`/proApi/support/wallet/bill/list`, data);