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
fb62017e
Unverified
Commit
fb62017e
authored
Aug 18, 2023
by
zxhlyh
Committed by
GitHub
Aug 18, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix/embedding chat (#899)
Co-authored-by:
Joel
<
iamjoel007@gmail.com
>
parent
9adbeade
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
36 additions
and
95 deletions
+36
-95
index.tsx
web/app/components/share/chatbot/index.tsx
+28
-93
share-app.en.ts
web/i18n/lang/share-app.en.ts
+2
-0
share-app.zh.ts
web/i18n/lang/share-app.zh.ts
+2
-0
base.ts
web/service/base.ts
+4
-2
No files found.
web/app/components/share/chatbot/index.tsx
View file @
fb62017e
...
@@ -12,13 +12,12 @@ import AppUnavailable from '../../base/app-unavailable'
...
@@ -12,13 +12,12 @@ import AppUnavailable from '../../base/app-unavailable'
import
useConversation
from
'./hooks/use-conversation'
import
useConversation
from
'./hooks/use-conversation'
import
s
from
'./style.module.css'
import
s
from
'./style.module.css'
import
{
ToastContext
}
from
'@/app/components/base/toast'
import
{
ToastContext
}
from
'@/app/components/base/toast'
import
Sidebar
from
'@/app/components/share/chatbot/sidebar'
import
ConfigScene
from
'@/app/components/share/chatbot/config-scence'
import
ConfigScene
from
'@/app/components/share/chatbot/config-scence'
import
Header
from
'@/app/components/share/header'
import
Header
from
'@/app/components/share/header'
import
{
/* delConversation, */
fetchAppInfo
,
fetchAppParams
,
fetchChatList
,
fetchConversations
,
fetchSuggestedQuestions
,
pinConversation
,
sendChatMessage
,
stopChatMessageResponding
,
unpinConversation
,
updateFeedback
}
from
'@/service/share'
import
{
fetchAppInfo
,
fetchAppParams
,
fetchChatList
,
fetchConversations
,
fetchSuggestedQuestions
,
sendChatMessage
,
stopChatMessageResponding
,
updateFeedback
}
from
'@/service/share'
import
type
{
ConversationItem
,
SiteInfo
}
from
'@/models/share'
import
type
{
ConversationItem
,
SiteInfo
}
from
'@/models/share'
import
type
{
PromptConfig
,
SuggestedQuestionsAfterAnswerConfig
}
from
'@/models/debug'
import
type
{
PromptConfig
,
SuggestedQuestionsAfterAnswerConfig
}
from
'@/models/debug'
import
type
{
Feedbacktype
,
IChatItem
}
from
'@/app/components/app/chat'
import
type
{
Feedbacktype
,
IChatItem
}
from
'@/app/components/app/chat
/type
'
import
Chat
from
'@/app/components/app/chat'
import
Chat
from
'@/app/components/app/chat'
import
{
changeLanguage
}
from
'@/i18n/i18next-config'
import
{
changeLanguage
}
from
'@/i18n/i18next-config'
import
useBreakpoints
,
{
MediaType
}
from
'@/hooks/use-breakpoints'
import
useBreakpoints
,
{
MediaType
}
from
'@/hooks/use-breakpoints'
...
@@ -26,7 +25,7 @@ import Loading from '@/app/components/base/loading'
...
@@ -26,7 +25,7 @@ import Loading from '@/app/components/base/loading'
import
{
replaceStringWithValues
}
from
'@/app/components/app/configuration/prompt-value-panel'
import
{
replaceStringWithValues
}
from
'@/app/components/app/configuration/prompt-value-panel'
import
{
userInputsFormToPromptVariables
}
from
'@/utils/model-config'
import
{
userInputsFormToPromptVariables
}
from
'@/utils/model-config'
import
type
{
InstalledApp
}
from
'@/models/explore'
import
type
{
InstalledApp
}
from
'@/models/explore'
// import Confirm from '@/app/components/base/confirm
'
import
{
AlertTriangle
}
from
'@/app/components/base/icons/src/vender/solid/alertsAndFeedback
'
export
type
IMainProps
=
{
export
type
IMainProps
=
{
isInstalledApp
?:
boolean
isInstalledApp
?:
boolean
...
@@ -52,8 +51,6 @@ const Main: FC<IMainProps> = ({
...
@@ -52,8 +51,6 @@ const Main: FC<IMainProps> = ({
const
[
promptConfig
,
setPromptConfig
]
=
useState
<
PromptConfig
|
null
>
(
null
)
const
[
promptConfig
,
setPromptConfig
]
=
useState
<
PromptConfig
|
null
>
(
null
)
const
[
inited
,
setInited
]
=
useState
<
boolean
>
(
false
)
const
[
inited
,
setInited
]
=
useState
<
boolean
>
(
false
)
const
[
plan
,
setPlan
]
=
useState
<
string
>
(
'basic'
)
// basic/plus/pro
const
[
plan
,
setPlan
]
=
useState
<
string
>
(
'basic'
)
// basic/plus/pro
// in mobile, show sidebar by click button
const
[
isShowSidebar
,
{
setTrue
:
showSidebar
,
setFalse
:
hideSidebar
}]
=
useBoolean
(
false
)
// Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
// Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
siteInfo
?.
title
)
{
if
(
siteInfo
?.
title
)
{
...
@@ -124,37 +121,6 @@ const Main: FC<IMainProps> = ({
...
@@ -124,37 +121,6 @@ const Main: FC<IMainProps> = ({
setControlUpdateConversationList
(
Date
.
now
())
setControlUpdateConversationList
(
Date
.
now
())
}
}
const
handlePin
=
async
(
id
:
string
)
=>
{
await
pinConversation
(
isInstalledApp
,
installedAppInfo
?.
id
,
id
)
notify
({
type
:
'success'
,
message
:
t
(
'common.api.success'
)
})
noticeUpdateList
()
}
const
handleUnpin
=
async
(
id
:
string
)
=>
{
await
unpinConversation
(
isInstalledApp
,
installedAppInfo
?.
id
,
id
)
notify
({
type
:
'success'
,
message
:
t
(
'common.api.success'
)
})
noticeUpdateList
()
}
const
[
isShowConfirm
,
{
setTrue
:
showConfirm
,
setFalse
:
hideConfirm
}]
=
useBoolean
(
false
)
const
[
toDeleteConversationId
,
setToDeleteConversationId
]
=
useState
(
''
)
const
handleDelete
=
(
id
:
string
)
=>
{
setToDeleteConversationId
(
id
)
hideSidebar
()
// mobile
showConfirm
()
}
// const didDelete = async () => {
// await delConversation(isInstalledApp, installedAppInfo?.id, toDeleteConversationId)
// notify({ type: 'success', message: t('common.api.success') })
// hideConfirm()
// if (currConversationId === toDeleteConversationId)
// handleConversationIdChange('-1')
// noticeUpdateList()
// }
const
[
suggestedQuestionsAfterAnswerConfig
,
setSuggestedQuestionsAfterAnswerConfig
]
=
useState
<
SuggestedQuestionsAfterAnswerConfig
|
null
>
(
null
)
const
[
suggestedQuestionsAfterAnswerConfig
,
setSuggestedQuestionsAfterAnswerConfig
]
=
useState
<
SuggestedQuestionsAfterAnswerConfig
|
null
>
(
null
)
const
[
speechToTextConfig
,
setSpeechToTextConfig
]
=
useState
<
SuggestedQuestionsAfterAnswerConfig
|
null
>
(
null
)
const
[
speechToTextConfig
,
setSpeechToTextConfig
]
=
useState
<
SuggestedQuestionsAfterAnswerConfig
|
null
>
(
null
)
...
@@ -235,20 +201,6 @@ const Main: FC<IMainProps> = ({
...
@@ -235,20 +201,6 @@ const Main: FC<IMainProps> = ({
}
}
useEffect
(
handleConversationSwitch
,
[
currConversationId
,
inited
])
useEffect
(
handleConversationSwitch
,
[
currConversationId
,
inited
])
const
handleConversationIdChange
=
(
id
:
string
)
=>
{
if
(
id
===
'-1'
)
{
createNewChat
()
setConversationIdChangeBecauseOfNew
(
true
)
}
else
{
setConversationIdChangeBecauseOfNew
(
false
)
}
// trigger handleConversationSwitch
setCurrConversationId
(
id
,
appId
)
setIsShowSuggestion
(
false
)
hideSidebar
()
}
/*
/*
* chat info. chat is under conversation.
* chat info. chat is under conversation.
*/
*/
...
@@ -416,6 +368,7 @@ const Main: FC<IMainProps> = ({
...
@@ -416,6 +368,7 @@ const Main: FC<IMainProps> = ({
const
[
suggestQuestions
,
setSuggestQuestions
]
=
useState
<
string
[]
>
([])
const
[
suggestQuestions
,
setSuggestQuestions
]
=
useState
<
string
[]
>
([])
const
[
messageTaskId
,
setMessageTaskId
]
=
useState
(
''
)
const
[
messageTaskId
,
setMessageTaskId
]
=
useState
(
''
)
const
[
hasStopResponded
,
setHasStopResponded
,
getHasStopResponded
]
=
useGetState
(
false
)
const
[
hasStopResponded
,
setHasStopResponded
,
getHasStopResponded
]
=
useGetState
(
false
)
const
[
shouldReload
,
setShouldReload
]
=
useState
(
false
)
const
handleSend
=
async
(
message
:
string
)
=>
{
const
handleSend
=
async
(
message
:
string
)
=>
{
if
(
isResponsing
)
{
if
(
isResponsing
)
{
...
@@ -500,7 +453,9 @@ const Main: FC<IMainProps> = ({
...
@@ -500,7 +453,9 @@ const Main: FC<IMainProps> = ({
setIsShowSuggestion
(
true
)
setIsShowSuggestion
(
true
)
}
}
},
},
onError
()
{
onError
(
errorMessage
,
errorCode
)
{
if
([
'provider_not_initialize'
,
'completion_request_error'
].
includes
(
errorCode
as
string
))
setShouldReload
(
true
)
setResponsingFalse
()
setResponsingFalse
()
// role back placeholder answer
// role back placeholder answer
setChatList
(
produce
(
getChatList
(),
(
draft
)
=>
{
setChatList
(
produce
(
getChatList
(),
(
draft
)
=>
{
...
@@ -525,31 +480,11 @@ const Main: FC<IMainProps> = ({
...
@@ -525,31 +480,11 @@ const Main: FC<IMainProps> = ({
notify
({
type
:
'success'
,
message
:
t
(
'common.api.success'
)
})
notify
({
type
:
'success'
,
message
:
t
(
'common.api.success'
)
})
}
}
const
renderSidebar
=
()
=>
{
const
handleReload
=
()
=>
{
if
(
!
appId
||
!
siteInfo
||
!
promptConfig
)
setCurrConversationId
(
'-1'
,
appId
,
false
)
return
null
setChatNotStarted
()
return
(
setShouldReload
(
false
)
<
Sidebar
createNewChat
()
list=
{
conversationList
}
isClearConversationList=
{
isClearConversationList
}
pinnedList=
{
pinnedConversationList
}
isClearPinnedConversationList=
{
isClearPinnedConversationList
}
onMoreLoaded=
{
onMoreLoaded
}
onPinnedMoreLoaded=
{
onPinnedMoreLoaded
}
isNoMore=
{
!
hasMore
}
isPinnedNoMore=
{
!
hasPinnedMore
}
onCurrentIdChange=
{
handleConversationIdChange
}
currentId=
{
currConversationId
}
copyRight=
{
siteInfo
.
copyright
||
siteInfo
.
title
}
isInstalledApp=
{
isInstalledApp
}
installedAppId=
{
installedAppInfo
?.
id
}
siteInfo=
{
siteInfo
}
onPin=
{
handlePin
}
onUnpin=
{
handleUnpin
}
controlUpdateList=
{
controlUpdateConversationList
}
onDelete=
{
handleDelete
}
/>
)
}
}
const
difyIcon
=
(
const
difyIcon
=
(
...
@@ -571,24 +506,9 @@ const Main: FC<IMainProps> = ({
...
@@ -571,24 +506,9 @@ const Main: FC<IMainProps> = ({
icon_background=
{
siteInfo
.
icon_background
}
icon_background=
{
siteInfo
.
icon_background
}
isEmbedScene=
{
true
}
isEmbedScene=
{
true
}
isMobile=
{
isMobile
}
isMobile=
{
isMobile
}
// onShowSideBar={showSidebar}
// onCreateNewChat={() => handleConversationIdChange('-1')}
/>
/>
<
div
className=
{
'flex bg-white overflow-hidden'
}
>
<
div
className=
{
'flex bg-white overflow-hidden'
}
>
{
/* sidebar */
}
{
/* {!isMobile && renderSidebar()} */
}
{
/* {isMobile && isShowSidebar && (
<div className='fixed inset-0 z-50'
style={{ backgroundColor: 'rgba(35, 56, 118, 0.2)' }}
onClick={hideSidebar}
>
<div className='inline-block' onClick={e => e.stopPropagation()}>
{renderSidebar()}
</div>
</div>
)} */
}
{
/* main */
}
<
div
className=
{
cn
(
<
div
className=
{
cn
(
isInstalledApp
?
s
.
installedApp
:
'h-[calc(100vh_-_3rem)]'
,
isInstalledApp
?
s
.
installedApp
:
'h-[calc(100vh_-_3rem)]'
,
'flex-grow flex flex-col overflow-y-auto'
,
'flex-grow flex flex-col overflow-y-auto'
,
...
@@ -606,7 +526,22 @@ const Main: FC<IMainProps> = ({
...
@@ -606,7 +526,22 @@ const Main: FC<IMainProps> = ({
onInputsChange=
{
setCurrInputs
}
onInputsChange=
{
setCurrInputs
}
plan=
{
plan
}
plan=
{
plan
}
></
ConfigScene
>
></
ConfigScene
>
{
shouldReload
&&
(
<
div
className=
'flex items-center justify-between mb-5 px-4 py-2 bg-[#FEF0C7]'
>
<
div
className=
'flex items-center text-xs font-medium text-[#DC6803]'
>
<
AlertTriangle
className=
'mr-2 w-4 h-4'
/>
{
t
(
'share.chat.temporarySystemIssue'
)
}
</
div
>
<
div
className=
'flex items-center px-3 h-7 bg-white shadow-xs rounded-md text-xs font-medium text-gray-700 cursor-pointer'
onClick=
{
handleReload
}
>
{
t
(
'share.chat.tryToSolve'
)
}
</
div
>
</
div
>
)
}
{
{
hasSetInputs
&&
(
hasSetInputs
&&
(
<
div
className=
{
cn
(
doShowSuggestion
?
'pb-[140px]'
:
(
isResponsing
?
'pb-[113px]'
:
'pb-[76px]'
),
'relative grow h-[200px] pc:w-[794px] max-w-full mobile:w-full mx-auto mb-3.5 overflow-hidden'
)
}
>
<
div
className=
{
cn
(
doShowSuggestion
?
'pb-[140px]'
:
(
isResponsing
?
'pb-[113px]'
:
'pb-[76px]'
),
'relative grow h-[200px] pc:w-[794px] max-w-full mobile:w-full mx-auto mb-3.5 overflow-hidden'
)
}
>
...
...
web/i18n/lang/share-app.en.ts
View file @
fb62017e
...
@@ -27,6 +27,8 @@ const translation = {
...
@@ -27,6 +27,8 @@ const translation = {
title
:
'Delete conversation'
,
title
:
'Delete conversation'
,
content
:
'Are you sure you want to delete this conversation?'
,
content
:
'Are you sure you want to delete this conversation?'
,
},
},
tryToSolve
:
'Try to solve'
,
temporarySystemIssue
:
'Sorry, temporary system issue.'
,
},
},
generation
:
{
generation
:
{
tabs
:
{
tabs
:
{
...
...
web/i18n/lang/share-app.zh.ts
View file @
fb62017e
...
@@ -23,6 +23,8 @@ const translation = {
...
@@ -23,6 +23,8 @@ const translation = {
title
:
'删除对话'
,
title
:
'删除对话'
,
content
:
'您确定要删除此对话吗?'
,
content
:
'您确定要删除此对话吗?'
,
},
},
tryToSolve
:
'尝试解决'
,
temporarySystemIssue
:
'抱歉,临时系统问题。'
,
},
},
generation
:
{
generation
:
{
tabs
:
{
tabs
:
{
...
...
web/service/base.ts
View file @
fb62017e
...
@@ -28,12 +28,13 @@ export type IOnDataMoreInfo = {
...
@@ -28,12 +28,13 @@ export type IOnDataMoreInfo = {
taskId
?:
string
taskId
?:
string
messageId
:
string
messageId
:
string
errorMessage
?:
string
errorMessage
?:
string
errorCode
?:
string
}
}
export
type
IOnData
=
(
message
:
string
,
isFirstMessage
:
boolean
,
moreInfo
:
IOnDataMoreInfo
)
=>
void
export
type
IOnData
=
(
message
:
string
,
isFirstMessage
:
boolean
,
moreInfo
:
IOnDataMoreInfo
)
=>
void
export
type
IOnThought
=
(
though
:
ThoughtItem
)
=>
void
export
type
IOnThought
=
(
though
:
ThoughtItem
)
=>
void
export
type
IOnCompleted
=
(
hasError
?:
boolean
)
=>
void
export
type
IOnCompleted
=
(
hasError
?:
boolean
)
=>
void
export
type
IOnError
=
(
msg
:
string
)
=>
void
export
type
IOnError
=
(
msg
:
string
,
code
?:
string
)
=>
void
type
IOtherOptions
=
{
type
IOtherOptions
=
{
isPublicAPI
?:
boolean
isPublicAPI
?:
boolean
...
@@ -102,6 +103,7 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted
...
@@ -102,6 +103,7 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted
conversationId
:
undefined
,
conversationId
:
undefined
,
messageId
:
''
,
messageId
:
''
,
errorMessage
:
bufferObj
.
message
,
errorMessage
:
bufferObj
.
message
,
errorCode
:
bufferObj
.
code
,
})
})
hasError
=
true
hasError
=
true
onCompleted
&&
onCompleted
(
true
)
onCompleted
&&
onCompleted
(
true
)
...
@@ -345,7 +347,7 @@ export const ssePost = (url: string, fetchOptions: any, { isPublicAPI = false, o
...
@@ -345,7 +347,7 @@ export const ssePost = (url: string, fetchOptions: any, { isPublicAPI = false, o
return
handleStream
(
res
,
(
str
:
string
,
isFirstMessage
:
boolean
,
moreInfo
:
IOnDataMoreInfo
)
=>
{
return
handleStream
(
res
,
(
str
:
string
,
isFirstMessage
:
boolean
,
moreInfo
:
IOnDataMoreInfo
)
=>
{
if
(
moreInfo
.
errorMessage
)
{
if
(
moreInfo
.
errorMessage
)
{
// debugger
// debugger
onError
?.(
moreInfo
.
errorMessage
)
onError
?.(
moreInfo
.
errorMessage
,
moreInfo
.
errorCode
)
if
(
moreInfo
.
errorMessage
!==
'AbortError: The user aborted a request.'
)
if
(
moreInfo
.
errorMessage
!==
'AbortError: The user aborted a request.'
)
Toast
.
notify
({
type
:
'error'
,
message
:
moreInfo
.
errorMessage
})
Toast
.
notify
({
type
:
'error'
,
message
:
moreInfo
.
errorMessage
})
return
return
...
...
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