@red-hat-developer-hub/backstage-plugin-lightspeed 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +26 -20
  3. package/dist/alpha.d.ts +24 -0
  4. package/dist/api/LightspeedApiClient.esm.js.map +1 -1
  5. package/dist/api/api.esm.js.map +1 -1
  6. package/dist/components/AttachmentContext.esm.js +12 -2
  7. package/dist/components/AttachmentContext.esm.js.map +1 -1
  8. package/dist/components/LightSpeedChat.esm.js +199 -39
  9. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  10. package/dist/components/LightspeedChatBox.esm.js +70 -9
  11. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  12. package/dist/components/LightspeedChatBoxHeader.esm.js +84 -26
  13. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  14. package/dist/components/LightspeedChatContainer.esm.js +118 -0
  15. package/dist/components/LightspeedChatContainer.esm.js.map +1 -0
  16. package/dist/components/LightspeedDrawerContext.esm.js +6 -0
  17. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -0
  18. package/dist/components/LightspeedDrawerProvider.esm.js +175 -0
  19. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -0
  20. package/dist/components/LightspeedDrawerStateExposer.esm.js +28 -0
  21. package/dist/components/LightspeedDrawerStateExposer.esm.js.map +1 -0
  22. package/dist/components/LightspeedFAB.esm.js +68 -0
  23. package/dist/components/LightspeedFAB.esm.js.map +1 -0
  24. package/dist/components/LightspeedIcon.esm.js +23 -2
  25. package/dist/components/LightspeedIcon.esm.js.map +1 -1
  26. package/dist/components/LightspeedPage.esm.js +5 -110
  27. package/dist/components/LightspeedPage.esm.js.map +1 -1
  28. package/dist/components/Router.esm.js +19 -0
  29. package/dist/components/Router.esm.js.map +1 -0
  30. package/dist/components/ToolCallContent.esm.js +217 -0
  31. package/dist/components/ToolCallContent.esm.js.map +1 -0
  32. package/dist/hooks/useConversationMessages.esm.js +136 -20
  33. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  34. package/dist/hooks/useLightspeedDrawerContext.esm.js +15 -0
  35. package/dist/hooks/useLightspeedDrawerContext.esm.js.map +1 -0
  36. package/dist/hooks/usePinnedChatsSettings.esm.js +118 -0
  37. package/dist/hooks/usePinnedChatsSettings.esm.js.map +1 -0
  38. package/dist/hooks/useSortSettings.esm.js +60 -0
  39. package/dist/hooks/useSortSettings.esm.js.map +1 -0
  40. package/dist/images/logo-black.svg +22 -0
  41. package/dist/images/rounded-logo.svg +22 -0
  42. package/dist/index.d.ts +52 -2
  43. package/dist/index.esm.js +4 -1
  44. package/dist/index.esm.js.map +1 -1
  45. package/dist/plugin.esm.js +44 -5
  46. package/dist/plugin.esm.js.map +1 -1
  47. package/dist/routes.esm.js +7 -2
  48. package/dist/routes.esm.js.map +1 -1
  49. package/dist/translations/de.esm.js +29 -1
  50. package/dist/translations/de.esm.js.map +1 -1
  51. package/dist/translations/es.esm.js +29 -1
  52. package/dist/translations/es.esm.js.map +1 -1
  53. package/dist/translations/fr.esm.js +120 -115
  54. package/dist/translations/fr.esm.js.map +1 -1
  55. package/dist/translations/index.esm.js +3 -1
  56. package/dist/translations/index.esm.js.map +1 -1
  57. package/dist/translations/it.esm.js +158 -0
  58. package/dist/translations/it.esm.js.map +1 -0
  59. package/dist/translations/ja.esm.js +158 -0
  60. package/dist/translations/ja.esm.js.map +1 -0
  61. package/dist/translations/ref.esm.js +29 -1
  62. package/dist/translations/ref.esm.js.map +1 -1
  63. package/dist/types.esm.js.map +1 -1
  64. package/dist/utils/lightspeed-chatbox-utils.esm.js +24 -5
  65. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  66. package/dist/utils/reasoningParser.esm.js +46 -0
  67. package/dist/utils/reasoningParser.esm.js.map +1 -0
  68. package/dist/utils/toolCallMapper.esm.js +15 -0
  69. package/dist/utils/toolCallMapper.esm.js.map +1 -0
  70. package/dist/utils/user-utils.esm.js +7 -0
  71. package/dist/utils/user-utils.esm.js.map +1 -0
  72. package/package.json +9 -4
  73. package/app-config.yaml +0 -18
@@ -1,12 +1,14 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { forwardRef, useRef, useImperativeHandle, useEffect, Fragment } from 'react';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { forwardRef, useRef, useImperativeHandle, useEffect } from 'react';
3
3
  import { makeStyles } from '@material-ui/core';
4
- import { MessageBox, ChatbotWelcomePrompt, Message } from '@patternfly/chatbot';
4
+ import { ChatbotDisplayMode, MessageBox, ChatbotWelcomePrompt, DeepThinking, ToolCall, 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';
8
8
  import { useFeedbackActions } from '../hooks/useFeedbackActions.esm.js';
9
9
  import { useTranslation } from '../hooks/useTranslation.esm.js';
10
+ import { parseReasoning } from '../utils/reasoningParser.esm.js';
11
+ import { mapToPatternFlyToolCall } from '../utils/toolCallMapper.esm.js';
10
12
 
11
13
  const useStyles = makeStyles((theme) => ({
12
14
  prompt: {
@@ -18,6 +20,11 @@ const useStyles = makeStyles((theme) => ({
18
20
  alert: {
19
21
  background: "unset !important"
20
22
  },
23
+ promptSuggestions: {
24
+ "& div.pf-chatbot__prompt-suggestions": {
25
+ "flex-direction": "column !important"
26
+ }
27
+ },
21
28
  userMessageText: {
22
29
  "& div.pf-chatbot__message--user": {
23
30
  "& div.pf-chatbot__message-text": {
@@ -37,7 +44,8 @@ const LightspeedChatBox = forwardRef(
37
44
  profileLoading,
38
45
  welcomePrompts,
39
46
  isStreaming,
40
- topicRestrictionEnabled
47
+ topicRestrictionEnabled,
48
+ displayMode
41
49
  }, ref) => {
42
50
  const classes = useStyles();
43
51
  const scrollQueued = useRef(false);
@@ -80,10 +88,21 @@ const LightspeedChatBox = forwardRef(
80
88
  };
81
89
  }, [autoScroll, cmessages, containerRef]);
82
90
  const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;
91
+ const isEmbeddedMode = displayMode === ChatbotDisplayMode.embedded;
92
+ const getMessageBoxClassName = () => {
93
+ if (!welcomePrompts.length) {
94
+ return messageBoxClasses;
95
+ }
96
+ const baseClasses = `${messageBoxClasses} ${classes.prompt}`;
97
+ if (isEmbeddedMode) {
98
+ return baseClasses;
99
+ }
100
+ return `${baseClasses} ${classes.promptSuggestions}`;
101
+ };
83
102
  return /* @__PURE__ */ jsxs(
84
103
  MessageBox,
85
104
  {
86
- className: welcomePrompts.length ? `${messageBoxClasses} ${classes.prompt}` : messageBoxClasses,
105
+ className: getMessageBoxClassName(),
87
106
  announcement,
88
107
  ref: containerRef,
89
108
  onScrollToTopClick: scrollToTop,
@@ -113,14 +132,56 @@ const LightspeedChatBox = forwardRef(
113
132
  userName: profileLoading ? t("user.loading") : userName ?? t("user.guest")
114
133
  }),
115
134
  description: t("chatbox.welcome.description"),
116
- prompts: welcomePrompts
135
+ prompts: welcomePrompts,
136
+ style: { paddingBottom: "0" }
117
137
  }
118
138
  ) : /* @__PURE__ */ jsx("br", {}),
119
139
  conversationMessages.map((message, index) => {
120
- if (index === cmessages.length - 1) {
121
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Message, { ...message }, `${message.role}-${index}`) }, `${message.role}-${index}`);
140
+ const messageContent = message.content;
141
+ const parsedReasoning = parseReasoning(messageContent || "");
142
+ const firstToolCall = message.toolCalls?.[0];
143
+ const toolCallProp = firstToolCall ? mapToPatternFlyToolCall(firstToolCall, t) : undefined;
144
+ const additionalToolCalls = message.toolCalls?.slice(1);
145
+ const extraContentParts = {};
146
+ let deepThinking = undefined;
147
+ if (parsedReasoning.isReasoningInProgress || parsedReasoning.hasReasoning) {
148
+ const reasoningContent = parsedReasoning.reasoning || (() => {
149
+ const reasoningMatch = messageContent.match(/<think>(.*?)$/s);
150
+ return reasoningMatch ? reasoningMatch[1].trim() : "";
151
+ })();
152
+ if (reasoningContent) {
153
+ deepThinking = {
154
+ toggleContent: t("reasoning.thinking"),
155
+ body: reasoningContent,
156
+ expandableSectionProps: {}
157
+ };
158
+ extraContentParts.beforeMainContent = /* @__PURE__ */ jsx(DeepThinking, { ...deepThinking });
159
+ }
160
+ }
161
+ if (additionalToolCalls && additionalToolCalls.length > 0) {
162
+ extraContentParts.afterMainContent = /* @__PURE__ */ jsx(Fragment, { children: additionalToolCalls.map((tc) => {
163
+ const tcProps = mapToPatternFlyToolCall(tc, t);
164
+ return /* @__PURE__ */ jsx(
165
+ "div",
166
+ {
167
+ style: { marginTop: "8px" },
168
+ children: /* @__PURE__ */ jsx(ToolCall, { ...tcProps })
169
+ },
170
+ `tool-${tc.id}-${tc.toolName}`
171
+ );
172
+ }) });
122
173
  }
123
- return /* @__PURE__ */ jsx(Message, { ...message }, `${message.role}-${index}`);
174
+ const extraContent = extraContentParts.beforeMainContent || extraContentParts.afterMainContent ? extraContentParts : undefined;
175
+ const finalMessage = parsedReasoning.hasReasoning || parsedReasoning.isReasoningInProgress ? { ...message, content: parsedReasoning.mainContent } : message;
176
+ return /* @__PURE__ */ jsx(
177
+ Message,
178
+ {
179
+ toolCall: toolCallProp,
180
+ extraContent,
181
+ ...finalMessage
182
+ },
183
+ `${message.role}-${index}`
184
+ );
124
185
  })
125
186
  ]
126
187
  }
@@ -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 Fragment,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\n\nimport { makeStyles } from '@material-ui/core';\nimport {\n ChatbotWelcomePrompt,\n Message,\n MessageBox,\n MessageBoxHandle,\n MessageProps,\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';\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 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}));\n\ntype LightspeedChatBoxProps = {\n userName?: string;\n messages: MessageProps[];\n profileLoading: boolean;\n announcement: string | undefined;\n topicRestrictionEnabled: boolean;\n welcomePrompts: WelcomePrompt[];\n conversationId: string;\n isStreaming: 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 }: LightspeedChatBoxProps,\n ref: ForwardedRef<ScrollContainerHandle>,\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 return (\n <MessageBox\n className={\n welcomePrompts.length\n ? `${messageBoxClasses} ${classes.prompt}`\n : messageBoxClasses\n }\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 />\n ) : (\n <br />\n )}\n {conversationMessages.map((message, index) => {\n if (index === cmessages.length - 1) {\n return (\n <Fragment key={`${message.role}-${index}`}>\n <Message key={`${message.role}-${index}`} {...message} />\n </Fragment>\n );\n }\n return <Message key={`${message.role}-${index}`} {...message} />;\n })}\n </MessageBox>\n );\n },\n);\n"],"names":[],"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 { 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';\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}));\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};\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 }: LightspeedChatBoxProps,\n ref: ForwardedRef<ScrollContainerHandle>,\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 getMessageBoxClassName = () => {\n if (!welcomePrompts.length) {\n return messageBoxClasses;\n }\n const baseClasses = `${messageBoxClasses} ${classes.prompt}`;\n if (isEmbeddedMode) {\n return baseClasses;\n }\n return `${baseClasses} ${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)\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 } = {};\n\n let deepThinking: DeepThinkingProps | undefined = undefined;\n\n if (\n parsedReasoning.isReasoningInProgress ||\n parsedReasoning.hasReasoning\n ) {\n const reasoningContent =\n parsedReasoning.reasoning ||\n (() => {\n const reasoningMatch = messageContent.match(/<think>(.*?)$/s);\n return reasoningMatch ? reasoningMatch[1].trim() : '';\n })();\n\n if (reasoningContent) {\n deepThinking = {\n toggleContent: t('reasoning.thinking'),\n body: reasoningContent,\n expandableSectionProps: {},\n };\n extraContentParts.beforeMainContent = (\n <DeepThinking {...deepThinking} />\n );\n }\n }\n\n if (additionalToolCalls && additionalToolCalls.length > 0) {\n extraContentParts.afterMainContent = (\n <>\n {additionalToolCalls.map(tc => {\n const tcProps = mapToPatternFlyToolCall(tc, t);\n return (\n <div\n key={`tool-${tc.id}-${tc.toolName}`}\n style={{ marginTop: '8px' }}\n >\n <PatternFlyToolCall {...tcProps} />\n </div>\n );\n })}\n </>\n );\n }\n\n const extraContent =\n extraContentParts.beforeMainContent ||\n extraContentParts.afterMainContent\n ? extraContentParts\n : undefined;\n\n const finalMessage =\n parsedReasoning.hasReasoning ||\n parsedReasoning.isReasoningInProgress\n ? { ...message, content: parsedReasoning.mainContent }\n : message;\n\n return (\n <Message\n key={`${message.role}-${index}`}\n toolCall={toolCallProp}\n extraContent={extraContent}\n {...finalMessage}\n />\n );\n })}\n </MessageBox>\n );\n },\n);\n"],"names":["PatternFlyToolCall"],"mappings":"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"}
@@ -3,18 +3,23 @@ import { useState, useMemo } from 'react';
3
3
  import { makeStyles, createStyles } from '@material-ui/core';
4
4
  import ToggleOffOutlinedIcon from '@mui/icons-material/ToggleOffOutlined';
5
5
  import ToggleOnOutlinedIcon from '@mui/icons-material/ToggleOnOutlined';
6
- import { ChatbotHeaderActions, ChatbotHeaderOptionsDropdown } from '@patternfly/chatbot';
7
- import { Dropdown, DropdownList, DropdownGroup, DropdownItem, Divider, MenuToggle } from '@patternfly/react-core';
6
+ import Divider from '@mui/material/Divider';
7
+ import { ChatbotHeaderActions, ChatbotHeaderOptionsDropdown, ChatbotDisplayMode } from '@patternfly/chatbot';
8
+ import { Dropdown, DropdownList, DropdownGroup, DropdownItem, MenuToggle } from '@patternfly/react-core';
9
+ import { OutlinedWindowRestoreIcon, OpenDrawerRightIcon, ExpandIcon } from '@patternfly/react-icons';
8
10
  import { useTranslation } from '../hooks/useTranslation.esm.js';
9
11
 
10
12
  const useStyles = makeStyles(
11
- () => createStyles({
13
+ (theme) => createStyles({
12
14
  dropdown: {
13
15
  "& ul, & li": {
14
16
  padding: 0,
15
17
  margin: 0
16
18
  }
17
19
  },
20
+ header: {
21
+ backgroundColor: theme.palette.action.disabled
22
+ },
18
23
  optionsToggle: {
19
24
  "& svg": {
20
25
  transform: "none !important"
@@ -27,10 +32,13 @@ const useStyles = makeStyles(
27
32
  );
28
33
  const LightspeedChatBoxHeader = ({
29
34
  selectedModel,
35
+ displayMode,
30
36
  handleSelectedModel,
31
37
  models,
32
38
  isPinningChatsEnabled,
33
- onPinnedChatsToggle
39
+ onPinnedChatsToggle,
40
+ isModelSelectorDisabled = false,
41
+ setDisplayMode
34
42
  }) => {
35
43
  const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);
36
44
  const { t } = useTranslation();
@@ -49,10 +57,12 @@ const LightspeedChatBoxHeader = ({
49
57
  const toggle = (toggleRef) => /* @__PURE__ */ jsx(
50
58
  MenuToggle,
51
59
  {
60
+ className: isModelSelectorDisabled ? styles.header : "",
52
61
  variant: "secondary",
53
62
  "aria-label": t("aria.chatbotSelector"),
54
63
  ref: toggleRef,
55
64
  isExpanded: isOptionsMenuOpen,
65
+ isDisabled: isModelSelectorDisabled,
56
66
  onClick: () => setIsOptionsMenuOpen(!isOptionsMenuOpen),
57
67
  children: selectedModel
58
68
  }
@@ -60,6 +70,15 @@ const LightspeedChatBoxHeader = ({
60
70
  const handlePinningChatsToggle = (state) => {
61
71
  onPinnedChatsToggle(state);
62
72
  };
73
+ const handleDockedToWindow = () => {
74
+ setDisplayMode(ChatbotDisplayMode.docked);
75
+ };
76
+ const handleFullscreen = () => {
77
+ setDisplayMode(ChatbotDisplayMode.embedded);
78
+ };
79
+ const handleOverlay = () => {
80
+ setDisplayMode(ChatbotDisplayMode.default);
81
+ };
63
82
  return /* @__PURE__ */ jsxs(ChatbotHeaderActions, { children: [
64
83
  /* @__PURE__ */ jsx(
65
84
  Dropdown,
@@ -92,7 +111,7 @@ const LightspeedChatBoxHeader = ({
92
111
  ) })
93
112
  }
94
113
  ),
95
- /* @__PURE__ */ jsx(
114
+ /* @__PURE__ */ jsxs(
96
115
  ChatbotHeaderOptionsDropdown,
97
116
  {
98
117
  isCompact: true,
@@ -103,27 +122,66 @@ const LightspeedChatBoxHeader = ({
103
122
  tooltipProps: {
104
123
  content: t("tooltip.settings")
105
124
  },
106
- children: /* @__PURE__ */ jsx(DropdownGroup, { children: /* @__PURE__ */ jsx(DropdownList, { children: isPinningChatsEnabled ? /* @__PURE__ */ jsx(
107
- DropdownItem,
108
- {
109
- value: "disablePinningChats",
110
- icon: /* @__PURE__ */ jsx(ToggleOnOutlinedIcon, { sx: { marginTop: "8px" } }),
111
- description: t("settings.pinned.enabled.description"),
112
- onClick: () => handlePinningChatsToggle(false),
113
- children: t("settings.pinned.disable")
114
- },
115
- "disablePinningChat"
116
- ) : /* @__PURE__ */ jsx(
117
- DropdownItem,
118
- {
119
- value: "enablePinningChats",
120
- icon: /* @__PURE__ */ jsx(ToggleOffOutlinedIcon, { sx: { marginTop: "8px" } }),
121
- description: t("settings.pinned.disabled.description"),
122
- onClick: () => handlePinningChatsToggle(true),
123
- children: t("settings.pinned.enable")
124
- },
125
- "enablePinningChats"
126
- ) }) })
125
+ children: [
126
+ /* @__PURE__ */ jsx(DropdownGroup, { children: /* @__PURE__ */ jsxs(DropdownList, { children: [
127
+ /* @__PURE__ */ jsx(DropdownItem, { isDisabled: true, children: t("settings.displayMode.label") }, "displayModeLabel"),
128
+ /* @__PURE__ */ jsx(
129
+ DropdownItem,
130
+ {
131
+ value: ChatbotDisplayMode.default,
132
+ icon: /* @__PURE__ */ jsx(OutlinedWindowRestoreIcon, {}),
133
+ onClick: handleOverlay,
134
+ isSelected: displayMode === ChatbotDisplayMode.default,
135
+ children: t("settings.displayMode.overlay")
136
+ },
137
+ "switchDisplayOverlay"
138
+ ),
139
+ /* @__PURE__ */ jsx(
140
+ DropdownItem,
141
+ {
142
+ value: ChatbotDisplayMode.docked,
143
+ icon: /* @__PURE__ */ jsx(OpenDrawerRightIcon, {}),
144
+ onClick: handleDockedToWindow,
145
+ isSelected: displayMode === ChatbotDisplayMode.docked,
146
+ children: t("settings.displayMode.docked")
147
+ },
148
+ "switchDisplayDock"
149
+ ),
150
+ /* @__PURE__ */ jsx(
151
+ DropdownItem,
152
+ {
153
+ value: ChatbotDisplayMode.embedded,
154
+ icon: /* @__PURE__ */ jsx(ExpandIcon, {}),
155
+ onClick: handleFullscreen,
156
+ isSelected: displayMode === ChatbotDisplayMode.embedded,
157
+ children: t("settings.displayMode.fullscreen")
158
+ },
159
+ "switchDisplayFullscreen"
160
+ )
161
+ ] }) }),
162
+ /* @__PURE__ */ jsx(Divider, {}),
163
+ /* @__PURE__ */ jsx(DropdownGroup, { children: /* @__PURE__ */ jsx(DropdownList, { children: isPinningChatsEnabled ? /* @__PURE__ */ jsx(
164
+ DropdownItem,
165
+ {
166
+ value: "disablePinningChats",
167
+ icon: /* @__PURE__ */ jsx(ToggleOnOutlinedIcon, { sx: { marginTop: "8px" } }),
168
+ description: t("settings.pinned.enabled.description"),
169
+ onClick: () => handlePinningChatsToggle(false),
170
+ children: t("settings.pinned.disable")
171
+ },
172
+ "disablePinningChat"
173
+ ) : /* @__PURE__ */ jsx(
174
+ DropdownItem,
175
+ {
176
+ value: "enablePinningChats",
177
+ icon: /* @__PURE__ */ jsx(ToggleOffOutlinedIcon, { sx: { marginTop: "8px" } }),
178
+ description: t("settings.pinned.disabled.description"),
179
+ onClick: () => handlePinningChatsToggle(true),
180
+ children: t("settings.pinned.enable")
181
+ },
182
+ "enablePinningChats"
183
+ ) }) })
184
+ ]
127
185
  }
128
186
  )
129
187
  ] });
@@ -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, useMemo, 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 {\n ChatbotHeaderActions,\n ChatbotHeaderOptionsDropdown,\n} from '@patternfly/chatbot';\nimport {\n Divider,\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype LightspeedChatBoxHeaderProps = {\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};\n\nconst useStyles = makeStyles(() =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\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 handleSelectedModel,\n models,\n isPinningChatsEnabled,\n onPinnedChatsToggle,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n // Group models by provider\n const groupedModels = useMemo(() => {\n const groups: {\n [key: string]: { label: string; value: string; provider: string }[];\n } = {};\n\n models.forEach(model => {\n const provider = model.provider || t('chatbox.provider.other');\n if (!groups[provider]) {\n groups[provider] = [];\n }\n groups[provider].push(model);\n });\n\n return groups;\n }, [models, t]);\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n const handlePinningChatsToggle = (state: boolean) => {\n onPinnedChatsToggle(state);\n };\n\n return (\n <ChatbotHeaderActions>\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 >\n <DropdownList>\n {Object.entries(groupedModels).map(\n ([provider, providerModels], index) => (\n <>\n <DropdownGroup\n className={styles.groupTitle}\n key={provider}\n label={provider}\n labelHeadingLevel=\"h1\"\n >\n {providerModels.map(model => (\n <DropdownItem value={model.value} key={model.value}>\n {model.label}\n </DropdownItem>\n ))}\n </DropdownGroup>\n {index < Object.entries(groupedModels).length - 1 && (\n <Divider component=\"li\" />\n )}\n </>\n ),\n )}\n </DropdownList>\n </Dropdown>\n <ChatbotHeaderOptionsDropdown\n isCompact\n toggleProps={{\n 'aria-label': t('aria.settings.label'),\n className: styles.optionsToggle,\n }}\n tooltipProps={{\n content: t('tooltip.settings'),\n }}\n >\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 </DropdownList>\n </DropdownGroup>\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, useMemo, 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 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';\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 isModelSelectorDisabled?: 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 isModelSelectorDisabled = false,\n setDisplayMode,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n // Group models by provider\n const groupedModels = useMemo(() => {\n const groups: {\n [key: string]: { label: string; value: string; provider: string }[];\n } = {};\n\n models.forEach(model => {\n const provider = model.provider || t('chatbox.provider.other');\n if (!groups[provider]) {\n groups[provider] = [];\n }\n groups[provider].push(model);\n });\n\n return groups;\n }, [models, t]);\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 >\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 return (\n <ChatbotHeaderActions>\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 >\n <DropdownList>\n {Object.entries(groupedModels).map(\n ([provider, providerModels], index) => (\n <>\n <DropdownGroup\n className={styles.groupTitle}\n key={provider}\n label={provider}\n labelHeadingLevel=\"h1\"\n >\n {providerModels.map(model => (\n <DropdownItem value={model.value} key={model.value}>\n {model.label}\n </DropdownItem>\n ))}\n </DropdownGroup>\n {index < Object.entries(groupedModels).length - 1 && (\n <Divider component=\"li\" />\n )}\n </>\n ),\n )}\n </DropdownList>\n </Dropdown>\n <ChatbotHeaderOptionsDropdown\n isCompact\n toggleProps={{\n 'aria-label': t('aria.settings.label'),\n className: styles.optionsToggle,\n }}\n tooltipProps={{\n content: t('tooltip.settings'),\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 <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 </DropdownList>\n </DropdownGroup>\n </ChatbotHeaderOptionsDropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useState, useMemo, useEffect } from 'react';
3
+ import { useAsync } from 'react-use';
4
+ import { useApi, identityApiRef } from '@backstage/core-plugin-api';
5
+ import { useTheme } from '@material-ui/core/styles';
6
+ import { QueryClientProvider } from '@tanstack/react-query';
7
+ import { useAllModels } from '../hooks/useAllModels.esm.js';
8
+ import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
9
+ import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
10
+ import queryClient from '../utils/queryClient.esm.js';
11
+ import FileAttachmentContextProvider from './AttachmentContext.esm.js';
12
+ import { LightspeedChat } from './LightSpeedChat.esm.js';
13
+ import PermissionRequiredState from './PermissionRequiredState.esm.js';
14
+
15
+ const THEME_DARK = "dark";
16
+ const THEME_DARK_CLASS = "pf-v6-theme-dark";
17
+ const LAST_SELECTED_MODEL_KEY = "lastSelectedModel";
18
+ const LightspeedChatContainerInner = () => {
19
+ const {
20
+ palette: { type }
21
+ } = useTheme();
22
+ const identityApi = useApi(identityApiRef);
23
+ const { data: models } = useAllModels();
24
+ const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();
25
+ const { value: profile, loading: profileLoading } = useAsync(
26
+ async () => await identityApi.getProfileInfo()
27
+ );
28
+ const [selectedModel, setSelectedModel] = useState("");
29
+ const [selectedProvider, setSelectedProvider] = useState("");
30
+ const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();
31
+ const modelsItems = useMemo(
32
+ () => models ? models.filter((model) => model.model_type === "llm").map((m) => ({
33
+ label: m.provider_resource_id,
34
+ value: m.provider_resource_id,
35
+ provider: m.provider_id
36
+ })) : [],
37
+ [models]
38
+ );
39
+ useEffect(() => {
40
+ const htmlTagElement = document.documentElement;
41
+ if (type === THEME_DARK) {
42
+ htmlTagElement.classList.add(THEME_DARK_CLASS);
43
+ } else {
44
+ htmlTagElement.classList.remove(THEME_DARK_CLASS);
45
+ }
46
+ }, [type]);
47
+ useEffect(() => {
48
+ if (modelsItems.length > 0) {
49
+ try {
50
+ const storedData = localStorage.getItem(LAST_SELECTED_MODEL_KEY);
51
+ const parsedData = storedData ? JSON.parse(storedData) : null;
52
+ const storedModel = parsedData?.model ? modelsItems.find((m) => m.value === parsedData.model) : null;
53
+ if (storedModel) {
54
+ setSelectedModel(storedModel.value);
55
+ setSelectedProvider(storedModel.provider);
56
+ } else {
57
+ setSelectedModel(modelsItems[0].value);
58
+ setSelectedProvider(modelsItems[0].provider);
59
+ }
60
+ } catch (error) {
61
+ console.error(
62
+ "Error loading last selected model from localStorage:",
63
+ error
64
+ );
65
+ setSelectedModel(modelsItems[0].value);
66
+ setSelectedProvider(modelsItems[0].provider);
67
+ }
68
+ }
69
+ }, [modelsItems]);
70
+ useEffect(() => {
71
+ if (selectedModel && selectedProvider) {
72
+ try {
73
+ localStorage.setItem(
74
+ LAST_SELECTED_MODEL_KEY,
75
+ JSON.stringify({
76
+ model: selectedModel,
77
+ provider: selectedProvider
78
+ })
79
+ );
80
+ } catch (error) {
81
+ console.error(
82
+ "Error saving last selected model to localStorage:",
83
+ error
84
+ );
85
+ }
86
+ }
87
+ }, [selectedModel, selectedProvider]);
88
+ if (loading) {
89
+ return null;
90
+ }
91
+ if (!hasViewAccess) {
92
+ return /* @__PURE__ */ jsx(PermissionRequiredState, {});
93
+ }
94
+ return /* @__PURE__ */ jsx(FileAttachmentContextProvider, { children: /* @__PURE__ */ jsx(
95
+ LightspeedChat,
96
+ {
97
+ selectedModel,
98
+ selectedProvider,
99
+ topicRestrictionEnabled: topicRestrictionEnabled ?? false,
100
+ handleSelectedModel: (item) => {
101
+ setSelectedModel(item);
102
+ setSelectedProvider(
103
+ modelsItems.find((m) => m.value === item)?.provider || ""
104
+ );
105
+ },
106
+ models: modelsItems,
107
+ userName: profile?.displayName,
108
+ avatar: profile?.picture,
109
+ profileLoading
110
+ }
111
+ ) });
112
+ };
113
+ const LightspeedChatContainer = () => {
114
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(LightspeedChatContainerInner, {}) });
115
+ };
116
+
117
+ export { LightspeedChatContainer };
118
+ //# sourceMappingURL=LightspeedChatContainer.esm.js.map
@@ -0,0 +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 { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\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\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n\n const { allowed: hasViewAccess, loading } = 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 // Handle dark theme class on document\n useEffect(() => {\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 return null;\n }\n\n if (!hasViewAccess) {\n return <PermissionRequiredState />;\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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"}
@@ -0,0 +1,6 @@
1
+ import { createContext } from 'react';
2
+
3
+ const LightspeedDrawerContext = createContext(undefined);
4
+
5
+ export { LightspeedDrawerContext };
6
+ //# sourceMappingURL=LightspeedDrawerContext.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LightspeedDrawerContext.esm.js","sources":["../../src/components/LightspeedDrawerContext.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 { createContext } from 'react';\n\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { FileContent } from '../types';\n\n/**\n * Type for LightspeedDrawerContext\n *\n * @public\n */\nexport interface LightspeedDrawerContextType {\n /**\n * Whether the chatbot is active\n */\n isChatbotActive: boolean;\n /**\n * Toggle the chatbot open/closed\n */\n toggleChatbot: () => void;\n /**\n * The current display mode\n */\n displayMode: ChatbotDisplayMode;\n /**\n * Set the display mode (overlay, docked, or fullscreen/embedded)\n */\n setDisplayMode: (mode: ChatbotDisplayMode) => void;\n /**\n * The drawer width (for docked mode)\n */\n drawerWidth: number;\n /**\n * The function for setting the drawer width\n */\n setDrawerWidth: React.Dispatch<React.SetStateAction<number>>;\n /**\n * The current conversation ID\n */\n currentConversationId?: string;\n /**\n * Set the current conversation ID and update the route if in embedded mode\n * Pass undefined to clear the conversation (example: for new chat)\n */\n setCurrentConversationId: (id: string | undefined) => void;\n /**\n * The message in the chat input box\n * Used to preserve input content when switching between display modes\n */\n draftMessage: string;\n /**\n * To save the input message as a draft when switching modes\n */\n setDraftMessage: (message: string) => void;\n /**\n * The file attachments in the chat input\n * Used to preserve file attachments when switching between display modes\n */\n draftFileContents: FileContent[];\n /**\n * To save file attachments as a draft when switching modes\n */\n setDraftFileContents: (files: FileContent[]) => void;\n}\n\n/**\n * @public\n */\nexport const LightspeedDrawerContext = createContext<\n LightspeedDrawerContextType | undefined\n>(undefined);\n"],"names":[],"mappings":";;AAoFa,MAAA,uBAAA,GAA0B,cAErC,SAAS;;;;"}