@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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/components/ai-chat/index.tsx
|
|
2
|
-
import
|
|
2
|
+
import styled17 from "@emotion/styled";
|
|
3
3
|
import { ConfigProvider } from "@xinghunm/compass-ui";
|
|
4
4
|
|
|
5
5
|
// src/components/ai-chat-provider/index.tsx
|
|
@@ -16,6 +16,7 @@ import { createStore } from "zustand/vanilla";
|
|
|
16
16
|
// src/types/index.ts
|
|
17
17
|
var CHAT_AGENT_MODES = ["ask", "plan", "agent"];
|
|
18
18
|
var DEFAULT_CHAT_AGENT_MODE = "agent";
|
|
19
|
+
var CHAT_MESSAGE_RENDER_ORDERS = ["blocks-first", "timeline"];
|
|
19
20
|
var DEFAULT_AI_CHAT_LABELS = {
|
|
20
21
|
sendButton: "Send",
|
|
21
22
|
stopButton: "Stop",
|
|
@@ -517,7 +518,14 @@ var createDefaultChatTransport = ({
|
|
|
517
518
|
// src/components/ai-chat-provider/index.tsx
|
|
518
519
|
import { jsx } from "@emotion/react/jsx-runtime";
|
|
519
520
|
var AiChatProvider = (props) => {
|
|
520
|
-
const {
|
|
521
|
+
const {
|
|
522
|
+
defaultMode,
|
|
523
|
+
labels,
|
|
524
|
+
renderMessageBlock,
|
|
525
|
+
messageRenderOrder,
|
|
526
|
+
enableImageAttachments = true,
|
|
527
|
+
children
|
|
528
|
+
} = props;
|
|
521
529
|
const [store] = useState(
|
|
522
530
|
() => createChatStore(defaultMode ? { preferredMode: defaultMode } : void 0)
|
|
523
531
|
);
|
|
@@ -569,6 +577,7 @@ var AiChatProvider = (props) => {
|
|
|
569
577
|
sendRef,
|
|
570
578
|
retryRef,
|
|
571
579
|
renderMessageBlock,
|
|
580
|
+
messageRenderOrder,
|
|
572
581
|
transformStreamPacket: defaultTransformStreamPacket,
|
|
573
582
|
enableImageAttachments
|
|
574
583
|
}),
|
|
@@ -579,6 +588,7 @@ var AiChatProvider = (props) => {
|
|
|
579
588
|
defaultTransformStreamPacket,
|
|
580
589
|
enableImageAttachments,
|
|
581
590
|
labels,
|
|
591
|
+
messageRenderOrder,
|
|
582
592
|
renderMessageBlock,
|
|
583
593
|
sendRef,
|
|
584
594
|
retryRef,
|
|
@@ -590,8 +600,8 @@ var AiChatProvider = (props) => {
|
|
|
590
600
|
};
|
|
591
601
|
|
|
592
602
|
// src/components/chat-thread/index.tsx
|
|
593
|
-
import { useCallback as useCallback2, useLayoutEffect, useMemo as
|
|
594
|
-
import
|
|
603
|
+
import { useCallback as useCallback2, useLayoutEffect, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
|
|
604
|
+
import styled9 from "@emotion/styled";
|
|
595
605
|
|
|
596
606
|
// src/context/use-chat-context.ts
|
|
597
607
|
import { useContext } from "react";
|
|
@@ -609,25 +619,9 @@ var useChatStore = (selector) => {
|
|
|
609
619
|
|
|
610
620
|
// src/components/chat-thread/lib/chat-thread.ts
|
|
611
621
|
var CHAT_THREAD_SCROLL_TOP_GAP = 16;
|
|
612
|
-
var findLatestUserMessageId = (historyMessages) => {
|
|
613
|
-
for (let index = historyMessages.length - 1; index >= 0; index -= 1) {
|
|
614
|
-
if (historyMessages[index]?.role === "user") {
|
|
615
|
-
return historyMessages[index]?.id;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return void 0;
|
|
619
|
-
};
|
|
620
|
-
var calculateChatThreadScrollSpacerHeight = ({
|
|
621
|
-
containerClientHeight,
|
|
622
|
-
containerScrollHeight,
|
|
623
|
-
targetOffsetTop
|
|
624
|
-
}) => Math.max(
|
|
625
|
-
0,
|
|
626
|
-
targetOffsetTop - CHAT_THREAD_SCROLL_TOP_GAP - (containerScrollHeight - containerClientHeight)
|
|
627
|
-
);
|
|
628
622
|
|
|
629
623
|
// src/components/chat-thread/components/chat-message-item.tsx
|
|
630
|
-
import { Fragment, memo, useState as
|
|
624
|
+
import { Fragment, memo, useState as useState4 } from "react";
|
|
631
625
|
import styled7 from "@emotion/styled";
|
|
632
626
|
import { keyframes } from "@emotion/react";
|
|
633
627
|
import ReactMarkdown from "react-markdown";
|
|
@@ -856,11 +850,319 @@ var useChatMessageReveal = (message) => {
|
|
|
856
850
|
}, [batchedTargetUnitCount, displayedUnitCount, isAssistantStreaming, message.role]);
|
|
857
851
|
const settledContent = isFreshBlockActive ? contentBlocks.slice(0, -1).join("\n\n") : displayedContent;
|
|
858
852
|
const freshContent = isFreshBlockActive ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
|
|
853
|
+
const displayedBlocks = isAssistantStreaming && contentBlocks.length > 1 ? contentBlocks.map((content, index) => ({
|
|
854
|
+
content,
|
|
855
|
+
tone: isFreshBlockActive && index === contentBlocks.length - 1 ? "fresh" : "settled"
|
|
856
|
+
})) : [
|
|
857
|
+
{
|
|
858
|
+
content: displayedContent,
|
|
859
|
+
tone: "settled"
|
|
860
|
+
}
|
|
861
|
+
];
|
|
859
862
|
return {
|
|
860
863
|
isAssistantStreaming,
|
|
864
|
+
isFreshBlockActive,
|
|
861
865
|
displayedContent,
|
|
862
866
|
settledContent,
|
|
863
|
-
freshContent
|
|
867
|
+
freshContent,
|
|
868
|
+
displayedBlocks
|
|
869
|
+
};
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
// src/components/chat-thread/hooks/use-timeline-block-anchors.ts
|
|
873
|
+
import { useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3, useState as useState2 } from "react";
|
|
874
|
+
|
|
875
|
+
// src/components/chat-thread/lib/chat-message-timeline.ts
|
|
876
|
+
var stringifyTimelineKeyPart = (value) => {
|
|
877
|
+
if (value === null || value === void 0) {
|
|
878
|
+
return String(value);
|
|
879
|
+
}
|
|
880
|
+
if (Array.isArray(value)) {
|
|
881
|
+
return `[${value.map((item) => stringifyTimelineKeyPart(item)).join(",")}]`;
|
|
882
|
+
}
|
|
883
|
+
if (typeof value === "object") {
|
|
884
|
+
return `{${Object.entries(value).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key, nestedValue]) => `${key}:${stringifyTimelineKeyPart(nestedValue)}`).join(",")}}`;
|
|
885
|
+
}
|
|
886
|
+
return String(value);
|
|
887
|
+
};
|
|
888
|
+
var getTimelineBlockKey = (block, index) => {
|
|
889
|
+
switch (block.type) {
|
|
890
|
+
case "markdown":
|
|
891
|
+
return null;
|
|
892
|
+
case "notice":
|
|
893
|
+
return `${index}:notice:${block.tone}:${block.text}`;
|
|
894
|
+
case "parameter_summary":
|
|
895
|
+
return `${index}:parameter_summary:${block.items.map((item) => `${item.label}:${item.value}:${item.fieldPath ?? ""}`).join("|")}`;
|
|
896
|
+
case "confirmation_card":
|
|
897
|
+
return `${index}:confirmation_card:${block.proposal.proposalId}`;
|
|
898
|
+
case "result_summary":
|
|
899
|
+
return `${index}:result_summary:${block.summary.taskId}:${block.summary.status}`;
|
|
900
|
+
case "questionnaire":
|
|
901
|
+
return `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
902
|
+
case "custom":
|
|
903
|
+
return `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
904
|
+
default:
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
var getTimelineConsumedText = (blocks) => blocks.filter(
|
|
909
|
+
(block) => block.type === "markdown"
|
|
910
|
+
).map((block) => block.text).join("\n\n");
|
|
911
|
+
var getTimelineTextStream = (content, blocks) => {
|
|
912
|
+
const consumedText = getTimelineConsumedText(blocks);
|
|
913
|
+
if (consumedText.length > 0 && content.startsWith(consumedText)) {
|
|
914
|
+
return content.slice(consumedText.length);
|
|
915
|
+
}
|
|
916
|
+
return content;
|
|
917
|
+
};
|
|
918
|
+
var buildTimelineTextDisplay = (content, isAssistantStreaming, isFreshBlockActive = isAssistantStreaming) => {
|
|
919
|
+
const contentBlocks = splitMarkdownBlocks(content);
|
|
920
|
+
const settledContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks.slice(0, -1).join("\n\n") : content;
|
|
921
|
+
const freshContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
|
|
922
|
+
const displayedBlocks = contentBlocks.length > 1 ? contentBlocks.map((blockContent, index) => ({
|
|
923
|
+
content: blockContent,
|
|
924
|
+
tone: isAssistantStreaming && isFreshBlockActive && freshContent && index === contentBlocks.length - 1 ? "fresh" : "settled"
|
|
925
|
+
})) : [{ content, tone: "settled" }];
|
|
926
|
+
return {
|
|
927
|
+
settledContent,
|
|
928
|
+
freshContent,
|
|
929
|
+
displayedBlocks
|
|
930
|
+
};
|
|
931
|
+
};
|
|
932
|
+
var getTimelineDisplayUnitCount = (content) => splitMarkdownBlocks(content).reduce((count, block) => count + Array.from(block).length, 0);
|
|
933
|
+
var buildAnchoredTimelineSegments = ({
|
|
934
|
+
blocks,
|
|
935
|
+
timelineBlockAnchors,
|
|
936
|
+
timelineDisplayedBlocks,
|
|
937
|
+
visibleTimelineBlockKeys
|
|
938
|
+
}) => {
|
|
939
|
+
const orderedTimelineSegments = [];
|
|
940
|
+
const totalTimelineUnits = timelineDisplayedBlocks.reduce(
|
|
941
|
+
(count, block) => count + Array.from(block.content).length,
|
|
942
|
+
0
|
|
943
|
+
);
|
|
944
|
+
let textCursor = 0;
|
|
945
|
+
const buildTextSegment = (start, end, options) => {
|
|
946
|
+
if (end <= start) {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
const displayedBlocks = [];
|
|
950
|
+
let blockCursor = 0;
|
|
951
|
+
for (const block of timelineDisplayedBlocks) {
|
|
952
|
+
const blockUnits = Array.from(block.content);
|
|
953
|
+
const blockStart = blockCursor;
|
|
954
|
+
const blockEnd = blockCursor + blockUnits.length;
|
|
955
|
+
if (blockEnd <= start) {
|
|
956
|
+
blockCursor = blockEnd;
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
if (blockStart >= end) {
|
|
960
|
+
break;
|
|
961
|
+
}
|
|
962
|
+
const sliceStart = Math.max(0, start - blockStart);
|
|
963
|
+
const sliceEnd = Math.min(blockUnits.length, end - blockStart);
|
|
964
|
+
const slicedContent = blockUnits.slice(sliceStart, sliceEnd).join("");
|
|
965
|
+
if (slicedContent) {
|
|
966
|
+
displayedBlocks.push({
|
|
967
|
+
content: slicedContent,
|
|
968
|
+
tone: options?.forceSettled ? "settled" : block.tone
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
blockCursor = blockEnd;
|
|
972
|
+
}
|
|
973
|
+
const content = displayedBlocks.map((block) => block.content).join("\n\n");
|
|
974
|
+
if (!content) {
|
|
975
|
+
return null;
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
type: "text",
|
|
979
|
+
content,
|
|
980
|
+
displayedBlocks,
|
|
981
|
+
useTimelineSegmentation: true
|
|
982
|
+
};
|
|
983
|
+
};
|
|
984
|
+
let trailingCutoff = totalTimelineUnits;
|
|
985
|
+
for (const [index, block] of blocks.entries()) {
|
|
986
|
+
if (block.type === "markdown") {
|
|
987
|
+
orderedTimelineSegments.push({
|
|
988
|
+
type: "markdown",
|
|
989
|
+
content: block.text
|
|
990
|
+
});
|
|
991
|
+
continue;
|
|
992
|
+
}
|
|
993
|
+
const blockKey = getTimelineBlockKey(block, index);
|
|
994
|
+
const anchor = blockKey !== null ? timelineBlockAnchors[blockKey] ?? totalTimelineUnits : totalTimelineUnits;
|
|
995
|
+
const isBlockVisible = blockKey !== null && visibleTimelineBlockKeys?.[blockKey] ? true : anchor <= totalTimelineUnits;
|
|
996
|
+
if (anchor > textCursor) {
|
|
997
|
+
const textSegment = buildTextSegment(textCursor, Math.min(anchor, totalTimelineUnits), {
|
|
998
|
+
forceSettled: isBlockVisible
|
|
999
|
+
});
|
|
1000
|
+
if (textSegment) {
|
|
1001
|
+
orderedTimelineSegments.push(textSegment);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
if (!isBlockVisible) {
|
|
1005
|
+
textCursor = Math.min(anchor, totalTimelineUnits);
|
|
1006
|
+
trailingCutoff = Math.min(trailingCutoff, textCursor);
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
trailingCutoff = totalTimelineUnits;
|
|
1010
|
+
orderedTimelineSegments.push({
|
|
1011
|
+
type: "block",
|
|
1012
|
+
block,
|
|
1013
|
+
index
|
|
1014
|
+
});
|
|
1015
|
+
textCursor = Math.max(textCursor, anchor);
|
|
1016
|
+
}
|
|
1017
|
+
const trailingTextSegment = buildTextSegment(textCursor, trailingCutoff);
|
|
1018
|
+
if (trailingTextSegment) {
|
|
1019
|
+
orderedTimelineSegments.push(trailingTextSegment);
|
|
1020
|
+
}
|
|
1021
|
+
return orderedTimelineSegments;
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
// src/components/chat-thread/hooks/use-timeline-block-anchors.ts
|
|
1025
|
+
var useTimelineBlockAnchors = ({
|
|
1026
|
+
blocks,
|
|
1027
|
+
displayedTimelineTextLength,
|
|
1028
|
+
isAssistantStreaming,
|
|
1029
|
+
message,
|
|
1030
|
+
messageRenderOrder
|
|
1031
|
+
}) => {
|
|
1032
|
+
const [timelineBlockAnchors, setTimelineBlockAnchors] = useState2({});
|
|
1033
|
+
const [visibleTimelineBlockKeys, setVisibleTimelineBlockKeys] = useState2({});
|
|
1034
|
+
const currentTimelineBlockKeys = useMemo3(
|
|
1035
|
+
() => blocks.map((block, index) => getTimelineBlockKey(block, index)).filter((blockKey) => Boolean(blockKey)),
|
|
1036
|
+
[blocks]
|
|
1037
|
+
);
|
|
1038
|
+
const timelineTextStreamLength = useMemo3(
|
|
1039
|
+
() => getTimelineDisplayUnitCount(getTimelineTextStream(message.content, blocks)),
|
|
1040
|
+
[blocks, message.content]
|
|
1041
|
+
);
|
|
1042
|
+
const previousTimelineStateRef = useRef3({
|
|
1043
|
+
messageId: message.id,
|
|
1044
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1045
|
+
textLength: timelineTextStreamLength
|
|
1046
|
+
});
|
|
1047
|
+
const effectiveTimelineBlockAnchors = useMemo3(() => {
|
|
1048
|
+
if (messageRenderOrder !== "timeline" || !isAssistantStreaming) {
|
|
1049
|
+
return timelineBlockAnchors;
|
|
1050
|
+
}
|
|
1051
|
+
const previousTimelineState = previousTimelineStateRef.current;
|
|
1052
|
+
const previousBlockKeys = new Set(previousTimelineState.blockKeys);
|
|
1053
|
+
return currentTimelineBlockKeys.reduce(
|
|
1054
|
+
(acc, blockKey) => {
|
|
1055
|
+
const existingAnchor = timelineBlockAnchors[blockKey];
|
|
1056
|
+
if (existingAnchor !== void 0) {
|
|
1057
|
+
acc[blockKey] = existingAnchor;
|
|
1058
|
+
return acc;
|
|
1059
|
+
}
|
|
1060
|
+
if (!previousBlockKeys.has(blockKey)) {
|
|
1061
|
+
acc[blockKey] = timelineTextStreamLength;
|
|
1062
|
+
}
|
|
1063
|
+
return acc;
|
|
1064
|
+
},
|
|
1065
|
+
{ ...timelineBlockAnchors }
|
|
1066
|
+
);
|
|
1067
|
+
}, [
|
|
1068
|
+
currentTimelineBlockKeys,
|
|
1069
|
+
isAssistantStreaming,
|
|
1070
|
+
messageRenderOrder,
|
|
1071
|
+
timelineBlockAnchors,
|
|
1072
|
+
timelineTextStreamLength
|
|
1073
|
+
]);
|
|
1074
|
+
useEffect2(() => {
|
|
1075
|
+
const previousTimelineState = previousTimelineStateRef.current;
|
|
1076
|
+
if (previousTimelineState.messageId !== message.id) {
|
|
1077
|
+
if (Object.keys(timelineBlockAnchors).length > 0) {
|
|
1078
|
+
setTimelineBlockAnchors({});
|
|
1079
|
+
}
|
|
1080
|
+
if (Object.keys(visibleTimelineBlockKeys).length > 0) {
|
|
1081
|
+
setVisibleTimelineBlockKeys({});
|
|
1082
|
+
}
|
|
1083
|
+
previousTimelineStateRef.current = {
|
|
1084
|
+
messageId: message.id,
|
|
1085
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1086
|
+
textLength: timelineTextStreamLength
|
|
1087
|
+
};
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (messageRenderOrder === "timeline" && isAssistantStreaming) {
|
|
1091
|
+
const previousBlockKeys = new Set(previousTimelineState.blockKeys);
|
|
1092
|
+
const nextAnchors = currentTimelineBlockKeys.reduce(
|
|
1093
|
+
(acc, blockKey) => {
|
|
1094
|
+
const existingAnchor = timelineBlockAnchors[blockKey];
|
|
1095
|
+
if (existingAnchor !== void 0) {
|
|
1096
|
+
acc[blockKey] = existingAnchor;
|
|
1097
|
+
return acc;
|
|
1098
|
+
}
|
|
1099
|
+
if (!previousBlockKeys.has(blockKey)) {
|
|
1100
|
+
acc[blockKey] = timelineTextStreamLength;
|
|
1101
|
+
}
|
|
1102
|
+
return acc;
|
|
1103
|
+
},
|
|
1104
|
+
{}
|
|
1105
|
+
);
|
|
1106
|
+
const hasAnchorChanged = Object.keys(nextAnchors).length !== Object.keys(timelineBlockAnchors).length || Object.entries(nextAnchors).some(
|
|
1107
|
+
([blockKey, anchor]) => timelineBlockAnchors[blockKey] !== anchor
|
|
1108
|
+
);
|
|
1109
|
+
if (hasAnchorChanged) {
|
|
1110
|
+
setTimelineBlockAnchors(nextAnchors);
|
|
1111
|
+
}
|
|
1112
|
+
} else if (messageRenderOrder !== "timeline" && Object.keys(timelineBlockAnchors).length > 0) {
|
|
1113
|
+
setTimelineBlockAnchors({});
|
|
1114
|
+
}
|
|
1115
|
+
previousTimelineStateRef.current = {
|
|
1116
|
+
messageId: message.id,
|
|
1117
|
+
blockKeys: currentTimelineBlockKeys,
|
|
1118
|
+
textLength: timelineTextStreamLength
|
|
1119
|
+
};
|
|
1120
|
+
}, [
|
|
1121
|
+
currentTimelineBlockKeys,
|
|
1122
|
+
isAssistantStreaming,
|
|
1123
|
+
message.id,
|
|
1124
|
+
message.content,
|
|
1125
|
+
messageRenderOrder,
|
|
1126
|
+
timelineBlockAnchors,
|
|
1127
|
+
timelineTextStreamLength,
|
|
1128
|
+
visibleTimelineBlockKeys
|
|
1129
|
+
]);
|
|
1130
|
+
useEffect2(() => {
|
|
1131
|
+
if (messageRenderOrder !== "timeline") {
|
|
1132
|
+
if (Object.keys(visibleTimelineBlockKeys).length > 0) {
|
|
1133
|
+
setVisibleTimelineBlockKeys({});
|
|
1134
|
+
}
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
const nextVisibleBlockKeys = currentTimelineBlockKeys.reduce(
|
|
1138
|
+
(acc, blockKey) => {
|
|
1139
|
+
if (visibleTimelineBlockKeys[blockKey]) {
|
|
1140
|
+
acc[blockKey] = true;
|
|
1141
|
+
return acc;
|
|
1142
|
+
}
|
|
1143
|
+
const anchor = effectiveTimelineBlockAnchors[blockKey];
|
|
1144
|
+
if (anchor !== void 0 && anchor <= displayedTimelineTextLength) {
|
|
1145
|
+
acc[blockKey] = true;
|
|
1146
|
+
}
|
|
1147
|
+
return acc;
|
|
1148
|
+
},
|
|
1149
|
+
{}
|
|
1150
|
+
);
|
|
1151
|
+
const hasVisibleBlockChanged = Object.keys(nextVisibleBlockKeys).length !== Object.keys(visibleTimelineBlockKeys).length || Object.keys(nextVisibleBlockKeys).some((blockKey) => !visibleTimelineBlockKeys[blockKey]);
|
|
1152
|
+
if (hasVisibleBlockChanged) {
|
|
1153
|
+
setVisibleTimelineBlockKeys(nextVisibleBlockKeys);
|
|
1154
|
+
}
|
|
1155
|
+
}, [
|
|
1156
|
+
currentTimelineBlockKeys,
|
|
1157
|
+
displayedTimelineTextLength,
|
|
1158
|
+
effectiveTimelineBlockAnchors,
|
|
1159
|
+
messageRenderOrder,
|
|
1160
|
+
timelineBlockAnchors,
|
|
1161
|
+
visibleTimelineBlockKeys
|
|
1162
|
+
]);
|
|
1163
|
+
return {
|
|
1164
|
+
timelineBlockAnchors: effectiveTimelineBlockAnchors,
|
|
1165
|
+
visibleTimelineBlockKeys
|
|
864
1166
|
};
|
|
865
1167
|
};
|
|
866
1168
|
|
|
@@ -1074,7 +1376,7 @@ var Value = styled3.span`
|
|
|
1074
1376
|
`;
|
|
1075
1377
|
|
|
1076
1378
|
// src/components/chat-thread/components/pde-ai-questionnaire-card.tsx
|
|
1077
|
-
import { useState as
|
|
1379
|
+
import { useState as useState3 } from "react";
|
|
1078
1380
|
import styled4 from "@emotion/styled";
|
|
1079
1381
|
import { jsx as jsx5, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
1080
1382
|
var OTHER_OPTION_VALUE = "__other__";
|
|
@@ -1176,10 +1478,10 @@ var PDEAIQuestionnaireCardInner = ({
|
|
|
1176
1478
|
interactive = false,
|
|
1177
1479
|
onSubmit
|
|
1178
1480
|
}) => {
|
|
1179
|
-
const [answers, setAnswers] =
|
|
1481
|
+
const [answers, setAnswers] = useState3(
|
|
1180
1482
|
() => createInitialAnswers(questionnaire)
|
|
1181
1483
|
);
|
|
1182
|
-
const [errorMessage, setErrorMessage] =
|
|
1484
|
+
const [errorMessage, setErrorMessage] = useState3(null);
|
|
1183
1485
|
const handleSubmit = () => {
|
|
1184
1486
|
const missingQuestions = questionnaire.questions.filter(
|
|
1185
1487
|
(question) => question.required && isMissingRequiredAnswer(question, answers)
|
|
@@ -1615,7 +1917,7 @@ var Detail = styled5.li`
|
|
|
1615
1917
|
|
|
1616
1918
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
1617
1919
|
import styled6 from "@emotion/styled";
|
|
1618
|
-
import { useEffect as
|
|
1920
|
+
import { useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
1619
1921
|
import { jsx as jsx7 } from "@emotion/react/jsx-runtime";
|
|
1620
1922
|
var Overlay = styled6.div`
|
|
1621
1923
|
position: fixed;
|
|
@@ -1634,8 +1936,8 @@ var Img = styled6.img`
|
|
|
1634
1936
|
border-radius: 4px;
|
|
1635
1937
|
`;
|
|
1636
1938
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
1637
|
-
const overlayRef =
|
|
1638
|
-
|
|
1939
|
+
const overlayRef = useRef4(null);
|
|
1940
|
+
useEffect3(() => {
|
|
1639
1941
|
const handleKey = (e) => {
|
|
1640
1942
|
if (e.key === "Escape")
|
|
1641
1943
|
onClose();
|
|
@@ -1643,7 +1945,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
1643
1945
|
document.addEventListener("keydown", handleKey);
|
|
1644
1946
|
return () => document.removeEventListener("keydown", handleKey);
|
|
1645
1947
|
}, [onClose]);
|
|
1646
|
-
|
|
1948
|
+
useEffect3(() => {
|
|
1647
1949
|
overlayRef.current?.focus();
|
|
1648
1950
|
}, []);
|
|
1649
1951
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -1806,9 +2108,16 @@ var ChatMessageItemView = ({
|
|
|
1806
2108
|
onQuestionnaireSubmit,
|
|
1807
2109
|
renderMessageBlock
|
|
1808
2110
|
}) => {
|
|
1809
|
-
const { labels } = useChatContext();
|
|
1810
|
-
const [activeImage, setActiveImage] =
|
|
1811
|
-
const {
|
|
2111
|
+
const { labels, messageRenderOrder = "blocks-first" } = useChatContext();
|
|
2112
|
+
const [activeImage, setActiveImage] = useState4(void 0);
|
|
2113
|
+
const {
|
|
2114
|
+
displayedBlocks,
|
|
2115
|
+
displayedContent,
|
|
2116
|
+
freshContent,
|
|
2117
|
+
isAssistantStreaming,
|
|
2118
|
+
isFreshBlockActive,
|
|
2119
|
+
settledContent
|
|
2120
|
+
} = useChatMessageReveal(message);
|
|
1812
2121
|
const isStoppedAssistant = message.role === "assistant" && message.status === "stopped";
|
|
1813
2122
|
const attachments = message.attachments ?? [];
|
|
1814
2123
|
const blocks = message.blocks ?? [];
|
|
@@ -1820,6 +2129,22 @@ var ChatMessageItemView = ({
|
|
|
1820
2129
|
const canSubmitConfirmation = isPlanMode && typeof onConfirmationSubmit === "function";
|
|
1821
2130
|
const canSubmitQuestionnaire = isPlanMode && typeof onQuestionnaireSubmit === "function";
|
|
1822
2131
|
const shouldShowStreamingCaret = isAssistantStreaming && (!shouldRenderStructuredBlocks || hasTextContent);
|
|
2132
|
+
const timelineConsumedText = messageRenderOrder === "timeline" ? getTimelineConsumedText(blocks) : "";
|
|
2133
|
+
const hasConsumedTimelineText = timelineConsumedText.length > 0 && displayedContent.startsWith(timelineConsumedText);
|
|
2134
|
+
const timelineDisplayedContent = hasConsumedTimelineText ? displayedContent.slice(timelineConsumedText.length) : displayedContent;
|
|
2135
|
+
const timelineTextDisplay = buildTimelineTextDisplay(
|
|
2136
|
+
timelineDisplayedContent,
|
|
2137
|
+
isAssistantStreaming,
|
|
2138
|
+
isFreshBlockActive
|
|
2139
|
+
);
|
|
2140
|
+
const displayedTimelineTextLength = getTimelineDisplayUnitCount(timelineDisplayedContent);
|
|
2141
|
+
const { timelineBlockAnchors, visibleTimelineBlockKeys } = useTimelineBlockAnchors({
|
|
2142
|
+
blocks,
|
|
2143
|
+
displayedTimelineTextLength,
|
|
2144
|
+
isAssistantStreaming,
|
|
2145
|
+
message,
|
|
2146
|
+
messageRenderOrder
|
|
2147
|
+
});
|
|
1823
2148
|
const renderChatMessageBlock = (block, index) => {
|
|
1824
2149
|
switch (block.type) {
|
|
1825
2150
|
case "markdown":
|
|
@@ -1876,11 +2201,69 @@ var ChatMessageItemView = ({
|
|
|
1876
2201
|
return null;
|
|
1877
2202
|
}
|
|
1878
2203
|
};
|
|
1879
|
-
const renderTextContent = () =>
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
2204
|
+
const renderTextContent = (options) => {
|
|
2205
|
+
const textContent = options?.content ?? displayedContent;
|
|
2206
|
+
const localTimelineTextDisplay = options?.displayedBlocks ? void 0 : options?.useTimelineSegmentation && options.content !== void 0 ? buildTimelineTextDisplay(options.content, isAssistantStreaming, isFreshBlockActive) : void 0;
|
|
2207
|
+
const textBlocks = options?.displayedBlocks ?? localTimelineTextDisplay?.displayedBlocks ?? displayedBlocks;
|
|
2208
|
+
const settledText = localTimelineTextDisplay?.settledContent ?? settledContent;
|
|
2209
|
+
const freshText = localTimelineTextDisplay?.freshContent ?? freshContent;
|
|
2210
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2211
|
+
textBlocks.filter((block) => block.content).map((block, index) => /* @__PURE__ */ jsx8(
|
|
2212
|
+
ContentBlock,
|
|
2213
|
+
{
|
|
2214
|
+
"data-testid": block.tone === "fresh" ? "chat-message-fresh-block" : "chat-message-settled-block",
|
|
2215
|
+
"data-block-tone": block.tone,
|
|
2216
|
+
"data-block-index": index,
|
|
2217
|
+
children: renderMarkdownContent(block.content)
|
|
2218
|
+
},
|
|
2219
|
+
`${block.tone}-${index}`
|
|
2220
|
+
)),
|
|
2221
|
+
!textBlocks.some((block) => block.content) && !settledText && !freshText && Boolean(textContent) ? /* @__PURE__ */ jsx8(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(textContent) }) : null
|
|
2222
|
+
] });
|
|
2223
|
+
};
|
|
2224
|
+
const renderStaticTextSegment = (content) => /* @__PURE__ */ jsx8(ContentBlock, { "data-testid": "chat-message-settled-block", "data-block-tone": "settled", children: renderMarkdownContent(content) });
|
|
2225
|
+
const bodySegments = (() => {
|
|
2226
|
+
if (!shouldRenderStructuredBlocks && hasTextContent) {
|
|
2227
|
+
return [{ type: "text" }];
|
|
2228
|
+
}
|
|
2229
|
+
if (!shouldRenderStructuredBlocks) {
|
|
2230
|
+
return [];
|
|
2231
|
+
}
|
|
2232
|
+
if (messageRenderOrder === "timeline" && hasTextContent) {
|
|
2233
|
+
const hasAnchoredStructuredBlocks = blocks.some((block, index) => {
|
|
2234
|
+
const blockKey = getTimelineBlockKey(block, index);
|
|
2235
|
+
return blockKey ? timelineBlockAnchors[blockKey] !== void 0 : false;
|
|
2236
|
+
});
|
|
2237
|
+
if (hasAnchoredStructuredBlocks) {
|
|
2238
|
+
return buildAnchoredTimelineSegments({
|
|
2239
|
+
blocks,
|
|
2240
|
+
timelineBlockAnchors,
|
|
2241
|
+
timelineDisplayedBlocks: timelineTextDisplay.displayedBlocks,
|
|
2242
|
+
visibleTimelineBlockKeys
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
const orderedTimelineSegments = blocks.map(
|
|
2246
|
+
(block, index) => block.type === "markdown" ? {
|
|
2247
|
+
type: "markdown",
|
|
2248
|
+
content: block.text
|
|
2249
|
+
} : {
|
|
2250
|
+
type: "block",
|
|
2251
|
+
block,
|
|
2252
|
+
index
|
|
2253
|
+
}
|
|
2254
|
+
);
|
|
2255
|
+
if (!timelineConsumedText) {
|
|
2256
|
+
return displayedContent ? [{ type: "text", content: displayedContent }, ...orderedTimelineSegments] : orderedTimelineSegments;
|
|
2257
|
+
}
|
|
2258
|
+
return timelineDisplayedContent ? [...orderedTimelineSegments, { type: "text", content: timelineDisplayedContent }] : orderedTimelineSegments;
|
|
2259
|
+
}
|
|
2260
|
+
const orderedBlocks = blocks.map((block, index) => ({
|
|
2261
|
+
type: "block",
|
|
2262
|
+
block,
|
|
2263
|
+
index
|
|
2264
|
+
}));
|
|
2265
|
+
return hasTextContent ? [...orderedBlocks, { type: "text" }] : orderedBlocks;
|
|
2266
|
+
})();
|
|
1884
2267
|
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1885
2268
|
/* @__PURE__ */ jsxs5(Bubble, { "data-role": message.role, "data-status": message.status ?? "done", children: [
|
|
1886
2269
|
/* @__PURE__ */ jsxs5(Header2, { children: [
|
|
@@ -1899,17 +2282,18 @@ var ChatMessageItemView = ({
|
|
|
1899
2282
|
isStoppedAssistant ? /* @__PURE__ */ jsx8(StatusTag, { "data-testid": "chat-message-stopped-tag", children: labels.stoppedResponse }) : null
|
|
1900
2283
|
] }),
|
|
1901
2284
|
/* @__PURE__ */ jsxs5(Content, { "data-testid": "chat-message-content", children: [
|
|
1902
|
-
shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
2285
|
+
shouldRenderStructuredBlocks || hasTextContent ? /* @__PURE__ */ jsx8(ContentStack, { "data-testid": "chat-message-body-stack", children: bodySegments.map((segment, index) => /* @__PURE__ */ jsx8(
|
|
2286
|
+
ContentSegment,
|
|
2287
|
+
{
|
|
2288
|
+
"data-testid": "chat-message-content-segment",
|
|
2289
|
+
children: segment.type === "block" ? renderChatMessageBlock(segment.block, segment.index) : segment.type === "text" ? segment.content !== void 0 ? segment.useTimelineSegmentation ? renderTextContent({
|
|
2290
|
+
content: segment.content,
|
|
2291
|
+
displayedBlocks: segment.displayedBlocks,
|
|
2292
|
+
useTimelineSegmentation: true
|
|
2293
|
+
}) : renderStaticTextSegment(segment.content) : renderTextContent() : renderStaticTextSegment(segment.content)
|
|
2294
|
+
},
|
|
2295
|
+
segment.type === "text" ? `text-${index}` : segment.type === "markdown" ? `markdown-${index}` : `${segment.block.type}-${segment.index}`
|
|
2296
|
+
)) }) : null,
|
|
1913
2297
|
attachments.length ? /* @__PURE__ */ jsx8(AttachmentGrid, { "data-testid": "chat-message-attachment-grid", children: attachments.map((attachment) => /* @__PURE__ */ jsx8(
|
|
1914
2298
|
AttachmentButton,
|
|
1915
2299
|
{
|
|
@@ -2143,65 +2527,21 @@ var StreamingCaret = styled7.span`
|
|
|
2143
2527
|
animation: ${caretBlink} 0.9s steps(1) infinite;
|
|
2144
2528
|
`;
|
|
2145
2529
|
|
|
2146
|
-
// src/components/chat-thread/components/chat-thread-history-list.tsx
|
|
2147
|
-
import { memo as memo2 } from "react";
|
|
2148
|
-
import styled8 from "@emotion/styled";
|
|
2149
|
-
import { jsx as jsx9 } from "@emotion/react/jsx-runtime";
|
|
2150
|
-
var ChatThreadHistoryList = memo2(
|
|
2151
|
-
({
|
|
2152
|
-
mode,
|
|
2153
|
-
historyMessages,
|
|
2154
|
-
latestUserMessageId,
|
|
2155
|
-
latestUserMessageRef,
|
|
2156
|
-
onConfirmationSubmit,
|
|
2157
|
-
onQuestionnaireSubmit,
|
|
2158
|
-
renderMessageBlock
|
|
2159
|
-
}) => /* @__PURE__ */ jsx9(HistoryGroup, { "data-testid": "chat-thread-history", children: historyMessages.map((message) => /* @__PURE__ */ jsx9(
|
|
2160
|
-
MessageSlot,
|
|
2161
|
-
{
|
|
2162
|
-
ref: message.id === latestUserMessageId ? latestUserMessageRef : null,
|
|
2163
|
-
"data-testid": message.id === latestUserMessageId ? "chat-latest-user-anchor" : void 0,
|
|
2164
|
-
style: message.id === latestUserMessageId ? {
|
|
2165
|
-
scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px`
|
|
2166
|
-
} : void 0,
|
|
2167
|
-
children: /* @__PURE__ */ jsx9(
|
|
2168
|
-
ChatMessageItem,
|
|
2169
|
-
{
|
|
2170
|
-
mode,
|
|
2171
|
-
message,
|
|
2172
|
-
onConfirmationSubmit,
|
|
2173
|
-
onQuestionnaireSubmit,
|
|
2174
|
-
renderMessageBlock
|
|
2175
|
-
}
|
|
2176
|
-
)
|
|
2177
|
-
},
|
|
2178
|
-
message.id
|
|
2179
|
-
)) })
|
|
2180
|
-
);
|
|
2181
|
-
ChatThreadHistoryList.displayName = "ChatThreadHistoryList";
|
|
2182
|
-
var HistoryGroup = styled8.div`
|
|
2183
|
-
display: contents;
|
|
2184
|
-
`;
|
|
2185
|
-
var MessageSlot = styled8.div`
|
|
2186
|
-
display: flex;
|
|
2187
|
-
align-items: flex-start;
|
|
2188
|
-
`;
|
|
2189
|
-
|
|
2190
2530
|
// src/components/chat-thread/components/chat-thread-empty-state.tsx
|
|
2191
|
-
import
|
|
2192
|
-
import { jsx as
|
|
2531
|
+
import styled8 from "@emotion/styled";
|
|
2532
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
|
|
2193
2533
|
var ChatThreadEmptyState = () => {
|
|
2194
2534
|
const { labels } = useChatContext();
|
|
2195
2535
|
return /* @__PURE__ */ jsxs6(EmptyShell, { "data-testid": "chat-empty-hero", children: [
|
|
2196
2536
|
/* @__PURE__ */ jsxs6(HeroMark, { children: [
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2537
|
+
/* @__PURE__ */ jsx9(HeroOrbit, {}),
|
|
2538
|
+
/* @__PURE__ */ jsx9(HeroCore, { children: "AI" })
|
|
2199
2539
|
] }),
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
/* @__PURE__ */
|
|
2540
|
+
/* @__PURE__ */ jsx9(HeroTitle, { children: labels.emptyStateTitle }),
|
|
2541
|
+
/* @__PURE__ */ jsx9(HeroSubtitle, { children: labels.emptyStateSubtitle })
|
|
2202
2542
|
] });
|
|
2203
2543
|
};
|
|
2204
|
-
var EmptyShell =
|
|
2544
|
+
var EmptyShell = styled8.div`
|
|
2205
2545
|
flex: 1;
|
|
2206
2546
|
min-height: 0;
|
|
2207
2547
|
display: flex;
|
|
@@ -2211,7 +2551,7 @@ var EmptyShell = styled9.div`
|
|
|
2211
2551
|
gap: 16px;
|
|
2212
2552
|
padding: 48px 24px 24px;
|
|
2213
2553
|
`;
|
|
2214
|
-
var HeroMark =
|
|
2554
|
+
var HeroMark = styled8.div`
|
|
2215
2555
|
position: relative;
|
|
2216
2556
|
width: 108px;
|
|
2217
2557
|
height: 108px;
|
|
@@ -2219,7 +2559,7 @@ var HeroMark = styled9.div`
|
|
|
2219
2559
|
display: grid;
|
|
2220
2560
|
place-items: center;
|
|
2221
2561
|
`;
|
|
2222
|
-
var HeroOrbit =
|
|
2562
|
+
var HeroOrbit = styled8.div`
|
|
2223
2563
|
position: absolute;
|
|
2224
2564
|
inset: 20px;
|
|
2225
2565
|
border-radius: 50%;
|
|
@@ -2242,7 +2582,7 @@ var HeroOrbit = styled9.div`
|
|
|
2242
2582
|
transform: rotate(-22deg);
|
|
2243
2583
|
}
|
|
2244
2584
|
`;
|
|
2245
|
-
var HeroCore =
|
|
2585
|
+
var HeroCore = styled8.div`
|
|
2246
2586
|
position: relative;
|
|
2247
2587
|
z-index: 1;
|
|
2248
2588
|
font-size: 28px;
|
|
@@ -2252,13 +2592,13 @@ var HeroCore = styled9.div`
|
|
|
2252
2592
|
color: rgba(242, 244, 255, 0.96);
|
|
2253
2593
|
text-shadow: 0 0 16px rgba(98, 116, 255, 0.65);
|
|
2254
2594
|
`;
|
|
2255
|
-
var HeroTitle =
|
|
2595
|
+
var HeroTitle = styled8.p`
|
|
2256
2596
|
margin: 0;
|
|
2257
2597
|
color: rgba(255, 255, 255, 0.88);
|
|
2258
2598
|
font-size: 16px;
|
|
2259
2599
|
line-height: 24px;
|
|
2260
2600
|
`;
|
|
2261
|
-
var HeroSubtitle =
|
|
2601
|
+
var HeroSubtitle = styled8.p`
|
|
2262
2602
|
margin: 0;
|
|
2263
2603
|
color: rgba(255, 255, 255, 0.72);
|
|
2264
2604
|
font-size: 14px;
|
|
@@ -2266,7 +2606,74 @@ var HeroSubtitle = styled9.p`
|
|
|
2266
2606
|
`;
|
|
2267
2607
|
|
|
2268
2608
|
// src/components/chat-thread/index.tsx
|
|
2269
|
-
import { jsx as
|
|
2609
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
|
|
2610
|
+
var renderChatMessage = ({
|
|
2611
|
+
message,
|
|
2612
|
+
mode,
|
|
2613
|
+
onConfirmationSubmit,
|
|
2614
|
+
onQuestionnaireSubmit,
|
|
2615
|
+
renderMessageBlock
|
|
2616
|
+
}) => /* @__PURE__ */ jsx10(
|
|
2617
|
+
ChatMessageItem,
|
|
2618
|
+
{
|
|
2619
|
+
mode,
|
|
2620
|
+
message,
|
|
2621
|
+
onConfirmationSubmit,
|
|
2622
|
+
onQuestionnaireSubmit,
|
|
2623
|
+
renderMessageBlock
|
|
2624
|
+
}
|
|
2625
|
+
);
|
|
2626
|
+
var renderErrorState = ({
|
|
2627
|
+
error,
|
|
2628
|
+
onRetry,
|
|
2629
|
+
retryButtonLabel
|
|
2630
|
+
}) => /* @__PURE__ */ jsxs7(ErrorState, { "data-testid": "chat-thread-error-state", children: [
|
|
2631
|
+
/* @__PURE__ */ jsx10(ErrorText, { children: error }),
|
|
2632
|
+
onRetry ? /* @__PURE__ */ jsx10(ErrorActions, { children: /* @__PURE__ */ jsx10(RetryButton, { type: "button", "data-testid": "chat-thread-retry", onClick: onRetry, children: retryButtonLabel }) }) : null
|
|
2633
|
+
] });
|
|
2634
|
+
var groupConversationTurns = (historyMessages, streamingMessage) => {
|
|
2635
|
+
const turns = [];
|
|
2636
|
+
let currentTurn = null;
|
|
2637
|
+
historyMessages.forEach((message) => {
|
|
2638
|
+
if (message.role === "user") {
|
|
2639
|
+
currentTurn = {
|
|
2640
|
+
id: message.id,
|
|
2641
|
+
userMessage: message,
|
|
2642
|
+
responseMessages: []
|
|
2643
|
+
};
|
|
2644
|
+
turns.push(currentTurn);
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
if (!currentTurn) {
|
|
2648
|
+
currentTurn = {
|
|
2649
|
+
id: `assistant-turn-${message.id}`,
|
|
2650
|
+
responseMessages: [message]
|
|
2651
|
+
};
|
|
2652
|
+
turns.push(currentTurn);
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
currentTurn.responseMessages.push(message);
|
|
2656
|
+
});
|
|
2657
|
+
if (!streamingMessage) {
|
|
2658
|
+
return turns;
|
|
2659
|
+
}
|
|
2660
|
+
const lastTurn = turns[turns.length - 1];
|
|
2661
|
+
if (lastTurn) {
|
|
2662
|
+
return [
|
|
2663
|
+
...turns.slice(0, -1),
|
|
2664
|
+
{
|
|
2665
|
+
...lastTurn,
|
|
2666
|
+
responseMessages: [...lastTurn.responseMessages, streamingMessage]
|
|
2667
|
+
}
|
|
2668
|
+
];
|
|
2669
|
+
}
|
|
2670
|
+
return [
|
|
2671
|
+
{
|
|
2672
|
+
id: `assistant-turn-${streamingMessage.id}`,
|
|
2673
|
+
responseMessages: [streamingMessage]
|
|
2674
|
+
}
|
|
2675
|
+
];
|
|
2676
|
+
};
|
|
2270
2677
|
var ChatThreadView = ({
|
|
2271
2678
|
activeSessionMode = DEFAULT_CHAT_AGENT_MODE,
|
|
2272
2679
|
historyMessages,
|
|
@@ -2278,32 +2685,46 @@ var ChatThreadView = ({
|
|
|
2278
2685
|
onQuestionnaireSubmit,
|
|
2279
2686
|
renderMessageBlock
|
|
2280
2687
|
}) => {
|
|
2281
|
-
const containerRef =
|
|
2282
|
-
const
|
|
2283
|
-
() =>
|
|
2284
|
-
[historyMessages]
|
|
2688
|
+
const containerRef = useRef5(null);
|
|
2689
|
+
const conversationTurns = useMemo4(
|
|
2690
|
+
() => groupConversationTurns(historyMessages, streamingMessage),
|
|
2691
|
+
[historyMessages, streamingMessage]
|
|
2285
2692
|
);
|
|
2286
|
-
const
|
|
2287
|
-
const
|
|
2288
|
-
const
|
|
2289
|
-
const
|
|
2290
|
-
const
|
|
2291
|
-
const
|
|
2693
|
+
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
2694
|
+
const previousTurns = conversationTurns.slice(0, -1);
|
|
2695
|
+
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
2696
|
+
const latestUserMessageRef = useRef5(null);
|
|
2697
|
+
const reservedSpaceFrameRef = useRef5(null);
|
|
2698
|
+
const [latestTurnMinHeight, setLatestTurnMinHeight] = useState5(0);
|
|
2699
|
+
const measureLatestTurnMinHeight = useCallback2(() => {
|
|
2700
|
+
const container = containerRef.current;
|
|
2701
|
+
if (!container)
|
|
2702
|
+
return;
|
|
2703
|
+
const computedStyle = window.getComputedStyle(container);
|
|
2704
|
+
const paddingTop = Number.parseFloat(computedStyle.paddingTop || "0") || 0;
|
|
2705
|
+
const paddingBottom = Number.parseFloat(computedStyle.paddingBottom || "0") || 0;
|
|
2706
|
+
const nextMinHeight = Math.max(0, container.clientHeight - paddingTop - paddingBottom);
|
|
2707
|
+
setLatestTurnMinHeight((current) => current === nextMinHeight ? current : nextMinHeight);
|
|
2708
|
+
}, []);
|
|
2709
|
+
const scrollLatestUserMessageToTop = useCallback2(() => {
|
|
2292
2710
|
const container = containerRef.current;
|
|
2293
2711
|
const target = latestUserMessageRef.current;
|
|
2294
2712
|
if (!container || !target)
|
|
2295
2713
|
return;
|
|
2296
|
-
const
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2714
|
+
const containerRect = container.getBoundingClientRect();
|
|
2715
|
+
const targetRect = target.getBoundingClientRect();
|
|
2716
|
+
const nextScrollTop = Math.max(
|
|
2717
|
+
0,
|
|
2718
|
+
container.scrollTop + (targetRect.top - containerRect.top) - CHAT_THREAD_SCROLL_TOP_GAP
|
|
2719
|
+
);
|
|
2720
|
+
if (typeof container.scrollTo === "function") {
|
|
2721
|
+
container.scrollTo({
|
|
2722
|
+
top: nextScrollTop,
|
|
2723
|
+
behavior: "auto"
|
|
2724
|
+
});
|
|
2725
|
+
return;
|
|
2726
|
+
}
|
|
2727
|
+
container.scrollTop = nextScrollTop;
|
|
2307
2728
|
}, []);
|
|
2308
2729
|
useLayoutEffect(() => {
|
|
2309
2730
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2311,12 +2732,9 @@ var ChatThreadView = ({
|
|
|
2311
2732
|
reservedSpaceFrameRef.current = null;
|
|
2312
2733
|
}
|
|
2313
2734
|
if (!latestUserMessageId) {
|
|
2314
|
-
pendingScrollUserMessageIdRef.current = void 0;
|
|
2315
2735
|
reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
|
|
2316
2736
|
reservedSpaceFrameRef.current = null;
|
|
2317
|
-
|
|
2318
|
-
(current) => current.messageId === void 0 && current.value === 0 ? current : { messageId: void 0, value: 0 }
|
|
2319
|
-
);
|
|
2737
|
+
setLatestTurnMinHeight((current) => current === 0 ? current : 0);
|
|
2320
2738
|
});
|
|
2321
2739
|
return () => {
|
|
2322
2740
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2325,10 +2743,10 @@ var ChatThreadView = ({
|
|
|
2325
2743
|
}
|
|
2326
2744
|
};
|
|
2327
2745
|
}
|
|
2328
|
-
pendingScrollUserMessageIdRef.current = latestUserMessageId;
|
|
2329
2746
|
reservedSpaceFrameRef.current = window.requestAnimationFrame(() => {
|
|
2330
2747
|
reservedSpaceFrameRef.current = null;
|
|
2331
|
-
|
|
2748
|
+
measureLatestTurnMinHeight();
|
|
2749
|
+
scrollLatestUserMessageToTop();
|
|
2332
2750
|
});
|
|
2333
2751
|
return () => {
|
|
2334
2752
|
if (reservedSpaceFrameRef.current !== null) {
|
|
@@ -2336,51 +2754,79 @@ var ChatThreadView = ({
|
|
|
2336
2754
|
reservedSpaceFrameRef.current = null;
|
|
2337
2755
|
}
|
|
2338
2756
|
};
|
|
2339
|
-
}, [latestUserMessageId,
|
|
2757
|
+
}, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
|
|
2340
2758
|
useLayoutEffect(() => {
|
|
2341
|
-
if (!latestUserMessageId
|
|
2342
|
-
return;
|
|
2343
|
-
if (latestUserMessageReservedSpace.messageId !== latestUserMessageId)
|
|
2759
|
+
if (!latestUserMessageId)
|
|
2344
2760
|
return;
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2761
|
+
const handleResize = () => {
|
|
2762
|
+
measureLatestTurnMinHeight();
|
|
2763
|
+
scrollLatestUserMessageToTop();
|
|
2764
|
+
};
|
|
2765
|
+
const container = containerRef.current;
|
|
2766
|
+
let resizeObserver = null;
|
|
2767
|
+
if (container && typeof ResizeObserver !== "undefined") {
|
|
2768
|
+
resizeObserver = new ResizeObserver(() => {
|
|
2769
|
+
handleResize();
|
|
2770
|
+
});
|
|
2771
|
+
resizeObserver.observe(container);
|
|
2772
|
+
}
|
|
2773
|
+
window.addEventListener("resize", handleResize);
|
|
2774
|
+
return () => {
|
|
2775
|
+
resizeObserver?.disconnect();
|
|
2776
|
+
window.removeEventListener("resize", handleResize);
|
|
2777
|
+
};
|
|
2778
|
+
}, [latestUserMessageId, measureLatestTurnMinHeight, scrollLatestUserMessageToTop]);
|
|
2779
|
+
return /* @__PURE__ */ jsxs7(Container, { ref: containerRef, "data-testid": "chat-thread", children: [
|
|
2780
|
+
previousTurns.map((turn) => /* @__PURE__ */ jsxs7(ConversationTurn, { "data-testid": "chat-thread-turn", children: [
|
|
2781
|
+
turn.userMessage ? /* @__PURE__ */ jsx10(MessageSlot, { children: renderChatMessage({
|
|
2782
|
+
message: turn.userMessage,
|
|
2783
|
+
mode: activeSessionMode,
|
|
2784
|
+
onConfirmationSubmit,
|
|
2785
|
+
onQuestionnaireSubmit,
|
|
2786
|
+
renderMessageBlock
|
|
2787
|
+
}) }) : null,
|
|
2788
|
+
turn.responseMessages.map((message) => /* @__PURE__ */ jsx10(MessageSlot, { children: renderChatMessage({
|
|
2789
|
+
message,
|
|
2790
|
+
mode: activeSessionMode,
|
|
2791
|
+
onConfirmationSubmit,
|
|
2792
|
+
onQuestionnaireSubmit,
|
|
2793
|
+
renderMessageBlock
|
|
2794
|
+
}) }, message.id))
|
|
2795
|
+
] }, turn.id)),
|
|
2796
|
+
latestTurn ? /* @__PURE__ */ jsxs7(
|
|
2797
|
+
ConversationTurn,
|
|
2798
|
+
{
|
|
2799
|
+
"data-testid": "chat-thread-latest-turn",
|
|
2800
|
+
style: latestTurnMinHeight > 0 ? { minHeight: `${latestTurnMinHeight}px` } : void 0,
|
|
2801
|
+
children: [
|
|
2802
|
+
latestTurn.userMessage ? /* @__PURE__ */ jsx10(
|
|
2803
|
+
MessageSlot,
|
|
2804
|
+
{
|
|
2805
|
+
ref: latestUserMessageRef,
|
|
2806
|
+
"data-testid": "chat-latest-user-anchor",
|
|
2807
|
+
style: { scrollMarginTop: `${CHAT_THREAD_SCROLL_TOP_GAP}px` },
|
|
2808
|
+
children: renderChatMessage({
|
|
2809
|
+
message: latestTurn.userMessage,
|
|
2810
|
+
mode: activeSessionMode,
|
|
2811
|
+
onConfirmationSubmit,
|
|
2812
|
+
onQuestionnaireSubmit,
|
|
2813
|
+
renderMessageBlock
|
|
2814
|
+
})
|
|
2815
|
+
}
|
|
2816
|
+
) : null,
|
|
2817
|
+
latestTurn.responseMessages.map((message) => /* @__PURE__ */ jsx10(MessageSlot, { children: renderChatMessage({
|
|
2818
|
+
message,
|
|
2370
2819
|
mode: activeSessionMode,
|
|
2371
|
-
message: streamingMessage,
|
|
2372
2820
|
onConfirmationSubmit,
|
|
2373
2821
|
onQuestionnaireSubmit,
|
|
2374
2822
|
renderMessageBlock
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
}
|
|
2383
|
-
);
|
|
2823
|
+
}) }, message.id)),
|
|
2824
|
+
error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
|
|
2825
|
+
]
|
|
2826
|
+
}
|
|
2827
|
+
) : null,
|
|
2828
|
+
!latestTurn && error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
|
|
2829
|
+
] });
|
|
2384
2830
|
};
|
|
2385
2831
|
var EMPTY_MESSAGES = [];
|
|
2386
2832
|
var ChatThread = () => {
|
|
@@ -2424,9 +2870,9 @@ var ChatThread = () => {
|
|
|
2424
2870
|
[sendRef]
|
|
2425
2871
|
);
|
|
2426
2872
|
if (!hasSessions || messages.length === 0 && !streamingMessage) {
|
|
2427
|
-
return /* @__PURE__ */
|
|
2873
|
+
return /* @__PURE__ */ jsx10(ChatThreadEmptyState, {});
|
|
2428
2874
|
}
|
|
2429
|
-
return /* @__PURE__ */
|
|
2875
|
+
return /* @__PURE__ */ jsx10(
|
|
2430
2876
|
ChatThreadView,
|
|
2431
2877
|
{
|
|
2432
2878
|
activeSessionMode,
|
|
@@ -2441,7 +2887,7 @@ var ChatThread = () => {
|
|
|
2441
2887
|
}
|
|
2442
2888
|
);
|
|
2443
2889
|
};
|
|
2444
|
-
var Container =
|
|
2890
|
+
var Container = styled9.div`
|
|
2445
2891
|
display: flex;
|
|
2446
2892
|
flex: 1;
|
|
2447
2893
|
flex-direction: column;
|
|
@@ -2464,27 +2910,29 @@ var Container = styled10.div`
|
|
|
2464
2910
|
background: transparent;
|
|
2465
2911
|
}
|
|
2466
2912
|
`;
|
|
2467
|
-
var
|
|
2913
|
+
var MessageSlot = styled9.div`
|
|
2468
2914
|
display: flex;
|
|
2469
2915
|
`;
|
|
2470
|
-
var
|
|
2471
|
-
display:
|
|
2916
|
+
var ConversationTurn = styled9.div`
|
|
2917
|
+
display: flex;
|
|
2918
|
+
flex-direction: column;
|
|
2919
|
+
gap: 18px;
|
|
2472
2920
|
`;
|
|
2473
|
-
var ErrorText =
|
|
2921
|
+
var ErrorText = styled9.div`
|
|
2474
2922
|
color: #ff7b72;
|
|
2475
2923
|
font-size: 14px;
|
|
2476
2924
|
`;
|
|
2477
|
-
var ErrorState =
|
|
2925
|
+
var ErrorState = styled9.div`
|
|
2478
2926
|
display: flex;
|
|
2479
2927
|
flex-direction: column;
|
|
2480
2928
|
align-items: flex-start;
|
|
2481
2929
|
gap: 10px;
|
|
2482
2930
|
`;
|
|
2483
|
-
var ErrorActions =
|
|
2931
|
+
var ErrorActions = styled9.div`
|
|
2484
2932
|
display: flex;
|
|
2485
2933
|
align-items: center;
|
|
2486
2934
|
`;
|
|
2487
|
-
var RetryButton =
|
|
2935
|
+
var RetryButton = styled9.button`
|
|
2488
2936
|
border: 1px solid rgba(255, 255, 255, 0.14);
|
|
2489
2937
|
border-radius: 999px;
|
|
2490
2938
|
background: rgba(255, 255, 255, 0.04);
|
|
@@ -2500,8 +2948,8 @@ var RetryButton = styled10.button`
|
|
|
2500
2948
|
`;
|
|
2501
2949
|
|
|
2502
2950
|
// src/components/chat-composer/index.tsx
|
|
2503
|
-
import { useEffect as
|
|
2504
|
-
import
|
|
2951
|
+
import { useEffect as useEffect6, useRef as useRef8 } from "react";
|
|
2952
|
+
import styled14 from "@emotion/styled";
|
|
2505
2953
|
|
|
2506
2954
|
// src/components/chat-composer/lib/chat-composer.ts
|
|
2507
2955
|
var DRAFT_CHAT_SESSION_ID_PREFIX = "draft-session-";
|
|
@@ -2612,10 +3060,10 @@ var resolveSendSession = ({
|
|
|
2612
3060
|
};
|
|
2613
3061
|
|
|
2614
3062
|
// src/components/chat-composer/hooks/use-chat-composer.ts
|
|
2615
|
-
import { useCallback as useCallback3, useEffect as
|
|
3063
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef7, useState as useState7 } from "react";
|
|
2616
3064
|
|
|
2617
3065
|
// src/components/chat-composer/hooks/use-composer-attachments.ts
|
|
2618
|
-
import { useEffect as
|
|
3066
|
+
import { useEffect as useEffect4, useRef as useRef6, useState as useState6 } from "react";
|
|
2619
3067
|
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
2620
3068
|
var MAX_COMPOSER_ATTACHMENTS = 10;
|
|
2621
3069
|
var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
|
|
@@ -2629,12 +3077,12 @@ var releaseComposerAttachments = (attachments) => {
|
|
|
2629
3077
|
attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
|
|
2630
3078
|
};
|
|
2631
3079
|
var useComposerAttachments = () => {
|
|
2632
|
-
const [attachments, setAttachments] =
|
|
2633
|
-
const attachmentsRef =
|
|
2634
|
-
|
|
3080
|
+
const [attachments, setAttachments] = useState6([]);
|
|
3081
|
+
const attachmentsRef = useRef6([]);
|
|
3082
|
+
useEffect4(() => {
|
|
2635
3083
|
attachmentsRef.current = attachments;
|
|
2636
3084
|
}, [attachments]);
|
|
2637
|
-
|
|
3085
|
+
useEffect4(
|
|
2638
3086
|
() => () => {
|
|
2639
3087
|
releaseComposerAttachments(attachmentsRef.current);
|
|
2640
3088
|
},
|
|
@@ -2747,9 +3195,9 @@ var useChatComposer = () => {
|
|
|
2747
3195
|
const clearSessionError = useChatStore((s) => s.clearSessionError);
|
|
2748
3196
|
const setPreferredMode = useChatStore((s) => s.setPreferredMode);
|
|
2749
3197
|
const setSessionMode = useChatStore((s) => s.setSessionMode);
|
|
2750
|
-
const [availableModels, setAvailableModels] =
|
|
2751
|
-
const [isModelsLoading, setIsModelsLoading] =
|
|
2752
|
-
const [isModelsError, setIsModelsError] =
|
|
3198
|
+
const [availableModels, setAvailableModels] = useState7([]);
|
|
3199
|
+
const [isModelsLoading, setIsModelsLoading] = useState7(true);
|
|
3200
|
+
const [isModelsError, setIsModelsError] = useState7(false);
|
|
2753
3201
|
const fetchModels = useCallback3(async () => {
|
|
2754
3202
|
setIsModelsLoading(true);
|
|
2755
3203
|
setIsModelsError(false);
|
|
@@ -2762,31 +3210,31 @@ var useChatComposer = () => {
|
|
|
2762
3210
|
setIsModelsLoading(false);
|
|
2763
3211
|
}
|
|
2764
3212
|
}, [transport]);
|
|
2765
|
-
|
|
3213
|
+
useEffect5(() => {
|
|
2766
3214
|
void fetchModels();
|
|
2767
3215
|
}, [fetchModels]);
|
|
2768
3216
|
const hasModels = availableModels.length > 0;
|
|
2769
|
-
const [value, setValue] =
|
|
2770
|
-
const [selectedModel, setSelectedModel] =
|
|
2771
|
-
const [selectedMode, setSelectedModeLocal] =
|
|
2772
|
-
const [attachmentNotice, setAttachmentNotice] =
|
|
3217
|
+
const [value, setValue] = useState7("");
|
|
3218
|
+
const [selectedModel, setSelectedModel] = useState7("");
|
|
3219
|
+
const [selectedMode, setSelectedModeLocal] = useState7(DEFAULT_CHAT_AGENT_MODE);
|
|
3220
|
+
const [attachmentNotice, setAttachmentNotice] = useState7(null);
|
|
2773
3221
|
const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
|
|
2774
|
-
const abortControllerRef =
|
|
2775
|
-
const stopRequestRef =
|
|
2776
|
-
const lastRequestRef =
|
|
2777
|
-
|
|
3222
|
+
const abortControllerRef = useRef7(null);
|
|
3223
|
+
const stopRequestRef = useRef7(null);
|
|
3224
|
+
const lastRequestRef = useRef7(null);
|
|
3225
|
+
useEffect5(() => {
|
|
2778
3226
|
setSelectedModel(
|
|
2779
3227
|
(current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
|
|
2780
3228
|
);
|
|
2781
3229
|
}, [availableModels, isModelsLoading]);
|
|
2782
|
-
|
|
3230
|
+
useEffect5(() => {
|
|
2783
3231
|
if (activeSession) {
|
|
2784
3232
|
setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
2785
3233
|
return;
|
|
2786
3234
|
}
|
|
2787
3235
|
setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
2788
3236
|
}, [activeSession, preferredMode]);
|
|
2789
|
-
|
|
3237
|
+
useEffect5(() => {
|
|
2790
3238
|
if (!attachmentNotice)
|
|
2791
3239
|
return;
|
|
2792
3240
|
const timeoutId = window.setTimeout(
|
|
@@ -3065,29 +3513,29 @@ var useChatComposer = () => {
|
|
|
3065
3513
|
};
|
|
3066
3514
|
|
|
3067
3515
|
// src/components/chat-composer/components/chat-composer-attachment-list.tsx
|
|
3068
|
-
import { useState as
|
|
3069
|
-
import
|
|
3070
|
-
import { Fragment as Fragment3, jsx as
|
|
3516
|
+
import { useState as useState8 } from "react";
|
|
3517
|
+
import styled10 from "@emotion/styled";
|
|
3518
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
|
|
3071
3519
|
var ChatComposerAttachmentList = ({
|
|
3072
3520
|
attachments,
|
|
3073
3521
|
onRemoveAttachment
|
|
3074
3522
|
}) => {
|
|
3075
|
-
const [activeImage, setActiveImage] =
|
|
3523
|
+
const [activeImage, setActiveImage] = useState8(null);
|
|
3076
3524
|
if (!attachments.length) {
|
|
3077
3525
|
return null;
|
|
3078
3526
|
}
|
|
3079
3527
|
return /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
3080
|
-
/* @__PURE__ */
|
|
3081
|
-
/* @__PURE__ */
|
|
3528
|
+
/* @__PURE__ */ jsx11(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ jsxs8(AttachmentCard, { children: [
|
|
3529
|
+
/* @__PURE__ */ jsx11(
|
|
3082
3530
|
AttachmentPreviewButton,
|
|
3083
3531
|
{
|
|
3084
3532
|
type: "button",
|
|
3085
3533
|
"aria-label": `${attachment.name} preview`,
|
|
3086
3534
|
onClick: () => setActiveImage(attachment),
|
|
3087
|
-
children: /* @__PURE__ */
|
|
3535
|
+
children: /* @__PURE__ */ jsx11(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
|
|
3088
3536
|
}
|
|
3089
3537
|
),
|
|
3090
|
-
/* @__PURE__ */
|
|
3538
|
+
/* @__PURE__ */ jsx11(
|
|
3091
3539
|
AttachmentRemoveButton,
|
|
3092
3540
|
{
|
|
3093
3541
|
type: "button",
|
|
@@ -3096,11 +3544,11 @@ var ChatComposerAttachmentList = ({
|
|
|
3096
3544
|
event.stopPropagation();
|
|
3097
3545
|
onRemoveAttachment(attachment.id);
|
|
3098
3546
|
},
|
|
3099
|
-
children: /* @__PURE__ */
|
|
3547
|
+
children: /* @__PURE__ */ jsx11(CloseGlyph, { "aria-hidden": "true" })
|
|
3100
3548
|
}
|
|
3101
3549
|
)
|
|
3102
3550
|
] }, attachment.id)) }),
|
|
3103
|
-
activeImage ? /* @__PURE__ */
|
|
3551
|
+
activeImage ? /* @__PURE__ */ jsx11(
|
|
3104
3552
|
ImageViewer,
|
|
3105
3553
|
{
|
|
3106
3554
|
src: activeImage.previewUrl,
|
|
@@ -3110,7 +3558,7 @@ var ChatComposerAttachmentList = ({
|
|
|
3110
3558
|
) : null
|
|
3111
3559
|
] });
|
|
3112
3560
|
};
|
|
3113
|
-
var AttachmentList =
|
|
3561
|
+
var AttachmentList = styled10.div`
|
|
3114
3562
|
display: flex;
|
|
3115
3563
|
flex-wrap: wrap;
|
|
3116
3564
|
gap: 10px;
|
|
@@ -3132,7 +3580,7 @@ var AttachmentList = styled11.div`
|
|
|
3132
3580
|
background: transparent;
|
|
3133
3581
|
}
|
|
3134
3582
|
`;
|
|
3135
|
-
var AttachmentCard =
|
|
3583
|
+
var AttachmentCard = styled10.div`
|
|
3136
3584
|
position: relative;
|
|
3137
3585
|
width: 108px;
|
|
3138
3586
|
height: 72px;
|
|
@@ -3141,7 +3589,7 @@ var AttachmentCard = styled11.div`
|
|
|
3141
3589
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
3142
3590
|
background: rgba(255, 255, 255, 0.04);
|
|
3143
3591
|
`;
|
|
3144
|
-
var AttachmentPreviewButton =
|
|
3592
|
+
var AttachmentPreviewButton = styled10.button`
|
|
3145
3593
|
width: 100%;
|
|
3146
3594
|
height: 100%;
|
|
3147
3595
|
padding: 0;
|
|
@@ -3149,13 +3597,13 @@ var AttachmentPreviewButton = styled11.button`
|
|
|
3149
3597
|
background: transparent;
|
|
3150
3598
|
cursor: zoom-in;
|
|
3151
3599
|
`;
|
|
3152
|
-
var AttachmentThumb =
|
|
3600
|
+
var AttachmentThumb = styled10.img`
|
|
3153
3601
|
width: 100%;
|
|
3154
3602
|
height: 100%;
|
|
3155
3603
|
object-fit: cover;
|
|
3156
3604
|
display: block;
|
|
3157
3605
|
`;
|
|
3158
|
-
var AttachmentRemoveButton =
|
|
3606
|
+
var AttachmentRemoveButton = styled10.button`
|
|
3159
3607
|
position: absolute;
|
|
3160
3608
|
top: 6px;
|
|
3161
3609
|
right: 6px;
|
|
@@ -3193,7 +3641,7 @@ var AttachmentRemoveButton = styled11.button`
|
|
|
3193
3641
|
background: rgba(30, 30, 35, 0.98);
|
|
3194
3642
|
}
|
|
3195
3643
|
`;
|
|
3196
|
-
var CloseGlyph =
|
|
3644
|
+
var CloseGlyph = styled10.span`
|
|
3197
3645
|
position: relative;
|
|
3198
3646
|
width: 11px;
|
|
3199
3647
|
height: 11px;
|
|
@@ -3222,9 +3670,9 @@ var CloseGlyph = styled11.span`
|
|
|
3222
3670
|
`;
|
|
3223
3671
|
|
|
3224
3672
|
// src/components/chat-composer/components/chat-model-control.tsx
|
|
3225
|
-
import
|
|
3673
|
+
import styled11 from "@emotion/styled";
|
|
3226
3674
|
import { Select } from "@xinghunm/compass-ui";
|
|
3227
|
-
import { jsx as
|
|
3675
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "@emotion/react/jsx-runtime";
|
|
3228
3676
|
var ChatModelControl = ({
|
|
3229
3677
|
selectedModel,
|
|
3230
3678
|
availableModels,
|
|
@@ -3243,7 +3691,7 @@ var ChatModelControl = ({
|
|
|
3243
3691
|
"aria-label": "Reload",
|
|
3244
3692
|
onClick: onReloadModels,
|
|
3245
3693
|
children: [
|
|
3246
|
-
/* @__PURE__ */
|
|
3694
|
+
/* @__PURE__ */ jsx12("span", { children: "Failed to load models" }),
|
|
3247
3695
|
/* @__PURE__ */ jsxs9(
|
|
3248
3696
|
ReloadIcon,
|
|
3249
3697
|
{
|
|
@@ -3255,8 +3703,8 @@ var ChatModelControl = ({
|
|
|
3255
3703
|
fill: "currentColor",
|
|
3256
3704
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3257
3705
|
children: [
|
|
3258
|
-
/* @__PURE__ */
|
|
3259
|
-
/* @__PURE__ */
|
|
3706
|
+
/* @__PURE__ */ jsx12("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" }),
|
|
3707
|
+
/* @__PURE__ */ jsx12("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" })
|
|
3260
3708
|
]
|
|
3261
3709
|
}
|
|
3262
3710
|
)
|
|
@@ -3265,11 +3713,11 @@ var ChatModelControl = ({
|
|
|
3265
3713
|
);
|
|
3266
3714
|
}
|
|
3267
3715
|
if (isModelsLoading) {
|
|
3268
|
-
return /* @__PURE__ */
|
|
3716
|
+
return /* @__PURE__ */ jsx12(ModelBadge, { children: "Loading models..." });
|
|
3269
3717
|
}
|
|
3270
3718
|
if (hasModels && selectedModel) {
|
|
3271
3719
|
if (availableModels.length > 1) {
|
|
3272
|
-
return /* @__PURE__ */
|
|
3720
|
+
return /* @__PURE__ */ jsx12(
|
|
3273
3721
|
ModelSelect,
|
|
3274
3722
|
{
|
|
3275
3723
|
"data-testid": "chat-model-select",
|
|
@@ -3283,11 +3731,11 @@ var ChatModelControl = ({
|
|
|
3283
3731
|
}
|
|
3284
3732
|
);
|
|
3285
3733
|
}
|
|
3286
|
-
return /* @__PURE__ */
|
|
3734
|
+
return /* @__PURE__ */ jsx12(ModelBadge, { children: selectedModel });
|
|
3287
3735
|
}
|
|
3288
|
-
return /* @__PURE__ */
|
|
3736
|
+
return /* @__PURE__ */ jsx12(ModelBadge, { children: "No model available" });
|
|
3289
3737
|
};
|
|
3290
|
-
var ModelBadge =
|
|
3738
|
+
var ModelBadge = styled11.span`
|
|
3291
3739
|
border-radius: 999px;
|
|
3292
3740
|
border: 1px solid var(--border-hover);
|
|
3293
3741
|
padding: 5px 12px;
|
|
@@ -3296,7 +3744,7 @@ var ModelBadge = styled12.span`
|
|
|
3296
3744
|
color: var(--text-secondary);
|
|
3297
3745
|
line-height: 12px;
|
|
3298
3746
|
`;
|
|
3299
|
-
var ModelReloadButton =
|
|
3747
|
+
var ModelReloadButton = styled11.button`
|
|
3300
3748
|
display: inline-flex;
|
|
3301
3749
|
align-items: center;
|
|
3302
3750
|
gap: 8px;
|
|
@@ -3321,10 +3769,10 @@ var ModelReloadButton = styled12.button`
|
|
|
3321
3769
|
color: rgba(255, 255, 255, 0.88);
|
|
3322
3770
|
}
|
|
3323
3771
|
`;
|
|
3324
|
-
var ReloadIcon =
|
|
3772
|
+
var ReloadIcon = styled11.svg`
|
|
3325
3773
|
flex-shrink: 0;
|
|
3326
3774
|
`;
|
|
3327
|
-
var ModelSelect =
|
|
3775
|
+
var ModelSelect = styled11(Select)`
|
|
3328
3776
|
&& {
|
|
3329
3777
|
width: auto;
|
|
3330
3778
|
min-width: 0;
|
|
@@ -3344,16 +3792,16 @@ var ModelSelect = styled12(Select)`
|
|
|
3344
3792
|
`;
|
|
3345
3793
|
|
|
3346
3794
|
// src/components/chat-composer/components/chat-mode-control.tsx
|
|
3347
|
-
import
|
|
3795
|
+
import styled12 from "@emotion/styled";
|
|
3348
3796
|
import { Select as Select2 } from "@xinghunm/compass-ui";
|
|
3349
|
-
import { jsx as
|
|
3797
|
+
import { jsx as jsx13 } from "@emotion/react/jsx-runtime";
|
|
3350
3798
|
var ChatModeControl = ({
|
|
3351
3799
|
value,
|
|
3352
3800
|
disabled = false,
|
|
3353
3801
|
labels,
|
|
3354
3802
|
onChange
|
|
3355
3803
|
}) => {
|
|
3356
|
-
return /* @__PURE__ */
|
|
3804
|
+
return /* @__PURE__ */ jsx13(
|
|
3357
3805
|
ModeSelect,
|
|
3358
3806
|
{
|
|
3359
3807
|
"data-testid": "chat-mode-select",
|
|
@@ -3368,7 +3816,7 @@ var ChatModeControl = ({
|
|
|
3368
3816
|
}
|
|
3369
3817
|
);
|
|
3370
3818
|
};
|
|
3371
|
-
var ModeSelect =
|
|
3819
|
+
var ModeSelect = styled12(Select2)`
|
|
3372
3820
|
&& {
|
|
3373
3821
|
flex: 0 1 auto;
|
|
3374
3822
|
width: auto;
|
|
@@ -3389,10 +3837,10 @@ var ModeSelect = styled13(Select2)`
|
|
|
3389
3837
|
`;
|
|
3390
3838
|
|
|
3391
3839
|
// src/components/chat-composer/components/chat-send-actions.tsx
|
|
3392
|
-
import
|
|
3840
|
+
import styled13 from "@emotion/styled";
|
|
3393
3841
|
import { Button } from "@xinghunm/compass-ui";
|
|
3394
|
-
import { Fragment as Fragment4, jsx as
|
|
3395
|
-
var ArrowUpIcon = () => /* @__PURE__ */
|
|
3842
|
+
import { Fragment as Fragment4, jsx as jsx14 } from "@emotion/react/jsx-runtime";
|
|
3843
|
+
var ArrowUpIcon = () => /* @__PURE__ */ jsx14(
|
|
3396
3844
|
"svg",
|
|
3397
3845
|
{
|
|
3398
3846
|
"aria-hidden": "true",
|
|
@@ -3401,7 +3849,7 @@ var ArrowUpIcon = () => /* @__PURE__ */ jsx15(
|
|
|
3401
3849
|
viewBox: "0 0 12 12",
|
|
3402
3850
|
fill: "none",
|
|
3403
3851
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3404
|
-
children: /* @__PURE__ */
|
|
3852
|
+
children: /* @__PURE__ */ jsx14(
|
|
3405
3853
|
"path",
|
|
3406
3854
|
{
|
|
3407
3855
|
d: "M6 10V2M6 2L2 6M6 2L10 6",
|
|
@@ -3419,7 +3867,7 @@ var ChatSendActions = ({
|
|
|
3419
3867
|
isStopping,
|
|
3420
3868
|
onStop,
|
|
3421
3869
|
onSend
|
|
3422
|
-
}) => /* @__PURE__ */
|
|
3870
|
+
}) => /* @__PURE__ */ jsx14(Fragment4, { children: isStreaming ? /* @__PURE__ */ jsx14(
|
|
3423
3871
|
StopButton,
|
|
3424
3872
|
{
|
|
3425
3873
|
type: "button",
|
|
@@ -3429,14 +3877,14 @@ var ChatSendActions = ({
|
|
|
3429
3877
|
disabled: isStopping,
|
|
3430
3878
|
shape: "circle",
|
|
3431
3879
|
onClick: () => void onStop(),
|
|
3432
|
-
children: /* @__PURE__ */
|
|
3880
|
+
children: isStopping ? /* @__PURE__ */ jsx14(StopSpinner, { "aria-hidden": "true", "data-testid": "chat-composer-stop-spinner" }) : /* @__PURE__ */ jsx14(StopGlyph, { "aria-hidden": "true", "data-testid": "chat-composer-stop-glyph" })
|
|
3433
3881
|
}
|
|
3434
|
-
) : /* @__PURE__ */
|
|
3882
|
+
) : /* @__PURE__ */ jsx14(
|
|
3435
3883
|
PrimaryButton,
|
|
3436
3884
|
{
|
|
3437
3885
|
$canSend: canSend,
|
|
3438
3886
|
type: "button",
|
|
3439
|
-
icon: /* @__PURE__ */
|
|
3887
|
+
icon: /* @__PURE__ */ jsx14(ArrowUpIcon, {}),
|
|
3440
3888
|
"aria-label": "Send",
|
|
3441
3889
|
"data-testid": "chat-composer-send",
|
|
3442
3890
|
disabled: !canSend,
|
|
@@ -3444,7 +3892,7 @@ var ChatSendActions = ({
|
|
|
3444
3892
|
onClick: () => void onSend()
|
|
3445
3893
|
}
|
|
3446
3894
|
) });
|
|
3447
|
-
var PrimaryButton =
|
|
3895
|
+
var PrimaryButton = styled13(Button)`
|
|
3448
3896
|
&& {
|
|
3449
3897
|
min-width: 24px;
|
|
3450
3898
|
width: 24px;
|
|
@@ -3470,7 +3918,7 @@ var PrimaryButton = styled14(Button)`
|
|
|
3470
3918
|
}
|
|
3471
3919
|
}
|
|
3472
3920
|
`;
|
|
3473
|
-
var StopButton =
|
|
3921
|
+
var StopButton = styled13(Button)`
|
|
3474
3922
|
&& {
|
|
3475
3923
|
min-width: 24px;
|
|
3476
3924
|
width: 24px;
|
|
@@ -3498,17 +3946,35 @@ var StopButton = styled14(Button)`
|
|
|
3498
3946
|
}
|
|
3499
3947
|
}
|
|
3500
3948
|
`;
|
|
3501
|
-
var StopGlyph =
|
|
3949
|
+
var StopGlyph = styled13.span`
|
|
3502
3950
|
width: 8px;
|
|
3503
3951
|
height: 8px;
|
|
3504
3952
|
border-radius: 2px;
|
|
3505
3953
|
background: #1b1b1b;
|
|
3506
3954
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
|
|
3507
3955
|
`;
|
|
3956
|
+
var StopSpinner = styled13.span`
|
|
3957
|
+
width: 10px;
|
|
3958
|
+
height: 10px;
|
|
3959
|
+
border-radius: 999px;
|
|
3960
|
+
border: 1.5px solid rgba(27, 27, 27, 0.2);
|
|
3961
|
+
border-top-color: #1b1b1b;
|
|
3962
|
+
animation: chat-composer-stop-spin 0.7s linear infinite;
|
|
3963
|
+
|
|
3964
|
+
@keyframes chat-composer-stop-spin {
|
|
3965
|
+
from {
|
|
3966
|
+
transform: rotate(0deg);
|
|
3967
|
+
}
|
|
3968
|
+
|
|
3969
|
+
to {
|
|
3970
|
+
transform: rotate(360deg);
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
`;
|
|
3508
3974
|
|
|
3509
3975
|
// src/components/chat-composer/index.tsx
|
|
3510
|
-
import { jsx as
|
|
3511
|
-
var PlusIcon = () => /* @__PURE__ */
|
|
3976
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "@emotion/react/jsx-runtime";
|
|
3977
|
+
var PlusIcon = () => /* @__PURE__ */ jsx15(
|
|
3512
3978
|
"svg",
|
|
3513
3979
|
{
|
|
3514
3980
|
"aria-hidden": "true",
|
|
@@ -3517,7 +3983,7 @@ var PlusIcon = () => /* @__PURE__ */ jsx16(
|
|
|
3517
3983
|
viewBox: "0 0 16 16",
|
|
3518
3984
|
fill: "none",
|
|
3519
3985
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3520
|
-
children: /* @__PURE__ */
|
|
3986
|
+
children: /* @__PURE__ */ jsx15("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
|
|
3521
3987
|
}
|
|
3522
3988
|
);
|
|
3523
3989
|
var ChatComposerView = ({
|
|
@@ -3546,7 +4012,7 @@ var ChatComposerView = ({
|
|
|
3546
4012
|
onStop,
|
|
3547
4013
|
onSend
|
|
3548
4014
|
}) => {
|
|
3549
|
-
const imageInputRef =
|
|
4015
|
+
const imageInputRef = useRef8(null);
|
|
3550
4016
|
const canSend = canSendChatMessage({
|
|
3551
4017
|
value,
|
|
3552
4018
|
attachmentCount: attachments.length,
|
|
@@ -3577,8 +4043,8 @@ var ChatComposerView = ({
|
|
|
3577
4043
|
event.preventDefault();
|
|
3578
4044
|
onPasteImages(imageFiles);
|
|
3579
4045
|
};
|
|
3580
|
-
return /* @__PURE__ */
|
|
3581
|
-
enableImageAttachments ? /* @__PURE__ */
|
|
4046
|
+
return /* @__PURE__ */ jsx15(Container2, { children: /* @__PURE__ */ jsxs10(Surface, { "data-testid": "chat-composer-surface", children: [
|
|
4047
|
+
enableImageAttachments ? /* @__PURE__ */ jsx15(
|
|
3582
4048
|
"input",
|
|
3583
4049
|
{
|
|
3584
4050
|
ref: imageInputRef,
|
|
@@ -3590,15 +4056,15 @@ var ChatComposerView = ({
|
|
|
3590
4056
|
onChange: handlePickImages
|
|
3591
4057
|
}
|
|
3592
4058
|
) : null,
|
|
3593
|
-
/* @__PURE__ */
|
|
4059
|
+
/* @__PURE__ */ jsx15(
|
|
3594
4060
|
ChatComposerAttachmentList,
|
|
3595
4061
|
{
|
|
3596
4062
|
attachments,
|
|
3597
4063
|
onRemoveAttachment
|
|
3598
4064
|
}
|
|
3599
4065
|
),
|
|
3600
|
-
attachmentNotice === "limit_reached" ? /* @__PURE__ */
|
|
3601
|
-
/* @__PURE__ */
|
|
4066
|
+
attachmentNotice === "limit_reached" ? /* @__PURE__ */ jsx15(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
|
|
4067
|
+
/* @__PURE__ */ jsx15(
|
|
3602
4068
|
Input,
|
|
3603
4069
|
{
|
|
3604
4070
|
"data-testid": "chat-composer-input",
|
|
@@ -3609,18 +4075,18 @@ var ChatComposerView = ({
|
|
|
3609
4075
|
placeholder
|
|
3610
4076
|
}
|
|
3611
4077
|
),
|
|
3612
|
-
/* @__PURE__ */
|
|
3613
|
-
enableImageAttachments ? /* @__PURE__ */
|
|
4078
|
+
/* @__PURE__ */ jsx15(Footer, { children: /* @__PURE__ */ jsxs10(Actions2, { "data-testid": "chat-composer-actions", children: [
|
|
4079
|
+
enableImageAttachments ? /* @__PURE__ */ jsx15(
|
|
3614
4080
|
AttachButton,
|
|
3615
4081
|
{
|
|
3616
4082
|
type: "button",
|
|
3617
4083
|
"data-testid": "chat-composer-attach-image",
|
|
3618
4084
|
"aria-label": "Attach image",
|
|
3619
4085
|
onClick: () => imageInputRef.current?.click(),
|
|
3620
|
-
children: /* @__PURE__ */
|
|
4086
|
+
children: /* @__PURE__ */ jsx15(PlusIcon, {})
|
|
3621
4087
|
}
|
|
3622
4088
|
) : null,
|
|
3623
|
-
/* @__PURE__ */
|
|
4089
|
+
/* @__PURE__ */ jsx15(
|
|
3624
4090
|
ChatModeControl,
|
|
3625
4091
|
{
|
|
3626
4092
|
value: selectedMode,
|
|
@@ -3629,7 +4095,7 @@ var ChatComposerView = ({
|
|
|
3629
4095
|
onChange: onSelectedModeChange
|
|
3630
4096
|
}
|
|
3631
4097
|
),
|
|
3632
|
-
/* @__PURE__ */
|
|
4098
|
+
/* @__PURE__ */ jsx15(
|
|
3633
4099
|
ChatModelControl,
|
|
3634
4100
|
{
|
|
3635
4101
|
selectedModel,
|
|
@@ -3641,7 +4107,7 @@ var ChatComposerView = ({
|
|
|
3641
4107
|
onReloadModels
|
|
3642
4108
|
}
|
|
3643
4109
|
),
|
|
3644
|
-
/* @__PURE__ */
|
|
4110
|
+
/* @__PURE__ */ jsx15(
|
|
3645
4111
|
ChatSendActions,
|
|
3646
4112
|
{
|
|
3647
4113
|
canSend,
|
|
@@ -3658,7 +4124,7 @@ var ChatComposer = () => {
|
|
|
3658
4124
|
const { labels, sendRef, retryRef, enableImageAttachments } = useChatContext();
|
|
3659
4125
|
const { state, actions } = useChatComposer();
|
|
3660
4126
|
const { send, retry } = actions;
|
|
3661
|
-
|
|
4127
|
+
useEffect6(() => {
|
|
3662
4128
|
sendRef.current = send;
|
|
3663
4129
|
retryRef.current = async () => {
|
|
3664
4130
|
retry();
|
|
@@ -3669,7 +4135,7 @@ var ChatComposer = () => {
|
|
|
3669
4135
|
plan: labels.modeLabelPlan,
|
|
3670
4136
|
agent: labels.modeLabelAgent
|
|
3671
4137
|
};
|
|
3672
|
-
return /* @__PURE__ */
|
|
4138
|
+
return /* @__PURE__ */ jsx15(
|
|
3673
4139
|
ChatComposerView,
|
|
3674
4140
|
{
|
|
3675
4141
|
value: state.value,
|
|
@@ -3699,10 +4165,10 @@ var ChatComposer = () => {
|
|
|
3699
4165
|
}
|
|
3700
4166
|
);
|
|
3701
4167
|
};
|
|
3702
|
-
var Container2 =
|
|
4168
|
+
var Container2 = styled14.div`
|
|
3703
4169
|
padding: 0 16px 16px;
|
|
3704
4170
|
`;
|
|
3705
|
-
var Surface =
|
|
4171
|
+
var Surface = styled14.div`
|
|
3706
4172
|
background: var(--border-color);
|
|
3707
4173
|
border-radius: 20px;
|
|
3708
4174
|
border: 1px solid var(--border-hover);
|
|
@@ -3711,7 +4177,7 @@ var Surface = styled15.div`
|
|
|
3711
4177
|
0 12px 36px rgba(0, 0, 0, 0.3);
|
|
3712
4178
|
backdrop-filter: blur(10px);
|
|
3713
4179
|
`;
|
|
3714
|
-
var AttachmentNotice =
|
|
4180
|
+
var AttachmentNotice = styled14.div`
|
|
3715
4181
|
margin: 10px 12px 0;
|
|
3716
4182
|
padding: 8px 10px;
|
|
3717
4183
|
border-radius: 10px;
|
|
@@ -3721,7 +4187,7 @@ var AttachmentNotice = styled15.div`
|
|
|
3721
4187
|
font-size: 12px;
|
|
3722
4188
|
line-height: 1.4;
|
|
3723
4189
|
`;
|
|
3724
|
-
var Input =
|
|
4190
|
+
var Input = styled14.textarea`
|
|
3725
4191
|
width: 100%;
|
|
3726
4192
|
min-height: 96px;
|
|
3727
4193
|
resize: none;
|
|
@@ -3743,14 +4209,14 @@ var Input = styled15.textarea`
|
|
|
3743
4209
|
display: none;
|
|
3744
4210
|
}
|
|
3745
4211
|
`;
|
|
3746
|
-
var Footer =
|
|
4212
|
+
var Footer = styled14.div`
|
|
3747
4213
|
display: flex;
|
|
3748
4214
|
align-items: flex-end;
|
|
3749
4215
|
justify-content: stretch;
|
|
3750
4216
|
gap: 16px;
|
|
3751
4217
|
padding: 0 14px 14px;
|
|
3752
4218
|
`;
|
|
3753
|
-
var Actions2 =
|
|
4219
|
+
var Actions2 = styled14.div`
|
|
3754
4220
|
display: flex;
|
|
3755
4221
|
align-items: center;
|
|
3756
4222
|
flex-wrap: wrap;
|
|
@@ -3759,7 +4225,7 @@ var Actions2 = styled15.div`
|
|
|
3759
4225
|
justify-content: flex-end;
|
|
3760
4226
|
gap: 8px;
|
|
3761
4227
|
`;
|
|
3762
|
-
var AttachButton =
|
|
4228
|
+
var AttachButton = styled14.button`
|
|
3763
4229
|
width: 28px;
|
|
3764
4230
|
height: 28px;
|
|
3765
4231
|
display: grid;
|
|
@@ -3776,42 +4242,42 @@ var AttachButton = styled15.button`
|
|
|
3776
4242
|
`;
|
|
3777
4243
|
|
|
3778
4244
|
// src/components/chat-conversation-list/index.tsx
|
|
3779
|
-
import
|
|
4245
|
+
import styled16 from "@emotion/styled";
|
|
3780
4246
|
|
|
3781
4247
|
// src/components/chat-conversation-list/components/chat-session-item.tsx
|
|
3782
|
-
import { memo as
|
|
3783
|
-
import
|
|
3784
|
-
import { jsx as
|
|
3785
|
-
var ChatSessionItem =
|
|
4248
|
+
import { memo as memo2 } from "react";
|
|
4249
|
+
import styled15 from "@emotion/styled";
|
|
4250
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "@emotion/react/jsx-runtime";
|
|
4251
|
+
var ChatSessionItem = memo2(
|
|
3786
4252
|
({ session, isActive, modeLabel, onClick }) => {
|
|
3787
|
-
return /* @__PURE__ */
|
|
4253
|
+
return /* @__PURE__ */ jsx16(
|
|
3788
4254
|
SessionButton,
|
|
3789
4255
|
{
|
|
3790
4256
|
type: "button",
|
|
3791
4257
|
"data-active": isActive,
|
|
3792
4258
|
onClick: () => onClick(session.sessionId),
|
|
3793
4259
|
children: /* @__PURE__ */ jsxs11(SessionMeta, { children: [
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
/* @__PURE__ */
|
|
4260
|
+
/* @__PURE__ */ jsx16(SessionTitle, { children: session.title }),
|
|
4261
|
+
/* @__PURE__ */ jsx16(ModeBadge, { children: modeLabel })
|
|
3796
4262
|
] })
|
|
3797
4263
|
}
|
|
3798
4264
|
);
|
|
3799
4265
|
}
|
|
3800
4266
|
);
|
|
3801
4267
|
ChatSessionItem.displayName = "ChatSessionItem";
|
|
3802
|
-
var SessionMeta =
|
|
4268
|
+
var SessionMeta = styled15.div`
|
|
3803
4269
|
display: flex;
|
|
3804
4270
|
align-items: center;
|
|
3805
4271
|
justify-content: space-between;
|
|
3806
4272
|
gap: 8px;
|
|
3807
4273
|
`;
|
|
3808
|
-
var SessionTitle =
|
|
4274
|
+
var SessionTitle = styled15.span`
|
|
3809
4275
|
min-width: 0;
|
|
3810
4276
|
overflow: hidden;
|
|
3811
4277
|
text-overflow: ellipsis;
|
|
3812
4278
|
white-space: nowrap;
|
|
3813
4279
|
`;
|
|
3814
|
-
var SessionButton =
|
|
4280
|
+
var SessionButton = styled15.button`
|
|
3815
4281
|
border: 1px solid transparent;
|
|
3816
4282
|
border-radius: 12px;
|
|
3817
4283
|
padding: 12px;
|
|
@@ -3825,7 +4291,7 @@ var SessionButton = styled16.button`
|
|
|
3825
4291
|
background: rgba(255, 255, 255, 0.08);
|
|
3826
4292
|
}
|
|
3827
4293
|
`;
|
|
3828
|
-
var ModeBadge =
|
|
4294
|
+
var ModeBadge = styled15.span`
|
|
3829
4295
|
flex-shrink: 0;
|
|
3830
4296
|
border-radius: 999px;
|
|
3831
4297
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
@@ -3837,7 +4303,7 @@ var ModeBadge = styled16.span`
|
|
|
3837
4303
|
`;
|
|
3838
4304
|
|
|
3839
4305
|
// src/components/chat-conversation-list/index.tsx
|
|
3840
|
-
import { jsx as
|
|
4306
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "@emotion/react/jsx-runtime";
|
|
3841
4307
|
var ChatConversationList = () => {
|
|
3842
4308
|
const { labels } = useChatContext();
|
|
3843
4309
|
const sessions = useChatStore((s) => s.sessions);
|
|
@@ -3862,10 +4328,10 @@ var ChatConversationList = () => {
|
|
|
3862
4328
|
};
|
|
3863
4329
|
return /* @__PURE__ */ jsxs12(Container3, { children: [
|
|
3864
4330
|
/* @__PURE__ */ jsxs12(Toolbar, { children: [
|
|
3865
|
-
/* @__PURE__ */
|
|
3866
|
-
/* @__PURE__ */
|
|
4331
|
+
/* @__PURE__ */ jsx17(Title4, { children: "Sessions" }),
|
|
4332
|
+
/* @__PURE__ */ jsx17(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
|
|
3867
4333
|
] }),
|
|
3868
|
-
/* @__PURE__ */
|
|
4334
|
+
/* @__PURE__ */ jsx17(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ jsx17(
|
|
3869
4335
|
ChatSessionItem,
|
|
3870
4336
|
{
|
|
3871
4337
|
session,
|
|
@@ -3877,7 +4343,7 @@ var ChatConversationList = () => {
|
|
|
3877
4343
|
)) })
|
|
3878
4344
|
] });
|
|
3879
4345
|
};
|
|
3880
|
-
var Container3 =
|
|
4346
|
+
var Container3 = styled16.aside`
|
|
3881
4347
|
width: 280px;
|
|
3882
4348
|
min-width: 280px;
|
|
3883
4349
|
border-right: 1px solid var(--border-default, rgba(255, 255, 255, 0.08));
|
|
@@ -3885,18 +4351,18 @@ var Container3 = styled17.aside`
|
|
|
3885
4351
|
flex-direction: column;
|
|
3886
4352
|
background: rgba(255, 255, 255, 0.02);
|
|
3887
4353
|
`;
|
|
3888
|
-
var Toolbar =
|
|
4354
|
+
var Toolbar = styled16.div`
|
|
3889
4355
|
padding: 20px 16px 12px;
|
|
3890
4356
|
display: flex;
|
|
3891
4357
|
flex-direction: column;
|
|
3892
4358
|
gap: 12px;
|
|
3893
4359
|
`;
|
|
3894
|
-
var Title4 =
|
|
4360
|
+
var Title4 = styled16.h2`
|
|
3895
4361
|
margin: 0;
|
|
3896
4362
|
font-size: 14px;
|
|
3897
4363
|
color: var(--text-secondary);
|
|
3898
4364
|
`;
|
|
3899
|
-
var CreateButton =
|
|
4365
|
+
var CreateButton = styled16.button`
|
|
3900
4366
|
border: none;
|
|
3901
4367
|
border-radius: 12px;
|
|
3902
4368
|
padding: 12px 14px;
|
|
@@ -3905,7 +4371,7 @@ var CreateButton = styled17.button`
|
|
|
3905
4371
|
text-align: left;
|
|
3906
4372
|
cursor: pointer;
|
|
3907
4373
|
`;
|
|
3908
|
-
var List2 =
|
|
4374
|
+
var List2 = styled16.div`
|
|
3909
4375
|
padding: 0 12px 16px;
|
|
3910
4376
|
display: flex;
|
|
3911
4377
|
flex-direction: column;
|
|
@@ -3914,8 +4380,8 @@ var List2 = styled17.div`
|
|
|
3914
4380
|
`;
|
|
3915
4381
|
|
|
3916
4382
|
// src/components/ai-chat/index.tsx
|
|
3917
|
-
import { jsx as
|
|
3918
|
-
var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */
|
|
4383
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "@emotion/react/jsx-runtime";
|
|
4384
|
+
var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE__ */ jsx18(
|
|
3919
4385
|
ConfigProvider,
|
|
3920
4386
|
{
|
|
3921
4387
|
theme: {
|
|
@@ -3950,23 +4416,23 @@ var AiChat = ({ showConversationList = false, ...providerProps }) => /* @__PURE_
|
|
|
3950
4416
|
}
|
|
3951
4417
|
}
|
|
3952
4418
|
},
|
|
3953
|
-
children: /* @__PURE__ */
|
|
3954
|
-
showConversationList ? /* @__PURE__ */
|
|
4419
|
+
children: /* @__PURE__ */ jsx18(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ jsxs13(Root, { "data-testid": "ai-chat", children: [
|
|
4420
|
+
showConversationList ? /* @__PURE__ */ jsx18(ChatConversationList, {}) : null,
|
|
3955
4421
|
/* @__PURE__ */ jsxs13(Workspace, { children: [
|
|
3956
|
-
/* @__PURE__ */
|
|
3957
|
-
/* @__PURE__ */
|
|
4422
|
+
/* @__PURE__ */ jsx18(ChatThread, {}),
|
|
4423
|
+
/* @__PURE__ */ jsx18(ChatComposer, {})
|
|
3958
4424
|
] })
|
|
3959
4425
|
] }) })
|
|
3960
4426
|
}
|
|
3961
4427
|
);
|
|
3962
|
-
var Root =
|
|
4428
|
+
var Root = styled17.div`
|
|
3963
4429
|
display: flex;
|
|
3964
4430
|
width: 100%;
|
|
3965
4431
|
height: 100%;
|
|
3966
4432
|
min-height: 0;
|
|
3967
4433
|
overflow: hidden;
|
|
3968
4434
|
`;
|
|
3969
|
-
var Workspace =
|
|
4435
|
+
var Workspace = styled17.section`
|
|
3970
4436
|
flex: 1;
|
|
3971
4437
|
display: flex;
|
|
3972
4438
|
flex-direction: column;
|
|
@@ -3977,6 +4443,7 @@ export {
|
|
|
3977
4443
|
AiChat,
|
|
3978
4444
|
AiChatProvider,
|
|
3979
4445
|
CHAT_AGENT_MODES,
|
|
4446
|
+
CHAT_MESSAGE_RENDER_ORDERS,
|
|
3980
4447
|
ChatComposer,
|
|
3981
4448
|
ChatConversationList,
|
|
3982
4449
|
ChatThread,
|