mirror of
https://github.com/langgenius/webapp-conversation.git
synced 2025-12-08 17:32:27 +08:00
@ -4,25 +4,25 @@ import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type IAppUnavailableProps = {
|
||||
isUnknwonReason: boolean
|
||||
isUnknownReason: boolean
|
||||
errMessage?: string
|
||||
}
|
||||
|
||||
const AppUnavailable: FC<IAppUnavailableProps> = ({
|
||||
isUnknwonReason,
|
||||
isUnknownReason,
|
||||
errMessage,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
let message = errMessage
|
||||
if (!errMessage)
|
||||
message = (isUnknwonReason ? t('app.common.appUnkonwError') : t('app.common.appUnavailable')) as string
|
||||
message = (isUnknownReason ? t('app.common.appUnkonwError') : t('app.common.appUnavailable')) as string
|
||||
|
||||
return (
|
||||
<div className='flex items-center justify-center w-screen h-screen'>
|
||||
<h1 className='mr-5 h-[50px] leading-[50px] pr-5 text-[24px] font-medium'
|
||||
style={{
|
||||
borderRight: '1px solid rgba(0,0,0,.3)',
|
||||
}}>{(errMessage || isUnknwonReason) ? 500 : 404}</h1>
|
||||
}}>{(errMessage || isUnknownReason) ? 500 : 404}</h1>
|
||||
<div className='text-sm'>{message}</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -58,7 +58,7 @@ type IAnswerProps = {
|
||||
item: ChatItem
|
||||
feedbackDisabled: boolean
|
||||
onFeedback?: FeedbackFunc
|
||||
isResponsing?: boolean
|
||||
isResponding?: boolean
|
||||
allToolIcons?: Record<string, string | Emoji>
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ const Answer: FC<IAnswerProps> = ({
|
||||
item,
|
||||
feedbackDisabled = false,
|
||||
onFeedback,
|
||||
isResponsing,
|
||||
isResponding,
|
||||
allToolIcons,
|
||||
}) => {
|
||||
const { id, content, feedback, agent_thoughts, workflowProcess } = item
|
||||
@ -153,7 +153,7 @@ const Answer: FC<IAnswerProps> = ({
|
||||
<Thought
|
||||
thought={item}
|
||||
allToolIcons={allToolIcons || {}}
|
||||
isFinished={!!item.observation || !isResponsing}
|
||||
isFinished={!!item.observation || !isResponding}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -169,7 +169,7 @@ const Answer: FC<IAnswerProps> = ({
|
||||
<div key={id}>
|
||||
<div className='flex items-start'>
|
||||
<div className={`${s.answerIcon} w-10 h-10 shrink-0`}>
|
||||
{isResponsing
|
||||
{isResponding
|
||||
&& <div className={s.typeingIcon}>
|
||||
<LoadingAnim type='avatar' />
|
||||
</div>
|
||||
@ -181,7 +181,7 @@ const Answer: FC<IAnswerProps> = ({
|
||||
{workflowProcess && (
|
||||
<WorkflowProcess data={workflowProcess} hideInfo />
|
||||
)}
|
||||
{(isResponsing && (isAgentMode ? (!content && (agent_thoughts || []).filter(item => !!item.thought || !!item.tool).length === 0) : !content))
|
||||
{(isResponding && (isAgentMode ? (!content && (agent_thoughts || []).filter(item => !!item.thought || !!item.tool).length === 0) : !content))
|
||||
? (
|
||||
<div className='flex items-center justify-center w-6 h-5'>
|
||||
<LoadingAnim type='text' />
|
||||
|
||||
@ -30,7 +30,7 @@ export type IChatProps = {
|
||||
checkCanSend?: () => boolean
|
||||
onSend?: (message: string, files: VisionFile[]) => void
|
||||
useCurrentUserAvatar?: boolean
|
||||
isResponsing?: boolean
|
||||
isResponding?: boolean
|
||||
controlClearQuery?: number
|
||||
visionConfig?: VisionSettings
|
||||
}
|
||||
@ -43,7 +43,7 @@ const Chat: FC<IChatProps> = ({
|
||||
checkCanSend,
|
||||
onSend = () => { },
|
||||
useCurrentUserAvatar,
|
||||
isResponsing,
|
||||
isResponding,
|
||||
controlClearQuery,
|
||||
visionConfig,
|
||||
}) => {
|
||||
@ -95,7 +95,7 @@ const Chat: FC<IChatProps> = ({
|
||||
if (!files.find(item => item.type === TransferMethod.local_file && !item.fileId)) {
|
||||
if (files.length)
|
||||
onClear()
|
||||
if (!isResponsing)
|
||||
if (!isResponding)
|
||||
setQuery('')
|
||||
}
|
||||
}
|
||||
@ -129,7 +129,7 @@ const Chat: FC<IChatProps> = ({
|
||||
item={item}
|
||||
feedbackDisabled={feedbackDisabled}
|
||||
onFeedback={onFeedback}
|
||||
isResponsing={isResponsing && isLast}
|
||||
isResponding={isResponding && isLast}
|
||||
/>
|
||||
}
|
||||
return (
|
||||
|
||||
@ -33,7 +33,7 @@ const Main: FC = () => {
|
||||
* app info
|
||||
*/
|
||||
const [appUnavailable, setAppUnavailable] = useState<boolean>(false)
|
||||
const [isUnknwonReason, setIsUnknwonReason] = useState<boolean>(false)
|
||||
const [isUnknownReason, setIsUnknownReason] = useState<boolean>(false)
|
||||
const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null)
|
||||
const [inited, setInited] = useState<boolean>(false)
|
||||
// in mobile, show sidebar by click button
|
||||
@ -86,7 +86,7 @@ const Main: FC = () => {
|
||||
setCurrInputs(inputs)
|
||||
setChatStarted()
|
||||
// parse variables in introduction
|
||||
setChatList(generateNewChatListWithOpenstatement('', inputs))
|
||||
setChatList(generateNewChatListWithOpenStatement('', inputs))
|
||||
}
|
||||
const hasSetInputs = (() => {
|
||||
if (!isNewConversation)
|
||||
@ -121,10 +121,10 @@ const Main: FC = () => {
|
||||
}
|
||||
|
||||
// update chat list of current conversation
|
||||
if (!isNewConversation && !conversationIdChangeBecauseOfNew && !isResponsing) {
|
||||
if (!isNewConversation && !conversationIdChangeBecauseOfNew && !isResponding) {
|
||||
fetchChatList(currConversationId).then((res: any) => {
|
||||
const { data } = res
|
||||
const newChatList: ChatItem[] = generateNewChatListWithOpenstatement(notSyncToStateIntroduction, notSyncToStateInputs)
|
||||
const newChatList: ChatItem[] = generateNewChatListWithOpenStatement(notSyncToStateIntroduction, notSyncToStateInputs)
|
||||
|
||||
data.forEach((item: any) => {
|
||||
newChatList.push({
|
||||
@ -148,7 +148,7 @@ const Main: FC = () => {
|
||||
}
|
||||
|
||||
if (isNewConversation && isChatStarted)
|
||||
setChatList(generateNewChatListWithOpenstatement())
|
||||
setChatList(generateNewChatListWithOpenStatement())
|
||||
}
|
||||
useEffect(handleConversationSwitch, [currConversationId, inited])
|
||||
|
||||
@ -176,7 +176,7 @@ const Main: FC = () => {
|
||||
chatListDomRef.current.scrollTop = chatListDomRef.current.scrollHeight
|
||||
}, [chatList, currConversationId])
|
||||
// user can not edit inputs if user had send message
|
||||
const canEditInpus = !chatList.some(item => item.isAnswer === false) && isNewConversation
|
||||
const canEditInputs = !chatList.some(item => item.isAnswer === false) && isNewConversation
|
||||
const createNewChat = () => {
|
||||
// if new chat is already exist, do not create new chat
|
||||
if (conversationList.some(item => item.id === '-1'))
|
||||
@ -193,21 +193,21 @@ const Main: FC = () => {
|
||||
}
|
||||
|
||||
// sometime introduction is not applied to state
|
||||
const generateNewChatListWithOpenstatement = (introduction?: string, inputs?: Record<string, any> | null) => {
|
||||
let caculatedIntroduction = introduction || conversationIntroduction || ''
|
||||
const caculatedPromptVariables = inputs || currInputs || null
|
||||
if (caculatedIntroduction && caculatedPromptVariables)
|
||||
caculatedIntroduction = replaceVarWithValues(caculatedIntroduction, promptConfig?.prompt_variables || [], caculatedPromptVariables)
|
||||
const generateNewChatListWithOpenStatement = (introduction?: string, inputs?: Record<string, any> | null) => {
|
||||
let calculatedIntroduction = introduction || conversationIntroduction || ''
|
||||
const calculatedPromptVariables = inputs || currInputs || null
|
||||
if (calculatedIntroduction && calculatedPromptVariables)
|
||||
calculatedIntroduction = replaceVarWithValues(calculatedIntroduction, promptConfig?.prompt_variables || [], calculatedPromptVariables)
|
||||
|
||||
const openstatement = {
|
||||
id: `${Date.now()}`,
|
||||
content: caculatedIntroduction,
|
||||
content: calculatedIntroduction,
|
||||
isAnswer: true,
|
||||
feedbackDisabled: true,
|
||||
isOpeningStatement: isShowPrompt,
|
||||
}
|
||||
if (caculatedIntroduction)
|
||||
return [openstatement]
|
||||
if (calculatedIntroduction)
|
||||
return [openStatement]
|
||||
|
||||
return []
|
||||
}
|
||||
@ -255,14 +255,14 @@ const Main: FC = () => {
|
||||
setAppUnavailable(true)
|
||||
}
|
||||
else {
|
||||
setIsUnknwonReason(true)
|
||||
setIsUnknownReason(true)
|
||||
setAppUnavailable(true)
|
||||
}
|
||||
}
|
||||
})()
|
||||
}, [])
|
||||
|
||||
const [isResponsing, { setTrue: setResponsingTrue, setFalse: setResponsingFalse }] = useBoolean(false)
|
||||
const [isResponding, { setTrue: setRespondingTrue, setFalse: setRespondingFalse }] = useBoolean(false)
|
||||
const [abortController, setAbortController] = useState<AbortController | null>(null)
|
||||
const { notify } = Toast
|
||||
const logError = (message: string) => {
|
||||
@ -279,8 +279,8 @@ const Main: FC = () => {
|
||||
const inputLens = Object.values(currInputs).length
|
||||
const promptVariablesLens = promptConfig.prompt_variables.length
|
||||
|
||||
const emytyInput = inputLens < promptVariablesLens || Object.values(currInputs).find(v => !v)
|
||||
if (emytyInput) {
|
||||
const emptyInput = inputLens < promptVariablesLens || Object.values(currInputs).find(v => !v)
|
||||
if (emptyInput) {
|
||||
logError(t('app.errorMessage.valueOfVarRequired'))
|
||||
return false
|
||||
}
|
||||
@ -291,7 +291,7 @@ const Main: FC = () => {
|
||||
const [openingSuggestedQuestions, setOpeningSuggestedQuestions] = useState<string[]>([])
|
||||
const [messageTaskId, setMessageTaskId] = useState('')
|
||||
const [hasStopResponded, setHasStopResponded, getHasStopResponded] = useGetState(false)
|
||||
const [isResponsingConIsCurrCon, setIsResponsingConCurrCon, getIsResponsingConIsCurrCon] = useGetState(true)
|
||||
const [isRespondingConIsCurrCon, setIsRespondingConCurrCon, getIsRespondingConIsCurrCon] = useGetState(true)
|
||||
const [userQuery, setUserQuery] = useState('')
|
||||
|
||||
const updateCurrentQA = ({
|
||||
@ -318,7 +318,7 @@ const Main: FC = () => {
|
||||
}
|
||||
|
||||
const handleSend = async (message: string, files?: VisionFile[]) => {
|
||||
if (isResponsing) {
|
||||
if (isResponding) {
|
||||
notify({ type: 'info', message: t('app.errorMessage.waitForResponse') })
|
||||
return
|
||||
}
|
||||
@ -340,7 +340,7 @@ const Main: FC = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// qustion
|
||||
// question
|
||||
const questionId = `question-${Date.now()}`
|
||||
const questionItem = {
|
||||
id: questionId,
|
||||
@ -374,7 +374,7 @@ const Main: FC = () => {
|
||||
const prevTempNewConversationId = getCurrConversationId() || '-1'
|
||||
let tempNewConversationId = ''
|
||||
|
||||
setResponsingTrue()
|
||||
setRespondingTrue()
|
||||
sendChatMessage(data, {
|
||||
getAbortController: (abortController) => {
|
||||
setAbortController(abortController)
|
||||
@ -399,7 +399,7 @@ const Main: FC = () => {
|
||||
setMessageTaskId(taskId)
|
||||
// has switched to other conversation
|
||||
if (prevTempNewConversationId !== getCurrConversationId()) {
|
||||
setIsResponsingConCurrCon(false)
|
||||
setIsRespondingConCurrCon(false)
|
||||
return
|
||||
}
|
||||
updateCurrentQA({
|
||||
@ -426,7 +426,7 @@ const Main: FC = () => {
|
||||
resetNewConversationInputs()
|
||||
setChatNotStarted()
|
||||
setCurrConversationId(tempNewConversationId, APP_ID, true)
|
||||
setResponsingFalse()
|
||||
setRespondingFalse()
|
||||
},
|
||||
onFile(file) {
|
||||
const lastThought = responseItem.agent_thoughts?.[responseItem.agent_thoughts?.length - 1]
|
||||
@ -465,7 +465,7 @@ const Main: FC = () => {
|
||||
}
|
||||
// has switched to other conversation
|
||||
if (prevTempNewConversationId !== getCurrConversationId()) {
|
||||
setIsResponsingConCurrCon(false)
|
||||
setIsRespondingConCurrCon(false)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -520,7 +520,7 @@ const Main: FC = () => {
|
||||
))
|
||||
},
|
||||
onError() {
|
||||
setResponsingFalse()
|
||||
setRespondingFalse()
|
||||
// role back placeholder answer
|
||||
setChatList(produce(getChatList(), (draft) => {
|
||||
draft.splice(draft.findIndex(item => item.id === placeholderAnswerId), 1)
|
||||
@ -604,7 +604,7 @@ const Main: FC = () => {
|
||||
}
|
||||
|
||||
if (appUnavailable)
|
||||
return <AppUnavailable isUnknwonReason={isUnknwonReason} errMessage={!hasSetAppConfig ? 'Please set APP_ID and API_KEY in config/index.tsx' : ''} />
|
||||
return <AppUnavailable isUnknownReason={isUnknownReason} errMessage={!hasSetAppConfig ? 'Please set APP_ID and API_KEY in config/index.tsx' : ''} />
|
||||
|
||||
if (!APP_ID || !APP_INFO || !promptConfig)
|
||||
return <Loading type='app' />
|
||||
@ -639,7 +639,7 @@ const Main: FC = () => {
|
||||
siteInfo={APP_INFO}
|
||||
promptConfig={promptConfig}
|
||||
onStartChat={handleStartChat}
|
||||
canEidtInpus={canEditInpus}
|
||||
canEditInputs={canEditInputs}
|
||||
savedInputs={currInputs as Record<string, any>}
|
||||
onInputsChange={setCurrInputs}
|
||||
></ConfigSence>
|
||||
@ -652,7 +652,7 @@ const Main: FC = () => {
|
||||
chatList={chatList}
|
||||
onSend={handleSend}
|
||||
onFeedback={handleFeedback}
|
||||
isResponsing={isResponsing}
|
||||
isResponding={isResponding}
|
||||
checkCanSend={checkCanSend}
|
||||
visionConfig={visionConfig}
|
||||
/>
|
||||
|
||||
@ -20,7 +20,7 @@ export type IWelcomeProps = {
|
||||
siteInfo: AppInfo
|
||||
promptConfig: PromptConfig
|
||||
onStartChat: (inputs: Record<string, any>) => void
|
||||
canEidtInpus: boolean
|
||||
canEditInputs: boolean
|
||||
savedInputs: Record<string, any>
|
||||
onInputsChange: (inputs: Record<string, any>) => void
|
||||
}
|
||||
@ -32,7 +32,7 @@ const Welcome: FC<IWelcomeProps> = ({
|
||||
siteInfo,
|
||||
promptConfig,
|
||||
onStartChat,
|
||||
canEidtInpus,
|
||||
canEditInputs,
|
||||
savedInputs,
|
||||
onInputsChange,
|
||||
}) => {
|
||||
@ -131,8 +131,8 @@ const Welcome: FC<IWelcomeProps> = ({
|
||||
const canChat = () => {
|
||||
const inputLens = Object.values(inputs).length
|
||||
const promptVariablesLens = promptConfig.prompt_variables.length
|
||||
const emytyInput = inputLens < promptVariablesLens || Object.values(inputs).filter(v => v === '').length > 0
|
||||
if (emytyInput) {
|
||||
const emptyInput = inputLens < promptVariablesLens || Object.values(inputs).filter(v => v === '').length > 0
|
||||
if (emptyInput) {
|
||||
logError(t('app.errorMessage.valueOfVarRequired'))
|
||||
return false
|
||||
}
|
||||
@ -217,7 +217,7 @@ const Welcome: FC<IWelcomeProps> = ({
|
||||
}
|
||||
|
||||
const renderHasSetInputsPublic = () => {
|
||||
if (!canEidtInpus) {
|
||||
if (!canEditInputs) {
|
||||
return (
|
||||
<TemplateVarPanel
|
||||
isFold={false}
|
||||
@ -260,7 +260,7 @@ const Welcome: FC<IWelcomeProps> = ({
|
||||
}
|
||||
|
||||
const renderHasSetInputsPrivate = () => {
|
||||
if (!canEidtInpus || !hasVar)
|
||||
if (!canEditInputs || !hasVar)
|
||||
return null
|
||||
|
||||
return (
|
||||
@ -284,7 +284,7 @@ const Welcome: FC<IWelcomeProps> = ({
|
||||
}
|
||||
|
||||
const renderHasSetInputs = () => {
|
||||
if ((!isPublicVersion && !canEidtInpus) || !hasVar)
|
||||
if ((!isPublicVersion && !canEditInputs) || !hasVar)
|
||||
return null
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user