@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.
Files changed (67) hide show
  1. package/dist/Theme/Palettes.d.ts +0 -9
  2. package/dist/Theme/Palettes.js +0 -18
  3. package/dist/components/AgentChat/ChatCommon/ChatCommon.d.ts +4 -1
  4. package/dist/components/AgentChat/ChatCommon/ChatCommon.js +74 -47
  5. package/dist/components/AgentChat/ChatCommon/Const.d.ts +1 -0
  6. package/dist/components/AgentChat/ChatCommon/Const.js +2 -0
  7. package/dist/components/AgentChat/ChatCommon/ControlButtons.d.ts +1 -1
  8. package/dist/components/AgentChat/ChatCommon/ControlButtons.js +7 -4
  9. package/dist/components/AgentChat/ChatCommon/FormattedMarkdown.js +3 -0
  10. package/dist/components/AgentChat/ChatCommon/SendButton.js +7 -6
  11. package/dist/components/AgentChat/ChatCommon/SyntaxHighlighterThemes.js +1 -1
  12. package/dist/components/AgentChat/ChatCommon/Thinking.d.ts +1 -0
  13. package/dist/components/AgentChat/ChatCommon/Thinking.js +10 -7
  14. package/dist/components/AgentChat/Common/LlmChatButton.d.ts +0 -2
  15. package/dist/components/AgentChat/Common/LlmChatButton.js +6 -9
  16. package/dist/components/AgentChat/VoiceChat/MicrophoneButton.js +12 -10
  17. package/dist/components/Common/Navbar.js +24 -22
  18. package/dist/components/Common/StatusLight.d.ts +9 -0
  19. package/dist/components/Common/StatusLight.js +21 -0
  20. package/dist/components/ErrorPage/ErrorBoundary.js +1 -1
  21. package/dist/components/ErrorPage/ErrorPage.d.ts +3 -3
  22. package/dist/components/ErrorPage/ErrorPage.js +4 -3
  23. package/dist/components/Logo/Common.d.ts +4 -0
  24. package/dist/components/Logo/Common.js +8 -0
  25. package/dist/components/Logo/CustomerLogo.d.ts +23 -0
  26. package/dist/components/Logo/CustomerLogo.js +41 -0
  27. package/dist/components/MultiAgentAccelerator/AgentConversations.js +0 -1
  28. package/dist/components/MultiAgentAccelerator/AgentFlow.js +85 -53
  29. package/dist/components/MultiAgentAccelerator/AgentNode.js +23 -27
  30. package/dist/components/MultiAgentAccelerator/GraphLayouts.d.ts +17 -10
  31. package/dist/components/MultiAgentAccelerator/GraphLayouts.js +4 -6
  32. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.d.ts +3 -9
  33. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.js +28 -32
  34. package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.d.ts +0 -5
  35. package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.js +30 -25
  36. package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.d.ts +3 -4
  37. package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.js +84 -168
  38. package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.d.ts +30 -13
  39. package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.js +157 -100
  40. package/dist/components/MultiAgentAccelerator/Tour/MainTourSteps.js +10 -8
  41. package/dist/components/MultiAgentAccelerator/const.d.ts +2 -0
  42. package/dist/components/MultiAgentAccelerator/const.js +4 -0
  43. package/dist/components/Settings/ApiKeyInput.js +7 -8
  44. package/dist/components/Settings/InfoTip.d.ts +8 -0
  45. package/dist/components/Settings/InfoTip.js +14 -0
  46. package/dist/components/Settings/SettingsDialog.js +355 -181
  47. package/dist/components/Settings/SettingsRow.d.ts +18 -0
  48. package/dist/components/Settings/SettingsRow.js +35 -0
  49. package/dist/controller/agent/Agent.d.ts +3 -20
  50. package/dist/controller/agent/Agent.js +9 -43
  51. package/dist/controller/agent/IconSuggestions.d.ts +35 -0
  52. package/dist/controller/agent/IconSuggestions.js +85 -0
  53. package/dist/index.d.ts +0 -2
  54. package/dist/index.js +0 -2
  55. package/dist/state/IconSuggestions.d.ts +27 -0
  56. package/dist/state/IconSuggestions.js +50 -0
  57. package/dist/state/Settings.d.ts +17 -3
  58. package/dist/state/Settings.js +23 -1
  59. package/dist/tsconfig.build.tsbuildinfo +1 -1
  60. package/dist/utils/title.js +1 -1
  61. package/package.json +5 -1
  62. package/dist/components/Common/CustomerLogo.d.ts +0 -17
  63. package/dist/components/Common/CustomerLogo.js +0 -47
  64. package/dist/components/Common/MUIAccordion.d.ts +0 -17
  65. package/dist/components/Common/MUIAccordion.js +0 -66
  66. package/dist/utils/useLocalStorage.d.ts +0 -1
  67. package/dist/utils/useLocalStorage.js +0 -55
@@ -24,13 +24,20 @@ export declare const getThoughtBubbleEdges: (thoughtBubbleEdges: Map<string, {
24
24
  edge: ThoughtBubbleEdgeShape;
25
25
  timestamp: number;
26
26
  }>) => ThoughtBubbleEdgeShape[];
27
- export declare const layoutRadial: (agentCounts: Map<string, number>, agentsInNetwork: ConnectivityInfo[], currentConversations: AgentConversation[] | null, // For plasma edges (live) and node highlighting
28
- isAwaitingLlm: boolean, isAgentNetworkDesignerMode: boolean, thoughtBubbleEdges: Map<string, {
29
- edge: ThoughtBubbleEdgeShape;
30
- timestamp: number;
31
- }>, agentIconSuggestions?: AgentIconSuggestions, isTemporaryNetwork?: boolean) => LayoutResult;
32
- export declare const layoutLinear: (agentCounts: Map<string, number>, agentsInNetwork: ConnectivityInfo[], currentConversations: AgentConversation[] | null, // For plasma edges (live) and node highlighting
33
- isAwaitingLlm: boolean, isAgentNetworkDesignerMode: boolean, thoughtBubbleEdges: Map<string, {
34
- edge: ThoughtBubbleEdgeShape;
35
- timestamp: number;
36
- }>, agentIconSuggestions?: AgentIconSuggestions, isTemporaryNetwork?: boolean) => LayoutResult;
27
+ /** * Shared options for graph layout functions. */
28
+ export type LayoutOptions = {
29
+ readonly agentCounts: Map<string, number>;
30
+ readonly agentIconSuggestions?: AgentIconSuggestions | null;
31
+ readonly agentsInNetwork: ConnectivityInfo[];
32
+ readonly currentConversations: AgentConversation[] | null;
33
+ readonly isAgentNetworkDesignerMode: boolean;
34
+ readonly isAwaitingLlm: boolean;
35
+ readonly isTemporaryNetwork?: boolean;
36
+ readonly thoughtBubbleEdges: Map<string, {
37
+ edge: ThoughtBubbleEdgeShape;
38
+ timestamp: number;
39
+ }>;
40
+ readonly useNativeNames: boolean;
41
+ };
42
+ export declare const layoutRadial: ({ agentCounts, agentIconSuggestions, agentsInNetwork, currentConversations, isAgentNetworkDesignerMode, isAwaitingLlm, isTemporaryNetwork, thoughtBubbleEdges, useNativeNames, }: LayoutOptions) => LayoutResult;
43
+ export declare const layoutLinear: ({ agentCounts, agentIconSuggestions, agentsInNetwork, currentConversations, isAgentNetworkDesignerMode, isAwaitingLlm, isTemporaryNetwork, thoughtBubbleEdges, useNativeNames, }: LayoutOptions) => LayoutResult;
@@ -102,8 +102,7 @@ const getEdgeProperties = (sourceId, targetId, sourceHandle, targetHandle, isAni
102
102
  type: isAnimated ? "plasmaEdge" : undefined,
103
103
  };
104
104
  };
105
- export const layoutRadial = (agentCounts, agentsInNetwork, currentConversations, // For plasma edges (live) and node highlighting
106
- isAwaitingLlm, isAgentNetworkDesignerMode, thoughtBubbleEdges, agentIconSuggestions = null, isTemporaryNetwork = false) => {
105
+ export const layoutRadial = ({ agentCounts, agentIconSuggestions = null, agentsInNetwork, currentConversations, isAgentNetworkDesignerMode, isAwaitingLlm, isTemporaryNetwork = false, thoughtBubbleEdges, useNativeNames, }) => {
107
106
  const nodesInNetwork = [];
108
107
  const edgesInNetwork = [];
109
108
  // Compute depth of each node using breadth-first traversal
@@ -186,7 +185,7 @@ isAwaitingLlm, isAgentNetworkDesignerMode, thoughtBubbleEdges, agentIconSuggesti
186
185
  type: AGENT_NODE_TYPE_NAME,
187
186
  data: {
188
187
  agentCounts,
189
- agentName: cleanUpAgentName(nodeId),
188
+ agentName: useNativeNames ? nodeId : cleanUpAgentName(nodeId),
190
189
  depth,
191
190
  displayAs: agentsInNetwork.find((a) => a.origin === nodeId)?.display_as,
192
191
  // Use current conversations for node highlighting (cleared at end)
@@ -216,8 +215,7 @@ isAwaitingLlm, isAgentNetworkDesignerMode, thoughtBubbleEdges, agentIconSuggesti
216
215
  edgesInNetwork.push(...thoughtBubbleEdgesToAdd);
217
216
  return { nodes: nodesInNetwork, edges: edgesInNetwork };
218
217
  };
219
- export const layoutLinear = (agentCounts, agentsInNetwork, currentConversations, // For plasma edges (live) and node highlighting
220
- isAwaitingLlm, isAgentNetworkDesignerMode, thoughtBubbleEdges, agentIconSuggestions = null, isTemporaryNetwork = false) => {
218
+ export const layoutLinear = ({ agentCounts, agentIconSuggestions = null, agentsInNetwork, currentConversations, isAgentNetworkDesignerMode, isAwaitingLlm, isTemporaryNetwork = false, thoughtBubbleEdges, useNativeNames, }) => {
221
219
  const nodesInNetwork = [];
222
220
  const edgesInNetwork = [];
223
221
  // Do these calculations outside the loop for efficiency
@@ -232,7 +230,7 @@ isAwaitingLlm, isAgentNetworkDesignerMode, thoughtBubbleEdges, agentIconSuggesti
232
230
  type: AGENT_NODE_TYPE_NAME,
233
231
  data: {
234
232
  agentCounts,
235
- agentName: cleanUpAgentName(nodeId),
233
+ agentName: useNativeNames ? nodeId : cleanUpAgentName(nodeId),
236
234
  displayAs: agentsInNetwork.find((a) => a.origin === nodeId)?.display_as,
237
235
  // Use current conversations for node highlighting (cleared at end)
238
236
  getConversations: () => currentConversations,
@@ -1,17 +1,11 @@
1
1
  import { FC } from "react";
2
2
  export interface MultiAgentAcceleratorProps {
3
- readonly userInfo: {
4
- userName: string;
5
- userImage: string;
6
- };
7
- readonly backendNeuroSanApiUrl: string;
3
+ readonly username: string;
4
+ readonly defaultNeuroSanUrl: string;
8
5
  }
9
- export declare const GRACE_PERIOD_MS: number;
10
- export declare const SHOW_TOUR_DELAY_MS = 5000;
11
6
  /**
12
7
  * Main Multi-Agent Accelerator component that contains the sidebar, agent flow, and chat components.
13
8
  * @param backendNeuroSanApiUrl Initial URL of the backend Neuro-San API. User can change this in the UI.
14
- * @param darkMode Whether dark mode is enabled.
15
- * @param userInfo Information about the current user, including userName and userImage.
9
+ * @param username Identifier to use for interactions with the backend (for personalization and tracking).
16
10
  */
17
11
  export declare const MultiAgentAccelerator: FC<MultiAgentAcceleratorProps>;
@@ -19,6 +19,7 @@ import Box from "@mui/material/Box";
19
19
  import Grid from "@mui/material/Grid";
20
20
  import Slide from "@mui/material/Slide";
21
21
  import { useTheme } from "@mui/material/styles";
22
+ import Tooltip from "@mui/material/Tooltip";
22
23
  import Typography from "@mui/material/Typography";
23
24
  import { ReactFlowProvider } from "@xyflow/react";
24
25
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -27,18 +28,18 @@ import { extractConversations } from "./AgentConversations.js";
27
28
  import { getUpdatedAgentCounts } from "./AgentCounts.js";
28
29
  import { AgentFlow } from "./AgentFlow.js";
29
30
  import { extractAgentNetworkDesignerProgress } from "./AgentNetworkDesigner.js";
30
- import { AGENT_NETWORK_DEFINITION_KEY, AGENT_NETWORK_DESIGNER_ID, AGENT_NETWORK_HOCON, AGENT_NETWORK_NAME_KEY, TRIGGER_APP_TOUR_EVENT_NAME, } from "./const.js";
31
+ import { AGENT_NETWORK_DEFINITION_KEY, AGENT_NETWORK_DESIGNER_ID, AGENT_NETWORK_HOCON, AGENT_NETWORK_NAME_KEY, GRACE_PERIOD_MS, SHOW_TOUR_DELAY_MS, TRIGGER_APP_TOUR_EVENT_NAME, } from "./const.js";
31
32
  import { Sidebar } from "./Sidebar/Sidebar.js";
32
33
  import { extractTemporaryNetworksFromMessage, isTemporaryNetwork, mergeNetworks } from "./TemporaryNetworks.js";
33
- import { getAgentFunction, getAgentIconSuggestions, getAgentNetworks, getConnectivity, getNetworkIconSuggestions, sendNetworkDesignerUpdate, } from "../../controller/agent/Agent.js";
34
+ import { getAgentFunction, getAgentNetworks, getConnectivity, sendNetworkDesignerUpdate, } from "../../controller/agent/Agent.js";
35
+ import { getAgentIconSuggestions, getNetworkIconSuggestions } from "../../controller/agent/IconSuggestions.js";
34
36
  import { useAgentChatHistoryStore } from "../../state/ChatHistory.js";
35
37
  import { useSettingsStore } from "../../state/Settings.js";
36
38
  import { useTempNetworksStore } from "../../state/TemporaryNetworks.js";
37
39
  import { TourPromptState, useTourStore } from "../../state/Tour.js";
38
- import { useLocalStorage } from "../../utils/useLocalStorage.js";
39
40
  import { getZIndex } from "../../utils/zIndexLayers.js";
40
41
  import { ChatCommon } from "../AgentChat/ChatCommon/ChatCommon.js";
41
- import { SmallLlmChatButton } from "../AgentChat/Common/LlmChatButton.js";
42
+ import { LlmChatButton } from "../AgentChat/Common/LlmChatButton.js";
42
43
  import { isLegacyAgentType } from "../AgentChat/Common/Types.js";
43
44
  import { chatMessageFromChunk, cleanUpAgentName, removeTrailingUuid } from "../AgentChat/Common/Utils.js";
44
45
  import { ConfirmationModal, StyledButton } from "../Common/ConfirmationModal.js";
@@ -47,14 +48,10 @@ import { MAIN_TOUR_STEPS } from "./Tour/MainTourSteps.js";
47
48
  import { MUIDialog } from "../Common/MUIDialog.js";
48
49
  // Check for expired networks every this many milliseconds
49
50
  const EXPIRED_NETWORKS_CHECK_INTERVAL_MS = 10 * 1000;
50
- // Display expired temporary networks for this amount of time after they expire so users can see what happened
51
- export const GRACE_PERIOD_MS = 5 * 60 * 1000; // 5 minutes
52
51
  // Animation time for the left and right panels to slide in or out when launching the animation
53
52
  const GROW_ANIMATION_TIME_MS = 800;
54
53
  // Optimization to avoid creating a new empty map on every render
55
54
  const EMPTY_THOUGHT_BUBBLE_EDGES = new Map();
56
- // We show the tour modal after this amount of time so as not to "pounce" on the user when they first open the app
57
- export const SHOW_TOUR_DELAY_MS = 5000;
58
55
  // #region: Agent-save helpers
59
56
  /**
60
57
  * Extracts TemporaryNetworks from a single streamed chunk, merging into `accumulated`.
@@ -76,7 +73,7 @@ const collectNetworksFromChunk = (chunk, updated, accumulated) => {
76
73
  return accumulated;
77
74
  }
78
75
  };
79
- /** Logs and notifies about a save error. Suppresses AbortError (user-cancelled). */
76
+ /** Logs and notifies about a save error. Suppresses AbortError (user-canceled). */
80
77
  const notifySaveError = (agentName, e) => {
81
78
  if (e instanceof DOMException && e.name === "AbortError")
82
79
  return;
@@ -90,14 +87,15 @@ const notifySaveError = (agentName, e) => {
90
87
  /**
91
88
  * Main Multi-Agent Accelerator component that contains the sidebar, agent flow, and chat components.
92
89
  * @param backendNeuroSanApiUrl Initial URL of the backend Neuro-San API. User can change this in the UI.
93
- * @param darkMode Whether dark mode is enabled.
94
- * @param userInfo Information about the current user, including userName and userImage.
90
+ * @param username Identifier to use for interactions with the backend (for personalization and tracking).
95
91
  */
96
- export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
92
+ export const MultiAgentAccelerator = ({ defaultNeuroSanUrl, username, }) => {
97
93
  // MUI theme
98
94
  const theme = useTheme();
99
95
  const enableZenMode = useSettingsStore((state) => state.settings.behavior.enableZenMode);
100
96
  const apiKeys = useSettingsStore((state) => state.settings.apiKeys);
97
+ // Display option for agent/network names
98
+ const useNativeNames = useSettingsStore((state) => state.settings.appearance.useNativeNames);
101
99
  // Stores whether are currently awaiting LLM response (for knowing when to show spinners)
102
100
  const [isAwaitingLlm, setIsAwaitingLlm] = useState(false);
103
101
  const [isEditingNetwork, setIsEditingNetwork] = useState(false);
@@ -118,11 +116,9 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
118
116
  const [agentIconSuggestions, setAgentIconSuggestions] = useState(null);
119
117
  const [selectedNetwork, setSelectedNetwork] = useState(null);
120
118
  const [networkDescription, setNetworkDescription] = useState("");
121
- const networkDisplayName = useMemo(() => cleanUpAgentName(removeTrailingUuid(selectedNetwork)), [selectedNetwork]);
119
+ const networkDisplayName = useMemo(() => (useNativeNames ? selectedNetwork : cleanUpAgentName(removeTrailingUuid(selectedNetwork))), [selectedNetwork, useNativeNames]);
122
120
  const [providerKeysRequired, setProviderKeysRequired] = useState(new Set());
123
- const [customURLLocalStorage, setCustomURLLocalStorage] = useLocalStorage("customAgentNetworkURL", null);
124
- // An extra set of quotes is making it in the string in local storage.
125
- const [neuroSanURL, setNeuroSanURL] = useState(customURLLocalStorage?.replaceAll('"', "") || backendNeuroSanApiUrl);
121
+ const neuroSanURL = useSettingsStore((state) => state.settings.externalServices.neuroSanUrl) ?? defaultNeuroSanUrl;
126
122
  // Tracks how many times each agent has been involved in the conversation
127
123
  const [agentCounts, setAgentCounts] = useState(new Map());
128
124
  // Common function to change the selected network and reset related state
@@ -138,10 +134,6 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
138
134
  const [confirmationModalOpen, setConfirmationModalOpen] = useState(false);
139
135
  const [tourModalOpen, setTourModalOpen] = useState(false);
140
136
  const [haveShownTourModal, setHaveShownTourModal] = useState(false);
141
- const customURLCallback = useCallback((url) => {
142
- setNeuroSanURL(url || backendNeuroSanApiUrl);
143
- setCustomURLLocalStorage(url === "" ? null : url);
144
- }, [backendNeuroSanApiUrl, setCustomURLLocalStorage]);
145
137
  // Memoized key for agent names to trigger icon suggestion updates when the set of agents changes, not just
146
138
  // when sorting/other operations on the agents list
147
139
  const agentNamesKey = useMemo(() => agentsInNetwork
@@ -281,7 +273,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
281
273
  const fetchAgentDetails = async () => {
282
274
  // It is a Neuro-san agent, so get the function and connectivity info
283
275
  try {
284
- const agentFunction = await getAgentFunction(neuroSanURL, selectedNetwork, userInfo.userName);
276
+ const agentFunction = await getAgentFunction(neuroSanURL, selectedNetwork, username);
285
277
  setNetworkDescription(agentFunction?.function?.description || "");
286
278
  const schema = agentFunction?.function?.sly_data_schema;
287
279
  const schemaProperties = isRecord(schema) ? schema["properties"] : undefined;
@@ -308,7 +300,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
308
300
  if (selectedNetwork && !isLegacyAgentType(selectedNetwork)) {
309
301
  void fetchAgentDetails();
310
302
  }
311
- }, [neuroSanURL, selectedNetwork, userInfo.userName]);
303
+ }, [neuroSanURL, selectedNetwork, username]);
312
304
  useEffect(() => {
313
305
  ;
314
306
  (async () => {
@@ -329,7 +321,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
329
321
  (async () => {
330
322
  if (selectedNetwork) {
331
323
  try {
332
- const connectivity = await getConnectivity(neuroSanURL, selectedNetwork, userInfo.userName);
324
+ const connectivity = await getConnectivity(neuroSanURL, selectedNetwork, username);
333
325
  const agentsInNetworkSorted = [...connectivity.connectivity_info].sort((a, b) => a?.origin.localeCompare(b?.origin));
334
326
  setAgentsInNetwork(agentsInNetworkSorted);
335
327
  const sampleQueriesTmp = connectivity?.metadata?.["sample_queries"];
@@ -352,7 +344,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
352
344
  setAgentsInNetwork([]);
353
345
  }
354
346
  })();
355
- }, [networkDisplayName, neuroSanURL, selectedNetwork, userInfo.userName]);
347
+ }, [networkDisplayName, neuroSanURL, selectedNetwork, username]);
356
348
  useEffect(() => {
357
349
  ;
358
350
  (async () => {
@@ -475,7 +467,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
475
467
  const onSaveAgent = useCallback(async (agentName, updated, agentNetworkName, signal) => {
476
468
  try {
477
469
  let newNetworks = [];
478
- await sendNetworkDesignerUpdate(neuroSanURL, signal, agentName, updated, agentNetworkName, userInfo.userName, (chunk) => {
470
+ await sendNetworkDesignerUpdate(neuroSanURL, signal, agentName, updated, agentNetworkName, username, (chunk) => {
479
471
  newNetworks = collectNetworksFromChunk(chunk, updated, newNetworks);
480
472
  });
481
473
  if (newNetworks.length === 0) {
@@ -499,7 +491,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
499
491
  catch (e) {
500
492
  notifySaveError(agentName, e);
501
493
  }
502
- }, [neuroSanURL, userInfo.userName, selectedNetwork]);
494
+ }, [neuroSanURL, username, selectedNetwork]);
503
495
  const onStreamingStarted = useCallback(() => {
504
496
  // Reset agent counts
505
497
  setAgentCounts(new Map());
@@ -570,7 +562,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
570
562
  setIsStreaming(true);
571
563
  }, children: _jsx(Grid, { id: "multi-agent-accelerator-grid-sidebar", size: enableZenMode && isStreaming ? 0 : 3.25, sx: {
572
564
  height: "100%",
573
- }, children: _jsx(Sidebar, { customURLLocalStorage: customURLLocalStorage, customURLCallback: customURLCallback, id: "multi-agent-accelerator-sidebar", isAwaitingLlm: isAwaitingLlm, networks: networks, networkIconSuggestions: networkIconSuggestions, newlyAddedTemporaryNetworks: newlyAddedTemporaryNetworks, onEditNetwork: handleEditNetwork, onDeleteNetwork: handleDeleteNetwork, setSelectedNetwork: (newNetwork) => changeSelectedNetwork(newNetwork), temporaryNetworks: temporaryNetworks }) }) }));
565
+ }, children: _jsx(Sidebar, { id: "multi-agent-accelerator-sidebar", isAwaitingLlm: isAwaitingLlm, networkIconSuggestions: networkIconSuggestions, networks: networks, neuroSanServerURL: neuroSanURL, newlyAddedTemporaryNetworks: newlyAddedTemporaryNetworks, onDeleteNetwork: handleDeleteNetwork, onEditNetwork: handleEditNetwork, setSelectedNetwork: (newNetwork) => changeSelectedNetwork(newNetwork), temporaryNetworks: temporaryNetworks }) }) }));
574
566
  };
575
567
  const getCenterPanel = () => {
576
568
  return (_jsx(Grid, { id: "multi-agent-accelerator-grid-agent-flow", size: enableZenMode && isStreaming ? 18 : 8.25, sx: {
@@ -583,7 +575,7 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
583
575
  height: "100%",
584
576
  maxWidth: 1000,
585
577
  margin: "0 auto",
586
- }, children: _jsx(AgentFlow, { agentCounts: agentCounts, agentsInNetwork: agentsInNetwork, agentIconSuggestions: agentIconSuggestions, id: "multi-agent-accelerator-agent-flow", currentConversations: currentConversations, currentUser: userInfo.userName, isAwaitingLlm: isAwaitingLlm, isEditMode: isEditingNetwork, isStreaming: isStreaming, isSelectedNetworkTemporary: isSelectedNetworkTemporary, networkDisplayName: selectedNetwork || undefined, networkId: isSelectedNetworkTemporary ? selectedNetwork : undefined, neuroSanURL: neuroSanURL, onEnterEditMode: () => setIsEditingNetwork(true), onExitEditMode: () => setIsEditingNetwork(false), onNetworkReplaced: (_old, newId) => changeSelectedNetwork(newId), onSaveAgent: onSaveAgent, thoughtBubbleEdges: thoughtBubbleEdges, setThoughtBubbleEdges: setThoughtBubbleEdges }, "multi-agent-accelerator-agent-flow") }) }) }));
578
+ }, children: _jsx(AgentFlow, { agentCounts: agentCounts, agentsInNetwork: agentsInNetwork, agentIconSuggestions: agentIconSuggestions, id: "multi-agent-accelerator-agent-flow", currentConversations: currentConversations, currentUser: username, isAwaitingLlm: isAwaitingLlm, isEditMode: isEditingNetwork, isStreaming: isStreaming, isSelectedNetworkTemporary: isSelectedNetworkTemporary, networkDisplayName: networkDisplayName || "", networkId: isSelectedNetworkTemporary ? selectedNetwork : "", neuroSanURL: neuroSanURL, onEnterEditMode: () => setIsEditingNetwork(true), onExitEditMode: () => setIsEditingNetwork(false), onNetworkReplaced: (_old, newId) => changeSelectedNetwork(newId), onSaveAgent: onSaveAgent, thoughtBubbleEdges: thoughtBubbleEdges, setThoughtBubbleEdges: setThoughtBubbleEdges }, "multi-agent-accelerator-agent-flow") }) }) }));
587
579
  };
588
580
  const getRightPanel = () => {
589
581
  return (_jsx(Slide, { id: "multi-agent-accelerator-grid-agent-chat-common-slide", in: !enableZenMode || !isAwaitingLlm, direction: "left", timeout: GROW_ANIMATION_TIME_MS, onExited: () => {
@@ -592,17 +584,21 @@ export const MultiAgentAccelerator = ({ backendNeuroSanApiUrl, userInfo, }) => {
592
584
  height: "100%",
593
585
  }, children: _jsx(ChatCommon, { agentPlaceholders: {
594
586
  [AGENT_NETWORK_DESIGNER_ID]: "Describe in plain language the network you would like to build.",
595
- }, currentUser: userInfo.userName, customAgentGreetings: {
587
+ }, currentUser: username, customAgentGreetings: {
596
588
  [AGENT_NETWORK_DESIGNER_ID]: "Let's build a network together!",
597
- }, extraSlyData: extraSlyData, id: "agent-network-ui", isAwaitingLlm: isAwaitingLlm, missingApiKeys: getMissingApiKeys(), networkDescription: networkDescription, neuroSanURL: neuroSanURL, onChunkReceived: onChunkReceived, onStreamingComplete: onStreamingComplete, onStreamingStarted: onStreamingStarted, ref: chatRef, sampleQueries: sampleQueries, setIsAwaitingLlm: setIsAwaitingLlm, selectedNetwork: selectedNetwork }, selectedNetwork ?? "no-network") }) }));
589
+ }, extraSlyData: extraSlyData, id: "agent-network-ui", isAwaitingLlm: isAwaitingLlm, missingApiKeys: getMissingApiKeys(), networkDescription: networkDescription, neuroSanURL: neuroSanURL, onChunkReceived: onChunkReceived, onStreamingComplete: onStreamingComplete, onStreamingStarted: onStreamingStarted, ref: chatRef, sampleQueries: sampleQueries, setIsAwaitingLlm: setIsAwaitingLlm, selectedNetwork: selectedNetwork, setSelectedNetwork: changeSelectedNetwork }, selectedNetwork ?? "no-network") }) }));
598
590
  };
599
591
  const getStopButton = () => {
600
592
  return (_jsx(_Fragment, { children: isAwaitingLlm && enableZenMode && (_jsx(Box, { id: "stop-button-container", sx: {
601
593
  position: "absolute",
602
594
  bottom: "1rem",
603
595
  right: "1rem",
604
- zIndex: 10,
605
- }, children: _jsx(SmallLlmChatButton, { "aria-label": "Stop", disabled: !isAwaitingLlm, id: "stop-output-button", onClick: handleExternalStop, posBottom: 8, posRight: 23, children: _jsx(StopCircle, { fontSize: "small", id: "stop-button-icon", sx: { color: "var(--bs-white)" } }) }) })) }));
596
+ zIndex: getZIndex(2, theme),
597
+ }, children: _jsx(Tooltip, { title: "Stop response (Esc)", children: _jsx(LlmChatButton, { "aria-label": "Stop", id: "stop-output-button", onClick: handleExternalStop, sx: {
598
+ "&:hover": {
599
+ backgroundColor: "error.main",
600
+ },
601
+ }, children: _jsx(StopCircle, { fontSize: "large", id: "stop-button-icon" }) }) }) })) }));
606
602
  };
607
603
  const getDeleteNetworkConfirmationModal = () => confirmationModalOpen ? (_jsx(ConfirmationModal, { id: "delete-network-confirmation-modal", content: `The network "${cleanUpAgentName(removeTrailingUuid(networkToBeDeleted))}" will be deleted. ` +
608
604
  "This action cannot be undone. Are you sure you want to proceed?", handleCancel: () => {
@@ -1,13 +1,8 @@
1
1
  import { TreeItemProps } from "@mui/x-tree-view/TreeItem";
2
2
  import { FC } from "react";
3
- import { NodeIndex } from "./TreeBuilder.js";
4
3
  export interface AgentNetworkNodeProps extends TreeItemProps {
5
- readonly nodeIndex: NodeIndex;
6
4
  readonly onDeleteNetwork?: (network: string, isExpired: boolean) => void;
7
5
  readonly onEditNetwork?: (network: string) => void;
8
- readonly networkIconSuggestions: Record<string, string>;
9
- readonly temporaryNetworkExpirationTimes?: Record<string, Date>;
10
- readonly temporaryNetworkHoconStrings?: Record<string, string | null>;
11
6
  }
12
7
  /**
13
8
  * Custom Tree Item for MUI RichTreeView to display agent networks with tags
@@ -9,14 +9,13 @@ import Edit from "@mui/icons-material/Edit";
9
9
  import Box from "@mui/material/Box";
10
10
  import Chip from "@mui/material/Chip";
11
11
  import IconButton from "@mui/material/IconButton";
12
- import { useTheme } from "@mui/material/styles";
13
12
  import Tooltip from "@mui/material/Tooltip";
13
+ import { useTreeItemModel } from "@mui/x-tree-view/hooks";
14
14
  import { TreeItemContent, TreeItemGroupTransition, TreeItemLabel, TreeItemRoot, } from "@mui/x-tree-view/TreeItem";
15
15
  import { TreeItemProvider } from "@mui/x-tree-view/TreeItemProvider";
16
16
  import { useTreeItem } from "@mui/x-tree-view/useTreeItem";
17
17
  import { useRef } from "react";
18
18
  import { downloadFile, toSafeFilename } from "../../../utils/File.js";
19
- import { cleanUpAgentName } from "../../AgentChat/Common/Utils.js";
20
19
  // Palette of colors we can use for tags
21
20
  const TAG_COLORS = [
22
21
  "--bs-accent2-light",
@@ -44,21 +43,15 @@ const isTemporaryNetworkExpired = (expirationDate) => {
44
43
  * @param props - see AgentNetworkNode interface
45
44
  * @returns JSX.Element containing the custom tree item
46
45
  */
47
- export const AgentNetworkTreeItem = ({ children, disabled, itemId, label, networkIconSuggestions, nodeIndex, onDeleteNetwork, onEditNetwork, temporaryNetworkExpirationTimes, temporaryNetworkHoconStrings, }) => {
48
- const theme = useTheme();
46
+ export const AgentNetworkTreeItem = ({ children, disabled, itemId, label, onDeleteNetwork, onEditNetwork, }) => {
47
+ const item = useTreeItemModel(itemId);
49
48
  // We know all labels are strings because we set them that way in the tree view items
50
49
  const labelString = label;
51
- const displayLabel = nodeIndex.get(itemId)?.displayName || cleanUpAgentName(labelString);
52
50
  const { getContextProviderProps, getRootProps, getContentProps, getLabelProps, getGroupTransitionProps } = useTreeItem({ itemId, children, label, disabled });
53
51
  const rootRef = useRef(null);
54
52
  const isParent = Array.isArray(children) && children.length > 0;
55
53
  const isChild = !isParent;
56
- const agentNode = nodeIndex?.get(itemId)?.agentInfo;
57
- // Only child items (the actual networks, not the containing folders) have tags. Retrieve tags from the
58
- // networkFolders data structure passed in as a prop. This could in theory be a custom property for the
59
- // RichTreeView item, but that isn't well-supported at this time.
60
- // Discussion: https://stackoverflow.com/questions/69481071/material-ui-how-to-pass-custom-props-to-a-custom-treeitem
61
- const tags = isChild ? agentNode?.tags || [] : [];
54
+ const tags = item.tags ?? [];
62
55
  // Assign colors to tags as needed and store in tagsToColors map
63
56
  for (const tag of tags) {
64
57
  if (!tagsToColors.has(tag)) {
@@ -67,18 +60,33 @@ export const AgentNetworkTreeItem = ({ children, disabled, itemId, label, networ
67
60
  }
68
61
  }
69
62
  // Determine if expired (temporary networks only)
70
- const expirationTime = temporaryNetworkExpirationTimes?.[itemId];
63
+ const expirationTime = item?.temporaryNetworkExpirationTime;
71
64
  const isTemporaryNetwork = Boolean(expirationTime);
72
65
  const isExpired = isChild && isTemporaryNetwork && isTemporaryNetworkExpired(expirationTime);
73
- const networkHocon = isTemporaryNetwork ? temporaryNetworkHoconStrings?.[itemId] : null;
74
- const iconNameSuggestion = isTemporaryNetwork ? "HourglassTop" : isChild ? networkIconSuggestions?.[itemId] : null;
75
- let muiIconElement = null;
76
- if (iconNameSuggestion && MuiIcons[iconNameSuggestion]) {
77
- const IconComponent = MuiIcons[iconNameSuggestion];
78
- muiIconElement = _jsx(IconComponent, { sx: { fontSize: "1rem" } });
66
+ const networkHocon = item?.temporaryNetworkHocon ?? null;
67
+ const iconNameSuggestion = item.iconSuggestion;
68
+ let muiIconElement;
69
+ // If the item is a child (i.e., a network), we want to render an icon next to it.
70
+ if (isChild) {
71
+ if (iconNameSuggestion) {
72
+ if (MuiIcons[iconNameSuggestion]) {
73
+ // If the icon name suggestion is valid, use it to render the icon
74
+ const IconComponent = MuiIcons[iconNameSuggestion];
75
+ muiIconElement = _jsx(IconComponent, { sx: { fontSize: "1rem" } });
76
+ }
77
+ else {
78
+ // If the icon name suggestion is not valid, use a default icon
79
+ muiIconElement = _jsx(MuiIcons.Hub, { sx: { fontSize: "1rem" } });
80
+ }
81
+ }
82
+ else {
83
+ // If no icon name suggestion is provided, use a default icon
84
+ muiIconElement = _jsx(MuiIcons.Hub, { sx: { fontSize: "1rem" } });
85
+ }
79
86
  }
80
- else if (iconNameSuggestion) {
81
- console.warn(`Icon "${iconNameSuggestion}" not found in MUI icons library.`);
87
+ else {
88
+ // Use folder icon for parent items (i.e., folders)
89
+ muiIconElement = _jsx(MuiIcons.Folder, { sx: { fontSize: "1rem" } });
82
90
  }
83
91
  return (_jsx(TreeItemProvider, { ...getContextProviderProps(), children: _jsxs(TreeItemRoot, { ...getRootProps(), ref: rootRef, "data-itemid": itemId, children: [_jsx(TreeItemContent, { ...getContentProps(), sx: {
84
92
  cursor: isExpired ? "not-allowed" : "pointer",
@@ -92,16 +100,13 @@ export const AgentNetworkTreeItem = ({ children, disabled, itemId, label, networ
92
100
  "&:hover": {
93
101
  textDecoration: "underline",
94
102
  },
95
- }, children: displayLabel })] }) }), isChild && tags?.length > 0 ? (_jsx(Tooltip, { title: [...tags]
103
+ }, children: item.displayName })] }) }), isChild && tags.length > 0 ? (_jsx(Tooltip, { title: [...tags]
96
104
  .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
97
105
  .map((tag) => (_jsx(Chip, { label: tag, style: {
98
106
  margin: "0.25rem",
99
107
  backgroundColor: `var(${tagsToColors.get(tag) || TAG_COLORS[0]})`,
100
108
  } }, tag))), placement: "right", arrow: true, children: _jsx(BookmarkIcon, { sx: { fontSize: "0.75rem", color: "var(--bs-accent1-medium)" } }) })) : null] }), isChild && isTemporaryNetwork && (_jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: "0.25rem", marginLeft: "auto" }, children: [networkHocon && (_jsx(Tooltip, { title: isExpired ? "Expired" : "Download network definition", children: _jsx("span", { children: _jsx(IconButton, { onClick: (e) => {
101
109
  e.stopPropagation();
102
- if (isExpired) {
103
- return;
104
- }
105
110
  const fileName = `${toSafeFilename(labelString)}.hocon`;
106
111
  downloadFile(networkHocon, fileName);
107
112
  }, disabled: isExpired, "aria-label": "Download network definition", size: "small", sx: {
@@ -128,7 +133,7 @@ export const AgentNetworkTreeItem = ({ children, disabled, itemId, label, networ
128
133
  onDeleteNetwork?.(itemId, isExpired);
129
134
  }, sx: {
130
135
  color: "var(--bs-secondary)",
131
- "&:hover": { color: theme.palette.warning.main },
136
+ "&:hover": { color: (theme) => theme.palette.warning.main },
132
137
  "&.Mui-disabled": {
133
138
  color: "var(--bs-secondary)",
134
139
  opacity: 0.3,
@@ -4,16 +4,15 @@ import { AgentInfo } from "../../../generated/neuro-san/NeuroSanClient.js";
4
4
  import { TemporaryNetwork } from "../../../state/TemporaryNetworks.js";
5
5
  export declare const SPARKLE_HIGHLIGHT_CLASS = "sparkle-highlight";
6
6
  export interface SidebarProps {
7
- readonly customURLCallback: (url: string) => void;
8
- readonly customURLLocalStorage?: string;
9
7
  readonly id: string;
10
8
  readonly isAwaitingLlm: boolean;
11
9
  readonly networkIconSuggestions?: NetworkIconSuggestions;
12
10
  readonly networks: readonly AgentInfo[];
13
- readonly onEditNetwork?: (network: string) => void;
11
+ readonly neuroSanServerURL: string;
12
+ readonly newlyAddedTemporaryNetworks?: Set<string>;
14
13
  readonly onDeleteNetwork?: (network: string, isExpired: boolean) => void;
14
+ readonly onEditNetwork?: (network: string) => void;
15
15
  readonly setSelectedNetwork: (network: string) => void;
16
16
  readonly temporaryNetworks?: readonly TemporaryNetwork[];
17
- readonly newlyAddedTemporaryNetworks?: Set<string>;
18
17
  }
19
18
  export declare const Sidebar: FC<SidebarProps>;