refactor: replace react markdown with streamdown (#32971)

Co-authored-by: Stephen Zhou <hi@hyoban.cc>
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
This commit is contained in:
Wu Tianwei
2026-03-10 17:02:37 +08:00
committed by GitHub
parent 2a468da440
commit 75bbb616ea
36 changed files with 1055 additions and 753 deletions

View File

@ -158,7 +158,7 @@ const Answer: FC<AnswerProps> = ({
<div className={cn('group relative pr-10', chatAnswerContainerInner)}>
<div
ref={humanInputFormContainerRef}
className={cn('body-lg-regular relative inline-block w-full max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary')}
className={cn('relative inline-block w-full max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary body-lg-regular')}
>
{
!responding && contentIsEmpty && !hasAgentThoughts && (
@ -227,7 +227,7 @@ const Answer: FC<AnswerProps> = ({
<div className="absolute -top-2 left-6 h-3 w-0.5 bg-chat-answer-human-input-form-divider-bg" />
<div
ref={contentRef}
className="body-lg-regular relative inline-block w-full max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary"
className="relative inline-block w-full max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary body-lg-regular"
>
{
!responding && (
@ -322,7 +322,7 @@ const Answer: FC<AnswerProps> = ({
<div className={cn('group relative pr-10', chatAnswerContainerInner)}>
<div
ref={contentRef}
className={cn('body-lg-regular relative inline-block max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary', workflowProcess && 'w-full')}
className={cn('relative inline-block max-w-full rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary body-lg-regular', workflowProcess && 'w-full')}
>
{
!responding && (

View File

@ -112,7 +112,7 @@ const ChatInputArea = ({
if (onSend) {
const { files, setFiles } = filesStore.getState()
if (files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)) {
if (files.some(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)) {
notify({ type: 'info', message: t('errorMessage.waitForFileUpload', { ns: 'appDebug' }) })
return
}
@ -215,14 +215,14 @@ const ChatInputArea = ({
<div className="relative flex w-full grow items-center">
<div
ref={textValueRef}
className="body-lg-regular pointer-events-none invisible absolute h-auto w-auto whitespace-pre p-1 leading-6"
className="pointer-events-none invisible absolute h-auto w-auto whitespace-pre p-1 leading-6 body-lg-regular"
>
{query}
</div>
<Textarea
ref={ref => textareaRef.current = ref as any}
className={cn(
'body-lg-regular w-full resize-none bg-transparent p-1 leading-6 text-text-primary outline-none',
'w-full resize-none bg-transparent p-1 leading-6 text-text-primary outline-none body-lg-regular',
)}
placeholder={decode(t(readonly ? 'chat.inputDisabledPlaceholder' : 'chat.inputPlaceholder', { ns: 'common', botName }) || '')}
autoFocus

View File

@ -299,7 +299,7 @@ export const useChat = (
updateChatTreeNode(messageId, (responseItem) => {
const lastThought = responseItem.agent_thoughts?.[responseItem.agent_thoughts?.length - 1]
if (lastThought) {
responseItem.agent_thoughts![responseItem.agent_thoughts!.length - 1].message_files = [...(lastThought as any).message_files, convertedFile]
responseItem.agent_thoughts!.at(-1)!.message_files = [...(lastThought as any).message_files, convertedFile]
}
else {
const currentFiles = (responseItem.message_files as FileEntity[] | undefined) ?? []
@ -321,8 +321,8 @@ export const useChat = (
responseItem.agent_thoughts.push(thought)
}
else {
const lastThought = responseItem.agent_thoughts[responseItem.agent_thoughts.length - 1]
if (lastThought.id === thought.id) {
const lastThought = responseItem.agent_thoughts.at(-1)
if (lastThought?.id === thought.id) {
thought.thought = lastThought.thought
thought.message_files = lastThought.message_files
responseItem.agent_thoughts[responseItem.agent_thoughts.length - 1] = thought
@ -743,7 +743,7 @@ export const useChat = (
content: isUseAgentThought ? '' : newResponseItem.answer,
log: [
...newResponseItem.message,
...(newResponseItem.message[newResponseItem.message.length - 1].role !== 'assistant'
...(newResponseItem.message.at(-1).role !== 'assistant'
? [
{
role: 'assistant',
@ -809,7 +809,7 @@ export const useChat = (
const lastThought = responseItem.agent_thoughts?.[responseItem.agent_thoughts?.length - 1]
if (lastThought) {
const thought = lastThought as { message_files?: FileEntity[] }
responseItem.agent_thoughts![responseItem.agent_thoughts!.length - 1].message_files = [...(thought.message_files ?? []), convertedFile]
responseItem.agent_thoughts!.at(-1)!.message_files = [...(thought.message_files ?? []), convertedFile]
}
// For non-agent mode, add files directly to responseItem.message_files
else {
@ -836,7 +836,7 @@ export const useChat = (
response.agent_thoughts.push(thought)
}
else {
const lastThought = response.agent_thoughts[response.agent_thoughts.length - 1]
const lastThought = response.agent_thoughts.at(-1)
// thought changed but still the same thought, so update.
if (lastThought.id === thought.id) {
thought.thought = lastThought.thought

View File

@ -246,7 +246,7 @@ const Chat: FC<ChatProps> = ({
useEffect(() => {
if (!sidebarCollapseState) {
const timer = setTimeout(() => handleWindowResize(), 200)
const timer = setTimeout(handleWindowResize, 200)
return () => clearTimeout(timer)
}
}, [handleWindowResize, sidebarCollapseState])
@ -285,7 +285,7 @@ const Chat: FC<ChatProps> = ({
{
chatList.map((item, index) => {
if (item.isAnswer) {
const isLast = item.id === chatList[chatList.length - 1]?.id
const isLast = item.id === chatList.at(-1)?.id
return (
<Answer
appData={appData}

View File

@ -262,7 +262,7 @@ const ChatWrapper = () => {
background={appData?.site.icon_background}
imageUrl={appData?.site.icon_url}
/>
<div className="body-lg-regular grow rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary">
<div className="grow rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary body-lg-regular">
<Markdown content={welcomeMessage.content} />
<SuggestedQuestions item={welcomeMessage} />
</div>
@ -280,7 +280,7 @@ const ChatWrapper = () => {
imageUrl={appData?.site.icon_url}
/>
<div className="max-w-[768px] px-4">
<Markdown className="!body-2xl-regular !text-text-tertiary" content={welcomeMessage.content} />
<Markdown className="!text-text-tertiary !body-2xl-regular" content={welcomeMessage.content} />
</div>
</div>
)