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
f9d83c48
authored
Jul 18, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
guide node
parent
d346d386
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
312 additions
and
278 deletions
+312
-278
client/public/imgs/module/db.png:Zone.Identifier
+0
-3
client/public/imgs/module/variable.png
+0
-0
client/src/api/response/chat.d.ts
+2
-1
client/src/components/ChatBox/index.tsx
+96
-69
client/src/constants/app.ts
+3
-5
client/src/constants/flow/ModuleTemplate.ts
+25
-17
client/src/constants/flow/index.ts
+1
-0
client/src/pages/api/chat/init.ts
+9
-14
client/src/pages/api/chat/shareChat/init.ts
+2
-6
client/src/pages/app/detail/components/Settings.tsx
+1
-1
client/src/pages/app/detail/components/edit/components/ChatTest.tsx
+6
-22
client/src/pages/app/detail/components/edit/components/Nodes/NodeAnswer.tsx
+4
-4
client/src/pages/app/detail/components/edit/components/Nodes/NodeCQNode.tsx
+6
-6
client/src/pages/app/detail/components/edit/components/Nodes/NodeChat.tsx
+5
-5
client/src/pages/app/detail/components/edit/components/Nodes/NodeHistory.tsx
+5
-5
client/src/pages/app/detail/components/edit/components/Nodes/NodeKbSearch.tsx
+6
-6
client/src/pages/app/detail/components/edit/components/Nodes/NodeQuestionInput.tsx
+2
-2
client/src/pages/app/detail/components/edit/components/Nodes/NodeTFSwitch.tsx
+5
-5
client/src/pages/app/detail/components/edit/components/Nodes/NodeUserGuide.tsx
+59
-0
client/src/pages/app/detail/components/edit/components/Nodes/NodeVariable.tsx
+57
-91
client/src/pages/app/detail/components/edit/components/TemplateList.tsx
+1
-1
client/src/pages/app/detail/components/edit/components/modules/NodeCard.tsx
+1
-1
client/src/pages/app/detail/components/edit/index.tsx
+13
-9
client/src/pages/chat/components/ChatHistorySlider.tsx
+2
-2
client/src/pages/chat/index.tsx
+1
-3
No files found.
client/public/imgs/module/db.png:Zone.Identifier
deleted
100644 → 0
View file @
d346d386
[ZoneTransfer]
ZoneId=3
HostUrl=about:internet
client/public/imgs/module/variable.png
0 → 100644
View file @
f9d83c48
1.61 KB
client/src/api/response/chat.d.ts
View file @
f9d83c48
...
@@ -3,7 +3,7 @@ import type { ChatItemType } from '@/types/chat';
...
@@ -3,7 +3,7 @@ import type { ChatItemType } from '@/types/chat';
import
{
VariableItemType
}
from
'@/types/app'
;
import
{
VariableItemType
}
from
'@/types/app'
;
export
interface
InitChatResponse
{
export
interface
InitChatResponse
{
history
Id
:
string
;
chat
Id
:
string
;
appId
:
string
;
appId
:
string
;
app
:
{
app
:
{
variableModules
?:
VariableItemType
[];
variableModules
?:
VariableItemType
[];
...
@@ -13,6 +13,7 @@ export interface InitChatResponse {
...
@@ -13,6 +13,7 @@ export interface InitChatResponse {
intro
:
string
;
intro
:
string
;
canUse
:
boolean
;
canUse
:
boolean
;
};
};
customTitle
?:
string
;
title
:
string
;
title
:
string
;
variables
:
Record
<
string
,
any
>
;
variables
:
Record
<
string
,
any
>
;
history
:
ChatItemType
[];
history
:
ChatItemType
[];
...
...
client/src/components/ChatBox/index.tsx
View file @
f9d83c48
...
@@ -22,8 +22,8 @@ import Avatar from '@/components/Avatar';
...
@@ -22,8 +22,8 @@ import Avatar from '@/components/Avatar';
import
{
adaptChatItem_openAI
}
from
'@/utils/plugin/openai'
;
import
{
adaptChatItem_openAI
}
from
'@/utils/plugin/openai'
;
import
{
useMarkdown
}
from
'@/hooks/useMarkdown'
;
import
{
useMarkdown
}
from
'@/hooks/useMarkdown'
;
import
{
VariableItemType
}
from
'@/types/app'
;
import
{
AppModuleItemType
,
VariableItemType
}
from
'@/types/app'
;
import
{
VariableInputEnum
}
from
'@/constants/app'
;
import
{
SystemInputEnum
,
VariableInputEnum
}
from
'@/constants/app'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useForm
}
from
'react-hook-form'
;
import
MySelect
from
'@/components/Select'
;
import
MySelect
from
'@/components/Select'
;
import
{
MessageItemType
}
from
'@/pages/api/openapi/v1/chat/completions'
;
import
{
MessageItemType
}
from
'@/pages/api/openapi/v1/chat/completions'
;
...
@@ -36,6 +36,7 @@ const QuoteModal = dynamic(() => import('./QuoteModal'));
...
@@ -36,6 +36,7 @@ const QuoteModal = dynamic(() => import('./QuoteModal'));
import
styles
from
'./index.module.scss'
;
import
styles
from
'./index.module.scss'
;
import
{
QuoteItemType
}
from
'@/pages/api/app/modules/kb/search'
;
import
{
QuoteItemType
}
from
'@/pages/api/app/modules/kb/search'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
const
textareaMinH
=
'22px'
;
const
textareaMinH
=
'22px'
;
export
type
StartChatFnProps
=
{
export
type
StartChatFnProps
=
{
...
@@ -94,6 +95,18 @@ const Empty = () => {
...
@@ -94,6 +95,18 @@ const Empty = () => {
);
);
};
};
const
ChatAvatar
=
({
src
,
order
,
ml
,
mr
}:
{
src
:
string
;
order
:
number
;
ml
?:
(
string
|
number
)
|
(
string
|
number
)[];
mr
?:
(
string
|
number
)
|
(
string
|
number
)[];
})
=>
<
Avatar
src=
{
src
}
w=
{
[
'24px'
,
'34px'
]
}
h=
{
[
'24px'
,
'34px'
]
}
order=
{
order
}
ml=
{
ml
}
mr=
{
mr
}
/>;
const
ChatBox
=
(
const
ChatBox
=
(
{
{
showEmptyIntro
=
false
,
showEmptyIntro
=
false
,
...
@@ -375,80 +388,79 @@ const ChatBox = (
...
@@ -375,80 +388,79 @@ const ChatBox = (
w
:
'100%'
w
:
'100%'
};
};
const
hasVariableInput
=
useMemo
(
const
showEmpty
=
useMemo
(
()
=>
variableModules
||
welcomeText
,
()
=>
showEmptyIntro
&&
chatHistory
.
length
===
0
&&
!
(
variableModules
||
welcomeText
)
,
[
variableModules
,
welcomeText
]
[
chatHistory
.
length
,
showEmptyIntro
,
variableModules
,
welcomeText
]
);
);
return
(
return
(
<
Flex
flexDirection=
{
'column'
}
h=
{
'100%'
}
>
<
Flex
flexDirection=
{
'column'
}
h=
{
'100%'
}
>
<
Box
ref=
{
ChatBoxRef
}
flex=
{
'1 0 0'
}
h=
{
0
}
overflow=
{
'overlay'
}
px=
{
[
2
,
5
,
8
]
}
py=
{
[
0
,
5
]
}
>
<
Box
ref=
{
ChatBoxRef
}
flex=
{
'1 0 0'
}
h=
{
0
}
overflow=
{
'overlay'
}
px=
{
[
2
,
5
,
7
]
}
py=
{
[
0
,
5
]
}
>
<
Box
maxW=
{
[
'100%'
,
'1000px'
,
'1200px'
]
}
h=
{
'100%'
}
mx=
{
'auto'
}
>
<
Box
maxW=
{
[
'100%'
,
'1000px'
,
'1200px'
]
}
h=
{
'100%'
}
mx=
{
'auto'
}
>
{
!!
welcomeText
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
<
ChatAvatar
src=
{
appAvatar
}
order=
{
1
}
mr=
{
[
'6px'
,
2
]
}
/>
{
/* message */
}
<
Flex
order=
{
2
}
pt=
{
2
}
maxW=
{
`calc(100% - ${isLargeWidth ? '75px' : '58px'})`
}
>
<
Card
bg=
{
'white'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'0 8px 8px 8px'
}
>
{
welcomeText
}
</
Card
>
</
Flex
>
</
Flex
>
)
}
{
/* variable input */
}
{
/* variable input */
}
{
hasVariableInput
&&
(
{
variableModules
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
{
/* avatar */
}
<
Avatar
<
ChatAvatar
src=
{
appAvatar
}
order=
{
1
}
mr=
{
[
'6px'
,
2
]
}
/>
src=
{
appAvatar
}
w=
{
[
'24px'
,
'34px'
]
}
h=
{
[
'24px'
,
'34px'
]
}
order=
{
1
}
mr=
{
[
'6px'
,
2
]
}
/>
{
/* message */
}
{
/* message */
}
<
Flex
order=
{
2
}
pt=
{
2
}
maxW=
{
`calc(100% - ${isLargeWidth ? '75px' : '58px'})`
}
>
<
Flex
order=
{
2
}
pt=
{
2
}
maxW=
{
`calc(100% - ${isLargeWidth ? '75px' : '58px'})`
}
>
<
Card
bg=
{
'white'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'0 8px 8px 8px'
}
>
<
Card
bg=
{
'white'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'0 8px 8px 8px'
}
>
{
welcomeText
&&
(
<
Box
>
<
Box
mb=
{
2
}
pb=
{
2
}
borderBottom=
{
theme
.
borders
.
base
}
>
{
variableModules
.
map
((
item
)
=>
(
{
welcomeText
}
<
Box
w=
{
'min(100%,300px)'
}
key=
{
item
.
id
}
mb=
{
4
}
>
</
Box
>
<
VariableLabel
required=
{
item
.
required
}
>
{
item
.
label
}
</
VariableLabel
>
)
}
{
item
.
type
===
VariableInputEnum
.
input
&&
(
{
variableModules
&&
(
<
Input
<
Box
>
isDisabled=
{
variableIsFinish
}
{
variableModules
.
map
((
item
)
=>
(
{
...
register
(
item
.
key
,
{
<
Box
w=
{
'min(100%,300px)'
}
key=
{
item
.
id
}
mb=
{
4
}
>
required
:
item
.
required
<
VariableLabel
required=
{
item
.
required
}
>
{
item
.
label
}
</
VariableLabel
>
})}
{
item
.
type
===
VariableInputEnum
.
input
&&
(
/>
<
Input
)
}
isDisabled=
{
variableIsFinish
}
{
item
.
type
===
VariableInputEnum
.
select
&&
(
{
...
register
(
item
.
key
,
{
<
MySelect
required
:
item
.
required
width=
{
'100%'
}
})}
isDisabled=
{
variableIsFinish
}
/>
list=
{
(
item
.
enums
||
[]).
map
((
item
)
=>
({
)
}
label
:
item
.
value
,
{
item
.
type
===
VariableInputEnum
.
select
&&
(
value
:
item
.
value
<
MySelect
}))
}
width=
{
'100%'
}
value=
{
getValues
(
item
.
key
)
}
isDisabled=
{
variableIsFinish
}
onchange=
{
(
e
)
=>
{
list=
{
(
item
.
enums
||
[]).
map
((
item
)
=>
({
setValue
(
item
.
key
,
e
);
label
:
item
.
value
,
setRefresh
(
!
refresh
);
value
:
item
.
value
}
}
}))
}
/>
value=
{
getValues
(
item
.
key
)
}
)
}
onchange=
{
(
e
)
=>
{
</
Box
>
setValue
(
item
.
key
,
e
);
))
}
setRefresh
(
!
refresh
);
{
!
variableIsFinish
&&
(
}
}
<
Button
/>
leftIcon=
{
<
MyIcon
name=
{
'chatFill'
}
w=
{
'16px'
}
/>
}
)
}
size=
{
'sm'
}
</
Box
>
maxW=
{
'100px'
}
))
}
borderRadius=
{
'lg'
}
{
!
variableIsFinish
&&
(
onClick=
{
handleSubmit
((
data
)
=>
{
<
Button
onUpdateVariable
?.(
data
);
leftIcon=
{
<
MyIcon
name=
{
'chatFill'
}
w=
{
'16px'
}
/>
}
setVariables
(
data
);
size=
{
'sm'
}
})
}
maxW=
{
'100px'
}
>
borderRadius=
{
'lg'
}
{
'开始对话'
}
onClick=
{
handleSubmit
((
data
)
=>
{
</
Button
>
onUpdateVariable
?.(
data
);
)
}
setVariables
(
data
);
</
Box
>
})
}
>
{
'开始对话'
}
</
Button
>
)
}
</
Box
>
)
}
</
Card
>
</
Card
>
</
Flex
>
</
Flex
>
</
Flex
>
</
Flex
>
...
@@ -469,10 +481,8 @@ const ChatBox = (
...
@@ -469,10 +481,8 @@ const ChatBox = (
>
>
{
item
.
obj
===
'Human'
&&
<
Box
flex=
{
1
}
/>
}
{
item
.
obj
===
'Human'
&&
<
Box
flex=
{
1
}
/>
}
{
/* avatar */
}
{
/* avatar */
}
<
Avatar
<
Chat
Avatar
src=
{
item
.
obj
===
'Human'
?
userInfo
?.
avatar
||
HUMAN_ICON
:
appAvatar
}
src=
{
item
.
obj
===
'Human'
?
userInfo
?.
avatar
||
HUMAN_ICON
:
appAvatar
}
w=
{
[
'24px'
,
'34px'
]
}
h=
{
[
'24px'
,
'34px'
]
}
{
...
(
item
.
obj
===
'
AI
'
{
...
(
item
.
obj
===
'
AI
'
?
{
?
{
order
:
1,
order
:
1,
...
@@ -597,7 +607,7 @@ const ChatBox = (
...
@@ -597,7 +607,7 @@ const ChatBox = (
))
}
))
}
</
Box
>
</
Box
>
{
showEmpty
Intro
&&
chatHistory
.
length
===
0
&&
!
hasVariableInput
&&
<
Empty
/>
}
{
showEmpty
&&
<
Empty
/>
}
</
Box
>
</
Box
>
</
Box
>
</
Box
>
{
/* input */
}
{
/* input */
}
...
@@ -770,3 +780,20 @@ export const useChatBox = () => {
...
@@ -770,3 +780,20 @@ export const useChatBox = () => {
onExportChat
onExportChat
}
;
}
;
};
};
export const getSpecialModule = (modules: AppModuleItemType[]) =
>
{
const
welcomeText
:
string
=
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
welcomeText
)?.
value
||
''
;
const
variableModules
:
VariableItemType
[]
=
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
variable
)
?.
inputs
.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
variables
)?.
value
||
[];
return
{
welcomeText
,
variableModules
};
}
;
client/src/constants/app.ts
View file @
f9d83c48
import
type
{
AppItemType
}
from
'@/types/app'
;
import
{
rawSearchKey
}
from
'./chat'
;
/* app */
/* app */
export
enum
AppModuleItemTypeEnum
{
export
enum
AppModuleItemTypeEnum
{
'userGuide'
=
'userGuide'
,
// default chat input: userChatInput, history
'variable'
=
'variable'
,
'initInput'
=
'initInput'
,
// default chat input: userChatInput, history
'userGuide'
=
'userGuide'
,
'initInput'
=
'initInput'
,
'http'
=
'http'
,
// send a http request
'http'
=
'http'
,
// send a http request
'switch'
=
'switch'
,
// one input and two outputs
'switch'
=
'switch'
,
// one input and two outputs
'answer'
=
'answer'
// redirect response
'answer'
=
'answer'
// redirect response
...
...
client/src/constants/flow/ModuleTemplate.ts
View file @
f9d83c48
...
@@ -9,10 +9,28 @@ import {
...
@@ -9,10 +9,28 @@ import {
}
from
'./inputTemplate'
;
}
from
'./inputTemplate'
;
import
{
rawSearchKey
}
from
'../chat'
;
import
{
rawSearchKey
}
from
'../chat'
;
export
const
VariableInputModule
:
AppModuleTemplateItemType
=
{
export
const
VariableModule
:
AppModuleTemplateItemType
=
{
logo
:
'/imgs/module/variable.png'
,
name
:
'全局变量'
,
intro
:
'可以在对话开始前,要求用户填写一些内容作为本轮对话的变量。该模块位于开场引导之后。'
,
description
:
'全局变量可以通过 {{变量key}} 的形式注入到其他模块的文本中。目前支持:提示词、限定词。'
,
type
:
AppModuleItemTypeEnum
.
variable
,
flowType
:
FlowModuleTypeEnum
.
variable
,
inputs
:
[
{
key
:
SystemInputEnum
.
variables
,
type
:
FlowInputItemTypeEnum
.
systemInput
,
label
:
'变量输入'
,
value
:
[]
}
],
outputs
:
[]
};
export
const
UserGuideModule
:
AppModuleTemplateItemType
=
{
logo
:
'/imgs/module/userGuide.png'
,
logo
:
'/imgs/module/userGuide.png'
,
name
:
'
开场
引导'
,
name
:
'
用户
引导'
,
intro
:
'可以
在每个新对话开始前,给用户发送一段开场白,或要求用户填写一些内容作为本轮对话的变量。
'
,
intro
:
'可以
添加特殊的对话前后引导模块,更好的让用户进行对话
'
,
type
:
AppModuleItemTypeEnum
.
userGuide
,
type
:
AppModuleItemTypeEnum
.
userGuide
,
flowType
:
FlowModuleTypeEnum
.
userGuide
,
flowType
:
FlowModuleTypeEnum
.
userGuide
,
inputs
:
[
inputs
:
[
...
@@ -20,12 +38,6 @@ export const VariableInputModule: AppModuleTemplateItemType = {
...
@@ -20,12 +38,6 @@ export const VariableInputModule: AppModuleTemplateItemType = {
key
:
SystemInputEnum
.
welcomeText
,
key
:
SystemInputEnum
.
welcomeText
,
type
:
FlowInputItemTypeEnum
.
input
,
type
:
FlowInputItemTypeEnum
.
input
,
label
:
'开场白'
label
:
'开场白'
},
{
key
:
SystemInputEnum
.
variables
,
type
:
FlowInputItemTypeEnum
.
systemInput
,
label
:
'变量输入'
,
value
:
[]
}
}
],
],
outputs
:
[]
outputs
:
[]
...
@@ -350,21 +362,17 @@ export const ClassifyQuestionModule: AppModuleTemplateItemType = {
...
@@ -350,21 +362,17 @@ export const ClassifyQuestionModule: AppModuleTemplateItemType = {
export const ModuleTemplates = [
export const ModuleTemplates = [
{
{
label: '输入模块',
label: '输入模块',
list: [UserInputModule, HistoryModule, Variable
Input
Module]
list: [UserInputModule, HistoryModule, Variable
Module, UserGuide
Module]
},
},
{
{
label: '
对话模块
',
label: '
内容生成
',
list: [ChatModule]
list: [ChatModule
, AnswerModule
]
},
},
{
{
label: '知识库模块',
label: '知识库模块',
list: [KBSearchModule]
list: [KBSearchModule]
},
},
{
{
label: '工具',
list: [AnswerModule]
},
{
label: 'Agent',
label: 'Agent',
list: [ClassifyQuestionModule]
list: [ClassifyQuestionModule]
}
}
...
@@ -1105,7 +1113,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
...
@@ -1105,7 +1113,7 @@ export const appTemplates: (AppItemType & { avatar: string; intro: string })[] =
moduleId: 'xj0c9p'
moduleId: 'xj0c9p'
},
},
{
{
...Variable
Input
Module,
...VariableModule,
inputs: [
inputs: [
{
{
key: 'welcomeText',
key: 'welcomeText',
...
...
client/src/constants/flow/index.ts
View file @
f9d83c48
...
@@ -19,6 +19,7 @@ export enum FlowOutputItemTypeEnum {
...
@@ -19,6 +19,7 @@ export enum FlowOutputItemTypeEnum {
}
}
export
enum
FlowModuleTypeEnum
{
export
enum
FlowModuleTypeEnum
{
variable
=
'variable'
,
userGuide
=
'userGuide'
,
userGuide
=
'userGuide'
,
questionInputNode
=
'questionInput'
,
questionInputNode
=
'questionInput'
,
historyNode
=
'historyNode'
,
historyNode
=
'historyNode'
,
...
...
client/src/pages/api/chat/init.ts
View file @
f9d83c48
...
@@ -7,18 +7,17 @@ import { ChatItemType } from '@/types/chat';
...
@@ -7,18 +7,17 @@ import { ChatItemType } from '@/types/chat';
import
{
authApp
}
from
'@/service/utils/auth'
;
import
{
authApp
}
from
'@/service/utils/auth'
;
import
mongoose
from
'mongoose'
;
import
mongoose
from
'mongoose'
;
import
type
{
AppSchema
,
ChatSchema
}
from
'@/types/mongoSchema'
;
import
type
{
AppSchema
,
ChatSchema
}
from
'@/types/mongoSchema'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
quoteLenKey
,
rawSearchKey
}
from
'@/constants/chat'
;
import
{
quoteLenKey
,
rawSearchKey
}
from
'@/constants/chat'
;
import
{
getSpecialModule
}
from
'@/components/ChatBox'
;
/* 初始化我的聊天框,需要身份验证 */
/* 初始化我的聊天框,需要身份验证 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
try
{
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
let
{
appId
,
history
Id
}
=
req
.
query
as
{
let
{
appId
,
chat
Id
}
=
req
.
query
as
{
appId
:
''
|
string
;
appId
:
''
|
string
;
history
Id
:
''
|
string
;
chat
Id
:
''
|
string
;
};
};
await
connectToDatabase
();
await
connectToDatabase
();
...
@@ -53,10 +52,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -53,10 +52,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
// 历史记录
// 历史记录
const
{
chat
,
history
=
[]
}:
{
chat
?:
ChatSchema
;
history
?:
ChatItemType
[]
}
=
const
{
chat
,
history
=
[]
}:
{
chat
?:
ChatSchema
;
history
?:
ChatItemType
[]
}
=
await
(
async
()
=>
{
await
(
async
()
=>
{
if
(
history
Id
)
{
if
(
chat
Id
)
{
// auth historyId
// auth historyId
const
chat
=
await
Chat
.
findOne
({
const
chat
=
await
Chat
.
findOne
({
_id
:
history
Id
,
_id
:
chat
Id
,
userId
userId
});
});
if
(
!
chat
)
{
if
(
!
chat
)
{
...
@@ -66,7 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -66,7 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
history
=
await
Chat
.
aggregate
([
const
history
=
await
Chat
.
aggregate
([
{
{
$match
:
{
$match
:
{
_id
:
new
mongoose
.
Types
.
ObjectId
(
history
Id
),
_id
:
new
mongoose
.
Types
.
ObjectId
(
chat
Id
),
userId
:
new
mongoose
.
Types
.
ObjectId
(
userId
)
userId
:
new
mongoose
.
Types
.
ObjectId
(
userId
)
}
}
},
},
...
@@ -96,20 +95,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -96,20 +95,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
jsonRes
<
InitChatResponse
>
(
res
,
{
jsonRes
<
InitChatResponse
>
(
res
,
{
data
:
{
data
:
{
history
Id
,
chat
Id
,
appId
,
appId
,
app
:
{
app
:
{
variableModules
:
app
.
modules
...
getSpecialModule
(
app
.
modules
),
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
variables
)?.
value
,
welcomeText
:
app
.
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
welcomeText
)?.
value
,
name
:
app
.
name
,
name
:
app
.
name
,
avatar
:
app
.
avatar
,
avatar
:
app
.
avatar
,
intro
:
app
.
intro
,
intro
:
app
.
intro
,
canUse
:
app
.
share
.
isShare
||
isOwner
canUse
:
app
.
share
.
isShare
||
isOwner
},
},
customTitle
:
chat
?.
customTitle
,
title
:
chat
?.
title
||
'新对话'
,
title
:
chat
?.
title
||
'新对话'
,
variables
:
chat
?.
variables
||
{},
variables
:
chat
?.
variables
||
{},
history
history
...
...
client/src/pages/api/chat/shareChat/init.ts
View file @
f9d83c48
...
@@ -7,6 +7,7 @@ import { hashPassword } from '@/service/utils/tools';
...
@@ -7,6 +7,7 @@ import { hashPassword } from '@/service/utils/tools';
import
{
HUMAN_ICON
}
from
'@/constants/chat'
;
import
{
HUMAN_ICON
}
from
'@/constants/chat'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
getSpecialModule
}
from
'@/components/ChatBox'
;
/* 初始化我的聊天框,需要身份验证 */
/* 初始化我的聊天框,需要身份验证 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
...
@@ -48,12 +49,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
...
@@ -48,12 +49,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
?.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
historyNode
)
?.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
historyNode
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
'maxContext'
)?.
value
||
0
,
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
'maxContext'
)?.
value
||
0
,
app
:
{
app
:
{
variableModules
:
app
.
modules
...
getSpecialModule
(
app
.
modules
),
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
variables
)?.
value
,
welcomeText
:
app
.
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
welcomeText
)?.
value
,
name
:
app
.
name
,
name
:
app
.
name
,
avatar
:
app
.
avatar
,
avatar
:
app
.
avatar
,
intro
:
app
.
intro
intro
:
app
.
intro
...
...
client/src/pages/app/detail/components/Settings.tsx
View file @
f9d83c48
...
@@ -28,7 +28,7 @@ const Settings = ({ appId }: { appId: string }) => {
...
@@ -28,7 +28,7 @@ const Settings = ({ appId }: { appId: string }) => {
content
:
'确认删除该应用?'
content
:
'确认删除该应用?'
});
});
const
[
settingAppInfo
,
setSettingAppInfo
]
=
useState
<
AppSchema
>
();
const
[
settingAppInfo
,
setSettingAppInfo
]
=
useState
<
AppSchema
>
();
const
[
fullScreen
,
setFullScreen
]
=
useState
(
fals
e
);
const
[
fullScreen
,
setFullScreen
]
=
useState
(
tru
e
);
/* 点击删除 */
/* 点击删除 */
const
handleDelModel
=
useCallback
(
async
()
=>
{
const
handleDelModel
=
useCallback
(
async
()
=>
{
...
...
client/src/pages/app/detail/components/edit/components/ChatTest.tsx
View file @
f9d83c48
...
@@ -11,12 +11,13 @@ import React, {
...
@@ -11,12 +11,13 @@ import React, {
import
{
Box
,
Flex
,
IconButton
,
useOutsideClick
}
from
'@chakra-ui/react'
;
import
{
Box
,
Flex
,
IconButton
,
useOutsideClick
}
from
'@chakra-ui/react'
;
import
MyIcon
from
'@/components/Icon'
;
import
MyIcon
from
'@/components/Icon'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
streamFetch
}
from
'@/api/fetch'
;
import
{
streamFetch
}
from
'@/api/fetch'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
import
ChatBox
,
{
type
ComponentRef
,
type
StartChatFnProps
}
from
'@/components/ChatBox'
;
import
ChatBox
,
{
import
{
useToast
}
from
'@/hooks/useToast'
;
getSpecialModule
,
import
{
getErrText
}
from
'@/utils/tools'
;
type
ComponentRef
,
type
StartChatFnProps
}
from
'@/components/ChatBox'
;
export
type
ChatTestComponentRef
=
{
export
type
ChatTestComponentRef
=
{
resetChatTest
:
()
=>
void
;
resetChatTest
:
()
=>
void
;
...
@@ -36,24 +37,8 @@ const ChatTest = (
...
@@ -36,24 +37,8 @@ const ChatTest = (
)
=>
{
)
=>
{
const
BoxRef
=
useRef
(
null
);
const
BoxRef
=
useRef
(
null
);
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
const
{
toast
}
=
useToast
();
const
isOpen
=
useMemo
(()
=>
modules
&&
modules
.
length
>
0
,
[
modules
]);
const
isOpen
=
useMemo
(()
=>
modules
&&
modules
.
length
>
0
,
[
modules
]);
const
variableModules
=
useMemo
(
()
=>
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
variables
)?.
value
,
[
modules
]
);
const
welcomeText
=
useMemo
(
()
=>
modules
.
find
((
item
)
=>
item
.
flowType
===
FlowModuleTypeEnum
.
userGuide
)
?.
inputs
?.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
welcomeText
)?.
value
,
[
modules
]
);
const
startChat
=
useCallback
(
const
startChat
=
useCallback
(
async
({
messages
,
controller
,
generatingMessage
,
variables
}:
StartChatFnProps
)
=>
{
async
({
messages
,
controller
,
generatingMessage
,
variables
}:
StartChatFnProps
)
=>
{
const
historyMaxLen
=
const
historyMaxLen
=
...
@@ -137,8 +122,7 @@ const ChatTest = (
...
@@ -137,8 +122,7 @@ const ChatTest = (
<
ChatBox
<
ChatBox
ref=
{
ChatBoxRef
}
ref=
{
ChatBoxRef
}
appAvatar=
{
app
.
avatar
}
appAvatar=
{
app
.
avatar
}
variableModules=
{
variableModules
}
{
...
getSpecialModule
(
modules
)}
welcomeText=
{
welcomeText
}
onStartChat=
{
startChat
}
onStartChat=
{
startChat
}
onDelMessage=
{
()
=>
{}
}
onDelMessage=
{
()
=>
{}
}
/>
/>
...
...
client/src/pages/app/detail/components/edit/components/NodeAnswer.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
Answer.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
NodeProps
}
from
'reactflow'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
RenderInput
from
'./render/RenderInput'
;
import
RenderInput
from
'.
.
/render/RenderInput'
;
const
NodeAnswer
=
({
const
NodeAnswer
=
({
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
...
...
client/src/pages/app/detail/components/edit/components/Node
RI
Node.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/NodeCQ
Node.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
Box
,
Input
,
Button
,
Flex
}
from
'@chakra-ui/react'
;
import
{
Box
,
Input
,
Button
,
Flex
}
from
'@chakra-ui/react'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
RenderInput
from
'./render/RenderInput'
;
import
RenderInput
from
'.
.
/render/RenderInput'
;
import
type
{
ClassifyQuestionAgentItemType
}
from
'@/types/app'
;
import
type
{
ClassifyQuestionAgentItemType
}
from
'@/types/app'
;
import
{
Handle
,
Position
}
from
'reactflow'
;
import
{
Handle
,
Position
}
from
'reactflow'
;
import
{
customAlphabet
}
from
'nanoid'
;
import
{
customAlphabet
}
from
'nanoid'
;
...
@@ -13,7 +13,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
...
@@ -13,7 +13,7 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 4);
import
MyIcon
from
'@/components/Icon'
;
import
MyIcon
from
'@/components/Icon'
;
import
{
FlowOutputItemTypeEnum
}
from
'@/constants/flow'
;
import
{
FlowOutputItemTypeEnum
}
from
'@/constants/flow'
;
const
Node
RI
Node
=
({
const
Node
CQ
Node
=
({
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
}:
NodeProps
<
FlowModuleItemType
>
)
=>
{
}:
NodeProps
<
FlowModuleItemType
>
)
=>
{
return
(
return
(
...
@@ -133,4 +133,4 @@ const NodeRINode = ({
...
@@ -133,4 +133,4 @@ const NodeRINode = ({
</
NodeCard
>
</
NodeCard
>
);
);
};
};
export
default
React
.
memo
(
Node
RI
Node
);
export
default
React
.
memo
(
Node
CQ
Node
);
client/src/pages/app/detail/components/edit/components/NodeChat.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
Chat.tsx
View file @
f9d83c48
import
React
,
{
useMemo
}
from
'react'
;
import
React
,
{
useMemo
}
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
NodeProps
}
from
'reactflow'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
RenderInput
from
'./render/RenderInput'
;
import
RenderInput
from
'.
.
/render/RenderInput'
;
import
RenderOutput
from
'./render/RenderOutput'
;
import
RenderOutput
from
'.
.
/render/RenderOutput'
;
import
{
FlowOutputItemTypeEnum
}
from
'@/constants/flow'
;
import
{
FlowOutputItemTypeEnum
}
from
'@/constants/flow'
;
import
MySelect
from
'@/components/Select'
;
import
MySelect
from
'@/components/Select'
;
import
{
chatModelList
}
from
'@/store/static'
;
import
{
chatModelList
}
from
'@/store/static'
;
...
...
client/src/pages/app/detail/components/edit/components/NodeHistory.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
History.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
NodeProps
}
from
'reactflow'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
RenderInput
from
'./render/RenderInput'
;
import
RenderInput
from
'.
.
/render/RenderInput'
;
import
RenderOutput
from
'./render/RenderOutput'
;
import
RenderOutput
from
'.
.
/render/RenderOutput'
;
const
NodeHistory
=
({
const
NodeHistory
=
({
data
:
{
inputs
,
outputs
,
onChangeNode
,
...
props
}
data
:
{
inputs
,
outputs
,
onChangeNode
,
...
props
}
...
...
client/src/pages/app/detail/components/edit/components/NodeKbSearch.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
KbSearch.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
NodeProps
}
from
'reactflow'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
RenderInput
from
'./render/RenderInput'
;
import
RenderInput
from
'.
.
/render/RenderInput'
;
import
RenderOutput
from
'./render/RenderOutput'
;
import
RenderOutput
from
'.
.
/render/RenderOutput'
;
import
KBSelect
from
'./Plugins/KBSelect'
;
import
KBSelect
from
'.
.
/Plugins/KBSelect'
;
const
NodeKbSearch
=
({
const
NodeKbSearch
=
({
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
data
:
{
moduleId
,
inputs
,
outputs
,
onChangeNode
,
...
props
}
...
...
client/src/pages/app/detail/components/edit/components/NodeQuestionInput.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
QuestionInput.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
Handle
,
Position
,
NodeProps
}
from
'reactflow'
;
import
{
Handle
,
Position
,
NodeProps
}
from
'reactflow'
;
import
{
Box
}
from
'@chakra-ui/react'
;
import
{
Box
}
from
'@chakra-ui/react'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
const
QuestionInputNode
=
({
const
QuestionInputNode
=
({
...
...
client/src/pages/app/detail/components/edit/components/NodeTFSwitch.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/Node
TFSwitch.tsx
View file @
f9d83c48
import
React
from
'react'
;
import
React
from
'react'
;
import
{
Handle
,
Position
,
NodeProps
}
from
'reactflow'
;
import
{
Handle
,
Position
,
NodeProps
}
from
'reactflow'
;
import
{
Flex
,
Box
}
from
'@chakra-ui/react'
;
import
{
Flex
,
Box
}
from
'@chakra-ui/react'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Divider
from
'./modules/Divider'
;
import
Divider
from
'.
.
/modules/Divider'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
Label
from
'./modules/Label'
;
import
Label
from
'.
.
/modules/Label'
;
const
NodeTFSwitch
=
({
data
:
{
inputs
,
outputs
,
...
props
}
}:
NodeProps
<
FlowModuleItemType
>
)
=>
{
const
NodeTFSwitch
=
({
data
:
{
inputs
,
outputs
,
...
props
}
}:
NodeProps
<
FlowModuleItemType
>
)
=>
{
return
(
return
(
<
NodeCard
minW=
{
'220px'
}
logo=
{
'/icon/logo.png'
}
name=
{
'TF 开关'
}
{
...
props
}
>
<
NodeCard
minW=
{
'220px'
}
{
...
props
}
>
<
Divider
text=
"输入输出"
/>
<
Divider
text=
"输入输出"
/>
<
Container
h=
{
'100px'
}
py=
{
0
}
px=
{
0
}
display=
{
'flex'
}
alignItems=
{
'center'
}
>
<
Container
h=
{
'100px'
}
py=
{
0
}
px=
{
0
}
display=
{
'flex'
}
alignItems=
{
'center'
}
>
<
Box
flex=
{
1
}
pl=
{
'12px'
}
>
<
Box
flex=
{
1
}
pl=
{
'12px'
}
>
...
...
client/src/pages/app/detail/components/edit/components/Nodes/NodeUserGuide.tsx
0 → 100644
View file @
f9d83c48
import
React
,
{
useMemo
}
from
'react'
;
import
{
NodeProps
}
from
'reactflow'
;
import
{
Box
,
Flex
,
Textarea
}
from
'@chakra-ui/react'
;
import
{
QuestionOutlineIcon
}
from
'@chakra-ui/icons'
;
import
NodeCard
from
'../modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Container
from
'../modules/Container'
;
import
{
SystemInputEnum
}
from
'@/constants/app'
;
import
MyIcon
from
'@/components/Icon'
;
import
{
customAlphabet
}
from
'nanoid'
;
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
6
);
import
MyTooltip
from
'@/components/MyTooltip'
;
const
welcomePlaceholder
=
'每次对话开始前,发送一个初始内容。可使用的特殊标记:\n[快捷按键]: 用户点击后可以直接发送该问题'
;
const
NodeUserGuide
=
({
data
:
{
inputs
,
outputs
,
onChangeNode
,
...
props
}
}:
NodeProps
<
FlowModuleItemType
>
)
=>
{
const
welcomeText
=
useMemo
(
()
=>
inputs
.
find
((
item
)
=>
item
.
key
===
SystemInputEnum
.
welcomeText
)?.
value
,
[
inputs
]
);
return
(
<>
<
NodeCard
minW=
{
'300px'
}
{
...
props
}
>
<
Container
borderTop=
{
'2px solid'
}
borderTopColor=
{
'myGray.200'
}
>
<>
<
Flex
mb=
{
1
}
alignItems=
{
'center'
}
>
<
MyIcon
name=
{
'welcomeText'
}
mr=
{
2
}
w=
{
'16px'
}
color=
{
'#E74694'
}
/>
<
Box
>
开场白
</
Box
>
<
MyTooltip
label=
{
welcomePlaceholder
}
>
<
QuestionOutlineIcon
display=
{
[
'none'
,
'inline'
]
}
ml=
{
1
}
/>
</
MyTooltip
>
</
Flex
>
<
Textarea
className=
"nodrag"
rows=
{
6
}
resize=
{
'both'
}
defaultValue=
{
welcomeText
}
bg=
{
'myWhite.500'
}
placeholder=
{
welcomePlaceholder
}
onChange=
{
(
e
)
=>
{
onChangeNode
({
moduleId
:
props
.
moduleId
,
key
:
SystemInputEnum
.
welcomeText
,
type
:
'inputs'
,
value
:
e
.
target
.
value
});
}
}
/>
</>
</
Container
>
</
NodeCard
>
</>
);
};
export
default
React
.
memo
(
NodeUserGuide
);
client/src/pages/app/detail/components/edit/components/Node
UserGuid
e.tsx
→
client/src/pages/app/detail/components/edit/components/Node
s/NodeVariabl
e.tsx
View file @
f9d83c48
...
@@ -27,13 +27,12 @@ import {
...
@@ -27,13 +27,12 @@ import {
useDisclosure
,
useDisclosure
,
useTheme
,
useTheme
,
Grid
,
Grid
,
FormControl
,
FormControl
Textarea
}
from
'@chakra-ui/react'
;
}
from
'@chakra-ui/react'
;
import
{
QuestionOutline
Icon
,
SmallAddIcon
}
from
'@chakra-ui/icons'
;
import
{
Add
Icon
,
SmallAddIcon
}
from
'@chakra-ui/icons'
;
import
NodeCard
from
'./modules/NodeCard'
;
import
NodeCard
from
'.
.
/modules/NodeCard'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
{
FlowModuleItemType
}
from
'@/types/flow'
;
import
Container
from
'./modules/Container'
;
import
Container
from
'.
.
/modules/Container'
;
import
{
SystemInputEnum
,
VariableInputEnum
}
from
'@/constants/app'
;
import
{
SystemInputEnum
,
VariableInputEnum
}
from
'@/constants/app'
;
import
type
{
VariableItemType
}
from
'@/types/app'
;
import
type
{
VariableItemType
}
from
'@/types/app'
;
import
MyIcon
from
'@/components/Icon'
;
import
MyIcon
from
'@/components/Icon'
;
...
@@ -41,8 +40,6 @@ import { useForm } from 'react-hook-form';
...
@@ -41,8 +40,6 @@ import { useForm } from 'react-hook-form';
import
{
useFieldArray
}
from
'react-hook-form'
;
import
{
useFieldArray
}
from
'react-hook-form'
;
import
{
customAlphabet
}
from
'nanoid'
;
import
{
customAlphabet
}
from
'nanoid'
;
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
6
);
const
nanoid
=
customAlphabet
(
'abcdefghijklmnopqrstuvwxyz1234567890'
,
6
);
import
{
Label
}
from
'./render/RenderInput'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
const
VariableTypeList
=
[
const
VariableTypeList
=
[
{
label
:
'文本'
,
icon
:
'settingLight'
,
key
:
VariableInputEnum
.
input
},
{
label
:
'文本'
,
icon
:
'settingLight'
,
key
:
VariableInputEnum
.
input
},
...
@@ -118,91 +115,60 @@ const NodeUserGuide = ({
...
@@ -118,91 +115,60 @@ const NodeUserGuide = ({
<>
<>
<
NodeCard
minW=
{
'300px'
}
{
...
props
}
>
<
NodeCard
minW=
{
'300px'
}
{
...
props
}
>
<
Container
borderTop=
{
'2px solid'
}
borderTopColor=
{
'myGray.200'
}
>
<
Container
borderTop=
{
'2px solid'
}
borderTopColor=
{
'myGray.200'
}
>
<>
<
TableContainer
>
<
Flex
mb=
{
1
}
alignItems=
{
'center'
}
>
<
Table
>
<
MyIcon
name=
{
'welcomeText'
}
mr=
{
2
}
w=
{
'16px'
}
color=
{
'#E74694'
}
/>
<
Thead
>
<
Box
>
对话开场白
</
Box
>
<
Tr
>
</
Flex
>
<
Th
>
变量名
</
Th
>
<
Textarea
<
Th
>
变量 key
</
Th
>
className=
"nodrag"
<
Th
>
必填
</
Th
>
rows=
{
3
}
<
Th
></
Th
>
resize=
{
'both'
}
</
Tr
>
defaultValue=
{
welcomeText
}
</
Thead
>
bg=
{
'myWhite.600'
}
<
Tbody
>
onChange=
{
(
e
)
=>
{
{
variables
.
map
((
item
,
index
)
=>
(
onChangeNode
({
<
Tr
key=
{
index
}
>
moduleId
:
props
.
moduleId
,
<
Td
>
{
item
.
label
}
</
Td
>
key
:
SystemInputEnum
.
welcomeText
,
<
Td
>
{
item
.
key
}
</
Td
>
type
:
'inputs'
,
<
Td
>
{
item
.
required
?
'✔'
:
''
}
</
Td
>
value
:
e
.
target
.
value
<
Td
>
});
<
MyIcon
}
}
mr=
{
3
}
/>
name=
{
'settingLight'
}
</>
w=
{
'16px'
}
<
Box
mt=
{
4
}
>
cursor=
{
'pointer'
}
<
Flex
alignItems=
{
'center'
}
>
onClick=
{
()
=>
{
<
MyIcon
name=
{
'variable'
}
mr=
{
2
}
w=
{
'20px'
}
color=
{
'#FF8A4C'
}
/>
onOpen
();
<
Box
>
变量
</
Box
>
reset
({
variable
:
item
});
<
MyTooltip
}
}
label=
{
`变量会在开始对话前输入,仅会在本次对话中生效。\n你可以在任何字符串模块(系统提示词、限定词等)中使用 {{变量key}} 来代表变量输入。`
}
/>
>
<
MyIcon
<
QuestionOutlineIcon
display=
{
[
'none'
,
'inline'
]
}
ml=
{
1
}
/>
name=
{
'delete'
}
</
MyTooltip
>
w=
{
'16px'
}
</
Flex
>
cursor=
{
'pointer'
}
<
TableContainer
>
onClick=
{
()
=>
<
Table
>
updateVariables
(
variables
.
filter
((
variable
)
=>
variable
.
id
!==
item
.
id
))
<
Thead
>
}
<
Tr
>
/>
<
Th
>
变量名
</
Th
>
</
Td
>
<
Th
>
变量 key
</
Th
>
<
Th
>
必填
</
Th
>
<
Th
></
Th
>
</
Tr
>
</
Tr
>
</
Thead
>
))
}
<
Tbody
>
</
Tbody
>
{
variables
.
map
((
item
,
index
)
=>
(
</
Table
>
<
Tr
key=
{
index
}
>
</
TableContainer
>
<
Td
>
{
item
.
label
}
</
Td
>
<
Box
mt=
{
2
}
textAlign=
{
'right'
}
>
<
Td
>
{
item
.
key
}
</
Td
>
<
Button
<
Td
>
{
item
.
required
?
'✔'
:
''
}
</
Td
>
variant=
{
'base'
}
<
Td
>
leftIcon=
{
<
AddIcon
fontSize=
{
'10px'
}
/>
}
<
MyIcon
onClick=
{
()
=>
{
mr=
{
3
}
const
newVariable
=
{
...
defaultVariable
,
id
:
nanoid
()
};
name=
{
'settingLight'
}
updateVariables
(
variables
.
concat
(
newVariable
));
w=
{
'16px'
}
reset
({
variable
:
newVariable
});
cursor=
{
'pointer'
}
onOpen
();
onClick=
{
()
=>
{
}
}
onOpen
();
>
reset
({
variable
:
item
});
新增
}
}
</
Button
>
/>
<
MyIcon
name=
{
'delete'
}
w=
{
'16px'
}
cursor=
{
'pointer'
}
onClick=
{
()
=>
updateVariables
(
variables
.
filter
((
variable
)
=>
variable
.
id
!==
item
.
id
))
}
/>
</
Td
>
</
Tr
>
))
}
</
Tbody
>
</
Table
>
</
TableContainer
>
<
Box
mt=
{
2
}
textAlign=
{
'right'
}
>
<
Button
variant=
{
'base'
}
onClick=
{
()
=>
{
const
newVariable
=
{
...
defaultVariable
,
id
:
nanoid
()
};
updateVariables
(
variables
.
concat
(
newVariable
));
reset
({
variable
:
newVariable
});
onOpen
();
}
}
>
+ 新增
</
Button
>
</
Box
>
</
Box
>
</
Box
>
</
Container
>
</
Container
>
</
NodeCard
>
</
NodeCard
>
...
...
client/src/pages/app/detail/components/edit/components/TemplateList.tsx
View file @
f9d83c48
...
@@ -74,7 +74,7 @@ const ModuleStoreList = ({
...
@@ -74,7 +74,7 @@ const ModuleStoreList = ({
});
});
}
}
}
}
>
>
<
Avatar
src=
{
item
.
logo
}
w=
{
'34px'
}
borderRadius=
{
'0'
}
/>
<
Avatar
src=
{
item
.
logo
}
w=
{
'34px'
}
objectFit=
{
'contain'
}
borderRadius=
{
'0'
}
/>
<
Box
ml=
{
5
}
flex=
{
'1 0 0'
}
>
<
Box
ml=
{
5
}
flex=
{
'1 0 0'
}
>
<
Box
color=
{
'black'
}
>
{
item
.
name
}
</
Box
>
<
Box
color=
{
'black'
}
>
{
item
.
name
}
</
Box
>
<
Box
color=
{
'myGray.500'
}
fontSize=
{
'sm'
}
>
<
Box
color=
{
'myGray.500'
}
fontSize=
{
'sm'
}
>
...
...
client/src/pages/app/detail/components/edit/components/modules/NodeCard.tsx
View file @
f9d83c48
...
@@ -31,7 +31,7 @@ const NodeCard = ({
...
@@ -31,7 +31,7 @@ const NodeCard = ({
return
(
return
(
<
Box
minW=
{
minW
}
bg=
{
'white'
}
border=
{
theme
.
borders
.
md
}
borderRadius=
{
'md'
}
boxShadow=
{
'sm'
}
>
<
Box
minW=
{
minW
}
bg=
{
'white'
}
border=
{
theme
.
borders
.
md
}
borderRadius=
{
'md'
}
boxShadow=
{
'sm'
}
>
<
Flex
className=
"custom-drag-handle"
px=
{
4
}
py=
{
3
}
alignItems=
{
'center'
}
>
<
Flex
className=
"custom-drag-handle"
px=
{
4
}
py=
{
3
}
alignItems=
{
'center'
}
>
<
Avatar
src=
{
logo
}
borderRadius=
{
'md'
}
w=
{
'30px'
}
h=
{
'30px'
}
/>
<
Avatar
src=
{
logo
}
borderRadius=
{
'md'
}
objectFit=
{
'contain'
}
w=
{
'30px'
}
h=
{
'30px'
}
/>
<
Box
ml=
{
3
}
fontSize=
{
'lg'
}
color=
{
'myGray.600'
}
>
<
Box
ml=
{
3
}
fontSize=
{
'lg'
}
color=
{
'myGray.600'
}
>
{
name
}
{
name
}
</
Box
>
</
Box
>
...
...
client/src/pages/app/detail/components/edit/index.tsx
View file @
f9d83c48
...
@@ -31,28 +31,31 @@ import MyTooltip from '@/components/MyTooltip';
...
@@ -31,28 +31,31 @@ import MyTooltip from '@/components/MyTooltip';
import
TemplateList
from
'./components/TemplateList'
;
import
TemplateList
from
'./components/TemplateList'
;
import
ChatTest
,
{
type
ChatTestComponentRef
}
from
'./components/ChatTest'
;
import
ChatTest
,
{
type
ChatTestComponentRef
}
from
'./components/ChatTest'
;
const
NodeChat
=
dynamic
(()
=>
import
(
'./components/NodeChat'
),
{
const
NodeChat
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
Chat'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeKbSearch
=
dynamic
(()
=>
import
(
'./components/NodeKbSearch'
),
{
const
NodeKbSearch
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
KbSearch'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeHistory
=
dynamic
(()
=>
import
(
'./components/NodeHistory'
),
{
const
NodeHistory
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
History'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeTFSwitch
=
dynamic
(()
=>
import
(
'./components/NodeTFSwitch'
),
{
const
NodeTFSwitch
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
TFSwitch'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeAnswer
=
dynamic
(()
=>
import
(
'./components/NodeAnswer'
),
{
const
NodeAnswer
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
Answer'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeQuestionInput
=
dynamic
(()
=>
import
(
'./components/NodeQuestionInput'
),
{
const
NodeQuestionInput
=
dynamic
(()
=>
import
(
'./components/Node
s/Node
QuestionInput'
),
{
ssr
:
false
ssr
:
false
});
});
const
Node
RINode
=
dynamic
(()
=>
import
(
'./components/NodeRI
Node'
),
{
const
Node
CQNode
=
dynamic
(()
=>
import
(
'./components/Nodes/NodeCQ
Node'
),
{
ssr
:
false
ssr
:
false
});
});
const
NodeUserGuide
=
dynamic
(()
=>
import
(
'./components/NodeUserGuide'
),
{
const
NodeVariable
=
dynamic
(()
=>
import
(
'./components/Nodes/NodeVariable'
),
{
ssr
:
false
});
const
NodeUserGuide
=
dynamic
(()
=>
import
(
'./components/Nodes/NodeUserGuide'
),
{
ssr
:
false
ssr
:
false
});
});
...
@@ -64,13 +67,14 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
...
@@ -64,13 +67,14 @@ const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6);
const
nodeTypes
=
{
const
nodeTypes
=
{
[
FlowModuleTypeEnum
.
userGuide
]:
NodeUserGuide
,
[
FlowModuleTypeEnum
.
userGuide
]:
NodeUserGuide
,
[
FlowModuleTypeEnum
.
variable
]:
NodeVariable
,
[
FlowModuleTypeEnum
.
questionInputNode
]:
NodeQuestionInput
,
[
FlowModuleTypeEnum
.
questionInputNode
]:
NodeQuestionInput
,
[
FlowModuleTypeEnum
.
historyNode
]:
NodeHistory
,
[
FlowModuleTypeEnum
.
historyNode
]:
NodeHistory
,
[
FlowModuleTypeEnum
.
chatNode
]:
NodeChat
,
[
FlowModuleTypeEnum
.
chatNode
]:
NodeChat
,
[
FlowModuleTypeEnum
.
kbSearchNode
]:
NodeKbSearch
,
[
FlowModuleTypeEnum
.
kbSearchNode
]:
NodeKbSearch
,
[
FlowModuleTypeEnum
.
tfSwitchNode
]:
NodeTFSwitch
,
[
FlowModuleTypeEnum
.
tfSwitchNode
]:
NodeTFSwitch
,
[
FlowModuleTypeEnum
.
answerNode
]:
NodeAnswer
,
[
FlowModuleTypeEnum
.
answerNode
]:
NodeAnswer
,
[
FlowModuleTypeEnum
.
classifyQuestion
]:
Node
RI
Node
[
FlowModuleTypeEnum
.
classifyQuestion
]:
Node
CQ
Node
};
};
const
edgeTypes
=
{
const
edgeTypes
=
{
buttonedge
:
ButtonEdge
buttonedge
:
ButtonEdge
...
...
client/src/pages/chat/components/ChatHistorySlider.tsx
View file @
f9d83c48
...
@@ -161,7 +161,7 @@ const ChatHistorySlider = ({
...
@@ -161,7 +161,7 @@ const ChatHistorySlider = ({
{
item
.
top
?
'取消置顶'
:
'置顶'
}
{
item
.
top
?
'取消置顶'
:
'置顶'
}
</
MenuItem
>
</
MenuItem
>
)
}
)
}
{
/* {
onUpdateTitle && (
{
onUpdateTitle
&&
(
<
MenuItem
<
MenuItem
onClick=
{
(
e
)
=>
{
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
e
.
stopPropagation
();
...
@@ -174,7 +174,7 @@ const ChatHistorySlider = ({
...
@@ -174,7 +174,7 @@ const ChatHistorySlider = ({
<
MyIcon
mr=
{
2
}
name=
{
'customTitle'
}
w=
{
'16px'
}
></
MyIcon
>
<
MyIcon
mr=
{
2
}
name=
{
'customTitle'
}
w=
{
'16px'
}
></
MyIcon
>
自定义标题
自定义标题
</
MenuItem
>
</
MenuItem
>
)}
*/
}
)
}
<
MenuItem
<
MenuItem
_hover=
{
{
color
:
'red.500'
}
}
_hover=
{
{
color
:
'red.500'
}
}
onClick=
{
(
e
)
=>
{
onClick=
{
(
e
)
=>
{
...
...
client/src/pages/chat/index.tsx
View file @
f9d83c48
...
@@ -301,9 +301,7 @@ const Chat = () => {
...
@@ -301,9 +301,7 @@ const Chat = () => {
appAvatar=
{
chatData
.
app
.
avatar
}
appAvatar=
{
chatData
.
app
.
avatar
}
variableModules=
{
chatData
.
app
.
variableModules
}
variableModules=
{
chatData
.
app
.
variableModules
}
welcomeText=
{
chatData
.
app
.
welcomeText
}
welcomeText=
{
chatData
.
app
.
welcomeText
}
onUpdateVariable=
{
(
e
)
=>
{
onUpdateVariable=
{
(
e
)
=>
{}
}
console
.
log
(
e
);
}
}
onStartChat=
{
startChat
}
onStartChat=
{
startChat
}
onDelMessage=
{
delOneHistoryItem
}
onDelMessage=
{
delOneHistoryItem
}
/>
/>
...
...
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