@red-hat-developer-hub/backstage-plugin-lightspeed 2.5.0 → 2.5.1
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 +9 -0
- package/README.md +5 -1
- package/dist/alpha.d.ts +5 -0
- package/dist/components/LightSpeedChat.esm.js +82 -17
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
- package/dist/components/notebooks/AddDocumentModal.esm.js +122 -23
- package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
- package/dist/components/notebooks/DocumentSidebar.esm.js +19 -1
- package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
- package/dist/components/notebooks/FileListItem.esm.js +94 -0
- package/dist/components/notebooks/FileListItem.esm.js.map +1 -0
- package/dist/components/notebooks/NotebookView.esm.js +46 -26
- package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
- package/dist/components/notebooks/OverwriteConfirmModal.esm.js +2 -1
- package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
- package/dist/components/notebooks/SidebarCollapseIcon.esm.js +5 -2
- package/dist/components/notebooks/SidebarCollapseIcon.esm.js.map +1 -1
- package/dist/hooks/toolCallsCacheStore.esm.js +61 -0
- package/dist/hooks/toolCallsCacheStore.esm.js.map +1 -0
- package/dist/hooks/useConversationMessages.esm.js +18 -14
- package/dist/hooks/useConversationMessages.esm.js.map +1 -1
- package/dist/hooks/useDeleteConversation.esm.js +2 -0
- package/dist/hooks/useDeleteConversation.esm.js.map +1 -1
- package/dist/hooks/useLightspeedProviderState.esm.js +35 -8
- package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -1
- package/dist/translations/de.esm.js +5 -0
- package/dist/translations/de.esm.js.map +1 -1
- package/dist/translations/es.esm.js +5 -0
- package/dist/translations/es.esm.js.map +1 -1
- package/dist/translations/fr.esm.js +5 -0
- package/dist/translations/fr.esm.js.map +1 -1
- package/dist/translations/it.esm.js +5 -0
- package/dist/translations/it.esm.js.map +1 -1
- package/dist/translations/ja.esm.js +5 -0
- package/dist/translations/ja.esm.js.map +1 -1
- package/dist/translations/ref.esm.js +5 -0
- package/dist/translations/ref.esm.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## @red-hat-developer-hub/backstage-plugin-lightspeed
|
|
2
2
|
|
|
3
|
+
## 2.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d621f93: Improved notebook upload modal and MessageBar UX.
|
|
8
|
+
- d621f93: Fixed overwrite flow to add duplicate files to the Add Document modal instead of uploading immediately. Reduced notebook delete toast timeout to 2 seconds.
|
|
9
|
+
- 5d17950: Retain Lightspeed chat and tool-call state when the chat UI remounts (for example when switching display mode between embedded and overlay), so the active thread and tool metadata are not dropped while messages are still streaming or before history refetches.
|
|
10
|
+
- @red-hat-developer-hub/backstage-plugin-lightspeed-common@2.5.1
|
|
11
|
+
|
|
3
12
|
## 2.5.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -85,7 +85,11 @@ Lightspeed is a front-end plugin that enables you to interact with any LLM serve
|
|
|
85
85
|
#### Procedure
|
|
86
86
|
|
|
87
87
|
1. Open your Backstage application and select a Lightspeed nav item from the **Navigation**.
|
|
88
|
-
2. Ask
|
|
88
|
+
2. Ask your questions to the Lightspeed chatbot.
|
|
89
|
+
|
|
90
|
+
### Display modes and chat continuity
|
|
91
|
+
|
|
92
|
+
Lightspeed supports multiple **display modes** from Settings (for example overlay, docked, embedded, and fullscreen). Switching modes can remount the chat surface; your **current conversation** and **tool-call metadata** for that thread stay with the session so the active chat is not reset. Live streaming text may not update continuously across a mode switch until the assistant response finishes loading.
|
|
89
93
|
|
|
90
94
|
### MCP servers settings
|
|
91
95
|
|
package/dist/alpha.d.ts
CHANGED
|
@@ -66,10 +66,12 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
66
66
|
readonly "notebook.view.upload.heading": string;
|
|
67
67
|
readonly "notebook.view.upload.action": string;
|
|
68
68
|
readonly "notebook.view.input.placeholder": string;
|
|
69
|
+
readonly "notebook.view.input.disabledTooltip": string;
|
|
69
70
|
readonly "notebook.view.sidebar.collapse": string;
|
|
70
71
|
readonly "notebook.view.sidebar.expand": string;
|
|
71
72
|
readonly "notebook.view.sidebar.resize": string;
|
|
72
73
|
readonly "notebook.view.documents.uploading": string;
|
|
74
|
+
readonly "notebook.view.documents.maxReached": string;
|
|
73
75
|
readonly "notebook.upload.success": string;
|
|
74
76
|
readonly "notebook.upload.failed": string;
|
|
75
77
|
readonly "notebook.upload.modal.title": string;
|
|
@@ -77,6 +79,9 @@ declare const lightspeedTranslationRef: _backstage_frontend_plugin_api.Translati
|
|
|
77
79
|
readonly "notebook.upload.modal.browseButton": string;
|
|
78
80
|
readonly "notebook.upload.modal.separator": string;
|
|
79
81
|
readonly "notebook.upload.modal.infoText": string;
|
|
82
|
+
readonly "notebook.upload.modal.selectedFiles": string;
|
|
83
|
+
readonly "notebook.upload.modal.addButton": string;
|
|
84
|
+
readonly "notebook.upload.modal.removeFile": string;
|
|
80
85
|
readonly "notebook.upload.error.unsupportedType": string;
|
|
81
86
|
readonly "notebook.upload.error.fileTooLarge": string;
|
|
82
87
|
readonly "notebook.upload.error.tooManyFiles": string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useEffect, useRef, useCallback,
|
|
2
|
+
import { useState, useEffect, useRef, useCallback, useLayoutEffect, useMemo } from 'react';
|
|
3
3
|
import { useNavigate, useMatch } from 'react-router-dom';
|
|
4
4
|
import { makeStyles, Button } from '@material-ui/core';
|
|
5
5
|
import { ChatbotDisplayMode, ChatbotContent, ChatbotFooter, MessageBar, ChatbotFootnote, Settings, Chatbot, ChatbotHeader, ChatbotHeaderMain, ChatbotHeaderMenu, ChatbotHeaderTitle, FileDropZone, ChatbotAlert } from '@patternfly/chatbot';
|
|
@@ -452,7 +452,8 @@ const LightspeedChat = ({
|
|
|
452
452
|
currentConversationId: routeConversationId,
|
|
453
453
|
setCurrentConversationId,
|
|
454
454
|
draftMessage,
|
|
455
|
-
setDraftMessage
|
|
455
|
+
setDraftMessage,
|
|
456
|
+
consumePendingOverlayThreadHandoff
|
|
456
457
|
} = useLightspeedDrawerContext();
|
|
457
458
|
const isFullscreenMode = displayMode === ChatbotDisplayMode.embedded;
|
|
458
459
|
const showChatPanel = !isFullscreenMode || activeTab === 0;
|
|
@@ -529,11 +530,44 @@ const LightspeedChat = ({
|
|
|
529
530
|
handleFileUpload,
|
|
530
531
|
setUploadError
|
|
531
532
|
} = useFileAttachmentContext();
|
|
533
|
+
useLayoutEffect(() => {
|
|
534
|
+
if (!isReady) return;
|
|
535
|
+
if (isFullscreenMode) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const handoff = consumePendingOverlayThreadHandoff?.() ?? false;
|
|
539
|
+
if (handoff) {
|
|
540
|
+
if (routeConversationId) {
|
|
541
|
+
setConversationId(routeConversationId);
|
|
542
|
+
setNewChatCreated(false);
|
|
543
|
+
} else {
|
|
544
|
+
setConversationId(TEMP_CONVERSATION_ID);
|
|
545
|
+
setNewChatCreated(true);
|
|
546
|
+
}
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (routeConversationId && routeConversationId !== conversationId) {
|
|
550
|
+
setConversationId(routeConversationId);
|
|
551
|
+
setNewChatCreated(false);
|
|
552
|
+
} else if (!routeConversationId && conversationId === "" && lastOpenedId !== null) {
|
|
553
|
+
setConversationId(lastOpenedId);
|
|
554
|
+
}
|
|
555
|
+
}, [
|
|
556
|
+
isReady,
|
|
557
|
+
isFullscreenMode,
|
|
558
|
+
routeConversationId,
|
|
559
|
+
conversationId,
|
|
560
|
+
lastOpenedId,
|
|
561
|
+
consumePendingOverlayThreadHandoff
|
|
562
|
+
]);
|
|
532
563
|
useEffect(() => {
|
|
533
|
-
if (isReady
|
|
564
|
+
if (!isReady || !isFullscreenMode) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (lastOpenedId !== null) {
|
|
534
568
|
setConversationId(lastOpenedId);
|
|
535
569
|
}
|
|
536
|
-
}, [lastOpenedId, isReady]);
|
|
570
|
+
}, [lastOpenedId, isReady, isFullscreenMode]);
|
|
537
571
|
const queryClient = useQueryClient();
|
|
538
572
|
const {
|
|
539
573
|
data: conversations = [],
|
|
@@ -545,27 +579,53 @@ const LightspeedChat = ({
|
|
|
545
579
|
const samplePrompts = useWelcomePrompts();
|
|
546
580
|
useEffect(() => {
|
|
547
581
|
if (!user || !isReady) return;
|
|
582
|
+
const onOverlayLikeSurface = isFullscreenMode || !routeConversationId;
|
|
583
|
+
const stillOnProvisionalThread = !conversationId || conversationId === TEMP_CONVERSATION_ID;
|
|
548
584
|
if (lastOpenedId === null) {
|
|
549
|
-
|
|
585
|
+
if (onOverlayLikeSurface && stillOnProvisionalThread) {
|
|
586
|
+
setConversationId(TEMP_CONVERSATION_ID);
|
|
587
|
+
}
|
|
550
588
|
}
|
|
551
589
|
if (lastOpenedId === TEMP_CONVERSATION_ID || lastOpenedId === null) {
|
|
552
|
-
|
|
590
|
+
if (onOverlayLikeSurface && stillOnProvisionalThread) {
|
|
591
|
+
setNewChatCreated(true);
|
|
592
|
+
}
|
|
553
593
|
}
|
|
554
|
-
}, [
|
|
594
|
+
}, [
|
|
595
|
+
user,
|
|
596
|
+
isReady,
|
|
597
|
+
lastOpenedId,
|
|
598
|
+
setConversationId,
|
|
599
|
+
isFullscreenMode,
|
|
600
|
+
routeConversationId,
|
|
601
|
+
conversationId
|
|
602
|
+
]);
|
|
555
603
|
useEffect(() => {
|
|
556
604
|
if (!isLoading && !isRefetching && conversations.length === 0 && lastOpenedId) {
|
|
557
605
|
clearLastOpenedId();
|
|
606
|
+
setConversationId(TEMP_CONVERSATION_ID);
|
|
607
|
+
setNewChatCreated(true);
|
|
608
|
+
setCurrentConversationId(undefined);
|
|
558
609
|
}
|
|
559
|
-
}, [
|
|
610
|
+
}, [
|
|
611
|
+
isLoading,
|
|
612
|
+
isRefetching,
|
|
613
|
+
conversations,
|
|
614
|
+
lastOpenedId,
|
|
615
|
+
clearLastOpenedId,
|
|
616
|
+
setCurrentConversationId
|
|
617
|
+
]);
|
|
560
618
|
useEffect(() => {
|
|
561
619
|
if (!isLoading && !isRefetching && routeConversationId && isFullscreenMode) {
|
|
562
620
|
const conversationExists = conversations.some(
|
|
563
621
|
(c) => c.conversation_id === routeConversationId
|
|
564
622
|
);
|
|
565
623
|
if (!conversationExists) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
624
|
+
if (routeConversationId !== conversationId) {
|
|
625
|
+
setConversationId(TEMP_CONVERSATION_ID);
|
|
626
|
+
setCurrentConversationId(undefined);
|
|
627
|
+
setNewChatCreated(true);
|
|
628
|
+
}
|
|
569
629
|
} else if (conversationId !== routeConversationId) {
|
|
570
630
|
setConversationId(routeConversationId);
|
|
571
631
|
}
|
|
@@ -585,6 +645,10 @@ const LightspeedChat = ({
|
|
|
585
645
|
setLastOpenedId(conversationId);
|
|
586
646
|
}
|
|
587
647
|
}, [conversationId, setLastOpenedId]);
|
|
648
|
+
const viewConversationId = useMemo(
|
|
649
|
+
() => !isFullscreenMode && routeConversationId ? routeConversationId : conversationId,
|
|
650
|
+
[isFullscreenMode, routeConversationId, conversationId]
|
|
651
|
+
);
|
|
588
652
|
const onStart = (conv_id) => {
|
|
589
653
|
setConversationId(conv_id);
|
|
590
654
|
setCurrentConversationId(conv_id);
|
|
@@ -602,12 +666,12 @@ const LightspeedChat = ({
|
|
|
602
666
|
queryKey: ["conversations"]
|
|
603
667
|
});
|
|
604
668
|
queryClient.invalidateQueries({
|
|
605
|
-
queryKey: ["conversationMessages",
|
|
669
|
+
queryKey: ["conversationMessages", viewConversationId]
|
|
606
670
|
});
|
|
607
671
|
setNewChatCreated(false);
|
|
608
672
|
};
|
|
609
673
|
const { conversationMessages, handleInputPrompt, scrollToBottomRef } = useConversationMessages(
|
|
610
|
-
|
|
674
|
+
viewConversationId,
|
|
611
675
|
userName,
|
|
612
676
|
selectedModel,
|
|
613
677
|
selectedProvider,
|
|
@@ -621,7 +685,7 @@ const LightspeedChat = ({
|
|
|
621
685
|
const sendMessage = (message) => {
|
|
622
686
|
if (!message.toString().trim()) return;
|
|
623
687
|
wasStoppedByUserRef.current = false;
|
|
624
|
-
if (
|
|
688
|
+
if (viewConversationId !== TEMP_CONVERSATION_ID) {
|
|
625
689
|
setNewChatCreated(false);
|
|
626
690
|
}
|
|
627
691
|
setAnnouncement(
|
|
@@ -839,7 +903,7 @@ const LightspeedChat = ({
|
|
|
839
903
|
]
|
|
840
904
|
);
|
|
841
905
|
const conversationFound = !!conversations.find(
|
|
842
|
-
(c) => c.conversation_id ===
|
|
906
|
+
(c) => c.conversation_id === viewConversationId
|
|
843
907
|
);
|
|
844
908
|
const getMaxPrompts = () => {
|
|
845
909
|
if (isFullscreenMode) {
|
|
@@ -1217,7 +1281,7 @@ const LightspeedChat = ({
|
|
|
1217
1281
|
variant: AlertVariant[variant ?? "success"],
|
|
1218
1282
|
title,
|
|
1219
1283
|
className: classes.toastAlert,
|
|
1220
|
-
timeout:
|
|
1284
|
+
timeout: 2e3,
|
|
1221
1285
|
onTimeout: () => handleRemoveNotebookAlert(key),
|
|
1222
1286
|
actionClose: /* @__PURE__ */ jsx(
|
|
1223
1287
|
AlertActionCloseButton,
|
|
@@ -1342,7 +1406,7 @@ const LightspeedChat = ({
|
|
|
1342
1406
|
"aria-label": t("aria.closeDrawerPanel")
|
|
1343
1407
|
},
|
|
1344
1408
|
setIsDrawerOpen: setIsChatHistoryDrawerOpen,
|
|
1345
|
-
activeItemId:
|
|
1409
|
+
activeItemId: viewConversationId,
|
|
1346
1410
|
onSelectActiveItem,
|
|
1347
1411
|
conversations: filterConversations(filterValue),
|
|
1348
1412
|
onNewChat: newChatCreated ? undefined : onNewChat,
|
|
@@ -1406,6 +1470,7 @@ const LightspeedChat = ({
|
|
|
1406
1470
|
avatar,
|
|
1407
1471
|
profileLoading,
|
|
1408
1472
|
topicRestrictionEnabled,
|
|
1473
|
+
selectedModel,
|
|
1409
1474
|
onClose: handleCloseNotebook
|
|
1410
1475
|
}
|
|
1411
1476
|
),
|