@cognizant-ai-lab/ui-common 1.3.3

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 (108) hide show
  1. package/dist/components/AgentChat/ChatCommon.d.ts +94 -0
  2. package/dist/components/AgentChat/ChatCommon.js +581 -0
  3. package/dist/components/AgentChat/ControlButtons.d.ts +16 -0
  4. package/dist/components/AgentChat/ControlButtons.js +24 -0
  5. package/dist/components/AgentChat/FormattedMarkdown.d.ts +32 -0
  6. package/dist/components/AgentChat/FormattedMarkdown.js +82 -0
  7. package/dist/components/AgentChat/Greetings.d.ts +1 -0
  8. package/dist/components/AgentChat/Greetings.js +38 -0
  9. package/dist/components/AgentChat/LlmChatButton.d.ts +12 -0
  10. package/dist/components/AgentChat/LlmChatButton.js +33 -0
  11. package/dist/components/AgentChat/SendButton.d.ts +12 -0
  12. package/dist/components/AgentChat/SendButton.js +28 -0
  13. package/dist/components/AgentChat/SyntaxHighlighterThemes.d.ts +14 -0
  14. package/dist/components/AgentChat/SyntaxHighlighterThemes.js +27 -0
  15. package/dist/components/AgentChat/Types.d.ts +17 -0
  16. package/dist/components/AgentChat/Types.js +26 -0
  17. package/dist/components/AgentChat/UserQueryDisplay.d.ts +5 -0
  18. package/dist/components/AgentChat/UserQueryDisplay.js +33 -0
  19. package/dist/components/AgentChat/Utils.d.ts +11 -0
  20. package/dist/components/AgentChat/Utils.js +64 -0
  21. package/dist/components/AgentChat/VoiceChat/MicrophoneButton.d.ts +29 -0
  22. package/dist/components/AgentChat/VoiceChat/MicrophoneButton.js +55 -0
  23. package/dist/components/AgentChat/VoiceChat/VoiceChat.d.ts +33 -0
  24. package/dist/components/AgentChat/VoiceChat/VoiceChat.js +180 -0
  25. package/dist/components/Authentication/Auth.d.ts +14 -0
  26. package/dist/components/Authentication/Auth.js +58 -0
  27. package/dist/components/ChatBot/ChatBot.d.ts +20 -0
  28. package/dist/components/ChatBot/ChatBot.js +75 -0
  29. package/dist/components/Common/Breadcrumbs.d.ts +6 -0
  30. package/dist/components/Common/Breadcrumbs.js +36 -0
  31. package/dist/components/Common/LlmChatOptionsButton.d.ts +9 -0
  32. package/dist/components/Common/LlmChatOptionsButton.js +31 -0
  33. package/dist/components/Common/LoadingSpinner.d.ts +10 -0
  34. package/dist/components/Common/LoadingSpinner.js +24 -0
  35. package/dist/components/Common/MUIAccordion.d.ts +17 -0
  36. package/dist/components/Common/MUIAccordion.js +76 -0
  37. package/dist/components/Common/MUIAlert.d.ts +11 -0
  38. package/dist/components/Common/MUIAlert.js +41 -0
  39. package/dist/components/Common/MUIDialog.d.ts +16 -0
  40. package/dist/components/Common/MUIDialog.js +40 -0
  41. package/dist/components/Common/Navbar.d.ts +15 -0
  42. package/dist/components/Common/Navbar.js +137 -0
  43. package/dist/components/Common/PageLoader.d.ts +5 -0
  44. package/dist/components/Common/PageLoader.js +26 -0
  45. package/dist/components/Common/Snackbar.d.ts +5 -0
  46. package/dist/components/Common/Snackbar.js +84 -0
  47. package/dist/components/Common/confirmationModal.d.ts +14 -0
  48. package/dist/components/Common/confirmationModal.js +65 -0
  49. package/dist/components/Common/notification.d.ts +18 -0
  50. package/dist/components/Common/notification.js +79 -0
  51. package/dist/components/ErrorPage/ErrorBoundary.d.ts +38 -0
  52. package/dist/components/ErrorPage/ErrorBoundary.js +77 -0
  53. package/dist/components/ErrorPage/ErrorPage.d.ts +12 -0
  54. package/dist/components/ErrorPage/ErrorPage.js +46 -0
  55. package/dist/components/MultiAgentAccelerator/AgentFlow.d.ts +21 -0
  56. package/dist/components/MultiAgentAccelerator/AgentFlow.js +394 -0
  57. package/dist/components/MultiAgentAccelerator/AgentNode.d.ts +18 -0
  58. package/dist/components/MultiAgentAccelerator/AgentNode.js +129 -0
  59. package/dist/components/MultiAgentAccelerator/GraphLayouts.d.ts +33 -0
  60. package/dist/components/MultiAgentAccelerator/GraphLayouts.js +297 -0
  61. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.d.ts +17 -0
  62. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.js +208 -0
  63. package/dist/components/MultiAgentAccelerator/PlasmaEdge.d.ts +3 -0
  64. package/dist/components/MultiAgentAccelerator/PlasmaEdge.js +124 -0
  65. package/dist/components/MultiAgentAccelerator/Sidebar.d.ts +12 -0
  66. package/dist/components/MultiAgentAccelerator/Sidebar.js +204 -0
  67. package/dist/components/MultiAgentAccelerator/ThoughtBubbleEdge.d.ts +12 -0
  68. package/dist/components/MultiAgentAccelerator/ThoughtBubbleEdge.js +15 -0
  69. package/dist/components/MultiAgentAccelerator/ThoughtBubbleOverlay.d.ts +11 -0
  70. package/dist/components/MultiAgentAccelerator/ThoughtBubbleOverlay.js +466 -0
  71. package/dist/components/MultiAgentAccelerator/const.d.ts +7 -0
  72. package/dist/components/MultiAgentAccelerator/const.js +39 -0
  73. package/dist/const.d.ts +10 -0
  74. package/dist/const.js +30 -0
  75. package/dist/controller/agent/Agent.d.ts +56 -0
  76. package/dist/controller/agent/Agent.js +162 -0
  77. package/dist/controller/llm/LlmChat.d.ts +18 -0
  78. package/dist/controller/llm/LlmChat.js +65 -0
  79. package/dist/controller/llm/endpoints.d.ts +1 -0
  80. package/dist/controller/llm/endpoints.js +17 -0
  81. package/dist/generated/neuro-san/NeuroSanClient.d.ts +413 -0
  82. package/dist/generated/neuro-san/NeuroSanClient.js +28 -0
  83. package/dist/index.d.ts +37 -0
  84. package/dist/index.js +52 -0
  85. package/dist/state/UserInfo.d.ts +16 -0
  86. package/dist/state/UserInfo.js +27 -0
  87. package/dist/state/environment.d.ts +18 -0
  88. package/dist/state/environment.js +33 -0
  89. package/dist/tsconfig.build.tsbuildinfo +1 -0
  90. package/dist/utils/Authentication.d.ts +31 -0
  91. package/dist/utils/Authentication.js +94 -0
  92. package/dist/utils/BrowserNavigation.d.ts +5 -0
  93. package/dist/utils/BrowserNavigation.js +22 -0
  94. package/dist/utils/Theme.d.ts +7 -0
  95. package/dist/utils/Theme.js +7 -0
  96. package/dist/utils/agentConversations.d.ts +24 -0
  97. package/dist/utils/agentConversations.js +113 -0
  98. package/dist/utils/text.d.ts +28 -0
  99. package/dist/utils/text.js +64 -0
  100. package/dist/utils/title.d.ts +1 -0
  101. package/dist/utils/title.js +20 -0
  102. package/dist/utils/types.d.ts +17 -0
  103. package/dist/utils/types.js +16 -0
  104. package/dist/utils/useLocalStorage.d.ts +1 -0
  105. package/dist/utils/useLocalStorage.js +55 -0
  106. package/dist/utils/zIndexLayers.d.ts +2 -0
  107. package/dist/utils/zIndexLayers.js +29 -0
  108. package/package.json +69 -0
@@ -0,0 +1,31 @@
1
+ import { OidcProvider } from "./types.js";
2
+ /**
3
+ * The Azure AD tenant ID.
4
+ */
5
+ export declare const AD_TENANT_ID = "de08c407-19b9-427d-9fe8-edf254300ca7";
6
+ /**
7
+ * Hook for abstracting away the authentication provider. We are migrating to ALB-based authentication, instead of it
8
+ * being handled by the app via NextAuth. This way existing pages only need trivial changes to use this hook instead
9
+ * of NextAuth's useSession hook.
10
+ */
11
+ export declare function useAuthentication(): {
12
+ data: {
13
+ user: {
14
+ name: string;
15
+ image: string;
16
+ };
17
+ };
18
+ };
19
+ /**
20
+ * Smart sign out function that abstracts away the authentication provider.
21
+ * We are migrating to ALB-based authentication, instead of it being handled by the app via NextAuth. This function
22
+ * handles the sign-out process for both NextAuth and ALB.
23
+ * @param currentUser The username of the current user. If undefined, we don't know what authentication provider we're
24
+ * using, so just return. If null, we're using NextAuth. Otherwise, we're using ALB.
25
+ * @param auth0Domain The Auth0 domain. See Auth0 doc for more details.
26
+ * @param auth0ClientId The Auth0 client ID. See Auth0 doc for more details. Identifies the app being used in Auth0.
27
+ * @param oidcProvider The OIDC provider. See OIDC doc for more details.
28
+ * @return Nothing, but executes the sign-out process.
29
+ *
30
+ */
31
+ export declare function smartSignOut(currentUser: string, auth0Domain: string, auth0ClientId: string, oidcProvider: OidcProvider): Promise<void>;
@@ -0,0 +1,94 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ // See main function comment for more details.
17
+ import { signOut, useSession } from "next-auth/react";
18
+ import { navigateToUrl } from "./BrowserNavigation.js";
19
+ import { useUserInfoStore } from "../state/UserInfo.js";
20
+ /**
21
+ * The Azure AD tenant ID.
22
+ */
23
+ export const AD_TENANT_ID = "de08c407-19b9-427d-9fe8-edf254300ca7";
24
+ /**
25
+ * Hook for abstracting away the authentication provider. We are migrating to ALB-based authentication, instead of it
26
+ * being handled by the app via NextAuth. This way existing pages only need trivial changes to use this hook instead
27
+ * of NextAuth's useSession hook.
28
+ */
29
+ export function useAuthentication() {
30
+ const { data: session } = useSession();
31
+ const { currentUser: albUser, picture: albPicture } = useUserInfoStore();
32
+ // Return the user data in the same format as NextAuth's useSession hook. We prioritize the ALB info if we have
33
+ // it, but if not degrade gracefully to the NextAuth info.
34
+ return {
35
+ data: {
36
+ user: {
37
+ name: albUser || session?.user?.name,
38
+ image: albPicture || session?.user?.image,
39
+ },
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Create the logout URL for Auth0.
45
+ * @param oidcProvider The OIDC provider. See OIDC doc for more details.
46
+ * @param auth0Domain The Auth0 domain. See Auth0 doc for more details.
47
+ * @param auth0ClientId The Auth0 client ID. See Auth0 doc for more details. Identifies the app being used in Auth0.
48
+ * @return The logout URL.
49
+ */
50
+ function createAuth0LogoutUrl(oidcProvider, auth0Domain, auth0ClientId) {
51
+ switch (oidcProvider) {
52
+ case "AD":
53
+ return `https://login.microsoftonline.com/${AD_TENANT_ID}/oauth2/v2.0/logout`;
54
+ case "Github":
55
+ default: {
56
+ const baseUrl = `${window.location.protocol}//${window.location.host}`;
57
+ const returnTo = encodeURIComponent(baseUrl);
58
+ return `https://${auth0Domain}/v2/logout?client_id=${auth0ClientId}&returnTo=${returnTo}`;
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * Smart sign out function that abstracts away the authentication provider.
64
+ * We are migrating to ALB-based authentication, instead of it being handled by the app via NextAuth. This function
65
+ * handles the sign-out process for both NextAuth and ALB.
66
+ * @param currentUser The username of the current user. If undefined, we don't know what authentication provider we're
67
+ * using, so just return. If null, we're using NextAuth. Otherwise, we're using ALB.
68
+ * @param auth0Domain The Auth0 domain. See Auth0 doc for more details.
69
+ * @param auth0ClientId The Auth0 client ID. See Auth0 doc for more details. Identifies the app being used in Auth0.
70
+ * @param oidcProvider The OIDC provider. See OIDC doc for more details.
71
+ * @return Nothing, but executes the sign-out process.
72
+ *
73
+ */
74
+ export async function smartSignOut(currentUser, auth0Domain, auth0ClientId, oidcProvider) {
75
+ if (currentUser === undefined) {
76
+ // Don't know what authentication provider we're using, so just return
77
+ return;
78
+ }
79
+ if (oidcProvider === "NextAuth") {
80
+ // NextAuth case
81
+ await signOut({ redirect: true });
82
+ }
83
+ else {
84
+ // ALB case
85
+ // Use server endpoint to clear ALB cookies
86
+ void (await fetch("/api/logout", {
87
+ method: "POST",
88
+ headers: {
89
+ "Content-Type": "application/json",
90
+ },
91
+ }));
92
+ navigateToUrl(createAuth0LogoutUrl(oidcProvider, auth0Domain, auth0ClientId));
93
+ }
94
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Navigate to the specified URL by setting window.location.href
3
+ * @param url The URL to navigate to
4
+ */
5
+ export declare const navigateToUrl: (url: string) => void;
@@ -0,0 +1,22 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ /**
17
+ * Navigate to the specified URL by setting window.location.href
18
+ * @param url The URL to navigate to
19
+ */
20
+ export const navigateToUrl = (url) => {
21
+ window.location.href = url;
22
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Helper to determine if dark mode is active based on mode and systemMode.
3
+ * @param mode Current mode setting: "light", "dark", or "system"
4
+ * @param systemMode If mode is "system", this indicates the system preference: "light" or "dark"
5
+ * @returns true if dark mode is active, false otherwise
6
+ */
7
+ export declare const isDarkMode: (mode: "light" | "dark" | "system", systemMode: "light" | "dark") => boolean;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Helper to determine if dark mode is active based on mode and systemMode.
3
+ * @param mode Current mode setting: "light", "dark", or "system"
4
+ * @param systemMode If mode is "system", this indicates the system preference: "light" or "dark"
5
+ * @returns true if dark mode is active, false otherwise
6
+ */
7
+ export const isDarkMode = (mode, systemMode) => mode === "dark" || (mode === "system" && systemMode === "dark");
@@ -0,0 +1,24 @@
1
+ import { ChatMessageType, Origin } from "../generated/neuro-san/NeuroSanClient.js";
2
+ export interface AgentConversationBase {
3
+ agents: Set<string>;
4
+ startedAt: Date;
5
+ text?: string;
6
+ type: ChatMessageType;
7
+ }
8
+ export interface AgentConversation extends AgentConversationBase {
9
+ id: string;
10
+ }
11
+ export declare const isFinalMessage: (chatMessage: {
12
+ structure?: {
13
+ tool_end?: boolean;
14
+ total_tokens?: number;
15
+ };
16
+ text?: string;
17
+ }) => boolean;
18
+ export declare const createConversation: (agents: string[], text: string, type: ChatMessageType) => AgentConversation;
19
+ export declare const updateAgentCounts: (agentCountsMap: Map<string, number>, origins: readonly Origin[]) => Map<string, number>;
20
+ export declare const processChatChunk: (chunk: string, agentCountsMap: Map<string, number>, currentConversations: AgentConversation[] | null) => {
21
+ success: boolean;
22
+ newCounts: Map<string, number>;
23
+ newConversations: AgentConversation[] | null;
24
+ };
@@ -0,0 +1,113 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { chatMessageFromChunk } from "../components/AgentChat/Utils.js";
17
+ import { NotificationType, sendNotification } from "../components/Common/notification.js";
18
+ import { ChatMessageType } from "../generated/neuro-san/NeuroSanClient.js";
19
+ export const isFinalMessage = (chatMessage) => {
20
+ const isAgentFinalResponse = chatMessage.structure?.total_tokens;
21
+ const isCodedToolFinalResponse = chatMessage.structure?.tool_end;
22
+ return Boolean(isAgentFinalResponse || isCodedToolFinalResponse);
23
+ };
24
+ export const createConversation = (agents, text, type) => ({
25
+ // Could use crypto.randomUUID, but it's only available under HTTPS, and don't want to use a different
26
+ // solution for HTTP on localhost.
27
+ // eslint-disable-next-line newline-per-chained-call
28
+ id: `conv_${Date.now()}${Math.random().toString(36).slice(2, 10)}`,
29
+ agents: new Set(agents),
30
+ startedAt: new Date(),
31
+ text,
32
+ type,
33
+ });
34
+ export const updateAgentCounts = (agentCountsMap, origins) => {
35
+ // Update agent counts.
36
+ // Note: we increment an agent's count each time it appears in the origin info, but another strategy
37
+ // would be to only count an agent when it is the "end destination" of the chain. Needs some thought to
38
+ // determine which is more useful.
39
+ return origins.reduce((acc, { tool }) => {
40
+ // If the agent is not already in the counts map, initialize it to 0 aka "upsert"
41
+ acc.set(tool, (acc.get(tool) || 0) + 1);
42
+ return acc;
43
+ }, new Map(agentCountsMap));
44
+ };
45
+ const processAgentCompletion = (conversations, tools) => {
46
+ const toolsToRemove = new Set(tools);
47
+ // For each conversation:
48
+ // 1) Remove all agents whose tool is in toolsToRemove
49
+ // 2) Only keep conversations that still have agents left
50
+ return (conversations
51
+ .map((conv) => {
52
+ // Remove all matching tools from this conversation's agents
53
+ const updatedAgents = new Set([...conv.agents].filter((agent) => !toolsToRemove.has(agent)));
54
+ // Return a new conversation object with updated agents
55
+ return { ...conv, agents: updatedAgents };
56
+ })
57
+ // Filter out conversations that have no agents left
58
+ .filter((conv) => conv.agents.size > 0));
59
+ };
60
+ export const processChatChunk = (chunk, agentCountsMap, currentConversations) => {
61
+ try {
62
+ const updatedConversations = [...(currentConversations || [])];
63
+ // Get chat message if it's a known message type
64
+ const chatMessage = chatMessageFromChunk(chunk);
65
+ // If there are no origins in a chat message, return current state
66
+ if (!chatMessage?.origin?.length) {
67
+ return {
68
+ success: true,
69
+ newCounts: agentCountsMap,
70
+ newConversations: currentConversations,
71
+ };
72
+ }
73
+ // Update agent counts
74
+ const updatedCounts = updateAgentCounts(agentCountsMap, chatMessage.origin);
75
+ const isFinal = isFinalMessage(chatMessage);
76
+ const agents = chatMessage.origin.map((originItem) => originItem.tool).filter(Boolean);
77
+ let finalConversations;
78
+ // Check if this is an AGENT message and if it's a final message, i.e. an end event (could be an AGENT final
79
+ // message or coded tool end, see isFinalMessage function)
80
+ if (chatMessage.type === ChatMessageType.AGENT && isFinal) {
81
+ const currentConversationsToUpdate = processAgentCompletion(updatedConversations, agents);
82
+ finalConversations = currentConversationsToUpdate.length === 0 ? null : currentConversationsToUpdate;
83
+ }
84
+ else {
85
+ // Create a new conversation for this communication path
86
+ let inquiryText;
87
+ const params = chatMessage.structure?.["params"];
88
+ if (params && typeof params === "object" && "inquiry" in params) {
89
+ inquiryText = params.inquiry;
90
+ }
91
+ const textToShow = inquiryText || chatMessage.text;
92
+ // Show inquiry (from structure), that's only for networks that use AAOSA with a JSON format.
93
+ // Otherwise show the raw data from the `text` field of the chat message.
94
+ const newConversation = createConversation(agents, textToShow, chatMessage.type);
95
+ updatedConversations.push(newConversation);
96
+ finalConversations = updatedConversations;
97
+ }
98
+ return {
99
+ success: true,
100
+ newCounts: updatedCounts,
101
+ newConversations: finalConversations,
102
+ };
103
+ }
104
+ catch (error) {
105
+ sendNotification(NotificationType.error, "Agent conversation error");
106
+ console.error("Agent conversation error:", error);
107
+ return {
108
+ success: false,
109
+ newCounts: agentCountsMap,
110
+ newConversations: currentConversations,
111
+ };
112
+ }
113
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tests if input contains only whitespace (meaning, not a valid query)
3
+ *
4
+ * @param input Input to be tested
5
+ * @returns True if input contains only whitespace, false otherwise
6
+ */
7
+ export declare function hasOnlyWhitespace(input: string): boolean;
8
+ /**
9
+ * Extracts the ID from a model ID
10
+ *
11
+ * @param modelId Model ID to be processed, eg. `"prescriptor-67fb86d3-9047-4ce0-0d42-4e3d3b0f715e-83_28"`
12
+ * @param modelType Type of model -- `"prescriptor"` or `"rio"`
13
+ * @returns Model ID with the last hyphenated item removed (eg. `"67fb86d3-9047-4ce0-0d42-4e3d3b0f715e"`)
14
+
15
+ * @example
16
+ * ```
17
+ * removeLast("prescriptor-67fb86d3-9047-4ce0-0d42-4e3d3b0f715e-83_28", "prescriptor")
18
+ * = "67fb86d3-9047-4ce0-0d42-4e3d3b0f715e"
19
+ * ```
20
+ */
21
+ export declare function extractId(modelId: string, modelType: "prescriptor" | "rio"): string;
22
+ /**
23
+ * Hashes a string using MD5. For example: for generating keys for React nodes from a longer string identifer.
24
+ *
25
+ * @param input String to be hashed
26
+ * @returns Hashed string
27
+ */
28
+ export declare const hashString: (input: string) => string;
@@ -0,0 +1,64 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ /**
17
+ * For text processing utility functions
18
+ */
19
+ import { createHash } from "crypto";
20
+ /**
21
+ * Tests if input contains only whitespace (meaning, not a valid query)
22
+ *
23
+ * @param input Input to be tested
24
+ * @returns True if input contains only whitespace, false otherwise
25
+ */
26
+ export function hasOnlyWhitespace(input) {
27
+ return input?.trim().length === 0;
28
+ }
29
+ /**
30
+ * Extracts the ID from a model ID
31
+ *
32
+ * @param modelId Model ID to be processed, eg. `"prescriptor-67fb86d3-9047-4ce0-0d42-4e3d3b0f715e-83_28"`
33
+ * @param modelType Type of model -- `"prescriptor"` or `"rio"`
34
+ * @returns Model ID with the last hyphenated item removed (eg. `"67fb86d3-9047-4ce0-0d42-4e3d3b0f715e"`)
35
+
36
+ * @example
37
+ * ```
38
+ * removeLast("prescriptor-67fb86d3-9047-4ce0-0d42-4e3d3b0f715e-83_28", "prescriptor")
39
+ * = "67fb86d3-9047-4ce0-0d42-4e3d3b0f715e"
40
+ * ```
41
+ */
42
+ export function extractId(modelId, modelType) {
43
+ if (!modelId || !modelType || !modelId.includes(modelType)) {
44
+ return "";
45
+ }
46
+ // conflicts with ESLint newline-per-chained-call rule
47
+ // prettier-ignore
48
+ return modelId.substring(`${modelType}-`.length) // remove the model type
49
+ .split("-") // split by hyphens
50
+ .slice(0, -1) // remove the last element
51
+ .join("-"); // join with hyphens
52
+ }
53
+ /**
54
+ * Hashes a string using MD5. For example: for generating keys for React nodes from a longer string identifer.
55
+ *
56
+ * @param input String to be hashed
57
+ * @returns Hashed string
58
+ */
59
+ export const hashString = (input) => {
60
+ // prettier-ignore
61
+ return createHash("md5")
62
+ .update(input)
63
+ .digest("hex");
64
+ };
@@ -0,0 +1 @@
1
+ export declare function getTitleBase(): string;
@@ -0,0 +1,20 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ // Miscellaneous utilities for dealing with browser tab title
17
+ export function getTitleBase() {
18
+ const subdomain = window.location.host.split(".")[0];
19
+ return `${subdomain[0].toUpperCase()}${subdomain.substring(1)}`;
20
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Types for userInfo API
3
+ */
4
+ /**
5
+ * The OIDC provider types we know about
6
+ */
7
+ export type OidcProvider = "Github" | "AD" | "NextAuth" | "None";
8
+ /**
9
+ * Response from the userInfo API
10
+ */
11
+ export type UserInfoResponse = {
12
+ readonly username?: string;
13
+ readonly picture?: string;
14
+ readonly oidcHeaderFound: boolean;
15
+ readonly oidcHeaderValid?: boolean;
16
+ readonly oidcProvider?: OidcProvider;
17
+ };
@@ -0,0 +1,16 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ export {};
@@ -0,0 +1 @@
1
+ export declare function useLocalStorage(key: string, initialValue: unknown): any[];
@@ -0,0 +1,55 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { useState } from "react";
17
+ export function useLocalStorage(key, initialValue) {
18
+ // State to store our value
19
+ // Pass initial state function to useState so logic is only executed once
20
+ const [storedValue, setStoredValue] = useState(() => {
21
+ if (typeof window === "undefined") {
22
+ return initialValue;
23
+ }
24
+ try {
25
+ // Get from local storage by key
26
+ const item = window.localStorage.getItem(key);
27
+ // Parse stored json or if none return initialValue
28
+ return item ? JSON.parse(item) : initialValue;
29
+ }
30
+ catch (error) {
31
+ // If error also return initialValue
32
+ console.error(error);
33
+ return initialValue;
34
+ }
35
+ });
36
+ // Return a wrapped version of useState's setter function that ...
37
+ // ... persists the new value to localStorage.
38
+ const setValue = (value) => {
39
+ try {
40
+ // Allow value to be a function so we have same API as useState
41
+ const valueToStore = typeof value === "function" ? value(storedValue) : value;
42
+ // Save state
43
+ setStoredValue(valueToStore);
44
+ // Save to local storage
45
+ if (typeof window !== "undefined") {
46
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
47
+ }
48
+ }
49
+ catch (error) {
50
+ // A more advanced implementation would handle the error case
51
+ console.error(error);
52
+ }
53
+ };
54
+ return [storedValue, setValue];
55
+ }
@@ -0,0 +1,2 @@
1
+ import { Theme } from "@mui/material";
2
+ export declare const getZIndex: (layer: number, appTheme: Theme) => number;
@@ -0,0 +1,29 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ const DEFAULT_Z_INDEX = 500;
17
+ export const getZIndex = (layer, appTheme) => {
18
+ switch (layer) {
19
+ case 1:
20
+ return DEFAULT_Z_INDEX;
21
+ case 2:
22
+ // MUI Drawer has a default z-index of 1200 and at least one of elements utilizing LAYER_2 is in
23
+ // an MUI Drawer, however, we also want to ensure that LAYER_2 is below the modal, which currently has a
24
+ // default z-index of 1300.
25
+ return (appTheme.zIndex.modal + appTheme.zIndex.drawer) / 2;
26
+ default:
27
+ return DEFAULT_Z_INDEX;
28
+ }
29
+ };
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@cognizant-ai-lab/ui-common",
3
+ "version": "1.3.3",
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "yarn clean && yarn generate && tsc --project tsconfig.build.json && fix-esm-import-path dist > /dev/null",
7
+ "clean": "rm -rf dist generated",
8
+ "generate": "rm -rf generated && ./build_scripts/do_openapi_generate.sh"
9
+ },
10
+ "dependencies": {
11
+ "@langchain/core": "0.2.36",
12
+ "dagre": "0.8.5",
13
+ "http-status": "1.7.3",
14
+ "jsonrepair": "3.8.0",
15
+ "lodash-es": "4.17.21",
16
+ "next": "15.4.6",
17
+ "next-auth": "5.0.0-beta.20",
18
+ "notistack": "3.0.1",
19
+ "react-dom": "18.2.0",
20
+ "react-markdown": "9.0.1",
21
+ "react-syntax-highlighter": "15.5.0",
22
+ "reactflow": "11.10.2",
23
+ "rehype-raw": "7.0.0",
24
+ "rehype-slug": "6.0.0",
25
+ "zustand": "4.4.7"
26
+ },
27
+ "devDependencies": {
28
+ "@babel/core": "7.23.7",
29
+ "@babel/preset-env": "7.28.3",
30
+ "@types/dagre": "0.7.53",
31
+ "@types/lodash-es": "4.17.12",
32
+ "@types/node": "20.11.5",
33
+ "@types/react": "18.2.0",
34
+ "@types/react-dom": "18.2.0",
35
+ "@types/react-syntax-highlighter": "15.5.13",
36
+ "babel-jest": "30.0.5",
37
+ "fix-esm-import-path": "1.10.3",
38
+ "globals": "16.3.0",
39
+ "openapi-typescript": "7.8.0"
40
+ },
41
+ "peerDependencies": {
42
+ "@emotion/react": "^11.13.3",
43
+ "@emotion/styled": "^11.13.0",
44
+ "@mui/icons-material": "^7.3.1",
45
+ "@mui/material": "^7.3.1",
46
+ "react": "^18.2.0",
47
+ "react-dom": "^18.2.0",
48
+ "typescript": "^5.9.2"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/cognizant-ai-lab/neuro-san-ui.git"
53
+ },
54
+ "publishConfig": {
55
+ "registry": "https://npm.pkg.github.com/",
56
+ "repository": "https://github.com/cognizant-ai-lab/neuro-san-ui"
57
+ },
58
+ "types": "dist/index.d.ts",
59
+ "exports": {
60
+ ".": {
61
+ "import": "./dist/index.js",
62
+ "types": "./dist/index.d.ts"
63
+ },
64
+ "./const": "./const.ts"
65
+ },
66
+ "files": [
67
+ "dist"
68
+ ]
69
+ }