@red-hat-developer-hub/backstage-plugin-lightspeed 0.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.
- package/CHANGELOG.md +24 -0
- package/README.md +179 -0
- package/app-config.dynamic.yaml +14 -0
- package/config.d.ts +41 -0
- package/dist/api/LightspeedApiClient.esm.js +108 -0
- package/dist/api/LightspeedApiClient.esm.js.map +1 -0
- package/dist/api/api.esm.js +8 -0
- package/dist/api/api.esm.js.map +1 -0
- package/dist/components/LightSpeedChat.esm.js +239 -0
- package/dist/components/LightSpeedChat.esm.js.map +1 -0
- package/dist/components/LightspeedChatBox.esm.js +58 -0
- package/dist/components/LightspeedChatBox.esm.js.map +1 -0
- package/dist/components/LightspeedChatBoxHeader.esm.js +41 -0
- package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -0
- package/dist/components/LightspeedIcon.esm.js +9 -0
- package/dist/components/LightspeedIcon.esm.js.map +1 -0
- package/dist/components/LightspeedPage.esm.js +71 -0
- package/dist/components/LightspeedPage.esm.js.map +1 -0
- package/dist/components/PermissionRequiredIcon.esm.js +9 -0
- package/dist/components/PermissionRequiredIcon.esm.js.map +1 -0
- package/dist/components/PermissionRequiredState.esm.js +42 -0
- package/dist/components/PermissionRequiredState.esm.js.map +1 -0
- package/dist/hooks/useAllModels.esm.js +19 -0
- package/dist/hooks/useAllModels.esm.js.map +1 -0
- package/dist/hooks/useBackstageUserIdentity.esm.js +14 -0
- package/dist/hooks/useBackstageUserIdentity.esm.js.map +1 -0
- package/dist/hooks/useConversationMessages.esm.js +195 -0
- package/dist/hooks/useConversationMessages.esm.js.map +1 -0
- package/dist/hooks/useConversations.esm.js +19 -0
- package/dist/hooks/useConversations.esm.js.map +1 -0
- package/dist/hooks/useCreateConversation.esm.js +19 -0
- package/dist/hooks/useCreateConversation.esm.js.map +1 -0
- package/dist/hooks/useCreateCoversationMessage.esm.js +29 -0
- package/dist/hooks/useCreateCoversationMessage.esm.js.map +1 -0
- package/dist/hooks/useDeleteConversation.esm.js +37 -0
- package/dist/hooks/useDeleteConversation.esm.js.map +1 -0
- package/dist/hooks/useLightspeedDeletePermission.esm.js +12 -0
- package/dist/hooks/useLightspeedDeletePermission.esm.js.map +1 -0
- package/dist/hooks/useLightspeedViewPermission.esm.js +18 -0
- package/dist/hooks/useLightspeedViewPermission.esm.js.map +1 -0
- package/dist/images/logo-white.svg +16 -0
- package/dist/images/logo.svg +1 -0
- package/dist/images/permission-required.svg +48 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +33 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/utils/lightspeed-chatbox-utils.esm.js +146 -0
- package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -0
- package/dist/utils/queryClient.esm.js +6 -0
- package/dist/utils/queryClient.esm.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightSpeedChat.esm.js","sources":["../../src/components/LightSpeedChat.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport { ErrorPanel } from '@backstage/core-components';\n\nimport { Box, makeStyles } from '@material-ui/core';\nimport { DropdownItem, Title } from '@patternfly/react-core';\nimport {\n Chatbot,\n ChatbotContent,\n ChatbotDisplayMode,\n ChatbotFooter,\n ChatbotFootnote,\n ChatbotHeader,\n ChatbotHeaderMain,\n ChatbotHeaderMenu,\n ChatbotHeaderTitle,\n MessageBar,\n MessageProps,\n} from '@patternfly/virtual-assistant';\nimport ChatbotConversationHistoryNav from '@patternfly/virtual-assistant/dist/dynamic/ChatbotConversationHistoryNav';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { useBackstageUserIdentity } from '../hooks/useBackstageUserIdentity';\nimport { useConversationMessages } from '../hooks/useConversationMessages';\nimport { useConversations } from '../hooks/useConversations';\nimport { useCreateConversation } from '../hooks/useCreateConversation';\nimport { useDeleteConversation } from '../hooks/useDeleteConversation';\nimport { useLightspeedDeletePermission } from '../hooks/useLightspeedDeletePermission';\nimport { ConversationSummary } from '../types';\nimport {\n getCategorizeMessages,\n getFootnoteProps,\n} from '../utils/lightspeed-chatbox-utils';\nimport { LightspeedChatBox } from './LightspeedChatBox';\nimport { LightspeedChatBoxHeader } from './LightspeedChatBoxHeader';\n\nconst useStyles = makeStyles(theme => ({\n content: {\n '&.pf-chatbot__content': {\n padding: 0,\n },\n },\n header: {\n padding: `${theme.spacing(3)}px !important`,\n },\n drawerActions: {\n '&.pf-v6-c-drawer__actions': {\n flexDirection: 'row-reverse',\n },\n },\n headerTitle: {\n justifyContent: 'left !important',\n },\n footer: {\n '&.pf-chatbot__footer': {\n padding:\n '0 var(--pf-t--global--spacer--lg) var(--pf-t--global--spacer--lg) var(--pf-t--global--spacer--lg)',\n },\n },\n}));\n\ntype LightspeedChatProps = {\n selectedModel: string;\n userName?: string;\n avatar?: string;\n profileLoading: boolean;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string }[];\n};\n\nexport const LightspeedChat = ({\n selectedModel,\n userName,\n avatar,\n profileLoading,\n handleSelectedModel,\n models,\n}: LightspeedChatProps) => {\n const classes = useStyles();\n const user = useBackstageUserIdentity();\n const [filterValue, setFilterValue] = React.useState<string>('');\n const [announcement, setAnnouncement] = React.useState<string>('');\n const [conversationId, setConversationId] = React.useState<string>('');\n const [isDrawerOpen, setIsDrawerOpen] = React.useState<boolean>(true);\n const [newChatCreated, setNewChatCreated] = React.useState<boolean>(true);\n const [isSendButtonDisabled, setIsSendButtonDisabled] =\n React.useState<boolean>(false);\n const [error, setError] = React.useState<Error | null>(null);\n\n const queryClient = useQueryClient();\n\n const { data: conversations = [] } = useConversations();\n const { mutateAsync: createConversation } = useCreateConversation();\n const { mutateAsync: deleteConversation } = useDeleteConversation();\n const { allowed: hasDeleteAccess } = useLightspeedDeletePermission();\n\n React.useEffect(() => {\n if (user) {\n createConversation()\n .then(({ conversation_id }) => {\n setConversationId(conversation_id);\n })\n .catch(e => {\n // eslint-disable-next-line\n console.warn(e);\n setError(e);\n });\n }\n }, [user, setConversationId, createConversation]);\n\n const onComplete = (message: string) => {\n setIsSendButtonDisabled(false);\n setAnnouncement(`Message from Bot: ${message}`);\n queryClient.invalidateQueries({\n queryKey: ['conversations'],\n });\n };\n\n const { conversationMessages, handleInputPrompt, scrollToBottomRef } =\n useConversationMessages(\n conversationId,\n userName,\n selectedModel,\n avatar,\n onComplete,\n );\n\n const [messages, setMessages] =\n React.useState<MessageProps[]>(conversationMessages);\n\n // Auto-scrolls to the latest message\n React.useEffect(() => {\n setTimeout(() => {\n scrollToBottomRef.current?.scrollIntoView({ behavior: 'auto' });\n }, 10);\n // eslint-disable-next-line\n }, [messages, scrollToBottomRef.current]);\n\n const sendMessage = (message: string) => {\n setNewChatCreated(false);\n setAnnouncement(\n `Message from User: ${prompt}. Message from Bot is loading.`,\n );\n handleInputPrompt(message);\n setIsSendButtonDisabled(true);\n };\n\n const onNewChat = React.useCallback(() => {\n (async () => {\n setMessages([]);\n const { conversation_id } = await createConversation();\n setConversationId(conversation_id);\n setNewChatCreated(true);\n })();\n }, [createConversation, setConversationId, setMessages]);\n\n const additionalMessageProps = React.useCallback(\n (conversationSummary: ConversationSummary) => ({\n menuItems: (\n <DropdownItem\n isDisabled={!hasDeleteAccess}\n onClick={async () => {\n try {\n await deleteConversation({\n conversation_id: conversationSummary.conversation_id,\n invalidateCache: false,\n });\n onNewChat();\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n }\n }}\n >\n Delete\n </DropdownItem>\n ),\n }),\n [deleteConversation, onNewChat, hasDeleteAccess],\n );\n const categorizedMessages = getCategorizeMessages(\n conversations,\n additionalMessageProps,\n );\n\n const filterConversations = React.useCallback(\n (targetValue: string) => {\n const filteredConversations = Object.entries(categorizedMessages).reduce(\n (acc, [key, items]) => {\n const filteredItems = items.filter(item =>\n item.text\n .toLocaleLowerCase('en-US')\n .includes(targetValue.toLocaleLowerCase('en-US')),\n );\n if (filteredItems.length > 0) {\n acc[key] = filteredItems;\n }\n return acc;\n },\n {} as any,\n );\n return filteredConversations;\n },\n [categorizedMessages],\n );\n\n React.useEffect(() => {\n setMessages(conversationMessages);\n }, [conversationMessages]);\n\n const onSelectActiveItem = React.useCallback(\n (\n _: React.MouseEvent | undefined,\n selectedItem: string | number | undefined,\n ) => {\n setNewChatCreated(false);\n setConversationId((c_id: string) => {\n if (c_id !== selectedItem) {\n return String(selectedItem);\n }\n return c_id;\n });\n },\n [setConversationId],\n );\n\n const welcomePrompts = newChatCreated\n ? [\n {\n title: 'Topic 1',\n message: 'Helpful prompt for Topic 1',\n onClick: () => sendMessage('Helpful prompt for Topic 1'),\n },\n {\n title: 'Topic 2',\n message: 'Helpful prompt for Topic 2',\n onClick: () => sendMessage('Helpful prompt for Topic 2'),\n },\n ]\n : [];\n\n const handleFilter = React.useCallback((value: string) => {\n setFilterValue(value);\n }, []);\n\n const onDrawerToggle = React.useCallback(() => {\n setIsDrawerOpen(isOpen => !isOpen);\n }, []);\n\n if (error) {\n return (\n <Box padding={1}>\n <ErrorPanel error={error} />\n </Box>\n );\n }\n\n return (\n <>\n <Chatbot displayMode={ChatbotDisplayMode.embedded}>\n <ChatbotHeader className={classes.header}>\n <ChatbotHeaderMain>\n <ChatbotHeaderMenu\n aria-expanded={isDrawerOpen}\n onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)}\n />\n <ChatbotHeaderTitle className={classes.headerTitle}>\n <Title headingLevel=\"h1\" size=\"3xl\">\n Developer Hub Lightspeed\n </Title>\n </ChatbotHeaderTitle>\n </ChatbotHeaderMain>\n\n <LightspeedChatBoxHeader\n selectedModel={selectedModel}\n handleSelectedModel={item => handleSelectedModel(item)}\n models={models}\n />\n </ChatbotHeader>\n <ChatbotConversationHistoryNav\n displayMode={ChatbotDisplayMode.embedded}\n onDrawerToggle={onDrawerToggle}\n isDrawerOpen={isDrawerOpen}\n setIsDrawerOpen={setIsDrawerOpen}\n activeItemId={conversationId}\n onSelectActiveItem={onSelectActiveItem}\n conversations={filterConversations(filterValue)}\n onNewChat={newChatCreated ? undefined : onNewChat}\n handleTextInputChange={handleFilter}\n drawerContent={\n <>\n <ChatbotContent className={classes.content}>\n <LightspeedChatBox\n userName={userName}\n messages={messages}\n profileLoading={profileLoading}\n announcement={announcement}\n ref={scrollToBottomRef}\n welcomePrompts={welcomePrompts}\n />\n </ChatbotContent>\n <ChatbotFooter className={classes.footer}>\n <MessageBar\n onSendMessage={sendMessage}\n isSendButtonDisabled={isSendButtonDisabled}\n hasAttachButton={false}\n hasMicrophoneButton\n />\n <ChatbotFootnote {...getFootnoteProps()} />\n </ChatbotFooter>\n </>\n }\n />\n </Chatbot>\n </>\n );\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { makeStyles } from '@material-ui/core';
|
|
3
|
+
import { MessageBox, ChatbotWelcomePrompt, Message } from '@patternfly/virtual-assistant';
|
|
4
|
+
|
|
5
|
+
const useStyles = makeStyles((theme) => ({
|
|
6
|
+
prompt: {
|
|
7
|
+
"justify-content": "flex-end"
|
|
8
|
+
},
|
|
9
|
+
userMessageText: {
|
|
10
|
+
"& div.pf-chatbot__message--user": {
|
|
11
|
+
"& div.pf-chatbot__message-text": {
|
|
12
|
+
"& p": {
|
|
13
|
+
color: theme.palette.common.white
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}));
|
|
19
|
+
const LightspeedChatBox = React__default.forwardRef(
|
|
20
|
+
({
|
|
21
|
+
userName,
|
|
22
|
+
messages,
|
|
23
|
+
announcement,
|
|
24
|
+
profileLoading,
|
|
25
|
+
welcomePrompts
|
|
26
|
+
}, ref) => {
|
|
27
|
+
const [cmessages, setCMessages] = React__default.useState(messages);
|
|
28
|
+
const classes = useStyles();
|
|
29
|
+
React__default.useEffect(() => {
|
|
30
|
+
setCMessages(messages);
|
|
31
|
+
}, [messages]);
|
|
32
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
33
|
+
MessageBox,
|
|
34
|
+
{
|
|
35
|
+
className: welcomePrompts.length ? `${classes.userMessageText} ${classes.prompt}` : classes.userMessageText,
|
|
36
|
+
announcement,
|
|
37
|
+
style: { justifyContent: "flex-end" }
|
|
38
|
+
},
|
|
39
|
+
welcomePrompts.length ? /* @__PURE__ */ React__default.createElement(
|
|
40
|
+
ChatbotWelcomePrompt,
|
|
41
|
+
{
|
|
42
|
+
title: `Hello, ${profileLoading ? "..." : userName ?? "Guest"}`,
|
|
43
|
+
description: "How can I help you today?",
|
|
44
|
+
prompts: welcomePrompts
|
|
45
|
+
}
|
|
46
|
+
) : /* @__PURE__ */ React__default.createElement("br", null),
|
|
47
|
+
cmessages.map((message, index) => {
|
|
48
|
+
if (index === cmessages.length - 1) {
|
|
49
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, { key: `${message.role}-${index}` }, /* @__PURE__ */ React__default.createElement(Message, { key: `${message.role}-${index}`, ...message }), /* @__PURE__ */ React__default.createElement("div", { ref }));
|
|
50
|
+
}
|
|
51
|
+
return /* @__PURE__ */ React__default.createElement(Message, { key: `${message.role}-${index}`, ...message });
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export { LightspeedChatBox };
|
|
58
|
+
//# sourceMappingURL=LightspeedChatBox.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedChatBox.esm.js","sources":["../../src/components/LightspeedChatBox.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport { makeStyles } from '@material-ui/core';\nimport {\n ChatbotWelcomePrompt,\n Message,\n MessageBox,\n MessageProps,\n WelcomePrompt,\n} from '@patternfly/virtual-assistant';\n\nconst useStyles = makeStyles(theme => ({\n prompt: {\n 'justify-content': 'flex-end',\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 welcomePrompts: WelcomePrompt[];\n};\n\nexport const LightspeedChatBox = React.forwardRef(\n (\n {\n userName,\n messages,\n announcement,\n profileLoading,\n welcomePrompts,\n }: LightspeedChatBoxProps,\n ref: React.ForwardedRef<HTMLDivElement>,\n ) => {\n const [cmessages, setCMessages] = React.useState(messages);\n const classes = useStyles();\n\n React.useEffect(() => {\n setCMessages(messages);\n }, [messages]);\n\n return (\n <MessageBox\n className={\n welcomePrompts.length\n ? `${classes.userMessageText} ${classes.prompt}`\n : classes.userMessageText\n }\n announcement={announcement}\n style={{ justifyContent: 'flex-end' }}\n >\n {welcomePrompts.length ? (\n <ChatbotWelcomePrompt\n title={`Hello, ${profileLoading ? '...' : (userName ?? 'Guest')}`}\n description=\"How can I help you today?\"\n prompts={welcomePrompts}\n />\n ) : (\n <br />\n )}\n {cmessages.map((message, index) => {\n if (index === cmessages.length - 1) {\n return (\n <React.Fragment key={`${message.role}-${index}`}>\n <Message key={`${message.role}-${index}`} {...message} />\n <div ref={ref} />\n </React.Fragment>\n );\n }\n return <Message key={`${message.role}-${index}`} {...message} />;\n })}\n </MessageBox>\n );\n },\n);\n"],"names":["React"],"mappings":";;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,iCAAmC,EAAA;AAAA,MACjC,gCAAkC,EAAA;AAAA,QAChC,KAAO,EAAA;AAAA,UACL,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA;AAAA;AAC9B;AACF;AACF;AAEJ,CAAE,CAAA,CAAA;AAUK,MAAM,oBAAoBA,cAAM,CAAA,UAAA;AAAA,EACrC,CACE;AAAA,IACE,QAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,KAEF,GACG,KAAA;AACH,IAAA,MAAM,CAAC,SAAW,EAAA,YAAY,CAAI,GAAAA,cAAA,CAAM,SAAS,QAAQ,CAAA;AACzD,IAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,IAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,MAAA,YAAA,CAAa,QAAQ,CAAA;AAAA,KACvB,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,IACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EACE,cAAe,CAAA,MAAA,GACX,CAAG,EAAA,OAAA,CAAQ,eAAe,CAAI,CAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,CAAA,GAC5C,OAAQ,CAAA,eAAA;AAAA,QAEd,YAAA;AAAA,QACA,KAAA,EAAO,EAAE,cAAA,EAAgB,UAAW;AAAA,OAAA;AAAA,MAEnC,eAAe,MACd,mBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,oBAAA;AAAA,QAAA;AAAA,UACC,KAAO,EAAA,CAAA,OAAA,EAAU,cAAiB,GAAA,KAAA,GAAS,YAAY,OAAQ,CAAA,CAAA;AAAA,UAC/D,WAAY,EAAA,2BAAA;AAAA,UACZ,OAAS,EAAA;AAAA;AAAA,OACX,gDAEC,IAAG,EAAA,IAAA,CAAA;AAAA,MAEL,SAAU,CAAA,GAAA,CAAI,CAAC,OAAA,EAAS,KAAU,KAAA;AACjC,QAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,UACE,uBAAAA,cAAA,CAAA,aAAA,CAACA,cAAM,CAAA,QAAA,EAAN,EAAe,GAAA,EAAK,CAAG,EAAA,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAA,kBAC1CA,cAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,KAAK,CAAG,EAAA,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAK,GAAG,OAAA,EAAS,CACvD,kBAAAA,cAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,GAAA,EAAU,CACjB,CAAA;AAAA;AAGJ,QAAO,uBAAAA,cAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,GAAA,EAAK,CAAG,EAAA,OAAA,CAAQ,IAAI,CAAI,CAAA,EAAA,KAAK,CAAK,CAAA,EAAA,GAAG,OAAS,EAAA,CAAA;AAAA,OAC/D;AAAA,KACH;AAAA;AAGN;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Dropdown, MenuToggle, DropdownList, DropdownItem } from '@patternfly/react-core';
|
|
3
|
+
import { ChatbotHeaderActions } from '@patternfly/virtual-assistant';
|
|
4
|
+
|
|
5
|
+
const LightspeedChatBoxHeader = ({
|
|
6
|
+
selectedModel,
|
|
7
|
+
handleSelectedModel,
|
|
8
|
+
models
|
|
9
|
+
}) => {
|
|
10
|
+
const [isOptionsMenuOpen, setIsOptionsMenuOpen] = React__default.useState(false);
|
|
11
|
+
const toggle = (toggleRef) => /* @__PURE__ */ React__default.createElement(
|
|
12
|
+
MenuToggle,
|
|
13
|
+
{
|
|
14
|
+
variant: "secondary",
|
|
15
|
+
"aria-label": "Chatbot selector",
|
|
16
|
+
ref: toggleRef,
|
|
17
|
+
isExpanded: isOptionsMenuOpen,
|
|
18
|
+
onClick: () => setIsOptionsMenuOpen(!isOptionsMenuOpen)
|
|
19
|
+
},
|
|
20
|
+
selectedModel
|
|
21
|
+
);
|
|
22
|
+
return /* @__PURE__ */ React__default.createElement(ChatbotHeaderActions, null, /* @__PURE__ */ React__default.createElement(
|
|
23
|
+
Dropdown,
|
|
24
|
+
{
|
|
25
|
+
isOpen: isOptionsMenuOpen,
|
|
26
|
+
onSelect: (_e, value) => {
|
|
27
|
+
handleSelectedModel(value);
|
|
28
|
+
setIsOptionsMenuOpen(false);
|
|
29
|
+
},
|
|
30
|
+
onOpenChange: (isOpen) => setIsOptionsMenuOpen(isOpen),
|
|
31
|
+
popperProps: { position: "right" },
|
|
32
|
+
shouldFocusToggleOnSelect: true,
|
|
33
|
+
shouldFocusFirstItemOnOpen: false,
|
|
34
|
+
toggle
|
|
35
|
+
},
|
|
36
|
+
/* @__PURE__ */ React__default.createElement(DropdownList, null, models.map((m) => /* @__PURE__ */ React__default.createElement(DropdownItem, { value: m.value, key: m.value }, m.label)))
|
|
37
|
+
));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { LightspeedChatBoxHeader };
|
|
41
|
+
//# sourceMappingURL=LightspeedChatBoxHeader.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport {\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\nimport { ChatbotHeaderActions } from '@patternfly/virtual-assistant';\n\ntype LightspeedChatBoxHeaderProps = {\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string }[];\n};\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n handleSelectedModel,\n models,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = React.useState(false);\n\n const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label=\"Chatbot selector\"\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n return (\n <ChatbotHeaderActions>\n <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 {models.map(m => (\n <DropdownItem value={m.value} key={m.value}>\n {m.label}\n </DropdownItem>\n ))}\n </DropdownList>\n </Dropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":["React"],"mappings":";;;;AAgCO,MAAM,0BAA0B,CAAC;AAAA,EACtC,aAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAoC,KAAA;AAClC,EAAA,MAAM,CAAC,iBAAmB,EAAA,oBAAoB,CAAI,GAAAA,cAAA,CAAM,SAAS,KAAK,CAAA;AAEtE,EAAM,MAAA,MAAA,GAAS,CAAC,SACd,qBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,YAAW,EAAA,kBAAA;AAAA,MACX,GAAK,EAAA,SAAA;AAAA,MACL,UAAY,EAAA,iBAAA;AAAA,MACZ,OAAS,EAAA,MAAM,oBAAqB,CAAA,CAAC,iBAAiB;AAAA,KAAA;AAAA,IAErD;AAAA,GACH;AAGF,EAAA,oDACG,oBACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,MAAQ,EAAA,iBAAA;AAAA,MACR,QAAA,EAAU,CAAC,EAAA,EAAI,KAAU,KAAA;AACvB,QAAA,mBAAA,CAAoB,KAAe,CAAA;AACnC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,OAC5B;AAAA,MACA,YAAA,EAAc,CAAU,MAAA,KAAA,oBAAA,CAAqB,MAAM,CAAA;AAAA,MACnD,WAAA,EAAa,EAAE,QAAA,EAAU,OAAQ,EAAA;AAAA,MACjC,yBAAyB,EAAA,IAAA;AAAA,MACzB,0BAA4B,EAAA,KAAA;AAAA,MAC5B;AAAA,KAAA;AAAA,iDAEC,YACE,EAAA,IAAA,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,CAAA,kDACT,YAAa,EAAA,EAAA,KAAA,EAAO,CAAE,CAAA,KAAA,EAAO,KAAK,CAAE,CAAA,KAAA,EAAA,EAClC,CAAE,CAAA,KACL,CACD,CACH;AAAA,GAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import logo from '../images/logo-white.svg';
|
|
3
|
+
|
|
4
|
+
const LightspeedIcon = () => {
|
|
5
|
+
return /* @__PURE__ */ React.createElement("img", { src: logo, alt: "lightspeed icon", style: { height: "25px" } });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { LightspeedIcon };
|
|
9
|
+
//# sourceMappingURL=LightspeedIcon.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedIcon.esm.js","sources":["../../src/components/LightspeedIcon.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport * as React from 'react';\n\nimport logo from '../images/logo-white.svg';\n\n/**\n * @public\n * Lightspeed Icon\n */\nexport const LightspeedIcon = () => {\n return (\n <img src={logo as any} alt=\"lightspeed icon\" style={{ height: '25px' }} />\n );\n};\n"],"names":[],"mappings":";;;AAuBO,MAAM,iBAAiB,MAAM;AAClC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,GAAA,EAAK,IAAa,EAAA,GAAA,EAAI,mBAAkB,KAAO,EAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA,CAAA;AAE5E;;;;"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { useAsync } from 'react-use';
|
|
3
|
+
import { Page, Content } from '@backstage/core-components';
|
|
4
|
+
import { useApi, identityApiRef } from '@backstage/core-plugin-api';
|
|
5
|
+
import { makeStyles, createStyles, 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 queryClient from '../utils/queryClient.esm.js';
|
|
10
|
+
import { LightspeedChat } from './LightSpeedChat.esm.js';
|
|
11
|
+
import PermissionRequiredState from './PermissionRequiredState.esm.js';
|
|
12
|
+
|
|
13
|
+
const useStyles = makeStyles(
|
|
14
|
+
() => createStyles({
|
|
15
|
+
container: {
|
|
16
|
+
padding: "0px"
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
const THEME_DARK = "dark";
|
|
21
|
+
const THEME_DARK_CLASS = "pf-v6-theme-dark";
|
|
22
|
+
const LightspeedPageInner = () => {
|
|
23
|
+
const classes = useStyles();
|
|
24
|
+
const {
|
|
25
|
+
palette: { type }
|
|
26
|
+
} = useTheme();
|
|
27
|
+
const identityApi = useApi(identityApiRef);
|
|
28
|
+
const { data: models } = useAllModels();
|
|
29
|
+
const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();
|
|
30
|
+
const { value: profile, loading: profileLoading } = useAsync(
|
|
31
|
+
async () => await identityApi.getProfileInfo()
|
|
32
|
+
);
|
|
33
|
+
const [selectedModel, setSelectedModel] = React__default.useState("");
|
|
34
|
+
const modelsItems = React__default.useMemo(
|
|
35
|
+
() => models ? models.map((m) => ({ label: m.id, value: m.id })) : [],
|
|
36
|
+
[models]
|
|
37
|
+
);
|
|
38
|
+
React__default.useEffect(() => {
|
|
39
|
+
const htmlTagElement = document.documentElement;
|
|
40
|
+
if (type === THEME_DARK) {
|
|
41
|
+
htmlTagElement.classList.add(THEME_DARK_CLASS);
|
|
42
|
+
} else {
|
|
43
|
+
htmlTagElement.classList.remove(THEME_DARK_CLASS);
|
|
44
|
+
}
|
|
45
|
+
}, [type]);
|
|
46
|
+
React__default.useEffect(() => {
|
|
47
|
+
if (modelsItems.length > 0) setSelectedModel(modelsItems[0].value);
|
|
48
|
+
}, [modelsItems]);
|
|
49
|
+
if (loading) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return /* @__PURE__ */ React__default.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React__default.createElement(Content, { className: classes.container }, !hasViewAccess ? /* @__PURE__ */ React__default.createElement(PermissionRequiredState, null) : /* @__PURE__ */ React__default.createElement(
|
|
53
|
+
LightspeedChat,
|
|
54
|
+
{
|
|
55
|
+
selectedModel,
|
|
56
|
+
handleSelectedModel: (item) => {
|
|
57
|
+
setSelectedModel(item);
|
|
58
|
+
},
|
|
59
|
+
models: modelsItems,
|
|
60
|
+
userName: profile?.displayName,
|
|
61
|
+
avatar: profile?.picture,
|
|
62
|
+
profileLoading
|
|
63
|
+
}
|
|
64
|
+
)));
|
|
65
|
+
};
|
|
66
|
+
const LightspeedPage = () => {
|
|
67
|
+
return /* @__PURE__ */ React__default.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React__default.createElement(LightspeedPageInner, null));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export { LightspeedPage };
|
|
71
|
+
//# sourceMappingURL=LightspeedPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Page } from '@backstage/core-components';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport queryClient from '../utils/queryClient';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\n\nconst LightspeedPageInner = () => {\n const classes = useStyles();\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\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] = React.useState('');\n\n const modelsItems = React.useMemo(\n () => (models ? models.map(m => ({ label: m.id, value: m.id })) : []),\n [models],\n );\n\n React.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 // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [type]);\n\n React.useEffect(() => {\n if (modelsItems.length > 0) setSelectedModel(modelsItems[0].value);\n }, [modelsItems]);\n\n if (loading) {\n return null;\n }\n\n return (\n <Page themeId=\"tool\">\n <Content className={classes.container}>\n {!hasViewAccess ? (\n <PermissionRequiredState />\n ) : (\n <LightspeedChat\n selectedModel={selectedModel}\n handleSelectedModel={item => {\n setSelectedModel(item);\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n )}\n </Content>\n </Page>\n );\n};\n\nexport const LightspeedPage = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedPageInner />\n </QueryClientProvider>\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;;;AA8BA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,SAAW,EAAA;AAAA,MACT,OAAS,EAAA;AAAA;AACX,GACD;AACH,CAAA;AAEA,MAAM,UAAa,GAAA,MAAA;AACnB,MAAM,gBAAmB,GAAA,kBAAA;AAEzB,MAAM,sBAAsB,MAAM;AAChC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA;AAAA,IACJ,OAAA,EAAS,EAAE,IAAK;AAAA,MACd,QAAS,EAAA;AAEb,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AAEzC,EAAA,MAAM,EAAE,IAAA,EAAM,MAAO,EAAA,GAAI,YAAa,EAAA;AACtC,EAAA,MAAM,EAAE,OAAA,EAAS,aAAe,EAAA,OAAA,KAAY,2BAA4B,EAAA;AAExE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAmB,GAAA,QAAA;AAAA,IAClD,YAAY,MAAM,WAAA,CAAY,cAAe;AAAA,GAC/C;AAEA,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAAA,cAAA,CAAM,SAAS,EAAE,CAAA;AAE3D,EAAA,MAAM,cAAcA,cAAM,CAAA,OAAA;AAAA,IACxB,MAAO,MAAA,GAAS,MAAO,CAAA,GAAA,CAAI,QAAM,EAAE,KAAA,EAAO,CAAE,CAAA,EAAA,EAAI,KAAO,EAAA,CAAA,CAAE,EAAG,EAAA,CAAE,IAAI,EAAC;AAAA,IACnE,CAAC,MAAM;AAAA,GACT;AAEA,EAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,IAAA,MAAM,iBAAiB,QAAS,CAAA,eAAA;AAChC,IAAA,IAAI,SAAS,UAAY,EAAA;AACvB,MAAe,cAAA,CAAA,SAAA,CAAU,IAAI,gBAAgB,CAAA;AAAA,KACxC,MAAA;AACL,MAAe,cAAA,CAAA,SAAA,CAAU,OAAO,gBAAgB,CAAA;AAAA;AAClD,GAEF,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,YAAY,MAAS,GAAA,CAAA,mBAAoB,WAAY,CAAA,CAAC,EAAE,KAAK,CAAA;AAAA,GACnE,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,IAAI,OAAS,EAAA;AACX,IAAO,OAAA,IAAA;AAAA;AAGT,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,OAAQ,EAAA,MAAA,EAAA,kBACXA,cAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,SAAW,EAAA,OAAA,CAAQ,SACzB,EAAA,EAAA,CAAC,aACA,mBAAAA,cAAA,CAAA,aAAA,CAAC,6BAAwB,CAEzB,mBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,qBAAqB,CAAQ,IAAA,KAAA;AAC3B,QAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,OACvB;AAAA,MACA,MAAQ,EAAA,WAAA;AAAA,MACR,UAAU,OAAS,EAAA,WAAA;AAAA,MACnB,QAAQ,OAAS,EAAA,OAAA;AAAA,MACjB;AAAA;AAAA,GAGN,CACF,CAAA;AAEJ,CAAA;AAEO,MAAM,iBAAiB,MAAM;AAClC,EAAA,oDACG,mBAAoB,EAAA,EAAA,MAAA,EAAQ,WAC3B,EAAA,kBAAAA,cAAA,CAAA,aAAA,CAAC,yBAAoB,CACvB,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import permissionRequired from '../images/permission-required.svg';
|
|
3
|
+
|
|
4
|
+
const PermissionRequiredIcon = () => {
|
|
5
|
+
return /* @__PURE__ */ React.createElement("img", { src: permissionRequired, alt: "permission required icon" });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { PermissionRequiredIcon };
|
|
9
|
+
//# sourceMappingURL=PermissionRequiredIcon.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PermissionRequiredIcon.esm.js","sources":["../../src/components/PermissionRequiredIcon.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport * as React from 'react';\n\nimport permissionRequired from '../images/permission-required.svg';\n\nexport const PermissionRequiredIcon = () => {\n return <img src={permissionRequired as any} alt=\"permission required icon\" />;\n};\n"],"names":[],"mappings":";;;AAmBO,MAAM,yBAAyB,MAAM;AAC1C,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,GAAK,EAAA,kBAAA,EAA2B,KAAI,0BAA2B,EAAA,CAAA;AAC7E;;;;"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { EmptyState } from '@backstage/core-components';
|
|
3
|
+
import { Button, Typography } from '@material-ui/core';
|
|
4
|
+
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
|
5
|
+
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
|
6
|
+
import { PermissionRequiredIcon } from './PermissionRequiredIcon.esm.js';
|
|
7
|
+
|
|
8
|
+
const useStyles = makeStyles(
|
|
9
|
+
() => createStyles({
|
|
10
|
+
permissionError: {
|
|
11
|
+
display: "flex",
|
|
12
|
+
height: "100%",
|
|
13
|
+
alignItems: "center",
|
|
14
|
+
padding: "100px"
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
const PermissionRequiredState = () => {
|
|
19
|
+
const classes = useStyles();
|
|
20
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: classes.permissionError }, /* @__PURE__ */ React__default.createElement(
|
|
21
|
+
EmptyState,
|
|
22
|
+
{
|
|
23
|
+
title: "Missing permissions",
|
|
24
|
+
description: /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "To view lightspeed plugin, contact your administrator to give the", " ", /* @__PURE__ */ React__default.createElement("b", null, "lightspeed.conversations.read"), " and", " ", /* @__PURE__ */ React__default.createElement("b", null, "lightspeed.conversations.create"), " permissions."),
|
|
25
|
+
missing: { customImage: /* @__PURE__ */ React__default.createElement(PermissionRequiredIcon, null) },
|
|
26
|
+
action: /* @__PURE__ */ React__default.createElement(
|
|
27
|
+
Button,
|
|
28
|
+
{
|
|
29
|
+
variant: "outlined",
|
|
30
|
+
color: "primary",
|
|
31
|
+
target: "_blank",
|
|
32
|
+
href: "https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support"
|
|
33
|
+
},
|
|
34
|
+
"Read more \xA0 ",
|
|
35
|
+
/* @__PURE__ */ React__default.createElement(OpenInNewIcon, null)
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { PermissionRequiredState as default };
|
|
42
|
+
//# sourceMappingURL=PermissionRequiredState.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PermissionRequiredState.esm.js","sources":["../../src/components/PermissionRequiredState.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport { EmptyState } from '@backstage/core-components';\n\nimport { Button, Typography } from '@material-ui/core';\nimport { createStyles, makeStyles } from '@material-ui/core/styles';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\n\nimport { PermissionRequiredIcon } from './PermissionRequiredIcon';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n permissionError: {\n display: 'flex',\n height: '100%',\n alignItems: 'center',\n padding: '100px',\n },\n }),\n);\n\nconst PermissionRequiredState = () => {\n const classes = useStyles();\n\n return (\n <div className={classes.permissionError}>\n <EmptyState\n title=\"Missing permissions\"\n description={\n <Typography variant=\"subtitle1\">\n To view lightspeed plugin, contact your administrator to give the{' '}\n <b>lightspeed.conversations.read</b> and{' '}\n <b>lightspeed.conversations.create</b> permissions.\n </Typography>\n }\n missing={{ customImage: <PermissionRequiredIcon /> }}\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/lightspeed/plugins/lightspeed/README.md#permission-framework-support\"\n >\n Read more <OpenInNewIcon />\n </Button>\n }\n />\n </div>\n );\n};\nexport default PermissionRequiredState;\n"],"names":["React"],"mappings":";;;;;;;AAyBA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,eAAiB,EAAA;AAAA,MACf,OAAS,EAAA,MAAA;AAAA,MACT,MAAQ,EAAA,MAAA;AAAA,MACR,UAAY,EAAA,QAAA;AAAA,MACZ,OAAS,EAAA;AAAA;AACX,GACD;AACH,CAAA;AAEA,MAAM,0BAA0B,MAAM;AACpC,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,eACtB,EAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,qBAAA;AAAA,MACN,6BACGA,cAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,WAAA,EAAA,EAAY,qEACoC,GAClE,kBAAAA,cAAA,CAAA,aAAA,CAAC,GAAE,EAAA,IAAA,EAAA,+BAA6B,GAAI,MAAK,EAAA,GAAA,+CACxC,GAAE,EAAA,IAAA,EAAA,iCAA+B,GAAI,eACxC,CAAA;AAAA,MAEF,OAAS,EAAA,EAAE,WAAa,kBAAAA,cAAA,CAAA,aAAA,CAAC,4BAAuB,CAAG,EAAA;AAAA,MACnD,MACE,kBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,UAAA;AAAA,UACR,KAAM,EAAA,SAAA;AAAA,UACN,MAAO,EAAA,QAAA;AAAA,UACP,IAAK,EAAA;AAAA,SAAA;AAAA,QACN,iBAAA;AAAA,qDACmB,aAAc,EAAA,IAAA;AAAA;AAClC;AAAA,GAGN,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
import { lightspeedApiRef } from '../api/api.esm.js';
|
|
4
|
+
|
|
5
|
+
const useAllModels = () => {
|
|
6
|
+
const lightspeedApi = useApi(lightspeedApiRef);
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: ["models"],
|
|
9
|
+
queryFn: async () => {
|
|
10
|
+
const response = await lightspeedApi.getAllModels();
|
|
11
|
+
return response;
|
|
12
|
+
},
|
|
13
|
+
staleTime: 1e3 * 60 * 5
|
|
14
|
+
// 5 minutes
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { useAllModels };
|
|
19
|
+
//# sourceMappingURL=useAllModels.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAllModels.esm.js","sources":["../../src/hooks/useAllModels.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\n// Fetch all models\nexport const useAllModels = () => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['models'],\n queryFn: async () => {\n const response = await lightspeedApi.getAllModels();\n return response;\n },\n staleTime: 1000 * 60 * 5, // 5 minutes\n });\n};\n"],"names":[],"mappings":";;;;AAsBO,MAAM,eAAe,MAAM;AAChC,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAA,OAAO,QAAS,CAAA;AAAA,IACd,QAAA,EAAU,CAAC,QAAQ,CAAA;AAAA,IACnB,SAAS,YAAY;AACnB,MAAM,MAAA,QAAA,GAAW,MAAM,aAAA,CAAc,YAAa,EAAA;AAClD,MAAO,OAAA,QAAA;AAAA,KACT;AAAA,IACA,SAAA,EAAW,MAAO,EAAK,GAAA;AAAA;AAAA,GACxB,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useAsync } from 'react-use';
|
|
2
|
+
import { useApi, identityApiRef } from '@backstage/core-plugin-api';
|
|
3
|
+
|
|
4
|
+
const useBackstageUserIdentity = () => {
|
|
5
|
+
const identityApi = useApi(identityApiRef);
|
|
6
|
+
const { value: user } = useAsync(async () => {
|
|
7
|
+
const identityRef = await identityApi.getBackstageIdentity();
|
|
8
|
+
return identityRef.userEntityRef;
|
|
9
|
+
});
|
|
10
|
+
return user;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { useBackstageUserIdentity };
|
|
14
|
+
//# sourceMappingURL=useBackstageUserIdentity.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBackstageUserIdentity.esm.js","sources":["../../src/hooks/useBackstageUserIdentity.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport { useAsync } from 'react-use';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nexport const useBackstageUserIdentity = () => {\n const identityApi = useApi(identityApiRef);\n const { value: user } = useAsync(async () => {\n const identityRef = await identityApi.getBackstageIdentity();\n return identityRef.userEntityRef;\n });\n return user;\n};\n"],"names":[],"mappings":";;;AAmBO,MAAM,2BAA2B,MAAM;AAC5C,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAA,MAAM,EAAE,KAAA,EAAO,IAAK,EAAA,GAAI,SAAS,YAAY;AAC3C,IAAM,MAAA,WAAA,GAAc,MAAM,WAAA,CAAY,oBAAqB,EAAA;AAC3D,IAAA,OAAO,WAAY,CAAA,aAAA;AAAA,GACpB,CAAA;AACD,EAAO,OAAA,IAAA;AACT;;;;"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import { useQuery } from '@tanstack/react-query';
|
|
4
|
+
import { lightspeedApiRef } from '../api/api.esm.js';
|
|
5
|
+
import logo from '../images/logo.svg';
|
|
6
|
+
import { getMessageData, createUserMessage, createBotMessage, getTimestamp, splitJsonStrings } from '../utils/lightspeed-chatbox-utils.esm.js';
|
|
7
|
+
import { useCreateConversationMessage } from './useCreateCoversationMessage.esm.js';
|
|
8
|
+
|
|
9
|
+
const useFetchConversationMessages = (currentConversation) => {
|
|
10
|
+
const lightspeedApi = useApi(lightspeedApiRef);
|
|
11
|
+
return useQuery({
|
|
12
|
+
queryKey: ["conversationMessages", currentConversation],
|
|
13
|
+
queryFn: currentConversation ? async () => {
|
|
14
|
+
const response = await lightspeedApi.getConversationMessages(currentConversation);
|
|
15
|
+
return response;
|
|
16
|
+
} : void 0,
|
|
17
|
+
retry: false
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
const useConversationMessages = (conversationId, userName, selectedModel, avatar, onComplete) => {
|
|
21
|
+
const { mutateAsync: createMessage } = useCreateConversationMessage();
|
|
22
|
+
const scrollToBottomRef = React__default.useRef(null);
|
|
23
|
+
const [currentConversation, setCurrentConversation] = React__default.useState(conversationId);
|
|
24
|
+
const [conversations, setConversations] = React__default.useState({
|
|
25
|
+
[currentConversation]: []
|
|
26
|
+
});
|
|
27
|
+
React__default.useEffect(() => {
|
|
28
|
+
if (currentConversation !== conversationId) {
|
|
29
|
+
setCurrentConversation(conversationId);
|
|
30
|
+
setConversations({
|
|
31
|
+
[conversationId]: []
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}, [currentConversation, conversationId]);
|
|
35
|
+
const { data: conversationsData = [], ...queryProps } = useFetchConversationMessages(currentConversation);
|
|
36
|
+
React__default.useEffect(() => {
|
|
37
|
+
if (!Array.isArray(conversationsData) || conversationsData.length === 0)
|
|
38
|
+
return;
|
|
39
|
+
if (conversations) {
|
|
40
|
+
const _conversations = {
|
|
41
|
+
[currentConversation]: []
|
|
42
|
+
};
|
|
43
|
+
for (let i = 0; i < conversationsData.length; i += 2) {
|
|
44
|
+
const userMessage = conversationsData[i];
|
|
45
|
+
const aiMessage = conversationsData[i + 1];
|
|
46
|
+
const { content: humanMessage, timestamp: userTimestamp } = getMessageData(userMessage);
|
|
47
|
+
const {
|
|
48
|
+
model,
|
|
49
|
+
content: botMessage,
|
|
50
|
+
timestamp: botTimestamp
|
|
51
|
+
} = getMessageData(aiMessage);
|
|
52
|
+
_conversations[currentConversation].push(
|
|
53
|
+
...[
|
|
54
|
+
createUserMessage({
|
|
55
|
+
avatar,
|
|
56
|
+
name: userName,
|
|
57
|
+
content: humanMessage,
|
|
58
|
+
timestamp: userTimestamp
|
|
59
|
+
}),
|
|
60
|
+
createBotMessage({
|
|
61
|
+
avatar: logo,
|
|
62
|
+
isLoading: false,
|
|
63
|
+
name: model ?? selectedModel,
|
|
64
|
+
content: botMessage,
|
|
65
|
+
timestamp: botTimestamp
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
setConversations(_conversations);
|
|
71
|
+
}
|
|
72
|
+
}, [conversationsData, userName, avatar, currentConversation, selectedModel]);
|
|
73
|
+
const handleInputPrompt = React__default.useCallback(
|
|
74
|
+
async (prompt) => {
|
|
75
|
+
setConversations((prevConv) => {
|
|
76
|
+
return {
|
|
77
|
+
...prevConv,
|
|
78
|
+
[currentConversation]: [
|
|
79
|
+
...prevConv?.[currentConversation] ?? [],
|
|
80
|
+
createUserMessage({
|
|
81
|
+
avatar,
|
|
82
|
+
name: userName,
|
|
83
|
+
content: prompt,
|
|
84
|
+
timestamp: getTimestamp(Date.now()) ?? ""
|
|
85
|
+
}),
|
|
86
|
+
createBotMessage({
|
|
87
|
+
avatar: logo,
|
|
88
|
+
isLoading: true,
|
|
89
|
+
name: selectedModel,
|
|
90
|
+
content: "",
|
|
91
|
+
timestamp: ""
|
|
92
|
+
})
|
|
93
|
+
]
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
scrollToBottomRef.current?.scrollIntoView({ behavior: "auto" });
|
|
98
|
+
}, 0);
|
|
99
|
+
const finalMessages = [];
|
|
100
|
+
try {
|
|
101
|
+
const reader = await createMessage({
|
|
102
|
+
prompt,
|
|
103
|
+
selectedModel,
|
|
104
|
+
currentConversation
|
|
105
|
+
});
|
|
106
|
+
const decoder = new TextDecoder("utf-8");
|
|
107
|
+
const keepGoing = true;
|
|
108
|
+
while (keepGoing) {
|
|
109
|
+
const { done, value } = await reader.read();
|
|
110
|
+
if (done) break;
|
|
111
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
112
|
+
const data = splitJsonStrings(chunk) ?? [];
|
|
113
|
+
data?.forEach((line) => {
|
|
114
|
+
const trimmedLine = line.trim();
|
|
115
|
+
if (!trimmedLine) return;
|
|
116
|
+
try {
|
|
117
|
+
const jsonData = JSON.parse(line);
|
|
118
|
+
const content = jsonData?.response?.kwargs?.content || "";
|
|
119
|
+
finalMessages.push(content);
|
|
120
|
+
setConversations((prevConversations) => {
|
|
121
|
+
const conversation = prevConversations[currentConversation];
|
|
122
|
+
if (!conversation) {
|
|
123
|
+
return prevConversations;
|
|
124
|
+
}
|
|
125
|
+
const lastMessageIndex = conversation.length - 1;
|
|
126
|
+
const lastMessage = { ...conversation[lastMessageIndex] };
|
|
127
|
+
lastMessage.isLoading = false;
|
|
128
|
+
lastMessage.content += content;
|
|
129
|
+
lastMessage.name = jsonData?.response?.kwargs?.response_metadata?.model;
|
|
130
|
+
lastMessage.timestamp = getTimestamp(
|
|
131
|
+
jsonData?.response?.kwargs?.response_metadata?.created_at || Date.now()
|
|
132
|
+
);
|
|
133
|
+
const updatedConversation = [
|
|
134
|
+
...conversation.slice(0, lastMessageIndex),
|
|
135
|
+
lastMessage
|
|
136
|
+
];
|
|
137
|
+
return {
|
|
138
|
+
...prevConversations,
|
|
139
|
+
[currentConversation]: updatedConversation
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.warn("Error parsing JSON:", error);
|
|
144
|
+
if (typeof onComplete === "function") {
|
|
145
|
+
onComplete("Invalid JSON received");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
} catch (e) {
|
|
151
|
+
setConversations((prevConversations) => {
|
|
152
|
+
const conversation = prevConversations[currentConversation];
|
|
153
|
+
if (!conversation) {
|
|
154
|
+
return prevConversations;
|
|
155
|
+
}
|
|
156
|
+
const lastMessageIndex = conversation.length - 1;
|
|
157
|
+
const lastMessage = { ...conversation[lastMessageIndex] };
|
|
158
|
+
lastMessage.isLoading = false;
|
|
159
|
+
lastMessage.content += e;
|
|
160
|
+
lastMessage.timestamp = getTimestamp(Date.now());
|
|
161
|
+
const updatedConversation = [
|
|
162
|
+
...conversation.slice(0, lastMessageIndex),
|
|
163
|
+
lastMessage
|
|
164
|
+
];
|
|
165
|
+
finalMessages.push(`${e}`);
|
|
166
|
+
return {
|
|
167
|
+
...prevConversations,
|
|
168
|
+
[currentConversation]: updatedConversation
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (typeof onComplete === "function") {
|
|
173
|
+
onComplete(finalMessages.join(""));
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
[
|
|
177
|
+
avatar,
|
|
178
|
+
userName,
|
|
179
|
+
onComplete,
|
|
180
|
+
selectedModel,
|
|
181
|
+
createMessage,
|
|
182
|
+
currentConversation
|
|
183
|
+
]
|
|
184
|
+
);
|
|
185
|
+
return {
|
|
186
|
+
conversationMessages: conversations[currentConversation] ?? [],
|
|
187
|
+
handleInputPrompt,
|
|
188
|
+
conversations,
|
|
189
|
+
scrollToBottomRef,
|
|
190
|
+
...queryProps
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export { useConversationMessages, useFetchConversationMessages };
|
|
195
|
+
//# sourceMappingURL=useConversationMessages.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useConversationMessages.esm.js","sources":["../../src/hooks/useConversationMessages.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\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 */\nimport React from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { MessageProps } from '@patternfly/virtual-assistant';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport logo from '../images/logo.svg';\nimport {\n createBotMessage,\n createUserMessage,\n getMessageData,\n getTimestamp,\n splitJsonStrings,\n} from '../utils/lightspeed-chatbox-utils';\nimport { useCreateConversationMessage } from './useCreateCoversationMessage';\n\n// Fetch all conversation messages\nexport const useFetchConversationMessages = (currentConversation: string) => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['conversationMessages', currentConversation],\n queryFn: currentConversation\n ? async () => {\n const response =\n await lightspeedApi.getConversationMessages(currentConversation);\n\n return response;\n }\n : undefined,\n retry: false,\n });\n};\n\ntype Conversations = { [_key: string]: MessageProps[] };\n\n/**\n * Fetches all the messages for given conversation_id\n * @param conversationId\n * @param userName\n * @param selectedModel\n * @param avatar\n *\n */\nexport const useConversationMessages = (\n conversationId: string,\n userName: string | undefined,\n selectedModel: string,\n avatar: string | undefined,\n onComplete?: (message: string) => void,\n) => {\n const { mutateAsync: createMessage } = useCreateConversationMessage();\n const scrollToBottomRef = React.useRef<HTMLDivElement>(null);\n\n const [currentConversation, setCurrentConversation] =\n React.useState(conversationId);\n const [conversations, setConversations] = React.useState<Conversations>({\n [currentConversation]: [],\n });\n\n React.useEffect(() => {\n if (currentConversation !== conversationId) {\n setCurrentConversation(conversationId);\n setConversations({\n [conversationId]: [],\n });\n }\n }, [currentConversation, conversationId]);\n\n const { data: conversationsData = [], ...queryProps } =\n useFetchConversationMessages(currentConversation);\n\n React.useEffect(() => {\n if (!Array.isArray(conversationsData) || conversationsData.length === 0)\n return;\n\n const newConvoIndex: number[] = [];\n\n if (conversations) {\n const _conversations: { [key: string]: any[] } = {\n [currentConversation]: [],\n };\n\n let index = 0;\n for (let i = 0; i < conversationsData.length; i += 2) {\n const userMessage = conversationsData[i];\n const aiMessage = conversationsData[i + 1];\n\n const { content: humanMessage, timestamp: userTimestamp } =\n getMessageData(userMessage);\n const {\n model,\n content: botMessage,\n timestamp: botTimestamp,\n } = getMessageData(aiMessage);\n\n _conversations[currentConversation].push(\n ...[\n createUserMessage({\n avatar,\n name: userName,\n content: humanMessage,\n timestamp: userTimestamp,\n }),\n createBotMessage({\n avatar: logo,\n isLoading: false,\n name: model ?? selectedModel,\n content: botMessage,\n timestamp: botTimestamp,\n }),\n ],\n );\n\n newConvoIndex.push(index);\n index++;\n }\n setConversations(_conversations);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [conversationsData, userName, avatar, currentConversation, selectedModel]);\n\n const handleInputPrompt = React.useCallback(\n async (prompt: string) => {\n setConversations((prevConv: Conversations) => {\n return {\n ...prevConv,\n [currentConversation]: [\n ...(prevConv?.[currentConversation] ?? []),\n createUserMessage({\n avatar,\n name: userName,\n content: prompt,\n timestamp: getTimestamp(Date.now()) ?? '',\n }),\n createBotMessage({\n avatar: logo,\n isLoading: true,\n name: selectedModel,\n content: '',\n timestamp: '',\n }),\n ],\n };\n });\n\n setTimeout(() => {\n scrollToBottomRef.current?.scrollIntoView({ behavior: 'auto' });\n }, 0);\n const finalMessages: string[] = [];\n\n try {\n const reader = await createMessage({\n prompt,\n selectedModel,\n currentConversation,\n });\n\n const decoder = new TextDecoder('utf-8');\n const keepGoing = true;\n while (keepGoing) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n\n const data = splitJsonStrings(chunk) ?? [];\n data?.forEach(line => {\n const trimmedLine = line.trim();\n // Ignore empty lines\n if (!trimmedLine) return;\n try {\n const jsonData = JSON.parse(line);\n const content = jsonData?.response?.kwargs?.content || '';\n finalMessages.push(content);\n setConversations(prevConversations => {\n const conversation = prevConversations[currentConversation];\n\n if (!conversation) {\n return prevConversations;\n }\n const lastMessageIndex = conversation.length - 1;\n const lastMessage = { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += content;\n lastMessage.name =\n jsonData?.response?.kwargs?.response_metadata?.model;\n lastMessage.timestamp = getTimestamp(\n jsonData?.response?.kwargs?.response_metadata?.created_at ||\n Date.now(),\n );\n\n const updatedConversation = [\n ...conversation.slice(0, lastMessageIndex),\n lastMessage,\n ];\n\n return {\n ...prevConversations,\n [currentConversation]: updatedConversation,\n };\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Error parsing JSON:', error);\n if (typeof onComplete === 'function') {\n onComplete('Invalid JSON received');\n }\n }\n });\n }\n } catch (e) {\n setConversations(prevConversations => {\n const conversation = prevConversations[currentConversation];\n\n if (!conversation) {\n return prevConversations;\n }\n const lastMessageIndex = conversation.length - 1;\n const lastMessage = { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += e;\n lastMessage.timestamp = getTimestamp(Date.now());\n\n const updatedConversation = [\n ...conversation.slice(0, lastMessageIndex),\n lastMessage,\n ];\n\n finalMessages.push(`${e}`);\n\n return {\n ...prevConversations,\n [currentConversation]: updatedConversation,\n };\n });\n }\n\n if (typeof onComplete === 'function') {\n onComplete(finalMessages.join(''));\n }\n },\n\n [\n avatar,\n userName,\n onComplete,\n selectedModel,\n createMessage,\n currentConversation,\n ],\n );\n\n return {\n conversationMessages: conversations[currentConversation] ?? [],\n handleInputPrompt,\n conversations,\n scrollToBottomRef,\n ...queryProps,\n };\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
import { lightspeedApiRef } from '../api/api.esm.js';
|
|
4
|
+
|
|
5
|
+
const useConversations = () => {
|
|
6
|
+
const lightspeedApi = useApi(lightspeedApiRef);
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: ["conversations"],
|
|
9
|
+
queryFn: async () => {
|
|
10
|
+
const response = await lightspeedApi.getConversations();
|
|
11
|
+
return response;
|
|
12
|
+
},
|
|
13
|
+
staleTime: 1e3 * 60 * 5
|
|
14
|
+
// 5 minutes
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { useConversations };
|
|
19
|
+
//# sourceMappingURL=useConversations.esm.js.map
|