@backstage-community/plugin-mcp-chat 0.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.
Files changed (42) hide show
  1. package/README.md +361 -0
  2. package/config.d.ts +47 -0
  3. package/dist/api/McpChatApi.esm.js +55 -0
  4. package/dist/api/McpChatApi.esm.js.map +1 -0
  5. package/dist/api/index.esm.js +8 -0
  6. package/dist/api/index.esm.js.map +1 -0
  7. package/dist/components/BotIcon/BotIcon.esm.js +57 -0
  8. package/dist/components/BotIcon/BotIcon.esm.js.map +1 -0
  9. package/dist/components/ChatContainer/ChatContainer.esm.js +246 -0
  10. package/dist/components/ChatContainer/ChatContainer.esm.js.map +1 -0
  11. package/dist/components/ChatContainer/ChatMessage.esm.js +466 -0
  12. package/dist/components/ChatContainer/ChatMessage.esm.js.map +1 -0
  13. package/dist/components/ChatContainer/QuickStart.esm.js +271 -0
  14. package/dist/components/ChatContainer/QuickStart.esm.js.map +1 -0
  15. package/dist/components/ChatContainer/TypingIndicator.esm.js +154 -0
  16. package/dist/components/ChatContainer/TypingIndicator.esm.js.map +1 -0
  17. package/dist/components/ChatPage/ChatPage.esm.js +142 -0
  18. package/dist/components/ChatPage/ChatPage.esm.js.map +1 -0
  19. package/dist/components/ChatPage/index.esm.js +2 -0
  20. package/dist/components/ChatPage/index.esm.js.map +1 -0
  21. package/dist/components/RightPane/ActiveMcpServers.esm.js +159 -0
  22. package/dist/components/RightPane/ActiveMcpServers.esm.js.map +1 -0
  23. package/dist/components/RightPane/ActiveTools.esm.js +308 -0
  24. package/dist/components/RightPane/ActiveTools.esm.js.map +1 -0
  25. package/dist/components/RightPane/ProviderStatus.esm.js +225 -0
  26. package/dist/components/RightPane/ProviderStatus.esm.js.map +1 -0
  27. package/dist/components/RightPane/RightPane.esm.js +242 -0
  28. package/dist/components/RightPane/RightPane.esm.js.map +1 -0
  29. package/dist/hooks/useAvailableTools.esm.js +33 -0
  30. package/dist/hooks/useAvailableTools.esm.js.map +1 -0
  31. package/dist/hooks/useMcpServers.esm.js +40 -0
  32. package/dist/hooks/useMcpServers.esm.js.map +1 -0
  33. package/dist/hooks/useProviderStatus.esm.js +22 -0
  34. package/dist/hooks/useProviderStatus.esm.js.map +1 -0
  35. package/dist/index.d.ts +150 -0
  36. package/dist/index.esm.js +3 -0
  37. package/dist/index.esm.js.map +1 -0
  38. package/dist/plugin.esm.js +33 -0
  39. package/dist/plugin.esm.js.map +1 -0
  40. package/dist/routes.esm.js +8 -0
  41. package/dist/routes.esm.js.map +1 -0
  42. package/package.json +91 -0
@@ -0,0 +1,271 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { useTheme } from '@mui/material/styles';
4
+ import BugReportIcon from '@mui/icons-material/BugReport';
5
+ import BuildIcon from '@mui/icons-material/Build';
6
+ import CloudIcon from '@mui/icons-material/Cloud';
7
+ import CodeIcon from '@mui/icons-material/Code';
8
+ import DataUsageIcon from '@mui/icons-material/DataUsage';
9
+ import DeveloperModeIcon from '@mui/icons-material/DeveloperMode';
10
+ import SearchIcon from '@mui/icons-material/Search';
11
+ import SecurityIcon from '@mui/icons-material/Security';
12
+ import SettingsIcon from '@mui/icons-material/Settings';
13
+ import DatabaseIcon from '@mui/icons-material/Storage';
14
+ import TrendingUpIcon from '@mui/icons-material/TrendingUp';
15
+ import Box from '@mui/material/Box';
16
+ import Card from '@mui/material/Card';
17
+ import CardContent from '@mui/material/CardContent';
18
+ import Chip from '@mui/material/Chip';
19
+ import Grid from '@mui/material/Grid';
20
+ import Typography from '@mui/material/Typography';
21
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
22
+ import SpeedIcon from '@mui/icons-material/Speed';
23
+ import ExtensionIcon from '@mui/icons-material/Extension';
24
+ import WebIcon from '@mui/icons-material/Web';
25
+ import DevicesIcon from '@mui/icons-material/Devices';
26
+ import ComputerIcon from '@mui/icons-material/Computer';
27
+
28
+ const availableIcons = [
29
+ /* @__PURE__ */ jsx(SearchIcon, {}),
30
+ /* @__PURE__ */ jsx(CodeIcon, {}),
31
+ /* @__PURE__ */ jsx(DatabaseIcon, {}),
32
+ /* @__PURE__ */ jsx(BuildIcon, {}),
33
+ /* @__PURE__ */ jsx(SecurityIcon, {}),
34
+ /* @__PURE__ */ jsx(DataUsageIcon, {}),
35
+ /* @__PURE__ */ jsx(CloudIcon, {}),
36
+ /* @__PURE__ */ jsx(DeveloperModeIcon, {}),
37
+ /* @__PURE__ */ jsx(SettingsIcon, {}),
38
+ /* @__PURE__ */ jsx(TrendingUpIcon, {}),
39
+ /* @__PURE__ */ jsx(BugReportIcon, {}),
40
+ /* @__PURE__ */ jsx(SpeedIcon, {}),
41
+ /* @__PURE__ */ jsx(ExtensionIcon, {}),
42
+ /* @__PURE__ */ jsx(WebIcon, {}),
43
+ /* @__PURE__ */ jsx(DevicesIcon, {}),
44
+ /* @__PURE__ */ jsx(ComputerIcon, {})
45
+ ];
46
+ const getRandomIcon = (index) => {
47
+ const iconIndex = index % availableIcons.length;
48
+ return availableIcons[iconIndex];
49
+ };
50
+ const QuickStart = ({
51
+ onSuggestionClick
52
+ }) => {
53
+ const theme = useTheme();
54
+ const configApi = useApi(configApiRef);
55
+ const suggestions = useMemo(() => {
56
+ try {
57
+ const configSuggestions = configApi.getOptionalConfigArray(
58
+ "mcpChat.quickPrompts"
59
+ );
60
+ if (!configSuggestions || configSuggestions.length === 0) {
61
+ return [];
62
+ }
63
+ return configSuggestions.map((config) => ({
64
+ title: config.getString("title"),
65
+ description: config.getString("description"),
66
+ prompt: config.getString("prompt"),
67
+ category: config.getString("category")
68
+ }));
69
+ } catch (error) {
70
+ return [];
71
+ }
72
+ }, [configApi]);
73
+ const getGridSize = () => {
74
+ const count = suggestions.length;
75
+ if (count <= 2) return { xs: 12, sm: 6, md: 6 };
76
+ if (count <= 4) return { xs: 12, sm: 6, md: 6 };
77
+ if (count <= 6) return { xs: 12, sm: 6, md: 4 };
78
+ return { xs: 12, sm: 6, md: 4 };
79
+ };
80
+ const gridSize = getGridSize();
81
+ return /* @__PURE__ */ jsxs(
82
+ Box,
83
+ {
84
+ sx: {
85
+ padding: theme.spacing(3, 3),
86
+ textAlign: "center",
87
+ maxWidth: 900,
88
+ margin: "auto auto 0 auto",
89
+ display: "flex",
90
+ flexDirection: "column",
91
+ justifyContent: "center",
92
+ minHeight: "calc(100vh - 120px)",
93
+ // Account for top bar and input area
94
+ paddingBottom: theme.spacing(15),
95
+ // Ensure no overlap with input area
96
+ overflowY: "auto"
97
+ // Allow scrolling if needed
98
+ },
99
+ children: [
100
+ /* @__PURE__ */ jsx(
101
+ Typography,
102
+ {
103
+ variant: "h3",
104
+ sx: {
105
+ fontWeight: 700,
106
+ marginBottom: theme.spacing(2),
107
+ color: theme.palette.text.primary,
108
+ background: theme.palette.mode === "dark" ? `linear-gradient(45deg, ${theme.palette.primary.light}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})` : `linear-gradient(45deg, ${theme.palette.primary.dark}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`,
109
+ WebkitBackgroundClip: "text",
110
+ WebkitTextFillColor: "transparent",
111
+ backgroundClip: "text"
112
+ },
113
+ children: "How can I help you today?"
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsx(
117
+ Typography,
118
+ {
119
+ variant: "body1",
120
+ sx: {
121
+ color: theme.palette.text.secondary,
122
+ fontSize: "1.1rem",
123
+ lineHeight: 1.6,
124
+ maxWidth: 600,
125
+ marginBottom: theme.spacing(4),
126
+ marginLeft: "auto",
127
+ marginRight: "auto"
128
+ },
129
+ children: "Explore powerful AI-assisted workflows with our comprehensive MCP tool integration. Choose a category below to get started with intelligent automation."
130
+ }
131
+ ),
132
+ /* @__PURE__ */ jsx(
133
+ Grid,
134
+ {
135
+ container: true,
136
+ spacing: 3,
137
+ sx: {
138
+ marginTop: theme.spacing(3),
139
+ marginBottom: theme.spacing(4)
140
+ },
141
+ justifyContent: "center",
142
+ children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsx(
143
+ Grid,
144
+ {
145
+ item: true,
146
+ xs: gridSize.xs,
147
+ sm: gridSize.sm,
148
+ md: gridSize.md,
149
+ children: /* @__PURE__ */ jsx(
150
+ Card,
151
+ {
152
+ onClick: () => onSuggestionClick(suggestion.prompt),
153
+ elevation: 0,
154
+ sx: {
155
+ cursor: "pointer",
156
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
157
+ border: `1px solid ${theme.palette.divider}`,
158
+ borderRadius: theme.spacing(2),
159
+ height: "160px",
160
+ position: "relative",
161
+ overflow: "hidden",
162
+ background: theme.palette.background.paper,
163
+ backdropFilter: "blur(10px)",
164
+ "&:hover": {
165
+ transform: "translateY(-4px) scale(1.01)",
166
+ boxShadow: theme.shadows[8],
167
+ borderColor: theme.palette.primary.main,
168
+ "& .suggestion-icon": {
169
+ transform: "scale(1.1)"
170
+ },
171
+ "&::before": {
172
+ opacity: 1
173
+ }
174
+ },
175
+ "&::before": {
176
+ content: '""',
177
+ position: "absolute",
178
+ top: 0,
179
+ left: 0,
180
+ right: 0,
181
+ height: 3,
182
+ background: theme.palette.mode === "dark" ? `linear-gradient(45deg, ${theme.palette.primary.light}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})` : `linear-gradient(45deg, ${theme.palette.primary.dark}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`,
183
+ opacity: 0,
184
+ transition: "opacity 0.3s ease"
185
+ }
186
+ },
187
+ children: /* @__PURE__ */ jsxs(
188
+ CardContent,
189
+ {
190
+ sx: {
191
+ padding: theme.spacing(2),
192
+ height: "100%",
193
+ display: "flex",
194
+ flexDirection: "column",
195
+ alignItems: "center",
196
+ justifyContent: "center",
197
+ position: "relative"
198
+ },
199
+ children: [
200
+ /* @__PURE__ */ jsx(
201
+ Chip,
202
+ {
203
+ label: suggestion.category,
204
+ size: "small",
205
+ sx: {
206
+ position: "absolute",
207
+ top: theme.spacing(1),
208
+ right: theme.spacing(1),
209
+ fontSize: "0.7rem",
210
+ height: 20,
211
+ background: theme.palette.action.hover,
212
+ color: theme.palette.primary.main,
213
+ border: `1px solid ${theme.palette.divider}`
214
+ }
215
+ }
216
+ ),
217
+ /* @__PURE__ */ jsx(
218
+ Box,
219
+ {
220
+ className: "suggestion-icon",
221
+ sx: {
222
+ fontSize: "2rem",
223
+ marginBottom: theme.spacing(1),
224
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
225
+ color: theme.palette.primary.main
226
+ },
227
+ children: getRandomIcon(index)
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx(
231
+ Typography,
232
+ {
233
+ variant: "h6",
234
+ sx: {
235
+ fontWeight: 600,
236
+ marginBottom: theme.spacing(0.5),
237
+ color: theme.palette.text.primary,
238
+ fontSize: "1rem"
239
+ },
240
+ children: suggestion.title
241
+ }
242
+ ),
243
+ /* @__PURE__ */ jsx(
244
+ Typography,
245
+ {
246
+ variant: "body2",
247
+ sx: {
248
+ color: theme.palette.text.secondary,
249
+ fontSize: "0.85rem",
250
+ lineHeight: 1.4
251
+ },
252
+ children: suggestion.description
253
+ }
254
+ )
255
+ ]
256
+ }
257
+ )
258
+ }
259
+ )
260
+ },
261
+ index
262
+ ))
263
+ }
264
+ )
265
+ ]
266
+ }
267
+ );
268
+ };
269
+
270
+ export { QuickStart };
271
+ //# sourceMappingURL=QuickStart.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickStart.esm.js","sources":["../../../src/components/ChatContainer/QuickStart.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useMemo } from 'react';\nimport { useTheme } from '@mui/material/styles';\nimport BugReportIcon from '@mui/icons-material/BugReport';\nimport BuildIcon from '@mui/icons-material/Build';\nimport CloudIcon from '@mui/icons-material/Cloud';\nimport CodeIcon from '@mui/icons-material/Code';\nimport DataUsageIcon from '@mui/icons-material/DataUsage';\nimport DeveloperModeIcon from '@mui/icons-material/DeveloperMode';\nimport SearchIcon from '@mui/icons-material/Search';\nimport SecurityIcon from '@mui/icons-material/Security';\nimport SettingsIcon from '@mui/icons-material/Settings';\nimport DatabaseIcon from '@mui/icons-material/Storage';\nimport TrendingUpIcon from '@mui/icons-material/TrendingUp';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport Chip from '@mui/material/Chip';\nimport Grid from '@mui/material/Grid';\nimport Typography from '@mui/material/Typography';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport SpeedIcon from '@mui/icons-material/Speed';\nimport ExtensionIcon from '@mui/icons-material/Extension';\nimport WebIcon from '@mui/icons-material/Web';\nimport DevicesIcon from '@mui/icons-material/Devices';\nimport ComputerIcon from '@mui/icons-material/Computer';\n\ninterface QuickStartProps {\n onSuggestionClick: (suggestion: string) => void;\n}\n\ninterface Suggestion {\n title: string;\n description: string;\n prompt: string;\n category: string;\n}\n\n// Available icons for random selection\nconst availableIcons = [\n <SearchIcon />,\n <CodeIcon />,\n <DatabaseIcon />,\n <BuildIcon />,\n <SecurityIcon />,\n <DataUsageIcon />,\n <CloudIcon />,\n <DeveloperModeIcon />,\n <SettingsIcon />,\n <TrendingUpIcon />,\n <BugReportIcon />,\n <SpeedIcon />,\n <ExtensionIcon />,\n <WebIcon />,\n <DevicesIcon />,\n <ComputerIcon />,\n];\n\n// Function to get a random icon\nconst getRandomIcon = (index: number): React.ReactElement => {\n // Use index as seed for consistent icon selection per suggestion\n const iconIndex = index % availableIcons.length;\n return availableIcons[iconIndex];\n};\n\nexport const QuickStart: React.FC<QuickStartProps> = ({\n onSuggestionClick,\n}) => {\n const theme = useTheme();\n const configApi = useApi(configApiRef);\n\n // Get suggestions from config\n const suggestions: Suggestion[] = useMemo(() => {\n try {\n const configSuggestions = configApi.getOptionalConfigArray(\n 'mcpChat.quickPrompts',\n );\n\n if (!configSuggestions || configSuggestions.length === 0) {\n return [];\n }\n\n return configSuggestions.map(config => ({\n title: config.getString('title'),\n description: config.getString('description'),\n prompt: config.getString('prompt'),\n category: config.getString('category'),\n }));\n } catch (error) {\n // Handle config errors gracefully by returning empty suggestions\n return [];\n }\n }, [configApi]);\n\n // Determine optimal grid layout based on number of suggestions\n const getGridSize = () => {\n const count = suggestions.length;\n if (count <= 2) return { xs: 12 as const, sm: 6 as const, md: 6 as const }; // 1 row on desktop\n if (count <= 4) return { xs: 12 as const, sm: 6 as const, md: 6 as const }; // 2x2 grid\n if (count <= 6) return { xs: 12 as const, sm: 6 as const, md: 4 as const }; // 2x3 grid\n return { xs: 12 as const, sm: 6 as const, md: 4 as const }; // 3 columns for larger counts\n };\n\n const gridSize = getGridSize();\n\n return (\n <Box\n sx={{\n padding: theme.spacing(3, 3),\n textAlign: 'center',\n maxWidth: 900,\n margin: 'auto auto 0 auto',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n minHeight: 'calc(100vh - 120px)', // Account for top bar and input area\n paddingBottom: theme.spacing(15), // Ensure no overlap with input area\n overflowY: 'auto', // Allow scrolling if needed\n }}\n >\n <Typography\n variant=\"h3\"\n sx={{\n fontWeight: 700,\n marginBottom: theme.spacing(2),\n color: theme.palette.text.primary,\n background:\n theme.palette.mode === 'dark'\n ? `linear-gradient(45deg, ${theme.palette.primary.light}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`\n : `linear-gradient(45deg, ${theme.palette.primary.dark}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`,\n WebkitBackgroundClip: 'text',\n WebkitTextFillColor: 'transparent',\n backgroundClip: 'text',\n }}\n >\n How can I help you today?\n </Typography>\n <Typography\n variant=\"body1\"\n sx={{\n color: theme.palette.text.secondary,\n fontSize: '1.1rem',\n lineHeight: 1.6,\n maxWidth: 600,\n marginBottom: theme.spacing(4),\n marginLeft: 'auto',\n marginRight: 'auto',\n }}\n >\n Explore powerful AI-assisted workflows with our comprehensive MCP tool\n integration. Choose a category below to get started with intelligent\n automation.\n </Typography>\n\n <Grid\n container\n spacing={3}\n sx={{\n marginTop: theme.spacing(3),\n marginBottom: theme.spacing(4),\n }}\n justifyContent=\"center\"\n >\n {suggestions.map((suggestion, index) => (\n <Grid\n item\n xs={gridSize.xs}\n sm={gridSize.sm}\n md={gridSize.md}\n key={index}\n >\n <Card\n onClick={() => onSuggestionClick(suggestion.prompt)}\n elevation={0}\n sx={{\n cursor: 'pointer',\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: theme.spacing(2),\n height: '160px',\n position: 'relative',\n overflow: 'hidden',\n background: theme.palette.background.paper,\n backdropFilter: 'blur(10px)',\n '&:hover': {\n transform: 'translateY(-4px) scale(1.01)',\n boxShadow: theme.shadows[8],\n borderColor: theme.palette.primary.main,\n '& .suggestion-icon': {\n transform: 'scale(1.1)',\n },\n '&::before': {\n opacity: 1,\n },\n },\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: 3,\n background:\n theme.palette.mode === 'dark'\n ? `linear-gradient(45deg, ${theme.palette.primary.light}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`\n : `linear-gradient(45deg, ${theme.palette.primary.dark}, ${theme.palette.primary.main}, ${theme.palette.secondary.main})`,\n opacity: 0,\n transition: 'opacity 0.3s ease',\n },\n }}\n >\n <CardContent\n sx={{\n padding: theme.spacing(2),\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n }}\n >\n <Chip\n label={suggestion.category}\n size=\"small\"\n sx={{\n position: 'absolute',\n top: theme.spacing(1),\n right: theme.spacing(1),\n fontSize: '0.7rem',\n height: 20,\n background: theme.palette.action.hover,\n color: theme.palette.primary.main,\n border: `1px solid ${theme.palette.divider}`,\n }}\n />\n <Box\n className=\"suggestion-icon\"\n sx={{\n fontSize: '2rem',\n marginBottom: theme.spacing(1),\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n color: theme.palette.primary.main,\n }}\n >\n {getRandomIcon(index)}\n </Box>\n <Typography\n variant=\"h6\"\n sx={{\n fontWeight: 600,\n marginBottom: theme.spacing(0.5),\n color: theme.palette.text.primary,\n fontSize: '1rem',\n }}\n >\n {suggestion.title}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{\n color: theme.palette.text.secondary,\n fontSize: '0.85rem',\n lineHeight: 1.4,\n }}\n >\n {suggestion.description}\n </Typography>\n </CardContent>\n </Card>\n </Grid>\n ))}\n </Grid>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTheme } from '@mui/material/styles';
3
+ import Avatar from '@mui/material/Avatar';
4
+ import Box from '@mui/material/Box';
5
+ import Card from '@mui/material/Card';
6
+ import CardContent from '@mui/material/CardContent';
7
+ import Typography from '@mui/material/Typography';
8
+ import { BotIcon } from '../BotIcon/BotIcon.esm.js';
9
+
10
+ const TypingIndicator = () => {
11
+ const theme = useTheme();
12
+ const isDarkMode = theme.palette.mode === "dark";
13
+ return /* @__PURE__ */ jsxs(
14
+ Box,
15
+ {
16
+ sx: {
17
+ display: "flex",
18
+ alignItems: "flex-start",
19
+ gap: theme.spacing(1),
20
+ marginBottom: theme.spacing(2)
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ jsx(
24
+ Avatar,
25
+ {
26
+ sx: {
27
+ width: 35,
28
+ height: 35,
29
+ fontSize: "1rem",
30
+ backgroundColor: isDarkMode ? theme.palette.background.default : theme.palette.background.paper,
31
+ color: isDarkMode ? theme.palette.text.primary : theme.palette.text.secondary
32
+ },
33
+ children: /* @__PURE__ */ jsx(
34
+ BotIcon,
35
+ {
36
+ color: isDarkMode ? theme.palette.text.primary : theme.palette.text.secondary
37
+ }
38
+ )
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(
42
+ Card,
43
+ {
44
+ elevation: 0,
45
+ sx: {
46
+ backgroundColor: "transparent",
47
+ border: `0px solid ${theme.palette.background.paper}`,
48
+ maxWidth: "70%"
49
+ },
50
+ children: /* @__PURE__ */ jsx(
51
+ CardContent,
52
+ {
53
+ sx: {
54
+ padding: `${theme.spacing(1.5)}px ${theme.spacing(2)}px !important`
55
+ },
56
+ children: /* @__PURE__ */ jsxs(
57
+ Box,
58
+ {
59
+ sx: {
60
+ display: "flex",
61
+ gap: theme.spacing(0.5),
62
+ alignItems: "center"
63
+ },
64
+ children: [
65
+ /* @__PURE__ */ jsx(
66
+ Box,
67
+ {
68
+ sx: {
69
+ width: 8,
70
+ height: 8,
71
+ borderRadius: "50%",
72
+ backgroundColor: theme.palette.text.secondary,
73
+ animation: "typing 1.4s infinite",
74
+ "@keyframes typing": {
75
+ "0%, 60%, 100%": {
76
+ transform: "translateY(0)",
77
+ opacity: 0.5
78
+ },
79
+ "30%": {
80
+ transform: "translateY(-10px)",
81
+ opacity: 1
82
+ }
83
+ }
84
+ }
85
+ }
86
+ ),
87
+ /* @__PURE__ */ jsx(
88
+ Box,
89
+ {
90
+ sx: {
91
+ width: 8,
92
+ height: 8,
93
+ borderRadius: "50%",
94
+ backgroundColor: theme.palette.text.secondary,
95
+ animation: "typing 1.4s infinite",
96
+ animationDelay: "0.2s",
97
+ "@keyframes typing": {
98
+ "0%, 60%, 100%": {
99
+ transform: "translateY(0)",
100
+ opacity: 0.5
101
+ },
102
+ "30%": {
103
+ transform: "translateY(-10px)",
104
+ opacity: 1
105
+ }
106
+ }
107
+ }
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsx(
111
+ Box,
112
+ {
113
+ sx: {
114
+ width: 8,
115
+ height: 8,
116
+ borderRadius: "50%",
117
+ backgroundColor: theme.palette.text.secondary,
118
+ animation: "typing 1.4s infinite",
119
+ animationDelay: "0.4s",
120
+ "@keyframes typing": {
121
+ "0%, 60%, 100%": {
122
+ transform: "translateY(0)",
123
+ opacity: 0.5
124
+ },
125
+ "30%": {
126
+ transform: "translateY(-10px)",
127
+ opacity: 1
128
+ }
129
+ }
130
+ }
131
+ }
132
+ ),
133
+ /* @__PURE__ */ jsx(
134
+ Typography,
135
+ {
136
+ variant: "caption",
137
+ sx: { marginLeft: 1, color: theme.palette.text.secondary },
138
+ children: "Hang on..."
139
+ }
140
+ )
141
+ ]
142
+ }
143
+ )
144
+ }
145
+ )
146
+ }
147
+ )
148
+ ]
149
+ }
150
+ );
151
+ };
152
+
153
+ export { TypingIndicator };
154
+ //# sourceMappingURL=TypingIndicator.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypingIndicator.esm.js","sources":["../../../src/components/ChatContainer/TypingIndicator.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useTheme } from '@mui/material/styles';\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Card from '@mui/material/Card';\nimport CardContent from '@mui/material/CardContent';\nimport Typography from '@mui/material/Typography';\nimport { BotIcon } from '../BotIcon';\n\nexport const TypingIndicator: React.FC = () => {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n return (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: theme.spacing(1),\n marginBottom: theme.spacing(2),\n }}\n >\n <Avatar\n sx={{\n width: 35,\n height: 35,\n fontSize: '1rem',\n backgroundColor: isDarkMode\n ? theme.palette.background.default\n : theme.palette.background.paper,\n color: isDarkMode\n ? theme.palette.text.primary\n : theme.palette.text.secondary,\n }}\n >\n <BotIcon\n color={\n isDarkMode\n ? theme.palette.text.primary\n : theme.palette.text.secondary\n }\n />\n </Avatar>\n <Card\n elevation={0}\n sx={{\n backgroundColor: 'transparent',\n border: `0px solid ${theme.palette.background.paper}`,\n maxWidth: '70%',\n }}\n >\n <CardContent\n sx={{\n padding: `${theme.spacing(1.5)}px ${theme.spacing(2)}px !important`,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n gap: theme.spacing(0.5),\n alignItems: 'center',\n }}\n >\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: theme.palette.text.secondary,\n animation: 'typing 1.4s infinite',\n '@keyframes typing': {\n '0%, 60%, 100%': {\n transform: 'translateY(0)',\n opacity: 0.5,\n },\n '30%': {\n transform: 'translateY(-10px)',\n opacity: 1,\n },\n },\n }}\n />\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: theme.palette.text.secondary,\n animation: 'typing 1.4s infinite',\n animationDelay: '0.2s',\n '@keyframes typing': {\n '0%, 60%, 100%': {\n transform: 'translateY(0)',\n opacity: 0.5,\n },\n '30%': {\n transform: 'translateY(-10px)',\n opacity: 1,\n },\n },\n }}\n />\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: theme.palette.text.secondary,\n animation: 'typing 1.4s infinite',\n animationDelay: '0.4s',\n '@keyframes typing': {\n '0%, 60%, 100%': {\n transform: 'translateY(0)',\n opacity: 0.5,\n },\n '30%': {\n transform: 'translateY(-10px)',\n opacity: 1,\n },\n },\n }}\n />\n <Typography\n variant=\"caption\"\n sx={{ marginLeft: 1, color: theme.palette.text.secondary }}\n >\n Hang on...\n </Typography>\n </Box>\n </CardContent>\n </Card>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useRef } from 'react';
3
+ import { useTheme } from '@mui/material/styles';
4
+ import Box from '@mui/material/Box';
5
+ import { Page, Content, ResponseErrorPanel } from '@backstage/core-components';
6
+ import { ChatContainer } from '../ChatContainer/ChatContainer.esm.js';
7
+ import '@mui/icons-material/Build';
8
+ import '@mui/icons-material/Code';
9
+ import '@mui/icons-material/FileCopy';
10
+ import '@mui/icons-material/Person';
11
+ import '@mui/material/Avatar';
12
+ import '@mui/material/Card';
13
+ import '@mui/material/Chip';
14
+ import '@mui/material/Collapse';
15
+ import '@mui/material/IconButton';
16
+ import '@mui/material/Typography';
17
+ import 'react-markdown';
18
+ import '@mui/icons-material/BugReport';
19
+ import '@mui/icons-material/Cloud';
20
+ import '@mui/icons-material/DataUsage';
21
+ import '@mui/icons-material/DeveloperMode';
22
+ import '@mui/icons-material/Search';
23
+ import '@mui/icons-material/Security';
24
+ import '@mui/icons-material/Settings';
25
+ import '@mui/icons-material/Storage';
26
+ import '@mui/icons-material/TrendingUp';
27
+ import '@mui/material/CardContent';
28
+ import '@mui/material/Grid';
29
+ import '@backstage/core-plugin-api';
30
+ import '@mui/icons-material/Speed';
31
+ import '@mui/icons-material/Extension';
32
+ import '@mui/icons-material/Web';
33
+ import '@mui/icons-material/Devices';
34
+ import '@mui/icons-material/Computer';
35
+ import { RightPane } from '../RightPane/RightPane.esm.js';
36
+ import '@mui/icons-material/ExpandMore';
37
+ import '@mui/material/Accordion';
38
+ import '@mui/material/AccordionDetails';
39
+ import '@mui/material/AccordionSummary';
40
+ import '@mui/material/CircularProgress';
41
+ import '@mui/icons-material/FiberManualRecord';
42
+ import '@mui/icons-material/Memory';
43
+ import '@mui/material/Tooltip';
44
+ import { useProviderStatus } from '../../hooks/useProviderStatus.esm.js';
45
+ import { useMcpServers } from '../../hooks/useMcpServers.esm.js';
46
+ import 'react-use/esm/useAsyncRetry';
47
+ import '../../api/index.esm.js';
48
+
49
+ const ChatPage = () => {
50
+ const theme = useTheme();
51
+ const providerStatus = useProviderStatus();
52
+ const {
53
+ mcpServers,
54
+ error: mcpServersError,
55
+ handleServerToggle
56
+ } = useMcpServers();
57
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(true);
58
+ const [error, setError] = useState(null);
59
+ const [messages, setMessages] = useState([]);
60
+ const chatContainerRef = useRef(null);
61
+ const combinedError = error || mcpServersError;
62
+ const toggleSidebar = () => {
63
+ setSidebarCollapsed(!sidebarCollapsed);
64
+ };
65
+ const handleNewChat = () => {
66
+ if (chatContainerRef.current) {
67
+ chatContainerRef.current.cancelOngoingRequest();
68
+ }
69
+ setError(null);
70
+ setMessages([]);
71
+ };
72
+ const handleMessagesChange = (newMessages) => {
73
+ setMessages(newMessages);
74
+ };
75
+ return /* @__PURE__ */ jsx(Page, { themeId: "tool", children: /* @__PURE__ */ jsx(Content, { noPadding: true, children: /* @__PURE__ */ jsx(
76
+ Box,
77
+ {
78
+ sx: {
79
+ display: "flex",
80
+ flexDirection: "column",
81
+ height: "100vh",
82
+ backgroundColor: theme.palette.background.default
83
+ },
84
+ children: /* @__PURE__ */ jsx(
85
+ Box,
86
+ {
87
+ sx: {
88
+ display: "flex",
89
+ flex: 1,
90
+ overflow: "hidden",
91
+ position: "relative"
92
+ },
93
+ children: combinedError ? /* @__PURE__ */ jsx(
94
+ Box,
95
+ {
96
+ sx: {
97
+ display: "flex",
98
+ justifyContent: "center",
99
+ alignItems: "center",
100
+ width: "100%",
101
+ height: "100%",
102
+ padding: "20px"
103
+ },
104
+ children: /* @__PURE__ */ jsx(
105
+ ResponseErrorPanel,
106
+ {
107
+ error: new Error(combinedError),
108
+ defaultExpanded: true
109
+ }
110
+ )
111
+ }
112
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
113
+ /* @__PURE__ */ jsx(
114
+ ChatContainer,
115
+ {
116
+ ref: chatContainerRef,
117
+ sidebarCollapsed,
118
+ mcpServers,
119
+ messages,
120
+ onMessagesChange: handleMessagesChange
121
+ }
122
+ ),
123
+ /* @__PURE__ */ jsx(
124
+ RightPane,
125
+ {
126
+ sidebarCollapsed,
127
+ onToggleSidebar: toggleSidebar,
128
+ onNewChat: handleNewChat,
129
+ mcpServers,
130
+ onServerToggle: handleServerToggle,
131
+ providerStatus
132
+ }
133
+ )
134
+ ] })
135
+ }
136
+ )
137
+ }
138
+ ) }) });
139
+ };
140
+
141
+ export { ChatPage };
142
+ //# sourceMappingURL=ChatPage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPage.esm.js","sources":["../../../src/components/ChatPage/ChatPage.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState, useRef } from 'react';\nimport { useTheme } from '@mui/material/styles';\nimport Box from '@mui/material/Box';\nimport { Content, Page, ResponseErrorPanel } from '@backstage/core-components';\nimport { ChatContainer, type ChatContainerRef } from '../ChatContainer';\nimport { RightPane } from '../RightPane';\nimport { useProviderStatus, useMcpServers } from '../../hooks';\n\ninterface Message {\n id: string;\n text: string;\n isUser: boolean;\n timestamp: Date;\n tools?: string[];\n toolsUsed?: string[];\n toolResponses?: any[];\n}\n\nexport const ChatPage = () => {\n const theme = useTheme();\n\n const providerStatus = useProviderStatus();\n const {\n mcpServers,\n error: mcpServersError,\n handleServerToggle,\n } = useMcpServers();\n const [sidebarCollapsed, setSidebarCollapsed] = useState(true);\n\n const [error, setError] = useState<string | null>(null);\n const [messages, setMessages] = useState<Message[]>([]);\n const chatContainerRef = useRef<ChatContainerRef>(null);\n\n // Combine errors from different sources\n const combinedError = error || mcpServersError;\n\n const toggleSidebar = () => {\n setSidebarCollapsed(!sidebarCollapsed);\n };\n\n const handleNewChat = () => {\n // Cancel any ongoing request first\n if (chatContainerRef.current) {\n chatContainerRef.current.cancelOngoingRequest();\n }\n\n setError(null);\n setMessages([]);\n };\n\n const handleMessagesChange = (newMessages: Message[]) => {\n setMessages(newMessages);\n };\n\n return (\n <Page themeId=\"tool\">\n <Content noPadding>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n height: '100vh',\n backgroundColor: theme.palette.background.default,\n }}\n >\n {/* Content Area */}\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n overflow: 'hidden',\n position: 'relative',\n }}\n >\n {combinedError ? (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n height: '100%',\n padding: '20px',\n }}\n >\n <ResponseErrorPanel\n error={new Error(combinedError)}\n defaultExpanded\n />\n </Box>\n ) : (\n <>\n {/* Chat Container */}\n <ChatContainer\n ref={chatContainerRef}\n sidebarCollapsed={sidebarCollapsed}\n mcpServers={mcpServers}\n messages={messages}\n onMessagesChange={handleMessagesChange}\n />\n\n {/* Sidebar - Right Side */}\n <RightPane\n sidebarCollapsed={sidebarCollapsed}\n onToggleSidebar={toggleSidebar}\n onNewChat={handleNewChat}\n mcpServers={mcpServers}\n onServerToggle={handleServerToggle}\n providerStatus={providerStatus}\n />\n </>\n )}\n </Box>\n </Box>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { ChatPage } from './ChatPage.esm.js';
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}