@cognizant-ai-lab/ui-common 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Theme/Palettes.d.ts +0 -9
- package/dist/Theme/Palettes.js +0 -18
- package/dist/components/AgentChat/ChatCommon/ChatCommon.d.ts +4 -1
- package/dist/components/AgentChat/ChatCommon/ChatCommon.js +74 -47
- package/dist/components/AgentChat/ChatCommon/Const.d.ts +1 -0
- package/dist/components/AgentChat/ChatCommon/Const.js +2 -0
- package/dist/components/AgentChat/ChatCommon/ControlButtons.d.ts +1 -1
- package/dist/components/AgentChat/ChatCommon/ControlButtons.js +7 -4
- package/dist/components/AgentChat/ChatCommon/FormattedMarkdown.js +3 -0
- package/dist/components/AgentChat/ChatCommon/SendButton.js +7 -6
- package/dist/components/AgentChat/ChatCommon/SyntaxHighlighterThemes.js +1 -1
- package/dist/components/AgentChat/ChatCommon/Thinking.d.ts +1 -0
- package/dist/components/AgentChat/ChatCommon/Thinking.js +10 -7
- package/dist/components/AgentChat/Common/LlmChatButton.d.ts +0 -2
- package/dist/components/AgentChat/Common/LlmChatButton.js +6 -9
- package/dist/components/AgentChat/VoiceChat/MicrophoneButton.js +12 -10
- package/dist/components/Common/Navbar.js +24 -22
- package/dist/components/Common/StatusLight.d.ts +9 -0
- package/dist/components/Common/StatusLight.js +21 -0
- package/dist/components/ErrorPage/ErrorBoundary.js +1 -1
- package/dist/components/ErrorPage/ErrorPage.d.ts +3 -3
- package/dist/components/ErrorPage/ErrorPage.js +4 -3
- package/dist/components/Logo/Common.d.ts +4 -0
- package/dist/components/Logo/Common.js +8 -0
- package/dist/components/Logo/CustomerLogo.d.ts +23 -0
- package/dist/components/Logo/CustomerLogo.js +41 -0
- package/dist/components/MultiAgentAccelerator/AgentConversations.js +0 -1
- package/dist/components/MultiAgentAccelerator/AgentFlow.js +85 -53
- package/dist/components/MultiAgentAccelerator/AgentNode.js +23 -27
- package/dist/components/MultiAgentAccelerator/GraphLayouts.d.ts +17 -10
- package/dist/components/MultiAgentAccelerator/GraphLayouts.js +4 -6
- package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.d.ts +3 -9
- package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.js +28 -32
- package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.d.ts +0 -5
- package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.js +30 -25
- package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.d.ts +3 -4
- package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.js +84 -168
- package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.d.ts +30 -13
- package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.js +157 -100
- package/dist/components/MultiAgentAccelerator/Tour/MainTourSteps.js +10 -8
- package/dist/components/MultiAgentAccelerator/const.d.ts +2 -0
- package/dist/components/MultiAgentAccelerator/const.js +4 -0
- package/dist/components/Settings/ApiKeyInput.js +7 -8
- package/dist/components/Settings/InfoTip.d.ts +8 -0
- package/dist/components/Settings/InfoTip.js +14 -0
- package/dist/components/Settings/SettingsDialog.js +355 -181
- package/dist/components/Settings/SettingsRow.d.ts +18 -0
- package/dist/components/Settings/SettingsRow.js +35 -0
- package/dist/controller/agent/Agent.d.ts +3 -20
- package/dist/controller/agent/Agent.js +9 -43
- package/dist/controller/agent/IconSuggestions.d.ts +35 -0
- package/dist/controller/agent/IconSuggestions.js +85 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/state/IconSuggestions.d.ts +27 -0
- package/dist/state/IconSuggestions.js +50 -0
- package/dist/state/Settings.d.ts +17 -3
- package/dist/state/Settings.js +23 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/title.js +1 -1
- package/package.json +5 -1
- package/dist/components/Common/CustomerLogo.d.ts +0 -17
- package/dist/components/Common/CustomerLogo.js +0 -47
- package/dist/components/Common/MUIAccordion.d.ts +0 -17
- package/dist/components/Common/MUIAccordion.js +0 -66
- package/dist/utils/useLocalStorage.d.ts +0 -1
- package/dist/utils/useLocalStorage.js +0 -55
|
@@ -15,27 +15,22 @@ See the License for the specific language governing permissions and
|
|
|
15
15
|
limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
import AddBoxRounded from "@mui/icons-material/AddBoxRounded";
|
|
18
|
-
import CheckCircleOutlinedIcon from "@mui/icons-material/CheckCircleOutlined";
|
|
19
|
-
import ClearIcon from "@mui/icons-material/Clear";
|
|
20
|
-
import HighlightOff from "@mui/icons-material/HighlightOff";
|
|
21
|
-
import SettingsIcon from "@mui/icons-material/Settings";
|
|
22
18
|
import Box from "@mui/material/Box";
|
|
23
19
|
import Button from "@mui/material/Button";
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import Popover from "@mui/material/Popover";
|
|
27
|
-
import { keyframes, styled, useTheme } from "@mui/material/styles";
|
|
28
|
-
import TextField from "@mui/material/TextField";
|
|
29
|
-
import Tooltip from "@mui/material/Tooltip";
|
|
20
|
+
import { keyframes, styled } from "@mui/material/styles";
|
|
21
|
+
import Tooltip, { tooltipClasses } from "@mui/material/Tooltip";
|
|
30
22
|
import Typography from "@mui/material/Typography";
|
|
31
23
|
import { RichTreeView } from "@mui/x-tree-view/RichTreeView";
|
|
32
|
-
import
|
|
24
|
+
import httpStatus from "http-status";
|
|
25
|
+
import { useEffect, useState } from "react";
|
|
33
26
|
import { AgentNetworkTreeItem } from "./AgentNetworkTreeItem.js";
|
|
34
|
-
import { buildTreeViewItems } from "./TreeBuilder.js";
|
|
27
|
+
import { buildTreeViewItems, findTreeItemById } from "./TreeBuilder.js";
|
|
35
28
|
import { testConnection } from "../../../controller/agent/Agent.js";
|
|
36
|
-
import {
|
|
29
|
+
import { useSettingsStore } from "../../../state/Settings.js";
|
|
37
30
|
import { getZIndex } from "../../../utils/zIndexLayers.js";
|
|
31
|
+
import { StatusLight } from "../../Common/StatusLight.js";
|
|
38
32
|
import { AGENT_NETWORK_DESIGNER_ID, TEMPORARY_NETWORK_FOLDER } from "../const.js";
|
|
33
|
+
//#region Constants
|
|
39
34
|
// Animation for the sparkle effect when a new temporary network is added.
|
|
40
35
|
const sparkle = keyframes `
|
|
41
36
|
0% {
|
|
@@ -71,13 +66,13 @@ const sparkle = keyframes `
|
|
|
71
66
|
opacity: 0.25;
|
|
72
67
|
}
|
|
73
68
|
`;
|
|
74
|
-
// #region: Styled Components
|
|
75
|
-
const PrimaryButton = styled(Button)({
|
|
76
|
-
marginLeft: "0.5rem",
|
|
77
|
-
marginTop: "2px",
|
|
78
|
-
});
|
|
79
69
|
// Name for sparkle animation CSS class
|
|
80
70
|
export const SPARKLE_HIGHLIGHT_CLASS = "sparkle-highlight";
|
|
71
|
+
const EMPTY_ARRAY = [];
|
|
72
|
+
// Interval for pinging the Neuro-san server to check if it's online, in milliseconds
|
|
73
|
+
const NEURO_SAN_PING_INTERVAL_MS = 30_000;
|
|
74
|
+
//#endregion: Constants
|
|
75
|
+
//#region: Styled Components
|
|
81
76
|
// Styled component for Sidebar aside element, including styles for the sparkle highlight animation
|
|
82
77
|
// when a new temporary network is added.
|
|
83
78
|
const SidebarAside = styled("aside")({
|
|
@@ -111,98 +106,48 @@ const SidebarHeading = styled("h2")(({ theme }) => ({
|
|
|
111
106
|
top: 0,
|
|
112
107
|
zIndex: getZIndex(1, theme),
|
|
113
108
|
}));
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaitingLlm, networkIconSuggestions, networks, newlyAddedTemporaryNetworks, onDeleteNetwork, onEditNetwork, setSelectedNetwork, temporaryNetworks = EMPTY_ARRAY, }) => {
|
|
125
|
-
// Get default URL from the environment store.
|
|
126
|
-
const { backendNeuroSanApiUrl } = useEnvironmentStore();
|
|
127
|
-
const [urlInput, setUrlInput] = useState(customURLLocalStorage || backendNeuroSanApiUrl);
|
|
128
|
-
const [connectionStatus, setConnectionStatus] = useState(CONNECTION_STATUS.IDLE);
|
|
129
|
-
const [testConnectionResult, setTestConnectionResult] = useState(null);
|
|
130
|
-
const connectionStatusSuccess = connectionStatus === CONNECTION_STATUS.SUCCESS;
|
|
131
|
-
const connectionStatusError = connectionStatus === CONNECTION_STATUS.ERROR;
|
|
132
|
-
const isDefaultUrl = urlInput === backendNeuroSanApiUrl;
|
|
133
|
-
const saveEnabled = urlInput && (connectionStatusSuccess || (isDefaultUrl && !connectionStatusError));
|
|
134
|
-
const [settingsAnchorEl, setSettingsAnchorEl] = useState(null);
|
|
135
|
-
const settingsPopoverOpen = Boolean(settingsAnchorEl);
|
|
109
|
+
// For showing server status which can be lengthy
|
|
110
|
+
const ServerStatusTooltip = styled(({ className, ...props }) => (_jsx(Tooltip, { describeChild: true, ...props, classes: { popper: className } })))({
|
|
111
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
112
|
+
backgroundColor: "rgba(97, 97, 97, 1)",
|
|
113
|
+
maxWidth: 500,
|
|
114
|
+
opacity: 1,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
//#endregion: Types
|
|
118
|
+
export const Sidebar = ({ id, isAwaitingLlm, networkIconSuggestions, networks, neuroSanServerURL, newlyAddedTemporaryNetworks, onDeleteNetwork, onEditNetwork, setSelectedNetwork, temporaryNetworks = EMPTY_ARRAY, }) => {
|
|
136
119
|
const [expandedItems, setExpandedItems] = useState([]);
|
|
137
120
|
const [selectedItem, setSelectedItem] = useState(null);
|
|
138
|
-
//
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
// On open of Settings popover, reset the connection status to idle
|
|
142
|
-
setConnectionStatus(CONNECTION_STATUS.IDLE);
|
|
143
|
-
setSettingsAnchorEl(event.currentTarget);
|
|
144
|
-
};
|
|
145
|
-
const handleSettingsClose = (cancel = false) => {
|
|
146
|
-
setSettingsAnchorEl(null);
|
|
147
|
-
// If the user cancels, reset the custom URL input to the local storage value, or the default URL
|
|
148
|
-
if (cancel) {
|
|
149
|
-
setUrlInput(customURLLocalStorage || backendNeuroSanApiUrl);
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
const handleURLChange = (event) => {
|
|
153
|
-
setUrlInput(event.target.value);
|
|
154
|
-
// Reset connection check since URL input was changed
|
|
155
|
-
setConnectionStatus(CONNECTION_STATUS.IDLE);
|
|
156
|
-
};
|
|
157
|
-
const handleDefaultSettings = () => {
|
|
158
|
-
// Clear input but don't close the popover
|
|
159
|
-
setUrlInput(backendNeuroSanApiUrl);
|
|
160
|
-
// Reset connection check since URL input was cleared
|
|
161
|
-
setConnectionStatus(CONNECTION_STATUS.IDLE);
|
|
162
|
-
};
|
|
163
|
-
const handleSaveSettings = () => {
|
|
164
|
-
let tempUrl = urlInput;
|
|
165
|
-
if (tempUrl.endsWith("/")) {
|
|
166
|
-
tempUrl = tempUrl.slice(0, -1);
|
|
167
|
-
}
|
|
168
|
-
if (tempUrl && !tempUrl.startsWith("http://") && !tempUrl.startsWith("https://")) {
|
|
169
|
-
tempUrl = `https://${tempUrl}`;
|
|
170
|
-
}
|
|
171
|
-
// Call setSelectedNetwork(null) otherwise it can cause issues when switching agent networks (i.e. for Save)
|
|
172
|
-
setSelectedNetwork(null);
|
|
173
|
-
handleSettingsClose();
|
|
174
|
-
customURLCallback(tempUrl);
|
|
175
|
-
};
|
|
176
|
-
const handleSettingsSaveEnterKey = (event) => {
|
|
177
|
-
if (event.key === "Enter" && saveEnabled) {
|
|
178
|
-
handleSaveSettings();
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
const handleTestConnection = async () => {
|
|
182
|
-
const result = await testConnection(urlInput);
|
|
183
|
-
setTestConnectionResult(result);
|
|
184
|
-
if (result.success) {
|
|
185
|
-
setConnectionStatus(CONNECTION_STATUS.SUCCESS);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
setConnectionStatus(CONNECTION_STATUS.ERROR);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
const handleClearInput = () => {
|
|
192
|
-
setUrlInput("");
|
|
193
|
-
setConnectionStatus(CONNECTION_STATUS.IDLE);
|
|
194
|
-
};
|
|
195
|
-
// Fetch Neuro-san version on load and whenever the saved URL changes
|
|
121
|
+
// Display option for agent/network names
|
|
122
|
+
const useNativeNames = useSettingsStore((state) => state.settings.appearance.useNativeNames);
|
|
123
|
+
const [neuroSanServerStatus, setNeuroSanServerStatus] = useState({ onlineStatus: "unknown", version: null });
|
|
196
124
|
useEffect(() => {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
125
|
+
let isCurrentRequest = true;
|
|
126
|
+
const checkStatus = async () => {
|
|
127
|
+
try {
|
|
128
|
+
const result = await testConnection(neuroSanServerURL);
|
|
129
|
+
if (!isCurrentRequest) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
setNeuroSanServerStatus(result.success
|
|
133
|
+
? { onlineStatus: "online", version: result.version }
|
|
134
|
+
: { error: result.status, httpStatus: result.httpStatus, onlineStatus: "offline", version: null });
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (!isCurrentRequest) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const errorString = error instanceof Error ? error.message : String(error);
|
|
141
|
+
setNeuroSanServerStatus({ error: errorString, onlineStatus: "offline", version: null });
|
|
202
142
|
}
|
|
203
143
|
};
|
|
204
|
-
void
|
|
205
|
-
|
|
144
|
+
void checkStatus();
|
|
145
|
+
const intervalId = setInterval(checkStatus, NEURO_SAN_PING_INTERVAL_MS);
|
|
146
|
+
return () => {
|
|
147
|
+
isCurrentRequest = false;
|
|
148
|
+
clearInterval(intervalId);
|
|
149
|
+
};
|
|
150
|
+
}, [neuroSanServerURL]);
|
|
206
151
|
// When the edit pencil is clicked, select the network first (if not already selected) so the network loads
|
|
207
152
|
// before entering edit mode — the user shouldn't have to click the network and then click the pencil separately.
|
|
208
153
|
const handleEditNetworkWithSelect = (network) => {
|
|
@@ -212,26 +157,21 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
212
157
|
}
|
|
213
158
|
onEditNetwork?.(network);
|
|
214
159
|
};
|
|
215
|
-
const
|
|
216
|
-
const temporaryNetworkExpirationTimes = temporaryNetworks.reduce((acc, tempNetwork) => {
|
|
217
|
-
acc[tempNetwork.agentInfo.agent_name] = new Date(tempNetwork.reservation.expiration_time_in_seconds * 1000);
|
|
218
|
-
return acc;
|
|
219
|
-
}, {});
|
|
220
|
-
const temporaryNetworkHoconStrings = temporaryNetworks.reduce((acc, tempNetwork) => {
|
|
221
|
-
acc[tempNetwork.agentInfo.agent_name] = tempNetwork.networkHocon;
|
|
222
|
-
return acc;
|
|
223
|
-
}, {});
|
|
160
|
+
const treeViewItems = buildTreeViewItems(useNativeNames, networks, temporaryNetworks, networkIconSuggestions);
|
|
224
161
|
const handleSelectedItemsChange = (_event, itemId) => {
|
|
225
162
|
if (!itemId) {
|
|
226
163
|
return;
|
|
227
164
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
165
|
+
const treeItem = findTreeItemById(treeViewItems, itemId);
|
|
166
|
+
if (!treeItem) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// Only allow selecting child nodes (i.e., actual networks), not parent nodes (folders).
|
|
170
|
+
if (!treeItem.isNetwork) {
|
|
231
171
|
return;
|
|
232
172
|
}
|
|
233
173
|
// Don't allow selecting expired temporary networks
|
|
234
|
-
const expirationTime =
|
|
174
|
+
const expirationTime = treeItem?.temporaryNetworkExpirationTime;
|
|
235
175
|
if (expirationTime && expirationTime < new Date()) {
|
|
236
176
|
return;
|
|
237
177
|
}
|
|
@@ -251,7 +191,7 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
251
191
|
in MUI RichTreeView including the imperative API (https://mui.com/x/react-tree-view/rich-tree-view/selection/#imperative-api)
|
|
252
192
|
but couldn't get it to work so resorting to this for now.
|
|
253
193
|
*/
|
|
254
|
-
const temporaryNetworkNode = document.querySelector(`[data-itemid="${firstItem}"]`);
|
|
194
|
+
const temporaryNetworkNode = document.querySelector(`[data-itemid="${CSS.escape(firstItem)}"]`);
|
|
255
195
|
if (temporaryNetworkNode) {
|
|
256
196
|
temporaryNetworkNode.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
|
|
257
197
|
temporaryNetworkNode.classList.add(SPARKLE_HIGHLIGHT_CLASS);
|
|
@@ -266,53 +206,29 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
266
206
|
clearTimeout(removeHighlightTimeout);
|
|
267
207
|
};
|
|
268
208
|
}, [newlyAddedTemporaryNetworks]);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
paddingTop: "0.75rem",
|
|
295
|
-
paddingLeft: "0.5rem",
|
|
296
|
-
paddingRight: "0.5rem",
|
|
297
|
-
paddingBottom: "0.2rem",
|
|
298
|
-
},
|
|
299
|
-
},
|
|
300
|
-
}, children: [_jsx(TextField, { autoComplete: "off", label: "Agent server address", id: "agent-network-settings-url", onChange: handleURLChange, onKeyUp: handleSettingsSaveEnterKey, placeholder: "https://my_server_address:port", size: "small", sx: { marginBottom: "0.5rem", minWidth: "400px" }, type: "url", variant: "outlined", value: urlInput, slotProps: {
|
|
301
|
-
input: {
|
|
302
|
-
endAdornment: urlInput && urlInput !== backendNeuroSanApiUrl ? (_jsx(InputAdornment, { id: "clear-input-adornment", position: "end", children: _jsx(IconButton, { id: "clear-input-icon-button", edge: "end", onClick: handleClearInput, size: "small", "aria-label": "Clear input", children: _jsx(ClearIcon, { fontSize: "small", id: "clear-input-icon" }) }) })) : undefined,
|
|
303
|
-
},
|
|
304
|
-
} }), _jsx(PrimaryButton, { disabled: !urlInput, id: "agent-network-settings-test-btn", onClick: handleTestConnection, variant: "contained", children: "Test" }), _jsx(PrimaryButton, { disabled: !saveEnabled, id: "agent-network-settings-save-btn", onClick: handleSaveSettings, variant: "contained", children: "Save" }), _jsx(PrimaryButton, { id: "agent-network-settings-cancel-btn", onClick: () => handleSettingsClose(true), variant: "contained", children: "Cancel" }), _jsx(Button, { id: "agent-network-settings-default-btn", onClick: handleDefaultSettings, sx: {
|
|
305
|
-
marginLeft: "0.35rem",
|
|
306
|
-
marginTop: "2px",
|
|
307
|
-
color: darkMode ? "var(--bs-dark-mode-link)" : undefined,
|
|
308
|
-
}, variant: "text", children: "Default" }), (connectionStatusSuccess || connectionStatusError) && (_jsxs(Box, { id: "connection-status-box", sx: {
|
|
309
|
-
display: "flex",
|
|
310
|
-
alignItems: "center",
|
|
311
|
-
marginLeft: "0.25rem",
|
|
312
|
-
marginBottom: "0.5rem",
|
|
313
|
-
}, children: [connectionStatusSuccess && (_jsxs(_Fragment, { children: [_jsx(CheckCircleOutlinedIcon, { id: "connection-status-success-icon", sx: { color: "var(--bs-green)", fontSize: "1.2rem", marginRight: "0.25rem" } }), _jsx(Typography, { id: "connection-status-success-msg", variant: "body2", sx: {
|
|
314
|
-
color: "var(--bs-green)",
|
|
315
|
-
}, children: "Connected successfully" })] })), connectionStatusError && (_jsxs(_Fragment, { children: [_jsx(HighlightOff, { id: "connection-status-error-icon", sx: { color: "var(--bs-red)", fontSize: "1.2rem", marginRight: "0.25rem" } }), _jsx(Typography, { id: "connection-status-failed-msg", variant: "body2", sx: {
|
|
316
|
-
color: "var(--bs-red)",
|
|
317
|
-
}, children: `Connection failed: "${testConnectionResult?.status || "unknown error"}"` })] }))] }))] })] }));
|
|
209
|
+
const toStatusColor = () => {
|
|
210
|
+
switch (neuroSanServerStatus.onlineStatus) {
|
|
211
|
+
case "online":
|
|
212
|
+
return "green";
|
|
213
|
+
case "offline":
|
|
214
|
+
return "red";
|
|
215
|
+
case "unknown":
|
|
216
|
+
default:
|
|
217
|
+
return "unknown";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
const getStatusLight = () => (_jsx(ServerStatusTooltip, { slotProps: {
|
|
221
|
+
popper: {
|
|
222
|
+
"aria-label": "Neuro-san server status",
|
|
223
|
+
},
|
|
224
|
+
}, title: _jsxs(Box, { sx: { display: "flex", flexDirection: "column", gap: 0.5 }, children: [_jsxs(Typography, { variant: "body2", children: [_jsx("strong", { children: "Status:" }), " ", neuroSanServerStatus.onlineStatus] }), _jsxs(Typography, { variant: "body2", children: [_jsx("strong", { children: "Version:" }), " ", neuroSanServerStatus.version ?? "unknown"] }), _jsxs(Typography, { variant: "body2", children: [_jsx("strong", { children: "URL:" }), " ", neuroSanServerURL || "unknown"] }), neuroSanServerStatus.error && (_jsxs(_Fragment, { children: [_jsxs(Typography, { variant: "body2", children: [_jsx("strong", { children: "Error:" }), " ", neuroSanServerStatus.error] }), neuroSanServerStatus.httpStatus && (_jsxs(Typography, { variant: "body2", children: [_jsx("strong", { children: "HTTP status:" }), " ", `${neuroSanServerStatus.httpStatus} (${httpStatus[neuroSanServerStatus.httpStatus] ?? "Unknown status"})`] }))] }))] }), placement: "right", children: _jsx("span", { children: _jsx(StatusLight, { id: `${id}-agent-network-status-light`, statusValue: toStatusColor() }) }) }));
|
|
225
|
+
const getAddNetworkButton = () => (_jsx(Box, { sx: { display: "flex" }, children: _jsx(Button, { "aria-label": "Add New Network", disabled: isAwaitingLlm, id: "add-network-btn", onClick: () => {
|
|
226
|
+
setSelectedItem(AGENT_NETWORK_DESIGNER_ID);
|
|
227
|
+
setSelectedNetwork(AGENT_NETWORK_DESIGNER_ID);
|
|
228
|
+
}, sx: { display: "inline-block", minWidth: "40px" }, children: _jsx(Tooltip, { title: "Create your own agent network", placement: "top", children: _jsx(AddBoxRounded, { id: "add-network-icon", sx: { color: "var(--bs-secondary)" } }) }) }) }));
|
|
229
|
+
const getSidebarHeading = () => (_jsxs(SidebarHeading, { id: `${id}-heading`, children: [_jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: (theme) => theme.spacing(1.5) }, children: [getStatusLight(), "Agent Networks"] }), getAddNetworkButton()] }));
|
|
230
|
+
const getSidebarNetworksTree = () => (_jsx(RichTreeView, { disableSelection: isAwaitingLlm, expandedItems: expandedItems, items: treeViewItems, multiSelect: false, onExpandedItemsChange: (_event, itemIds) => setExpandedItems(itemIds), onSelectedItemsChange: handleSelectedItemsChange, selectedItems: selectedItem, slotProps: {
|
|
231
|
+
item: { onDeleteNetwork, onEditNetwork: handleEditNetworkWithSelect },
|
|
232
|
+
}, slots: { item: AgentNetworkTreeItem } }));
|
|
233
|
+
return (_jsxs(SidebarAside, { id: `${id}-sidebar`, children: [getSidebarHeading(), getSidebarNetworksTree()] }));
|
|
318
234
|
};
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
import { TreeViewDefaultItemModelProperties } from "@mui/x-tree-view/models";
|
|
2
2
|
import { AgentInfo } from "../../../generated/neuro-san/NeuroSanClient.js";
|
|
3
3
|
import { TemporaryNetwork } from "../../../state/TemporaryNetworks.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Represents either a category (folder) or a network (leaf) in the tree view.
|
|
6
|
+
* Note that we omit the `children` property from the parent as we want to use read-only semantics
|
|
7
|
+
*/
|
|
8
|
+
export interface AgentNetworkTreeItemModel extends Omit<TreeViewDefaultItemModelProperties, "children"> {
|
|
9
|
+
readonly children?: readonly AgentNetworkTreeItemModel[];
|
|
10
|
+
readonly displayName: string;
|
|
11
|
+
readonly iconSuggestion?: string;
|
|
12
|
+
readonly isNetwork: boolean;
|
|
13
|
+
readonly tags?: readonly string[];
|
|
14
|
+
readonly temporaryNetworkExpirationTime?: Date;
|
|
15
|
+
readonly temporaryNetworkHocon?: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Recursively searches for a tree item with the specified ID within the given list of tree items.
|
|
19
|
+
* @param items - The list of tree items to search through
|
|
20
|
+
* @param itemId - The ID of the tree item to find
|
|
21
|
+
* @returns The tree item with the matching ID, or undefined if not found
|
|
22
|
+
*
|
|
23
|
+
* @note Short-circuiting is used to avoid unnecessary searches once a match is found (compared to e.g., `flatMap()`)
|
|
24
|
+
*/
|
|
25
|
+
export declare const findTreeItemById: (items: readonly AgentNetworkTreeItemModel[], itemId: string) => AgentNetworkTreeItemModel | undefined;
|
|
8
26
|
/**
|
|
9
27
|
* Build a tree view structure from a flat list of networks.
|
|
10
28
|
* The list of networks comes from a call to the Neuro-san /list API
|
|
11
|
-
* The tree structure is used by the RichTreeView component to display the networks
|
|
12
|
-
*
|
|
13
|
-
* @param
|
|
14
|
-
* @
|
|
15
|
-
*
|
|
29
|
+
* The tree structure is used by the RichTreeView component to display the networks.
|
|
30
|
+
*
|
|
31
|
+
* @param useNativeNames - Whether to use the raw agent names from the API or to clean them up for display.
|
|
32
|
+
* @param regularNetworks - Array of networks from the Neuro-san /list API
|
|
33
|
+
* @param temporaryNetworks - Array of temporary networks (e.g., ones recently created by the user)
|
|
34
|
+
* @param iconSuggestions
|
|
35
|
+
* @returns Array of {@linkcode AgentNetworkTreeItemModel} objects representing the tree structure
|
|
16
36
|
*/
|
|
17
|
-
export declare const buildTreeViewItems: (
|
|
18
|
-
treeViewItems: TreeViewDefaultItemModelProperties[];
|
|
19
|
-
nodeIndex: NodeIndex;
|
|
20
|
-
};
|
|
37
|
+
export declare const buildTreeViewItems: (useNativeNames: boolean, regularNetworks?: readonly AgentInfo[], temporaryNetworks?: readonly TemporaryNetwork[], iconSuggestions?: Record<string, string>) => AgentNetworkTreeItemModel[];
|