mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-23 08:25:57 +00:00
refactor(frontend): simplify and deduplicate Citation-related code
- Extract removeCitationsBlocks in utils, reuse in parseCitations and removeAllCitations - Add hasCitationsBlock; isCitationsBlockIncomplete now uses it - Add useParsedCitations hook (parseCitations + buildCitationMap) for message/artifact - Add CitationAwareLink to unify link rendering (message-list-item + artifact-file-detail) - Add getCleanContent helper; message-group uses it and useParsedCitations - ArtifactFileDetail: single useParsedCitations, pass cleanContent/citationMap to Preview - Stop exporting buildCitationMap and removeCitationsBlocks from citations index - Remove duplicate MessageLink and inline link logic in artifact preview Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,7 +25,11 @@ import { CodeBlock } from "@/components/ai-elements/code-block";
|
||||
import { CitationsLoadingIndicator } from "@/components/ai-elements/inline-citation";
|
||||
import { MessageResponse } from "@/components/ai-elements/message";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { parseCitations } from "@/core/citations";
|
||||
import {
|
||||
getCleanContent,
|
||||
hasCitationsBlock,
|
||||
useParsedCitations,
|
||||
} from "@/core/citations";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import {
|
||||
extractReasoningContentFromMessage,
|
||||
@@ -124,7 +128,7 @@ export function MessageGroup({
|
||||
remarkPlugins={streamdownPlugins.remarkPlugins}
|
||||
rehypePlugins={rehypePlugins}
|
||||
>
|
||||
{parseCitations(step.reasoning ?? "").cleanContent}
|
||||
{getCleanContent(step.reasoning ?? "")}
|
||||
</MessageResponse>
|
||||
}
|
||||
></ChainOfThoughtStep>
|
||||
@@ -177,10 +181,7 @@ export function MessageGroup({
|
||||
remarkPlugins={streamdownPlugins.remarkPlugins}
|
||||
rehypePlugins={rehypePlugins}
|
||||
>
|
||||
{
|
||||
parseCitations(lastReasoningStep.reasoning ?? "")
|
||||
.cleanContent
|
||||
}
|
||||
{getCleanContent(lastReasoningStep.reasoning ?? "")}
|
||||
</MessageResponse>
|
||||
}
|
||||
></ChainOfThoughtStep>
|
||||
@@ -215,12 +216,8 @@ function ToolCall({
|
||||
const { thread } = useThread();
|
||||
const threadIsLoading = thread.isLoading;
|
||||
|
||||
// Move useMemo to top level to comply with React Hooks rules
|
||||
const fileContent = typeof args.content === "string" ? args.content : "";
|
||||
const { citations } = useMemo(
|
||||
() => parseCitations(fileContent),
|
||||
[fileContent],
|
||||
);
|
||||
const { citations } = useParsedCitations(fileContent);
|
||||
|
||||
if (name === "web_search") {
|
||||
let label: React.ReactNode = t.toolCalls.searchForRelatedInfo;
|
||||
@@ -370,9 +367,8 @@ function ToolCall({
|
||||
const isMarkdown =
|
||||
path?.toLowerCase().endsWith(".md") ||
|
||||
path?.toLowerCase().endsWith(".markdown");
|
||||
const hasCitationsBlock = fileContent.includes("<citations>");
|
||||
const showCitationsLoading =
|
||||
isMarkdown && threadIsLoading && hasCitationsBlock && isLast;
|
||||
isMarkdown && threadIsLoading && hasCitationsBlock(fileContent) && isLast;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user