@xinghunm/ai-chat 1.3.1 → 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.
- package/dist/index.js +63 -50
- package/dist/index.mjs +109 -96
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -852,6 +852,21 @@ var AiChatProvider = (props) => {
|
|
|
852
852
|
defaultAuthToken,
|
|
853
853
|
defaultTransformStreamPacket
|
|
854
854
|
]);
|
|
855
|
+
const latestTransportRef = (0, import_react2.useRef)(transport);
|
|
856
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
857
|
+
latestTransportRef.current = transport;
|
|
858
|
+
}, [transport]);
|
|
859
|
+
(0, import_react2.useEffect)(() => {
|
|
860
|
+
return () => {
|
|
861
|
+
const { isStreamingBySession } = store.getState();
|
|
862
|
+
const streamingIds = Object.entries(isStreamingBySession).filter(([, streaming]) => streaming).map(([id]) => id);
|
|
863
|
+
for (const sessionId of streamingIds) {
|
|
864
|
+
const terminateId = isDraftChatSessionId(sessionId) ? void 0 : sessionId;
|
|
865
|
+
void latestTransportRef.current.terminateStream(terminateId).catch(() => {
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
}, [store]);
|
|
855
870
|
const contextValue = (0, import_react2.useMemo)(
|
|
856
871
|
() => ({
|
|
857
872
|
store,
|
|
@@ -1323,6 +1338,14 @@ var createTimelineAnchorState = ({
|
|
|
1323
1338
|
timelineBlockAnchors: {},
|
|
1324
1339
|
visibleTimelineBlockKeys: {}
|
|
1325
1340
|
});
|
|
1341
|
+
var createInitialTimelineAnchorState = ({
|
|
1342
|
+
messageId
|
|
1343
|
+
}) => ({
|
|
1344
|
+
messageId,
|
|
1345
|
+
previousBlockKeys: [],
|
|
1346
|
+
timelineBlockAnchors: {},
|
|
1347
|
+
visibleTimelineBlockKeys: {}
|
|
1348
|
+
});
|
|
1326
1349
|
var timelineAnchorReducer = (state, action) => {
|
|
1327
1350
|
switch (action.type) {
|
|
1328
1351
|
case "reset-message":
|
|
@@ -1412,7 +1435,7 @@ var useTimelineBlockAnchors = ({
|
|
|
1412
1435
|
messageId: message.id,
|
|
1413
1436
|
currentBlockKeys: currentTimelineBlockKeys
|
|
1414
1437
|
},
|
|
1415
|
-
|
|
1438
|
+
createInitialTimelineAnchorState
|
|
1416
1439
|
);
|
|
1417
1440
|
const effectiveTimelineBlockAnchors = (0, import_react6.useMemo)(() => {
|
|
1418
1441
|
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
@@ -3609,7 +3632,6 @@ var ChatThreadView = ({
|
|
|
3609
3632
|
[historyMessages, streamingMessage]
|
|
3610
3633
|
);
|
|
3611
3634
|
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
3612
|
-
const previousTurns = conversationTurns.slice(0, -1);
|
|
3613
3635
|
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
3614
3636
|
const latestHistoryMessage = historyMessages[historyMessages.length - 1];
|
|
3615
3637
|
const latestTurnRef = (0, import_react11.useRef)(null);
|
|
@@ -3798,54 +3820,42 @@ var ChatThreadView = ({
|
|
|
3798
3820
|
}, [latestTurn, scrollToBottom]);
|
|
3799
3821
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ThreadViewport, { children: [
|
|
3800
3822
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Container, { ref: containerRef, "data-testid": "chat-thread", onScroll: handleContainerScroll, children: [
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
) : null,
|
|
3838
|
-
latestTurn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
|
|
3839
|
-
message,
|
|
3840
|
-
mode: activeSessionMode,
|
|
3841
|
-
onConfirmationSubmit,
|
|
3842
|
-
onQuestionnaireSubmit,
|
|
3843
|
-
renderMessageBlock
|
|
3844
|
-
}) }, message.id)),
|
|
3845
|
-
error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3846
|
-
]
|
|
3847
|
-
}
|
|
3848
|
-
) : null,
|
|
3823
|
+
conversationTurns.map((turn, turnIndex) => {
|
|
3824
|
+
const isLatestTurn = turnIndex === conversationTurns.length - 1;
|
|
3825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3826
|
+
ConversationTurn,
|
|
3827
|
+
{
|
|
3828
|
+
ref: isLatestTurn ? latestTurnRef : null,
|
|
3829
|
+
"data-testid": isLatestTurn ? "chat-thread-latest-turn" : "chat-thread-turn",
|
|
3830
|
+
style: isLatestTurn && latestTurnMinHeight > 0 ? { minHeight: `${latestTurnMinHeight}px` } : void 0,
|
|
3831
|
+
children: [
|
|
3832
|
+
turn.userMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3833
|
+
MessageSlot,
|
|
3834
|
+
{
|
|
3835
|
+
"data-testid": isLatestTurn ? "chat-latest-user-anchor" : void 0,
|
|
3836
|
+
style: isLatestTurn ? { scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px` } : void 0,
|
|
3837
|
+
children: renderChatMessage({
|
|
3838
|
+
message: turn.userMessage,
|
|
3839
|
+
mode: activeSessionMode,
|
|
3840
|
+
onConfirmationSubmit,
|
|
3841
|
+
onQuestionnaireSubmit,
|
|
3842
|
+
renderMessageBlock
|
|
3843
|
+
})
|
|
3844
|
+
}
|
|
3845
|
+
) : null,
|
|
3846
|
+
turn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
|
|
3847
|
+
message,
|
|
3848
|
+
mode: activeSessionMode,
|
|
3849
|
+
onConfirmationSubmit,
|
|
3850
|
+
onQuestionnaireSubmit,
|
|
3851
|
+
renderMessageBlock
|
|
3852
|
+
}) }, message.id)),
|
|
3853
|
+
isLatestTurn && error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3854
|
+
]
|
|
3855
|
+
},
|
|
3856
|
+
turn.id
|
|
3857
|
+
);
|
|
3858
|
+
}),
|
|
3849
3859
|
!latestTurn && error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3850
3860
|
] }),
|
|
3851
3861
|
isDetached ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScrollToLatestOverlay, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
@@ -7224,6 +7234,9 @@ var useChatComposer = () => {
|
|
|
7224
7234
|
}
|
|
7225
7235
|
if (isDraftChatSessionId(sessionId)) {
|
|
7226
7236
|
finalizeStop(sessionId);
|
|
7237
|
+
void transport.terminateStream(void 0).catch((err) => {
|
|
7238
|
+
console.error("Failed to terminate draft chat session", err);
|
|
7239
|
+
});
|
|
7227
7240
|
return;
|
|
7228
7241
|
}
|
|
7229
7242
|
requestStopStreaming(sessionId);
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/components/ai-chat/index.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect10 } from "react";
|
|
3
3
|
import styled17 from "@emotion/styled";
|
|
4
4
|
import { ConfigProvider } from "@xinghunm/compass-ui";
|
|
5
5
|
|
|
6
6
|
// src/components/ai-chat-provider/index.tsx
|
|
7
|
-
import { useRef, useMemo, useState } from "react";
|
|
7
|
+
import { useRef, useMemo, useState, useEffect, useLayoutEffect } from "react";
|
|
8
8
|
import axios2 from "axios";
|
|
9
9
|
|
|
10
10
|
// src/context/chat-context.ts
|
|
@@ -805,6 +805,21 @@ var AiChatProvider = (props) => {
|
|
|
805
805
|
defaultAuthToken,
|
|
806
806
|
defaultTransformStreamPacket
|
|
807
807
|
]);
|
|
808
|
+
const latestTransportRef = useRef(transport);
|
|
809
|
+
useLayoutEffect(() => {
|
|
810
|
+
latestTransportRef.current = transport;
|
|
811
|
+
}, [transport]);
|
|
812
|
+
useEffect(() => {
|
|
813
|
+
return () => {
|
|
814
|
+
const { isStreamingBySession } = store.getState();
|
|
815
|
+
const streamingIds = Object.entries(isStreamingBySession).filter(([, streaming]) => streaming).map(([id]) => id);
|
|
816
|
+
for (const sessionId of streamingIds) {
|
|
817
|
+
const terminateId = isDraftChatSessionId(sessionId) ? void 0 : sessionId;
|
|
818
|
+
void latestTransportRef.current.terminateStream(terminateId).catch(() => {
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
}, [store]);
|
|
808
823
|
const contextValue = useMemo(
|
|
809
824
|
() => ({
|
|
810
825
|
store,
|
|
@@ -845,7 +860,7 @@ var AiChatProvider = (props) => {
|
|
|
845
860
|
};
|
|
846
861
|
|
|
847
862
|
// src/components/chat-thread/index.tsx
|
|
848
|
-
import { useCallback as useCallback3, useLayoutEffect as
|
|
863
|
+
import { useCallback as useCallback3, useLayoutEffect as useLayoutEffect3, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
|
|
849
864
|
import styled9 from "@emotion/styled";
|
|
850
865
|
|
|
851
866
|
// src/context/use-chat-context.ts
|
|
@@ -866,7 +881,7 @@ var useChatStore = (selector) => {
|
|
|
866
881
|
var CHAT_THREAD_SCROLL_TOP_GAP = 16;
|
|
867
882
|
|
|
868
883
|
// src/components/chat-thread/components/chat-message-item.tsx
|
|
869
|
-
import { Fragment, memo, useCallback as useCallback2, useLayoutEffect, useState as useState3 } from "react";
|
|
884
|
+
import { Fragment, memo, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useState as useState3 } from "react";
|
|
870
885
|
import styled7 from "@emotion/styled";
|
|
871
886
|
import { keyframes } from "@emotion/react";
|
|
872
887
|
import ReactMarkdown from "react-markdown";
|
|
@@ -875,7 +890,7 @@ import remarkMath from "remark-math";
|
|
|
875
890
|
import rehypeKatex from "rehype-katex";
|
|
876
891
|
|
|
877
892
|
// src/components/chat-thread/hooks/use-chat-message-reveal.ts
|
|
878
|
-
import { useCallback, useEffect, useMemo as useMemo2, useReducer, useRef as useRef2 } from "react";
|
|
893
|
+
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useReducer, useRef as useRef2 } from "react";
|
|
879
894
|
|
|
880
895
|
// src/components/chat-thread/lib/message-reveal.ts
|
|
881
896
|
var STREAM_REVEAL_TICK_MS = 36;
|
|
@@ -1010,7 +1025,7 @@ var useChatMessageReveal = (message) => {
|
|
|
1010
1025
|
},
|
|
1011
1026
|
[isAssistantStreaming, message.role]
|
|
1012
1027
|
);
|
|
1013
|
-
|
|
1028
|
+
useEffect2(() => {
|
|
1014
1029
|
if (previousMessageIdRef.current === message.id) {
|
|
1015
1030
|
return;
|
|
1016
1031
|
}
|
|
@@ -1028,7 +1043,7 @@ var useChatMessageReveal = (message) => {
|
|
|
1028
1043
|
targetUnitCount: targetUnits.length
|
|
1029
1044
|
});
|
|
1030
1045
|
}, [isAssistantStreaming, message.id, targetUnits.length]);
|
|
1031
|
-
|
|
1046
|
+
useEffect2(() => {
|
|
1032
1047
|
pendingTargetUnitCountRef.current = targetUnits.length;
|
|
1033
1048
|
if (message.role !== "assistant" || !isAssistantStreaming) {
|
|
1034
1049
|
if (inputBatchTimeoutRef.current !== null) {
|
|
@@ -1064,7 +1079,7 @@ var useChatMessageReveal = (message) => {
|
|
|
1064
1079
|
[displayedUnitCount, targetUnits]
|
|
1065
1080
|
);
|
|
1066
1081
|
const contentBlocks = useMemo2(() => splitMarkdownBlocks(displayedContent), [displayedContent]);
|
|
1067
|
-
|
|
1082
|
+
useEffect2(() => {
|
|
1068
1083
|
const hasNewDisplayedBlock = message.role === "assistant" && contentBlocks.length > 1 && contentBlocks.length > lastDisplayedBlockCountRef.current;
|
|
1069
1084
|
lastDisplayedBlockCountRef.current = contentBlocks.length;
|
|
1070
1085
|
if (!hasNewDisplayedBlock) {
|
|
@@ -1078,7 +1093,7 @@ var useChatMessageReveal = (message) => {
|
|
|
1078
1093
|
window.clearTimeout(timer);
|
|
1079
1094
|
};
|
|
1080
1095
|
}, [contentBlocks.length, message.role]);
|
|
1081
|
-
|
|
1096
|
+
useEffect2(() => {
|
|
1082
1097
|
const shouldAnimateReveal = message.role === "assistant" && displayedUnitCount < batchedTargetUnitCount && (isAssistantStreaming || displayedUnitCount > 0);
|
|
1083
1098
|
if (!shouldAnimateReveal) {
|
|
1084
1099
|
if (displayedUnitCount !== batchedTargetUnitCount) {
|
|
@@ -1115,7 +1130,7 @@ var useChatMessageReveal = (message) => {
|
|
|
1115
1130
|
};
|
|
1116
1131
|
|
|
1117
1132
|
// src/components/chat-thread/hooks/use-timeline-block-anchors.ts
|
|
1118
|
-
import { useEffect as
|
|
1133
|
+
import { useEffect as useEffect3, useMemo as useMemo3, useReducer as useReducer2 } from "react";
|
|
1119
1134
|
|
|
1120
1135
|
// src/components/chat-thread/lib/chat-message-timeline.ts
|
|
1121
1136
|
var stringifyTimelineKeyPart = (value) => {
|
|
@@ -1276,6 +1291,14 @@ var createTimelineAnchorState = ({
|
|
|
1276
1291
|
timelineBlockAnchors: {},
|
|
1277
1292
|
visibleTimelineBlockKeys: {}
|
|
1278
1293
|
});
|
|
1294
|
+
var createInitialTimelineAnchorState = ({
|
|
1295
|
+
messageId
|
|
1296
|
+
}) => ({
|
|
1297
|
+
messageId,
|
|
1298
|
+
previousBlockKeys: [],
|
|
1299
|
+
timelineBlockAnchors: {},
|
|
1300
|
+
visibleTimelineBlockKeys: {}
|
|
1301
|
+
});
|
|
1279
1302
|
var timelineAnchorReducer = (state, action) => {
|
|
1280
1303
|
switch (action.type) {
|
|
1281
1304
|
case "reset-message":
|
|
@@ -1365,7 +1388,7 @@ var useTimelineBlockAnchors = ({
|
|
|
1365
1388
|
messageId: message.id,
|
|
1366
1389
|
currentBlockKeys: currentTimelineBlockKeys
|
|
1367
1390
|
},
|
|
1368
|
-
|
|
1391
|
+
createInitialTimelineAnchorState
|
|
1369
1392
|
);
|
|
1370
1393
|
const effectiveTimelineBlockAnchors = useMemo3(() => {
|
|
1371
1394
|
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
@@ -1394,14 +1417,14 @@ var useTimelineBlockAnchors = ({
|
|
|
1394
1417
|
state.timelineBlockAnchors,
|
|
1395
1418
|
timelineTextStreamLength
|
|
1396
1419
|
]);
|
|
1397
|
-
|
|
1420
|
+
useEffect3(() => {
|
|
1398
1421
|
dispatch({
|
|
1399
1422
|
type: "reset-message",
|
|
1400
1423
|
messageId: message.id,
|
|
1401
1424
|
currentBlockKeys: currentTimelineBlockKeys
|
|
1402
1425
|
});
|
|
1403
1426
|
}, [currentTimelineBlockKeys, message.id]);
|
|
1404
|
-
|
|
1427
|
+
useEffect3(() => {
|
|
1405
1428
|
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
1406
1429
|
return;
|
|
1407
1430
|
}
|
|
@@ -1411,7 +1434,7 @@ var useTimelineBlockAnchors = ({
|
|
|
1411
1434
|
timelineTextStreamLength
|
|
1412
1435
|
});
|
|
1413
1436
|
}, [currentTimelineBlockKeys, isAssistantStreaming, messageRenderOrder, timelineTextStreamLength]);
|
|
1414
|
-
|
|
1437
|
+
useEffect3(() => {
|
|
1415
1438
|
if (messageRenderOrder !== "timeline") {
|
|
1416
1439
|
return;
|
|
1417
1440
|
}
|
|
@@ -1636,7 +1659,7 @@ var Value = styled3.span`
|
|
|
1636
1659
|
|
|
1637
1660
|
// src/components/chat-thread/components/questionnaire-card.tsx
|
|
1638
1661
|
import {
|
|
1639
|
-
useEffect as
|
|
1662
|
+
useEffect as useEffect4,
|
|
1640
1663
|
useRef as useRef3,
|
|
1641
1664
|
useState as useState2
|
|
1642
1665
|
} from "react";
|
|
@@ -2029,11 +2052,11 @@ var QuestionnaireCardInner = ({
|
|
|
2029
2052
|
const visibleErrorMessage = questionnaire.statusMessage ?? errorMessage;
|
|
2030
2053
|
const isInteractionLocked = !interactive || isSubmitting || isSubmitted || hasExternalFailureStatus;
|
|
2031
2054
|
questionnaireRef.current = questionnaire;
|
|
2032
|
-
|
|
2055
|
+
useEffect4(() => {
|
|
2033
2056
|
setAnswers(createInitialAnswers(questionnaireRef.current));
|
|
2034
2057
|
setOtherDrafts(createInitialOtherDrafts(questionnaireRef.current));
|
|
2035
2058
|
}, [questionnaire.answers]);
|
|
2036
|
-
|
|
2059
|
+
useEffect4(() => {
|
|
2037
2060
|
if (!pendingFocusQuestionId || isInteractionLocked) {
|
|
2038
2061
|
return;
|
|
2039
2062
|
}
|
|
@@ -2557,7 +2580,7 @@ var Detail = styled5.li`
|
|
|
2557
2580
|
|
|
2558
2581
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
2559
2582
|
import styled6 from "@emotion/styled";
|
|
2560
|
-
import { useEffect as
|
|
2583
|
+
import { useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
2561
2584
|
import { jsx as jsx7 } from "@emotion/react/jsx-runtime";
|
|
2562
2585
|
var Overlay = styled6.div`
|
|
2563
2586
|
position: fixed;
|
|
@@ -2577,7 +2600,7 @@ var Img = styled6.img`
|
|
|
2577
2600
|
`;
|
|
2578
2601
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
2579
2602
|
const overlayRef = useRef4(null);
|
|
2580
|
-
|
|
2603
|
+
useEffect5(() => {
|
|
2581
2604
|
const handleKey = (e) => {
|
|
2582
2605
|
if (e.key === "Escape")
|
|
2583
2606
|
onClose();
|
|
@@ -2585,7 +2608,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
2585
2608
|
document.addEventListener("keydown", handleKey);
|
|
2586
2609
|
return () => document.removeEventListener("keydown", handleKey);
|
|
2587
2610
|
}, [onClose]);
|
|
2588
|
-
|
|
2611
|
+
useEffect5(() => {
|
|
2589
2612
|
overlayRef.current?.focus();
|
|
2590
2613
|
}, []);
|
|
2591
2614
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -2671,7 +2694,7 @@ var useUserMessageCollapse = ({
|
|
|
2671
2694
|
},
|
|
2672
2695
|
[syncCollapseState]
|
|
2673
2696
|
);
|
|
2674
|
-
|
|
2697
|
+
useLayoutEffect2(() => {
|
|
2675
2698
|
if (!bodyStackElement) {
|
|
2676
2699
|
return;
|
|
2677
2700
|
}
|
|
@@ -2691,7 +2714,7 @@ var useUserMessageCollapse = ({
|
|
|
2691
2714
|
settledContent,
|
|
2692
2715
|
syncCollapseState
|
|
2693
2716
|
]);
|
|
2694
|
-
|
|
2717
|
+
useLayoutEffect2(() => {
|
|
2695
2718
|
if (!bodyStackElement || !enabled || typeof ResizeObserver === "undefined") {
|
|
2696
2719
|
return;
|
|
2697
2720
|
}
|
|
@@ -3566,7 +3589,6 @@ var ChatThreadView = ({
|
|
|
3566
3589
|
[historyMessages, streamingMessage]
|
|
3567
3590
|
);
|
|
3568
3591
|
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
3569
|
-
const previousTurns = conversationTurns.slice(0, -1);
|
|
3570
3592
|
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
3571
3593
|
const latestHistoryMessage = historyMessages[historyMessages.length - 1];
|
|
3572
3594
|
const latestTurnRef = useRef5(null);
|
|
@@ -3628,7 +3650,7 @@ var ChatThreadView = ({
|
|
|
3628
3650
|
setPendingNewMessageCount(0);
|
|
3629
3651
|
}
|
|
3630
3652
|
}, []);
|
|
3631
|
-
|
|
3653
|
+
useLayoutEffect3(() => {
|
|
3632
3654
|
const nextHistoryMessageId = latestHistoryMessage?.id;
|
|
3633
3655
|
if (lastHistoryMessageIdRef.current === nextHistoryMessageId) {
|
|
3634
3656
|
return;
|
|
@@ -3652,7 +3674,7 @@ var ChatThreadView = ({
|
|
|
3652
3674
|
});
|
|
3653
3675
|
}
|
|
3654
3676
|
}, [latestHistoryMessage, markThreadPinned, scrollToBottom]);
|
|
3655
|
-
|
|
3677
|
+
useLayoutEffect3(() => {
|
|
3656
3678
|
const nextStreamingMessageId = streamingMessage?.id;
|
|
3657
3679
|
if (lastStreamingMessageIdRef.current === nextStreamingMessageId) {
|
|
3658
3680
|
return;
|
|
@@ -3667,7 +3689,7 @@ var ChatThreadView = ({
|
|
|
3667
3689
|
});
|
|
3668
3690
|
}
|
|
3669
3691
|
}, [streamingMessage]);
|
|
3670
|
-
|
|
3692
|
+
useLayoutEffect3(() => {
|
|
3671
3693
|
if (reservedSpaceFrameRef.current !== null) {
|
|
3672
3694
|
window.cancelAnimationFrame(reservedSpaceFrameRef.current);
|
|
3673
3695
|
reservedSpaceFrameRef.current = null;
|
|
@@ -3697,7 +3719,7 @@ var ChatThreadView = ({
|
|
|
3697
3719
|
}
|
|
3698
3720
|
};
|
|
3699
3721
|
}, [latestTurn, latestUserMessageId, error2, measureLatestTurnMinHeight, scrollToBottom]);
|
|
3700
|
-
|
|
3722
|
+
useLayoutEffect3(() => {
|
|
3701
3723
|
if (!latestTurn)
|
|
3702
3724
|
return;
|
|
3703
3725
|
const handleResize = () => {
|
|
@@ -3723,7 +3745,7 @@ var ChatThreadView = ({
|
|
|
3723
3745
|
window.removeEventListener("resize", handleResize);
|
|
3724
3746
|
};
|
|
3725
3747
|
}, [latestTurn, latestUserMessageId, measureLatestTurnMinHeight, scrollToBottom]);
|
|
3726
|
-
|
|
3748
|
+
useLayoutEffect3(() => {
|
|
3727
3749
|
const latestTurnElement = latestTurnRef.current;
|
|
3728
3750
|
if (!latestTurnElement || typeof ResizeObserver === "undefined") {
|
|
3729
3751
|
return;
|
|
@@ -3736,7 +3758,7 @@ var ChatThreadView = ({
|
|
|
3736
3758
|
observer.disconnect();
|
|
3737
3759
|
};
|
|
3738
3760
|
}, [latestTurn, scrollToBottom]);
|
|
3739
|
-
|
|
3761
|
+
useLayoutEffect3(() => {
|
|
3740
3762
|
const latestTurnElement = latestTurnRef.current;
|
|
3741
3763
|
if (!latestTurnElement || typeof MutationObserver === "undefined") {
|
|
3742
3764
|
return;
|
|
@@ -3755,54 +3777,42 @@ var ChatThreadView = ({
|
|
|
3755
3777
|
}, [latestTurn, scrollToBottom]);
|
|
3756
3778
|
return /* @__PURE__ */ jsxs7(ThreadViewport, { children: [
|
|
3757
3779
|
/* @__PURE__ */ jsxs7(Container, { ref: containerRef, "data-testid": "chat-thread", onScroll: handleContainerScroll, children: [
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
) : null,
|
|
3795
|
-
latestTurn.responseMessages.map((message) => /* @__PURE__ */ jsx10(MessageSlot, { children: renderChatMessage({
|
|
3796
|
-
message,
|
|
3797
|
-
mode: activeSessionMode,
|
|
3798
|
-
onConfirmationSubmit,
|
|
3799
|
-
onQuestionnaireSubmit,
|
|
3800
|
-
renderMessageBlock
|
|
3801
|
-
}) }, message.id)),
|
|
3802
|
-
error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3803
|
-
]
|
|
3804
|
-
}
|
|
3805
|
-
) : null,
|
|
3780
|
+
conversationTurns.map((turn, turnIndex) => {
|
|
3781
|
+
const isLatestTurn = turnIndex === conversationTurns.length - 1;
|
|
3782
|
+
return /* @__PURE__ */ jsxs7(
|
|
3783
|
+
ConversationTurn,
|
|
3784
|
+
{
|
|
3785
|
+
ref: isLatestTurn ? latestTurnRef : null,
|
|
3786
|
+
"data-testid": isLatestTurn ? "chat-thread-latest-turn" : "chat-thread-turn",
|
|
3787
|
+
style: isLatestTurn && latestTurnMinHeight > 0 ? { minHeight: `${latestTurnMinHeight}px` } : void 0,
|
|
3788
|
+
children: [
|
|
3789
|
+
turn.userMessage ? /* @__PURE__ */ jsx10(
|
|
3790
|
+
MessageSlot,
|
|
3791
|
+
{
|
|
3792
|
+
"data-testid": isLatestTurn ? "chat-latest-user-anchor" : void 0,
|
|
3793
|
+
style: isLatestTurn ? { scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px` } : void 0,
|
|
3794
|
+
children: renderChatMessage({
|
|
3795
|
+
message: turn.userMessage,
|
|
3796
|
+
mode: activeSessionMode,
|
|
3797
|
+
onConfirmationSubmit,
|
|
3798
|
+
onQuestionnaireSubmit,
|
|
3799
|
+
renderMessageBlock
|
|
3800
|
+
})
|
|
3801
|
+
}
|
|
3802
|
+
) : null,
|
|
3803
|
+
turn.responseMessages.map((message) => /* @__PURE__ */ jsx10(MessageSlot, { children: renderChatMessage({
|
|
3804
|
+
message,
|
|
3805
|
+
mode: activeSessionMode,
|
|
3806
|
+
onConfirmationSubmit,
|
|
3807
|
+
onQuestionnaireSubmit,
|
|
3808
|
+
renderMessageBlock
|
|
3809
|
+
}) }, message.id)),
|
|
3810
|
+
isLatestTurn && error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3811
|
+
]
|
|
3812
|
+
},
|
|
3813
|
+
turn.id
|
|
3814
|
+
);
|
|
3815
|
+
}),
|
|
3806
3816
|
!latestTurn && error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
|
|
3807
3817
|
] }),
|
|
3808
3818
|
isDetached ? /* @__PURE__ */ jsx10(ScrollToLatestOverlay, { children: /* @__PURE__ */ jsxs7(
|
|
@@ -4030,7 +4040,7 @@ var ScrollToLatestBadge = styled9.span`
|
|
|
4030
4040
|
`;
|
|
4031
4041
|
|
|
4032
4042
|
// src/components/chat-composer/index.tsx
|
|
4033
|
-
import { useCallback as useCallback8, useEffect as
|
|
4043
|
+
import { useCallback as useCallback8, useEffect as useEffect9, useLayoutEffect as useLayoutEffect6, useRef as useRef11, useState as useState10 } from "react";
|
|
4034
4044
|
import styled14 from "@emotion/styled";
|
|
4035
4045
|
|
|
4036
4046
|
// ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
|
|
@@ -4192,7 +4202,7 @@ function getFrameElement(win) {
|
|
|
4192
4202
|
|
|
4193
4203
|
// ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs
|
|
4194
4204
|
import * as React from "react";
|
|
4195
|
-
import { useLayoutEffect as
|
|
4205
|
+
import { useLayoutEffect as useLayoutEffect4 } from "react";
|
|
4196
4206
|
|
|
4197
4207
|
// ../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
|
|
4198
4208
|
var min = Math.min;
|
|
@@ -4679,7 +4689,7 @@ function getDocument(node) {
|
|
|
4679
4689
|
var isClient = typeof document !== "undefined";
|
|
4680
4690
|
var noop = function noop2() {
|
|
4681
4691
|
};
|
|
4682
|
-
var index = isClient ?
|
|
4692
|
+
var index = isClient ? useLayoutEffect4 : noop;
|
|
4683
4693
|
var SafeReact = {
|
|
4684
4694
|
...React
|
|
4685
4695
|
};
|
|
@@ -5888,12 +5898,12 @@ var computePosition2 = (reference, floating, options) => {
|
|
|
5888
5898
|
|
|
5889
5899
|
// ../../node_modules/.pnpm/@floating-ui+react-dom@2.1.6_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
|
|
5890
5900
|
import * as React2 from "react";
|
|
5891
|
-
import { useLayoutEffect as
|
|
5901
|
+
import { useLayoutEffect as useLayoutEffect5 } from "react";
|
|
5892
5902
|
import * as ReactDOM from "react-dom";
|
|
5893
5903
|
var isClient2 = typeof document !== "undefined";
|
|
5894
5904
|
var noop3 = function noop4() {
|
|
5895
5905
|
};
|
|
5896
|
-
var index2 = isClient2 ?
|
|
5906
|
+
var index2 = isClient2 ? useLayoutEffect5 : noop3;
|
|
5897
5907
|
function deepEqual(a, b) {
|
|
5898
5908
|
if (a === b) {
|
|
5899
5909
|
return true;
|
|
@@ -6630,10 +6640,10 @@ var resolveSendSession = ({
|
|
|
6630
6640
|
};
|
|
6631
6641
|
|
|
6632
6642
|
// src/components/chat-composer/hooks/use-chat-composer.ts
|
|
6633
|
-
import { useCallback as useCallback7, useEffect as
|
|
6643
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef10, useState as useState8 } from "react";
|
|
6634
6644
|
|
|
6635
6645
|
// src/components/chat-composer/hooks/use-composer-attachments.ts
|
|
6636
|
-
import { useEffect as
|
|
6646
|
+
import { useEffect as useEffect7, useRef as useRef9, useState as useState7 } from "react";
|
|
6637
6647
|
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
6638
6648
|
var MAX_COMPOSER_ATTACHMENTS = 10;
|
|
6639
6649
|
var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
|
|
@@ -6649,10 +6659,10 @@ var releaseComposerAttachments = (attachments) => {
|
|
|
6649
6659
|
var useComposerAttachments = () => {
|
|
6650
6660
|
const [attachments, setAttachments] = useState7([]);
|
|
6651
6661
|
const attachmentsRef = useRef9([]);
|
|
6652
|
-
|
|
6662
|
+
useEffect7(() => {
|
|
6653
6663
|
attachmentsRef.current = attachments;
|
|
6654
6664
|
}, [attachments]);
|
|
6655
|
-
|
|
6665
|
+
useEffect7(
|
|
6656
6666
|
() => () => {
|
|
6657
6667
|
releaseComposerAttachments(attachmentsRef.current);
|
|
6658
6668
|
},
|
|
@@ -6825,10 +6835,10 @@ var useChatComposer = () => {
|
|
|
6825
6835
|
setIsModelsLoading(false);
|
|
6826
6836
|
}
|
|
6827
6837
|
}, [modelsLoader]);
|
|
6828
|
-
|
|
6838
|
+
useEffect8(() => {
|
|
6829
6839
|
void fetchModels();
|
|
6830
6840
|
}, [fetchModels]);
|
|
6831
|
-
|
|
6841
|
+
useEffect8(() => {
|
|
6832
6842
|
activeSkillsLoaderRef.current = skillsLoader;
|
|
6833
6843
|
const cachedSkills = getCachedSkills(skillsLoader);
|
|
6834
6844
|
setAvailableSkills(cachedSkills.skills);
|
|
@@ -6864,7 +6874,7 @@ var useChatComposer = () => {
|
|
|
6864
6874
|
}
|
|
6865
6875
|
}
|
|
6866
6876
|
}, [skillsLoader]);
|
|
6867
|
-
|
|
6877
|
+
useEffect8(() => {
|
|
6868
6878
|
void fetchSkills();
|
|
6869
6879
|
}, [fetchSkills]);
|
|
6870
6880
|
const hasModels = availableModels.length > 0;
|
|
@@ -6878,25 +6888,25 @@ var useChatComposer = () => {
|
|
|
6878
6888
|
const stopRequestBySessionRef = useRef10(/* @__PURE__ */ new Map());
|
|
6879
6889
|
const lastRequestBySessionRef = useRef10(/* @__PURE__ */ new Map());
|
|
6880
6890
|
const previousActiveSessionIdRef = useRef10(activeSessionId);
|
|
6881
|
-
|
|
6891
|
+
useEffect8(() => {
|
|
6882
6892
|
setSelectedModel(
|
|
6883
6893
|
(current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
|
|
6884
6894
|
);
|
|
6885
6895
|
}, [availableModels, isModelsLoading]);
|
|
6886
|
-
|
|
6896
|
+
useEffect8(() => {
|
|
6887
6897
|
if (activeSession) {
|
|
6888
6898
|
setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
6889
6899
|
return;
|
|
6890
6900
|
}
|
|
6891
6901
|
setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
6892
6902
|
}, [activeSession, preferredMode]);
|
|
6893
|
-
|
|
6903
|
+
useEffect8(() => {
|
|
6894
6904
|
if (previousActiveSessionIdRef.current !== activeSessionId) {
|
|
6895
6905
|
setSelectedSkills([]);
|
|
6896
6906
|
previousActiveSessionIdRef.current = activeSessionId;
|
|
6897
6907
|
}
|
|
6898
6908
|
}, [activeSessionId]);
|
|
6899
|
-
|
|
6909
|
+
useEffect8(() => {
|
|
6900
6910
|
if (!attachmentNotice)
|
|
6901
6911
|
return;
|
|
6902
6912
|
const timeoutId = window.setTimeout(
|
|
@@ -7181,6 +7191,9 @@ var useChatComposer = () => {
|
|
|
7181
7191
|
}
|
|
7182
7192
|
if (isDraftChatSessionId(sessionId)) {
|
|
7183
7193
|
finalizeStop(sessionId);
|
|
7194
|
+
void transport.terminateStream(void 0).catch((err) => {
|
|
7195
|
+
console.error("Failed to terminate draft chat session", err);
|
|
7196
|
+
});
|
|
7184
7197
|
return;
|
|
7185
7198
|
}
|
|
7186
7199
|
requestStopStreaming(sessionId);
|
|
@@ -8026,7 +8039,7 @@ var ChatComposerView = ({
|
|
|
8026
8039
|
[refs]
|
|
8027
8040
|
);
|
|
8028
8041
|
const activeSkillIndex = activeSkillNavigation.queryKey === activeSkillQueryKey ? activeSkillNavigation.index : 0;
|
|
8029
|
-
|
|
8042
|
+
useLayoutEffect6(() => {
|
|
8030
8043
|
const element = inputRef.current;
|
|
8031
8044
|
if (!element) {
|
|
8032
8045
|
return;
|
|
@@ -8264,7 +8277,7 @@ var ChatComposer = () => {
|
|
|
8264
8277
|
const { labels, sendRef, retryRef, stopRef, enableImageAttachments } = useChatContext();
|
|
8265
8278
|
const { state, actions } = useChatComposer();
|
|
8266
8279
|
const { send, retry } = actions;
|
|
8267
|
-
|
|
8280
|
+
useEffect9(() => {
|
|
8268
8281
|
sendRef.current = send;
|
|
8269
8282
|
retryRef.current = async (sessionId) => {
|
|
8270
8283
|
retry(sessionId);
|
|
@@ -8779,7 +8792,7 @@ var AiChatWorkspaceContent = ({
|
|
|
8779
8792
|
})
|
|
8780
8793
|
);
|
|
8781
8794
|
const shouldShowComposerOnly = showComposerOnlyBeforeFirstMessage && !showConversationList && !isConversationStarted;
|
|
8782
|
-
|
|
8795
|
+
useEffect10(() => {
|
|
8783
8796
|
onConversationStartedChange?.(isConversationStarted);
|
|
8784
8797
|
}, [isConversationStarted, onConversationStartedChange]);
|
|
8785
8798
|
return /* @__PURE__ */ jsxs14(Root, { "data-testid": "ai-chat", children: [
|