@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.
- 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/Message/Message.d.ts +6 -0
- package/dist/cjs/Message/Message.js +4 -2
- package/dist/cjs/Message/Message.test.js +25 -0
- package/dist/cjs/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/cjs/ToolResponse/ToolResponse.js +18 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.js +60 -0
- package/dist/cjs/ToolResponse/index.d.ts +2 -0
- package/dist/cjs/ToolResponse/index.js +23 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +7 -1
- package/dist/css/main.css +61 -0
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/DeepThinking/package.json +1 -0
- package/dist/dynamic/ToolResponse/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/Message/Message.d.ts +6 -0
- package/dist/esm/Message/Message.js +4 -2
- package/dist/esm/Message/Message.test.js +25 -0
- package/dist/esm/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/esm/ToolResponse/ToolResponse.js +14 -0
- package/dist/esm/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/esm/ToolResponse/ToolResponse.test.js +55 -0
- package/dist/esm/ToolResponse/index.d.ts +2 -0
- package/dist/esm/ToolResponse/index.js +2 -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/MessageWithDeepThinking.tsx +17 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +135 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +19 -1
- 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/Message/Message.test.tsx +35 -0
- package/src/Message/Message.tsx +10 -0
- package/src/ToolResponse/ToolResponse.scss +36 -0
- package/src/ToolResponse/ToolResponse.test.tsx +78 -0
- package/src/ToolResponse/ToolResponse.tsx +95 -0
- package/src/ToolResponse/index.ts +3 -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
|
+
});
|
|
@@ -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 = ``;
|
|
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: ',
|
|
@@ -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
|
+
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -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.
|
|
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",
|
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
|
+
);
|
package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx
ADDED
|
@@ -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
|
+
}
|