@gooddata/sdk-ui-gen-ai 11.54.0-alpha.0 → 11.54.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.
Files changed (46) hide show
  1. package/esm/components/GenAIChat.d.ts +7 -0
  2. package/esm/components/GenAIChat.d.ts.map +1 -1
  3. package/esm/components/GenAIChat.js +3 -1
  4. package/esm/components/GenAIChatContextIndicator.js +2 -2
  5. package/esm/components/GenAIChatDialog.d.ts +2 -1
  6. package/esm/components/GenAIChatDialog.d.ts.map +1 -1
  7. package/esm/components/GenAIChatDialog.js +4 -4
  8. package/esm/components/GenAiChatContextChooserBody.js +2 -2
  9. package/esm/components/completion/useToolsReferences.d.ts.map +1 -1
  10. package/esm/components/completion/useToolsReferences.js +80 -7
  11. package/esm/components/hooks/useContextItems.js +1 -0
  12. package/esm/components/intelligence/data/deriveInteractionIntelligenceFromSteps.d.ts.map +1 -1
  13. package/esm/components/intelligence/data/deriveInteractionIntelligenceFromSteps.js +29 -2
  14. package/esm/components/messages/AssistantItem.d.ts.map +1 -1
  15. package/esm/components/messages/AssistantItem.js +1 -1
  16. package/esm/components/utils/icons.d.ts +1 -1
  17. package/esm/components/utils/icons.d.ts.map +1 -1
  18. package/esm/components/utils/icons.js +36 -3
  19. package/esm/context/collectContextReferences.d.ts.map +1 -1
  20. package/esm/context/collectContextReferences.js +4 -0
  21. package/esm/context/dashboard.d.ts +2 -2
  22. package/esm/context/dashboard.d.ts.map +1 -1
  23. package/esm/context/dashboard.js +10 -2
  24. package/esm/context/hooks/useDashboardAmbientContext.d.ts +3 -0
  25. package/esm/context/hooks/useDashboardAmbientContext.d.ts.map +1 -0
  26. package/esm/context/hooks/useDashboardAmbientContext.js +68 -0
  27. package/esm/hooks/useGenAiDispatcher.d.ts +11 -0
  28. package/esm/hooks/useGenAiDispatcher.d.ts.map +1 -0
  29. package/esm/hooks/useGenAiDispatcher.js +14 -0
  30. package/esm/index.d.ts +1 -0
  31. package/esm/index.d.ts.map +1 -1
  32. package/esm/index.js +1 -0
  33. package/esm/localization/bundles/zh-HK.localization-bundle.js +1 -1
  34. package/esm/sdk-ui-gen-ai.d.ts +17 -0
  35. package/esm/store/sideEffects/loadContextObjects.js +3 -3
  36. package/esm/types.d.ts +8 -0
  37. package/esm/types.d.ts.map +1 -1
  38. package/esm/utils.d.ts +1 -1
  39. package/esm/utils.d.ts.map +1 -1
  40. package/esm/utils.js +2 -1
  41. package/package.json +20 -20
  42. package/styles/css/main.css +18 -0
  43. package/styles/css/main.css.map +1 -1
  44. package/styles/css/messages.css +18 -0
  45. package/styles/css/messages.css.map +1 -1
  46. package/styles/scss/messages.scss +16 -0
@@ -1,4 +1,5 @@
1
1
  import { type ComponentType } from "react";
2
+ import { type DashboardSelectorEvaluator } from "@gooddata/sdk-ui-dashboard";
2
3
  import { type GenAIAssistantMode, type LinkHandlerEvent } from "./ConfigContext.js";
3
4
  import { type GenAiStoreProps } from "./GenAiStore.js";
4
5
  /**
@@ -33,6 +34,12 @@ export type GenAIAssistantProps = Omit<GenAiStoreProps, "children"> & {
33
34
  * This will disable full control permissions for the user even if the user has them defined.
34
35
  */
35
36
  disableFullControl?: boolean;
37
+ /**
38
+ * Selector that is used to automatically build ambient context for the chat.
39
+ * If its provided, the chat will automatically load the dashboards and related data
40
+ * from it.
41
+ */
42
+ dashboardSelector?: DashboardSelectorEvaluator;
36
43
  /**
37
44
  * Custom React node rendered when no conversation exists yet.
38
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAQ3C,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGpG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IAClE;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IAEvE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IAErD;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAyDxD;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,uBAAiB,CAAC"}
1
+ {"version":3,"file":"GenAIChat.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAO7E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGpG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IAClE;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IAEvE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,0BAA0B,CAAC;IAE/C;;OAEG;IACH,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IAErD;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAyDxD;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,uBAAiB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { BackendProvider, WorkspaceProvider, useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
3
+ import { useDashboardAmbientContext } from "../context/hooks/useDashboardAmbientContext.js";
3
4
  import { IntlWrapper } from "../localization/IntlWrapper.js";
4
5
  import { PermissionsProvider } from "../permissions/PermissionsContext.js";
5
6
  import { usePermissions } from "../permissions/usePermissions.js";
@@ -24,7 +25,8 @@ export function GenAIAssistant(props) {
24
25
  */
25
26
  export const GenAIChat = GenAIAssistant;
26
27
  function GenAIContent(props) {
27
- const { LandingScreenComponentProvider, DisclaimerComponentProvider, className, catalogItems } = props;
28
+ const { LandingScreenComponentProvider, DisclaimerComponentProvider, dashboardSelector, className, catalogItems, } = props;
28
29
  const { permissions, loading } = usePermissions();
30
+ useDashboardAmbientContext(dashboardSelector);
29
31
  return (_jsx(ConfigProvider, { catalogItems: catalogItems, canFullControl: props.disableFullControl ? false : (permissions.canManageProject ?? false), canManage: props.disableManage ? false : (permissions.canManageProject ?? false), canAnalyze: props.disableAnalyze ? false : (permissions.canCreateVisualization ?? false), children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, disclaimerComponentProvider: DisclaimerComponentProvider, children: _jsx(GenAIChatWrapper, { initializing: loading, className: className }) }) }));
30
32
  }
@@ -8,7 +8,7 @@ import { collectContextReferences } from "../context/collectContextReferences.js
8
8
  import { contextSetupEnabledSelector, userContextSelector } from "../store/chatWindow/chatWindowSelectors.js";
9
9
  import { removeContextReferenceAction } from "../store/chatWindow/chatWindowSlice.js";
10
10
  import { useContextChangeAnnouncement } from "./hooks/useContextChangeAnnouncement.js";
11
- import { getIconByType, getTypeLabel } from "./utils/icons.js";
11
+ import { getIconByObject, getTypeLabel } from "./utils/icons.js";
12
12
  const msgs = defineMessages({
13
13
  untitled: {
14
14
  id: "gd.gen-ai.context.untitled",
@@ -48,7 +48,7 @@ export function GenAIChatContextIndicator({ onDelete }) {
48
48
  return null;
49
49
  }
50
50
  return (_jsxs(_Fragment, { children: [references.length > 0 ? (_jsxs(_Fragment, { children: [
51
- _jsx("span", { className: "sr-only", id: groupLabelId, children: intl.formatMessage(msgs.groupLabel) }), _jsx("div", { className: "gd-gen-ai-chat__context-indicator", role: "group", "aria-labelledby": groupLabelId, children: references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...getIconByType(reference.type), label: reference.title, isExpandable: false, onDelete: onDeleteHandler(reference), accessibilityConfig: {
51
+ _jsx("span", { className: "sr-only", id: groupLabelId, children: intl.formatMessage(msgs.groupLabel) }), _jsx("div", { className: "gd-gen-ai-chat__context-indicator", role: "group", "aria-labelledby": groupLabelId, children: references.map((reference, index) => (_jsx(UiChip, { isDisabled: true, isDeletable: true, ...getIconByObject(reference), label: reference.title, isExpandable: false, onDelete: onDeleteHandler(reference), accessibilityConfig: {
52
52
  deleteAriaLabel: intl.formatMessage(msgs.remove, {
53
53
  title: reference.title,
54
54
  }),
@@ -15,11 +15,12 @@ export type GenAIChatDialogProps = Omit<GenAiStoreProps, "children"> & {
15
15
  returnFocusTo?: RefObject<HTMLElement | null> | string;
16
16
  onLinkClick?: (linkClickEvent: LinkHandlerEvent) => string | undefined;
17
17
  LandingScreenComponentProvider?: () => ComponentType;
18
+ DisclaimerComponentProvider?: () => ComponentType | null;
18
19
  /**
19
20
  * Set to false while the host renders its own overlay above the chat, so that Escape aimed at
20
21
  * that overlay does not also close the chat (see GenAIChatOverlayExternalProps.closeOnEscape).
21
22
  */
22
23
  closeOnEscape?: boolean;
23
24
  };
24
- export declare function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks, returnFocusTo, objectTypes, includeTags, excludeTags, canManage, canAnalyze, canFullControl, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, closeOnEscape }: GenAIChatDialogProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks, returnFocusTo, objectTypes, includeTags, excludeTags, canManage, canAnalyze, canFullControl, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape }: GenAIChatDialogProps): import("react/jsx-runtime").JSX.Element;
25
26
  //# sourceMappingURL=GenAIChatDialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GenAIChatDialog.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAcpG,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IACvD,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IACrD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AASF,wBAAgB,eAAe,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,cAAc,EACd,gBAAuB,EACvB,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAiB,EACjB,UAAkB,EAClB,cAAsB,EACtB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,8BAA8B,EAC9B,aAAa,EAChB,EAAE,oBAAoB,2CA8CtB"}
1
+ {"version":3,"file":"GenAIChatDialog.d.ts","sourceRoot":"","sources":["../../src/components/GenAIChatDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAcpG,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IACvD,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,8BAA8B,CAAC,EAAE,MAAM,aAAa,CAAC;IACrD,2BAA2B,CAAC,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IACzD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AASF,wBAAgB,eAAe,CAAC,EAC5B,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,cAAc,EACd,gBAAuB,EACvB,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAiB,EACjB,UAAkB,EAClB,cAAsB,EACtB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,8BAA8B,EAC9B,2BAA2B,EAC3B,aAAa,EAChB,EAAE,oBAAoB,2CA+CtB"}
@@ -18,12 +18,12 @@ import { KeyDriverAnalysis } from "./KeyDriverAnalysis.js";
18
18
  const DEFAULT_CHAT_Z_INDEX = 3000;
19
19
  // - Must be more than DEFAULT_CHAT_Z_INDEX
20
20
  const DEFAULT_KDA_Z_INDEX = 3050;
21
- export function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks = true, returnFocusTo, objectTypes, includeTags, excludeTags, canManage = false, canAnalyze = false, canFullControl = false, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, closeOnEscape, }) {
21
+ export function GenAIChatDialog({ backend, workspace, locale, disabled, isOpen, onOpen, onClose, settings, className, dialogPosition, allowNativeLinks = true, returnFocusTo, objectTypes, includeTags, excludeTags, canManage = false, canAnalyze = false, canFullControl = false, eventHandlers, catalogItems, colorPalette, onLinkClick, onDispatcher, mode, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape, }) {
22
22
  const effectiveBackend = useBackendStrict(backend);
23
23
  const effectiveWorkspace = useWorkspaceStrict(workspace);
24
- return (_jsx(IntlWrapper, { locale: locale, children: _jsx(GenAiStore, { backend: effectiveBackend, workspace: effectiveWorkspace, onDispatcher: onDispatcher, eventHandlers: eventHandlers, colorPalette: colorPalette, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, settings: settings, objectTypes: objectTypes, includeTags: includeTags, excludeTags: excludeTags, catalogItems: catalogItems, mode: mode, children: (genAIStore) => (_jsx(GenAIChatDialogContent, { genAIStore: genAIStore, backend: effectiveBackend, workspace: effectiveWorkspace, className: className, dialogPosition: dialogPosition, disabled: disabled, isOpen: isOpen, onOpen: onOpen, onClose: onClose, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, LandingScreenComponentProvider: LandingScreenComponentProvider })) }) }));
24
+ return (_jsx(IntlWrapper, { locale: locale, children: _jsx(GenAiStore, { backend: effectiveBackend, workspace: effectiveWorkspace, onDispatcher: onDispatcher, eventHandlers: eventHandlers, colorPalette: colorPalette, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, settings: settings, objectTypes: objectTypes, includeTags: includeTags, excludeTags: excludeTags, catalogItems: catalogItems, mode: mode, children: (genAIStore) => (_jsx(GenAIChatDialogContent, { genAIStore: genAIStore, backend: effectiveBackend, workspace: effectiveWorkspace, className: className, dialogPosition: dialogPosition, disabled: disabled, isOpen: isOpen, onOpen: onOpen, onClose: onClose, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, allowNativeLinks: allowNativeLinks, onLinkClick: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, LandingScreenComponentProvider: LandingScreenComponentProvider, DisclaimerComponentProvider: DisclaimerComponentProvider })) }) }));
25
25
  }
26
- function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dialogPosition, disabled, isOpen, onOpen, onClose, returnFocusTo, onLinkClick, allowNativeLinks, catalogItems, canManage, canAnalyze, canFullControl, LandingScreenComponentProvider, closeOnEscape, }) {
26
+ function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dialogPosition, disabled, isOpen, onOpen, onClose, returnFocusTo, onLinkClick, allowNativeLinks, catalogItems, canManage, canAnalyze, canFullControl, LandingScreenComponentProvider, DisclaimerComponentProvider, closeOnEscape, }) {
27
27
  const open = useRef(onOpen);
28
28
  open.current = onOpen;
29
29
  const close = useRef(onClose);
@@ -63,6 +63,6 @@ function GenAIChatDialogContent({ genAIStore, backend, workspace, className, dia
63
63
  const parentOverlayController = useOverlayController();
64
64
  const chatOverlayController = useMemo(() => parentOverlayController ?? OverlayController.getInstance(DEFAULT_CHAT_Z_INDEX), [parentOverlayController]);
65
65
  const kdaOverlayController = useMemo(() => parentOverlayController ?? OverlayController.getInstance(DEFAULT_KDA_Z_INDEX), [parentOverlayController]);
66
- return (_jsx(BackendProvider, { backend: backend, children: _jsx(WorkspaceProvider, { workspace: workspace, children: _jsxs(OverlayControllerProvider, { overlayController: chatOverlayController, children: [isOpen && !disabled ? (_jsx(ConfigProvider, { allowNativeLinks: allowNativeLinks, linkHandler: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, children: _jsx(GenAIChatOverlay, { className: className, dialogPosition: dialogPosition, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, onClose: onCloseHandler }) }) })) : null, _jsx(OverlayControllerProvider, { overlayController: kdaOverlayController, children: _jsx(KeyDriverAnalysis, {}) })
66
+ return (_jsx(BackendProvider, { backend: backend, children: _jsx(WorkspaceProvider, { workspace: workspace, children: _jsxs(OverlayControllerProvider, { overlayController: chatOverlayController, children: [isOpen && !disabled ? (_jsx(ConfigProvider, { allowNativeLinks: allowNativeLinks, linkHandler: onLinkClick, catalogItems: catalogItems, canManage: canManage, canAnalyze: canAnalyze, canFullControl: canFullControl, children: _jsx(CustomizationProvider, { landingScreenComponentProvider: LandingScreenComponentProvider, disclaimerComponentProvider: DisclaimerComponentProvider, children: _jsx(GenAIChatOverlay, { className: className, dialogPosition: dialogPosition, returnFocusTo: returnFocusTo, closeOnEscape: closeOnEscape, onClose: onCloseHandler }) }) })) : null, _jsx(OverlayControllerProvider, { overlayController: kdaOverlayController, children: _jsx(KeyDriverAnalysis, {}) })
67
67
  ] }) }) }));
68
68
  }
@@ -5,7 +5,7 @@ import cx from "classnames";
5
5
  import { defineMessages, useIntl } from "react-intl";
6
6
  import { useDebouncedState } from "@gooddata/sdk-ui";
7
7
  import { DEFAULT_ITEM_HEIGHT, DETAILED_ANNOUNCEMENT_THRESHOLD, Input, NoData, ScopedIdStore, ShortenedText, UiIcon, UiPagedVirtualList, UiSearchResultsAnnouncement, UiSubmenuHeader, isTypingKey, useScopedIdStoreValue, } from "@gooddata/sdk-ui-kit";
8
- import { getIconByType } from "./utils/icons.js";
8
+ import { getIconByObject } from "./utils/icons.js";
9
9
  const SEARCH_FIELD_VISIBILITY_THRESHOLD = 7;
10
10
  const SEARCH_DEBOUNCE_MS = 300;
11
11
  const MAX_VISIBLE_ITEMS = 7;
@@ -79,7 +79,7 @@ export function GenAiChatContextChooserBody({ inputItems, title, titleId, search
79
79
  }, children: (item) => _jsx(ContextChooserItem, { item: item, onSelect: () => handleSelect(item) }) }) })) : (_jsx(NoData, { hasNoMatchingData: hasNoMatchingData, notFoundLabel: intl.formatMessage(msgs.noMatchingData), noDataLabel: intl.formatMessage(msgs.noDataAvailable) }))] }));
80
80
  }
81
81
  function ContextChooserItem({ item, onSelect }) {
82
- const icon = getIconByType(item.type);
82
+ const icon = getIconByObject(item);
83
83
  return (_jsxs("div", { className: "gd-list-item", onClick: onSelect, children: [icon.iconBefore ? _jsx(UiIcon, { size: 16, type: icon.iconBefore, color: icon.iconColor }) : null, _jsx(ShortenedText, { ellipsisPosition: "end", children: item.title })
84
84
  ] }));
85
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useToolsReferences.d.ts","sourceRoot":"","sources":["../../../src/components/completion/useToolsReferences.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,EAAE,CAmBpF"}
1
+ {"version":3,"file":"useToolsReferences.d.ts","sourceRoot":"","sources":["../../../src/components/completion/useToolsReferences.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,EAAE,CAuBpF"}
@@ -1,9 +1,10 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { useMemo } from "react";
3
- import { isChatConversationToolResultContent, } from "@gooddata/sdk-backend-spi";
3
+ import { isChatConversationToolCallContent, isChatConversationToolResultContent, } from "@gooddata/sdk-backend-spi";
4
4
  export function useToolsReferences(groups) {
5
5
  return useMemo(() => {
6
6
  const references = [];
7
+ const mapping = {};
7
8
  groups.forEach((group) => {
8
9
  group.messages.forEach((message) => {
9
10
  const cont = message.content;
@@ -11,15 +12,18 @@ export function useToolsReferences(groups) {
11
12
  if (cont.type === "error" || cont.type === "system") {
12
13
  return;
13
14
  }
15
+ if (isChatConversationToolCallContent(cont)) {
16
+ mapping[cont.callId] = cont;
17
+ }
14
18
  if (isChatConversationToolResultContent(cont)) {
15
- parseToolResults(references, cont);
19
+ parseToolResults(references, mapping[cont.callId], cont);
16
20
  }
17
21
  });
18
22
  });
19
- return references;
23
+ return references.map((obj) => ({ ...obj, title: obj.title ?? obj.id }));
20
24
  }, [groups]);
21
25
  }
22
- function parseToolResults(references, cont) {
26
+ function parseToolResults(references, call, cont) {
23
27
  // Is not an objects, skip it
24
28
  if (typeof cont.result === "string") {
25
29
  return;
@@ -31,7 +35,6 @@ function parseToolResults(references, cont) {
31
35
  const created = res.parsed_objects.map((obj) => ({
32
36
  type: obj.object_type,
33
37
  id: obj.object_id,
34
- title: "",
35
38
  }));
36
39
  mergeReferenceObjectInfos(references, created);
37
40
  }
@@ -44,15 +47,85 @@ function parseToolResults(references, cont) {
44
47
  }));
45
48
  mergeReferenceObjectInfos(references, created);
46
49
  }
47
- //.objects
50
+ //.res.data.metrics
48
51
  if (Array.isArray(res.data?.metrics)) {
49
52
  const created = res.data.metrics.map((obj) => ({
50
53
  type: obj.type,
51
54
  id: obj.id,
52
- title: obj.attributes?.title ?? "",
55
+ title: obj.attributes?.title,
53
56
  }));
54
57
  mergeReferenceObjectInfos(references, created);
55
58
  }
59
+ //.dashboard in "get_dashboard_context"
60
+ if (call?.name === "get_dashboard_context" && res.dashboard) {
61
+ const dash = res.dashboard;
62
+ if (dash.id) {
63
+ mergeReferenceObjectInfos(references, [
64
+ {
65
+ type: "dashboard",
66
+ id: dash.id,
67
+ title: dash.title,
68
+ },
69
+ ]);
70
+ dash.widgets?.forEach((widget) => {
71
+ switch (widget.widget_type) {
72
+ case "visualization_switcher": {
73
+ const created = [];
74
+ created.push({
75
+ type: "visualization",
76
+ id: widget.active_visualization_id,
77
+ title: widget.title,
78
+ });
79
+ widget.visualization_ids?.forEach((id) => {
80
+ created.push({
81
+ type: "visualization",
82
+ id,
83
+ });
84
+ });
85
+ widget.visualizations?.forEach(({ visualization_id, title }) => {
86
+ created.push({
87
+ type: "visualization",
88
+ id: visualization_id,
89
+ title,
90
+ });
91
+ });
92
+ mergeReferenceObjectInfos(references, created);
93
+ break;
94
+ }
95
+ case "insight": {
96
+ mergeReferenceObjectInfos(references, [
97
+ {
98
+ type: "visualization",
99
+ id: widget.visualization_id,
100
+ title: widget.title,
101
+ },
102
+ ]);
103
+ break;
104
+ }
105
+ }
106
+ });
107
+ }
108
+ }
109
+ //.parent in "get_object_with_children"
110
+ if (call?.name === "get_object_with_children" && res.parent) {
111
+ const par = res.parent;
112
+ mergeReferenceObjectInfos(references, [
113
+ {
114
+ type: (par.final_type ?? par.type),
115
+ id: par.id,
116
+ title: par.title,
117
+ },
118
+ ]);
119
+ }
120
+ //.children in "get_object_with_children"
121
+ if (call?.name === "get_object_with_children" && res.children) {
122
+ const children = res.children;
123
+ mergeReferenceObjectInfos(references, children.map((child) => ({
124
+ type: (child.final_type ?? child.type),
125
+ id: child.id,
126
+ title: child.title,
127
+ })));
128
+ }
56
129
  }
57
130
  function mergeReferenceObjectInfos(objects, created) {
58
131
  created.forEach((obj) => {
@@ -73,6 +73,7 @@ function toContextObjects(items, type, emptyReferenceLabel) {
73
73
  where: "referencedObjects",
74
74
  title: item.title || emptyReferenceLabel || item.id,
75
75
  nesting: 1,
76
+ ...(item.visualizationUrl ? { visualizationUrl: item.visualizationUrl } : {}),
76
77
  }));
77
78
  }
78
79
  function isSameObject(a, b) {
@@ -1 +1 @@
1
- {"version":3,"file":"deriveInteractionIntelligenceFromSteps.d.ts","sourceRoot":"","sources":["../../../../src/components/intelligence/data/deriveInteractionIntelligenceFromSteps.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,KAAK,EAIR,wBAAwB,EACxB,8BAA8B,EAEjC,MAAM,YAAY,CAAC;AAuCpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sCAAsC,CAClD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,8BAA8B,GACtC,wBAAwB,CAmF1B;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAC/C,KAAK,EAAE,8BAA8B,GACtC,8BAA8B,CAgBhC"}
1
+ {"version":3,"file":"deriveInteractionIntelligenceFromSteps.d.ts","sourceRoot":"","sources":["../../../../src/components/intelligence/data/deriveInteractionIntelligenceFromSteps.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,KAAK,EAIR,wBAAwB,EACxB,8BAA8B,EAEjC,MAAM,YAAY,CAAC;AAmEpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sCAAsC,CAClD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,8BAA8B,GACtC,wBAAwB,CAoF1B;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAC/C,KAAK,EAAE,8BAA8B,GACtC,8BAA8B,CAgBhC"}
@@ -16,10 +16,36 @@ const CATEGORY_LABEL_MESSAGES = defineMessages({
16
16
  });
17
17
  /** `stepId` of the memory step. The backend records none for it, so this collides with no real one. */
18
18
  const MEMORY_STEP_ID = "memory";
19
+ /**
20
+ * Skills hidden from the skill-routing card. Neither is user-configurable — Object search is
21
+ * auto-attached to every agent, Knowledge search comes from the agent's "AI knowledge" setting —
22
+ * so showing them implies a routing decision the model never made. The detail identifies skills
23
+ * by title only; these literals mirror the backend's `SearchSkill`/`KnowledgeSkill` title constants.
24
+ */
25
+ const HIDDEN_SKILL_TITLES = ["Object search", "Knowledge search"];
26
+ /**
27
+ * Drops the hidden skills from a skill-routing detail, and the whole detail when no configurable
28
+ * skill was available — routing over auto-attached skills alone is no decision to display. Other
29
+ * categories pass through unchanged.
30
+ */
31
+ function filterHiddenSkills(detail) {
32
+ if (detail.category !== "skillRouting") {
33
+ return detail;
34
+ }
35
+ const available = detail.available.filter((title) => !HIDDEN_SKILL_TITLES.includes(title));
36
+ if (available.length === 0) {
37
+ return undefined;
38
+ }
39
+ return {
40
+ ...detail,
41
+ available,
42
+ activated: detail.activated.filter((title) => !HIDDEN_SKILL_TITLES.includes(title)),
43
+ };
44
+ }
19
45
  /** The details of the work done before the first step — the memory applied to the turn. */
20
46
  function preStepDetails(trace) {
21
47
  return (trace.responseDetails ?? [])
22
- .map(({ detail }) => detail)
48
+ .map(({ detail }) => (detail ? filterHiddenSkills(detail) : undefined))
23
49
  .filter((detail) => !!detail);
24
50
  }
25
51
  /** How long that work took, and so the width of its step. 0 when it reported no duration. */
@@ -64,7 +90,8 @@ export function deriveInteractionIntelligenceFromSteps(responseId, trace) {
64
90
  const index = position + firstStepIndex;
65
91
  const actions = trace.detailsByStepId[step.stepId] ?? [];
66
92
  const categoriesInStep = [];
67
- for (const { detail } of actions) {
93
+ for (const action of actions) {
94
+ const detail = action.detail ? filterHiddenSkills(action.detail) : undefined;
68
95
  if (!detail) {
69
96
  continue;
70
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/AssistantItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMjE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,KAAK,kBAAkB,GAAG;IACtB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,kDAgFrF"}
1
+ {"version":3,"file":"AssistantItem.d.ts","sourceRoot":"","sources":["../../../src/components/messages/AssistantItem.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMjE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,KAAK,kBAAkB,GAAG;IACtB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,kBAAkB,kDAiFrF"}
@@ -21,7 +21,7 @@ export function AssistantItemComponent({ message, groups, isLast }) {
21
21
  const references = useToolsReferences(groups);
22
22
  const [isInteractionIntelligenceOpen, setIsInteractionIntelligenceOpen] = useState(false);
23
23
  const interactionIntelligenceEnabled = useSelector(interactionIntelligenceEnabledSelector);
24
- const showInteractionIntelligence = interactionIntelligenceEnabled && !!message.responseId;
24
+ const showInteractionIntelligence = interactionIntelligenceEnabled && !!message.responseId && message.content.type !== "reasoning";
25
25
  const interactionIntelligenceTotals = useInteractionIntelligenceTotals(showInteractionIntelligence ? message.responseId : "");
26
26
  // The trigger only renders once its totals exist, so this is what actually shares the actions
27
27
  // row with feedback — a message with no trace keeps its feedback exactly as before.
@@ -1,7 +1,7 @@
1
1
  import { type IntlShape } from "react-intl";
2
2
  import { type IconType, type ThemeColor } from "@gooddata/sdk-ui-kit";
3
3
  import { type IGenAIContextObject } from "../../types.js";
4
- export declare function getIconByType(type: IGenAIContextObject["type"]): {
4
+ export declare function getIconByObject(object: Pick<IGenAIContextObject, "type" | "visualizationUrl">): {
5
5
  iconBefore?: IconType;
6
6
  iconColor?: ThemeColor;
7
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/utils/icons.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAW1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG;IAC9D,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,CAAC;CAC1B,CAgBA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAUnG"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/utils/icons.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAuC1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,kBAAkB,CAAC,GAAG;IAC7F,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,CAAC;CAC1B,CAgBA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAUnG"}
@@ -8,8 +8,35 @@ const msgs = defineMessages({
8
8
  id: "gd.gen-ai.context.type.visualization",
9
9
  },
10
10
  });
11
- export function getIconByType(type) {
12
- switch (type) {
11
+ const VISUALIZATION_TYPE_ICONS = {
12
+ area: "visualizationArea",
13
+ bar: "visualizationBar",
14
+ bubble: "visualizationBubble",
15
+ bullet: "visualizationBullet",
16
+ column: "visualizationColumn",
17
+ combo: "visualizationCombo",
18
+ combo2: "visualizationCombo",
19
+ dependencywheel: "visualizationDependencywheel",
20
+ donut: "visualizationDonut",
21
+ funnel: "visualizationFunnel",
22
+ headline: "visualizationHeadline",
23
+ heatmap: "visualizationHeatmap",
24
+ line: "visualizationLine",
25
+ pie: "visualizationPie",
26
+ pushpin: "visualizationPushpin",
27
+ pushpinnext: "visualizationPushpin",
28
+ pyramid: "visualizationPyramid",
29
+ repeater: "visualizationRepeater",
30
+ sankey: "visualizationSankey",
31
+ scatter: "visualizationScatter",
32
+ table: "visualizationTable",
33
+ tablenext: "visualizationTable",
34
+ treemap: "visualizationTreemap",
35
+ waterfall: "visualizationWaterfall",
36
+ xirr: "visualizationXirr",
37
+ };
38
+ export function getIconByObject(object) {
39
+ switch (object.type) {
13
40
  case "dashboard":
14
41
  return {
15
42
  iconBefore: "dashboard",
@@ -18,7 +45,7 @@ export function getIconByType(type) {
18
45
  case "visualization":
19
46
  case "widget":
20
47
  return {
21
- iconBefore: "visualization",
48
+ iconBefore: getVisualizationIcon(object.visualizationUrl),
22
49
  iconColor: "complementary-6",
23
50
  };
24
51
  default:
@@ -36,3 +63,9 @@ export function getTypeLabel(type, intl) {
36
63
  return undefined;
37
64
  }
38
65
  }
66
+ function getVisualizationIcon(visualizationUrl) {
67
+ const type = visualizationUrl?.split(":").at(-1);
68
+ return type && Object.hasOwn(VISUALIZATION_TYPE_ICONS, type)
69
+ ? VISUALIZATION_TYPE_ICONS[type]
70
+ : "visualization";
71
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EAGzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAwCvB;AAED,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAmFvB"}
1
+ {"version":3,"file":"collectContextReferences.d.ts","sourceRoot":"","sources":["../../src/context/collectContextReferences.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EAGzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,wBAAwB,CACpC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAwCvB;AAED,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,gBAAgB,CAAC,EAAE,MAAM,GAC1B,mBAAmB,EAAE,CAuFvB"}
@@ -82,6 +82,7 @@ export function collectAvailableReferences(context, placeholderTitle) {
82
82
  type: "widget",
83
83
  context,
84
84
  insightRef: widget.insightRef,
85
+ ...(widget.visualizationUrl ? { visualizationUrl: widget.visualizationUrl } : {}),
85
86
  });
86
87
  }
87
88
  break;
@@ -105,6 +106,9 @@ export function collectAvailableReferences(context, placeholderTitle) {
105
106
  type: "widget",
106
107
  context,
107
108
  insightRef: visualization.insightRef,
109
+ ...(visualization.visualizationUrl
110
+ ? { visualizationUrl: visualization.visualizationUrl }
111
+ : {}),
108
112
  });
109
113
  }
110
114
  });
@@ -1,4 +1,4 @@
1
- import { type FilterContextItem, type GenAIUserContextFilter, type IAttributeDisplayFormMetadataObject, type IDashboardDefinition, type IGenAIDashboardContext, type IGenAIObjectReference, type IGenAIUserContext, type IGenAIWidgetDescriptor, type IWidget, type ObjRef } from "@gooddata/sdk-model";
1
+ import { type FilterContextItem, type GenAIUserContextFilter, type IAttributeDisplayFormMetadataObject, type IDashboardDefinition, type IGenAIDashboardContext, type IGenAIObjectReference, type IGenAIUserContext, type IGenAIWidgetDescriptor, type IInsight, type IWidget, type ObjRef } from "@gooddata/sdk-model";
2
2
  /**
3
3
  * @internal
4
4
  */
@@ -14,7 +14,7 @@ export declare function buildFiltersContext(filters: FilterContextItem[], displa
14
14
  /**
15
15
  * @internal
16
16
  */
17
- export declare function buildWidgetsContext(widgetsMap: Pick<Map<ObjRef, IWidget>, "values" | "get"> | undefined, resultsIdMap?: Pick<Map<string, string | undefined>, "values" | "get">, visualizationSwitcherActiveVisualizations?: Record<string, string>): {
17
+ export declare function buildWidgetsContext(widgetsMap: Pick<Map<ObjRef, IWidget>, "values" | "get"> | undefined, resultsIdMap?: Pick<Map<string, string | undefined>, "values" | "get">, visualizationSwitcherActiveVisualizations?: Record<string, string>, insightsMap?: Pick<Map<ObjRef, IInsight>, "get">): {
18
18
  widgets: IGenAIWidgetDescriptor[];
19
19
  referencedObjects: IGenAIObjectReference[];
20
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/context/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEtB,KAAK,sBAAsB,EAC3B,KAAK,OAAO,EACZ,KAAK,MAAM,EASd,MAAM,qBAAqB,CAAC;AAM7B;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC,EACrD,UAAU,CAAC,EAAE,oBAAoB,GAClC,iBAAiB,CASnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,SAAS,GAAG,uBAAuB,GAAG,UAAU,EAC5D,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,GACpF,sBAAsB,CAOxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,CAAC,EAAE,KAAK,CAAC,GAC7E,sBAAsB,EAAE,CA2E1B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,GAAG,SAAS,EACpE,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,EACtE,yCAAyC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnE;IAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,CAuEnF"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/context/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAEtB,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,MAAM,EAUd,MAAM,qBAAqB,CAAC;AAM7B;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,SAAS,EAAE,IAAI,CAAC,sBAAsB,EAAE,YAAY,CAAC,EACrD,UAAU,CAAC,EAAE,oBAAoB,GAClC,iBAAiB,CASnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,SAAS,GAAG,uBAAuB,GAAG,UAAU,EAC5D,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,GACpF,sBAAsB,CAOxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mCAAmC,CAAC,EAAE,KAAK,CAAC,GAC7E,sBAAsB,EAAE,CA2E1B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,GAAG,SAAS,EACpE,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,EACtE,yCAAyC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClE,WAAW,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,GACjD;IAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAAC,iBAAiB,EAAE,qBAAqB,EAAE,CAAA;CAAE,CA0EnF"}
@@ -1,5 +1,5 @@
1
1
  // (C) 2026 GoodData Corporation
2
- import { isAttributeElementsByRef, isDashboardAttributeFilter, isDashboardDateFilter, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
2
+ import { insightVisualizationUrl, isAttributeElementsByRef, isDashboardAttributeFilter, isDashboardDateFilter, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
3
3
  import { DEFAULT_MESSAGES } from "@gooddata/sdk-ui";
4
4
  import { DateFilterHelpers } from "@gooddata/sdk-ui-filters";
5
5
  import { buildContext } from "./build.js";
@@ -94,7 +94,7 @@ export function buildFiltersContext(filters, displayForms) {
94
94
  /**
95
95
  * @internal
96
96
  */
97
- export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitcherActiveVisualizations) {
97
+ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitcherActiveVisualizations, insightsMap) {
98
98
  const widgets = [];
99
99
  const referencedObjects = [];
100
100
  if (!widgetsMap) {
@@ -114,6 +114,7 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
114
114
  widgets.push(buildWidgetContext(widget.title, widget.ref, "insight", {
115
115
  insightRef: widget.insight,
116
116
  resultId: resultsIdMap?.get(serializeObjRef(widget.ref)),
117
+ ...visualizationUrlOf(insightsMap, widget.insight),
117
118
  }));
118
119
  referencedObjects.push({ type: "WIDGET", ref: widget.ref, title: widget.title });
119
120
  }
@@ -127,10 +128,12 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
127
128
  resultId: activeVisualization
128
129
  ? resultsIdMap?.get(serializeObjRef(activeVisualization.ref))
129
130
  : undefined,
131
+ ...visualizationUrlOf(insightsMap, activeVisualization?.insight),
130
132
  // All child insights, so the BE can execute the non-active children
131
133
  // (which have no cached result).
132
134
  visualizations: widget.visualizations.map((v) => buildWidgetContext(v.title, v.ref, "insight", {
133
135
  insightRef: v.insight,
136
+ ...visualizationUrlOf(insightsMap, v.insight),
134
137
  })),
135
138
  }));
136
139
  referencedObjects.push({
@@ -147,6 +150,11 @@ export function buildWidgetsContext(widgetsMap, resultsIdMap, visualizationSwitc
147
150
  }
148
151
  return { widgets, referencedObjects };
149
152
  }
153
+ //utils
154
+ function visualizationUrlOf(insightsMap, insightRef) {
155
+ const insight = insightRef ? insightsMap?.get(insightRef) : undefined;
156
+ return insight ? { visualizationUrl: insightVisualizationUrl(insight) } : {};
157
+ }
150
158
  const GRANULARITY_TO_GENAI = {
151
159
  "GDC.time.minute": "MINUTE",
152
160
  "GDC.time.hour": "HOUR",
@@ -0,0 +1,3 @@
1
+ import { type DashboardSelectorEvaluator } from "@gooddata/sdk-ui-dashboard";
2
+ export declare function useDashboardAmbientContext(dashboardSelector?: DashboardSelectorEvaluator): void;
3
+ //# sourceMappingURL=useDashboardAmbientContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDashboardAmbientContext.d.ts","sourceRoot":"","sources":["../../../src/context/hooks/useDashboardAmbientContext.ts"],"names":[],"mappings":"AAOA,OAAO,EAEH,KAAK,0BAA0B,EAalC,MAAM,4BAA4B,CAAC;AAMpC,wBAAgB,0BAA0B,CAAC,iBAAiB,CAAC,EAAE,0BAA0B,QAQxF"}
@@ -0,0 +1,68 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useEffect, useRef } from "react";
3
+ import { useDispatch } from "react-redux";
4
+ import { idRef } from "@gooddata/sdk-model";
5
+ import { newDisplayFormMap, newMapForObjectWithIdentity, selectActiveTab, selectAttributeFilterDisplayFormsMap, selectDashboardId, selectDashboardTitle, selectDashboardWorkingDefinition, selectFilterContextFilters, selectIsNewDashboard, selectVisualizationSwitcherActiveVisualizations, selectWidgetsMap, } from "@gooddata/sdk-ui-dashboard";
6
+ import { setAmbientUserContextAction } from "../../store/chatWindow/chatWindowSlice.js";
7
+ import { mergeContexts } from "../build.js";
8
+ import { buildDashboardContext, buildFiltersContext, buildWidgetsContext } from "../dashboard.js";
9
+ export function useDashboardAmbientContext(dashboardSelector) {
10
+ const dispatch = useDispatch();
11
+ const used = useRef(false);
12
+ useEffect(() => {
13
+ const context = dashboardSelector ? buildFromDashboard(dashboardSelector) : undefined;
14
+ setContext(dispatch, context, used);
15
+ }, [dashboardSelector, dispatch]);
16
+ }
17
+ function setContext(dispatch, context, used) {
18
+ if (context) {
19
+ dispatch(setAmbientUserContextAction({ userContext: context }));
20
+ used.current = true;
21
+ }
22
+ if (!context && used.current) {
23
+ dispatch(setAmbientUserContextAction({ userContext: undefined }));
24
+ used.current = false;
25
+ }
26
+ }
27
+ function buildFromDashboard(dashboardSelector) {
28
+ const dashboardId = selectWithDefault(dashboardSelector, selectDashboardId, "new-dashboard");
29
+ const dashboardTitle = selectWithDefault(dashboardSelector, selectDashboardTitle, "");
30
+ const isNewDashboard = selectWithDefault(dashboardSelector, selectIsNewDashboard, false);
31
+ const filterContextItems = selectWithDefault(dashboardSelector, selectFilterContextFilters, []);
32
+ const displayForms = selectWithDefault(dashboardSelector, selectAttributeFilterDisplayFormsMap, newDisplayFormMap([]));
33
+ const widgetsMap = selectWithDefault(dashboardSelector, selectWidgetsMap, newMapForObjectWithIdentity([]));
34
+ const activeTab = selectWithOptional(dashboardSelector, selectActiveTab);
35
+ const workingDefinition = selectWithOptional(dashboardSelector, selectDashboardWorkingDefinition);
36
+ const visualizationSwitcherActiveVisualizations = selectWithDefault(dashboardSelector, selectVisualizationSwitcherActiveVisualizations, {});
37
+ const resultsEnvelopes = dashboardSelector((state) => state.executionResults.entities);
38
+ const results = Object.entries(resultsEnvelopes).reduce((acc, [key, value]) => {
39
+ acc.set(key, value.executionResult?.resultId() ?? undefined);
40
+ return acc;
41
+ }, new Map());
42
+ const filters = buildFiltersContext(filterContextItems ?? [], displayForms);
43
+ const { widgets } = buildWidgetsContext(widgetsMap, results, visualizationSwitcherActiveVisualizations);
44
+ return mergeContexts(buildDashboardContext({
45
+ ref: idRef(dashboardId, "analyticalDashboard"),
46
+ isNew: isNewDashboard,
47
+ title: dashboardTitle,
48
+ widgets,
49
+ filters,
50
+ ...(activeTab ? { activeTabId: activeTab.localIdentifier } : {}),
51
+ }, workingDefinition));
52
+ }
53
+ function selectWithDefault(dashboardSelector, selector, defaultValue) {
54
+ try {
55
+ return dashboardSelector(selector) ?? defaultValue;
56
+ }
57
+ catch {
58
+ return defaultValue;
59
+ }
60
+ }
61
+ function selectWithOptional(dashboardSelector, selector) {
62
+ try {
63
+ return dashboardSelector(selector);
64
+ }
65
+ catch {
66
+ return undefined;
67
+ }
68
+ }
@@ -0,0 +1,11 @@
1
+ import { type EnhancedStore } from "@reduxjs/toolkit";
2
+ /**
3
+ * Hook to retrieve the GenAI dispatcher.
4
+ *
5
+ * @remarks
6
+ * This hook must be used within a GenAiStore component.
7
+ *
8
+ * @public
9
+ */
10
+ export declare function useGenAiDispatcher(): EnhancedStore["dispatch"];
11
+ //# sourceMappingURL=useGenAiDispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGenAiDispatcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useGenAiDispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,aAAa,CAAC,UAAU,CAAC,CAE9D"}