mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-18 20:14:44 +08:00
feat: enhance message display
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { Message } from "@langchain/langgraph-sdk";
|
||||
import { memo } from "react";
|
||||
import { memo, useMemo } from "react";
|
||||
|
||||
import {
|
||||
Message as AIElementMessage,
|
||||
@@ -9,25 +9,20 @@ import {
|
||||
} from "@/components/ai-elements/message";
|
||||
import {
|
||||
extractContentFromMessage,
|
||||
hasReasoning,
|
||||
hasToolCalls,
|
||||
extractReasoningContentFromMessage,
|
||||
} from "@/core/messages/utils";
|
||||
import { useRehypeSplitWordsIntoSpans } from "@/core/rehype";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { CopyButton } from "../copy-button";
|
||||
|
||||
import { MessageGroup } from "./message-group";
|
||||
|
||||
export function MessageListItem({
|
||||
className,
|
||||
message,
|
||||
messagesInGroup,
|
||||
isLoading,
|
||||
}: {
|
||||
className?: string;
|
||||
message: Message;
|
||||
messagesInGroup: Message[];
|
||||
isLoading?: boolean;
|
||||
}) {
|
||||
return (
|
||||
@@ -38,7 +33,6 @@ export function MessageListItem({
|
||||
<MessageContent
|
||||
className={message.type === "human" ? "w-fit" : "w-full"}
|
||||
message={message}
|
||||
messagesInGroup={messagesInGroup}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<MessageToolbar
|
||||
@@ -49,7 +43,13 @@ export function MessageListItem({
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-1">
|
||||
<CopyButton clipboardData={extractContentFromMessage(message)} />
|
||||
<CopyButton
|
||||
clipboardData={
|
||||
extractContentFromMessage(message)
|
||||
? extractContentFromMessage(message)
|
||||
: (extractReasoningContentFromMessage(message) ?? "")
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</MessageToolbar>
|
||||
</AIElementMessage>
|
||||
@@ -59,26 +59,26 @@ export function MessageListItem({
|
||||
function MessageContent_({
|
||||
className,
|
||||
message,
|
||||
messagesInGroup,
|
||||
isLoading = false,
|
||||
}: {
|
||||
className?: string;
|
||||
message: Message;
|
||||
messagesInGroup: Message[];
|
||||
isLoading?: boolean;
|
||||
}) {
|
||||
const rehypePlugins = useRehypeSplitWordsIntoSpans(isLoading);
|
||||
const content = useMemo(() => {
|
||||
const reasoningContent = extractReasoningContentFromMessage(message);
|
||||
const content = extractContentFromMessage(message);
|
||||
if (!isLoading && reasoningContent && !content) {
|
||||
return reasoningContent;
|
||||
}
|
||||
return content;
|
||||
}, [isLoading, message]);
|
||||
return (
|
||||
<AIElementMessageContent className={className}>
|
||||
{hasReasoning(message) && (
|
||||
<MessageGroup messages={messagesInGroup} isLoading={isLoading} />
|
||||
)}
|
||||
<AIElementMessageResponse rehypePlugins={rehypePlugins}>
|
||||
{extractContentFromMessage(message)}
|
||||
{content}
|
||||
</AIElementMessageResponse>
|
||||
{hasToolCalls(message) && (
|
||||
<MessageGroup messages={messagesInGroup} isLoading={isLoading} />
|
||||
)}
|
||||
</AIElementMessageContent>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
import {
|
||||
extractPresentFilesFromMessage,
|
||||
groupMessages,
|
||||
hasContent,
|
||||
hasPresentFiles,
|
||||
} from "@/core/messages/utils";
|
||||
import type { AgentThreadState } from "@/core/threads";
|
||||
@@ -39,28 +38,26 @@ export function MessageList({
|
||||
<ConversationContent className="mx-auto w-full max-w-(--container-width-md) gap-10 pt-12">
|
||||
{groupMessages(
|
||||
thread.messages,
|
||||
(groupedMessages) => {
|
||||
if (groupedMessages[0] && hasContent(groupedMessages[0])) {
|
||||
const message = groupedMessages[0];
|
||||
(group) => {
|
||||
if (group.type === "human" || group.type === "assistant") {
|
||||
return (
|
||||
<MessageListItem
|
||||
key={message.id}
|
||||
message={message}
|
||||
messagesInGroup={groupedMessages}
|
||||
key={group.id}
|
||||
message={group.messages[0]!}
|
||||
isLoading={thread.isLoading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (groupedMessages[0] && hasPresentFiles(groupedMessages[0])) {
|
||||
if (group.type === "assistant:present-files") {
|
||||
const files = [];
|
||||
for (const message of groupedMessages) {
|
||||
for (const message of group.messages) {
|
||||
if (hasPresentFiles(message)) {
|
||||
files.push(...extractPresentFilesFromMessage(message));
|
||||
}
|
||||
}
|
||||
return (
|
||||
<ArtifactFileList
|
||||
key={groupedMessages[0].id}
|
||||
key={group.id}
|
||||
files={files}
|
||||
threadId={threadId}
|
||||
/>
|
||||
@@ -68,8 +65,8 @@ export function MessageList({
|
||||
}
|
||||
return (
|
||||
<MessageGroup
|
||||
key={groupedMessages[0]!.id}
|
||||
messages={groupedMessages}
|
||||
key={group.id}
|
||||
messages={group.messages}
|
||||
isLoading={thread.isLoading}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user