@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.0.0 → 5.0.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 (102) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/alpha.d.ts +1 -2
  3. package/dist/components/Attachment.esm.js +14 -14
  4. package/dist/components/Attachment.esm.js.map +1 -1
  5. package/dist/components/CollapsedHistoryStrip.esm.js +46 -51
  6. package/dist/components/CollapsedHistoryStrip.esm.js.map +1 -1
  7. package/dist/components/DeleteModal.esm.js +1 -0
  8. package/dist/components/DeleteModal.esm.js.map +1 -1
  9. package/dist/components/FilePreview.esm.js +3 -2
  10. package/dist/components/FilePreview.esm.js.map +1 -1
  11. package/dist/components/LightSpeedChat.esm.js +580 -745
  12. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatBox.esm.js +44 -72
  14. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  15. package/dist/components/LightspeedChatBoxHeader.esm.js +38 -34
  16. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  17. package/dist/components/LightspeedChatContainer.esm.js +6 -8
  18. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  19. package/dist/components/LightspeedChatModelsState.esm.js +67 -73
  20. package/dist/components/LightspeedChatModelsState.esm.js.map +1 -1
  21. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  22. package/dist/components/LightspeedDrawerProvider.esm.js +13 -16
  23. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  24. package/dist/components/LightspeedFABContent.esm.js +40 -9
  25. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  26. package/dist/components/LightspeedPage.esm.js +1 -10
  27. package/dist/components/LightspeedPage.esm.js.map +1 -1
  28. package/dist/components/McpConfigureServerModal.esm.js +79 -86
  29. package/dist/components/McpConfigureServerModal.esm.js.map +1 -1
  30. package/dist/components/McpServersSettings.esm.js +246 -212
  31. package/dist/components/McpServersSettings.esm.js.map +1 -1
  32. package/dist/components/MessageBarModelSelector.esm.js +29 -33
  33. package/dist/components/MessageBarModelSelector.esm.js.map +1 -1
  34. package/dist/components/PermissionRequiredState.esm.js +63 -63
  35. package/dist/components/PermissionRequiredState.esm.js.map +1 -1
  36. package/dist/components/RagSourceLabel.esm.js +22 -0
  37. package/dist/components/RagSourceLabel.esm.js.map +1 -0
  38. package/dist/components/RenameConversationModal.esm.js +38 -31
  39. package/dist/components/RenameConversationModal.esm.js.map +1 -1
  40. package/dist/components/Router.esm.js +4 -13
  41. package/dist/components/Router.esm.js.map +1 -1
  42. package/dist/components/SourcesChipModal.esm.js +94 -89
  43. package/dist/components/SourcesChipModal.esm.js.map +1 -1
  44. package/dist/components/ToastAlertGroup.esm.js +24 -40
  45. package/dist/components/ToastAlertGroup.esm.js.map +1 -1
  46. package/dist/components/ToolCallContent.esm.js +8 -11
  47. package/dist/components/ToolCallContent.esm.js.map +1 -1
  48. package/dist/components/notebooks/AddDocumentModal.esm.js +232 -252
  49. package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
  50. package/dist/components/notebooks/DeleteDocumentModal.esm.js +35 -77
  51. package/dist/components/notebooks/DeleteDocumentModal.esm.js.map +1 -1
  52. package/dist/components/notebooks/DeleteNotebookModal.esm.js +46 -81
  53. package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -1
  54. package/dist/components/notebooks/DocumentSidebar.esm.js +172 -196
  55. package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
  56. package/dist/components/notebooks/FileListItem.esm.js +69 -57
  57. package/dist/components/notebooks/FileListItem.esm.js.map +1 -1
  58. package/dist/components/notebooks/FileTypeIcon.esm.js +17 -27
  59. package/dist/components/notebooks/FileTypeIcon.esm.js.map +1 -1
  60. package/dist/components/notebooks/NotebookCard.esm.js +86 -25
  61. package/dist/components/notebooks/NotebookCard.esm.js.map +1 -1
  62. package/dist/components/notebooks/NotebookView.esm.js +367 -380
  63. package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
  64. package/dist/components/notebooks/NotebooksTab.esm.js +93 -30
  65. package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -1
  66. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +142 -184
  67. package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
  68. package/dist/components/notebooks/UploadResourceScreen.esm.js +58 -50
  69. package/dist/components/notebooks/UploadResourceScreen.esm.js.map +1 -1
  70. package/dist/components/notebooks/notebookDialogStyles.esm.js +33 -37
  71. package/dist/components/notebooks/notebookDialogStyles.esm.js.map +1 -1
  72. package/dist/const.esm.js +15 -2
  73. package/dist/const.esm.js.map +1 -1
  74. package/dist/hooks/useAutoScroll.esm.js +11 -11
  75. package/dist/hooks/useAutoScroll.esm.js.map +1 -1
  76. package/dist/hooks/useBufferedMessages.esm.js +5 -5
  77. package/dist/hooks/useBufferedMessages.esm.js.map +1 -1
  78. package/dist/hooks/useFeedbackActions.esm.js.map +1 -1
  79. package/dist/hooks/useIsMobile.esm.js +3 -3
  80. package/dist/hooks/useIsMobile.esm.js.map +1 -1
  81. package/dist/translations/de.esm.js +1 -2
  82. package/dist/translations/de.esm.js.map +1 -1
  83. package/dist/translations/es.esm.js +1 -2
  84. package/dist/translations/es.esm.js.map +1 -1
  85. package/dist/translations/fr.esm.js +1 -2
  86. package/dist/translations/fr.esm.js.map +1 -1
  87. package/dist/translations/it.esm.js +1 -2
  88. package/dist/translations/it.esm.js.map +1 -1
  89. package/dist/translations/ja.esm.js +1 -2
  90. package/dist/translations/ja.esm.js.map +1 -1
  91. package/dist/translations/ref.esm.js +1 -2
  92. package/dist/translations/ref.esm.js.map +1 -1
  93. package/dist/types.esm.js.map +1 -1
  94. package/dist/utils/fab-anchor-utils.esm.js +41 -0
  95. package/dist/utils/fab-anchor-utils.esm.js.map +1 -0
  96. package/dist/utils/lightspeed-chatbox-utils.esm.js +13 -6
  97. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  98. package/dist/utils/scoped-dialog-utils.esm.js +6 -3
  99. package/dist/utils/scoped-dialog-utils.esm.js.map +1 -1
  100. package/package.json +5 -9
  101. package/dist/utils/generateClassName.esm.js +0 -12
  102. package/dist/utils/generateClassName.esm.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { forwardRef, useRef, useImperativeHandle, useEffect } from 'react';
3
- import { makeStyles } from '@material-ui/core';
4
- import { ChatbotDisplayMode, MessageBox, ChatbotWelcomePrompt, ToolCall, DeepThinking, Message } from '@patternfly/chatbot';
3
+ import { keyframes, styled } from '@mui/material/styles';
4
+ import { MessageBox, ChatbotDisplayMode, ChatbotWelcomePrompt, ToolCall, DeepThinking, Message } from '@patternfly/chatbot';
5
5
  import { Alert } from '@patternfly/react-core';
6
6
  import { useAutoScroll } from '../hooks/useAutoScroll.esm.js';
7
7
  import { useBufferedMessages } from '../hooks/useBufferedMessages.esm.js';
@@ -11,57 +11,48 @@ import { parseReasoning } from '../utils/reasoningParser.esm.js';
11
11
  import { mapToPatternFlyToolCall } from '../utils/toolCallMapper.esm.js';
12
12
  import { SourcesChipModal } from './SourcesChipModal.esm.js';
13
13
 
14
- const useStyles = makeStyles((theme) => ({
15
- prompt: {
16
- "justify-content": "flex-end"
17
- },
18
- container: {
19
- maxWidth: "unset !important"
20
- },
21
- alert: {
22
- background: "unset !important"
23
- },
24
- promptSuggestions: {
25
- "& div.pf-chatbot__prompt-suggestions": {
26
- "flex-direction": "column !important"
27
- }
28
- },
29
- userMessageText: {
14
+ const DEEP_THINKING_CLASS = "lightspeed-deep-thinking";
15
+ const deepThinkingPulse = keyframes`
16
+ 0% { opacity: 0.65 }
17
+ 50% { opacity: 1 }
18
+ 100% { opacity: 0.65 }
19
+ `;
20
+ const StyledMessageBox = styled(MessageBox, {
21
+ shouldForwardProp: (prop) => prop !== "$isNewChat" && prop !== "$hasWelcomePrompts" && prop !== "$showPromptSuggestions"
22
+ })(
23
+ ({ theme, $isNewChat, $hasWelcomePrompts, $showPromptSuggestions }) => ({
24
+ maxWidth: "unset !important",
25
+ [`& .${DEEP_THINKING_CLASS}`]: {
26
+ animation: `${deepThinkingPulse} 1.6s ease-in-out infinite`
27
+ },
30
28
  "& div.pf-chatbot__message--user": {
31
29
  "& div.pf-chatbot__message-text": {
32
30
  "& p": {
33
31
  color: theme.palette.common.white
34
32
  }
35
33
  }
36
- }
37
- },
38
- deepThinking: {
39
- animation: "$deepThinking 1.6s ease-in-out infinite"
40
- },
41
- "@keyframes deepThinking": {
42
- "0%": {
43
- opacity: 0.65
44
34
  },
45
- "50%": {
46
- opacity: 1
35
+ ...$isNewChat ? {
36
+ flex: "none",
37
+ height: "auto !important",
38
+ overflow: "visible"
39
+ } : {
40
+ flex: 1,
41
+ minHeight: 0
47
42
  },
48
- "100%": {
49
- opacity: 0.65
50
- }
51
- },
52
- // Message box fills remaining height and scrolls when there are messages.
53
- messageBoxFlex: {
54
- flex: 1,
55
- minHeight: 0
56
- },
57
- // New chat: message box sizes to content so ChatbotContent is the scroll container.
58
- // overflow: visible so full height is included in parent's scrollHeight (no clipping).
59
- messageBoxAutoHeight: {
60
- flex: "none",
61
- height: "auto",
62
- overflow: "visible"
63
- }
64
- }));
43
+ ...$hasWelcomePrompts ? {
44
+ justifyContent: "flex-end"
45
+ } : {},
46
+ ...$showPromptSuggestions ? {
47
+ "& div.pf-chatbot__prompt-suggestions": {
48
+ flexDirection: "column !important"
49
+ }
50
+ } : {}
51
+ })
52
+ );
53
+ const DisclaimerAlert = styled(Alert)({
54
+ background: "unset !important"
55
+ });
65
56
  const LightspeedChatBox = forwardRef(
66
57
  ({
67
58
  userName,
@@ -71,11 +62,9 @@ const LightspeedChatBox = forwardRef(
71
62
  profileLoading,
72
63
  welcomePrompts,
73
64
  isStreaming,
74
- topicRestrictionEnabled,
75
65
  displayMode,
76
66
  showSourcesChipPopover: showSourcesChipModal = false
77
67
  }, ref) => {
78
- const classes = useStyles();
79
68
  const scrollQueued = useRef(false);
80
69
  const containerRef = useRef(null);
81
70
  const { t } = useTranslation();
@@ -115,24 +104,16 @@ const LightspeedChatBox = forwardRef(
115
104
  scrollQueued.current = false;
116
105
  };
117
106
  }, [autoScroll, cmessages, containerRef]);
118
- const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;
119
107
  const isEmbeddedMode = displayMode === ChatbotDisplayMode.embedded;
120
108
  const isNewChat = welcomePrompts.length > 0 && messages.length === 0;
121
- const getMessageBoxClassName = () => {
122
- const base = isNewChat ? `${messageBoxClasses} ${classes.messageBoxAutoHeight}` : `${messageBoxClasses} ${classes.messageBoxFlex}`;
123
- if (!welcomePrompts.length) {
124
- return base;
125
- }
126
- const withPrompt = `${base} ${classes.prompt}`;
127
- if (isEmbeddedMode) {
128
- return withPrompt;
129
- }
130
- return `${withPrompt} ${classes.promptSuggestions}`;
131
- };
109
+ const hasWelcomePrompts = welcomePrompts.length > 0;
110
+ const showPromptSuggestions = hasWelcomePrompts && !isEmbeddedMode;
132
111
  return /* @__PURE__ */ jsxs(
133
- MessageBox,
112
+ StyledMessageBox,
134
113
  {
135
- className: getMessageBoxClassName(),
114
+ $isNewChat: isNewChat,
115
+ $hasWelcomePrompts: hasWelcomePrompts,
116
+ $showPromptSuggestions: showPromptSuggestions,
136
117
  announcement,
137
118
  ref: containerRef,
138
119
  onScrollToTopClick: scrollToTop,
@@ -143,16 +124,7 @@ const LightspeedChatBox = forwardRef(
143
124
  jumpButtonTopTooltipProps: { content: t("tooltip.backToTop") },
144
125
  children: [
145
126
  /* @__PURE__ */ jsxs("div", { children: [
146
- /* @__PURE__ */ jsx(
147
- Alert,
148
- {
149
- title: t("aria.important"),
150
- variant: "info",
151
- isInline: true,
152
- className: classes.alert,
153
- children: topicRestrictionEnabled ? t("disclaimer.withValidation") : t("disclaimer.withoutValidation")
154
- }
155
- ),
127
+ /* @__PURE__ */ jsx(DisclaimerAlert, { title: t("aria.important"), variant: "info", isInline: true, children: t("disclaimer") }),
156
128
  /* @__PURE__ */ jsx("br", {})
157
129
  ] }),
158
130
  welcomePrompts.length ? /* @__PURE__ */ jsx(
@@ -181,7 +153,7 @@ const LightspeedChatBox = forwardRef(
181
153
  cardBodyProps: {
182
154
  id: `deep-thinking-${index}`,
183
155
  style: { whiteSpace: "pre-line" },
184
- className: parsedReasoning.isReasoningInProgress ? classes.deepThinking : void 0
156
+ className: parsedReasoning.isReasoningInProgress ? DEEP_THINKING_CLASS : void 0
185
157
  },
186
158
  toggleContent: t("reasoning.thinking"),
187
159
  body: reasoningContent,
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatBox.esm.js","sources":["../../src/components/LightspeedChatBox.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\n\nimport { makeStyles } from '@material-ui/core';\nimport {\n ChatbotDisplayMode,\n ChatbotWelcomePrompt,\n DeepThinking,\n DeepThinkingProps,\n Message,\n MessageBox,\n MessageBoxHandle,\n MessageProps,\n ToolCall as PatternFlyToolCall,\n WelcomePrompt,\n} from '@patternfly/chatbot';\nimport { Alert } from '@patternfly/react-core';\n\nimport { useAutoScroll } from '../hooks/useAutoScroll';\nimport { useBufferedMessages } from '../hooks/useBufferedMessages';\nimport { useFeedbackActions } from '../hooks/useFeedbackActions';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { ToolCall } from '../types';\nimport { parseReasoning } from '../utils/reasoningParser';\nimport { mapToPatternFlyToolCall } from '../utils/toolCallMapper';\nimport { SourcesChipModal } from './SourcesChipModal';\n\nconst useStyles = makeStyles(theme => ({\n prompt: {\n 'justify-content': 'flex-end',\n },\n container: {\n maxWidth: 'unset !important',\n },\n alert: {\n background: 'unset !important',\n },\n promptSuggestions: {\n '& div.pf-chatbot__prompt-suggestions': {\n 'flex-direction': 'column !important',\n },\n },\n\n userMessageText: {\n '& div.pf-chatbot__message--user': {\n '& div.pf-chatbot__message-text': {\n '& p': {\n color: theme.palette.common.white,\n },\n },\n },\n },\n deepThinking: {\n animation: '$deepThinking 1.6s ease-in-out infinite',\n },\n\n '@keyframes deepThinking': {\n '0%': {\n opacity: 0.65,\n },\n '50%': {\n opacity: 1,\n },\n '100%': {\n opacity: 0.65,\n },\n },\n // Message box fills remaining height and scrolls when there are messages.\n messageBoxFlex: {\n flex: 1,\n minHeight: 0,\n },\n // New chat: message box sizes to content so ChatbotContent is the scroll container.\n // overflow: visible so full height is included in parent's scrollHeight (no clipping).\n messageBoxAutoHeight: {\n flex: 'none',\n height: 'auto',\n overflow: 'visible',\n },\n}));\n\n// Extended message type that includes tool calls\ninterface ExtendedMessageProps extends MessageProps {\n toolCalls?: ToolCall[];\n}\n\ntype LightspeedChatBoxProps = {\n userName?: string;\n messages: ExtendedMessageProps[];\n profileLoading: boolean;\n announcement: string | undefined;\n topicRestrictionEnabled: boolean;\n welcomePrompts: WelcomePrompt[];\n conversationId: string;\n isStreaming: boolean;\n displayMode?: ChatbotDisplayMode;\n /** When true, sources are shown as a compact chip + popover instead of the inline SourcesCard. */\n showSourcesChipPopover?: boolean;\n};\n\nexport interface ScrollContainerHandle {\n scrollToBottom: () => void;\n}\n\nexport const LightspeedChatBox = forwardRef(\n (\n {\n userName,\n messages,\n announcement,\n conversationId,\n profileLoading,\n welcomePrompts,\n isStreaming,\n topicRestrictionEnabled,\n displayMode,\n showSourcesChipPopover: showSourcesChipModal = false,\n }: LightspeedChatBoxProps,\n ref: ForwardedRef<ScrollContainerHandle | null>,\n ) => {\n const classes = useStyles();\n const scrollQueued = useRef(false);\n const containerRef = useRef<MessageBoxHandle>(null);\n const { t } = useTranslation();\n\n const cmessages = useBufferedMessages(messages, 30);\n const { autoScroll, scrollToBottom, scrollToTop } =\n useAutoScroll(containerRef);\n const conversationMessages = useFeedbackActions(\n cmessages,\n conversationId,\n isStreaming,\n );\n\n useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n if (scrollQueued.current) return;\n scrollQueued.current = true;\n\n requestAnimationFrame(() => {\n scrollToBottom();\n scrollQueued.current = false;\n });\n },\n }));\n\n // Auto-scrolls to the latest message\n useEffect(() => {\n if (!autoScroll || scrollQueued.current) return undefined;\n\n scrollQueued.current = true;\n\n const rafId = requestAnimationFrame(() => {\n const container = containerRef.current;\n if (!container) return;\n\n setTimeout(() => {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'auto',\n });\n }, 0);\n\n scrollQueued.current = false;\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n scrollQueued.current = false;\n };\n\n // eslint-disable-next-line\n }, [autoScroll, cmessages, containerRef]);\n\n const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;\n const isEmbeddedMode = displayMode === ChatbotDisplayMode.embedded;\n\n const isNewChat = welcomePrompts.length > 0 && messages.length === 0;\n const getMessageBoxClassName = () => {\n const base = isNewChat\n ? `${messageBoxClasses} ${classes.messageBoxAutoHeight}`\n : `${messageBoxClasses} ${classes.messageBoxFlex}`;\n if (!welcomePrompts.length) {\n return base;\n }\n const withPrompt = `${base} ${classes.prompt}`;\n if (isEmbeddedMode) {\n return withPrompt;\n }\n return `${withPrompt} ${classes.promptSuggestions}`;\n };\n\n return (\n <MessageBox\n className={getMessageBoxClassName()}\n announcement={announcement}\n ref={containerRef}\n onScrollToTopClick={scrollToTop}\n onScrollToBottomClick={scrollToBottom}\n jumpButtonBottomProps={{ 'aria-label': t('aria.scroll.down') }}\n jumpButtonTopProps={{ 'aria-label': t('aria.scroll.up') }}\n jumpButtonBottomTooltipProps={{ content: t('tooltip.backToBottom') }}\n jumpButtonTopTooltipProps={{ content: t('tooltip.backToTop') }}\n >\n <div>\n <Alert\n title={t('aria.important')}\n variant=\"info\"\n isInline\n className={classes.alert}\n >\n {topicRestrictionEnabled\n ? t('disclaimer.withValidation')\n : t('disclaimer.withoutValidation')}\n </Alert>\n <br />\n </div>\n {welcomePrompts.length ? (\n <ChatbotWelcomePrompt\n title={t('chatbox.welcome.greeting' as any, {\n userName: profileLoading\n ? t('user.loading')\n : (userName ?? t('user.guest')),\n })}\n description={t('chatbox.welcome.description')}\n prompts={welcomePrompts}\n style={{ paddingBottom: '0' }}\n />\n ) : (\n <br />\n )}\n {conversationMessages.map((message, index) => {\n const messageContent = message.content as string;\n const parsedReasoning = parseReasoning(messageContent || '');\n\n // Map first tool call to PatternFly's toolCall prop\n const firstToolCall = message.toolCalls?.[0];\n const toolCallProp = firstToolCall\n ? mapToPatternFlyToolCall(firstToolCall, t, message.role)\n : undefined;\n\n // Handle additional tool calls (if any) via extraContent\n const additionalToolCalls = message.toolCalls?.slice(1);\n\n const extraContentParts: {\n beforeMainContent?: React.ReactNode;\n afterMainContent?: React.ReactNode;\n endContent?: React.ReactNode;\n } = {};\n\n let deepThinking: DeepThinkingProps | undefined = undefined;\n\n if (\n parsedReasoning.isReasoningInProgress ||\n parsedReasoning.hasReasoning\n ) {\n const reasoningContent = parsedReasoning.reasoning;\n\n if (reasoningContent) {\n deepThinking = {\n cardBodyProps: {\n id: `deep-thinking-${index}`,\n style: { whiteSpace: 'pre-line' },\n className: parsedReasoning.isReasoningInProgress\n ? classes.deepThinking\n : undefined,\n },\n toggleContent: t('reasoning.thinking'),\n body: reasoningContent,\n isDefaultExpanded: false,\n };\n }\n }\n\n const allToolCalls: React.ReactNode[] = [];\n\n // Add first tool call if it exists\n if (toolCallProp && firstToolCall) {\n allToolCalls.push(\n <div\n key={`tool-${firstToolCall.id}-${firstToolCall.toolName}`}\n style={{ marginTop: '8px' }}\n >\n <PatternFlyToolCall {...toolCallProp} />\n </div>,\n );\n }\n\n // Add additional tool calls\n if (additionalToolCalls && additionalToolCalls.length > 0) {\n additionalToolCalls.forEach(tc => {\n const tcProps = mapToPatternFlyToolCall(tc, t, message.role);\n allToolCalls.push(\n <div\n key={`tool-${tc.id}-${tc.toolName}`}\n style={{ marginTop: '8px' }}\n >\n <PatternFlyToolCall {...tcProps} />\n </div>,\n );\n });\n }\n\n // Show Thinking first, then tool calls\n if (deepThinking || allToolCalls.length > 0) {\n extraContentParts.beforeMainContent = (\n <>\n {deepThinking && <DeepThinking {...deepThinking} />}\n {allToolCalls.length > 0 && (\n <div style={{ marginTop: deepThinking ? '8px' : '0' }}>\n {allToolCalls}\n </div>\n )}\n </>\n );\n }\n\n const messageToPrepare =\n parsedReasoning.hasReasoning ||\n parsedReasoning.isReasoningInProgress\n ? { ...message, content: parsedReasoning.mainContent }\n : message;\n\n let finalMessage = messageToPrepare;\n\n if (showSourcesChipModal) {\n const { sources: messageSources, ...messageWithoutSources } =\n messageToPrepare;\n\n if (messageSources?.sources?.length) {\n extraContentParts.endContent = (\n <SourcesChipModal sources={messageSources} />\n );\n }\n\n finalMessage = messageWithoutSources;\n }\n\n const extraContent =\n extraContentParts.beforeMainContent ||\n extraContentParts.afterMainContent ||\n extraContentParts.endContent\n ? extraContentParts\n : undefined;\n\n return (\n <Message\n key={`${message.role}-${index}`}\n extraContent={extraContent}\n {...finalMessage}\n />\n );\n })}\n </MessageBox>\n );\n },\n);\n"],"names":["PatternFlyToolCall"],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedChatBox.esm.js","sources":["../../src/components/LightspeedChatBox.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ForwardedRef,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\n\nimport { keyframes, styled } from '@mui/material/styles';\nimport {\n ChatbotDisplayMode,\n ChatbotWelcomePrompt,\n DeepThinking,\n DeepThinkingProps,\n Message,\n MessageBox,\n MessageBoxHandle,\n MessageProps,\n ToolCall as PatternFlyToolCall,\n WelcomePrompt,\n} from '@patternfly/chatbot';\nimport { Alert } from '@patternfly/react-core';\n\nimport { useAutoScroll } from '../hooks/useAutoScroll';\nimport { useBufferedMessages } from '../hooks/useBufferedMessages';\nimport { useFeedbackActions } from '../hooks/useFeedbackActions';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { ToolCall } from '../types';\nimport { parseReasoning } from '../utils/reasoningParser';\nimport { mapToPatternFlyToolCall } from '../utils/toolCallMapper';\nimport { SourcesChipModal } from './SourcesChipModal';\n\nconst DEEP_THINKING_CLASS = 'lightspeed-deep-thinking';\n\nconst deepThinkingPulse = keyframes`\n 0% { opacity: 0.65 }\n 50% { opacity: 1 }\n 100% { opacity: 0.65 }\n`;\n\ntype StyledMessageBoxProps = {\n $isNewChat: boolean;\n $hasWelcomePrompts: boolean;\n $showPromptSuggestions: boolean;\n};\n\nconst StyledMessageBox = styled(MessageBox, {\n shouldForwardProp: prop =>\n prop !== '$isNewChat' &&\n prop !== '$hasWelcomePrompts' &&\n prop !== '$showPromptSuggestions',\n})<StyledMessageBoxProps>(\n ({ theme, $isNewChat, $hasWelcomePrompts, $showPromptSuggestions }) => ({\n maxWidth: 'unset !important',\n [`& .${DEEP_THINKING_CLASS}`]: {\n animation: `${deepThinkingPulse} 1.6s ease-in-out infinite`,\n },\n '& div.pf-chatbot__message--user': {\n '& div.pf-chatbot__message-text': {\n '& p': {\n color: theme.palette.common.white,\n },\n },\n },\n ...($isNewChat\n ? {\n flex: 'none',\n height: 'auto !important',\n overflow: 'visible',\n }\n : {\n flex: 1,\n minHeight: 0,\n }),\n ...($hasWelcomePrompts\n ? {\n justifyContent: 'flex-end',\n }\n : {}),\n ...($showPromptSuggestions\n ? {\n '& div.pf-chatbot__prompt-suggestions': {\n flexDirection: 'column !important',\n },\n }\n : {}),\n }),\n);\n\nconst DisclaimerAlert = styled(Alert)({\n background: 'unset !important',\n});\n\n// Extended message type that includes tool calls\ninterface ExtendedMessageProps extends MessageProps {\n toolCalls?: ToolCall[];\n}\n\ntype LightspeedChatBoxProps = {\n userName?: string;\n messages: ExtendedMessageProps[];\n profileLoading: boolean;\n announcement: string | undefined;\n topicRestrictionEnabled: boolean;\n welcomePrompts: WelcomePrompt[];\n conversationId: string;\n isStreaming: boolean;\n displayMode?: ChatbotDisplayMode;\n /** When true, sources are shown as a compact chip + popover instead of the inline SourcesCard. */\n showSourcesChipPopover?: boolean;\n};\n\nexport interface ScrollContainerHandle {\n scrollToBottom: () => void;\n}\n\nexport const LightspeedChatBox = forwardRef(\n (\n {\n userName,\n messages,\n announcement,\n conversationId,\n profileLoading,\n welcomePrompts,\n isStreaming,\n displayMode,\n showSourcesChipPopover: showSourcesChipModal = false,\n }: LightspeedChatBoxProps,\n ref: ForwardedRef<ScrollContainerHandle | null>,\n ) => {\n const scrollQueued = useRef(false);\n const containerRef = useRef<MessageBoxHandle>(null);\n const { t } = useTranslation();\n\n const cmessages = useBufferedMessages(messages, 30);\n const { autoScroll, scrollToBottom, scrollToTop } =\n useAutoScroll(containerRef);\n const conversationMessages = useFeedbackActions(\n cmessages,\n conversationId,\n isStreaming,\n );\n\n useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n if (scrollQueued.current) return;\n scrollQueued.current = true;\n\n requestAnimationFrame(() => {\n scrollToBottom();\n scrollQueued.current = false;\n });\n },\n }));\n\n // Auto-scrolls to the latest message\n useEffect(() => {\n if (!autoScroll || scrollQueued.current) return undefined;\n\n scrollQueued.current = true;\n\n const rafId = requestAnimationFrame(() => {\n const container = containerRef.current;\n if (!container) return;\n\n setTimeout(() => {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'auto',\n });\n }, 0);\n\n scrollQueued.current = false;\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n scrollQueued.current = false;\n };\n\n // eslint-disable-next-line\n }, [autoScroll, cmessages, containerRef]);\n\n const isEmbeddedMode = displayMode === ChatbotDisplayMode.embedded;\n const isNewChat = welcomePrompts.length > 0 && messages.length === 0;\n const hasWelcomePrompts = welcomePrompts.length > 0;\n const showPromptSuggestions = hasWelcomePrompts && !isEmbeddedMode;\n\n return (\n <StyledMessageBox\n $isNewChat={isNewChat}\n $hasWelcomePrompts={hasWelcomePrompts}\n $showPromptSuggestions={showPromptSuggestions}\n announcement={announcement}\n ref={containerRef}\n onScrollToTopClick={scrollToTop}\n onScrollToBottomClick={scrollToBottom}\n jumpButtonBottomProps={{ 'aria-label': t('aria.scroll.down') }}\n jumpButtonTopProps={{ 'aria-label': t('aria.scroll.up') }}\n jumpButtonBottomTooltipProps={{ content: t('tooltip.backToBottom') }}\n jumpButtonTopTooltipProps={{ content: t('tooltip.backToTop') }}\n >\n <div>\n <DisclaimerAlert title={t('aria.important')} variant=\"info\" isInline>\n {t('disclaimer')}\n </DisclaimerAlert>\n <br />\n </div>\n {welcomePrompts.length ? (\n <ChatbotWelcomePrompt\n title={t('chatbox.welcome.greeting' as any, {\n userName: profileLoading\n ? t('user.loading')\n : (userName ?? t('user.guest')),\n })}\n description={t('chatbox.welcome.description')}\n prompts={welcomePrompts}\n style={{ paddingBottom: '0' }}\n />\n ) : (\n <br />\n )}\n {conversationMessages.map((message, index) => {\n const messageContent = message.content as string;\n const parsedReasoning = parseReasoning(messageContent || '');\n\n // Map first tool call to PatternFly's toolCall prop\n const firstToolCall = message.toolCalls?.[0];\n const toolCallProp = firstToolCall\n ? mapToPatternFlyToolCall(firstToolCall, t, message.role)\n : undefined;\n\n // Handle additional tool calls (if any) via extraContent\n const additionalToolCalls = message.toolCalls?.slice(1);\n\n const extraContentParts: {\n beforeMainContent?: React.ReactNode;\n afterMainContent?: React.ReactNode;\n endContent?: React.ReactNode;\n } = {};\n\n let deepThinking: DeepThinkingProps | undefined = undefined;\n\n if (\n parsedReasoning.isReasoningInProgress ||\n parsedReasoning.hasReasoning\n ) {\n const reasoningContent = parsedReasoning.reasoning;\n\n if (reasoningContent) {\n deepThinking = {\n cardBodyProps: {\n id: `deep-thinking-${index}`,\n style: { whiteSpace: 'pre-line' },\n className: parsedReasoning.isReasoningInProgress\n ? DEEP_THINKING_CLASS\n : undefined,\n },\n toggleContent: t('reasoning.thinking'),\n body: reasoningContent,\n isDefaultExpanded: false,\n };\n }\n }\n\n const allToolCalls: React.ReactNode[] = [];\n\n // Add first tool call if it exists\n if (toolCallProp && firstToolCall) {\n allToolCalls.push(\n <div\n key={`tool-${firstToolCall.id}-${firstToolCall.toolName}`}\n style={{ marginTop: '8px' }}\n >\n <PatternFlyToolCall {...toolCallProp} />\n </div>,\n );\n }\n\n // Add additional tool calls\n if (additionalToolCalls && additionalToolCalls.length > 0) {\n additionalToolCalls.forEach(tc => {\n const tcProps = mapToPatternFlyToolCall(tc, t, message.role);\n allToolCalls.push(\n <div\n key={`tool-${tc.id}-${tc.toolName}`}\n style={{ marginTop: '8px' }}\n >\n <PatternFlyToolCall {...tcProps} />\n </div>,\n );\n });\n }\n\n // Show Thinking first, then tool calls\n if (deepThinking || allToolCalls.length > 0) {\n extraContentParts.beforeMainContent = (\n <>\n {deepThinking && <DeepThinking {...deepThinking} />}\n {allToolCalls.length > 0 && (\n <div style={{ marginTop: deepThinking ? '8px' : '0' }}>\n {allToolCalls}\n </div>\n )}\n </>\n );\n }\n\n const messageToPrepare =\n parsedReasoning.hasReasoning ||\n parsedReasoning.isReasoningInProgress\n ? { ...message, content: parsedReasoning.mainContent }\n : message;\n\n let finalMessage = messageToPrepare;\n\n if (showSourcesChipModal) {\n const { sources: messageSources, ...messageWithoutSources } =\n messageToPrepare;\n\n if (messageSources?.sources?.length) {\n extraContentParts.endContent = (\n <SourcesChipModal sources={messageSources} />\n );\n }\n\n finalMessage = messageWithoutSources;\n }\n\n const extraContent =\n extraContentParts.beforeMainContent ||\n extraContentParts.afterMainContent ||\n extraContentParts.endContent\n ? extraContentParts\n : undefined;\n\n return (\n <Message\n key={`${message.role}-${index}`}\n extraContent={extraContent}\n {...finalMessage}\n />\n );\n })}\n </StyledMessageBox>\n );\n },\n);\n"],"names":["PatternFlyToolCall"],"mappings":"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"}
@@ -1,36 +1,37 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useState } from 'react';
3
- import { makeStyles, createStyles } from '@material-ui/core';
4
3
  import ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';
5
4
  import ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';
6
5
  import Divider from '@mui/material/Divider';
7
- import { ChatbotDisplayMode, ChatbotHeaderActions, ChatbotHeaderOptionsDropdown } from '@patternfly/chatbot';
8
- import { Dropdown, DropdownList, DropdownGroup, DropdownItem, Label, MenuToggle } from '@patternfly/react-core';
9
- import { OutlinedWindowRestoreIcon, OpenDrawerRightIcon, ExpandIcon } from '@patternfly/react-icons';
6
+ import { styled } from '@mui/material/styles';
7
+ import { ChatbotHeaderOptionsDropdown, ChatbotDisplayMode, ChatbotHeaderActions } from '@patternfly/chatbot';
8
+ import { Dropdown, MenuToggle, DropdownGroup, DropdownList, DropdownItem, Label, Icon } from '@patternfly/react-core';
9
+ import { OutlinedWindowRestoreIcon, OpenDrawerRightIcon, ExpandIcon, RhUiEllipsisVerticalFillIcon } from '@patternfly/react-icons';
10
10
  import { useTranslation } from '../hooks/useTranslation.esm.js';
11
11
  import { McpSettingsIcon } from './McpSettingsIcon.esm.js';
12
12
 
13
- const useStyles = makeStyles(
14
- (theme) => createStyles({
15
- dropdown: {
16
- "& ul, & li": {
17
- padding: 0,
18
- margin: 0
19
- }
20
- },
21
- header: {
22
- backgroundColor: theme.palette.action.disabled
23
- },
24
- optionsToggle: {
25
- "& svg": {
26
- transform: "none !important"
27
- }
28
- },
29
- groupTitle: {
30
- fontWeight: "bold"
31
- }
32
- })
33
- );
13
+ const StyledDropdown = styled(Dropdown)({
14
+ "& ul, & li": {
15
+ padding: 0,
16
+ margin: 0
17
+ }
18
+ });
19
+ const StyledOptionsDropdown = styled(ChatbotHeaderOptionsDropdown)({
20
+ "& ul, & li": {
21
+ padding: 0,
22
+ margin: 0
23
+ }
24
+ });
25
+ const SelectorToggle = styled(MenuToggle, {
26
+ shouldForwardProp: (prop) => prop !== "dimmed"
27
+ })(({ theme, dimmed }) => ({
28
+ ...dimmed && {
29
+ backgroundColor: theme.palette.action.disabled
30
+ }
31
+ }));
32
+ const StyledDropdownGroup = styled(DropdownGroup)({
33
+ fontWeight: "bold"
34
+ });
34
35
  const LightspeedChatBoxHeader = ({
35
36
  selectedModel,
36
37
  displayMode,
@@ -46,7 +47,6 @@ const LightspeedChatBoxHeader = ({
46
47
  }) => {
47
48
  const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);
48
49
  const { t } = useTranslation();
49
- const styles = useStyles();
50
50
  const maxLabelLength = Math.max(
51
51
  ...models.map((m) => m.label.length),
52
52
  selectedModel.length,
@@ -54,9 +54,9 @@ const LightspeedChatBoxHeader = ({
54
54
  );
55
55
  const toggleMinWidth = `${maxLabelLength + 4}ch`;
56
56
  const toggle = (toggleRef) => /* @__PURE__ */ jsx(
57
- MenuToggle,
57
+ SelectorToggle,
58
58
  {
59
- className: isModelSelectorDisabled ? styles.header : "",
59
+ dimmed: isModelSelectorDisabled,
60
60
  variant: "secondary",
61
61
  "aria-label": t("aria.chatbotSelector"),
62
62
  ref: toggleRef,
@@ -84,9 +84,8 @@ const LightspeedChatBoxHeader = ({
84
84
  const isModelDropdownScrollable = models.length > scrollThreshold;
85
85
  return /* @__PURE__ */ jsxs(ChatbotHeaderActions, { children: [
86
86
  !hideModelSelector && /* @__PURE__ */ jsx(
87
- Dropdown,
87
+ StyledDropdown,
88
88
  {
89
- className: styles.dropdown,
90
89
  isOpen: isOptionsMenuOpen,
91
90
  onSelect: (_e, value) => {
92
91
  handleSelectedModel(value);
@@ -99,7 +98,7 @@ const LightspeedChatBoxHeader = ({
99
98
  toggle,
100
99
  isScrollable: isModelDropdownScrollable,
101
100
  maxMenuHeight: isModelDropdownScrollable ? "240px" : void 0,
102
- children: /* @__PURE__ */ jsx(DropdownList, { children: models.map((model) => /* @__PURE__ */ jsx(DropdownGroup, { className: styles.groupTitle, children: /* @__PURE__ */ jsx(
101
+ children: /* @__PURE__ */ jsx(DropdownList, { children: models.map((model) => /* @__PURE__ */ jsx(StyledDropdownGroup, { children: /* @__PURE__ */ jsx(
103
102
  DropdownItem,
104
103
  {
105
104
  value: model.value,
@@ -111,14 +110,19 @@ const LightspeedChatBoxHeader = ({
111
110
  }
112
111
  ),
113
112
  /* @__PURE__ */ jsxs(
114
- ChatbotHeaderOptionsDropdown,
113
+ StyledOptionsDropdown,
115
114
  {
116
- className: styles.dropdown,
117
115
  isCompact: true,
118
116
  shouldFocusFirstItemOnOpen: false,
117
+ popperProps: {
118
+ position: "right",
119
+ preventOverflow: true,
120
+ appendTo: () => document.body
121
+ },
119
122
  toggleProps: {
120
123
  "aria-label": t("aria.options.label"),
121
- className: styles.optionsToggle
124
+ className: "pf-chatbot__button--toggle-options pf-m-compact",
125
+ icon: /* @__PURE__ */ jsx(Icon, { size: "lg", isInline: true, children: /* @__PURE__ */ jsx(RhUiEllipsisVerticalFillIcon, {}) })
122
126
  },
123
127
  tooltipProps: {
124
128
  trigger: "manual",
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n Label,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n} from '@patternfly/react-icons';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { McpSettingsIcon } from './McpSettingsIcon';\n\ntype LightspeedChatBoxHeaderProps = {\n displayMode: ChatbotDisplayMode;\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string; provider: string }[];\n isPinningChatsEnabled: boolean;\n onPinnedChatsToggle: (state: boolean) => void;\n onMcpSettingsClick: () => void;\n isModelSelectorDisabled?: boolean;\n hideModelSelector?: boolean;\n /** When false, omits pinned-chats and MCP entries (Chat tab only). */\n showChatTabOptions?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst useStyles = makeStyles(theme =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n header: {\n backgroundColor: theme.palette.action.disabled,\n },\n optionsToggle: {\n '& svg': {\n transform: 'none !important',\n },\n },\n groupTitle: {\n fontWeight: 'bold',\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n onMcpSettingsClick,\n isModelSelectorDisabled = false,\n hideModelSelector = false,\n showChatTabOptions = true,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n const maxLabelLength = Math.max(\n ...models.map(m => m.label.length),\n selectedModel.length,\n 1,\n );\n const toggleMinWidth = `${maxLabelLength + 4}ch`;\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n className={isModelSelectorDisabled ? styles.header : ''}\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n isDisabled={isModelSelectorDisabled}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n style={{ minWidth: toggleMinWidth }}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n const handlePinningChatsToggle = (state: boolean) => {\n onPinnedChatsToggle(state);\n };\n\n const handleDockedToWindow = () => {\n setDisplayMode(ChatbotDisplayMode.docked);\n };\n\n const handleFullscreen = () => {\n setDisplayMode(ChatbotDisplayMode.embedded);\n };\n\n const handleOverlay = () => {\n setDisplayMode(ChatbotDisplayMode.default);\n };\n\n const isOverlayMode = displayMode === ChatbotDisplayMode.default;\n const scrollThreshold = isOverlayMode ? 8 : 10;\n const isModelDropdownScrollable = models.length > scrollThreshold;\n\n return (\n <ChatbotHeaderActions>\n {!hideModelSelector && (\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n isScrollable={isModelDropdownScrollable}\n maxMenuHeight={isModelDropdownScrollable ? '240px' : undefined}\n >\n <DropdownList>\n {models.map(model => (\n <DropdownGroup className={styles.groupTitle} key={model.label}>\n <DropdownItem\n value={model.value}\n key={model.value}\n isSelected={selectedModel === model.value}\n >\n {model.label}\n </DropdownItem>\n </DropdownGroup>\n ))}\n </DropdownList>\n </Dropdown>\n )}\n <ChatbotHeaderOptionsDropdown\n className={styles.dropdown}\n isCompact\n shouldFocusFirstItemOnOpen={false}\n toggleProps={{\n 'aria-label': t('aria.options.label'),\n className: styles.optionsToggle,\n }}\n tooltipProps={{\n trigger: 'manual',\n content: '',\n }}\n >\n <DropdownGroup>\n <DropdownList>\n <DropdownItem key=\"displayModeLabel\" isDisabled>\n {t('settings.displayMode.label')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.default}\n key=\"switchDisplayOverlay\"\n icon={<OutlinedWindowRestoreIcon />}\n onClick={handleOverlay}\n isSelected={displayMode === ChatbotDisplayMode.default}\n >\n {t('settings.displayMode.overlay')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.docked}\n key=\"switchDisplayDock\"\n icon={<OpenDrawerRightIcon />}\n onClick={handleDockedToWindow}\n isSelected={displayMode === ChatbotDisplayMode.docked}\n >\n {t('settings.displayMode.docked')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.embedded}\n key=\"switchDisplayFullscreen\"\n icon={<ExpandIcon />}\n onClick={handleFullscreen}\n isSelected={displayMode === ChatbotDisplayMode.embedded}\n >\n {t('settings.displayMode.fullscreen')}\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n {showChatTabOptions && (\n <>\n <Divider />\n <DropdownGroup>\n <DropdownList>\n {isPinningChatsEnabled ? (\n <DropdownItem\n value=\"disablePinningChats\"\n key=\"disablePinningChat\"\n icon={<ToggleOnOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.enabled.description')}\n onClick={() => handlePinningChatsToggle(false)}\n >\n {t('settings.pinned.disable')}\n </DropdownItem>\n ) : (\n <DropdownItem\n value=\"enablePinningChats\"\n key=\"enablePinningChats\"\n icon={<ToggleOffOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.disabled.description')}\n onClick={() => handlePinningChatsToggle(true)}\n >\n {t('settings.pinned.enable')}\n </DropdownItem>\n )}\n <DropdownItem\n value=\"mcpSettings\"\n key=\"mcpSettings\"\n icon={<McpSettingsIcon />}\n onClick={onMcpSettingsClick}\n >\n {t('settings.mcp.label')}\n <Label color=\"purple\" isCompact style={{ marginLeft: 8 }}>\n {t('settings.mcp.badge')}\n </Label>\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n </>\n )}\n </ChatbotHeaderOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useState } from 'react';\n\nimport ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';\nimport ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';\nimport Divider from '@mui/material/Divider';\nimport { styled } from '@mui/material/styles';\nimport {\n ChatbotDisplayMode,\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n Icon,\n Label,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport {\n ExpandIcon,\n OpenDrawerRightIcon,\n OutlinedWindowRestoreIcon,\n RhUiEllipsisVerticalFillIcon,\n} from '@patternfly/react-icons';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { McpSettingsIcon } from './McpSettingsIcon';\n\ntype LightspeedChatBoxHeaderProps = {\n displayMode: ChatbotDisplayMode;\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string; provider: string }[];\n isPinningChatsEnabled: boolean;\n onPinnedChatsToggle: (state: boolean) => void;\n onMcpSettingsClick: () => void;\n isModelSelectorDisabled?: boolean;\n hideModelSelector?: boolean;\n /** When false, omits pinned-chats and MCP entries (Chat tab only). */\n showChatTabOptions?: boolean;\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n};\n\nconst StyledDropdown = styled(Dropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst StyledOptionsDropdown = styled(ChatbotHeaderOptionsDropdown)({\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n});\n\nconst SelectorToggle = styled(MenuToggle, {\n shouldForwardProp: prop => prop !== 'dimmed',\n})<{ dimmed?: boolean }>(({ theme, dimmed }) => ({\n ...(dimmed && {\n backgroundColor: theme.palette.action.disabled,\n }),\n}));\n\nconst StyledDropdownGroup = styled(DropdownGroup)({\n fontWeight: 'bold',\n});\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n displayMode,\n handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n onMcpSettingsClick,\n isModelSelectorDisabled = false,\n hideModelSelector = false,\n showChatTabOptions = true,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const maxLabelLength = Math.max(\n ...models.map(m => m.label.length),\n selectedModel.length,\n 1,\n );\n const toggleMinWidth = `${maxLabelLength + 4}ch`;\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <SelectorToggle\n dimmed={isModelSelectorDisabled}\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n isDisabled={isModelSelectorDisabled}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n style={{ minWidth: toggleMinWidth }}\n >\n {selectedModel}\n </SelectorToggle>\n );\n\n const handlePinningChatsToggle = (state: boolean) => {\n onPinnedChatsToggle(state);\n };\n\n const handleDockedToWindow = () => {\n setDisplayMode(ChatbotDisplayMode.docked);\n };\n\n const handleFullscreen = () => {\n setDisplayMode(ChatbotDisplayMode.embedded);\n };\n\n const handleOverlay = () => {\n setDisplayMode(ChatbotDisplayMode.default);\n };\n\n const isOverlayMode = displayMode === ChatbotDisplayMode.default;\n const scrollThreshold = isOverlayMode ? 8 : 10;\n const isModelDropdownScrollable = models.length > scrollThreshold;\n\n return (\n <ChatbotHeaderActions>\n {!hideModelSelector && (\n <StyledDropdown\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n isScrollable={isModelDropdownScrollable}\n maxMenuHeight={isModelDropdownScrollable ? '240px' : undefined}\n >\n <DropdownList>\n {models.map(model => (\n <StyledDropdownGroup key={model.label}>\n <DropdownItem\n value={model.value}\n key={model.value}\n isSelected={selectedModel === model.value}\n >\n {model.label}\n </DropdownItem>\n </StyledDropdownGroup>\n ))}\n </DropdownList>\n </StyledDropdown>\n )}\n <StyledOptionsDropdown\n isCompact\n shouldFocusFirstItemOnOpen={false}\n popperProps={{\n position: 'right',\n preventOverflow: true,\n appendTo: () => document.body,\n }}\n toggleProps={{\n 'aria-label': t('aria.options.label'),\n className: 'pf-chatbot__button--toggle-options pf-m-compact',\n icon: (\n <Icon size=\"lg\" isInline>\n <RhUiEllipsisVerticalFillIcon />\n </Icon>\n ),\n }}\n tooltipProps={{\n trigger: 'manual',\n content: '',\n }}\n >\n <DropdownGroup>\n <DropdownList>\n <DropdownItem key=\"displayModeLabel\" isDisabled>\n {t('settings.displayMode.label')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.default}\n key=\"switchDisplayOverlay\"\n icon={<OutlinedWindowRestoreIcon />}\n onClick={handleOverlay}\n isSelected={displayMode === ChatbotDisplayMode.default}\n >\n {t('settings.displayMode.overlay')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.docked}\n key=\"switchDisplayDock\"\n icon={<OpenDrawerRightIcon />}\n onClick={handleDockedToWindow}\n isSelected={displayMode === ChatbotDisplayMode.docked}\n >\n {t('settings.displayMode.docked')}\n </DropdownItem>\n <DropdownItem\n value={ChatbotDisplayMode.embedded}\n key=\"switchDisplayFullscreen\"\n icon={<ExpandIcon />}\n onClick={handleFullscreen}\n isSelected={displayMode === ChatbotDisplayMode.embedded}\n >\n {t('settings.displayMode.fullscreen')}\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n {showChatTabOptions && (\n <>\n <Divider />\n <DropdownGroup>\n <DropdownList>\n {isPinningChatsEnabled ? (\n <DropdownItem\n value=\"disablePinningChats\"\n key=\"disablePinningChat\"\n icon={<ToggleOnOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.enabled.description')}\n onClick={() => handlePinningChatsToggle(false)}\n >\n {t('settings.pinned.disable')}\n </DropdownItem>\n ) : (\n <DropdownItem\n value=\"enablePinningChats\"\n key=\"enablePinningChats\"\n icon={<ToggleOffOutlinedIcon sx={{ marginTop: '8px' }} />}\n description={t('settings.pinned.disabled.description')}\n onClick={() => handlePinningChatsToggle(true)}\n >\n {t('settings.pinned.enable')}\n </DropdownItem>\n )}\n <DropdownItem\n value=\"mcpSettings\"\n key=\"mcpSettings\"\n icon={<McpSettingsIcon />}\n onClick={onMcpSettingsClick}\n >\n {t('settings.mcp.label')}\n <Label color=\"purple\" isCompact style={{ marginLeft: 8 }}>\n {t('settings.mcp.badge')}\n </Label>\n </DropdownItem>\n </DropdownList>\n </DropdownGroup>\n </>\n )}\n </StyledOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -4,16 +4,14 @@ import '@patternfly/chatbot/dist/css/main.css';
4
4
  import { useState, useMemo, useLayoutEffect, useEffect } from 'react';
5
5
  import { useAsync } from 'react-use';
6
6
  import { useApi, identityApiRef } from '@backstage/core-plugin-api';
7
- import { Button } from '@material-ui/core';
8
- import { StylesProvider as StylesProvider$1, useTheme } from '@material-ui/core/styles';
9
7
  import OpenInNewIcon from '@mui/icons-material/OpenInNew';
10
- import { StylesProvider } from '@mui/styles';
8
+ import Button from '@mui/material/Button';
9
+ import { useTheme } from '@mui/material/styles';
11
10
  import { QueryClientProvider } from '@tanstack/react-query';
12
11
  import { useAllModels } from '../hooks/useAllModels.esm.js';
13
12
  import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
14
13
  import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
15
14
  import { useTranslation } from '../hooks/useTranslation.esm.js';
16
- import { generateClassName, generateClassNameV4 } from '../utils/generateClassName.esm.js';
17
15
  import queryClient from '../utils/queryClient.esm.js';
18
16
  import FileAttachmentContextProvider from './AttachmentContext.esm.js';
19
17
  import { LightspeedChat } from './LightSpeedChat.esm.js';
@@ -25,7 +23,7 @@ const THEME_DARK_CLASS = "pf-v6-theme-dark";
25
23
  const LAST_SELECTED_MODEL_KEY = "lastSelectedModel";
26
24
  const LightspeedChatContainerInner = () => {
27
25
  const {
28
- palette: { type }
26
+ palette: { mode }
29
27
  } = useTheme();
30
28
  const { t } = useTranslation();
31
29
  const identityApi = useApi(identityApiRef);
@@ -56,12 +54,12 @@ const LightspeedChatContainerInner = () => {
56
54
  );
57
55
  useLayoutEffect(() => {
58
56
  const htmlTagElement = document.documentElement;
59
- if (type === THEME_DARK) {
57
+ if (mode === THEME_DARK) {
60
58
  htmlTagElement.classList.add(THEME_DARK_CLASS);
61
59
  } else {
62
60
  htmlTagElement.classList.remove(THEME_DARK_CLASS);
63
61
  }
64
- }, [type]);
62
+ }, [mode]);
65
63
  useEffect(() => {
66
64
  if (modelsItems.length > 0) {
67
65
  try {
@@ -158,7 +156,7 @@ const LightspeedChatContainerInner = () => {
158
156
  ) });
159
157
  };
160
158
  const LightspeedChatContainer = () => {
161
- return /* @__PURE__ */ jsx(StylesProvider, { generateClassName, children: /* @__PURE__ */ jsx(StylesProvider$1, { generateClassName: generateClassNameV4, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(LightspeedChatContainerInner, {}) }) }) });
159
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(LightspeedChatContainerInner, {}) });
162
160
  };
163
161
 
164
162
  export { LightspeedChatContainer };
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatContainer.esm.js","sources":["../../src/components/LightspeedChatContainer.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@patternfly/react-core/dist/styles/base-no-reset.css';\nimport '@patternfly/chatbot/dist/css/main.css';\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { Button } from '@material-ui/core';\nimport {\n StylesProvider as StylesProviderV4,\n useTheme,\n} from '@material-ui/core/styles';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport { StylesProvider } from '@mui/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport { useTranslation } from '../hooks/useTranslation';\nimport {\n generateClassName,\n generateClassNameV4,\n} from '../utils/generateClassName';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport {\n LcoreNotConfiguredEmptyState,\n LightspeedChatModelsLoading,\n ModelsLoadErrorEmptyState,\n} from './LightspeedChatModelsState';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\nconst LAST_SELECTED_MODEL_KEY = 'lastSelectedModel';\n\n/**\n * Inner component that contains all the Lightspeed chat rendering logic\n */\nconst LightspeedChatContainerInner = () => {\n const {\n palette: { type },\n } = useTheme();\n const { t } = useTranslation();\n\n const identityApi = useApi(identityApiRef);\n\n const {\n data: models,\n isLoading: modelsLoading,\n isError: modelsError,\n refetch: refetchModels,\n } = useAllModels();\n\n const {\n allowed: hasViewAccess,\n loading,\n iaChatPermissionName,\n } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n const [selectedProvider, setSelectedProvider] = useState('');\n\n const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();\n\n const modelsItems = useMemo(\n () =>\n models\n ? models\n .filter(model => model.model_type === 'llm')\n .map(m => ({\n label: m.provider_resource_id,\n value: m.provider_resource_id,\n provider: m.provider_id,\n }))\n : [],\n [models],\n );\n\n useLayoutEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [type]);\n\n // Load last selected model from localStorage\n useEffect(() => {\n if (modelsItems.length > 0) {\n try {\n const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);\n const parsedData = storedData ? JSON.parse(storedData) : null;\n\n const storedModel = parsedData?.model\n ? modelsItems.find(m => m.value === parsedData.model)\n : null;\n\n if (storedModel) {\n setSelectedModel(storedModel.value);\n setSelectedProvider(storedModel.provider);\n } else {\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error loading last selected model from localStorage:',\n error,\n );\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n }\n }, [modelsItems]);\n\n // Save selected model to localStorage\n useEffect(() => {\n if (selectedModel && selectedProvider) {\n try {\n localStorage.setItem(\n LAST_SELECTED_MODEL_KEY,\n JSON.stringify({\n model: selectedModel,\n provider: selectedProvider,\n }),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error saving last selected model to localStorage:',\n error,\n );\n }\n }\n }, [selectedModel, selectedProvider]);\n\n if (loading) {\n // Never return null inside the overlay modal: PatternFly's focus-trap requires at least\n // one tabbable node (e.g. after removing the modal close button). Locale switches can\n // briefly re-enter this loading state.\n return <LightspeedChatModelsLoading />;\n }\n\n if (!hasViewAccess) {\n return (\n <PermissionRequiredState\n subject={t('permission.subject.plugin')}\n permissions={[iaChatPermissionName]}\n action={\n <Button\n variant=\"outlined\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/intelligent-assistant/plugins/intelligent-assistant/README.md#permission-framework-support\"\n >\n {t('common.readMore')} &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n );\n }\n\n if (modelsLoading) {\n return <LightspeedChatModelsLoading />;\n }\n\n // TanStack Query can keep the last successful `data` while `isError` is true after a\n // failed refetch. Prefer showing chat when we still have LLM rows; only use the full-page\n // error state when there is nothing usable to render.\n if (modelsError && modelsItems.length === 0) {\n return <ModelsLoadErrorEmptyState onRetry={() => refetchModels()} />;\n }\n\n if (modelsItems.length === 0) {\n return <LcoreNotConfiguredEmptyState />;\n }\n\n return (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n selectedProvider={selectedProvider}\n topicRestrictionEnabled={topicRestrictionEnabled ?? false}\n handleSelectedModel={item => {\n setSelectedModel(item);\n setSelectedProvider(\n modelsItems.find((m: any) => m.value === item)?.provider || '',\n );\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n );\n};\n\n/**\n * @public\n */\nexport const LightspeedChatContainer = () => {\n return (\n <StylesProvider generateClassName={generateClassName}>\n <StylesProviderV4 generateClassName={generateClassNameV4}>\n <QueryClientProvider client={queryClient}>\n <LightspeedChatContainerInner />\n </QueryClientProvider>\n </StylesProviderV4>\n </StylesProvider>\n );\n};\n"],"names":["StylesProviderV4"],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedChatContainer.esm.js","sources":["../../src/components/LightspeedChatContainer.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@patternfly/react-core/dist/styles/base-no-reset.css';\nimport '@patternfly/chatbot/dist/css/main.css';\n\nimport { useEffect, useLayoutEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport Button from '@mui/material/Button';\nimport { useTheme } from '@mui/material/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport { useTranslation } from '../hooks/useTranslation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport {\n LcoreNotConfiguredEmptyState,\n LightspeedChatModelsLoading,\n ModelsLoadErrorEmptyState,\n} from './LightspeedChatModelsState';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\nconst LAST_SELECTED_MODEL_KEY = 'lastSelectedModel';\n\n/**\n * Inner component that contains all the Lightspeed chat rendering logic\n */\nconst LightspeedChatContainerInner = () => {\n const {\n palette: { mode },\n } = useTheme();\n const { t } = useTranslation();\n\n const identityApi = useApi(identityApiRef);\n\n const {\n data: models,\n isLoading: modelsLoading,\n isError: modelsError,\n refetch: refetchModels,\n } = useAllModels();\n\n const {\n allowed: hasViewAccess,\n loading,\n iaChatPermissionName,\n } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n const [selectedProvider, setSelectedProvider] = useState('');\n\n const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();\n\n const modelsItems = useMemo(\n () =>\n models\n ? models\n .filter(model => model.model_type === 'llm')\n .map(m => ({\n label: m.provider_resource_id,\n value: m.provider_resource_id,\n provider: m.provider_id,\n }))\n : [],\n [models],\n );\n\n useLayoutEffect(() => {\n const htmlTagElement = document.documentElement;\n if (mode === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n }, [mode]);\n\n // Load last selected model from localStorage\n useEffect(() => {\n if (modelsItems.length > 0) {\n try {\n const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);\n const parsedData = storedData ? JSON.parse(storedData) : null;\n\n const storedModel = parsedData?.model\n ? modelsItems.find(m => m.value === parsedData.model)\n : null;\n\n if (storedModel) {\n setSelectedModel(storedModel.value);\n setSelectedProvider(storedModel.provider);\n } else {\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error loading last selected model from localStorage:',\n error,\n );\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n }\n }, [modelsItems]);\n\n // Save selected model to localStorage\n useEffect(() => {\n if (selectedModel && selectedProvider) {\n try {\n localStorage.setItem(\n LAST_SELECTED_MODEL_KEY,\n JSON.stringify({\n model: selectedModel,\n provider: selectedProvider,\n }),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\n 'Error saving last selected model to localStorage:',\n error,\n );\n }\n }\n }, [selectedModel, selectedProvider]);\n\n if (loading) {\n // Never return null inside the overlay modal: PatternFly's focus-trap requires at least\n // one tabbable node (e.g. after removing the modal close button). Locale switches can\n // briefly re-enter this loading state.\n return <LightspeedChatModelsLoading />;\n }\n\n if (!hasViewAccess) {\n return (\n <PermissionRequiredState\n subject={t('permission.subject.plugin')}\n permissions={[iaChatPermissionName]}\n action={\n <Button\n variant=\"outlined\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/intelligent-assistant/plugins/intelligent-assistant/README.md#permission-framework-support\"\n >\n {t('common.readMore')} &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n );\n }\n\n if (modelsLoading) {\n return <LightspeedChatModelsLoading />;\n }\n\n // TanStack Query can keep the last successful `data` while `isError` is true after a\n // failed refetch. Prefer showing chat when we still have LLM rows; only use the full-page\n // error state when there is nothing usable to render.\n if (modelsError && modelsItems.length === 0) {\n return <ModelsLoadErrorEmptyState onRetry={() => refetchModels()} />;\n }\n\n if (modelsItems.length === 0) {\n return <LcoreNotConfiguredEmptyState />;\n }\n\n return (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n selectedProvider={selectedProvider}\n topicRestrictionEnabled={topicRestrictionEnabled ?? false}\n handleSelectedModel={item => {\n setSelectedModel(item);\n setSelectedProvider(\n modelsItems.find((m: any) => m.value === item)?.provider || '',\n );\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n );\n};\n\n/**\n * @public\n */\nexport const LightspeedChatContainer = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedChatContainerInner />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}