@cognizant-ai-lab/ui-common 1.5.0 → 1.6.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/Theme.js +3 -3
- package/dist/components/AgentChat/ChatCommon/ChatCommon.d.ts +11 -1
- package/dist/components/AgentChat/ChatCommon/ChatCommon.js +284 -285
- package/dist/components/AgentChat/ChatCommon/ChatHistory.d.ts +1 -7
- package/dist/components/AgentChat/ChatCommon/ChatHistory.js +33 -22
- package/dist/components/AgentChat/ChatCommon/ControlButtons.js +2 -2
- package/dist/components/AgentChat/ChatCommon/Conversation.d.ts +13 -0
- package/dist/components/AgentChat/ChatCommon/Conversation.js +80 -0
- package/dist/components/AgentChat/ChatCommon/ConversationTurn.d.ts +23 -0
- package/dist/components/AgentChat/ChatCommon/ConversationTurn.js +11 -0
- package/dist/components/AgentChat/ChatCommon/FormattedMarkdown.js +5 -3
- package/dist/components/AgentChat/ChatCommon/SampleQueries.d.ts +3 -0
- package/dist/components/AgentChat/ChatCommon/SampleQueries.js +6 -3
- package/dist/components/AgentChat/ChatCommon/Thinking.d.ts +12 -0
- package/dist/components/AgentChat/ChatCommon/Thinking.js +51 -0
- package/dist/components/AgentChat/Common/LlmChatButton.d.ts +2 -2
- package/dist/components/AgentChat/Common/Types.d.ts +6 -5
- package/dist/components/AgentChat/Common/Types.js +5 -0
- package/dist/components/AgentChat/Common/Utils.d.ts +1 -1
- package/dist/components/AgentChat/Common/Utils.js +14 -9
- package/dist/components/Common/AccordionLite.d.ts +14 -0
- package/dist/components/Common/AccordionLite.js +25 -0
- package/dist/components/Common/ConfirmationModal.d.ts +1 -0
- package/dist/components/Common/ConfirmationModal.js +1 -1
- package/dist/components/Common/CustomerLogo.js +1 -1
- package/dist/components/Common/MUIAlert.d.ts +1 -0
- package/dist/components/Common/MUIAlert.js +3 -4
- package/dist/components/Common/Navbar.d.ts +2 -1
- package/dist/components/Common/Navbar.js +8 -4
- package/dist/components/Common/notification.d.ts +1 -1
- package/dist/components/Common/notification.js +17 -12
- package/dist/components/MultiAgentAccelerator/AgentFlow.d.ts +8 -0
- package/dist/components/MultiAgentAccelerator/AgentFlow.js +282 -82
- package/dist/components/MultiAgentAccelerator/AgentNode.d.ts +3 -1
- package/dist/components/MultiAgentAccelerator/AgentNode.js +64 -28
- package/dist/components/MultiAgentAccelerator/AgentNodePopup.d.ts +1 -4
- package/dist/components/MultiAgentAccelerator/AgentNodePopup.js +4 -5
- package/dist/components/MultiAgentAccelerator/GraphLayouts.js +19 -9
- package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.d.ts +2 -2
- package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.js +268 -60
- package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.d.ts +1 -0
- package/dist/components/MultiAgentAccelerator/Sidebar/AgentNetworkTreeItem.js +28 -12
- package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.d.ts +1 -0
- package/dist/components/MultiAgentAccelerator/Sidebar/Sidebar.js +21 -5
- package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.d.ts +4 -3
- package/dist/components/MultiAgentAccelerator/Sidebar/TreeBuilder.js +8 -2
- package/dist/components/MultiAgentAccelerator/TemporaryNetworks.d.ts +19 -2
- package/dist/components/MultiAgentAccelerator/TemporaryNetworks.js +40 -5
- package/dist/components/MultiAgentAccelerator/ThoughtBubbleOverlay.js +27 -14
- package/dist/components/MultiAgentAccelerator/Tour/MainTourSteps.d.ts +7 -0
- package/dist/components/MultiAgentAccelerator/Tour/MainTourSteps.js +88 -0
- package/dist/components/MultiAgentAccelerator/const.d.ts +7 -10
- package/dist/components/MultiAgentAccelerator/const.js +9 -10
- package/dist/const.d.ts +5 -1
- package/dist/const.js +5 -2
- package/dist/controller/agent/Agent.d.ts +10 -0
- package/dist/controller/agent/Agent.js +17 -1
- package/dist/controller/llm/LlmChat.js +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/state/TemporaryNetworks.d.ts +5 -15
- package/dist/state/TemporaryNetworks.js +15 -34
- package/dist/state/Tour.d.ts +29 -0
- package/dist/state/Tour.js +22 -0
- package/dist/state/UserInfo.d.ts +2 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/Authentication.js +12 -3
- package/dist/utils/File.d.ts +7 -0
- package/dist/utils/File.js +14 -3
- package/dist/utils/text.js +2 -2
- package/dist/utils/title.js +1 -1
- package/dist/utils/zIndexLayers.js +3 -0
- package/package.json +15 -11
- package/dist/components/AgentChat/ChatCommon/AgentConnectivity.d.ts +0 -14
- package/dist/components/AgentChat/ChatCommon/AgentConnectivity.js +0 -23
- package/dist/components/AgentChat/ChatCommon/Greetings.d.ts +0 -1
- package/dist/components/AgentChat/ChatCommon/Greetings.js +0 -38
- package/dist/components/AgentChat/ChatCommon/UserQueryDisplay.d.ts +0 -7
- package/dist/components/AgentChat/ChatCommon/UserQueryDisplay.js +0 -32
- package/dist/components/Common/LlmChatOptionsButton.d.ts +0 -6
- package/dist/components/Common/LlmChatOptionsButton.js +0 -31
|
@@ -15,7 +15,7 @@ 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
|
|
18
|
+
import CheckCircleOutlinedIcon from "@mui/icons-material/CheckCircleOutlined";
|
|
19
19
|
import ClearIcon from "@mui/icons-material/Clear";
|
|
20
20
|
import HighlightOff from "@mui/icons-material/HighlightOff";
|
|
21
21
|
import SettingsIcon from "@mui/icons-material/Settings";
|
|
@@ -121,7 +121,7 @@ var CONNECTION_STATUS;
|
|
|
121
121
|
})(CONNECTION_STATUS || (CONNECTION_STATUS = {}));
|
|
122
122
|
// #endregion: Types
|
|
123
123
|
const EMPTY_ARRAY = [];
|
|
124
|
-
export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaitingLlm, networkIconSuggestions, networks, newlyAddedTemporaryNetworks, onDeleteNetwork, setSelectedNetwork, temporaryNetworks = EMPTY_ARRAY, }) => {
|
|
124
|
+
export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaitingLlm, networkIconSuggestions, networks, newlyAddedTemporaryNetworks, onDeleteNetwork, onEditNetwork, setSelectedNetwork, temporaryNetworks = EMPTY_ARRAY, }) => {
|
|
125
125
|
// Get default URL from the environment store.
|
|
126
126
|
const { backendNeuroSanApiUrl } = useEnvironmentStore();
|
|
127
127
|
const [urlInput, setUrlInput] = useState(customURLLocalStorage || backendNeuroSanApiUrl);
|
|
@@ -134,6 +134,7 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
134
134
|
const [settingsAnchorEl, setSettingsAnchorEl] = useState(null);
|
|
135
135
|
const settingsPopoverOpen = Boolean(settingsAnchorEl);
|
|
136
136
|
const [expandedItems, setExpandedItems] = useState([]);
|
|
137
|
+
const [selectedItem, setSelectedItem] = useState(null);
|
|
137
138
|
// Theming/Dark mode
|
|
138
139
|
const darkMode = useTheme().palette.mode === "dark";
|
|
139
140
|
const handleSettingsClick = (event) => {
|
|
@@ -202,6 +203,15 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
202
203
|
};
|
|
203
204
|
void fetchVersion();
|
|
204
205
|
}, [customURLLocalStorage, backendNeuroSanApiUrl]);
|
|
206
|
+
// When the edit pencil is clicked, select the network first (if not already selected) so the network loads
|
|
207
|
+
// before entering edit mode — the user shouldn't have to click the network and then click the pencil separately.
|
|
208
|
+
const handleEditNetworkWithSelect = (network) => {
|
|
209
|
+
if (selectedItem !== network) {
|
|
210
|
+
setSelectedItem(network);
|
|
211
|
+
setSelectedNetwork(network);
|
|
212
|
+
}
|
|
213
|
+
onEditNetwork?.(network);
|
|
214
|
+
};
|
|
205
215
|
const { treeViewItems, nodeIndex } = buildTreeViewItems(networks, temporaryNetworks);
|
|
206
216
|
const temporaryNetworkExpirationTimes = temporaryNetworks.reduce((acc, tempNetwork) => {
|
|
207
217
|
acc[tempNetwork.agentInfo.agent_name] = new Date(tempNetwork.reservation.expiration_time_in_seconds * 1000);
|
|
@@ -211,7 +221,6 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
211
221
|
acc[tempNetwork.agentInfo.agent_name] = tempNetwork.networkHocon;
|
|
212
222
|
return acc;
|
|
213
223
|
}, {});
|
|
214
|
-
const [selectedItem, setSelectedItem] = useState(null);
|
|
215
224
|
const handleSelectedItemsChange = (_event, itemId) => {
|
|
216
225
|
if (!itemId) {
|
|
217
226
|
return;
|
|
@@ -272,6 +281,7 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
272
281
|
networkIconSuggestions,
|
|
273
282
|
nodeIndex,
|
|
274
283
|
onDeleteNetwork,
|
|
284
|
+
onEditNetwork: handleEditNetworkWithSelect,
|
|
275
285
|
temporaryNetworkExpirationTimes,
|
|
276
286
|
temporaryNetworkHoconStrings,
|
|
277
287
|
},
|
|
@@ -295,8 +305,14 @@ export const Sidebar = ({ customURLCallback, customURLLocalStorage, id, isAwaiti
|
|
|
295
305
|
marginLeft: "0.35rem",
|
|
296
306
|
marginTop: "2px",
|
|
297
307
|
color: darkMode ? "var(--bs-dark-mode-link)" : undefined,
|
|
298
|
-
}, variant: "text", children: "Default" }), (connectionStatusSuccess || connectionStatusError) && (_jsxs(Box, { id: "connection-status-box",
|
|
308
|
+
}, variant: "text", children: "Default" }), (connectionStatusSuccess || connectionStatusError) && (_jsxs(Box, { id: "connection-status-box", sx: {
|
|
309
|
+
display: "flex",
|
|
310
|
+
alignItems: "center",
|
|
299
311
|
marginLeft: "0.25rem",
|
|
300
312
|
marginBottom: "0.5rem",
|
|
301
|
-
}, children: [connectionStatusSuccess && (_jsxs(_Fragment, { children: [_jsx(
|
|
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"}"` })] }))] }))] })] }));
|
|
302
318
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
4
|
export type NodeIndex = Map<string, {
|
|
@@ -11,9 +11,10 @@ export type NodeIndex = Map<string, {
|
|
|
11
11
|
* The tree structure is used by the RichTreeView component to display the networks
|
|
12
12
|
* @param networks - Array of networks from the Neuro-san /list API
|
|
13
13
|
* @param temporaryNetworks - Array of temporary networks (e.g. ones recently created by the user)
|
|
14
|
-
* @returns Array of
|
|
14
|
+
* @returns Array of {@linkcode TreeViewDefaultItemModelProperties} objects representing the tree structure and an
|
|
15
|
+
* index for rapid access
|
|
15
16
|
*/
|
|
16
17
|
export declare const buildTreeViewItems: (networks: readonly AgentInfo[], temporaryNetworks: readonly TemporaryNetwork[]) => {
|
|
17
|
-
treeViewItems:
|
|
18
|
+
treeViewItems: TreeViewDefaultItemModelProperties[];
|
|
18
19
|
nodeIndex: NodeIndex;
|
|
19
20
|
};
|
|
@@ -2,6 +2,7 @@ import { cleanUpAgentName, removeTrailingUuid } from "../../AgentChat/Common/Uti
|
|
|
2
2
|
/**
|
|
3
3
|
* Iteratively sort all children of tree nodes using a queue-based approach
|
|
4
4
|
* @param nodes - Array of tree nodes to sort
|
|
5
|
+
* @param nodeIndex - Index mapping node IDs to their AgentInfo and display names, used for sorting by display name
|
|
5
6
|
*/
|
|
6
7
|
const sortTreeNodes = (nodes, nodeIndex) => {
|
|
7
8
|
// Sort the top level nodes first. We sort by displayName because that's what the user sees
|
|
@@ -85,7 +86,8 @@ const addNetworkToTree = (network, result, uncategorized, map, nodeIndex, displa
|
|
|
85
86
|
* The tree structure is used by the RichTreeView component to display the networks
|
|
86
87
|
* @param networks - Array of networks from the Neuro-san /list API
|
|
87
88
|
* @param temporaryNetworks - Array of temporary networks (e.g. ones recently created by the user)
|
|
88
|
-
* @returns Array of
|
|
89
|
+
* @returns Array of {@linkcode TreeViewDefaultItemModelProperties} objects representing the tree structure and an
|
|
90
|
+
* index for rapid access
|
|
89
91
|
*/
|
|
90
92
|
export const buildTreeViewItems = (networks, temporaryNetworks) => {
|
|
91
93
|
// Map to keep track of created nodes in a tree structure
|
|
@@ -95,7 +97,11 @@ export const buildTreeViewItems = (networks, temporaryNetworks) => {
|
|
|
95
97
|
// Resulting tree view items, ready for consumption by RichTreeView
|
|
96
98
|
const treeViewItems = [];
|
|
97
99
|
// Special parent node for networks that aren't in any folder
|
|
98
|
-
const uncategorized = {
|
|
100
|
+
const uncategorized = {
|
|
101
|
+
id: "uncategorized",
|
|
102
|
+
label: "Uncategorized",
|
|
103
|
+
children: [],
|
|
104
|
+
};
|
|
99
105
|
const displayNameCounts = new Map();
|
|
100
106
|
// Build a tree structure from the flat list of networks.
|
|
101
107
|
// The networks come in as a series of "paths" like "industry/retail/macys" and we need to build a tree
|
|
@@ -40,8 +40,25 @@ export declare const extractNetworkHocon: (message: ChatMessage) => string | nul
|
|
|
40
40
|
* @param networkHocon Optional network HOCON string associated with the reservations.
|
|
41
41
|
* @param agentNetworkDefinition Optional agent network definition entries.
|
|
42
42
|
* @param agentNetworkName Optional backend canonical network name used to match / deduplicate networks.
|
|
43
|
-
* When omitted, the name is derived from the reservation_id via {@link extractNetworkNameFromReservationId}.
|
|
44
43
|
* @returns List of TemporaryNetwork objects ready for the store.
|
|
45
44
|
*/
|
|
46
45
|
export declare const convertReservationsToNetworks: (agentReservations: AgentReservation[], networkHocon: string | null, agentNetworkDefinition?: AgentNetworkDefinitionEntry[], agentNetworkName?: string) => TemporaryNetwork[];
|
|
47
|
-
export
|
|
46
|
+
export declare const isEditableAgent: (displayAs: string | undefined) => boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Extracts TemporaryNetwork objects from a chat message by reading reservations, HOCON,
|
|
49
|
+
* agent network definition, and agent network name from the message / sly_data.
|
|
50
|
+
* @param message The chat message to extract from.
|
|
51
|
+
* @param agentNetworkDefinitionOverride Optional definition override (e.g. a locally-edited version) that
|
|
52
|
+
* takes precedence over whatever the backend echoes in sly_data.
|
|
53
|
+
* @returns A (possibly empty) array of TemporaryNetwork objects ready for the store.
|
|
54
|
+
*/
|
|
55
|
+
export declare const extractTemporaryNetworksFromMessage: (message: ChatMessage, agentNetworkDefinitionOverride?: AgentNetworkDefinitionEntry[]) => TemporaryNetwork[];
|
|
56
|
+
/**
|
|
57
|
+
* Returns true when agentName refers to a known temporary network.
|
|
58
|
+
*/
|
|
59
|
+
export declare const isTemporaryNetwork: (agentName: string | null, networks: TemporaryNetwork[]) => boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Merges incoming networks into target, keeping the entry with the highest expiration time.
|
|
62
|
+
* Returns a new array; does not mutate either argument.
|
|
63
|
+
*/
|
|
64
|
+
export declare const mergeNetworks: (target: TemporaryNetwork[], incoming: TemporaryNetwork[]) => TemporaryNetwork[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AGENT_NETWORK_HOCON, AGENT_RESERVATIONS_KEY, TEMPORARY_NETWORK_FOLDER, } from "./const.js";
|
|
1
|
+
import { AGENT_NETWORK_DEFINITION_KEY, AGENT_NETWORK_HOCON, AGENT_RESERVATIONS_KEY, DisplayAs, TEMPORARY_NETWORK_FOLDER, } from "./const.js";
|
|
2
2
|
import { ChatMessageType } from "../../generated/neuro-san/NeuroSanClient.js";
|
|
3
|
-
import {
|
|
3
|
+
import { removeTrailingUuid } from "../AgentChat/Common/Utils.js";
|
|
4
4
|
/**
|
|
5
5
|
* Extracts agent reservations from a chat message, if they exist.
|
|
6
6
|
* @param message The chat message to extract reservations from. We expect reservations to be present in messages of
|
|
@@ -41,7 +41,6 @@ export const extractNetworkHocon = (message) => {
|
|
|
41
41
|
* @param networkHocon Optional network HOCON string associated with the reservations.
|
|
42
42
|
* @param agentNetworkDefinition Optional agent network definition entries.
|
|
43
43
|
* @param agentNetworkName Optional backend canonical network name used to match / deduplicate networks.
|
|
44
|
-
* When omitted, the name is derived from the reservation_id via {@link extractNetworkNameFromReservationId}.
|
|
45
44
|
* @returns List of TemporaryNetwork objects ready for the store.
|
|
46
45
|
*/
|
|
47
46
|
export const convertReservationsToNetworks = (agentReservations, networkHocon, agentNetworkDefinition, agentNetworkName) => {
|
|
@@ -52,9 +51,45 @@ export const convertReservationsToNetworks = (agentReservations, networkHocon, a
|
|
|
52
51
|
},
|
|
53
52
|
// Use the explicit name when provided; fall back to extracting it from the reservation_id so that
|
|
54
53
|
// networks are always deduplicated by name even when the backend omits AGENT_NETWORK_NAME_KEY.
|
|
55
|
-
agentNetworkName: agentNetworkName ??
|
|
54
|
+
agentNetworkName: agentNetworkName ?? removeTrailingUuid(reservation.reservation_id),
|
|
56
55
|
networkHocon,
|
|
57
56
|
agentNetworkDefinition,
|
|
58
57
|
}));
|
|
59
58
|
};
|
|
60
|
-
export
|
|
59
|
+
export const isEditableAgent = (displayAs) => displayAs === DisplayAs.LLM_AGENT;
|
|
60
|
+
/**
|
|
61
|
+
* Extracts TemporaryNetwork objects from a chat message by reading reservations, HOCON,
|
|
62
|
+
* agent network definition, and agent network name from the message / sly_data.
|
|
63
|
+
* @param message The chat message to extract from.
|
|
64
|
+
* @param agentNetworkDefinitionOverride Optional definition override (e.g. a locally-edited version) that
|
|
65
|
+
* takes precedence over whatever the backend echoes in sly_data.
|
|
66
|
+
* @returns A (possibly empty) array of TemporaryNetwork objects ready for the store.
|
|
67
|
+
*/
|
|
68
|
+
export const extractTemporaryNetworksFromMessage = (message, agentNetworkDefinitionOverride) => {
|
|
69
|
+
const reservations = extractReservations(message);
|
|
70
|
+
if (reservations.length === 0)
|
|
71
|
+
return [];
|
|
72
|
+
const networkHocon = extractNetworkHocon(message);
|
|
73
|
+
const agentNetworkDefinition = agentNetworkDefinitionOverride ??
|
|
74
|
+
message.sly_data?.[AGENT_NETWORK_DEFINITION_KEY];
|
|
75
|
+
return convertReservationsToNetworks(reservations, networkHocon, agentNetworkDefinition);
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Returns true when agentName refers to a known temporary network.
|
|
79
|
+
*/
|
|
80
|
+
export const isTemporaryNetwork = (agentName, networks) => agentName !== null && networks.some((n) => n.agentInfo.agent_name === agentName);
|
|
81
|
+
/**
|
|
82
|
+
* Merges incoming networks into target, keeping the entry with the highest expiration time.
|
|
83
|
+
* Returns a new array; does not mutate either argument.
|
|
84
|
+
*/
|
|
85
|
+
export const mergeNetworks = (target, incoming) => incoming.reduce((result, n) => {
|
|
86
|
+
const existingIdx = result.findIndex((e) => e.agentNetworkName === n.agentNetworkName);
|
|
87
|
+
// No existing entry with this name - append.
|
|
88
|
+
if (existingIdx < 0)
|
|
89
|
+
return [...result, n];
|
|
90
|
+
// Existing entry found - keep whichever reservation expires later.
|
|
91
|
+
if (n.reservation.expiration_time_in_seconds > result[existingIdx].reservation.expiration_time_in_seconds) {
|
|
92
|
+
return result.map((e, i) => (i === existingIdx ? n : e));
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}, [...target]);
|
|
@@ -81,6 +81,13 @@ const TruncatedText = styled("div")(({ isHovered, isTruncated }) => ({
|
|
|
81
81
|
}));
|
|
82
82
|
// #endregion: Styled Components
|
|
83
83
|
export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true, isStreaming = false, onBubbleHoverChange, }) => {
|
|
84
|
+
/**
|
|
85
|
+
* A pure, managed timestamp that can be safely referenced during renders.
|
|
86
|
+
* Instead of calling the impure Date.now() directly in the render phase (which violates React's purity rules
|
|
87
|
+
* and triggers linting warnings), the component captures timestamps at controlled moments and stores them
|
|
88
|
+
* in state.
|
|
89
|
+
*/
|
|
90
|
+
const [time, setTime] = useState(() => Date.now());
|
|
84
91
|
// hoveredBubbleId: id of currently hovered bubble (or null)
|
|
85
92
|
const [hoveredBubbleId, setHoveredBubbleId] = useState(null);
|
|
86
93
|
// truncatedBubbles: set of edge ids whose text overflows the collapsed box
|
|
@@ -101,6 +108,13 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
101
108
|
// rAF ref for scheduling post-paint updates
|
|
102
109
|
const rafRef = useRef(null);
|
|
103
110
|
const mountedRef = useRef(true);
|
|
111
|
+
// Effect to update `time` every second to trigger re-renders for animation timing and line updates.
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
const interval = setInterval(() => {
|
|
114
|
+
setTime(Date.now());
|
|
115
|
+
}, 250);
|
|
116
|
+
return () => clearInterval(interval);
|
|
117
|
+
}, []);
|
|
104
118
|
// Filter edges with meaningful text (memoized to prevent infinite re-renders)
|
|
105
119
|
const thoughtBubbleEdges = useMemo(() => edges.filter((e) => {
|
|
106
120
|
const text = e.data?.text;
|
|
@@ -120,13 +134,12 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
120
134
|
// Find new bubbles that should appear
|
|
121
135
|
const newBubbles = thoughtBubbleEdges.filter((e) => !previousBubbleIds.has(e.id));
|
|
122
136
|
// Find bubbles that should disappear
|
|
123
|
-
const removingBubbles =
|
|
137
|
+
const removingBubbles = [...previousBubbleIds].filter((id) => !currentEdgeIds.has(id));
|
|
124
138
|
const newState = new Map(prev);
|
|
125
139
|
// Add new bubbles in entering state. Record when they entered so we can delay showing
|
|
126
140
|
// connecting lines until the bubble's entrance animation delay.
|
|
127
|
-
const now = Date.now();
|
|
128
141
|
newBubbles.forEach((edge) => {
|
|
129
|
-
newState.set(edge.id, { isVisible: true, isExiting: false, enteredAt:
|
|
142
|
+
newState.set(edge.id, { isVisible: true, isExiting: false, enteredAt: time });
|
|
130
143
|
});
|
|
131
144
|
// Mark removing bubbles as exiting
|
|
132
145
|
removingBubbles.forEach((id) => {
|
|
@@ -152,7 +165,7 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
152
165
|
});
|
|
153
166
|
return newState;
|
|
154
167
|
});
|
|
155
|
-
}, [thoughtBubbleEdges]);
|
|
168
|
+
}, [thoughtBubbleEdges, time]);
|
|
156
169
|
// Cleanup timeouts on unmount
|
|
157
170
|
useEffect(() => {
|
|
158
171
|
const timeouts = animationTimeouts.current;
|
|
@@ -178,9 +191,9 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
178
191
|
for (const node of nodes) {
|
|
179
192
|
const getConversations = node.data?.["getConversations"];
|
|
180
193
|
if (typeof getConversations === "function") {
|
|
181
|
-
const
|
|
182
|
-
if (Array.isArray(
|
|
183
|
-
const hasSelf =
|
|
194
|
+
const conversations = getConversations();
|
|
195
|
+
if (Array.isArray(conversations)) {
|
|
196
|
+
const hasSelf = conversations.some((conversation) => conversation?.agents?.has?.(node.id));
|
|
184
197
|
if (hasSelf) {
|
|
185
198
|
set.add(node.id);
|
|
186
199
|
}
|
|
@@ -297,13 +310,13 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
297
310
|
}
|
|
298
311
|
return results;
|
|
299
312
|
}, [activeAgentIds]);
|
|
300
|
-
// Get all bubbles to render (including exiting ones)
|
|
301
|
-
const allBubbleIds = Array.from(bubbleStates.keys());
|
|
302
313
|
// Memoize the resolved edges so updateAllLines (and effects depending on it)
|
|
303
314
|
// doesn't get recreated on every render unnecessarily.
|
|
304
|
-
const renderableBubbles = useMemo(() =>
|
|
315
|
+
const renderableBubbles = useMemo(() =>
|
|
316
|
+
// Get all bubbles to render (including exiting ones)
|
|
317
|
+
[...bubbleStates.keys()]
|
|
305
318
|
.map((id) => sortedEdges.find((e) => e.id === id) ?? edges.find((e) => e.id === id))
|
|
306
|
-
.filter((edge) => edge !== undefined), [
|
|
319
|
+
.filter((edge) => edge !== undefined), [bubbleStates, sortedEdges, edges]);
|
|
307
320
|
// Update all SVG lines imperatively after paint. This reads DOM (getBoundingClientRect)
|
|
308
321
|
// and writes attributes on existing <line> elements stored in `lineRefs`.
|
|
309
322
|
const updateAllLines = useCallback(() => {
|
|
@@ -313,7 +326,7 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
313
326
|
if (!bubbleState.isVisible || bubbleState.isExiting)
|
|
314
327
|
return;
|
|
315
328
|
// Respect the entrance animation delay gating (lines appear only after bubble start)
|
|
316
|
-
const elapsed =
|
|
329
|
+
const elapsed = time - (bubbleState?.enteredAt ?? 0);
|
|
317
330
|
const animationDelay = index * LAYOUT_BUBBLES_ANIMATION_DELAY_MS;
|
|
318
331
|
if (elapsed < animationDelay)
|
|
319
332
|
return;
|
|
@@ -338,7 +351,7 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
338
351
|
// Do not throw to avoid breaking the app
|
|
339
352
|
console.error("ThoughtBubbleOverlay: updateAllLines error", err);
|
|
340
353
|
}
|
|
341
|
-
}, [
|
|
354
|
+
}, [bubbleStates, calculateLineCoordinates, renderableBubbles, time]);
|
|
342
355
|
// Schedule post-paint updates with rAF and ResizeObserver. Also, optionally run a
|
|
343
356
|
// continuous loop while `isStreaming` is true to keep lines in sync during streaming.
|
|
344
357
|
useEffect(() => {
|
|
@@ -416,7 +429,7 @@ export const ThoughtBubbleOverlay = ({ nodes, edges, showThoughtBubbles = true,
|
|
|
416
429
|
if (!bubbleState.isVisible)
|
|
417
430
|
return null;
|
|
418
431
|
// Only render lines after the bubble's entrance animation delay has elapsed.
|
|
419
|
-
const elapsed =
|
|
432
|
+
const elapsed = time - (bubbleState.enteredAt || 0);
|
|
420
433
|
const shouldShowLines = elapsed >= animationDelay;
|
|
421
434
|
if (!shouldShowLines)
|
|
422
435
|
return null;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file defines the steps for the main tour of the Multi-Agent Accelerator application.
|
|
3
|
+
*
|
|
4
|
+
* @see https://react-joyride.com/docs/step
|
|
5
|
+
*/
|
|
6
|
+
export const MAIN_TOUR_STEPS = [
|
|
7
|
+
{
|
|
8
|
+
// First step doesn't refer to any particular UI element, just a welcome message
|
|
9
|
+
content: "Welcome to Cognizant AI Lab Multi-Agent Accelerator! This tour will give you a quick overview of " +
|
|
10
|
+
"the application.",
|
|
11
|
+
target: () => document.querySelector("#multi-agent-accelerator-grid"),
|
|
12
|
+
placement: "center",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
content: "This is the list of agent networks available on the server. Select a network to see its agents and " +
|
|
16
|
+
"start interacting with it!",
|
|
17
|
+
target: () => document.querySelector("#multi-agent-accelerator-sidebar-heading"),
|
|
18
|
+
placement: "bottom",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
content: "Agent Network Designer: Click here to create and edit your own network, with the help of a " +
|
|
22
|
+
"powerful AI assistant.",
|
|
23
|
+
target: () => document.querySelector("#add-network-icon"),
|
|
24
|
+
placement: "bottom",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
content: "Click this icon to connect to any Neuro SAN backend service. Mouse over it to see the current " +
|
|
28
|
+
"server you are connected to including the version.",
|
|
29
|
+
target: () => document.querySelector("#agent-network-settings-icon"),
|
|
30
|
+
placement: "bottom",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
content: "These are the agents within the current network.",
|
|
34
|
+
target: () => document.querySelector("#multi-agent-accelerator-grid-agent-flow"),
|
|
35
|
+
placement: "auto",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
content: "These buttons allow you to adjust the look of the agent flow to your liking. " +
|
|
39
|
+
"Mouse over them to see what they do!",
|
|
40
|
+
// get by aria-label "Control Panel"
|
|
41
|
+
target: () => document.querySelector('div[aria-label="Control Panel"]'),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
content: "This is the legend for the agent flow. You can select either 'depth' or 'heatmap' view " +
|
|
45
|
+
"to see the corresponding information about the agents in the flow.",
|
|
46
|
+
target: () => document.querySelector("#multi-agent-accelerator-agent-flow-legend"),
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
content: "This is the chat window where you can interact with the currently selected network.",
|
|
50
|
+
target: () => document.querySelector("#llm-chat-agent-network-ui"),
|
|
51
|
+
placement: "auto",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
content: "These are the sample queries for your currently selected network. Click one to send it to the agents!",
|
|
55
|
+
target: () => document.querySelector("#sample-queries-box"),
|
|
56
|
+
placement: "top",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
content: "Try typing your query here and sending it to the agents by hitting <Enter>!",
|
|
60
|
+
target: () => document.querySelector("#user-input-div"),
|
|
61
|
+
placement: "top",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
content: "These buttons allow you to control what is shown in the Chat window. " +
|
|
65
|
+
"Try mousing over them to see what they do!",
|
|
66
|
+
target: () => document.querySelector("#show-thinking-button"),
|
|
67
|
+
placement: "bottom",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
content: "Access Settings from this icon. Here you can change the look and feel of the application, including " +
|
|
71
|
+
"auto branding for a particular customer!",
|
|
72
|
+
target: () => document.querySelector("#settings-icon"),
|
|
73
|
+
placement: "top",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
content: "Select the items in this menu to learn more about Neuro-san, our open-source framework for building " +
|
|
77
|
+
"and running multi-agent systems, including access our GitHub repository with code samples " +
|
|
78
|
+
"and documentation.",
|
|
79
|
+
target: () => document.querySelector("#explore-dropdown"),
|
|
80
|
+
placement: "top",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
content: "If you want to take the tour again, or if you have any questions or need help, click here to access " +
|
|
84
|
+
"the help information or to contact the Cognizant AI Labs team. We'd love to hear from you!",
|
|
85
|
+
target: () => document.querySelector("#help-dropdown"),
|
|
86
|
+
placement: "top",
|
|
87
|
+
},
|
|
88
|
+
];
|
|
@@ -10,6 +10,7 @@ export declare const AGENT_PROGRESS_CONNECTIVITY_KEY = "connectivity_info";
|
|
|
10
10
|
export declare const AGENT_NETWORK_DESIGNER_ID = "agent_network_designer";
|
|
11
11
|
export declare const AGENT_NETWORK_DEFINITION_KEY = "agent_network_definition";
|
|
12
12
|
export declare const AGENT_NETWORK_NAME_KEY = "agent_network_name";
|
|
13
|
+
export declare const TRIGGER_APP_TOUR_EVENT_NAME = "trigger-app-tour";
|
|
13
14
|
/**
|
|
14
15
|
* A single agent entry within an agent network definition, as received in sly_data from the backend.
|
|
15
16
|
* Extends ConnectivityInfo with editable instructions and description fields for the Agent Network Designer.
|
|
@@ -19,13 +20,9 @@ export type AgentNetworkDefinitionEntry = ConnectivityInfo & {
|
|
|
19
20
|
readonly description?: string;
|
|
20
21
|
};
|
|
21
22
|
/** Possible values for the `display_as` field in ConnectivityInfo / AgentNetworkDefinitionEntry. */
|
|
22
|
-
export declare
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* Only `llm_agent` nodes (and the Frontman, whose `display_as` is undefined) are editable.
|
|
29
|
-
* `coded_tool`, `langchain_tool`, `external_agent`, and any other types are read-only.
|
|
30
|
-
*/
|
|
31
|
-
export declare const isEditableAgent: (displayAs: string | undefined) => boolean;
|
|
23
|
+
export declare enum DisplayAs {
|
|
24
|
+
LLM_AGENT = "llm_agent",
|
|
25
|
+
CODED_TOOL = "coded_tool",
|
|
26
|
+
LANGCHAIN_TOOL = "langchain_tool",
|
|
27
|
+
EXTERNAL_AGENT = "external_agent"
|
|
28
|
+
}
|
|
@@ -35,14 +35,13 @@ export const AGENT_NETWORK_DESIGNER_ID = "agent_network_designer";
|
|
|
35
35
|
export const AGENT_NETWORK_DEFINITION_KEY = "agent_network_definition";
|
|
36
36
|
// The key in sly_data where the agent network name is stored
|
|
37
37
|
export const AGENT_NETWORK_NAME_KEY = "agent_network_name";
|
|
38
|
+
// The event name that needs to be fired for the app tour to start
|
|
39
|
+
export const TRIGGER_APP_TOUR_EVENT_NAME = "trigger-app-tour";
|
|
38
40
|
/** Possible values for the `display_as` field in ConnectivityInfo / AgentNetworkDefinitionEntry. */
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* `coded_tool`, `langchain_tool`, `external_agent`, and any other types are read-only.
|
|
47
|
-
*/
|
|
48
|
-
export const isEditableAgent = (displayAs) => displayAs === DISPLAY_AS_LLM_AGENT;
|
|
41
|
+
export var DisplayAs;
|
|
42
|
+
(function (DisplayAs) {
|
|
43
|
+
DisplayAs["LLM_AGENT"] = "llm_agent";
|
|
44
|
+
DisplayAs["CODED_TOOL"] = "coded_tool";
|
|
45
|
+
DisplayAs["LANGCHAIN_TOOL"] = "langchain_tool";
|
|
46
|
+
DisplayAs["EXTERNAL_AGENT"] = "external_agent";
|
|
47
|
+
})(DisplayAs || (DisplayAs = {}));
|
package/dist/const.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export declare const LOGO: string;
|
|
2
2
|
export declare const NEURO_SAN_UI_VERSION: string;
|
|
3
3
|
export declare const getContactUsConfirmationText: (email: string) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The default username to use when the user is not authenticated or does not have a name available, or when
|
|
6
|
+
* auentication is disabled
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULT_USERNAME = "Guest";
|
|
4
9
|
/**
|
|
5
10
|
* The default user image to use when the user does not have a profile picture.
|
|
6
11
|
*/
|
|
7
12
|
export declare const DEFAULT_USER_IMAGE = "https://www.gravatar.com/avatar/?d=mp";
|
|
8
13
|
export declare const authenticationEnabled: () => boolean;
|
|
9
|
-
export declare const DEFAULT_NEURO_SAN_SERVER_URL = "https://neuro-san-dev.decisionai.ml";
|
package/dist/const.js
CHANGED
|
@@ -20,10 +20,13 @@ export const getContactUsConfirmationText = (email) => "Would you like to send t
|
|
|
20
20
|
"You will need to have an email client installed on your device in order " +
|
|
21
21
|
"to continue. If you don't have an email client, you can still contact us at " +
|
|
22
22
|
`${email} using a web based email client.`;
|
|
23
|
+
/**
|
|
24
|
+
* The default username to use when the user is not authenticated or does not have a name available, or when
|
|
25
|
+
* auentication is disabled
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_USERNAME = "Guest";
|
|
23
28
|
/**
|
|
24
29
|
* The default user image to use when the user does not have a profile picture.
|
|
25
30
|
*/
|
|
26
31
|
export const DEFAULT_USER_IMAGE = "https://www.gravatar.com/avatar/?d=mp";
|
|
27
32
|
export const authenticationEnabled = () => process.env["NEXT_PUBLIC_ENABLE_AUTHENTICATION"] !== "false";
|
|
28
|
-
// Default "dev URL" for NeuroSan server, to allow for "zero config" execution.
|
|
29
|
-
export const DEFAULT_NEURO_SAN_SERVER_URL = "https://neuro-san-dev.decisionai.ml";
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controller module for interacting with the Agent LLM API.
|
|
3
|
+
*/
|
|
4
|
+
import { AgentNetworkDefinitionEntry } from "../../components/MultiAgentAccelerator/const.js";
|
|
1
5
|
import { AgentInfo, ChatContext, ChatResponse, ConnectivityResponse, FunctionResponse } from "../../generated/neuro-san/NeuroSanClient.js";
|
|
2
6
|
import { StreamingUnit } from "../llm/LlmChat.js";
|
|
3
7
|
import { AgentIconSuggestions } from "../Types/AgentIconSuggestions.js";
|
|
@@ -76,3 +80,9 @@ export declare const getConnectivity: (url: string, network: string, userId: str
|
|
|
76
80
|
* @throws Various exceptions if anything goes wrong such as network issues or invalid agent type.
|
|
77
81
|
*/
|
|
78
82
|
export declare const getAgentFunction: (url: string, agent: string, userId: string) => Promise<FunctionResponse>;
|
|
83
|
+
/**
|
|
84
|
+
* Streams the Agent Network Designer endpoint with an updated agent definition.
|
|
85
|
+
* Calls `onChunk` for each line received; callers are responsible for parsing
|
|
86
|
+
* reservations / networks out of each chunk.
|
|
87
|
+
*/
|
|
88
|
+
export declare const sendNetworkDesignerUpdate: (url: string, signal: AbortSignal, agentName: string, updated: AgentNetworkDefinitionEntry[], agentNetworkName: string | undefined, currentUser: string, onChunk: (chunk: string) => void) => Promise<void>;
|
|
@@ -16,7 +16,7 @@ limitations under the License.
|
|
|
16
16
|
/**
|
|
17
17
|
* Controller module for interacting with the Agent LLM API.
|
|
18
18
|
*/
|
|
19
|
-
import { TEMPORARY_NETWORK_FOLDER } from "../../components/MultiAgentAccelerator/const.js";
|
|
19
|
+
import { AGENT_NETWORK_DEFINITION_KEY, AGENT_NETWORK_DESIGNER_ID, AGENT_NETWORK_NAME_KEY, TEMPORARY_NETWORK_FOLDER, } from "../../components/MultiAgentAccelerator/const.js";
|
|
20
20
|
import { ApiPaths,
|
|
21
21
|
// eslint-disable-next-line camelcase
|
|
22
22
|
ChatFilterChat_filter_type, ChatMessageType, } from "../../generated/neuro-san/NeuroSanClient.js";
|
|
@@ -213,3 +213,19 @@ export const getAgentFunction = async (url, agent, userId) => {
|
|
|
213
213
|
}
|
|
214
214
|
return response.json();
|
|
215
215
|
};
|
|
216
|
+
/**
|
|
217
|
+
* Streams the Agent Network Designer endpoint with an updated agent definition.
|
|
218
|
+
* Calls `onChunk` for each line received; callers are responsible for parsing
|
|
219
|
+
* reservations / networks out of each chunk.
|
|
220
|
+
*/
|
|
221
|
+
export const sendNetworkDesignerUpdate = async (url, signal, agentName, updated, agentNetworkName, currentUser, onChunk) => {
|
|
222
|
+
await sendChatQuery(url, signal,
|
|
223
|
+
// Shouldn't have to pass a user message, but API behaves different without it
|
|
224
|
+
`Update instructions for agent "${agentName}"`, AGENT_NETWORK_DESIGNER_ID, onChunk, null, {
|
|
225
|
+
[AGENT_NETWORK_DEFINITION_KEY]: updated,
|
|
226
|
+
// Use the backend's canonical name, not the local UUID-based key.
|
|
227
|
+
...(agentNetworkName ? { [AGENT_NETWORK_NAME_KEY]: agentNetworkName } : {}),
|
|
228
|
+
// skip_designer prevents the backend from using a reasoning model for edits
|
|
229
|
+
skip_designer: true,
|
|
230
|
+
}, currentUser, StreamingUnit.Line);
|
|
231
|
+
};
|
|
@@ -56,9 +56,9 @@ const handleStreamingCallback = async (res, callback, streamingUnit) => {
|
|
|
56
56
|
let newlineIndex;
|
|
57
57
|
while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
|
|
58
58
|
// Extract the complete line (without the newline)
|
|
59
|
-
const line = buffer.
|
|
59
|
+
const line = buffer.slice(0, Math.max(0, newlineIndex)).trim();
|
|
60
60
|
// Keep the rest for next iteration
|
|
61
|
-
buffer = buffer.
|
|
61
|
+
buffer = buffer.slice(Math.max(0, newlineIndex + 1));
|
|
62
62
|
// Skip empty lines
|
|
63
63
|
if (line.length > 0) {
|
|
64
64
|
// Send the current line
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export * from "./components/Authentication/Auth.js";
|
|
|
13
13
|
export * from "./components/Common/Breadcrumbs.js";
|
|
14
14
|
export * from "./components/Common/ConfirmationModal.js";
|
|
15
15
|
export * from "./components/Common/Footer.js";
|
|
16
|
-
export * from "./components/Common/LlmChatOptionsButton.js";
|
|
17
16
|
export * from "./components/Common/LoadingSpinner.js";
|
|
18
17
|
export * from "./components/Common/MUIAccordion.js";
|
|
19
18
|
export * from "./components/Common/MUIAlert.js";
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,6 @@ export * from "./components/Authentication/Auth.js";
|
|
|
28
28
|
export * from "./components/Common/Breadcrumbs.js";
|
|
29
29
|
export * from "./components/Common/ConfirmationModal.js";
|
|
30
30
|
export * from "./components/Common/Footer.js";
|
|
31
|
-
export * from "./components/Common/LlmChatOptionsButton.js";
|
|
32
31
|
export * from "./components/Common/LoadingSpinner.js";
|
|
33
32
|
export * from "./components/Common/MUIAccordion.js";
|
|
34
33
|
export * from "./components/Common/MUIAlert.js";
|
|
@@ -9,7 +9,7 @@ export type TemporaryNetwork = {
|
|
|
9
9
|
readonly reservation: AgentReservation;
|
|
10
10
|
readonly agentInfo: AgentInfo;
|
|
11
11
|
/** The agent_network_name as sent by the backend — used when bouncing sly_data back to the backend. */
|
|
12
|
-
readonly agentNetworkName
|
|
12
|
+
readonly agentNetworkName: string;
|
|
13
13
|
readonly networkHocon?: string | null;
|
|
14
14
|
readonly agentNetworkDefinition?: AgentNetworkDefinitionEntry[];
|
|
15
15
|
};
|
|
@@ -21,24 +21,14 @@ interface TempNetworksStore {
|
|
|
21
21
|
readonly setTempNetworks: (tempNetworks: TemporaryNetwork[]) => void;
|
|
22
22
|
/**
|
|
23
23
|
* Upsert new networks into the store. Networks are matched by the UUID-stripped portion of
|
|
24
|
-
* their `reservation_id` (e.g. `"travel_agency_ops"` from `"travel_agency_ops-{uuid}"`),
|
|
25
|
-
*
|
|
24
|
+
* their `reservation_id` (e.g. `"travel_agency_ops"` from `"travel_agency_ops-{uuid}"`), or, just
|
|
25
|
+
* `agentNetworkName` which is the same as having the UUID-stripped. If an incoming network
|
|
26
26
|
* matches an existing one, the existing entry is replaced. Returns the final list of upserted
|
|
27
27
|
* networks (those that were added or replaced).
|
|
28
28
|
*/
|
|
29
|
-
readonly upsertTempNetworks: (
|
|
30
|
-
readonly updateTempNetworkDefinition: (networkName: string,
|
|
29
|
+
readonly upsertTempNetworks: (incomingNetworks: TemporaryNetwork[]) => TemporaryNetwork[];
|
|
30
|
+
readonly updateTempNetworkDefinition: (networkName: string, agentNetworkDefinition: AgentNetworkDefinitionEntry[]) => void;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Derives the canonical network name from a reservation ID.
|
|
34
|
-
*
|
|
35
|
-
* The backend encodes the network name as a prefix in the reservation ID, followed by a UUID suffix:
|
|
36
|
-
* `{network_name}-{uuid}`, e.g. `travel_agency_ops-7876642e-fe75-4d44-a61e-300688a1a6c5`.
|
|
37
|
-
*
|
|
38
|
-
* Stripping the UUID suffix gives the stable name that can be used for deduplication across reservations.
|
|
39
|
-
* Returns `undefined` when the reservation ID doesn't match the expected format.
|
|
40
|
-
*/
|
|
41
|
-
export declare const extractNetworkNameFromReservationId: (reservationId: string) => string | undefined;
|
|
42
32
|
/**
|
|
43
33
|
* The hook that lets apps use the store.
|
|
44
34
|
*/
|