@gravity-ui/aikit 2.26.1-beta.b9e8ea9673cd054c91abb99e76fc312f3ebb1c25.0 → 2.27.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/build/cjs/components/atoms/InlineCitation/index.d.ts +1 -2
- package/build/cjs/components/atoms/InlineCitation/index.js +0 -3
- package/build/cjs/components/atoms/InlineCitation/index.js.map +1 -1
- package/build/cjs/components/atoms/MarkdownRenderer/MdxPortals.js +1 -3
- package/build/cjs/components/atoms/MarkdownRenderer/MdxPortals.js.map +1 -1
- package/build/cjs/components/organisms/AssistantMessage/AssistantMessage.d.ts +3 -1
- package/build/cjs/components/organisms/AssistantMessage/AssistantMessage.js +16 -2
- package/build/cjs/components/organisms/AssistantMessage/AssistantMessage.js.map +1 -1
- package/build/cjs/components/organisms/MessageList/MessageItem.d.ts +2 -1
- package/build/cjs/components/organisms/MessageList/MessageItem.js +2 -2
- package/build/cjs/components/organisms/MessageList/MessageItem.js.map +1 -1
- package/build/cjs/components/organisms/MessageList/MessageList.d.ts +1 -0
- package/build/cjs/components/organisms/MessageList/MessageList.js +2 -2
- package/build/cjs/components/organisms/MessageList/MessageList.js.map +1 -1
- package/build/cjs/components/organisms/MessageList/MessageList.virtualized.d.ts +1 -1
- package/build/cjs/components/organisms/MessageList/MessageList.virtualized.js +3 -1
- package/build/cjs/components/organisms/MessageList/MessageList.virtualized.js.map +1 -1
- package/build/cjs/components/organisms/ThinkingMessage/index.d.ts +1 -0
- package/build/cjs/components/organisms/ThinkingMessage/index.js +1 -0
- package/build/cjs/components/organisms/ThinkingMessage/index.js.map +1 -1
- package/build/cjs/components/organisms/ThinkingMessageGroup/CompactHeading.d.ts +11 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/CompactHeading.js +25 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/CompactHeading.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/StepIcon.d.ts +6 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/StepIcon.js +20 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/StepIcon.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.css +190 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.d.ts +3 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.js +86 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/i18n/en.json +9 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/i18n/index.d.ts +13 -0
- package/build/cjs/components/{atoms/InlineCitation → organisms/ThinkingMessageGroup}/i18n/index.js +1 -1
- package/build/cjs/components/organisms/ThinkingMessageGroup/i18n/index.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/i18n/ru.json +9 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/index.d.ts +4 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/index.js +9 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/index.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/types.d.ts +37 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/types.js +3 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/types.js.map +1 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/utils.d.ts +23 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/utils.js +46 -0
- package/build/cjs/components/organisms/ThinkingMessageGroup/utils.js.map +1 -0
- package/build/cjs/components/organisms/index.d.ts +1 -0
- package/build/cjs/components/organisms/index.js +1 -0
- package/build/cjs/components/organisms/index.js.map +1 -1
- package/build/cjs/package.json +1 -1
- package/build/docs/INDEX.md +1 -1
- package/build/docs/components/organisms/AssistantMessage.md +7 -0
- package/build/docs/components/organisms/MessageList.md +7 -0
- package/build/docs/components/organisms/ThinkingMessage.md +2 -0
- package/build/docs/components/organisms/ThinkingMessageGroup.md +146 -0
- package/build/docs/components/pages/ChatContainer.md +8 -0
- package/build/docs/guides/COMPONENTS.md +14 -13
- package/build/docs/guides/PROJECT_STRUCTURE.md +1 -1
- package/build/esm/components/atoms/InlineCitation/index.d.ts +1 -2
- package/build/esm/components/atoms/InlineCitation/index.js +1 -1
- package/build/esm/components/atoms/InlineCitation/index.js.map +1 -1
- package/build/esm/components/atoms/MarkdownRenderer/MdxPortals.js +1 -3
- package/build/esm/components/atoms/MarkdownRenderer/MdxPortals.js.map +1 -1
- package/build/esm/components/organisms/AssistantMessage/AssistantMessage.d.ts +3 -1
- package/build/esm/components/organisms/AssistantMessage/AssistantMessage.js +16 -2
- package/build/esm/components/organisms/AssistantMessage/AssistantMessage.js.map +1 -1
- package/build/esm/components/organisms/MessageList/MessageItem.d.ts +2 -1
- package/build/esm/components/organisms/MessageList/MessageItem.js +2 -2
- package/build/esm/components/organisms/MessageList/MessageItem.js.map +1 -1
- package/build/esm/components/organisms/MessageList/MessageList.d.ts +1 -0
- package/build/esm/components/organisms/MessageList/MessageList.js +2 -2
- package/build/esm/components/organisms/MessageList/MessageList.js.map +1 -1
- package/build/esm/components/organisms/MessageList/MessageList.virtualized.d.ts +1 -1
- package/build/esm/components/organisms/MessageList/MessageList.virtualized.js +3 -1
- package/build/esm/components/organisms/MessageList/MessageList.virtualized.js.map +1 -1
- package/build/esm/components/organisms/ThinkingMessage/index.d.ts +1 -0
- package/build/esm/components/organisms/ThinkingMessage/index.js +1 -0
- package/build/esm/components/organisms/ThinkingMessage/index.js.map +1 -1
- package/build/esm/components/organisms/ThinkingMessageGroup/CompactHeading.d.ts +11 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/CompactHeading.js +22 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/CompactHeading.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/StepIcon.d.ts +6 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/StepIcon.js +17 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/StepIcon.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.css +190 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.d.ts +3 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.js +83 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/ThinkingMessageGroup.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/i18n/en.json +9 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/i18n/index.d.ts +13 -0
- package/build/esm/components/{atoms/InlineCitation → organisms/ThinkingMessageGroup}/i18n/index.js +1 -1
- package/build/esm/components/organisms/ThinkingMessageGroup/i18n/index.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/i18n/ru.json +9 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/index.d.ts +4 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/index.js +3 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/index.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/types.d.ts +37 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/types.js +2 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/types.js.map +1 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/utils.d.ts +23 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/utils.js +42 -0
- package/build/esm/components/organisms/ThinkingMessageGroup/utils.js.map +1 -0
- package/build/esm/components/organisms/index.d.ts +1 -0
- package/build/esm/components/organisms/index.js +1 -0
- package/build/esm/components/organisms/index.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/docs/COMPONENTS.md +14 -13
- package/docs/PROJECT_STRUCTURE.md +1 -1
- package/llms-full.txt +16 -15
- package/llms.txt +1 -1
- package/package.json +11 -1
- package/build/cjs/components/atoms/InlineCitation/InlineCitation.css +0 -76
- package/build/cjs/components/atoms/InlineCitation/InlineCitation.d.ts +0 -24
- package/build/cjs/components/atoms/InlineCitation/InlineCitation.js +0 -136
- package/build/cjs/components/atoms/InlineCitation/InlineCitation.js.map +0 -1
- package/build/cjs/components/atoms/InlineCitation/i18n/en.json +0 -7
- package/build/cjs/components/atoms/InlineCitation/i18n/index.d.ts +0 -13
- package/build/cjs/components/atoms/InlineCitation/i18n/index.js.map +0 -1
- package/build/cjs/components/atoms/InlineCitation/i18n/ru.json +0 -7
- package/build/docs/components/atoms/InlineCitation.md +0 -148
- package/build/esm/components/atoms/InlineCitation/InlineCitation.css +0 -76
- package/build/esm/components/atoms/InlineCitation/InlineCitation.d.ts +0 -24
- package/build/esm/components/atoms/InlineCitation/InlineCitation.js +0 -133
- package/build/esm/components/atoms/InlineCitation/InlineCitation.js.map +0 -1
- package/build/esm/components/atoms/InlineCitation/i18n/en.json +0 -7
- package/build/esm/components/atoms/InlineCitation/i18n/index.d.ts +0 -13
- package/build/esm/components/atoms/InlineCitation/i18n/index.js.map +0 -1
- package/build/esm/components/atoms/InlineCitation/i18n/ru.json +0 -7
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type { InlineCitationProps, InlineCitationSource } from "./InlineCitation.js";
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InlineCitation = void 0;
|
|
4
|
-
var InlineCitation_1 = require("./InlineCitation.js");
|
|
5
|
-
Object.defineProperty(exports, "InlineCitation", { enumerable: true, get: function () { return InlineCitation_1.InlineCitation; } });
|
|
6
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["components/atoms/InlineCitation/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["components/atoms/InlineCitation/index.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
|
|
@@ -8,8 +8,6 @@ const mdx_extension_1 = require("@diplodoc/mdx-extension");
|
|
|
8
8
|
const runtime = tslib_1.__importStar(require("react/jsx-runtime"));
|
|
9
9
|
const MdxContext_1 = require("./MdxContext.js");
|
|
10
10
|
const asyncExecuteCode_1 = require("./asyncExecuteCode.js");
|
|
11
|
-
// Keep the MDX mounting effect stable when a child creates a React portal.
|
|
12
|
-
const contextList = [MdxContext_1.MdxDataContext];
|
|
13
11
|
function useMdxComponentLoader(mdxArtifacts, nonce) {
|
|
14
12
|
const idMdx = mdxArtifacts === null || mdxArtifacts === void 0 ? void 0 : mdxArtifacts.idMdx;
|
|
15
13
|
const resolvedNonce = (0, asyncExecuteCode_1.resolveCspNonce)(nonce);
|
|
@@ -58,7 +56,7 @@ function MdxPortals({ refCtr, html, components, mdxArtifacts, nonce, mdxContext,
|
|
|
58
56
|
html,
|
|
59
57
|
components,
|
|
60
58
|
mdxArtifacts,
|
|
61
|
-
contextList,
|
|
59
|
+
contextList: [MdxContext_1.MdxDataContext],
|
|
62
60
|
idMdxComponentLoader,
|
|
63
61
|
});
|
|
64
62
|
return (0, jsx_runtime_1.jsx)(MdxContext_1.MdxDataContext.Provider, { value: mdxContext, children: portals });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MdxPortals.js","sourceRoot":"../../../../../src","sources":["components/atoms/MarkdownRenderer/MdxPortals.tsx"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"MdxPortals.js","sourceRoot":"../../../../../src","sources":["components/atoms/MarkdownRenderer/MdxPortals.tsx"],"names":[],"mappings":";;AAsFA,gCAmBC;;;AAzGD,iCAA0C;AAG1C,2DAA+C;AAG/C,mEAA6C;AAE7C,gDAA4C;AAC5C,4DAAqE;AAOrE,SAAS,qBAAqB,CAAC,YAAsC,EAAE,KAAc;IACjF,MAAM,KAAK,GAAG,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAC;IAClC,MAAM,aAAa,GAAG,IAAA,kCAAe,EAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAiB,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC,CAAC;IAEvE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACX,IAAI,CAAC,aAAa,EAAE,CAAC;YACjB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC;QAC3B,CAAC;QAED,IAAI,QAAQ,GAAG,IAAI,CAAC;QAEpB,CAAC,KAAK,IAAI,EAAE;YACR,IAAI,CAAC;gBACD,MAAM,IAAI,GAAkD,EAAE,CAAC;gBAE/D,KAAK,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC,EAAE,CAAC;oBAC3D,MAAM,EAAE,GAAG,MAAM,IAAA,mCAAgB,EAC7B,IAAI,EACJ,aAAa,CAChB,CAAC;oBAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACZ,OAAO;oBACX,CAAC;oBAED,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;gBAC3C,CAAC;gBAED,IAAI,QAAQ,EAAE,CAAC;oBACX,QAAQ,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;gBACnE,CAAC;YACL,CAAC;YAAC,WAAM,CAAC;gBACL,IAAI,QAAQ,EAAE,CAAC;oBACX,QAAQ,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAC,CAAC,CAAC;gBAC9D,CAAC;YACL,CAAC;QACL,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAG,EAAE;YACR,QAAQ,GAAG,KAAK,CAAC;QACrB,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;IAE3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;QACzD,OAAO,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAiBD,SAAgB,UAAU,CAAC,EACvB,MAAM,EACN,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,KAAK,EACL,UAAU,GACI;IACd,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,IAAA,sBAAM,EAAC;QACnB,MAAM;QACN,IAAI;QACJ,UAAU;QACV,YAAY;QACZ,WAAW,EAAE,CAAC,2BAAc,CAAC;QAC7B,oBAAoB;KACvB,CAAC,CAAC;IAEH,OAAO,uBAAC,2BAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,UAAU,YAAG,OAAO,GAA2B,CAAC;AAC3F,CAAC;AAED,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC","sourcesContent":["import {useEffect, useState} from 'react';\nimport type {RefObject} from 'react';\n\nimport {useMdx} from '@diplodoc/mdx-extension';\nimport type {IdMdxComponentLoader, MdxArtifacts} from '@diplodoc/mdx-extension';\nimport type {MDXComponents, MDXModule, MDXProps} from 'mdx/types';\nimport * as runtime from 'react/jsx-runtime';\n\nimport {MdxDataContext} from './MdxContext';\nimport {asyncExecuteCode, resolveCspNonce} from './asyncExecuteCode';\n\ninterface MdxLoaderState extends IdMdxComponentLoader {\n idMdx?: Record<string, string>;\n nonce?: string;\n}\n\nfunction useMdxComponentLoader(mdxArtifacts: MdxArtifacts | undefined, nonce?: string) {\n const idMdx = mdxArtifacts?.idMdx;\n const resolvedNonce = resolveCspNonce(nonce);\n const [state, setState] = useState<MdxLoaderState>({isSuccess: false});\n\n useEffect(() => {\n if (!resolvedNonce) {\n return () => undefined;\n }\n\n let isActive = true;\n\n (async () => {\n try {\n const data: Record<string, React.ComponentType<MDXProps>> = {};\n\n for (const [artifactId, code] of Object.entries(idMdx ?? {})) {\n const fn = await asyncExecuteCode<(jsxRuntime: typeof runtime) => MDXModule>(\n code,\n resolvedNonce,\n );\n\n if (!isActive) {\n return;\n }\n\n data[artifactId] = fn(runtime).default;\n }\n\n if (isActive) {\n setState({idMdx, nonce: resolvedNonce, data, isSuccess: true});\n }\n } catch {\n if (isActive) {\n setState({idMdx, nonce: resolvedNonce, isSuccess: false});\n }\n }\n })();\n\n return () => {\n isActive = false;\n };\n }, [idMdx, resolvedNonce]);\n\n if (!resolvedNonce) {\n return undefined;\n }\n\n if (state.idMdx !== idMdx || state.nonce !== resolvedNonce) {\n return {isSuccess: false};\n }\n\n return state;\n}\n\nexport interface MdxPortalsProps {\n /** Ref to the container element into which the rendered HTML is injected. */\n refCtr: RefObject<HTMLDivElement | null>;\n /** HTML produced by the markdown transform for the current content. */\n html: string;\n /** Map of components rendered from embedded MDX/JSX in the markdown content. */\n components?: MDXComponents;\n /** Artifacts collected by the MDX transform, required to hydrate the components. */\n mdxArtifacts?: MdxArtifacts;\n /** CSP nonce applied to compiled MDX scripts. Defaults to a nonce found in the document. */\n nonce?: string;\n /** Arbitrary value exposed to the MDX components through {@link MdxDataContext}. */\n mdxContext?: Record<string, unknown>;\n}\n\nexport function MdxPortals({\n refCtr,\n html,\n components,\n mdxArtifacts,\n nonce,\n mdxContext,\n}: MdxPortalsProps) {\n const idMdxComponentLoader = useMdxComponentLoader(mdxArtifacts, nonce);\n const portals = useMdx({\n refCtr,\n html,\n components,\n mdxArtifacts,\n contextList: [MdxDataContext],\n idMdxComponentLoader,\n });\n\n return <MdxDataContext.Provider value={mdxContext}>{portals}</MdxDataContext.Provider>;\n}\n\nMdxPortals.displayName = 'MdxPortals';\n"]}
|
|
@@ -8,6 +8,8 @@ type BaseMessagePick = Pick<BaseMessageProps, 'actions' | 'extraInfo' | 'timesta
|
|
|
8
8
|
type AssistantMessagePick<TContent extends TMessageContent> = Pick<TAssistantMessage<TContent, TMessageMetadata>, 'id' | 'content' | 'userRating'>;
|
|
9
9
|
export type AssistantMessageProps<TContent extends TMessageContent = never> = BaseMessagePick & AssistantMessagePick<TContent> & {
|
|
10
10
|
messageRendererRegistry?: MessageRendererRegistry;
|
|
11
|
+
/** Opt in to grouping adjacent legacy thinking parts. Custom thinking renderers take precedence. */
|
|
12
|
+
thinkingMessageView?: 'default' | 'grouped';
|
|
11
13
|
transformOptions?: OptionsType;
|
|
12
14
|
shouldParseIncompleteMarkdown?: boolean;
|
|
13
15
|
mermaidOptions?: MermaidOptions;
|
|
@@ -19,6 +21,6 @@ export type AssistantMessageProps<TContent extends TMessageContent = never> = Ba
|
|
|
19
21
|
className?: string;
|
|
20
22
|
qa?: string;
|
|
21
23
|
};
|
|
22
|
-
declare function AssistantMessageComponent<TContent extends TMessageContent = never>({ content, actions, extraInfo, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, mdxContext, markdownExtraProps, showActionsOnHover, showTimestamp, userRating, className, qa, onActionPopup, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
24
|
+
declare function AssistantMessageComponent<TContent extends TMessageContent = never>({ content, actions, extraInfo, timestamp, id, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, mdxContext, markdownExtraProps, showActionsOnHover, showTimestamp, userRating, className, qa, onActionPopup, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
23
25
|
export declare const AssistantMessage: typeof AssistantMessageComponent;
|
|
24
26
|
export {};
|
|
@@ -7,10 +7,11 @@ const cn_1 = require("../../../utils/cn.js");
|
|
|
7
7
|
const messageTypeRegistry_1 = require("../../../utils/messageTypeRegistry.js");
|
|
8
8
|
const messageUtils_1 = require("../../../utils/messageUtils.js");
|
|
9
9
|
const BaseMessage_1 = require("../../molecules/BaseMessage/index.js");
|
|
10
|
+
const ThinkingMessageGroup_1 = require("../ThinkingMessageGroup/index.js");
|
|
10
11
|
const defaultMessageTypeRegistry_1 = require("./defaultMessageTypeRegistry.js");
|
|
11
12
|
require("./AssistantMessage.css");
|
|
12
13
|
const b = (0, cn_1.block)('assistant-message');
|
|
13
|
-
function AssistantMessageComponent({ content, actions, extraInfo, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, mdxContext, markdownExtraProps, showActionsOnHover, showTimestamp, userRating, className, qa, onActionPopup, }) {
|
|
14
|
+
function AssistantMessageComponent({ content, actions, extraInfo, timestamp, id, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, mdxContext, markdownExtraProps, showActionsOnHover, showTimestamp, userRating, className, qa, onActionPopup, }) {
|
|
14
15
|
const registry = (0, react_1.useMemo)(() => {
|
|
15
16
|
const defaultRegistry = (0, defaultMessageTypeRegistry_1.createDefaultMessageRegistry)(transformOptions, shouldParseIncompleteMarkdown, openMarkdownLinksInNewTab, mdxOptions, mdxContext, markdownExtraProps, mermaidOptions);
|
|
16
17
|
if (messageRendererRegistry) {
|
|
@@ -28,6 +29,17 @@ function AssistantMessageComponent({ content, actions, extraInfo, timestamp, id,
|
|
|
28
29
|
markdownExtraProps,
|
|
29
30
|
]);
|
|
30
31
|
const parts = (0, react_1.useMemo)(() => (0, messageUtils_1.normalizeContent)(content), [content]);
|
|
32
|
+
const groupedParts = thinkingMessageView === 'grouped' && !(messageRendererRegistry === null || messageRendererRegistry === void 0 ? void 0 : messageRendererRegistry.thinking)
|
|
33
|
+
? (0, ThinkingMessageGroup_1.groupThinkingMessages)(parts, {
|
|
34
|
+
getStep: (part, index) => {
|
|
35
|
+
var _a;
|
|
36
|
+
return part.type === 'thinking'
|
|
37
|
+
? (0, ThinkingMessageGroup_1.thinkingMessageToStep)((_a = part.id) !== null && _a !== void 0 ? _a : `${id !== null && id !== void 0 ? id : 'message'}-part-${index}`, part.data)
|
|
38
|
+
: undefined;
|
|
39
|
+
},
|
|
40
|
+
getGroupKey: () => id !== null && id !== void 0 ? id : 'message',
|
|
41
|
+
})
|
|
42
|
+
: undefined;
|
|
31
43
|
if (parts.length === 0) {
|
|
32
44
|
return null;
|
|
33
45
|
}
|
|
@@ -39,7 +51,9 @@ function AssistantMessageComponent({ content, actions, extraInfo, timestamp, id,
|
|
|
39
51
|
const key = part.id || `${id || 'message'}-part-${partIndex}`;
|
|
40
52
|
return (0, jsx_runtime_1.jsx)(PartComponent, { part: part }, key);
|
|
41
53
|
};
|
|
42
|
-
return ((0, jsx_runtime_1.jsx)(BaseMessage_1.BaseMessage, { role: "assistant", actions: actions, extraInfo: extraInfo, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, userRating: userRating, className: b(null, className), qa: qa, onActionPopup: onActionPopup, children: (0, jsx_runtime_1.jsx)("div", { className: b('content'), children:
|
|
54
|
+
return ((0, jsx_runtime_1.jsx)(BaseMessage_1.BaseMessage, { role: "assistant", actions: actions, extraInfo: extraInfo, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, userRating: userRating, className: b(null, className), qa: qa, onActionPopup: onActionPopup, children: (0, jsx_runtime_1.jsx)("div", { className: b('content'), children: groupedParts
|
|
55
|
+
? groupedParts.map((entry) => entry.type === 'item' ? (renderPart(entry.item, entry.index)) : ((0, jsx_runtime_1.jsx)(ThinkingMessageGroup_1.ThinkingMessageGroup, { steps: entry.steps, format: "markdown", transformOptions: transformOptions, mermaidOptions: mermaidOptions, openMarkdownLinksInNewTab: openMarkdownLinksInNewTab, mdxOptions: mdxOptions, mdxContext: mdxContext, markdownExtraProps: markdownExtraProps }, entry.id)))
|
|
56
|
+
: parts.map((part, index) => renderPart(part, index)) }) }));
|
|
43
57
|
}
|
|
44
58
|
const MemoizedAssistantMessage = (0, react_1.memo)(AssistantMessageComponent);
|
|
45
59
|
MemoizedAssistantMessage.displayName = 'AssistantMessage';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantMessage.js","sourceRoot":"../../../../../src","sources":["components/organisms/AssistantMessage/AssistantMessage.tsx"],"names":[],"mappings":";;;;AAAA,iCAAyD;
|
|
1
|
+
{"version":3,"file":"AssistantMessage.js","sourceRoot":"../../../../../src","sources":["components/organisms/AssistantMessage/AssistantMessage.tsx"],"names":[],"mappings":"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","sourcesContent":["import {type HTMLAttributes, memo, useMemo} from 'react';\n\nimport type {OptionsType} from '@diplodoc/transform/lib/typings';\n\nimport type {\n BaseMessageProps,\n TAssistantMessage,\n TMessageContent,\n TMessageContentUnion,\n TMessageMetadata,\n ThinkingMessageContent,\n} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {\n type MessageRendererRegistry,\n getMessageRenderer,\n mergeMessageRendererRegistries,\n} from '../../../utils/messageTypeRegistry';\nimport {normalizeContent} from '../../../utils/messageUtils';\nimport type {MarkdownRendererMdxOptions, MermaidOptions} from '../../atoms/MarkdownRenderer';\nimport {BaseMessage} from '../../molecules/BaseMessage';\nimport {\n ThinkingMessageGroup,\n groupThinkingMessages,\n thinkingMessageToStep,\n} from '../ThinkingMessageGroup';\n\nimport {createDefaultMessageRegistry} from './defaultMessageTypeRegistry';\n\nimport './AssistantMessage.scss';\n\ntype BaseMessagePick = Pick<\n BaseMessageProps,\n 'actions' | 'extraInfo' | 'timestamp' | 'showActionsOnHover' | 'showTimestamp' | 'onActionPopup'\n>;\ntype AssistantMessagePick<TContent extends TMessageContent> = Pick<\n TAssistantMessage<TContent, TMessageMetadata>,\n 'id' | 'content' | 'userRating'\n>;\n\nexport type AssistantMessageProps<TContent extends TMessageContent = never> = BaseMessagePick &\n AssistantMessagePick<TContent> & {\n messageRendererRegistry?: MessageRendererRegistry;\n /** Opt in to grouping adjacent legacy thinking parts. Custom thinking renderers take precedence. */\n thinkingMessageView?: 'default' | 'grouped';\n transformOptions?: OptionsType;\n shouldParseIncompleteMarkdown?: boolean;\n mermaidOptions?: MermaidOptions;\n openMarkdownLinksInNewTab?: boolean;\n mdxOptions?: MarkdownRendererMdxOptions;\n mdxContext?: Record<string, unknown>;\n /** Extra props forwarded to the root container `div` of each rendered markdown block. */\n markdownExtraProps?: HTMLAttributes<HTMLDivElement>;\n className?: string;\n qa?: string;\n };\n\nconst b = block('assistant-message');\n\nfunction AssistantMessageComponent<TContent extends TMessageContent = never>({\n content,\n actions,\n extraInfo,\n timestamp,\n id,\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions,\n mdxContext,\n markdownExtraProps,\n showActionsOnHover,\n showTimestamp,\n userRating,\n className,\n qa,\n onActionPopup,\n}: AssistantMessageProps<TContent>) {\n const registry = useMemo<MessageRendererRegistry>(() => {\n const defaultRegistry = createDefaultMessageRegistry(\n transformOptions,\n shouldParseIncompleteMarkdown,\n openMarkdownLinksInNewTab,\n mdxOptions,\n mdxContext,\n markdownExtraProps,\n mermaidOptions,\n );\n if (messageRendererRegistry) {\n return mergeMessageRendererRegistries(defaultRegistry, messageRendererRegistry);\n }\n\n return defaultRegistry;\n }, [\n messageRendererRegistry,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions,\n mdxContext,\n markdownExtraProps,\n ]);\n\n const parts = useMemo(() => normalizeContent<TContent>(content), [content]);\n\n const groupedParts =\n thinkingMessageView === 'grouped' && !messageRendererRegistry?.thinking\n ? groupThinkingMessages(parts, {\n getStep: (part, index) =>\n part.type === 'thinking'\n ? thinkingMessageToStep(\n part.id ?? `${id ?? 'message'}-part-${index}`,\n (part as ThinkingMessageContent).data,\n )\n : undefined,\n getGroupKey: () => id ?? 'message',\n })\n : undefined;\n\n if (parts.length === 0) {\n return null;\n }\n\n const renderPart = (part: TMessageContentUnion<TContent>, partIndex: number) => {\n const PartComponent = getMessageRenderer(registry, part.type);\n\n if (!PartComponent) {\n return null;\n }\n\n const key = part.id || `${id || 'message'}-part-${partIndex}`;\n\n return <PartComponent key={key} part={part} />;\n };\n\n return (\n <BaseMessage\n role=\"assistant\"\n actions={actions}\n extraInfo={extraInfo}\n showActionsOnHover={showActionsOnHover}\n showTimestamp={showTimestamp}\n timestamp={timestamp}\n userRating={userRating}\n className={b(null, className)}\n qa={qa}\n onActionPopup={onActionPopup}\n >\n <div className={b('content')}>\n {groupedParts\n ? groupedParts.map((entry) =>\n entry.type === 'item' ? (\n renderPart(entry.item, entry.index)\n ) : (\n <ThinkingMessageGroup\n key={entry.id}\n steps={entry.steps}\n format=\"markdown\"\n transformOptions={transformOptions}\n mermaidOptions={mermaidOptions}\n openMarkdownLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxOptions}\n mdxContext={mdxContext}\n markdownExtraProps={markdownExtraProps}\n />\n ),\n )\n : parts.map((part, index) => renderPart(part, index))}\n </div>\n </BaseMessage>\n );\n}\n\nconst MemoizedAssistantMessage = memo(AssistantMessageComponent);\nMemoizedAssistantMessage.displayName = 'AssistantMessage';\n\nexport const AssistantMessage = MemoizedAssistantMessage as typeof AssistantMessageComponent;\n"]}
|
|
@@ -10,6 +10,7 @@ import type { MarkdownRendererMdxOptions, MermaidOptions } from "../../atoms/Mar
|
|
|
10
10
|
*/
|
|
11
11
|
export type MessageItemConfig<TContent extends TMessageContent = never> = {
|
|
12
12
|
messageRendererRegistry?: MessageRendererRegistry;
|
|
13
|
+
thinkingMessageView?: 'default' | 'grouped';
|
|
13
14
|
transformOptions?: OptionsType;
|
|
14
15
|
shouldParseIncompleteMarkdown?: boolean;
|
|
15
16
|
mermaidOptions?: MermaidOptions;
|
|
@@ -36,7 +37,7 @@ export type MessageItemProps<TContent extends TMessageContent = never> = Message
|
|
|
36
37
|
*/
|
|
37
38
|
suppressActions: boolean;
|
|
38
39
|
};
|
|
39
|
-
declare function MessageItemComponent<TContent extends TMessageContent = never>({ message, suppressActions, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, getMarkdownExtraProps, getMdxContext, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup, }: MessageItemProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
40
|
+
declare function MessageItemComponent<TContent extends TMessageContent = never>({ message, suppressActions, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, getMarkdownExtraProps, getMdxContext, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup, }: MessageItemProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
|
|
40
41
|
/**
|
|
41
42
|
* Memoized single message renderer shared by the plain and virtualized message lists.
|
|
42
43
|
* Re-renders only when `message`, `suppressActions`, or one of the (stable) config props changes,
|
|
@@ -6,7 +6,7 @@ const react_1 = require("react");
|
|
|
6
6
|
const utils_1 = require("../../../utils/index.js");
|
|
7
7
|
const AssistantMessage_1 = require("../AssistantMessage/index.js");
|
|
8
8
|
const UserMessage_1 = require("../UserMessage/index.js");
|
|
9
|
-
function MessageItemComponent({ message, suppressActions, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, getMarkdownExtraProps, getMdxContext, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup, }) {
|
|
9
|
+
function MessageItemComponent({ message, suppressActions, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxOptions, getMarkdownExtraProps, getMdxContext, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup, }) {
|
|
10
10
|
const mdxContext = (0, react_1.useMemo)(() => getMdxContext === null || getMdxContext === void 0 ? void 0 : getMdxContext(message), [getMdxContext, message]);
|
|
11
11
|
const markdownExtraProps = (0, react_1.useMemo)(() => getMarkdownExtraProps === null || getMarkdownExtraProps === void 0 ? void 0 : getMarkdownExtraProps(message), [getMarkdownExtraProps, message]);
|
|
12
12
|
if ((0, utils_1.isUserMessage)(message)) {
|
|
@@ -19,7 +19,7 @@ function MessageItemComponent({ message, suppressActions, messageRendererRegistr
|
|
|
19
19
|
const actions = !suppressActions && !(0, utils_1.hasOnlyThinkingContent)(message.content)
|
|
20
20
|
? (0, utils_1.resolveMessageActions)(message, assistantActions)
|
|
21
21
|
: undefined;
|
|
22
|
-
return ((0, jsx_runtime_1.jsx)(AssistantMessage_1.AssistantMessage, { content: message.content, actions: actions, extraInfo: AssistantExtraInfo ? (0, jsx_runtime_1.jsx)(AssistantExtraInfo, { message: message }) : undefined, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, mermaidOptions: mermaidOptions, openMarkdownLinksInNewTab: openMarkdownLinksInNewTab, mdxOptions: mdxOptions, mdxContext: mdxContext, markdownExtraProps: markdownExtraProps, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, userRating: message.userRating, onActionPopup: (action, anchor) => onActionPopup(message, action, anchor) }));
|
|
22
|
+
return ((0, jsx_runtime_1.jsx)(AssistantMessage_1.AssistantMessage, { content: message.content, actions: actions, extraInfo: AssistantExtraInfo ? (0, jsx_runtime_1.jsx)(AssistantExtraInfo, { message: message }) : undefined, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, thinkingMessageView: thinkingMessageView, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, mermaidOptions: mermaidOptions, openMarkdownLinksInNewTab: openMarkdownLinksInNewTab, mdxOptions: mdxOptions, mdxContext: mdxContext, markdownExtraProps: markdownExtraProps, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, userRating: message.userRating, onActionPopup: (action, anchor) => onActionPopup(message, action, anchor) }));
|
|
23
23
|
}
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageItem.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageItem.tsx"],"names":[],"mappings":";;;;AAAA,iCAAyD;AAczD,mDAKwB;AAGxB,mEAAqD;AACrD,yDAA2C;
|
|
1
|
+
{"version":3,"file":"MessageItem.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageItem.tsx"],"names":[],"mappings":";;;;AAAA,iCAAyD;AAczD,mDAKwB;AAGxB,mEAAqD;AACrD,yDAA2C;AAgD3C,SAAS,oBAAoB,CAA2C,EACpE,OAAO,EACP,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,6BAA6B,EAC7B,cAAc,EACd,yBAAyB,EACzB,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,GACY;IACzB,MAAM,UAAU,GAAG,IAAA,eAAO,EACtB,GAAG,EAAE,CAAC,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,OAAO,CAAwC,EACrE,CAAC,aAAa,EAAE,OAAO,CAAC,CAC3B,CAAC;IACF,MAAM,kBAAkB,GAAG,IAAA,eAAO,EAC9B,GAAG,EAAE,CAAC,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAG,OAAO,CAAC,EACtC,CAAC,qBAAqB,EAAE,OAAO,CAAC,CACnC,CAAC;IAEF,IAAI,IAAA,qBAAa,EAA6B,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,IAAA,6BAAqB,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAE5D,OAAO,CACH,uBAAC,yBAAW,IACR,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,uBAAC,aAAa,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC,CAAC,CAAC,SAAS,EAC1E,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,eAAe,EAAE,OAAO,CAAC,eAAe,EACxC,gBAAgB,EAAE,gBAAgB,EAClC,6BAA6B,EAAE,6BAA6B,EAC5D,cAAc,EAAE,cAAc,EAC9B,yBAAyB,EAAE,yBAAyB,EACpD,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,kBAAkB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,GAC3E,CACL,CAAC;IACN,CAAC;IAED,IAAI,IAAA,0BAAkB,EAA6B,OAAO,CAAC,EAAE,CAAC;QAC1D,uEAAuE;QACvE,sFAAsF;QACtF,MAAM,OAAO,GACT,CAAC,eAAe,IAAI,CAAC,IAAA,8BAAsB,EAAC,OAAO,CAAC,OAAO,CAAC;YACxD,CAAC,CAAC,IAAA,6BAAqB,EAAC,OAAO,EAAE,gBAAgB,CAAC;YAClD,CAAC,CAAC,SAAS,CAAC;QAEpB,OAAO,CACH,uBAAC,mCAAgB,IACb,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,OAAO,EAAE,OAAO,EAChB,SAAS,EACL,kBAAkB,CAAC,CAAC,CAAC,uBAAC,kBAAkB,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC,CAAC,CAAC,SAAS,EAE7E,SAAS,EAAE,OAAO,CAAC,SAAS,EAC5B,EAAE,EAAE,OAAO,CAAC,EAAE,EACd,uBAAuB,EAAE,uBAAuB,EAChD,mBAAmB,EAAE,mBAAmB,EACxC,gBAAgB,EAAE,gBAAgB,EAClC,6BAA6B,EAAE,6BAA6B,EAC5D,cAAc,EAAE,cAAc,EAC9B,yBAAyB,EAAE,yBAAyB,EACpD,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,kBAAkB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,OAAO,CAAC,UAAU,EAC9B,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,GAC3E,CACL,CAAC;IACN,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACU,QAAA,WAAW,GAAG,IAAA,YAAI,EAAC,oBAAoB,CAAgC,CAAC","sourcesContent":["import {type HTMLAttributes, memo, useMemo} from 'react';\n\nimport type {OptionsType} from '@diplodoc/transform/lib/typings';\n\nimport type {\n BaseMessageActionConfig,\n DefaultMessageAction,\n MessageExtraInfoComponent,\n TAssistantMessage,\n TChatMessage,\n TMessageContent,\n TMessageMetadata,\n TUserMessage,\n} from '../../../types/messages';\nimport {\n hasOnlyThinkingContent,\n isAssistantMessage,\n isUserMessage,\n resolveMessageActions,\n} from '../../../utils';\nimport {type MessageRendererRegistry} from '../../../utils/messageTypeRegistry';\nimport type {MarkdownRendererMdxOptions, MermaidOptions} from '../../atoms/MarkdownRenderer';\nimport {AssistantMessage} from '../AssistantMessage';\nimport {UserMessage} from '../UserMessage';\n\n/**\n * Shared configuration for a single rendered message. These props are expected to be\n * referentially stable across renders (memoized by the parent list), so that the memoized\n * `MessageItem` only re-renders when the `message` itself changes.\n */\nexport type MessageItemConfig<TContent extends TMessageContent = never> = {\n messageRendererRegistry?: MessageRendererRegistry;\n thinkingMessageView?: 'default' | 'grouped';\n transformOptions?: OptionsType;\n shouldParseIncompleteMarkdown?: boolean;\n mermaidOptions?: MermaidOptions;\n openMarkdownLinksInNewTab?: boolean;\n mdxOptions?: MarkdownRendererMdxOptions;\n getMarkdownExtraProps?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => HTMLAttributes<HTMLDivElement> | undefined;\n\n getMdxContext?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => Record<string, unknown> | undefined;\n showActionsOnHover?: boolean;\n showTimestamp?: boolean;\n showAvatar?: boolean;\n userActions?: DefaultMessageAction<TUserMessage<TMessageMetadata>>[];\n assistantActions?: DefaultMessageAction<TAssistantMessage<TContent, TMessageMetadata>>[];\n userExtraInfo?: MessageExtraInfoComponent<TUserMessage<TMessageMetadata>>;\n assistantExtraInfo?: MessageExtraInfoComponent<TAssistantMessage<TContent, TMessageMetadata>>;\n /** Stable popup handler from `usePopup`; bound to the concrete message internally. */\n onActionPopup: (\n message: TChatMessage<TContent, TMessageMetadata>,\n action: BaseMessageActionConfig,\n anchor: HTMLElement,\n ) => void;\n};\n\nexport type MessageItemProps<TContent extends TMessageContent = never> =\n MessageItemConfig<TContent> & {\n message: TChatMessage<TContent, TMessageMetadata>;\n /**\n * Whether action buttons should be hidden for this message. Precomputed by the parent\n * (the last message while a response is still streaming/submitted) so that completed\n * messages keep a stable value and stay memoized.\n */\n suppressActions: boolean;\n };\n\nfunction MessageItemComponent<TContent extends TMessageContent = never>({\n message,\n suppressActions,\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions,\n getMarkdownExtraProps,\n getMdxContext,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n onActionPopup,\n}: MessageItemProps<TContent>) {\n const mdxContext = useMemo(\n () => getMdxContext?.(message) as Record<string, unknown> | undefined,\n [getMdxContext, message],\n );\n const markdownExtraProps = useMemo(\n () => getMarkdownExtraProps?.(message),\n [getMarkdownExtraProps, message],\n );\n\n if (isUserMessage<TMessageMetadata, TContent>(message)) {\n const actions = resolveMessageActions(message, userActions);\n\n return (\n <UserMessage\n content={message.content}\n actions={actions}\n extraInfo={UserExtraInfo ? <UserExtraInfo message={message} /> : undefined}\n timestamp={message.timestamp}\n format={message.format}\n avatarUrl={message.avatarUrl}\n images={message.images}\n fileAttachments={message.fileAttachments}\n transformOptions={transformOptions}\n shouldParseIncompleteMarkdown={shouldParseIncompleteMarkdown}\n mermaidOptions={mermaidOptions}\n openMarkdownLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxOptions}\n mdxContext={mdxContext}\n markdownExtraProps={markdownExtraProps}\n showActionsOnHover={showActionsOnHover}\n showTimestamp={showTimestamp}\n showAvatar={showAvatar}\n onActionPopup={(action, anchor) => onActionPopup(message, action, anchor)}\n />\n );\n }\n\n if (isAssistantMessage<TMessageMetadata, TContent>(message)) {\n // Don't show assistantActions for messages with ONLY thinking content.\n // For mixed content (thinking + text), actions are shown and copy the entire message.\n const actions =\n !suppressActions && !hasOnlyThinkingContent(message.content)\n ? resolveMessageActions(message, assistantActions)\n : undefined;\n\n return (\n <AssistantMessage<TContent>\n content={message.content}\n actions={actions}\n extraInfo={\n AssistantExtraInfo ? <AssistantExtraInfo message={message} /> : undefined\n }\n timestamp={message.timestamp}\n id={message.id}\n messageRendererRegistry={messageRendererRegistry}\n thinkingMessageView={thinkingMessageView}\n transformOptions={transformOptions}\n shouldParseIncompleteMarkdown={shouldParseIncompleteMarkdown}\n mermaidOptions={mermaidOptions}\n openMarkdownLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxOptions}\n mdxContext={mdxContext}\n markdownExtraProps={markdownExtraProps}\n showActionsOnHover={showActionsOnHover}\n showTimestamp={showTimestamp}\n userRating={message.userRating}\n onActionPopup={(action, anchor) => onActionPopup(message, action, anchor)}\n />\n );\n }\n\n return null;\n}\n\n/**\n * Memoized single message renderer shared by the plain and virtualized message lists.\n * Re-renders only when `message`, `suppressActions`, or one of the (stable) config props changes,\n * so that during streaming only the message that actually changed is re-rendered.\n */\nexport const MessageItem = memo(MessageItemComponent) as typeof MessageItemComponent;\n"]}
|
|
@@ -54,6 +54,7 @@ export type MessageListProps<TContent extends TMessageContent = never> = {
|
|
|
54
54
|
withLoaderShimmer?: boolean;
|
|
55
55
|
onRetry?: () => void;
|
|
56
56
|
messageRendererRegistry?: MessageRendererRegistry;
|
|
57
|
+
thinkingMessageView?: 'default' | 'grouped';
|
|
57
58
|
transformOptions?: OptionsType;
|
|
58
59
|
shouldParseIncompleteMarkdown?: boolean;
|
|
59
60
|
mermaidOptions?: MermaidOptions;
|
|
@@ -25,7 +25,7 @@ function MessageList(props) {
|
|
|
25
25
|
}
|
|
26
26
|
return (0, jsx_runtime_1.jsx)(PlainMessageList, Object.assign({}, props));
|
|
27
27
|
}
|
|
28
|
-
function PlainMessageList({ messages, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }) {
|
|
28
|
+
function PlainMessageList({ messages, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }) {
|
|
29
29
|
const isStreaming = status === 'streaming' || status === 'streaming_loading';
|
|
30
30
|
const isSubmitted = status === 'submitted';
|
|
31
31
|
const showLoader = status && loaderStatuses.includes(status);
|
|
@@ -40,6 +40,6 @@ function PlainMessageList({ messages, messageRendererRegistry, transformOptions,
|
|
|
40
40
|
(0, hooks_1.useScrollPreservation)(containerRef, messages.length);
|
|
41
41
|
const isNotCompleted = isSubmitted || isStreaming;
|
|
42
42
|
return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: b(null, className), "data-qa": qa !== null && qa !== void 0 ? qa : MessageListQa.Root, children: [hasPreviousMessages && ((0, jsx_runtime_1.jsx)(IntersectionContainer_1.IntersectionContainer, { onIntersect: onLoadPreviousMessages, className: b('load-trigger'), children: (0, jsx_runtime_1.jsx)(Loader_1.Loader, { view: "loading" }) })), (0, jsx_runtime_1.jsx)("div", { className: b('messages'), "data-qa": qa ? `${qa}-messages` : MessageListQa.Messages, children: messages.map((message, index) => ((0, jsx_runtime_1.jsx)(MessageItem_1.MessageItem, { message: message, suppressActions: index === messages.length - 1 && isNotCompleted, showActionsOnHover: showActionsOnHover &&
|
|
43
|
-
!(0, usePopup_1.isActionPopupOpenForMessage)(popupState, message.id), messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, mermaidOptions: mermaidOptions, openMarkdownLinksInNewTab: openMarkdownLinksInNewTab, mdxOptions: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.mdxOptions, getMarkdownExtraProps: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.getMarkdownExtraProps, getMdxContext: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.getMdxContext, showTimestamp: showTimestamp, showAvatar: showAvatar, userActions: userActions, assistantActions: assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup: handleActionPopup }, message.id || `message-${index}`))) }), (0, jsx_runtime_1.jsx)(MessageListFooter_1.MessageListFooter, { showLoader: showLoader, status: status, errorMessage: errorMessage, loaderMessage: loaderMessage, withLoaderShimmer: withLoaderShimmer, onRetry: onRetry, ratingBlockProps: ratingBlockProps, actionPopupProps: actionPopupProps, qa: qa, showActionPopup: showActionPopup, popupState: popupState, onPopupOpenChange: handlePopupOpenChange }), footerContent !== undefined && footerContent !== null && ((0, jsx_runtime_1.jsx)("div", { className: b('footer-content'), children: footerContent }))] }));
|
|
43
|
+
!(0, usePopup_1.isActionPopupOpenForMessage)(popupState, message.id), messageRendererRegistry: messageRendererRegistry, thinkingMessageView: thinkingMessageView, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, mermaidOptions: mermaidOptions, openMarkdownLinksInNewTab: openMarkdownLinksInNewTab, mdxOptions: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.mdxOptions, getMarkdownExtraProps: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.getMarkdownExtraProps, getMdxContext: mdxProps === null || mdxProps === void 0 ? void 0 : mdxProps.getMdxContext, showTimestamp: showTimestamp, showAvatar: showAvatar, userActions: userActions, assistantActions: assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, onActionPopup: handleActionPopup }, message.id || `message-${index}`))) }), (0, jsx_runtime_1.jsx)(MessageListFooter_1.MessageListFooter, { showLoader: showLoader, status: status, errorMessage: errorMessage, loaderMessage: loaderMessage, withLoaderShimmer: withLoaderShimmer, onRetry: onRetry, ratingBlockProps: ratingBlockProps, actionPopupProps: actionPopupProps, qa: qa, showActionPopup: showActionPopup, popupState: popupState, onPopupOpenChange: handlePopupOpenChange }), footerContent !== undefined && footerContent !== null && ((0, jsx_runtime_1.jsx)("div", { className: b('footer-content'), children: footerContent }))] }));
|
|
44
44
|
}
|
|
45
45
|
//# sourceMappingURL=MessageList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageList.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {HTMLAttributes} from 'react';\n\nimport type {OptionsType} from '@diplodoc/transform/lib/typings';\nimport type {PopupPlacement} from '@gravity-ui/uikit';\n\nimport {useScrollPreservation, useSmartScroll} from '../../../hooks';\nimport {ChatStatus} from '../../../types';\nimport type {\n DefaultMessageAction,\n MessageExtraInfoComponent,\n TAssistantMessage,\n TChatMessage,\n TMessageContent,\n TMessageMetadata,\n TUserMessage,\n} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {type MessageRendererRegistry} from '../../../utils/messageTypeRegistry';\nimport {AlertProps} from '../../atoms/Alert';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\nimport type {MarkdownRendererMdxOptions, MermaidOptions} from '../../atoms/MarkdownRenderer';\nimport {type RatingBlockProps} from '../../molecules/RatingBlock/RatingBlock';\n\nimport {MessageItem} from './MessageItem';\nimport {VirtualizedMessageList} from './MessageList.virtualized';\nimport {MessageListFooter} from './MessageListFooter';\nimport {isActionPopupOpenForMessage, usePopup} from './usePopup';\n\nimport './MessageList.scss';\n\nconst b = block('message-list');\n\nexport enum MessageListQa {\n Root = 'message-list',\n Messages = 'message-list-messages',\n}\n\n/** Configuration for action popup behavior */\nexport interface MessageListActionPopupConfig {\n /** Override title for all popups (overrides action-specific title) */\n title?: string;\n /** Override subtitle for all popups (overrides action-specific subtitle) */\n subtitle?: string;\n /** Override placement for all popups (overrides action-specific placement) */\n placement?: PopupPlacement;\n /** Additional CSS class for popup */\n className?: string;\n /** QA/test identifier for popup */\n qa?: string;\n}\n\n/**\n * Grouped MDX/markdown rendering props exposed as a single object on `MessageList` and\n * `ChatContainer`. They are destructured back into individual props before being handed to\n * the low-level `MessageItem` renderer.\n */\nexport type MdxProps<TContent extends TMessageContent = never> = {\n /** Options for rendering MDX (`@diplodoc/mdx-extension`) in the default message renderers */\n mdxOptions?: MarkdownRendererMdxOptions;\n /**\n * Resolves the extra props forwarded to the root container `div` of each rendered\n * markdown block. Called with the concrete message so handlers (e.g. `onClick`) can\n * identify the message they belong to.\n */\n getMarkdownExtraProps?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => HTMLAttributes<HTMLDivElement> | undefined;\n /**\n * Resolves the per-message value exposed to MDX components (via `useMdxContext`).\n * Called with the concrete message so embedded MDX components can read data\n * unique to the message they belong to.\n */\n getMdxContext?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => Record<string, unknown> | undefined;\n};\n\nexport type MessageListProps<TContent extends TMessageContent = never> = {\n messages: TChatMessage<TContent, TMessageMetadata>[];\n status?: ChatStatus;\n errorMessage?: AlertProps;\n loaderMessage?: string;\n withLoaderShimmer?: boolean;\n onRetry?: () => void;\n messageRendererRegistry?: MessageRendererRegistry;\n transformOptions?: OptionsType;\n shouldParseIncompleteMarkdown?: boolean;\n mermaidOptions?: MermaidOptions;\n openMarkdownLinksInNewTab?: boolean;\n /** Grouped MDX/markdown rendering props (`mdxOptions`, `getMarkdownExtraProps`, `getMdxContext`). */\n mdxProps?: MdxProps<TContent>;\n showActionsOnHover?: boolean;\n showTimestamp?: boolean;\n showAvatar?: boolean;\n userActions?: DefaultMessageAction<TUserMessage<TMessageMetadata>>[];\n assistantActions?: DefaultMessageAction<TAssistantMessage<TContent, TMessageMetadata>>[];\n /** Component rendered alongside action buttons for each user message. Receives message as prop. */\n userExtraInfo?: MessageExtraInfoComponent<TUserMessage<TMessageMetadata>>;\n /** Component rendered alongside action buttons for each assistant message. Receives message as prop. */\n assistantExtraInfo?: MessageExtraInfoComponent<TAssistantMessage<TContent, TMessageMetadata>>;\n /** Array of chat statuses that should display the loader */\n loaderStatuses?: ChatStatus[];\n className?: string;\n qa?: string;\n hasPreviousMessages?: boolean;\n onLoadPreviousMessages?: () => void;\n /** Rating block configuration (for CSAT or other feedback use cases) - renders after messages list */\n ratingBlockProps?: RatingBlockProps;\n /** Action popup configuration - applies to all action popups */\n actionPopupProps?: MessageListActionPopupConfig;\n /**\n * Enable windowed rendering via react-window for very large histories.\n * Off by default to preserve the existing rendering/scroll behavior.\n */\n virtualized?: boolean;\n /** Last scrollable row rendered after all messages. */\n footerContent?: React.ReactNode;\n};\n\nexport function MessageList<TContent extends TMessageContent = never>(\n props: MessageListProps<TContent>,\n) {\n // Opt-in virtualized path - keeps the proven non-virtualized rendering untouched below.\n if (props.virtualized) {\n return <VirtualizedMessageList<TContent> {...props} />;\n }\n\n return <PlainMessageList<TContent> {...props} />;\n}\n\nfunction PlainMessageList<TContent extends TMessageContent = never>({\n messages,\n messageRendererRegistry,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n loaderStatuses = ['submitted', 'streaming_loading'],\n className,\n qa,\n status,\n errorMessage,\n loaderMessage,\n withLoaderShimmer,\n onRetry,\n hasPreviousMessages = false,\n onLoadPreviousMessages,\n ratingBlockProps,\n actionPopupProps,\n footerContent,\n}: MessageListProps<TContent>) {\n const isStreaming = status === 'streaming' || status === 'streaming_loading';\n const isSubmitted = status === 'submitted';\n const showLoader = status && loaderStatuses.includes(status);\n\n // Use popup hook for managing popup state\n const {popupState, handleActionPopup, handlePopupOpenChange, showActionPopup} = usePopup<\n TContent,\n TMessageMetadata\n >();\n\n const {containerRef} = useSmartScroll<HTMLDivElement>({\n isStreaming: isStreaming || isSubmitted,\n messagesCount: messages.length,\n status,\n });\n\n // Preserve scroll position when older messages are loaded\n useScrollPreservation(containerRef, messages.length);\n\n const isNotCompleted = isSubmitted || isStreaming;\n\n return (\n <div ref={containerRef} className={b(null, className)} data-qa={qa ?? MessageListQa.Root}>\n {hasPreviousMessages && (\n <IntersectionContainer\n onIntersect={onLoadPreviousMessages}\n className={b('load-trigger')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n )}\n <div className={b('messages')} data-qa={qa ? `${qa}-messages` : MessageListQa.Messages}>\n {messages.map((message, index) => (\n <MessageItem<TContent>\n key={message.id || `message-${index}`}\n message={message}\n suppressActions={index === messages.length - 1 && isNotCompleted}\n showActionsOnHover={\n showActionsOnHover &&\n !isActionPopupOpenForMessage(popupState, message.id)\n }\n messageRendererRegistry={messageRendererRegistry}\n transformOptions={transformOptions}\n shouldParseIncompleteMarkdown={shouldParseIncompleteMarkdown}\n mermaidOptions={mermaidOptions}\n openMarkdownLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxProps?.mdxOptions}\n getMarkdownExtraProps={mdxProps?.getMarkdownExtraProps}\n getMdxContext={mdxProps?.getMdxContext}\n showTimestamp={showTimestamp}\n showAvatar={showAvatar}\n userActions={userActions}\n assistantActions={assistantActions}\n userExtraInfo={UserExtraInfo}\n assistantExtraInfo={AssistantExtraInfo}\n onActionPopup={handleActionPopup}\n />\n ))}\n </div>\n <MessageListFooter\n showLoader={showLoader}\n status={status}\n errorMessage={errorMessage}\n loaderMessage={loaderMessage}\n withLoaderShimmer={withLoaderShimmer}\n onRetry={onRetry}\n ratingBlockProps={ratingBlockProps}\n actionPopupProps={actionPopupProps}\n qa={qa}\n showActionPopup={showActionPopup}\n popupState={popupState}\n onPopupOpenChange={handlePopupOpenChange}\n />\n {footerContent !== undefined && footerContent !== null && (\n <div className={b('footer-content')}>{footerContent}</div>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageList.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {HTMLAttributes} from 'react';\n\nimport type {OptionsType} from '@diplodoc/transform/lib/typings';\nimport type {PopupPlacement} from '@gravity-ui/uikit';\n\nimport {useScrollPreservation, useSmartScroll} from '../../../hooks';\nimport {ChatStatus} from '../../../types';\nimport type {\n DefaultMessageAction,\n MessageExtraInfoComponent,\n TAssistantMessage,\n TChatMessage,\n TMessageContent,\n TMessageMetadata,\n TUserMessage,\n} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {type MessageRendererRegistry} from '../../../utils/messageTypeRegistry';\nimport {AlertProps} from '../../atoms/Alert';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\nimport type {MarkdownRendererMdxOptions, MermaidOptions} from '../../atoms/MarkdownRenderer';\nimport {type RatingBlockProps} from '../../molecules/RatingBlock/RatingBlock';\n\nimport {MessageItem} from './MessageItem';\nimport {VirtualizedMessageList} from './MessageList.virtualized';\nimport {MessageListFooter} from './MessageListFooter';\nimport {isActionPopupOpenForMessage, usePopup} from './usePopup';\n\nimport './MessageList.scss';\n\nconst b = block('message-list');\n\nexport enum MessageListQa {\n Root = 'message-list',\n Messages = 'message-list-messages',\n}\n\n/** Configuration for action popup behavior */\nexport interface MessageListActionPopupConfig {\n /** Override title for all popups (overrides action-specific title) */\n title?: string;\n /** Override subtitle for all popups (overrides action-specific subtitle) */\n subtitle?: string;\n /** Override placement for all popups (overrides action-specific placement) */\n placement?: PopupPlacement;\n /** Additional CSS class for popup */\n className?: string;\n /** QA/test identifier for popup */\n qa?: string;\n}\n\n/**\n * Grouped MDX/markdown rendering props exposed as a single object on `MessageList` and\n * `ChatContainer`. They are destructured back into individual props before being handed to\n * the low-level `MessageItem` renderer.\n */\nexport type MdxProps<TContent extends TMessageContent = never> = {\n /** Options for rendering MDX (`@diplodoc/mdx-extension`) in the default message renderers */\n mdxOptions?: MarkdownRendererMdxOptions;\n /**\n * Resolves the extra props forwarded to the root container `div` of each rendered\n * markdown block. Called with the concrete message so handlers (e.g. `onClick`) can\n * identify the message they belong to.\n */\n getMarkdownExtraProps?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => HTMLAttributes<HTMLDivElement> | undefined;\n /**\n * Resolves the per-message value exposed to MDX components (via `useMdxContext`).\n * Called with the concrete message so embedded MDX components can read data\n * unique to the message they belong to.\n */\n getMdxContext?: (\n message: TChatMessage<TContent, TMessageMetadata>,\n ) => Record<string, unknown> | undefined;\n};\n\nexport type MessageListProps<TContent extends TMessageContent = never> = {\n messages: TChatMessage<TContent, TMessageMetadata>[];\n status?: ChatStatus;\n errorMessage?: AlertProps;\n loaderMessage?: string;\n withLoaderShimmer?: boolean;\n onRetry?: () => void;\n messageRendererRegistry?: MessageRendererRegistry;\n thinkingMessageView?: 'default' | 'grouped';\n transformOptions?: OptionsType;\n shouldParseIncompleteMarkdown?: boolean;\n mermaidOptions?: MermaidOptions;\n openMarkdownLinksInNewTab?: boolean;\n /** Grouped MDX/markdown rendering props (`mdxOptions`, `getMarkdownExtraProps`, `getMdxContext`). */\n mdxProps?: MdxProps<TContent>;\n showActionsOnHover?: boolean;\n showTimestamp?: boolean;\n showAvatar?: boolean;\n userActions?: DefaultMessageAction<TUserMessage<TMessageMetadata>>[];\n assistantActions?: DefaultMessageAction<TAssistantMessage<TContent, TMessageMetadata>>[];\n /** Component rendered alongside action buttons for each user message. Receives message as prop. */\n userExtraInfo?: MessageExtraInfoComponent<TUserMessage<TMessageMetadata>>;\n /** Component rendered alongside action buttons for each assistant message. Receives message as prop. */\n assistantExtraInfo?: MessageExtraInfoComponent<TAssistantMessage<TContent, TMessageMetadata>>;\n /** Array of chat statuses that should display the loader */\n loaderStatuses?: ChatStatus[];\n className?: string;\n qa?: string;\n hasPreviousMessages?: boolean;\n onLoadPreviousMessages?: () => void;\n /** Rating block configuration (for CSAT or other feedback use cases) - renders after messages list */\n ratingBlockProps?: RatingBlockProps;\n /** Action popup configuration - applies to all action popups */\n actionPopupProps?: MessageListActionPopupConfig;\n /**\n * Enable windowed rendering via react-window for very large histories.\n * Off by default to preserve the existing rendering/scroll behavior.\n */\n virtualized?: boolean;\n /** Last scrollable row rendered after all messages. */\n footerContent?: React.ReactNode;\n};\n\nexport function MessageList<TContent extends TMessageContent = never>(\n props: MessageListProps<TContent>,\n) {\n // Opt-in virtualized path - keeps the proven non-virtualized rendering untouched below.\n if (props.virtualized) {\n return <VirtualizedMessageList<TContent> {...props} />;\n }\n\n return <PlainMessageList<TContent> {...props} />;\n}\n\nfunction PlainMessageList<TContent extends TMessageContent = never>({\n messages,\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n loaderStatuses = ['submitted', 'streaming_loading'],\n className,\n qa,\n status,\n errorMessage,\n loaderMessage,\n withLoaderShimmer,\n onRetry,\n hasPreviousMessages = false,\n onLoadPreviousMessages,\n ratingBlockProps,\n actionPopupProps,\n footerContent,\n}: MessageListProps<TContent>) {\n const isStreaming = status === 'streaming' || status === 'streaming_loading';\n const isSubmitted = status === 'submitted';\n const showLoader = status && loaderStatuses.includes(status);\n\n // Use popup hook for managing popup state\n const {popupState, handleActionPopup, handlePopupOpenChange, showActionPopup} = usePopup<\n TContent,\n TMessageMetadata\n >();\n\n const {containerRef} = useSmartScroll<HTMLDivElement>({\n isStreaming: isStreaming || isSubmitted,\n messagesCount: messages.length,\n status,\n });\n\n // Preserve scroll position when older messages are loaded\n useScrollPreservation(containerRef, messages.length);\n\n const isNotCompleted = isSubmitted || isStreaming;\n\n return (\n <div ref={containerRef} className={b(null, className)} data-qa={qa ?? MessageListQa.Root}>\n {hasPreviousMessages && (\n <IntersectionContainer\n onIntersect={onLoadPreviousMessages}\n className={b('load-trigger')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n )}\n <div className={b('messages')} data-qa={qa ? `${qa}-messages` : MessageListQa.Messages}>\n {messages.map((message, index) => (\n <MessageItem<TContent>\n key={message.id || `message-${index}`}\n message={message}\n suppressActions={index === messages.length - 1 && isNotCompleted}\n showActionsOnHover={\n showActionsOnHover &&\n !isActionPopupOpenForMessage(popupState, message.id)\n }\n messageRendererRegistry={messageRendererRegistry}\n thinkingMessageView={thinkingMessageView}\n transformOptions={transformOptions}\n shouldParseIncompleteMarkdown={shouldParseIncompleteMarkdown}\n mermaidOptions={mermaidOptions}\n openMarkdownLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxProps?.mdxOptions}\n getMarkdownExtraProps={mdxProps?.getMarkdownExtraProps}\n getMdxContext={mdxProps?.getMdxContext}\n showTimestamp={showTimestamp}\n showAvatar={showAvatar}\n userActions={userActions}\n assistantActions={assistantActions}\n userExtraInfo={UserExtraInfo}\n assistantExtraInfo={AssistantExtraInfo}\n onActionPopup={handleActionPopup}\n />\n ))}\n </div>\n <MessageListFooter\n showLoader={showLoader}\n status={status}\n errorMessage={errorMessage}\n loaderMessage={loaderMessage}\n withLoaderShimmer={withLoaderShimmer}\n onRetry={onRetry}\n ratingBlockProps={ratingBlockProps}\n actionPopupProps={actionPopupProps}\n qa={qa}\n showActionPopup={showActionPopup}\n popupState={popupState}\n onPopupOpenChange={handlePopupOpenChange}\n />\n {footerContent !== undefined && footerContent !== null && (\n <div className={b('footer-content')}>{footerContent}</div>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TMessageContent } from "../../../types/messages.js";
|
|
2
2
|
import { type MessageListProps } from "./MessageList.js";
|
|
3
|
-
export declare function VirtualizedMessageList<TContent extends TMessageContent = never>({ messages, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses, className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }: MessageListProps<TContent>): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function VirtualizedMessageList<TContent extends TMessageContent = never>({ messages, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses, className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }: MessageListProps<TContent>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -34,7 +34,7 @@ function MessageRow({ index, style, ariaAttributes, messages, isNotCompleted, he
|
|
|
34
34
|
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ style: style }, ariaAttributes, { children: (0, jsx_runtime_1.jsx)("div", { className: b('row'), "data-message-id": message.id, children: (0, jsx_runtime_1.jsx)(MessageItem_1.MessageItem, Object.assign({ message: message, suppressActions: isLast && isNotCompleted }, config, { showActionsOnHover: Boolean(config.showActionsOnHover) &&
|
|
35
35
|
!(0, usePopup_1.isActionPopupOpenForMessage)(popupState, message.id) })) }) })));
|
|
36
36
|
}
|
|
37
|
-
function VirtualizedMessageList({ messages, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }) {
|
|
37
|
+
function VirtualizedMessageList({ messages, messageRendererRegistry, thinkingMessageView, transformOptions, shouldParseIncompleteMarkdown, mermaidOptions, openMarkdownLinksInNewTab, mdxProps, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, userExtraInfo: UserExtraInfo, assistantExtraInfo: AssistantExtraInfo, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, loaderMessage, withLoaderShimmer, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, ratingBlockProps, actionPopupProps, footerContent, }) {
|
|
38
38
|
var _a;
|
|
39
39
|
const isStreaming = status === 'streaming' || status === 'streaming_loading';
|
|
40
40
|
const isSubmitted = status === 'submitted';
|
|
@@ -47,6 +47,7 @@ function VirtualizedMessageList({ messages, messageRendererRegistry, transformOp
|
|
|
47
47
|
const rowCount = messages.length + headerOffset + footerOffset;
|
|
48
48
|
const config = (0, react_1.useMemo)(() => ({
|
|
49
49
|
messageRendererRegistry,
|
|
50
|
+
thinkingMessageView,
|
|
50
51
|
transformOptions,
|
|
51
52
|
shouldParseIncompleteMarkdown,
|
|
52
53
|
mermaidOptions,
|
|
@@ -64,6 +65,7 @@ function VirtualizedMessageList({ messages, messageRendererRegistry, transformOp
|
|
|
64
65
|
onActionPopup: handleActionPopup,
|
|
65
66
|
}), [
|
|
66
67
|
messageRendererRegistry,
|
|
68
|
+
thinkingMessageView,
|
|
67
69
|
transformOptions,
|
|
68
70
|
shouldParseIncompleteMarkdown,
|
|
69
71
|
mermaidOptions,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.virtualized.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageList.virtualized.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useCallback, useMemo} from 'react';\n\nimport {List, type RowComponentProps, useDynamicRowHeight} from 'react-window';\n\nimport {useVirtualStickToBottom} from '../../../hooks';\nimport type {TChatMessage, TMessageContent, TMessageMetadata} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\n\nimport {MessageItem, type MessageItemConfig} from './MessageItem';\nimport {type MessageListProps, MessageListQa} from './MessageList';\nimport {MessageListFooter} from './MessageListFooter';\nimport {type PopupState, isActionPopupOpenForMessage, usePopup} from './usePopup';\n\nconst b = block('message-list');\n\n/** Estimated row height used before a row has been measured (and for SSR). */\nconst DEFAULT_ROW_HEIGHT = 80;\n/** Extra rows rendered outside the viewport to reduce flicker while scrolling. */\nconst OVERSCAN_COUNT = 5;\n\ntype MessageRowProps = {\n messages: TChatMessage<TMessageContent, TMessageMetadata>[];\n /** Whether the current response is still streaming/submitted (hide actions on last row). */\n isNotCompleted: boolean;\n /** Number of non-message rows before the messages (the load-more trigger). */\n headerOffset: number;\n hasPreviousMessages: boolean;\n onLoadPreviousMessages?: () => void;\n popupState: PopupState;\n config: MessageItemConfig<TMessageContent>;\n footerContent?: React.ReactNode;\n};\n\nfunction MessageRow({\n index,\n style,\n ariaAttributes,\n messages,\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config,\n footerContent,\n}: RowComponentProps<MessageRowProps>) {\n // Header row: the \"load previous messages\" intersection trigger.\n if (hasPreviousMessages && index === 0) {\n return (\n <div style={style} {...ariaAttributes}>\n <IntersectionContainer\n onIntersect={onLoadPreviousMessages}\n className={b('load-trigger')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n </div>\n );\n }\n\n const messageIndex = index - headerOffset;\n const message = messages[messageIndex];\n if (!message) {\n if (messageIndex === messages.length && footerContent !== undefined) {\n return (\n <div style={style} {...ariaAttributes}>\n <div className={b('footer-content')}>{footerContent}</div>\n </div>\n );\n }\n return <div style={style} {...ariaAttributes} />;\n }\n\n const isLast = messageIndex === messages.length - 1;\n\n return (\n <div style={style} {...ariaAttributes}>\n {/* data-message-id lets useVirtualStickToBottom anchor scroll position to a specific\n rendered row (robust to off-screen height estimation) when older messages load. */}\n <div className={b('row')} data-message-id={message.id}>\n <MessageItem\n message={message}\n suppressActions={isLast && isNotCompleted}\n {...config}\n showActionsOnHover={\n Boolean(config.showActionsOnHover) &&\n !isActionPopupOpenForMessage(popupState, message.id)\n }\n />\n </div>\n </div>\n );\n}\n\nexport function VirtualizedMessageList<TContent extends TMessageContent = never>({\n messages,\n messageRendererRegistry,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n loaderStatuses = ['submitted', 'streaming_loading'],\n className,\n qa,\n status,\n errorMessage,\n loaderMessage,\n withLoaderShimmer,\n onRetry,\n hasPreviousMessages = false,\n onLoadPreviousMessages,\n ratingBlockProps,\n actionPopupProps,\n footerContent,\n}: MessageListProps<TContent>) {\n const isStreaming = status === 'streaming' || status === 'streaming_loading';\n const isSubmitted = status === 'submitted';\n const isNotCompleted = isSubmitted || isStreaming;\n const showLoader = status && loaderStatuses.includes(status);\n\n const {popupState, handleActionPopup, handlePopupOpenChange, showActionPopup} = usePopup<\n TContent,\n TMessageMetadata\n >();\n\n const headerOffset = hasPreviousMessages ? 1 : 0;\n const hasFooterContent = footerContent !== undefined && footerContent !== null;\n const footerOffset = hasFooterContent ? 1 : 0;\n const rowCount = messages.length + headerOffset + footerOffset;\n\n const config = useMemo<MessageItemConfig<TContent>>(\n () => ({\n messageRendererRegistry,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions: mdxProps?.mdxOptions,\n getMarkdownExtraProps: mdxProps?.getMarkdownExtraProps,\n getMdxContext: mdxProps?.getMdxContext,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n onActionPopup: handleActionPopup,\n }),\n [\n messageRendererRegistry,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n UserExtraInfo,\n AssistantExtraInfo,\n handleActionPopup,\n ],\n );\n\n const rowProps = useMemo<MessageRowProps>(\n () => ({\n messages: messages as TChatMessage<TMessageContent, TMessageMetadata>[],\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config: config as unknown as MessageItemConfig<TMessageContent>,\n footerContent: hasFooterContent ? footerContent : undefined,\n }),\n [\n messages,\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config,\n hasFooterContent,\n footerContent,\n ],\n );\n\n const rowHeight = useDynamicRowHeight({defaultRowHeight: DEFAULT_ROW_HEIGHT});\n\n const {listRef, isPrepending} = useVirtualStickToBottom({\n rowCount,\n isStreaming: isNotCompleted,\n status,\n messagesCount: messages.length,\n firstMessageId: messages[0]?.id,\n headerOffset,\n // The last message reference changes on every streamed token, so it pins the view to the\n // growing last row even while react-window keeps the same set of rows mounted.\n streamingSignal: isNotCompleted ? messages[messages.length - 1] : undefined,\n trailingContentSignal: footerOffset,\n });\n\n // Close a popup whose anchor row scrolls out of view (react-window unmounts off-screen rows,\n // detaching the popup's anchor element).\n const onRowsRendered = useCallback(\n (visibleRows: {startIndex: number; stopIndex: number}) => {\n if (!popupState.open || popupState.messageId === null) {\n return;\n }\n const messageIndex = messages.findIndex(\n (message) => message.id === popupState.messageId,\n );\n // Anchor message no longer in the list - its row is gone, so close the popup.\n if (messageIndex === -1) {\n handlePopupOpenChange(false);\n return;\n }\n const anchorIndex = messageIndex + headerOffset;\n if (anchorIndex < visibleRows.startIndex || anchorIndex > visibleRows.stopIndex) {\n handlePopupOpenChange(false);\n }\n },\n [popupState.open, popupState.messageId, messages, headerOffset, handlePopupOpenChange],\n );\n\n return (\n <div className={b({virtualized: true}, className)} data-qa={qa ?? MessageListQa.Root}>\n {isPrepending && (\n <div className={b('shimmer')} aria-hidden=\"true\">\n {Array.from({length: 6}, (_, i) => (\n <div key={i} className={b('shimmer-row', {assistant: i % 2 === 1})} />\n ))}\n </div>\n )}\n <List<MessageRowProps>\n className={b('list')}\n listRef={listRef}\n rowComponent={MessageRow}\n rowCount={rowCount}\n rowHeight={rowHeight}\n rowProps={rowProps}\n overscanCount={OVERSCAN_COUNT}\n onRowsRendered={onRowsRendered}\n data-qa={qa ? `${qa}-messages` : MessageListQa.Messages}\n />\n <MessageListFooter\n showLoader={showLoader}\n status={status}\n errorMessage={errorMessage}\n loaderMessage={loaderMessage}\n withLoaderShimmer={withLoaderShimmer}\n onRetry={onRetry}\n ratingBlockProps={ratingBlockProps}\n actionPopupProps={actionPopupProps}\n qa={qa}\n showActionPopup={showActionPopup}\n popupState={popupState}\n onPopupOpenChange={handlePopupOpenChange}\n />\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MessageList.virtualized.js","sourceRoot":"../../../../../src","sources":["components/organisms/MessageList/MessageList.virtualized.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useCallback, useMemo} from 'react';\n\nimport {List, type RowComponentProps, useDynamicRowHeight} from 'react-window';\n\nimport {useVirtualStickToBottom} from '../../../hooks';\nimport type {TChatMessage, TMessageContent, TMessageMetadata} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\n\nimport {MessageItem, type MessageItemConfig} from './MessageItem';\nimport {type MessageListProps, MessageListQa} from './MessageList';\nimport {MessageListFooter} from './MessageListFooter';\nimport {type PopupState, isActionPopupOpenForMessage, usePopup} from './usePopup';\n\nconst b = block('message-list');\n\n/** Estimated row height used before a row has been measured (and for SSR). */\nconst DEFAULT_ROW_HEIGHT = 80;\n/** Extra rows rendered outside the viewport to reduce flicker while scrolling. */\nconst OVERSCAN_COUNT = 5;\n\ntype MessageRowProps = {\n messages: TChatMessage<TMessageContent, TMessageMetadata>[];\n /** Whether the current response is still streaming/submitted (hide actions on last row). */\n isNotCompleted: boolean;\n /** Number of non-message rows before the messages (the load-more trigger). */\n headerOffset: number;\n hasPreviousMessages: boolean;\n onLoadPreviousMessages?: () => void;\n popupState: PopupState;\n config: MessageItemConfig<TMessageContent>;\n footerContent?: React.ReactNode;\n};\n\nfunction MessageRow({\n index,\n style,\n ariaAttributes,\n messages,\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config,\n footerContent,\n}: RowComponentProps<MessageRowProps>) {\n // Header row: the \"load previous messages\" intersection trigger.\n if (hasPreviousMessages && index === 0) {\n return (\n <div style={style} {...ariaAttributes}>\n <IntersectionContainer\n onIntersect={onLoadPreviousMessages}\n className={b('load-trigger')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n </div>\n );\n }\n\n const messageIndex = index - headerOffset;\n const message = messages[messageIndex];\n if (!message) {\n if (messageIndex === messages.length && footerContent !== undefined) {\n return (\n <div style={style} {...ariaAttributes}>\n <div className={b('footer-content')}>{footerContent}</div>\n </div>\n );\n }\n return <div style={style} {...ariaAttributes} />;\n }\n\n const isLast = messageIndex === messages.length - 1;\n\n return (\n <div style={style} {...ariaAttributes}>\n {/* data-message-id lets useVirtualStickToBottom anchor scroll position to a specific\n rendered row (robust to off-screen height estimation) when older messages load. */}\n <div className={b('row')} data-message-id={message.id}>\n <MessageItem\n message={message}\n suppressActions={isLast && isNotCompleted}\n {...config}\n showActionsOnHover={\n Boolean(config.showActionsOnHover) &&\n !isActionPopupOpenForMessage(popupState, message.id)\n }\n />\n </div>\n </div>\n );\n}\n\nexport function VirtualizedMessageList<TContent extends TMessageContent = never>({\n messages,\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n loaderStatuses = ['submitted', 'streaming_loading'],\n className,\n qa,\n status,\n errorMessage,\n loaderMessage,\n withLoaderShimmer,\n onRetry,\n hasPreviousMessages = false,\n onLoadPreviousMessages,\n ratingBlockProps,\n actionPopupProps,\n footerContent,\n}: MessageListProps<TContent>) {\n const isStreaming = status === 'streaming' || status === 'streaming_loading';\n const isSubmitted = status === 'submitted';\n const isNotCompleted = isSubmitted || isStreaming;\n const showLoader = status && loaderStatuses.includes(status);\n\n const {popupState, handleActionPopup, handlePopupOpenChange, showActionPopup} = usePopup<\n TContent,\n TMessageMetadata\n >();\n\n const headerOffset = hasPreviousMessages ? 1 : 0;\n const hasFooterContent = footerContent !== undefined && footerContent !== null;\n const footerOffset = hasFooterContent ? 1 : 0;\n const rowCount = messages.length + headerOffset + footerOffset;\n\n const config = useMemo<MessageItemConfig<TContent>>(\n () => ({\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions: mdxProps?.mdxOptions,\n getMarkdownExtraProps: mdxProps?.getMarkdownExtraProps,\n getMdxContext: mdxProps?.getMdxContext,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n userExtraInfo: UserExtraInfo,\n assistantExtraInfo: AssistantExtraInfo,\n onActionPopup: handleActionPopup,\n }),\n [\n messageRendererRegistry,\n thinkingMessageView,\n transformOptions,\n shouldParseIncompleteMarkdown,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxProps,\n showActionsOnHover,\n showTimestamp,\n showAvatar,\n userActions,\n assistantActions,\n UserExtraInfo,\n AssistantExtraInfo,\n handleActionPopup,\n ],\n );\n\n const rowProps = useMemo<MessageRowProps>(\n () => ({\n messages: messages as TChatMessage<TMessageContent, TMessageMetadata>[],\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config: config as unknown as MessageItemConfig<TMessageContent>,\n footerContent: hasFooterContent ? footerContent : undefined,\n }),\n [\n messages,\n isNotCompleted,\n headerOffset,\n hasPreviousMessages,\n onLoadPreviousMessages,\n popupState,\n config,\n hasFooterContent,\n footerContent,\n ],\n );\n\n const rowHeight = useDynamicRowHeight({defaultRowHeight: DEFAULT_ROW_HEIGHT});\n\n const {listRef, isPrepending} = useVirtualStickToBottom({\n rowCount,\n isStreaming: isNotCompleted,\n status,\n messagesCount: messages.length,\n firstMessageId: messages[0]?.id,\n headerOffset,\n // The last message reference changes on every streamed token, so it pins the view to the\n // growing last row even while react-window keeps the same set of rows mounted.\n streamingSignal: isNotCompleted ? messages[messages.length - 1] : undefined,\n trailingContentSignal: footerOffset,\n });\n\n // Close a popup whose anchor row scrolls out of view (react-window unmounts off-screen rows,\n // detaching the popup's anchor element).\n const onRowsRendered = useCallback(\n (visibleRows: {startIndex: number; stopIndex: number}) => {\n if (!popupState.open || popupState.messageId === null) {\n return;\n }\n const messageIndex = messages.findIndex(\n (message) => message.id === popupState.messageId,\n );\n // Anchor message no longer in the list - its row is gone, so close the popup.\n if (messageIndex === -1) {\n handlePopupOpenChange(false);\n return;\n }\n const anchorIndex = messageIndex + headerOffset;\n if (anchorIndex < visibleRows.startIndex || anchorIndex > visibleRows.stopIndex) {\n handlePopupOpenChange(false);\n }\n },\n [popupState.open, popupState.messageId, messages, headerOffset, handlePopupOpenChange],\n );\n\n return (\n <div className={b({virtualized: true}, className)} data-qa={qa ?? MessageListQa.Root}>\n {isPrepending && (\n <div className={b('shimmer')} aria-hidden=\"true\">\n {Array.from({length: 6}, (_, i) => (\n <div key={i} className={b('shimmer-row', {assistant: i % 2 === 1})} />\n ))}\n </div>\n )}\n <List<MessageRowProps>\n className={b('list')}\n listRef={listRef}\n rowComponent={MessageRow}\n rowCount={rowCount}\n rowHeight={rowHeight}\n rowProps={rowProps}\n overscanCount={OVERSCAN_COUNT}\n onRowsRendered={onRowsRendered}\n data-qa={qa ? `${qa}-messages` : MessageListQa.Messages}\n />\n <MessageListFooter\n showLoader={showLoader}\n status={status}\n errorMessage={errorMessage}\n loaderMessage={loaderMessage}\n withLoaderShimmer={withLoaderShimmer}\n onRetry={onRetry}\n ratingBlockProps={ratingBlockProps}\n actionPopupProps={actionPopupProps}\n qa={qa}\n showActionPopup={showActionPopup}\n popupState={popupState}\n onPopupOpenChange={handlePopupOpenChange}\n />\n </div>\n );\n}\n"]}
|
|
@@ -31,6 +31,7 @@ export type ThinkingMessageProps = DOMProps & QAProps & ThinkingMessageContentDa
|
|
|
31
31
|
* Shows a collapsible block with thinking content and a copy button.
|
|
32
32
|
* Displays a loader when the thinking process is still in progress.
|
|
33
33
|
*
|
|
34
|
+
* @deprecated Use ThinkingMessageGroup. Planned for removal in the next major release.
|
|
34
35
|
* @param props - Component props
|
|
35
36
|
* @returns Rendered thinking message component
|
|
36
37
|
*/
|
|
@@ -21,6 +21,7 @@ const defaultTransformOptions = {
|
|
|
21
21
|
* Shows a collapsible block with thinking content and a copy button.
|
|
22
22
|
* Displays a loader when the thinking process is still in progress.
|
|
23
23
|
*
|
|
24
|
+
* @deprecated Use ThinkingMessageGroup. Planned for removal in the next major release.
|
|
24
25
|
* @param props - Component props
|
|
25
26
|
* @returns Rendered thinking message component
|
|
26
27
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["components/organisms/ThinkingMessage/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;AAKb,6CAA+D;AAC/D,6CAAwE;AAGxE,6CAAwC;AACxC,oEAAsD;AACtD,wDAA0C;AAC1C,4EAIsC;AAEtC,gEAAwD;AAExD,iCAAgC;AAEhC,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,kBAAkB,CAAC,CAAC;AA2BpC,MAAM,uBAAuB,GAAgB;IACzC,oBAAoB,EAAE,IAAI;CAC7B,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["components/organisms/ThinkingMessage/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;AAKb,6CAA+D;AAC/D,6CAAwE;AAGxE,6CAAwC;AACxC,oEAAsD;AACtD,wDAA0C;AAC1C,4EAIsC;AAEtC,gEAAwD;AAExD,iCAAgC;AAEhC,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,kBAAkB,CAAC,CAAC;AA2BpC,MAAM,uBAAuB,GAAgB;IACzC,oBAAoB,EAAE,IAAI;CAC7B,CAAC;AAEF;;;;;;;;GAQG;AACI,MAAM,eAAe,GAAG,CAAC,KAA2B,EAAE,EAAE;IAC3D,MAAM,EACF,SAAS,EACT,EAAE,EACF,KAAK,EACL,MAAM,GAAG,OAAO,EAChB,gBAAgB,EAChB,cAAc,EACd,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,kBAAkB,KAElB,KAAK,EADF,IAAI,kBACP,KAAK,EAZH,2JAYL,CAAQ,CAAC;IAEV,MAAM,wBAAwB,mCACvB,uBAAuB,GACvB,gBAAgB,CACtB,CAAC;IAEF,MAAM,EACF,UAAU,EACV,cAAc,EACd,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,cAAc,GACjB,GAAG,IAAA,uCAAkB,EAAC,IAAI,CAAC,CAAC;IAE7B,OAAO,CACH,iCAAK,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,aAAW,EAAE,EAAE,KAAK,EAAE,KAAK,aACzD,iCAAK,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,aACxB,wBAAC,cAAM,IAAC,IAAI,EAAC,GAAG,EAAC,OAAO,EAAE,cAAc,aACnC,WAAW,EACZ,uBAAC,YAAI,IAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,iBAAS,CAAC,CAAC,CAAC,mBAAW,GAAI,IAC/C,EACR,UAAU,CAAC,CAAC,CAAC,CACV,uBAAC,eAAM,IAAC,IAAI,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,GAAG,CACtC,CAAC,CAAC,CAAC,CACA,cAAc,IAAI,CACd,uBAAC,2BAAY,IAAC,IAAI,EAAC,GAAG,EAAC,OAAO,EAAE,UAAU,YACtC,uBAAC,YAAI,IAAC,IAAI,EAAE,YAAI,EAAE,IAAI,EAAE,EAAE,GAAI,GACnB,CAClB,CACJ,IACC,EACL,UAAU,IAAI,CACX,gCAAK,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,YACzB,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACzB,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CACpB,uBAAC,mCAAgB,IACb,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,EAEvB,OAAO,EAAE,IAAI,EACb,gBAAgB,EAAE,wBAAwB,EAC1C,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,yBAAyB,EAC5C,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,kBAAkB,IAPzB,KAAK,CAQZ,CACL,CAAC,CAAC,CAAC,CACA,uBAAC,YAAI,IAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,YACxB,IAAI,IAD2B,KAAK,CAElC,CACV,CACJ,GACC,CACT,IACC,CACT,CAAC;AACN,CAAC,CAAC;AAxEW,QAAA,eAAe,mBAwE1B","sourcesContent":["'use client';\n\nimport type {HTMLAttributes} from 'react';\n\nimport {OptionsType} from '@diplodoc/transform/lib/typings';\nimport {ChevronDown, ChevronUp, Copy} from '@gravity-ui/icons';\nimport {Button, DOMProps, Icon, QAProps, Text} from '@gravity-ui/uikit';\n\nimport type {ThinkingMessageContentData} from '../../../types/messages';\nimport {block} from '../../../utils/cn';\nimport {ActionButton} from '../../atoms/ActionButton';\nimport {Loader} from '../../atoms/Loader';\nimport {\n MarkdownRenderer,\n type MarkdownRendererMdxOptions,\n type MermaidOptions,\n} from '../../atoms/MarkdownRenderer';\n\nimport {useThinkingMessage} from './useThinkingMessage';\n\nimport './ThinkingMessage.scss';\n\nconst b = block('thinking-message');\n\n/**\n * Props for the ThinkingMessage component.\n * Combines DOM props, QA props, and thinking message data.\n */\nexport type ThinkingMessageProps = DOMProps &\n QAProps &\n ThinkingMessageContentData & {\n /**\n * How thinking content strings are rendered.\n * @default 'plain'\n */\n format?: 'plain' | 'markdown';\n /**\n * Options for @diplodoc/transform when `format` is `'markdown'`.\n * Shallow-merged with the component defaults (`disableCommonAnchors: true`).\n */\n transformOptions?: OptionsType;\n mermaidOptions?: MermaidOptions;\n openMarkdownLinksInNewTab?: boolean;\n mdxOptions?: MarkdownRendererMdxOptions;\n mdxContext?: Record<string, unknown>;\n /** Extra props forwarded to the root container `div` of each rendered markdown block. */\n markdownExtraProps?: HTMLAttributes<HTMLDivElement>;\n };\n\nconst defaultTransformOptions: OptionsType = {\n disableCommonAnchors: true,\n};\n\n/**\n * ThinkingMessage component displays AI model's internal reasoning process.\n * Shows a collapsible block with thinking content and a copy button.\n * Displays a loader when the thinking process is still in progress.\n *\n * @deprecated Use ThinkingMessageGroup. Planned for removal in the next major release.\n * @param props - Component props\n * @returns Rendered thinking message component\n */\nexport const ThinkingMessage = (props: ThinkingMessageProps) => {\n const {\n className,\n qa,\n style,\n format = 'plain',\n transformOptions,\n mermaidOptions,\n openMarkdownLinksInNewTab,\n mdxOptions,\n mdxContext,\n markdownExtraProps,\n ...data\n } = props;\n\n const markdownTransformOptions: OptionsType = {\n ...defaultTransformOptions,\n ...transformOptions,\n };\n\n const {\n isExpanded,\n toggleExpanded,\n buttonTitle,\n content,\n showLoader,\n handleCopy,\n showCopyButton,\n } = useThinkingMessage(data);\n\n return (\n <div className={b(null, className)} data-qa={qa} style={style}>\n <div className={b('buttons')}>\n <Button size=\"s\" onClick={toggleExpanded}>\n {buttonTitle}\n <Icon data={isExpanded ? ChevronUp : ChevronDown} />\n </Button>\n {showLoader ? (\n <Loader view=\"loading\" size=\"xs\" />\n ) : (\n showCopyButton && (\n <ActionButton size=\"s\" onClick={handleCopy}>\n <Icon data={Copy} size={16} />\n </ActionButton>\n )\n )}\n </div>\n {isExpanded && (\n <div className={b('container')}>\n {content.map((item, index) =>\n format === 'markdown' ? (\n <MarkdownRenderer\n className={b('content')}\n key={index}\n content={item}\n transformOptions={markdownTransformOptions}\n mermaidOptions={mermaidOptions}\n openLinksInNewTab={openMarkdownLinksInNewTab}\n mdxOptions={mdxOptions}\n mdxContext={mdxContext}\n extraProps={markdownExtraProps}\n />\n ) : (\n <Text className={b('content')} key={index}>\n {item}\n </Text>\n ),\n )}\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ThinkingMessageGroupProps, ThinkingStep } from "./types.js";
|
|
3
|
+
interface CompactHeadingProps extends Pick<ThinkingMessageGroupProps, 'stepTypes'> {
|
|
4
|
+
status: NonNullable<ThinkingMessageGroupProps['status']>;
|
|
5
|
+
activeStep?: ThinkingStep;
|
|
6
|
+
summary: ReactNode;
|
|
7
|
+
hasDetails: boolean;
|
|
8
|
+
isExpanded: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function CompactHeading({ activeStep, stepTypes, status, summary, hasDetails, isExpanded, }: CompactHeadingProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CompactHeading = CompactHeading;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const icons_1 = require("@gravity-ui/icons");
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
|
+
const cn_1 = require("../../../utils/cn.js");
|
|
8
|
+
const StepIcon_1 = require("./StepIcon.js");
|
|
9
|
+
const i18n_1 = require("./i18n/index.js");
|
|
10
|
+
const b = (0, cn_1.block)('thinking-message-group');
|
|
11
|
+
function CompactHeading({ activeStep, stepTypes, status, summary, hasDetails, isExpanded, }) {
|
|
12
|
+
var _a;
|
|
13
|
+
const isThinking = status === 'thinking';
|
|
14
|
+
const showActiveStep = Boolean(activeStep && isThinking);
|
|
15
|
+
const hasSummary = summary !== null && summary !== undefined && summary !== false && summary !== '';
|
|
16
|
+
const showCompletedSummary = status === 'thought' && hasSummary;
|
|
17
|
+
const label = (showActiveStep && (activeStep === null || activeStep === void 0 ? void 0 : activeStep.title)) || (0, i18n_1.i18n)(`status-${status}`);
|
|
18
|
+
const operationIcon = showActiveStep && activeStep ? (_a = stepTypes === null || stepTypes === void 0 ? void 0 : stepTypes[activeStep.type]) === null || _a === void 0 ? void 0 : _a.icon : null;
|
|
19
|
+
const showSecondarySummary = !showCompletedSummary && hasSummary;
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)("span", { className: b('compact-heading'), children: [(0, jsx_runtime_1.jsxs)("span", { className: b('compact-current'), children: [status !== 'thought' && ((0, jsx_runtime_1.jsx)("span", { className: b('step-icon', { error: status === 'error' }), "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)(StepIcon_1.StepIcon, { status: status, operationIcon: operationIcon }) })), (0, jsx_runtime_1.jsx)("span", { className: b('compact-label', {
|
|
21
|
+
active: isThinking && (activeStep === null || activeStep === void 0 ? void 0 : activeStep.status) === 'thinking',
|
|
22
|
+
error: status === 'error',
|
|
23
|
+
}), title: showCompletedSummary ? undefined : label, children: showCompletedSummary ? summary : label }), hasDetails && ((0, jsx_runtime_1.jsx)("span", { className: b('disclosure', { expanded: isExpanded }), "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.ChevronRight, size: 12 }) }))] }), showSecondarySummary && ((0, jsx_runtime_1.jsx)("span", { className: b('compact-summary', { indented: true }), children: summary }))] }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=CompactHeading.js.map
|