@gravity-ui/aikit 1.8.0 → 1.9.0
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/components/atoms/Alert/index.js +1 -1
- package/dist/components/atoms/ChatDate/ChatDate.js +1 -1
- package/dist/components/atoms/ContextIndicator/index.js +1 -1
- package/dist/components/atoms/DiffStat/index.js +1 -1
- package/dist/components/atoms/Disclaimer/Disclaimer.js +1 -1
- package/dist/components/atoms/IntersectionContainer/IntersectionContainer.js +1 -1
- package/dist/components/atoms/Loader/Loader.js +1 -1
- package/dist/components/atoms/MarkdownRenderer/MarkdownRenderer.js +1 -1
- package/dist/components/atoms/MessageBalloon/index.js +1 -1
- package/dist/components/atoms/Shimmer/index.js +1 -1
- package/dist/components/atoms/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/atoms/ToolIndicator/index.js +1 -1
- package/dist/components/molecules/BaseMessage/BaseMessage.css +1 -0
- package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.d.ts +1 -0
- package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.js +10 -0
- package/dist/components/molecules/BaseMessage/index.js +22 -14
- package/dist/components/molecules/ButtonGroup/index.js +1 -1
- package/dist/components/molecules/PromptInputBody/PromptInputBody.js +1 -1
- package/dist/components/molecules/PromptInputFooter/PromptInputFooter.js +1 -1
- package/dist/components/molecules/PromptInputHeader/PromptInputHeader.js +1 -1
- package/dist/components/molecules/PromptInputPanel/PromptInputPanel.js +1 -1
- package/dist/components/molecules/Suggestions/Suggestions.js +1 -1
- package/dist/components/molecules/Tabs/Tabs.js +1 -1
- package/dist/components/molecules/ToolFooter/index.js +1 -1
- package/dist/components/molecules/ToolHeader/index.js +1 -1
- package/dist/components/molecules/ToolStatus/index.js +1 -1
- package/dist/components/organisms/AssistantMessage/AssistantMessage.d.ts +2 -2
- package/dist/components/organisms/AssistantMessage/AssistantMessage.js +3 -3
- package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.d.ts +1 -0
- package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.js +12 -1
- package/dist/components/organisms/Header/Header.js +1 -1
- package/dist/components/organisms/MessageList/MessageList.js +2 -2
- package/dist/components/organisms/MessageList/__stories__/MessageList.stories.d.ts +1 -0
- package/dist/components/organisms/MessageList/__stories__/MessageList.stories.js +54 -4
- package/dist/components/organisms/PromptInput/PromptInput.js +1 -1
- package/dist/components/organisms/ThinkingMessage/index.js +1 -1
- package/dist/components/organisms/ToolMessage/index.js +1 -1
- package/dist/components/organisms/UserMessage/index.js +1 -1
- package/dist/components/pages/ChatContainer/ChatContainer.js +1 -1
- package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.d.ts +5 -0
- package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.js +77 -0
- package/dist/components/templates/ChatContent/ChatContent.js +1 -1
- package/dist/components/templates/EmptyContainer/EmptyContainer.js +1 -1
- package/dist/components/templates/History/HistoryList.js +1 -1
- package/dist/demo/ContentWrapper/ContentWrapper.js +1 -1
- package/dist/demo/Showcase/Showcase.js +1 -1
- package/dist/demo/ShowcaseItem/ShowcaseItem.js +1 -1
- package/dist/demo/SwapArea/SwapArea.js +1 -1
- package/dist/types/messages.d.ts +3 -0
- package/package.json +3 -2
|
@@ -3,7 +3,7 @@ import { useMemo, useState } from 'react';
|
|
|
3
3
|
import { ChevronDown, ChevronUp, CircleExclamationFill, CircleInfoFill, TriangleExclamationFill, } from '@gravity-ui/icons';
|
|
4
4
|
import { Button, Icon, Text } from '@gravity-ui/uikit';
|
|
5
5
|
import { block } from '../../../utils/cn';
|
|
6
|
-
import './Alert.
|
|
6
|
+
import './Alert.css';
|
|
7
7
|
const b = block('alert');
|
|
8
8
|
const statusIcons = {
|
|
9
9
|
info: CircleInfoFill,
|
|
@@ -3,7 +3,7 @@ import { Fragment } from 'react';
|
|
|
3
3
|
import { useDateFormatter } from '../../../hooks';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
5
|
import { i18n } from './i18n';
|
|
6
|
-
import './ChatDate.
|
|
6
|
+
import './ChatDate.css';
|
|
7
7
|
const b = block('chat-date');
|
|
8
8
|
/**
|
|
9
9
|
* ChatDate component displays formatted dates with optional time
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
3
|
import { getProgressColor } from './utils';
|
|
4
|
-
import './ContextIndicator.
|
|
4
|
+
import './ContextIndicator.css';
|
|
5
5
|
const b = block('context-indicator');
|
|
6
6
|
export const ContextIndicator = (props) => {
|
|
7
7
|
const { className, qa, orientation = 'horizontal', reversed = false } = props;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
|
-
import './DiffStat.
|
|
3
|
+
import './DiffStat.css';
|
|
4
4
|
const b = block('diff-stat');
|
|
5
5
|
export const DiffStat = (props) => {
|
|
6
6
|
const { added, deleted, className, style, qa } = props;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Text } from '@gravity-ui/uikit';
|
|
3
3
|
import { block } from '../../../utils/cn';
|
|
4
|
-
import './Disclaimer.
|
|
4
|
+
import './Disclaimer.css';
|
|
5
5
|
const b = block('disclaimer');
|
|
6
6
|
/**
|
|
7
7
|
* Disclaimer component displays informational or warning messages
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { useIntersection } from '@gravity-ui/uikit';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
|
-
import './IntersectionContainer.
|
|
5
|
+
import './IntersectionContainer.css';
|
|
6
6
|
const b = block('intersection-container');
|
|
7
7
|
export const IntersectionContainer = ({ children, onIntersect, options, className, }) => {
|
|
8
8
|
const [ref, setRef] = React.useState(null);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Spin } from '@gravity-ui/uikit';
|
|
3
3
|
import { block } from '../../../utils/cn';
|
|
4
|
-
import './Loader.
|
|
4
|
+
import './Loader.css';
|
|
5
5
|
const b = block('loader');
|
|
6
6
|
export function Loader({ view = 'streaming', size = 's', className, qa }) {
|
|
7
7
|
if (view === 'streaming') {
|
|
@@ -4,7 +4,7 @@ import { useMarkdownTransform } from '../../../hooks/useMarkdownTransform';
|
|
|
4
4
|
import { useRemend } from '../../../hooks/useRemend';
|
|
5
5
|
import { block } from '../../../utils/cn';
|
|
6
6
|
import { areOptionsEqual } from '../../../utils/markdownUtils';
|
|
7
|
-
import './MarkdownRenderer.
|
|
7
|
+
import './MarkdownRenderer.css';
|
|
8
8
|
const b = block('markdown-renderer');
|
|
9
9
|
function MarkdownRendererComponent({ content, className, qa, transformOptions, shouldParseIncompleteMarkdown = false, }) {
|
|
10
10
|
const closedContent = useRemend(content, shouldParseIncompleteMarkdown);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
|
-
import './MessageBalloon.
|
|
3
|
+
import './MessageBalloon.css';
|
|
4
4
|
const b = block('message-balloon');
|
|
5
5
|
export const MessageBalloon = (props) => {
|
|
6
6
|
const { className, qa, children } = props;
|
|
@@ -5,7 +5,7 @@ import { Icon, Spin } from '@gravity-ui/uikit';
|
|
|
5
5
|
import { block } from '../../../utils/cn';
|
|
6
6
|
import { ActionButton } from '../ActionButton';
|
|
7
7
|
import { i18n } from './i18n';
|
|
8
|
-
import './SubmitButton.
|
|
8
|
+
import './SubmitButton.css';
|
|
9
9
|
const b = block('submit-button');
|
|
10
10
|
/**
|
|
11
11
|
* Submit button component with state management through props
|
|
@@ -3,7 +3,7 @@ import { CircleCheck, CircleInfo, CircleXmark } from '@gravity-ui/icons';
|
|
|
3
3
|
import { Icon } from '@gravity-ui/uikit';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
5
|
import { Loader } from '../Loader';
|
|
6
|
-
import './ToolIndicator.
|
|
6
|
+
import './ToolIndicator.css';
|
|
7
7
|
const b = block('tool-indicator');
|
|
8
8
|
export const ToolIndicator = (props) => {
|
|
9
9
|
const { status = 'info', className, qa } = props;
|
|
@@ -7,3 +7,4 @@ export declare const Variant: StoryObj<BaseMessageProps>;
|
|
|
7
7
|
export declare const ShowActionsOnHover: StoryFn<BaseMessageProps>;
|
|
8
8
|
export declare const ShowTimestamp: StoryObj<BaseMessageProps>;
|
|
9
9
|
export declare const WithCustomAction: StoryFn<BaseMessageProps>;
|
|
10
|
+
export declare const WithUserRating: StoryObj<BaseMessageProps>;
|
|
@@ -50,6 +50,12 @@ const buttons = [
|
|
|
50
50
|
// eslint-disable-next-line no-console
|
|
51
51
|
{ actionType: 'unlike', onClick: () => console.log('unlike') },
|
|
52
52
|
];
|
|
53
|
+
const likeUnlikeButtons = [
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
{ actionType: 'like', onClick: () => console.log('like') },
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
{ actionType: 'unlike', onClick: () => console.log('unlike') },
|
|
58
|
+
];
|
|
53
59
|
export const Playground = (args) => (_jsx(ContentWrapper, { children: _jsx(BaseMessage, Object.assign({}, args)) }));
|
|
54
60
|
Playground.args = {
|
|
55
61
|
children: 'My message',
|
|
@@ -75,3 +81,7 @@ export const WithCustomAction = (args) => (_jsx(ContentWrapper, { children: _jsx
|
|
|
75
81
|
// eslint-disable-next-line no-console
|
|
76
82
|
onClick: () => console.log('custom'), children: "Custom" }, "custom"),
|
|
77
83
|
], role: "assistant", children: 'Message with custom action button' })) }));
|
|
84
|
+
export const WithUserRating = {
|
|
85
|
+
render: (args) => (_jsxs(_Fragment, { children: [_jsx(ShowcaseItem, { title: "No rating", width: "300px", children: _jsx(BaseMessage, Object.assign({}, args, { actions: likeUnlikeButtons, role: "assistant", children: 'Message' })) }), _jsx(ShowcaseItem, { title: "Rated like", width: "300px", children: _jsx(BaseMessage, Object.assign({}, args, { actions: likeUnlikeButtons, role: "assistant", userRating: "like", children: 'Message' })) }), _jsx(ShowcaseItem, { title: "Rated dislike", width: "300px", children: _jsx(BaseMessage, Object.assign({}, args, { actions: likeUnlikeButtons, role: "assistant", userRating: "dislike", children: 'Message' })) })] })),
|
|
86
|
+
decorators: defaultDecorators,
|
|
87
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { ArrowRotateLeft, Copy as CopyIcon, Pencil, ThumbsDown, ThumbsUp, TrashBin, } from '@gravity-ui/icons';
|
|
3
|
+
import { ArrowRotateLeft, Copy as CopyIcon, Pencil, ThumbsDown, ThumbsDownFill, ThumbsUp, ThumbsUpFill, TrashBin, } from '@gravity-ui/icons';
|
|
4
4
|
import { Icon } from '@gravity-ui/uikit';
|
|
5
5
|
import { isActionConfig } from '../../../utils/actionUtils';
|
|
6
6
|
import { block } from '../../../utils/cn';
|
|
@@ -8,7 +8,7 @@ import { ActionButton } from '../../atoms';
|
|
|
8
8
|
import { ChatDate } from '../../atoms/ChatDate';
|
|
9
9
|
import { ButtonGroup } from '../ButtonGroup';
|
|
10
10
|
import { i18n } from './i18n';
|
|
11
|
-
import './BaseMessage.
|
|
11
|
+
import './BaseMessage.css';
|
|
12
12
|
const b = block('base-message');
|
|
13
13
|
export var BaseMessageActionType;
|
|
14
14
|
(function (BaseMessageActionType) {
|
|
@@ -19,16 +19,8 @@ export var BaseMessageActionType;
|
|
|
19
19
|
BaseMessageActionType["Unlike"] = "unlike";
|
|
20
20
|
BaseMessageActionType["Delete"] = "delete";
|
|
21
21
|
})(BaseMessageActionType || (BaseMessageActionType = {}));
|
|
22
|
-
const BaseMessageActionIcons = {
|
|
23
|
-
[BaseMessageActionType.Copy]: CopyIcon,
|
|
24
|
-
[BaseMessageActionType.Edit]: Pencil,
|
|
25
|
-
[BaseMessageActionType.Retry]: ArrowRotateLeft,
|
|
26
|
-
[BaseMessageActionType.Like]: ThumbsUp,
|
|
27
|
-
[BaseMessageActionType.Unlike]: ThumbsDown,
|
|
28
|
-
[BaseMessageActionType.Delete]: TrashBin,
|
|
29
|
-
};
|
|
30
22
|
export const BaseMessage = (props) => {
|
|
31
|
-
const { className, qa, showActionsOnHover, actions, children, role: variant, showTimestamp, timestamp = '', } = props;
|
|
23
|
+
const { className, qa, showActionsOnHover, actions, children, role: variant, showTimestamp, timestamp = '', userRating, } = props;
|
|
32
24
|
// Get tooltip text for action
|
|
33
25
|
const getTooltipText = (actionType) => {
|
|
34
26
|
if (!actionType) {
|
|
@@ -49,9 +41,7 @@ export const BaseMessage = (props) => {
|
|
|
49
41
|
return _jsx(React.Fragment, { children: action }, index);
|
|
50
42
|
}
|
|
51
43
|
const tooltipText = getTooltipText(action.actionType);
|
|
52
|
-
const defaultIcon = action.actionType
|
|
53
|
-
? BaseMessageActionIcons[action.actionType]
|
|
54
|
-
: undefined;
|
|
44
|
+
const defaultIcon = getDefaultIcon(action.actionType, userRating);
|
|
55
45
|
// Determine tooltip title
|
|
56
46
|
let tooltipTitle;
|
|
57
47
|
if (action.label) {
|
|
@@ -77,3 +67,21 @@ export const BaseMessage = (props) => {
|
|
|
77
67
|
return (_jsx(ActionButton, Object.assign({}, action, { tooltipTitle: tooltipTitle, view: action.view || 'flat-secondary', children: buttonContent }), action.actionType || index));
|
|
78
68
|
}) })] }))] }));
|
|
79
69
|
};
|
|
70
|
+
function getDefaultIcon(actionType, userRating) {
|
|
71
|
+
switch (actionType) {
|
|
72
|
+
case BaseMessageActionType.Copy:
|
|
73
|
+
return CopyIcon;
|
|
74
|
+
case BaseMessageActionType.Edit:
|
|
75
|
+
return Pencil;
|
|
76
|
+
case BaseMessageActionType.Retry:
|
|
77
|
+
return ArrowRotateLeft;
|
|
78
|
+
case BaseMessageActionType.Delete:
|
|
79
|
+
return TrashBin;
|
|
80
|
+
case BaseMessageActionType.Like:
|
|
81
|
+
return userRating === 'like' ? ThumbsUpFill : ThumbsUp;
|
|
82
|
+
case BaseMessageActionType.Unlike:
|
|
83
|
+
return userRating === 'dislike' ? ThumbsDownFill : ThumbsDown;
|
|
84
|
+
default:
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
|
-
import './ButtonGroup.
|
|
3
|
+
import './ButtonGroup.css';
|
|
4
4
|
const b = block('button-group');
|
|
5
5
|
export const ButtonGroup = (props) => {
|
|
6
6
|
const { orientation = 'horizontal', className, qa, children } = props;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
3
|
import { TextArea } from '@gravity-ui/uikit';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
|
-
import './PromptInputBody.
|
|
5
|
+
import './PromptInputBody.css';
|
|
6
6
|
const b = block('prompt-input-body');
|
|
7
7
|
/**
|
|
8
8
|
* PromptInputBody component displays the main input area
|
|
@@ -6,7 +6,7 @@ import { ActionButton } from '../../atoms/ActionButton';
|
|
|
6
6
|
import { SubmitButton } from '../../atoms/SubmitButton';
|
|
7
7
|
import { ButtonGroup } from '../ButtonGroup';
|
|
8
8
|
import { i18n } from './i18n';
|
|
9
|
-
import './PromptInputFooter.
|
|
9
|
+
import './PromptInputFooter.css';
|
|
10
10
|
const b = block('prompt-input-footer');
|
|
11
11
|
/**
|
|
12
12
|
* PromptInputFooter component displays the footer section with action icons
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
3
|
import { ContextIndicator } from '../../atoms/ContextIndicator';
|
|
4
4
|
import { ContextItem } from '../../atoms/ContextItem';
|
|
5
|
-
import './PromptInputHeader.
|
|
5
|
+
import './PromptInputHeader.css';
|
|
6
6
|
const b = block('prompt-input-header');
|
|
7
7
|
/**
|
|
8
8
|
* PromptInputHeader component displays the header section of prompt input
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
|
-
import './PromptInputPanel.
|
|
3
|
+
import './PromptInputPanel.css';
|
|
4
4
|
const b = block('prompt-input-panel');
|
|
5
5
|
/**
|
|
6
6
|
* PromptInputPanel component displays a panel with custom content
|
|
@@ -3,7 +3,7 @@ import { ChevronLeft, ChevronRight } from '@gravity-ui/icons';
|
|
|
3
3
|
import { Icon, Text } from '@gravity-ui/uikit';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
5
|
import { ActionButton } from '../../atoms';
|
|
6
|
-
import './Suggestions.
|
|
6
|
+
import './Suggestions.css';
|
|
7
7
|
const b = block('suggestions');
|
|
8
8
|
/**
|
|
9
9
|
* Suggestions component displays a group of clickable suggestion buttons
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import { Label } from '@gravity-ui/uikit';
|
|
5
5
|
import { block } from '../../../utils/cn';
|
|
6
|
-
import './Tabs.
|
|
6
|
+
import './Tabs.css';
|
|
7
7
|
const b = block('tabs');
|
|
8
8
|
export const Tabs = (props) => {
|
|
9
9
|
const { items, activeId, onSelectItem, onDeleteItem, allowDelete = false, className, style, qa, } = props;
|
|
@@ -5,7 +5,7 @@ import { isActionConfig } from '../../../utils/actionUtils';
|
|
|
5
5
|
import { block } from '../../../utils/cn';
|
|
6
6
|
import { Loader, Shimmer } from '../../atoms';
|
|
7
7
|
import { ButtonGroup } from '../ButtonGroup';
|
|
8
|
-
import './ToolFooter.
|
|
8
|
+
import './ToolFooter.css';
|
|
9
9
|
const b = block('tool-footer');
|
|
10
10
|
export function ToolFooter({ actions, content, showLoader = true, className, qa }) {
|
|
11
11
|
return (_jsxs("div", { className: b('', className), "data-qa": qa, children: [_jsxs("div", { className: b('left'), children: [showLoader && _jsx(Loader, { view: "loading", size: "xs" }), content && (_jsx(Shimmer, { children: _jsx(Text, { children: content }) }))] }), _jsx(ButtonGroup, { children: actions.map((action, index) => {
|
|
@@ -6,7 +6,7 @@ import { block } from '../../../utils/cn';
|
|
|
6
6
|
import { ActionButton } from '../../atoms';
|
|
7
7
|
import { ButtonGroup } from '../ButtonGroup';
|
|
8
8
|
import { ToolStatus } from '../ToolStatus';
|
|
9
|
-
import './ToolHeader.
|
|
9
|
+
import './ToolHeader.css';
|
|
10
10
|
const b = block('tool-header');
|
|
11
11
|
export function ToolHeader(props) {
|
|
12
12
|
const { toolIcon, toolName, content, actions, status, className, qa } = props;
|
|
@@ -3,7 +3,7 @@ import { Text } from '@gravity-ui/uikit';
|
|
|
3
3
|
import { block } from '../../../utils/cn';
|
|
4
4
|
import { ToolIndicator } from '../../atoms';
|
|
5
5
|
import { i18n } from './i18n';
|
|
6
|
-
import './ToolStatus.
|
|
6
|
+
import './ToolStatus.css';
|
|
7
7
|
const b = block('tool-status');
|
|
8
8
|
function getIndicatorStatus(status) {
|
|
9
9
|
if (status === 'success' || status === 'error' || status === 'loading') {
|
|
@@ -3,7 +3,7 @@ import type { BaseMessageProps, TAssistantMessage, TMessageContent, TMessageMeta
|
|
|
3
3
|
import { type MessageRendererRegistry } from '../../../utils/messageTypeRegistry';
|
|
4
4
|
import './AssistantMessage.scss';
|
|
5
5
|
type BaseMessagePick = Pick<BaseMessageProps, 'actions' | 'timestamp' | 'showActionsOnHover' | 'showTimestamp'>;
|
|
6
|
-
type AssistantMessagePick<TContent extends TMessageContent> = Pick<TAssistantMessage<TContent, TMessageMetadata>, 'id' | 'content'>;
|
|
6
|
+
type AssistantMessagePick<TContent extends TMessageContent> = Pick<TAssistantMessage<TContent, TMessageMetadata>, 'id' | 'content' | 'userRating'>;
|
|
7
7
|
export type AssistantMessageProps<TContent extends TMessageContent = never> = BaseMessagePick & AssistantMessagePick<TContent> & {
|
|
8
8
|
messageRendererRegistry?: MessageRendererRegistry;
|
|
9
9
|
transformOptions?: OptionsType;
|
|
@@ -11,5 +11,5 @@ export type AssistantMessageProps<TContent extends TMessageContent = never> = Ba
|
|
|
11
11
|
className?: string;
|
|
12
12
|
qa?: string;
|
|
13
13
|
};
|
|
14
|
-
export declare function AssistantMessage<TContent extends TMessageContent = never>({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, className, qa, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
14
|
+
export declare function AssistantMessage<TContent extends TMessageContent = never>({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, userRating, className, qa, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
15
15
|
export {};
|
|
@@ -5,9 +5,9 @@ import { getMessageRenderer, mergeMessageRendererRegistries, } from '../../../ut
|
|
|
5
5
|
import { normalizeContent } from '../../../utils/messageUtils';
|
|
6
6
|
import { BaseMessage } from '../../molecules/BaseMessage';
|
|
7
7
|
import { createDefaultMessageRegistry } from './defaultMessageTypeRegistry';
|
|
8
|
-
import './AssistantMessage.
|
|
8
|
+
import './AssistantMessage.css';
|
|
9
9
|
const b = block('assistant-message');
|
|
10
|
-
export function AssistantMessage({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, className, qa, }) {
|
|
10
|
+
export function AssistantMessage({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, userRating, className, qa, }) {
|
|
11
11
|
const registry = useMemo(() => {
|
|
12
12
|
const defaultRegistry = createDefaultMessageRegistry(transformOptions, shouldParseIncompleteMarkdown);
|
|
13
13
|
if (messageRendererRegistry) {
|
|
@@ -27,5 +27,5 @@ export function AssistantMessage({ content, actions, timestamp, id, messageRende
|
|
|
27
27
|
const key = part.id || `${id || 'message'}-part-${partIndex}`;
|
|
28
28
|
return _jsx(PartComponent, { part: part }, key);
|
|
29
29
|
};
|
|
30
|
-
return (_jsx(BaseMessage, { role: "assistant", actions: actions, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, className: b(null, className), qa: qa, children: _jsx("div", { className: b('content'), children: parts.map((part, index) => renderPart(part, index)) }) }));
|
|
30
|
+
return (_jsx(BaseMessage, { role: "assistant", actions: actions, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, userRating: userRating, className: b(null, className), qa: qa, children: _jsx("div", { className: b('content'), children: parts.map((part, index) => renderPart(part, index)) }) }));
|
|
31
31
|
}
|
package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { TMessageContent } from '../../../../types/messages';
|
|
|
4
4
|
declare const _default: Meta;
|
|
5
5
|
export default _default;
|
|
6
6
|
export declare const Playground: StoryFn<AssistantMessageProps>;
|
|
7
|
+
export declare const WithUserRating: StoryObj<AssistantMessageProps>;
|
|
7
8
|
export declare const WithToolCall: StoryObj<AssistantMessageProps>;
|
|
8
9
|
export declare const WithThinkingContent: StoryObj<AssistantMessageProps>;
|
|
9
10
|
interface CustomMessageData {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
3
|
import { Pencil } from '@gravity-ui/icons';
|
|
4
4
|
import { Icon, Text } from '@gravity-ui/uikit';
|
|
@@ -45,6 +45,11 @@ export default {
|
|
|
45
45
|
control: 'boolean',
|
|
46
46
|
description: 'Show timestamp in actions area',
|
|
47
47
|
},
|
|
48
|
+
userRating: {
|
|
49
|
+
control: 'radio',
|
|
50
|
+
options: [undefined, 'like', 'dislike'],
|
|
51
|
+
description: 'Current user rating (filled like/unlike icons when set)',
|
|
52
|
+
},
|
|
48
53
|
className: {
|
|
49
54
|
control: 'text',
|
|
50
55
|
description: 'Additional CSS class',
|
|
@@ -102,6 +107,12 @@ Playground.args = {
|
|
|
102
107
|
timestamp: simpleMessage.timestamp,
|
|
103
108
|
id: simpleMessage.id,
|
|
104
109
|
};
|
|
110
|
+
export const WithUserRating = {
|
|
111
|
+
render: (args) => (_jsxs(_Fragment, { children: [_jsx(ShowcaseItem, { title: "Rated like", width: "400px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: "This message has userRating: like (thumb up filled).", actions: actions, userRating: "like" })) }), _jsx(ShowcaseItem, { title: "Rated dislike", width: "400px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: "This message has userRating: dislike (thumb down filled).", actions: actions, userRating: "dislike" })) })] })),
|
|
112
|
+
decorators: [
|
|
113
|
+
(Story) => (_jsx(ContentWrapper, { children: _jsx(Showcase, { children: _jsx(Story, {}) }) })),
|
|
114
|
+
],
|
|
115
|
+
};
|
|
105
116
|
export const WithToolCall = {
|
|
106
117
|
render: (args) => (_jsx(ShowcaseItem, { title: "With Tool Call", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: multiPartMessage.content, actions: actions, timestamp: multiPartMessage.timestamp, id: multiPartMessage.id })) }) })),
|
|
107
118
|
decorators: [
|
|
@@ -9,7 +9,7 @@ import { ButtonGroup } from '../../molecules';
|
|
|
9
9
|
import { i18n } from './i18n';
|
|
10
10
|
import { HeaderAction } from './types';
|
|
11
11
|
import { useHeader } from './useHeader';
|
|
12
|
-
import './Header.
|
|
12
|
+
import './Header.css';
|
|
13
13
|
const b = block('header');
|
|
14
14
|
// Icons for base actions
|
|
15
15
|
const ACTION_ICONS = {
|
|
@@ -7,7 +7,7 @@ import { Loader } from '../../atoms/Loader';
|
|
|
7
7
|
import { AssistantMessage } from '../AssistantMessage';
|
|
8
8
|
import { UserMessage } from '../UserMessage';
|
|
9
9
|
import { ErrorAlert } from './ErrorAlert';
|
|
10
|
-
import './MessageList.
|
|
10
|
+
import './MessageList.css';
|
|
11
11
|
const b = block('message-list');
|
|
12
12
|
export function MessageList({ messages, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, }) {
|
|
13
13
|
const isStreaming = status === 'streaming' || status === 'streaming_loading';
|
|
@@ -34,7 +34,7 @@ export function MessageList({ messages, messageRendererRegistry, transformOption
|
|
|
34
34
|
const actions = showActions && !hasOnlyThinkingContent(message.content)
|
|
35
35
|
? resolveMessageActions(message, assistantActions)
|
|
36
36
|
: undefined;
|
|
37
|
-
return (_jsx(AssistantMessage, { content: message.content, actions: actions, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp }, message.id || `message-${index}`));
|
|
37
|
+
return (_jsx(AssistantMessage, { content: message.content, actions: actions, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, userRating: message.userRating }, message.id || `message-${index}`));
|
|
38
38
|
}
|
|
39
39
|
return null;
|
|
40
40
|
};
|
|
@@ -22,4 +22,5 @@ type ChartMessageContent = TMessageContent<'chart', ChartMessageData>;
|
|
|
22
22
|
export declare const WithCustomMessageType: StoryObj<MessageListProps<ChartMessageContent>>;
|
|
23
23
|
export declare const WithStreamingMessage: StoryObj<MessageListProps>;
|
|
24
24
|
export declare const WithDefaultActions: StoryObj<MessageListProps>;
|
|
25
|
+
export declare const WithUserRating: StoryObj<MessageListProps>;
|
|
25
26
|
export declare const WithPreviousMessages: StoryObj<MessageListProps>;
|
|
@@ -223,14 +223,14 @@ export const WithDefaultActions = {
|
|
|
223
223
|
render: (args) => {
|
|
224
224
|
const userActions = [
|
|
225
225
|
{
|
|
226
|
-
|
|
226
|
+
type: BaseMessageActionType.Edit,
|
|
227
227
|
onClick: (message) => {
|
|
228
228
|
// eslint-disable-next-line no-console
|
|
229
229
|
console.log('Edit user message:', message.id);
|
|
230
230
|
},
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
|
-
|
|
233
|
+
type: BaseMessageActionType.Delete,
|
|
234
234
|
onClick: (message) => {
|
|
235
235
|
// eslint-disable-next-line no-console
|
|
236
236
|
console.log('Delete user message:', message.id);
|
|
@@ -239,14 +239,14 @@ export const WithDefaultActions = {
|
|
|
239
239
|
];
|
|
240
240
|
const assistantActions = [
|
|
241
241
|
{
|
|
242
|
-
|
|
242
|
+
type: BaseMessageActionType.Copy,
|
|
243
243
|
onClick: (message) => {
|
|
244
244
|
// eslint-disable-next-line no-console
|
|
245
245
|
console.log('Copy assistant message:', message.id);
|
|
246
246
|
},
|
|
247
247
|
},
|
|
248
248
|
{
|
|
249
|
-
|
|
249
|
+
type: BaseMessageActionType.Like,
|
|
250
250
|
onClick: (message) => {
|
|
251
251
|
// eslint-disable-next-line no-console
|
|
252
252
|
console.log('Like assistant message:', message.id);
|
|
@@ -291,6 +291,56 @@ export const WithDefaultActions = {
|
|
|
291
291
|
},
|
|
292
292
|
decorators: defaultDecorators,
|
|
293
293
|
};
|
|
294
|
+
export const WithUserRating = {
|
|
295
|
+
render: (args) => {
|
|
296
|
+
const assistantActions = [
|
|
297
|
+
{
|
|
298
|
+
type: BaseMessageActionType.Copy,
|
|
299
|
+
onClick: (message) => {
|
|
300
|
+
// eslint-disable-next-line no-console
|
|
301
|
+
console.log('Copy:', message.id);
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
type: BaseMessageActionType.Like,
|
|
306
|
+
onClick: (message) => {
|
|
307
|
+
// eslint-disable-next-line no-console
|
|
308
|
+
console.log('Like:', message.id);
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
type: BaseMessageActionType.Unlike,
|
|
313
|
+
onClick: (message) => {
|
|
314
|
+
// eslint-disable-next-line no-console
|
|
315
|
+
console.log('Unlike:', message.id);
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
];
|
|
319
|
+
return (_jsx(ShowcaseItem, { title: "With User Rating", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [
|
|
320
|
+
{
|
|
321
|
+
id: 'user-1',
|
|
322
|
+
role: 'user',
|
|
323
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
324
|
+
content: 'Compare these two answers.',
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
id: 'assistant-like',
|
|
328
|
+
role: 'assistant',
|
|
329
|
+
timestamp: '2024-01-01T00:00:01Z',
|
|
330
|
+
content: 'This message is rated as liked (filled thumb up).',
|
|
331
|
+
userRating: 'like',
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
id: 'assistant-dislike',
|
|
335
|
+
role: 'assistant',
|
|
336
|
+
timestamp: '2024-01-01T00:00:02Z',
|
|
337
|
+
content: 'This message is rated as disliked (filled thumb down).',
|
|
338
|
+
userRating: 'dislike',
|
|
339
|
+
},
|
|
340
|
+
], assistantActions: assistantActions, status: "ready" })) }) }));
|
|
341
|
+
},
|
|
342
|
+
decorators: defaultDecorators,
|
|
343
|
+
};
|
|
294
344
|
export const WithPreviousMessages = {
|
|
295
345
|
render: (args) => {
|
|
296
346
|
const createMessage = (num) => {
|
|
@@ -4,7 +4,7 @@ import { PromptInputSimple } from './PromptInputSimple';
|
|
|
4
4
|
import { PromptInputWithPanels } from './PromptInputWithPanels';
|
|
5
5
|
import { PromptInputWithSuggestions } from './PromptInputWithSuggestions';
|
|
6
6
|
import { usePromptInput } from './usePromptInput';
|
|
7
|
-
import './PromptInput.
|
|
7
|
+
import './PromptInput.css';
|
|
8
8
|
/**
|
|
9
9
|
* PromptInput component - a flexible input component for chat interfaces
|
|
10
10
|
* with support for simple and full views, attachments, suggestions, and expandable panels
|
|
@@ -7,7 +7,7 @@ import { block } from '../../../utils/cn';
|
|
|
7
7
|
import { ActionButton } from '../../atoms';
|
|
8
8
|
import { Loader } from '../../atoms/Loader';
|
|
9
9
|
import { useThinkingMessage } from './useThinkingMessage';
|
|
10
|
-
import './ThinkingMessage.
|
|
10
|
+
import './ThinkingMessage.css';
|
|
11
11
|
const b = block('thinking-message');
|
|
12
12
|
/**
|
|
13
13
|
* ThinkingMessage component displays AI model's internal reasoning process.
|
|
@@ -3,7 +3,7 @@ import { Card } from '@gravity-ui/uikit';
|
|
|
3
3
|
import { useToolMessage } from '../../../hooks/useToolMessage';
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
5
|
import { ToolFooter, ToolHeader } from '../../molecules';
|
|
6
|
-
import './ToolMessage.
|
|
6
|
+
import './ToolMessage.css';
|
|
7
7
|
const b = block('tool-message');
|
|
8
8
|
export function ToolMessage(props) {
|
|
9
9
|
const { toolName, className, qa, bodyContent, status, toolIcon, headerContent } = props;
|
|
@@ -4,7 +4,7 @@ import { block, modsClassName } from '../../../utils/cn';
|
|
|
4
4
|
import { MarkdownRenderer } from '../../atoms/MarkdownRenderer';
|
|
5
5
|
import { MessageBalloon } from '../../atoms/MessageBalloon';
|
|
6
6
|
import { BaseMessage } from '../../molecules/BaseMessage';
|
|
7
|
-
import './UserMessage.
|
|
7
|
+
import './UserMessage.css';
|
|
8
8
|
const b = block('user-message');
|
|
9
9
|
export const UserMessage = (props) => {
|
|
10
10
|
const { className, qa, content, actions, showActionsOnHover, showAvatar, avatarUrl = '', timestamp = '', showTimestamp, format = 'plain', transformOptions, shouldParseIncompleteMarkdown, } = props;
|
|
@@ -8,7 +8,7 @@ import { ChatContent } from '../../templates/ChatContent';
|
|
|
8
8
|
import { History } from '../../templates/History';
|
|
9
9
|
import { i18n } from './i18n';
|
|
10
10
|
import { useChatContainer } from './useChatContainer';
|
|
11
|
-
import './ChatContainer.
|
|
11
|
+
import './ChatContainer.css';
|
|
12
12
|
const b = block('chat-container');
|
|
13
13
|
/**
|
|
14
14
|
* ChatContainer - fully assembled chat component, the main exportable component of the library.
|
|
@@ -83,3 +83,8 @@ export declare const EmbeddedInPageWithStreaming: Story;
|
|
|
83
83
|
* Demonstrates passing additional actions to Header and custom actions to BaseMessage
|
|
84
84
|
*/
|
|
85
85
|
export declare const WithAdditionalActions: Story;
|
|
86
|
+
/**
|
|
87
|
+
* Like / Unlike actions with local rating state.
|
|
88
|
+
* Only like and unlike actions; rating toggles on repeated click (like → clear, dislike → clear).
|
|
89
|
+
*/
|
|
90
|
+
export declare const WithLikeUnlikeActions: Story;
|
|
@@ -5,6 +5,7 @@ import { Gear, Sparkles, Star } from '@gravity-ui/icons';
|
|
|
5
5
|
import { Icon } from '@gravity-ui/uikit';
|
|
6
6
|
import { ChatContainer } from '..';
|
|
7
7
|
import { ContentWrapper } from '../../../../demo/ContentWrapper';
|
|
8
|
+
import { BaseMessageActionType } from '../../../molecules/BaseMessage';
|
|
8
9
|
import MDXDocs from './Docs.mdx';
|
|
9
10
|
export default {
|
|
10
11
|
title: 'pages/ChatContainer',
|
|
@@ -1110,3 +1111,79 @@ export const WithAdditionalActions = {
|
|
|
1110
1111
|
},
|
|
1111
1112
|
decorators: defaultDecorators,
|
|
1112
1113
|
};
|
|
1114
|
+
/**
|
|
1115
|
+
* Like / Unlike actions with local rating state.
|
|
1116
|
+
* Only like and unlike actions; rating toggles on repeated click (like → clear, dislike → clear).
|
|
1117
|
+
*/
|
|
1118
|
+
export const WithLikeUnlikeActions = {
|
|
1119
|
+
args: {
|
|
1120
|
+
chats: mockChats,
|
|
1121
|
+
activeChat: mockChats[0],
|
|
1122
|
+
showHistory: true,
|
|
1123
|
+
showNewChat: true,
|
|
1124
|
+
showActionsOnHover: true,
|
|
1125
|
+
},
|
|
1126
|
+
render: (args) => {
|
|
1127
|
+
const initialChat = mockChats[0];
|
|
1128
|
+
const [messages, setMessages] = useState(() => mockChatMessages[initialChat.id] || []);
|
|
1129
|
+
const [status, setStatus] = useState('ready');
|
|
1130
|
+
const [activeChat, setActiveChat] = useState(initialChat);
|
|
1131
|
+
const assistantActions = [
|
|
1132
|
+
{
|
|
1133
|
+
type: BaseMessageActionType.Like,
|
|
1134
|
+
onClick: (message) => {
|
|
1135
|
+
setMessages((prev) => prev.map((m) => m.id === message.id
|
|
1136
|
+
? Object.assign(Object.assign({}, m), { userRating: m.userRating === 'like'
|
|
1137
|
+
? undefined
|
|
1138
|
+
: 'like' }) : m));
|
|
1139
|
+
},
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
type: BaseMessageActionType.Unlike,
|
|
1143
|
+
onClick: (message) => {
|
|
1144
|
+
setMessages((prev) => prev.map((m) => m.id === message.id
|
|
1145
|
+
? Object.assign(Object.assign({}, m), { userRating: m.userRating === 'dislike'
|
|
1146
|
+
? undefined
|
|
1147
|
+
: 'dislike' }) : m));
|
|
1148
|
+
},
|
|
1149
|
+
},
|
|
1150
|
+
];
|
|
1151
|
+
const handleSendMessage = async (data) => {
|
|
1152
|
+
const timestamp = Date.now();
|
|
1153
|
+
const userMessageId = `user-${timestamp}`;
|
|
1154
|
+
const userMessage = {
|
|
1155
|
+
id: userMessageId,
|
|
1156
|
+
role: 'user',
|
|
1157
|
+
content: data.content,
|
|
1158
|
+
timestamp: new Date().toISOString(),
|
|
1159
|
+
};
|
|
1160
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
1161
|
+
setStatus('streaming');
|
|
1162
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1163
|
+
const assistantMessageId = `assistant-${timestamp + 1}`;
|
|
1164
|
+
const assistantMessage = {
|
|
1165
|
+
id: assistantMessageId,
|
|
1166
|
+
role: 'assistant',
|
|
1167
|
+
content: `Response to: "${data.content}". Use like/unlike below — they toggle on second click.`,
|
|
1168
|
+
timestamp: new Date().toISOString(),
|
|
1169
|
+
};
|
|
1170
|
+
setMessages((prev) => [...prev, assistantMessage]);
|
|
1171
|
+
setStatus('ready');
|
|
1172
|
+
};
|
|
1173
|
+
const handleSelectChat = (chat) => {
|
|
1174
|
+
setActiveChat(chat);
|
|
1175
|
+
setMessages(mockChatMessages[chat.id] || []);
|
|
1176
|
+
};
|
|
1177
|
+
const handleCreateChat = () => {
|
|
1178
|
+
setActiveChat(null);
|
|
1179
|
+
setMessages([]);
|
|
1180
|
+
};
|
|
1181
|
+
const handleCancel = async () => {
|
|
1182
|
+
setStatus('ready');
|
|
1183
|
+
};
|
|
1184
|
+
return (_jsx(ChatContainer, Object.assign({}, args, { messages: messages, activeChat: activeChat, onSendMessage: handleSendMessage, onCancel: handleCancel, onSelectChat: handleSelectChat, onCreateChat: handleCreateChat, status: status, messageListConfig: {
|
|
1185
|
+
assistantActions,
|
|
1186
|
+
} })));
|
|
1187
|
+
},
|
|
1188
|
+
decorators: defaultDecorators,
|
|
1189
|
+
};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { block } from '../../../utils/cn';
|
|
3
3
|
import { MessageList } from '../../organisms/MessageList';
|
|
4
4
|
import { EmptyContainer } from '../EmptyContainer';
|
|
5
|
-
import './ChatContent.
|
|
5
|
+
import './ChatContent.css';
|
|
6
6
|
const b = block('chat-content');
|
|
7
7
|
/**
|
|
8
8
|
* ChatContent - main chat content with state switching (EmptyContainer/MessageList).
|
|
@@ -4,7 +4,7 @@ import { Button, Text } from '@gravity-ui/uikit';
|
|
|
4
4
|
import { block } from '../../../utils/cn';
|
|
5
5
|
import { Suggestions } from '../../molecules/Suggestions';
|
|
6
6
|
import { i18n } from './i18n';
|
|
7
|
-
import './EmptyContainer.
|
|
7
|
+
import './EmptyContainer.css';
|
|
8
8
|
const b = block('empty-container');
|
|
9
9
|
/**
|
|
10
10
|
* EmptyContainer component - displays a welcome screen with image, title, description,
|
|
@@ -7,7 +7,7 @@ import { Loader } from '../../atoms/Loader';
|
|
|
7
7
|
import { ChatItem } from './ChatItem';
|
|
8
8
|
import { DateHeaderItem } from './DateHeaderItem';
|
|
9
9
|
import { i18n } from './i18n';
|
|
10
|
-
import './History.
|
|
10
|
+
import './History.css';
|
|
11
11
|
const b = block('history');
|
|
12
12
|
/**
|
|
13
13
|
* HistoryList component - displays a list of chats with search, grouping, and actions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { cn } from '../../utils/cn';
|
|
4
|
-
import './ContentWrapper.
|
|
4
|
+
import './ContentWrapper.css';
|
|
5
5
|
const b = cn('content-wrapper');
|
|
6
6
|
export function ContentWrapper(props) {
|
|
7
7
|
const { children } = props, style = __rest(props, ["children"]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from '../../utils/cn';
|
|
3
|
-
import './Showcase.
|
|
3
|
+
import './Showcase.css';
|
|
4
4
|
const b = cn('showcase');
|
|
5
5
|
export function Showcase({ title, description, direction = 'row', className, children }) {
|
|
6
6
|
return (_jsxs("div", { className: b({ direction }, className), children: [title && _jsx("div", { className: b('title'), children: title }), description && _jsx("div", { className: b('description'), children: description }), _jsx("div", { className: b('content'), children: children })] }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from '../../utils/cn';
|
|
3
|
-
import './ShowcaseItem.
|
|
3
|
+
import './ShowcaseItem.css';
|
|
4
4
|
const b = cn('showcase-item');
|
|
5
5
|
export function ShowcaseItem({ title, children, width }) {
|
|
6
6
|
return (_jsxs("div", { className: b(), style: { width }, children: [_jsx("div", { className: b('title'), children: title }), _jsx("div", { className: b('content'), children: children })] }));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { block } from '../../utils/cn';
|
|
3
|
-
import './SwapArea.
|
|
3
|
+
import './SwapArea.css';
|
|
4
4
|
const b = block('swap-area');
|
|
5
5
|
export const SwapArea = () => {
|
|
6
6
|
return _jsx("div", { className: b(), children: "Swap Area" });
|
package/dist/types/messages.d.ts
CHANGED
|
@@ -8,10 +8,12 @@ export type BaseMessageActionConfig = ActionConfig;
|
|
|
8
8
|
* - React.ReactNode for fully custom content
|
|
9
9
|
*/
|
|
10
10
|
export type BaseMessageAction = BaseMessageActionConfig | React.ReactNode;
|
|
11
|
+
export type UserRating = 'like' | 'dislike';
|
|
11
12
|
export type BaseMessageProps = {
|
|
12
13
|
children: React.ReactNode;
|
|
13
14
|
role: TMessageRole;
|
|
14
15
|
actions?: BaseMessageAction[];
|
|
16
|
+
userRating?: UserRating;
|
|
15
17
|
timestamp?: string;
|
|
16
18
|
showTimestamp?: boolean;
|
|
17
19
|
showActionsOnHover?: boolean;
|
|
@@ -65,5 +67,6 @@ export type TUserMessage<Metadata = TMessageMetadata> = TBaseMessage<Metadata> &
|
|
|
65
67
|
export type TAssistantMessage<TCustomMessageContent extends TMessageContent = never, Metadata = TMessageMetadata> = TBaseMessage<Metadata> & {
|
|
66
68
|
role: 'assistant';
|
|
67
69
|
content: TAssistantMessageContent<TCustomMessageContent>;
|
|
70
|
+
userRating?: UserRating;
|
|
68
71
|
};
|
|
69
72
|
export type TChatMessage<TCustomMessageContent extends TMessageContent = never, Metadata = TMessageMetadata> = TUserMessage<Metadata> | TAssistantMessage<TCustomMessageContent, Metadata>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/aikit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Gravity UI base kit for building ai assistant chats",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,10 +55,11 @@
|
|
|
55
55
|
"lint:prettier": "prettier --check '**/*.{js,jsx,ts,tsx,css,scss,json,yaml,yml,md,mdx}'",
|
|
56
56
|
"lint:prettier:fix": "prettier --write '**/*.{js,jsx,ts,tsx,css,scss,json,yaml,yml,md,mdx}'",
|
|
57
57
|
"test": "npm run test:unit && npm run test:server:unit",
|
|
58
|
-
"build": "npm run build:clean && npm run build:ts && npm run build:compile:scss && npm run build:copy && npm run build:server",
|
|
58
|
+
"build": "npm run build:clean && npm run build:ts && npm run build:fix-imports && npm run build:compile:scss && npm run build:copy && npm run build:server",
|
|
59
59
|
"build:clean": "rm -rf dist",
|
|
60
60
|
"build:ts": "tsc",
|
|
61
61
|
"build:compile:scss": "sass --no-source-map --load-path=src --load-path=node_modules src:dist",
|
|
62
|
+
"build:fix-imports": "find dist -type f -name '*.js' -exec perl -i -pe \"s/\\.scss'/.css'/g; s/\\.scss\\\"/.css\\\"/g\" {} +",
|
|
62
63
|
"build:copy": "npm run build:copy:themes && npm run build:copy:i18n",
|
|
63
64
|
"build:copy:themes": "copyfiles -u 1 'src/themes/**/*.css' dist",
|
|
64
65
|
"build:copy:i18n": "copyfiles -u 1 'src/**/i18n/*.json' dist",
|