@red-hat-developer-hub/backstage-plugin-lightspeed 1.4.0 → 2.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 +35 -0
- package/README.md +59 -0
- package/dist/alpha/LightspeedFAB.esm.js +69 -0
- package/dist/alpha/LightspeedFAB.esm.js.map +1 -0
- package/dist/alpha/LightspeedProvider.esm.js +6 -0
- package/dist/alpha/LightspeedProvider.esm.js.map +1 -0
- package/dist/alpha.d.ts +170 -1
- package/dist/alpha.esm.js +97 -1
- package/dist/alpha.esm.js.map +1 -1
- package/dist/api/LightspeedApiClient.esm.js +19 -0
- package/dist/api/LightspeedApiClient.esm.js.map +1 -1
- package/dist/api/NotebooksApiClient.esm.js +72 -0
- package/dist/api/NotebooksApiClient.esm.js.map +1 -0
- package/dist/api/api.esm.js.map +1 -1
- package/dist/api/notebooksApi.esm.js +10 -0
- package/dist/api/notebooksApi.esm.js.map +1 -0
- package/dist/components/DeleteModal.esm.js +2 -0
- package/dist/components/DeleteModal.esm.js.map +1 -1
- package/dist/components/LightSpeedChat.esm.js +714 -66
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedChatBox.esm.js +18 -4
- package/dist/components/LightspeedChatBox.esm.js.map +1 -1
- package/dist/components/LightspeedChatBoxHeader.esm.js +59 -50
- package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
- package/dist/components/LightspeedChatContainer.esm.js +26 -2
- package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
- package/dist/components/LightspeedDrawerProvider.esm.js +12 -157
- package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
- package/dist/components/LightspeedFAB.esm.js +5 -4
- package/dist/components/LightspeedFAB.esm.js.map +1 -1
- package/dist/components/McpServersSettings.esm.js +932 -0
- package/dist/components/McpServersSettings.esm.js.map +1 -0
- package/dist/components/McpSettingsIcon.esm.js +26 -0
- package/dist/components/McpSettingsIcon.esm.js.map +1 -0
- package/dist/components/PermissionRequiredState.esm.js +18 -22
- package/dist/components/PermissionRequiredState.esm.js.map +1 -1
- package/dist/components/RenameConversationModal.esm.js +2 -2
- package/dist/components/RenameConversationModal.esm.js.map +1 -1
- package/dist/components/ToolCallContent.esm.js +14 -4
- package/dist/components/ToolCallContent.esm.js.map +1 -1
- package/dist/components/notebooks/DeleteNotebookModal.esm.js +143 -0
- package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -0
- package/dist/components/notebooks/NotebookCard.esm.js +96 -0
- package/dist/components/notebooks/NotebookCard.esm.js.map +1 -0
- package/dist/components/notebooks/NotebooksTab.esm.js +61 -0
- package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -0
- package/dist/components/notebooks/RenameNotebookModal.esm.js +187 -0
- package/dist/components/notebooks/RenameNotebookModal.esm.js.map +1 -0
- package/dist/const.esm.js +3 -1
- package/dist/const.esm.js.map +1 -1
- package/dist/hooks/notebooks/useDeleteNotebook.esm.js +19 -0
- package/dist/hooks/notebooks/useDeleteNotebook.esm.js.map +1 -0
- package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js +15 -0
- package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +1 -0
- package/dist/hooks/notebooks/useNotebookSessions.esm.js +18 -0
- package/dist/hooks/notebooks/useNotebookSessions.esm.js.map +1 -0
- package/dist/hooks/notebooks/useRenameNotebook.esm.js +19 -0
- package/dist/hooks/notebooks/useRenameNotebook.esm.js.map +1 -0
- package/dist/hooks/useConversationMessages.esm.js +136 -36
- package/dist/hooks/useConversationMessages.esm.js.map +1 -1
- package/dist/hooks/useConversations.esm.js +6 -0
- package/dist/hooks/useConversations.esm.js.map +1 -1
- package/dist/hooks/useCreateCoversationMessage.esm.js.map +1 -1
- package/dist/hooks/useLightspeedProviderState.esm.js +205 -0
- package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -0
- package/dist/hooks/useStopConversation.esm.js +18 -0
- package/dist/hooks/useStopConversation.esm.js.map +1 -0
- package/dist/hooks/useWelcomePrompts.esm.js +2 -2
- package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
- package/dist/index.d.ts +31 -31
- package/dist/plugin.esm.js +10 -0
- package/dist/plugin.esm.js.map +1 -1
- package/dist/translations/de.esm.js +78 -0
- package/dist/translations/de.esm.js.map +1 -1
- package/dist/translations/es.esm.js +78 -0
- package/dist/translations/es.esm.js.map +1 -1
- package/dist/translations/fr.esm.js +64 -1
- package/dist/translations/fr.esm.js.map +1 -1
- package/dist/translations/it.esm.js +66 -1
- package/dist/translations/it.esm.js.map +1 -1
- package/dist/translations/ja.esm.js +66 -1
- package/dist/translations/ja.esm.js.map +1 -1
- package/dist/translations/ref.esm.js +65 -1
- package/dist/translations/ref.esm.js.map +1 -1
- package/dist/types.esm.js.map +1 -1
- package/dist/utils/formatToolResponseForMarkdown.esm.js +46 -0
- package/dist/utils/formatToolResponseForMarkdown.esm.js.map +1 -0
- package/dist/utils/lightspeed-chatbox-utils.esm.js +7 -3
- package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
- package/dist/utils/notebooks-utils.esm.js +25 -0
- package/dist/utils/notebooks-utils.esm.js.map +1 -0
- package/package.json +20 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
## @red-hat-developer-hub/backstage-plugin-lightspeed
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6ae51d4: migrated plugin to nfs
|
|
8
|
+
- f20f9f3: Add AI notebooks UI, hooks, and backend support for listing/renaming/deleting sessions.
|
|
9
|
+
- 0277bd0: Added the MCP servers selector/settings feature in Lightspeed with backend
|
|
10
|
+
integration for listing servers, per-user token updates, and validation.
|
|
11
|
+
|
|
12
|
+
In the settings panel, users can review server status, enable or disable
|
|
13
|
+
eligible servers, configure personal tokens, and get inline token validation
|
|
14
|
+
feedback. Token validation now runs automatically after typing stops and shows
|
|
15
|
+
success (`Connection successful`) or error (`Authorization failed. Try again.`)
|
|
16
|
+
before save.
|
|
17
|
+
|
|
18
|
+
- 01241c2: Backstage version bump to v1.49.2
|
|
19
|
+
moved existing app to app-legacy
|
|
20
|
+
app now runs the NFS model
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 5d4f070: update how tool call info is retrived
|
|
25
|
+
- afd7a1e: Update translations for Lightspeed.
|
|
26
|
+
- c45aa19: Add stop button to interrupt a streaming conversation
|
|
27
|
+
- c0f9d6a: fixes lightspeed overlay (remove horizontal scrollbar, and adds vertical scrollbar for newly created chats)
|
|
28
|
+
- 8f2c7f2: fix the overlay mode opening underneath the ApplicationDrawer
|
|
29
|
+
- a8b3dd9: Fixed "new chat" cta behavior
|
|
30
|
+
Added vertical scroll when too many models are available
|
|
31
|
+
Removed model grouping/categories in the model selector dropdown
|
|
32
|
+
- 7ce8caa: Added a missing permission screen for the Notebooks tab. When a user lacks the `lightspeed.notebooks.use` permission, the Notebooks tab now displays a "Missing permission" message with a "Go back" button instead of the notebook list.
|
|
33
|
+
- Updated dependencies [024d5a8]
|
|
34
|
+
- Updated dependencies [7db4bed]
|
|
35
|
+
- Updated dependencies [01241c2]
|
|
36
|
+
- @red-hat-developer-hub/backstage-plugin-lightspeed-common@2.0.0
|
|
37
|
+
|
|
3
38
|
## 1.4.0
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -24,6 +24,9 @@ p, role:default/team_a, lightspeed.chat.create, create, allow
|
|
|
24
24
|
p, role:default/team_a, lightspeed.chat.delete, delete, allow
|
|
25
25
|
p, role:default/team_a, lightspeed.chat.update, update, allow
|
|
26
26
|
|
|
27
|
+
# Required for AI Notebooks feature (if enabled)
|
|
28
|
+
p, role:default/team_a, lightspeed.notebooks.use, update, allow
|
|
29
|
+
|
|
27
30
|
g, user:default/<your-user-name>, role:default/team_a
|
|
28
31
|
|
|
29
32
|
```
|
|
@@ -84,6 +87,62 @@ Lightspeed is a front-end plugin that enables you to interact with any LLM serve
|
|
|
84
87
|
1. Open your Backstage application and select a Lightspeed nav item from the **Navigation**.
|
|
85
88
|
2. Ask you questions to the Lightspeed chatbot.
|
|
86
89
|
|
|
90
|
+
### MCP servers settings
|
|
91
|
+
|
|
92
|
+
Lightspeed includes an MCP servers settings panel where users can:
|
|
93
|
+
|
|
94
|
+
- View configured MCP servers and current status
|
|
95
|
+
- Enable or disable eligible servers
|
|
96
|
+
- Configure a personal token per server
|
|
97
|
+
- See inline status and validation feedback
|
|
98
|
+
|
|
99
|
+
#### Token validation behavior
|
|
100
|
+
|
|
101
|
+
When configuring a server token in the settings modal, the token is validated
|
|
102
|
+
automatically after typing stops briefly. The input shows inline feedback:
|
|
103
|
+
|
|
104
|
+
- Success: `Connection successful`
|
|
105
|
+
- Error: `Authorization failed. Try again.`
|
|
106
|
+
|
|
107
|
+
Users can then save the configuration after validation feedback is displayed.
|
|
108
|
+
|
|
109
|
+
### AI Notebooks (Developer Preview)
|
|
110
|
+
|
|
111
|
+
AI Notebooks is an experimental feature that enables **document-based conversations with Retrieval-Augmented Generation (RAG)**. This feature allows you to:
|
|
112
|
+
|
|
113
|
+
- **Create persistent notebook sessions** with their own vector databases
|
|
114
|
+
- **Upload and manage documents** to query against, including:
|
|
115
|
+
- Text files (`.txt`, `.md`, `.log`)
|
|
116
|
+
- PDF documents with automatic text extraction
|
|
117
|
+
- Structured data (`.json`, `.yaml`)
|
|
118
|
+
- Web content via URL (up to 20MB per file)
|
|
119
|
+
- **Query your documents** using natural language and get context-aware AI responses
|
|
120
|
+
- **Organize documents** by sessions with metadata and tagging
|
|
121
|
+
- **Maintain context** across conversations - all uploaded documents remain available throughout the session
|
|
122
|
+
|
|
123
|
+
#### How AI Notebooks Works
|
|
124
|
+
|
|
125
|
+
1. **Session Management**: Create a notebook session, which is backed by its own vector database
|
|
126
|
+
2. **Document Upload**: Upload documents - they are automatically processed, chunked, and embedded into the vector database
|
|
127
|
+
3. **RAG Conversations**: Ask questions about your documents - relevant chunks are retrieved and provided as context to the LLM
|
|
128
|
+
4. **Persistent Storage**: Your documents and conversations remain available throughout the session lifecycle
|
|
129
|
+
|
|
130
|
+
#### Prerequisites for AI Notebooks
|
|
131
|
+
|
|
132
|
+
- AI Notebooks requires a **Llama Stack service** to be running
|
|
133
|
+
- The backend administrator must enable the feature (see [Backend Configuration](../lightspeed-backend/README.md#ai-notebooks-developer-preview))
|
|
134
|
+
- Users need the appropriate RBAC permissions (if enabled)
|
|
135
|
+
|
|
136
|
+
#### Using AI Notebooks
|
|
137
|
+
|
|
138
|
+
1. Ensure AI Notebooks is enabled in your Backstage instance
|
|
139
|
+
2. Navigate to the Lightspeed page
|
|
140
|
+
3. Create a new notebook session or select an existing one
|
|
141
|
+
4. Upload documents you want to query
|
|
142
|
+
5. Start asking questions about your uploaded documents
|
|
143
|
+
|
|
144
|
+
For backend configuration and API details, administrators should refer to the [Lightspeed Backend Plugin Documentation](../lightspeed-backend/README.md#ai-notebooks-developer-preview).
|
|
145
|
+
|
|
87
146
|
## Loading as Dynamic Plugin
|
|
88
147
|
|
|
89
148
|
#### To configure Lightspeed plugin into Red Hat Developer Hub use this configuration:
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
3
|
+
import Fab from '@mui/material/Fab';
|
|
4
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
5
|
+
import { makeStyles } from '@mui/styles';
|
|
6
|
+
import { ChatbotDisplayMode } from '@patternfly/chatbot';
|
|
7
|
+
import { LightspeedFABIcon } from '../components/LightspeedIcon.esm.js';
|
|
8
|
+
import { DOCKED_CONTENT_OFFSET } from '../const.esm.js';
|
|
9
|
+
import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
|
|
10
|
+
|
|
11
|
+
const useStyles = makeStyles((theme) => ({
|
|
12
|
+
fab: {
|
|
13
|
+
opacity: "1 !important",
|
|
14
|
+
backgroundColor: `${theme?.palette?.primary?.main ?? "#1976d2"} !important`,
|
|
15
|
+
color: `${theme?.palette?.primary?.contrastText ?? "#fff"} !important`,
|
|
16
|
+
boxShadow: `${theme?.shadows?.[6] ?? "0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)"} !important`
|
|
17
|
+
},
|
|
18
|
+
"fab-button": {
|
|
19
|
+
bottom: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`,
|
|
20
|
+
right: `calc(${theme?.spacing?.(2) ?? "16px"} + 1.5em)`,
|
|
21
|
+
alignItems: "end",
|
|
22
|
+
zIndex: 200,
|
|
23
|
+
display: "flex",
|
|
24
|
+
position: "fixed",
|
|
25
|
+
// When ApplicationDrawer is docked, match main content inset
|
|
26
|
+
"body.docked-drawer-open &": {
|
|
27
|
+
transition: "margin-right 0.3s ease",
|
|
28
|
+
marginRight: DOCKED_CONTENT_OFFSET
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
const LightspeedFAB = () => {
|
|
33
|
+
const { isChatbotActive, toggleChatbot, displayMode } = useLightspeedDrawerContext();
|
|
34
|
+
const fabButton = useStyles();
|
|
35
|
+
if (displayMode === ChatbotDisplayMode.embedded) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
className: fabButton["fab-button"],
|
|
42
|
+
id: "lightspeed-fab",
|
|
43
|
+
"data-testid": "lightspeed-fab",
|
|
44
|
+
children: /* @__PURE__ */ jsx(
|
|
45
|
+
Tooltip,
|
|
46
|
+
{
|
|
47
|
+
title: isChatbotActive ? "Close Lightspeed" : "Open Lightspeed",
|
|
48
|
+
placement: "left",
|
|
49
|
+
children: /* @__PURE__ */ jsx(
|
|
50
|
+
Fab,
|
|
51
|
+
{
|
|
52
|
+
color: "primary",
|
|
53
|
+
variant: "circular",
|
|
54
|
+
size: "small",
|
|
55
|
+
onClick: toggleChatbot,
|
|
56
|
+
"aria-label": isChatbotActive ? "lightspeed-close" : "lightspeed-open",
|
|
57
|
+
className: fabButton.fab,
|
|
58
|
+
sx: { borderRadius: "100% !important" },
|
|
59
|
+
children: isChatbotActive ? /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(LightspeedFABIcon, {})
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { LightspeedFAB };
|
|
69
|
+
//# sourceMappingURL=LightspeedFAB.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedFAB.esm.js","sources":["../../src/alpha/LightspeedFAB.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 Close from '@mui/icons-material/Close';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { makeStyles } from '@mui/styles';\nimport { ChatbotDisplayMode } from '@patternfly/chatbot';\n\nimport { LightspeedFABIcon } from '../components/LightspeedIcon';\nimport { DOCKED_CONTENT_OFFSET } from '../const';\nimport { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext';\n\nconst useStyles = makeStyles(theme => ({\n fab: {\n opacity: '1 !important',\n backgroundColor: `${theme?.palette?.primary?.main ?? '#1976d2'} !important`,\n color: `${theme?.palette?.primary?.contrastText ?? '#fff'} !important`,\n boxShadow: `${\n theme?.shadows?.[6] ??\n '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)'\n } !important`,\n },\n 'fab-button': {\n bottom: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n right: `calc(${theme?.spacing?.(2) ?? '16px'} + 1.5em)`,\n alignItems: 'end',\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n\n // When ApplicationDrawer is docked, match main content inset\n 'body.docked-drawer-open &': {\n transition: 'margin-right 0.3s ease',\n marginRight: DOCKED_CONTENT_OFFSET,\n },\n },\n}));\n\n/**\n * @alpha\n * Lightspeed Floating action button to open/close the lightspeed chatbot\n */\n\nexport const LightspeedFAB = () => {\n const { isChatbotActive, toggleChatbot, displayMode } =\n useLightspeedDrawerContext();\n const fabButton = useStyles();\n\n if (displayMode === ChatbotDisplayMode.embedded) {\n return null;\n }\n\n return (\n <div\n className={fabButton['fab-button']}\n id=\"lightspeed-fab\"\n data-testid=\"lightspeed-fab\"\n >\n <Tooltip\n title={isChatbotActive ? 'Close Lightspeed' : 'Open Lightspeed'}\n placement=\"left\"\n >\n <Fab\n color=\"primary\"\n variant=\"circular\"\n size=\"small\"\n onClick={toggleChatbot}\n aria-label={isChatbotActive ? 'lightspeed-close' : 'lightspeed-open'}\n className={fabButton.fab}\n sx={{ borderRadius: '100% !important' }}\n >\n {isChatbotActive ? <Close fontSize=\"small\" /> : <LightspeedFABIcon />}\n </Fab>\n </Tooltip>\n </div>\n );\n};\n"],"names":["Close"],"mappings":";;;;;;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,GAAK,EAAA;AAAA,IACH,OAAS,EAAA,cAAA;AAAA,IACT,iBAAiB,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,QAAQ,SAAS,CAAA,WAAA,CAAA;AAAA,IAC9D,OAAO,CAAG,EAAA,KAAA,EAAO,OAAS,EAAA,OAAA,EAAS,gBAAgB,MAAM,CAAA,WAAA,CAAA;AAAA,IACzD,WAAW,CACT,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAClB,wGACF,CAAA,WAAA;AAAA,GACF;AAAA,EACA,YAAc,EAAA;AAAA,IACZ,QAAQ,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC7C,OAAO,CAAQ,KAAA,EAAA,KAAA,EAAO,OAAU,GAAA,CAAC,KAAK,MAAM,CAAA,SAAA,CAAA;AAAA,IAC5C,UAAY,EAAA,KAAA;AAAA,IACZ,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA;AAAA,IAGV,2BAA6B,EAAA;AAAA,MAC3B,UAAY,EAAA,wBAAA;AAAA,MACZ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAOK,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,aAAe,EAAA,WAAA,KACtC,0BAA2B,EAAA;AAC7B,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAI,IAAA,WAAA,KAAgB,mBAAmB,QAAU,EAAA;AAC/C,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAU,YAAY,CAAA;AAAA,MACjC,EAAG,EAAA,gBAAA;AAAA,MACH,aAAY,EAAA,gBAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,UAC9C,SAAU,EAAA,MAAA;AAAA,UAEV,QAAA,kBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,KAAM,EAAA,SAAA;AAAA,cACN,OAAQ,EAAA,UAAA;AAAA,cACR,IAAK,EAAA,OAAA;AAAA,cACL,OAAS,EAAA,aAAA;AAAA,cACT,YAAA,EAAY,kBAAkB,kBAAqB,GAAA,iBAAA;AAAA,cACnD,WAAW,SAAU,CAAA,GAAA;AAAA,cACrB,EAAA,EAAI,EAAE,YAAA,EAAc,iBAAkB,EAAA;AAAA,cAErC,4CAAmB,GAAA,CAAAA,SAAA,EAAA,EAAM,UAAS,OAAQ,EAAA,CAAA,uBAAM,iBAAkB,EAAA,EAAA;AAAA;AAAA;AACrE;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightspeedProvider.esm.js","sources":["../../src/alpha/LightspeedProvider.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 { LightspeedDrawerProvider } from '../components/LightspeedDrawerProvider';\n\n/**\n * This file is exported as LightspeedProvider from the alpha entry point.\n * @alpha\n */\n\nexport const LightspeedProvider = LightspeedDrawerProvider;\n"],"names":[],"mappings":";;AAuBO,MAAM,kBAAqB,GAAA;;;;"}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as _red_hat_developer_hub_backstage_plugin_app_react from '@red-hat-developer-hub/backstage-plugin-app-react';
|
|
1
3
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
2
4
|
|
|
3
5
|
/**
|
|
@@ -33,6 +35,30 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
33
35
|
readonly "prompts.rhdh.message": string;
|
|
34
36
|
readonly "page.title": string;
|
|
35
37
|
readonly "page.subtitle": string;
|
|
38
|
+
readonly "tabs.ariaLabel": string;
|
|
39
|
+
readonly "tabs.chat": string;
|
|
40
|
+
readonly "tabs.notebooks": string;
|
|
41
|
+
readonly "tabs.notebooks.empty": string;
|
|
42
|
+
readonly "notebooks.title": string;
|
|
43
|
+
readonly "notebooks.empty.title": string;
|
|
44
|
+
readonly "notebooks.empty.description": string;
|
|
45
|
+
readonly "notebooks.empty.action": string;
|
|
46
|
+
readonly "notebooks.documents": string;
|
|
47
|
+
readonly "notebooks.actions.rename": string;
|
|
48
|
+
readonly "notebooks.actions.delete": string;
|
|
49
|
+
readonly "notebooks.rename.title": string;
|
|
50
|
+
readonly "notebooks.rename.description": string;
|
|
51
|
+
readonly "notebooks.rename.label": string;
|
|
52
|
+
readonly "notebooks.rename.placeholder": string;
|
|
53
|
+
readonly "notebooks.rename.action": string;
|
|
54
|
+
readonly "notebooks.delete.title": string;
|
|
55
|
+
readonly "notebooks.delete.message": string;
|
|
56
|
+
readonly "notebooks.delete.action": string;
|
|
57
|
+
readonly "notebooks.delete.toast": string;
|
|
58
|
+
readonly "notebooks.updated.today": string;
|
|
59
|
+
readonly "notebooks.updated.yesterday": string;
|
|
60
|
+
readonly "notebooks.updated.days": string;
|
|
61
|
+
readonly "notebooks.updated.on": string;
|
|
36
62
|
readonly "conversation.delete.confirm.title": string;
|
|
37
63
|
readonly "conversation.delete.confirm.message": string;
|
|
38
64
|
readonly "conversation.delete.confirm.action": string;
|
|
@@ -41,6 +67,9 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
41
67
|
readonly "conversation.rename.placeholder": string;
|
|
42
68
|
readonly "permission.required.title": string;
|
|
43
69
|
readonly "permission.required.description": string;
|
|
70
|
+
readonly "permission.subject.plugin": string;
|
|
71
|
+
readonly "permission.subject.notebooks": string;
|
|
72
|
+
readonly "permission.notebooks.goBack": string;
|
|
44
73
|
readonly "footer.accuracy.label": string;
|
|
45
74
|
readonly "common.cancel": string;
|
|
46
75
|
readonly "common.close": string;
|
|
@@ -80,6 +109,7 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
80
109
|
readonly "conversation.addToPinnedChats": string;
|
|
81
110
|
readonly "conversation.removeFromPinnedChats": string;
|
|
82
111
|
readonly "conversation.announcement.userMessage": string;
|
|
112
|
+
readonly "conversation.announcement.responseStopped": string;
|
|
83
113
|
readonly "user.guest": string;
|
|
84
114
|
readonly "user.loading": string;
|
|
85
115
|
readonly "tooltip.attach": string;
|
|
@@ -127,6 +157,41 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
127
157
|
readonly "settings.pinned.disable": string;
|
|
128
158
|
readonly "settings.pinned.enabled.description": string;
|
|
129
159
|
readonly "settings.pinned.disabled.description": string;
|
|
160
|
+
readonly "settings.mcp.label": string;
|
|
161
|
+
readonly "mcp.settings.title": string;
|
|
162
|
+
readonly "mcp.settings.selectedCount": string;
|
|
163
|
+
readonly "mcp.settings.closeAriaLabel": string;
|
|
164
|
+
readonly "mcp.settings.readOnlyAccess": string;
|
|
165
|
+
readonly "mcp.settings.tableAriaLabel": string;
|
|
166
|
+
readonly "mcp.settings.enabled": string;
|
|
167
|
+
readonly "mcp.settings.name": string;
|
|
168
|
+
readonly "mcp.settings.status": string;
|
|
169
|
+
readonly "mcp.settings.edit": string;
|
|
170
|
+
readonly "mcp.settings.loading": string;
|
|
171
|
+
readonly "mcp.settings.noneAvailable": string;
|
|
172
|
+
readonly "mcp.settings.status.disabled": string;
|
|
173
|
+
readonly "mcp.settings.status.tokenRequired": string;
|
|
174
|
+
readonly "mcp.settings.status.failed": string;
|
|
175
|
+
readonly "mcp.settings.status.oneTool": string;
|
|
176
|
+
readonly "mcp.settings.status.manyTools": string;
|
|
177
|
+
readonly "mcp.settings.status.unknown": string;
|
|
178
|
+
readonly "mcp.settings.toggleServerAriaLabel": string;
|
|
179
|
+
readonly "mcp.settings.editServerAriaLabel": string;
|
|
180
|
+
readonly "mcp.settings.configureServerTitle": string;
|
|
181
|
+
readonly "mcp.settings.closeConfigureModalAriaLabel": string;
|
|
182
|
+
readonly "mcp.settings.modalDescription": string;
|
|
183
|
+
readonly "mcp.settings.savedToken": string;
|
|
184
|
+
readonly "mcp.settings.personalAccessToken": string;
|
|
185
|
+
readonly "mcp.settings.usingAdminCredential": string;
|
|
186
|
+
readonly "mcp.settings.enterToken": string;
|
|
187
|
+
readonly "mcp.settings.removePersonalToken": string;
|
|
188
|
+
readonly "mcp.settings.token.clearAriaLabel": string;
|
|
189
|
+
readonly "mcp.settings.token.validating": string;
|
|
190
|
+
readonly "mcp.settings.token.savingAndValidating": string;
|
|
191
|
+
readonly "mcp.settings.token.urlUnavailableForValidation": string;
|
|
192
|
+
readonly "mcp.settings.token.invalidCredentials": string;
|
|
193
|
+
readonly "mcp.settings.token.validationFailed": string;
|
|
194
|
+
readonly "mcp.settings.token.connectionSuccessful": string;
|
|
130
195
|
readonly "toolCall.header": string;
|
|
131
196
|
readonly "toolCall.thinking": string;
|
|
132
197
|
readonly "toolCall.executionTime": string;
|
|
@@ -157,4 +222,108 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
157
222
|
**/
|
|
158
223
|
declare const lightspeedTranslations: _backstage_frontend_plugin_api.TranslationResource<"plugin.lightspeed">;
|
|
159
224
|
|
|
160
|
-
|
|
225
|
+
/**
|
|
226
|
+
* @alpha
|
|
227
|
+
*/
|
|
228
|
+
declare const lightspeedFABModule: _backstage_frontend_plugin_api.FrontendModule;
|
|
229
|
+
/**
|
|
230
|
+
* Translation wiring for the language selector (app-config `app.extensions`).
|
|
231
|
+
*
|
|
232
|
+
* @alpha
|
|
233
|
+
*/
|
|
234
|
+
declare const lightspeedTranslationsModule: _backstage_frontend_plugin_api.FrontendModule;
|
|
235
|
+
/**
|
|
236
|
+
* Lightspeed plugin for the Backstage new frontend system.
|
|
237
|
+
*
|
|
238
|
+
* @alpha
|
|
239
|
+
*/
|
|
240
|
+
declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
|
|
241
|
+
root: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
242
|
+
lightspeedConversation: _backstage_frontend_plugin_api.SubRouteRef<{
|
|
243
|
+
conversationId: string;
|
|
244
|
+
}>;
|
|
245
|
+
}, {}, {
|
|
246
|
+
"api:lightspeed/lightspeed": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
247
|
+
kind: "api";
|
|
248
|
+
name: "lightspeed";
|
|
249
|
+
config: {};
|
|
250
|
+
configInput: {};
|
|
251
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
252
|
+
inputs: {};
|
|
253
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
254
|
+
}>;
|
|
255
|
+
"api:lightspeed/notebooks": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
256
|
+
kind: "api";
|
|
257
|
+
name: "notebooks";
|
|
258
|
+
config: {};
|
|
259
|
+
configInput: {};
|
|
260
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
261
|
+
inputs: {};
|
|
262
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
263
|
+
}>;
|
|
264
|
+
"app-drawer-content:lightspeed/lightspeed": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
265
|
+
kind: "app-drawer-content";
|
|
266
|
+
name: "lightspeed";
|
|
267
|
+
config: {
|
|
268
|
+
defaultWidth: number | undefined;
|
|
269
|
+
resizable: boolean | undefined;
|
|
270
|
+
priority: number | undefined;
|
|
271
|
+
};
|
|
272
|
+
configInput: {
|
|
273
|
+
defaultWidth?: number | undefined;
|
|
274
|
+
resizable?: boolean | undefined;
|
|
275
|
+
priority?: number | undefined;
|
|
276
|
+
};
|
|
277
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_red_hat_developer_hub_backstage_plugin_app_react.AppDrawerContent, "app.drawer.content", {}>;
|
|
278
|
+
inputs: {};
|
|
279
|
+
params: {
|
|
280
|
+
id: string;
|
|
281
|
+
element: React.ReactElement;
|
|
282
|
+
resizable?: boolean;
|
|
283
|
+
defaultWidth?: number;
|
|
284
|
+
priority?: number;
|
|
285
|
+
};
|
|
286
|
+
}>;
|
|
287
|
+
"page:lightspeed": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
288
|
+
kind: "page";
|
|
289
|
+
name: undefined;
|
|
290
|
+
config: {
|
|
291
|
+
path: string | undefined;
|
|
292
|
+
title: string | undefined;
|
|
293
|
+
};
|
|
294
|
+
configInput: {
|
|
295
|
+
title?: string | undefined;
|
|
296
|
+
path?: string | undefined;
|
|
297
|
+
};
|
|
298
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
299
|
+
optional: true;
|
|
300
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
|
|
301
|
+
optional: true;
|
|
302
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
303
|
+
optional: true;
|
|
304
|
+
}>;
|
|
305
|
+
inputs: {
|
|
306
|
+
pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
307
|
+
optional: true;
|
|
308
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
|
|
309
|
+
optional: true;
|
|
310
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
311
|
+
optional: true;
|
|
312
|
+
}>, {
|
|
313
|
+
singleton: false;
|
|
314
|
+
optional: false;
|
|
315
|
+
internal: false;
|
|
316
|
+
}>;
|
|
317
|
+
};
|
|
318
|
+
params: {
|
|
319
|
+
path: string;
|
|
320
|
+
title?: string;
|
|
321
|
+
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
322
|
+
loader?: () => Promise<react.JSX.Element>;
|
|
323
|
+
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
324
|
+
noHeader?: boolean;
|
|
325
|
+
};
|
|
326
|
+
}>;
|
|
327
|
+
}>;
|
|
328
|
+
|
|
329
|
+
export { _default as default, lightspeedFABModule, lightspeedTranslationRef, lightspeedTranslations, lightspeedTranslationsModule };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,3 +1,99 @@
|
|
|
1
|
-
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { createRouteRef, createSubRouteRef, ApiBlueprint, createApiFactory, configApiRef, fetchApiRef, PageBlueprint, createFrontendModule, createFrontendPlugin } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { AppRootWrapperBlueprint, TranslationBlueprint } from '@backstage/plugin-app-react';
|
|
4
|
+
import { AppDrawerContentBlueprint } from '@red-hat-developer-hub/backstage-plugin-app-react/alpha';
|
|
5
|
+
import { lightspeedApiRef } from './api/api.esm.js';
|
|
6
|
+
import { LightspeedApiClient } from './api/LightspeedApiClient.esm.js';
|
|
7
|
+
import { notebooksApiRef } from './api/notebooksApi.esm.js';
|
|
8
|
+
import { NotebooksApiClient } from './api/NotebooksApiClient.esm.js';
|
|
9
|
+
import { LightspeedChatContainer } from './components/LightspeedChatContainer.esm.js';
|
|
10
|
+
import { LIGHTSPEED_APP_DRAWER_ID } from './const.esm.js';
|
|
11
|
+
import { lightspeedTranslations } from './translations/index.esm.js';
|
|
12
|
+
import { LightspeedFAB } from './alpha/LightspeedFAB.esm.js';
|
|
13
|
+
import { LightspeedProvider } from './alpha/LightspeedProvider.esm.js';
|
|
2
14
|
export { lightspeedTranslationRef } from './translations/ref.esm.js';
|
|
15
|
+
|
|
16
|
+
const nfsRootRouteRef = createRouteRef();
|
|
17
|
+
const nfsConversationRouteRef = createSubRouteRef({
|
|
18
|
+
parent: nfsRootRouteRef,
|
|
19
|
+
path: "/conversation/:conversationId"
|
|
20
|
+
});
|
|
21
|
+
const lightspeedApi = ApiBlueprint.make({
|
|
22
|
+
name: "lightspeed",
|
|
23
|
+
params: (defineParams) => defineParams(
|
|
24
|
+
createApiFactory({
|
|
25
|
+
api: lightspeedApiRef,
|
|
26
|
+
deps: {
|
|
27
|
+
configApi: configApiRef,
|
|
28
|
+
fetchApi: fetchApiRef
|
|
29
|
+
},
|
|
30
|
+
factory: ({ configApi, fetchApi }) => new LightspeedApiClient({ configApi, fetchApi })
|
|
31
|
+
})
|
|
32
|
+
)
|
|
33
|
+
});
|
|
34
|
+
const notebooksApi = ApiBlueprint.make({
|
|
35
|
+
name: "notebooks",
|
|
36
|
+
params: (defineParams) => defineParams(
|
|
37
|
+
createApiFactory({
|
|
38
|
+
api: notebooksApiRef,
|
|
39
|
+
deps: {
|
|
40
|
+
configApi: configApiRef,
|
|
41
|
+
fetchApi: fetchApiRef
|
|
42
|
+
},
|
|
43
|
+
factory: ({ configApi, fetchApi }) => new NotebooksApiClient({ configApi, fetchApi })
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
});
|
|
47
|
+
const lightspeedPage = PageBlueprint.make({
|
|
48
|
+
params: {
|
|
49
|
+
path: "/lightspeed",
|
|
50
|
+
routeRef: nfsRootRouteRef,
|
|
51
|
+
noHeader: true,
|
|
52
|
+
loader: () => import('./components/Router.esm.js').then((m) => /* @__PURE__ */ jsx(m.Router, {}))
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const lightspeedDrawer = AppDrawerContentBlueprint.make({
|
|
56
|
+
name: "lightspeed",
|
|
57
|
+
params: {
|
|
58
|
+
id: LIGHTSPEED_APP_DRAWER_ID,
|
|
59
|
+
element: /* @__PURE__ */ jsx(LightspeedChatContainer, {}),
|
|
60
|
+
resizable: false,
|
|
61
|
+
defaultWidth: 400,
|
|
62
|
+
priority: 100
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
const lightspeedFAB = AppRootWrapperBlueprint.make({
|
|
66
|
+
name: "lightspeed-fab",
|
|
67
|
+
params: {
|
|
68
|
+
component: ({ children }) => /* @__PURE__ */ jsxs(LightspeedProvider, { children: [
|
|
69
|
+
/* @__PURE__ */ jsx(LightspeedFAB, {}),
|
|
70
|
+
children
|
|
71
|
+
] })
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
const lightspeedFABModule = createFrontendModule({
|
|
75
|
+
pluginId: "app",
|
|
76
|
+
extensions: [lightspeedFAB]
|
|
77
|
+
});
|
|
78
|
+
const lightspeedTranslationsModule = createFrontendModule({
|
|
79
|
+
pluginId: "app",
|
|
80
|
+
extensions: [
|
|
81
|
+
TranslationBlueprint.make({
|
|
82
|
+
name: "lightspeed-translations",
|
|
83
|
+
params: {
|
|
84
|
+
resource: lightspeedTranslations
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
var index = createFrontendPlugin({
|
|
90
|
+
pluginId: "lightspeed",
|
|
91
|
+
extensions: [lightspeedApi, notebooksApi, lightspeedPage, lightspeedDrawer],
|
|
92
|
+
routes: {
|
|
93
|
+
root: nfsRootRouteRef,
|
|
94
|
+
lightspeedConversation: nfsConversationRouteRef
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export { index as default, lightspeedFABModule, lightspeedTranslations, lightspeedTranslationsModule };
|
|
3
99
|
//# sourceMappingURL=alpha.esm.js.map
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha/index.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ApiBlueprint,\n configApiRef,\n createApiFactory,\n createFrontendModule,\n createFrontendPlugin,\n createRouteRef,\n createSubRouteRef,\n fetchApiRef,\n PageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppRootWrapperBlueprint,\n TranslationBlueprint,\n} from '@backstage/plugin-app-react';\n\nimport { AppDrawerContentBlueprint } from '@red-hat-developer-hub/backstage-plugin-app-react/alpha';\n\nimport { lightspeedApiRef } from '../api/api';\nimport { LightspeedApiClient } from '../api/LightspeedApiClient';\nimport { notebooksApiRef } from '../api/notebooksApi';\nimport { NotebooksApiClient } from '../api/NotebooksApiClient';\nimport { LightspeedChatContainer } from '../components/LightspeedChatContainer';\nimport { LIGHTSPEED_APP_DRAWER_ID } from '../const';\nimport { lightspeedTranslations } from '../translations';\nimport { LightspeedFAB } from './LightspeedFAB';\nimport { LightspeedProvider } from './LightspeedProvider';\n\nconst nfsRootRouteRef = createRouteRef();\nconst nfsConversationRouteRef = createSubRouteRef({\n parent: nfsRootRouteRef,\n path: '/conversation/:conversationId',\n});\n\nconst lightspeedApi = ApiBlueprint.make({\n name: 'lightspeed',\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: lightspeedApiRef,\n deps: {\n configApi: configApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, fetchApi }) =>\n new LightspeedApiClient({ configApi, fetchApi }),\n }),\n ),\n});\n\nconst notebooksApi = ApiBlueprint.make({\n name: 'notebooks',\n params: defineParams =>\n defineParams(\n createApiFactory({\n api: notebooksApiRef,\n deps: {\n configApi: configApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ configApi, fetchApi }) =>\n new NotebooksApiClient({ configApi, fetchApi }),\n }),\n ),\n});\n\nconst lightspeedPage = PageBlueprint.make({\n params: {\n path: '/lightspeed',\n routeRef: nfsRootRouteRef,\n noHeader: true,\n loader: () => import('../components/Router').then(m => <m.Router />),\n },\n});\n\nconst lightspeedDrawer = AppDrawerContentBlueprint.make({\n name: 'lightspeed',\n params: {\n id: LIGHTSPEED_APP_DRAWER_ID,\n element: <LightspeedChatContainer />,\n resizable: false,\n defaultWidth: 400,\n priority: 100,\n },\n});\n\n/**\n * Lightspeed FAB module\n * @alpha\n */\nconst lightspeedFAB = AppRootWrapperBlueprint.make({\n name: 'lightspeed-fab',\n params: {\n component: ({ children }) => (\n <LightspeedProvider>\n <LightspeedFAB />\n {children}\n </LightspeedProvider>\n ),\n },\n});\n\n/**\n * @alpha\n */\nexport const lightspeedFABModule = createFrontendModule({\n pluginId: 'app',\n extensions: [lightspeedFAB],\n});\n\n/**\n * Translation wiring for the language selector (app-config `app.extensions`).\n *\n * @alpha\n */\nexport const lightspeedTranslationsModule = createFrontendModule({\n pluginId: 'app',\n extensions: [\n TranslationBlueprint.make({\n name: 'lightspeed-translations',\n params: {\n resource: lightspeedTranslations,\n },\n }),\n ],\n});\n\n/**\n * Lightspeed plugin for the Backstage new frontend system.\n *\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'lightspeed',\n extensions: [lightspeedApi, notebooksApi, lightspeedPage, lightspeedDrawer],\n routes: {\n root: nfsRootRouteRef,\n lightspeedConversation: nfsConversationRouteRef,\n },\n});\n\nexport * from '../translations';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA4CA,MAAM,kBAAkB,cAAe,EAAA;AACvC,MAAM,0BAA0B,iBAAkB,CAAA;AAAA,EAChD,MAAQ,EAAA,eAAA;AAAA,EACR,IAAM,EAAA;AACR,CAAC,CAAA;AAED,MAAM,aAAA,GAAgB,aAAa,IAAK,CAAA;AAAA,EACtC,IAAM,EAAA,YAAA;AAAA,EACN,QAAQ,CACN,YAAA,KAAA,YAAA;AAAA,IACE,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,gBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,SAAW,EAAA,YAAA;AAAA,QACX,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,SAAW,EAAA,QAAA,EACrB,KAAA,IAAI,mBAAoB,CAAA,EAAE,SAAW,EAAA,QAAA,EAAU;AAAA,KAClD;AAAA;AAEP,CAAC,CAAA;AAED,MAAM,YAAA,GAAe,aAAa,IAAK,CAAA;AAAA,EACrC,IAAM,EAAA,WAAA;AAAA,EACN,QAAQ,CACN,YAAA,KAAA,YAAA;AAAA,IACE,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,eAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,SAAW,EAAA,YAAA;AAAA,QACX,QAAU,EAAA;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,SAAW,EAAA,QAAA,EACrB,KAAA,IAAI,kBAAmB,CAAA,EAAE,SAAW,EAAA,QAAA,EAAU;AAAA,KACjD;AAAA;AAEP,CAAC,CAAA;AAED,MAAM,cAAA,GAAiB,cAAc,IAAK,CAAA;AAAA,EACxC,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,aAAA;AAAA,IACN,QAAU,EAAA,eAAA;AAAA,IACV,QAAU,EAAA,IAAA;AAAA,IACV,MAAA,EAAQ,MAAM,OAAO,4BAAsB,CAAA,CAAE,IAAK,CAAA,CAAA,CAAA,qBAAM,GAAA,CAAA,CAAA,CAAE,MAAF,EAAA,EAAS,CAAE;AAAA;AAEvE,CAAC,CAAA;AAED,MAAM,gBAAA,GAAmB,0BAA0B,IAAK,CAAA;AAAA,EACtD,IAAM,EAAA,YAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,EAAI,EAAA,wBAAA;AAAA,IACJ,OAAA,sBAAU,uBAAwB,EAAA,EAAA,CAAA;AAAA,IAClC,SAAW,EAAA,KAAA;AAAA,IACX,YAAc,EAAA,GAAA;AAAA,IACd,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA;AAMD,MAAM,aAAA,GAAgB,wBAAwB,IAAK,CAAA;AAAA,EACjD,IAAM,EAAA,gBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,WAAW,CAAC,EAAE,QAAS,EAAA,0BACpB,kBACC,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,aAAc,EAAA,EAAA,CAAA;AAAA,MACd;AAAA,KACH,EAAA;AAAA;AAGN,CAAC,CAAA;AAKM,MAAM,sBAAsB,oBAAqB,CAAA;AAAA,EACtD,QAAU,EAAA,KAAA;AAAA,EACV,UAAA,EAAY,CAAC,aAAa;AAC5B,CAAC;AAOM,MAAM,+BAA+B,oBAAqB,CAAA;AAAA,EAC/D,QAAU,EAAA,KAAA;AAAA,EACV,UAAY,EAAA;AAAA,IACV,qBAAqB,IAAK,CAAA;AAAA,MACxB,IAAM,EAAA,yBAAA;AAAA,MACN,MAAQ,EAAA;AAAA,QACN,QAAU,EAAA;AAAA;AACZ,KACD;AAAA;AAEL,CAAC;AAOD,YAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,YAAA;AAAA,EACV,UAAY,EAAA,CAAC,aAAe,EAAA,YAAA,EAAc,gBAAgB,gBAAgB,CAAA;AAAA,EAC1E,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,eAAA;AAAA,IACN,sBAAwB,EAAA;AAAA;AAE5B,CAAC,CAAA;;;;"}
|
|
@@ -115,6 +115,25 @@ class LightspeedApiClient {
|
|
|
115
115
|
const response = await result.json();
|
|
116
116
|
return response.conversations ?? [];
|
|
117
117
|
}
|
|
118
|
+
async stopMessage(requestId) {
|
|
119
|
+
const baseUrl = await this.getBaseUrl();
|
|
120
|
+
const response = await this.fetchApi.fetch(
|
|
121
|
+
`${baseUrl}/v1/query/interrupt`,
|
|
122
|
+
{
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers: {
|
|
125
|
+
"Content-Type": "application/json"
|
|
126
|
+
},
|
|
127
|
+
body: JSON.stringify({ request_id: requestId })
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`failed to stop message, status ${response.status}: ${response.statusText}`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
return await response.json();
|
|
136
|
+
}
|
|
118
137
|
async deleteConversation(conversation_id) {
|
|
119
138
|
const baseUrl = await this.getBaseUrl();
|
|
120
139
|
const response = await this.fetchApi.fetch(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LightspeedApiClient.esm.js","sources":["../../src/api/LightspeedApiClient.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 { ConfigApi, FetchApi } from '@backstage/core-plugin-api';\n\nimport {\n TEMP_CONVERSATION_ID,\n VALID_TOPIC_RESTRICTION_PROVIDER_IDS,\n} from '../const';\nimport { Attachment, CaptureFeedback } from '../types';\nimport { LightspeedAPI } from './api';\n\n/**\n * @public\n * Lightspeed API client options\n */\n\nexport type Options = {\n configApi: ConfigApi;\n fetchApi: FetchApi;\n};\n\n/**\n * @public\n * Lightspeed API client implementation\n */\n\nexport class LightspeedApiClient implements LightspeedAPI {\n private readonly configApi: ConfigApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: Options) {\n this.configApi = options.configApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getBaseUrl() {\n return `${this.configApi.getString('backend.baseUrl')}/api/lightspeed`;\n }\n\n async createMessage(\n prompt: string,\n selectedModel: string,\n selectedProvider: string,\n conversation_id: string,\n attachments: Attachment[],\n ) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v1/query`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n conversation_id:\n conversation_id === TEMP_CONVERSATION_ID\n ? undefined\n : conversation_id,\n model: selectedModel,\n provider: selectedProvider,\n query: prompt,\n attachments,\n }),\n });\n\n if (!response.body) {\n throw new Error('Readable stream is not supported or there is no body.');\n }\n\n if (!response.ok) {\n const body = await response.body.getReader();\n const reader = body.read();\n const decoder = new TextDecoder('utf-8');\n const text = await reader.then(({ done, value }) => {\n if (done) {\n return '';\n }\n return decoder.decode(value);\n });\n const errorMessage = JSON.parse(text);\n if (errorMessage?.error) {\n throw new Error(`failed to create message: ${errorMessage.error}`);\n }\n }\n return response.body.getReader();\n }\n\n private async fetcher(url: string) {\n const response = await this.fetchApi.fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return response;\n }\n\n async isTopicRestrictionEnabled() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v1/shields`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get shields, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n if (!response?.shields || !Array.isArray(response.shields)) {\n return false;\n }\n\n return response.shields.some((shield: any) => {\n const providerId = shield.provider_resource_id;\n\n return VALID_TOPIC_RESTRICTION_PROVIDER_IDS.some(\n validId => providerId.toLowerCase() === validId.toLowerCase(),\n );\n });\n }\n\n async getAllModels() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v1/models`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get models, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n\n return response?.models ? response?.models : [];\n }\n\n async getConversationMessages(conversation_id: string) {\n if (conversation_id === TEMP_CONVERSATION_ID) {\n return [];\n }\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n );\n if (!result.ok) {\n throw new Error(\n `failed to get conversation messages, status ${result.status}: ${result.statusText}`,\n );\n }\n const response = await result.json();\n return response.chat_history ?? [];\n }\n\n async getConversations() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v2/conversations`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get conversation, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n return response.conversations ?? [];\n }\n\n async deleteConversation(conversation_id: string) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n {\n method: 'DELETE',\n headers: {},\n },\n );\n\n if (!response.ok) {\n let errorMessage = `failed to delete conversation, status ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (errorBody?.error) {\n errorMessage = errorBody.error;\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n }\n\n throw new Error(errorMessage);\n }\n return { success: true };\n }\n\n async renameConversation(conversation_id: string, newName: string) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ topic_summary: newName }),\n },\n );\n\n if (!response.ok) {\n let errorMessage = `failed to rename conversation, status ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (errorBody?.error) {\n errorMessage = errorBody.error;\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n }\n\n throw new Error(errorMessage);\n }\n return { success: true };\n }\n\n getFeedbackStatus = async () => {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v1/feedback/status`,\n {\n method: 'GET',\n headers: {},\n },\n );\n\n if (!response.ok) {\n throw new Error(\n `failed to GET feedback status, status ${response.status}: ${response.statusText}`,\n );\n }\n const result = await response.json();\n return result?.status?.enabled ?? false;\n };\n\n captureFeedback = async (payload: CaptureFeedback) => {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v1/feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(\n `failed to capture feedback, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LightspeedApiClient.esm.js","sources":["../../src/api/LightspeedApiClient.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 { ConfigApi, FetchApi } from '@backstage/core-plugin-api';\n\nimport {\n TEMP_CONVERSATION_ID,\n VALID_TOPIC_RESTRICTION_PROVIDER_IDS,\n} from '../const';\nimport { Attachment, CaptureFeedback } from '../types';\nimport { LightspeedAPI } from './api';\n\n/**\n * @public\n * Lightspeed API client options\n */\n\nexport type Options = {\n configApi: ConfigApi;\n fetchApi: FetchApi;\n};\n\n/**\n * @public\n * Lightspeed API client implementation\n */\n\nexport class LightspeedApiClient implements LightspeedAPI {\n private readonly configApi: ConfigApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: Options) {\n this.configApi = options.configApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getBaseUrl() {\n return `${this.configApi.getString('backend.baseUrl')}/api/lightspeed`;\n }\n\n async createMessage(\n prompt: string,\n selectedModel: string,\n selectedProvider: string,\n conversation_id: string,\n attachments: Attachment[],\n ) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v1/query`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n conversation_id:\n conversation_id === TEMP_CONVERSATION_ID\n ? undefined\n : conversation_id,\n model: selectedModel,\n provider: selectedProvider,\n query: prompt,\n attachments,\n }),\n });\n\n if (!response.body) {\n throw new Error('Readable stream is not supported or there is no body.');\n }\n\n if (!response.ok) {\n const body = await response.body.getReader();\n const reader = body.read();\n const decoder = new TextDecoder('utf-8');\n const text = await reader.then(({ done, value }) => {\n if (done) {\n return '';\n }\n return decoder.decode(value);\n });\n const errorMessage = JSON.parse(text);\n if (errorMessage?.error) {\n throw new Error(`failed to create message: ${errorMessage.error}`);\n }\n }\n return response.body.getReader();\n }\n\n private async fetcher(url: string) {\n const response = await this.fetchApi.fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return response;\n }\n\n async isTopicRestrictionEnabled() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v1/shields`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get shields, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n if (!response?.shields || !Array.isArray(response.shields)) {\n return false;\n }\n\n return response.shields.some((shield: any) => {\n const providerId = shield.provider_resource_id;\n\n return VALID_TOPIC_RESTRICTION_PROVIDER_IDS.some(\n validId => providerId.toLowerCase() === validId.toLowerCase(),\n );\n });\n }\n\n async getAllModels() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v1/models`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get models, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n\n return response?.models ? response?.models : [];\n }\n\n async getConversationMessages(conversation_id: string) {\n if (conversation_id === TEMP_CONVERSATION_ID) {\n return [];\n }\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n );\n if (!result.ok) {\n throw new Error(\n `failed to get conversation messages, status ${result.status}: ${result.statusText}`,\n );\n }\n const response = await result.json();\n return response.chat_history ?? [];\n }\n\n async getConversations() {\n const baseUrl = await this.getBaseUrl();\n const result = await this.fetcher(`${baseUrl}/v2/conversations`);\n\n if (!result.ok) {\n throw new Error(\n `failed to get conversation, status ${result.status}: ${result.statusText}`,\n );\n }\n\n const response = await result.json();\n return response.conversations ?? [];\n }\n\n async stopMessage(requestId: string): Promise<{ success: boolean }> {\n const baseUrl = await this.getBaseUrl();\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v1/query/interrupt`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ request_id: requestId }),\n },\n );\n if (!response.ok) {\n throw new Error(\n `failed to stop message, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n async deleteConversation(conversation_id: string) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n {\n method: 'DELETE',\n headers: {},\n },\n );\n\n if (!response.ok) {\n let errorMessage = `failed to delete conversation, status ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (errorBody?.error) {\n errorMessage = errorBody.error;\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n }\n\n throw new Error(errorMessage);\n }\n return { success: true };\n }\n\n async renameConversation(conversation_id: string, newName: string) {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v2/conversations/${encodeURIComponent(conversation_id)}`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ topic_summary: newName }),\n },\n );\n\n if (!response.ok) {\n let errorMessage = `failed to rename conversation, status ${response.status}: ${response.statusText}`;\n\n try {\n const errorBody = await response.json();\n if (errorBody?.error) {\n errorMessage = errorBody.error;\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(e);\n }\n\n throw new Error(errorMessage);\n }\n return { success: true };\n }\n\n getFeedbackStatus = async () => {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(\n `${baseUrl}/v1/feedback/status`,\n {\n method: 'GET',\n headers: {},\n },\n );\n\n if (!response.ok) {\n throw new Error(\n `failed to GET feedback status, status ${response.status}: ${response.statusText}`,\n );\n }\n const result = await response.json();\n return result?.status?.enabled ?? false;\n };\n\n captureFeedback = async (payload: CaptureFeedback) => {\n const baseUrl = await this.getBaseUrl();\n\n const response = await this.fetchApi.fetch(`${baseUrl}/v1/feedback`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n accept: 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(\n `failed to capture feedback, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n };\n}\n"],"names":[],"mappings":"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"}
|