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
d52700c6
authored
Mar 19, 2025
by
heheer
Committed by
archer
Mar 27, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add external variable debug (#4204)
* add external variable debug * fix ui * plugin variables
parent
ec30d792
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
471 additions
and
95 deletions
+471
-95
packages/web/i18n/en/common.json
+2
-0
packages/web/i18n/zh-CN/common.json
+2
-0
packages/web/i18n/zh-Hant/common.json
+2
-0
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/VariableInput.tsx
+182
-35
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/VariablePopover.tsx
+98
-0
projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx
+51
-4
projects/app/src/components/core/chat/ChatContainer/PluginRunBox/components/RenderInput.tsx
+37
-29
projects/app/src/components/core/chat/ChatContainer/PluginRunBox/components/renderPluginInput.tsx
+15
-3
projects/app/src/pageComponents/app/detail/SimpleApp/ChatTest.tsx
+9
-3
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/ChatTest.tsx
+5
-1
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/hooks/useDebug.tsx
+27
-10
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/InputTypeConfig.tsx
+16
-5
projects/app/src/pageComponents/app/detail/useChatTest.tsx
+1
-1
projects/app/src/pageComponents/chat/ChatHeader.tsx
+10
-2
projects/app/src/web/core/chat/context/chatItemContext.tsx
+14
-2
No files found.
packages/web/i18n/en/common.json
View file @
d52700c6
...
@@ -430,6 +430,8 @@
...
@@ -430,6 +430,8 @@
"core.chat.Start Chat"
:
"Start Chat"
,
"core.chat.Start Chat"
:
"Start Chat"
,
"core.chat.Type a message"
:
"Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line"
,
"core.chat.Type a message"
:
"Enter a Question, Press [Enter] to Send / Press [Ctrl(Alt/Shift) + Enter] for New Line"
,
"core.chat.Unpin"
:
"Unpin"
,
"core.chat.Unpin"
:
"Unpin"
,
"core.chat.Variable_Visiable_in_test"
:
"This variable is not visible in the login-free link"
,
"core.chat.Visiable_in_test"
:
"Custom variables are not visible in login-free links"
,
"core.chat.You need to a chat app"
:
"You Do Not Have an Available App"
,
"core.chat.You need to a chat app"
:
"You Do Not Have an Available App"
,
"core.chat.error.Chat error"
:
"Chat Error"
,
"core.chat.error.Chat error"
:
"Chat Error"
,
"core.chat.error.Messages empty"
:
"API Content is Empty, Possibly Due to Text Being Too Long"
,
"core.chat.error.Messages empty"
:
"API Content is Empty, Possibly Due to Text Being Too Long"
,
...
...
packages/web/i18n/zh-CN/common.json
View file @
d52700c6
...
@@ -433,6 +433,8 @@
...
@@ -433,6 +433,8 @@
"core.chat.Start Chat"
:
"开始对话"
,
"core.chat.Start Chat"
:
"开始对话"
,
"core.chat.Type a message"
:
"输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]"
,
"core.chat.Type a message"
:
"输入问题,发送 [Enter]/换行 [Ctrl(Alt/Shift) + Enter]"
,
"core.chat.Unpin"
:
"取消置顶"
,
"core.chat.Unpin"
:
"取消置顶"
,
"core.chat.Variable_Visiable_in_test"
:
"该变量在免登录链接中不可见"
,
"core.chat.Visiable_in_test"
:
"自定义变量在免登录链接中不可见"
,
"core.chat.You need to a chat app"
:
"你没有可用的应用"
,
"core.chat.You need to a chat app"
:
"你没有可用的应用"
,
"core.chat.error.Chat error"
:
"对话出现异常"
,
"core.chat.error.Chat error"
:
"对话出现异常"
,
"core.chat.error.Messages empty"
:
"接口内容为空,可能文本超长了~"
,
"core.chat.error.Messages empty"
:
"接口内容为空,可能文本超长了~"
,
...
...
packages/web/i18n/zh-Hant/common.json
View file @
d52700c6
...
@@ -429,6 +429,8 @@
...
@@ -429,6 +429,8 @@
"core.chat.Start Chat"
:
"開始對話"
,
"core.chat.Start Chat"
:
"開始對話"
,
"core.chat.Type a message"
:
"輸入問題,按 [Enter] 傳送 / 按 [Ctrl(Alt/Shift) + Enter] 換行"
,
"core.chat.Type a message"
:
"輸入問題,按 [Enter] 傳送 / 按 [Ctrl(Alt/Shift) + Enter] 換行"
,
"core.chat.Unpin"
:
"取消釘選"
,
"core.chat.Unpin"
:
"取消釘選"
,
"core.chat.Variable_Visiable_in_test"
:
"該變量在免登錄鏈接中不可見"
,
"core.chat.Visiable_in_test"
:
"自定義變量在免登錄鏈接中不可見"
,
"core.chat.You need to a chat app"
:
"您沒有可用的應用程式"
,
"core.chat.You need to a chat app"
:
"您沒有可用的應用程式"
,
"core.chat.error.Chat error"
:
"對話發生錯誤"
,
"core.chat.error.Chat error"
:
"對話發生錯誤"
,
"core.chat.error.Messages empty"
:
"API 內容為空,可能是文字過長"
,
"core.chat.error.Messages empty"
:
"API 內容為空,可能是文字過長"
,
...
...
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/VariableInput.tsx
View file @
d52700c6
import
React
,
{
useEffect
}
from
'react'
;
import
React
,
{
useEffect
,
useMemo
}
from
'react'
;
import
{
Controller
,
UseFormReturn
}
from
'react-hook-form'
;
import
{
Controller
,
UseFormReturn
}
from
'react-hook-form'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
{
Box
,
Button
,
Card
,
Textarea
}
from
'@chakra-ui/react'
;
import
{
Box
,
Button
,
Card
,
Flex
,
Switch
,
Textarea
}
from
'@chakra-ui/react'
;
import
ChatAvatar
from
'./ChatAvatar'
;
import
ChatAvatar
from
'./ChatAvatar'
;
import
{
MessageCardStyle
}
from
'../constants'
;
import
{
MessageCardStyle
}
from
'../constants'
;
import
{
VariableInputEnum
}
from
'@fastgpt/global/core/workflow/constants'
;
import
{
VariableInputEnum
,
WorkflowIOValueTypeEnum
}
from
'@fastgpt/global/core/workflow/constants'
;
import
MySelect
from
'@fastgpt/web/components/common/MySelect'
;
import
MySelect
from
'@fastgpt/web/components/common/MySelect'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
{
ChatBoxInputFormType
}
from
'../type.d'
;
import
{
ChatBoxInputFormType
}
from
'../type.d'
;
import
{
useContextSelector
}
from
'use-context-selector'
;
import
{
useContextSelector
}
from
'use-context-selector'
;
import
{
ChatBoxContext
}
from
'../Provider'
;
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
{
VariableItemType
}
from
'@fastgpt/global/core/app/type'
;
import
{
VariableItemType
}
from
'@fastgpt/global/core/app/type'
;
import
MyTextarea
from
'@/components/common/Textarea/MyTextarea'
;
import
MyTextarea
from
'@/components/common/Textarea/MyTextarea'
;
import
MyNumberInput
from
'@fastgpt/web/components/common/Input/NumberInput'
;
import
MyNumberInput
from
'@fastgpt/web/components/common/Input/NumberInput'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatBoxContext
}
from
'../Provider'
;
import
dynamic
from
'next/dynamic'
;
const
JsonEditor
=
dynamic
(()
=>
import
(
'@fastgpt/web/components/common/Textarea/JsonEditor'
));
export
const
VariableInputItem
=
({
export
const
VariableInputItem
=
({
item
,
item
,
...
@@ -108,23 +114,118 @@ export const VariableInputItem = ({
...
@@ -108,23 +114,118 @@ export const VariableInputItem = ({
);
);
};
};
export
const
ExternalVariableInputItem
=
({
item
,
variablesForm
,
showTag
=
false
}:
{
item
:
VariableItemType
;
variablesForm
:
UseFormReturn
<
any
>
;
showTag
?:
boolean
;
})
=>
{
const
{
t
}
=
useTranslation
();
const
{
register
,
control
}
=
variablesForm
;
return
(
<
Box
key=
{
item
.
id
}
mb=
{
4
}
pl=
{
1
}
>
<
Box
as=
{
'label'
}
display=
{
'flex'
}
position=
{
'relative'
}
mb=
{
1
}
alignItems=
{
'center'
}
w=
{
'full'
}
>
{
item
.
label
}
{
item
.
required
&&
(
<
Box
position=
{
'absolute'
}
top=
{
'-2px'
}
left=
{
'-8px'
}
color=
{
'red.500'
}
>
*
</
Box
>
)
}
{
item
.
description
&&
<
QuestionTip
ml=
{
1
}
label=
{
item
.
description
}
/>
}
{
showTag
&&
(
<
Flex
color=
{
'primary.600'
}
bg=
{
'primary.100'
}
px=
{
2
}
py=
{
1
}
gap=
{
1
}
ml=
{
2
}
fontSize=
{
'mini'
}
rounded=
{
'sm'
}
>
<
MyIcon
name=
{
'common/info'
}
color=
{
'primary.600'
}
w=
{
4
}
/>
{
t
(
'common:core.chat.Variable_Visiable_in_test'
)
}
</
Flex
>
)
}
</
Box
>
<
Controller
control=
{
control
}
name=
{
`variables.${item.key}`
}
rules=
{
{
required
:
item
.
required
,
validate
:
(
value
)
=>
{
if
(
item
.
valueType
===
WorkflowIOValueTypeEnum
.
boolean
)
{
return
value
!==
undefined
;
}
return
!!
value
;
}
}
}
render=
{
({
field
:
{
onChange
,
value
}
})
=>
{
if
(
item
.
valueType
===
WorkflowIOValueTypeEnum
.
string
)
{
return
(
<
MyTextarea
autoHeight
minH=
{
40
}
maxH=
{
160
}
bg=
{
'myGray.50'
}
{
...
register
(`
variables
.
$
{
item
.
key
}`,
{
required
:
item
.
required
})}
/>
);
}
if
(
item
.
valueType
===
WorkflowIOValueTypeEnum
.
number
)
{
return
<
MyNumberInput
step=
{
1
}
bg=
{
'myGray.50'
}
value=
{
value
}
onChange=
{
onChange
}
/>;
}
if
(
item
.
valueType
===
WorkflowIOValueTypeEnum
.
boolean
)
{
return
<
Switch
isChecked=
{
value
}
onChange=
{
onChange
}
/>;
}
return
<
JsonEditor
bg=
{
'myGray.50'
}
resize
value=
{
value
}
onChange=
{
onChange
}
/>;
}
}
/>
</
Box
>
);
};
const
VariableInput
=
({
const
VariableInput
=
({
chatForm
,
chatForm
,
chatStarted
chatStarted
,
showExternalVariables
=
false
}:
{
}:
{
chatStarted
:
boolean
;
chatForm
:
UseFormReturn
<
ChatBoxInputFormType
>
;
chatForm
:
UseFormReturn
<
ChatBoxInputFormType
>
;
chatStarted
:
boolean
;
showExternalVariables
?:
boolean
;
})
=>
{
})
=>
{
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
const
appAvatar
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
?.
app
?.
avatar
);
const
appAvatar
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
?.
app
?.
avatar
);
const
variablesForm
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
variablesForm
);
const
variablesForm
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
variablesForm
);
const
variableList
=
useContextSelector
(
ChatBoxContext
,
(
v
)
=>
v
.
variableList
);
const
variableList
=
useContextSelector
(
ChatBoxContext
,
(
v
)
=>
v
.
variableList
);
const
allVariableList
=
useContextSelector
(
ChatBoxContext
,
(
v
)
=>
v
.
allVariableList
);
const
externalVariableList
=
useMemo
(
()
=>
allVariableList
.
filter
((
item
)
=>
showExternalVariables
?
item
.
type
===
VariableInputEnum
.
custom
:
false
),
[
allVariableList
,
showExternalVariables
]
);
const
{
getValues
,
setValue
,
handleSubmit
:
handleSubmitChat
}
=
variablesForm
;
const
{
getValues
,
setValue
,
handleSubmit
:
handleSubmitChat
}
=
variablesForm
;
useEffect
(()
=>
{
useEffect
(()
=>
{
v
ariableList
.
forEach
((
item
)
=>
{
allV
ariableList
.
forEach
((
item
)
=>
{
const
val
=
getValues
(
`variables.
${
item
.
key
}
`
);
const
val
=
getValues
(
`variables.
${
item
.
key
}
`
);
if
(
item
.
defaultValue
!==
undefined
&&
(
val
===
undefined
||
val
===
null
||
val
===
''
))
{
if
(
item
.
defaultValue
!==
undefined
&&
(
val
===
undefined
||
val
===
null
||
val
===
''
))
{
setValue
(
`variables.
${
item
.
key
}
`
,
item
.
defaultValue
);
setValue
(
`variables.
${
item
.
key
}
`
,
item
.
defaultValue
);
...
@@ -135,34 +236,80 @@ const VariableInput = ({
...
@@ -135,34 +236,80 @@ const VariableInput = ({
return
(
return
(
<
Box
py=
{
3
}
>
<
Box
py=
{
3
}
>
<
ChatAvatar
src=
{
appAvatar
}
type=
{
'AI'
}
/>
<
ChatAvatar
src=
{
appAvatar
}
type=
{
'AI'
}
/>
<
Box
textAlign=
{
'left'
}
>
{
externalVariableList
.
length
>
0
&&
(
<
Card
<
Box
textAlign=
{
'left'
}
>
order=
{
2
}
<
Card
mt=
{
2
}
order=
{
2
}
w=
{
'400px'
}
mt=
{
2
}
{
...
MessageCardStyle
}
w=
{
'400px'
}
bg=
{
'white'
}
{
...
MessageCardStyle
}
boxShadow=
{
'0 0 8px rgba(0,0,0,0.15)'
}
bg=
{
'white'
}
>
boxShadow=
{
'0 0 8px rgba(0,0,0,0.15)'
}
{
variableList
.
map
((
item
)
=>
(
>
<
VariableInputItem
key=
{
item
.
id
}
item=
{
item
}
variablesForm=
{
variablesForm
}
/>
<
Flex
))
}
color=
{
'primary.600'
}
{
!
chatStarted
&&
(
bg=
{
'primary.100'
}
<
Box
>
mb=
{
3
}
<
Button
px=
{
3
}
leftIcon=
{
<
MyIcon
name=
{
'core/chat/chatFill'
}
w=
{
'16px'
}
/>
}
py=
{
1.5
}
size=
{
'sm'
}
gap=
{
1
}
maxW=
{
'100px'
}
fontSize=
{
'mini'
}
onClick=
{
handleSubmitChat
(()
=>
{
rounded=
{
'sm'
}
chatForm
.
setValue
(
'chatStarted'
,
true
);
>
})
}
<
MyIcon
name=
{
'common/info'
}
color=
{
'primary.600'
}
w=
{
4
}
/>
>
{
t
(
'common:core.chat.Visiable_in_test'
)
}
{
t
(
'common:core.chat.Start Chat'
)
}
</
Flex
>
</
Button
>
{
externalVariableList
.
map
((
item
)
=>
(
</
Box
>
<
ExternalVariableInputItem
key=
{
item
.
id
}
item=
{
item
}
variablesForm=
{
variablesForm
}
/>
)
}
))
}
</
Card
>
{
variableList
.
length
===
0
&&
!
chatStarted
&&
(
</
Box
>
<
Box
>
<
Button
leftIcon=
{
<
MyIcon
name=
{
'core/chat/chatFill'
}
w=
{
'16px'
}
/>
}
size=
{
'sm'
}
maxW=
{
'100px'
}
onClick=
{
handleSubmitChat
(()
=>
{
chatForm
.
setValue
(
'chatStarted'
,
true
);
})
}
>
{
t
(
'common:core.chat.Start Chat'
)
}
</
Button
>
</
Box
>
)
}
</
Card
>
</
Box
>
)
}
{
variableList
.
length
>
0
&&
(
<
Box
textAlign=
{
'left'
}
>
<
Card
order=
{
2
}
mt=
{
2
}
w=
{
'400px'
}
{
...
MessageCardStyle
}
bg=
{
'white'
}
boxShadow=
{
'0 0 8px rgba(0,0,0,0.15)'
}
>
{
variableList
.
map
((
item
)
=>
(
<
VariableInputItem
key=
{
item
.
id
}
item=
{
item
}
variablesForm=
{
variablesForm
}
/>
))
}
{
!
chatStarted
&&
(
<
Box
>
<
Button
leftIcon=
{
<
MyIcon
name=
{
'core/chat/chatFill'
}
w=
{
'16px'
}
/>
}
size=
{
'sm'
}
maxW=
{
'100px'
}
onClick=
{
handleSubmitChat
(()
=>
{
chatForm
.
setValue
(
'chatStarted'
,
true
);
})
}
>
{
t
(
'common:core.chat.Start Chat'
)
}
</
Button
>
</
Box
>
)
}
</
Card
>
</
Box
>
)
}
</
Box
>
</
Box
>
);
);
};
};
...
...
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/VariablePopover.tsx
0 → 100644
View file @
d52700c6
import
{
Box
,
Button
,
Flex
}
from
'@chakra-ui/react'
;
import
MyPopover
from
'@fastgpt/web/components/common/MyPopover'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
{
useContextSelector
}
from
'use-context-selector'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
VariableInputEnum
}
from
'@fastgpt/global/core/workflow/constants'
;
import
{
useEffect
}
from
'react'
;
import
{
ExternalVariableInputItem
,
VariableInputItem
}
from
'./VariableInput'
;
import
MyDivider
from
'@fastgpt/web/components/common/MyDivider'
;
const
VariablePopover
=
({
showExternalVariables
=
false
}:
{
showExternalVariables
?:
boolean
;
})
=>
{
const
{
t
}
=
useTranslation
();
const
variablesForm
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
variablesForm
);
const
variables
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
?.
app
?.
chatConfig
?.
variables
??
[]
);
const
variableList
=
variables
.
filter
((
item
)
=>
item
.
type
!==
VariableInputEnum
.
custom
);
const
externalVariableList
=
variables
.
filter
((
item
)
=>
showExternalVariables
?
item
.
type
===
VariableInputEnum
.
custom
:
false
);
const
hasExternalVariable
=
externalVariableList
.
length
>
0
;
const
hasVariable
=
variableList
.
length
>
0
;
const
{
getValues
,
setValue
}
=
variablesForm
;
useEffect
(()
=>
{
variables
.
forEach
((
item
)
=>
{
const
val
=
getValues
(
`variables.
${
item
.
key
}
`
);
if
(
item
.
defaultValue
!==
undefined
&&
(
val
===
undefined
||
val
===
null
||
val
===
''
))
{
setValue
(
`variables.
${
item
.
key
}
`
,
item
.
defaultValue
);
}
});
},
[
variables
]);
return
(
<
MyPopover
placement=
"bottom"
trigger=
{
'click'
}
closeOnBlur=
{
true
}
Trigger=
{
<
Button
variant=
{
'whiteBase'
}
leftIcon=
{
<
MyIcon
name=
{
'edit'
}
w=
{
4
}
/>
}
>
{
t
(
'common:core.module.Variable'
)
}
</
Button
>
}
>
{
({
onClose
})
=>
(
<
Box
p=
{
4
}
>
{
hasExternalVariable
&&
(
<
Box
textAlign=
{
'left'
}
>
<
Flex
color=
{
'primary.600'
}
bg=
{
'primary.100'
}
mb=
{
3
}
px=
{
3
}
py=
{
1.5
}
gap=
{
1
}
fontSize=
{
'mini'
}
rounded=
{
'sm'
}
>
<
MyIcon
name=
{
'common/info'
}
color=
{
'primary.600'
}
w=
{
4
}
/>
{
t
(
'common:core.chat.Visiable_in_test'
)
}
</
Flex
>
{
externalVariableList
.
map
((
item
)
=>
(
<
ExternalVariableInputItem
key=
{
item
.
id
}
item=
{
item
}
variablesForm=
{
variablesForm
}
/>
))
}
</
Box
>
)
}
{
hasExternalVariable
&&
hasVariable
&&
<
MyDivider
h=
{
'1px'
}
/>
}
{
hasVariable
&&
(
<
Box
textAlign=
{
'left'
}
>
{
variableList
.
map
((
item
)
=>
(
<
VariableInputItem
key=
{
item
.
id
}
item=
{
item
}
variablesForm=
{
variablesForm
}
/>
))
}
</
Box
>
)
}
<
Flex
w=
{
'full'
}
justifyContent=
{
'flex-end'
}
>
<
Button
size=
{
'sm'
}
onClick=
{
onClose
}
>
{
t
(
'common:common.Confirm'
)
}
</
Button
>
</
Flex
>
</
Box
>
)
}
</
MyPopover
>
);
};
export
default
VariablePopover
;
projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx
View file @
d52700c6
...
@@ -65,6 +65,7 @@ import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
...
@@ -65,6 +65,7 @@ import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
TimeBox
from
'./components/TimeBox'
;
import
TimeBox
from
'./components/TimeBox'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
{
VariableInputEnum
}
from
'@fastgpt/global/core/workflow/constants'
;
const
ResponseTags
=
dynamic
(()
=>
import
(
'./components/ResponseTags'
));
const
ResponseTags
=
dynamic
(()
=>
import
(
'./components/ResponseTags'
));
const
FeedbackModal
=
dynamic
(()
=>
import
(
'./components/FeedbackModal'
));
const
FeedbackModal
=
dynamic
(()
=>
import
(
'./components/FeedbackModal'
));
...
@@ -103,7 +104,8 @@ const ChatBox = ({
...
@@ -103,7 +104,8 @@ const ChatBox = ({
showVoiceIcon
=
true
,
showVoiceIcon
=
true
,
showEmptyIntro
=
false
,
showEmptyIntro
=
false
,
active
=
true
,
active
=
true
,
onStartChat
onStartChat
,
chatType
}:
Props
)
=>
{
}:
Props
)
=>
{
const
ScrollContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
ScrollContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
...
@@ -129,6 +131,8 @@ const ChatBox = ({
...
@@ -129,6 +131,8 @@ const ChatBox = ({
const
chatBoxData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
);
const
chatBoxData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
);
const
ChatBoxRef
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
ChatBoxRef
);
const
ChatBoxRef
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
ChatBoxRef
);
const
variablesForm
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
variablesForm
);
const
variablesForm
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
variablesForm
);
const
setIsVariableVisible
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
setIsVariableVisible
);
const
chatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
chatRecords
);
const
chatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
chatRecords
);
const
setChatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
setChatRecords
);
const
setChatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
setChatRecords
);
const
isChatRecordsLoaded
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
isChatRecordsLoaded
);
const
isChatRecordsLoaded
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
isChatRecordsLoaded
);
...
@@ -150,6 +154,12 @@ const ChatBox = ({
...
@@ -150,6 +154,12 @@ const ChatBox = ({
// Workflow running, there are user input or selection
// Workflow running, there are user input or selection
const
isInteractive
=
useMemo
(()
=>
checkIsInteractiveByHistories
(
chatRecords
),
[
chatRecords
]);
const
isInteractive
=
useMemo
(()
=>
checkIsInteractiveByHistories
(
chatRecords
),
[
chatRecords
]);
const
externalVariableList
=
useMemo
(()
=>
{
if
(
chatType
===
'chat'
)
{
return
allVariableList
.
filter
((
item
)
=>
item
.
type
===
VariableInputEnum
.
custom
);
}
return
[];
},
[
allVariableList
,
chatType
]);
// compute variable input is finish.
// compute variable input is finish.
const
chatForm
=
useForm
<
ChatBoxInputFormType
>
({
const
chatForm
=
useForm
<
ChatBoxInputFormType
>
({
defaultValues
:
{
defaultValues
:
{
...
@@ -162,7 +172,9 @@ const ChatBox = ({
...
@@ -162,7 +172,9 @@ const ChatBox = ({
const
chatStartedWatch
=
watch
(
'chatStarted'
);
const
chatStartedWatch
=
watch
(
'chatStarted'
);
const
chatStarted
=
const
chatStarted
=
chatBoxData
?.
appId
===
appId
&&
chatBoxData
?.
appId
===
appId
&&
(
chatStartedWatch
||
chatRecords
.
length
>
0
||
variableList
.
length
===
0
);
(
chatStartedWatch
||
chatRecords
.
length
>
0
||
[...
variableList
,
...
externalVariableList
].
length
===
0
);
// 滚动到底部
// 滚动到底部
const
scrollToBottom
=
useMemoizedFn
((
behavior
:
'smooth'
|
'auto'
=
'smooth'
,
delay
=
0
)
=>
{
const
scrollToBottom
=
useMemoizedFn
((
behavior
:
'smooth'
|
'auto'
=
'smooth'
,
delay
=
0
)
=>
{
...
@@ -891,6 +903,33 @@ const ChatBox = ({
...
@@ -891,6 +903,33 @@ const ChatBox = ({
}
}
}));
}));
// Visibility check
useEffect
(()
=>
{
const
checkVariableVisibility
=
()
=>
{
if
(
!
ScrollContainerRef
.
current
)
return
;
const
container
=
ScrollContainerRef
.
current
;
const
variableInput
=
container
.
querySelector
(
'#variable-input'
);
if
(
!
variableInput
)
return
;
const
containerRect
=
container
.
getBoundingClientRect
();
const
elementRect
=
variableInput
.
getBoundingClientRect
();
setIsVariableVisible
(
elementRect
.
bottom
>
containerRect
.
top
&&
elementRect
.
top
<
containerRect
.
bottom
);
};
const
container
=
ScrollContainerRef
.
current
;
if
(
container
)
{
container
.
addEventListener
(
'scroll'
,
checkVariableVisibility
);
checkVariableVisibility
();
return
()
=>
{
container
.
removeEventListener
(
'scroll'
,
checkVariableVisibility
);
};
}
},
[
setIsVariableVisible
]);
const
RenderRecords
=
useMemo
(()
=>
{
const
RenderRecords
=
useMemo
(()
=>
{
return
(
return
(
<
ScrollData
<
ScrollData
...
@@ -906,8 +945,14 @@ const ChatBox = ({
...
@@ -906,8 +945,14 @@ const ChatBox = ({
{
showEmpty
&&
<
Empty
/>
}
{
showEmpty
&&
<
Empty
/>
}
{
!!
welcomeText
&&
<
WelcomeBox
welcomeText=
{
welcomeText
}
/>
}
{
!!
welcomeText
&&
<
WelcomeBox
welcomeText=
{
welcomeText
}
/>
}
{
/* variable input */
}
{
/* variable input */
}
{
!!
variableList
?.
length
&&
(
{
(
!!
variableList
?.
length
||
!!
externalVariableList
?.
length
)
&&
(
<
VariableInput
chatStarted=
{
chatStarted
}
chatForm=
{
chatForm
}
/>
<
Box
id=
"variable-input"
>
<
VariableInput
chatStarted=
{
chatStarted
}
chatForm=
{
chatForm
}
showExternalVariables=
{
chatType
===
'chat'
}
/>
</
Box
>
)
}
)
}
{
/* chat history */
}
{
/* chat history */
}
<
Box
id=
{
'history'
}
>
<
Box
id=
{
'history'
}
>
...
@@ -1006,7 +1051,9 @@ const ChatBox = ({
...
@@ -1006,7 +1051,9 @@ const ChatBox = ({
chatForm
,
chatForm
,
chatRecords
,
chatRecords
,
chatStarted
,
chatStarted
,
chatType
,
delOneMessage
,
delOneMessage
,
externalVariableList
?.
length
,
isChatting
,
isChatting
,
onAddUserDislike
,
onAddUserDislike
,
onAddUserLike
,
onAddUserLike
,
...
...
projects/app/src/components/core/chat/ChatContainer/PluginRunBox/components/RenderInput.tsx
View file @
d52700c6
...
@@ -18,6 +18,7 @@ import { ChatBoxInputFormType } from '../../ChatBox/type';
...
@@ -18,6 +18,7 @@ import { ChatBoxInputFormType } from '../../ChatBox/type';
import
{
FlowNodeInputItemType
}
from
'@fastgpt/global/core/workflow/type/io'
;
import
{
FlowNodeInputItemType
}
from
'@fastgpt/global/core/workflow/type/io'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatRecordContext
}
from
'@/web/core/chat/context/chatRecordContext'
;
import
{
ChatRecordContext
}
from
'@/web/core/chat/context/chatRecordContext'
;
import
{
FlowNodeInputTypeEnum
}
from
'@fastgpt/global/core/workflow/node/constant'
;
const
RenderInput
=
()
=>
{
const
RenderInput
=
()
=>
{
const
{
t
}
=
useTranslation
();
const
{
t
}
=
useTranslation
();
...
@@ -213,36 +214,43 @@ const RenderInput = () => {
...
@@ -213,36 +214,43 @@ const RenderInput = () => {
</
Box
>
</
Box
>
)
}
)
}
{
/* Filed */
}
{
/* Filed */
}
{
formatPluginInputs
.
map
((
input
)
=>
{
{
formatPluginInputs
return
(
.
filter
((
input
)
=>
{
<
Controller
if
(
outLinkAuthData
&&
Object
.
keys
(
outLinkAuthData
).
length
>
0
)
{
key=
{
`variables.${input.key}`
}
return
input
.
renderTypeList
[
0
]
!==
FlowNodeInputTypeEnum
.
customVariable
;
control=
{
control
}
}
name=
{
`variables.${input.key}`
}
return
true
;
rules=
{
{
})
validate
:
(
value
)
=>
{
.
map
((
input
)
=>
{
if
(
!
input
.
required
)
return
true
;
return
(
if
(
input
.
valueType
===
WorkflowIOValueTypeEnum
.
boolean
)
{
<
Controller
return
value
!==
undefined
;
key=
{
`variables.${input.key}`
}
control=
{
control
}
name=
{
`variables.${input.key}`
}
rules=
{
{
validate
:
(
value
)
=>
{
if
(
!
input
.
required
)
return
true
;
if
(
input
.
valueType
===
WorkflowIOValueTypeEnum
.
boolean
)
{
return
value
!==
undefined
;
}
return
!!
value
;
}
}
return
!!
value
;
}
}
}
render=
{
({
field
:
{
onChange
,
value
}
})
=>
{
}
}
return
(
render=
{
({
field
:
{
onChange
,
value
}
})
=>
{
<
RenderPluginInput
return
(
value=
{
value
}
<
RenderPluginInput
onChange=
{
onChange
}
value=
{
value
}
isDisabled=
{
isDisabledInput
}
onChange=
{
onChange
}
isInvalid=
{
errors
&&
Object
.
keys
(
errors
).
includes
(
input
.
key
)
}
isDisabled=
{
isDisabledInput
}
input=
{
input
}
isInvalid=
{
errors
&&
Object
.
keys
(
errors
).
includes
(
input
.
key
)
}
setUploading=
{
setUploading
}
input=
{
input
}
/>
setUploading=
{
setUploading
}
);
/>
}
}
);
/>
}
}
);
/>
})
}
);
})
}
{
/* Run Button */
}
{
/* Run Button */
}
{
onStartChat
&&
onNewChat
&&
(
{
onStartChat
&&
onNewChat
&&
(
<
Flex
justifyContent=
{
'end'
}
mt=
{
8
}
>
<
Flex
justifyContent=
{
'end'
}
mt=
{
8
}
>
...
...
projects/app/src/components/core/chat/ChatContainer/PluginRunBox/components/renderPluginInput.tsx
View file @
d52700c6
...
@@ -157,9 +157,6 @@ const RenderPluginInput = ({
...
@@ -157,9 +157,6 @@ const RenderPluginInput = ({
const
{
llmModelList
}
=
useSystemStore
();
const
{
llmModelList
}
=
useSystemStore
();
const
render
=
(()
=>
{
const
render
=
(()
=>
{
if
(
inputType
===
FlowNodeInputTypeEnum
.
customVariable
)
{
return
null
;
}
if
(
inputType
===
FlowNodeInputTypeEnum
.
select
&&
input
.
list
)
{
if
(
inputType
===
FlowNodeInputTypeEnum
.
select
&&
input
.
list
)
{
return
(
return
(
<
MySelect
list=
{
input
.
list
}
value=
{
value
}
onChange=
{
onChange
}
isDisabled=
{
isDisabled
}
/>
<
MySelect
list=
{
input
.
list
}
value=
{
value
}
onChange=
{
onChange
}
isDisabled=
{
isDisabled
}
/>
...
@@ -246,6 +243,21 @@ const RenderPluginInput = ({
...
@@ -246,6 +243,21 @@ const RenderPluginInput = ({
<
FormLabel
fontWeight=
{
'500'
}
>
{
t
(
input
.
label
as
any
)
}
</
FormLabel
>
<
FormLabel
fontWeight=
{
'500'
}
>
{
t
(
input
.
label
as
any
)
}
</
FormLabel
>
</
Box
>
</
Box
>
{
input
.
description
&&
<
QuestionTip
ml=
{
2
}
label=
{
t
(
input
.
description
as
any
)
}
/>
}
{
input
.
description
&&
<
QuestionTip
ml=
{
2
}
label=
{
t
(
input
.
description
as
any
)
}
/>
}
{
inputType
===
FlowNodeInputTypeEnum
.
customVariable
&&
(
<
Flex
color=
{
'primary.600'
}
bg=
{
'primary.100'
}
px=
{
2
}
py=
{
1
}
gap=
{
1
}
ml=
{
2
}
fontSize=
{
'mini'
}
rounded=
{
'sm'
}
>
<
MyIcon
name=
{
'common/info'
}
color=
{
'primary.600'
}
w=
{
4
}
/>
{
t
(
'common:core.chat.Variable_Visiable_in_test'
)
}
</
Flex
>
)
}
</
Flex
>
</
Flex
>
)
}
)
}
...
...
projects/app/src/pageComponents/app/detail/SimpleApp/ChatTest.tsx
View file @
d52700c6
import
{
Box
,
Flex
,
IconButton
}
from
'@chakra-ui/react'
;
import
{
Box
,
Button
,
Flex
,
IconButton
}
from
'@chakra-ui/react'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
React
,
{
useEffect
,
useMemo
}
from
'react'
;
import
React
,
{
useEffect
,
useMemo
}
from
'react'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
...
@@ -10,12 +10,14 @@ import { form2AppWorkflow } from '@/web/core/app/utils';
...
@@ -10,12 +10,14 @@ import { form2AppWorkflow } from '@/web/core/app/utils';
import
{
useContextSelector
}
from
'use-context-selector'
;
import
{
useContextSelector
}
from
'use-context-selector'
;
import
{
AppContext
}
from
'../context'
;
import
{
AppContext
}
from
'../context'
;
import
{
useChatTest
}
from
'../useChatTest'
;
import
{
useChatTest
}
from
'../useChatTest'
;
import
{
useDatasetStore
}
from
'@/web/core/dataset/store/dataset'
;
import
ChatItemContextProvider
,
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
ChatItemContextProvider
,
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
ChatRecordContextProvider
from
'@/web/core/chat/context/chatRecordContext'
;
import
ChatRecordContextProvider
from
'@/web/core/chat/context/chatRecordContext'
;
import
{
useChatStore
}
from
'@/web/core/chat/context/useChatStore'
;
import
{
useChatStore
}
from
'@/web/core/chat/context/useChatStore'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
{
cardStyles
}
from
'../constants'
;
import
{
cardStyles
}
from
'../constants'
;
import
ChatQuoteList
from
'@/pageComponents/chat/ChatQuoteList'
;
import
ChatQuoteList
from
'@/pageComponents/chat/ChatQuoteList'
;
import
VariablePopover
from
'@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover'
;
type
Props
=
{
type
Props
=
{
appForm
:
AppSimpleEditFormType
;
appForm
:
AppSimpleEditFormType
;
...
@@ -27,6 +29,8 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
...
@@ -27,6 +29,8 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
const
{
appDetail
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
{
appDetail
}
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
);
const
quoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
quoteData
);
const
quoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
quoteData
);
const
setQuoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
setQuoteData
);
const
setQuoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
setQuoteData
);
// form2AppWorkflow dependent allDatasets
const
isVariableVisible
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
isVariableVisible
);
const
[
workflowData
,
setWorkflowData
]
=
useSafeState
({
const
[
workflowData
,
setWorkflowData
]
=
useSafeState
({
nodes
:
appDetail
.
modules
||
[],
nodes
:
appDetail
.
modules
||
[],
...
@@ -62,10 +66,12 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
...
@@ -62,10 +66,12 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
{
...
cardStyles
}
{
...
cardStyles
}
boxShadow=
{
'3'
}
boxShadow=
{
'3'
}
>
>
<
Flex
px=
{
[
2
,
5
]
}
>
<
Flex
px=
{
[
2
,
5
]
}
pb=
{
2
}
>
<
Box
fontSize=
{
[
'md'
,
'lg'
]
}
fontWeight=
{
'bold'
}
flex=
{
1
}
color=
{
'myGray.900'
}
>
<
Box
fontSize=
{
[
'md'
,
'lg'
]
}
fontWeight=
{
'bold'
}
color=
{
'myGray.900'
}
mr=
{
3
}
>
{
t
(
'app:chat_debug'
)
}
{
t
(
'app:chat_debug'
)
}
</
Box
>
</
Box
>
{
!
isVariableVisible
&&
<
VariablePopover
showExternalVariables=
{
true
}
/>
}
<
Box
flex=
{
1
}
/>
<
MyTooltip
label=
{
t
(
'common:core.chat.Restart'
)
}
>
<
MyTooltip
label=
{
t
(
'common:core.chat.Restart'
)
}
>
<
IconButton
<
IconButton
className=
"chat"
className=
"chat"
...
...
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/ChatTest.tsx
View file @
d52700c6
...
@@ -21,6 +21,7 @@ import ChatRecordContextProvider, {
...
@@ -21,6 +21,7 @@ import ChatRecordContextProvider, {
import
{
useChatStore
}
from
'@/web/core/chat/context/useChatStore'
;
import
{
useChatStore
}
from
'@/web/core/chat/context/useChatStore'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
ChatQuoteList
from
'@/pageComponents/chat/ChatQuoteList'
;
import
ChatQuoteList
from
'@/pageComponents/chat/ChatQuoteList'
;
import
VariablePopover
from
'@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover'
;
type
Props
=
{
type
Props
=
{
isOpen
:
boolean
;
isOpen
:
boolean
;
...
@@ -45,6 +46,7 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
...
@@ -45,6 +46,7 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
const
quoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
quoteData
);
const
quoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
quoteData
);
const
setQuoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
setQuoteData
);
const
setQuoteData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
setQuoteData
);
const
isVariableVisible
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
isVariableVisible
);
const
chatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
chatRecords
);
const
chatRecords
=
useContextSelector
(
ChatRecordContext
,
(
v
)
=>
v
.
chatRecords
);
return
(
return
(
...
@@ -115,10 +117,12 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
...
@@ -115,10 +117,12 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
bg=
{
'myGray.25'
}
bg=
{
'myGray.25'
}
borderBottom=
{
'1px solid #F4F4F7'
}
borderBottom=
{
'1px solid #F4F4F7'
}
>
>
<
Flex
fontSize=
{
'16px'
}
fontWeight=
{
'bold'
}
flex=
{
1
}
alignItems=
{
'center'
}
>
<
Flex
fontSize=
{
'16px'
}
fontWeight=
{
'bold'
}
alignItems=
{
'center'
}
mr=
{
3
}
>
<
MyIcon
name=
{
'common/paused'
}
w=
{
'14px'
}
mr=
{
2.5
}
/>
<
MyIcon
name=
{
'common/paused'
}
w=
{
'14px'
}
mr=
{
2.5
}
/>
{
t
(
'common:core.chat.Run test'
)
}
{
t
(
'common:core.chat.Run test'
)
}
</
Flex
>
</
Flex
>
{
!
isVariableVisible
&&
<
VariablePopover
showExternalVariables=
{
true
}
/>
}
<
Box
flex=
{
1
}
/>
<
MyTooltip
label=
{
t
(
'common:core.chat.Restart'
)
}
>
<
MyTooltip
label=
{
t
(
'common:core.chat.Restart'
)
}
>
<
IconButton
<
IconButton
className=
"chat"
className=
"chat"
...
...
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/hooks/useDebug.tsx
View file @
d52700c6
...
@@ -31,7 +31,10 @@ import { WorkflowContext } from '../../context';
...
@@ -31,7 +31,10 @@ import { WorkflowContext } from '../../context';
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
{
FlowNodeTypeEnum
}
from
'@fastgpt/global/core/workflow/node/constant'
;
import
{
FlowNodeTypeEnum
}
from
'@fastgpt/global/core/workflow/node/constant'
;
import
{
AppContext
}
from
'../../../context'
;
import
{
AppContext
}
from
'../../../context'
;
import
{
VariableInputItem
}
from
'@/components/core/chat/ChatContainer/ChatBox/components/VariableInput'
;
import
{
ExternalVariableInputItem
,
VariableInputItem
}
from
'@/components/core/chat/ChatContainer/ChatBox/components/VariableInput'
;
import
LightRowTabs
from
'@fastgpt/web/components/common/Tabs/LightRowTabs'
;
import
LightRowTabs
from
'@fastgpt/web/components/common/Tabs/LightRowTabs'
;
import
MyTextarea
from
'@/components/common/Textarea/MyTextarea'
;
import
MyTextarea
from
'@/components/common/Textarea/MyTextarea'
;
import
{
WorkflowNodeEdgeContext
}
from
'../../context/workflowInitContext'
;
import
{
WorkflowNodeEdgeContext
}
from
'../../context/workflowInitContext'
;
...
@@ -58,13 +61,17 @@ export const useDebug = () => {
...
@@ -58,13 +61,17 @@ export const useDebug = () => {
const
appDetail
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
.
appDetail
);
const
appDetail
=
useContextSelector
(
AppContext
,
(
v
)
=>
v
.
appDetail
);
const
filteredVar
=
useMemo
(()
=>
{
const
{
filteredVar
,
customVar
,
variables
}
=
useMemo
(()
=>
{
const
variables
=
appDetail
.
chatConfig
?.
variables
;
const
variables
=
appDetail
.
chatConfig
?.
variables
||
[];
return
variables
?.
filter
((
item
)
=>
item
.
type
!==
VariableInputEnum
.
custom
)
||
[];
return
{
filteredVar
:
variables
.
filter
((
item
)
=>
item
.
type
!==
VariableInputEnum
.
custom
)
||
[],
customVar
:
variables
.
filter
((
item
)
=>
item
.
type
===
VariableInputEnum
.
custom
)
||
[],
variables
};
},
[
appDetail
.
chatConfig
?.
variables
]);
},
[
appDetail
.
chatConfig
?.
variables
]);
const
[
defaultGlobalVariables
,
setDefaultGlobalVariables
]
=
useState
<
Record
<
string
,
any
>>
(
const
[
defaultGlobalVariables
,
setDefaultGlobalVariables
]
=
useState
<
Record
<
string
,
any
>>
(
filteredVar
.
reduce
(
variables
.
reduce
(
(
acc
,
item
)
=>
{
(
acc
,
item
)
=>
{
acc
[
item
.
key
]
=
item
.
defaultValue
;
acc
[
item
.
key
]
=
item
.
defaultValue
;
return
acc
;
return
acc
;
...
@@ -241,7 +248,7 @@ export const useDebug = () => {
...
@@ -241,7 +248,7 @@ export const useDebug = () => {
px=
{
0
}
px=
{
0
}
>
>
<
Box
flex=
{
'1 0 0'
}
overflow=
{
'auto'
}
px=
{
6
}
>
<
Box
flex=
{
'1 0 0'
}
overflow=
{
'auto'
}
px=
{
6
}
>
{
filteredVar
.
length
>
0
&&
(
{
variables
.
length
>
0
&&
(
<
LightRowTabs
<
TabEnum
>
<
LightRowTabs
<
TabEnum
>
gap=
{
3
}
gap=
{
3
}
ml=
{
-
2
}
ml=
{
-
2
}
...
@@ -256,6 +263,14 @@ export const useDebug = () => {
...
@@ -256,6 +263,14 @@ export const useDebug = () => {
/
>
/
>
)
}
)
}
<
Box
display=
{
currentTab
===
TabEnum
.
global
?
'block'
:
'none'
}
>
<
Box
display=
{
currentTab
===
TabEnum
.
global
?
'block'
:
'none'
}
>
{
customVar
.
map
((
item
)
=>
(
<
ExternalVariableInputItem
key=
{
item
.
id
}
item=
{
{
...
item
,
key
:
item
.
key
}
}
variablesForm=
{
variablesForm
}
showTag=
{
true
}
/>
))
}
{
filteredVar
.
map
((
item
)
=>
(
{
filteredVar
.
map
((
item
)
=>
(
<
VariableInputItem
<
VariableInputItem
key=
{
item
.
id
}
key=
{
item
.
id
}
...
@@ -354,13 +369,15 @@ export const useDebug = () => {
...
@@ -354,13 +369,15 @@ export const useDebug = () => {
</
MyRightDrawer
>
</
MyRightDrawer
>
);
);
},
[
},
[
runtimeNodes
,
runtimeEdges
,
defaultGlobalVariables
,
defaultGlobalVariables
,
t
,
variables
.
length
,
customVar
,
filteredVar
,
filteredVar
,
onStartNodeDebug
,
runtimeEdges
,
runtimeNodeId
,
runtimeNodeId
,
runtimeNodes
,
onStartNodeDebug
t
]);
]);
return
{
return
{
...
...
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/InputTypeConfig.tsx
View file @
d52700c6
...
@@ -297,8 +297,10 @@ const InputTypeConfig = ({
...
@@ -297,8 +297,10 @@ const InputTypeConfig = ({
<
FormLabel
flex=
{
'0 0 132px'
}
fontWeight=
{
'medium'
}
>
<
FormLabel
flex=
{
'0 0 132px'
}
fontWeight=
{
'medium'
}
>
{
t
(
'common:core.module.Default Value'
)
}
{
t
(
'common:core.module.Default Value'
)
}
</
FormLabel
>
</
FormLabel
>
<
Flex
alignItems=
{
'start'
}
flex=
{
1
}
h=
{
10
}
>
<
Flex
alignItems=
{
'center'
}
flex=
{
1
}
h=
{
10
}
>
{
inputType
===
FlowNodeInputTypeEnum
.
numberInput
&&
(
{
(
inputType
===
FlowNodeInputTypeEnum
.
numberInput
||
(
inputType
===
VariableInputEnum
.
custom
&&
valueType
===
WorkflowIOValueTypeEnum
.
number
))
&&
(
<
MyNumberInput
<
MyNumberInput
value=
{
defaultValue
}
value=
{
defaultValue
}
min=
{
min
}
min=
{
min
}
...
@@ -310,7 +312,8 @@ const InputTypeConfig = ({
...
@@ -310,7 +312,8 @@ const InputTypeConfig = ({
/>
/>
)
}
)
}
{
(
inputType
===
FlowNodeInputTypeEnum
.
input
||
{
(
inputType
===
FlowNodeInputTypeEnum
.
input
||
inputType
===
VariableInputEnum
.
custom
)
&&
(
(
inputType
===
VariableInputEnum
.
custom
&&
valueType
===
WorkflowIOValueTypeEnum
.
string
))
&&
(
<
MyTextarea
<
MyTextarea
{
...
register
('
defaultValue
')}
{
...
register
('
defaultValue
')}
bg=
{
'myGray.50'
}
bg=
{
'myGray.50'
}
...
@@ -319,7 +322,13 @@ const InputTypeConfig = ({
...
@@ -319,7 +322,13 @@ const InputTypeConfig = ({
maxH=
{
100
}
maxH=
{
100
}
/>
/>
)
}
)
}
{
inputType
===
FlowNodeInputTypeEnum
.
JSONEditor
&&
(
{
(
inputType
===
FlowNodeInputTypeEnum
.
JSONEditor
||
(
inputType
===
VariableInputEnum
.
custom
&&
!
[
WorkflowIOValueTypeEnum
.
number
,
WorkflowIOValueTypeEnum
.
string
,
WorkflowIOValueTypeEnum
.
boolean
].
includes
(
valueType
)))
&&
(
<
JsonEditor
<
JsonEditor
bg=
{
'myGray.50'
}
bg=
{
'myGray.50'
}
resize
resize
...
@@ -330,7 +339,9 @@ const InputTypeConfig = ({
...
@@ -330,7 +339,9 @@ const InputTypeConfig = ({
defaultValue=
{
defaultValue
}
defaultValue=
{
defaultValue
}
/>
/>
)
}
)
}
{
inputType
===
FlowNodeInputTypeEnum
.
switch
&&
(
{
(
inputType
===
FlowNodeInputTypeEnum
.
switch
||
(
inputType
===
VariableInputEnum
.
custom
&&
valueType
===
WorkflowIOValueTypeEnum
.
boolean
))
&&
(
<
Switch
{
...
register
('
defaultValue
')}
/>
<
Switch
{
...
register
('
defaultValue
')}
/>
)
}
)
}
{
inputType
===
FlowNodeInputTypeEnum
.
select
&&
(
{
inputType
===
FlowNodeInputTypeEnum
.
select
&&
(
...
...
projects/app/src/pageComponents/app/detail/useChatTest.tsx
View file @
d52700c6
...
@@ -140,7 +140,7 @@ export const useChatTest = ({
...
@@ -140,7 +140,7 @@ export const useChatTest = ({
appId=
{
appId
}
appId=
{
appId
}
chatId=
{
chatId
}
chatId=
{
chatId
}
showMarkIcon
showMarkIcon
chatType=
"chat"
chatType=
{
'chat'
}
onStartChat=
{
startChat
}
onStartChat=
{
startChat
}
/>
/>
)
)
...
...
projects/app/src/pageComponents/chat/ChatHeader.tsx
View file @
d52700c6
...
@@ -22,6 +22,7 @@ import {
...
@@ -22,6 +22,7 @@ import {
import
{
getMyApps
}
from
'@/web/core/app/api'
;
import
{
getMyApps
}
from
'@/web/core/app/api'
;
import
SelectOneResource
from
'@/components/common/folder/SelectOneResource'
;
import
SelectOneResource
from
'@/components/common/folder/SelectOneResource'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
VariablePopover
from
'@/components/core/chat/ChatContainer/ChatBox/components/VariablePopover'
;
const
ChatHeader
=
({
const
ChatHeader
=
({
history
,
history
,
...
@@ -38,7 +39,10 @@ const ChatHeader = ({
...
@@ -38,7 +39,10 @@ const ChatHeader = ({
const
{
isPc
}
=
useSystem
();
const
{
isPc
}
=
useSystem
();
const
chatData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
);
const
chatData
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
chatBoxData
);
const
isVariableVisible
=
useContextSelector
(
ChatItemContext
,
(
v
)
=>
v
.
isVariableVisible
);
const
isPlugin
=
chatData
.
app
.
type
===
AppTypeEnum
.
plugin
;
const
isPlugin
=
chatData
.
app
.
type
===
AppTypeEnum
.
plugin
;
const
router
=
useRouter
();
const
isChat
=
router
.
pathname
===
'/chat'
;
return
isPc
&&
isPlugin
?
null
:
(
return
isPc
&&
isPlugin
?
null
:
(
<
Flex
<
Flex
...
@@ -68,8 +72,12 @@ const ChatHeader = ({
...
@@ -68,8 +72,12 @@ const ChatHeader = ({
/>
/>
)
}
)
}
{
/* control */
}
<
Flex
gap=
{
2
}
alignItems=
{
'center'
}
>
{
!
isPlugin
&&
<
ToolMenu
history=
{
history
}
/>
}
{
!
isVariableVisible
&&
<
VariablePopover
showExternalVariables=
{
isChat
}
/>
}
{
/* control */
}
{
!
isPlugin
&&
<
ToolMenu
history=
{
history
}
/>
}
</
Flex
>
</
Flex
>
</
Flex
>
);
);
};
};
...
...
projects/app/src/web/core/chat/context/chatItemContext.tsx
View file @
d52700c6
...
@@ -74,6 +74,8 @@ type ChatItemContextType = {
...
@@ -74,6 +74,8 @@ type ChatItemContextType = {
quoteData
?:
QuoteDataType
;
quoteData
?:
QuoteDataType
;
setQuoteData
:
React
.
Dispatch
<
React
.
SetStateAction
<
QuoteDataType
|
undefined
>>
;
setQuoteData
:
React
.
Dispatch
<
React
.
SetStateAction
<
QuoteDataType
|
undefined
>>
;
isVariableVisible
:
boolean
;
setIsVariableVisible
:
React
.
Dispatch
<
React
.
SetStateAction
<
boolean
>>
;
}
&
ContextProps
;
}
&
ContextProps
;
export
const
ChatItemContext
=
createContext
<
ChatItemContextType
>
({
export
const
ChatItemContext
=
createContext
<
ChatItemContextType
>
({
...
@@ -97,6 +99,10 @@ export const ChatItemContext = createContext<ChatItemContextType>({
...
@@ -97,6 +99,10 @@ export const ChatItemContext = createContext<ChatItemContextType>({
quoteData
:
undefined
,
quoteData
:
undefined
,
setQuoteData
:
function
(
value
:
React
.
SetStateAction
<
QuoteDataType
|
undefined
>
):
void
{
setQuoteData
:
function
(
value
:
React
.
SetStateAction
<
QuoteDataType
|
undefined
>
):
void
{
throw
new
Error
(
'Function not implemented.'
);
throw
new
Error
(
'Function not implemented.'
);
},
isVariableVisible
:
true
,
setIsVariableVisible
:
function
(
value
:
React
.
SetStateAction
<
boolean
>
):
void
{
throw
new
Error
(
'Function not implemented.'
);
}
}
});
});
...
@@ -116,6 +122,8 @@ const ChatItemContextProvider = ({
...
@@ -116,6 +122,8 @@ const ChatItemContextProvider = ({
const
ChatBoxRef
=
useRef
<
ChatComponentRef
>
(
null
);
const
ChatBoxRef
=
useRef
<
ChatComponentRef
>
(
null
);
const
variablesForm
=
useForm
<
ChatBoxInputFormType
>
();
const
variablesForm
=
useForm
<
ChatBoxInputFormType
>
();
const
[
quoteData
,
setQuoteData
]
=
useState
<
QuoteDataType
>
();
const
[
quoteData
,
setQuoteData
]
=
useState
<
QuoteDataType
>
();
const
[
isVariableVisible
,
setIsVariableVisible
]
=
useState
(
true
);
const
[
chatBoxData
,
setChatBoxData
]
=
useState
<
ChatBoxDataType
>
({
const
[
chatBoxData
,
setChatBoxData
]
=
useState
<
ChatBoxDataType
>
({
...
defaultChatData
...
defaultChatData
});
});
...
@@ -172,7 +180,9 @@ const ChatItemContextProvider = ({
...
@@ -172,7 +180,9 @@ const ChatItemContextProvider = ({
showNodeStatus
,
showNodeStatus
,
quoteData
,
quoteData
,
setQuoteData
setQuoteData
,
isVariableVisible
,
setIsVariableVisible
};
};
},
[
},
[
chatBoxData
,
chatBoxData
,
...
@@ -187,7 +197,9 @@ const ChatItemContextProvider = ({
...
@@ -187,7 +197,9 @@ const ChatItemContextProvider = ({
// isShowFullText,
// isShowFullText,
showNodeStatus
,
showNodeStatus
,
quoteData
,
quoteData
,
setQuoteData
setQuoteData
,
isVariableVisible
,
setIsVariableVisible
]);
]);
return
<
ChatItemContext
.
Provider
value=
{
contextValue
}
>
{
children
}
</
ChatItemContext
.
Provider
>;
return
<
ChatItemContext
.
Provider
value=
{
contextValue
}
>
{
children
}
</
ChatItemContext
.
Provider
>;
...
...
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