@red-hat-developer-hub/backstage-plugin-lightspeed 0.6.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +40 -58
- package/config.d.ts +1 -24
- package/dist/api/LightspeedApiClient.esm.js +26 -11
- package/dist/api/LightspeedApiClient.esm.js.map +1 -1
- package/dist/api/api.esm.js.map +1 -1
- package/dist/components/LightSpeedChat.esm.js +17 -1
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedChatBox.esm.js +3 -5
- package/dist/components/LightspeedChatBox.esm.js.map +1 -1
- package/dist/components/LightspeedChatBoxHeader.esm.js +14 -3
- package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
- package/dist/components/LightspeedPage.esm.js +17 -2
- package/dist/components/LightspeedPage.esm.js.map +1 -1
- package/dist/const.esm.js +4 -1
- package/dist/const.esm.js.map +1 -1
- package/dist/hooks/useConversationMessages.esm.js +23 -21
- package/dist/hooks/useConversationMessages.esm.js.map +1 -1
- package/dist/hooks/useCreateCoversationMessage.esm.js +2 -0
- package/dist/hooks/useCreateCoversationMessage.esm.js.map +1 -1
- package/dist/hooks/useQuestionValidation.esm.js +16 -0
- package/dist/hooks/useQuestionValidation.esm.js.map +1 -0
- package/dist/hooks/useWelcomePrompts.esm.js +3 -2
- package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
- package/dist/types.esm.js.map +1 -1
- package/dist/utils/lightspeed-chatbox-utils.esm.js +18 -8
- package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
3
|
import { makeStyles, createStyles } from '@material-ui/core';
|
|
4
4
|
import { ChatbotHeaderActions } from '@patternfly/chatbot';
|
|
5
|
-
import { Dropdown, DropdownList, DropdownItem, MenuToggle } from '@patternfly/react-core';
|
|
5
|
+
import { Dropdown, DropdownList, DropdownGroup, DropdownItem, MenuToggle } from '@patternfly/react-core';
|
|
6
6
|
import { useTranslation } from '../hooks/useTranslation.esm.js';
|
|
7
7
|
|
|
8
8
|
const useStyles = makeStyles(
|
|
@@ -23,6 +23,17 @@ const LightspeedChatBoxHeader = ({
|
|
|
23
23
|
const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);
|
|
24
24
|
const { t } = useTranslation();
|
|
25
25
|
const styles = useStyles();
|
|
26
|
+
const groupedModels = useMemo(() => {
|
|
27
|
+
const groups = {};
|
|
28
|
+
models.forEach((model) => {
|
|
29
|
+
const provider = model.provider || "Other";
|
|
30
|
+
if (!groups[provider]) {
|
|
31
|
+
groups[provider] = [];
|
|
32
|
+
}
|
|
33
|
+
groups[provider].push(model);
|
|
34
|
+
});
|
|
35
|
+
return groups;
|
|
36
|
+
}, [models]);
|
|
26
37
|
const toggle = (toggleRef) => /* @__PURE__ */ jsx(
|
|
27
38
|
MenuToggle,
|
|
28
39
|
{
|
|
@@ -48,7 +59,7 @@ const LightspeedChatBoxHeader = ({
|
|
|
48
59
|
shouldFocusToggleOnSelect: true,
|
|
49
60
|
shouldFocusFirstItemOnOpen: false,
|
|
50
61
|
toggle,
|
|
51
|
-
children: /* @__PURE__ */ jsx(DropdownList, { children:
|
|
62
|
+
children: /* @__PURE__ */ jsx(DropdownList, { children: Object.entries(groupedModels).map(([provider, providerModels]) => /* @__PURE__ */ jsx(DropdownGroup, { label: provider, children: providerModels.map((model) => /* @__PURE__ */ jsx(DropdownItem, { value: model.value, children: model.label }, model.value)) }, provider)) })
|
|
52
63
|
}
|
|
53
64
|
) });
|
|
54
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport { ChatbotHeaderActions } from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype LightspeedChatBoxHeaderProps = {\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string }[];\n};\n\nconst useStyles = makeStyles(() =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n handleSelectedModel,\n models,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n >\n <DropdownList>\n {
|
|
1
|
+
{"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Ref, useMemo, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport { ChatbotHeaderActions } from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownGroup,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype LightspeedChatBoxHeaderProps = {\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string; provider: string }[];\n};\n\nconst useStyles = makeStyles(() =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n handleSelectedModel,\n models,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n // Group models by provider\n const groupedModels = useMemo(() => {\n const groups: {\n [key: string]: { label: string; value: string; provider: string }[];\n } = {};\n\n models.forEach(model => {\n const provider = model.provider || 'Other';\n if (!groups[provider]) {\n groups[provider] = [];\n }\n groups[provider].push(model);\n });\n\n return groups;\n }, [models]);\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n >\n <DropdownList>\n {Object.entries(groupedModels).map(([provider, providerModels]) => (\n <DropdownGroup key={provider} label={provider}>\n {providerModels.map(model => (\n <DropdownItem value={model.value} key={model.value}>\n {model.label}\n </DropdownItem>\n ))}\n </DropdownGroup>\n ))}\n </DropdownList>\n </Dropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAqCA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,QAAU,EAAA;AAAA,MACR,YAAc,EAAA;AAAA,QACZ,OAAS,EAAA,CAAA;AAAA,QACT,MAAQ,EAAA;AAAA;AACV;AACF,GACD;AACH,CAAA;AAEO,MAAM,0BAA0B,CAAC;AAAA,EACtC,aAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAoC,KAAA;AAClC,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAAS,KAAK,CAAA;AAChE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAA,MAAM,SAAS,SAAU,EAAA;AAGzB,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,MAAM,SAEF,EAAC;AAEL,IAAA,MAAA,CAAO,QAAQ,CAAS,KAAA,KAAA;AACtB,MAAM,MAAA,QAAA,GAAW,MAAM,QAAY,IAAA,OAAA;AACnC,MAAI,IAAA,CAAC,MAAO,CAAA,QAAQ,CAAG,EAAA;AACrB,QAAO,MAAA,CAAA,QAAQ,IAAI,EAAC;AAAA;AAEtB,MAAO,MAAA,CAAA,QAAQ,CAAE,CAAA,IAAA,CAAK,KAAK,CAAA;AAAA,KAC5B,CAAA;AAED,IAAO,OAAA,MAAA;AAAA,GACT,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAM,MAAA,MAAA,GAAS,CAAC,SACd,qBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,YAAA,EAAY,EAAE,sBAAsB,CAAA;AAAA,MACpC,GAAK,EAAA,SAAA;AAAA,MACL,UAAY,EAAA,iBAAA;AAAA,MACZ,OAAS,EAAA,MAAM,oBAAqB,CAAA,CAAC,iBAAiB,CAAA;AAAA,MAErD,QAAA,EAAA;AAAA;AAAA,GACH;AAGF,EAAA,2BACG,oBACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAW,MAAO,CAAA,QAAA;AAAA,MAClB,MAAQ,EAAA,iBAAA;AAAA,MACR,QAAA,EAAU,CAAC,EAAA,EAAI,KAAU,KAAA;AACvB,QAAA,mBAAA,CAAoB,KAAe,CAAA;AACnC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,OAC5B;AAAA,MACA,YAAA,EAAc,CAAU,MAAA,KAAA,oBAAA,CAAqB,MAAM,CAAA;AAAA,MACnD,WAAA,EAAa,EAAE,QAAA,EAAU,OAAQ,EAAA;AAAA,MACjC,yBAAyB,EAAA,IAAA;AAAA,MACzB,0BAA4B,EAAA,KAAA;AAAA,MAC5B,MAAA;AAAA,MAEA,QAAC,kBAAA,GAAA,CAAA,YAAA,EAAA,EACE,QAAO,EAAA,MAAA,CAAA,OAAA,CAAQ,aAAa,CAAE,CAAA,GAAA,CAAI,CAAC,CAAC,QAAU,EAAA,cAAc,CAC3D,qBAAA,GAAA,CAAC,iBAA6B,KAAO,EAAA,QAAA,EAClC,QAAe,EAAA,cAAA,CAAA,GAAA,CAAI,CAClB,KAAA,qBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,KAAA,EAAO,MAAM,KACxB,EAAA,QAAA,EAAA,KAAA,CAAM,KAD8B,EAAA,EAAA,KAAA,CAAM,KAE7C,CACD,CALiB,EAAA,EAAA,QAMpB,CACD,CACH,EAAA;AAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -7,6 +7,7 @@ import { makeStyles, createStyles, useTheme } from '@material-ui/core/styles';
|
|
|
7
7
|
import { QueryClientProvider } from '@tanstack/react-query';
|
|
8
8
|
import { useAllModels } from '../hooks/useAllModels.esm.js';
|
|
9
9
|
import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
|
|
10
|
+
import { useTopicRestrictionStatus } from '../hooks/useQuestionValidation.esm.js';
|
|
10
11
|
import { useTranslation } from '../hooks/useTranslation.esm.js';
|
|
11
12
|
import queryClient from '../utils/queryClient.esm.js';
|
|
12
13
|
import FileAttachmentContextProvider from './AttachmentContext.esm.js';
|
|
@@ -35,8 +36,14 @@ const LightspeedPageInner = () => {
|
|
|
35
36
|
async () => await identityApi.getProfileInfo()
|
|
36
37
|
);
|
|
37
38
|
const [selectedModel, setSelectedModel] = useState("");
|
|
39
|
+
const [selectedProvider, setSelectedProvider] = useState("");
|
|
40
|
+
const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();
|
|
38
41
|
const modelsItems = useMemo(
|
|
39
|
-
() => models ? models.map((m) => ({
|
|
42
|
+
() => models ? models.map((m) => ({
|
|
43
|
+
label: m.provider_resource_id,
|
|
44
|
+
value: m.provider_resource_id,
|
|
45
|
+
provider: m.provider_id
|
|
46
|
+
})) : [],
|
|
40
47
|
[models]
|
|
41
48
|
);
|
|
42
49
|
useEffect(() => {
|
|
@@ -48,7 +55,10 @@ const LightspeedPageInner = () => {
|
|
|
48
55
|
}
|
|
49
56
|
}, [type]);
|
|
50
57
|
useEffect(() => {
|
|
51
|
-
if (modelsItems.length > 0)
|
|
58
|
+
if (modelsItems.length > 0) {
|
|
59
|
+
setSelectedModel(modelsItems[0].value);
|
|
60
|
+
setSelectedProvider(modelsItems[0].provider);
|
|
61
|
+
}
|
|
52
62
|
}, [modelsItems]);
|
|
53
63
|
if (loading) {
|
|
54
64
|
return null;
|
|
@@ -66,8 +76,13 @@ const LightspeedPageInner = () => {
|
|
|
66
76
|
LightspeedChat,
|
|
67
77
|
{
|
|
68
78
|
selectedModel,
|
|
79
|
+
selectedProvider,
|
|
80
|
+
topicRestrictionEnabled: topicRestrictionEnabled ?? false,
|
|
69
81
|
handleSelectedModel: (item) => {
|
|
70
82
|
setSelectedModel(item);
|
|
83
|
+
setSelectedProvider(
|
|
84
|
+
modelsItems.find((m) => m.value === item)?.provider || ""
|
|
85
|
+
);
|
|
71
86
|
},
|
|
72
87
|
models: modelsItems,
|
|
73
88
|
userName: profile?.displayName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Header, Page } from '@backstage/core-components';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTranslation } from '../hooks/useTranslation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\n\nconst LightspeedPageInner = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n\n const modelsItems = useMemo(\n ()
|
|
1
|
+
{"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Header, Page } from '@backstage/core-components';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTopicRestrictionStatus } from '../hooks/useQuestionValidation';\nimport { useTranslation } from '../hooks/useTranslation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\n\nconst LightspeedPageInner = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n const [selectedProvider, setSelectedProvider] = useState('');\n\n const { data: topicRestrictionEnabled } = useTopicRestrictionStatus();\n\n const modelsItems = useMemo(\n () =>\n models\n ? models.map(m => ({\n label: m.provider_resource_id,\n value: m.provider_resource_id,\n provider: m.provider_id,\n }))\n : [],\n [models],\n );\n\n useEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [type]);\n\n useEffect(() => {\n if (modelsItems.length > 0) {\n setSelectedModel(modelsItems[0].value);\n setSelectedProvider(modelsItems[0].provider);\n }\n }, [modelsItems]);\n\n if (loading) {\n return null;\n }\n\n return (\n <Page themeId=\"tool\">\n <Header\n title={t('page.title')}\n style={{ display: 'none' }}\n pageTitleOverride={t('page.title')}\n />\n <Content className={classes.container}>\n {!hasViewAccess ? (\n <PermissionRequiredState />\n ) : (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n selectedProvider={selectedProvider}\n topicRestrictionEnabled={topicRestrictionEnabled ?? false}\n handleSelectedModel={item => {\n setSelectedModel(item);\n setSelectedProvider(\n modelsItems.find((m: any) => m.value === item)?.provider ||\n '',\n );\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n )}\n </Content>\n </Page>\n );\n};\n\nexport const LightspeedPage = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedPageInner />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/const.esm.js
CHANGED
|
@@ -39,6 +39,9 @@ const RHDH_SAMPLE_PROMPTS = [
|
|
|
39
39
|
createPrompt("prompts.openshift.title", "prompts.openshift.message"),
|
|
40
40
|
createPrompt("prompts.rhdh.title", "prompts.rhdh.message")
|
|
41
41
|
];
|
|
42
|
+
const VALID_TOPIC_RESTRICTION_PROVIDER_IDS = [
|
|
43
|
+
"lightspeed_question_validity-shield"
|
|
44
|
+
];
|
|
42
45
|
|
|
43
|
-
export { DEFAULT_SAMPLE_PROMPTS, RHDH_SAMPLE_PROMPTS, TEMP_CONVERSATION_ID, supportedFileTypes };
|
|
46
|
+
export { DEFAULT_SAMPLE_PROMPTS, RHDH_SAMPLE_PROMPTS, TEMP_CONVERSATION_ID, VALID_TOPIC_RESTRICTION_PROVIDER_IDS, supportedFileTypes };
|
|
44
47
|
//# sourceMappingURL=const.esm.js.map
|
package/dist/const.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.esm.js","sources":["../src/const.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"const.esm.js","sources":["../src/const.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 { SamplePrompts } from './types';\n\nexport const TEMP_CONVERSATION_ID = 'temp-conversation-id';\n\n// Translation keys for disclaimers\nexport const FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION_KEY =\n 'disclaimer.withoutValidation';\nexport const FUNCTION_DISCLAIMER_KEY = 'disclaimer.withValidation';\n\nconst createPrompt = (titleKey: string, messageKey: string) => {\n return { titleKey, messageKey };\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 'prompts.codeReadability.title',\n 'prompts.codeReadability.message',\n ),\n createPrompt('prompts.debugging.title', 'prompts.debugging.message'),\n createPrompt(\n 'prompts.developmentConcept.title',\n 'prompts.developmentConcept.message',\n ),\n createPrompt(\n 'prompts.codeOptimization.title',\n 'prompts.codeOptimization.message',\n ),\n createPrompt('prompts.documentation.title', 'prompts.documentation.message'),\n createPrompt('prompts.gitWorkflows.title', 'prompts.gitWorkflows.message'),\n createPrompt(\n 'prompts.testingStrategies.title',\n 'prompts.testingStrategies.message',\n ),\n createPrompt(\n 'prompts.sortingAlgorithms.title',\n 'prompts.sortingAlgorithms.message',\n ),\n createPrompt('prompts.eventDriven.title', 'prompts.eventDriven.message'),\n];\n\nexport const RHDH_SAMPLE_PROMPTS: SamplePrompts = [\n createPrompt('prompts.tekton.title', 'prompts.tekton.message'),\n createPrompt('prompts.openshift.title', 'prompts.openshift.message'),\n createPrompt('prompts.rhdh.title', 'prompts.rhdh.message'),\n];\n\n// Topic restriction valid provider IDs\nexport const VALID_TOPIC_RESTRICTION_PROVIDER_IDS = [\n 'lightspeed_question_validity-shield',\n];\n"],"names":[],"mappings":"AAkBO,MAAM,oBAAuB,GAAA;AAOpC,MAAM,YAAA,GAAe,CAAC,QAAA,EAAkB,UAAuB,KAAA;AAC7D,EAAO,OAAA,EAAE,UAAU,UAAW,EAAA;AAChC,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,+BAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA,CAAa,2BAA2B,2BAA2B,CAAA;AAAA,EACnE,YAAA;AAAA,IACE,kCAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,gCAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA,CAAa,+BAA+B,+BAA+B,CAAA;AAAA,EAC3E,YAAA,CAAa,8BAA8B,8BAA8B,CAAA;AAAA,EACzE,YAAA;AAAA,IACE,iCAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA;AAAA,IACE,iCAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA,CAAa,6BAA6B,6BAA6B;AACzE;AAEO,MAAM,mBAAqC,GAAA;AAAA,EAChD,YAAA,CAAa,wBAAwB,wBAAwB,CAAA;AAAA,EAC7D,YAAA,CAAa,2BAA2B,2BAA2B,CAAA;AAAA,EACnE,YAAA,CAAa,sBAAsB,sBAAsB;AAC3D;AAGO,MAAM,oCAAuC,GAAA;AAAA,EAClD;AACF;;;;"}
|
|
@@ -5,7 +5,7 @@ import { lightspeedApiRef } from '../api/api.esm.js';
|
|
|
5
5
|
import { TEMP_CONVERSATION_ID } from '../const.esm.js';
|
|
6
6
|
import botAvatar from '../images/bot-avatar.svg';
|
|
7
7
|
import userAvatar from '../images/user-avatar.svg';
|
|
8
|
-
import {
|
|
8
|
+
import { getConversationsData, createUserMessage, createBotMessage, transformDocumentsToSources, getTimestamp } from '../utils/lightspeed-chatbox-utils.esm.js';
|
|
9
9
|
import { useCreateConversationMessage } from './useCreateCoversationMessage.esm.js';
|
|
10
10
|
|
|
11
11
|
const useFetchConversationMessages = (currentConversation) => {
|
|
@@ -19,7 +19,7 @@ const useFetchConversationMessages = (currentConversation) => {
|
|
|
19
19
|
retry: false
|
|
20
20
|
});
|
|
21
21
|
};
|
|
22
|
-
const useConversationMessages = (conversationId, userName, selectedModel, avatar = userAvatar, onComplete, onStart) => {
|
|
22
|
+
const useConversationMessages = (conversationId, userName, selectedModel, selectedProvider, avatar = userAvatar, onComplete, onStart) => {
|
|
23
23
|
const { mutateAsync: createMessage } = useCreateConversationMessage();
|
|
24
24
|
const scrollToBottomRef = React.useRef(null);
|
|
25
25
|
const [currentConversation, setCurrentConversation] = React.useState(conversationId);
|
|
@@ -49,31 +49,27 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
49
49
|
const _conversations = {
|
|
50
50
|
[currentConversation]: []
|
|
51
51
|
};
|
|
52
|
-
for (let i = 0; i < conversationsData.length; i
|
|
53
|
-
const userMessage =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const {
|
|
57
|
-
model,
|
|
58
|
-
content: botMessage,
|
|
59
|
-
timestamp: botTimestamp,
|
|
60
|
-
referencedDocuments
|
|
61
|
-
} = getMessageData(aiMessage);
|
|
52
|
+
for (let i = 0; i < conversationsData.length; i++) {
|
|
53
|
+
const [userMessage, aiMessage] = getConversationsData(
|
|
54
|
+
conversationsData[i]
|
|
55
|
+
);
|
|
62
56
|
_conversations[currentConversation].push(
|
|
63
57
|
...[
|
|
64
58
|
createUserMessage({
|
|
65
59
|
avatar,
|
|
66
60
|
name: userName,
|
|
67
|
-
content:
|
|
68
|
-
timestamp:
|
|
61
|
+
content: userMessage.content,
|
|
62
|
+
timestamp: userMessage.timestamp
|
|
69
63
|
}),
|
|
70
64
|
createBotMessage({
|
|
71
65
|
avatar: botAvatar,
|
|
72
66
|
isLoading: false,
|
|
73
|
-
name: model ?? selectedModel,
|
|
74
|
-
content:
|
|
75
|
-
timestamp:
|
|
76
|
-
sources: transformDocumentsToSources(
|
|
67
|
+
name: conversationsData[i].model ?? selectedModel,
|
|
68
|
+
content: aiMessage.content,
|
|
69
|
+
timestamp: aiMessage.timestamp,
|
|
70
|
+
sources: transformDocumentsToSources(
|
|
71
|
+
aiMessage?.referencedDocuments ?? []
|
|
72
|
+
)
|
|
77
73
|
})
|
|
78
74
|
]
|
|
79
75
|
);
|
|
@@ -133,6 +129,7 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
133
129
|
const reader = await createMessage({
|
|
134
130
|
prompt,
|
|
135
131
|
selectedModel,
|
|
132
|
+
selectedProvider,
|
|
136
133
|
currentConversation,
|
|
137
134
|
attachments
|
|
138
135
|
});
|
|
@@ -154,7 +151,7 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
154
151
|
newConversationId = data?.conversation_id;
|
|
155
152
|
}
|
|
156
153
|
}
|
|
157
|
-
if (event === "token") {
|
|
154
|
+
if (event === "token" && data?.role === "inference") {
|
|
158
155
|
const content = data?.token || "";
|
|
159
156
|
finalMessages.push(content);
|
|
160
157
|
const [humanMessage, aiMessage] = streamingConversations.current[currentConversation];
|
|
@@ -169,10 +166,13 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
169
166
|
content: "",
|
|
170
167
|
timestamp: getTimestamp(Date.now())
|
|
171
168
|
}) : { ...conversation[lastMessageIndex] };
|
|
172
|
-
lastMessage.
|
|
169
|
+
if ((lastMessage?.content ?? "").trim().length > 0) {
|
|
170
|
+
lastMessage.isLoading = false;
|
|
171
|
+
}
|
|
173
172
|
lastMessage.content += content;
|
|
174
173
|
lastMessage.name = data?.response_metadata?.model || selectedModel;
|
|
175
174
|
lastMessage.timestamp = getTimestamp(
|
|
175
|
+
// TODO: To be fixed in the query response
|
|
176
176
|
data?.response_metadata?.created_at || Date.now()
|
|
177
177
|
);
|
|
178
178
|
const updatedConversation = [
|
|
@@ -192,8 +192,9 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
192
192
|
const lastMessageIndex = conversation.length - 1;
|
|
193
193
|
const lastMessage = conversation.length === 0 ? createBotMessage({
|
|
194
194
|
content: "",
|
|
195
|
+
isLoading: false,
|
|
195
196
|
timestamp: getTimestamp(Date.now())
|
|
196
|
-
}) : { ...conversation[lastMessageIndex] };
|
|
197
|
+
}) : { ...conversation[lastMessageIndex], isLoading: false };
|
|
197
198
|
if (documents.length) {
|
|
198
199
|
lastMessage.sources = {
|
|
199
200
|
sources: documents.map((doc) => ({
|
|
@@ -270,6 +271,7 @@ const useConversationMessages = (conversationId, userName, selectedModel, avatar
|
|
|
270
271
|
onComplete,
|
|
271
272
|
onStart,
|
|
272
273
|
selectedModel,
|
|
274
|
+
selectedProvider,
|
|
273
275
|
createMessage,
|
|
274
276
|
currentConversation
|
|
275
277
|
]
|
|
@@ -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 botAvatar from '../images/bot-avatar.svg';\nimport userAvatar from '../images/user-avatar.svg';\nimport { Attachment, ReferencedDocument } from '../types';\nimport {\n createBotMessage,\n createUserMessage,\n getMessageData,\n getTimestamp,\n transformDocumentsToSources,\n} from '../utils/lightspeed-chatbox-utils';\nimport { useCreateConversationMessage } from './useCreateCoversationMessage';\n\n// Fetch all conversation messages\nexport const useFetchConversationMessages = (currentConversation: string) => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['conversationMessages', currentConversation],\n queryFn: currentConversation\n ? async () => {\n const response =\n await lightspeedApi.getConversationMessages(currentConversation);\n\n return response;\n }\n : undefined,\n retry: false,\n });\n};\n\ntype Conversations = { [_key: string]: MessageProps[] };\n\n/**\n * Fetches all the messages for given conversation_id\n * @param conversationId\n * @param userName\n * @param selectedModel\n * @param avatar\n *\n */\nexport const useConversationMessages = (\n conversationId: string,\n userName: string | undefined,\n selectedModel: string,\n avatar: string = userAvatar,\n onComplete?: (message: string) => void,\n onStart?: (conversation_id: string) => void,\n) => {\n const { mutateAsync: createMessage } = useCreateConversationMessage();\n const scrollToBottomRef = React.useRef<ScrollContainerHandle>(null);\n\n const [currentConversation, setCurrentConversation] =\n React.useState(conversationId);\n const [conversations, setConversations] = React.useState<Conversations>({\n [currentConversation]: [],\n });\n const streamingConversations = React.useRef<Conversations>({\n [currentConversation]: [],\n });\n\n React.useEffect(() => {\n if (currentConversation !== conversationId) {\n setCurrentConversation(conversationId);\n setConversations(prev => {\n if (prev[conversationId]) return prev;\n\n return {\n ...prev,\n [conversationId]: [],\n };\n });\n }\n }, [currentConversation, conversationId]);\n\n const { data: conversationsData = [], ...queryProps } =\n useFetchConversationMessages(currentConversation);\n\n React.useEffect(() => {\n if (\n !Array.isArray(conversationsData) ||\n (conversationsData.length === 0 &&\n conversationId !== TEMP_CONVERSATION_ID)\n )\n return;\n\n const newConvoIndex: number[] = [];\n\n if (conversations) {\n const _conversations: { [key: string]: any[] } = {\n [currentConversation]: [],\n };\n\n let index = 0;\n for (let i = 0; i < conversationsData.length; i += 2) {\n const userMessage = conversationsData[i];\n const aiMessage = conversationsData[i + 1];\n\n const { content: humanMessage, timestamp: userTimestamp } =\n getMessageData(userMessage);\n const {\n model,\n content: botMessage,\n timestamp: botTimestamp,\n referencedDocuments,\n } = getMessageData(aiMessage);\n\n _conversations[currentConversation].push(\n ...[\n createUserMessage({\n avatar,\n name: userName,\n content: humanMessage,\n timestamp: userTimestamp,\n }),\n createBotMessage({\n avatar: botAvatar,\n isLoading: false,\n name: model ?? selectedModel,\n content: botMessage,\n timestamp: botTimestamp,\n sources: transformDocumentsToSources(referencedDocuments),\n }),\n ],\n );\n\n newConvoIndex.push(index);\n index++;\n }\n\n if (streamingConversations.current[currentConversation]) {\n _conversations[currentConversation].push(\n ...streamingConversations.current[currentConversation],\n );\n }\n\n setConversations(_conversations);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n conversationsData,\n userName,\n avatar,\n currentConversation,\n selectedModel,\n streamingConversations,\n ]);\n\n const handleInputPrompt = React.useCallback(\n async (prompt: string, attachments: Attachment[] = []) => {\n let newConversationId = '';\n\n const conversationTuple = [\n createUserMessage({\n avatar,\n name: userName,\n content: prompt,\n timestamp: getTimestamp(Date.now()) ?? '',\n }),\n createBotMessage({\n avatar: botAvatar,\n isLoading: true,\n name: selectedModel,\n content: '',\n timestamp: '',\n }),\n ];\n\n streamingConversations.current = {\n ...streamingConversations.current,\n [currentConversation]: conversationTuple,\n };\n\n setConversations((prevConv: Conversations) => {\n return {\n ...prevConv,\n [currentConversation]: [\n ...(prevConv?.[currentConversation] ?? []),\n ...conversationTuple,\n ],\n };\n });\n\n setTimeout(() => {\n scrollToBottomRef.current?.scrollToBottom();\n }, 0);\n const finalMessages: string[] = [];\n let buffer = '';\n\n try {\n const reader = await createMessage({\n prompt,\n selectedModel,\n currentConversation,\n attachments,\n });\n\n const decoder = new TextDecoder('utf-8');\n const keepGoing = true;\n\n while (keepGoing) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process all complete messages separated by double newlines\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop()!;\n\n for (const part of parts) {\n const lines = part\n .split('\\n')\n .filter(line => line.startsWith('data:'));\n\n const jsonString = lines\n .map(line => line.trim().slice(5).trim())\n .join('');\n try {\n const { event, data } = JSON.parse(jsonString);\n if (event === 'start') {\n if (currentConversation === TEMP_CONVERSATION_ID) {\n // If the conversation is temp, we need to set the new conversation id\n newConversationId = data?.conversation_id;\n }\n }\n\n if (event === 'token') {\n const content = data?.token || '';\n\n finalMessages.push(content);\n\n // Store streaming message\n const [humanMessage, aiMessage] =\n streamingConversations.current[currentConversation];\n streamingConversations.current[currentConversation] = [\n humanMessage,\n { ...aiMessage, content: aiMessage.content + content },\n ];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n lastMessage.isLoading = false;\n lastMessage.content += content;\n lastMessage.name =\n data?.response_metadata?.model || selectedModel;\n lastMessage.timestamp = getTimestamp(\n data?.response_metadata?.created_at || Date.now(),\n );\n\n const updatedConversation = [\n ...conversation.slice(0, lastMessageIndex),\n lastMessage,\n ];\n\n return {\n ...prevConversations,\n [currentConversation]: updatedConversation,\n };\n });\n }\n\n if (event === 'end') {\n const documents = data?.referenced_documents || [];\n\n setConversations(prevConversations => {\n const conversation =\n prevConversations[currentConversation] ?? [];\n\n const lastMessageIndex = conversation.length - 1;\n const lastMessage =\n conversation.length === 0\n ? createBotMessage({\n content: '',\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex] };\n\n if (documents.length) {\n lastMessage.sources = {\n sources: documents.map((doc: ReferencedDocument) => ({\n title: doc.doc_title,\n link: doc.doc_url,\n body: doc.doc_description,\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":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useConversationMessages.esm.js","sources":["../../src/hooks/useConversationMessages.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { MessageProps } from '@patternfly/chatbot';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { ScrollContainerHandle } from '../components/LightspeedChatBox';\nimport { TEMP_CONVERSATION_ID } from '../const';\nimport botAvatar from '../images/bot-avatar.svg';\nimport userAvatar from '../images/user-avatar.svg';\nimport { Attachment, LCSConversation, ReferencedDocument } from '../types';\nimport {\n createBotMessage,\n createUserMessage,\n getConversationsData,\n getTimestamp,\n transformDocumentsToSources,\n} from '../utils/lightspeed-chatbox-utils';\nimport { useCreateConversationMessage } from './useCreateCoversationMessage';\n\n// Fetch all conversation messages\nexport const useFetchConversationMessages = (currentConversation: string) => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['conversationMessages', currentConversation],\n queryFn: currentConversation\n ? async () => {\n const response =\n await lightspeedApi.getConversationMessages(currentConversation);\n\n return response;\n }\n : undefined,\n retry: false,\n });\n};\n\ntype Conversations = { [_key: string]: MessageProps[] };\n\n/**\n * Fetches all the messages for given conversation_id\n * @param conversationId\n * @param userName\n * @param selectedModel\n * @param selectedProvider\n * @param avatar\n *\n */\nexport const useConversationMessages = (\n conversationId: string,\n userName: string | undefined,\n selectedModel: string,\n selectedProvider: string,\n avatar: string = userAvatar,\n onComplete?: (message: string) => void,\n onStart?: (conversation_id: string) => void,\n) => {\n const { mutateAsync: createMessage } = useCreateConversationMessage();\n const scrollToBottomRef = React.useRef<ScrollContainerHandle>(null);\n\n const [currentConversation, setCurrentConversation] =\n React.useState(conversationId);\n const [conversations, setConversations] = React.useState<Conversations>({\n [currentConversation]: [],\n });\n const streamingConversations = React.useRef<Conversations>({\n [currentConversation]: [],\n });\n\n React.useEffect(() => {\n if (currentConversation !== conversationId) {\n setCurrentConversation(conversationId);\n setConversations(prev => {\n if (prev[conversationId]) return prev;\n\n return {\n ...prev,\n [conversationId]: [],\n };\n });\n }\n }, [currentConversation, conversationId]);\n\n const { data: conversationsData = [], ...queryProps } =\n useFetchConversationMessages(currentConversation);\n\n React.useEffect(() => {\n if (\n !Array.isArray(conversationsData) ||\n (conversationsData.length === 0 &&\n conversationId !== TEMP_CONVERSATION_ID)\n )\n return;\n\n const newConvoIndex: number[] = [];\n\n if (conversations) {\n const _conversations: { [key: string]: any[] } = {\n [currentConversation]: [],\n };\n\n let index = 0;\n for (let i = 0; i < conversationsData.length; i++) {\n const [userMessage, aiMessage] = getConversationsData(\n conversationsData[i] as unknown as LCSConversation,\n );\n\n _conversations[currentConversation].push(\n ...[\n createUserMessage({\n avatar,\n name: userName,\n content: userMessage.content,\n timestamp: userMessage.timestamp,\n }),\n createBotMessage({\n avatar: botAvatar,\n isLoading: false,\n name: conversationsData[i].model ?? selectedModel,\n content: aiMessage.content,\n timestamp: aiMessage.timestamp,\n sources: transformDocumentsToSources(\n aiMessage?.referencedDocuments ?? [],\n ),\n }),\n ],\n );\n\n newConvoIndex.push(index);\n index++;\n }\n\n if (streamingConversations.current[currentConversation]) {\n _conversations[currentConversation].push(\n ...streamingConversations.current[currentConversation],\n );\n }\n\n setConversations(_conversations);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n conversationsData,\n userName,\n avatar,\n currentConversation,\n selectedModel,\n streamingConversations,\n ]);\n\n const handleInputPrompt = React.useCallback(\n async (prompt: string, attachments: Attachment[] = []) => {\n let newConversationId = '';\n\n const conversationTuple = [\n createUserMessage({\n avatar,\n name: userName,\n content: prompt,\n timestamp: getTimestamp(Date.now()) ?? '',\n }),\n createBotMessage({\n avatar: botAvatar,\n isLoading: true,\n name: selectedModel,\n content: '',\n timestamp: '',\n }),\n ];\n\n streamingConversations.current = {\n ...streamingConversations.current,\n [currentConversation]: conversationTuple,\n };\n\n setConversations((prevConv: Conversations) => {\n return {\n ...prevConv,\n [currentConversation]: [\n ...(prevConv?.[currentConversation] ?? []),\n ...conversationTuple,\n ],\n };\n });\n\n setTimeout(() => {\n scrollToBottomRef.current?.scrollToBottom();\n }, 0);\n const finalMessages: string[] = [];\n let buffer = '';\n\n try {\n const reader = await createMessage({\n prompt,\n selectedModel,\n selectedProvider,\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' && data?.role === 'inference') {\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 if ((lastMessage?.content ?? '').trim().length > 0) {\n lastMessage.isLoading = false;\n }\n lastMessage.content += content;\n lastMessage.name =\n data?.response_metadata?.model || selectedModel;\n lastMessage.timestamp = getTimestamp(\n // TODO: To be fixed in the query response\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 isLoading: false,\n timestamp: getTimestamp(Date.now()),\n })\n : { ...conversation[lastMessageIndex], isLoading: false };\n\n if (documents.length) {\n lastMessage.sources = {\n sources: documents.map((doc: ReferencedDocument) => ({\n title: doc.doc_title,\n link: doc.doc_url,\n body: doc.doc_description,\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 selectedProvider,\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":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ const useCreateConversationMessage = () => {
|
|
|
8
8
|
mutationFn: async ({
|
|
9
9
|
prompt,
|
|
10
10
|
selectedModel,
|
|
11
|
+
selectedProvider,
|
|
11
12
|
currentConversation,
|
|
12
13
|
attachments
|
|
13
14
|
}) => {
|
|
@@ -17,6 +18,7 @@ const useCreateConversationMessage = () => {
|
|
|
17
18
|
return await lightspeedApi.createMessage(
|
|
18
19
|
`${prompt}`,
|
|
19
20
|
selectedModel,
|
|
21
|
+
selectedProvider,
|
|
20
22
|
currentConversation,
|
|
21
23
|
attachments
|
|
22
24
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCreateCoversationMessage.esm.js","sources":["../../src/hooks/useCreateCoversationMessage.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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useMutation } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { Attachment } from '../types';\n\nexport const useCreateConversationMessage = () => {\n const lightspeedApi = useApi(lightspeedApiRef);\n\n return useMutation({\n mutationFn: async ({\n prompt,\n selectedModel,\n currentConversation,\n attachments,\n }: {\n prompt: string;\n selectedModel: string;\n currentConversation: string;\n attachments: Attachment[];\n }) => {\n if (!currentConversation) {\n throw new Error('Failed to generate AI response');\n }\n\n return await lightspeedApi.createMessage(\n `${prompt}`,\n selectedModel,\n currentConversation,\n attachments,\n );\n },\n onError: error => {\n // eslint-disable-next-line\n console.warn(error);\n },\n });\n};\n"],"names":[],"mappings":";;;;AAuBO,MAAM,+BAA+B,MAAM;AAChD,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAE7C,EAAA,OAAO,WAAY,CAAA;AAAA,IACjB,YAAY,OAAO;AAAA,MACjB,MAAA;AAAA,MACA,aAAA;AAAA,MACA,mBAAA;AAAA,MACA;AAAA,
|
|
1
|
+
{"version":3,"file":"useCreateCoversationMessage.esm.js","sources":["../../src/hooks/useCreateCoversationMessage.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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useMutation } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { Attachment } from '../types';\n\nexport const useCreateConversationMessage = () => {\n const lightspeedApi = useApi(lightspeedApiRef);\n\n return useMutation({\n mutationFn: async ({\n prompt,\n selectedModel,\n selectedProvider,\n currentConversation,\n attachments,\n }: {\n prompt: string;\n selectedModel: string;\n selectedProvider: string;\n currentConversation: string;\n attachments: Attachment[];\n }) => {\n if (!currentConversation) {\n throw new Error('Failed to generate AI response');\n }\n\n return await lightspeedApi.createMessage(\n `${prompt}`,\n selectedModel,\n selectedProvider,\n currentConversation,\n attachments,\n );\n },\n onError: error => {\n // eslint-disable-next-line\n console.warn(error);\n },\n });\n};\n"],"names":[],"mappings":";;;;AAuBO,MAAM,+BAA+B,MAAM;AAChD,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAE7C,EAAA,OAAO,WAAY,CAAA;AAAA,IACjB,YAAY,OAAO;AAAA,MACjB,MAAA;AAAA,MACA,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,mBAAA;AAAA,MACA;AAAA,KAOI,KAAA;AACJ,MAAA,IAAI,CAAC,mBAAqB,EAAA;AACxB,QAAM,MAAA,IAAI,MAAM,gCAAgC,CAAA;AAAA;AAGlD,MAAA,OAAO,MAAM,aAAc,CAAA,aAAA;AAAA,QACzB,GAAG,MAAM,CAAA,CAAA;AAAA,QACT,aAAA;AAAA,QACA,gBAAA;AAAA,QACA,mBAAA;AAAA,QACA;AAAA,OACF;AAAA,KACF;AAAA,IACA,SAAS,CAAS,KAAA,KAAA;AAEhB,MAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA;AACpB,GACD,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
import { lightspeedApiRef } from '../api/api.esm.js';
|
|
4
|
+
|
|
5
|
+
const useTopicRestrictionStatus = () => {
|
|
6
|
+
const lightspeedApi = useApi(lightspeedApiRef);
|
|
7
|
+
return useQuery({
|
|
8
|
+
queryKey: ["topicRestrictionStatus"],
|
|
9
|
+
queryFn: async () => {
|
|
10
|
+
return await lightspeedApi.isTopicRestrictionEnabled();
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { useTopicRestrictionStatus };
|
|
16
|
+
//# sourceMappingURL=useQuestionValidation.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQuestionValidation.esm.js","sources":["../../src/hooks/useQuestionValidation.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 { useApi } from '@backstage/core-plugin-api';\n\nimport { useQuery } from '@tanstack/react-query';\n\nimport { lightspeedApiRef } from '../api/api';\n\nexport const useTopicRestrictionStatus = () => {\n const lightspeedApi = useApi(lightspeedApiRef);\n return useQuery({\n queryKey: ['topicRestrictionStatus'],\n queryFn: async () => {\n return await lightspeedApi.isTopicRestrictionEnabled();\n },\n });\n};\n"],"names":[],"mappings":";;;;AAsBO,MAAM,4BAA4B,MAAM;AAC7C,EAAM,MAAA,aAAA,GAAgB,OAAO,gBAAgB,CAAA;AAC7C,EAAA,OAAO,QAAS,CAAA;AAAA,IACd,QAAA,EAAU,CAAC,wBAAwB,CAAA;AAAA,IACnC,SAAS,YAAY;AACnB,MAAO,OAAA,MAAM,cAAc,yBAA0B,EAAA;AAAA;AACvD,GACD,CAAA;AACH;;;;"}
|
|
@@ -2,13 +2,14 @@ import React from 'react';
|
|
|
2
2
|
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
3
3
|
import { RHDH_SAMPLE_PROMPTS, DEFAULT_SAMPLE_PROMPTS } from '../const.esm.js';
|
|
4
4
|
import { getRandomSamplePrompts } from '../utils/prompt-utils.esm.js';
|
|
5
|
+
import { useTopicRestrictionStatus } from './useQuestionValidation.esm.js';
|
|
5
6
|
import { useTranslation } from './useTranslation.esm.js';
|
|
6
7
|
|
|
7
8
|
const useWelcomePrompts = () => {
|
|
8
9
|
const configApi = useApi(configApiRef);
|
|
9
10
|
const { t } = useTranslation();
|
|
11
|
+
const { data: questionValidationEnabled } = useTopicRestrictionStatus();
|
|
10
12
|
return React.useMemo(() => {
|
|
11
|
-
const questionValidationEnabled = configApi.getOptionalBoolean("lightspeed.questionValidation") ?? true;
|
|
12
13
|
const translatePrompts = (prompts) => {
|
|
13
14
|
return prompts.map((prompt) => {
|
|
14
15
|
if ("titleKey" in prompt && "messageKey" in prompt) {
|
|
@@ -28,7 +29,7 @@ const useWelcomePrompts = () => {
|
|
|
28
29
|
message: config.getString("message") ?? ""
|
|
29
30
|
}));
|
|
30
31
|
return getRandomSamplePrompts(userConfiguredPrompts, DEFAULT_PROMPTS);
|
|
31
|
-
}, [configApi, t]);
|
|
32
|
+
}, [configApi, t, questionValidationEnabled]);
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export { useWelcomePrompts };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWelcomePrompts.esm.js","sources":["../../src/hooks/useWelcomePrompts.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 React from 'react';\n\nimport { ConfigApi, configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { DEFAULT_SAMPLE_PROMPTS, RHDH_SAMPLE_PROMPTS } from '../const';\nimport { SamplePrompt, SamplePrompts } from '../types';\nimport { getRandomSamplePrompts } from '../utils/prompt-utils';\nimport { useTranslation } from './useTranslation';\n\nexport const useWelcomePrompts = (): SamplePrompts => {\n const configApi: ConfigApi = useApi(configApiRef);\n const { t } = useTranslation();\n\n return React.useMemo(() => {\n
|
|
1
|
+
{"version":3,"file":"useWelcomePrompts.esm.js","sources":["../../src/hooks/useWelcomePrompts.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 React from 'react';\n\nimport { ConfigApi, configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { DEFAULT_SAMPLE_PROMPTS, RHDH_SAMPLE_PROMPTS } from '../const';\nimport { SamplePrompt, SamplePrompts } from '../types';\nimport { getRandomSamplePrompts } from '../utils/prompt-utils';\nimport { useTopicRestrictionStatus } from './useQuestionValidation';\nimport { useTranslation } from './useTranslation';\n\nexport const useWelcomePrompts = (): SamplePrompts => {\n const configApi: ConfigApi = useApi(configApiRef);\n const { t } = useTranslation();\n const { data: questionValidationEnabled } = useTopicRestrictionStatus();\n\n return React.useMemo(() => {\n // Transform translation keys to actual prompts\n const translatePrompts = (prompts: SamplePrompts): SamplePrompts => {\n return prompts.map((prompt: SamplePrompt) => {\n if ('titleKey' in prompt && 'messageKey' in prompt) {\n return {\n title: t(prompt.titleKey as any, { defaultValue: prompt.titleKey }),\n message: t(prompt.messageKey as any, {\n defaultValue: prompt.messageKey,\n }),\n };\n }\n return prompt as { title: string; message: string };\n });\n };\n\n const DEFAULT_PROMPTS = questionValidationEnabled\n ? translatePrompts(RHDH_SAMPLE_PROMPTS)\n : translatePrompts([...DEFAULT_SAMPLE_PROMPTS, ...RHDH_SAMPLE_PROMPTS]);\n\n const userConfiguredPrompts: SamplePrompts = (\n configApi?.getOptionalConfigArray('lightspeed.prompts') ?? []\n ).map(config => ({\n title: config.getString('title') ?? '',\n message: config.getString('message') ?? '',\n }));\n return getRandomSamplePrompts(userConfiguredPrompts, DEFAULT_PROMPTS);\n }, [configApi, t, questionValidationEnabled]);\n};\n"],"names":[],"mappings":";;;;;;;AAyBO,MAAM,oBAAoB,MAAqB;AACpD,EAAM,MAAA,SAAA,GAAuB,OAAO,YAAY,CAAA;AAChD,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,EAAE,IAAA,EAAM,yBAA0B,EAAA,GAAI,yBAA0B,EAAA;AAEtE,EAAO,OAAA,KAAA,CAAM,QAAQ,MAAM;AAEzB,IAAM,MAAA,gBAAA,GAAmB,CAAC,OAA0C,KAAA;AAClE,MAAO,OAAA,OAAA,CAAQ,GAAI,CAAA,CAAC,MAAyB,KAAA;AAC3C,QAAI,IAAA,UAAA,IAAc,MAAU,IAAA,YAAA,IAAgB,MAAQ,EAAA;AAClD,UAAO,OAAA;AAAA,YACL,KAAA,EAAO,EAAE,MAAO,CAAA,QAAA,EAAiB,EAAE,YAAc,EAAA,MAAA,CAAO,UAAU,CAAA;AAAA,YAClE,OAAA,EAAS,CAAE,CAAA,MAAA,CAAO,UAAmB,EAAA;AAAA,cACnC,cAAc,MAAO,CAAA;AAAA,aACtB;AAAA,WACH;AAAA;AAEF,QAAO,OAAA,MAAA;AAAA,OACR,CAAA;AAAA,KACH;AAEA,IAAM,MAAA,eAAA,GAAkB,yBACpB,GAAA,gBAAA,CAAiB,mBAAmB,CAAA,GACpC,gBAAiB,CAAA,CAAC,GAAG,sBAAA,EAAwB,GAAG,mBAAmB,CAAC,CAAA;AAExE,IAAM,MAAA,qBAAA,GAAA,CACJ,WAAW,sBAAuB,CAAA,oBAAoB,KAAK,EAAC,EAC5D,IAAI,CAAW,MAAA,MAAA;AAAA,MACf,KAAO,EAAA,MAAA,CAAO,SAAU,CAAA,OAAO,CAAK,IAAA,EAAA;AAAA,MACpC,OAAS,EAAA,MAAA,CAAO,SAAU,CAAA,SAAS,CAAK,IAAA;AAAA,KACxC,CAAA,CAAA;AACF,IAAO,OAAA,sBAAA,CAAuB,uBAAuB,eAAe,CAAA;AAAA,GACnE,EAAA,CAAC,SAAW,EAAA,CAAA,EAAG,yBAAyB,CAAC,CAAA;AAC9C;;;;"}
|
package/dist/types.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SourcesCardProps } from '@patternfly/chatbot';\nimport { AlertProps } from '@patternfly/react-core';\n\nexport type Conversations = {\n [key: string]: {\n user: string;\n bot: string;\n model: string;\n loading: boolean;\n timestamp: string;\n botTimestamp: string;\n error?: AlertProps;\n };\n};\n\nexport type ReferencedDocument = {\n doc_title: string;\n doc_url: string;\n doc_description?: string;\n};\n\nexport type ReferencedDocuments = ReferencedDocument[];\nexport interface
|
|
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 ReferencedDocument = {\n doc_title: string;\n doc_url: string;\n doc_description?: string;\n};\n\nexport type ReferencedDocuments = ReferencedDocument[];\n\nexport type LCSModelType = 'embedding' | 'llm';\nexport type LCSModelApiModelType = 'embedding' | 'llm';\n\nexport interface LCSModel {\n identifier: string;\n metadata: {\n embedding_dimension: number;\n };\n api_model_type: LCSModelApiModelType;\n provider_id: string;\n type: 'model';\n provider_resource_id: string;\n model_type: LCSModelType;\n}\nexport interface LCSConversation {\n provider: string;\n model: string;\n messages: BaseMessage[];\n started_at: string;\n completed_at: string;\n referencedDocuments?: ReferencedDocuments;\n}\n\nexport interface LCSShield {\n identifier: string;\n provider_id: string;\n type: 'shield';\n params: {};\n provider_resource_id: string;\n}\nexport interface BaseMessage {\n name: string;\n type: string;\n id: number;\n content: string;\n model: string;\n timestamp: string;\n sources?: SourcesCardProps;\n referencedDocuments?: ReferencedDocuments;\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 SamplePrompt =\n | {\n title: string;\n message: string;\n }\n | {\n titleKey: string;\n messageKey: string;\n };\n\nexport type SamplePrompts = SamplePrompt[];\n\nexport type CaptureFeedback = {\n conversation_id: string;\n user_question: string;\n llm_response: string;\n user_feedback: string;\n sentiment: number;\n};\n"],"names":["SupportedFileType"],"mappings":"AAsFY,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;;;;"}
|
|
@@ -71,13 +71,23 @@ const createBotMessage = (props) => createMessage({
|
|
|
71
71
|
...props,
|
|
72
72
|
role: "bot"
|
|
73
73
|
});
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
const getConversationsData = (conversation) => {
|
|
75
|
+
const [userMessage, botMessage] = conversation.messages || [];
|
|
76
|
+
return [
|
|
77
|
+
{
|
|
78
|
+
...userMessage,
|
|
79
|
+
timestamp: getTimestamp(
|
|
80
|
+
conversation.started_at ? new Date(conversation.started_at).getTime() : Date.now()
|
|
81
|
+
)
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
...botMessage,
|
|
85
|
+
timestamp: getTimestamp(
|
|
86
|
+
conversation.completed_at ? new Date(conversation.completed_at).getTime() : Date.now()
|
|
87
|
+
),
|
|
88
|
+
referencedDocuments: botMessage?.referencedDocuments ?? []
|
|
89
|
+
}
|
|
90
|
+
];
|
|
81
91
|
};
|
|
82
92
|
const transformDocumentsToSources = (referenced_documents) => {
|
|
83
93
|
if (!referenced_documents || referenced_documents?.length === 0) {
|
|
@@ -155,5 +165,5 @@ const getCategorizeMessages = (messages, addProps, t) => {
|
|
|
155
165
|
return filteredCategories;
|
|
156
166
|
};
|
|
157
167
|
|
|
158
|
-
export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getDayDifference, getFootnoteProps,
|
|
168
|
+
export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getConversationsData, getDayDifference, getFootnoteProps, getTimestamp, getTimestampVariablesString, transformDocumentsToSources };
|
|
159
169
|
//# sourceMappingURL=lightspeed-chatbox-utils.esm.js.map
|