@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.2.0 → 5.3.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +14 -2
  3. package/dist/alpha.d.ts +24 -0
  4. package/dist/components/AttachmentContext.esm.js +1 -1
  5. package/dist/components/ChatLoadingFallback.esm.js +37 -0
  6. package/dist/components/ChatLoadingFallback.esm.js.map +1 -0
  7. package/dist/components/CollapsedHistoryStrip.esm.js +1 -1
  8. package/dist/components/LightSpeedChat.esm.js +76 -29
  9. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  10. package/dist/components/LightspeedChatBox.esm.js +2 -2
  11. package/dist/components/LightspeedChatBoxHeader.esm.js +30 -2
  12. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatContainer.esm.js +20 -4
  14. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  15. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  16. package/dist/components/LightspeedDrawerProvider.esm.js +11 -25
  17. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  18. package/dist/components/LightspeedFABContent.esm.js +14 -2
  19. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  20. package/dist/components/LightspeedOverlayChat.esm.js +39 -0
  21. package/dist/components/LightspeedOverlayChat.esm.js.map +1 -0
  22. package/dist/components/McpConfigureServerModal.esm.js +2 -2
  23. package/dist/components/MessageBarModelSelector.esm.js +105 -13
  24. package/dist/components/MessageBarModelSelector.esm.js.map +1 -1
  25. package/dist/components/ScreenContextChip.esm.js +172 -0
  26. package/dist/components/ScreenContextChip.esm.js.map +1 -0
  27. package/dist/components/ToastAlertGroup.esm.js +1 -1
  28. package/dist/components/criticalFabBundle.esm.js +3 -0
  29. package/dist/components/criticalFabBundle.esm.js.map +1 -0
  30. package/dist/components/loaders.esm.js +11 -0
  31. package/dist/components/loaders.esm.js.map +1 -0
  32. package/dist/components/notebooks/AddDocumentModal.esm.js +2 -2
  33. package/dist/components/notebooks/DocumentSidebar.esm.js +1 -1
  34. package/dist/components/notebooks/NotebookCard.esm.js +1 -1
  35. package/dist/components/notebooks/NotebookStreamProvider.esm.js +1 -1
  36. package/dist/components/notebooks/NotebookView.esm.js +3 -3
  37. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +1 -1
  38. package/dist/components/notebooks/UploadResourceScreen.esm.js +1 -1
  39. package/dist/components/notebooks/notebookStreamStore.esm.js +1 -1
  40. package/dist/components/notebooks/notebookStreamStore.esm.js.map +1 -1
  41. package/dist/const.esm.js +9 -1
  42. package/dist/const.esm.js.map +1 -1
  43. package/dist/fabModule.esm.js +51 -0
  44. package/dist/fabModule.esm.js.map +1 -0
  45. package/dist/hooks/screenContextLabelSubscription.esm.js +113 -0
  46. package/dist/hooks/screenContextLabelSubscription.esm.js.map +1 -0
  47. package/dist/hooks/useConversationMessages.esm.js +2 -1
  48. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  49. package/dist/hooks/useDisplayModeSettings.esm.js +1 -1
  50. package/dist/hooks/useDisplayModeSettings.esm.js.map +1 -1
  51. package/dist/hooks/useLightspeedProviderState.esm.js +1 -2
  52. package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -1
  53. package/dist/hooks/useScreenContextLabelRevision.esm.js +13 -0
  54. package/dist/hooks/useScreenContextLabelRevision.esm.js.map +1 -0
  55. package/dist/hooks/useScreenContextSettings.esm.js +110 -0
  56. package/dist/hooks/useScreenContextSettings.esm.js.map +1 -0
  57. package/dist/hooks/useWindowLocation.esm.js +28 -0
  58. package/dist/hooks/useWindowLocation.esm.js.map +1 -0
  59. package/dist/index.d.ts +1 -15
  60. package/dist/index.esm.js +7 -69
  61. package/dist/index.esm.js.map +1 -1
  62. package/dist/intelligent-assistant-fab-module.d.ts +12 -4
  63. package/dist/intelligent-assistant-fab-module.esm.js +1 -1
  64. package/dist/intelligent-assistant-translations-module.d.ts +10 -4
  65. package/dist/intelligent-assistant-translations-module.esm.js +1 -1
  66. package/dist/lazy/LazyLightspeedChatDrawerContent.esm.js +13 -0
  67. package/dist/lazy/LazyLightspeedChatDrawerContent.esm.js.map +1 -0
  68. package/dist/lazy/LazyLightspeedFabRootWrapper.esm.js +17 -0
  69. package/dist/lazy/LazyLightspeedFabRootWrapper.esm.js.map +1 -0
  70. package/dist/legacy.d.ts +14 -16
  71. package/dist/legacy.esm.js +2 -9
  72. package/dist/legacy.esm.js.map +1 -1
  73. package/dist/loadChatPatternflyStyles.esm.js +14 -0
  74. package/dist/loadChatPatternflyStyles.esm.js.map +1 -0
  75. package/dist/muiClassNameConfig.esm.js +6 -0
  76. package/dist/muiClassNameConfig.esm.js.map +1 -0
  77. package/dist/plugin.esm.js +4 -4
  78. package/dist/plugin.esm.js.map +1 -1
  79. package/dist/translations/de.esm.js +24 -0
  80. package/dist/translations/de.esm.js.map +1 -1
  81. package/dist/translations/es.esm.js +24 -0
  82. package/dist/translations/es.esm.js.map +1 -1
  83. package/dist/translations/fr.esm.js +24 -0
  84. package/dist/translations/fr.esm.js.map +1 -1
  85. package/dist/translations/it.esm.js +24 -0
  86. package/dist/translations/it.esm.js.map +1 -1
  87. package/dist/translations/ja.esm.js +24 -0
  88. package/dist/translations/ja.esm.js.map +1 -1
  89. package/dist/translations/ref.esm.js +24 -0
  90. package/dist/translations/ref.esm.js.map +1 -1
  91. package/dist/translationsModule.esm.js +18 -0
  92. package/dist/translationsModule.esm.js.map +1 -0
  93. package/dist/types.esm.js.map +1 -1
  94. package/dist/utils/dom-selectors.esm.js +22 -2
  95. package/dist/utils/dom-selectors.esm.js.map +1 -1
  96. package/dist/utils/lightspeed-chatbox-message-utils.esm.js +145 -0
  97. package/dist/utils/lightspeed-chatbox-message-utils.esm.js.map +1 -0
  98. package/dist/utils/lightspeed-chatbox-utils.esm.js +20 -144
  99. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  100. package/dist/utils/screen-capture.esm.js +116 -0
  101. package/dist/utils/screen-capture.esm.js.map +1 -0
  102. package/dist/utils/screen-context-utils.esm.js +343 -0
  103. package/dist/utils/screen-context-utils.esm.js.map +1 -0
  104. package/dist/utils/sensitive-data-redactor.esm.js +39 -1
  105. package/dist/utils/sensitive-data-redactor.esm.js.map +1 -1
  106. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-intelligent-assistant
2
2
 
3
+ ## 5.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9dc3351: Split Module Federation entry points and lazy-load chat UI so NFS, FAB, and translations remotes ship minimal synchronous bundles.
8
+ - @red-hat-developer-hub/backstage-plugin-intelligent-assistant-common@5.3.1
9
+
10
+ ## 5.3.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 0f9a3e8: Add screen context UX: kebab opt-in, context chip (recording/paused/unavailable), and gated DOM and screenshot attachments on send per RHIDP-14319.
15
+
16
+ ### Patch Changes
17
+
18
+ - 2bebbeb: Updated dependency `prettier` to `3.9.8`.
19
+ - 22ab37c: Updated dependency `prettier` to `3.9.7`.
20
+ - Updated dependencies [2bebbeb]
21
+ - Updated dependencies [22ab37c]
22
+ - @red-hat-developer-hub/backstage-plugin-intelligent-assistant-common@5.3.0
23
+
3
24
  ## 5.2.0
4
25
 
5
26
  ### Minor Changes
package/README.md CHANGED
@@ -161,7 +161,18 @@ Intelligent assistant supports multiple **display modes** from Settings (for exa
161
161
 
162
162
  ### Screen Context
163
163
 
164
- When enabled, the assistant automatically captures structured page context from the current RHDH viewport and attaches it to each message. This provides the LLM with headings, tables, alerts, form fields, filters, and other on-screen content for more accurate, context-aware responses.
164
+ Screen context attaches structured page content from the current RHDH viewport to chat messages (headings, tables, alerts, form fields, filters, and optional screenshots) so the LLM can give more accurate, context-aware responses.
165
+
166
+ Enablement has two levels:
167
+
168
+ 1. **Administrator** — set `screen-context.enabled: true` in `app-config.yaml` (default: `false`).
169
+ 2. **User** — opt in from the chatbot options (kebab) menu with **Enable screen context**. Sharing is off until the user opts in.
170
+
171
+ When sharing is on, a **context chip** in the message bar shows the current page label and state:
172
+
173
+ - **Recording** — context will be attached on send; click the chip to pause.
174
+ - **Paused** — context is not attached; click to resume.
175
+ - **Unavailable** — fullscreen mode; switch to Overlay or Docked to use screen context.
165
176
 
166
177
  Configure in `app-config.yaml`:
167
178
 
@@ -176,7 +187,8 @@ intelligent-assistant:
176
187
  maxChars: 8000 # Max characters extracted per page (default: 8000)
177
188
  ```
178
189
 
179
- - `screen-context.enabled` — enables the full screen-context feature (DOM extraction and optional screenshots).
190
+ - `screen-context.enabled` — enables the full screen-context feature (DOM extraction and optional screenshots). Users must still opt in via the kebab menu.
191
+ - `screen-context.screenshots.enabled` — toggles screenshot capture. Screenshots are only attached when the selected model supports vision (`supportsVision`).
180
192
  - `screen-context.dom-extraction.enabled` — toggles DOM text extraction independently of screenshots.
181
193
  - `screen-context.dom-extraction.maxChars` — caps the extracted text size to control LLM token usage.
182
194
 
package/dist/alpha.d.ts CHANGED
@@ -144,6 +144,9 @@ declare const intelligentAssistantTranslationRef: _backstage_frontend_plugin_api
144
144
  readonly 'chatbox.fileUpload.failed': string;
145
145
  readonly 'chatbox.fileUpload.infoText': string;
146
146
  readonly 'modelSelector.disabledTooltip': string;
147
+ readonly 'modelSelector.visionScreenshot.line1': string;
148
+ readonly 'modelSelector.visionScreenshot.line2': string;
149
+ readonly 'modelSelector.visionScreenshot.ariaLabel': string;
147
150
  readonly 'aria.chatbotSelector': string;
148
151
  readonly 'aria.important': string;
149
152
  readonly 'aria.chatHistoryMenu': string;
@@ -223,6 +226,27 @@ declare const intelligentAssistantTranslationRef: _backstage_frontend_plugin_api
223
226
  readonly 'settings.savedPrompts.disable': string;
224
227
  readonly 'settings.savedPrompts.enabled.description': string;
225
228
  readonly 'settings.savedPrompts.disabled.description': string;
229
+ readonly 'settings.screenContext.enable': string;
230
+ readonly 'settings.screenContext.disable': string;
231
+ readonly 'settings.screenContext.enabled.description': string;
232
+ readonly 'settings.screenContext.disabled.description': string;
233
+ readonly 'contextChip.label.paused': string;
234
+ readonly 'contextChip.label.unavailable': string;
235
+ readonly 'contextChip.label.softwareTemplates': string;
236
+ readonly 'contextChip.tooltip.askAbout': string;
237
+ readonly 'contextChip.tooltip.template': string;
238
+ readonly 'contextChip.tooltip.search': string;
239
+ readonly 'contextChip.tooltip.paused': string;
240
+ readonly 'contextChip.tooltip.unavailable': string;
241
+ readonly 'contextChip.tooltip.line2.fullContext': string;
242
+ readonly 'contextChip.tooltip.line2.adminLimited': string;
243
+ readonly 'contextChip.tooltip.line2.screenshotOnly': string;
244
+ readonly 'contextChip.tooltip.line2.domOffNoVision': string;
245
+ readonly 'contextChip.tooltip.line2.textOnlyNoVision': string;
246
+ readonly 'contextChip.tooltip.line2.textOnlyAdminScreenshotsOff': string;
247
+ readonly 'contextChip.tooltip.line2.textOnlyCombined': string;
248
+ readonly 'contextChip.aria.pause': string;
249
+ readonly 'contextChip.aria.resume': string;
226
250
  readonly 'settings.panel.title': string;
227
251
  readonly 'settings.mcp.label': string;
228
252
  readonly 'settings.prompt.label': string;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createContext, useState, useEffect, useContext } from 'react';
2
+ import { useState, useEffect, createContext, useContext } from 'react';
3
3
  import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.esm.js';
4
4
  import { useTranslation } from '../hooks/useTranslation.esm.js';
5
5
  import { isSupportedFileType, readFileAsText } from '../utils/attachment-utils.esm.js';
@@ -0,0 +1,37 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import Box from '@mui/material/Box';
3
+ import LinearProgress from '@mui/material/LinearProgress';
4
+ import { LIGHTSPEED_OVERLAY_MAX_WIDTH, LIGHTSPEED_OVERLAY_RIGHT, LIGHTSPEED_OVERLAY_BOTTOM } from '../const.esm.js';
5
+
6
+ const ChatLoadingFallback = ({ variant = "default" }) => {
7
+ const isOverlay = variant === "overlay";
8
+ return /* @__PURE__ */ jsx(
9
+ Box,
10
+ {
11
+ role: "status",
12
+ "aria-busy": "true",
13
+ "aria-label": "Loading chat",
14
+ "data-testid": "chat-loading-fallback",
15
+ sx: isOverlay ? {
16
+ position: "fixed",
17
+ zIndex: 300,
18
+ bottom: LIGHTSPEED_OVERLAY_BOTTOM,
19
+ right: LIGHTSPEED_OVERLAY_RIGHT,
20
+ width: LIGHTSPEED_OVERLAY_MAX_WIDTH,
21
+ maxWidth: "100vw",
22
+ p: 1.5,
23
+ borderRadius: 1,
24
+ bgcolor: "background.paper",
25
+ boxShadow: 3
26
+ } : {
27
+ width: "100%",
28
+ p: 2,
29
+ boxSizing: "border-box"
30
+ },
31
+ children: /* @__PURE__ */ jsx(LinearProgress, {})
32
+ }
33
+ );
34
+ };
35
+
36
+ export { ChatLoadingFallback };
37
+ //# sourceMappingURL=ChatLoadingFallback.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatLoadingFallback.esm.js","sources":["../../src/components/ChatLoadingFallback.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 Box from '@mui/material/Box';\nimport LinearProgress from '@mui/material/LinearProgress';\n\nimport {\n LIGHTSPEED_OVERLAY_BOTTOM,\n LIGHTSPEED_OVERLAY_MAX_WIDTH,\n LIGHTSPEED_OVERLAY_RIGHT,\n} from '../const';\n\ntype Props = {\n variant?: 'default' | 'overlay';\n};\n\n/** Immediate loading feedback while chat chunks / PF CSS load (MUI, no PF). */\nexport const ChatLoadingFallback = ({ variant = 'default' }: Props) => {\n const isOverlay = variant === 'overlay';\n\n return (\n <Box\n role=\"status\"\n aria-busy=\"true\"\n aria-label=\"Loading chat\"\n data-testid=\"chat-loading-fallback\"\n sx={\n isOverlay\n ? {\n position: 'fixed',\n zIndex: 300,\n bottom: LIGHTSPEED_OVERLAY_BOTTOM,\n right: LIGHTSPEED_OVERLAY_RIGHT,\n width: LIGHTSPEED_OVERLAY_MAX_WIDTH,\n maxWidth: '100vw',\n p: 1.5,\n borderRadius: 1,\n bgcolor: 'background.paper',\n boxShadow: 3,\n }\n : {\n width: '100%',\n p: 2,\n boxSizing: 'border-box',\n }\n }\n >\n <LinearProgress />\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;AA8BO,MAAM,mBAAA,GAAsB,CAAC,EAAE,OAAA,GAAU,WAAU,KAAa;AACrE,EAAA,MAAM,YAAY,OAAA,KAAY,SAAA;AAE9B,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,MAAA;AAAA,MACV,YAAA,EAAW,cAAA;AAAA,MACX,aAAA,EAAY,uBAAA;AAAA,MACZ,IACE,SAAA,GACI;AAAA,QACE,QAAA,EAAU,OAAA;AAAA,QACV,MAAA,EAAQ,GAAA;AAAA,QACR,MAAA,EAAQ,yBAAA;AAAA,QACR,KAAA,EAAO,wBAAA;AAAA,QACP,KAAA,EAAO,4BAAA;AAAA,QACP,QAAA,EAAU,OAAA;AAAA,QACV,CAAA,EAAG,GAAA;AAAA,QACH,YAAA,EAAc,CAAA;AAAA,QACd,OAAA,EAAS,kBAAA;AAAA,QACT,SAAA,EAAW;AAAA,OACb,GACA;AAAA,QACE,KAAA,EAAO,MAAA;AAAA,QACP,CAAA,EAAG,CAAA;AAAA,QACH,SAAA,EAAW;AAAA,OACb;AAAA,MAGN,8BAAC,cAAA,EAAA,EAAe;AAAA;AAAA,GAClB;AAEJ;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { styled } from '@mui/material/styles';
3
- import { Button, Tooltip } from '@patternfly/react-core';
3
+ import { Tooltip, Button } from '@patternfly/react-core';
4
4
  import { PenIcon } from '@patternfly/react-icons';
5
5
  import { useTranslation } from '../hooks/useTranslation.esm.js';
6
6
  import { SidebarExpandIcon } from './notebooks/SidebarCollapseIcon.esm.js';
@@ -5,9 +5,9 @@ import { useApi, configApiRef } from '@backstage/core-plugin-api';
5
5
  import { styled } from '@mui/material/styles';
6
6
  import Tab from '@mui/material/Tab';
7
7
  import Tabs from '@mui/material/Tabs';
8
- import { Chatbot, ChatbotHeader, ChatbotHeaderTitle, ChatbotFooter, MessageBar, ChatbotContent, Settings, ChatbotDisplayMode, ChatbotHeaderMain, ChatbotAlert, FileDropZone } from '@patternfly/chatbot';
8
+ import { ChatbotDisplayMode, ChatbotHeaderMain, ChatbotAlert, ChatbotContent, ChatbotFooter, MessageBar, Chatbot, ChatbotHeader, ChatbotHeaderTitle, FileDropZone, Settings } from '@patternfly/chatbot';
9
9
  import ChatbotConversationHistoryNav from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
10
- import { SelectList, DropdownItem, Tooltip, MenuToggle, Select, SelectOption, Button, Title, Label } from '@patternfly/react-core';
10
+ import { DropdownItem, Tooltip, MenuToggle, Select, SelectOption, Button, Title, Label, SelectList } from '@patternfly/react-core';
11
11
  import { PenIcon, ThumbtackIcon, TrashIcon, SortAmountDownAltIcon, SortAmountDownIcon, PlusIcon, SearchIcon } from '@patternfly/react-icons';
12
12
  import { RhUiAiExperienceIcon } from '@patternfly/react-icons/dist/esm/icons/rh-ui-ai-experience-icon';
13
13
  import { useQueryClient } from '@tanstack/react-query';
@@ -29,6 +29,8 @@ import { useNotebookConversationIds } from '../hooks/useNotebookConversationIds.
29
29
  import { useNotebookSession } from '../hooks/notebooks/useNotebookSession.esm.js';
30
30
  import { useNotebookSessions } from '../hooks/notebooks/useNotebookSessions.esm.js';
31
31
  import { usePinnedChatsSettings } from '../hooks/usePinnedChatsSettings.esm.js';
32
+ import { useScreenContextSettings } from '../hooks/useScreenContextSettings.esm.js';
33
+ import { buildScreenContextAttachments } from '../utils/screen-context-utils.esm.js';
32
34
  import { useSavedPromptsSettings } from '../hooks/useSavedPromptsSettings.esm.js';
33
35
  import { useSavedPrompts } from '../hooks/useSavedPrompts.esm.js';
34
36
  import { useSavedPromptActions } from '../hooks/useSavedPromptActions.esm.js';
@@ -44,7 +46,6 @@ import { useLightspeedDrawerContext } from '../hooks/useLightspeedDrawerContext.
44
46
  import { useWelcomePrompts } from '../hooks/useWelcomePrompts.esm.js';
45
47
  import { getAttachments } from '../utils/attachment-utils.esm.js';
46
48
  import { isSavedPromptConversationId, SAVED_PROMPT_CONVERSATION_ID_PREFIX } from '../utils/buildConversationHistoryGroups.esm.js';
47
- import { extractPageContext } from '../utils/dom-extractor.esm.js';
48
49
  import { getCategorizeMessages, ChatbotFootnoteWithIcon, getFootnoteProps } from '../utils/lightspeed-chatbox-utils.esm.js';
49
50
  import Attachment from './Attachment.esm.js';
50
51
  import { useFileAttachmentContext } from './AttachmentContext.esm.js';
@@ -63,6 +64,7 @@ import { NotebookView } from './notebooks/NotebookView.esm.js';
63
64
  import { SidebarCollapseIcon, SidebarExpandIcon } from './notebooks/SidebarCollapseIcon.esm.js';
64
65
  import { RenameConversationModal } from './RenameConversationModal.esm.js';
65
66
  import { SavedPromptMenuItems } from './SavedPromptMenuItems.esm.js';
67
+ import { ScreenContextChip } from './ScreenContextChip.esm.js';
66
68
  import { SettingsPanel } from './SettingsPanel.esm.js';
67
69
  import { ToastAlertGroup } from './ToastAlertGroup.esm.js';
68
70
 
@@ -237,6 +239,14 @@ const StyledMessageBar = styled(MessageBar)(({ theme }) => ({
237
239
  display: "none"
238
240
  }
239
241
  }));
242
+ const MessageBarActionsRow = styled("div")({
243
+ display: "flex",
244
+ flex: "1 1 0",
245
+ minWidth: 0,
246
+ overflow: "hidden",
247
+ alignItems: "center",
248
+ gap: 8
249
+ });
240
250
  const StyledSelectList = styled(SelectList)({
241
251
  padding: 0,
242
252
  margin: 0
@@ -463,6 +473,9 @@ const LightspeedChat = ({
463
473
  const domExtractionMaxChars = configApi.getOptionalNumber(
464
474
  "intelligent-assistant.screen-context.dom-extraction.maxChars"
465
475
  ) ?? 8e3;
476
+ const screenshotsEnabled = configApi.getOptionalBoolean(
477
+ "intelligent-assistant.screen-context.screenshots.enabled"
478
+ ) ?? true;
466
479
  const notebooksRouteMatch = useMatch(`${LIGHTSPEED_PATH}/notebooks`);
467
480
  const notebookViewRouteMatch = useMatch(
468
481
  `${LIGHTSPEED_PATH}/notebooks/:notebookId`
@@ -816,6 +829,22 @@ const LightspeedChat = ({
816
829
  unpinChat
817
830
  } = usePinnedChatsSettings(user);
818
831
  const { isSavedPromptsEnabled, handleSavedPromptsToggle } = useSavedPromptsSettings(user);
832
+ const {
833
+ isScreenContextSharingEnabled,
834
+ isScreenContextPaused,
835
+ handleScreenContextSharingToggle,
836
+ toggleScreenContextPaused
837
+ } = useScreenContextSettings(user);
838
+ const selectedModelSupportsVision = useMemo(
839
+ () => models.find((m) => m.value === selectedModel)?.supportsVision ?? false,
840
+ [models, selectedModel]
841
+ );
842
+ let screenContextChipState = "recording";
843
+ if (isFullscreenMode) {
844
+ screenContextChipState = "unavailable";
845
+ } else if (isScreenContextPaused) {
846
+ screenContextChipState = "paused";
847
+ }
819
848
  const { selectedSort, handleSortChange } = useSortSettings(user);
820
849
  const {
821
850
  uploadError,
@@ -1004,26 +1033,28 @@ const LightspeedChat = ({
1004
1033
  prompt: message.toString()
1005
1034
  })
1006
1035
  );
1007
- const allAttachments = getAttachments(fileContents);
1008
- if (screenContextEnabled && domExtractionEnabled) {
1036
+ const messageText = message.toString();
1037
+ setIsSendButtonDisabled(true);
1038
+ void (async () => {
1039
+ const allAttachments = getAttachments(fileContents);
1009
1040
  try {
1010
- const domContext = extractPageContext({
1011
- maxChars: domExtractionMaxChars
1041
+ const screenAttachments = await buildScreenContextAttachments({
1042
+ adminEnabled: screenContextEnabled,
1043
+ sharingEnabled: isScreenContextSharingEnabled,
1044
+ paused: isScreenContextPaused,
1045
+ isFullscreen: isFullscreenMode,
1046
+ domEnabled: domExtractionEnabled,
1047
+ screenshotsEnabled,
1048
+ supportsVision: selectedModelSupportsVision,
1049
+ domExtractionMaxChars
1012
1050
  });
1013
- if (domContext) {
1014
- allAttachments.push({
1015
- attachment_type: "configuration",
1016
- content_type: "text/plain",
1017
- content: domContext
1018
- });
1019
- }
1051
+ allAttachments.push(...screenAttachments);
1020
1052
  } catch {
1021
1053
  }
1022
- }
1023
- handleInputPrompt(message.toString(), allAttachments);
1024
- setIsSendButtonDisabled(true);
1025
- setFileContents([]);
1026
- setDraftMessage("");
1054
+ handleInputPrompt(messageText, allAttachments);
1055
+ setFileContents([]);
1056
+ setDraftMessage("");
1057
+ })();
1027
1058
  };
1028
1059
  const handleApplySavedPrompt = useCallback(
1029
1060
  (content) => {
@@ -1561,16 +1592,28 @@ const LightspeedChat = ({
1561
1592
  tooltipContent: t("tooltip.send")
1562
1593
  }
1563
1594
  },
1564
- additionalActions: /* @__PURE__ */ jsx(
1565
- MessageBarModelSelector,
1566
- {
1567
- selectedModel,
1568
- models,
1569
- onSelect: handleSelectedModel,
1570
- disabled: isSendButtonDisabled || messages.length > 0,
1571
- disabledTooltip: t("modelSelector.disabledTooltip")
1572
- }
1573
- ),
1595
+ additionalActions: /* @__PURE__ */ jsxs(MessageBarActionsRow, { children: [
1596
+ /* @__PURE__ */ jsx(
1597
+ MessageBarModelSelector,
1598
+ {
1599
+ selectedModel,
1600
+ models,
1601
+ onSelect: handleSelectedModel,
1602
+ disabled: isSendButtonDisabled || messages.length > 0,
1603
+ disabledTooltip: t("modelSelector.disabledTooltip")
1604
+ }
1605
+ ),
1606
+ screenContextEnabled && isScreenContextSharingEnabled && showChatPanel && /* @__PURE__ */ jsx(
1607
+ ScreenContextChip,
1608
+ {
1609
+ state: screenContextChipState,
1610
+ domEnabled: domExtractionEnabled,
1611
+ screenshotsEnabled,
1612
+ supportsVision: selectedModelSupportsVision,
1613
+ onTogglePaused: toggleScreenContextPaused
1614
+ }
1615
+ )
1616
+ ] }),
1574
1617
  forceMultilineLayout: true,
1575
1618
  allowedFileTypes: supportedFileTypes,
1576
1619
  onAttachRejected,
@@ -1677,6 +1720,7 @@ const LightspeedChat = ({
1677
1720
  isCompact: !isFullscreenMode,
1678
1721
  compactDrawerOpen: !isFullscreenMode && isChatHistoryDrawerOpen,
1679
1722
  mcpDrawerFix: isSettingsOpen && !isChatHistoryDrawerOpen,
1723
+ "data-screen-capture-exclude": true,
1680
1724
  children: showCompactSettings ? settingsPanel : /* @__PURE__ */ jsxs(Fragment, { children: [
1681
1725
  /* @__PURE__ */ jsxs(StyledChatbotHeader, { children: [
1682
1726
  /* @__PURE__ */ jsxs(ChatbotHeaderMain, { children: [
@@ -1772,6 +1816,9 @@ const LightspeedChat = ({
1772
1816
  setDisplayMode: setDisplayModeFromHeader,
1773
1817
  displayMode,
1774
1818
  onPinnedChatsToggle: handlePinningChatsToggle,
1819
+ screenContextAdminEnabled: screenContextEnabled,
1820
+ isScreenContextSharingEnabled,
1821
+ onScreenContextSharingToggle: handleScreenContextSharingToggle,
1775
1822
  onMcpSettingsClick: () => {
1776
1823
  openSettings(
1777
1824
  mcpToolsPermissionResolved ? "mcp-servers" : "saved-prompts"