Skip to content

Commit e1092d3

Browse files
feat(Message): Strip images from user messages by default (#673)
1 parent bb21eb0 commit e1092d3

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ _Italic text, formatted with single underscores_
392392
clobberPrefix: 'user-message-'
393393
}
394394
}}
395+
hasNoImagesInUserMessages={false}
395396
/>
396397
</>
397398
);

packages/module/src/Message/Message.test.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,12 +919,16 @@ describe('Message', () => {
919919
expect(screen.getByTestId('after-main-content')).toContainHTML('<strong>Bold after content</strong>');
920920
expect(screen.getByTestId('end-main-content')).toContainHTML('<strong>Bold end content</strong>');
921921
});
922-
it('should handle image correctly', () => {
922+
it('should handle image correctly for user', () => {
923923
render(<Message avatar="./img" role="user" name="User" content={IMAGE} />);
924+
expect(screen.queryByRole('img', { name: /Multi-colored wavy lines on a black background/i })).toBeFalsy();
925+
});
926+
it('should handle image correctly for bot', () => {
927+
render(<Message avatar="./img" role="bot" name="Bot" content={IMAGE} />);
924928
expect(screen.getByRole('img', { name: /Multi-colored wavy lines on a black background/i })).toBeTruthy();
925929
});
926930
it('inline image parent should have class pf-chatbot__message-and-actions', () => {
927-
render(<Message avatar="./img" role="user" name="User" content={INLINE_IMAGE} />);
931+
render(<Message avatar="./img" role="bot" name="Bot" content={INLINE_IMAGE} />);
928932
expect(screen.getByRole('img', { name: /Multi-colored wavy lines on a black background/i })).toBeTruthy();
929933
expect(
930934
screen.getByRole('img', { name: /Multi-colored wavy lines on a black background/i }).parentElement
@@ -1046,6 +1050,25 @@ describe('Message', () => {
10461050
// code block isn't rendering
10471051
expect(screen.queryByRole('button', { name: 'Copy code' })).toBeFalsy();
10481052
});
1053+
it('should disable images and additional tags for user messages', () => {
1054+
render(
1055+
<Message
1056+
avatar="./img"
1057+
role="user"
1058+
name="User"
1059+
content={`${IMAGE} ${CODE_MESSAGE}`}
1060+
reactMarkdownProps={{ disallowedElements: ['code'] }}
1061+
/>
1062+
);
1063+
expect(screen.getByText('Here is some YAML code:')).toBeTruthy();
1064+
// code block isn't rendering
1065+
expect(screen.queryByRole('button', { name: 'Copy code' })).toBeFalsy();
1066+
expect(screen.queryByRole('img', { name: /Multi-colored wavy lines on a black background/i })).toBeFalsy();
1067+
});
1068+
it('can override image tag removal default for user messages', () => {
1069+
render(<Message avatar="./img" role="user" name="User" content={IMAGE} hasNoImagesInUserMessages={false} />);
1070+
expect(screen.getByRole('img', { name: /Multi-colored wavy lines on a black background/i })).toBeTruthy();
1071+
});
10491072
it('should render deep thinking section correctly', () => {
10501073
render(<Message avatar="./img" role="user" name="User" content="" deepThinking={DEEP_THINKING} />);
10511074
expect(screen.getByRole('button', { name: /Show thinking/i })).toBeTruthy();

packages/module/src/Message/Message.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
203203
remarkGfmProps?: Options;
204204
/** Props for a tool call message */
205205
toolCall?: ToolCallProps;
206+
/** Whether user messages default to stripping out images in markdown */
207+
hasNoImagesInUserMessages?: boolean;
206208
}
207209

208210
export const MessageBase: FunctionComponent<MessageProps> = ({
@@ -249,6 +251,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
249251
deepThinking,
250252
remarkGfmProps,
251253
toolCall,
254+
hasNoImagesInUserMessages = true,
252255
...props
253256
}: MessageProps) => {
254257
const [messageText, setMessageText] = useState(content);
@@ -275,6 +278,11 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
275278
const date = new Date();
276279
const dateString = timestamp ?? `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
277280

281+
const disallowedElements = role === 'user' && hasNoImagesInUserMessages ? ['img'] : [];
282+
if (reactMarkdownProps && reactMarkdownProps.disallowedElements) {
283+
disallowedElements.push(...reactMarkdownProps.disallowedElements);
284+
}
285+
278286
const handleMarkdown = () => {
279287
if (isMarkdownDisabled) {
280288
return (
@@ -415,6 +423,7 @@ export const MessageBase: FunctionComponent<MessageProps> = ({
415423
footnoteLabelProperties: { className: [''] },
416424
...reactMarkdownProps?.remarkRehypeOptions
417425
}}
426+
disallowedElements={disallowedElements}
418427
>
419428
{messageText}
420429
</Markdown>

0 commit comments

Comments
 (0)