mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-23 10:36:09 +00:00
* feat: copy messages as rich text Adds an opt-in setting that places a rendered HTML flavor on the clipboard next to the markdown, so pasting an assistant response into an app that does not understand Markdown (Teams, Outlook, Word) keeps its headings, lists, tables and code formatting. The HTML is serialized from the same mdast pipeline the message renderer already uses, with inline styles because those paste targets strip stylesheets. Raw HTML in a message is escaped rather than passed through, matching the renderer, and link and image URLs go through the existing isSafeUrl allowlist. The plain copies (share links, API keys, OAuth callback URLs) keep using the base hook, so they are never wrapped in markup. The setting is off by default: markdown-aware targets prefer the HTML flavor when it is present, so making it unconditional would regress them. Closes #13973 * fix: address review feedback on rich text clipboard copy Mirror the renderer's `singleDollarTextMath: false` so paired currency such as "$5 to $10" is not read as math and stripped of its dollar signs in the HTML flavor. Pair every background the serializer sets with its own foreground, and let blockquotes and table cells inherit the destination's colors. The paste target's theme is unknowable, so a lone light background could land under a dark editor's light text. Resolve reference-style links and images against their definitions rather than dropping the hyperlink. Skip the HTML flavor for user messages while `enableUserMsgMarkdown` is off. Those render as literal text on screen, so formatting them on paste would not match what was copied. * fix: mirror the message renderers more closely in rich text copies Apply the same `remarkApproxTilde` and `remark-supersub` transforms the renderers apply to the parsed tree, so `x^2^` arrives as a superscript instead of literal markers. Select the renderer to mirror per message: `Markdown` (assistant) enables directives, `MarkdownLite` (user) does not, so a user message showing literal `:::` markers keeps them in the HTML flavor. Resolve path-relative URLs against the app's base URI. A generated file or image link resolves against LibreChat on screen but against the destination document once pasted. Absolute URLs are passed through verbatim rather than normalized. Serialize each text content part as its own document. Each part renders through its own Markdown instance on screen, so a construct must not span two of them; a private-use sentinel carries the boundary through citation processing, which only touches its own markers. * fix: match the renderer on line breaks, relative URLs and LaTeX Message text renders under white-space: pre-wrap, so a soft line break is a visible line on screen. Emit those as <br /> instead of a raw newline, which every HTML paste target would collapse to a space. Screen URLs through react-markdown's own transform rather than the artifact template's isSafeUrl, which rejected bare relative targets like docs/guide.html and dropped links the conversation shows as working. Everything relative is then resolved against the app's base URI. Apply preprocessLaTeX to assistant segments when LaTeXParsing is on, as the assistant renderer does, so single-dollar math is read as math rather than left as literal dollar signs. * fix: align rich text copies with directives, footnotes and search rendering Show an inline directive by name, as the artifact plugin displays it, rather than dropping the marker and keeping only its children. Number footnotes by the order their references appear and omit a definition nothing references, matching what the renderer displays instead of emitting the source label. Keep a generated citation marker from resolving against a reference definition that happens to share its number, which linked the citation to the wrong URL. An unresolved reference now falls back to its own source form, as remark-rehype reverts one. Let a caller state the renderer its row was displayed with. SearchContent falls back to MarkdownLite for a message without content parts whatever its author, so search results and shared links pass that through. Replace the part-boundary sentinel with a citation processor that carries its numbering across parts, so each part is formatted on its own without a private-use character that message text could itself contain. * fix: close remaining gaps between rich text copies and the rendered message Route rooted /images/ sources through apiBaseUrl the way the renderer's image component does, so a subdirectory deployment's images survive the paste instead of losing the base path to the leading slash. Show an artifact directive by its title, which is what its button displays, rather than pasting the implementation the conversation hides. Gather footnote definitions into a footer ordered by first reference, matching where and in what order the renderer shows them. Keep a loose list's paragraph wrappers. mdast records looseness on the list, not on every item, so the parent decides whether an item is tight. Emit the citation footer as its own segment. Appended to a segment ending in an unclosed fence, the sources were swallowed into the code block. Pass the search results MessageParts already loads into useMessageHelpers, which was copying assistant responses with their citation markers stripped and no sources appended. * fix: transform MCP markers and default an untitled artifact Run mcpUIResourcePlugin over assistant segments as the full renderer does, so a UI resource marker leaves as nothing rather than pasting the protocol text. An embedded interactive resource has no static form, and MarkdownLite does not transform the markers, so user turns keep them literal exactly as they are displayed. Fall back to the Artifact component's own default title when a directive carries none, instead of dropping the artifact from the copy. * fix: honor definition precedence, file link rewrites and error rows Keep the first of two reference definitions sharing a label, as CommonMark does, instead of letting the last one win. Route a user's own generated-file links through the app's file endpoint the way the anchor component does, so a pasted link points where the one in the conversation points rather than at the provider URL. Skip the HTML flavor for an errored row. ErrorMessage renders those, so serializing the raw payload as markdown would paste something the conversation never showed. Scope reserved citation labels to the segment that generated them. Each part is its own document, so a legitimate reference in one part is no longer suppressed by a citation numbered the same in another. * fix: resolve file citations against the references collection File-search sources live under references, as useCitation reads them, but the clipboard's type map had no entry for file. Their markers were therefore stripped without a source, so a citation visible in the response went missing from the copy. |
||
|---|---|---|
| .. | ||
| __tests__ | ||
| agents.ts | ||
| artifacts.ts | ||
| autoScroll.ts | ||
| clockFormat.ts | ||
| endpoints.ts | ||
| families.ts | ||
| favorites.ts | ||
| fontSize.ts | ||
| index.ts | ||
| jotai-utils.ts | ||
| language.ts | ||
| mcp.ts | ||
| misc.ts | ||
| preset.ts | ||
| prompts.ts | ||
| ptc.ts | ||
| sandbox.ts | ||
| search.ts | ||
| settings.ts | ||
| showThinking.ts | ||
| smoothStreaming.ts | ||
| steer.ts | ||
| submission.ts | ||
| temporary.ts | ||
| text.ts | ||
| toast.ts | ||
| usage.spec.ts | ||
| usage.ts | ||
| user.ts | ||
| utils.ts | ||
| weekStart.ts | ||