mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-31 23:50:36 +00:00
fix(citations): keep copied markdown references valid (#7743)
* fix(citations): keep copied markdown references valid formatCitationMarkdownReference pasted the source title and URL into "[title](url)" verbatim. A title with a stray "[" or "]" ends the link text early, and a URL with an unbalanced parenthesis ends the destination, so a copied reference no longer rendered as a link. Escape brackets in the title and wrap a parenthesized URL in the angle-bracket form. * fix(citations): only angle-bracket a parenthesized URL normalizeUrl already percent-encodes "<", ">" and whitespace, so including them in the trigger could wrap such a URL in an angle-bracket destination that CommonMark forbids, which is worse than the bare form. Parentheses are the only reachable delimiter that breaks the bare destination.
This commit is contained in:
parent
c6a3993695
commit
a9bd03ef57
@ -1708,7 +1708,10 @@ provider, document title, and retrieved excerpt in chat, including after reload
|
||||
and when a subagent performed the retrieval. Missing page numbers and public
|
||||
URLs remain absent; sources without a URL are readable as local evidence.
|
||||
Inline citations remain readable after Markdown sanitization, and supplied page
|
||||
numbers use the selected interface language. New providers use the shared
|
||||
numbers use the selected interface language.
|
||||
Copying a source reference produces a Markdown link that escapes brackets in the
|
||||
visible title and wraps a URL containing parentheses in angle brackets, so the
|
||||
copied reference stays a valid link. New providers use the shared
|
||||
envelope; existing RAGFlow citation histories remain supported.
|
||||
Expand a completed subtask card to inspect its report's forwarded knowledge
|
||||
sources, including when reopening a saved conversation.
|
||||
|
||||
@ -206,7 +206,13 @@ export function extractCitationSources(
|
||||
export function formatCitationMarkdownReference(
|
||||
source: CitationSource,
|
||||
): string {
|
||||
return `[${source.title}](${source.url})`;
|
||||
// Link text may contain balanced brackets, but a stray "[" or "]" would end
|
||||
// it early; escape both so a copied reference keeps the visible title.
|
||||
const title = source.title.replace(/([\\[\]])/g, "\\$1");
|
||||
// A bare link destination stops at an unbalanced parenthesis. The
|
||||
// angle-bracket form keeps URLs with parentheses valid.
|
||||
const url = /[()]/.test(source.url) ? `<${source.url}>` : source.url;
|
||||
return `[${title}](${url})`;
|
||||
}
|
||||
|
||||
function normalizeTitle(title: string, domain: string): string {
|
||||
|
||||
@ -1042,4 +1042,30 @@ describe("formatCitationMarkdownReference", () => {
|
||||
"[Paper A](https://example.com/a)",
|
||||
);
|
||||
});
|
||||
|
||||
it("escapes brackets in the title so the copied link keeps its label", () => {
|
||||
const [source] = extractCitationSources(
|
||||
"Evidence [citation:Paper A](https://example.com/a).",
|
||||
);
|
||||
|
||||
expect(
|
||||
formatCitationMarkdownReference({
|
||||
...source!,
|
||||
title: "Why ] matters [draft",
|
||||
}),
|
||||
).toBe("[Why \\] matters \\[draft](https://example.com/a)");
|
||||
});
|
||||
|
||||
it("wraps a URL with parentheses so the destination stays intact", () => {
|
||||
const [source] = extractCitationSources(
|
||||
"Evidence [citation:Paper A](https://example.com/a).",
|
||||
);
|
||||
|
||||
expect(
|
||||
formatCitationMarkdownReference({
|
||||
...source!,
|
||||
url: "https://example.com/a)b(c",
|
||||
}),
|
||||
).toBe("[Paper A](<https://example.com/a)b(c>)");
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user