@gooddata/sdk-ui-gen-ai 11.45.0-alpha.0 → 11.45.0-alpha.2
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/NOTICE +3 -3
- package/esm/components/GenAIChatDialogConnected.d.ts +108 -0
- package/esm/components/GenAIChatDialogConnected.d.ts.map +1 -0
- package/esm/components/GenAIChatDialogConnected.js +117 -0
- package/esm/components/messages/ItemsGroup.d.ts +2 -0
- package/esm/components/messages/ItemsGroup.d.ts.map +1 -1
- package/esm/components/messages/ItemsGroup.js +33 -25
- package/esm/components/messages/conversationContents/ConversationAlertProposalContent.d.ts.map +1 -1
- package/esm/components/messages/conversationContents/ConversationAlertProposalContent.js +11 -9
- package/esm/components/utils/animation.d.ts +8 -0
- package/esm/components/utils/animation.d.ts.map +1 -0
- package/esm/components/utils/animation.js +78 -0
- package/esm/components/utils/markdownUtils.d.ts +1 -0
- package/esm/components/utils/markdownUtils.d.ts.map +1 -1
- package/esm/components/utils/markdownUtils.js +12 -0
- package/esm/internal.d.ts +1 -0
- package/esm/internal.d.ts.map +1 -1
- package/esm/internal.js +1 -0
- package/package.json +20 -20
- package/styles/css/animation.css +76 -0
- package/styles/css/animation.css.map +1 -0
- package/styles/css/main.css +85 -18
- package/styles/css/main.css.map +1 -1
- package/styles/css/messages.css +10 -18
- package/styles/css/messages.css.map +1 -1
- package/styles/scss/animation.scss +84 -0
- package/styles/scss/main.scss +1 -0
- package/styles/scss/messages.scss +11 -23
package/NOTICE
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
The following 3rd-party software packages may be used by or distributed with gooddata-ui-sdk. Any information relevant to third-party vendors listed below are collected using common, reasonable means.
|
|
9
9
|
|
|
10
|
-
Date generated: 2026-
|
|
10
|
+
Date generated: 2026-7-1
|
|
11
11
|
|
|
12
|
-
Revision ID:
|
|
12
|
+
Revision ID: 9473b8ff1342704ff1498f54591ef2ab4c6943f4
|
|
13
13
|
|
|
14
14
|
================================================================================
|
|
15
15
|
================================================================================
|
|
@@ -29272,4 +29272,4 @@ POSSIBILITY OF SUCH DAMAGE.
|
|
|
29272
29272
|
--------------------------------------------------------------------------------
|
|
29273
29273
|
--------------------------------------------------------------------------------
|
|
29274
29274
|
|
|
29275
|
-
Report Generated by FOSSA on 2026-
|
|
29275
|
+
Report Generated by FOSSA on 2026-7-1
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import { type IAnalyticalBackend, type IUserWorkspaceSettings } from "@gooddata/sdk-backend-spi";
|
|
3
|
+
import type { GenAIObjectType, IColorPalette, IGenAIUserContext } from "@gooddata/sdk-model";
|
|
4
|
+
import { type ChatAssistantMessageEvent, type ChatClosedEvent, type ChatCopyToClipboardEvent, type ChatEvent, type ChatFeedbackErrorEvent, type ChatFeedbackEvent, type ChatOpenedEvent, type ChatResetEvent, type ChatSaveVisualizationErrorEvent, type ChatSaveVisualizationSuccessEvent, type ChatUserMessageEvent } from "../store/events.js";
|
|
5
|
+
import { type LinkHandlerEvent } from "./ConfigContext.js";
|
|
6
|
+
/**
|
|
7
|
+
* Discriminated union of GenAI chat events surfaced to a caller via {@link IGenAIChatDialogConnectedProps.onEvent}.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Each consuming application maps these to its own telemetry sink and toast strings (the message ids differ
|
|
11
|
+
* per app — e.g. the host's `messages.genAi.*` vs KD's `gd.gen-ai.feedback.*`), so this connected wrapper
|
|
12
|
+
* deliberately does NOT render toasts itself; it only normalizes the raw chat events into this union.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export type GenAIChatConnectedEvent = {
|
|
17
|
+
name: "opened";
|
|
18
|
+
payload: ChatOpenedEvent;
|
|
19
|
+
} | {
|
|
20
|
+
name: "closed";
|
|
21
|
+
payload: ChatClosedEvent;
|
|
22
|
+
} | {
|
|
23
|
+
name: "reset";
|
|
24
|
+
payload: ChatResetEvent;
|
|
25
|
+
} | {
|
|
26
|
+
name: "user-message";
|
|
27
|
+
payload: ChatUserMessageEvent;
|
|
28
|
+
} | {
|
|
29
|
+
name: "assistant-message";
|
|
30
|
+
payload: ChatAssistantMessageEvent;
|
|
31
|
+
} | {
|
|
32
|
+
name: "feedback";
|
|
33
|
+
payload: ChatFeedbackEvent;
|
|
34
|
+
} | {
|
|
35
|
+
name: "feedback-error";
|
|
36
|
+
payload: ChatFeedbackErrorEvent;
|
|
37
|
+
} | {
|
|
38
|
+
name: "save-visualization-success";
|
|
39
|
+
payload: ChatSaveVisualizationSuccessEvent;
|
|
40
|
+
} | {
|
|
41
|
+
name: "save-visualization-error";
|
|
42
|
+
payload: ChatSaveVisualizationErrorEvent;
|
|
43
|
+
} | {
|
|
44
|
+
name: "copy-to-clipboard";
|
|
45
|
+
payload: ChatCopyToClipboardEvent;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Props for {@link GenAIChatDialogConnected}.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
export interface IGenAIChatDialogConnectedProps {
|
|
53
|
+
/** Backend; defaults to the ambient `BackendProvider` when omitted. */
|
|
54
|
+
backend?: IAnalyticalBackend;
|
|
55
|
+
/** Workspace; defaults to the ambient `WorkspaceProvider` when omitted. */
|
|
56
|
+
workspace?: string;
|
|
57
|
+
locale?: string;
|
|
58
|
+
canManage?: boolean;
|
|
59
|
+
canAnalyze?: boolean;
|
|
60
|
+
canFullControl?: boolean;
|
|
61
|
+
settings?: IUserWorkspaceSettings;
|
|
62
|
+
/** Open-state is fully controlled by the caller (props, not redux). */
|
|
63
|
+
isOpen: boolean;
|
|
64
|
+
onOpen: () => void;
|
|
65
|
+
onClose: () => void;
|
|
66
|
+
/** A question to seed into the chat when it opens. */
|
|
67
|
+
askedQuestion?: string | null;
|
|
68
|
+
/**
|
|
69
|
+
* Monotonic counter bumped on every ask. Keying the seeding effect on it re-seeds the chat
|
|
70
|
+
* (clear thread + send message) even when `askedQuestion` is identical to the previous ask.
|
|
71
|
+
*/
|
|
72
|
+
askSeq?: number;
|
|
73
|
+
/** Context of the user's location when the question was asked, sent alongside the seeded question. */
|
|
74
|
+
userContext?: IGenAIUserContext;
|
|
75
|
+
/** When true, the seeded question is appended to the existing thread instead of clearing it first. */
|
|
76
|
+
appendToChat?: boolean;
|
|
77
|
+
/** Object-search tag scope reflecting the caller's current view. */
|
|
78
|
+
includeTags?: string[];
|
|
79
|
+
excludeTags?: string[];
|
|
80
|
+
/** Override the derived object types (default: dashboard, visualization, + metric when `canManage`). */
|
|
81
|
+
objectTypes?: GenAIObjectType[];
|
|
82
|
+
/** Normalized chat events for telemetry/toasts; mapped per-consumer. */
|
|
83
|
+
onEvent?: (event: GenAIChatConnectedEvent) => void;
|
|
84
|
+
/** Escape hatch firing for every raw chat event (e.g. a catch-all telemetry sink). */
|
|
85
|
+
onAnyEvent?: (event: ChatEvent) => void;
|
|
86
|
+
dialogPosition?: "left" | "right";
|
|
87
|
+
className?: string;
|
|
88
|
+
colorPalette?: IColorPalette;
|
|
89
|
+
/** Defaults to `true`; embedded callers pass `false` to intercept link clicks. */
|
|
90
|
+
allowNativeLinks?: boolean;
|
|
91
|
+
/** Override the default open-in-tab / same-tab navigation link handling. */
|
|
92
|
+
onLinkClick?: (linkClickEvent: LinkHandlerEvent) => string | undefined;
|
|
93
|
+
/** Element (or id) focus returns to on close. */
|
|
94
|
+
returnFocusTo?: RefObject<HTMLElement | null> | string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A "connected" wrapper over {@link GenAIChatDialog} that centralizes the wiring every consumer otherwise
|
|
98
|
+
* duplicates: object-type derivation, the dispatcher-based seeding flow (clear thread / set user context /
|
|
99
|
+
* agentic-vs-classic message keyed on `enableAiAgenticConversations`), default link handling, and normalizing
|
|
100
|
+
* raw chat events into the {@link GenAIChatConnectedEvent} union.
|
|
101
|
+
*
|
|
102
|
+
* Consumers supply their own data sources (backend/workspace/permissions), open-state, telemetry sink and
|
|
103
|
+
* toast strings — keeping per-app i18n out of this shared component.
|
|
104
|
+
*
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export declare function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, appendToChat, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks, onLinkClick, returnFocusTo }: IGenAIChatDialogConnectedProps): import("react/jsx-runtime").JSX.Element;
|
|
108
|
+
//# sourceMappingURL=GenAIChatDialogConnected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GenAIChatDialogConnected.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialogConnected.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { makeTextContents, makeUserItem, makeUserMessage } from "../model.js";
|
|
5
|
+
import { setUserContextAction } from "../store/chatWindow/chatWindowSlice.js";
|
|
6
|
+
import { isChatAssistantMessageEvent, isChatClosedEvent, isChatCopyToClipboardEvent, isChatFeedbackErrorEvent, isChatFeedbackEvent, isChatOpenedEvent, isChatResetEvent, isChatSaveVisualizationErrorEvent, isChatSaveVisualizationSuccessEvent, isChatUserMessageEvent, } from "../store/events.js";
|
|
7
|
+
import { clearThreadAction, newMessageAction } from "../store/messages/messagesSlice.js";
|
|
8
|
+
import { GenAIChatDialog } from "./GenAIChatDialog.js";
|
|
9
|
+
/**
|
|
10
|
+
* A "connected" wrapper over {@link GenAIChatDialog} that centralizes the wiring every consumer otherwise
|
|
11
|
+
* duplicates: object-type derivation, the dispatcher-based seeding flow (clear thread / set user context /
|
|
12
|
+
* agentic-vs-classic message keyed on `enableAiAgenticConversations`), default link handling, and normalizing
|
|
13
|
+
* raw chat events into the {@link GenAIChatConnectedEvent} union.
|
|
14
|
+
*
|
|
15
|
+
* Consumers supply their own data sources (backend/workspace/permissions), open-state, telemetry sink and
|
|
16
|
+
* toast strings — keeping per-app i18n out of this shared component.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export function GenAIChatDialogConnected({ backend, workspace, locale, canManage, canAnalyze, canFullControl, settings, isOpen, onOpen, onClose, askedQuestion, askSeq, userContext, appendToChat, includeTags, excludeTags, objectTypes: objectTypesOverride, onEvent, onAnyEvent, dialogPosition, className, colorPalette, allowNativeLinks = true, onLinkClick, returnFocusTo, }) {
|
|
21
|
+
const defaultLinkClick = useCallback(({ itemUrl, newTab, preventDefault }) => {
|
|
22
|
+
if (itemUrl) {
|
|
23
|
+
preventDefault();
|
|
24
|
+
if (newTab) {
|
|
25
|
+
window.open(itemUrl, "_blank");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
window.location.assign(itemUrl);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return itemUrl;
|
|
32
|
+
}, []);
|
|
33
|
+
const eventHandlers = useMemo(() => [
|
|
34
|
+
{
|
|
35
|
+
// Single catch-all that both fans out to `onEvent` (named) and `onAnyEvent` (raw).
|
|
36
|
+
eval: (_e) => true,
|
|
37
|
+
handler: (event) => {
|
|
38
|
+
onAnyEvent?.(event);
|
|
39
|
+
if (!onEvent) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (isChatOpenedEvent(event)) {
|
|
43
|
+
onEvent({ name: "opened", payload: event });
|
|
44
|
+
}
|
|
45
|
+
else if (isChatClosedEvent(event)) {
|
|
46
|
+
onEvent({ name: "closed", payload: event });
|
|
47
|
+
}
|
|
48
|
+
else if (isChatResetEvent(event)) {
|
|
49
|
+
onEvent({ name: "reset", payload: event });
|
|
50
|
+
}
|
|
51
|
+
else if (isChatUserMessageEvent(event)) {
|
|
52
|
+
onEvent({ name: "user-message", payload: event });
|
|
53
|
+
}
|
|
54
|
+
else if (isChatAssistantMessageEvent(event)) {
|
|
55
|
+
onEvent({ name: "assistant-message", payload: event });
|
|
56
|
+
}
|
|
57
|
+
else if (isChatFeedbackEvent(event)) {
|
|
58
|
+
onEvent({ name: "feedback", payload: event });
|
|
59
|
+
}
|
|
60
|
+
else if (isChatFeedbackErrorEvent(event)) {
|
|
61
|
+
onEvent({ name: "feedback-error", payload: event });
|
|
62
|
+
}
|
|
63
|
+
else if (isChatSaveVisualizationSuccessEvent(event)) {
|
|
64
|
+
onEvent({ name: "save-visualization-success", payload: event });
|
|
65
|
+
}
|
|
66
|
+
else if (isChatSaveVisualizationErrorEvent(event)) {
|
|
67
|
+
onEvent({ name: "save-visualization-error", payload: event });
|
|
68
|
+
}
|
|
69
|
+
else if (isChatCopyToClipboardEvent(event)) {
|
|
70
|
+
onEvent({ name: "copy-to-clipboard", payload: event });
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
], [onEvent, onAnyEvent]);
|
|
75
|
+
const objectTypes = useMemo(() => {
|
|
76
|
+
if (objectTypesOverride) {
|
|
77
|
+
return objectTypesOverride;
|
|
78
|
+
}
|
|
79
|
+
const types = ["dashboard", "visualization"];
|
|
80
|
+
if (canManage) {
|
|
81
|
+
types.push("metric");
|
|
82
|
+
}
|
|
83
|
+
return types;
|
|
84
|
+
}, [objectTypesOverride, canManage]);
|
|
85
|
+
const [chatDispatcher, setDispatcher] = useState(null);
|
|
86
|
+
const onDispatcher = useCallback((dispatcher) => {
|
|
87
|
+
setDispatcher(() => dispatcher);
|
|
88
|
+
}, []);
|
|
89
|
+
// The token of the last seed we applied. Each ask is identified by `askSeq` (bumped on every ask,
|
|
90
|
+
// so even a repeated identical question re-seeds); we seed once per token. Without this guard the
|
|
91
|
+
// effect would replay the question whenever `settings`/`userContext` merely change object identity.
|
|
92
|
+
const lastSeedTokenRef = useRef(null);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
// Only seed while the chat is open, and only once per ask (LX-2544).
|
|
95
|
+
if (!isOpen || !chatDispatcher || !askedQuestion || !settings) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const seedToken = askSeq ?? askedQuestion;
|
|
99
|
+
if (lastSeedTokenRef.current === seedToken) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
lastSeedTokenRef.current = seedToken;
|
|
103
|
+
if (!appendToChat) {
|
|
104
|
+
chatDispatcher(clearThreadAction());
|
|
105
|
+
}
|
|
106
|
+
// Always set (and thereby clear when undefined) so a follow-up ask without context does not
|
|
107
|
+
// inherit the previous ask's user context (LX-2544).
|
|
108
|
+
chatDispatcher(setUserContextAction({ userContext }));
|
|
109
|
+
if (settings.enableAiAgenticConversations) {
|
|
110
|
+
chatDispatcher(newMessageAction(makeUserItem({ type: "text", text: askedQuestion })));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
chatDispatcher(newMessageAction(makeUserMessage([makeTextContents(askedQuestion, [])])));
|
|
114
|
+
}
|
|
115
|
+
}, [isOpen, chatDispatcher, askedQuestion, askSeq, userContext, appendToChat, settings]);
|
|
116
|
+
return (_jsx(GenAIChatDialog, { isOpen: isOpen, locale: locale, backend: backend, workspace: workspace, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, settings: settings, objectTypes: objectTypes, includeTags: includeTags, excludeTags: excludeTags, className: className, dialogPosition: dialogPosition, colorPalette: colorPalette, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick ?? defaultLinkClick, onOpen: onOpen, onClose: onClose, eventHandlers: eventHandlers, onDispatcher: onDispatcher, returnFocusTo: returnFocusTo }));
|
|
117
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import { type IntlShape } from "react-intl";
|
|
2
3
|
import { type IChatMessagesGroup } from "../utils/groupUtility.js";
|
|
3
4
|
interface IItemsGroupProps {
|
|
4
5
|
previousGroup?: IChatMessagesGroup;
|
|
@@ -6,5 +7,6 @@ interface IItemsGroupProps {
|
|
|
6
7
|
children: ReactNode;
|
|
7
8
|
}
|
|
8
9
|
export declare function ItemsGroup({ group, previousGroup, children }: IItemsGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function formatDuration(intl: IntlShape, ms: number): string;
|
|
9
11
|
export {};
|
|
10
12
|
//# sourceMappingURL=ItemsGroup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemsGroup.d.ts","sourceRoot":"","sources":["../../../src/components/messages/ItemsGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ItemsGroup.d.ts","sourceRoot":"","sources":["../../../src/components/messages/ItemsGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAG1D,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,YAAY,CAAC;AAKrE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,UAAU,gBAAgB;IACtB,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAsB9E;AA4ID,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAqBlE"}
|
|
@@ -3,8 +3,9 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
4
|
import cx from "classnames";
|
|
5
5
|
import { defineMessages, useIntl } from "react-intl";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { UiButton } from "@gooddata/sdk-ui-kit";
|
|
7
|
+
import { AIThinkingLoader, AIThinkingSummary } from "../utils/animation.js";
|
|
8
|
+
import { extractHeading } from "../utils/markdownUtils.js";
|
|
8
9
|
export function ItemsGroup({ group, previousGroup, children }) {
|
|
9
10
|
const classNames = cx("gd-gen-ai-chat__messages__conversation-group", {
|
|
10
11
|
[`gd-gen-ai-chat__messages__conversation-group--${group.type}`]: true,
|
|
@@ -18,7 +19,11 @@ export function ItemsGroup({ group, previousGroup, children }) {
|
|
|
18
19
|
return (_jsx(DefaultItemsGroup, { classNames: classNames, previousGroup: previousGroup, group: group, children: children }));
|
|
19
20
|
}
|
|
20
21
|
function ReasoningItemsGroup({ classNames, group, previousGroup, children }) {
|
|
21
|
-
const
|
|
22
|
+
const intl = useIntl();
|
|
23
|
+
const { headings, isExpanded, setIsExpanded, isCompleted, isEmpty, duration } = useReasoningGroup(previousGroup, group);
|
|
24
|
+
if (isCompleted && isEmpty) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
22
27
|
return (_jsxs("div", { className: cx(classNames, {
|
|
23
28
|
"gd-gen-ai-chat__messages__conversation-group--completed": isCompleted,
|
|
24
29
|
"gd-gen-ai-chat__messages__conversation-group--expanded": isExpanded,
|
|
@@ -26,7 +31,9 @@ function ReasoningItemsGroup({ classNames, group, previousGroup, children }) {
|
|
|
26
31
|
_jsxs("div", { className: cx("gd-gen-ai-chat__messages__conversation-group--header", {
|
|
27
32
|
"gd-gen-ai-chat__messages__conversation-group--header--completed": isCompleted,
|
|
28
33
|
}), children: [
|
|
29
|
-
_jsx("span", { className: "gd-gen-ai-chat__visually__hidden", "aria-live": "polite", "aria-atomic": "true", children:
|
|
34
|
+
_jsx("span", { className: "gd-gen-ai-chat__visually__hidden", "aria-live": "polite", "aria-atomic": "true", children: headings[headings.length - 1] }), isCompleted ? (_jsx(UiButton, { label: intl.formatMessage({ id: "gd.gen-ai.routing.thinking-process" }), dataTestId: "reasoning", onClick: () => setIsExpanded(!isExpanded), accessibilityConfig: { ariaExpanded: isExpanded }, iconBefore: isExpanded ? "navigateDown" : "navigateRight", iconBeforeSize: 12, variant: "tertiary" })) : (_jsxs("div", { className: "gd-gen-ai-chat__messages__conversation-group--header--thinking", "data-testid": "reasoning", children: [
|
|
35
|
+
_jsx(AIThinkingLoader, { size: 30 }), _jsx(AIThinkingSummary, { headings: headings })
|
|
36
|
+
] })), isCompleted && duration ? (_jsx("div", { className: "gd-gen-ai-chat__messages__conversation-group--header--duration", children: duration })) : null] }), isExpanded ? (_jsx("div", { className: "gd-gen-ai-chat__messages__conversation-group--content", "data-testid": "gen-ai-reasoning-group-content", children: children })) : null] }));
|
|
30
37
|
}
|
|
31
38
|
function useReasoningGroup(previousGroup, group) {
|
|
32
39
|
const intl = useIntl();
|
|
@@ -46,30 +53,25 @@ function useReasoningGroup(previousGroup, group) {
|
|
|
46
53
|
return false;
|
|
47
54
|
}));
|
|
48
55
|
}, [group.messages]);
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
const headings = useMemo(() => {
|
|
57
|
+
const headings = [intl.formatMessage({ id: "gd.gen-ai.state.thinking" })];
|
|
58
|
+
group.messages.forEach((m) => {
|
|
52
59
|
switch (m.content.type) {
|
|
53
|
-
case "reasoning":
|
|
54
|
-
last = m.content.summary
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
case "reasoning": {
|
|
61
|
+
const last = m.content.summary ? extractHeading(m.content.summary) : undefined;
|
|
62
|
+
if (last && headings[headings.length - 1] !== last) {
|
|
63
|
+
headings.push(last);
|
|
64
|
+
}
|
|
57
65
|
break;
|
|
66
|
+
}
|
|
58
67
|
case "toolCall":
|
|
59
68
|
case "toolResult":
|
|
60
69
|
default:
|
|
61
70
|
break;
|
|
62
71
|
}
|
|
63
|
-
return last;
|
|
64
72
|
});
|
|
73
|
+
return headings;
|
|
65
74
|
}, [group.messages, intl]);
|
|
66
|
-
const lastMessage = useMemo(() => {
|
|
67
|
-
if (isCompleted) {
|
|
68
|
-
return intl.formatMessage({ id: "gd.gen-ai.routing.thinking-process" });
|
|
69
|
-
}
|
|
70
|
-
const lastMessageContent = messages[messages.length - 1];
|
|
71
|
-
return `${lastMessageContent || intl.formatMessage({ id: "gd.gen-ai.state.thinking" })}...`;
|
|
72
|
-
}, [intl, isCompleted, messages]);
|
|
73
75
|
const duration = useMemo(() => {
|
|
74
76
|
if (!previousGroup) {
|
|
75
77
|
return undefined;
|
|
@@ -83,8 +85,8 @@ function useReasoningGroup(previousGroup, group) {
|
|
|
83
85
|
return formatDuration(intl, duration);
|
|
84
86
|
}, [group.messages, intl, previousGroup]);
|
|
85
87
|
return {
|
|
88
|
+
headings,
|
|
86
89
|
duration,
|
|
87
|
-
lastMessage,
|
|
88
90
|
isEmpty,
|
|
89
91
|
isCompleted,
|
|
90
92
|
isExpanded,
|
|
@@ -92,17 +94,23 @@ function useReasoningGroup(previousGroup, group) {
|
|
|
92
94
|
};
|
|
93
95
|
}
|
|
94
96
|
//duration
|
|
95
|
-
function formatDuration(intl, ms) {
|
|
97
|
+
export function formatDuration(intl, ms) {
|
|
96
98
|
const messages = defineMessages({
|
|
97
99
|
seconds: { id: "gd.gen-ai.state.seconds" },
|
|
98
100
|
minutes: { id: "gd.gen-ai.state.minutes" },
|
|
99
101
|
});
|
|
100
102
|
const seconds = Math.round((ms / 1000) * 100) / 100;
|
|
101
|
-
if (seconds < 60) {
|
|
102
|
-
return `${seconds}${intl.formatMessage(messages.seconds)}`;
|
|
103
|
-
}
|
|
104
103
|
const minutes = Math.floor(seconds / 60);
|
|
105
|
-
const remainingSeconds = Math.round(
|
|
104
|
+
const remainingSeconds = Math.round(seconds % 60);
|
|
105
|
+
if (remainingSeconds === 60) {
|
|
106
|
+
return `${minutes + 1}${intl.formatMessage(messages.minutes)}`;
|
|
107
|
+
}
|
|
108
|
+
if (minutes === 0) {
|
|
109
|
+
return `${Math.max(remainingSeconds, 1)}${intl.formatMessage(messages.seconds)}`;
|
|
110
|
+
}
|
|
111
|
+
if (remainingSeconds === 0) {
|
|
112
|
+
return `${minutes}${intl.formatMessage(messages.minutes)}`;
|
|
113
|
+
}
|
|
106
114
|
return `${minutes}${intl.formatMessage(messages.minutes)} ${remainingSeconds}${intl.formatMessage(messages.seconds)}`;
|
|
107
115
|
}
|
|
108
116
|
function DefaultItemsGroup({ classNames, children }) {
|
package/esm/components/messages/conversationContents/ConversationAlertProposalContent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationAlertProposalContent.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/conversationContents/ConversationAlertProposalContent.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAWhE,OAAO,KAAK,EACR,0BAA0B,EAC1B,mCAAmC,EACnC,iBAAiB,EACpB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,MAAM,qCAAqC,GAAG;IAChD,OAAO,EAAE,0BAA0B,CAAC;IACpC,IAAI,EAAE,mCAAmC,CAAC;IAC1C,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,aAAa,EAAE,cAAc,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,qCAAqC,
|
|
1
|
+
{"version":3,"file":"ConversationAlertProposalContent.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/conversationContents/ConversationAlertProposalContent.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAWhE,OAAO,KAAK,EACR,0BAA0B,EAC1B,mCAAmC,EACnC,iBAAiB,EACpB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,MAAM,qCAAqC,GAAG;IAChD,OAAO,EAAE,0BAA0B,CAAC;IACpC,IAAI,EAAE,mCAAmC,CAAC;IAC1C,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,aAAa,EAAE,cAAc,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,qCAAqC,kDAmD5F"}
|
|
@@ -10,18 +10,20 @@ export function ConversationAlertProposalContent(props) {
|
|
|
10
10
|
const { objects, alertProposal, className } = props;
|
|
11
11
|
const intl = useIntl();
|
|
12
12
|
const classNames = cx("gd-gen-ai-chat__conversation__item__content", "gd-gen-ai-chat__conversation__item__content--alertProposal", className);
|
|
13
|
+
const classNamesCta = cx("gd-gen-ai-chat__conversation__item__content", className);
|
|
13
14
|
if (!alertProposal) {
|
|
14
15
|
return null;
|
|
15
16
|
}
|
|
16
|
-
return (_jsxs(
|
|
17
|
-
_jsxs("div", { className:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
return (_jsxs(_Fragment, { children: [
|
|
18
|
+
_jsxs("div", { className: classNames, children: [
|
|
19
|
+
_jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-alertProposal-header", children: [
|
|
20
|
+
_jsx(UiIcon, { type: "alert", size: 14, color: "complementary-6", backgroundSize: 26, backgroundColor: "complementary-2" }), _jsx(FormattedMessage, { id: "gd.gen-ai.alert-proposal.title" })
|
|
21
|
+
] }), _jsxs("div", { className: "gd-gen-ai-chat__conversation__item__content-alertProposal-frame", children: [
|
|
22
|
+
_jsxs("ul", { children: [
|
|
23
|
+
_jsx(AlertItem, { markdown: true, title: intl.formatMessage({ id: "gd.gen-ai.alert-proposal.summary.title" }), description: alertProposal.title, objects: objects }), _jsx(FiltersPreview, { ...props }), _jsx(NotificationChannelPreview, { ...props }), _jsx(DashboardPreview, { ...props })
|
|
24
|
+
] }), _jsx(AlertAttributes, { attributes: alertProposal.alert?.execution.attributes, objects: objects }), _jsx(ConditionsPreview, { ...props }), _jsx(TriggerPreview, { ...props }), _jsx(RecipientsPreview, { ...props })
|
|
25
|
+
] })
|
|
26
|
+
] }), alertProposal.cta ? _jsx("div", { className: classNamesCta, children: alertProposal.cta }) : null] }));
|
|
25
27
|
}
|
|
26
28
|
function FiltersPreview({ alertProposal, objects }) {
|
|
27
29
|
const intl = useIntl();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function AIThinkingLoader({ size, color }: {
|
|
2
|
+
color?: string | undefined;
|
|
3
|
+
size?: number | undefined;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function AIThinkingSummary({ headings }: {
|
|
6
|
+
headings: string[];
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=animation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../../src/components/utils/animation.tsx"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,EAAE,IAAU,EAAE,KAAiB,EAAE;;;CAAA,2CA2HjE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,2CAoCrE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import cx from "classnames";
|
|
5
|
+
export function AIThinkingLoader({ size = 200, color = "#14B2E2" }) {
|
|
6
|
+
const urRef = useRef(null);
|
|
7
|
+
const llRef = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
let running = true;
|
|
10
|
+
let timer = -1;
|
|
11
|
+
let sparkIndex = 0;
|
|
12
|
+
const rand = (min, max) => min + Math.random() * (max - min);
|
|
13
|
+
const blink = (el) => {
|
|
14
|
+
if (!el) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const rot = rand(-10, 10);
|
|
18
|
+
el.animate([
|
|
19
|
+
{
|
|
20
|
+
transform: "translate(-50%, -50%) scale(1) rotate(0deg)",
|
|
21
|
+
easing: "cubic-bezier(0.4, 0, 0.7, 1)",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
transform: `translate(-50%, -50%) scale(0) rotate(${rot}deg)`,
|
|
25
|
+
offset: 0.5,
|
|
26
|
+
easing: "cubic-bezier(0.2, 0.8, 0.2, 1)",
|
|
27
|
+
},
|
|
28
|
+
{ transform: "translate(-50%, -50%) scale(1) rotate(0deg)" },
|
|
29
|
+
], { duration: rand(260, 440) });
|
|
30
|
+
};
|
|
31
|
+
const loop = () => {
|
|
32
|
+
if (!running) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (Math.random() < 0.8) {
|
|
36
|
+
sparkIndex = 1 - sparkIndex;
|
|
37
|
+
}
|
|
38
|
+
blink(sparkIndex === 0 ? urRef.current : llRef.current);
|
|
39
|
+
timer = window.setTimeout(loop, rand(280, 1100));
|
|
40
|
+
};
|
|
41
|
+
loop();
|
|
42
|
+
return () => {
|
|
43
|
+
running = false;
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
};
|
|
46
|
+
}, []);
|
|
47
|
+
const s = size / 200;
|
|
48
|
+
return (_jsxs("div", { className: "gd-gen-ai-chat__animations--loader", style: { width: size, height: size, perspective: 700 * s }, children: [
|
|
49
|
+
_jsx("div", { className: "gd-gen-ai-chat__animations--loader--inner", style: {
|
|
50
|
+
width: 120 * s,
|
|
51
|
+
height: 120 * s,
|
|
52
|
+
}, children: _jsx("div", { className: "gd-gen-ai-chat__animations--loader--flip", style: {
|
|
53
|
+
width: 120 * s,
|
|
54
|
+
height: 120 * s,
|
|
55
|
+
}, children: _jsx("svg", { width: 120 * s, height: 120 * s, viewBox: "0 0 24 24", fill: "none", className: "gd-gen-ai-chat__animations--loader--svg", children: _jsx("path", { d: "M11.4 20.9999C11.4 18.8549 10.8654 17.286 10.0945 16.1296C9.32103 14.9694 8.28542 14.1885 7.2316 13.6616C6.17551 13.1336 5.1122 12.8664 4.30777 12.7323C3.9073 12.6656 3.57461 12.6328 3.34449 12.6163C3.22952 12.6081 3.13966 12.6042 3.08082 12.6022C3.0517 12.6013 3.03005 12.6001 3.01636 12.5999H2.99996C2.66858 12.5999 2.39996 12.3313 2.39996 11.9999C2.39996 11.6685 2.66859 11.3999 2.99996 11.3999H3.01636C3.03005 11.3997 3.0517 11.3985 3.08082 11.3976C3.13966 11.3956 3.22952 11.3917 3.34449 11.3835C3.57461 11.367 3.9073 11.3342 4.30777 11.2675C5.1122 11.1334 6.17551 10.8662 7.2316 10.3382C8.28541 9.81127 9.32103 9.0304 10.0945 7.87021C10.8654 6.71379 11.4 5.14491 11.4 2.9999C11.4 2.66853 11.6686 2.3999 12 2.3999C12.3313 2.39991 12.6 2.66853 12.6 2.9999C12.6 5.14491 13.1345 6.71379 13.9054 7.87021C14.6789 9.0304 15.7145 9.81127 16.7683 10.3382C17.8244 10.8662 18.8877 11.1334 19.6921 11.2675C20.0926 11.3342 20.4253 11.367 20.6554 11.3835C20.7704 11.3917 20.8603 11.3956 20.9191 11.3976C20.9482 11.3985 20.9699 11.3997 20.9835 11.3999H21L21.1207 11.4116C21.3942 11.4675 21.5999 11.7099 21.6 11.9999C21.6 12.29 21.3942 12.5323 21.1207 12.5882L21 12.5999H20.9835C20.9699 12.6001 20.9482 12.6013 20.9191 12.6022C20.8603 12.6042 20.7704 12.6081 20.6554 12.6163C20.4253 12.6328 20.0926 12.6656 19.6921 12.7323C18.8877 12.8664 17.8244 13.1336 16.7683 13.6616C15.7145 14.1885 14.6789 14.9694 13.9054 16.1296C13.1826 17.2138 12.6673 18.6607 12.6058 20.605L12.6 20.9999L12.5882 21.1206C12.5324 21.3942 12.29 21.5999 12 21.5999C11.6686 21.5999 11.4 21.3313 11.4 20.9999Z", fill: color }) }) }) }), _jsx("svg", { ref: urRef, width: 30 * s, height: 30 * s, viewBox: "16.5 2.1 5.3 5.3", fill: "none", className: "gd-gen-ai-chat__animations--loader--sparkle", style: {
|
|
56
|
+
left: 135.85 * s,
|
|
57
|
+
top: 64 * s,
|
|
58
|
+
}, children: _jsx("path", { d: "M18.9645 2.59958C19.0084 2.33334 19.3912 2.33334 19.4351 2.59958C19.6011 3.60808 20.3916 4.39853 21.4002 4.56465C21.6663 4.60849 21.6663 4.9913 21.4002 5.03516C20.3916 5.20128 19.6011 5.99171 19.4351 7.00022C19.3912 7.26646 19.0084 7.26646 18.9645 7.00022C18.7984 5.99171 18.0079 5.20128 16.9994 5.03516C16.7333 4.9913 16.7333 4.60849 16.9994 4.56465C18.0079 4.39853 18.7984 3.60808 18.9645 2.59958Z", fill: color }) }), _jsx("svg", { ref: llRef, width: 30 * s, height: 30 * s, viewBox: "2.1 16.5 5.3 5.3", fill: "none", className: "gd-gen-ai-chat__animations--loader--sparkle", style: {
|
|
59
|
+
left: 64 * s,
|
|
60
|
+
top: 135.85 * s,
|
|
61
|
+
}, children: _jsx("path", { d: "M4.56465 16.9994C4.60849 16.7333 4.9913 16.7333 5.03516 16.9994C5.20128 18.0079 5.99171 18.7984 7.00022 18.9645C7.26646 19.0083 7.26646 19.3912 7.00022 19.4351C5.99171 19.6011 5.20128 20.3916 5.03516 21.4002C4.9913 21.6663 4.60849 21.6663 4.56465 21.4002C4.39853 20.3916 3.60808 19.6011 2.59958 19.4351C2.33334 19.3912 2.33334 19.0083 2.59958 18.9645C3.60808 18.7984 4.39853 18.0079 4.56465 16.9994Z", fill: color }) })
|
|
62
|
+
] }));
|
|
63
|
+
}
|
|
64
|
+
export function AIThinkingSummary({ headings }) {
|
|
65
|
+
const [currentHeading, setCurrentHeading] = useState(headings[headings.length - 1]);
|
|
66
|
+
const [previousHeading, setPreviousHeading] = useState(undefined);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const lastHeading = headings[headings.length - 1];
|
|
69
|
+
if (lastHeading !== currentHeading) {
|
|
70
|
+
setPreviousHeading(currentHeading);
|
|
71
|
+
setCurrentHeading(lastHeading);
|
|
72
|
+
}
|
|
73
|
+
}, [headings, currentHeading]);
|
|
74
|
+
return (_jsxs("div", { className: "gd-gen-ai-chat__animations--headings", children: [previousHeading ? (_jsxs("div", { className: cx("gd-gen-ai-chat__animations--headings--heading", "gd-gen-ai-chat__animations--headings--heading--old"), onAnimationEnd: () => setPreviousHeading(undefined), children: [previousHeading, "..."] }, `${previousHeading}-old`)) : null, _jsxs("div", { className: cx("gd-gen-ai-chat__animations--headings--heading", {
|
|
75
|
+
"gd-gen-ai-chat__animations--headings--heading--new": !!previousHeading,
|
|
76
|
+
}), children: [currentHeading, "..."] }, `${currentHeading}-new`)
|
|
77
|
+
] }));
|
|
78
|
+
}
|
|
@@ -3,4 +3,5 @@ export declare function escapeMarkdown(text: string): string;
|
|
|
3
3
|
* Removes all markdown marks and replaces newlines with space.
|
|
4
4
|
*/
|
|
5
5
|
export declare function removeMarkdown(text: string): string;
|
|
6
|
+
export declare function extractHeading(text: string): string | null;
|
|
6
7
|
//# sourceMappingURL=markdownUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdownUtils.d.ts","sourceRoot":"","sources":["../../../src/components/utils/markdownUtils.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD"}
|
|
1
|
+
{"version":3,"file":"markdownUtils.d.ts","sourceRoot":"","sources":["../../../src/components/utils/markdownUtils.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,iBAa1C"}
|
|
@@ -20,3 +20,15 @@ export function removeMarkdown(text) {
|
|
|
20
20
|
.replace(/ {2,}/g, " ") // remove double spaces
|
|
21
21
|
.trim();
|
|
22
22
|
}
|
|
23
|
+
export function extractHeading(text) {
|
|
24
|
+
const headingMatch = text.match(/^(#+)\s+(.*)$/m);
|
|
25
|
+
if (headingMatch) {
|
|
26
|
+
return removeMarkdown(headingMatch[2]);
|
|
27
|
+
}
|
|
28
|
+
const lines = text.split("\n");
|
|
29
|
+
const firstLine = lines.find((line) => line.trim().length > 0);
|
|
30
|
+
if (firstLine) {
|
|
31
|
+
return removeMarkdown(firstLine);
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
package/esm/internal.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ import { setUserContextAction } from "./store/chatWindow/chatWindowSlice.js";
|
|
|
3
3
|
import { clearThreadAction, newMessageAction } from "./store/messages/messagesSlice.js";
|
|
4
4
|
export { ChatSkeleton } from "./components/ChatSkeleton.js";
|
|
5
5
|
export { GenAIChatDialog, type GenAIChatDialogProps } from "./components/GenAIChatDialog.js";
|
|
6
|
+
export { GenAIChatDialogConnected, type IGenAIChatDialogConnectedProps, type GenAIChatConnectedEvent, } from "./components/GenAIChatDialogConnected.js";
|
|
6
7
|
export { clearThreadAction, newMessageAction, makeUserMessage, makeTextContents, setUserContextAction };
|
|
7
8
|
//# sourceMappingURL=internal.d.ts.map
|
package/esm/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,wBAAwB,EACxB,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,GAC/B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC"}
|
package/esm/internal.js
CHANGED
|
@@ -5,4 +5,5 @@ import { setUserContextAction } from "./store/chatWindow/chatWindowSlice.js";
|
|
|
5
5
|
import { clearThreadAction, newMessageAction } from "./store/messages/messagesSlice.js";
|
|
6
6
|
export { ChatSkeleton } from "./components/ChatSkeleton.js";
|
|
7
7
|
export { GenAIChatDialog } from "./components/GenAIChatDialog.js";
|
|
8
|
+
export { GenAIChatDialogConnected, } from "./components/GenAIChatDialogConnected.js";
|
|
8
9
|
export { clearThreadAction, newMessageAction, makeUserMessage, makeTextContents, setUserContextAction };
|