Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
eb28bfb2
authored
Aug 04, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: ts
parent
ffd4e194
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
188 additions
and
63 deletions
+188
-63
client/Dockerfile
+7
-3
client/src/constants/flow/ModuleTemplate.ts
+0
-0
client/src/pages/api/admin/initv4.ts
+18
-0
client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx
+65
-32
client/src/pages/app/detail/components/AdEdit/components/modules/ExtractFieldModal.tsx
+4
-11
client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx
+7
-5
client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx
+25
-6
client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx
+1
-1
client/src/pages/chat/components/SliderApps.tsx
+3
-1
client/src/utils/app.ts
+58
-4
No files found.
client/Dockerfile
View file @
eb28bfb2
...
...
@@ -7,15 +7,16 @@ WORKDIR /app
# Install dependencies based on the preferred package manager
COPY
package.json ./
COPY
pnpm-lock.yaml* ./
RUN
pnpm config
set
registry https://registry.npmmirror.com/
RUN
\
[
-f
pnpm-lock.yaml
]
&&
pnpm
install
||
\
[
-f
pnpm-lock.yaml
]
&&
pnpm
fetch
||
\
(
echo
"Lockfile not found."
&&
exit
1
)
# Rebuild the source code only when needed
FROM
node:current-alpine AS builder
WORKDIR
/app
COPY
--from=deps /app/node_modules ./node_modules
COPY
pnpm-lock.yaml* ./
COPY
package.json ./
COPY
. .
# Next.js collects completely anonymous telemetry data about general usage.
...
...
@@ -23,7 +24,10 @@ COPY . .
# Uncomment the following line in case you want to disable telemetry during the build.
ENV
NEXT_TELEMETRY_DISABLED 1
RUN
npm install
-g
pnpm
&&
pnpm run build
RUN
npm install
-g
pnpm
RUN
\
[
-f
pnpm-lock.yaml
]
&&
(
pnpm
--offline
install
&&
pnpm run build
)
||
\
(
echo
"Lockfile not found."
&&
exit
1
)
# Production image, copy all the files and run next
FROM
node:current-alpine AS runner
...
...
client/src/constants/flow/ModuleTemplate.ts
View file @
eb28bfb2
This diff is collapsed.
Click to expand it.
client/src/pages/api/admin/initv4.ts
View file @
eb28bfb2
...
...
@@ -25,42 +25,60 @@ const chatModelInput = ({
{
key
:
'model'
,
value
:
model
,
type
:
'custom'
,
label
:
'对话模型'
,
connected
:
true
},
{
key
:
'temperature'
,
value
:
temperature
,
label
:
'温度'
,
type
:
'slider'
,
connected
:
true
},
{
key
:
'maxToken'
,
value
:
maxToken
,
type
:
'custom'
,
label
:
'回复上限'
,
connected
:
true
},
{
key
:
'systemPrompt'
,
value
:
systemPrompt
,
type
:
'textarea'
,
label
:
'系统提示词'
,
connected
:
true
},
{
key
:
'limitPrompt'
,
label
:
'限定词'
,
type
:
'textarea'
,
value
:
limitPrompt
,
connected
:
true
},
{
key
:
'switch'
,
type
:
'target'
,
label
:
'触发器'
,
connected
:
kbList
.
length
>
0
},
{
key
:
'quoteQA'
,
type
:
'target'
,
label
:
'引用内容'
,
connected
:
kbList
.
length
>
0
},
{
key
:
'history'
,
type
:
'target'
,
label
:
'聊天记录'
,
connected
:
true
},
{
key
:
'userChatInput'
,
type
:
'target'
,
label
:
'用户问题'
,
connected
:
true
}
];
...
...
client/src/pages/app/detail/components/AdEdit/components/Nodes/NodeExtract.tsx
View file @
eb28bfb2
...
...
@@ -22,7 +22,7 @@ const NodeExtract = ({
const
[
editExtractFiled
,
setEditExtractField
]
=
useState
<
ContextExtractAgentItemType
>
();
return
(
<
NodeCard
minW=
{
'
38
0px'
}
moduleId=
{
moduleId
}
{
...
props
}
>
<
NodeCard
minW=
{
'
40
0px'
}
moduleId=
{
moduleId
}
{
...
props
}
>
<
Divider
text=
"Input"
/>
<
Container
>
<
RenderInput
...
...
@@ -64,11 +64,14 @@ const NodeExtract = ({
</
Thead
>
<
Tbody
>
{
extractKeys
.
map
((
item
,
index
)
=>
(
<
Tr
key=
{
index
}
position=
{
'relative'
}
>
<
Tr
key=
{
index
}
position=
{
'relative'
}
whiteSpace=
{
'pre-wrap'
}
wordBreak=
{
'break-all'
}
>
<
Td
>
{
item
.
key
}
</
Td
>
<
Td
whiteSpace=
{
'pre-wrap'
}
wordBreak=
{
'break-all'
}
>
{
item
.
desc
}
</
Td
>
<
Td
>
{
item
.
desc
}
</
Td
>
<
Td
>
{
item
.
required
?
'✔'
:
''
}
</
Td
>
<
Td
whiteSpace=
{
'nowrap'
}
>
<
MyIcon
...
...
@@ -139,24 +142,6 @@ const NodeExtract = ({
const
newInputs
=
exists
?
extracts
.
map
((
item
)
=>
(
item
.
key
===
editExtractFiled
.
key
?
data
:
item
))
:
extracts
.
concat
(
data
);
const
newOutputs
=
exists
?
outputs
.
map
((
output
)
=>
output
.
key
===
editExtractFiled
.
key
?
{
...
output
,
key
:
data
.
key
,
label
:
`提取结果-${data.desc}`
}
:
output
)
:
outputs
.
concat
({
key
:
data
.
key
,
label
:
`提取结果-${data.desc}`
,
description
:
'无法提取时不会返回'
,
valueType
:
FlowValueTypeEnum
.
string
,
type
:
FlowOutputItemTypeEnum
.
source
,
targets
:
[]
});
onChangeNode
({
moduleId
,
...
...
@@ -167,15 +152,63 @@ const NodeExtract = ({
value
:
newInputs
}
});
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
newOutputs
});
if
(
editExtractFiled
.
key
&&
editExtractFiled
.
key
!==
data
.
key
)
{
onDelEdge
({
moduleId
,
sourceHandle
:
editExtractFiled
.
key
});
if
(
!
exists
)
{
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
outputs
.
concat
({
key
:
data
.
key
,
label
:
`提取结果-${data.desc}`
,
description
:
'无法提取时不会返回'
,
valueType
:
FlowValueTypeEnum
.
string
,
type
:
FlowOutputItemTypeEnum
.
source
,
targets
:
[]
})
});
}
else
{
if
(
editExtractFiled
.
key
===
data
.
key
)
{
// update
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
outputs
.
map
((
output
)
=>
output
.
key
===
data
.
key
?
{
...
output
,
label
:
`提取结果-${data.desc}`
}
:
output
)
});
}
else
{
// del and push
const
newOutputs
=
outputs
.
filter
((
output
)
=>
output
.
key
!==
editExtractFiled
.
key
);
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
newOutputs
});
setTimeout
(()
=>
{
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
newOutputs
.
concat
({
key
:
data
.
key
,
label
:
`提取结果-${data.desc}`
,
description
:
'无法提取时不会返回'
,
valueType
:
FlowValueTypeEnum
.
string
,
type
:
FlowOutputItemTypeEnum
.
source
,
targets
:
[]
})
});
},
10
);
}
}
setEditExtractField
(
undefined
);
...
...
@@ -186,4 +219,4 @@ const NodeExtract = ({
);
};
export
default
NodeExtract
;
export
default
React
.
memo
(
NodeExtract
)
;
client/src/pages/app/detail/components/AdEdit/components/modules/ExtractFieldModal.tsx
View file @
eb28bfb2
...
...
@@ -34,7 +34,6 @@ const ExtractFieldModal = ({
const
{
register
,
handleSubmit
}
=
useForm
<
ContextExtractAgentItemType
>
({
defaultValues
:
defaultField
});
const
isEdit
=
useMemo
(()
=>
!!
defaultField
.
key
,
[
defaultField
]);
return
(
<
MyModal
isOpen=
{
true
}
onClose=
{
onClose
}
>
...
...
@@ -56,17 +55,11 @@ const ExtractFieldModal = ({
</
Flex
>
<
Flex
mt=
{
5
}
alignItems=
{
'center'
}
>
<
Box
flex=
{
'0 0 70px'
}
>
字段 key
</
Box
>
<
MyTooltip
label=
{
isEdit
?
'不支持修改 key'
:
''
}
shouldWrapChildren=
{
false
}
>
<
Input
isDisabled=
{
isEdit
}
placeholder=
"name/age/sql"
{
...
register
('
key
',
{
required
:
'字段
key
不能为空'
})}
/>
</
MyTooltip
>
<
Input
placeholder=
"name/age/sql"
{
...
register
('
key
',
{
required
:
'字段
key
不能为空'
})}
/>
</
Flex
>
<
Box
mt=
{
1
}
pl=
{
'70px'
}
color=
{
'myGray.600'
}
fontSize=
{
'sm'
}
>
注意: key 字段创建后无法修改
</
Box
>
</
ModalBody
>
<
ModalFooter
>
...
...
client/src/pages/app/detail/components/AdEdit/components/render/RenderInput.tsx
View file @
eb28bfb2
...
...
@@ -114,11 +114,13 @@ export const Label = ({
key
:
data
.
key
,
value
:
data
});
onChangeNode
({
moduleId
,
type
:
'delInput'
,
key
:
editField
.
key
,
value
:
''
setTimeout
(()
=>
{
onChangeNode
({
moduleId
,
type
:
'delInput'
,
key
:
editField
.
key
,
value
:
''
});
});
}
setEditField
(
undefined
);
...
...
client/src/pages/app/detail/components/AdEdit/components/render/RenderOutput.tsx
View file @
eb28bfb2
...
...
@@ -77,12 +77,31 @@ const Label = ({
defaultField=
{
editField
}
onClose=
{
()
=>
setEditField
(
undefined
)
}
onSubmit=
{
(
data
)
=>
{
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
outputs
.
map
((
output
)
=>
(
output
.
key
===
outputKey
?
data
:
output
))
});
if
(
editField
.
key
===
data
.
key
)
{
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
outputs
.
map
((
output
)
=>
(
output
.
key
===
outputKey
?
data
:
output
))
});
}
else
{
const
storeOutputs
=
outputs
.
filter
((
output
)
=>
output
.
key
!==
editField
.
key
);
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
storeOutputs
});
setTimeout
(()
=>
{
onChangeNode
({
moduleId
,
type
:
'outputs'
,
key
:
''
,
value
:
storeOutputs
.
concat
(
data
)
});
},
10
);
}
setEditField
(
undefined
);
}
}
...
...
client/src/pages/app/detail/components/AdEdit/components/render/SourceHandle.tsx
View file @
eb28bfb2
...
...
@@ -42,4 +42,4 @@ const SourceHandle = ({ handleKey, valueType, ...props }: Props) => {
);
};
export
default
SourceHandle
;
export
default
React
.
memo
(
SourceHandle
)
;
client/src/pages/chat/components/SliderApps.tsx
View file @
eb28bfb2
...
...
@@ -3,10 +3,12 @@ import { Flex, Box, IconButton } from '@chakra-ui/react';
import
{
useRouter
}
from
'next/router'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
MyIcon
from
'@/components/Icon'
;
import
Avatar
from
'@/components/Avatar'
;
const
SliderApps
=
({
appId
}:
{
appId
:
string
})
=>
{
const
{
t
}
=
useTranslation
();
const
router
=
useRouter
();
const
{
myApps
,
loadMyApps
}
=
useUserStore
();
...
...
@@ -33,7 +35,7 @@ const SliderApps = ({ appId }: { appId: string }) => {
borderRadius=
{
'50%'
}
aria
-
label=
{
''
}
/>
退出聊天
{
t
(
'chat.Exit Chat'
)
}
</
Flex
>
<
Box
mt=
{
5
}
>
{
myApps
.
map
((
item
)
=>
(
...
...
client/src/utils/app.ts
View file @
eb28bfb2
import
type
{
AppModuleItemType
,
VariableItemType
}
from
'@/types/app'
;
import
{
chatModelList
,
vectorModelList
}
from
'@/store/static'
;
import
{
FlowModuleTypeEnum
,
SpecialInputKeyEnum
}
from
'@/constants/flow'
;
import
{
FlowInputItemTypeEnum
,
FlowModuleTypeEnum
,
FlowValueTypeEnum
,
SpecialInputKeyEnum
}
from
'@/constants/flow'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
TaskResponseKeyEnum
}
from
'@/constants/chat'
;
import
type
{
SelectedKbType
}
from
'@/types/plugin'
;
...
...
@@ -153,42 +158,60 @@ const chatModelInput = (formData: EditFormType): FlowInputItemType[] => [
{
key
:
'model'
,
value
:
formData
.
chatModel
.
model
,
type
:
'custom'
,
label
:
'对话模型'
,
connected
:
true
},
{
key
:
'temperature'
,
value
:
formData
.
chatModel
.
temperature
,
type
:
'slider'
,
label
:
'温度'
,
connected
:
true
},
{
key
:
'maxToken'
,
value
:
formData
.
chatModel
.
maxToken
,
type
:
'custom'
,
label
:
'回复上限'
,
connected
:
true
},
{
key
:
'systemPrompt'
,
value
:
formData
.
chatModel
.
systemPrompt
,
type
:
'textarea'
,
label
:
'系统提示词'
,
connected
:
true
},
{
key
:
'limitPrompt'
,
type
:
'textarea'
,
value
:
formData
.
chatModel
.
limitPrompt
,
label
:
'限定词'
,
connected
:
true
},
{
key
:
'switch'
,
type
:
'target'
,
label
:
'触发器'
,
connected
:
formData
.
kb
.
list
.
length
>
0
},
{
key
:
'quoteQA'
,
type
:
'target'
,
label
:
'引用内容'
,
connected
:
formData
.
kb
.
list
.
length
>
0
},
{
key
:
'history'
,
type
:
'target'
,
label
:
'聊天记录'
,
connected
:
true
},
{
key
:
'userChatInput'
,
type
:
'target'
,
label
:
'用户问题'
,
connected
:
true
}
];
...
...
@@ -200,6 +223,8 @@ const welcomeTemplate = (formData: EditFormType): AppModuleItemType[] =>
inputs
:
[
{
key
:
'welcomeText'
,
type
:
'input'
,
label
:
'开场白'
,
value
:
formData
.
guide
.
welcome
.
text
,
connected
:
true
}
...
...
@@ -222,6 +247,8 @@ const variableTemplate = (formData: EditFormType): AppModuleItemType[] =>
{
key
:
'variables'
,
value
:
formData
.
variables
,
type
:
'systemInput'
,
label
:
'变量输入'
,
connected
:
true
}
],
...
...
@@ -240,7 +267,9 @@ const simpleChatTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs
:
[
{
key
:
'userChatInput'
,
connected
:
true
connected
:
true
,
label
:
'用户问题'
,
type
:
'target'
}
],
outputs
:
[
...
...
@@ -266,10 +295,14 @@ const simpleChatTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key
:
'maxContext'
,
value
:
6
,
connected
:
true
connected
:
true
,
type
:
'numberInput'
,
label
:
'最长记录数'
},
{
key
:
'history'
,
type
:
'hidden'
,
label
:
'聊天记录'
,
connected
:
true
}
],
...
...
@@ -312,6 +345,8 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs
:
[
{
key
:
'userChatInput'
,
label
:
'用户问题'
,
type
:
'target'
,
connected
:
true
}
],
...
...
@@ -342,10 +377,14 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key
:
'maxContext'
,
value
:
6
,
connected
:
true
connected
:
true
,
type
:
'numberInput'
,
label
:
'最长记录数'
},
{
key
:
'history'
,
type
:
'hidden'
,
label
:
'聊天记录'
,
connected
:
true
}
],
...
...
@@ -372,24 +411,34 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
{
key
:
'kbList'
,
value
:
formData
.
kb
.
list
,
type
:
FlowInputItemTypeEnum
.
custom
,
label
:
'关联的知识库'
,
connected
:
true
},
{
key
:
'similarity'
,
value
:
formData
.
kb
.
searchSimilarity
,
type
:
FlowInputItemTypeEnum
.
slider
,
label
:
'相似度'
,
connected
:
true
},
{
key
:
'limit'
,
value
:
formData
.
kb
.
searchLimit
,
type
:
FlowInputItemTypeEnum
.
slider
,
label
:
'单次搜索上限'
,
connected
:
true
},
{
key
:
'switch'
,
type
:
FlowInputItemTypeEnum
.
target
,
label
:
'触发器'
,
connected
:
false
},
{
key
:
'userChatInput'
,
type
:
FlowInputItemTypeEnum
.
target
,
label
:
'用户问题'
,
connected
:
true
}
],
...
...
@@ -442,11 +491,16 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
inputs
:
[
{
key
:
'switch'
,
type
:
FlowInputItemTypeEnum
.
target
,
label
:
'触发器'
,
connected
:
true
},
{
key
:
SpecialInputKeyEnum
.
answerText
,
value
:
formData
.
kb
.
searchEmptyText
,
type
:
FlowInputItemTypeEnum
.
textarea
,
valueType
:
FlowValueTypeEnum
.
string
,
label
:
'回复的内容'
,
connected
:
true
}
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment