mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-11-12 00:57:27 +00:00
fix: Keep Untagged Chat Code Fences Plain (#17986)
Some checks are pending
Backend Unit Tests / Build packages (push) Waiting to run
Backend Unit Tests / Codegraph select (push) Waiting to run
Backend Unit Tests / TypeScript type checks (push) Blocked by required conditions
Backend Unit Tests / Circular dependency checks (push) Waiting to run
Backend Unit Tests / Tests: api (shard 1/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 2/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 3/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: data-provider (push) Blocked by required conditions
Backend Unit Tests / Tests: data-schemas (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 1/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 2/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 3/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 4/4) (push) Blocked by required conditions
Codegraph E2E Vote Gate / Gate (push) Waiting to run
Codegraph E2E Votes / vote (shard 1/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 10/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 2/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 3/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 4/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 5/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 6/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 7/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 8/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 9/10) (push) Waiting to run
Docker Dev Branch Images Build / publish (push) Waiting to run
Frontend Unit Tests / Client build recovery regression (push) Waiting to run
Frontend Unit Tests / Codegraph select (push) Waiting to run
Frontend Unit Tests / Build packages (push) Waiting to run
Frontend Unit Tests / TypeScript type checks (client) (push) Blocked by required conditions
Frontend Unit Tests / Tests: @librechat/chat (push) Blocked by required conditions
Frontend Unit Tests / Tests: @librechat/client (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 1/2) (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 2/2) (push) Blocked by required conditions
Frontend Unit Tests / Vite build verification (push) Blocked by required conditions
Some checks are pending
Backend Unit Tests / Build packages (push) Waiting to run
Backend Unit Tests / Codegraph select (push) Waiting to run
Backend Unit Tests / TypeScript type checks (push) Blocked by required conditions
Backend Unit Tests / Circular dependency checks (push) Waiting to run
Backend Unit Tests / Tests: api (shard 1/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 2/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 3/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: data-provider (push) Blocked by required conditions
Backend Unit Tests / Tests: data-schemas (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 1/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 2/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 3/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 4/4) (push) Blocked by required conditions
Codegraph E2E Vote Gate / Gate (push) Waiting to run
Codegraph E2E Votes / vote (shard 1/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 10/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 2/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 3/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 4/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 5/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 6/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 7/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 8/10) (push) Waiting to run
Codegraph E2E Votes / vote (shard 9/10) (push) Waiting to run
Docker Dev Branch Images Build / publish (push) Waiting to run
Frontend Unit Tests / Client build recovery regression (push) Waiting to run
Frontend Unit Tests / Codegraph select (push) Waiting to run
Frontend Unit Tests / Build packages (push) Waiting to run
Frontend Unit Tests / TypeScript type checks (client) (push) Blocked by required conditions
Frontend Unit Tests / Tests: @librechat/chat (push) Blocked by required conditions
Frontend Unit Tests / Tests: @librechat/client (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 1/2) (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 2/2) (push) Blocked by required conditions
Frontend Unit Tests / Vite build verification (push) Blocked by required conditions
This commit is contained in:
parent
317dd05a82
commit
fbbf343286
4 changed files with 111 additions and 3 deletions
|
|
@ -68,7 +68,7 @@ class MarkdownErrorBoundary extends React.Component<
|
|||
[
|
||||
rehypeHighlight,
|
||||
{
|
||||
detect: true,
|
||||
detect: false,
|
||||
ignoreMissing: true,
|
||||
subset: langSubset,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const MarkdownLite = memo(
|
|||
[
|
||||
rehypeHighlight,
|
||||
{
|
||||
detect: true,
|
||||
detect: false,
|
||||
ignoreMissing: true,
|
||||
subset: langSubset,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
import React from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { render } from '@testing-library/react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { getRehypePlugins, getMarkdownComponents } from '../markdownConfig';
|
||||
import { ArtifactProvider, CodeBlockProvider } from '~/Providers';
|
||||
import MarkdownErrorBoundary from '../MarkdownErrorBoundary';
|
||||
import MarkdownLite from '../MarkdownLite';
|
||||
import Markdown from '../Markdown';
|
||||
|
||||
jest.mock('~/components/Messages/Content/CodeBlock', () => ({
|
||||
__esModule: true,
|
||||
default: ({ lang, codeChildren }: { lang: string; codeChildren: React.ReactNode }) => (
|
||||
<code data-language={lang}>{codeChildren}</code>
|
||||
),
|
||||
}));
|
||||
|
||||
const WholeMessage = ({ content }: { content: string }) => (
|
||||
<ArtifactProvider>
|
||||
<CodeBlockProvider>
|
||||
<ReactMarkdown
|
||||
rehypePlugins={
|
||||
getRehypePlugins() as React.ComponentProps<typeof ReactMarkdown>['rehypePlugins']
|
||||
}
|
||||
components={getMarkdownComponents()}
|
||||
>
|
||||
{content}
|
||||
</ReactMarkdown>
|
||||
</CodeBlockProvider>
|
||||
</ArtifactProvider>
|
||||
);
|
||||
|
||||
const Throw = (): never => {
|
||||
throw new Error('Exercise markdown fallback');
|
||||
};
|
||||
|
||||
const Fallback = ({
|
||||
content,
|
||||
codeExecution = true,
|
||||
}: {
|
||||
content: string;
|
||||
codeExecution?: boolean;
|
||||
}) => (
|
||||
<MarkdownErrorBoundary content={content} codeExecution={codeExecution}>
|
||||
<Throw />
|
||||
</MarkdownErrorBoundary>
|
||||
);
|
||||
|
||||
const renderers = [
|
||||
['whole message', WholeMessage],
|
||||
['blocks', (props: { content: string }) => <Markdown {...props} isLatestMessage={false} />],
|
||||
['lite', MarkdownLite],
|
||||
[
|
||||
'lite without execution',
|
||||
(props: { content: string }) => <MarkdownLite {...props} codeExecution={false} />,
|
||||
],
|
||||
['fallback', Fallback],
|
||||
[
|
||||
'fallback without execution',
|
||||
(props: { content: string }) => <Fallback {...props} codeExecution={false} />,
|
||||
],
|
||||
] as const;
|
||||
|
||||
const prose = 'Pick up milk, eggs and bread on the way home. Call the dentist: Tuesday at 3.';
|
||||
|
||||
describe.each(renderers)('%s highlighting', (_name, Renderer) => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
const renderContent = (content: string) => {
|
||||
const { container } = render(
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
<RecoilRoot>
|
||||
<Renderer content={content} />
|
||||
</RecoilRoot>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
return container.querySelector('code');
|
||||
};
|
||||
|
||||
it.each([
|
||||
['', prose, true],
|
||||
['', prose, false],
|
||||
['', 'const answer = 42;', true],
|
||||
['text', prose, true],
|
||||
['plaintext', prose, true],
|
||||
['unknownlang', prose, true],
|
||||
])('keeps %s fences plain for %s (closed: %s)', (language, content, closed) => {
|
||||
const code = renderContent(`\`\`\`${language}\n${content}\n${closed ? '```' : ''}`);
|
||||
expect(code).toHaveAttribute('data-language', language || 'text');
|
||||
expect(code?.textContent).toBe(`${content}\n`);
|
||||
expect(code?.querySelector('[class*="hljs-"]')).toBeNull();
|
||||
});
|
||||
|
||||
it('retains explicit Python highlighting', () => {
|
||||
const code = renderContent('```python\nprint("hello")\n```');
|
||||
expect(code).toHaveAttribute('data-language', 'python');
|
||||
expect(code?.querySelector('[class*="hljs-"]')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('keeps inline code inline', () => {
|
||||
const code = renderContent('Use `const answer = 42;` here.');
|
||||
expect(code).not.toHaveAttribute('data-language');
|
||||
expect(code?.textContent).toBe('const answer = 42;');
|
||||
});
|
||||
});
|
||||
|
|
@ -65,7 +65,7 @@ export const getRemarkPlugins = (latexParsing = true): PluggableList => [
|
|||
|
||||
export const getRehypePlugins = (): PluggableList => [
|
||||
[rehypeKatex],
|
||||
[rehypeHighlight, { detect: true, ignoreMissing: true, subset: langSubset }],
|
||||
[rehypeHighlight, { detect: false, ignoreMissing: true, subset: langSubset }],
|
||||
];
|
||||
|
||||
export const getMarkdownComponents = (): { [nodeType: string]: ElementType } => ({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue