@red-hat-developer-hub/backstage-plugin-lightspeed 0.5.3 → 0.5.4

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  ## @red-hat-developer-hub/backstage-plugin-lightspeed
2
2
 
3
+ ## 0.5.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 555ef5b: Added support for Drag and Drop attachment upload
8
+ - ee1da3b: enable only supported file types in file picker
9
+ - 13dd7b1: Updated dependency `@patternfly/chatbot` to `6.3.0-prerelease.20`.
10
+ Updated dependency `@patternfly/react-core` to `6.3.0-prerelease.17`.
11
+ - 717a32b: Updated dependency `@patternfly/react-core` to `6.3.0-prerelease.16`.
12
+ - 6495f17: Make source card links as external links
13
+
3
14
  ## 0.5.3
4
15
 
5
16
  ### Patch Changes
@@ -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":"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"}
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":";;;AA4Ca,MAAA,qBAAA,GACXA,cAAM,CAAA,aAAA,CAAgD,IAAI;AAE5D,MAAM,6BAED,GAAA,CAAC,EAAE,QAAA,EAAe,KAAA;AACrB,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAIA,eAAM,QAExD,EAAA;AACF,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,IAAIA,cAAM,CAAA,QAAA,CAE9C,EAAE,CAAA;AACJ,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAAA,cAAA,CAAM,SAAiB,CAAC,CAAA;AACtE,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,CAAI,GAAAA,cAAA,CAAM,SAAkB,KAAK,CAAA;AAC/D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAM,QAAsB,CAAA;AAAA,IAChE,OAAS,EAAA;AAAA,GACV,CAAA;AACD,EAAA,MAAM,CAAC,YAAc,EAAA,eAAe,IAAIA,cAAM,CAAA,QAAA,CAAwB,EAAE,CAAA;AACxE,EAAA,MAAM,CAAC,kBAAoB,EAAA,qBAAqB,CAC9C,GAAAA,cAAA,CAAM,SAAkB,KAAK,CAAA;AAC/B,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAAA,cAAA,CAAM,SAAkB,KAAK,CAAA;AAC3E,EAAM,MAAA,gBAAA,GAAmB,CAAC,OAAoB,KAAA;AAC5C,IAAA,MAAM,eAAe,YAAa,CAAA,IAAA;AAAA,MAChC,CAAQ,IAAA,KAAA,IAAA,CAAK,IAAS,KAAA,OAAA,CAAQ,CAAC,CAAE,CAAA;AAAA,KACnC;AACA,IAAA,IAAI,YAAc,EAAA;AAChB,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,cAAA,CAAe,EAAE,IAAA,EAAM,MAAQ,EAAA,OAAA,EAAS,wBAAwB,CAAA;AAChE,MAAA;AAAA;AAGF,IAAiB,gBAAA,CAAA,EAAE,CAAC,OAAQ,CAAA,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;AAE5C,IAAI,IAAA,OAAA,CAAQ,SAAS,CAAG,EAAA;AACtB,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAe,cAAA,CAAA;AAAA,QACb,OAAS,EAAA;AAAA,OACV,CAAA;AACD,MAAA;AAAA;AAEF,IAAA,IAAI,CAAC,mBAAA,CAAoB,OAAQ,CAAA,CAAC,CAAC,CAAG,EAAA;AACpC,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAe,cAAA,CAAA;AAAA,QACb,OACE,EAAA;AAAA,OACH,CAAA;AACD,MAAA;AAAA;AAIF,IAAA,IAAI,OAAQ,CAAA,CAAC,CAAE,CAAA,IAAA,GAAO,IAAU,EAAA;AAC9B,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAe,cAAA,CAAA;AAAA,QACb,OACE,EAAA;AAAA,OACH,CAAA;AACD,MAAA;AAAA;AAGF,IAAA,cAAA,CAAe,OAAQ,CAAA,CAAC,CAAC,CAAA,CACtB,KAAK,CAAQ,IAAA,KAAA;AACZ,MAAA,eAAA,CAAgB,CAAQ,IAAA,KAAA;AAAA,QACtB,GAAG,IAAA;AAAA,QACH;AAAA,UACE,IAAA,EAAM,OAAQ,CAAA,CAAC,CAAE,CAAA,IAAA;AAAA,UACjB,IAAA,EAAM,OAAQ,CAAA,CAAC,CAAE,CAAA,IAAA;AAAA,UACjB,OAAS,EAAA;AAAA;AACX,OACD,CAAA;AACD,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAe,cAAA,CAAA,EAAE,OAAS,EAAA,IAAA,EAAM,CAAA;AAChC,MAAiB,gBAAA,CAAA,EAAE,CAAC,OAAQ,CAAA,CAAC,EAAE,IAAI,GAAG,OAAO,CAAA;AAAA,KAC9C,CAAA,CACA,KAAM,CAAA,CAAC,KAAwB,KAAA;AAC9B,MAAe,cAAA,CAAA;AAAA,QACb,OAAA,EAAS,CAAwB,qBAAA,EAAA,KAAA,CAAM,OAAO,CAAA;AAAA,OAC/C,CAAA;AAAA,KACF,CAAA;AAAA,GACL;AAEA,EAAA,MAAM,UAAa,GAAA;AAAA,IACjB,kBAAA;AAAA,IACA,qBAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF;AACA,EACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,qBAAsB,CAAA,QAAA;AAAA,IAAtB;AAAA,MACC,KAAO,EAAA;AAAA,QACL,UAAA;AAAA,QACA,YAAA;AAAA,QACA,eAAA;AAAA,QACA,gBAAA;AAAA,QACA,aAAA;AAAA,QACA,SAAA;AAAA,QACA,YAAA;AAAA,QACA,WAAA;AAAA,QACA,cAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA;AACF,KAAA;AAAA,IAEC;AAAA,GACH;AAEJ;AAIO,MAAM,2BAA2B,MAAiC;AACvE,EAAA,MAAM,UAAUA,cAAM,CAAA,UAAA;AAAA,IACpB;AAAA,GACF;AAEA,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAGF,EAAO,OAAA,OAAA;AACT;;;;"}
@@ -1,17 +1,14 @@
1
1
  import React__default from 'react';
2
2
  import { Divider } from '@material-ui/core';
3
- import { FileDetailsLabel, ChatbotAlert } from '@patternfly/chatbot';
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
- ))), showAlert && uploadError.message && /* @__PURE__ */ React__default.createElement(
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 { ChatbotAlert, FileDetailsLabel } from '@patternfly/chatbot';\n\nimport { useFileAttachmentContext } from './AttachmentContext';\n\nconst FilePreview = () => {\n const {\n showAlert,\n fileContents,\n isLoadingFile,\n uploadError,\n modalState,\n setFileContents,\n setUploadError,\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 {showAlert && uploadError.message && (\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 )}\n </>\n );\n};\n\nexport default FilePreview;\n"],"names":["React"],"mappings":";;;;;AAsBA,MAAM,cAAc,MAAM;AACxB,EAAM,MAAA;AAAA,IACJ,SAAA;AAAA,IACA,YAAA;AAAA,IACA,aAAA;AAAA,IACA,WAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA;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,CAED,EAAA,SAAA,IAAa,YAAY,OACxB,oBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,IAAA;AAAA,MACV,KAAM,EAAA,oBAAA;AAAA,MACN,OAAA,EAAS,YAAY,IAAQ,IAAA,QAAA;AAAA,MAC7B,QAAQ,EAAA,IAAA;AAAA,MACR,SAAS,MAAM,cAAA,CAAe,EAAE,OAAA,EAAS,MAAM;AAAA,KAAA;AAAA,IAE9C,WAAY,CAAA;AAAA,GAGnB,CAAA;AAEJ;;;;"}
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 { fileContents, setFileContents, handleFileUpload } = useFileAttachmentContext();
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
- }, [conversationId, setConversationId, setMessages]);
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
  }
@@ -299,26 +330,56 @@ const LightspeedChat = ({
299
330
  conversations: filterConversations(filterValue),
300
331
  onNewChat: newChatCreated ? undefined : onNewChat,
301
332
  handleTextInputChange: handleFilter,
302
- drawerContent: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ChatbotContent, null, /* @__PURE__ */ React__default.createElement(
303
- LightspeedChatBox,
333
+ drawerContent: /* @__PURE__ */ React__default.createElement(
334
+ FileDropZone,
304
335
  {
305
- userName,
306
- messages,
307
- profileLoading,
308
- announcement,
309
- ref: scrollToBottomRef,
310
- welcomePrompts
311
- }
312
- )), /* @__PURE__ */ React__default.createElement(ChatbotFooter, { className: classes.footer }, /* @__PURE__ */ React__default.createElement(FilePreview, null), /* @__PURE__ */ React__default.createElement(
313
- MessageBar,
314
- {
315
- onSendMessage: sendMessage,
316
- isSendButtonDisabled,
317
- hasAttachButton: true,
318
- handleAttach,
319
- hasMicrophoneButton: true
320
- }
321
- ), /* @__PURE__ */ React__default.createElement(ChatbotFootnote, { ...getFootnoteProps(classes.footerPopover) })))
336
+ onFileDrop: (e, data) => handleAttach(data, e),
337
+ displayMode: ChatbotDisplayMode.embedded,
338
+ infoText: "Supported file types are: .txt, .yaml, .json and .xml. The maximum file size is 25 MB.",
339
+ allowedFileTypes: supportedFileTypes,
340
+ onAttachRejected
341
+ },
342
+ showAlert && uploadError.message && /* @__PURE__ */ React__default.createElement("div", { className: classes.errorContainer }, /* @__PURE__ */ React__default.createElement(
343
+ ChatbotAlert,
344
+ {
345
+ component: "h4",
346
+ title: "File upload failed",
347
+ variant: uploadError.type ?? "danger",
348
+ isInline: true,
349
+ onClose: () => setUploadError({ message: null })
350
+ },
351
+ uploadError.message
352
+ )),
353
+ /* @__PURE__ */ React__default.createElement(ChatbotContent, null, /* @__PURE__ */ React__default.createElement(
354
+ LightspeedChatBox,
355
+ {
356
+ userName,
357
+ messages,
358
+ profileLoading,
359
+ announcement,
360
+ ref: scrollToBottomRef,
361
+ welcomePrompts
362
+ }
363
+ )),
364
+ /* @__PURE__ */ React__default.createElement(ChatbotFooter, { className: classes.footer }, /* @__PURE__ */ React__default.createElement(FilePreview, null), /* @__PURE__ */ React__default.createElement(
365
+ MessageBar,
366
+ {
367
+ onSendMessage: sendMessage,
368
+ isSendButtonDisabled,
369
+ hasAttachButton: true,
370
+ handleAttach,
371
+ hasMicrophoneButton: true,
372
+ buttonProps: {
373
+ attach: {
374
+ inputTestId: "attachment-input"
375
+ }
376
+ },
377
+ allowedFileTypes: supportedFileTypes,
378
+ onAttachRejected,
379
+ placeholder: "Send a message and optionally upload a JSON, YAML, TXT, or XML file..."
380
+ }
381
+ ), /* @__PURE__ */ React__default.createElement(ChatbotFootnote, { ...getFootnoteProps(classes.footerPopover) }))
382
+ )
322
383
  }
323
384
  )
324
385
  ), /* @__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 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 <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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"}
package/dist/const.esm.js CHANGED
@@ -4,6 +4,12 @@ const FUNCTION_DISCLAIMER = `Red Hat Developer Hub Lightspeed can answer questio
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",
@@ -57,5 +63,5 @@ const RHDH_SAMPLE_PROMPTS = [
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
@@ -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 = `Red Hat Developer Hub 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 Hub Lightspeed may be reviewed and used to improve products or services.`;\n\nexport const FUNCTION_DISCLAIMER = `Red Hat Developer Hub 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 Hub 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 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 Backstage',\n 'Can you guide me through the first steps to start using Backstage 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,kbAAA;AAExD,MAAM,mBAAsB,GAAA,CAAA,gnBAAA;AAEnC,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,OAAoB,KAAA;AACvD,EAAO,OAAA,EAAE,OAAO,OAAQ,EAAA;AAC1B,CAAA;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,gCAAA;AAAA,IACA;AAAA;AAEJ;;;;"}
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 = `Red Hat Developer Hub 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 Hub Lightspeed may be reviewed and used to improve products or services.`;\n\nexport const FUNCTION_DISCLAIMER = `Red Hat Developer Hub 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 Hub 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 Backstage',\n 'Can you guide me through the first steps to start using Backstage 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,kbAAA;AAExD,MAAM,mBAAsB,GAAA,CAAA,gnBAAA;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,gCAAA;AAAA,IACA;AAAA;AAEJ;;;;"}
@@ -4,7 +4,7 @@ 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
6
  import logo from '../images/logo.svg';
7
- import { getMessageData, createUserMessage, createBotMessage, getTimestamp } from '../utils/lightspeed-chatbox-utils.esm.js';
7
+ import { getMessageData, createUserMessage, createBotMessage, transformDocumentsToSources, getTimestamp } from '../utils/lightspeed-chatbox-utils.esm.js';
8
8
  import { useCreateConversationMessage } from './useCreateCoversationMessage.esm.js';
9
9
 
10
10
  const useFetchConversationMessages = (currentConversation) => {
@@ -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
  ...[
@@ -71,7 +72,8 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
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
  );
@@ -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 logo from '../images/logo.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\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 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: logo,\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: 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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"}
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
 
@@ -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":"AAqDY,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;AAHG,EAAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA;;;;"}
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
- return isJson || isYaml || isText;
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) => fileContent.type === SupportedFileType.YAML ? "application/yaml" : fileContent.type;
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 =>\n fileContent.type === SupportedFileType.YAML\n ? 'application/yaml'\n : fileContent.type;\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,OAAO,UAAU,MAAU,IAAA,MAAA;AAC7B;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,WAC/B,KAAA,WAAA,CAAY,SAAS,iBAAkB,CAAA,IAAA,GACnC,qBACA,WAAY,CAAA;AAEX,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;;;;"}
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;;;;"}
@@ -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":"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"}
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 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",
3
+ "version": "0.5.4",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -44,8 +44,8 @@
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.17",
48
- "@patternfly/react-core": "6.3.0-prerelease.4",
47
+ "@patternfly/chatbot": "6.3.0-prerelease.23",
48
+ "@patternfly/react-core": "6.3.0-prerelease.17",
49
49
  "@red-hat-developer-hub/backstage-plugin-lightspeed-common": "^0.3.1",
50
50
  "@tanstack/react-query": "^5.59.15",
51
51
  "openai": "^4.52.6",