@drewswiredin/backstage-plugin-assistants 0.1.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 (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +113 -0
  3. package/dist/alpha.d.ts +64 -0
  4. package/dist/alpha.esm.js +35 -0
  5. package/dist/alpha.esm.js.map +1 -0
  6. package/dist/api/AssistantsApi.esm.js +55 -0
  7. package/dist/api/AssistantsApi.esm.js.map +1 -0
  8. package/dist/collapsible/AssistantDetailDialog.esm.js +209 -0
  9. package/dist/collapsible/AssistantDetailDialog.esm.js.map +1 -0
  10. package/dist/collapsible/AssistantsList.esm.js +119 -0
  11. package/dist/collapsible/AssistantsList.esm.js.map +1 -0
  12. package/dist/collapsible/CollapsiblePage.esm.js +724 -0
  13. package/dist/collapsible/CollapsiblePage.esm.js.map +1 -0
  14. package/dist/collapsible/ConversationsPanel.esm.js +198 -0
  15. package/dist/collapsible/ConversationsPanel.esm.js.map +1 -0
  16. package/dist/collapsible/FullHeightRegion.esm.js +54 -0
  17. package/dist/collapsible/FullHeightRegion.esm.js.map +1 -0
  18. package/dist/collapsible/SidePane.esm.js +89 -0
  19. package/dist/collapsible/SidePane.esm.js.map +1 -0
  20. package/dist/collapsible/surface/AssistantAvatar.esm.js +98 -0
  21. package/dist/collapsible/surface/AssistantAvatar.esm.js.map +1 -0
  22. package/dist/collapsible/surface/BackstageLogo.esm.js +24 -0
  23. package/dist/collapsible/surface/BackstageLogo.esm.js.map +1 -0
  24. package/dist/collapsible/surface/ConversationSurface.esm.js +268 -0
  25. package/dist/collapsible/surface/ConversationSurface.esm.js.map +1 -0
  26. package/dist/collapsible/surface/MarkdownText.esm.js +24 -0
  27. package/dist/collapsible/surface/MarkdownText.esm.js.map +1 -0
  28. package/dist/collapsible/surface/MermaidDiagram.esm.js +245 -0
  29. package/dist/collapsible/surface/MermaidDiagram.esm.js.map +1 -0
  30. package/dist/collapsible/surface/parts.esm.js +216 -0
  31. package/dist/collapsible/surface/parts.esm.js.map +1 -0
  32. package/dist/collapsible/surface/styles/assistant-ui-markdown.css.esm.js +5 -0
  33. package/dist/collapsible/surface/styles/assistant-ui-markdown.css.esm.js.map +1 -0
  34. package/dist/collapsible/surface/styles/assistant-ui.css.esm.js +5 -0
  35. package/dist/collapsible/surface/styles/assistant-ui.css.esm.js.map +1 -0
  36. package/dist/collapsible/unreadStore.esm.js +79 -0
  37. package/dist/collapsible/unreadStore.esm.js.map +1 -0
  38. package/dist/collapsible/useConversations.esm.js +171 -0
  39. package/dist/collapsible/useConversations.esm.js.map +1 -0
  40. package/dist/index.d.ts +63 -0
  41. package/dist/index.esm.js +3 -0
  42. package/dist/index.esm.js.map +1 -0
  43. package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js +29 -0
  44. package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -0
  45. package/dist/routes.esm.js +8 -0
  46. package/dist/routes.esm.js.map +1 -0
  47. package/package.json +107 -0
@@ -0,0 +1,209 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTheme, fade, makeStyles } from '@material-ui/core/styles';
3
+ import Dialog from '@material-ui/core/Dialog';
4
+ import DialogContent from '@material-ui/core/DialogContent';
5
+ import IconButton from '@material-ui/core/IconButton';
6
+ import Typography from '@material-ui/core/Typography';
7
+ import Tooltip from '@material-ui/core/Tooltip';
8
+ import CloseIcon from '@material-ui/icons/Close';
9
+ import StarIcon from '@material-ui/icons/Star';
10
+ import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';
11
+ import { resolveAssistantColor, AssistantAvatar } from './surface/AssistantAvatar.esm.js';
12
+
13
+ const MONO = '"SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", monospace';
14
+ const useStyles = makeStyles((theme) => ({
15
+ // overflow:hidden so the accent bar clips to the dialog's radius.
16
+ paper: {
17
+ overflow: "hidden"
18
+ },
19
+ accent: {
20
+ height: 3,
21
+ width: "100%"
22
+ },
23
+ closeButton: {
24
+ position: "absolute",
25
+ right: theme.spacing(1),
26
+ top: theme.spacing(1),
27
+ color: theme.palette.text.secondary,
28
+ zIndex: 1
29
+ },
30
+ content: {
31
+ padding: theme.spacing(2, 3, 3)
32
+ },
33
+ // Centered, profile-style identity.
34
+ profile: {
35
+ display: "flex",
36
+ flexDirection: "column",
37
+ alignItems: "center",
38
+ textAlign: "center",
39
+ gap: theme.spacing(1)
40
+ },
41
+ avatarHalo: {
42
+ display: "inline-flex",
43
+ alignItems: "center",
44
+ justifyContent: "center",
45
+ borderRadius: "50%",
46
+ padding: theme.spacing(1.25)
47
+ },
48
+ name: {
49
+ fontWeight: 600
50
+ },
51
+ description: {
52
+ color: theme.palette.text.secondary,
53
+ maxWidth: "34ch"
54
+ },
55
+ section: {
56
+ marginTop: theme.spacing(2.5)
57
+ },
58
+ sectionLabel: {
59
+ display: "block",
60
+ color: theme.palette.text.secondary,
61
+ fontWeight: 600,
62
+ fontSize: "0.7rem",
63
+ textTransform: "uppercase",
64
+ letterSpacing: 0.6,
65
+ marginBottom: theme.spacing(0.5)
66
+ },
67
+ count: {
68
+ color: theme.palette.text.hint,
69
+ fontWeight: 400
70
+ },
71
+ list: {
72
+ listStyle: "none",
73
+ margin: 0,
74
+ padding: 0,
75
+ display: "flex",
76
+ flexDirection: "column"
77
+ },
78
+ // Technical list row: monospace name; a hover-revealed ⓘ carries the detail.
79
+ row: {
80
+ display: "flex",
81
+ alignItems: "center",
82
+ gap: theme.spacing(1),
83
+ padding: theme.spacing(0.5, 0.75),
84
+ borderRadius: theme.shape.borderRadius,
85
+ "&:hover": {
86
+ backgroundColor: theme.palette.action.hover
87
+ },
88
+ "&:hover $infoIcon": {
89
+ opacity: 1,
90
+ pointerEvents: "auto"
91
+ }
92
+ },
93
+ itemName: {
94
+ fontFamily: MONO,
95
+ fontSize: "0.8rem",
96
+ fontWeight: 500,
97
+ color: theme.palette.text.primary
98
+ },
99
+ // Hidden until row hover; its tooltip holds the tool's description.
100
+ infoIcon: {
101
+ marginLeft: "auto",
102
+ flexShrink: 0,
103
+ fontSize: "1rem",
104
+ color: theme.palette.text.hint,
105
+ cursor: "help",
106
+ opacity: 0,
107
+ pointerEvents: "none",
108
+ transition: theme.transitions.create("opacity")
109
+ },
110
+ defaultMarker: {
111
+ marginLeft: "auto",
112
+ display: "inline-flex",
113
+ alignItems: "center",
114
+ gap: theme.spacing(0.25),
115
+ flexShrink: 0,
116
+ fontSize: "0.7rem",
117
+ textTransform: "uppercase",
118
+ letterSpacing: 0.5,
119
+ color: theme.palette.text.secondary
120
+ },
121
+ defaultStar: {
122
+ fontSize: "0.9rem"
123
+ },
124
+ muted: {
125
+ color: theme.palette.text.secondary,
126
+ fontStyle: "italic"
127
+ }
128
+ }));
129
+ const modelName = (id) => id.split(/[:/]/).pop() || id;
130
+ const AssistantDetailDialog = ({ assistant, open, onClose }) => {
131
+ const classes = useStyles();
132
+ const theme = useTheme();
133
+ if (!assistant) {
134
+ return null;
135
+ }
136
+ const tools = assistant.tools ?? [];
137
+ const models = assistant.models;
138
+ const color = resolveAssistantColor(assistant.color, theme.palette.type);
139
+ return /* @__PURE__ */ jsxs(
140
+ Dialog,
141
+ {
142
+ open,
143
+ onClose,
144
+ maxWidth: "xs",
145
+ fullWidth: true,
146
+ classes: { paper: classes.paper },
147
+ children: [
148
+ /* @__PURE__ */ jsx("div", { className: classes.accent, style: { backgroundColor: color } }),
149
+ /* @__PURE__ */ jsx(
150
+ IconButton,
151
+ {
152
+ "aria-label": "Close",
153
+ className: classes.closeButton,
154
+ size: "small",
155
+ onClick: onClose,
156
+ children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" })
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsxs(DialogContent, { className: classes.content, children: [
160
+ /* @__PURE__ */ jsxs("div", { className: classes.profile, children: [
161
+ /* @__PURE__ */ jsx(
162
+ "span",
163
+ {
164
+ className: classes.avatarHalo,
165
+ style: { backgroundColor: fade(color, 0.15) },
166
+ children: /* @__PURE__ */ jsx(AssistantAvatar, { color: assistant.color, size: 56 })
167
+ }
168
+ ),
169
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", className: classes.name, children: assistant.title }),
170
+ assistant.description && /* @__PURE__ */ jsx(Typography, { variant: "body2", className: classes.description, children: assistant.description })
171
+ ] }),
172
+ /* @__PURE__ */ jsxs("div", { className: classes.section, children: [
173
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: classes.sectionLabel, children: [
174
+ "Tools ",
175
+ /* @__PURE__ */ jsx("span", { className: classes.count, children: tools.length })
176
+ ] }),
177
+ tools.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "body2", className: classes.muted, children: "No tools available" }) : /* @__PURE__ */ jsx("ul", { className: classes.list, children: tools.map((t) => /* @__PURE__ */ jsxs("li", { className: classes.row, children: [
178
+ /* @__PURE__ */ jsx("span", { className: classes.itemName, children: t.name }),
179
+ t.description && /* @__PURE__ */ jsx(Tooltip, { title: t.description, placement: "top-end", children: /* @__PURE__ */ jsx(InfoOutlinedIcon, { className: classes.infoIcon }) })
180
+ ] }, t.name)) })
181
+ ] }),
182
+ /* @__PURE__ */ jsxs("div", { className: classes.section, children: [
183
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", className: classes.sectionLabel, children: [
184
+ "Models",
185
+ " ",
186
+ models && /* @__PURE__ */ jsx("span", { className: classes.count, children: models.length })
187
+ ] }),
188
+ !models ? /* @__PURE__ */ jsx(Typography, { variant: "body2", className: classes.muted, children: "All available models" }) : /* @__PURE__ */ jsx("ul", { className: classes.list, children: models.map((m) => /* @__PURE__ */ jsxs("li", { className: classes.row, children: [
189
+ /* @__PURE__ */ jsx("span", { className: classes.itemName, children: modelName(m) }),
190
+ m === assistant.defaultModel && /* @__PURE__ */ jsxs("span", { className: classes.defaultMarker, children: [
191
+ /* @__PURE__ */ jsx(
192
+ StarIcon,
193
+ {
194
+ className: classes.defaultStar,
195
+ style: { color }
196
+ }
197
+ ),
198
+ "default"
199
+ ] })
200
+ ] }, m)) })
201
+ ] })
202
+ ] })
203
+ ]
204
+ }
205
+ );
206
+ };
207
+
208
+ export { AssistantDetailDialog };
209
+ //# sourceMappingURL=AssistantDetailDialog.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantDetailDialog.esm.js","sources":["../../src/collapsible/AssistantDetailDialog.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { makeStyles, useTheme, fade } from '@material-ui/core/styles';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport IconButton from '@material-ui/core/IconButton';\nimport Typography from '@material-ui/core/Typography';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport CloseIcon from '@material-ui/icons/Close';\nimport StarIcon from '@material-ui/icons/Star';\nimport InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';\nimport { AssistantSummary } from '@drewswiredin/backstage-plugin-assistants-common';\nimport { AssistantAvatar, resolveAssistantColor } from './surface/AssistantAvatar';\n\nconst MONO =\n '\"SFMono-Regular\", Menlo, Monaco, Consolas, \"Liberation Mono\", monospace';\n\nconst useStyles = makeStyles(theme => ({\n // overflow:hidden so the accent bar clips to the dialog's radius.\n paper: {\n overflow: 'hidden',\n },\n accent: {\n height: 3,\n width: '100%',\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.text.secondary,\n zIndex: 1,\n },\n content: {\n padding: theme.spacing(2, 3, 3),\n },\n // Centered, profile-style identity.\n profile: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n textAlign: 'center',\n gap: theme.spacing(1),\n },\n avatarHalo: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '50%',\n padding: theme.spacing(1.25),\n },\n name: {\n fontWeight: 600,\n },\n description: {\n color: theme.palette.text.secondary,\n maxWidth: '34ch',\n },\n section: {\n marginTop: theme.spacing(2.5),\n },\n sectionLabel: {\n display: 'block',\n color: theme.palette.text.secondary,\n fontWeight: 600,\n fontSize: '0.7rem',\n textTransform: 'uppercase',\n letterSpacing: 0.6,\n marginBottom: theme.spacing(0.5),\n },\n count: {\n color: theme.palette.text.hint,\n fontWeight: 400,\n },\n list: {\n listStyle: 'none',\n margin: 0,\n padding: 0,\n display: 'flex',\n flexDirection: 'column',\n },\n // Technical list row: monospace name; a hover-revealed ⓘ carries the detail.\n row: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n padding: theme.spacing(0.5, 0.75),\n borderRadius: theme.shape.borderRadius,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n '&:hover $infoIcon': {\n opacity: 1,\n pointerEvents: 'auto',\n },\n },\n itemName: {\n fontFamily: MONO,\n fontSize: '0.8rem',\n fontWeight: 500,\n color: theme.palette.text.primary,\n },\n // Hidden until row hover; its tooltip holds the tool's description.\n infoIcon: {\n marginLeft: 'auto',\n flexShrink: 0,\n fontSize: '1rem',\n color: theme.palette.text.hint,\n cursor: 'help',\n opacity: 0,\n pointerEvents: 'none',\n transition: theme.transitions.create('opacity'),\n },\n defaultMarker: {\n marginLeft: 'auto',\n display: 'inline-flex',\n alignItems: 'center',\n gap: theme.spacing(0.25),\n flexShrink: 0,\n fontSize: '0.7rem',\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n color: theme.palette.text.secondary,\n },\n defaultStar: {\n fontSize: '0.9rem',\n },\n muted: {\n color: theme.palette.text.secondary,\n fontStyle: 'italic',\n },\n}));\n\n/** Compact model name: drop the `provider:` and `vendor/` prefixes. */\nconst modelName = (id: string) => id.split(/[:/]/).pop() || id;\n\n/**\n * Assistant detail modal: a centered, profile-style identity (avatar + name +\n * description, with an agent-color accent bar and avatar halo) over technical\n * lists of the assistant's Tools (monospace name + description, full text on\n * hover) and Models (monospace, default marked). All data comes from the\n * browser-safe {@link AssistantSummary}.\n *\n * @public\n */\nexport const AssistantDetailDialog: FC<{\n assistant?: AssistantSummary;\n open: boolean;\n onClose: () => void;\n}> = ({ assistant, open, onClose }) => {\n const classes = useStyles();\n const theme = useTheme();\n if (!assistant) {\n return null;\n }\n const tools = assistant.tools ?? [];\n const models = assistant.models;\n const color = resolveAssistantColor(assistant.color, theme.palette.type);\n\n return (\n <Dialog\n open={open}\n onClose={onClose}\n maxWidth=\"xs\"\n fullWidth\n classes={{ paper: classes.paper }}\n >\n <div className={classes.accent} style={{ backgroundColor: color }} />\n <IconButton\n aria-label=\"Close\"\n className={classes.closeButton}\n size=\"small\"\n onClick={onClose}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n\n <DialogContent className={classes.content}>\n <div className={classes.profile}>\n <span\n className={classes.avatarHalo}\n style={{ backgroundColor: fade(color, 0.15) }}\n >\n <AssistantAvatar color={assistant.color} size={56} />\n </span>\n <Typography variant=\"h6\" className={classes.name}>\n {assistant.title}\n </Typography>\n {assistant.description && (\n <Typography variant=\"body2\" className={classes.description}>\n {assistant.description}\n </Typography>\n )}\n </div>\n\n <div className={classes.section}>\n <Typography variant=\"caption\" className={classes.sectionLabel}>\n Tools <span className={classes.count}>{tools.length}</span>\n </Typography>\n {tools.length === 0 ? (\n <Typography variant=\"body2\" className={classes.muted}>\n No tools available\n </Typography>\n ) : (\n <ul className={classes.list}>\n {tools.map(t => (\n <li key={t.name} className={classes.row}>\n <span className={classes.itemName}>{t.name}</span>\n {t.description && (\n <Tooltip title={t.description} placement=\"top-end\">\n <InfoOutlinedIcon className={classes.infoIcon} />\n </Tooltip>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n\n <div className={classes.section}>\n <Typography variant=\"caption\" className={classes.sectionLabel}>\n Models{' '}\n {models && <span className={classes.count}>{models.length}</span>}\n </Typography>\n {!models ? (\n <Typography variant=\"body2\" className={classes.muted}>\n All available models\n </Typography>\n ) : (\n <ul className={classes.list}>\n {models.map(m => (\n <li key={m} className={classes.row}>\n <span className={classes.itemName}>{modelName(m)}</span>\n {m === assistant.defaultModel && (\n <span className={classes.defaultMarker}>\n <StarIcon\n className={classes.defaultStar}\n style={{ color }}\n />\n default\n </span>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
3
+ import { makeStyles } from '@material-ui/core/styles';
4
+ import List from '@material-ui/core/List';
5
+ import ListItem from '@material-ui/core/ListItem';
6
+ import ListItemIcon from '@material-ui/core/ListItemIcon';
7
+ import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
8
+ import ListItemText from '@material-ui/core/ListItemText';
9
+ import IconButton from '@material-ui/core/IconButton';
10
+ import Badge from '@material-ui/core/Badge';
11
+ import Tooltip from '@material-ui/core/Tooltip';
12
+ import Typography from '@material-ui/core/Typography';
13
+ import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';
14
+ import { AssistantAvatar } from './surface/AssistantAvatar.esm.js';
15
+ import { AssistantDetailDialog } from './AssistantDetailDialog.esm.js';
16
+ import { useUnreadVersion, hasUnread } from './unreadStore.esm.js';
17
+
18
+ const useStyles = makeStyles((theme) => ({
19
+ root: {
20
+ display: "flex",
21
+ flexDirection: "column",
22
+ padding: theme.spacing(1, 1.5, 0)
23
+ },
24
+ label: {
25
+ color: theme.palette.text.secondary,
26
+ fontWeight: 600,
27
+ textTransform: "uppercase",
28
+ letterSpacing: 0.5,
29
+ padding: theme.spacing(0, 0.5, 0.5)
30
+ },
31
+ item: {
32
+ borderRadius: theme.shape.borderRadius
33
+ },
34
+ // The hover rule lives on the container <li> (ListItem's ContainerProps), which
35
+ // wraps BOTH the row and the secondary action. The action is a *sibling* of the
36
+ // ListItem root, so a :hover rule on the row itself can't reach it.
37
+ container: {
38
+ "&:hover $infoAction": {
39
+ opacity: 1,
40
+ pointerEvents: "auto"
41
+ }
42
+ },
43
+ icon: {
44
+ minWidth: 32,
45
+ display: "inline-flex",
46
+ alignItems: "center"
47
+ },
48
+ // Hidden until row hover (opacity + pointer-events so it's not clickable while
49
+ // hidden); no reserved gutter so the title uses full width and truncates later.
50
+ infoAction: {
51
+ opacity: 0,
52
+ pointerEvents: "none",
53
+ color: theme.palette.text.secondary,
54
+ transition: theme.transitions.create("opacity")
55
+ }
56
+ }));
57
+ const AssistantsList = ({ assistants, activeId, onSelect }) => {
58
+ const classes = useStyles();
59
+ useUnreadVersion();
60
+ const [detailId, setDetailId] = useState(null);
61
+ const openDetail = (e, id) => {
62
+ e.stopPropagation();
63
+ setDetailId(id);
64
+ };
65
+ return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
66
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: classes.label, children: "Assistants" }),
67
+ /* @__PURE__ */ jsx(List, { dense: true, disablePadding: true, children: assistants.map((a) => /* @__PURE__ */ jsxs(
68
+ ListItem,
69
+ {
70
+ button: true,
71
+ selected: a.id === activeId,
72
+ className: classes.item,
73
+ ContainerProps: { className: classes.container },
74
+ onClick: () => onSelect(a.id),
75
+ children: [
76
+ /* @__PURE__ */ jsx(ListItemIcon, { className: classes.icon, children: /* @__PURE__ */ jsx(
77
+ Badge,
78
+ {
79
+ color: "error",
80
+ variant: "dot",
81
+ overlap: "circular",
82
+ invisible: !hasUnread(a.id),
83
+ children: /* @__PURE__ */ jsx(AssistantAvatar, { color: a.color, size: 22 })
84
+ }
85
+ ) }),
86
+ /* @__PURE__ */ jsx(
87
+ ListItemText,
88
+ {
89
+ primary: a.title,
90
+ primaryTypographyProps: { variant: "body2", noWrap: true }
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(ListItemSecondaryAction, { className: classes.infoAction, children: /* @__PURE__ */ jsx(Tooltip, { title: "Details", children: /* @__PURE__ */ jsx(
94
+ IconButton,
95
+ {
96
+ edge: "end",
97
+ size: "small",
98
+ "aria-label": `${a.title} details`,
99
+ onClick: (e) => openDetail(e, a.id),
100
+ children: /* @__PURE__ */ jsx(InfoOutlinedIcon, { fontSize: "small" })
101
+ }
102
+ ) }) })
103
+ ]
104
+ },
105
+ a.id
106
+ )) }),
107
+ /* @__PURE__ */ jsx(
108
+ AssistantDetailDialog,
109
+ {
110
+ assistant: assistants.find((a) => a.id === detailId),
111
+ open: detailId !== null,
112
+ onClose: () => setDetailId(null)
113
+ }
114
+ )
115
+ ] });
116
+ };
117
+
118
+ export { AssistantsList };
119
+ //# sourceMappingURL=AssistantsList.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantsList.esm.js","sources":["../../src/collapsible/AssistantsList.tsx"],"sourcesContent":["import { FC, MouseEvent, useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport IconButton from '@material-ui/core/IconButton';\nimport Badge from '@material-ui/core/Badge';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport InfoOutlinedIcon from '@material-ui/icons/InfoOutlined';\nimport { AssistantSummary } from '@drewswiredin/backstage-plugin-assistants-common';\nimport { AssistantAvatar } from './surface/AssistantAvatar';\nimport { AssistantDetailDialog } from './AssistantDetailDialog';\nimport { hasUnread, useUnreadVersion } from './unreadStore';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n flexDirection: 'column',\n padding: theme.spacing(1, 1.5, 0),\n },\n label: {\n color: theme.palette.text.secondary,\n fontWeight: 600,\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n padding: theme.spacing(0, 0.5, 0.5),\n },\n item: {\n borderRadius: theme.shape.borderRadius,\n },\n // The hover rule lives on the container <li> (ListItem's ContainerProps), which\n // wraps BOTH the row and the secondary action. The action is a *sibling* of the\n // ListItem root, so a :hover rule on the row itself can't reach it.\n container: {\n '&:hover $infoAction': {\n opacity: 1,\n pointerEvents: 'auto',\n },\n },\n icon: {\n minWidth: 32,\n display: 'inline-flex',\n alignItems: 'center',\n },\n // Hidden until row hover (opacity + pointer-events so it's not clickable while\n // hidden); no reserved gutter so the title uses full width and truncates later.\n infoAction: {\n opacity: 0,\n pointerEvents: 'none',\n color: theme.palette.text.secondary,\n transition: theme.transitions.create('opacity'),\n },\n}));\n\n/**\n * The in-page assistant switcher (top tier of the left sidebar). Lists every\n * accessible assistant; selecting one drives `?assistant=<id>` via `onSelect`,\n * which remounts the chat onto that assistant's (siloed) conversation set. The\n * active assistant is highlighted. A hover-revealed info button opens the\n * {@link AssistantDetailDialog} (description, tools, models).\n *\n * @public\n */\nexport const AssistantsList: FC<{\n assistants: AssistantSummary[];\n activeId: string;\n onSelect: (id: string) => void;\n}> = ({ assistants, activeId, onSelect }) => {\n const classes = useStyles();\n useUnreadVersion(); // re-render when unread state changes\n const [detailId, setDetailId] = useState<string | null>(null);\n\n const openDetail = (e: MouseEvent<HTMLElement>, id: string) => {\n e.stopPropagation();\n setDetailId(id);\n };\n\n return (\n <div className={classes.root}>\n <Typography variant=\"caption\" className={classes.label}>\n Assistants\n </Typography>\n <List dense disablePadding>\n {assistants.map(a => (\n <ListItem\n key={a.id}\n button\n selected={a.id === activeId}\n className={classes.item}\n ContainerProps={{ className: classes.container }}\n onClick={() => onSelect(a.id)}\n >\n <ListItemIcon className={classes.icon}>\n <Badge\n color=\"error\"\n variant=\"dot\"\n overlap=\"circular\"\n invisible={!hasUnread(a.id)}\n >\n <AssistantAvatar color={a.color} size={22} />\n </Badge>\n </ListItemIcon>\n <ListItemText\n primary={a.title}\n primaryTypographyProps={{ variant: 'body2', noWrap: true }}\n />\n <ListItemSecondaryAction className={classes.infoAction}>\n <Tooltip title=\"Details\">\n <IconButton\n edge=\"end\"\n size=\"small\"\n aria-label={`${a.title} details`}\n onClick={e => openDetail(e, a.id)}\n >\n <InfoOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </ListItemSecondaryAction>\n </ListItem>\n ))}\n </List>\n\n <AssistantDetailDialog\n assistant={assistants.find(a => a.id === detailId)}\n open={detailId !== null}\n onClose={() => setDetailId(null)}\n />\n </div>\n );\n};\n"],"names":[],"mappings":"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"}