@red-hat-developer-hub/backstage-plugin-lightspeed 0.5.3 → 0.5.5
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 +26 -0
- package/README.md +3 -3
- package/dist/components/AttachmentContext.esm.js +2 -1
- package/dist/components/AttachmentContext.esm.js.map +1 -1
- package/dist/components/FilePreview.esm.js +2 -15
- package/dist/components/FilePreview.esm.js.map +1 -1
- package/dist/components/LightSpeedChat.esm.js +87 -25
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedPage.esm.js +9 -2
- package/dist/components/LightspeedPage.esm.js.map +1 -1
- package/dist/components/PermissionRequiredState.esm.js +1 -1
- package/dist/components/PermissionRequiredState.esm.js.map +1 -1
- package/dist/const.esm.js +11 -5
- package/dist/const.esm.js.map +1 -1
- package/dist/hooks/useConversationMessages.esm.js +10 -8
- package/dist/hooks/useConversationMessages.esm.js.map +1 -1
- package/dist/hooks/useLightspeedDeletePermission.esm.js +2 -2
- package/dist/hooks/useLightspeedDeletePermission.esm.js.map +1 -1
- package/dist/hooks/useLightspeedViewPermission.esm.js +7 -7
- package/dist/hooks/useLightspeedViewPermission.esm.js.map +1 -1
- package/dist/images/bot-avatar.svg +15 -0
- package/dist/images/user-avatar.svg +4 -0
- package/dist/types.esm.js +1 -0
- package/dist/types.esm.js.map +1 -1
- package/dist/utils/attachment-utils.esm.js +12 -2
- package/dist/utils/attachment-utils.esm.js.map +1 -1
- package/dist/utils/lightspeed-chatbox-utils.esm.js +18 -3
- package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
- package/package.json +4 -4
- package/dist/images/logo.svg +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
## @red-hat-developer-hub/backstage-plugin-lightspeed
|
|
2
2
|
|
|
3
|
+
## 0.5.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5d80736: Renamed permissions to align with the updated naming convention:
|
|
8
|
+
|
|
9
|
+
- `lightspeed.conversations.read` → `lightspeed.chat.read`
|
|
10
|
+
- `lightspeed.conversations.create` → `lightspeed.chat.create`
|
|
11
|
+
- `lightspeed.conversations.delete` → `lightspeed.chat.delete`
|
|
12
|
+
|
|
13
|
+
- 936c52c: Update the plugin name to Developer lightspeed
|
|
14
|
+
- 717c505: change the lightspeed user and bot avatars
|
|
15
|
+
- Updated dependencies [5d80736]
|
|
16
|
+
- @red-hat-developer-hub/backstage-plugin-lightspeed-common@0.3.2
|
|
17
|
+
|
|
18
|
+
## 0.5.4
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- 555ef5b: Added support for Drag and Drop attachment upload
|
|
23
|
+
- ee1da3b: enable only supported file types in file picker
|
|
24
|
+
- 13dd7b1: Updated dependency `@patternfly/chatbot` to `6.3.0-prerelease.20`.
|
|
25
|
+
Updated dependency `@patternfly/react-core` to `6.3.0-prerelease.17`.
|
|
26
|
+
- 717a32b: Updated dependency `@patternfly/react-core` to `6.3.0-prerelease.16`.
|
|
27
|
+
- 6495f17: Make source card links as external links
|
|
28
|
+
|
|
3
29
|
## 0.5.3
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ The Lightspeed plugin has support for the permission framework.
|
|
|
17
17
|
- When [RBAC permission](https://github.com/backstage/community-plugins/tree/main/workspaces/rbac/plugins/rbac-backend#installation) framework is enabled, for non-admin users to access lightspeed UI, the role associated with your user should have the following permission policies associated with it. Add the following in your permission policies configuration file named `rbac-policy.csv`:
|
|
18
18
|
|
|
19
19
|
```CSV
|
|
20
|
-
p, role:default/team_a, lightspeed.
|
|
21
|
-
p, role:default/team_a, lightspeed.
|
|
22
|
-
p, role:default/team_a, lightspeed.
|
|
20
|
+
p, role:default/team_a, lightspeed.chat.read, read, allow
|
|
21
|
+
p, role:default/team_a, lightspeed.chat.create, create, allow
|
|
22
|
+
p, role:default/team_a, lightspeed.chat.delete, delete, allow
|
|
23
23
|
|
|
24
24
|
g, user:default/<your-user-name>, role:default/team_a
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ const FileAttachmentContextProvider = ({ children }) => {
|
|
|
33
33
|
if (!isSupportedFileType(fileArr[0])) {
|
|
34
34
|
setShowAlert(true);
|
|
35
35
|
setUploadError({
|
|
36
|
-
message: "Unsupported file type. Supported types are: .txt, .yaml, .json."
|
|
36
|
+
message: "Unsupported file type. Supported types are: .txt, .yaml, .json and .xml."
|
|
37
37
|
});
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
@@ -80,6 +80,7 @@ const FileAttachmentContextProvider = ({ children }) => {
|
|
|
80
80
|
handleFileUpload,
|
|
81
81
|
isLoadingFile,
|
|
82
82
|
showAlert,
|
|
83
|
+
setShowAlert,
|
|
83
84
|
uploadError,
|
|
84
85
|
setUploadError,
|
|
85
86
|
currentFileContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachmentContext.esm.js","sources":["../../src/components/AttachmentContext.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 */\nimport React from 'react';\n\nimport { FileContent } from '../types';\nimport { isSupportedFileType, readFileAsText } from '../utils/attachment-utils';\n\ntype UploadError = { type?: 'info' | 'danger'; message: string | null };\ninterface FileAttachmentContextType {\n showAlert: boolean;\n uploadError: UploadError;\n fileContents: FileContent[];\n isLoadingFile: Record<string, boolean>;\n handleFileUpload: (files: File[]) => void;\n setFileContents: React.Dispatch<React.SetStateAction<FileContent[]>>;\n setUploadError: React.Dispatch<React.SetStateAction<UploadError>>;\n currentFileContent?: FileContent;\n setCurrentFileContent: React.Dispatch<\n React.SetStateAction<FileContent | undefined>\n >;\n modalState: {\n previewModalKey: number;\n setPreviewModalKey: React.Dispatch<React.SetStateAction<number>>;\n isPreviewModalOpen: boolean;\n setIsPreviewModalOpen: React.Dispatch<React.SetStateAction<boolean>>;\n isEditModalOpen: boolean;\n setIsEditModalOpen: React.Dispatch<React.SetStateAction<boolean>>;\n };\n}\n\nexport const FileAttachmentContext =\n React.createContext<FileAttachmentContextType | null>(null);\n\nconst FileAttachmentContextProvider: React.FC<{\n children: React.ReactNode;\n}> = ({ children }) => {\n const [currentFileContent, setCurrentFileContent] = React.useState<\n FileContent | undefined\n >();\n const [isLoadingFile, setIsLoadingFile] = React.useState<\n Record<string, boolean>\n >({});\n const [previewModalKey, setPreviewModalKey] = React.useState<number>(0);\n const [showAlert, setShowAlert] = React.useState<boolean>(false);\n const [uploadError, setUploadError] = React.useState<UploadError>({\n message: null,\n });\n const [fileContents, setFileContents] = React.useState<FileContent[]>([]);\n const [isPreviewModalOpen, setIsPreviewModalOpen] =\n React.useState<boolean>(false);\n const [isEditModalOpen, setIsEditModalOpen] = React.useState<boolean>(false);\n const handleFileUpload = (fileArr: File[]) => {\n const existingFile = fileContents.find(\n file => file.name === fileArr[0].name,\n );\n if (existingFile) {\n setShowAlert(true);\n setUploadError({ type: 'info', message: 'File already exists.' });\n return;\n }\n\n setIsLoadingFile({ [fileArr[0].name]: true });\n\n if (fileArr.length > 1) {\n setShowAlert(true);\n setUploadError({\n message: 'Uploaded more than one file.',\n });\n return;\n }\n if (!isSupportedFileType(fileArr[0])) {\n setShowAlert(true);\n setUploadError({\n message:\n 'Unsupported file type. Supported types are: .txt, .yaml, .json.',\n });\n return;\n }\n\n // this is 25MB in bytes; size is in bytes\n if (fileArr[0].size > 25000000) {\n setShowAlert(true);\n setUploadError({\n message:\n 'Your file size is too large. Please ensure that your file is less than 25 MB.',\n });\n return;\n }\n\n readFileAsText(fileArr[0])\n .then(data => {\n setFileContents(prev => [\n ...prev,\n {\n name: fileArr[0].name,\n type: fileArr[0].type,\n content: data as string,\n },\n ]);\n setShowAlert(false);\n setUploadError({ message: null });\n setIsLoadingFile({ [fileArr[0].name]: false });\n })\n .catch((error: DOMException) => {\n setUploadError({\n message: `Failed to read file: ${error.message}`,\n });\n });\n };\n\n const modalState = {\n isPreviewModalOpen,\n setIsPreviewModalOpen,\n isEditModalOpen,\n setIsEditModalOpen,\n previewModalKey,\n setPreviewModalKey,\n };\n return (\n <FileAttachmentContext.Provider\n value={{\n modalState,\n fileContents,\n setFileContents,\n handleFileUpload,\n isLoadingFile,\n showAlert,\n uploadError,\n setUploadError,\n currentFileContent,\n setCurrentFileContent,\n }}\n >\n {children}\n </FileAttachmentContext.Provider>\n );\n};\n\nexport default FileAttachmentContextProvider;\n\nexport const useFileAttachmentContext = (): FileAttachmentContextType => {\n const context = React.useContext<FileAttachmentContextType | null>(\n FileAttachmentContext,\n );\n\n if (context === null) {\n throw new Error(\n 'useFileAttachmentContext must be within a FileAttachmentContextProvider',\n );\n }\n\n return context;\n};\n"],"names":["React"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"AttachmentContext.esm.js","sources":["../../src/components/AttachmentContext.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 */\nimport React from 'react';\n\nimport { FileContent } from '../types';\nimport { isSupportedFileType, readFileAsText } from '../utils/attachment-utils';\n\ntype UploadError = { type?: 'info' | 'danger'; message: string | null };\ninterface FileAttachmentContextType {\n showAlert: boolean;\n uploadError: UploadError;\n fileContents: FileContent[];\n isLoadingFile: Record<string, boolean>;\n handleFileUpload: (files: File[]) => void;\n setFileContents: React.Dispatch<React.SetStateAction<FileContent[]>>;\n setUploadError: React.Dispatch<React.SetStateAction<UploadError>>;\n setShowAlert: React.Dispatch<React.SetStateAction<boolean>>;\n currentFileContent?: FileContent;\n setCurrentFileContent: React.Dispatch<\n React.SetStateAction<FileContent | undefined>\n >;\n modalState: {\n previewModalKey: number;\n setPreviewModalKey: React.Dispatch<React.SetStateAction<number>>;\n isPreviewModalOpen: boolean;\n setIsPreviewModalOpen: React.Dispatch<React.SetStateAction<boolean>>;\n isEditModalOpen: boolean;\n setIsEditModalOpen: React.Dispatch<React.SetStateAction<boolean>>;\n };\n}\n\nexport const FileAttachmentContext =\n React.createContext<FileAttachmentContextType | null>(null);\n\nconst FileAttachmentContextProvider: React.FC<{\n children: React.ReactNode;\n}> = ({ children }) => {\n const [currentFileContent, setCurrentFileContent] = React.useState<\n FileContent | undefined\n >();\n const [isLoadingFile, setIsLoadingFile] = React.useState<\n Record<string, boolean>\n >({});\n const [previewModalKey, setPreviewModalKey] = React.useState<number>(0);\n const [showAlert, setShowAlert] = React.useState<boolean>(false);\n const [uploadError, setUploadError] = React.useState<UploadError>({\n message: null,\n });\n const [fileContents, setFileContents] = React.useState<FileContent[]>([]);\n const [isPreviewModalOpen, setIsPreviewModalOpen] =\n React.useState<boolean>(false);\n const [isEditModalOpen, setIsEditModalOpen] = React.useState<boolean>(false);\n const handleFileUpload = (fileArr: File[]) => {\n const existingFile = fileContents.find(\n file => file.name === fileArr[0].name,\n );\n if (existingFile) {\n setShowAlert(true);\n setUploadError({ type: 'info', message: 'File already exists.' });\n return;\n }\n\n setIsLoadingFile({ [fileArr[0].name]: true });\n\n if (fileArr.length > 1) {\n setShowAlert(true);\n setUploadError({\n message: 'Uploaded more than one file.',\n });\n return;\n }\n if (!isSupportedFileType(fileArr[0])) {\n setShowAlert(true);\n setUploadError({\n message:\n 'Unsupported file type. Supported types are: .txt, .yaml, .json and .xml.',\n });\n return;\n }\n\n // this is 25MB in bytes; size is in bytes\n if (fileArr[0].size > 25000000) {\n setShowAlert(true);\n setUploadError({\n message:\n 'Your file size is too large. Please ensure that your file is less than 25 MB.',\n });\n return;\n }\n\n readFileAsText(fileArr[0])\n .then(data => {\n setFileContents(prev => [\n ...prev,\n {\n name: fileArr[0].name,\n type: fileArr[0].type,\n content: data as string,\n },\n ]);\n setShowAlert(false);\n setUploadError({ message: null });\n setIsLoadingFile({ [fileArr[0].name]: false });\n })\n .catch((error: DOMException) => {\n setUploadError({\n message: `Failed to read file: ${error.message}`,\n });\n });\n };\n\n const modalState = {\n isPreviewModalOpen,\n setIsPreviewModalOpen,\n isEditModalOpen,\n setIsEditModalOpen,\n previewModalKey,\n setPreviewModalKey,\n };\n return (\n <FileAttachmentContext.Provider\n value={{\n modalState,\n fileContents,\n setFileContents,\n handleFileUpload,\n isLoadingFile,\n showAlert,\n setShowAlert,\n uploadError,\n setUploadError,\n currentFileContent,\n setCurrentFileContent,\n }}\n >\n {children}\n </FileAttachmentContext.Provider>\n );\n};\n\nexport default FileAttachmentContextProvider;\n\nexport const useFileAttachmentContext = (): FileAttachmentContextType => {\n const context = React.useContext<FileAttachmentContextType | null>(\n FileAttachmentContext,\n );\n\n if (context === null) {\n throw new Error(\n 'useFileAttachmentContext must be within a FileAttachmentContextProvider',\n );\n }\n\n return context;\n};\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
2
|
import { Divider } from '@material-ui/core';
|
|
3
|
-
import { FileDetailsLabel
|
|
3
|
+
import { FileDetailsLabel } from '@patternfly/chatbot';
|
|
4
4
|
import { useFileAttachmentContext } from './AttachmentContext.esm.js';
|
|
5
5
|
|
|
6
6
|
const FilePreview = () => {
|
|
7
7
|
const {
|
|
8
|
-
showAlert,
|
|
9
8
|
fileContents,
|
|
10
9
|
isLoadingFile,
|
|
11
|
-
uploadError,
|
|
12
10
|
modalState,
|
|
13
11
|
setFileContents,
|
|
14
|
-
setUploadError,
|
|
15
12
|
setCurrentFileContent
|
|
16
13
|
} = useFileAttachmentContext();
|
|
17
14
|
const { setIsEditModalOpen, setIsPreviewModalOpen, setPreviewModalKey } = modalState;
|
|
@@ -42,17 +39,7 @@ const FilePreview = () => {
|
|
|
42
39
|
removeFile(index);
|
|
43
40
|
}
|
|
44
41
|
}
|
|
45
|
-
)))
|
|
46
|
-
ChatbotAlert,
|
|
47
|
-
{
|
|
48
|
-
component: "h4",
|
|
49
|
-
title: "File upload failed",
|
|
50
|
-
variant: uploadError.type ?? "danger",
|
|
51
|
-
isInline: true,
|
|
52
|
-
onClose: () => setUploadError({ message: null })
|
|
53
|
-
},
|
|
54
|
-
uploadError.message
|
|
55
|
-
));
|
|
42
|
+
))));
|
|
56
43
|
};
|
|
57
44
|
|
|
58
45
|
export { FilePreview as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePreview.esm.js","sources":["../../src/components/FilePreview.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 */\nimport React from 'react';\n\nimport { Divider } from '@material-ui/core';\nimport {
|
|
1
|
+
{"version":3,"file":"FilePreview.esm.js","sources":["../../src/components/FilePreview.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 */\nimport React from 'react';\n\nimport { Divider } from '@material-ui/core';\nimport { FileDetailsLabel } from '@patternfly/chatbot';\n\nimport { useFileAttachmentContext } from './AttachmentContext';\n\nconst FilePreview = () => {\n const {\n fileContents,\n isLoadingFile,\n modalState,\n setFileContents,\n setCurrentFileContent,\n } = useFileAttachmentContext();\n\n const { setIsEditModalOpen, setIsPreviewModalOpen, setPreviewModalKey } =\n modalState;\n\n const onAttachmentClick = (_: React.MouseEvent, name: string) => {\n const file = fileContents?.find(f => f.name === name);\n setCurrentFileContent({\n name,\n type: file?.type ?? 'text/plain',\n content: file?.content ?? '',\n });\n setPreviewModalKey(prev => prev + 1); // update key to re-render content\n setIsEditModalOpen(false);\n setIsPreviewModalOpen(true);\n };\n\n const removeFile = (indexToRemove: number) => {\n setFileContents(prevContents =>\n prevContents.filter((_, index) => index !== indexToRemove),\n );\n };\n\n return (\n <>\n {fileContents.length > 0 && <Divider />}\n {fileContents && (\n <div style={{ display: 'flex', gap: '10px' }}>\n {fileContents.map((file, index) => (\n <FileDetailsLabel\n key={index}\n fileName={file.name}\n isLoading={isLoadingFile[file.name]}\n onClick={onAttachmentClick}\n onClose={() => {\n removeFile(index);\n }}\n />\n ))}\n </div>\n )}\n </>\n );\n};\n\nexport default FilePreview;\n"],"names":["React"],"mappings":";;;;;AAsBA,MAAM,cAAc,MAAM;AACxB,EAAM,MAAA;AAAA,IACJ,YAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,MACE,wBAAyB,EAAA;AAE7B,EAAA,MAAM,EAAE,kBAAA,EAAoB,qBAAuB,EAAA,kBAAA,EACjD,GAAA,UAAA;AAEF,EAAM,MAAA,iBAAA,GAAoB,CAAC,CAAA,EAAqB,IAAiB,KAAA;AAC/D,IAAA,MAAM,OAAO,YAAc,EAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,IAAI,CAAA;AACpD,IAAsB,qBAAA,CAAA;AAAA,MACpB,IAAA;AAAA,MACA,IAAA,EAAM,MAAM,IAAQ,IAAA,YAAA;AAAA,MACpB,OAAA,EAAS,MAAM,OAAW,IAAA;AAAA,KAC3B,CAAA;AACD,IAAmB,kBAAA,CAAA,CAAA,IAAA,KAAQ,OAAO,CAAC,CAAA;AACnC,IAAA,kBAAA,CAAmB,KAAK,CAAA;AACxB,IAAA,qBAAA,CAAsB,IAAI,CAAA;AAAA,GAC5B;AAEA,EAAM,MAAA,UAAA,GAAa,CAAC,aAA0B,KAAA;AAC5C,IAAA,eAAA;AAAA,MAAgB,kBACd,YAAa,CAAA,MAAA,CAAO,CAAC,CAAG,EAAA,KAAA,KAAU,UAAU,aAAa;AAAA,KAC3D;AAAA,GACF;AAEA,EACE,uBAAAA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA,EACG,aAAa,MAAS,GAAA,CAAA,iDAAM,OAAQ,EAAA,IAAA,CAAA,EACpC,gCACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,OAAO,EAAE,OAAA,EAAS,QAAQ,GAAK,EAAA,MAAA,MACjC,YAAa,CAAA,GAAA,CAAI,CAAC,IAAA,EAAM,KACvB,qBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,KAAA;AAAA,MACL,UAAU,IAAK,CAAA,IAAA;AAAA,MACf,SAAA,EAAW,aAAc,CAAA,IAAA,CAAK,IAAI,CAAA;AAAA,MAClC,OAAS,EAAA,iBAAA;AAAA,MACT,SAAS,MAAM;AACb,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB;AAAA,GAEH,CACH,CAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
2
|
import { ErrorPanel } from '@backstage/core-components';
|
|
3
3
|
import { makeStyles, Box } from '@material-ui/core';
|
|
4
|
-
import { Chatbot, ChatbotDisplayMode, ChatbotHeader, ChatbotHeaderMain, ChatbotHeaderMenu, ChatbotHeaderTitle, ChatbotContent, ChatbotFooter, MessageBar, ChatbotFootnote } from '@patternfly/chatbot';
|
|
4
|
+
import { Chatbot, ChatbotDisplayMode, ChatbotHeader, ChatbotHeaderMain, ChatbotHeaderMenu, ChatbotHeaderTitle, FileDropZone, ChatbotAlert, ChatbotContent, ChatbotFooter, MessageBar, ChatbotFootnote } from '@patternfly/chatbot';
|
|
5
5
|
import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
|
|
6
6
|
import { DropdownItem, Title } from '@patternfly/react-core';
|
|
7
7
|
import { useQueryClient } from '@tanstack/react-query';
|
|
8
|
-
import { TEMP_CONVERSATION_ID } from '../const.esm.js';
|
|
8
|
+
import { TEMP_CONVERSATION_ID, supportedFileTypes } from '../const.esm.js';
|
|
9
9
|
import '@backstage/core-plugin-api';
|
|
10
10
|
import '../api/api.esm.js';
|
|
11
11
|
import { useBackstageUserIdentity } from '../hooks/useBackstageUserIdentity.esm.js';
|
|
@@ -38,6 +38,9 @@ const useStyles = makeStyles((theme) => ({
|
|
|
38
38
|
header: {
|
|
39
39
|
padding: `${theme.spacing(3)}px !important`
|
|
40
40
|
},
|
|
41
|
+
errorContainer: {
|
|
42
|
+
padding: theme.spacing(3)
|
|
43
|
+
},
|
|
41
44
|
headerMenu: {
|
|
42
45
|
// align hamburger icon with title
|
|
43
46
|
"& .pf-v6-c-button": {
|
|
@@ -81,7 +84,15 @@ const LightspeedChat = ({
|
|
|
81
84
|
const [targetConversationId, setTargetConversationId] = React__default.useState("");
|
|
82
85
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = React__default.useState(false);
|
|
83
86
|
const { isReady, lastOpenedId, setLastOpenedId, clearLastOpenedId } = useLastOpenedConversation(user);
|
|
84
|
-
const {
|
|
87
|
+
const {
|
|
88
|
+
uploadError,
|
|
89
|
+
showAlert,
|
|
90
|
+
fileContents,
|
|
91
|
+
setShowAlert,
|
|
92
|
+
setFileContents,
|
|
93
|
+
handleFileUpload,
|
|
94
|
+
setUploadError
|
|
95
|
+
} = useFileAttachmentContext();
|
|
85
96
|
React__default.useEffect(() => {
|
|
86
97
|
if (isReady && lastOpenedId !== null) {
|
|
87
98
|
setConversationId(lastOpenedId);
|
|
@@ -150,11 +161,19 @@ const LightspeedChat = ({
|
|
|
150
161
|
(async () => {
|
|
151
162
|
if (conversationId !== TEMP_CONVERSATION_ID) {
|
|
152
163
|
setMessages([]);
|
|
164
|
+
setFileContents([]);
|
|
165
|
+
setUploadError({ message: null });
|
|
153
166
|
setConversationId(TEMP_CONVERSATION_ID);
|
|
154
167
|
setNewChatCreated(true);
|
|
155
168
|
}
|
|
156
169
|
})();
|
|
157
|
-
}, [
|
|
170
|
+
}, [
|
|
171
|
+
conversationId,
|
|
172
|
+
setConversationId,
|
|
173
|
+
setMessages,
|
|
174
|
+
setUploadError,
|
|
175
|
+
setFileContents
|
|
176
|
+
]);
|
|
158
177
|
const openDeleteModal = (conversation_id) => {
|
|
159
178
|
setTargetConversationId(conversation_id);
|
|
160
179
|
setIsDeleteModalOpen(true);
|
|
@@ -230,9 +249,11 @@ const LightspeedChat = ({
|
|
|
230
249
|
}
|
|
231
250
|
return c_id;
|
|
232
251
|
});
|
|
252
|
+
setFileContents([]);
|
|
253
|
+
setUploadError({ message: null });
|
|
233
254
|
scrollToBottomRef.current?.scrollToBottom();
|
|
234
255
|
},
|
|
235
|
-
[setConversationId, scrollToBottomRef]
|
|
256
|
+
[setConversationId, setUploadError, setFileContents, scrollToBottomRef]
|
|
236
257
|
);
|
|
237
258
|
const conversationFound = !!conversations.find(
|
|
238
259
|
(c) => c.conversation_id === conversationId
|
|
@@ -254,6 +275,16 @@ const LightspeedChat = ({
|
|
|
254
275
|
event.preventDefault();
|
|
255
276
|
handleFileUpload(data);
|
|
256
277
|
};
|
|
278
|
+
const onAttachRejected = (data) => {
|
|
279
|
+
data.forEach((attachment) => {
|
|
280
|
+
if (!!attachment.errors.find((e) => e.code === "file-invalid-type")) {
|
|
281
|
+
setShowAlert(true);
|
|
282
|
+
setUploadError({
|
|
283
|
+
message: "Unsupported file type. Supported types are: .txt, .yaml, .json and .xml."
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
};
|
|
257
288
|
if (error) {
|
|
258
289
|
return /* @__PURE__ */ React__default.createElement(Box, { padding: 1 }, /* @__PURE__ */ React__default.createElement(ErrorPanel, { error }));
|
|
259
290
|
}
|
|
@@ -277,7 +308,7 @@ const LightspeedChat = ({
|
|
|
277
308
|
onMenuToggle: () => setIsDrawerOpen(!isDrawerOpen),
|
|
278
309
|
className: classes.headerMenu
|
|
279
310
|
}
|
|
280
|
-
), /* @__PURE__ */ React__default.createElement(ChatbotHeaderTitle, { className: classes.headerTitle }, /* @__PURE__ */ React__default.createElement(Title, { headingLevel: "h1", size: "3xl" }, "Developer
|
|
311
|
+
), /* @__PURE__ */ React__default.createElement(ChatbotHeaderTitle, { className: classes.headerTitle }, /* @__PURE__ */ React__default.createElement(Title, { headingLevel: "h1", size: "3xl" }, "Developer Lightspeed"))), /* @__PURE__ */ React__default.createElement(
|
|
281
312
|
LightspeedChatBoxHeader,
|
|
282
313
|
{
|
|
283
314
|
selectedModel,
|
|
@@ -299,26 +330,57 @@ const LightspeedChat = ({
|
|
|
299
330
|
conversations: filterConversations(filterValue),
|
|
300
331
|
onNewChat: newChatCreated ? undefined : onNewChat,
|
|
301
332
|
handleTextInputChange: handleFilter,
|
|
302
|
-
|
|
303
|
-
|
|
333
|
+
searchInputPlaceholder: "Search previous chats...",
|
|
334
|
+
drawerContent: /* @__PURE__ */ React__default.createElement(
|
|
335
|
+
FileDropZone,
|
|
304
336
|
{
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
337
|
+
onFileDrop: (e, data) => handleAttach(data, e),
|
|
338
|
+
displayMode: ChatbotDisplayMode.embedded,
|
|
339
|
+
infoText: "Supported file types are: .txt, .yaml, .json and .xml. The maximum file size is 25 MB.",
|
|
340
|
+
allowedFileTypes: supportedFileTypes,
|
|
341
|
+
onAttachRejected
|
|
342
|
+
},
|
|
343
|
+
showAlert && uploadError.message && /* @__PURE__ */ React__default.createElement("div", { className: classes.errorContainer }, /* @__PURE__ */ React__default.createElement(
|
|
344
|
+
ChatbotAlert,
|
|
345
|
+
{
|
|
346
|
+
component: "h4",
|
|
347
|
+
title: "File upload failed",
|
|
348
|
+
variant: uploadError.type ?? "danger",
|
|
349
|
+
isInline: true,
|
|
350
|
+
onClose: () => setUploadError({ message: null })
|
|
351
|
+
},
|
|
352
|
+
uploadError.message
|
|
353
|
+
)),
|
|
354
|
+
/* @__PURE__ */ React__default.createElement(ChatbotContent, null, /* @__PURE__ */ React__default.createElement(
|
|
355
|
+
LightspeedChatBox,
|
|
356
|
+
{
|
|
357
|
+
userName,
|
|
358
|
+
messages,
|
|
359
|
+
profileLoading,
|
|
360
|
+
announcement,
|
|
361
|
+
ref: scrollToBottomRef,
|
|
362
|
+
welcomePrompts
|
|
363
|
+
}
|
|
364
|
+
)),
|
|
365
|
+
/* @__PURE__ */ React__default.createElement(ChatbotFooter, { className: classes.footer }, /* @__PURE__ */ React__default.createElement(FilePreview, null), /* @__PURE__ */ React__default.createElement(
|
|
366
|
+
MessageBar,
|
|
367
|
+
{
|
|
368
|
+
onSendMessage: sendMessage,
|
|
369
|
+
isSendButtonDisabled,
|
|
370
|
+
hasAttachButton: true,
|
|
371
|
+
handleAttach,
|
|
372
|
+
hasMicrophoneButton: true,
|
|
373
|
+
buttonProps: {
|
|
374
|
+
attach: {
|
|
375
|
+
inputTestId: "attachment-input"
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
allowedFileTypes: supportedFileTypes,
|
|
379
|
+
onAttachRejected,
|
|
380
|
+
placeholder: "Send a message and optionally upload a JSON, YAML, TXT, or XML file..."
|
|
381
|
+
}
|
|
382
|
+
), /* @__PURE__ */ React__default.createElement(ChatbotFootnote, { ...getFootnoteProps(classes.footerPopover) }))
|
|
383
|
+
)
|
|
322
384
|
}
|
|
323
385
|
)
|
|
324
386
|
), /* @__PURE__ */ React__default.createElement(Attachment, null));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightSpeedChat.esm.js","sources":["../../src/components/LightSpeedChat.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 React from 'react';\n\nimport { ErrorPanel } from '@backstage/core-components';\n\nimport { Box, makeStyles } from '@material-ui/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/chatbot';\nimport ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';\nimport { DropdownItem, DropEvent, Title } from '@patternfly/react-core';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { TEMP_CONVERSATION_ID } from '../const';\nimport {\n useBackstageUserIdentity,\n useConversationMessages,\n useConversations,\n useDeleteConversation,\n useIsMobile,\n useLastOpenedConversation,\n useLightspeedDeletePermission,\n} from '../hooks';\nimport { useWelcomePrompts } from '../hooks/useWelcomePrompts';\nimport { ConversationSummary } from '../types';\nimport { getAttachments } from '../utils/attachment-utils';\nimport {\n getCategorizeMessages,\n getFootnoteProps,\n} from '../utils/lightspeed-chatbox-utils';\nimport Attachment from './Attachment';\nimport { useFileAttachmentContext } from './AttachmentContext';\nimport { DeleteModal } from './DeleteModal';\nimport FilePreview from './FilePreview';\nimport { LightspeedChatBox } from './LightspeedChatBox';\nimport { LightspeedChatBoxHeader } from './LightspeedChatBoxHeader';\n\nconst useStyles = makeStyles(theme => ({\n body: {\n // remove default margin and padding from common elements\n '& h1, & h2, & h3, & h4, & h5, & h6, & p, & ul, & ol, & li': {\n margin: 0,\n padding: 0,\n },\n },\n header: {\n padding: `${theme.spacing(3)}px !important`,\n },\n headerMenu: {\n // align hamburger icon with title\n '& .pf-v6-c-button': {\n display: 'flex',\n alignItems: 'center',\n },\n },\n headerTitle: {\n justifyContent: 'left !important',\n },\n footer: {\n '&>.pf-chatbot__footer-container': {\n width: '95% !important',\n maxWidth: 'unset !important',\n },\n },\n footerPopover: {\n '& img': {\n maxWidth: '100%',\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 isMobile = useIsMobile();\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>(!isMobile);\n const [newChatCreated, setNewChatCreated] = React.useState<boolean>(false);\n const [isSendButtonDisabled, setIsSendButtonDisabled] =\n React.useState<boolean>(false);\n const [error, setError] = React.useState<Error | null>(null);\n const [targetConversationId, setTargetConversationId] =\n React.useState<string>('');\n const [isDeleteModalOpen, setIsDeleteModalOpen] =\n React.useState<boolean>(false);\n const { isReady, lastOpenedId, setLastOpenedId, clearLastOpenedId } =\n useLastOpenedConversation(user);\n\n const { fileContents, setFileContents, handleFileUpload } =\n useFileAttachmentContext();\n\n // Sync conversationId with lastOpenedId whenever lastOpenedId changes\n React.useEffect(() => {\n if (isReady && lastOpenedId !== null) {\n setConversationId(lastOpenedId);\n }\n }, [lastOpenedId, isReady]);\n\n const queryClient = useQueryClient();\n\n const {\n data: conversations = [],\n isLoading,\n isRefetching,\n } = useConversations();\n const { mutateAsync: deleteConversation } = useDeleteConversation();\n const { allowed: hasDeleteAccess } = useLightspeedDeletePermission();\n const samplePrompts = useWelcomePrompts();\n React.useEffect(() => {\n if (user && lastOpenedId === null && isReady) {\n setConversationId(TEMP_CONVERSATION_ID);\n setNewChatCreated(true);\n }\n }, [user, isReady, lastOpenedId, setConversationId]);\n\n React.useEffect(() => {\n // Clear last opened conversationId when there are no conversations.\n if (\n !isLoading &&\n !isRefetching &&\n conversations.length === 0 &&\n lastOpenedId\n ) {\n clearLastOpenedId();\n }\n }, [isLoading, isRefetching, conversations, lastOpenedId, clearLastOpenedId]);\n\n React.useEffect(() => {\n // Update last opened conversation whenever `conversationId` changes\n if (conversationId) {\n setLastOpenedId(conversationId);\n }\n }, [conversationId, setLastOpenedId]);\n\n const onStart = (conv_id: string) => {\n setConversationId(conv_id);\n };\n\n const onComplete = (message: string) => {\n setIsSendButtonDisabled(false);\n setAnnouncement(`Message from Bot: ${message}`);\n queryClient.invalidateQueries({\n queryKey: ['conversations'],\n });\n queryClient.invalidateQueries({\n queryKey: ['conversationMessages', conversationId],\n });\n setNewChatCreated(false);\n };\n\n const { conversationMessages, handleInputPrompt, scrollToBottomRef } =\n useConversationMessages(\n conversationId,\n userName,\n selectedModel,\n avatar,\n onComplete,\n onStart,\n );\n\n const [messages, setMessages] =\n React.useState<MessageProps[]>(conversationMessages);\n\n const sendMessage = (message: string | number) => {\n if (conversationId !== TEMP_CONVERSATION_ID) {\n setNewChatCreated(false);\n }\n setAnnouncement(\n `Message from User: ${prompt}. Message from Bot is loading.`,\n );\n handleInputPrompt(message.toString(), getAttachments(fileContents));\n setIsSendButtonDisabled(true);\n setFileContents([]);\n };\n\n const onNewChat = React.useCallback(() => {\n (async () => {\n if (conversationId !== TEMP_CONVERSATION_ID) {\n setMessages([]);\n setConversationId(TEMP_CONVERSATION_ID);\n setNewChatCreated(true);\n }\n })();\n }, [conversationId, setConversationId, setMessages]);\n\n const openDeleteModal = (conversation_id: string) => {\n setTargetConversationId(conversation_id);\n setIsDeleteModalOpen(true);\n };\n\n const handleDeleteConversation = React.useCallback(() => {\n (async () => {\n try {\n await deleteConversation({\n conversation_id: targetConversationId,\n invalidateCache: false,\n });\n if (targetConversationId === lastOpenedId) {\n onNewChat();\n clearLastOpenedId();\n }\n setIsDeleteModalOpen(false);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n setError(e);\n }\n })();\n }, [\n deleteConversation,\n clearLastOpenedId,\n lastOpenedId,\n onNewChat,\n targetConversationId,\n ]);\n\n const additionalMessageProps = React.useCallback(\n (conversationSummary: ConversationSummary) => ({\n menuItems: (\n <DropdownItem\n isDisabled={!hasDeleteAccess}\n onClick={() => openDeleteModal(conversationSummary.conversation_id)}\n >\n Delete\n </DropdownItem>\n ),\n }),\n [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 scrollToBottomRef.current?.scrollToBottom();\n },\n [setConversationId, scrollToBottomRef],\n );\n\n const conversationFound = !!conversations.find(\n (c: ConversationSummary) => c.conversation_id === conversationId,\n );\n\n const welcomePrompts =\n (newChatCreated && conversationMessages.length === 0) ||\n (!conversationFound && conversationMessages.length === 0)\n ? samplePrompts?.map(prompt => ({\n title: prompt.title,\n message: prompt.message,\n onClick: () => {\n sendMessage(prompt.message);\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 const handleAttach = (data: File[], event: DropEvent) => {\n event.preventDefault();\n handleFileUpload(data);\n };\n\n if (error) {\n return (\n <Box padding={1}>\n <ErrorPanel error={error} />\n </Box>\n );\n }\n\n return (\n <>\n {isDeleteModalOpen && (\n <DeleteModal\n isOpen={isDeleteModalOpen}\n onClose={() => setIsDeleteModalOpen(false)}\n onConfirm={handleDeleteConversation}\n />\n )}\n <Chatbot\n displayMode={ChatbotDisplayMode.embedded}\n className={classes.body}\n >\n <ChatbotHeader className={classes.header}>\n <ChatbotHeaderMain>\n <ChatbotHeaderMenu\n aria-expanded={isDrawerOpen}\n onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)}\n className={classes.headerMenu}\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 drawerPanelContentProps={{ isResizable: true, minSize: '200px' }}\n reverseButtonOrder\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>\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 <FilePreview />\n <MessageBar\n onSendMessage={sendMessage}\n isSendButtonDisabled={isSendButtonDisabled}\n hasAttachButton\n handleAttach={handleAttach}\n hasMicrophoneButton\n />\n <ChatbotFootnote {...getFootnoteProps(classes.footerPopover)} />\n </ChatbotFooter>\n </>\n }\n />\n </Chatbot>\n <Attachment />\n </>\n );\n};\n"],"names":["React","prompt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LightSpeedChat.esm.js","sources":["../../src/components/LightSpeedChat.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 React from 'react';\nimport { FileRejection } from 'react-dropzone/.';\n\nimport { ErrorPanel } from '@backstage/core-components';\n\nimport { Box, makeStyles } from '@material-ui/core';\nimport {\n Chatbot,\n ChatbotAlert,\n ChatbotContent,\n ChatbotDisplayMode,\n ChatbotFooter,\n ChatbotFootnote,\n ChatbotHeader,\n ChatbotHeaderMain,\n ChatbotHeaderMenu,\n ChatbotHeaderTitle,\n FileDropZone,\n MessageBar,\n MessageProps,\n} from '@patternfly/chatbot';\nimport ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';\nimport { DropdownItem, DropEvent, Title } from '@patternfly/react-core';\nimport { useQueryClient } from '@tanstack/react-query';\n\nimport { supportedFileTypes, TEMP_CONVERSATION_ID } from '../const';\nimport {\n useBackstageUserIdentity,\n useConversationMessages,\n useConversations,\n useDeleteConversation,\n useIsMobile,\n useLastOpenedConversation,\n useLightspeedDeletePermission,\n} from '../hooks';\nimport { useWelcomePrompts } from '../hooks/useWelcomePrompts';\nimport { ConversationSummary } from '../types';\nimport { getAttachments } from '../utils/attachment-utils';\nimport {\n getCategorizeMessages,\n getFootnoteProps,\n} from '../utils/lightspeed-chatbox-utils';\nimport Attachment from './Attachment';\nimport { useFileAttachmentContext } from './AttachmentContext';\nimport { DeleteModal } from './DeleteModal';\nimport FilePreview from './FilePreview';\nimport { LightspeedChatBox } from './LightspeedChatBox';\nimport { LightspeedChatBoxHeader } from './LightspeedChatBoxHeader';\n\nconst useStyles = makeStyles(theme => ({\n body: {\n // remove default margin and padding from common elements\n '& h1, & h2, & h3, & h4, & h5, & h6, & p, & ul, & ol, & li': {\n margin: 0,\n padding: 0,\n },\n },\n header: {\n padding: `${theme.spacing(3)}px !important`,\n },\n errorContainer: {\n padding: theme.spacing(3),\n },\n headerMenu: {\n // align hamburger icon with title\n '& .pf-v6-c-button': {\n display: 'flex',\n alignItems: 'center',\n },\n },\n headerTitle: {\n justifyContent: 'left !important',\n },\n footer: {\n '&>.pf-chatbot__footer-container': {\n width: '95% !important',\n maxWidth: 'unset !important',\n },\n },\n footerPopover: {\n '& img': {\n maxWidth: '100%',\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 isMobile = useIsMobile();\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>(!isMobile);\n const [newChatCreated, setNewChatCreated] = React.useState<boolean>(false);\n const [isSendButtonDisabled, setIsSendButtonDisabled] =\n React.useState<boolean>(false);\n const [error, setError] = React.useState<Error | null>(null);\n const [targetConversationId, setTargetConversationId] =\n React.useState<string>('');\n const [isDeleteModalOpen, setIsDeleteModalOpen] =\n React.useState<boolean>(false);\n const { isReady, lastOpenedId, setLastOpenedId, clearLastOpenedId } =\n useLastOpenedConversation(user);\n\n const {\n uploadError,\n showAlert,\n fileContents,\n setShowAlert,\n setFileContents,\n handleFileUpload,\n setUploadError,\n } = useFileAttachmentContext();\n\n // Sync conversationId with lastOpenedId whenever lastOpenedId changes\n React.useEffect(() => {\n if (isReady && lastOpenedId !== null) {\n setConversationId(lastOpenedId);\n }\n }, [lastOpenedId, isReady]);\n\n const queryClient = useQueryClient();\n\n const {\n data: conversations = [],\n isLoading,\n isRefetching,\n } = useConversations();\n const { mutateAsync: deleteConversation } = useDeleteConversation();\n const { allowed: hasDeleteAccess } = useLightspeedDeletePermission();\n const samplePrompts = useWelcomePrompts();\n React.useEffect(() => {\n if (user && lastOpenedId === null && isReady) {\n setConversationId(TEMP_CONVERSATION_ID);\n setNewChatCreated(true);\n }\n }, [user, isReady, lastOpenedId, setConversationId]);\n\n React.useEffect(() => {\n // Clear last opened conversationId when there are no conversations.\n if (\n !isLoading &&\n !isRefetching &&\n conversations.length === 0 &&\n lastOpenedId\n ) {\n clearLastOpenedId();\n }\n }, [isLoading, isRefetching, conversations, lastOpenedId, clearLastOpenedId]);\n\n React.useEffect(() => {\n // Update last opened conversation whenever `conversationId` changes\n if (conversationId) {\n setLastOpenedId(conversationId);\n }\n }, [conversationId, setLastOpenedId]);\n\n const onStart = (conv_id: string) => {\n setConversationId(conv_id);\n };\n\n const onComplete = (message: string) => {\n setIsSendButtonDisabled(false);\n setAnnouncement(`Message from Bot: ${message}`);\n queryClient.invalidateQueries({\n queryKey: ['conversations'],\n });\n queryClient.invalidateQueries({\n queryKey: ['conversationMessages', conversationId],\n });\n setNewChatCreated(false);\n };\n\n const { conversationMessages, handleInputPrompt, scrollToBottomRef } =\n useConversationMessages(\n conversationId,\n userName,\n selectedModel,\n avatar,\n onComplete,\n onStart,\n );\n\n const [messages, setMessages] =\n React.useState<MessageProps[]>(conversationMessages);\n\n const sendMessage = (message: string | number) => {\n if (conversationId !== TEMP_CONVERSATION_ID) {\n setNewChatCreated(false);\n }\n setAnnouncement(\n `Message from User: ${prompt}. Message from Bot is loading.`,\n );\n handleInputPrompt(message.toString(), getAttachments(fileContents));\n setIsSendButtonDisabled(true);\n setFileContents([]);\n };\n\n const onNewChat = React.useCallback(() => {\n (async () => {\n if (conversationId !== TEMP_CONVERSATION_ID) {\n setMessages([]);\n setFileContents([]);\n setUploadError({ message: null });\n setConversationId(TEMP_CONVERSATION_ID);\n setNewChatCreated(true);\n }\n })();\n }, [\n conversationId,\n setConversationId,\n setMessages,\n setUploadError,\n setFileContents,\n ]);\n\n const openDeleteModal = (conversation_id: string) => {\n setTargetConversationId(conversation_id);\n setIsDeleteModalOpen(true);\n };\n\n const handleDeleteConversation = React.useCallback(() => {\n (async () => {\n try {\n await deleteConversation({\n conversation_id: targetConversationId,\n invalidateCache: false,\n });\n if (targetConversationId === lastOpenedId) {\n onNewChat();\n clearLastOpenedId();\n }\n setIsDeleteModalOpen(false);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n setError(e);\n }\n })();\n }, [\n deleteConversation,\n clearLastOpenedId,\n lastOpenedId,\n onNewChat,\n targetConversationId,\n ]);\n\n const additionalMessageProps = React.useCallback(\n (conversationSummary: ConversationSummary) => ({\n menuItems: (\n <DropdownItem\n isDisabled={!hasDeleteAccess}\n onClick={() => openDeleteModal(conversationSummary.conversation_id)}\n >\n Delete\n </DropdownItem>\n ),\n }),\n [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 setFileContents([]);\n setUploadError({ message: null });\n scrollToBottomRef.current?.scrollToBottom();\n },\n [setConversationId, setUploadError, setFileContents, scrollToBottomRef],\n );\n\n const conversationFound = !!conversations.find(\n (c: ConversationSummary) => c.conversation_id === conversationId,\n );\n\n const welcomePrompts =\n (newChatCreated && conversationMessages.length === 0) ||\n (!conversationFound && conversationMessages.length === 0)\n ? samplePrompts?.map(prompt => ({\n title: prompt.title,\n message: prompt.message,\n onClick: () => {\n sendMessage(prompt.message);\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 const handleAttach = (data: File[], event: DropEvent) => {\n event.preventDefault();\n handleFileUpload(data);\n };\n\n const onAttachRejected = (data: FileRejection[]) => {\n data.forEach(attachment => {\n if (!!attachment.errors.find(e => e.code === 'file-invalid-type')) {\n setShowAlert(true);\n setUploadError({\n message:\n 'Unsupported file type. Supported types are: .txt, .yaml, .json and .xml.',\n });\n }\n });\n };\n\n if (error) {\n return (\n <Box padding={1}>\n <ErrorPanel error={error} />\n </Box>\n );\n }\n\n return (\n <>\n {isDeleteModalOpen && (\n <DeleteModal\n isOpen={isDeleteModalOpen}\n onClose={() => setIsDeleteModalOpen(false)}\n onConfirm={handleDeleteConversation}\n />\n )}\n <Chatbot\n displayMode={ChatbotDisplayMode.embedded}\n className={classes.body}\n >\n <ChatbotHeader className={classes.header}>\n <ChatbotHeaderMain>\n <ChatbotHeaderMenu\n aria-expanded={isDrawerOpen}\n onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)}\n className={classes.headerMenu}\n />\n <ChatbotHeaderTitle className={classes.headerTitle}>\n <Title headingLevel=\"h1\" size=\"3xl\">\n Developer 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 drawerPanelContentProps={{ isResizable: true, minSize: '200px' }}\n reverseButtonOrder\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 searchInputPlaceholder=\"Search previous chats...\"\n drawerContent={\n <FileDropZone\n onFileDrop={(e, data) => handleAttach(data, e)}\n displayMode={ChatbotDisplayMode.embedded}\n infoText=\"Supported file types are: .txt, .yaml, .json and .xml. The maximum file size is 25 MB.\"\n allowedFileTypes={supportedFileTypes}\n onAttachRejected={onAttachRejected}\n >\n {showAlert && uploadError.message && (\n <div className={classes.errorContainer}>\n <ChatbotAlert\n component=\"h4\"\n title=\"File upload failed\"\n variant={uploadError.type ?? 'danger'}\n isInline\n onClose={() => setUploadError({ message: null })}\n >\n {uploadError.message}\n </ChatbotAlert>\n </div>\n )}\n\n <ChatbotContent>\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 <FilePreview />\n <MessageBar\n onSendMessage={sendMessage}\n isSendButtonDisabled={isSendButtonDisabled}\n hasAttachButton\n handleAttach={handleAttach}\n hasMicrophoneButton\n buttonProps={{\n attach: {\n inputTestId: 'attachment-input',\n },\n }}\n allowedFileTypes={supportedFileTypes}\n onAttachRejected={onAttachRejected}\n placeholder=\"Send a message and optionally upload a JSON, YAML, TXT, or XML file...\"\n />\n <ChatbotFootnote {...getFootnoteProps(classes.footerPopover)} />\n </ChatbotFooter>\n </FileDropZone>\n }\n />\n </Chatbot>\n <Attachment />\n </>\n );\n};\n"],"names":["React","prompt"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
2
|
import { useAsync } from 'react-use';
|
|
3
|
-
import { Page, Content } from '@backstage/core-components';
|
|
3
|
+
import { Page, Header, Content } from '@backstage/core-components';
|
|
4
4
|
import { useApi, identityApiRef } from '@backstage/core-plugin-api';
|
|
5
5
|
import { makeStyles, createStyles, useTheme } from '@material-ui/core/styles';
|
|
6
6
|
import { QueryClientProvider } from '@tanstack/react-query';
|
|
@@ -50,7 +50,14 @@ const LightspeedPageInner = () => {
|
|
|
50
50
|
if (loading) {
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
|
-
return /* @__PURE__ */ React__default.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React__default.createElement(
|
|
53
|
+
return /* @__PURE__ */ React__default.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React__default.createElement(
|
|
54
|
+
Header,
|
|
55
|
+
{
|
|
56
|
+
title: "Lightspeed",
|
|
57
|
+
style: { display: "none" },
|
|
58
|
+
pageTitleOverride: "Developer Lightspeed"
|
|
59
|
+
}
|
|
60
|
+
), /* @__PURE__ */ React__default.createElement(Content, { className: classes.container }, !hasViewAccess ? /* @__PURE__ */ React__default.createElement(PermissionRequiredState, null) : /* @__PURE__ */ React__default.createElement(FileAttachmentContextProvider, null, /* @__PURE__ */ React__default.createElement(
|
|
54
61
|
LightspeedChat,
|
|
55
62
|
{
|
|
56
63
|
selectedModel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.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 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 FileAttachmentContextProvider from './AttachmentContext';\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 <FileAttachmentContextProvider>\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 </FileAttachmentContextProvider>\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":";;;;;;;;;;;;;AAgCA,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,
|
|
1
|
+
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.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 React from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Header, 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 FileAttachmentContextProvider from './AttachmentContext';\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 <Header\n title=\"Lightspeed\"\n style={{ display: 'none' }}\n pageTitleOverride=\"Developer Lightspeed\"\n />\n <Content className={classes.container}>\n {!hasViewAccess ? (\n <PermissionRequiredState />\n ) : (\n <FileAttachmentContextProvider>\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 </FileAttachmentContextProvider>\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":"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"}
|
|
@@ -21,7 +21,7 @@ const PermissionRequiredState = () => {
|
|
|
21
21
|
EmptyState,
|
|
22
22
|
{
|
|
23
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.
|
|
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.chat.read"), " and ", /* @__PURE__ */ React__default.createElement("b", null, "lightspeed.chat.create"), " ", "permissions."),
|
|
25
25
|
missing: { customImage: /* @__PURE__ */ React__default.createElement(PermissionRequiredIcon, null) },
|
|
26
26
|
action: /* @__PURE__ */ React__default.createElement(
|
|
27
27
|
Button,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionRequiredState.esm.js","sources":["../../src/components/PermissionRequiredState.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 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.
|
|
1
|
+
{"version":3,"file":"PermissionRequiredState.esm.js","sources":["../../src/components/PermissionRequiredState.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 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.chat.read</b> and <b>lightspeed.chat.create</b>{' '}\n 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":";;;;;;;AA0BA,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,sBAAoB,GAAI,OAAK,kBAAAA,cAAA,CAAA,aAAA,CAAC,WAAE,wBAAsB,CAAA,EAAK,KAAI,cAEpE,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;;;;"}
|
package/dist/const.esm.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
const TEMP_CONVERSATION_ID = "temp-conversation-id";
|
|
2
|
-
const FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION = `
|
|
3
|
-
const FUNCTION_DISCLAIMER = `
|
|
2
|
+
const FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION = `Developer Lightspeed can answer questions on many topics using your configured models. Lightspeed's responses are influenced by the Red Hat Developer Hub documentation but Lightspeed does not have access to your Software Catalog, TechDocs, or Templates etc. Do not include personal or sensitive information in your input. Interactions with Developer Lightspeed may be reviewed and used to improve products or services.`;
|
|
3
|
+
const FUNCTION_DISCLAIMER = `Developer Lightspeed can answer questions on many topics using your configured models. Lightspeed's responses are influenced by the Red Hat Developer Hub documentation but Lightspeed does not have access to your Software Catalog, TechDocs, or Templates etc. Lightspeed uses question (prompt) validation to ensure that conversations remain focused on technical topics relevant to Red Hat Developer Hub, such as Backstage, Kubernetes, and OpenShift. Do not include personal or sensitive information in your input. Interactions with Developer Lightspeed may be reviewed and used to improve products or services.`;
|
|
4
4
|
const createPrompt = (title, message) => {
|
|
5
5
|
return { title, message };
|
|
6
6
|
};
|
|
7
|
+
const supportedFileTypes = {
|
|
8
|
+
"text/plain": [".txt"],
|
|
9
|
+
"application/json": [".json"],
|
|
10
|
+
"application/yaml": [".yaml", ".yml"],
|
|
11
|
+
"application/xml": [".xml"]
|
|
12
|
+
};
|
|
7
13
|
const DEFAULT_SAMPLE_PROMPTS = [
|
|
8
14
|
createPrompt(
|
|
9
15
|
"Get Help On Code Readability",
|
|
@@ -52,10 +58,10 @@ const RHDH_SAMPLE_PROMPTS = [
|
|
|
52
58
|
"Can you guide me through creating a new deployment in OpenShift for a containerized application?"
|
|
53
59
|
),
|
|
54
60
|
createPrompt(
|
|
55
|
-
"Getting Started with
|
|
56
|
-
"Can you guide me through the first steps to start using
|
|
61
|
+
"Getting Started with Red Hat Developer Hub",
|
|
62
|
+
"Can you guide me through the first steps to start using Developer Hub as a developer, like exploring the Software Catalog and adding my service?"
|
|
57
63
|
)
|
|
58
64
|
];
|
|
59
65
|
|
|
60
|
-
export { DEFAULT_SAMPLE_PROMPTS, FUNCTION_DISCLAIMER, FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION, RHDH_SAMPLE_PROMPTS, TEMP_CONVERSATION_ID };
|
|
66
|
+
export { DEFAULT_SAMPLE_PROMPTS, FUNCTION_DISCLAIMER, FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION, RHDH_SAMPLE_PROMPTS, TEMP_CONVERSATION_ID, supportedFileTypes };
|
|
61
67
|
//# sourceMappingURL=const.esm.js.map
|
package/dist/const.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.esm.js","sources":["../src/const.ts"],"sourcesContent":["import { SamplePrompts } from './types';\n\n/*\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 */\nexport const TEMP_CONVERSATION_ID = 'temp-conversation-id';\n\nexport const FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION = `
|
|
1
|
+
{"version":3,"file":"const.esm.js","sources":["../src/const.ts"],"sourcesContent":["import { SamplePrompts } from './types';\n\n/*\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 */\nexport const TEMP_CONVERSATION_ID = 'temp-conversation-id';\n\nexport const FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION = `Developer Lightspeed can answer questions on many topics using your configured models. Lightspeed's responses are influenced by the Red Hat Developer Hub documentation but Lightspeed does not have access to your Software Catalog, TechDocs, or Templates etc. Do not include personal or sensitive information in your input. Interactions with Developer Lightspeed may be reviewed and used to improve products or services.`;\n\nexport const FUNCTION_DISCLAIMER = `Developer Lightspeed can answer questions on many topics using your configured models. Lightspeed's responses are influenced by the Red Hat Developer Hub documentation but Lightspeed does not have access to your Software Catalog, TechDocs, or Templates etc. Lightspeed uses question (prompt) validation to ensure that conversations remain focused on technical topics relevant to Red Hat Developer Hub, such as Backstage, Kubernetes, and OpenShift. Do not include personal or sensitive information in your input. Interactions with Developer Lightspeed may be reviewed and used to improve products or services.`;\n\nconst createPrompt = (title: string, message: string) => {\n return { title, message };\n};\n\nexport const supportedFileTypes = {\n 'text/plain': ['.txt'],\n 'application/json': ['.json'],\n 'application/yaml': ['.yaml', '.yml'],\n 'application/xml': ['.xml'],\n};\n\nexport const DEFAULT_SAMPLE_PROMPTS: SamplePrompts = [\n createPrompt(\n 'Get Help On Code Readability',\n 'Can you suggest techniques I can use to make my code more readable and maintainable?',\n ),\n createPrompt(\n 'Get Help With Debugging',\n 'My application is throwing an error when trying to connect to the database. Can you help me identify the issue?',\n ),\n createPrompt(\n 'Explain a Development Concept',\n 'Can you explain how microservices architecture works and its advantages over a monolithic design?',\n ),\n createPrompt(\n 'Suggest Code Optimizations',\n 'Can you suggest common ways to optimize code to achieve better performance?',\n ),\n createPrompt(\n 'Documentation Summary',\n 'Can you summarize the documentation for implementing OAuth 2.0 authentication in a web app?',\n ),\n createPrompt(\n 'Workflows With Git',\n 'I want to make changes to code on another branch without loosing my existing work. What is the procedure to do this using Git?',\n ),\n createPrompt(\n 'Suggest Testing Strategies',\n 'Can you recommend some common testing strategies that will make my application robust and error-free?',\n ),\n createPrompt(\n 'Demystify Sorting Algorithms',\n 'Can you explain the difference between a quicksort and a merge sort algorithm, and when to use each?',\n ),\n createPrompt(\n 'Understand Event-Driven Architecture',\n 'Can you explain what event-driven architecture is and when it’s beneficial to use it in software development?',\n ),\n];\n\nexport const RHDH_SAMPLE_PROMPTS: SamplePrompts = [\n createPrompt(\n 'Deploy With Tekton',\n 'Can you help me automate the deployment of my application using Tekton pipelines?',\n ),\n createPrompt(\n 'Create An OpenShift Deployment',\n 'Can you guide me through creating a new deployment in OpenShift for a containerized application?',\n ),\n createPrompt(\n 'Getting Started with Red Hat Developer Hub',\n 'Can you guide me through the first steps to start using Developer Hub as a developer, like exploring the Software Catalog and adding my service?',\n ),\n];\n"],"names":[],"mappings":"AAiBO,MAAM,oBAAuB,GAAA;AAE7B,MAAM,+CAAkD,GAAA,CAAA,kaAAA;AAExD,MAAM,mBAAsB,GAAA,CAAA,gmBAAA;AAEnC,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,OAAoB,KAAA;AACvD,EAAO,OAAA,EAAE,OAAO,OAAQ,EAAA;AAC1B,CAAA;AAEO,MAAM,kBAAqB,GAAA;AAAA,EAChC,YAAA,EAAc,CAAC,MAAM,CAAA;AAAA,EACrB,kBAAA,EAAoB,CAAC,OAAO,CAAA;AAAA,EAC5B,kBAAA,EAAoB,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpC,iBAAA,EAAmB,CAAC,MAAM;AAC5B;AAEO,MAAM,sBAAwC,GAAA;AAAA,EACnD,YAAA;AAAA,IACE,8BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,yBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,+BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,4BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,uBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,oBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,4BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,8BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,sCAAA;AAAA,IACA;AAAA;AAEJ;AAEO,MAAM,mBAAqC,GAAA;AAAA,EAChD,YAAA;AAAA,IACE,oBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,gCAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,4CAAA;AAAA,IACA;AAAA;AAEJ;;;;"}
|
|
@@ -3,8 +3,9 @@ import { useApi } from '@backstage/core-plugin-api';
|
|
|
3
3
|
import { useQuery } from '@tanstack/react-query';
|
|
4
4
|
import { lightspeedApiRef } from '../api/api.esm.js';
|
|
5
5
|
import { TEMP_CONVERSATION_ID } from '../const.esm.js';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import botAvatar from '../images/bot-avatar.svg';
|
|
7
|
+
import userAvatar from '../images/user-avatar.svg';
|
|
8
|
+
import { getMessageData, createUserMessage, createBotMessage, transformDocumentsToSources, getTimestamp } from '../utils/lightspeed-chatbox-utils.esm.js';
|
|
8
9
|
import { useCreateConversationMessage } from './useCreateCoversationMessage.esm.js';
|
|
9
10
|
|
|
10
11
|
const useFetchConversationMessages = (currentConversation) => {
|
|
@@ -18,8 +19,7 @@ const useFetchConversationMessages = (currentConversation) => {
|
|
|
18
19
|
retry: false
|
|
19
20
|
});
|
|
20
21
|
};
|
|
21
|
-
const
|
|
22
|
-
const useConversationMessages = (conversationId, userName, selectedModel, avatar = defaultAvatar, onComplete, onStart) => {
|
|
22
|
+
const useConversationMessages = (conversationId, userName, selectedModel, avatar = userAvatar, onComplete, onStart) => {
|
|
23
23
|
const { mutateAsync: createMessage } = useCreateConversationMessage();
|
|
24
24
|
const scrollToBottomRef = React__default.useRef(null);
|
|
25
25
|
const [currentConversation, setCurrentConversation] = React__default.useState(conversationId);
|
|
@@ -56,7 +56,8 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
56
56
|
const {
|
|
57
57
|
model,
|
|
58
58
|
content: botMessage,
|
|
59
|
-
timestamp: botTimestamp
|
|
59
|
+
timestamp: botTimestamp,
|
|
60
|
+
referencedDocuments
|
|
60
61
|
} = getMessageData(aiMessage);
|
|
61
62
|
_conversations[currentConversation].push(
|
|
62
63
|
...[
|
|
@@ -67,11 +68,12 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
67
68
|
timestamp: userTimestamp
|
|
68
69
|
}),
|
|
69
70
|
createBotMessage({
|
|
70
|
-
avatar:
|
|
71
|
+
avatar: botAvatar,
|
|
71
72
|
isLoading: false,
|
|
72
73
|
name: model ?? selectedModel,
|
|
73
74
|
content: botMessage,
|
|
74
|
-
timestamp: botTimestamp
|
|
75
|
+
timestamp: botTimestamp,
|
|
76
|
+
sources: transformDocumentsToSources(referencedDocuments)
|
|
75
77
|
})
|
|
76
78
|
]
|
|
77
79
|
);
|
|
@@ -102,7 +104,7 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
102
104
|
timestamp: getTimestamp(Date.now()) ?? ""
|
|
103
105
|
}),
|
|
104
106
|
createBotMessage({
|
|
105
|
-
avatar:
|
|
107
|
+
avatar: botAvatar,
|
|
106
108
|
isLoading: true,
|
|
107
109
|
name: selectedModel,
|
|
108
110
|
content: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConversationMessages.esm.js","sources":["../../src/hooks/useConversationMessages.ts"],"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 React from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { MessageProps } from '@patternfly/chatbot';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { ScrollContainerHandle } from '../components/LightspeedChatBox';\nimport { TEMP_CONVERSATION_ID } from '../const';\nimport logo from '../images/logo.svg';\nimport { Attachment } from '../types';\nimport {\n createBotMessage,\n createUserMessage,\n getMessageData,\n getTimestamp,\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\nconst defaultAvatar =\n 'https://img.freepik.com/premium-photo/graphic-designer-digital-avatar-generative-ai_934475-9292.jpg';\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 = defaultAvatar,\n onComplete?: (message: string) => void,\n onStart?: (conversation_id: string) => void,\n) => {\n const { mutateAsync: createMessage } = useCreateConversationMessage();\n const scrollToBottomRef = React.useRef<ScrollContainerHandle>(null);\n\n const [currentConversation, setCurrentConversation] =\n React.useState(conversationId);\n const [conversations, setConversations] = React.useState<Conversations>({\n [currentConversation]: [],\n });\n const streamingConversations = React.useRef<Conversations>({\n [currentConversation]: [],\n });\n\n React.useEffect(() => {\n if (currentConversation !== conversationId) {\n setCurrentConversation(conversationId);\n setConversations(prev => {\n if (prev[conversationId]) return prev;\n\n return {\n ...prev,\n [conversationId]: [],\n };\n });\n }\n }, [currentConversation, conversationId]);\n\n const { data: conversationsData = [], ...queryProps } =\n useFetchConversationMessages(currentConversation);\n\n React.useEffect(() => {\n if (\n !Array.isArray(conversationsData) ||\n (conversationsData.length === 0 &&\n conversationId !== TEMP_CONVERSATION_ID)\n )\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\n if (streamingConversations.current[currentConversation]) {\n _conversations[currentConversation].push(\n ...streamingConversations.current[currentConversation],\n );\n }\n\n setConversations(_conversations);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n conversationsData,\n userName,\n avatar,\n currentConversation,\n selectedModel,\n streamingConversations,\n ]);\n\n const handleInputPrompt = React.useCallback(\n async (prompt: string, attachments: Attachment[] = []) => {\n let newConversationId = '';\n\n const conversationTuple = [\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 streamingConversations.current = {\n ...streamingConversations.current,\n [currentConversation]: conversationTuple,\n };\n\n setConversations((prevConv: Conversations) => {\n return {\n ...prevConv,\n [currentConversation]: [\n ...(prevConv?.[currentConversation] ?? []),\n ...conversationTuple,\n ],\n };\n });\n\n setTimeout(() => {\n scrollToBottomRef.current?.scrollToBottom();\n }, 0);\n const finalMessages: string[] = [];\n let buffer = '';\n\n try {\n const reader = await createMessage({\n prompt,\n selectedModel,\n currentConversation,\n attachments,\n });\n\n const decoder = new TextDecoder('utf-8');\n const keepGoing = true;\n\n while (keepGoing) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process all complete messages separated by double newlines\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop()!;\n\n for (const part of parts) {\n const lines = part\n .split('\\n')\n .filter(line => line.startsWith('data:'));\n\n const jsonString = lines\n .map(line => line.trim().slice(5).trim())\n .join('');\n try {\n const { event, data } = JSON.parse(jsonString);\n if (event === 'start') {\n if (currentConversation === TEMP_CONVERSATION_ID) {\n // If the conversation is temp, we need to set the new conversation id\n newConversationId = data?.conversation_id;\n }\n }\n\n if (event === 'token') {\n const content = data?.token || '';\n\n finalMessages.push(content);\n\n // Store streaming message\n const [humanMessage, aiMessage] =\n streamingConversations.current[currentConversation];\n streamingConversations.current[currentConversation] = [\n humanMessage,\n { ...aiMessage, content: aiMessage.content + content },\n ];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += content;\n lastMessage.name =\n data?.response_metadata?.model || selectedModel;\n lastMessage.timestamp = getTimestamp(\n data?.response_metadata?.created_at || 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 }\n\n if (event === 'end') {\n const documents = data?.referenced_documents || [];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n if (documents.length) {\n lastMessage.sources = {\n sources: documents.map(\n (doc: { doc_title: string; doc_url: string }) => ({\n title: doc.doc_title,\n link: doc.doc_url,\n }),\n ),\n };\n }\n\n const updatedConversation = [\n ...conversation.slice(0, lastMessageIndex),\n lastMessage,\n ];\n\n return {\n ...prevConversations,\n [currentConversation]: updatedConversation,\n };\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 const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += e;\n lastMessage.error = {\n title: e.message,\n };\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 [newConversationId.length > 0\n ? newConversationId\n : currentConversation]: updatedConversation,\n };\n });\n }\n // reset current streaming\n streamingConversations.current[currentConversation] = [];\n if (typeof onComplete === 'function') {\n onComplete(finalMessages.join(''));\n }\n // Swap temp conversation messages with new conversation\n\n if (currentConversation === TEMP_CONVERSATION_ID && newConversationId) {\n setConversations(prevConversations => {\n return {\n ...prevConversations,\n [newConversationId]: prevConversations[TEMP_CONVERSATION_ID],\n };\n });\n\n onStart?.(newConversationId);\n\n setConversations(prev => {\n const { temp, ...rest } = prev;\n return rest;\n });\n }\n },\n\n [\n avatar,\n userName,\n onComplete,\n onStart,\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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"}
|
|
1
|
+
{"version":3,"file":"useConversationMessages.esm.js","sources":["../../src/hooks/useConversationMessages.ts"],"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 React from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { MessageProps } from '@patternfly/chatbot';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { ScrollContainerHandle } from '../components/LightspeedChatBox';\nimport { TEMP_CONVERSATION_ID } from '../const';\nimport botAvatar from '../images/bot-avatar.svg';\nimport userAvatar from '../images/user-avatar.svg';\nimport { Attachment } from '../types';\nimport {\n createBotMessage,\n createUserMessage,\n getMessageData,\n getTimestamp,\n transformDocumentsToSources,\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 = userAvatar,\n onComplete?: (message: string) => void,\n onStart?: (conversation_id: string) => void,\n) => {\n const { mutateAsync: createMessage } = useCreateConversationMessage();\n const scrollToBottomRef = React.useRef<ScrollContainerHandle>(null);\n\n const [currentConversation, setCurrentConversation] =\n React.useState(conversationId);\n const [conversations, setConversations] = React.useState<Conversations>({\n [currentConversation]: [],\n });\n const streamingConversations = React.useRef<Conversations>({\n [currentConversation]: [],\n });\n\n React.useEffect(() => {\n if (currentConversation !== conversationId) {\n setCurrentConversation(conversationId);\n setConversations(prev => {\n if (prev[conversationId]) return prev;\n\n return {\n ...prev,\n [conversationId]: [],\n };\n });\n }\n }, [currentConversation, conversationId]);\n\n const { data: conversationsData = [], ...queryProps } =\n useFetchConversationMessages(currentConversation);\n\n React.useEffect(() => {\n if (\n !Array.isArray(conversationsData) ||\n (conversationsData.length === 0 &&\n conversationId !== TEMP_CONVERSATION_ID)\n )\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 referencedDocuments,\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: botAvatar,\n isLoading: false,\n name: model ?? selectedModel,\n content: botMessage,\n timestamp: botTimestamp,\n sources: transformDocumentsToSources(referencedDocuments),\n }),\n ],\n );\n\n newConvoIndex.push(index);\n index++;\n }\n\n if (streamingConversations.current[currentConversation]) {\n _conversations[currentConversation].push(\n ...streamingConversations.current[currentConversation],\n );\n }\n\n setConversations(_conversations);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n conversationsData,\n userName,\n avatar,\n currentConversation,\n selectedModel,\n streamingConversations,\n ]);\n\n const handleInputPrompt = React.useCallback(\n async (prompt: string, attachments: Attachment[] = []) => {\n let newConversationId = '';\n\n const conversationTuple = [\n createUserMessage({\n avatar,\n name: userName,\n content: prompt,\n timestamp: getTimestamp(Date.now()) ?? '',\n }),\n createBotMessage({\n avatar: botAvatar,\n isLoading: true,\n name: selectedModel,\n content: '',\n timestamp: '',\n }),\n ];\n\n streamingConversations.current = {\n ...streamingConversations.current,\n [currentConversation]: conversationTuple,\n };\n\n setConversations((prevConv: Conversations) => {\n return {\n ...prevConv,\n [currentConversation]: [\n ...(prevConv?.[currentConversation] ?? []),\n ...conversationTuple,\n ],\n };\n });\n\n setTimeout(() => {\n scrollToBottomRef.current?.scrollToBottom();\n }, 0);\n const finalMessages: string[] = [];\n let buffer = '';\n\n try {\n const reader = await createMessage({\n prompt,\n selectedModel,\n currentConversation,\n attachments,\n });\n\n const decoder = new TextDecoder('utf-8');\n const keepGoing = true;\n\n while (keepGoing) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process all complete messages separated by double newlines\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop()!;\n\n for (const part of parts) {\n const lines = part\n .split('\\n')\n .filter(line => line.startsWith('data:'));\n\n const jsonString = lines\n .map(line => line.trim().slice(5).trim())\n .join('');\n try {\n const { event, data } = JSON.parse(jsonString);\n if (event === 'start') {\n if (currentConversation === TEMP_CONVERSATION_ID) {\n // If the conversation is temp, we need to set the new conversation id\n newConversationId = data?.conversation_id;\n }\n }\n\n if (event === 'token') {\n const content = data?.token || '';\n\n finalMessages.push(content);\n\n // Store streaming message\n const [humanMessage, aiMessage] =\n streamingConversations.current[currentConversation];\n streamingConversations.current[currentConversation] = [\n humanMessage,\n { ...aiMessage, content: aiMessage.content + content },\n ];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += content;\n lastMessage.name =\n data?.response_metadata?.model || selectedModel;\n lastMessage.timestamp = getTimestamp(\n data?.response_metadata?.created_at || 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 }\n\n if (event === 'end') {\n const documents = data?.referenced_documents || [];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n if (documents.length) {\n lastMessage.sources = {\n sources: documents.map(\n (doc: { doc_title: string; doc_url: string }) => ({\n title: doc.doc_title,\n link: doc.doc_url,\n }),\n ),\n };\n }\n\n const updatedConversation = [\n ...conversation.slice(0, lastMessageIndex),\n lastMessage,\n ];\n\n return {\n ...prevConversations,\n [currentConversation]: updatedConversation,\n };\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 const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += e;\n lastMessage.error = {\n title: e.message,\n };\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 [newConversationId.length > 0\n ? newConversationId\n : currentConversation]: updatedConversation,\n };\n });\n }\n // reset current streaming\n streamingConversations.current[currentConversation] = [];\n if (typeof onComplete === 'function') {\n onComplete(finalMessages.join(''));\n }\n // Swap temp conversation messages with new conversation\n\n if (currentConversation === TEMP_CONVERSATION_ID && newConversationId) {\n setConversations(prevConversations => {\n return {\n ...prevConversations,\n [newConversationId]: prevConversations[TEMP_CONVERSATION_ID],\n };\n });\n\n onStart?.(newConversationId);\n\n setConversations(prev => {\n const { temp, ...rest } = prev;\n return rest;\n });\n }\n },\n\n [\n avatar,\n userName,\n onComplete,\n onStart,\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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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
2
|
-
import {
|
|
2
|
+
import { lightspeedChatDeletePermission } from '@red-hat-developer-hub/backstage-plugin-lightspeed-common';
|
|
3
3
|
|
|
4
4
|
const useLightspeedDeletePermission = () => {
|
|
5
5
|
const lightspeedDeletePermissionResult = usePermission({
|
|
6
|
-
permission:
|
|
6
|
+
permission: lightspeedChatDeletePermission
|
|
7
7
|
});
|
|
8
8
|
return lightspeedDeletePermissionResult;
|
|
9
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLightspeedDeletePermission.esm.js","sources":["../../src/hooks/useLightspeedDeletePermission.ts"],"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 { usePermission } from '@backstage/plugin-permission-react';\n\nimport {
|
|
1
|
+
{"version":3,"file":"useLightspeedDeletePermission.esm.js","sources":["../../src/hooks/useLightspeedDeletePermission.ts"],"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 { usePermission } from '@backstage/plugin-permission-react';\n\nimport { lightspeedChatDeletePermission } from '@red-hat-developer-hub/backstage-plugin-lightspeed-common';\n\nexport const useLightspeedDeletePermission = () => {\n const lightspeedDeletePermissionResult = usePermission({\n permission: lightspeedChatDeletePermission,\n });\n\n return lightspeedDeletePermissionResult;\n};\n"],"names":[],"mappings":";;;AAoBO,MAAM,gCAAgC,MAAM;AACjD,EAAA,MAAM,mCAAmC,aAAc,CAAA;AAAA,IACrD,UAAY,EAAA;AAAA,GACb,CAAA;AAED,EAAO,OAAA,gCAAA;AACT;;;;"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { usePermission } from '@backstage/plugin-permission-react';
|
|
2
|
-
import {
|
|
2
|
+
import { lightspeedChatReadPermission, lightspeedChatCreatePermission } from '@red-hat-developer-hub/backstage-plugin-lightspeed-common';
|
|
3
3
|
|
|
4
4
|
const useLightspeedViewPermission = () => {
|
|
5
|
-
const
|
|
6
|
-
permission:
|
|
5
|
+
const canReadChats = usePermission({
|
|
6
|
+
permission: lightspeedChatReadPermission
|
|
7
7
|
});
|
|
8
|
-
const
|
|
9
|
-
permission:
|
|
8
|
+
const canCreateChats = usePermission({
|
|
9
|
+
permission: lightspeedChatCreatePermission
|
|
10
10
|
});
|
|
11
11
|
return {
|
|
12
|
-
loading:
|
|
13
|
-
allowed:
|
|
12
|
+
loading: canReadChats.loading || canCreateChats.loading,
|
|
13
|
+
allowed: canReadChats.allowed && canCreateChats.allowed
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLightspeedViewPermission.esm.js","sources":["../../src/hooks/useLightspeedViewPermission.ts"],"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 { usePermission } from '@backstage/plugin-permission-react';\n\nimport {\n
|
|
1
|
+
{"version":3,"file":"useLightspeedViewPermission.esm.js","sources":["../../src/hooks/useLightspeedViewPermission.ts"],"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 { usePermission } from '@backstage/plugin-permission-react';\n\nimport {\n lightspeedChatCreatePermission,\n lightspeedChatReadPermission,\n} from '@red-hat-developer-hub/backstage-plugin-lightspeed-common';\n\nexport const useLightspeedViewPermission = () => {\n const canReadChats = usePermission({\n permission: lightspeedChatReadPermission,\n });\n\n const canCreateChats = usePermission({\n permission: lightspeedChatCreatePermission,\n });\n\n return {\n loading: canReadChats.loading || canCreateChats.loading,\n allowed: canReadChats.allowed && canCreateChats.allowed,\n };\n};\n"],"names":[],"mappings":";;;AAuBO,MAAM,8BAA8B,MAAM;AAC/C,EAAA,MAAM,eAAe,aAAc,CAAA;AAAA,IACjC,UAAY,EAAA;AAAA,GACb,CAAA;AAED,EAAA,MAAM,iBAAiB,aAAc,CAAA;AAAA,IACnC,UAAY,EAAA;AAAA,GACb,CAAA;AAED,EAAO,OAAA;AAAA,IACL,OAAA,EAAS,YAAa,CAAA,OAAA,IAAW,cAAe,CAAA,OAAA;AAAA,IAChD,OAAA,EAAS,YAAa,CAAA,OAAA,IAAW,cAAe,CAAA;AAAA,GAClD;AACF;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg width="47" height="47" viewBox="0 0 47 47" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<circle cx="23.5" cy="23.5" r="22.75" fill="white" stroke="#E0E0E0" stroke-width="1.5"/>
|
|
3
|
+
<path d="M24.5067 18.9867C24.0533 18.9867 23.68 18.6133 23.68 18.16V8.82667C23.68 8.37333 24.0533 8 24.5067 8C24.96 8 25.3333 8.37333 25.3333 8.82667V18.16C25.3333 18.6133 24.96 18.9867 24.5067 18.9867Z" fill="#EE0000"/>
|
|
4
|
+
<path d="M19.1733 24.3203H9.84C9.38667 24.3203 9.01334 23.947 9.01334 23.4937C9.01334 23.0403 9.38667 22.667 9.84 22.667H19.1733C19.6267 22.667 20 23.0403 20 23.4937C20 23.947 19.6267 24.3203 19.1733 24.3203Z" fill="#EE0000"/>
|
|
5
|
+
<path d="M24.5067 38.9867C24.0533 38.9867 23.68 38.6133 23.68 38.16V28.8267C23.68 28.3733 24.0533 28 24.5067 28C24.96 28 25.3333 28.3733 25.3333 28.8267V38.16C25.3333 38.6133 24.96 38.9867 24.5067 38.9867Z" fill="#EE0000"/>
|
|
6
|
+
<path d="M38.6133 23.813C38.6533 23.7197 38.6667 23.6263 38.6667 23.533C38.6667 23.533 38.6667 23.5063 38.6667 23.493C38.6667 23.4797 38.6667 23.4663 38.6667 23.453C38.6667 23.3597 38.6533 23.2663 38.6133 23.173C38.5867 23.1063 38.5467 23.053 38.5067 22.9997C38.48 22.973 38.4667 22.933 38.44 22.893L35.7733 20.2263C35.4533 19.9063 34.92 19.9063 34.6 20.2263C34.28 20.5463 34.28 21.0797 34.6 21.3997L35.84 22.6397H23.1867C22.7333 22.6397 22.36 23.013 22.36 23.4663C22.36 23.9197 22.7333 24.293 23.1867 24.293H35.84L34.6 25.533C34.28 25.853 34.28 26.3863 34.6 26.7063C34.76 26.8663 34.9733 26.9463 35.1867 26.9463C35.4 26.9463 35.6133 26.8663 35.7733 26.7063L38.44 24.0397C38.44 24.0397 38.48 23.973 38.5067 23.933C38.5467 23.8797 38.5867 23.8263 38.6133 23.7597V23.813Z" fill="black"/>
|
|
7
|
+
<path d="M20.5067 20.3197C20.2933 20.3197 20.08 20.2397 19.92 20.0797L14.5867 14.7463C14.2667 14.4263 14.2667 13.893 14.5867 13.573C14.9067 13.253 15.44 13.253 15.76 13.573L21.0933 18.9063C21.4133 19.2263 21.4133 19.7597 21.0933 20.0797C20.9333 20.2397 20.72 20.3197 20.5067 20.3197Z" fill="black"/>
|
|
8
|
+
<path d="M15.1733 33.6537C14.96 33.6537 14.7467 33.5737 14.5867 33.4137C14.2667 33.0937 14.2667 32.5603 14.5867 32.2403L19.92 26.907C20.24 26.587 20.7733 26.587 21.0933 26.907C21.4133 27.227 21.4133 27.7603 21.0933 28.0803L15.76 33.4137C15.6 33.5737 15.3867 33.6537 15.1733 33.6537Z" fill="black"/>
|
|
9
|
+
<path d="M21.0667 16.3205C20.68 16.3205 20.3333 16.0538 20.2533 15.6538L19.6933 12.9871C19.6 12.5338 19.88 12.0938 20.3333 12.0005C20.7867 11.8938 21.2267 12.1871 21.32 12.6405L21.88 15.3071C21.9733 15.7605 21.6933 16.2005 21.24 16.2938C21.1867 16.2938 21.12 16.3071 21.0667 16.3071V16.3205Z" fill="#EE0000"/>
|
|
10
|
+
<path d="M16.5067 20.8938C16.5067 20.8938 16.3867 20.8938 16.3333 20.8805L13.6667 20.3205C13.2133 20.2271 12.9333 19.7871 13.0267 19.3338C13.12 18.8805 13.56 18.5871 14.0133 18.6938L16.68 19.2538C17.1333 19.3471 17.4133 19.7871 17.32 20.2405C17.24 20.6271 16.8933 20.9071 16.5067 20.9071V20.8938Z" fill="#EE0000"/>
|
|
11
|
+
<path d="M20.5067 34.9868C20.5067 34.9868 20.3867 34.9868 20.3333 34.9735C19.88 34.8801 19.6 34.4401 19.6933 33.9868L20.2533 31.3201C20.3467 30.8668 20.7867 30.5735 21.24 30.6801C21.6933 30.7735 21.9733 31.2135 21.88 31.6668L21.32 34.3335C21.24 34.7201 20.8933 35.0001 20.5067 35.0001V34.9868Z" fill="#EE0000"/>
|
|
12
|
+
<path d="M13.84 28.3202C13.4533 28.3202 13.1067 28.0536 13.0267 27.6536C12.9333 27.2002 13.2133 26.7602 13.6667 26.6669L16.3333 26.1069C16.7867 26.0002 17.2267 26.2936 17.32 26.7469C17.4133 27.2002 17.1333 27.6402 16.68 27.7336L14.0133 28.2936C14.0133 28.2936 13.8933 28.3069 13.84 28.3069V28.3202Z" fill="#EE0000"/>
|
|
13
|
+
<path d="M9.84 18.9996C9.62667 18.9996 9.41333 18.9063 9.25333 18.7463C9.17333 18.6662 9.12 18.5863 9.06667 18.4796C9.02667 18.3729 9 18.2663 9 18.1596C9 17.9463 9.09333 17.7329 9.25333 17.5729C9.56 17.2663 10.12 17.2529 10.4267 17.5729C10.5867 17.7329 10.68 17.9463 10.68 18.1596C10.68 18.2663 10.6533 18.3729 10.6133 18.4796C10.5733 18.5863 10.5067 18.6662 10.4267 18.7463C10.2667 18.9063 10.0533 18.9996 9.84 18.9996Z" fill="black"/>
|
|
14
|
+
<path d="M9.84 29.6666C9.62667 29.6666 9.41333 29.5732 9.25333 29.4132C9.09333 29.2666 9 29.0399 9 28.8266C9 28.6132 9.09333 28.3999 9.25333 28.2399C9.56 27.9332 10.1067 27.9199 10.4267 28.2399C10.5867 28.3999 10.68 28.6132 10.68 28.8266C10.68 29.0399 10.5867 29.2666 10.4267 29.4132C10.2667 29.5732 10.0533 29.6666 9.84 29.6666Z" fill="black"/>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<circle cx="24" cy="24" r="24" fill="white"/>
|
|
3
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.0625 23.5C27.7908 23.5 30.8125 20.4783 30.8125 16.75C30.8125 13.0217 27.7908 10 24.0625 10C20.3342 10 17.3125 13.0217 17.3125 16.75C17.3125 20.4783 20.3342 23.5 24.0625 23.5ZM33.3437 36.9999C34.7412 36.9999 35.8749 35.8661 35.8749 34.4687V32.275C35.8749 28.3621 32.7003 25.1875 28.7874 25.1875H27.9068C26.7361 25.7254 25.4336 26.0312 24.0625 26.0312C22.6914 26.0312 21.3941 25.7254 20.2181 25.1875H19.3375C15.4246 25.1875 12.25 28.3621 12.25 32.275V34.4687C12.25 35.8661 13.3838 36.9999 14.7812 36.9999H33.3437Z" fill="#1F1F1F"/>
|
|
4
|
+
</svg>
|
package/dist/types.esm.js
CHANGED
|
@@ -2,6 +2,7 @@ var SupportedFileType = /* @__PURE__ */ ((SupportedFileType2) => {
|
|
|
2
2
|
SupportedFileType2["JSON"] = "application/json";
|
|
3
3
|
SupportedFileType2["YAML"] = "application/x-yaml";
|
|
4
4
|
SupportedFileType2["TEXT"] = "text/plain";
|
|
5
|
+
SupportedFileType2["XML"] = "text/xml";
|
|
5
6
|
return SupportedFileType2;
|
|
6
7
|
})(SupportedFileType || {});
|
|
7
8
|
|
package/dist/types.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"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 { SourcesCardProps } from '@patternfly/chatbot';\nimport { AlertProps } from '@patternfly/react-core';\n\nexport type Conversations = {\n [key: string]: {\n user: string;\n bot: string;\n model: string;\n loading: boolean;\n timestamp: string;\n botTimestamp: string;\n error?: AlertProps;\n };\n};\n\nexport interface BaseMessage {\n name: string;\n type: string;\n id: number;\n content: string;\n response_metadata: {\n model?: string;\n created_at: number;\n role?: string;\n };\n sources?: SourcesCardProps;\n additional_kwargs: {\n [_key: string]: any;\n };\n error?: AlertProps;\n}\nexport type ConversationSummary = {\n conversation_id: string;\n last_message_timestamp: number;\n topic_summary: string;\n};\n\nexport enum SupportedFileType {\n JSON = 'application/json',\n YAML = 'application/x-yaml',\n TEXT = 'text/plain',\n}\nexport interface FileContent {\n content: string;\n type: string;\n name: string;\n}\n\nexport type Attachment = {\n attachment_type: string;\n content_type: string;\n content: string;\n};\n\nexport type ConversationList = ConversationSummary[];\n\nexport type SamplePrompts = {\n title: string;\n message: string;\n}[];\n"],"names":["SupportedFileType"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"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 { SourcesCardProps } from '@patternfly/chatbot';\nimport { AlertProps } from '@patternfly/react-core';\n\nexport type Conversations = {\n [key: string]: {\n user: string;\n bot: string;\n model: string;\n loading: boolean;\n timestamp: string;\n botTimestamp: string;\n error?: AlertProps;\n };\n};\n\nexport type ReferencedDocuments = {\n doc_title: string;\n doc_url: string;\n}[];\nexport interface BaseMessage {\n name: string;\n type: string;\n id: number;\n content: string;\n response_metadata: {\n model?: string;\n created_at: number;\n role?: string;\n };\n sources?: SourcesCardProps;\n additional_kwargs: {\n referenced_documents?: ReferencedDocuments;\n [_key: string]: any;\n };\n error?: AlertProps;\n}\nexport type ConversationSummary = {\n conversation_id: string;\n last_message_timestamp: number;\n topic_summary: string;\n};\n\nexport enum SupportedFileType {\n JSON = 'application/json',\n YAML = 'application/x-yaml',\n TEXT = 'text/plain',\n XML = 'text/xml',\n}\nexport interface FileContent {\n content: string;\n type: string;\n name: string;\n}\n\nexport type Attachment = {\n attachment_type: string;\n content_type: string;\n content: string;\n};\n\nexport type ConversationList = ConversationSummary[];\n\nexport type SamplePrompts = {\n title: string;\n message: string;\n}[];\n"],"names":["SupportedFileType"],"mappings":"AA0DY,IAAA,iBAAA,qBAAAA,kBAAL,KAAA;AACL,EAAAA,mBAAA,MAAO,CAAA,GAAA,kBAAA;AACP,EAAAA,mBAAA,MAAO,CAAA,GAAA,oBAAA;AACP,EAAAA,mBAAA,MAAO,CAAA,GAAA,YAAA;AACP,EAAAA,mBAAA,KAAM,CAAA,GAAA,UAAA;AAJI,EAAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;;;;"}
|
|
@@ -4,7 +4,8 @@ const isSupportedFileType = (file) => {
|
|
|
4
4
|
const isJson = file.type === SupportedFileType.JSON;
|
|
5
5
|
const isYaml = file.type === SupportedFileType.YAML || file.name.endsWith(".yaml") || file.name.endsWith(".yml");
|
|
6
6
|
const isText = file.type === SupportedFileType.TEXT;
|
|
7
|
-
|
|
7
|
+
const isXml = file.name.endsWith(".xml");
|
|
8
|
+
return isJson || isYaml || isText || isXml;
|
|
8
9
|
};
|
|
9
10
|
const readFileAsText = (file) => new Promise((resolve, reject) => {
|
|
10
11
|
const reader = new FileReader();
|
|
@@ -12,7 +13,16 @@ const readFileAsText = (file) => new Promise((resolve, reject) => {
|
|
|
12
13
|
reader.onerror = () => reject(reader.error);
|
|
13
14
|
reader.readAsText(file);
|
|
14
15
|
});
|
|
15
|
-
const sanitizeFileType = (fileContent) =>
|
|
16
|
+
const sanitizeFileType = (fileContent) => {
|
|
17
|
+
switch (fileContent.type) {
|
|
18
|
+
case SupportedFileType.YAML:
|
|
19
|
+
return "application/yaml";
|
|
20
|
+
case SupportedFileType.XML:
|
|
21
|
+
return "application/xml";
|
|
22
|
+
default:
|
|
23
|
+
return fileContent.type;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
16
26
|
const getAttachments = (fileContents) => fileContents.map((file) => ({
|
|
17
27
|
attachment_type: "api object",
|
|
18
28
|
content_type: sanitizeFileType(file),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-utils.esm.js","sources":["../../src/utils/attachment-utils.ts"],"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 */\nimport { Attachment, FileContent, SupportedFileType } from '../types';\n\nexport const isSupportedFileType = (file: File) => {\n const isJson = file.type === SupportedFileType.JSON;\n const isYaml =\n file.type === SupportedFileType.YAML ||\n file.name.endsWith('.yaml') ||\n file.name.endsWith('.yml');\n const isText = file.type === SupportedFileType.TEXT;\n return isJson || isYaml || isText;\n};\n\nexport const readFileAsText = (file: File): Promise<string | null> =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsText(file);\n });\n\nexport const sanitizeFileType = (fileContent: FileContent): string
|
|
1
|
+
{"version":3,"file":"attachment-utils.esm.js","sources":["../../src/utils/attachment-utils.ts"],"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 */\nimport { Attachment, FileContent, SupportedFileType } from '../types';\n\nexport const isSupportedFileType = (file: File) => {\n const isJson = file.type === SupportedFileType.JSON;\n const isYaml =\n file.type === SupportedFileType.YAML ||\n file.name.endsWith('.yaml') ||\n file.name.endsWith('.yml');\n const isText = file.type === SupportedFileType.TEXT;\n const isXml = file.name.endsWith('.xml');\n\n return isJson || isYaml || isText || isXml;\n};\n\nexport const readFileAsText = (file: File): Promise<string | null> =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = () => reject(reader.error);\n reader.readAsText(file);\n });\n\nexport const sanitizeFileType = (fileContent: FileContent): string => {\n switch (fileContent.type) {\n case SupportedFileType.YAML:\n return 'application/yaml';\n case SupportedFileType.XML:\n return 'application/xml';\n default:\n return fileContent.type;\n }\n};\n\nexport const getAttachments = (fileContents: FileContent[]): Attachment[] =>\n fileContents.map(file => ({\n attachment_type: 'api object',\n content_type: sanitizeFileType(file),\n content: fileContents.find(f => f.name === file.name)?.content || '',\n }));\n"],"names":[],"mappings":";;AAiBa,MAAA,mBAAA,GAAsB,CAAC,IAAe,KAAA;AACjD,EAAM,MAAA,MAAA,GAAS,IAAK,CAAA,IAAA,KAAS,iBAAkB,CAAA,IAAA;AAC/C,EAAA,MAAM,MACJ,GAAA,IAAA,CAAK,IAAS,KAAA,iBAAA,CAAkB,IAChC,IAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,OAAO,CAAA,IAC1B,IAAK,CAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAC3B,EAAM,MAAA,MAAA,GAAS,IAAK,CAAA,IAAA,KAAS,iBAAkB,CAAA,IAAA;AAC/C,EAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,MAAM,CAAA;AAEvC,EAAO,OAAA,MAAA,IAAU,UAAU,MAAU,IAAA,KAAA;AACvC;AAEO,MAAM,iBAAiB,CAAC,IAAA,KAC7B,IAAI,OAAQ,CAAA,CAAC,SAAS,MAAW,KAAA;AAC/B,EAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA;AAC9B,EAAA,MAAA,CAAO,MAAS,GAAA,MAAM,OAAQ,CAAA,MAAA,CAAO,MAAgB,CAAA;AACrD,EAAA,MAAA,CAAO,OAAU,GAAA,MAAM,MAAO,CAAA,MAAA,CAAO,KAAK,CAAA;AAC1C,EAAA,MAAA,CAAO,WAAW,IAAI,CAAA;AACxB,CAAC;AAEU,MAAA,gBAAA,GAAmB,CAAC,WAAqC,KAAA;AACpE,EAAA,QAAQ,YAAY,IAAM;AAAA,IACxB,KAAK,iBAAkB,CAAA,IAAA;AACrB,MAAO,OAAA,kBAAA;AAAA,IACT,KAAK,iBAAkB,CAAA,GAAA;AACrB,MAAO,OAAA,iBAAA;AAAA,IACT;AACE,MAAA,OAAO,WAAY,CAAA,IAAA;AAAA;AAEzB;AAEO,MAAM,cAAiB,GAAA,CAAC,YAC7B,KAAA,YAAA,CAAa,IAAI,CAAS,IAAA,MAAA;AAAA,EACxB,eAAiB,EAAA,YAAA;AAAA,EACjB,YAAA,EAAc,iBAAiB,IAAI,CAAA;AAAA,EACnC,OAAA,EAAS,aAAa,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,IAAS,KAAA,IAAA,CAAK,IAAI,CAAA,EAAG,OAAW,IAAA;AACpE,CAAE,CAAA;;;;"}
|
|
@@ -5,7 +5,7 @@ const getFootnoteProps = (additionalClassName) => ({
|
|
|
5
5
|
className: additionalClassName ?? ""
|
|
6
6
|
},
|
|
7
7
|
title: "Verify accuracy",
|
|
8
|
-
description: `While Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
|
|
8
|
+
description: `While Developer Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,
|
|
9
9
|
bannerImage: {
|
|
10
10
|
src: "https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif",
|
|
11
11
|
alt: "Example image for footnote popover"
|
|
@@ -74,7 +74,22 @@ const getMessageData = (message) => {
|
|
|
74
74
|
return {
|
|
75
75
|
model: message?.response_metadata?.model,
|
|
76
76
|
content: message?.content || "",
|
|
77
|
-
timestamp: getTimestamp(message?.response_metadata?.created_at * 1e3)
|
|
77
|
+
timestamp: getTimestamp(message?.response_metadata?.created_at * 1e3),
|
|
78
|
+
referencedDocuments: message?.additional_kwargs?.referenced_documents ?? []
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
const transformDocumentsToSources = (referenced_documents) => {
|
|
82
|
+
if (!referenced_documents || referenced_documents?.length === 0) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
sources: referenced_documents.map(
|
|
87
|
+
(doc) => ({
|
|
88
|
+
title: doc.doc_title,
|
|
89
|
+
link: doc?.doc_url,
|
|
90
|
+
isExternal: true
|
|
91
|
+
})
|
|
92
|
+
)
|
|
78
93
|
};
|
|
79
94
|
};
|
|
80
95
|
const getDayDifference = (sourceTime, targetTime) => {
|
|
@@ -138,5 +153,5 @@ const getCategorizeMessages = (messages, addProps) => {
|
|
|
138
153
|
return filteredCategories;
|
|
139
154
|
};
|
|
140
155
|
|
|
141
|
-
export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getDayDifference, getFootnoteProps, getMessageData, getTimestamp, getTimestampVariablesString };
|
|
156
|
+
export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getDayDifference, getFootnoteProps, getMessageData, getTimestamp, getTimestampVariablesString, transformDocumentsToSources };
|
|
142
157
|
//# sourceMappingURL=lightspeed-chatbox-utils.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightspeed-chatbox-utils.esm.js","sources":["../../src/utils/lightspeed-chatbox-utils.ts"],"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 */\nimport { Conversation, SourcesCardProps } from '@patternfly/chatbot';\nimport { PopoverProps } from '@patternfly/react-core';\n\nimport { BaseMessage, ConversationList, ConversationSummary } from '../types';\n\nexport const getFootnoteProps = (additionalClassName: string) => ({\n label: 'Always check AI/LLM generated responses for accuracy prior to use.',\n popover: {\n popoverProps: {\n className: additionalClassName ?? '',\n } as PopoverProps,\n title: 'Verify accuracy',\n description: `While Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,\n bannerImage: {\n src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',\n alt: 'Example image for footnote popover',\n },\n cta: {\n label: 'Got it',\n onClick: () => {},\n },\n link: {\n label: 'Learn more',\n url: 'https://www.redhat.com/',\n },\n },\n});\n\nexport const getTimestampVariablesString = (v: number) => {\n if (v < 10) {\n return `0${v}`;\n }\n return `${v}`;\n};\n\nexport const getTimestamp = (unix_timestamp: number) => {\n if (typeof unix_timestamp !== 'number' || isNaN(unix_timestamp)) {\n // eslint-disable-next-line no-console\n console.error('Invalid Unix timestamp provided');\n return '';\n }\n\n const a = new Date(unix_timestamp);\n const month = getTimestampVariablesString(a.getMonth() + 1);\n const year = a.getFullYear();\n const date = getTimestampVariablesString(a.getDate());\n const hour = getTimestampVariablesString(a.getHours());\n const min = getTimestampVariablesString(a.getMinutes());\n const sec = getTimestampVariablesString(a.getSeconds());\n const time = `${date}/${month}/${year}, ${hour}:${min}:${sec}`;\n return time;\n};\n\nexport const splitJsonStrings = (jsonString: string): string[] => {\n const chunks = jsonString.split('}{');\n\n if (chunks.length <= 1) {\n return [jsonString];\n }\n\n return chunks.map((chunk, index, arr) => {\n if (index === 0) {\n return `${chunk}}`;\n } else if (index === arr.length - 1) {\n return `{${chunk}`;\n }\n return `{${chunk}}`;\n });\n};\n\ntype MessageProps = {\n content: string;\n timestamp: string;\n name?: string;\n avatar?: string | any;\n isLoading?: boolean;\n error?: {\n title: string;\n };\n sources?: SourcesCardProps;\n};\n\nexport const createMessage = ({\n role,\n name = 'Guest',\n avatar,\n isLoading = false,\n content,\n timestamp,\n error,\n sources,\n}: MessageProps & { role: 'user' | 'bot' }) => ({\n role,\n name,\n avatar,\n isLoading,\n content,\n timestamp,\n error,\n sources,\n});\n\nexport const createUserMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'user',\n name: props.name ?? 'Guest',\n });\n\nexport const createBotMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'bot',\n });\n\nexport const getMessageData = (message: BaseMessage) => {\n return {\n model: message?.response_metadata?.model,\n content: message?.content || '',\n timestamp: getTimestamp(message?.response_metadata?.created_at * 1000),\n };\n};\n\nexport const getDayDifference = (sourceTime: number, targetTime: number) => {\n const sourceDate = new Date(sourceTime);\n const targetDate = new Date(targetTime);\n\n sourceDate.setHours(0, 0, 0, 0);\n targetDate.setHours(0, 0, 0, 0);\n\n const timeDifference = sourceDate.getTime() - targetDate.getTime();\n\n return Math.floor(timeDifference / (1000 * 60 * 60 * 24));\n};\n\nexport const getCategorizeMessages = (\n messages: ConversationList,\n addProps: (c: ConversationSummary) => { [k: string]: any },\n): { [k: string]: Conversation[] } => {\n const now: any = new Date();\n const today = now.toDateString();\n\n const categorizedMessages: { [k: string]: Conversation[] } = {\n Today: [],\n Yesterday: [],\n 'Previous 7 Days': [],\n 'Previous 30 Days': [],\n };\n messages\n .sort((a, b) => b.last_message_timestamp - a.last_message_timestamp)\n .forEach(c => {\n const messageDate = new Date(c.last_message_timestamp * 1000);\n const messageDayString = messageDate.toDateString();\n const dayDifference = getDayDifference(\n now,\n c.last_message_timestamp * 1000,\n );\n const message: Conversation = {\n id: c.conversation_id,\n text: c.topic_summary,\n label: 'Options',\n ...addProps(c),\n };\n\n if (messageDayString === today) {\n categorizedMessages.Today.push(message);\n } else if (dayDifference === 1) {\n categorizedMessages.Yesterday.push(message);\n } else if (dayDifference <= 7) {\n categorizedMessages['Previous 7 Days'].push(message);\n } else if (dayDifference <= 30) {\n categorizedMessages['Previous 30 Days'].push(message);\n } else {\n // handle month-wise grouping\n const monthYear = messageDate.toLocaleString('default', {\n month: 'long',\n year: 'numeric',\n });\n if (!categorizedMessages[monthYear]) {\n categorizedMessages[monthYear] = [];\n }\n categorizedMessages[monthYear].push(message);\n }\n });\n\n const filteredCategories = Object.keys(categorizedMessages).reduce(\n (result, category) => {\n if (categorizedMessages[category].length > 0) {\n result[category] = categorizedMessages[category];\n }\n return result;\n },\n {} as any,\n );\n\n return filteredCategories;\n};\n"],"names":[],"mappings":"AAoBa,MAAA,gBAAA,GAAmB,CAAC,mBAAiC,MAAA;AAAA,EAChE,KAAO,EAAA,oEAAA;AAAA,EACP,OAAS,EAAA;AAAA,IACP,YAAc,EAAA;AAAA,MACZ,WAAW,mBAAuB,IAAA;AAAA,KACpC;AAAA,IACA,KAAO,EAAA,iBAAA;AAAA,IACP,WAAa,EAAA,CAAA,oNAAA,CAAA;AAAA,IACb,WAAa,EAAA;AAAA,MACX,GAAK,EAAA,iGAAA;AAAA,MACL,GAAK,EAAA;AAAA,KACP;AAAA,IACA,GAAK,EAAA;AAAA,MACH,KAAO,EAAA,QAAA;AAAA,MACP,SAAS,MAAM;AAAA;AAAC,KAClB;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,KAAO,EAAA,YAAA;AAAA,MACP,GAAK,EAAA;AAAA;AACP;AAEJ,CAAA;AAEa,MAAA,2BAAA,GAA8B,CAAC,CAAc,KAAA;AACxD,EAAA,IAAI,IAAI,EAAI,EAAA;AACV,IAAA,OAAO,IAAI,CAAC,CAAA,CAAA;AAAA;AAEd,EAAA,OAAO,GAAG,CAAC,CAAA,CAAA;AACb;AAEa,MAAA,YAAA,GAAe,CAAC,cAA2B,KAAA;AACtD,EAAA,IAAI,OAAO,cAAA,KAAmB,QAAY,IAAA,KAAA,CAAM,cAAc,CAAG,EAAA;AAE/D,IAAA,OAAA,CAAQ,MAAM,iCAAiC,CAAA;AAC/C,IAAO,OAAA,EAAA;AAAA;AAGT,EAAM,MAAA,CAAA,GAAI,IAAI,IAAA,CAAK,cAAc,CAAA;AACjC,EAAA,MAAM,KAAQ,GAAA,2BAAA,CAA4B,CAAE,CAAA,QAAA,KAAa,CAAC,CAAA;AAC1D,EAAM,MAAA,IAAA,GAAO,EAAE,WAAY,EAAA;AAC3B,EAAA,MAAM,IAAO,GAAA,2BAAA,CAA4B,CAAE,CAAA,OAAA,EAAS,CAAA;AACpD,EAAA,MAAM,IAAO,GAAA,2BAAA,CAA4B,CAAE,CAAA,QAAA,EAAU,CAAA;AACrD,EAAA,MAAM,GAAM,GAAA,2BAAA,CAA4B,CAAE,CAAA,UAAA,EAAY,CAAA;AACtD,EAAA,MAAM,GAAM,GAAA,2BAAA,CAA4B,CAAE,CAAA,UAAA,EAAY,CAAA;AACtD,EAAA,MAAM,IAAO,GAAA,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA;AAC5D,EAAO,OAAA,IAAA;AACT;AA+BO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,IAAA;AAAA,EACA,IAAO,GAAA,OAAA;AAAA,EACP,MAAA;AAAA,EACA,SAAY,GAAA,KAAA;AAAA,EACZ,OAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAgD,MAAA;AAAA,EAC9C,IAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA;AAEa,MAAA,iBAAA,GAAoB,CAAC,KAAA,KAChC,aAAc,CAAA;AAAA,EACZ,GAAG,KAAA;AAAA,EACH,IAAM,EAAA,MAAA;AAAA,EACN,IAAA,EAAM,MAAM,IAAQ,IAAA;AACtB,CAAC;AAEU,MAAA,gBAAA,GAAmB,CAAC,KAAA,KAC/B,aAAc,CAAA;AAAA,EACZ,GAAG,KAAA;AAAA,EACH,IAAM,EAAA;AACR,CAAC;AAEU,MAAA,cAAA,GAAiB,CAAC,OAAyB,KAAA;AACtD,EAAO,OAAA;AAAA,IACL,KAAA,EAAO,SAAS,iBAAmB,EAAA,KAAA;AAAA,IACnC,OAAA,EAAS,SAAS,OAAW,IAAA,EAAA;AAAA,IAC7B,SAAW,EAAA,YAAA,CAAa,OAAS,EAAA,iBAAA,EAAmB,aAAa,GAAI;AAAA,GACvE;AACF;AAEa,MAAA,gBAAA,GAAmB,CAAC,UAAA,EAAoB,UAAuB,KAAA;AAC1E,EAAM,MAAA,UAAA,GAAa,IAAI,IAAA,CAAK,UAAU,CAAA;AACtC,EAAM,MAAA,UAAA,GAAa,IAAI,IAAA,CAAK,UAAU,CAAA;AAEtC,EAAA,UAAA,CAAW,QAAS,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,CAAC,CAAA;AAC9B,EAAA,UAAA,CAAW,QAAS,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,CAAC,CAAA;AAE9B,EAAA,MAAM,cAAiB,GAAA,UAAA,CAAW,OAAQ,EAAA,GAAI,WAAW,OAAQ,EAAA;AAEjE,EAAA,OAAO,KAAK,KAAM,CAAA,cAAA,IAAkB,GAAO,GAAA,EAAA,GAAK,KAAK,EAAG,CAAA,CAAA;AAC1D;AAEa,MAAA,qBAAA,GAAwB,CACnC,QAAA,EACA,QACoC,KAAA;AACpC,EAAM,MAAA,GAAA,uBAAe,IAAK,EAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,IAAI,YAAa,EAAA;AAE/B,EAAA,MAAM,mBAAuD,GAAA;AAAA,IAC3D,OAAO,EAAC;AAAA,IACR,WAAW,EAAC;AAAA,IACZ,mBAAmB,EAAC;AAAA,IACpB,oBAAoB;AAAC,GACvB;AACA,EACG,QAAA,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAM,KAAA,CAAA,CAAE,yBAAyB,CAAE,CAAA,sBAAsB,CAClE,CAAA,OAAA,CAAQ,CAAK,CAAA,KAAA;AACZ,IAAA,MAAM,WAAc,GAAA,IAAI,IAAK,CAAA,CAAA,CAAE,yBAAyB,GAAI,CAAA;AAC5D,IAAM,MAAA,gBAAA,GAAmB,YAAY,YAAa,EAAA;AAClD,IAAA,MAAM,aAAgB,GAAA,gBAAA;AAAA,MACpB,GAAA;AAAA,MACA,EAAE,sBAAyB,GAAA;AAAA,KAC7B;AACA,IAAA,MAAM,OAAwB,GAAA;AAAA,MAC5B,IAAI,CAAE,CAAA,eAAA;AAAA,MACN,MAAM,CAAE,CAAA,aAAA;AAAA,MACR,KAAO,EAAA,SAAA;AAAA,MACP,GAAG,SAAS,CAAC;AAAA,KACf;AAEA,IAAA,IAAI,qBAAqB,KAAO,EAAA;AAC9B,MAAoB,mBAAA,CAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAAA,KACxC,MAAA,IAAW,kBAAkB,CAAG,EAAA;AAC9B,MAAoB,mBAAA,CAAA,SAAA,CAAU,KAAK,OAAO,CAAA;AAAA,KAC5C,MAAA,IAAW,iBAAiB,CAAG,EAAA;AAC7B,MAAoB,mBAAA,CAAA,iBAAiB,CAAE,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KACrD,MAAA,IAAW,iBAAiB,EAAI,EAAA;AAC9B,MAAoB,mBAAA,CAAA,kBAAkB,CAAE,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KAC/C,MAAA;AAEL,MAAM,MAAA,SAAA,GAAY,WAAY,CAAA,cAAA,CAAe,SAAW,EAAA;AAAA,QACtD,KAAO,EAAA,MAAA;AAAA,QACP,IAAM,EAAA;AAAA,OACP,CAAA;AACD,MAAI,IAAA,CAAC,mBAAoB,CAAA,SAAS,CAAG,EAAA;AACnC,QAAoB,mBAAA,CAAA,SAAS,IAAI,EAAC;AAAA;AAEpC,MAAoB,mBAAA,CAAA,SAAS,CAAE,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA;AAC7C,GACD,CAAA;AAEH,EAAA,MAAM,kBAAqB,GAAA,MAAA,CAAO,IAAK,CAAA,mBAAmB,CAAE,CAAA,MAAA;AAAA,IAC1D,CAAC,QAAQ,QAAa,KAAA;AACpB,MAAA,IAAI,mBAAoB,CAAA,QAAQ,CAAE,CAAA,MAAA,GAAS,CAAG,EAAA;AAC5C,QAAO,MAAA,CAAA,QAAQ,CAAI,GAAA,mBAAA,CAAoB,QAAQ,CAAA;AAAA;AAEjD,MAAO,OAAA,MAAA;AAAA,KACT;AAAA,IACA;AAAC,GACH;AAEA,EAAO,OAAA,kBAAA;AACT;;;;"}
|
|
1
|
+
{"version":3,"file":"lightspeed-chatbox-utils.esm.js","sources":["../../src/utils/lightspeed-chatbox-utils.ts"],"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 */\nimport { Conversation, SourcesCardProps } from '@patternfly/chatbot';\nimport { PopoverProps } from '@patternfly/react-core';\n\nimport {\n BaseMessage,\n ConversationList,\n ConversationSummary,\n ReferencedDocuments,\n} from '../types';\n\nexport const getFootnoteProps = (additionalClassName: string) => ({\n label: 'Always check AI/LLM generated responses for accuracy prior to use.',\n popover: {\n popoverProps: {\n className: additionalClassName ?? '',\n } as PopoverProps,\n title: 'Verify accuracy',\n description: `While Developer Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,\n bannerImage: {\n src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',\n alt: 'Example image for footnote popover',\n },\n cta: {\n label: 'Got it',\n onClick: () => {},\n },\n link: {\n label: 'Learn more',\n url: 'https://www.redhat.com/',\n },\n },\n});\n\nexport const getTimestampVariablesString = (v: number) => {\n if (v < 10) {\n return `0${v}`;\n }\n return `${v}`;\n};\n\nexport const getTimestamp = (unix_timestamp: number) => {\n if (typeof unix_timestamp !== 'number' || isNaN(unix_timestamp)) {\n // eslint-disable-next-line no-console\n console.error('Invalid Unix timestamp provided');\n return '';\n }\n\n const a = new Date(unix_timestamp);\n const month = getTimestampVariablesString(a.getMonth() + 1);\n const year = a.getFullYear();\n const date = getTimestampVariablesString(a.getDate());\n const hour = getTimestampVariablesString(a.getHours());\n const min = getTimestampVariablesString(a.getMinutes());\n const sec = getTimestampVariablesString(a.getSeconds());\n const time = `${date}/${month}/${year}, ${hour}:${min}:${sec}`;\n return time;\n};\n\nexport const splitJsonStrings = (jsonString: string): string[] => {\n const chunks = jsonString.split('}{');\n\n if (chunks.length <= 1) {\n return [jsonString];\n }\n\n return chunks.map((chunk, index, arr) => {\n if (index === 0) {\n return `${chunk}}`;\n } else if (index === arr.length - 1) {\n return `{${chunk}`;\n }\n return `{${chunk}}`;\n });\n};\n\ntype MessageProps = {\n content: string;\n timestamp: string;\n name?: string;\n avatar?: string | any;\n isLoading?: boolean;\n error?: {\n title: string;\n };\n sources?: SourcesCardProps;\n};\n\nexport const createMessage = ({\n role,\n name = 'Guest',\n avatar,\n isLoading = false,\n content,\n timestamp,\n error,\n sources,\n}: MessageProps & { role: 'user' | 'bot' }) => ({\n role,\n name,\n avatar,\n isLoading,\n content,\n timestamp,\n error,\n sources,\n});\n\nexport const createUserMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'user',\n name: props.name ?? 'Guest',\n });\n\nexport const createBotMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'bot',\n });\n\nexport const getMessageData = (message: BaseMessage) => {\n return {\n model: message?.response_metadata?.model,\n content: message?.content || '',\n timestamp: getTimestamp(message?.response_metadata?.created_at * 1000),\n referencedDocuments: message?.additional_kwargs?.referenced_documents ?? [],\n };\n};\n\nexport const transformDocumentsToSources = (\n referenced_documents: ReferencedDocuments,\n): SourcesCardProps | undefined => {\n if (!referenced_documents || referenced_documents?.length === 0) {\n return undefined;\n }\n return {\n sources: referenced_documents.map(\n (doc: { doc_title: string; doc_url: string }) => ({\n title: doc.doc_title,\n link: doc?.doc_url,\n isExternal: true,\n }),\n ),\n };\n};\n\nexport const getDayDifference = (sourceTime: number, targetTime: number) => {\n const sourceDate = new Date(sourceTime);\n const targetDate = new Date(targetTime);\n\n sourceDate.setHours(0, 0, 0, 0);\n targetDate.setHours(0, 0, 0, 0);\n\n const timeDifference = sourceDate.getTime() - targetDate.getTime();\n\n return Math.floor(timeDifference / (1000 * 60 * 60 * 24));\n};\n\nexport const getCategorizeMessages = (\n messages: ConversationList,\n addProps: (c: ConversationSummary) => { [k: string]: any },\n): { [k: string]: Conversation[] } => {\n const now: any = new Date();\n const today = now.toDateString();\n\n const categorizedMessages: { [k: string]: Conversation[] } = {\n Today: [],\n Yesterday: [],\n 'Previous 7 Days': [],\n 'Previous 30 Days': [],\n };\n messages\n .sort((a, b) => b.last_message_timestamp - a.last_message_timestamp)\n .forEach(c => {\n const messageDate = new Date(c.last_message_timestamp * 1000);\n const messageDayString = messageDate.toDateString();\n const dayDifference = getDayDifference(\n now,\n c.last_message_timestamp * 1000,\n );\n const message: Conversation = {\n id: c.conversation_id,\n text: c.topic_summary,\n label: 'Options',\n ...addProps(c),\n };\n\n if (messageDayString === today) {\n categorizedMessages.Today.push(message);\n } else if (dayDifference === 1) {\n categorizedMessages.Yesterday.push(message);\n } else if (dayDifference <= 7) {\n categorizedMessages['Previous 7 Days'].push(message);\n } else if (dayDifference <= 30) {\n categorizedMessages['Previous 30 Days'].push(message);\n } else {\n // handle month-wise grouping\n const monthYear = messageDate.toLocaleString('default', {\n month: 'long',\n year: 'numeric',\n });\n if (!categorizedMessages[monthYear]) {\n categorizedMessages[monthYear] = [];\n }\n categorizedMessages[monthYear].push(message);\n }\n });\n\n const filteredCategories = Object.keys(categorizedMessages).reduce(\n (result, category) => {\n if (categorizedMessages[category].length > 0) {\n result[category] = categorizedMessages[category];\n }\n return result;\n },\n {} as any,\n );\n\n return filteredCategories;\n};\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@red-hat-developer-hub/backstage-plugin-lightspeed",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"main": "dist/index.esm.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"@material-ui/core": "^4.9.13",
|
|
45
45
|
"@material-ui/lab": "^4.0.0-alpha.61",
|
|
46
46
|
"@mui/icons-material": "^6.1.8",
|
|
47
|
-
"@patternfly/chatbot": "6.3.0-prerelease.
|
|
48
|
-
"@patternfly/react-core": "6.3.0-prerelease.
|
|
49
|
-
"@red-hat-developer-hub/backstage-plugin-lightspeed-common": "^0.3.
|
|
47
|
+
"@patternfly/chatbot": "6.3.0-prerelease.23",
|
|
48
|
+
"@patternfly/react-core": "6.3.0-prerelease.17",
|
|
49
|
+
"@red-hat-developer-hub/backstage-plugin-lightspeed-common": "^0.3.2",
|
|
50
50
|
"@tanstack/react-query": "^5.59.15",
|
|
51
51
|
"openai": "^4.52.6",
|
|
52
52
|
"react-markdown": "^9.0.1",
|
package/dist/images/logo.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?><svg id="uuid-46701468-6641-48cb-987a-ad8aaaa4cc57" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 38"><defs><style>.uuid-05c8f53d-396a-4a77-b610-4cae1607b37f{fill:#e00;}.uuid-058b635d-b61c-46f4-982a-a91d6a2263eb{fill:#fff;}.uuid-0168188c-d0a6-496e-a2d8-5cd6ee30dcb2{fill:#e0e0e0;}</style></defs><path class="uuid-058b635d-b61c-46f4-982a-a91d6a2263eb" d="m28,1H10C5.02944,1,1,5.02944,1,10v18c0,4.97057,4.02944,9,9,9h18c4.97056,0,9-4.02943,9-9V10c0-4.97056-4.02944-9-9-9h0Z"/><path class="uuid-0168188c-d0a6-496e-a2d8-5cd6ee30dcb2" d="m28,2.25c4.27332,0,7.75,3.47664,7.75,7.75v18c0,4.27336-3.47668,7.75-7.75,7.75H10c-4.27332,0-7.75-3.47664-7.75-7.75V10c0-4.27336,3.47668-7.75,7.75-7.75h18m0-1.25H10C5.02942,1,1,5.02944,1,10v18c0,4.97057,4.02942,9,9,9h18c4.97058,0,9-4.02943,9-9V10c0-4.97056-4.02942-9-9-9h0Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m20,15.625c-.34473,0-.625-.28027-.625-.625v-7c0-.34473.28027-.625.625-.625s.625.28027.625.625v7c0,.34473-.28027.625-.625.625Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m16,19.625h-7c-.34473,0-.625-.28027-.625-.625s.28027-.625.625-.625h7c.34473,0,.625.28027.625.625s-.28027.625-.625.625Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m20,30.625c-.34473,0-.625-.28027-.625-.625v-7c0-.34473.28027-.625.625-.625s.625.28027.625.625v7c0,.34473-.28027.625-.625.625Z"/><path d="m30.57654,19.23944c.02795-.06769.03955-.13947.04285-.21149.00049-.00983.00562-.01807.00562-.02795s-.00513-.01813-.00562-.02795c-.0033-.07202-.01489-.1438-.04285-.21149-.02002-.04791-.05383-.08667-.08447-.12775-.01807-.02448-.02759-.05304-.04968-.0752l-2-2c-.24414-.24414-.64062-.24414-.88477,0-.24316.24414-.24316.64062,0,.88477l.93323.93262h-9.49084c-.34473,0-.625.28027-.625.625s.28027.625.625.625h9.49084l-.93323.93262c-.24316.24414-.24316.64062,0,.88477.12207.12207.28223.18262.44238.18262s.32031-.06055.44238-.18262l2-2c.02209-.02216.03162-.05072.04968-.0752.03064-.04108.06445-.07983.08447-.12775Z"/><path d="m17,16.625c-.16016,0-.32031-.06055-.44238-.18262l-4-4c-.24316-.24414-.24316-.64062,0-.88477.24414-.24414.64062-.24414.88477,0l4,4c.24316.24414.24316.64062,0,.88477-.12207.12207-.28223.18262-.44238.18262Z"/><path d="m13,26.625c-.16016,0-.32031-.06055-.44238-.18262-.24316-.24414-.24316-.64062,0-.88477l4-4c.24414-.24414.64062-.24414.88477,0,.24316.24414.24316.64062,0,.88477l-4,4c-.12207.12207-.28223.18262-.44238.18262Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m17.42383,13.625c-.28809,0-.54785-.20117-.61035-.49512l-.4248-2c-.07129-.33789.14355-.66992.48145-.74121.33887-.0752.66992.14355.74121.48145l.4248,2c.07129.33789-.14355.66992-.48145.74121-.04395.00977-.08789.01367-.13086.01367Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m14.00098,17.0498c-.04297,0-.08691-.00391-.13086-.01367l-2-.4248c-.33789-.07129-.55273-.40332-.48145-.74121.07227-.33789.40234-.55859.74121-.48145l2,.4248c.33789.07129.55273.40332.48145.74121-.0625.29395-.32227.49512-.61035.49512Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m17.00098,27.625c-.04297,0-.08691-.00391-.13086-.01367-.33789-.07129-.55273-.40332-.48145-.74121l.4248-2c.07227-.33789.40137-.55566.74121-.48145.33789.07129.55273.40332.48145.74121l-.4248,2c-.0625.29395-.32227.49512-.61035.49512Z"/><path class="uuid-05c8f53d-396a-4a77-b610-4cae1607b37f" d="m11.99902,22.625c-.28809,0-.54785-.20117-.61035-.49512-.07129-.33789.14355-.66992.48145-.74121l2-.4248c.34082-.07617.66992.14355.74121.48145s-.14355.66992-.48145.74121l-2,.4248c-.04395.00977-.08789.01367-.13086.01367Z"/><path d="m9,15.62988c-.16016,0-.32031-.07031-.44043-.19043-.05957-.05957-.09961-.12012-.13965-.19922-.03027-.08008-.0498-.16016-.0498-.24023,0-.16016.06934-.32031.18945-.44043.23047-.22949.65039-.24023.87988,0,.12012.12012.19043.28027.19043.44043,0,.08008-.02051.16016-.0498.24023-.03027.0791-.08008.13965-.14062.19922-.12012.12012-.2793.19043-.43945.19043Z"/><path d="m9,23.62988c-.16016,0-.32031-.07031-.44043-.19043-.12012-.10938-.18945-.2793-.18945-.43945s.06934-.32031.18945-.44043c.23047-.22949.64062-.24023.87988,0,.12012.12012.19043.28027.19043.44043s-.07031.33008-.19043.43945c-.12012.12012-.2793.19043-.43945.19043Z"/></svg>
|