Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
50a006fd
Commit
50a006fd
authored
Jul 25, 2023
by
Joel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat/universal-chat-fe' into deploy/dev
parents
5456c7cf
36c84fb2
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
29 additions
and
12 deletions
+29
-12
index.tsx
web/app/components/app/chat/answer/index.tsx
+10
-4
index.tsx
web/app/components/app/chat/index.tsx
+5
-0
index.tsx
web/app/components/app/chat/thought/index.tsx
+10
-4
index.tsx
web/app/components/base/voice-input/index.tsx
+1
-1
index.tsx
web/app/components/explore/universal-chat/index.tsx
+1
-1
explore.en.ts
web/i18n/lang/explore.en.ts
+1
-1
explore.zh.ts
web/i18n/lang/explore.zh.ts
+1
-1
No files found.
web/app/components/app/chat/answer/index.tsx
View file @
50a006fd
...
@@ -20,6 +20,7 @@ import Tooltip from '@/app/components/base/tooltip'
...
@@ -20,6 +20,7 @@ import Tooltip from '@/app/components/base/tooltip'
import
{
Markdown
}
from
'@/app/components/base/markdown'
import
{
Markdown
}
from
'@/app/components/base/markdown'
import
AutoHeightTextarea
from
'@/app/components/base/auto-height-textarea'
import
AutoHeightTextarea
from
'@/app/components/base/auto-height-textarea'
import
Button
from
'@/app/components/base/button'
import
Button
from
'@/app/components/base/button'
import
type
{
DataSet
}
from
'@/models/datasets'
const
Divider
:
FC
<
{
name
:
string
}
>
=
({
name
})
=>
{
const
Divider
:
FC
<
{
name
:
string
}
>
=
({
name
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
return
<
div
className=
'flex items-center my-2'
>
return
<
div
className=
'flex items-center my-2'
>
...
@@ -45,9 +46,10 @@ export type IAnswerProps = {
...
@@ -45,9 +46,10 @@ export type IAnswerProps = {
answerIconClassName
?:
string
answerIconClassName
?:
string
thoughts
?:
ThoughtItem
[]
thoughts
?:
ThoughtItem
[]
isThinking
?:
boolean
isThinking
?:
boolean
dataSets
?:
DataSet
[]
}
}
// The component needs to maintain its own state to control whether to display input component
// The component needs to maintain its own state to control whether to display input component
const
Answer
:
FC
<
IAnswerProps
>
=
({
item
,
feedbackDisabled
=
false
,
isHideFeedbackEdit
=
false
,
onFeedback
,
onSubmitAnnotation
,
displayScene
=
'web'
,
isResponsing
,
answerIconClassName
,
thoughts
,
isThinking
})
=>
{
const
Answer
:
FC
<
IAnswerProps
>
=
({
item
,
feedbackDisabled
=
false
,
isHideFeedbackEdit
=
false
,
onFeedback
,
onSubmitAnnotation
,
displayScene
=
'web'
,
isResponsing
,
answerIconClassName
,
thoughts
,
isThinking
,
dataSets
})
=>
{
const
{
id
,
content
,
more
,
feedback
,
adminFeedback
,
annotation
:
initAnnotation
}
=
item
const
{
id
,
content
,
more
,
feedback
,
adminFeedback
,
annotation
:
initAnnotation
}
=
item
const
[
showEdit
,
setShowEdit
]
=
useState
(
false
)
const
[
showEdit
,
setShowEdit
]
=
useState
(
false
)
const
[
loading
,
setLoading
]
=
useState
(
false
)
const
[
loading
,
setLoading
]
=
useState
(
false
)
...
@@ -196,6 +198,13 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
...
@@ -196,6 +198,13 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
<
div
className=
'text-xs text-gray-500'
>
{
t
(
'appDebug.openingStatement.title'
)
}
</
div
>
<
div
className=
'text-xs text-gray-500'
>
{
t
(
'appDebug.openingStatement.title'
)
}
</
div
>
</
div
>
</
div
>
)
}
)
}
{
(
thoughts
&&
thoughts
.
length
>
0
)
&&
(
<
Thought
list=
{
thoughts
||
[]
}
isThinking=
{
isThinking
}
dataSets=
{
dataSets
}
/>
)
}
{
(
isResponsing
&&
!
content
)
{
(
isResponsing
&&
!
content
)
?
(
?
(
<
div
className=
'flex items-center justify-center w-6 h-5'
>
<
div
className=
'flex items-center justify-center w-6 h-5'
>
...
@@ -204,9 +213,6 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
...
@@ -204,9 +213,6 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
)
)
:
(
:
(
<
div
>
<
div
>
{
(
thoughts
&&
thoughts
.
length
>
0
)
&&
(
<
Thought
list=
{
thoughts
||
[]
}
isThinking=
{
isThinking
}
/>
)
}
<
Markdown
content=
{
content
}
/>
<
Markdown
content=
{
content
}
/>
</
div
>
</
div
>
)
}
)
}
...
...
web/app/components/app/chat/index.tsx
View file @
50a006fd
...
@@ -19,6 +19,8 @@ import VoiceInput from '@/app/components/base/voice-input'
...
@@ -19,6 +19,8 @@ import VoiceInput from '@/app/components/base/voice-input'
import
{
Microphone01
}
from
'@/app/components/base/icons/src/vender/line/mediaAndDevices'
import
{
Microphone01
}
from
'@/app/components/base/icons/src/vender/line/mediaAndDevices'
import
{
Microphone01
as
Microphone01Solid
}
from
'@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import
{
Microphone01
as
Microphone01Solid
}
from
'@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import
{
XCircle
}
from
'@/app/components/base/icons/src/vender/solid/general'
import
{
XCircle
}
from
'@/app/components/base/icons/src/vender/solid/general'
import
type
{
DataSet
}
from
'@/models/datasets'
export
type
IChatProps
=
{
export
type
IChatProps
=
{
configElem
?:
React
.
ReactNode
configElem
?:
React
.
ReactNode
chatList
:
IChatItem
[]
chatList
:
IChatItem
[]
...
@@ -48,6 +50,7 @@ export type IChatProps = {
...
@@ -48,6 +50,7 @@ export type IChatProps = {
answerIconClassName
?:
string
answerIconClassName
?:
string
isShowConfigElem
?:
boolean
isShowConfigElem
?:
boolean
isThoughting
?:
boolean
isThoughting
?:
boolean
dataSets
?:
DataSet
[]
}
}
const
Chat
:
FC
<
IChatProps
>
=
({
const
Chat
:
FC
<
IChatProps
>
=
({
...
@@ -72,6 +75,7 @@ const Chat: FC<IChatProps> = ({
...
@@ -72,6 +75,7 @@ const Chat: FC<IChatProps> = ({
isShowSpeechToText
,
isShowSpeechToText
,
answerIconClassName
,
answerIconClassName
,
isShowConfigElem
,
isShowConfigElem
,
dataSets
,
})
=>
{
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
const
{
notify
}
=
useContext
(
ToastContext
)
const
{
notify
}
=
useContext
(
ToastContext
)
...
@@ -170,6 +174,7 @@ const Chat: FC<IChatProps> = ({
...
@@ -170,6 +174,7 @@ const Chat: FC<IChatProps> = ({
answerIconClassName=
{
answerIconClassName
}
answerIconClassName=
{
answerIconClassName
}
thoughts=
{
thoughts
}
thoughts=
{
thoughts
}
isThinking=
{
isThinking
}
isThinking=
{
isThinking
}
dataSets=
{
dataSets
}
/>
/>
}
}
return
<
Question
key=
{
item
.
id
}
id=
{
item
.
id
}
content=
{
item
.
content
}
more=
{
item
.
more
}
useCurrentUserAvatar=
{
useCurrentUserAvatar
}
/>
return
<
Question
key=
{
item
.
id
}
id=
{
item
.
id
}
content=
{
item
.
content
}
more=
{
item
.
more
}
useCurrentUserAvatar=
{
useCurrentUserAvatar
}
/>
...
...
web/app/components/app/chat/thought/index.tsx
View file @
50a006fd
...
@@ -5,20 +5,22 @@ import cn from 'classnames'
...
@@ -5,20 +5,22 @@ import cn from 'classnames'
import
{
useTranslation
}
from
'react-i18next'
import
{
useTranslation
}
from
'react-i18next'
import
type
{
ThoughtItem
}
from
'../type'
import
type
{
ThoughtItem
}
from
'../type'
import
s
from
'./style.module.css'
import
s
from
'./style.module.css'
import
{
DataSet
,
Loading
as
LodingIcon
,
Search
,
ThoughtList
,
WebReader
}
from
'@/app/components/base/icons/src/public/thought'
import
{
DataSet
as
DataSetIcon
,
Loading
as
LodingIcon
,
Search
,
ThoughtList
,
WebReader
}
from
'@/app/components/base/icons/src/public/thought'
import
{
ChevronDown
}
from
'@/app/components/base/icons/src/vender/line/arrows'
import
{
ChevronDown
}
from
'@/app/components/base/icons/src/vender/line/arrows'
import
type
{
DataSet
}
from
'@/models/datasets'
// https://www.freecodecamp.org/news/how-to-write-a-regular-expression-for-a-url/
// https://www.freecodecamp.org/news/how-to-write-a-regular-expression-for-a-url/
const
urlRegex
=
/
(
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z
]{2,}(\.[
a-zA-Z
]{2,})(\.[
a-zA-Z
]{2,})?\/[
a-zA-Z0-9
]{2,}
|
((
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z
]{2,}(\.[
a-zA-Z
]{2,})(\.[
a-zA-Z
]{2,})?)
|
(
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z0-9
]{2,}\.[
a-zA-Z0-9
]{2,}\.[
a-zA-Z0-9
]{2,}(\.[
a-zA-Z0-9
]{2,})?
/gi
const
urlRegex
=
/
(
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z
]{2,}(\.[
a-zA-Z
]{2,})(\.[
a-zA-Z
]{2,})?\/[
a-zA-Z0-9
]{2,}
|
((
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z
]{2,}(\.[
a-zA-Z
]{2,})(\.[
a-zA-Z
]{2,})?)
|
(
https:
\/\/
www
\.
|http:
\/\/
www
\.
|https:
\/\/
|http:
\/\/)?[
a-zA-Z0-9
]{2,}\.[
a-zA-Z0-9
]{2,}\.[
a-zA-Z0-9
]{2,}(\.[
a-zA-Z0-9
]{2,})?
/gi
export
type
IThoughtProps
=
{
export
type
IThoughtProps
=
{
list
:
ThoughtItem
[]
list
:
ThoughtItem
[]
isThinking
?:
boolean
isThinking
?:
boolean
dataSets
?:
DataSet
[]
}
}
const
getIcon
=
(
toolId
:
string
)
=>
{
const
getIcon
=
(
toolId
:
string
)
=>
{
switch
(
toolId
)
{
switch
(
toolId
)
{
case
'dataset'
:
case
'dataset'
:
return
<
DataSet
/>
return
<
DataSet
Icon
/>
case
'web_reader'
:
case
'web_reader'
:
return
<
WebReader
/>
return
<
WebReader
/>
default
:
default
:
...
@@ -29,16 +31,20 @@ const getIcon = (toolId: string) => {
...
@@ -29,16 +31,20 @@ const getIcon = (toolId: string) => {
const
Thought
:
FC
<
IThoughtProps
>
=
({
const
Thought
:
FC
<
IThoughtProps
>
=
({
list
,
list
,
isThinking
,
isThinking
,
dataSets
,
})
=>
{
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
t
}
=
useTranslation
()
const
[
isShowDetail
,
setIsShowDetail
]
=
React
.
useState
(
false
)
const
[
isShowDetail
,
setIsShowDetail
]
=
React
.
useState
(
false
)
const
getThoughtText
=
(
item
:
ThoughtItem
)
=>
{
const
getThoughtText
=
(
item
:
ThoughtItem
)
=>
{
try
{
try
{
const
input
=
JSON
.
parse
(
item
.
tool_input
)
const
input
=
JSON
.
parse
(
item
.
tool_input
)
switch
(
item
.
tool
)
{
switch
(
item
.
tool
)
{
case
'dataset'
:
case
'dataset'
:
// debugger
// eslint-disable-next-line no-case-declarations
return
t
(
'explore.universalChat.thought.res.dataset'
,
{
input
:
input
.
dataset_id
})
const
datasetName
=
dataSets
?.
find
(
item
=>
item
.
id
===
input
.
dataset_id
)?.
name
||
'unknown dataset'
return
t
(
'explore.universalChat.thought.res.dataset'
).
replace
(
'{datasetName}'
,
`<span class="text-gray-700">
${
datasetName
}
</span>`
)
case
'web_reader'
:
case
'web_reader'
:
return
t
(
`explore.universalChat.thought.res.webReader.
${
!
input
.
cursor
?
'normal'
:
'hasPageInfo'
}
`
).
replace
(
'{url}'
,
`<a href="
${
input
.
url
}
" class="text-[#155EEF]">
${
input
.
url
}
</a>`
)
return
t
(
`explore.universalChat.thought.res.webReader.
${
!
input
.
cursor
?
'normal'
:
'hasPageInfo'
}
`
).
replace
(
'{url}'
,
`<a href="
${
input
.
url
}
" class="text-[#155EEF]">
${
input
.
url
}
</a>`
)
default
:
// google, wikipedia
default
:
// google, wikipedia
...
...
web/app/components/base/voice-input/index.tsx
View file @
50a006fd
...
@@ -86,7 +86,7 @@ const VoiceInput = ({
...
@@ -86,7 +86,7 @@ const VoiceInput = ({
const
formData
=
new
FormData
()
const
formData
=
new
FormData
()
formData
.
append
(
'file'
,
mp3File
)
formData
.
append
(
'file'
,
mp3File
)
let
url
=
''
let
url
=
'
/universal-chat/audio-to-text
'
let
isPublic
=
false
let
isPublic
=
false
if
(
params
.
token
)
{
if
(
params
.
token
)
{
...
...
web/app/components/explore/universal-chat/index.tsx
View file @
50a006fd
...
@@ -518,7 +518,6 @@ const Main: FC<IMainProps> = () => {
...
@@ -518,7 +518,6 @@ const Main: FC<IMainProps> = () => {
draft
.
push
({
...
questionItem
})
draft
.
push
({
...
questionItem
})
draft
.
push
({
...
responseItem
})
draft
.
push
({
...
responseItem
})
})
})
// console.log('start render thought')
setChatList
(
newListWithAnswer
)
setChatList
(
newListWithAnswer
)
},
},
onError
()
{
onError
()
{
...
@@ -663,6 +662,7 @@ const Main: FC<IMainProps> = () => {
...
@@ -663,6 +662,7 @@ const Main: FC<IMainProps> = () => {
isShowSuggestion=
{
doShowSuggestion
}
isShowSuggestion=
{
doShowSuggestion
}
suggestionList=
{
suggestQuestions
}
suggestionList=
{
suggestQuestions
}
isShowSpeechToText=
{
speechToTextConfig
?.
enabled
}
isShowSpeechToText=
{
speechToTextConfig
?.
enabled
}
dataSets=
{
dataSets
}
/>
/>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/i18n/lang/explore.en.ts
View file @
50a006fd
...
@@ -67,7 +67,7 @@ const translation = {
...
@@ -67,7 +67,7 @@ const translation = {
hasPageInfo
:
'Reading next page of {url}'
,
hasPageInfo
:
'Reading next page of {url}'
,
},
},
search
:
'Searching {{query}}'
,
search
:
'Searching {{query}}'
,
dataset
:
'Retrieving dataset {
{datasetName}
}'
,
dataset
:
'Retrieving dataset {
datasetName
}'
,
},
},
},
},
viewConfigDetailTip
:
'In conversation, cannot change above settings'
,
viewConfigDetailTip
:
'In conversation, cannot change above settings'
,
...
...
web/i18n/lang/explore.zh.ts
View file @
50a006fd
...
@@ -67,7 +67,7 @@ const translation = {
...
@@ -67,7 +67,7 @@ const translation = {
hasPageInfo
:
'解析链接 {url} 的下一页'
,
hasPageInfo
:
'解析链接 {url} 的下一页'
,
},
},
search
:
'搜索 {{query}}'
,
search
:
'搜索 {{query}}'
,
dataset
:
'检索数据集 {
{dataset}
}'
,
dataset
:
'检索数据集 {
datasetName
}'
,
},
},
},
},
viewConfigDetailTip
:
'在对话中,无法更改上述设置'
,
viewConfigDetailTip
:
'在对话中,无法更改上述设置'
,
...
...
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