@xinghunm/ai-chat 0.2.1 → 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 +755 -287
- package/dist/index.mjs +767 -300
- 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,
|
|
@@ -45,7 +46,7 @@ __export(src_exports, {
|
|
|
45
46
|
module.exports = __toCommonJS(src_exports);
|
|
46
47
|
|
|
47
48
|
// src/components/ai-chat/index.tsx
|
|
48
|
-
var
|
|
49
|
+
var import_styled17 = __toESM(require("@emotion/styled"));
|
|
49
50
|
var import_compass_ui4 = require("@xinghunm/compass-ui");
|
|
50
51
|
|
|
51
52
|
// src/components/ai-chat-provider/index.tsx
|
|
@@ -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,
|
|
@@ -637,7 +648,7 @@ var AiChatProvider = (props) => {
|
|
|
637
648
|
|
|
638
649
|
// src/components/chat-thread/index.tsx
|
|
639
650
|
var import_react11 = require("react");
|
|
640
|
-
var
|
|
651
|
+
var import_styled9 = __toESM(require("@emotion/styled"));
|
|
641
652
|
|
|
642
653
|
// src/context/use-chat-context.ts
|
|
643
654
|
var import_react3 = require("react");
|
|
@@ -655,27 +666,11 @@ var useChatStore = (selector) => {
|
|
|
655
666
|
|
|
656
667
|
// src/components/chat-thread/lib/chat-thread.ts
|
|
657
668
|
var CHAT_THREAD_SCROLL_TOP_GAP = 16;
|
|
658
|
-
var findLatestUserMessageId = (historyMessages) => {
|
|
659
|
-
for (let index = historyMessages.length - 1; index >= 0; index -= 1) {
|
|
660
|
-
if (historyMessages[index]?.role === "user") {
|
|
661
|
-
return historyMessages[index]?.id;
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
return void 0;
|
|
665
|
-
};
|
|
666
|
-
var calculateChatThreadScrollSpacerHeight = ({
|
|
667
|
-
containerClientHeight,
|
|
668
|
-
containerScrollHeight,
|
|
669
|
-
targetOffsetTop
|
|
670
|
-
}) => Math.max(
|
|
671
|
-
0,
|
|
672
|
-
targetOffsetTop - CHAT_THREAD_SCROLL_TOP_GAP - (containerScrollHeight - containerClientHeight)
|
|
673
|
-
);
|
|
674
669
|
|
|
675
670
|
// src/components/chat-thread/components/chat-message-item.tsx
|
|
676
|
-
var
|
|
671
|
+
var import_react9 = require("react");
|
|
677
672
|
var import_styled7 = __toESM(require("@emotion/styled"));
|
|
678
|
-
var
|
|
673
|
+
var import_react10 = require("@emotion/react");
|
|
679
674
|
var import_react_markdown = __toESM(require("react-markdown"));
|
|
680
675
|
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
681
676
|
var import_remark_math = __toESM(require("remark-math"));
|
|
@@ -902,11 +897,319 @@ var useChatMessageReveal = (message) => {
|
|
|
902
897
|
}, [batchedTargetUnitCount, displayedUnitCount, isAssistantStreaming, message.role]);
|
|
903
898
|
const settledContent = isFreshBlockActive ? contentBlocks.slice(0, -1).join("\n\n") : displayedContent;
|
|
904
899
|
const freshContent = isFreshBlockActive ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
|
|
900
|
+
const displayedBlocks = isAssistantStreaming && contentBlocks.length > 1 ? contentBlocks.map((content, index) => ({
|
|
901
|
+
content,
|
|
902
|
+
tone: isFreshBlockActive && index === contentBlocks.length - 1 ? "fresh" : "settled"
|
|
903
|
+
})) : [
|
|
904
|
+
{
|
|
905
|
+
content: displayedContent,
|
|
906
|
+
tone: "settled"
|
|
907
|
+
}
|
|
908
|
+
];
|
|
905
909
|
return {
|
|
906
910
|
isAssistantStreaming,
|
|
911
|
+
isFreshBlockActive,
|
|
907
912
|
displayedContent,
|
|
908
913
|
settledContent,
|
|
909
|
-
freshContent
|
|
914
|
+
freshContent,
|
|
915
|
+
displayedBlocks
|
|
916
|
+
};
|
|
917
|
+
};
|
|
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
|
|
910
1213
|
};
|
|
911
1214
|
};
|
|
912
1215
|
|
|
@@ -1120,7 +1423,7 @@ var Value = import_styled3.default.span`
|
|
|
1120
1423
|
`;
|
|
1121
1424
|
|
|
1122
1425
|
// src/components/chat-thread/components/pde-ai-questionnaire-card.tsx
|
|
1123
|
-
var
|
|
1426
|
+
var import_react7 = require("react");
|
|
1124
1427
|
var import_styled4 = __toESM(require("@emotion/styled"));
|
|
1125
1428
|
var import_jsx_runtime5 = require("@emotion/react/jsx-runtime");
|
|
1126
1429
|
var OTHER_OPTION_VALUE = "__other__";
|
|
@@ -1222,10 +1525,10 @@ var PDEAIQuestionnaireCardInner = ({
|
|
|
1222
1525
|
interactive = false,
|
|
1223
1526
|
onSubmit
|
|
1224
1527
|
}) => {
|
|
1225
|
-
const [answers, setAnswers] = (0,
|
|
1528
|
+
const [answers, setAnswers] = (0, import_react7.useState)(
|
|
1226
1529
|
() => createInitialAnswers(questionnaire)
|
|
1227
1530
|
);
|
|
1228
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
1531
|
+
const [errorMessage, setErrorMessage] = (0, import_react7.useState)(null);
|
|
1229
1532
|
const handleSubmit = () => {
|
|
1230
1533
|
const missingQuestions = questionnaire.questions.filter(
|
|
1231
1534
|
(question) => question.required && isMissingRequiredAnswer(question, answers)
|
|
@@ -1661,7 +1964,7 @@ var Detail = import_styled5.default.li`
|
|
|
1661
1964
|
|
|
1662
1965
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
1663
1966
|
var import_styled6 = __toESM(require("@emotion/styled"));
|
|
1664
|
-
var
|
|
1967
|
+
var import_react8 = require("react");
|
|
1665
1968
|
var import_jsx_runtime7 = require("@emotion/react/jsx-runtime");
|
|
1666
1969
|
var Overlay = import_styled6.default.div`
|
|
1667
1970
|
position: fixed;
|
|
@@ -1680,8 +1983,8 @@ var Img = import_styled6.default.img`
|
|
|
1680
1983
|
border-radius: 4px;
|
|
1681
1984
|
`;
|
|
1682
1985
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
1683
|
-
const overlayRef = (0,
|
|
1684
|
-
(0,
|
|
1986
|
+
const overlayRef = (0, import_react8.useRef)(null);
|
|
1987
|
+
(0, import_react8.useEffect)(() => {
|
|
1685
1988
|
const handleKey = (e) => {
|
|
1686
1989
|
if (e.key === "Escape")
|
|
1687
1990
|
onClose();
|
|
@@ -1689,7 +1992,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
1689
1992
|
document.addEventListener("keydown", handleKey);
|
|
1690
1993
|
return () => document.removeEventListener("keydown", handleKey);
|
|
1691
1994
|
}, [onClose]);
|
|
1692
|
-
(0,
|
|
1995
|
+
(0, import_react8.useEffect)(() => {
|
|
1693
1996
|
overlayRef.current?.focus();
|
|
1694
1997
|
}, []);
|
|
1695
1998
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -1852,9 +2155,16 @@ var ChatMessageItemView = ({
|
|
|
1852
2155
|
onQuestionnaireSubmit,
|
|
1853
2156
|
renderMessageBlock
|
|
1854
2157
|
}) => {
|
|
1855
|
-
const { labels } = useChatContext();
|
|
1856
|
-
const [activeImage, setActiveImage] = (0,
|
|
1857
|
-
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);
|
|
1858
2168
|
const isStoppedAssistant = message.role === "assistant" && message.status === "stopped";
|
|
1859
2169
|
const attachments = message.attachments ?? [];
|
|
1860
2170
|
const blocks = message.blocks ?? [];
|
|
@@ -1866,6 +2176,22 @@ var ChatMessageItemView = ({
|
|
|
1866
2176
|
const canSubmitConfirmation = isPlanMode && typeof onConfirmationSubmit === "function";
|
|
1867
2177
|
const canSubmitQuestionnaire = isPlanMode && typeof onQuestionnaireSubmit === "function";
|
|
1868
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
|
+
});
|
|
1869
2195
|
const renderChatMessageBlock = (block, index) => {
|
|
1870
2196
|
switch (block.type) {
|
|
1871
2197
|
case "markdown":
|
|
@@ -1879,11 +2205,11 @@ var ChatMessageItemView = ({
|
|
|
1879
2205
|
`markdown-${index}`
|
|
1880
2206
|
);
|
|
1881
2207
|
case "notice":
|
|
1882
|
-
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}`);
|
|
1883
2209
|
case "parameter_summary":
|
|
1884
|
-
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}`);
|
|
1885
2211
|
case "confirmation_card":
|
|
1886
|
-
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)(
|
|
1887
2213
|
PDEAIExecutionConfirmationCard,
|
|
1888
2214
|
{
|
|
1889
2215
|
proposal: block.proposal,
|
|
@@ -1896,9 +2222,9 @@ var ChatMessageItemView = ({
|
|
|
1896
2222
|
}
|
|
1897
2223
|
) }, `confirmation-card-${index}`);
|
|
1898
2224
|
case "result_summary":
|
|
1899
|
-
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}`);
|
|
1900
2226
|
case "questionnaire":
|
|
1901
|
-
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)(
|
|
1902
2228
|
PDEAIQuestionnaireCard,
|
|
1903
2229
|
{
|
|
1904
2230
|
questionnaire: block.questionnaire,
|
|
@@ -1910,7 +2236,7 @@ var ChatMessageItemView = ({
|
|
|
1910
2236
|
}
|
|
1911
2237
|
) }, `questionnaire-${index}`);
|
|
1912
2238
|
case "custom":
|
|
1913
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: renderMessageBlock?.({
|
|
1914
2240
|
block,
|
|
1915
2241
|
index,
|
|
1916
2242
|
message,
|
|
@@ -1922,11 +2248,69 @@ var ChatMessageItemView = ({
|
|
|
1922
2248
|
return null;
|
|
1923
2249
|
}
|
|
1924
2250
|
};
|
|
1925
|
-
const renderTextContent = () =>
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
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
|
+
})();
|
|
1930
2314
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1931
2315
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
|
|
1932
2316
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Header2, { children: [
|
|
@@ -1945,17 +2329,18 @@ var ChatMessageItemView = ({
|
|
|
1945
2329
|
isStoppedAssistant ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StatusTag, { "data-testid": "chat-message-stopped-tag", children: labels.stoppedResponse }) : null
|
|
1946
2330
|
] }),
|
|
1947
2331
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Content, { "data-testid": "chat-message-content", children: [
|
|
1948
|
-
shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ (0, import_jsx_runtime8.
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
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,
|
|
1959
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)(
|
|
1960
2345
|
AttachmentButton,
|
|
1961
2346
|
{
|
|
@@ -1982,7 +2367,7 @@ var ChatMessageItemView = ({
|
|
|
1982
2367
|
) : null
|
|
1983
2368
|
] });
|
|
1984
2369
|
};
|
|
1985
|
-
var ChatMessageItem = (0,
|
|
2370
|
+
var ChatMessageItem = (0, import_react9.memo)(
|
|
1986
2371
|
ChatMessageItemView,
|
|
1987
2372
|
(previousProps, nextProps) => isSameMessage(
|
|
1988
2373
|
previousProps.message,
|
|
@@ -2127,7 +2512,7 @@ var AttachmentImage = import_styled7.default.img`
|
|
|
2127
2512
|
var TableWrapper = import_styled7.default.div`
|
|
2128
2513
|
overflow-x: auto;
|
|
2129
2514
|
`;
|
|
2130
|
-
var caretBlink =
|
|
2515
|
+
var caretBlink = import_react10.keyframes`
|
|
2131
2516
|
0%, 49% {
|
|
2132
2517
|
opacity: 1;
|
|
2133
2518
|
}
|
|
@@ -2136,7 +2521,7 @@ var caretBlink = import_react9.keyframes`
|
|
|
2136
2521
|
opacity: 0.2;
|
|
2137
2522
|
}
|
|
2138
2523
|
`;
|
|
2139
|
-
var shimmer =
|
|
2524
|
+
var shimmer = import_react10.keyframes`
|
|
2140
2525
|
0%, 100% {
|
|
2141
2526
|
transform: scale(0.9) rotate(0deg);
|
|
2142
2527
|
opacity: 0.55;
|
|
@@ -2189,65 +2574,21 @@ var StreamingCaret = import_styled7.default.span`
|
|
|
2189
2574
|
animation: ${caretBlink} 0.9s steps(1) infinite;
|
|
2190
2575
|
`;
|
|
2191
2576
|
|
|
2192
|
-
// src/components/chat-thread/components/chat-thread-
|
|
2193
|
-
var import_react10 = require("react");
|
|
2577
|
+
// src/components/chat-thread/components/chat-thread-empty-state.tsx
|
|
2194
2578
|
var import_styled8 = __toESM(require("@emotion/styled"));
|
|
2195
2579
|
var import_jsx_runtime9 = require("@emotion/react/jsx-runtime");
|
|
2196
|
-
var ChatThreadHistoryList = (0, import_react10.memo)(
|
|
2197
|
-
({
|
|
2198
|
-
mode,
|
|
2199
|
-
historyMessages,
|
|
2200
|
-
latestUserMessageId,
|
|
2201
|
-
latestUserMessageRef,
|
|
2202
|
-
onConfirmationSubmit,
|
|
2203
|
-
onQuestionnaireSubmit,
|
|
2204
|
-
renderMessageBlock
|
|
2205
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HistoryGroup, { "data-testid": "chat-thread-history", children: historyMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2206
|
-
MessageSlot,
|
|
2207
|
-
{
|
|
2208
|
-
ref: message.id === latestUserMessageId ? latestUserMessageRef : null,
|
|
2209
|
-
"data-testid": message.id === latestUserMessageId ? "chat-latest-user-anchor" : void 0,
|
|
2210
|
-
style: message.id === latestUserMessageId ? {
|
|
2211
|
-
scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px`
|
|
2212
|
-
} : void 0,
|
|
2213
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2214
|
-
ChatMessageItem,
|
|
2215
|
-
{
|
|
2216
|
-
mode,
|
|
2217
|
-
message,
|
|
2218
|
-
onConfirmationSubmit,
|
|
2219
|
-
onQuestionnaireSubmit,
|
|
2220
|
-
renderMessageBlock
|
|
2221
|
-
}
|
|
2222
|
-
)
|
|
2223
|
-
},
|
|
2224
|
-
message.id
|
|
2225
|
-
)) })
|
|
2226
|
-
);
|
|
2227
|
-
ChatThreadHistoryList.displayName = "ChatThreadHistoryList";
|
|
2228
|
-
var HistoryGroup = import_styled8.default.div`
|
|
2229
|
-
display: contents;
|
|
2230
|
-
`;
|
|
2231
|
-
var MessageSlot = import_styled8.default.div`
|
|
2232
|
-
display: flex;
|
|
2233
|
-
align-items: flex-start;
|
|
2234
|
-
`;
|
|
2235
|
-
|
|
2236
|
-
// src/components/chat-thread/components/chat-thread-empty-state.tsx
|
|
2237
|
-
var import_styled9 = __toESM(require("@emotion/styled"));
|
|
2238
|
-
var import_jsx_runtime10 = require("@emotion/react/jsx-runtime");
|
|
2239
2580
|
var ChatThreadEmptyState = () => {
|
|
2240
2581
|
const { labels } = useChatContext();
|
|
2241
|
-
return /* @__PURE__ */ (0,
|
|
2242
|
-
/* @__PURE__ */ (0,
|
|
2243
|
-
/* @__PURE__ */ (0,
|
|
2244
|
-
/* @__PURE__ */ (0,
|
|
2582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(EmptyShell, { "data-testid": "chat-empty-hero", children: [
|
|
2583
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(HeroMark, { children: [
|
|
2584
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroOrbit, {}),
|
|
2585
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroCore, { children: "AI" })
|
|
2245
2586
|
] }),
|
|
2246
|
-
/* @__PURE__ */ (0,
|
|
2247
|
-
/* @__PURE__ */ (0,
|
|
2587
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroTitle, { children: labels.emptyStateTitle }),
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(HeroSubtitle, { children: labels.emptyStateSubtitle })
|
|
2248
2589
|
] });
|
|
2249
2590
|
};
|
|
2250
|
-
var EmptyShell =
|
|
2591
|
+
var EmptyShell = import_styled8.default.div`
|
|
2251
2592
|
flex: 1;
|
|
2252
2593
|
min-height: 0;
|
|
2253
2594
|
display: flex;
|
|
@@ -2257,7 +2598,7 @@ var EmptyShell = import_styled9.default.div`
|
|
|
2257
2598
|
gap: 16px;
|
|
2258
2599
|
padding: 48px 24px 24px;
|
|
2259
2600
|
`;
|
|
2260
|
-
var HeroMark =
|
|
2601
|
+
var HeroMark = import_styled8.default.div`
|
|
2261
2602
|
position: relative;
|
|
2262
2603
|
width: 108px;
|
|
2263
2604
|
height: 108px;
|
|
@@ -2265,7 +2606,7 @@ var HeroMark = import_styled9.default.div`
|
|
|
2265
2606
|
display: grid;
|
|
2266
2607
|
place-items: center;
|
|
2267
2608
|
`;
|
|
2268
|
-
var HeroOrbit =
|
|
2609
|
+
var HeroOrbit = import_styled8.default.div`
|
|
2269
2610
|
position: absolute;
|
|
2270
2611
|
inset: 20px;
|
|
2271
2612
|
border-radius: 50%;
|
|
@@ -2288,7 +2629,7 @@ var HeroOrbit = import_styled9.default.div`
|
|
|
2288
2629
|
transform: rotate(-22deg);
|
|
2289
2630
|
}
|
|
2290
2631
|
`;
|
|
2291
|
-
var HeroCore =
|
|
2632
|
+
var HeroCore = import_styled8.default.div`
|
|
2292
2633
|
position: relative;
|
|
2293
2634
|
z-index: 1;
|
|
2294
2635
|
font-size: 28px;
|
|
@@ -2298,13 +2639,13 @@ var HeroCore = import_styled9.default.div`
|
|
|
2298
2639
|
color: rgba(242, 244, 255, 0.96);
|
|
2299
2640
|
text-shadow: 0 0 16px rgba(98, 116, 255, 0.65);
|
|
2300
2641
|
`;
|
|
2301
|
-
var HeroTitle =
|
|
2642
|
+
var HeroTitle = import_styled8.default.p`
|
|
2302
2643
|
margin: 0;
|
|
2303
2644
|
color: rgba(255, 255, 255, 0.88);
|
|
2304
2645
|
font-size: 16px;
|
|
2305
2646
|
line-height: 24px;
|
|
2306
2647
|
`;
|
|
2307
|
-
var HeroSubtitle =
|
|
2648
|
+
var HeroSubtitle = import_styled8.default.p`
|
|
2308
2649
|
margin: 0;
|
|
2309
2650
|
color: rgba(255, 255, 255, 0.72);
|
|
2310
2651
|
font-size: 14px;
|
|
@@ -2312,7 +2653,74 @@ var HeroSubtitle = import_styled9.default.p`
|
|
|
2312
2653
|
`;
|
|
2313
2654
|
|
|
2314
2655
|
// src/components/chat-thread/index.tsx
|
|
2315
|
-
var
|
|
2656
|
+
var import_jsx_runtime10 = require("@emotion/react/jsx-runtime");
|
|
2657
|
+
var renderChatMessage = ({
|
|
2658
|
+
message,
|
|
2659
|
+
mode,
|
|
2660
|
+
onConfirmationSubmit,
|
|
2661
|
+
onQuestionnaireSubmit,
|
|
2662
|
+
renderMessageBlock
|
|
2663
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2664
|
+
ChatMessageItem,
|
|
2665
|
+
{
|
|
2666
|
+
mode,
|
|
2667
|
+
message,
|
|
2668
|
+
onConfirmationSubmit,
|
|
2669
|
+
onQuestionnaireSubmit,
|
|
2670
|
+
renderMessageBlock
|
|
2671
|
+
}
|
|
2672
|
+
);
|
|
2673
|
+
var renderErrorState = ({
|
|
2674
|
+
error,
|
|
2675
|
+
onRetry,
|
|
2676
|
+
retryButtonLabel
|
|
2677
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ErrorState, { "data-testid": "chat-thread-error-state", children: [
|
|
2678
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorText, { children: error }),
|
|
2679
|
+
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorActions, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RetryButton, { type: "button", "data-testid": "chat-thread-retry", onClick: onRetry, children: retryButtonLabel }) }) : null
|
|
2680
|
+
] });
|
|
2681
|
+
var groupConversationTurns = (historyMessages, streamingMessage) => {
|
|
2682
|
+
const turns = [];
|
|
2683
|
+
let currentTurn = null;
|
|
2684
|
+
historyMessages.forEach((message) => {
|
|
2685
|
+
if (message.role === "user") {
|
|
2686
|
+
currentTurn = {
|
|
2687
|
+
id: message.id,
|
|
2688
|
+
userMessage: message,
|
|
2689
|
+
responseMessages: []
|
|
2690
|
+
};
|
|
2691
|
+
turns.push(currentTurn);
|
|
2692
|
+
return;
|
|
2693
|
+
}
|
|
2694
|
+
if (!currentTurn) {
|
|
2695
|
+
currentTurn = {
|
|
2696
|
+
id: `assistant-turn-${message.id}`,
|
|
2697
|
+
responseMessages: [message]
|
|
2698
|
+
};
|
|
2699
|
+
turns.push(currentTurn);
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
currentTurn.responseMessages.push(message);
|
|
2703
|
+
});
|
|
2704
|
+
if (!streamingMessage) {
|
|
2705
|
+
return turns;
|
|
2706
|
+
}
|
|
2707
|
+
const lastTurn = turns[turns.length - 1];
|
|
2708
|
+
if (lastTurn) {
|
|
2709
|
+
return [
|
|
2710
|
+
...turns.slice(0, -1),
|
|
2711
|
+
{
|
|
2712
|
+
...lastTurn,
|
|
2713
|
+
responseMessages: [...lastTurn.responseMessages, streamingMessage]
|
|
2714
|
+
}
|
|
2715
|
+
];
|
|
2716
|
+
}
|
|
2717
|
+
return [
|
|
2718
|
+
{
|
|
2719
|
+
id: `assistant-turn-${streamingMessage.id}`,
|
|
2720
|
+
responseMessages: [streamingMessage]
|
|
2721
|
+
}
|
|
2722
|
+
];
|
|
2723
|
+
};
|
|
2316
2724
|
var ChatThreadView = ({
|
|
2317
2725
|
activeSessionMode = DEFAULT_CHAT_AGENT_MODE,
|
|
2318
2726
|
historyMessages,
|
|
@@ -2325,31 +2733,45 @@ var ChatThreadView = ({
|
|
|
2325
2733
|
renderMessageBlock
|
|
2326
2734
|
}) => {
|
|
2327
2735
|
const containerRef = (0, import_react11.useRef)(null);
|
|
2328
|
-
const
|
|
2329
|
-
() =>
|
|
2330
|
-
[historyMessages]
|
|
2736
|
+
const conversationTurns = (0, import_react11.useMemo)(
|
|
2737
|
+
() => groupConversationTurns(historyMessages, streamingMessage),
|
|
2738
|
+
[historyMessages, streamingMessage]
|
|
2331
2739
|
);
|
|
2740
|
+
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
2741
|
+
const previousTurns = conversationTurns.slice(0, -1);
|
|
2742
|
+
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
2332
2743
|
const latestUserMessageRef = (0, import_react11.useRef)(null);
|
|
2333
|
-
const pendingScrollUserMessageIdRef = (0, import_react11.useRef)(void 0);
|
|
2334
2744
|
const reservedSpaceFrameRef = (0, import_react11.useRef)(null);
|
|
2335
|
-
const [
|
|
2336
|
-
const
|
|
2337
|
-
|
|
2745
|
+
const [latestTurnMinHeight, setLatestTurnMinHeight] = (0, import_react11.useState)(0);
|
|
2746
|
+
const measureLatestTurnMinHeight = (0, import_react11.useCallback)(() => {
|
|
2747
|
+
const container = containerRef.current;
|
|
2748
|
+
if (!container)
|
|
2749
|
+
return;
|
|
2750
|
+
const computedStyle = window.getComputedStyle(container);
|
|
2751
|
+
const paddingTop = Number.parseFloat(computedStyle.paddingTop || "0") || 0;
|
|
2752
|
+
const paddingBottom = Number.parseFloat(computedStyle.paddingBottom || "0") || 0;
|
|
2753
|
+
const nextMinHeight = Math.max(0, container.clientHeight - paddingTop - paddingBottom);
|
|
2754
|
+
setLatestTurnMinHeight((current) => current === nextMinHeight ? current : nextMinHeight);
|
|
2755
|
+
}, []);
|
|
2756
|
+
const scrollLatestUserMessageToTop = (0, import_react11.useCallback)(() => {
|
|
2338
2757
|
const container = containerRef.current;
|
|
2339
2758
|
const target = latestUserMessageRef.current;
|
|
2340
2759
|
if (!container || !target)
|
|
2341
2760
|
return;
|
|
2342
|
-
const
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2761
|
+
const containerRect = container.getBoundingClientRect();
|
|
2762
|
+
const targetRect = target.getBoundingClientRect();
|
|
2763
|
+
const nextScrollTop = Math.max(
|
|
2764
|
+
0,
|
|
2765
|
+
container.scrollTop + (targetRect.top - containerRect.top) - CHAT_THREAD_SCROLL_TOP_GAP
|
|
2766
|
+
);
|
|
2767
|
+
if (typeof container.scrollTo === "function") {
|
|
2768
|
+
container.scrollTo({
|
|
2769
|
+
top: nextScrollTop,
|
|
2770
|
+
behavior: "auto"
|
|
2771
|
+
});
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
container.scrollTop = nextScrollTop;
|
|
2353
2775
|
}, []);
|
|
2354
2776
|
(0, import_react11.useLayoutEffect)(() => {
|
|
2355
2777
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2357,12 +2779,9 @@ var ChatThreadView = ({
|
|
|
2357
2779
|
reservedSpaceFrameRef.current = null;
|
|
2358
2780
|
}
|
|
2359
2781
|
if (!latestUserMessageId) {
|
|
2360
|
-
pendingScrollUserMessageIdRef.current = void 0;
|
|
2361
2782
|
reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
|
|
2362
2783
|
reservedSpaceFrameRef.current = null;
|
|
2363
|
-
|
|
2364
|
-
(current) => current.messageId === void 0 && current.value === 0 ? current : { messageId: void 0, value: 0 }
|
|
2365
|
-
);
|
|
2784
|
+
setLatestTurnMinHeight((current) => current === 0 ? current : 0);
|
|
2366
2785
|
});
|
|
2367
2786
|
return () => {
|
|
2368
2787
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2371,10 +2790,10 @@ var ChatThreadView = ({
|
|
|
2371
2790
|
}
|
|
2372
2791
|
};
|
|
2373
2792
|
}
|
|
2374
|
-
pendingScrollUserMessageIdRef.current = latestUserMessageId;
|
|
2375
2793
|
reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
|
|
2376
2794
|
reservedSpaceFrameRef.current = null;
|
|
2377
|
-
|
|
2795
|
+
measureLatestTurnMinHeight();
|
|
2796
|
+
scrollLatestUserMessageToTop();
|
|
2378
2797
|
});
|
|
2379
2798
|
return () => {
|
|
2380
2799
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2382,51 +2801,79 @@ var ChatThreadView = ({
|
|
|
2382
2801
|
reservedSpaceFrameRef.current = null;
|
|
2383
2802
|
}
|
|
2384
2803
|
};
|
|
2385
|
-
}, [latestUserMessageId,
|
|
2804
|
+
}, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
|
|
2386
2805
|
(0, import_react11.useLayoutEffect)(() => {
|
|
2387
|
-
if (!latestUserMessageId
|
|
2388
|
-
return;
|
|
2389
|
-
if (latestUserMessageReservedSpace.messageId !== latestUserMessageId)
|
|
2806
|
+
if (!latestUserMessageId)
|
|
2390
2807
|
return;
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2808
|
+
const handleResize = () => {
|
|
2809
|
+
measureLatestTurnMinHeight();
|
|
2810
|
+
scrollLatestUserMessageToTop();
|
|
2811
|
+
};
|
|
2812
|
+
const container = containerRef.current;
|
|
2813
|
+
let resizeObserver = null;
|
|
2814
|
+
if (container && typeof ResizeObserver !== "undefined") {
|
|
2815
|
+
resizeObserver = new ResizeObserver(() => {
|
|
2816
|
+
handleResize();
|
|
2817
|
+
});
|
|
2818
|
+
resizeObserver.observe(container);
|
|
2819
|
+
}
|
|
2820
|
+
window.addEventListener("resize", handleResize);
|
|
2821
|
+
return () => {
|
|
2822
|
+
resizeObserver?.disconnect();
|
|
2823
|
+
window.removeEventListener("resize", handleResize);
|
|
2824
|
+
};
|
|
2825
|
+
}, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
|
|
2826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Container, { ref: containerRef, "data-testid": "chat-thread", children: [
|
|
2827
|
+
previousTurns.map((turn) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ConversationTurn, { "data-testid": "chat-thread-turn", children: [
|
|
2828
|
+
turn.userMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
|
|
2829
|
+
message: turn.userMessage,
|
|
2830
|
+
mode: activeSessionMode,
|
|
2831
|
+
onConfirmationSubmit,
|
|
2832
|
+
onQuestionnaireSubmit,
|
|
2833
|
+
renderMessageBlock
|
|
2834
|
+
}) }) : null,
|
|
2835
|
+
turn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
|
|
2836
|
+
message,
|
|
2837
|
+
mode: activeSessionMode,
|
|
2838
|
+
onConfirmationSubmit,
|
|
2839
|
+
onQuestionnaireSubmit,
|
|
2840
|
+
renderMessageBlock
|
|
2841
|
+
}) }, message.id))
|
|
2842
|
+
] }, turn.id)),
|
|
2843
|
+
latestTurn ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2844
|
+
ConversationTurn,
|
|
2845
|
+
{
|
|
2846
|
+
"data-testid": "chat-thread-latest-turn",
|
|
2847
|
+
style: latestTurnMinHeight > 0 ? { minHeight: `${latestTurnMinHeight}px` } : void 0,
|
|
2848
|
+
children: [
|
|
2849
|
+
latestTurn.userMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2850
|
+
MessageSlot,
|
|
2851
|
+
{
|
|
2852
|
+
ref: latestUserMessageRef,
|
|
2853
|
+
"data-testid": "chat-latest-user-anchor",
|
|
2854
|
+
style: { scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px` },
|
|
2855
|
+
children: renderChatMessage({
|
|
2856
|
+
message: latestTurn.userMessage,
|
|
2857
|
+
mode: activeSessionMode,
|
|
2858
|
+
onConfirmationSubmit,
|
|
2859
|
+
onQuestionnaireSubmit,
|
|
2860
|
+
renderMessageBlock
|
|
2861
|
+
})
|
|
2862
|
+
}
|
|
2863
|
+
) : null,
|
|
2864
|
+
latestTurn.responseMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageSlot, { children: renderChatMessage({
|
|
2865
|
+
message,
|
|
2416
2866
|
mode: activeSessionMode,
|
|
2417
|
-
message: streamingMessage,
|
|
2418
2867
|
onConfirmationSubmit,
|
|
2419
2868
|
onQuestionnaireSubmit,
|
|
2420
2869
|
renderMessageBlock
|
|
2421
|
-
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
}
|
|
2429
|
-
);
|
|
2870
|
+
}) }, message.id)),
|
|
2871
|
+
error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
|
|
2872
|
+
]
|
|
2873
|
+
}
|
|
2874
|
+
) : null,
|
|
2875
|
+
!latestTurn && error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
|
|
2876
|
+
] });
|
|
2430
2877
|
};
|
|
2431
2878
|
var EMPTY_MESSAGES = [];
|
|
2432
2879
|
var ChatThread = () => {
|
|
@@ -2470,9 +2917,9 @@ var ChatThread = () => {
|
|
|
2470
2917
|
[sendRef]
|
|
2471
2918
|
);
|
|
2472
2919
|
if (!hasSessions || messages.length === 0 && !streamingMessage) {
|
|
2473
|
-
return /* @__PURE__ */ (0,
|
|
2920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatThreadEmptyState, {});
|
|
2474
2921
|
}
|
|
2475
|
-
return /* @__PURE__ */ (0,
|
|
2922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2476
2923
|
ChatThreadView,
|
|
2477
2924
|
{
|
|
2478
2925
|
activeSessionMode,
|
|
@@ -2487,7 +2934,7 @@ var ChatThread = () => {
|
|
|
2487
2934
|
}
|
|
2488
2935
|
);
|
|
2489
2936
|
};
|
|
2490
|
-
var Container =
|
|
2937
|
+
var Container = import_styled9.default.div`
|
|
2491
2938
|
display: flex;
|
|
2492
2939
|
flex: 1;
|
|
2493
2940
|
flex-direction: column;
|
|
@@ -2510,27 +2957,29 @@ var Container = import_styled10.default.div`
|
|
|
2510
2957
|
background: transparent;
|
|
2511
2958
|
}
|
|
2512
2959
|
`;
|
|
2513
|
-
var
|
|
2960
|
+
var MessageSlot = import_styled9.default.div`
|
|
2514
2961
|
display: flex;
|
|
2515
2962
|
`;
|
|
2516
|
-
var
|
|
2517
|
-
display:
|
|
2963
|
+
var ConversationTurn = import_styled9.default.div`
|
|
2964
|
+
display: flex;
|
|
2965
|
+
flex-direction: column;
|
|
2966
|
+
gap: 18px;
|
|
2518
2967
|
`;
|
|
2519
|
-
var ErrorText =
|
|
2968
|
+
var ErrorText = import_styled9.default.div`
|
|
2520
2969
|
color: #ff7b72;
|
|
2521
2970
|
font-size: 14px;
|
|
2522
2971
|
`;
|
|
2523
|
-
var ErrorState =
|
|
2972
|
+
var ErrorState = import_styled9.default.div`
|
|
2524
2973
|
display: flex;
|
|
2525
2974
|
flex-direction: column;
|
|
2526
2975
|
align-items: flex-start;
|
|
2527
2976
|
gap: 10px;
|
|
2528
2977
|
`;
|
|
2529
|
-
var ErrorActions =
|
|
2978
|
+
var ErrorActions = import_styled9.default.div`
|
|
2530
2979
|
display: flex;
|
|
2531
2980
|
align-items: center;
|
|
2532
2981
|
`;
|
|
2533
|
-
var RetryButton =
|
|
2982
|
+
var RetryButton = import_styled9.default.button`
|
|
2534
2983
|
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
2535
2984
|
border-radius: 999px;
|
|
2536
2985
|
background: rgba(255, 255, 255, 0.04);
|
|
@@ -2547,7 +2996,7 @@ var RetryButton = import_styled10.default.button`
|
|
|
2547
2996
|
|
|
2548
2997
|
// src/components/chat-composer/index.tsx
|
|
2549
2998
|
var import_react15 = require("react");
|
|
2550
|
-
var
|
|
2999
|
+
var import_styled14 = __toESM(require("@emotion/styled"));
|
|
2551
3000
|
|
|
2552
3001
|
// src/components/chat-composer/lib/chat-composer.ts
|
|
2553
3002
|
var DRAFT_CHAT_SESSION_ID_PREFIX = "draft-session-";
|
|
@@ -3112,8 +3561,8 @@ var useChatComposer = () => {
|
|
|
3112
3561
|
|
|
3113
3562
|
// src/components/chat-composer/components/chat-composer-attachment-list.tsx
|
|
3114
3563
|
var import_react14 = require("react");
|
|
3115
|
-
var
|
|
3116
|
-
var
|
|
3564
|
+
var import_styled10 = __toESM(require("@emotion/styled"));
|
|
3565
|
+
var import_jsx_runtime11 = require("@emotion/react/jsx-runtime");
|
|
3117
3566
|
var ChatComposerAttachmentList = ({
|
|
3118
3567
|
attachments,
|
|
3119
3568
|
onRemoveAttachment
|
|
@@ -3122,18 +3571,18 @@ var ChatComposerAttachmentList = ({
|
|
|
3122
3571
|
if (!attachments.length) {
|
|
3123
3572
|
return null;
|
|
3124
3573
|
}
|
|
3125
|
-
return /* @__PURE__ */ (0,
|
|
3126
|
-
/* @__PURE__ */ (0,
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3575
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(AttachmentCard, { children: [
|
|
3576
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3128
3577
|
AttachmentPreviewButton,
|
|
3129
3578
|
{
|
|
3130
3579
|
type: "button",
|
|
3131
3580
|
"aria-label": `${attachment.name} preview`,
|
|
3132
3581
|
onClick: () => setActiveImage(attachment),
|
|
3133
|
-
children: /* @__PURE__ */ (0,
|
|
3582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
|
|
3134
3583
|
}
|
|
3135
3584
|
),
|
|
3136
|
-
/* @__PURE__ */ (0,
|
|
3585
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3137
3586
|
AttachmentRemoveButton,
|
|
3138
3587
|
{
|
|
3139
3588
|
type: "button",
|
|
@@ -3142,11 +3591,11 @@ var ChatComposerAttachmentList = ({
|
|
|
3142
3591
|
event.stopPropagation();
|
|
3143
3592
|
onRemoveAttachment(attachment.id);
|
|
3144
3593
|
},
|
|
3145
|
-
children: /* @__PURE__ */ (0,
|
|
3594
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CloseGlyph, { "aria-hidden": "true" })
|
|
3146
3595
|
}
|
|
3147
3596
|
)
|
|
3148
3597
|
] }, attachment.id)) }),
|
|
3149
|
-
activeImage ? /* @__PURE__ */ (0,
|
|
3598
|
+
activeImage ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3150
3599
|
ImageViewer,
|
|
3151
3600
|
{
|
|
3152
3601
|
src: activeImage.previewUrl,
|
|
@@ -3156,7 +3605,7 @@ var ChatComposerAttachmentList = ({
|
|
|
3156
3605
|
) : null
|
|
3157
3606
|
] });
|
|
3158
3607
|
};
|
|
3159
|
-
var AttachmentList =
|
|
3608
|
+
var AttachmentList = import_styled10.default.div`
|
|
3160
3609
|
display: flex;
|
|
3161
3610
|
flex-wrap: wrap;
|
|
3162
3611
|
gap: 10px;
|
|
@@ -3178,7 +3627,7 @@ var AttachmentList = import_styled11.default.div`
|
|
|
3178
3627
|
background: transparent;
|
|
3179
3628
|
}
|
|
3180
3629
|
`;
|
|
3181
|
-
var AttachmentCard =
|
|
3630
|
+
var AttachmentCard = import_styled10.default.div`
|
|
3182
3631
|
position: relative;
|
|
3183
3632
|
width: 108px;
|
|
3184
3633
|
height: 72px;
|
|
@@ -3187,7 +3636,7 @@ var AttachmentCard = import_styled11.default.div`
|
|
|
3187
3636
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
3188
3637
|
background: rgba(255, 255, 255, 0.04);
|
|
3189
3638
|
`;
|
|
3190
|
-
var AttachmentPreviewButton =
|
|
3639
|
+
var AttachmentPreviewButton = import_styled10.default.button`
|
|
3191
3640
|
width: 100%;
|
|
3192
3641
|
height: 100%;
|
|
3193
3642
|
padding: 0;
|
|
@@ -3195,13 +3644,13 @@ var AttachmentPreviewButton = import_styled11.default.button`
|
|
|
3195
3644
|
background: transparent;
|
|
3196
3645
|
cursor: zoom-in;
|
|
3197
3646
|
`;
|
|
3198
|
-
var AttachmentThumb =
|
|
3647
|
+
var AttachmentThumb = import_styled10.default.img`
|
|
3199
3648
|
width: 100%;
|
|
3200
3649
|
height: 100%;
|
|
3201
3650
|
object-fit: cover;
|
|
3202
3651
|
display: block;
|
|
3203
3652
|
`;
|
|
3204
|
-
var AttachmentRemoveButton =
|
|
3653
|
+
var AttachmentRemoveButton = import_styled10.default.button`
|
|
3205
3654
|
position: absolute;
|
|
3206
3655
|
top: 6px;
|
|
3207
3656
|
right: 6px;
|
|
@@ -3239,7 +3688,7 @@ var AttachmentRemoveButton = import_styled11.default.button`
|
|
|
3239
3688
|
background: rgba(30, 30, 35, 0.98);
|
|
3240
3689
|
}
|
|
3241
3690
|
`;
|
|
3242
|
-
var CloseGlyph =
|
|
3691
|
+
var CloseGlyph = import_styled10.default.span`
|
|
3243
3692
|
position: relative;
|
|
3244
3693
|
width: 11px;
|
|
3245
3694
|
height: 11px;
|
|
@@ -3268,9 +3717,9 @@ var CloseGlyph = import_styled11.default.span`
|
|
|
3268
3717
|
`;
|
|
3269
3718
|
|
|
3270
3719
|
// src/components/chat-composer/components/chat-model-control.tsx
|
|
3271
|
-
var
|
|
3720
|
+
var import_styled11 = __toESM(require("@emotion/styled"));
|
|
3272
3721
|
var import_compass_ui = require("@xinghunm/compass-ui");
|
|
3273
|
-
var
|
|
3722
|
+
var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
|
|
3274
3723
|
var ChatModelControl = ({
|
|
3275
3724
|
selectedModel,
|
|
3276
3725
|
availableModels,
|
|
@@ -3281,7 +3730,7 @@ var ChatModelControl = ({
|
|
|
3281
3730
|
onReloadModels
|
|
3282
3731
|
}) => {
|
|
3283
3732
|
if (isModelsError) {
|
|
3284
|
-
return /* @__PURE__ */ (0,
|
|
3733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3285
3734
|
ModelReloadButton,
|
|
3286
3735
|
{
|
|
3287
3736
|
type: "button",
|
|
@@ -3289,8 +3738,8 @@ var ChatModelControl = ({
|
|
|
3289
3738
|
"aria-label": "Reload",
|
|
3290
3739
|
onClick: onReloadModels,
|
|
3291
3740
|
children: [
|
|
3292
|
-
/* @__PURE__ */ (0,
|
|
3293
|
-
/* @__PURE__ */ (0,
|
|
3741
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Failed to load models" }),
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3294
3743
|
ReloadIcon,
|
|
3295
3744
|
{
|
|
3296
3745
|
"data-testid": "chat-model-reload-icon",
|
|
@@ -3301,8 +3750,8 @@ var ChatModelControl = ({
|
|
|
3301
3750
|
fill: "currentColor",
|
|
3302
3751
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3303
3752
|
children: [
|
|
3304
|
-
/* @__PURE__ */ (0,
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
3753
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M895.469672 511.745197c0-146.498562-82.099856-273.805016-202.788589-338.470805l22.072715-46.630017c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-92.436272 33.040511c-12.609179 4.50664-19.176758 18.382673-14.670118 30.991852l33.040511 92.436272c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l24.581861-51.92972c99.069343 54.335513 166.240185 159.596881 166.240185 280.561907 0 165.56685-125.817544 301.747415-287.057855 318.14692l0 0.022513c-17.730826 0-32.105209 14.374382-32.105209 32.105209 0 17.730826 14.374382 32.105209 32.105209 32.105209 2.098801 0 4.149507-0.207731 6.135744-0.592494C744.270041 874.039593 895.469672 710.564381 895.469672 511.745197z" }),
|
|
3754
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M480.616222 129.23948c-0.041956 0-0.082888 0.00307-0.124843 0.00307l0-0.00307c-0.01535 0.001023-0.031722 0.00307-0.047072 0.004093-1.892093 0.010233-3.744277 0.189312-5.545296 0.5137-194.674794 18.529005-346.957083 182.459588-346.957083 381.987924 0 147.431817 83.146699 275.42798 205.097168 339.700819l-24.814152 52.419883c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l92.436272-33.040511c12.609179-4.50664 19.176758-18.382673 14.670118-30.991852l-33.040511-92.436272c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-21.853727 46.167482c-100.326986-53.964052-168.535461-159.920246-168.535461-281.81955 0-166.089759 126.616746-302.591643 288.588721-318.284043l0-0.014326c0.041956 0 0.082888 0.00307 0.124843 0.00307 17.730826 0 32.105209-14.374382 32.105209-32.105209C512.721431 143.613862 498.347049 129.23948 480.616222 129.23948z" })
|
|
3306
3755
|
]
|
|
3307
3756
|
}
|
|
3308
3757
|
)
|
|
@@ -3311,11 +3760,11 @@ var ChatModelControl = ({
|
|
|
3311
3760
|
);
|
|
3312
3761
|
}
|
|
3313
3762
|
if (isModelsLoading) {
|
|
3314
|
-
return /* @__PURE__ */ (0,
|
|
3763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "Loading models..." });
|
|
3315
3764
|
}
|
|
3316
3765
|
if (hasModels && selectedModel) {
|
|
3317
3766
|
if (availableModels.length > 1) {
|
|
3318
|
-
return /* @__PURE__ */ (0,
|
|
3767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3319
3768
|
ModelSelect,
|
|
3320
3769
|
{
|
|
3321
3770
|
"data-testid": "chat-model-select",
|
|
@@ -3329,11 +3778,11 @@ var ChatModelControl = ({
|
|
|
3329
3778
|
}
|
|
3330
3779
|
);
|
|
3331
3780
|
}
|
|
3332
|
-
return /* @__PURE__ */ (0,
|
|
3781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: selectedModel });
|
|
3333
3782
|
}
|
|
3334
|
-
return /* @__PURE__ */ (0,
|
|
3783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "No model available" });
|
|
3335
3784
|
};
|
|
3336
|
-
var ModelBadge =
|
|
3785
|
+
var ModelBadge = import_styled11.default.span`
|
|
3337
3786
|
border-radius: 999px;
|
|
3338
3787
|
border: 1px solid var(--border-hover);
|
|
3339
3788
|
padding: 5px 12px;
|
|
@@ -3342,7 +3791,7 @@ var ModelBadge = import_styled12.default.span`
|
|
|
3342
3791
|
color: var(--text-secondary);
|
|
3343
3792
|
line-height: 12px;
|
|
3344
3793
|
`;
|
|
3345
|
-
var ModelReloadButton =
|
|
3794
|
+
var ModelReloadButton = import_styled11.default.button`
|
|
3346
3795
|
display: inline-flex;
|
|
3347
3796
|
align-items: center;
|
|
3348
3797
|
gap: 8px;
|
|
@@ -3367,10 +3816,10 @@ var ModelReloadButton = import_styled12.default.button`
|
|
|
3367
3816
|
color: rgba(255, 255, 255, 0.88);
|
|
3368
3817
|
}
|
|
3369
3818
|
`;
|
|
3370
|
-
var ReloadIcon =
|
|
3819
|
+
var ReloadIcon = import_styled11.default.svg`
|
|
3371
3820
|
flex-shrink: 0;
|
|
3372
3821
|
`;
|
|
3373
|
-
var ModelSelect = (0,
|
|
3822
|
+
var ModelSelect = (0, import_styled11.default)(import_compass_ui.Select)`
|
|
3374
3823
|
&& {
|
|
3375
3824
|
width: auto;
|
|
3376
3825
|
min-width: 0;
|
|
@@ -3390,16 +3839,16 @@ var ModelSelect = (0, import_styled12.default)(import_compass_ui.Select)`
|
|
|
3390
3839
|
`;
|
|
3391
3840
|
|
|
3392
3841
|
// src/components/chat-composer/components/chat-mode-control.tsx
|
|
3393
|
-
var
|
|
3842
|
+
var import_styled12 = __toESM(require("@emotion/styled"));
|
|
3394
3843
|
var import_compass_ui2 = require("@xinghunm/compass-ui");
|
|
3395
|
-
var
|
|
3844
|
+
var import_jsx_runtime13 = require("@emotion/react/jsx-runtime");
|
|
3396
3845
|
var ChatModeControl = ({
|
|
3397
3846
|
value,
|
|
3398
3847
|
disabled = false,
|
|
3399
3848
|
labels,
|
|
3400
3849
|
onChange
|
|
3401
3850
|
}) => {
|
|
3402
|
-
return /* @__PURE__ */ (0,
|
|
3851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3403
3852
|
ModeSelect,
|
|
3404
3853
|
{
|
|
3405
3854
|
"data-testid": "chat-mode-select",
|
|
@@ -3414,7 +3863,7 @@ var ChatModeControl = ({
|
|
|
3414
3863
|
}
|
|
3415
3864
|
);
|
|
3416
3865
|
};
|
|
3417
|
-
var ModeSelect = (0,
|
|
3866
|
+
var ModeSelect = (0, import_styled12.default)(import_compass_ui2.Select)`
|
|
3418
3867
|
&& {
|
|
3419
3868
|
flex: 0 1 auto;
|
|
3420
3869
|
width: auto;
|
|
@@ -3435,10 +3884,10 @@ var ModeSelect = (0, import_styled13.default)(import_compass_ui2.Select)`
|
|
|
3435
3884
|
`;
|
|
3436
3885
|
|
|
3437
3886
|
// src/components/chat-composer/components/chat-send-actions.tsx
|
|
3438
|
-
var
|
|
3887
|
+
var import_styled13 = __toESM(require("@emotion/styled"));
|
|
3439
3888
|
var import_compass_ui3 = require("@xinghunm/compass-ui");
|
|
3440
|
-
var
|
|
3441
|
-
var ArrowUpIcon = () => /* @__PURE__ */ (0,
|
|
3889
|
+
var import_jsx_runtime14 = require("@emotion/react/jsx-runtime");
|
|
3890
|
+
var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3442
3891
|
"svg",
|
|
3443
3892
|
{
|
|
3444
3893
|
"aria-hidden": "true",
|
|
@@ -3447,7 +3896,7 @@ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
|
3447
3896
|
viewBox: "0 0 12 12",
|
|
3448
3897
|
fill: "none",
|
|
3449
3898
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3450
|
-
children: /* @__PURE__ */ (0,
|
|
3899
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3451
3900
|
"path",
|
|
3452
3901
|
{
|
|
3453
3902
|
d: "M6 10V2M6 2L2 6M6 2L10 6",
|
|
@@ -3465,7 +3914,7 @@ var ChatSendActions = ({
|
|
|
3465
3914
|
isStopping,
|
|
3466
3915
|
onStop,
|
|
3467
3916
|
onSend
|
|
3468
|
-
}) => /* @__PURE__ */ (0,
|
|
3917
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3469
3918
|
StopButton,
|
|
3470
3919
|
{
|
|
3471
3920
|
type: "button",
|
|
@@ -3475,14 +3924,14 @@ var ChatSendActions = ({
|
|
|
3475
3924
|
disabled: isStopping,
|
|
3476
3925
|
shape: "circle",
|
|
3477
3926
|
onClick: () => void onStop(),
|
|
3478
|
-
children: /* @__PURE__ */ (0,
|
|
3927
|
+
children: isStopping ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopSpinner, { "aria-hidden": "true", "data-testid": "chat-composer-stop-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopGlyph, { "aria-hidden": "true", "data-testid": "chat-composer-stop-glyph" })
|
|
3479
3928
|
}
|
|
3480
|
-
) : /* @__PURE__ */ (0,
|
|
3929
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3481
3930
|
PrimaryButton,
|
|
3482
3931
|
{
|
|
3483
3932
|
$canSend: canSend,
|
|
3484
3933
|
type: "button",
|
|
3485
|
-
icon: /* @__PURE__ */ (0,
|
|
3934
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowUpIcon, {}),
|
|
3486
3935
|
"aria-label": "Send",
|
|
3487
3936
|
"data-testid": "chat-composer-send",
|
|
3488
3937
|
disabled: !canSend,
|
|
@@ -3490,7 +3939,7 @@ var ChatSendActions = ({
|
|
|
3490
3939
|
onClick: () => void onSend()
|
|
3491
3940
|
}
|
|
3492
3941
|
) });
|
|
3493
|
-
var PrimaryButton = (0,
|
|
3942
|
+
var PrimaryButton = (0, import_styled13.default)(import_compass_ui3.Button)`
|
|
3494
3943
|
&& {
|
|
3495
3944
|
min-width: 24px;
|
|
3496
3945
|
width: 24px;
|
|
@@ -3516,7 +3965,7 @@ var PrimaryButton = (0, import_styled14.default)(import_compass_ui3.Button)`
|
|
|
3516
3965
|
}
|
|
3517
3966
|
}
|
|
3518
3967
|
`;
|
|
3519
|
-
var StopButton = (0,
|
|
3968
|
+
var StopButton = (0, import_styled13.default)(import_compass_ui3.Button)`
|
|
3520
3969
|
&& {
|
|
3521
3970
|
min-width: 24px;
|
|
3522
3971
|
width: 24px;
|
|
@@ -3544,17 +3993,35 @@ var StopButton = (0, import_styled14.default)(import_compass_ui3.Button)`
|
|
|
3544
3993
|
}
|
|
3545
3994
|
}
|
|
3546
3995
|
`;
|
|
3547
|
-
var StopGlyph =
|
|
3996
|
+
var StopGlyph = import_styled13.default.span`
|
|
3548
3997
|
width: 8px;
|
|
3549
3998
|
height: 8px;
|
|
3550
3999
|
border-radius: 2px;
|
|
3551
4000
|
background: #1b1b1b;
|
|
3552
4001
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
|
|
3553
4002
|
`;
|
|
4003
|
+
var StopSpinner = import_styled13.default.span`
|
|
4004
|
+
width: 10px;
|
|
4005
|
+
height: 10px;
|
|
4006
|
+
border-radius: 999px;
|
|
4007
|
+
border: 1.5px solid rgba(27, 27, 27, 0.2);
|
|
4008
|
+
border-top-color: #1b1b1b;
|
|
4009
|
+
animation: chat-composer-stop-spin 0.7s linear infinite;
|
|
4010
|
+
|
|
4011
|
+
@keyframes chat-composer-stop-spin {
|
|
4012
|
+
from {
|
|
4013
|
+
transform: rotate(0deg);
|
|
4014
|
+
}
|
|
4015
|
+
|
|
4016
|
+
to {
|
|
4017
|
+
transform: rotate(360deg);
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
`;
|
|
3554
4021
|
|
|
3555
4022
|
// src/components/chat-composer/index.tsx
|
|
3556
|
-
var
|
|
3557
|
-
var PlusIcon = () => /* @__PURE__ */ (0,
|
|
4023
|
+
var import_jsx_runtime15 = require("@emotion/react/jsx-runtime");
|
|
4024
|
+
var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3558
4025
|
"svg",
|
|
3559
4026
|
{
|
|
3560
4027
|
"aria-hidden": "true",
|
|
@@ -3563,7 +4030,7 @@ var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
|
3563
4030
|
viewBox: "0 0 16 16",
|
|
3564
4031
|
fill: "none",
|
|
3565
4032
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3566
|
-
children: /* @__PURE__ */ (0,
|
|
4033
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
|
|
3567
4034
|
}
|
|
3568
4035
|
);
|
|
3569
4036
|
var ChatComposerView = ({
|
|
@@ -3623,8 +4090,8 @@ var ChatComposerView = ({
|
|
|
3623
4090
|
event.preventDefault();
|
|
3624
4091
|
onPasteImages(imageFiles);
|
|
3625
4092
|
};
|
|
3626
|
-
return /* @__PURE__ */ (0,
|
|
3627
|
-
enableImageAttachments ? /* @__PURE__ */ (0,
|
|
4093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Container2, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Surface, { "data-testid": "chat-composer-surface", children: [
|
|
4094
|
+
enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3628
4095
|
"input",
|
|
3629
4096
|
{
|
|
3630
4097
|
ref: imageInputRef,
|
|
@@ -3636,15 +4103,15 @@ var ChatComposerView = ({
|
|
|
3636
4103
|
onChange: handlePickImages
|
|
3637
4104
|
}
|
|
3638
4105
|
) : null,
|
|
3639
|
-
/* @__PURE__ */ (0,
|
|
4106
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3640
4107
|
ChatComposerAttachmentList,
|
|
3641
4108
|
{
|
|
3642
4109
|
attachments,
|
|
3643
4110
|
onRemoveAttachment
|
|
3644
4111
|
}
|
|
3645
4112
|
),
|
|
3646
|
-
attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0,
|
|
3647
|
-
/* @__PURE__ */ (0,
|
|
4113
|
+
attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
|
|
4114
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3648
4115
|
Input,
|
|
3649
4116
|
{
|
|
3650
4117
|
"data-testid": "chat-composer-input",
|
|
@@ -3655,18 +4122,18 @@ var ChatComposerView = ({
|
|
|
3655
4122
|
placeholder
|
|
3656
4123
|
}
|
|
3657
4124
|
),
|
|
3658
|
-
/* @__PURE__ */ (0,
|
|
3659
|
-
enableImageAttachments ? /* @__PURE__ */ (0,
|
|
4125
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Footer, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Actions2, { "data-testid": "chat-composer-actions", children: [
|
|
4126
|
+
enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3660
4127
|
AttachButton,
|
|
3661
4128
|
{
|
|
3662
4129
|
type: "button",
|
|
3663
4130
|
"data-testid": "chat-composer-attach-image",
|
|
3664
4131
|
"aria-label": "Attach image",
|
|
3665
4132
|
onClick: () => imageInputRef.current?.click(),
|
|
3666
|
-
children: /* @__PURE__ */ (0,
|
|
4133
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PlusIcon, {})
|
|
3667
4134
|
}
|
|
3668
4135
|
) : null,
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
4136
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3670
4137
|
ChatModeControl,
|
|
3671
4138
|
{
|
|
3672
4139
|
value: selectedMode,
|
|
@@ -3675,7 +4142,7 @@ var ChatComposerView = ({
|
|
|
3675
4142
|
onChange: onSelectedModeChange
|
|
3676
4143
|
}
|
|
3677
4144
|
),
|
|
3678
|
-
/* @__PURE__ */ (0,
|
|
4145
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3679
4146
|
ChatModelControl,
|
|
3680
4147
|
{
|
|
3681
4148
|
selectedModel,
|
|
@@ -3687,7 +4154,7 @@ var ChatComposerView = ({
|
|
|
3687
4154
|
onReloadModels
|
|
3688
4155
|
}
|
|
3689
4156
|
),
|
|
3690
|
-
/* @__PURE__ */ (0,
|
|
4157
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3691
4158
|
ChatSendActions,
|
|
3692
4159
|
{
|
|
3693
4160
|
canSend,
|
|
@@ -3715,7 +4182,7 @@ var ChatComposer = () => {
|
|
|
3715
4182
|
plan: labels.modeLabelPlan,
|
|
3716
4183
|
agent: labels.modeLabelAgent
|
|
3717
4184
|
};
|
|
3718
|
-
return /* @__PURE__ */ (0,
|
|
4185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3719
4186
|
ChatComposerView,
|
|
3720
4187
|
{
|
|
3721
4188
|
value: state.value,
|
|
@@ -3745,10 +4212,10 @@ var ChatComposer = () => {
|
|
|
3745
4212
|
}
|
|
3746
4213
|
);
|
|
3747
4214
|
};
|
|
3748
|
-
var Container2 =
|
|
4215
|
+
var Container2 = import_styled14.default.div`
|
|
3749
4216
|
padding: 0 16px 16px;
|
|
3750
4217
|
`;
|
|
3751
|
-
var Surface =
|
|
4218
|
+
var Surface = import_styled14.default.div`
|
|
3752
4219
|
background: var(--border-color);
|
|
3753
4220
|
border-radius: 20px;
|
|
3754
4221
|
border: 1px solid var(--border-hover);
|
|
@@ -3757,7 +4224,7 @@ var Surface = import_styled15.default.div`
|
|
|
3757
4224
|
0 12px 36px rgba(0, 0, 0, 0.3);
|
|
3758
4225
|
backdrop-filter: blur(10px);
|
|
3759
4226
|
`;
|
|
3760
|
-
var AttachmentNotice =
|
|
4227
|
+
var AttachmentNotice = import_styled14.default.div`
|
|
3761
4228
|
margin: 10px 12px 0;
|
|
3762
4229
|
padding: 8px 10px;
|
|
3763
4230
|
border-radius: 10px;
|
|
@@ -3767,7 +4234,7 @@ var AttachmentNotice = import_styled15.default.div`
|
|
|
3767
4234
|
font-size: 12px;
|
|
3768
4235
|
line-height: 1.4;
|
|
3769
4236
|
`;
|
|
3770
|
-
var Input =
|
|
4237
|
+
var Input = import_styled14.default.textarea`
|
|
3771
4238
|
width: 100%;
|
|
3772
4239
|
min-height: 96px;
|
|
3773
4240
|
resize: none;
|
|
@@ -3789,14 +4256,14 @@ var Input = import_styled15.default.textarea`
|
|
|
3789
4256
|
display: none;
|
|
3790
4257
|
}
|
|
3791
4258
|
`;
|
|
3792
|
-
var Footer =
|
|
4259
|
+
var Footer = import_styled14.default.div`
|
|
3793
4260
|
display: flex;
|
|
3794
4261
|
align-items: flex-end;
|
|
3795
4262
|
justify-content: stretch;
|
|
3796
4263
|
gap: 16px;
|
|
3797
4264
|
padding: 0 14px 14px;
|
|
3798
4265
|
`;
|
|
3799
|
-
var Actions2 =
|
|
4266
|
+
var Actions2 = import_styled14.default.div`
|
|
3800
4267
|
display: flex;
|
|
3801
4268
|
align-items: center;
|
|
3802
4269
|
flex-wrap: wrap;
|
|
@@ -3805,7 +4272,7 @@ var Actions2 = import_styled15.default.div`
|
|
|
3805
4272
|
justify-content: flex-end;
|
|
3806
4273
|
gap: 8px;
|
|
3807
4274
|
`;
|
|
3808
|
-
var AttachButton =
|
|
4275
|
+
var AttachButton = import_styled14.default.button`
|
|
3809
4276
|
width: 28px;
|
|
3810
4277
|
height: 28px;
|
|
3811
4278
|
display: grid;
|
|
@@ -3822,42 +4289,42 @@ var AttachButton = import_styled15.default.button`
|
|
|
3822
4289
|
`;
|
|
3823
4290
|
|
|
3824
4291
|
// src/components/chat-conversation-list/index.tsx
|
|
3825
|
-
var
|
|
4292
|
+
var import_styled16 = __toESM(require("@emotion/styled"));
|
|
3826
4293
|
|
|
3827
4294
|
// src/components/chat-conversation-list/components/chat-session-item.tsx
|
|
3828
4295
|
var import_react16 = require("react");
|
|
3829
|
-
var
|
|
3830
|
-
var
|
|
4296
|
+
var import_styled15 = __toESM(require("@emotion/styled"));
|
|
4297
|
+
var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
|
|
3831
4298
|
var ChatSessionItem = (0, import_react16.memo)(
|
|
3832
4299
|
({ session, isActive, modeLabel, onClick }) => {
|
|
3833
|
-
return /* @__PURE__ */ (0,
|
|
4300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3834
4301
|
SessionButton,
|
|
3835
4302
|
{
|
|
3836
4303
|
type: "button",
|
|
3837
4304
|
"data-active": isActive,
|
|
3838
4305
|
onClick: () => onClick(session.sessionId),
|
|
3839
|
-
children: /* @__PURE__ */ (0,
|
|
3840
|
-
/* @__PURE__ */ (0,
|
|
3841
|
-
/* @__PURE__ */ (0,
|
|
4306
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(SessionMeta, { children: [
|
|
4307
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SessionTitle, { children: session.title }),
|
|
4308
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ModeBadge, { children: modeLabel })
|
|
3842
4309
|
] })
|
|
3843
4310
|
}
|
|
3844
4311
|
);
|
|
3845
4312
|
}
|
|
3846
4313
|
);
|
|
3847
4314
|
ChatSessionItem.displayName = "ChatSessionItem";
|
|
3848
|
-
var SessionMeta =
|
|
4315
|
+
var SessionMeta = import_styled15.default.div`
|
|
3849
4316
|
display: flex;
|
|
3850
4317
|
align-items: center;
|
|
3851
4318
|
justify-content: space-between;
|
|
3852
4319
|
gap: 8px;
|
|
3853
4320
|
`;
|
|
3854
|
-
var SessionTitle =
|
|
4321
|
+
var SessionTitle = import_styled15.default.span`
|
|
3855
4322
|
min-width: 0;
|
|
3856
4323
|
overflow: hidden;
|
|
3857
4324
|
text-overflow: ellipsis;
|
|
3858
4325
|
white-space: nowrap;
|
|
3859
4326
|
`;
|
|
3860
|
-
var SessionButton =
|
|
4327
|
+
var SessionButton = import_styled15.default.button`
|
|
3861
4328
|
border: 1px solid transparent;
|
|
3862
4329
|
border-radius: 12px;
|
|
3863
4330
|
padding: 12px;
|
|
@@ -3871,7 +4338,7 @@ var SessionButton = import_styled16.default.button`
|
|
|
3871
4338
|
background: rgba(255, 255, 255, 0.08);
|
|
3872
4339
|
}
|
|
3873
4340
|
`;
|
|
3874
|
-
var ModeBadge =
|
|
4341
|
+
var ModeBadge = import_styled15.default.span`
|
|
3875
4342
|
flex-shrink: 0;
|
|
3876
4343
|
border-radius: 999px;
|
|
3877
4344
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
@@ -3883,7 +4350,7 @@ var ModeBadge = import_styled16.default.span`
|
|
|
3883
4350
|
`;
|
|
3884
4351
|
|
|
3885
4352
|
// src/components/chat-conversation-list/index.tsx
|
|
3886
|
-
var
|
|
4353
|
+
var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
|
|
3887
4354
|
var ChatConversationList = () => {
|
|
3888
4355
|
const { labels } = useChatContext();
|
|
3889
4356
|
const sessions = useChatStore((s) => s.sessions);
|
|
@@ -3906,12 +4373,12 @@ var ChatConversationList = () => {
|
|
|
3906
4373
|
});
|
|
3907
4374
|
createSession(session);
|
|
3908
4375
|
};
|
|
3909
|
-
return /* @__PURE__ */ (0,
|
|
3910
|
-
/* @__PURE__ */ (0,
|
|
3911
|
-
/* @__PURE__ */ (0,
|
|
3912
|
-
/* @__PURE__ */ (0,
|
|
4376
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Container3, { children: [
|
|
4377
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Toolbar, { children: [
|
|
4378
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Title4, { children: "Sessions" }),
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
|
|
3913
4380
|
] }),
|
|
3914
|
-
/* @__PURE__ */ (0,
|
|
4381
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3915
4382
|
ChatSessionItem,
|
|
3916
4383
|
{
|
|
3917
4384
|
session,
|
|
@@ -3923,7 +4390,7 @@ var ChatConversationList = () => {
|
|
|
3923
4390
|
)) })
|
|
3924
4391
|
] });
|
|
3925
4392
|
};
|
|
3926
|
-
var Container3 =
|
|
4393
|
+
var Container3 = import_styled16.default.aside`
|
|
3927
4394
|
width: 280px;
|
|
3928
4395
|
min-width: 280px;
|
|
3929
4396
|
border-right: 1px solid var(--border-default, rgba(255, 255, 255, 0.08));
|
|
@@ -3931,18 +4398,18 @@ var Container3 = import_styled17.default.aside`
|
|
|
3931
4398
|
flex-direction: column;
|
|
3932
4399
|
background: rgba(255, 255, 255, 0.02);
|
|
3933
4400
|
`;
|
|
3934
|
-
var Toolbar =
|
|
4401
|
+
var Toolbar = import_styled16.default.div`
|
|
3935
4402
|
padding: 20px 16px 12px;
|
|
3936
4403
|
display: flex;
|
|
3937
4404
|
flex-direction: column;
|
|
3938
4405
|
gap: 12px;
|
|
3939
4406
|
`;
|
|
3940
|
-
var Title4 =
|
|
4407
|
+
var Title4 = import_styled16.default.h2`
|
|
3941
4408
|
margin: 0;
|
|
3942
4409
|
font-size: 14px;
|
|
3943
4410
|
color: var(--text-secondary);
|
|
3944
4411
|
`;
|
|
3945
|
-
var CreateButton =
|
|
4412
|
+
var CreateButton = import_styled16.default.button`
|
|
3946
4413
|
border: none;
|
|
3947
4414
|
border-radius: 12px;
|
|
3948
4415
|
padding: 12px 14px;
|
|
@@ -3951,7 +4418,7 @@ var CreateButton = import_styled17.default.button`
|
|
|
3951
4418
|
text-align: left;
|
|
3952
4419
|
cursor: pointer;
|
|
3953
4420
|
`;
|
|
3954
|
-
var List2 =
|
|
4421
|
+
var List2 = import_styled16.default.div`
|
|
3955
4422
|
padding: 0 12px 16px;
|
|
3956
4423
|
display: flex;
|
|
3957
4424
|
flex-direction: column;
|
|
@@ -3960,8 +4427,8 @@ var List2 = import_styled17.default.div`
|
|
|
3960
4427
|
`;
|
|
3961
4428
|
|
|
3962
4429
|
// src/components/ai-chat/index.tsx
|
|
3963
|
-
var
|
|
3964
|
-
var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */ (0,
|
|
4430
|
+
var import_jsx_runtime18 = require("@emotion/react/jsx-runtime");
|
|
4431
|
+
var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3965
4432
|
import_compass_ui4.ConfigProvider,
|
|
3966
4433
|
{
|
|
3967
4434
|
theme: {
|
|
@@ -3996,23 +4463,23 @@ var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE_
|
|
|
3996
4463
|
}
|
|
3997
4464
|
}
|
|
3998
4465
|
},
|
|
3999
|
-
children: /* @__PURE__ */ (0,
|
|
4000
|
-
showConversationList ? /* @__PURE__ */ (0,
|
|
4001
|
-
/* @__PURE__ */ (0,
|
|
4002
|
-
/* @__PURE__ */ (0,
|
|
4003
|
-
/* @__PURE__ */ (0,
|
|
4466
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Root, { "data-testid": "ai-chat", children: [
|
|
4467
|
+
showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatConversationList, {}) : null,
|
|
4468
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Workspace, { children: [
|
|
4469
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatThread, {}),
|
|
4470
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatComposer, {})
|
|
4004
4471
|
] })
|
|
4005
4472
|
] }) })
|
|
4006
4473
|
}
|
|
4007
4474
|
);
|
|
4008
|
-
var Root =
|
|
4475
|
+
var Root = import_styled17.default.div`
|
|
4009
4476
|
display: flex;
|
|
4010
4477
|
width: 100%;
|
|
4011
4478
|
height: 100%;
|
|
4012
4479
|
min-height: 0;
|
|
4013
4480
|
overflow: hidden;
|
|
4014
4481
|
`;
|
|
4015
|
-
var Workspace =
|
|
4482
|
+
var Workspace = import_styled17.default.section`
|
|
4016
4483
|
flex: 1;
|
|
4017
4484
|
display: flex;
|
|
4018
4485
|
flex-direction: column;
|
|
@@ -4024,6 +4491,7 @@ var Workspace = import_styled18.default.section`
|
|
|
4024
4491
|
AiChat,
|
|
4025
4492
|
AiChatProvider,
|
|
4026
4493
|
CHAT_AGENT_MODES,
|
|
4494
|
+
CHAT_MESSAGE_RENDER_ORDERS,
|
|
4027
4495
|
ChatComposer,
|
|
4028
4496
|
ChatConversationList,
|
|
4029
4497
|
ChatThread,
|