@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
|
@@ -24,13 +24,20 @@ export declare const getThoughtBubbleEdges: (thoughtBubbleEdges: Map<string, {
|
|
|
24
24
|
edge: ThoughtBubbleEdgeShape;
|
|
25
25
|
timestamp: number;
|
|
26
26
|
}>) => ThoughtBubbleEdgeShape[];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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,
|
|
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,
|
|
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
|
|
4
|
-
|
|
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
|
|
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,
|
|
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 {
|
|
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-
|
|
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
|
|
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 = ({
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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, {
|
|
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:
|
|
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:
|
|
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:
|
|
605
|
-
}, children: _jsx(
|
|
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,
|
|
48
|
-
const
|
|
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
|
|
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 =
|
|
63
|
+
const expirationTime = item?.temporaryNetworkExpirationTime;
|
|
71
64
|
const isTemporaryNetwork = Boolean(expirationTime);
|
|
72
65
|
const isExpired = isChild && isTemporaryNetwork && isTemporaryNetworkExpired(expirationTime);
|
|
73
|
-
const networkHocon =
|
|
74
|
-
const iconNameSuggestion =
|
|
75
|
-
let muiIconElement
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
81
|
-
|
|
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:
|
|
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
|
|
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>;
|