@patternfly/chatbot 6.4.0-prerelease.16 → 6.4.0-prerelease.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/cjs/DeepThinking/DeepThinking.d.ts +18 -0
  2. package/dist/cjs/DeepThinking/DeepThinking.js +18 -0
  3. package/dist/cjs/DeepThinking/DeepThinking.test.d.ts +1 -0
  4. package/dist/cjs/DeepThinking/DeepThinking.test.js +48 -0
  5. package/dist/cjs/DeepThinking/index.d.ts +2 -0
  6. package/dist/cjs/DeepThinking/index.js +23 -0
  7. package/dist/cjs/Message/Message.d.ts +6 -0
  8. package/dist/cjs/Message/Message.js +4 -2
  9. package/dist/cjs/Message/Message.test.js +25 -0
  10. package/dist/cjs/ToolResponse/ToolResponse.d.ts +30 -0
  11. package/dist/cjs/ToolResponse/ToolResponse.js +18 -0
  12. package/dist/cjs/ToolResponse/ToolResponse.test.d.ts +1 -0
  13. package/dist/cjs/ToolResponse/ToolResponse.test.js +60 -0
  14. package/dist/cjs/ToolResponse/index.d.ts +2 -0
  15. package/dist/cjs/ToolResponse/index.js +23 -0
  16. package/dist/cjs/index.d.ts +4 -0
  17. package/dist/cjs/index.js +7 -1
  18. package/dist/css/main.css +61 -0
  19. package/dist/css/main.css.map +1 -1
  20. package/dist/dynamic/DeepThinking/package.json +1 -0
  21. package/dist/dynamic/ToolResponse/package.json +1 -0
  22. package/dist/esm/DeepThinking/DeepThinking.d.ts +18 -0
  23. package/dist/esm/DeepThinking/DeepThinking.js +14 -0
  24. package/dist/esm/DeepThinking/DeepThinking.test.d.ts +1 -0
  25. package/dist/esm/DeepThinking/DeepThinking.test.js +43 -0
  26. package/dist/esm/DeepThinking/index.d.ts +2 -0
  27. package/dist/esm/DeepThinking/index.js +2 -0
  28. package/dist/esm/Message/Message.d.ts +6 -0
  29. package/dist/esm/Message/Message.js +4 -2
  30. package/dist/esm/Message/Message.test.js +25 -0
  31. package/dist/esm/ToolResponse/ToolResponse.d.ts +30 -0
  32. package/dist/esm/ToolResponse/ToolResponse.js +14 -0
  33. package/dist/esm/ToolResponse/ToolResponse.test.d.ts +1 -0
  34. package/dist/esm/ToolResponse/ToolResponse.test.js +55 -0
  35. package/dist/esm/ToolResponse/index.d.ts +2 -0
  36. package/dist/esm/ToolResponse/index.js +2 -0
  37. package/dist/esm/index.d.ts +4 -0
  38. package/dist/esm/index.js +4 -0
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +1 -1
  41. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +17 -0
  42. package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +135 -0
  43. package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +19 -1
  44. package/src/DeepThinking/DeepThinking.scss +24 -0
  45. package/src/DeepThinking/DeepThinking.test.tsx +61 -0
  46. package/src/DeepThinking/DeepThinking.tsx +68 -0
  47. package/src/DeepThinking/index.ts +3 -0
  48. package/src/Message/Message.test.tsx +35 -0
  49. package/src/Message/Message.tsx +10 -0
  50. package/src/ToolResponse/ToolResponse.scss +36 -0
  51. package/src/ToolResponse/ToolResponse.test.tsx +78 -0
  52. package/src/ToolResponse/ToolResponse.tsx +95 -0
  53. package/src/ToolResponse/index.ts +3 -0
  54. package/src/index.ts +6 -0
  55. package/src/main.scss +2 -0
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import DeepThinking from './DeepThinking';
5
+ describe('DeepThinking', () => {
6
+ const defaultProps = {
7
+ toggleContent: 'Show thinking'
8
+ };
9
+ it('should render with required props only', () => {
10
+ render(_jsx(DeepThinking, Object.assign({}, defaultProps)));
11
+ expect(screen.getByText('Show thinking')).toBeTruthy();
12
+ });
13
+ it('should render subheading when provided', () => {
14
+ const subheading = 'Thought for 3 seconds';
15
+ render(_jsx(DeepThinking, Object.assign({}, defaultProps, { subheading: subheading })));
16
+ expect(screen.getByText(subheading)).toBeTruthy();
17
+ });
18
+ it('should render body content when provided', () => {
19
+ const body = "Here's why I think that";
20
+ render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: body })));
21
+ expect(screen.getByText(body)).toBeTruthy();
22
+ });
23
+ it('should render with complex content including React elements', () => {
24
+ const body = (_jsxs("div", { children: [_jsx("p", { children: "Complex body content" }), _jsxs("ul", { children: [_jsx("li", { children: "Item 1" }), _jsx("li", { children: "Item 2" })] })] }));
25
+ render(_jsx(DeepThinking, Object.assign({}, defaultProps, { body: body })));
26
+ expect(screen.getByText('Complex body content')).toBeTruthy();
27
+ expect(screen.getByText('Item 1')).toBeTruthy();
28
+ expect(screen.getByText('Item 2')).toBeTruthy();
29
+ });
30
+ it('should apply custom className from cardProps', () => {
31
+ const { container } = render(_jsx(DeepThinking, Object.assign({}, defaultProps, { cardProps: { className: 'custom-tool-response-class' } })));
32
+ expect(container.querySelector('.custom-tool-response-class')).toBeTruthy();
33
+ });
34
+ it('should pass through expandableSectionProps', () => {
35
+ render(_jsx(DeepThinking, Object.assign({}, defaultProps, { expandableSectionProps: { className: 'custom-expandable-class' } })));
36
+ expect(document.querySelector('.custom-expandable-class')).toBeTruthy();
37
+ });
38
+ it('should not render subheading span when subheading is not provided', () => {
39
+ const { container } = render(_jsx(DeepThinking, Object.assign({}, defaultProps)));
40
+ const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
41
+ expect(subheadingContainer).toBeFalsy();
42
+ });
43
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from './DeepThinking';
2
+ export * from './DeepThinking';
@@ -0,0 +1,2 @@
1
+ export { default } from './DeepThinking';
2
+ export * from './DeepThinking';
@@ -10,6 +10,8 @@ import { UserFeedbackProps } from './UserFeedback/UserFeedback';
10
10
  import { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete';
11
11
  import { TableProps } from '@patternfly/react-table';
12
12
  import { PluggableList } from 'unified';
13
+ import { ToolResponseProps } from '../ToolResponse';
14
+ import { DeepThinkingProps } from '../DeepThinking';
13
15
  export interface MessageAttachment {
14
16
  /** Name of file attached to the message */
15
17
  name: string;
@@ -145,6 +147,10 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
145
147
  isMarkdownDisabled?: boolean;
146
148
  /** Allows passing additional props down to markdown parser react-markdown, such as allowedElements and disallowedElements. See https://github.com/remarkjs/react-markdown?tab=readme-ov-file#options for options */
147
149
  reactMarkdownProps?: Options;
150
+ /** Props for tool response card */
151
+ toolResponse?: ToolResponseProps;
152
+ /** Props for deep thinking card */
153
+ deepThinking?: DeepThinkingProps;
148
154
  }
149
155
  export declare const MessageBase: FunctionComponent<MessageProps>;
150
156
  declare const Message: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -44,8 +44,10 @@ import LinkMessage from './LinkMessage/LinkMessage';
44
44
  import ErrorMessage from './ErrorMessage/ErrorMessage';
45
45
  import MessageInput from './MessageInput';
46
46
  import { rehypeMoveImagesOutOfParagraphs } from './Plugins/rehypeMoveImagesOutOfParagraphs';
47
+ import ToolResponse from '../ToolResponse';
48
+ import DeepThinking from '../DeepThinking';
47
49
  export const MessageBase = (_a) => {
48
- var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps"]);
50
+ var { role, content, extraContent, name, avatar, timestamp, isLoading, actions, sources, botWord = 'AI', loadingWord = 'Loading message', codeBlockProps, quickResponses, quickResponseContainerProps = { numLabels: 5 }, attachments, hasRoundAvatar = true, avatarProps, quickStarts, userFeedbackForm, userFeedbackComplete, isLiveRegion = true, innerRef, tableProps, openLinkInNewTab = true, additionalRehypePlugins = [], linkProps, error, isEditable, editPlaceholder = 'Edit prompt message...', updateWord = 'Update', cancelWord = 'Cancel', onEditUpdate, onEditCancel, inputRef, editFormProps, isCompact, isMarkdownDisabled, reactMarkdownProps, toolResponse, deepThinking } = _a, props = __rest(_a, ["role", "content", "extraContent", "name", "avatar", "timestamp", "isLoading", "actions", "sources", "botWord", "loadingWord", "codeBlockProps", "quickResponses", "quickResponseContainerProps", "attachments", "hasRoundAvatar", "avatarProps", "quickStarts", "userFeedbackForm", "userFeedbackComplete", "isLiveRegion", "innerRef", "tableProps", "openLinkInNewTab", "additionalRehypePlugins", "linkProps", "error", "isEditable", "editPlaceholder", "updateWord", "cancelWord", "onEditUpdate", "onEditCancel", "inputRef", "editFormProps", "isCompact", "isMarkdownDisabled", "reactMarkdownProps", "toolResponse", "deepThinking"]);
49
51
  const [messageText, setMessageText] = useState(content);
50
52
  useEffect(() => {
51
53
  setMessageText(content);
@@ -114,7 +116,7 @@ export const MessageBase = (_a) => {
114
116
  }
115
117
  return (_jsxs(_Fragment, { children: [beforeMainContent && _jsx(_Fragment, { children: beforeMainContent }), error ? _jsx(ErrorMessage, Object.assign({}, error)) : handleMarkdown()] }));
116
118
  };
117
- return (_jsxs("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [_jsx(Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)), _jsxs("div", { className: "pf-chatbot__message-contents", children: [_jsxs("div", { className: "pf-chatbot__message-meta", children: [name && (_jsx("span", { className: "pf-chatbot__message-name", children: _jsx(Truncate, { content: name }) })), role === 'bot' && (_jsx(Label, { variant: "outline", isCompact: true, children: botWord })), _jsx(Timestamp, { date: date, children: timestamp })] }), _jsxs("div", { className: "pf-chatbot__message-response", children: [_jsxs("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && _jsx(_Fragment, { children: afterMainContent }), !isLoading && sources && _jsx(SourcesCard, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && (_jsx(QuickStartTile, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && _jsx(ResponseActions, { actions: actions }), userFeedbackForm && _jsx(UserFeedback, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && (_jsx(UserFeedbackComplete, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && (_jsx(QuickResponse, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && (_jsx("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
119
+ return (_jsxs("section", Object.assign({ "aria-label": `Message from ${role} - ${dateString}`, className: `pf-chatbot__message pf-chatbot__message--${role}`, "aria-live": isLiveRegion ? 'polite' : undefined, "aria-atomic": isLiveRegion ? false : undefined, ref: innerRef }, props, { children: [_jsx(Avatar, Object.assign({ className: `pf-chatbot__message-avatar ${hasRoundAvatar ? 'pf-chatbot__message-avatar--round' : ''} ${avatarClassName ? avatarClassName : ''}`, src: avatar, alt: "" }, avatarProps)), _jsxs("div", { className: "pf-chatbot__message-contents", children: [_jsxs("div", { className: "pf-chatbot__message-meta", children: [name && (_jsx("span", { className: "pf-chatbot__message-name", children: _jsx(Truncate, { content: name }) })), role === 'bot' && (_jsx(Label, { variant: "outline", isCompact: true, children: botWord })), _jsx(Timestamp, { date: date, children: timestamp })] }), _jsxs("div", { className: "pf-chatbot__message-response", children: [_jsxs("div", { className: "pf-chatbot__message-and-actions", children: [renderMessage(), afterMainContent && _jsx(_Fragment, { children: afterMainContent }), toolResponse && _jsx(ToolResponse, Object.assign({}, toolResponse)), deepThinking && _jsx(DeepThinking, Object.assign({}, deepThinking)), !isLoading && sources && _jsx(SourcesCard, Object.assign({}, sources, { isCompact: isCompact })), quickStarts && quickStarts.quickStart && (_jsx(QuickStartTile, { quickStart: quickStarts.quickStart, onSelectQuickStart: quickStarts.onSelectQuickStart, minuteWord: quickStarts.minuteWord, minuteWordPlural: quickStarts.minuteWordPlural, prerequisiteWord: quickStarts.prerequisiteWord, prerequisiteWordPlural: quickStarts.prerequisiteWordPlural, quickStartButtonAriaLabel: quickStarts.quickStartButtonAriaLabel, isCompact: isCompact })), !isLoading && !isEditable && actions && _jsx(ResponseActions, { actions: actions }), userFeedbackForm && _jsx(UserFeedback, Object.assign({}, userFeedbackForm, { timestamp: dateString, isCompact: isCompact })), userFeedbackComplete && (_jsx(UserFeedbackComplete, Object.assign({}, userFeedbackComplete, { timestamp: dateString, isCompact: isCompact }))), !isLoading && quickResponses && (_jsx(QuickResponse, { quickResponses: quickResponses, quickResponseContainerProps: quickResponseContainerProps, isCompact: isCompact }))] }), attachments && (_jsx("div", { className: "pf-chatbot__message-attachments-container", children: attachments.map((attachment) => {
118
120
  var _a;
119
121
  return (_jsx("div", { className: "pf-chatbot__message-attachment", children: _jsx(FileDetailsLabel, { fileName: attachment.name, fileId: attachment.id, onClose: attachment.onClose, onClick: attachment.onClick, isLoading: attachment.isLoading, closeButtonAriaLabel: attachment.closeButtonAriaLabel, languageTestId: attachment.languageTestId, spinnerTestId: attachment.spinnerTestId }) }, (_a = attachment.id) !== null && _a !== void 0 ? _a : attachment.name));
120
122
  }) })), !isLoading && endContent && _jsx(_Fragment, { children: endContent })] })] })] })));
@@ -138,6 +138,11 @@ const EMPTY_TABLE = `
138
138
  `;
139
139
  const IMAGE = `![Multi-colored wavy lines on a black background](https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif)`;
140
140
  const INLINE_IMAGE = `inline text ![Multi-colored wavy lines on a black background](https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif)`;
141
+ const DEEP_THINKING = {
142
+ toggleContent: 'Show thinking',
143
+ subheading: 'Thought for 3 seconds',
144
+ body: "Here's why I said this."
145
+ };
141
146
  const ERROR = {
142
147
  title: 'Could not load chat',
143
148
  children: 'Wait a few minutes and check your network settings. If the issue persists: ',
@@ -521,6 +526,20 @@ describe('Message', () => {
521
526
  } }));
522
527
  expect(screen.getAllByRole('img')[1]).toHaveAttribute('src', 'test.png');
523
528
  }));
529
+ it('should handle tool response correctly', () => __awaiter(void 0, void 0, void 0, function* () {
530
+ render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: "Hi", toolResponse: {
531
+ toggleContent: 'Tool response: Name',
532
+ subheading: 'Thought for 3 seconds',
533
+ body: 'Lorem ipsum dolor sit amet',
534
+ cardTitle: 'Card title',
535
+ cardBody: 'Card body'
536
+ } }));
537
+ expect(screen.getByRole('button', { name: /Tool response: Name/i })).toBeTruthy();
538
+ expect(screen.getByText('Thought for 3 seconds')).toBeTruthy();
539
+ expect(screen.getByText('Lorem ipsum dolor sit amet')).toBeTruthy();
540
+ expect(screen.getByText('Card title')).toBeTruthy();
541
+ expect(screen.getByText('Card body')).toBeTruthy();
542
+ }));
524
543
  it('should handle block quote correctly', () => {
525
544
  render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: BLOCK_QUOTES }));
526
545
  expect(screen.getByText(/Blockquotes can also be nested.../)).toBeTruthy();
@@ -745,4 +764,10 @@ describe('Message', () => {
745
764
  // code block isn't rendering
746
765
  expect(screen.queryByRole('button', { name: 'Copy code' })).toBeFalsy();
747
766
  });
767
+ it('should render deep thinking section correctly', () => {
768
+ render(_jsx(Message, { avatar: "./img", role: "user", name: "User", content: "", deepThinking: DEEP_THINKING }));
769
+ expect(screen.getByRole('button', { name: /Show thinking/i })).toBeTruthy();
770
+ expect(screen.getByText('Thought for 3 seconds')).toBeTruthy();
771
+ expect(screen.getByText("Here's why I said this.")).toBeTruthy();
772
+ });
748
773
  });
@@ -0,0 +1,30 @@
1
+ import { CardBodyProps, CardProps, CardTitleProps, DividerProps, ExpandableSectionProps } from '@patternfly/react-core';
2
+ import { type FunctionComponent } from 'react';
3
+ export interface ToolResponseProps {
4
+ /** Toggle content shown for expandable section */
5
+ toggleContent: React.ReactNode;
6
+ /** Additional props passed to expandable section */
7
+ expandableSectionProps?: Omit<ExpandableSectionProps, 'ref'>;
8
+ /** Subheading rendered inside expandable section */
9
+ subheading?: string;
10
+ /** Body text rendered inside expandable section */
11
+ body?: React.ReactNode | string;
12
+ /** Content passed into tool response card body */
13
+ cardBody: React.ReactNode;
14
+ /** Content passed into tool response card title */
15
+ cardTitle: React.ReactNode;
16
+ /** Additional props passed to main card */
17
+ cardProps?: CardProps;
18
+ /** Additional props passed to main card body */
19
+ cardBodyProps?: CardBodyProps;
20
+ /** Additional props passed to tool response card */
21
+ toolResponseCardProps?: CardProps;
22
+ /** Additional props passed to tool response card body */
23
+ toolResponseCardBodyProps?: CardBodyProps;
24
+ /** Additional props passed to tool response card divider */
25
+ toolResponseCardDividerProps?: DividerProps;
26
+ /** Additional props passed to tool response card title */
27
+ toolResponseCardTitleProps?: CardTitleProps;
28
+ }
29
+ export declare const ToolResponse: FunctionComponent<ToolResponseProps>;
30
+ export default ToolResponse;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // Tool Response Card
4
+ // ============================================================================
5
+ import { Card, CardBody, CardTitle, Divider, ExpandableSection } from '@patternfly/react-core';
6
+ import { useState } from 'react';
7
+ export const ToolResponse = ({ body, cardProps, expandableSectionProps, subheading, cardBody, cardTitle, cardBodyProps, toggleContent, toolResponseCardBodyProps, toolResponseCardDividerProps, toolResponseCardProps, toolResponseCardTitleProps }) => {
8
+ const [isExpanded, setIsExpanded] = useState(true);
9
+ const onToggle = (_event, isExpanded) => {
10
+ setIsExpanded(isExpanded);
11
+ };
12
+ return (_jsx(Card, Object.assign({ isCompact: true, className: "pf-chatbot__tool-response" }, cardProps, { children: _jsx(CardBody, Object.assign({}, cardBodyProps, { children: _jsx(ExpandableSection, Object.assign({ toggleContent: toggleContent, onToggle: onToggle, isExpanded: isExpanded, isIndented: true, className: "pf-chatbot__tool-response-expandable-section" }, expandableSectionProps, { children: _jsxs("div", { className: "pf-chatbot__tool-response-section", children: [subheading && (_jsx("div", { className: "pf-chatbot__tool-response-subheading", children: _jsx("span", { children: subheading }) })), body && _jsx("div", { className: "pf-chatbot__tool-response-body", children: body }), _jsxs(Card, Object.assign({ isCompact: true, className: "pf-chatbot__tool-response-card" }, toolResponseCardProps, { children: [_jsx(CardTitle, Object.assign({}, toolResponseCardTitleProps, { children: cardTitle })), _jsx(Divider, Object.assign({}, toolResponseCardDividerProps)), _jsx(CardBody, Object.assign({}, toolResponseCardBodyProps, { children: cardBody }))] }))] }) })) })) })));
13
+ };
14
+ export default ToolResponse;
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import ToolResponse from './ToolResponse';
5
+ describe('ToolResponse', () => {
6
+ const defaultProps = {
7
+ toggleContent: 'Tool response: toolName',
8
+ cardTitle: 'Title',
9
+ cardBody: 'Body'
10
+ };
11
+ it('should render with required props only', () => {
12
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps)));
13
+ expect(screen.getByText('Title')).toBeTruthy();
14
+ expect(screen.getByText('Body')).toBeTruthy();
15
+ expect(screen.getByText('Tool response: toolName')).toBeTruthy();
16
+ });
17
+ it('should render subheading when provided', () => {
18
+ const subheading = 'Tool execution result';
19
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps, { subheading: subheading })));
20
+ expect(screen.getByText(subheading)).toBeTruthy();
21
+ });
22
+ it('should render body content when provided', () => {
23
+ const body = 'This is the tool response body content';
24
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps, { body: body })));
25
+ expect(screen.getByText(body)).toBeTruthy();
26
+ });
27
+ it('should render with complex content including React elements', () => {
28
+ const body = (_jsxs("div", { children: [_jsx("p", { children: "Complex body content" }), _jsxs("ul", { children: [_jsx("li", { children: "Item 1" }), _jsx("li", { children: "Item 2" })] })] }));
29
+ const cardTitle = _jsx("strong", { children: "API Response" });
30
+ const cardBody = (_jsx("div", { children: _jsx("code", { children: "{ status: 'success' }" }) }));
31
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps, { body: body, cardTitle: cardTitle, cardBody: cardBody })));
32
+ expect(screen.getByText('Complex body content')).toBeTruthy();
33
+ expect(screen.getByText('Item 1')).toBeTruthy();
34
+ expect(screen.getByText('Item 2')).toBeTruthy();
35
+ expect(screen.getByText('API Response')).toBeTruthy();
36
+ expect(screen.getByText("{ status: 'success' }")).toBeTruthy();
37
+ });
38
+ it('should apply custom className from cardProps', () => {
39
+ const { container } = render(_jsx(ToolResponse, Object.assign({}, defaultProps, { cardProps: { className: 'custom-tool-response-class' } })));
40
+ expect(container.querySelector('.custom-tool-response-class')).toBeTruthy();
41
+ });
42
+ it('should pass through expandableSectionProps', () => {
43
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps, { expandableSectionProps: { className: 'custom-expandable-class' } })));
44
+ expect(document.querySelector('.custom-expandable-class')).toBeTruthy();
45
+ });
46
+ it('should pass through toolResponseCardProps', () => {
47
+ render(_jsx(ToolResponse, Object.assign({}, defaultProps, { toolResponseCardProps: { className: 'custom-card-class' } })));
48
+ expect(document.querySelector('.custom-card-class')).toBeTruthy();
49
+ });
50
+ it('should not render subheading span when subheading is not provided', () => {
51
+ const { container } = render(_jsx(ToolResponse, Object.assign({}, defaultProps)));
52
+ const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
53
+ expect(subheadingContainer).toBeFalsy();
54
+ });
55
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from './ToolResponse';
2
+ export * from './ToolResponse';
@@ -0,0 +1,2 @@
1
+ export { default } from './ToolResponse';
2
+ export * from './ToolResponse';
@@ -26,6 +26,8 @@ export { default as CodeModal } from './CodeModal';
26
26
  export * from './CodeModal';
27
27
  export { default as Compare } from './Compare';
28
28
  export * from './Compare';
29
+ export { default as DeepThinking } from './DeepThinking';
30
+ export * from './DeepThinking';
29
31
  export { default as FileDetails } from './FileDetails';
30
32
  export * from './FileDetails';
31
33
  export { default as FileDetailsLabel } from './FileDetailsLabel';
@@ -54,5 +56,7 @@ export { default as SourcesCard } from './SourcesCard';
54
56
  export * from './SourcesCard';
55
57
  export { default as TermsOfUse } from './TermsOfUse';
56
58
  export * from './TermsOfUse';
59
+ export { default as ToolResponse } from './ToolResponse';
60
+ export * from './ToolResponse';
57
61
  export { default as tracking } from './tracking';
58
62
  export * from './tracking';
package/dist/esm/index.js CHANGED
@@ -27,6 +27,8 @@ export { default as CodeModal } from './CodeModal';
27
27
  export * from './CodeModal';
28
28
  export { default as Compare } from './Compare';
29
29
  export * from './Compare';
30
+ export { default as DeepThinking } from './DeepThinking';
31
+ export * from './DeepThinking';
30
32
  export { default as FileDetails } from './FileDetails';
31
33
  export * from './FileDetails';
32
34
  export { default as FileDetailsLabel } from './FileDetailsLabel';
@@ -55,5 +57,7 @@ export { default as SourcesCard } from './SourcesCard';
55
57
  export * from './SourcesCard';
56
58
  export { default as TermsOfUse } from './TermsOfUse';
57
59
  export * from './TermsOfUse';
60
+ export { default as ToolResponse } from './ToolResponse';
61
+ export * from './ToolResponse';
58
62
  export { default as tracking } from './tracking';
59
63
  export * from './tracking';
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/EmptyState.tsx","../src/ChatbotConversationHistoryNav/LoadingState.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.test.tsx","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.test.tsx","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageInput.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ErrorMessage/ErrorMessage.tsx","../src/Message/ImageMessage/ImageMessage.tsx","../src/Message/LinkMessage/LinkMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/Plugins/index.ts","../src/Message/Plugins/rehypeCodeBlockToggle.ts","../src/Message/Plugins/rehypeMoveImagesOutOfParagraphs.ts","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/MessageDivider/MessageDivider.test.tsx","../src/MessageDivider/MessageDivider.tsx","../src/MessageDivider/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/__mocks__/rehype-external-links.ts","../src/__mocks__/rehype-sanitize.ts","../src/__mocks__/rehype-unwrap-images.tsx","../src/tracking/console_tracking_provider.ts","../src/tracking/index.ts","../src/tracking/posthog_tracking_provider.ts","../src/tracking/segment_tracking_provider.ts","../src/tracking/trackingProviderProxy.ts","../src/tracking/tracking_api.ts","../src/tracking/tracking_registry.ts","../src/tracking/tracking_spi.ts","../src/tracking/umami_tracking_provider.ts"],"version":"5.6.3"}
1
+ {"root":["../src/index.ts","../src/AttachMenu/AttachMenu.tsx","../src/AttachMenu/index.ts","../src/AttachmentEdit/AttachmentEdit.test.tsx","../src/AttachmentEdit/AttachmentEdit.tsx","../src/AttachmentEdit/index.ts","../src/Chatbot/Chatbot.test.tsx","../src/Chatbot/Chatbot.tsx","../src/Chatbot/index.ts","../src/ChatbotAlert/ChatbotAlert.test.tsx","../src/ChatbotAlert/ChatbotAlert.tsx","../src/ChatbotAlert/index.ts","../src/ChatbotContent/ChatbotContent.test.tsx","../src/ChatbotContent/ChatbotContent.tsx","../src/ChatbotContent/index.ts","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx","../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx","../src/ChatbotConversationHistoryNav/EmptyState.tsx","../src/ChatbotConversationHistoryNav/LoadingState.tsx","../src/ChatbotConversationHistoryNav/index.ts","../src/ChatbotFooter/ChatbotFooter.test.tsx","../src/ChatbotFooter/ChatbotFooter.tsx","../src/ChatbotFooter/ChatbotFooternote.test.tsx","../src/ChatbotFooter/ChatbotFootnote.tsx","../src/ChatbotFooter/index.ts","../src/ChatbotHeader/ChatbotHeader.test.tsx","../src/ChatbotHeader/ChatbotHeader.tsx","../src/ChatbotHeader/ChatbotHeaderActions.test.tsx","../src/ChatbotHeader/ChatbotHeaderActions.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderCloseButton.tsx","../src/ChatbotHeader/ChatbotHeaderMain.test.tsx","../src/ChatbotHeader/ChatbotHeaderMain.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.test.tsx","../src/ChatbotHeader/ChatbotHeaderMenu.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx","../src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderOptionsDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx","../src/ChatbotHeader/ChatbotHeaderSelectorDropdown.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.test.tsx","../src/ChatbotHeader/ChatbotHeaderTitle.tsx","../src/ChatbotHeader/index.ts","../src/ChatbotModal/ChatbotModal.test.tsx","../src/ChatbotModal/ChatbotModal.tsx","../src/ChatbotModal/index.ts","../src/ChatbotPopover/ChatbotPopover.tsx","../src/ChatbotPopover/index.ts","../src/ChatbotToggle/ChatbotToggle.test.tsx","../src/ChatbotToggle/ChatbotToggle.tsx","../src/ChatbotToggle/index.ts","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.test.tsx","../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.tsx","../src/ChatbotWelcomePrompt/index.ts","../src/CodeModal/CodeModal.test.tsx","../src/CodeModal/CodeModal.tsx","../src/CodeModal/index.ts","../src/Compare/Compare.test.tsx","../src/Compare/Compare.tsx","../src/Compare/index.ts","../src/DeepThinking/DeepThinking.test.tsx","../src/DeepThinking/DeepThinking.tsx","../src/DeepThinking/index.ts","../src/FileDetails/FileDetails.test.tsx","../src/FileDetails/FileDetails.tsx","../src/FileDetails/index.ts","../src/FileDetailsLabel/FileDetailsLabel.test.tsx","../src/FileDetailsLabel/FileDetailsLabel.tsx","../src/FileDetailsLabel/index.ts","../src/FileDropZone/FileDropZone.test.tsx","../src/FileDropZone/FileDropZone.tsx","../src/FileDropZone/index.ts","../src/LoadingMessage/LoadingMessage.test.tsx","../src/LoadingMessage/LoadingMessage.tsx","../src/LoadingMessage/index.ts","../src/Message/Message.test.tsx","../src/Message/Message.tsx","../src/Message/MessageInput.tsx","../src/Message/MessageLoading.tsx","../src/Message/index.ts","../src/Message/CodeBlockMessage/CodeBlockMessage.tsx","../src/Message/ErrorMessage/ErrorMessage.tsx","../src/Message/ImageMessage/ImageMessage.tsx","../src/Message/LinkMessage/LinkMessage.tsx","../src/Message/ListMessage/ListItemMessage.tsx","../src/Message/ListMessage/OrderedListMessage.tsx","../src/Message/ListMessage/UnorderedListMessage.tsx","../src/Message/Plugins/index.ts","../src/Message/Plugins/rehypeCodeBlockToggle.ts","../src/Message/Plugins/rehypeMoveImagesOutOfParagraphs.ts","../src/Message/QuickResponse/QuickResponse.tsx","../src/Message/QuickStarts/FallbackImg.tsx","../src/Message/QuickStarts/QuickStartTile.tsx","../src/Message/QuickStarts/QuickStartTileDescription.test.tsx","../src/Message/QuickStarts/QuickStartTileDescription.tsx","../src/Message/QuickStarts/QuickStartTileHeader.tsx","../src/Message/QuickStarts/monitor-sampleapp-quickstart-with-image.ts","../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts","../src/Message/QuickStarts/types.ts","../src/Message/TableMessage/TableMessage.tsx","../src/Message/TableMessage/TbodyMessage.tsx","../src/Message/TableMessage/TdMessage.tsx","../src/Message/TableMessage/ThMessage.tsx","../src/Message/TableMessage/TheadMessage.tsx","../src/Message/TableMessage/TrMessage.tsx","../src/Message/TextMessage/TextMessage.tsx","../src/Message/UserFeedback/CloseButton.tsx","../src/Message/UserFeedback/UserFeedback.test.tsx","../src/Message/UserFeedback/UserFeedback.tsx","../src/Message/UserFeedback/UserFeedbackComplete.test.tsx","../src/Message/UserFeedback/UserFeedbackComplete.tsx","../src/MessageBar/AttachButton.test.tsx","../src/MessageBar/AttachButton.tsx","../src/MessageBar/MessageBar.test.tsx","../src/MessageBar/MessageBar.tsx","../src/MessageBar/MicrophoneButton.tsx","../src/MessageBar/SendButton.test.tsx","../src/MessageBar/SendButton.tsx","../src/MessageBar/StopButton.test.tsx","../src/MessageBar/StopButton.tsx","../src/MessageBar/index.ts","../src/MessageBox/JumpButton.test.tsx","../src/MessageBox/JumpButton.tsx","../src/MessageBox/MessageBox.test.tsx","../src/MessageBox/MessageBox.tsx","../src/MessageBox/index.ts","../src/MessageDivider/MessageDivider.test.tsx","../src/MessageDivider/MessageDivider.tsx","../src/MessageDivider/index.ts","../src/PreviewAttachment/PreviewAttachment.test.tsx","../src/PreviewAttachment/PreviewAttachment.tsx","../src/PreviewAttachment/index.ts","../src/ResponseActions/ResponseActionButton.test.tsx","../src/ResponseActions/ResponseActionButton.tsx","../src/ResponseActions/ResponseActions.test.tsx","../src/ResponseActions/ResponseActions.tsx","../src/ResponseActions/index.ts","../src/Settings/SettingsForm.test.tsx","../src/Settings/SettingsForm.tsx","../src/Settings/index.ts","../src/SourceDetailsMenuItem/SourceDetailsMenuItem.tsx","../src/SourceDetailsMenuItem/index.ts","../src/SourcesCard/SourcesCard.test.tsx","../src/SourcesCard/SourcesCard.tsx","../src/SourcesCard/index.ts","../src/TermsOfUse/TermsOfUse.test.tsx","../src/TermsOfUse/TermsOfUse.tsx","../src/TermsOfUse/index.ts","../src/ToolResponse/ToolResponse.test.tsx","../src/ToolResponse/ToolResponse.tsx","../src/ToolResponse/index.ts","../src/__mocks__/rehype-external-links.ts","../src/__mocks__/rehype-sanitize.ts","../src/__mocks__/rehype-unwrap-images.tsx","../src/tracking/console_tracking_provider.ts","../src/tracking/index.ts","../src/tracking/posthog_tracking_provider.ts","../src/tracking/segment_tracking_provider.ts","../src/tracking/trackingProviderProxy.ts","../src/tracking/tracking_api.ts","../src/tracking/tracking_registry.ts","../src/tracking/tracking_spi.ts","../src/tracking/umami_tracking_provider.ts"],"version":"5.6.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "6.4.0-prerelease.16",
3
+ "version": "6.4.0-prerelease.18",
4
4
  "description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -0,0 +1,17 @@
1
+ import { FunctionComponent } from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from './patternfly_avatar.jpg';
4
+
5
+ export const MessageWithDeepThinkingExample: FunctionComponent = () => (
6
+ <Message
7
+ name="Bot"
8
+ role="bot"
9
+ avatar={patternflyAvatar}
10
+ content="This example has a body description that's within the recommended limit of 2 lines."
11
+ deepThinking={{
12
+ toggleContent: 'Show thinking',
13
+ subheading: 'Thought for 3 seconds',
14
+ body: "Here's why I said this."
15
+ }}
16
+ />
17
+ );
@@ -0,0 +1,135 @@
1
+ import { useState, FunctionComponent, MouseEvent as ReactMouseEvent } from 'react';
2
+ import Message from '@patternfly/chatbot/dist/dynamic/Message';
3
+ import patternflyAvatar from './patternfly_avatar.jpg';
4
+ import { CopyIcon, WrenchIcon } from '@patternfly/react-icons';
5
+ import {
6
+ Button,
7
+ DescriptionList,
8
+ DescriptionListDescription,
9
+ DescriptionListGroup,
10
+ DescriptionListTerm,
11
+ ExpandableSection,
12
+ ExpandableSectionVariant,
13
+ Flex,
14
+ FlexItem,
15
+ Label
16
+ } from '@patternfly/react-core';
17
+
18
+ export const MessageWithToolResponseExample: FunctionComponent = () => {
19
+ const [isExpanded, setIsExpanded] = useState(false);
20
+
21
+ const onToggle = (_event: ReactMouseEvent, isExpanded: boolean) => {
22
+ setIsExpanded(isExpanded);
23
+ };
24
+
25
+ return (
26
+ <Message
27
+ name="Bot"
28
+ role="bot"
29
+ avatar={patternflyAvatar}
30
+ content="This example has a body description that's within the recommended limit of 2 lines:"
31
+ toolResponse={{
32
+ toggleContent: 'Tool response: toolName',
33
+ subheading: 'Thought for 3 seconds',
34
+ body: "Here's the summary for your toolName response:",
35
+ cardTitle: (
36
+ <Flex alignItems={{ default: 'alignItemsCenter' }} justifyContent={{ default: 'justifyContentSpaceBetween' }}>
37
+ <FlexItem>
38
+ <Flex direction={{ default: 'column' }} gap={{ default: 'gapXs' }}>
39
+ <FlexItem grow={{ default: 'grow' }}>
40
+ <Flex gap={{ default: 'gapXs' }}>
41
+ <FlexItem>
42
+ <WrenchIcon style={{ color: 'var(--pf-t--global--icon--color--brand--default' }} />
43
+ </FlexItem>
44
+ <FlexItem>toolName</FlexItem>
45
+ </Flex>
46
+ </FlexItem>
47
+ <FlexItem>
48
+ <Flex gap={{ default: 'gapSm' }} style={{ fontSize: '12px', fontWeight: '400' }}>
49
+ <FlexItem>Execution time:</FlexItem>
50
+ <FlexItem>0.12 seconds</FlexItem>
51
+ </Flex>
52
+ </FlexItem>
53
+ </Flex>
54
+ </FlexItem>
55
+ <FlexItem>
56
+ <Button
57
+ variant="plain"
58
+ aria-label="Copy tool response to clipboard"
59
+ icon={<CopyIcon style={{ color: 'var(--pf-t--global--icon--color--subtle)' }} />}
60
+ ></Button>
61
+ </FlexItem>
62
+ </Flex>
63
+ ),
64
+ cardBody: (
65
+ <>
66
+ <DescriptionList
67
+ style={{ '--pf-v6-c-description-list--RowGap': 'var(--pf-t--global--spacer--md)' } as any}
68
+ aria-label="Tool response"
69
+ >
70
+ <DescriptionListGroup
71
+ style={{ '--pf-v6-c-description-list__group--RowGap': 'var(--pf-t--global--spacer--xs)' } as any}
72
+ >
73
+ <DescriptionListTerm>Parameters</DescriptionListTerm>
74
+ <DescriptionListDescription>
75
+ <Flex direction={{ default: 'column' }}>
76
+ <FlexItem>Optional description text for parameters.</FlexItem>
77
+ <FlexItem>
78
+ <Flex gap={{ default: 'gapSm' }}>
79
+ <FlexItem>
80
+ <Label variant="outline" color="blue">
81
+ type
82
+ </Label>
83
+ </FlexItem>
84
+ <FlexItem>
85
+ <Label variant="outline" color="blue">
86
+ properties
87
+ </Label>
88
+ </FlexItem>
89
+ <FlexItem>
90
+ <Label variant="outline" color="blue">
91
+ label
92
+ </Label>
93
+ </FlexItem>
94
+ <FlexItem>
95
+ <Label variant="outline" color="blue">
96
+ label
97
+ </Label>
98
+ </FlexItem>
99
+ </Flex>
100
+ </FlexItem>
101
+ </Flex>
102
+ </DescriptionListDescription>
103
+ </DescriptionListGroup>
104
+ <DescriptionListGroup
105
+ style={{ '--pf-v6-c-description-list__group--RowGap': 'var(--pf-t--global--spacer--xs)' } as any}
106
+ >
107
+ <DescriptionListTerm>Response</DescriptionListTerm>
108
+ <DescriptionListDescription>
109
+ <ExpandableSection
110
+ variant={ExpandableSectionVariant.truncate}
111
+ toggleTextExpanded="show less of response"
112
+ toggleTextCollapsed="show more of response"
113
+ onToggle={onToggle}
114
+ isExpanded={isExpanded}
115
+ style={
116
+ {
117
+ '--pf-v6-c-expandable-section__content--Opacity': '1',
118
+ '--pf-v6-c-expandable-section__content--PaddingInlineStart': 0,
119
+ '--pf-v6-c-expandable-section__content--TranslateY': 0,
120
+ '--pf-v6-c-expandable-section--m-expand-top__content--TranslateY': 0
121
+ } as any
122
+ }
123
+ >
124
+ Descriptive text about the tool response, including completion status, details on the data that was
125
+ processed, or anything else relevant to the use case.
126
+ </ExpandableSection>
127
+ </DescriptionListDescription>
128
+ </DescriptionListGroup>
129
+ </DescriptionList>
130
+ </>
131
+ )
132
+ }}
133
+ />
134
+ );
135
+ };
@@ -34,7 +34,7 @@ import Message from '@patternfly/chatbot/dist/dynamic/Message';
34
34
  import MessageDivider from '@patternfly/chatbot/dist/dynamic/MessageDivider';
35
35
  import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle';
36
36
  import SourcesCard from '@patternfly/chatbot/dist/dynamic/SourcesCard';
37
- import { ArrowCircleDownIcon, ArrowRightIcon, CheckCircleIcon, CubeIcon, CubesIcon, DownloadIcon, InfoCircleIcon, OutlinedQuestionCircleIcon, RedoIcon, RobotIcon } from '@patternfly/react-icons';
37
+ import { ArrowCircleDownIcon, ArrowRightIcon, CheckCircleIcon, CopyIcon, CubeIcon, CubesIcon, DownloadIcon, InfoCircleIcon, OutlinedQuestionCircleIcon, RedoIcon, RobotIcon, WrenchIcon } from '@patternfly/react-icons';
38
38
  import patternflyAvatar from './patternfly_avatar.jpg';
39
39
  import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit';
40
40
  import FileDetails from '@patternfly/chatbot/dist/dynamic/FileDetails';
@@ -178,6 +178,24 @@ The API for a source requires a link at minimum, but we strongly recommend provi
178
178
 
179
179
  ```
180
180
 
181
+ ### Messages with tool responses
182
+
183
+ If you are using [model context protocol (MCP)](https://www.redhat.com/en/blog/model-context-protocol-discover-missing-link-ai-integration), you may find it useful to display information on tool responses as part of a message. Passing `toolResponse` to `<Message>` allows you to display a card with an optional subheading and body, as well as custom card content. Content is intentionally left fully customizable for now as this is an evolving area.
184
+
185
+ ```js file="./MessageWithToolResponse.tsx"
186
+
187
+ ```
188
+
189
+ ### Messages with deep thinking
190
+
191
+ You can share details about the "thought process" behind an LLM's response, also known as deep thinking. To display a customizable, expandable card with these details, pass `deepThinking` to `<Message>` and provide a subheading (optional) and content body.
192
+
193
+ Because this is an evolving area, this card content is currently fully customizable.
194
+
195
+ ```js file="./MessageWithDeepThinking.tsx"
196
+
197
+ ```
198
+
181
199
  ### Messages with quick start tiles
182
200
 
183
201
  [Quick start](/extensions/quick-starts/) tiles can be added to messages via the `quickStarts` prop. Users can initiate the quick start from a link within the message tile.
@@ -0,0 +1,24 @@
1
+ .pf-chatbot__deep-thinking {
2
+ --pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--control--read-only);
3
+ overflow: unset;
4
+ }
5
+
6
+ .pf-chatbot__deep-thinking-expandable-section {
7
+ --pf-v6-c-expandable-section--Gap: var(--pf-t--global--spacer--xs);
8
+ }
9
+
10
+ .pf-chatbot__deep-thinking-section {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: var(--pf-t--global--spacer--xs);
14
+ }
15
+
16
+ .pf-chatbot__deep-thinking-subheading {
17
+ font-size: var(--pf-t--global--font--size--body--sm);
18
+ font-weight: var(--pf-t--global--font--weight--body--default);
19
+ color: var(--pf-t--global--text--color--subtle);
20
+ }
21
+
22
+ .pf-chatbot__deep-thinking-body {
23
+ color: var(--pf-t--global--text--color--subtle);
24
+ }