@xinghunm/ai-chat 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -9
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +475 -91
- package/dist/index.mjs +450 -67
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
AiChat: () => AiChat,
|
|
34
34
|
AiChatProvider: () => AiChatProvider,
|
|
35
35
|
CHAT_AGENT_MODES: () => CHAT_AGENT_MODES,
|
|
36
|
+
CHAT_MESSAGE_RENDER_ORDERS: () => CHAT_MESSAGE_RENDER_ORDERS,
|
|
36
37
|
ChatComposer: () => ChatComposer,
|
|
37
38
|
ChatConversationList: () => ChatConversationList,
|
|
38
39
|
ChatThread: () => ChatThread,
|
|
@@ -62,6 +63,7 @@ var import_vanilla = require("zustand/vanilla");
|
|
|
62
63
|
// src/types/index.ts
|
|
63
64
|
var CHAT_AGENT_MODES = ["ask", "plan", "agent"];
|
|
64
65
|
var DEFAULT_CHAT_AGENT_MODE = "agent";
|
|
66
|
+
var CHAT_MESSAGE_RENDER_ORDERS = ["blocks-first", "timeline"];
|
|
65
67
|
var DEFAULT_AI_CHAT_LABELS = {
|
|
66
68
|
sendButton: "Send",
|
|
67
69
|
stopButton: "Stop",
|
|
@@ -563,7 +565,14 @@ var createDefaultChatTransport = ({
|
|
|
563
565
|
// src/components/ai-chat-provider/index.tsx
|
|
564
566
|
var import_jsx_runtime = require("@emotion/react/jsx-runtime");
|
|
565
567
|
var AiChatProvider = (props) => {
|
|
566
|
-
const {
|
|
568
|
+
const {
|
|
569
|
+
defaultMode,
|
|
570
|
+
labels,
|
|
571
|
+
renderMessageBlock,
|
|
572
|
+
messageRenderOrder,
|
|
573
|
+
enableImageAttachments = true,
|
|
574
|
+
children
|
|
575
|
+
} = props;
|
|
567
576
|
const [store] = (0, import_react2.useState)(
|
|
568
577
|
() => createChatStore(defaultMode ? { preferredMode: defaultMode } : void 0)
|
|
569
578
|
);
|
|
@@ -615,6 +624,7 @@ var AiChatProvider = (props) => {
|
|
|
615
624
|
sendRef,
|
|
616
625
|
retryRef,
|
|
617
626
|
renderMessageBlock,
|
|
627
|
+
messageRenderOrder,
|
|
618
628
|
transformStreamPacket: defaultTransformStreamPacket,
|
|
619
629
|
enableImageAttachments
|
|
620
630
|
}),
|
|
@@ -625,6 +635,7 @@ var AiChatProvider = (props) => {
|
|
|
625
635
|
defaultTransformStreamPacket,
|
|
626
636
|
enableImageAttachments,
|
|
627
637
|
labels,
|
|
638
|
+
messageRenderOrder,
|
|
628
639
|
renderMessageBlock,
|
|
629
640
|
sendRef,
|
|
630
641
|
retryRef,
|
|
@@ -636,7 +647,7 @@ var AiChatProvider = (props) => {
|
|
|
636
647
|
};
|
|
637
648
|
|
|
638
649
|
// src/components/chat-thread/index.tsx
|
|
639
|
-
var
|
|
650
|
+
var import_react11 = require("react");
|
|
640
651
|
var import_styled9 = __toESM(require("@emotion/styled"));
|
|
641
652
|
|
|
642
653
|
// src/context/use-chat-context.ts
|
|
@@ -657,9 +668,9 @@ var useChatStore = (selector) => {
|
|
|
657
668
|
var CHAT_THREAD_SCROLL_TOP_GAP = 16;
|
|
658
669
|
|
|
659
670
|
// src/components/chat-thread/components/chat-message-item.tsx
|
|
660
|
-
var
|
|
671
|
+
var import_react9 = require("react");
|
|
661
672
|
var import_styled7 = __toESM(require("@emotion/styled"));
|
|
662
|
-
var
|
|
673
|
+
var import_react10 = require("@emotion/react");
|
|
663
674
|
var import_react_markdown = __toESM(require("react-markdown"));
|
|
664
675
|
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
665
676
|
var import_remark_math = __toESM(require("remark-math"));
|
|
@@ -897,6 +908,7 @@ var useChatMessageReveal = (message) => {
|
|
|
897
908
|
];
|
|
898
909
|
return {
|
|
899
910
|
isAssistantStreaming,
|
|
911
|
+
isFreshBlockActive,
|
|
900
912
|
displayedContent,
|
|
901
913
|
settledContent,
|
|
902
914
|
freshContent,
|
|
@@ -904,6 +916,303 @@ var useChatMessageReveal = (message) => {
|
|
|
904
916
|
};
|
|
905
917
|
};
|
|
906
918
|
|
|
919
|
+
// src/components/chat-thread/hooks/use-timeline-block-anchors.ts
|
|
920
|
+
var import_react6 = require("react");
|
|
921
|
+
|
|
922
|
+
// src/components/chat-thread/lib/chat-message-timeline.ts
|
|
923
|
+
var stringifyTimelineKeyPart = (value) => {
|
|
924
|
+
if (value === null || value === void 0) {
|
|
925
|
+
return String(value);
|
|
926
|
+
}
|
|
927
|
+
if (Array.isArray(value)) {
|
|
928
|
+
return `[${value.map((item) => stringifyTimelineKeyPart(item)).join(",")}]`;
|
|
929
|
+
}
|
|
930
|
+
if (typeof value === "object") {
|
|
931
|
+
return `{${Object.entries(value).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key, nestedValue]) => `${key}:${stringifyTimelineKeyPart(nestedValue)}`).join(",")}}`;
|
|
932
|
+
}
|
|
933
|
+
return String(value);
|
|
934
|
+
};
|
|
935
|
+
var getTimelineBlockKey = (block, index) => {
|
|
936
|
+
switch (block.type) {
|
|
937
|
+
case "markdown":
|
|
938
|
+
return null;
|
|
939
|
+
case "notice":
|
|
940
|
+
return `${index}:notice:${block.tone}:${block.text}`;
|
|
941
|
+
case "parameter_summary":
|
|
942
|
+
return `${index}:parameter_summary:${block.items.map((item) => `${item.label}:${item.value}:${item.fieldPath ?? ""}`).join("|")}`;
|
|
943
|
+
case "confirmation_card":
|
|
944
|
+
return `${index}:confirmation_card:${block.proposal.proposalId}`;
|
|
945
|
+
case "result_summary":
|
|
946
|
+
return `${index}:result_summary:${block.summary.taskId}:${block.summary.status}`;
|
|
947
|
+
case "questionnaire":
|
|
948
|
+
return `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
949
|
+
case "custom":
|
|
950
|
+
return `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
951
|
+
default:
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
var getTimelineConsumedText = (blocks) => blocks.filter(
|
|
956
|
+
(block) => block.type === "markdown"
|
|
957
|
+
).map((block) => block.text).join("\n\n");
|
|
958
|
+
var getTimelineTextStream = (content, blocks) => {
|
|
959
|
+
const consumedText = getTimelineConsumedText(blocks);
|
|
960
|
+
if (consumedText.length > 0 && content.startsWith(consumedText)) {
|
|
961
|
+
return content.slice(consumedText.length);
|
|
962
|
+
}
|
|
963
|
+
return content;
|
|
964
|
+
};
|
|
965
|
+
var buildTimelineTextDisplay = (content, isAssistantStreaming, isFreshBlockActive = isAssistantStreaming) => {
|
|
966
|
+
const contentBlocks = splitMarkdownBlocks(content);
|
|
967
|
+
const settledContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks.slice(0, -1).join("\n\n") : content;
|
|
968
|
+
const freshContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
|
|
969
|
+
const displayedBlocks = contentBlocks.length > 1 ? contentBlocks.map((blockContent, index) => ({
|
|
970
|
+
content: blockContent,
|
|
971
|
+
tone: isAssistantStreaming && isFreshBlockActive && freshContent && index === contentBlocks.length - 1 ? "fresh" : "settled"
|
|
972
|
+
})) : [{ content, tone: "settled" }];
|
|
973
|
+
return {
|
|
974
|
+
settledContent,
|
|
975
|
+
freshContent,
|
|
976
|
+
displayedBlocks
|
|
977
|
+
};
|
|
978
|
+
};
|
|
979
|
+
var getTimelineDisplayUnitCount = (content) => splitMarkdownBlocks(content).reduce((count, block) => count + Array.from(block).length, 0);
|
|
980
|
+
var buildAnchoredTimelineSegments = ({
|
|
981
|
+
blocks,
|
|
982
|
+
timelineBlockAnchors,
|
|
983
|
+
timelineDisplayedBlocks,
|
|
984
|
+
visibleTimelineBlockKeys
|
|
985
|
+
}) => {
|
|
986
|
+
const orderedTimelineSegments = [];
|
|
987
|
+
const totalTimelineUnits = timelineDisplayedBlocks.reduce(
|
|
988
|
+
(count, block) => count + Array.from(block.content).length,
|
|
989
|
+
0
|
|
990
|
+
);
|
|
991
|
+
let textCursor = 0;
|
|
992
|
+
const buildTextSegment = (start, end, options) => {
|
|
993
|
+
if (end <= start) {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
const displayedBlocks = [];
|
|
997
|
+
let blockCursor = 0;
|
|
998
|
+
for (const block of timelineDisplayedBlocks) {
|
|
999
|
+
const blockUnits = Array.from(block.content);
|
|
1000
|
+
const blockStart = blockCursor;
|
|
1001
|
+
const blockEnd = blockCursor + blockUnits.length;
|
|
1002
|
+
if (blockEnd <= start) {
|
|
1003
|
+
blockCursor = blockEnd;
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (blockStart >= end) {
|
|
1007
|
+
break;
|
|
1008
|
+
}
|
|
1009
|
+
const sliceStart = Math.max(0, start - blockStart);
|
|
1010
|
+
const sliceEnd = Math.min(blockUnits.length, end - blockStart);
|
|
1011
|
+
const slicedContent = blockUnits.slice(sliceStart, sliceEnd).join("");
|
|
1012
|
+
if (slicedContent) {
|
|
1013
|
+
displayedBlocks.push({
|
|
1014
|
+
content: slicedContent,
|
|
1015
|
+
tone: options?.forceSettled ? "settled" : block.tone
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
blockCursor = blockEnd;
|
|
1019
|
+
}
|
|
1020
|
+
const content = displayedBlocks.map((block) => block.content).join("\n\n");
|
|
1021
|
+
if (!content) {
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
type: "text",
|
|
1026
|
+
content,
|
|
1027
|
+
displayedBlocks,
|
|
1028
|
+
useTimelineSegmentation: true
|
|
1029
|
+
};
|
|
1030
|
+
};
|
|
1031
|
+
let trailingCutoff = totalTimelineUnits;
|
|
1032
|
+
for (const [index, block] of blocks.entries()) {
|
|
1033
|
+
if (block.type === "markdown") {
|
|
1034
|
+
orderedTimelineSegments.push({
|
|
1035
|
+
type: "markdown",
|
|
1036
|
+
content: block.text
|
|
1037
|
+
});
|
|
1038
|
+
continue;
|
|
1039
|
+
}
|
|
1040
|
+
const blockKey = getTimelineBlockKey(block, index);
|
|
1041
|
+
const anchor = blockKey !== null ? timelineBlockAnchors[blockKey] ?? totalTimelineUnits : totalTimelineUnits;
|
|
1042
|
+
const isBlockVisible = blockKey !== null && visibleTimelineBlockKeys?.[blockKey] ? true : anchor <= totalTimelineUnits;
|
|
1043
|
+
if (anchor > textCursor) {
|
|
1044
|
+
const textSegment = buildTextSegment(textCursor, Math.min(anchor, totalTimelineUnits), {
|
|
1045
|
+
forceSettled: isBlockVisible
|
|
1046
|
+
});
|
|
1047
|
+
if (textSegment) {
|
|
1048
|
+
orderedTimelineSegments.push(textSegment);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
if (!isBlockVisible) {
|
|
1052
|
+
textCursor = Math.min(anchor, totalTimelineUnits);
|
|
1053
|
+
trailingCutoff = Math.min(trailingCutoff, textCursor);
|
|
1054
|
+
continue;
|
|
1055
|
+
}
|
|
1056
|
+
trailingCutoff = totalTimelineUnits;
|
|
1057
|
+
orderedTimelineSegments.push({
|
|
1058
|
+
type: "block",
|
|
1059
|
+
block,
|
|
1060
|
+
index
|
|
1061
|
+
});
|
|
1062
|
+
textCursor = Math.max(textCursor, anchor);
|
|
1063
|
+
}
|
|
1064
|
+
const trailingTextSegment = buildTextSegment(textCursor, trailingCutoff);
|
|
1065
|
+
if (trailingTextSegment) {
|
|
1066
|
+
orderedTimelineSegments.push(trailingTextSegment);
|
|
1067
|
+
}
|
|
1068
|
+
return orderedTimelineSegments;
|
|
1069
|
+
};
|
|
1070
|
+
|
|
1071
|
+
// src/components/chat-thread/hooks/use-timeline-block-anchors.ts
|
|
1072
|
+
var useTimelineBlockAnchors = ({
|
|
1073
|
+
blocks,
|
|
1074
|
+
displayedTimelineTextLength,
|
|
1075
|
+
isAssistantStreaming,
|
|
1076
|
+
message,
|
|
1077
|
+
messageRenderOrder
|
|
1078
|
+
}) => {
|
|
1079
|
+
const [timelineBlockAnchors, setTimelineBlockAnchors] = (0, import_react6.useState)({});
|
|
1080
|
+
const [visibleTimelineBlockKeys, setVisibleTimelineBlockKeys] = (0, import_react6.useState)({});
|
|
1081
|
+
const currentTimelineBlockKeys = (0, import_react6.useMemo)(
|
|
1082
|
+
() => blocks.map((block, index) => getTimelineBlockKey(block, index)).filter((blockKey) => Boolean(blockKey)),
|
|
1083
|
+
[blocks]
|
|
1084
|
+
);
|
|
1085
|
+
const timelineTextStreamLength = (0, import_react6.useMemo)(
|
|
1086
|
+
() => getTimelineDisplayUnitCount(getTimelineTextStream(message.content, blocks)),
|
|
1087
|
+
[blocks, message.content]
|
|
1088
|
+
);
|
|
1089
|
+
const previousTimelineStateRef = (0, import_react6.useRef)({
|
|
1090
|
+
messageId: message.id,
|
|
1091
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1092
|
+
textLength: timelineTextStreamLength
|
|
1093
|
+
});
|
|
1094
|
+
const effectiveTimelineBlockAnchors = (0, import_react6.useMemo)(() => {
|
|
1095
|
+
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
1096
|
+
return timelineBlockAnchors;
|
|
1097
|
+
}
|
|
1098
|
+
const previousTimelineState = previousTimelineStateRef.current;
|
|
1099
|
+
const previousBlockKeys = new Set(previousTimelineState.blockKeys);
|
|
1100
|
+
return currentTimelineBlockKeys.reduce(
|
|
1101
|
+
(acc, blockKey) => {
|
|
1102
|
+
const existingAnchor = timelineBlockAnchors[blockKey];
|
|
1103
|
+
if (existingAnchor !== void 0) {
|
|
1104
|
+
acc[blockKey] = existingAnchor;
|
|
1105
|
+
return acc;
|
|
1106
|
+
}
|
|
1107
|
+
if (!previousBlockKeys.has(blockKey)) {
|
|
1108
|
+
acc[blockKey] = timelineTextStreamLength;
|
|
1109
|
+
}
|
|
1110
|
+
return acc;
|
|
1111
|
+
},
|
|
1112
|
+
{ ...timelineBlockAnchors }
|
|
1113
|
+
);
|
|
1114
|
+
}, [
|
|
1115
|
+
currentTimelineBlockKeys,
|
|
1116
|
+
isAssistantStreaming,
|
|
1117
|
+
messageRenderOrder,
|
|
1118
|
+
timelineBlockAnchors,
|
|
1119
|
+
timelineTextStreamLength
|
|
1120
|
+
]);
|
|
1121
|
+
(0, import_react6.useEffect)(() => {
|
|
1122
|
+
const previousTimelineState = previousTimelineStateRef.current;
|
|
1123
|
+
if (previousTimelineState.messageId !== message.id) {
|
|
1124
|
+
if (Object.keys(timelineBlockAnchors).length > 0) {
|
|
1125
|
+
setTimelineBlockAnchors({});
|
|
1126
|
+
}
|
|
1127
|
+
if (Object.keys(visibleTimelineBlockKeys).length > 0) {
|
|
1128
|
+
setVisibleTimelineBlockKeys({});
|
|
1129
|
+
}
|
|
1130
|
+
previousTimelineStateRef.current = {
|
|
1131
|
+
messageId: message.id,
|
|
1132
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1133
|
+
textLength: timelineTextStreamLength
|
|
1134
|
+
};
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
if (messageRenderOrder === "timeline" && isAssistantStreaming) {
|
|
1138
|
+
const previousBlockKeys = new Set(previousTimelineState.blockKeys);
|
|
1139
|
+
const nextAnchors = currentTimelineBlockKeys.reduce(
|
|
1140
|
+
(acc, blockKey) => {
|
|
1141
|
+
const existingAnchor = timelineBlockAnchors[blockKey];
|
|
1142
|
+
if (existingAnchor !== void 0) {
|
|
1143
|
+
acc[blockKey] = existingAnchor;
|
|
1144
|
+
return acc;
|
|
1145
|
+
}
|
|
1146
|
+
if (!previousBlockKeys.has(blockKey)) {
|
|
1147
|
+
acc[blockKey] = timelineTextStreamLength;
|
|
1148
|
+
}
|
|
1149
|
+
return acc;
|
|
1150
|
+
},
|
|
1151
|
+
{}
|
|
1152
|
+
);
|
|
1153
|
+
const hasAnchorChanged = Object.keys(nextAnchors).length !== Object.keys(timelineBlockAnchors).length || Object.entries(nextAnchors).some(
|
|
1154
|
+
([blockKey, anchor]) => timelineBlockAnchors[blockKey] !== anchor
|
|
1155
|
+
);
|
|
1156
|
+
if (hasAnchorChanged) {
|
|
1157
|
+
setTimelineBlockAnchors(nextAnchors);
|
|
1158
|
+
}
|
|
1159
|
+
} else if (messageRenderOrder !== "timeline" && Object.keys(timelineBlockAnchors).length > 0) {
|
|
1160
|
+
setTimelineBlockAnchors({});
|
|
1161
|
+
}
|
|
1162
|
+
previousTimelineStateRef.current = {
|
|
1163
|
+
messageId: message.id,
|
|
1164
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1165
|
+
textLength: timelineTextStreamLength
|
|
1166
|
+
};
|
|
1167
|
+
}, [
|
|
1168
|
+
currentTimelineBlockKeys,
|
|
1169
|
+
isAssistantStreaming,
|
|
1170
|
+
message.id,
|
|
1171
|
+
message.content,
|
|
1172
|
+
messageRenderOrder,
|
|
1173
|
+
timelineBlockAnchors,
|
|
1174
|
+
timelineTextStreamLength,
|
|
1175
|
+
visibleTimelineBlockKeys
|
|
1176
|
+
]);
|
|
1177
|
+
(0, import_react6.useEffect)(() => {
|
|
1178
|
+
if (messageRenderOrder !== "timeline") {
|
|
1179
|
+
if (Object.keys(visibleTimelineBlockKeys).length > 0) {
|
|
1180
|
+
setVisibleTimelineBlockKeys({});
|
|
1181
|
+
}
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
const nextVisibleBlockKeys = currentTimelineBlockKeys.reduce(
|
|
1185
|
+
(acc, blockKey) => {
|
|
1186
|
+
if (visibleTimelineBlockKeys[blockKey]) {
|
|
1187
|
+
acc[blockKey] = true;
|
|
1188
|
+
return acc;
|
|
1189
|
+
}
|
|
1190
|
+
const anchor = effectiveTimelineBlockAnchors[blockKey];
|
|
1191
|
+
if (anchor !== void 0 && anchor <= displayedTimelineTextLength) {
|
|
1192
|
+
acc[blockKey] = true;
|
|
1193
|
+
}
|
|
1194
|
+
return acc;
|
|
1195
|
+
},
|
|
1196
|
+
{}
|
|
1197
|
+
);
|
|
1198
|
+
const hasVisibleBlockChanged = Object.keys(nextVisibleBlockKeys).length !== Object.keys(visibleTimelineBlockKeys).length || Object.keys(nextVisibleBlockKeys).some((blockKey) => !visibleTimelineBlockKeys[blockKey]);
|
|
1199
|
+
if (hasVisibleBlockChanged) {
|
|
1200
|
+
setVisibleTimelineBlockKeys(nextVisibleBlockKeys);
|
|
1201
|
+
}
|
|
1202
|
+
}, [
|
|
1203
|
+
currentTimelineBlockKeys,
|
|
1204
|
+
displayedTimelineTextLength,
|
|
1205
|
+
effectiveTimelineBlockAnchors,
|
|
1206
|
+
messageRenderOrder,
|
|
1207
|
+
timelineBlockAnchors,
|
|
1208
|
+
visibleTimelineBlockKeys
|
|
1209
|
+
]);
|
|
1210
|
+
return {
|
|
1211
|
+
timelineBlockAnchors: effectiveTimelineBlockAnchors,
|
|
1212
|
+
visibleTimelineBlockKeys
|
|
1213
|
+
};
|
|
1214
|
+
};
|
|
1215
|
+
|
|
907
1216
|
// src/components/chat-thread/components/pde-ai-execution-confirmation-card.tsx
|
|
908
1217
|
var import_styled = __toESM(require("@emotion/styled"));
|
|
909
1218
|
var import_jsx_runtime2 = require("@emotion/react/jsx-runtime");
|
|
@@ -1114,7 +1423,7 @@ var Value = import_styled3.default.span`
|
|
|
1114
1423
|
`;
|
|
1115
1424
|
|
|
1116
1425
|
// src/components/chat-thread/components/pde-ai-questionnaire-card.tsx
|
|
1117
|
-
var
|
|
1426
|
+
var import_react7 = require("react");
|
|
1118
1427
|
var import_styled4 = __toESM(require("@emotion/styled"));
|
|
1119
1428
|
var import_jsx_runtime5 = require("@emotion/react/jsx-runtime");
|
|
1120
1429
|
var OTHER_OPTION_VALUE = "__other__";
|
|
@@ -1216,10 +1525,10 @@ var PDEAIQuestionnaireCardInner = ({
|
|
|
1216
1525
|
interactive = false,
|
|
1217
1526
|
onSubmit
|
|
1218
1527
|
}) => {
|
|
1219
|
-
const [answers, setAnswers] = (0,
|
|
1528
|
+
const [answers, setAnswers] = (0, import_react7.useState)(
|
|
1220
1529
|
() => createInitialAnswers(questionnaire)
|
|
1221
1530
|
);
|
|
1222
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
1531
|
+
const [errorMessage, setErrorMessage] = (0, import_react7.useState)(null);
|
|
1223
1532
|
const handleSubmit = () => {
|
|
1224
1533
|
const missingQuestions = questionnaire.questions.filter(
|
|
1225
1534
|
(question) => question.required && isMissingRequiredAnswer(question, answers)
|
|
@@ -1655,7 +1964,7 @@ var Detail = import_styled5.default.li`
|
|
|
1655
1964
|
|
|
1656
1965
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
1657
1966
|
var import_styled6 = __toESM(require("@emotion/styled"));
|
|
1658
|
-
var
|
|
1967
|
+
var import_react8 = require("react");
|
|
1659
1968
|
var import_jsx_runtime7 = require("@emotion/react/jsx-runtime");
|
|
1660
1969
|
var Overlay = import_styled6.default.div`
|
|
1661
1970
|
position: fixed;
|
|
@@ -1674,8 +1983,8 @@ var Img = import_styled6.default.img`
|
|
|
1674
1983
|
border-radius: 4px;
|
|
1675
1984
|
`;
|
|
1676
1985
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
1677
|
-
const overlayRef = (0,
|
|
1678
|
-
(0,
|
|
1986
|
+
const overlayRef = (0, import_react8.useRef)(null);
|
|
1987
|
+
(0, import_react8.useEffect)(() => {
|
|
1679
1988
|
const handleKey = (e) => {
|
|
1680
1989
|
if (e.key === "Escape")
|
|
1681
1990
|
onClose();
|
|
@@ -1683,7 +1992,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
1683
1992
|
document.addEventListener("keydown", handleKey);
|
|
1684
1993
|
return () => document.removeEventListener("keydown", handleKey);
|
|
1685
1994
|
}, [onClose]);
|
|
1686
|
-
(0,
|
|
1995
|
+
(0, import_react8.useEffect)(() => {
|
|
1687
1996
|
overlayRef.current?.focus();
|
|
1688
1997
|
}, []);
|
|
1689
1998
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -1846,9 +2155,16 @@ var ChatMessageItemView = ({
|
|
|
1846
2155
|
onQuestionnaireSubmit,
|
|
1847
2156
|
renderMessageBlock
|
|
1848
2157
|
}) => {
|
|
1849
|
-
const { labels } = useChatContext();
|
|
1850
|
-
const [activeImage, setActiveImage] = (0,
|
|
1851
|
-
const {
|
|
2158
|
+
const { labels, messageRenderOrder = "blocks-first" } = useChatContext();
|
|
2159
|
+
const [activeImage, setActiveImage] = (0, import_react9.useState)(void 0);
|
|
2160
|
+
const {
|
|
2161
|
+
displayedBlocks,
|
|
2162
|
+
displayedContent,
|
|
2163
|
+
freshContent,
|
|
2164
|
+
isAssistantStreaming,
|
|
2165
|
+
isFreshBlockActive,
|
|
2166
|
+
settledContent
|
|
2167
|
+
} = useChatMessageReveal(message);
|
|
1852
2168
|
const isStoppedAssistant = message.role === "assistant" && message.status === "stopped";
|
|
1853
2169
|
const attachments = message.attachments ?? [];
|
|
1854
2170
|
const blocks = message.blocks ?? [];
|
|
@@ -1860,6 +2176,22 @@ var ChatMessageItemView = ({
|
|
|
1860
2176
|
const canSubmitConfirmation = isPlanMode && typeof onConfirmationSubmit === "function";
|
|
1861
2177
|
const canSubmitQuestionnaire = isPlanMode && typeof onQuestionnaireSubmit === "function";
|
|
1862
2178
|
const shouldShowStreamingCaret = isAssistantStreaming && (!shouldRenderStructuredBlocks || hasTextContent);
|
|
2179
|
+
const timelineConsumedText = messageRenderOrder === "timeline" ? getTimelineConsumedText(blocks) : "";
|
|
2180
|
+
const hasConsumedTimelineText = timelineConsumedText.length > 0 && displayedContent.startsWith(timelineConsumedText);
|
|
2181
|
+
const timelineDisplayedContent = hasConsumedTimelineText ? displayedContent.slice(timelineConsumedText.length) : displayedContent;
|
|
2182
|
+
const timelineTextDisplay = buildTimelineTextDisplay(
|
|
2183
|
+
timelineDisplayedContent,
|
|
2184
|
+
isAssistantStreaming,
|
|
2185
|
+
isFreshBlockActive
|
|
2186
|
+
);
|
|
2187
|
+
const displayedTimelineTextLength = getTimelineDisplayUnitCount(timelineDisplayedContent);
|
|
2188
|
+
const { timelineBlockAnchors, visibleTimelineBlockKeys } = useTimelineBlockAnchors({
|
|
2189
|
+
blocks,
|
|
2190
|
+
displayedTimelineTextLength,
|
|
2191
|
+
isAssistantStreaming,
|
|
2192
|
+
message,
|
|
2193
|
+
messageRenderOrder
|
|
2194
|
+
});
|
|
1863
2195
|
const renderChatMessageBlock = (block, index) => {
|
|
1864
2196
|
switch (block.type) {
|
|
1865
2197
|
case "markdown":
|
|
@@ -1873,11 +2205,11 @@ var ChatMessageItemView = ({
|
|
|
1873
2205
|
`markdown-${index}`
|
|
1874
2206
|
);
|
|
1875
2207
|
case "notice":
|
|
1876
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PDEAINoticeCard, { text: block.text, tone: block.tone }) }, `notice-${index}`);
|
|
1877
2209
|
case "parameter_summary":
|
|
1878
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PDEAIParameterSummaryCard, { items: block.items }) }, `parameter-summary-${index}`);
|
|
1879
2211
|
case "confirmation_card":
|
|
1880
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1881
2213
|
PDEAIExecutionConfirmationCard,
|
|
1882
2214
|
{
|
|
1883
2215
|
proposal: block.proposal,
|
|
@@ -1890,9 +2222,9 @@ var ChatMessageItemView = ({
|
|
|
1890
2222
|
}
|
|
1891
2223
|
) }, `confirmation-card-${index}`);
|
|
1892
2224
|
case "result_summary":
|
|
1893
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PDEAIResultSummaryCard, { summary: block.summary }) }, `result-summary-${index}`);
|
|
1894
2226
|
case "questionnaire":
|
|
1895
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1896
2228
|
PDEAIQuestionnaireCard,
|
|
1897
2229
|
{
|
|
1898
2230
|
questionnaire: block.questionnaire,
|
|
@@ -1904,7 +2236,7 @@ var ChatMessageItemView = ({
|
|
|
1904
2236
|
}
|
|
1905
2237
|
) }, `questionnaire-${index}`);
|
|
1906
2238
|
case "custom":
|
|
1907
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: renderMessageBlock?.({
|
|
1908
2240
|
block,
|
|
1909
2241
|
index,
|
|
1910
2242
|
message,
|
|
@@ -1916,19 +2248,69 @@ var ChatMessageItemView = ({
|
|
|
1916
2248
|
return null;
|
|
1917
2249
|
}
|
|
1918
2250
|
};
|
|
1919
|
-
const renderTextContent = () =>
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
2251
|
+
const renderTextContent = (options) => {
|
|
2252
|
+
const textContent = options?.content ?? displayedContent;
|
|
2253
|
+
const localTimelineTextDisplay = options?.displayedBlocks ? void 0 : options?.useTimelineSegmentation && options.content !== void 0 ? buildTimelineTextDisplay(options.content, isAssistantStreaming, isFreshBlockActive) : void 0;
|
|
2254
|
+
const textBlocks = options?.displayedBlocks ?? localTimelineTextDisplay?.displayedBlocks ?? displayedBlocks;
|
|
2255
|
+
const settledText = localTimelineTextDisplay?.settledContent ?? settledContent;
|
|
2256
|
+
const freshText = localTimelineTextDisplay?.freshContent ?? freshContent;
|
|
2257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
2258
|
+
textBlocks.filter((block) => block.content).map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2259
|
+
ContentBlock,
|
|
2260
|
+
{
|
|
2261
|
+
"data-testid": block.tone === "fresh" ? "chat-message-fresh-block" : "chat-message-settled-block",
|
|
2262
|
+
"data-block-tone": block.tone,
|
|
2263
|
+
"data-block-index": index,
|
|
2264
|
+
children: renderMarkdownContent(block.content)
|
|
2265
|
+
},
|
|
2266
|
+
`${block.tone}-${index}`
|
|
2267
|
+
)),
|
|
2268
|
+
!textBlocks.some((block) => block.content) && !settledText && !freshText && Boolean(textContent) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(textContent) }) : null
|
|
2269
|
+
] });
|
|
2270
|
+
};
|
|
2271
|
+
const renderStaticTextSegment = (content) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(content) });
|
|
2272
|
+
const bodySegments = (() => {
|
|
2273
|
+
if (!shouldRenderStructuredBlocks && hasTextContent) {
|
|
2274
|
+
return [{ type: "text" }];
|
|
2275
|
+
}
|
|
2276
|
+
if (!shouldRenderStructuredBlocks) {
|
|
2277
|
+
return [];
|
|
2278
|
+
}
|
|
2279
|
+
if (messageRenderOrder === "timeline" && hasTextContent) {
|
|
2280
|
+
const hasAnchoredStructuredBlocks = blocks.some((block, index) => {
|
|
2281
|
+
const blockKey = getTimelineBlockKey(block, index);
|
|
2282
|
+
return blockKey ? timelineBlockAnchors[blockKey] !== void 0 : false;
|
|
2283
|
+
});
|
|
2284
|
+
if (hasAnchoredStructuredBlocks) {
|
|
2285
|
+
return buildAnchoredTimelineSegments({
|
|
2286
|
+
blocks,
|
|
2287
|
+
timelineBlockAnchors,
|
|
2288
|
+
timelineDisplayedBlocks: timelineTextDisplay.displayedBlocks,
|
|
2289
|
+
visibleTimelineBlockKeys
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
const orderedTimelineSegments = blocks.map(
|
|
2293
|
+
(block, index) => block.type === "markdown" ? {
|
|
2294
|
+
type: "markdown",
|
|
2295
|
+
content: block.text
|
|
2296
|
+
} : {
|
|
2297
|
+
type: "block",
|
|
2298
|
+
block,
|
|
2299
|
+
index
|
|
2300
|
+
}
|
|
2301
|
+
);
|
|
2302
|
+
if (!timelineConsumedText) {
|
|
2303
|
+
return displayedContent ? [{ type: "text", content: displayedContent }, ...orderedTimelineSegments] : orderedTimelineSegments;
|
|
2304
|
+
}
|
|
2305
|
+
return timelineDisplayedContent ? [...orderedTimelineSegments, { type: "text", content: timelineDisplayedContent }] : orderedTimelineSegments;
|
|
2306
|
+
}
|
|
2307
|
+
const orderedBlocks = blocks.map((block, index) => ({
|
|
2308
|
+
type: "block",
|
|
2309
|
+
block,
|
|
2310
|
+
index
|
|
2311
|
+
}));
|
|
2312
|
+
return hasTextContent ? [...orderedBlocks, { type: "text" }] : orderedBlocks;
|
|
2313
|
+
})();
|
|
1932
2314
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1933
2315
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
|
|
1934
2316
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Header2, { children: [
|
|
@@ -1947,17 +2329,18 @@ var ChatMessageItemView = ({
|
|
|
1947
2329
|
isStoppedAssistant ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StatusTag, { "data-testid": "chat-message-stopped-tag", children: labels.stoppedResponse }) : null
|
|
1948
2330
|
] }),
|
|
1949
2331
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Content, { "data-testid": "chat-message-content", children: [
|
|
1950
|
-
shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2332
|
+
shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentStack, { "data-testid": "chat-message-body-stack", children: bodySegments.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2333
|
+
ContentSegment,
|
|
2334
|
+
{
|
|
2335
|
+
"data-testid": "chat-message-content-segment",
|
|
2336
|
+
children: segment.type === "block" ? renderChatMessageBlock(segment.block, segment.index) : segment.type === "text" ? segment.content !== void 0 ? segment.useTimelineSegmentation ? renderTextContent({
|
|
2337
|
+
content: segment.content,
|
|
2338
|
+
displayedBlocks: segment.displayedBlocks,
|
|
2339
|
+
useTimelineSegmentation: true
|
|
2340
|
+
}) : renderStaticTextSegment(segment.content) : renderTextContent() : renderStaticTextSegment(segment.content)
|
|
2341
|
+
},
|
|
2342
|
+
segment.type === "text" ? `text-${index}` : segment.type === "markdown" ? `markdown-${index}` : `${segment.block.type}-${segment.index}`
|
|
2343
|
+
)) }) : null,
|
|
1961
2344
|
attachments.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AttachmentGrid, { "data-testid": "chat-message-attachment-grid", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1962
2345
|
AttachmentButton,
|
|
1963
2346
|
{
|
|
@@ -1984,7 +2367,7 @@ var ChatMessageItemView = ({
|
|
|
1984
2367
|
) : null
|
|
1985
2368
|
] });
|
|
1986
2369
|
};
|
|
1987
|
-
var ChatMessageItem = (0,
|
|
2370
|
+
var ChatMessageItem = (0, import_react9.memo)(
|
|
1988
2371
|
ChatMessageItemView,
|
|
1989
2372
|
(previousProps, nextProps) => isSameMessage(
|
|
1990
2373
|
previousProps.message,
|
|
@@ -2129,7 +2512,7 @@ var AttachmentImage = import_styled7.default.img`
|
|
|
2129
2512
|
var TableWrapper = import_styled7.default.div`
|
|
2130
2513
|
overflow-x: auto;
|
|
2131
2514
|
`;
|
|
2132
|
-
var caretBlink =
|
|
2515
|
+
var caretBlink = import_react10.keyframes`
|
|
2133
2516
|
0%, 49% {
|
|
2134
2517
|
opacity: 1;
|
|
2135
2518
|
}
|
|
@@ -2138,7 +2521,7 @@ var caretBlink = import_react9.keyframes`
|
|
|
2138
2521
|
opacity: 0.2;
|
|
2139
2522
|
}
|
|
2140
2523
|
`;
|
|
2141
|
-
var shimmer =
|
|
2524
|
+
var shimmer = import_react10.keyframes`
|
|
2142
2525
|
0%, 100% {
|
|
2143
2526
|
transform: scale(0.9) rotate(0deg);
|
|
2144
2527
|
opacity: 0.55;
|
|
@@ -2349,18 +2732,18 @@ var ChatThreadView = ({
|
|
|
2349
2732
|
onQuestionnaireSubmit,
|
|
2350
2733
|
renderMessageBlock
|
|
2351
2734
|
}) => {
|
|
2352
|
-
const containerRef = (0,
|
|
2353
|
-
const conversationTurns = (0,
|
|
2735
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
2736
|
+
const conversationTurns = (0, import_react11.useMemo)(
|
|
2354
2737
|
() => groupConversationTurns(historyMessages, streamingMessage),
|
|
2355
2738
|
[historyMessages, streamingMessage]
|
|
2356
2739
|
);
|
|
2357
2740
|
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
2358
2741
|
const previousTurns = conversationTurns.slice(0, -1);
|
|
2359
2742
|
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
2360
|
-
const latestUserMessageRef = (0,
|
|
2361
|
-
const reservedSpaceFrameRef = (0,
|
|
2362
|
-
const [latestTurnMinHeight, setLatestTurnMinHeight] = (0,
|
|
2363
|
-
const measureLatestTurnMinHeight = (0,
|
|
2743
|
+
const latestUserMessageRef = (0, import_react11.useRef)(null);
|
|
2744
|
+
const reservedSpaceFrameRef = (0, import_react11.useRef)(null);
|
|
2745
|
+
const [latestTurnMinHeight, setLatestTurnMinHeight] = (0, import_react11.useState)(0);
|
|
2746
|
+
const measureLatestTurnMinHeight = (0, import_react11.useCallback)(() => {
|
|
2364
2747
|
const container = containerRef.current;
|
|
2365
2748
|
if (!container)
|
|
2366
2749
|
return;
|
|
@@ -2370,7 +2753,7 @@ var ChatThreadView = ({
|
|
|
2370
2753
|
const nextMinHeight = Math.max(0, container.clientHeight - paddingTop - paddingBottom);
|
|
2371
2754
|
setLatestTurnMinHeight((current) => current === nextMinHeight ? current : nextMinHeight);
|
|
2372
2755
|
}, []);
|
|
2373
|
-
const scrollLatestUserMessageToTop = (0,
|
|
2756
|
+
const scrollLatestUserMessageToTop = (0, import_react11.useCallback)(() => {
|
|
2374
2757
|
const container = containerRef.current;
|
|
2375
2758
|
const target = latestUserMessageRef.current;
|
|
2376
2759
|
if (!container || !target)
|
|
@@ -2390,7 +2773,7 @@ var ChatThreadView = ({
|
|
|
2390
2773
|
}
|
|
2391
2774
|
container.scrollTop = nextScrollTop;
|
|
2392
2775
|
}, []);
|
|
2393
|
-
(0,
|
|
2776
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
2394
2777
|
if (reservedSpaceFrameRef.current !== null) {
|
|
2395
2778
|
window.cancelAnimationFrame(reservedSpaceFrameRef.current);
|
|
2396
2779
|
reservedSpaceFrameRef.current = null;
|
|
@@ -2419,7 +2802,7 @@ var ChatThreadView = ({
|
|
|
2419
2802
|
}
|
|
2420
2803
|
};
|
|
2421
2804
|
}, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
|
|
2422
|
-
(0,
|
|
2805
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
2423
2806
|
if (!latestUserMessageId)
|
|
2424
2807
|
return;
|
|
2425
2808
|
const handleResize = () => {
|
|
@@ -2507,13 +2890,13 @@ var ChatThread = () => {
|
|
|
2507
2890
|
const updateQA = useChatStore((s) => s.updateQuestionnaireAnswers);
|
|
2508
2891
|
const clearSessionError = useChatStore((s) => s.clearSessionError);
|
|
2509
2892
|
const { sendRef, retryRef, renderMessageBlock, labels } = useChatContext();
|
|
2510
|
-
const handleRetry = (0,
|
|
2893
|
+
const handleRetry = (0, import_react11.useCallback)(() => {
|
|
2511
2894
|
if (!activeSessionId)
|
|
2512
2895
|
return;
|
|
2513
2896
|
clearSessionError(activeSessionId);
|
|
2514
2897
|
void retryRef.current();
|
|
2515
2898
|
}, [activeSessionId, clearSessionError, retryRef]);
|
|
2516
|
-
const handleQuestionnaireSubmit = (0,
|
|
2899
|
+
const handleQuestionnaireSubmit = (0, import_react11.useCallback)(
|
|
2517
2900
|
(submission) => {
|
|
2518
2901
|
if (activeSessionId && submission.sourceMessageId) {
|
|
2519
2902
|
updateQA(
|
|
@@ -2527,7 +2910,7 @@ var ChatThread = () => {
|
|
|
2527
2910
|
},
|
|
2528
2911
|
[activeSessionId, updateQA, sendRef]
|
|
2529
2912
|
);
|
|
2530
|
-
const handleConfirmationSubmit = (0,
|
|
2913
|
+
const handleConfirmationSubmit = (0, import_react11.useCallback)(
|
|
2531
2914
|
(submission) => {
|
|
2532
2915
|
void sendRef.current(submission.content);
|
|
2533
2916
|
},
|
|
@@ -2612,7 +2995,7 @@ var RetryButton = import_styled9.default.button`
|
|
|
2612
2995
|
`;
|
|
2613
2996
|
|
|
2614
2997
|
// src/components/chat-composer/index.tsx
|
|
2615
|
-
var
|
|
2998
|
+
var import_react15 = require("react");
|
|
2616
2999
|
var import_styled14 = __toESM(require("@emotion/styled"));
|
|
2617
3000
|
|
|
2618
3001
|
// src/components/chat-composer/lib/chat-composer.ts
|
|
@@ -2724,10 +3107,10 @@ var resolveSendSession = ({
|
|
|
2724
3107
|
};
|
|
2725
3108
|
|
|
2726
3109
|
// src/components/chat-composer/hooks/use-chat-composer.ts
|
|
2727
|
-
var
|
|
3110
|
+
var import_react13 = require("react");
|
|
2728
3111
|
|
|
2729
3112
|
// src/components/chat-composer/hooks/use-composer-attachments.ts
|
|
2730
|
-
var
|
|
3113
|
+
var import_react12 = require("react");
|
|
2731
3114
|
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
2732
3115
|
var MAX_COMPOSER_ATTACHMENTS = 10;
|
|
2733
3116
|
var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
|
|
@@ -2741,12 +3124,12 @@ var releaseComposerAttachments = (attachments) => {
|
|
|
2741
3124
|
attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
|
|
2742
3125
|
};
|
|
2743
3126
|
var useComposerAttachments = () => {
|
|
2744
|
-
const [attachments, setAttachments] = (0,
|
|
2745
|
-
const attachmentsRef = (0,
|
|
2746
|
-
(0,
|
|
3127
|
+
const [attachments, setAttachments] = (0, import_react12.useState)([]);
|
|
3128
|
+
const attachmentsRef = (0, import_react12.useRef)([]);
|
|
3129
|
+
(0, import_react12.useEffect)(() => {
|
|
2747
3130
|
attachmentsRef.current = attachments;
|
|
2748
3131
|
}, [attachments]);
|
|
2749
|
-
(0,
|
|
3132
|
+
(0, import_react12.useEffect)(
|
|
2750
3133
|
() => () => {
|
|
2751
3134
|
releaseComposerAttachments(attachmentsRef.current);
|
|
2752
3135
|
},
|
|
@@ -2859,10 +3242,10 @@ var useChatComposer = () => {
|
|
|
2859
3242
|
const clearSessionError = useChatStore((s) => s.clearSessionError);
|
|
2860
3243
|
const setPreferredMode = useChatStore((s) => s.setPreferredMode);
|
|
2861
3244
|
const setSessionMode = useChatStore((s) => s.setSessionMode);
|
|
2862
|
-
const [availableModels, setAvailableModels] = (0,
|
|
2863
|
-
const [isModelsLoading, setIsModelsLoading] = (0,
|
|
2864
|
-
const [isModelsError, setIsModelsError] = (0,
|
|
2865
|
-
const fetchModels = (0,
|
|
3245
|
+
const [availableModels, setAvailableModels] = (0, import_react13.useState)([]);
|
|
3246
|
+
const [isModelsLoading, setIsModelsLoading] = (0, import_react13.useState)(true);
|
|
3247
|
+
const [isModelsError, setIsModelsError] = (0, import_react13.useState)(false);
|
|
3248
|
+
const fetchModels = (0, import_react13.useCallback)(async () => {
|
|
2866
3249
|
setIsModelsLoading(true);
|
|
2867
3250
|
setIsModelsError(false);
|
|
2868
3251
|
try {
|
|
@@ -2874,31 +3257,31 @@ var useChatComposer = () => {
|
|
|
2874
3257
|
setIsModelsLoading(false);
|
|
2875
3258
|
}
|
|
2876
3259
|
}, [transport]);
|
|
2877
|
-
(0,
|
|
3260
|
+
(0, import_react13.useEffect)(() => {
|
|
2878
3261
|
void fetchModels();
|
|
2879
3262
|
}, [fetchModels]);
|
|
2880
3263
|
const hasModels = availableModels.length > 0;
|
|
2881
|
-
const [value, setValue] = (0,
|
|
2882
|
-
const [selectedModel, setSelectedModel] = (0,
|
|
2883
|
-
const [selectedMode, setSelectedModeLocal] = (0,
|
|
2884
|
-
const [attachmentNotice, setAttachmentNotice] = (0,
|
|
3264
|
+
const [value, setValue] = (0, import_react13.useState)("");
|
|
3265
|
+
const [selectedModel, setSelectedModel] = (0, import_react13.useState)("");
|
|
3266
|
+
const [selectedMode, setSelectedModeLocal] = (0, import_react13.useState)(DEFAULT_CHAT_AGENT_MODE);
|
|
3267
|
+
const [attachmentNotice, setAttachmentNotice] = (0, import_react13.useState)(null);
|
|
2885
3268
|
const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
|
|
2886
|
-
const abortControllerRef = (0,
|
|
2887
|
-
const stopRequestRef = (0,
|
|
2888
|
-
const lastRequestRef = (0,
|
|
2889
|
-
(0,
|
|
3269
|
+
const abortControllerRef = (0, import_react13.useRef)(null);
|
|
3270
|
+
const stopRequestRef = (0, import_react13.useRef)(null);
|
|
3271
|
+
const lastRequestRef = (0, import_react13.useRef)(null);
|
|
3272
|
+
(0, import_react13.useEffect)(() => {
|
|
2890
3273
|
setSelectedModel(
|
|
2891
3274
|
(current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
|
|
2892
3275
|
);
|
|
2893
3276
|
}, [availableModels, isModelsLoading]);
|
|
2894
|
-
(0,
|
|
3277
|
+
(0, import_react13.useEffect)(() => {
|
|
2895
3278
|
if (activeSession) {
|
|
2896
3279
|
setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
2897
3280
|
return;
|
|
2898
3281
|
}
|
|
2899
3282
|
setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
2900
3283
|
}, [activeSession, preferredMode]);
|
|
2901
|
-
(0,
|
|
3284
|
+
(0, import_react13.useEffect)(() => {
|
|
2902
3285
|
if (!attachmentNotice)
|
|
2903
3286
|
return;
|
|
2904
3287
|
const timeoutId = window.setTimeout(
|
|
@@ -2917,7 +3300,7 @@ var useChatComposer = () => {
|
|
|
2917
3300
|
stopRequestRef.current.timeoutId = null;
|
|
2918
3301
|
}
|
|
2919
3302
|
};
|
|
2920
|
-
const clearStopRequest = (0,
|
|
3303
|
+
const clearStopRequest = (0, import_react13.useCallback)((sessionId) => {
|
|
2921
3304
|
if (!stopRequestRef.current)
|
|
2922
3305
|
return;
|
|
2923
3306
|
if (sessionId && stopRequestRef.current.sessionId !== sessionId)
|
|
@@ -2925,7 +3308,7 @@ var useChatComposer = () => {
|
|
|
2925
3308
|
clearStopTimeout(sessionId);
|
|
2926
3309
|
stopRequestRef.current = null;
|
|
2927
3310
|
}, []);
|
|
2928
|
-
const finalizeStop = (0,
|
|
3311
|
+
const finalizeStop = (0, import_react13.useCallback)(
|
|
2929
3312
|
(sessionId) => {
|
|
2930
3313
|
if (stopRequestRef.current?.sessionId === sessionId) {
|
|
2931
3314
|
if (stopRequestRef.current.finalized)
|
|
@@ -2940,7 +3323,7 @@ var useChatComposer = () => {
|
|
|
2940
3323
|
},
|
|
2941
3324
|
[clearStopRequest, finalizeStoppedStreamingMessage]
|
|
2942
3325
|
);
|
|
2943
|
-
const runStream = (0,
|
|
3326
|
+
const runStream = (0, import_react13.useCallback)(
|
|
2944
3327
|
async ({
|
|
2945
3328
|
localSessionId,
|
|
2946
3329
|
sessionId,
|
|
@@ -3029,7 +3412,7 @@ var useChatComposer = () => {
|
|
|
3029
3412
|
setSessionError
|
|
3030
3413
|
]
|
|
3031
3414
|
);
|
|
3032
|
-
const send = (0,
|
|
3415
|
+
const send = (0, import_react13.useCallback)(
|
|
3033
3416
|
async (contentOverride) => {
|
|
3034
3417
|
const content = (contentOverride ?? value).trim();
|
|
3035
3418
|
const hasText = Boolean(content);
|
|
@@ -3177,14 +3560,14 @@ var useChatComposer = () => {
|
|
|
3177
3560
|
};
|
|
3178
3561
|
|
|
3179
3562
|
// src/components/chat-composer/components/chat-composer-attachment-list.tsx
|
|
3180
|
-
var
|
|
3563
|
+
var import_react14 = require("react");
|
|
3181
3564
|
var import_styled10 = __toESM(require("@emotion/styled"));
|
|
3182
3565
|
var import_jsx_runtime11 = require("@emotion/react/jsx-runtime");
|
|
3183
3566
|
var ChatComposerAttachmentList = ({
|
|
3184
3567
|
attachments,
|
|
3185
3568
|
onRemoveAttachment
|
|
3186
3569
|
}) => {
|
|
3187
|
-
const [activeImage, setActiveImage] = (0,
|
|
3570
|
+
const [activeImage, setActiveImage] = (0, import_react14.useState)(null);
|
|
3188
3571
|
if (!attachments.length) {
|
|
3189
3572
|
return null;
|
|
3190
3573
|
}
|
|
@@ -3676,7 +4059,7 @@ var ChatComposerView = ({
|
|
|
3676
4059
|
onStop,
|
|
3677
4060
|
onSend
|
|
3678
4061
|
}) => {
|
|
3679
|
-
const imageInputRef = (0,
|
|
4062
|
+
const imageInputRef = (0, import_react15.useRef)(null);
|
|
3680
4063
|
const canSend = canSendChatMessage({
|
|
3681
4064
|
value,
|
|
3682
4065
|
attachmentCount: attachments.length,
|
|
@@ -3788,7 +4171,7 @@ var ChatComposer = () => {
|
|
|
3788
4171
|
const { labels, sendRef, retryRef, enableImageAttachments } = useChatContext();
|
|
3789
4172
|
const { state, actions } = useChatComposer();
|
|
3790
4173
|
const { send, retry } = actions;
|
|
3791
|
-
(0,
|
|
4174
|
+
(0, import_react15.useEffect)(() => {
|
|
3792
4175
|
sendRef.current = send;
|
|
3793
4176
|
retryRef.current = async () => {
|
|
3794
4177
|
retry();
|
|
@@ -3909,10 +4292,10 @@ var AttachButton = import_styled14.default.button`
|
|
|
3909
4292
|
var import_styled16 = __toESM(require("@emotion/styled"));
|
|
3910
4293
|
|
|
3911
4294
|
// src/components/chat-conversation-list/components/chat-session-item.tsx
|
|
3912
|
-
var
|
|
4295
|
+
var import_react16 = require("react");
|
|
3913
4296
|
var import_styled15 = __toESM(require("@emotion/styled"));
|
|
3914
4297
|
var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
|
|
3915
|
-
var ChatSessionItem = (0,
|
|
4298
|
+
var ChatSessionItem = (0, import_react16.memo)(
|
|
3916
4299
|
({ session, isActive, modeLabel, onClick }) => {
|
|
3917
4300
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3918
4301
|
SessionButton,
|
|
@@ -4108,6 +4491,7 @@ var Workspace = import_styled17.default.section`
|
|
|
4108
4491
|
AiChat,
|
|
4109
4492
|
AiChatProvider,
|
|
4110
4493
|
CHAT_AGENT_MODES,
|
|
4494
|
+
CHAT_MESSAGE_RENDER_ORDERS,
|
|
4111
4495
|
ChatComposer,
|
|
4112
4496
|
ChatConversationList,
|
|
4113
4497
|
ChatThread,
|