mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-09 19:14:23 +01:00
🔄 refactor: Artifact Visibility Management (#7181)
* fix: Reset artifacts on unmount and remove useIdChangeEffect hook * feat: Replace SVG icons with Lucide icons for improved consistency * fix: Refactor artifact reset logic on unmount and conversation change * refactor: Rename artifactsVisible to artifactsVisibility for consistency * feat: Replace custom SVG icons with Lucide icons for improved consistency * feat: Add visibleArtifacts atom for managing visibility state * feat: Implement debounced visibility state management for artifacts * refactor: Add useIdChangeEffect hook to reset visible artifacts on conversation ID change * refactor: Remove unnecessary dependency from useMemo in TextPart component * refactor: Enhance artifact visibility management by incorporating location checks for search path * refactor: Improve transition effects for artifact visibility in Artifacts component * chore: Remove preprocessCodeArtifacts function and related tests * fix: Update regex for detecting enclosed artifacts in latest message * refactor: Update artifact visibility checks to be more generic (not just search) * chore: Enhance artifact visibility logging * refactor: Extract closeArtifacts function to improve button click handling * refactor: remove nested logic from use artifacts effect * refactor: Update regex for detecting enclosed artifacts to handle new line variations
This commit is contained in:
parent
e6e7935fd8
commit
9a7f763714
10 changed files with 132 additions and 209 deletions
|
|
@ -1,94 +0,0 @@
|
|||
import { preprocessCodeArtifacts } from './artifacts';
|
||||
|
||||
describe('preprocessCodeArtifacts', () => {
|
||||
test('should return non-string inputs unchanged', () => {
|
||||
expect(preprocessCodeArtifacts(123 as unknown as string)).toBe('');
|
||||
expect(preprocessCodeArtifacts(null as unknown as string)).toBe('');
|
||||
expect(preprocessCodeArtifacts(undefined)).toBe('');
|
||||
expect(preprocessCodeArtifacts({} as unknown as string)).toEqual('');
|
||||
});
|
||||
|
||||
test('should remove <thinking> tags and their content', () => {
|
||||
const input = '<thinking>This should be removed</thinking>Some content';
|
||||
const expected = 'Some content';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should remove unclosed <thinking> tags and their content', () => {
|
||||
const input = '<thinking>This should be removed\nSome content';
|
||||
const expected = '';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should remove artifact headers up to and including empty code block', () => {
|
||||
const input = ':::artifact{identifier="test"}\n```\n```\nSome content';
|
||||
const expected = ':::artifact{identifier="test"}\n```\n```\nSome content';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should keep artifact headers when followed by empty code block and content', () => {
|
||||
const input = ':::artifact{identifier="test"}\n```\n```\nSome content';
|
||||
const expected = ':::artifact{identifier="test"}\n```\n```\nSome content';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should handle multiple artifact headers correctly', () => {
|
||||
const input = ':::artifact{id="1"}\n```\n```\n:::artifact{id="2"}\n```\ncode\n```\nContent';
|
||||
const expected = ':::artifact{id="1"}\n```\n```\n:::artifact{id="2"}\n```\ncode\n```\nContent';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should handle complex input with multiple patterns', () => {
|
||||
const input = `
|
||||
<thinking>Remove this</thinking>
|
||||
Some text
|
||||
:::artifact{id="1"}
|
||||
\`\`\`
|
||||
\`\`\`
|
||||
<thinking>And this</thinking>
|
||||
:::artifact{id="2"}
|
||||
\`\`\`
|
||||
keep this code
|
||||
\`\`\`
|
||||
More text
|
||||
`;
|
||||
const expected = `
|
||||
|
||||
Some text
|
||||
:::artifact{id="1"}
|
||||
\`\`\`
|
||||
\`\`\`
|
||||
|
||||
:::artifact{id="2"}
|
||||
\`\`\`
|
||||
keep this code
|
||||
\`\`\`
|
||||
More text
|
||||
`;
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should remove artifact headers without code blocks', () => {
|
||||
const input = ':::artifact{identifier="test"}\nSome content without code block';
|
||||
const expected = '';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should remove artifact headers up to incomplete code block', () => {
|
||||
const input = ':::artifact{identifier="react-cal';
|
||||
const expected = '';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should keep artifact headers when any character follows code block', () => {
|
||||
const input = ':::artifact{identifier="react-calculator"}\n```t';
|
||||
const expected = ':::artifact{identifier="react-calculator"}\n```t';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should keep artifact headers when whitespace follows code block', () => {
|
||||
const input = ':::artifact{identifier="react-calculator"}\n``` ';
|
||||
const expected = ':::artifact{identifier="react-calculator"}\n``` ';
|
||||
expect(preprocessCodeArtifacts(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
|
@ -214,23 +214,3 @@ export const sharedFiles = {
|
|||
</html>
|
||||
`,
|
||||
};
|
||||
|
||||
export function preprocessCodeArtifacts(text?: string): string {
|
||||
if (typeof text !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Remove <thinking> tags and their content
|
||||
text = text.replace(/<thinking>[\s\S]*?<\/thinking>|<thinking>[\s\S]*/g, '');
|
||||
|
||||
// Process artifact headers
|
||||
const regex = /(^|\n)(:::artifact[\s\S]*?(?:```[\s\S]*?```|$))/g;
|
||||
return text.replace(regex, (match, newline, artifactBlock) => {
|
||||
if (artifactBlock.includes('```') === true) {
|
||||
// Keep artifact headers with code blocks (empty or not)
|
||||
return newline + artifactBlock;
|
||||
}
|
||||
// Remove artifact headers without code blocks, but keep the newline
|
||||
return newline;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue