synapse-react-client 4.0.30 → 4.0.31
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/SWC.index.d.ts +4 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +2 -1
- package/dist/SWC.index.js.map +1 -1
- package/dist/assets/illustrations/curie_avatar.svg +52 -0
- package/dist/assets/illustrations/curie_avatar_head.js +91 -0
- package/dist/assets/illustrations/curie_avatar_head.js.map +1 -0
- package/dist/assets/illustrations/curie_avatar_head.svg +21 -0
- package/dist/assets/illustrations/discussions_illustration2.js +96 -0
- package/dist/assets/illustrations/discussions_illustration2.js.map +1 -0
- package/dist/assets/illustrations/discussions_illustration2.svg +17 -0
- package/dist/assets/illustrations/index.d.ts +3 -0
- package/dist/assets/illustrations/index.d.ts.map +1 -1
- package/dist/assets/illustrations/index.js +34 -32
- package/dist/assets/illustrations/index.js.map +1 -1
- package/dist/assets/mui_components/CurieAvatarHead.d.ts +5 -0
- package/dist/assets/mui_components/CurieAvatarHead.d.ts.map +1 -0
- package/dist/assets/mui_components/CurieAvatarHead.js +17 -0
- package/dist/assets/mui_components/CurieAvatarHead.js.map +1 -0
- package/dist/assets/themed_icons/Model.d.ts +3 -0
- package/dist/assets/themed_icons/Model.d.ts.map +1 -0
- package/dist/assets/themed_icons/Model.js +31 -0
- package/dist/assets/themed_icons/Model.js.map +1 -0
- package/dist/assets/themed_icons/index.d.ts +2 -1
- package/dist/assets/themed_icons/index.d.ts.map +1 -1
- package/dist/assets/themed_icons/index.js +19 -18
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.d.ts.map +1 -1
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js +49 -39
- package/dist/components/ChallengeDataDownload/ChallengeDataDownload.js.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +46 -45
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/utils/DataGridUtils.js +1 -1
- package/dist/components/DataGrid/utils/DataGridUtils.js.map +1 -1
- package/dist/components/EntityFinder/EntityFinder.js +127 -127
- package/dist/components/EntityFinder/EntityFinder.js.map +1 -1
- package/dist/components/EntityFinder/details/view/DetailsView.js +53 -53
- package/dist/components/EntitySidebar/EntitySidebar.css +1 -1
- package/dist/components/EntitySidebar/EntitySidebar.module.js +11 -11
- package/dist/components/EntitySidebar/EntitySidebar.module.js.map +1 -1
- package/dist/components/EntitySidebar/EntitySidebar.module.scss +2 -2
- package/dist/components/EntityTreeTable/EntityTreeTable.d.ts +7 -0
- package/dist/components/EntityTreeTable/EntityTreeTable.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/EntityTreeTable.js +24 -20
- package/dist/components/EntityTreeTable/EntityTreeTable.js.map +1 -1
- package/dist/components/EntityTreeTable/components/CheckboxCell.d.ts +4 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.d.ts.map +1 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.js +43 -0
- package/dist/components/EntityTreeTable/components/CheckboxCell.js.map +1 -0
- package/dist/components/EntityTreeTable/components/EntityNameCell.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityNameCell.js +10 -9
- package/dist/components/EntityTreeTable/components/EntityNameCell.js.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.d.ts +6 -0
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/components/EntityTreeTableContext.js.map +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.d.ts +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.d.ts.map +1 -1
- package/dist/components/EntityTreeTable/hooks/useTableColumns.js +49 -39
- package/dist/components/EntityTreeTable/hooks/useTableColumns.js.map +1 -1
- package/dist/components/EntityUpload/EntityUpload.js +6 -6
- package/dist/components/Forum/DiscussionEmpty.css +1 -0
- package/dist/components/Forum/DiscussionEmpty.d.ts +6 -0
- package/dist/components/Forum/DiscussionEmpty.d.ts.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.js +30 -0
- package/dist/components/Forum/DiscussionEmpty.js.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.module.js +10 -0
- package/dist/components/Forum/DiscussionEmpty.module.js.map +1 -0
- package/dist/components/Forum/DiscussionEmpty.module.scss +37 -0
- package/dist/components/Icon/Icon.d.ts.map +1 -1
- package/dist/components/Icon/Icon.js +82 -80
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.d.ts.map +1 -1
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js +39 -41
- package/dist/components/ProvenanceGraph/ProvenanceGraph.js.map +1 -1
- package/dist/components/SynapseChat/AccessLevelMenu.d.ts.map +1 -1
- package/dist/components/SynapseChat/AccessLevelMenu.js +1 -0
- package/dist/components/SynapseChat/AccessLevelMenu.js.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/GridAgentChat.js +34 -25
- package/dist/components/SynapseChat/GridAgentChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.d.ts +10 -12
- package/dist/components/SynapseChat/SynapseChat.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChat.js +106 -103
- package/dist/components/SynapseChat/SynapseChat.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.css +1 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.d.ts +22 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.js +123 -94
- package/dist/components/SynapseChat/SynapseChatInteraction.js.map +1 -1
- package/dist/components/SynapseChat/SynapseChatInteraction.module.js +8 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.module.js.map +1 -0
- package/dist/components/SynapseChat/SynapseChatInteraction.module.scss +25 -0
- package/dist/components/SynapseChat/SynapseChatMessage.d.ts +16 -1
- package/dist/components/SynapseChat/SynapseChatMessage.d.ts.map +1 -1
- package/dist/components/SynapseChat/SynapseChatMessage.js +25 -11
- package/dist/components/SynapseChat/SynapseChatMessage.js.map +1 -1
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.d.ts +27 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.js +79 -0
- package/dist/components/SynapseChat/components/AddFilesDialog/AddFilesDialog.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.css +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.d.ts +33 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.js +77 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.js +8 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.js.map +1 -0
- package/dist/components/SynapseChat/components/AttachmentChip/AttachmentChip.module.scss +16 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.css +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.d.ts +23 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.js +24 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.js +9 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatAttachmentStrip/ChatAttachmentStrip.module.scss +19 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.css +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.d.ts +22 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.d.ts.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js +80 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.js +9 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.js.map +1 -0
- package/dist/components/SynapseChat/components/ChatInputArea/ChatInputArea.module.scss +39 -0
- package/dist/components/SynapseChat/useChatState.d.ts +12 -4
- package/dist/components/SynapseChat/useChatState.d.ts.map +1 -1
- package/dist/components/SynapseChat/useChatState.js +38 -20
- package/dist/components/SynapseChat/useChatState.js.map +1 -1
- package/dist/components/SynapseChat/utils/constants.d.ts +8 -0
- package/dist/components/SynapseChat/utils/constants.d.ts.map +1 -0
- package/dist/components/SynapseChat/utils/constants.js +12 -0
- package/dist/components/SynapseChat/utils/constants.js.map +1 -0
- package/dist/components/SynapseChat/utils/types.d.ts +13 -0
- package/dist/components/SynapseChat/utils/types.d.ts.map +1 -0
- package/dist/components/SynapseChat/utils/types.js +0 -0
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +101 -101
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts +1 -0
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +8 -0
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js.map +1 -1
- package/dist/components/file/upload/BasicFileHandleUpload.d.ts +35 -4
- package/dist/components/file/upload/BasicFileHandleUpload.d.ts.map +1 -1
- package/dist/components/file/upload/BasicFileHandleUpload.js +22 -16
- package/dist/components/file/upload/BasicFileHandleUpload.js.map +1 -1
- package/dist/components/file/upload/MultiFileUploadProgress.js +6 -6
- package/dist/components/file/upload/UploadFilePanel.d.ts +32 -0
- package/dist/components/file/upload/UploadFilePanel.d.ts.map +1 -1
- package/dist/components/file/upload/UploadFilePanel.js +58 -42
- package/dist/components/file/upload/UploadFilePanel.js.map +1 -1
- package/dist/components/file/upload/validateFileSelection.d.ts +25 -0
- package/dist/components/file/upload/validateFileSelection.d.ts.map +1 -0
- package/dist/components/file/upload/validateFileSelection.js +18 -0
- package/dist/components/file/upload/validateFileSelection.js.map +1 -0
- package/dist/components/menu/DropdownMenu.d.ts +3 -0
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +108 -83
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.css +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.js +13 -13
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.js.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCard.module.scss +2 -1
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.d.ts.map +1 -1
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js +35 -27
- package/dist/features/curator/dashboard/components/CurationTaskCardLayout.js.map +1 -1
- package/dist/mocks/chat/mockChat.d.ts +13 -1
- package/dist/mocks/chat/mockChat.d.ts.map +1 -1
- package/dist/mocks/chat/mockChat.js +34 -9
- package/dist/mocks/chat/mockChat.js.map +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.d.ts +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/chatHandlers.js +21 -7
- package/dist/mocks/msw/handlers/chatHandlers.js.map +1 -1
- package/dist/synapse-client/SynapseClient.d.ts +2 -2
- package/dist/synapse-client/SynapseClient.d.ts.map +1 -1
- package/dist/synapse-client/SynapseClient.js.map +1 -1
- package/dist/synapse-queries/KeyFactory.d.ts +10 -1
- package/dist/synapse-queries/KeyFactory.d.ts.map +1 -1
- package/dist/synapse-queries/KeyFactory.js +29 -2
- package/dist/synapse-queries/KeyFactory.js.map +1 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.d.ts +2 -2
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.d.ts.map +1 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.js +2 -1
- package/dist/synapse-queries/asynchronous/usePollAsynchronousJob.js.map +1 -1
- package/dist/synapse-queries/chat/useChat.d.ts +3 -2
- package/dist/synapse-queries/chat/useChat.d.ts.map +1 -1
- package/dist/synapse-queries/chat/useChat.js +7 -6
- package/dist/synapse-queries/chat/useChat.js.map +1 -1
- package/dist/synapse-queries/dataaccess/index.d.ts +1 -0
- package/dist/synapse-queries/dataaccess/index.d.ts.map +1 -1
- package/dist/synapse-queries/dataaccess/index.js +4 -3
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts +44 -0
- package/dist/synapse-queries/dataaccess/useEDuc.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useEDuc.js +75 -0
- package/dist/synapse-queries/dataaccess/useEDuc.js.map +1 -0
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.d.ts.map +1 -1
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.js +1 -1
- package/dist/synapse-queries/featureflags/useGetFeatureFlag.js.map +1 -1
- package/dist/synapse-queries/file/useDirectUploadToS3.js +6 -6
- package/dist/synapse-queries/index.js +181 -172
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/SynapseConstants.d.ts +2 -0
- package/dist/utils/SynapseConstants.d.ts.map +1 -1
- package/dist/utils/SynapseConstants.js +122 -120
- package/dist/utils/SynapseConstants.js.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts +3 -1
- package/dist/utils/featureflag/FeatureFlags.d.ts.map +1 -1
- package/dist/utils/featureflag/FeatureFlags.js +1 -1
- package/dist/utils/featureflag/FeatureFlags.js.map +1 -1
- package/dist/utils/hooks/useUploadFileEntity/useUploadFileEntities.js +5 -5
- package/dist/utils/hooks/useUploadFileEntity/useUploadFiles.js +14 -14
- package/package.json +4 -4
|
@@ -1,56 +1,72 @@
|
|
|
1
1
|
import { displayToast as e } from "../ToastMessage/ToastMessage.js";
|
|
2
2
|
import { useSynapseContext as t } from "../../utils/context/SynapseContext.js";
|
|
3
|
+
import { useApplicationSessionContext as n } from "../../utils/AppUtils/session/ApplicationSessionContext.js";
|
|
3
4
|
import "../ToastMessage/index.js";
|
|
5
|
+
import "../../utils/AppUtils/index.js";
|
|
4
6
|
import "../../utils/index.js";
|
|
5
|
-
import { SkeletonParagraph as
|
|
7
|
+
import { SkeletonParagraph as r } from "../Skeleton/SkeletonParagraph.js";
|
|
6
8
|
import "../Skeleton/index.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
9
|
+
import { UserCard as i } from "../UserCard/UserCard.js";
|
|
10
|
+
import { useCreateAgentSession as a, useUpdateAgentSession as o } from "../../synapse-queries/chat/useChat.js";
|
|
11
|
+
import { useChatState as ee } from "./useChatState.js";
|
|
12
|
+
import { AccessLevelMenu as s } from "./AccessLevelMenu.js";
|
|
13
|
+
import { ChatInputArea as c } from "./components/ChatInputArea/ChatInputArea.js";
|
|
14
|
+
import l from "./SynapseChatMessage.js";
|
|
15
|
+
import { useEffect as u, useRef as d, useState as f } from "react";
|
|
16
|
+
import { Alert as te, Box as p, Chip as m, List as h, Stack as ne, Typography as g } from "@mui/material";
|
|
17
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
18
|
+
import { AgentAccessLevel as y } from "@sage-bionetworks/synapse-types";
|
|
19
|
+
import { FileHandleAssociateType as b } from "@sage-bionetworks/synapse-client";
|
|
20
|
+
import { SmartToyTwoTone as x } from "@mui/icons-material";
|
|
17
21
|
//#region src/components/SynapseChat/SynapseChat.tsx
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
var S = /* @__PURE__ */ _(p, {
|
|
23
|
+
sx: {
|
|
24
|
+
p: "3px",
|
|
25
|
+
borderRadius: "50%",
|
|
26
|
+
borderStyle: "solid",
|
|
27
|
+
borderWidth: "1px",
|
|
28
|
+
borderColor: "grey.300",
|
|
29
|
+
mt: "10px",
|
|
30
|
+
height: "31px"
|
|
31
|
+
},
|
|
32
|
+
children: /* @__PURE__ */ _(x, { sx: { color: "secondary.main" } })
|
|
33
|
+
});
|
|
34
|
+
function C({ initialMessage: x, agentRegistrationId: C, chatbotName: w = "SynapseChat", agentAvatar: re = S, hideTitle: T = !1, textboxPositionOffset: E = "0px", sessionContext: D, externalSession: O, setExternalSession: k, externalChatState: A, showAccessLevelMenu: j = !0, onChatResponse: M, suggestedPrompts: N, allowAttachments: P = !1 }) {
|
|
35
|
+
let { accessToken: F } = t(), { userId: I } = n(), L = /* @__PURE__ */ _(i, {
|
|
36
|
+
ownerId: I,
|
|
37
|
+
size: "AVATAR",
|
|
38
|
+
avatarSize: "MEDIUM"
|
|
39
|
+
}), [R, z] = f(), B = O ?? R, V = k ?? z, { mutate: H, error: U } = a({ onSuccess: (e) => V(e) }), { mutate: W } = o({
|
|
40
|
+
onSuccess: (e) => V(e),
|
|
21
41
|
onError: (t) => e(`Unable to update the agent session: ${t.message}`, "danger")
|
|
22
|
-
}),
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
42
|
+
}), [G, K] = f(D ? y.WRITE_YOUR_PRIVATE_DATA : y.PUBLICLY_ACCESSIBLE), q = ee(B, M), { interactions: J, isAwaitingResponse: Y, sendChat: X } = A ?? q, Z = d(void 0);
|
|
43
|
+
Z.current === void 0 && (Z.current = new Set(J.map((e) => e.id)));
|
|
44
|
+
let ie = Z.current, [ae, Q] = f(""), [$, oe] = f(!1), [se, ce] = f([]);
|
|
45
|
+
return u(() => {
|
|
46
|
+
H && !B && H({
|
|
47
|
+
agentAccessLevel: G,
|
|
26
48
|
agentRegistrationId: C,
|
|
27
|
-
sessionContext:
|
|
49
|
+
sessionContext: D
|
|
28
50
|
});
|
|
29
51
|
}, [
|
|
30
|
-
|
|
52
|
+
H,
|
|
53
|
+
B,
|
|
31
54
|
F,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
V,
|
|
55
|
+
D,
|
|
56
|
+
G,
|
|
35
57
|
C
|
|
36
|
-
]),
|
|
37
|
-
|
|
58
|
+
]), u(() => {
|
|
59
|
+
B && x && !$ && (X(x), oe(!0));
|
|
38
60
|
}, [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
])
|
|
44
|
-
let Z = () => {
|
|
45
|
-
q.trim() && (K(q.trim()), J(""));
|
|
46
|
-
}, Q = !F || !q || !!W, ie = (e) => {
|
|
47
|
-
!Q && e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Z());
|
|
48
|
-
}, $ = B.palette.secondary[300];
|
|
49
|
-
return R ? /* @__PURE__ */ v(u, {
|
|
61
|
+
B,
|
|
62
|
+
x,
|
|
63
|
+
$,
|
|
64
|
+
X
|
|
65
|
+
]), U ? /* @__PURE__ */ _(te, {
|
|
50
66
|
severity: "error",
|
|
51
67
|
sx: { my: 2 },
|
|
52
|
-
children:
|
|
53
|
-
}) : /* @__PURE__ */
|
|
68
|
+
children: U.reason
|
|
69
|
+
}) : /* @__PURE__ */ v(p, {
|
|
54
70
|
sx: {
|
|
55
71
|
display: "flex",
|
|
56
72
|
flexDirection: "column",
|
|
@@ -60,7 +76,7 @@ function S({ initialMessage: S, agentRegistrationId: C, chatbotName: w = "Synaps
|
|
|
60
76
|
height: "100%"
|
|
61
77
|
},
|
|
62
78
|
children: [
|
|
63
|
-
!
|
|
79
|
+
!T && /* @__PURE__ */ _(g, {
|
|
64
80
|
variant: "headline1",
|
|
65
81
|
sx: {
|
|
66
82
|
p: "20px",
|
|
@@ -73,23 +89,23 @@ function S({ initialMessage: S, agentRegistrationId: C, chatbotName: w = "Synaps
|
|
|
73
89
|
},
|
|
74
90
|
children: w
|
|
75
91
|
}),
|
|
76
|
-
|
|
77
|
-
initAccessLevel:
|
|
92
|
+
j && /* @__PURE__ */ _(s, {
|
|
93
|
+
initAccessLevel: G,
|
|
78
94
|
onChange: (e) => {
|
|
79
|
-
|
|
95
|
+
K(e), W({
|
|
80
96
|
agentAccessLevel: e,
|
|
81
|
-
sessionId:
|
|
97
|
+
sessionId: B.sessionId
|
|
82
98
|
});
|
|
83
99
|
}
|
|
84
100
|
}),
|
|
85
|
-
!
|
|
86
|
-
|
|
101
|
+
!B && /* @__PURE__ */ _(r, { numRows: 10 }),
|
|
102
|
+
B && /* @__PURE__ */ _(p, {
|
|
87
103
|
sx: {
|
|
88
104
|
flexGrow: 1,
|
|
89
105
|
overflowY: "auto",
|
|
90
106
|
mb: 2
|
|
91
107
|
},
|
|
92
|
-
children: /* @__PURE__ */
|
|
108
|
+
children: /* @__PURE__ */ _(h, {
|
|
93
109
|
sx: {
|
|
94
110
|
flex: 1,
|
|
95
111
|
overflowY: "auto",
|
|
@@ -97,25 +113,29 @@ function S({ initialMessage: S, agentRegistrationId: C, chatbotName: w = "Synaps
|
|
|
97
113
|
display: "flex",
|
|
98
114
|
flexDirection: "column"
|
|
99
115
|
},
|
|
100
|
-
children:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
116
|
+
children: J.map((e, t) => {
|
|
117
|
+
let n = t === J.length - 1, r = e.jobId == null;
|
|
118
|
+
return /* @__PURE__ */ _(l, {
|
|
119
|
+
agentAvatar: re,
|
|
120
|
+
userAvatar: L,
|
|
121
|
+
userMessage: e.userMessage,
|
|
122
|
+
chatJobId: e.jobId,
|
|
123
|
+
onSendChat: X,
|
|
124
|
+
scrollIntoView: n,
|
|
125
|
+
animateEntry: !ie.has(e.id),
|
|
126
|
+
isAwaitingResponse: Y,
|
|
127
|
+
pendingAttachments: r ? se : void 0
|
|
128
|
+
}, e.id);
|
|
129
|
+
})
|
|
110
130
|
})
|
|
111
131
|
}),
|
|
112
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ v(p, {
|
|
113
133
|
sx: {
|
|
114
134
|
position: "sticky",
|
|
115
|
-
bottom:
|
|
135
|
+
bottom: E,
|
|
116
136
|
backgroundColor: "white"
|
|
117
137
|
},
|
|
118
|
-
children: [
|
|
138
|
+
children: [N && N.length > 0 && J.length === 0 && /* @__PURE__ */ _(ne, {
|
|
119
139
|
direction: "row",
|
|
120
140
|
spacing: 1,
|
|
121
141
|
sx: {
|
|
@@ -123,60 +143,43 @@ function S({ initialMessage: S, agentRegistrationId: C, chatbotName: w = "Synaps
|
|
|
123
143
|
flexWrap: "wrap",
|
|
124
144
|
gap: 1
|
|
125
145
|
},
|
|
126
|
-
children:
|
|
146
|
+
children: N.map((e) => /* @__PURE__ */ _(m, {
|
|
127
147
|
label: e,
|
|
128
148
|
variant: "outlined",
|
|
129
|
-
onClick: () =>
|
|
130
|
-
disabled: !
|
|
149
|
+
onClick: () => Q(e),
|
|
150
|
+
disabled: !B,
|
|
131
151
|
sx: { cursor: "pointer" }
|
|
132
152
|
}, e))
|
|
133
|
-
}), /* @__PURE__ */
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
children: [/* @__PURE__ */ v(g, {
|
|
145
|
-
fullWidth: !0,
|
|
146
|
-
value: q,
|
|
147
|
-
onChange: (e) => J(e.target.value),
|
|
148
|
-
onKeyDown: ie,
|
|
149
|
-
placeholder: `Message ${w}`,
|
|
150
|
-
slotProps: { input: {
|
|
151
|
-
sx: { borderRadius: 96.6 },
|
|
152
|
-
endAdornment: /* @__PURE__ */ v(p, {
|
|
153
|
-
disabled: Q,
|
|
154
|
-
onClick: Z,
|
|
155
|
-
sx: {
|
|
156
|
-
ml: "7px",
|
|
157
|
-
mr: "-8px",
|
|
158
|
-
color: $,
|
|
159
|
-
borderStyle: "solid",
|
|
160
|
-
borderWidth: Q ? "1px" : "2px",
|
|
161
|
-
borderColor: Q ? "gray" : $
|
|
162
|
-
},
|
|
163
|
-
children: /* @__PURE__ */ v(x, {})
|
|
164
|
-
})
|
|
165
|
-
} }
|
|
166
|
-
}), /* @__PURE__ */ y(_, {
|
|
167
|
-
variant: "smallText1",
|
|
168
|
-
sx: {
|
|
169
|
-
pt: "8px",
|
|
170
|
-
textAlign: "center"
|
|
153
|
+
}), /* @__PURE__ */ _(p, {
|
|
154
|
+
sx: { mt: "5px" },
|
|
155
|
+
children: /* @__PURE__ */ _(c, {
|
|
156
|
+
value: ae,
|
|
157
|
+
onValueChange: Q,
|
|
158
|
+
onSend: (e, t) => {
|
|
159
|
+
X(e, t.length ? t.map((e) => ({
|
|
160
|
+
fileHandleId: e.fileHandleId,
|
|
161
|
+
associateObjectId: e.fileHandleId,
|
|
162
|
+
associateObjectType: b.MessageAttachment
|
|
163
|
+
})) : void 0), Q(""), ce(t);
|
|
171
164
|
},
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
placeholder: `Message ${w}`,
|
|
166
|
+
disabled: !B || Y,
|
|
167
|
+
allowAttachments: P
|
|
168
|
+
})
|
|
174
169
|
})]
|
|
170
|
+
}),
|
|
171
|
+
/* @__PURE__ */ v(g, {
|
|
172
|
+
variant: "smallText1",
|
|
173
|
+
sx: {
|
|
174
|
+
pt: "8px",
|
|
175
|
+
textAlign: "center"
|
|
176
|
+
},
|
|
177
|
+
children: [w, " can make mistakes."]
|
|
175
178
|
})
|
|
176
179
|
]
|
|
177
180
|
});
|
|
178
181
|
}
|
|
179
182
|
//#endregion
|
|
180
|
-
export {
|
|
183
|
+
export { C as SynapseChat, C as default };
|
|
181
184
|
|
|
182
185
|
//# sourceMappingURL=SynapseChat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport { ArrowUpward } from '@mui/icons-material'\nimport {\n Alert,\n Box,\n Chip,\n IconButton,\n List,\n Stack,\n TextField,\n Typography,\n useTheme,\n} from '@mui/material'\nimport { Color } from '@mui/material/styles'\nimport { GridAgentSessionContext } from '@sage-bionetworks/synapse-client'\nimport {\n AgentAccessLevel,\n AgentSession,\n TraceEvent,\n} from '@sage-bionetworks/synapse-types'\nimport { KeyboardEventHandler, useEffect, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport SynapseChatInteraction from './SynapseChatInteraction'\nimport SynapseChatMessage from './SynapseChatMessage'\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n}\n\nexport type ChatInteraction = {\n userMessage: string\n chatResponseText?: string\n chatErrorReason?: string\n chatResponseTrace?: TraceEventWithFriendlyMessage[]\n}\n\nexport type TraceEventWithFriendlyMessage = {\n friendlyMessage?: string\n} & TraceEvent\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n}: SynapseChatProps) {\n const { accessToken } = useSynapseContext()\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const theme = useTheme()\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { pendingMessage, chatJobIds, sendChat } = chatState\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSendMessage = () => {\n if (userChatTextfieldValue.trim()) {\n sendChat(userChatTextfieldValue.trim())\n setUserChatTextfieldValue('')\n }\n }\n\n const isDisabled =\n !agentSession || !userChatTextfieldValue || !!pendingMessage\n\n const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = event => {\n if (!isDisabled && event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n handleSendMessage()\n }\n }\n\n const sendMessageButtonColor = (\n theme.palette.secondary as unknown as Color\n )[300]\n if (createAgentSessionError) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box sx={{ flexGrow: 1, overflowY: 'auto', mb: 2 }}>\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {chatJobIds.map(jobId => {\n return (\n <SynapseChatMessage\n key={jobId}\n chatJobId={jobId}\n onSendChat={sendChat}\n />\n )\n })}\n {pendingMessage && (\n <SynapseChatInteraction\n userMessage={pendingMessage}\n chatResponseText={''}\n chatErrorReason={''}\n scrollIntoView\n onSendChat={sendChat}\n />\n )}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n chatJobIds.length === 0 &&\n !pendingMessage && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box\n component=\"form\"\n sx={{\n pt: '8px',\n mt: '5px',\n pb: '10px',\n position: 'sticky',\n borderTop: '1px solid',\n borderColor: 'grey.400',\n }}\n onSubmit={handleSendMessage}\n >\n <TextField\n fullWidth\n value={userChatTextfieldValue}\n onChange={e => setUserChatTextfieldValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={`Message ${chatbotName}`}\n slotProps={{\n input: {\n sx: { borderRadius: 96.6 },\n endAdornment: (\n <IconButton\n disabled={isDisabled}\n onClick={handleSendMessage}\n sx={{\n ml: '7px',\n mr: '-8px',\n color: sendMessageButtonColor,\n borderStyle: 'solid',\n borderWidth: isDisabled ? '1px' : '2px',\n borderColor: isDisabled ? 'gray' : sendMessageButtonColor,\n }}\n >\n <ArrowUpward />\n </IconButton>\n ),\n },\n }}\n />\n <Typography\n variant=\"smallText1\"\n sx={{ pt: '8px', textAlign: 'center' }}\n >\n {chatbotName} can make mistakes.\n </Typography>\n </Box>\n </Box>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SynapseChat.js","names":[],"sources":["../../../src/components/SynapseChat/SynapseChat.tsx"],"sourcesContent":["import { ChatState, useChatState } from '@/components/SynapseChat/useChatState'\nimport {\n useCreateAgentSession,\n useUpdateAgentSession,\n} from '@/synapse-queries/chat/useChat'\nimport { useSynapseContext } from '@/utils'\nimport { Alert, Box, Chip, List, Stack, Typography } from '@mui/material'\nimport {\n AgentSession,\n FileHandleAssociateType,\n GridAgentSessionContext,\n} from '@sage-bionetworks/synapse-client'\nimport { AgentAccessLevel } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useRef, useState } from 'react'\nimport { SkeletonParagraph } from '../Skeleton'\nimport { displayToast } from '../ToastMessage'\nimport AccessLevelMenu from './AccessLevelMenu'\nimport { ChatAttachment } from './utils/types'\nimport { ChatInputArea } from './components/ChatInputArea/ChatInputArea'\nimport SynapseChatMessage from './SynapseChatMessage'\nimport { SmartToyTwoTone } from '@mui/icons-material'\nimport { UserCard } from '../UserCard/UserCard'\nimport { useApplicationSessionContext } from '@/utils/AppUtils'\n\nconst DEFAULT_AVATAR = (\n <Box\n sx={{\n p: '3px',\n borderRadius: '50%',\n borderStyle: 'solid',\n borderWidth: '1px',\n borderColor: 'grey.300',\n mt: '10px',\n height: '31px',\n }}\n >\n <SmartToyTwoTone sx={{ color: 'secondary.main' }} />\n </Box>\n)\n\nexport type SynapseChatProps = {\n initialMessage?: string //optional initial message\n agentRegistrationId?: string // if provided, use this agent\n chatbotName?: string // optional name of this chatbot agent\n hideTitle?: boolean\n textboxPositionOffset?: string // when embedded in a form, the textbox (form) stuck to the bottom may need to be offset due to container padding (dialog content for example!)\n /* optional session context for the agent session */\n sessionContext?: GridAgentSessionContext\n /* The current session, if state is lifted out of this component */\n externalSession?: AgentSession\n /* A callback invoked to bootstrap the current session, if state is to be lifted out of this component */\n setExternalSession?: (s: AgentSession | undefined) => void\n /* The current chat history, if state is lifted out of this component */\n externalChatState?: ChatState\n // default access level for the agent session.\n defaultAgentAccessLevel?: AgentAccessLevel\n // Whether to show the access level menu for the agent session.\n showAccessLevelMenu?: boolean\n /**\n * Optional callback invoked once when a chat response is received from the server.\n * Use this for side effects such as navigation based on the response content.\n * Called in the mutation onSuccess handler so it runs exactly once per response.\n */\n onChatResponse?: (responseText: string) => void\n /** Optional list of prompt suggestions shown as clickable pills above the text input */\n suggestedPrompts?: string[]\n /** Optional custom avatar for the chatbot agent */\n agentAvatar?: React.ReactNode\n /**\n * Whether to allow the user to attach local files to their chat message.\n * @default false\n */\n allowAttachments?: boolean\n}\n\nexport function SynapseChat({\n initialMessage,\n agentRegistrationId,\n chatbotName = 'SynapseChat',\n agentAvatar = DEFAULT_AVATAR,\n hideTitle = false,\n textboxPositionOffset = '0px',\n sessionContext,\n externalSession,\n setExternalSession,\n externalChatState,\n showAccessLevelMenu = true,\n onChatResponse,\n suggestedPrompts,\n allowAttachments = false,\n}: SynapseChatProps) {\n const { accessToken } = useSynapseContext()\n const { userId } = useApplicationSessionContext()\n\n const userAvatar = (\n <UserCard ownerId={userId} size=\"AVATAR\" avatarSize=\"MEDIUM\" />\n )\n const [localAgentSession, setLocalAgentSession] = useState<AgentSession>()\n const agentSession = externalSession ?? localAgentSession\n const setAgentSession = setExternalSession ?? setLocalAgentSession\n\n const { mutate: createAgentSession, error: createAgentSessionError } =\n useCreateAgentSession({\n onSuccess: newAgentSession => setAgentSession(newAgentSession),\n })\n\n const { mutate: updateAgentSession } = useUpdateAgentSession({\n onSuccess: updatedAgentSession => setAgentSession(updatedAgentSession),\n onError: err =>\n displayToast(\n `Unable to update the agent session: ${err.message}`,\n 'danger',\n ),\n })\n const [agentAccessLevel, setAgentAccessLevel] = useState<AgentAccessLevel>(\n sessionContext\n ? AgentAccessLevel.WRITE_YOUR_PRIVATE_DATA\n : AgentAccessLevel.PUBLICLY_ACCESSIBLE,\n )\n\n const internalChatState = useChatState(agentSession, onChatResponse)\n const chatState = externalChatState ?? internalChatState\n const { interactions, isAwaitingResponse, sendChat } = chatState\n\n // Only interactions added after this component instance mounted should play the entry\n // animation. Callers may lift state so history survives a `Dialog` closing, but the\n // `Dialog` unmounts its children, so every reopen would otherwise re-animate the whole\n // conversation.\n const presentAtMountRef = useRef<Set<string> | undefined>(undefined)\n if (presentAtMountRef.current === undefined) {\n presentAtMountRef.current = new Set(interactions.map(i => i.id))\n }\n const presentAtMount = presentAtMountRef.current\n\n // Keep track of the text that the user is currently typing into the textfield\n const [userChatTextfieldValue, setUserChatTextfieldValue] = useState('')\n const [initialMessageProcessed, setInitialMessageProcessed] = useState(false)\n\n // A copy of the attachments sent with the optimistic/pending interaction, so it can still show\n // rich (name/type) chips after ChatInputArea has cleared its own attachment state. Once the\n // interaction gains a jobId, SynapseChatMessage renders its attachments from the polled async\n // job's requestBody instead (see below), so this value is simply overwritten on the next send.\n const [lastSentAttachments, setLastSentAttachments] = useState<\n ChatAttachment[]\n >([])\n\n // Restore chat session history, if exists.\n // TODO: currently only a single page is restored. Add support for multiple pages (and detect the user scrolling up to restore the next page of results older)\n // const {\n // data: sessionHistoryInfiniteData,\n // } = //, hasNextPage: hasMoreSessionHistory, fetchNextPage: fetchNextSessionHistoryPage, isLoading: isSessionHistoryLoading } =\n // useGetAgentChatSessionHistoryInfinite(\n // {\n // sessionId: agentSession?.sessionId,\n // },\n // {\n // enabled: !!agentSession,\n // },\n // )\n\n // const sessionHistory = useMemo(\n // () =>\n // sessionHistoryInfiniteData?.pages\n // .flatMap(page => page.page)\n // /* Note: session history is ordered from most recent to least recent in each page, so reverse the order when restoring the chat interface */\n // .reverse() ?? [],\n // [sessionHistoryInfiniteData],\n // )\n\n useEffect(() => {\n // on mount, create a new agent session!\n if (createAgentSession && !agentSession) {\n createAgentSession({\n agentAccessLevel,\n agentRegistrationId,\n sessionContext,\n })\n }\n }, [\n createAgentSession,\n agentSession,\n accessToken,\n sessionContext,\n agentAccessLevel,\n agentRegistrationId,\n ])\n\n useEffect(() => {\n // on mount, resolve the initial message chat interaction (if set)\n if (agentSession && initialMessage && !initialMessageProcessed) {\n sendChat(initialMessage)\n setInitialMessageProcessed(true)\n }\n }, [agentSession, initialMessage, initialMessageProcessed, sendChat])\n\n const handleSend = (message: string, attachments: ChatAttachment[]) => {\n sendChat(\n message,\n attachments.length\n ? attachments.map(attachment => ({\n fileHandleId: attachment.fileHandleId,\n // The backend short-circuits the FileHandleAssociation auth check for a user's own\n // uploaded file handle, so associateObjectId/associateObjectType are effectively\n // unused here. FileHandleAssociateType has no dedicated value for \"the uploader's\n // own bare file handle\", so this stubs associateObjectId to the fileHandleId itself\n // and picks an arbitrary existing enum value.\n associateObjectId: attachment.fileHandleId,\n associateObjectType: FileHandleAssociateType.MessageAttachment,\n }))\n : undefined,\n )\n setUserChatTextfieldValue('')\n setLastSentAttachments(attachments)\n }\n\n if (createAgentSessionError) {\n return (\n <Alert severity={'error'} sx={{ my: 2 }}>\n {createAgentSessionError.reason}\n </Alert>\n )\n }\n\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'space-between',\n maxWidth: '1100px',\n mx: 'auto',\n height: '100%',\n }}\n >\n {!hideTitle && (\n <Typography\n variant=\"headline1\"\n sx={{\n p: '20px',\n borderBottom: '1px solid',\n borderColor: 'grey.300',\n position: 'sticky',\n top: '0px',\n backgroundColor: 'white',\n zIndex: 1,\n }}\n >\n {chatbotName}\n </Typography>\n )}\n {showAccessLevelMenu && (\n <AccessLevelMenu\n initAccessLevel={agentAccessLevel}\n onChange={newAccessLevel => {\n setAgentAccessLevel(newAccessLevel)\n updateAgentSession({\n agentAccessLevel: newAccessLevel,\n sessionId: agentSession!.sessionId!,\n })\n }}\n />\n )}\n {!agentSession && <SkeletonParagraph numRows={10} />}\n {agentSession && (\n <Box sx={{ flexGrow: 1, overflowY: 'auto', mb: 2 }}>\n <List\n sx={{\n flex: 1,\n overflowY: 'auto',\n pt: '20px',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {/* {sessionHistory &&\n sessionHistory.map((interaction, index) => {\n return (\n <SynapseChatInteraction\n key={index}\n userMessage={interaction.usersRequestText}\n chatResponseText={interaction.agentResponseText}\n />\n )\n })} */}\n {interactions.map((interaction, index) => {\n const isLast = index === interactions.length - 1\n // The interaction has no jobId until the async job is registered; until then,\n // show the attachments the user just sent rather than waiting on the polled job.\n const isPending = interaction.jobId == null\n return (\n <SynapseChatMessage\n agentAvatar={agentAvatar}\n userAvatar={userAvatar}\n key={interaction.id}\n userMessage={interaction.userMessage}\n chatJobId={interaction.jobId}\n onSendChat={sendChat}\n scrollIntoView={isLast}\n animateEntry={!presentAtMount.has(interaction.id)}\n isAwaitingResponse={isAwaitingResponse}\n pendingAttachments={\n isPending ? lastSentAttachments : undefined\n }\n />\n )\n })}\n </List>\n </Box>\n )}\n <Box\n sx={{\n position: 'sticky',\n bottom: textboxPositionOffset,\n backgroundColor: 'white',\n }}\n >\n {suggestedPrompts &&\n suggestedPrompts.length > 0 &&\n interactions.length === 0 && (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ pt: '8px', flexWrap: 'wrap', gap: 1 }}\n >\n {suggestedPrompts.map(prompt => (\n <Chip\n key={prompt}\n label={prompt}\n variant=\"outlined\"\n onClick={() => setUserChatTextfieldValue(prompt)}\n disabled={!agentSession}\n sx={{ cursor: 'pointer' }}\n />\n ))}\n </Stack>\n )}\n <Box sx={{ mt: '5px' }}>\n <ChatInputArea\n value={userChatTextfieldValue}\n onValueChange={setUserChatTextfieldValue}\n onSend={handleSend}\n placeholder={`Message ${chatbotName}`}\n disabled={!agentSession || isAwaitingResponse}\n allowAttachments={allowAttachments}\n />\n </Box>\n </Box>\n <Typography variant=\"smallText1\" sx={{ pt: '8px', textAlign: 'center' }}>\n {chatbotName} can make mistakes.\n </Typography>\n </Box>\n )\n}\n\nexport default SynapseChat\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@keyframes _chatInteractionEntry_14na6_1{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}._entryAnimation_14na6_11{animation:.5s cubic-bezier(.2,0,0,1) _chatInteractionEntry_14na6_1}@media (prefers-reduced-motion:reduce){._entryAnimation_14na6_11{animation:none}}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { TraceEvent } from '@sage-bionetworks/synapse-types';
|
|
2
|
+
import { AgentChatAttachmentStatus } from '@sage-bionetworks/synapse-client';
|
|
3
|
+
/**
|
|
4
|
+
* A chat attachment to display on a sent/pending turn. Only `fileHandleId` is guaranteed --
|
|
5
|
+
* `fileName`/`contentType` are omitted for a restored/polled turn, where only the fileHandleId
|
|
6
|
+
* that was sent to the server is known (see SynapseChatMessage).
|
|
7
|
+
*/
|
|
8
|
+
export type SynapseChatInteractionAttachment = {
|
|
9
|
+
fileHandleId: string;
|
|
10
|
+
fileName?: string;
|
|
11
|
+
contentType?: string;
|
|
12
|
+
};
|
|
2
13
|
export type SynapseChatInteractionProps = {
|
|
3
14
|
userMessage: string;
|
|
4
15
|
chatResponseText?: string;
|
|
@@ -6,7 +17,17 @@ export type SynapseChatInteractionProps = {
|
|
|
6
17
|
scrollIntoView?: boolean;
|
|
7
18
|
chatErrorReason?: string;
|
|
8
19
|
onSendChat?: (message: string) => void;
|
|
20
|
+
agentAvatar: React.ReactNode;
|
|
21
|
+
userAvatar: React.ReactNode;
|
|
22
|
+
/** Whether to play the fade/rise-in entry animation for this interaction on mount. */
|
|
23
|
+
animateEntry?: boolean;
|
|
24
|
+
/** Whether a turn is currently in flight; gates the guide-prompt chips so they can't bypass the composer. */
|
|
25
|
+
isAwaitingResponse?: boolean;
|
|
26
|
+
/** Attachments the user sent with this message, if any. */
|
|
27
|
+
attachments?: SynapseChatInteractionAttachment[];
|
|
28
|
+
/** Server-reported outcome of staging each attachment, if available (see AgentChatResponseWithAttachmentStatuses). */
|
|
29
|
+
attachmentStatuses?: AgentChatAttachmentStatus[];
|
|
9
30
|
};
|
|
10
|
-
export declare function SynapseChatInteraction({ userMessage, chatResponseText, chatErrorReason, chatResponseTrace, scrollIntoView, onSendChat, }: SynapseChatInteractionProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function SynapseChatInteraction({ userMessage, chatResponseText, chatErrorReason, chatResponseTrace, scrollIntoView, onSendChat, agentAvatar, userAvatar, animateEntry, isAwaitingResponse, attachments, attachmentStatuses, }: SynapseChatInteractionProps): import("react/jsx-runtime").JSX.Element;
|
|
11
32
|
export default SynapseChatInteraction;
|
|
12
33
|
//# sourceMappingURL=SynapseChatInteraction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseChatInteraction.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SynapseChatInteraction.d.ts","sourceRoot":"","sources":["../../../src/components/SynapseChat/SynapseChatInteraction.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAQ5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE5E;;;;GAIG;AACH,MAAM,MAAM,gCAAgC,GAAG;IAC7C,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAA;IAChC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,gCAAgC,EAAE,CAAA;IAChD,sHAAsH;IACtH,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAA;CACjD,CAAA;AAqBD,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAsB,EACtB,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAoB,EACpB,kBAA0B,EAC1B,WAAW,EACX,kBAAkB,GACnB,EAAE,2BAA2B,2CAmP7B;AAED,eAAe,sBAAsB,CAAA"}
|