@patternfly/chatbot 6.4.0-prerelease.17 → 6.4.0-prerelease.19
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.
- package/dist/cjs/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.js +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.js +48 -0
- package/dist/cjs/DeepThinking/index.d.ts +2 -0
- package/dist/cjs/DeepThinking/index.js +23 -0
- package/dist/cjs/FilePreview/FilePreview.d.ts +26 -0
- package/dist/cjs/FilePreview/FilePreview.js +26 -0
- package/dist/cjs/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/cjs/FilePreview/FilePreview.test.js +97 -0
- package/dist/cjs/FilePreview/index.d.ts +2 -0
- package/dist/cjs/FilePreview/index.js +23 -0
- package/dist/cjs/Message/Message.d.ts +3 -0
- package/dist/cjs/Message/Message.js +3 -2
- package/dist/cjs/Message/Message.test.js +11 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +7 -1
- package/dist/css/main.css +49 -0
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/DeepThinking/package.json +1 -0
- package/dist/dynamic/FilePreview/package.json +1 -0
- package/dist/esm/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/esm/DeepThinking/DeepThinking.js +14 -0
- package/dist/esm/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/esm/DeepThinking/DeepThinking.test.js +43 -0
- package/dist/esm/DeepThinking/index.d.ts +2 -0
- package/dist/esm/DeepThinking/index.js +2 -0
- package/dist/esm/FilePreview/FilePreview.d.ts +26 -0
- package/dist/esm/FilePreview/FilePreview.js +21 -0
- package/dist/esm/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/esm/FilePreview/FilePreview.test.js +92 -0
- package/dist/esm/FilePreview/index.d.ts +2 -0
- package/dist/esm/FilePreview/index.js +2 -0
- package/dist/esm/Message/Message.d.ts +3 -0
- package/dist/esm/Message/Message.js +3 -2
- package/dist/esm/Message/Message.test.js +11 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/FilePreview.tsx +33 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +17 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +19 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +1 -0
- package/src/DeepThinking/DeepThinking.scss +24 -0
- package/src/DeepThinking/DeepThinking.test.tsx +61 -0
- package/src/DeepThinking/DeepThinking.tsx +68 -0
- package/src/DeepThinking/index.ts +3 -0
- package/src/FilePreview/FilePreview.scss +22 -0
- package/src/FilePreview/FilePreview.test.tsx +112 -0
- package/src/FilePreview/FilePreview.tsx +58 -0
- package/src/FilePreview/index.ts +3 -0
- package/src/Message/Message.test.tsx +13 -0
- package/src/Message/Message.tsx +5 -0
- package/src/index.ts +6 -0
- 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,26 @@
|
|
|
1
|
+
import { ModalBodyProps, ModalHeaderProps } from '@patternfly/react-core';
|
|
2
|
+
import type { FunctionComponent } from 'react';
|
|
3
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
4
|
+
import { ChatbotModalProps } from '../ChatbotModal';
|
|
5
|
+
export interface FilePreviewProps extends ChatbotModalProps {
|
|
6
|
+
/** Class applied to modal */
|
|
7
|
+
className?: string;
|
|
8
|
+
/** Function that handles modal toggle */
|
|
9
|
+
handleModalToggle: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
|
|
10
|
+
/** Whether modal is open */
|
|
11
|
+
isModalOpen: boolean;
|
|
12
|
+
/** Title of modal */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Display mode for the Chatbot parent; this influences the styles applied */
|
|
15
|
+
displayMode?: ChatbotDisplayMode;
|
|
16
|
+
/** File name */
|
|
17
|
+
fileName: string;
|
|
18
|
+
/** Sets modal to compact styling. */
|
|
19
|
+
isCompact?: boolean;
|
|
20
|
+
/** Additional props passed to modal header */
|
|
21
|
+
modalHeaderProps?: ModalHeaderProps;
|
|
22
|
+
/** Additional props passed to modal body */
|
|
23
|
+
modalBodyProps?: ModalBodyProps;
|
|
24
|
+
}
|
|
25
|
+
declare const FilePreview: FunctionComponent<FilePreviewProps>;
|
|
26
|
+
export default FilePreview;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { ModalBody, ModalHeader } from '@patternfly/react-core';
|
|
14
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
15
|
+
import ChatbotModal from '../ChatbotModal';
|
|
16
|
+
import { FileIcon } from '@patternfly/react-icons';
|
|
17
|
+
const FilePreview = (_a) => {
|
|
18
|
+
var { isModalOpen, displayMode = ChatbotDisplayMode.default, children, fileName, isCompact, className, handleModalToggle, title = 'File preview', modalHeaderProps, modalBodyProps } = _a, props = __rest(_a, ["isModalOpen", "displayMode", "children", "fileName", "isCompact", "className", "handleModalToggle", "title", "modalHeaderProps", "modalBodyProps"]);
|
|
19
|
+
return (_jsxs(ChatbotModal, Object.assign({ isOpen: isModalOpen, className: `pf-chatbot__file-preview-modal pf-chatbot__file-preview-modal--${displayMode} ${isCompact ? 'pf-m-compact' : ''} ${className ? className : ''}`, displayMode: displayMode, onClose: handleModalToggle, isCompact: isCompact }, props, { children: [_jsx(ModalHeader, Object.assign({ title: title }, modalHeaderProps)), _jsxs(ModalBody, Object.assign({ className: "pf-chatbot__file-preview-body" }, modalBodyProps, { children: [_jsx(FileIcon, { className: "pf-chatbot__file-preview-icon" }), _jsx("h2", { className: "pf-chatbot__file-preview-name", children: fileName }), children && _jsx("div", { className: "pf-chatbot__file-preview-body", children: children })] }))] })));
|
|
20
|
+
};
|
|
21
|
+
export default FilePreview;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
@@ -0,0 +1,92 @@
|
|
|
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 FilePreview from './FilePreview';
|
|
5
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
6
|
+
import { Button } from '@patternfly/react-core';
|
|
7
|
+
describe('FilePreview', () => {
|
|
8
|
+
const defaultProps = {
|
|
9
|
+
isModalOpen: true,
|
|
10
|
+
handleModalToggle: jest.fn(),
|
|
11
|
+
fileName: 'test-file.txt',
|
|
12
|
+
children: 'File content preview'
|
|
13
|
+
};
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
it('should render with basic props', () => {
|
|
18
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps)));
|
|
19
|
+
expect(screen.getByText('File preview')).toBeInTheDocument();
|
|
20
|
+
expect(screen.getByText('test-file.txt')).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
it('should render with custom title', () => {
|
|
23
|
+
const customTitle = 'Custom file preview title';
|
|
24
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { title: customTitle })));
|
|
25
|
+
expect(screen.getByRole('heading', { name: customTitle })).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
it('should handle modal toggle when closed', () => {
|
|
28
|
+
const mockToggle = jest.fn();
|
|
29
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { isModalOpen: false, handleModalToggle: mockToggle })));
|
|
30
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
31
|
+
});
|
|
32
|
+
it('should apply default display mode class', () => {
|
|
33
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps)));
|
|
34
|
+
const modal = screen.getByRole('dialog');
|
|
35
|
+
expect(modal).toHaveClass('pf-chatbot__file-preview-modal--default');
|
|
36
|
+
});
|
|
37
|
+
it('should apply custom display mode class', () => {
|
|
38
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { displayMode: ChatbotDisplayMode.fullscreen })));
|
|
39
|
+
const modal = screen.getByRole('dialog');
|
|
40
|
+
expect(modal).toHaveClass('pf-chatbot__file-preview-modal--fullscreen');
|
|
41
|
+
});
|
|
42
|
+
it('should apply compact styling when isCompact is true', () => {
|
|
43
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { isCompact: true })));
|
|
44
|
+
const modal = screen.getByRole('dialog');
|
|
45
|
+
expect(modal).toHaveClass('pf-m-compact');
|
|
46
|
+
});
|
|
47
|
+
it('should not apply compact styling when isCompact is false', () => {
|
|
48
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { isCompact: false })));
|
|
49
|
+
const modal = screen.getByRole('dialog');
|
|
50
|
+
expect(modal).not.toHaveClass('pf-m-compact');
|
|
51
|
+
});
|
|
52
|
+
it('should apply custom className', () => {
|
|
53
|
+
const customClass = 'custom-file-preview';
|
|
54
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { className: customClass })));
|
|
55
|
+
const modal = screen.getByRole('dialog');
|
|
56
|
+
expect(modal).toHaveClass(customClass);
|
|
57
|
+
});
|
|
58
|
+
it('should pass through additional props to ChatbotModal', () => {
|
|
59
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { "data-testid": "file-preview-modal" })));
|
|
60
|
+
const modal = screen.getByTestId('file-preview-modal');
|
|
61
|
+
expect(modal).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
it('should pass modalHeaderProps to ModalHeader', () => {
|
|
64
|
+
const modalHeaderProps = {
|
|
65
|
+
'data-testid': 'custom-header'
|
|
66
|
+
};
|
|
67
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { modalHeaderProps: modalHeaderProps })));
|
|
68
|
+
const header = screen.getByTestId('custom-header');
|
|
69
|
+
expect(header).toBeInTheDocument();
|
|
70
|
+
});
|
|
71
|
+
it('should pass modalBodyProps to ModalBody', () => {
|
|
72
|
+
const modalBodyProps = {
|
|
73
|
+
'data-testid': 'custom-body'
|
|
74
|
+
};
|
|
75
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { modalBodyProps: modalBodyProps })));
|
|
76
|
+
const body = screen.getByTestId('custom-body');
|
|
77
|
+
expect(body).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
it('should pass ouiaId to ChatbotModal', () => {
|
|
80
|
+
const ouiaId = 'file-preview-ouia-id';
|
|
81
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { ouiaId: ouiaId })));
|
|
82
|
+
const modal = screen.getByRole('dialog');
|
|
83
|
+
expect(modal).toHaveAttribute('data-ouia-component-id', ouiaId);
|
|
84
|
+
});
|
|
85
|
+
it('should handle complex children', () => {
|
|
86
|
+
const complexChildren = (_jsxs("div", { children: [_jsx("h3", { children: "File details" }), _jsx("p", { children: "Size: 1.2 MB" }), _jsx(Button, { children: "Download" })] }));
|
|
87
|
+
render(_jsx(FilePreview, Object.assign({}, defaultProps, { children: complexChildren })));
|
|
88
|
+
expect(screen.getByRole('heading', { name: /File details/i })).toBeTruthy();
|
|
89
|
+
expect(screen.getByText('Size: 1.2 MB')).toBeTruthy();
|
|
90
|
+
expect(screen.getByRole('button', { name: /Download/i })).toBeTruthy();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -11,6 +11,7 @@ import { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete';
|
|
|
11
11
|
import { TableProps } from '@patternfly/react-table';
|
|
12
12
|
import { PluggableList } from 'unified';
|
|
13
13
|
import { ToolResponseProps } from '../ToolResponse';
|
|
14
|
+
import { DeepThinkingProps } from '../DeepThinking';
|
|
14
15
|
export interface MessageAttachment {
|
|
15
16
|
/** Name of file attached to the message */
|
|
16
17
|
name: string;
|
|
@@ -148,6 +149,8 @@ export interface MessageProps extends Omit<HTMLProps<HTMLDivElement>, 'role'> {
|
|
|
148
149
|
reactMarkdownProps?: Options;
|
|
149
150
|
/** Props for tool response card */
|
|
150
151
|
toolResponse?: ToolResponseProps;
|
|
152
|
+
/** Props for deep thinking card */
|
|
153
|
+
deepThinking?: DeepThinkingProps;
|
|
151
154
|
}
|
|
152
155
|
export declare const MessageBase: FunctionComponent<MessageProps>;
|
|
153
156
|
declare const Message: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -45,8 +45,9 @@ import ErrorMessage from './ErrorMessage/ErrorMessage';
|
|
|
45
45
|
import MessageInput from './MessageInput';
|
|
46
46
|
import { rehypeMoveImagesOutOfParagraphs } from './Plugins/rehypeMoveImagesOutOfParagraphs';
|
|
47
47
|
import ToolResponse from '../ToolResponse';
|
|
48
|
+
import DeepThinking from '../DeepThinking';
|
|
48
49
|
export const MessageBase = (_a) => {
|
|
49
|
-
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 } = _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"]);
|
|
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"]);
|
|
50
51
|
const [messageText, setMessageText] = useState(content);
|
|
51
52
|
useEffect(() => {
|
|
52
53
|
setMessageText(content);
|
|
@@ -115,7 +116,7 @@ export const MessageBase = (_a) => {
|
|
|
115
116
|
}
|
|
116
117
|
return (_jsxs(_Fragment, { children: [beforeMainContent && _jsx(_Fragment, { children: beforeMainContent }), error ? _jsx(ErrorMessage, Object.assign({}, error)) : handleMarkdown()] }));
|
|
117
118
|
};
|
|
118
|
-
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)), !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) => {
|
|
119
120
|
var _a;
|
|
120
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));
|
|
121
122
|
}) })), !isLoading && endContent && _jsx(_Fragment, { children: endContent })] })] })] })));
|
|
@@ -138,6 +138,11 @@ const EMPTY_TABLE = `
|
|
|
138
138
|
`;
|
|
139
139
|
const IMAGE = ``;
|
|
140
140
|
const INLINE_IMAGE = `inline text `;
|
|
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: ',
|
|
@@ -759,4 +764,10 @@ describe('Message', () => {
|
|
|
759
764
|
// code block isn't rendering
|
|
760
765
|
expect(screen.queryByRole('button', { name: 'Copy code' })).toBeFalsy();
|
|
761
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
|
+
});
|
|
762
773
|
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -26,12 +26,16 @@ 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';
|
|
32
34
|
export * from './FileDetailsLabel';
|
|
33
35
|
export { default as FileDropZone } from './FileDropZone';
|
|
34
36
|
export * from './FileDropZone';
|
|
37
|
+
export { default as FilePreview } from './FilePreview';
|
|
38
|
+
export * from './FilePreview';
|
|
35
39
|
export { default as LoadingMessage } from './LoadingMessage';
|
|
36
40
|
export * from './LoadingMessage';
|
|
37
41
|
export { default as Message } from './Message';
|
package/dist/esm/index.js
CHANGED
|
@@ -27,12 +27,16 @@ 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';
|
|
33
35
|
export * from './FileDetailsLabel';
|
|
34
36
|
export { default as FileDropZone } from './FileDropZone';
|
|
35
37
|
export * from './FileDropZone';
|
|
38
|
+
export { default as FilePreview } from './FilePreview';
|
|
39
|
+
export * from './FilePreview';
|
|
36
40
|
export { default as LoadingMessage } from './LoadingMessage';
|
|
37
41
|
export * from './LoadingMessage';
|
|
38
42
|
export { default as Message } from './Message';
|
|
@@ -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/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"}
|
|
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/FilePreview/FilePreview.test.tsx","../src/FilePreview/FilePreview.tsx","../src/FilePreview/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.
|
|
3
|
+
"version": "6.4.0-prerelease.19",
|
|
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,33 @@
|
|
|
1
|
+
import { useState, FunctionComponent, MouseEvent as ReactMouseEvent } from 'react';
|
|
2
|
+
import { Button, Checkbox } from '@patternfly/react-core';
|
|
3
|
+
import FilePreview from '@patternfly/chatbot/dist/dynamic/FilePreview';
|
|
4
|
+
|
|
5
|
+
export const AttachmentEditModalExample: FunctionComponent = () => {
|
|
6
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
7
|
+
const [isCompact, setIsCompact] = useState(false);
|
|
8
|
+
|
|
9
|
+
const handleModalToggle = (_event: ReactMouseEvent | MouseEvent | KeyboardEvent) => {
|
|
10
|
+
setIsModalOpen(!isModalOpen);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
<Checkbox
|
|
16
|
+
label="Show compact version"
|
|
17
|
+
isChecked={isCompact}
|
|
18
|
+
onChange={() => setIsCompact(!isCompact)}
|
|
19
|
+
id="modal-compact-no-preview"
|
|
20
|
+
name="modal-compact-no-preview"
|
|
21
|
+
></Checkbox>
|
|
22
|
+
<Button onClick={handleModalToggle}>Launch file preview modal</Button>
|
|
23
|
+
<FilePreview
|
|
24
|
+
isModalOpen={isModalOpen}
|
|
25
|
+
handleModalToggle={handleModalToggle}
|
|
26
|
+
fileName="compressed-file.zip"
|
|
27
|
+
isCompact={isCompact}
|
|
28
|
+
>
|
|
29
|
+
Preview unavailable
|
|
30
|
+
</FilePreview>
|
|
31
|
+
</>
|
|
32
|
+
);
|
|
33
|
+
};
|
package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx
ADDED
|
@@ -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
|
+
);
|
|
@@ -47,6 +47,7 @@ import { monitorSampleAppQuickStart } from '@patternfly/chatbot/src/Message/Quic
|
|
|
47
47
|
import userAvatar from './user_avatar.svg';
|
|
48
48
|
import squareImg from './PF-social-color-square.svg';
|
|
49
49
|
import { CSSProperties, useState, Fragment, FunctionComponent, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent, Ref, isValidElement, cloneElement, Children, ReactNode, useRef, useEffect } from 'react';
|
|
50
|
+
import FilePreview from '@patternfly/chatbot/dist/dynamic/FilePreview';
|
|
50
51
|
|
|
51
52
|
The `content` prop of the `<Message>` component is passed to a `<Markdown>` component (from [react-markdown](https://remarkjs.github.io/react-markdown/)), which is configured to translate plain text strings into PatternFly [`<Content>` components](/components/content) and code blocks into PatternFly [`<CodeBlock>` components.](/components/code-block)
|
|
52
53
|
|
|
@@ -186,6 +187,16 @@ If you are using [model context protocol (MCP)](https://www.redhat.com/en/blog/m
|
|
|
186
187
|
|
|
187
188
|
```
|
|
188
189
|
|
|
190
|
+
### Messages with deep thinking
|
|
191
|
+
|
|
192
|
+
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.
|
|
193
|
+
|
|
194
|
+
Because this is an evolving area, this card content is currently fully customizable.
|
|
195
|
+
|
|
196
|
+
```js file="./MessageWithDeepThinking.tsx"
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
|
|
189
200
|
### Messages with quick start tiles
|
|
190
201
|
|
|
191
202
|
[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.
|
|
@@ -263,6 +274,14 @@ To allow users to edit an attached file, load a new code editor within the ChatB
|
|
|
263
274
|
|
|
264
275
|
```
|
|
265
276
|
|
|
277
|
+
### File preview
|
|
278
|
+
|
|
279
|
+
If the contents of an attachment cannot be previewed, load a file preview modal with a view of the file name and an unavailable message. When users close the modal, return to the main ChatBot window.
|
|
280
|
+
|
|
281
|
+
```js file="./FilePreview.tsx"
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
|
|
266
285
|
### Failed attachment error
|
|
267
286
|
|
|
268
287
|
When an attachment upload fails, a [danger alert](/components/alert) is displayed to provide details about the reason for failure.
|
|
@@ -87,6 +87,7 @@ import patternflyAvatar from '../Messages/patternfly_avatar.jpg';
|
|
|
87
87
|
import termsAndConditionsHeader from './PF-TermsAndConditionsHeader.svg';
|
|
88
88
|
import { CloseIcon, SearchIcon, OutlinedCommentsIcon } from '@patternfly/react-icons';
|
|
89
89
|
import { FunctionComponent, FormEvent, useState, useRef, MouseEvent, isValidElement, cloneElement, Children, ReactNode, Ref, MouseEvent as ReactMouseEvent, CSSProperties, useEffect} from 'react';
|
|
90
|
+
import FilePreview from '@patternfly/chatbot/dist/dynamic/FilePreview';
|
|
90
91
|
|
|
91
92
|
## Structure
|
|
92
93
|
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import DeepThinking from './DeepThinking';
|
|
4
|
+
|
|
5
|
+
describe('DeepThinking', () => {
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
toggleContent: 'Show thinking'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
it('should render with required props only', () => {
|
|
11
|
+
render(<DeepThinking {...defaultProps} />);
|
|
12
|
+
expect(screen.getByText('Show thinking')).toBeTruthy();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should render subheading when provided', () => {
|
|
16
|
+
const subheading = 'Thought for 3 seconds';
|
|
17
|
+
render(<DeepThinking {...defaultProps} subheading={subheading} />);
|
|
18
|
+
expect(screen.getByText(subheading)).toBeTruthy();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should render body content when provided', () => {
|
|
22
|
+
const body = "Here's why I think that";
|
|
23
|
+
render(<DeepThinking {...defaultProps} body={body} />);
|
|
24
|
+
expect(screen.getByText(body)).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should render with complex content including React elements', () => {
|
|
28
|
+
const body = (
|
|
29
|
+
<div>
|
|
30
|
+
<p>Complex body content</p>
|
|
31
|
+
<ul>
|
|
32
|
+
<li>Item 1</li>
|
|
33
|
+
<li>Item 2</li>
|
|
34
|
+
</ul>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
render(<DeepThinking {...defaultProps} body={body} />);
|
|
39
|
+
expect(screen.getByText('Complex body content')).toBeTruthy();
|
|
40
|
+
expect(screen.getByText('Item 1')).toBeTruthy();
|
|
41
|
+
expect(screen.getByText('Item 2')).toBeTruthy();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should apply custom className from cardProps', () => {
|
|
45
|
+
const { container } = render(
|
|
46
|
+
<DeepThinking {...defaultProps} cardProps={{ className: 'custom-tool-response-class' }} />
|
|
47
|
+
);
|
|
48
|
+
expect(container.querySelector('.custom-tool-response-class')).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should pass through expandableSectionProps', () => {
|
|
52
|
+
render(<DeepThinking {...defaultProps} expandableSectionProps={{ className: 'custom-expandable-class' }} />);
|
|
53
|
+
expect(document.querySelector('.custom-expandable-class')).toBeTruthy();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should not render subheading span when subheading is not provided', () => {
|
|
57
|
+
const { container } = render(<DeepThinking {...defaultProps} />);
|
|
58
|
+
const subheadingContainer = container.querySelector('.pf-chatbot__tool-response-subheading');
|
|
59
|
+
expect(subheadingContainer).toBeFalsy();
|
|
60
|
+
});
|
|
61
|
+
});
|