@copilotz/chat-ui 0.9.44 → 0.9.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +65 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +65 -84
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -840,6 +840,10 @@ var hasRenderableAssistantBody = (message) => {
|
|
|
840
840
|
if (Array.isArray(message.attachments) && message.attachments.length > 0) return true;
|
|
841
841
|
return Boolean(message.activity?.items.length);
|
|
842
842
|
};
|
|
843
|
+
var filterActivity = (message, placement) => {
|
|
844
|
+
const items = message.activity?.items.filter((item) => placement === "after-content" ? item.kind === "tool" : item.kind !== "tool") ?? [];
|
|
845
|
+
return items.length > 0 ? { items } : void 0;
|
|
846
|
+
};
|
|
843
847
|
var defaultMarkdownComponents = {
|
|
844
848
|
code: ({ node, className, children, ...props }) => {
|
|
845
849
|
const inline = props.inline;
|
|
@@ -1106,6 +1110,7 @@ var MediaRenderer = memo2(function MediaRenderer2({ attachment }) {
|
|
|
1106
1110
|
});
|
|
1107
1111
|
var arePropsEqual = (prevProps, nextProps) => {
|
|
1108
1112
|
if (prevProps.message !== nextProps.message) return false;
|
|
1113
|
+
if (prevProps.fragments !== nextProps.fragments) return false;
|
|
1109
1114
|
if (prevProps.isUser !== nextProps.isUser) return false;
|
|
1110
1115
|
if (prevProps.userAvatar !== nextProps.userAvatar) return false;
|
|
1111
1116
|
if (prevProps.userName !== nextProps.userName) return false;
|
|
@@ -1135,6 +1140,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
1135
1140
|
};
|
|
1136
1141
|
var Message = memo2(({
|
|
1137
1142
|
message,
|
|
1143
|
+
fragments,
|
|
1138
1144
|
isUser,
|
|
1139
1145
|
userAvatar,
|
|
1140
1146
|
userName = "Voc\xEA",
|
|
@@ -1167,12 +1173,15 @@ var Message = memo2(({
|
|
|
1167
1173
|
const [showActions, setShowActions] = useState2(false);
|
|
1168
1174
|
const [actionsFocused, setActionsFocused] = useState2(false);
|
|
1169
1175
|
const [copied, setCopied] = useState2(false);
|
|
1176
|
+
const sourceMessages = fragments?.length ? fragments : [message];
|
|
1177
|
+
const headerMessage = sourceMessages[0];
|
|
1178
|
+
const groupContent = sourceMessages.map((sourceMessage) => sourceMessage.content.trim()).filter(Boolean).join("\n\n");
|
|
1170
1179
|
const messageIsUser = isUser ?? message.role === "user";
|
|
1171
|
-
if (!hasRenderableAssistantBody
|
|
1180
|
+
if (!sourceMessages.some(hasRenderableAssistantBody)) {
|
|
1172
1181
|
return null;
|
|
1173
1182
|
}
|
|
1174
1183
|
const senderDisplay = resolveMessageSenderDisplay({
|
|
1175
|
-
sender:
|
|
1184
|
+
sender: headerMessage.sender,
|
|
1176
1185
|
fallbackName: messageIsUser ? userName : assistantName,
|
|
1177
1186
|
fallbackAvatar: messageIsUser ? void 0 : assistantAvatar,
|
|
1178
1187
|
fallbackAvatarUrl: messageIsUser ? userAvatar : void 0,
|
|
@@ -1182,17 +1191,17 @@ var Message = memo2(({
|
|
|
1182
1191
|
const normalizedPreviewChars = Math.max(longMessagePreviewChars, 1);
|
|
1183
1192
|
const normalizedChunkChars = Math.max(longMessageChunkChars, 1);
|
|
1184
1193
|
const previewOverride = typeof message.metadata?.previewContent === "string" ? message.metadata.previewContent : void 0;
|
|
1185
|
-
const canCollapseMessage = collapseLongMessages && !
|
|
1194
|
+
const canCollapseMessage = collapseLongMessages && sourceMessages.length === 1 && !sourceMessages.some((sourceMessage) => sourceMessage.isStreaming) && groupContent.length > normalizedPreviewChars && (!collapseLongMessagesForUserOnly || messageIsUser);
|
|
1186
1195
|
const isCollapsed = canCollapseMessage && !isExpanded;
|
|
1187
|
-
const contentToRender = isCollapsed ? getCollapsedPreview(
|
|
1196
|
+
const contentToRender = isCollapsed ? getCollapsedPreview(groupContent, normalizedPreviewChars, previewOverride) : groupContent;
|
|
1188
1197
|
const shouldRenderMarkdown = !isCollapsed && (!messageIsUser || renderUserMarkdown);
|
|
1189
1198
|
const horizontalOffsetClass = showAvatar ? messageIsUser ? compactMode ? "mr-9" : "mr-11" : compactMode ? "ml-9" : "ml-11" : "";
|
|
1190
1199
|
const handleCopy = async () => {
|
|
1191
1200
|
try {
|
|
1192
|
-
await navigator.clipboard.writeText(
|
|
1201
|
+
await navigator.clipboard.writeText(groupContent);
|
|
1193
1202
|
setCopied(true);
|
|
1194
1203
|
setTimeout(() => setCopied(false), 2e3);
|
|
1195
|
-
onAction?.({ action: "copy", messageId: message.id, content:
|
|
1204
|
+
onAction?.({ action: "copy", messageId: message.id, content: groupContent });
|
|
1196
1205
|
} catch (error) {
|
|
1197
1206
|
console.error("Failed to copy message:", error);
|
|
1198
1207
|
}
|
|
@@ -1238,7 +1247,7 @@ var Message = memo2(({
|
|
|
1238
1247
|
showAvatar && /* @__PURE__ */ jsx9("div", { className: `flex-shrink-0 ${compactMode ? "mt-1" : "mt-0"}`, children: /* @__PURE__ */ jsx9(
|
|
1239
1248
|
MessageSenderAvatar,
|
|
1240
1249
|
{
|
|
1241
|
-
sender:
|
|
1250
|
+
sender: headerMessage.sender,
|
|
1242
1251
|
fallbackName: messageIsUser ? userName : assistantName,
|
|
1243
1252
|
fallbackAvatar: messageIsUser ? void 0 : assistantAvatar,
|
|
1244
1253
|
fallbackAvatarUrl: messageIsUser ? userAvatar : void 0,
|
|
@@ -1254,8 +1263,8 @@ var Message = memo2(({
|
|
|
1254
1263
|
children: senderDisplay.name
|
|
1255
1264
|
}
|
|
1256
1265
|
),
|
|
1257
|
-
showTimestamp && /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: formatTime(
|
|
1258
|
-
|
|
1266
|
+
showTimestamp && /* @__PURE__ */ jsx9("span", { className: "text-xs text-muted-foreground", children: formatTime(headerMessage.timestamp) }),
|
|
1267
|
+
sourceMessages.some((sourceMessage) => sourceMessage.isEdited) && /* @__PURE__ */ jsx9(Badge, { variant: "outline", className: "text-xs", children: "editado" })
|
|
1259
1268
|
] })
|
|
1260
1269
|
] }),
|
|
1261
1270
|
/* @__PURE__ */ jsxs5("div", { className: `flex-1 min-w-0 ${messageIsUser ? "text-right" : "text-left"} ${horizontalOffsetClass}`, children: [
|
|
@@ -1300,25 +1309,42 @@ var Message = memo2(({
|
|
|
1300
1309
|
)
|
|
1301
1310
|
] })
|
|
1302
1311
|
] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1312
|
+
sourceMessages.map((sourceMessage) => {
|
|
1313
|
+
const beforeContentActivity = filterActivity(sourceMessage, "before-content");
|
|
1314
|
+
const afterContentActivity = filterActivity(sourceMessage, "after-content");
|
|
1315
|
+
const fragmentContent = sourceMessages.length === 1 ? contentToRender : sourceMessage.content;
|
|
1316
|
+
return /* @__PURE__ */ jsxs5(React3.Fragment, { children: [
|
|
1317
|
+
!messageIsUser && /* @__PURE__ */ jsx9(
|
|
1318
|
+
AssistantActivity,
|
|
1319
|
+
{
|
|
1320
|
+
activity: beforeContentActivity,
|
|
1321
|
+
showActivity,
|
|
1322
|
+
showActivityDetails,
|
|
1323
|
+
labels
|
|
1324
|
+
}
|
|
1325
|
+
),
|
|
1326
|
+
fragmentContent.length > 0 && /* @__PURE__ */ jsx9(
|
|
1327
|
+
StreamingText,
|
|
1328
|
+
{
|
|
1329
|
+
content: fragmentContent,
|
|
1330
|
+
isStreaming: sourceMessage.isStreaming,
|
|
1331
|
+
renderMarkdown: shouldRenderMarkdown,
|
|
1332
|
+
markdown,
|
|
1333
|
+
plainTextChunkChars: normalizedChunkChars
|
|
1334
|
+
}
|
|
1335
|
+
),
|
|
1336
|
+
!messageIsUser && /* @__PURE__ */ jsx9(
|
|
1337
|
+
AssistantActivity,
|
|
1338
|
+
{
|
|
1339
|
+
activity: afterContentActivity,
|
|
1340
|
+
showActivity,
|
|
1341
|
+
showActivityDetails,
|
|
1342
|
+
labels
|
|
1343
|
+
}
|
|
1344
|
+
),
|
|
1345
|
+
sourceMessage.attachments && sourceMessage.attachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-3 space-y-2", children: sourceMessage.attachments.map((attachment, index) => /* @__PURE__ */ jsx9(MediaRenderer, { attachment }, `${sourceMessage.id}:${index}`)) })
|
|
1346
|
+
] }, sourceMessage.id);
|
|
1347
|
+
}),
|
|
1322
1348
|
canCollapseMessage && /* @__PURE__ */ jsx9("div", { className: "mt-3", children: /* @__PURE__ */ jsx9(
|
|
1323
1349
|
Button,
|
|
1324
1350
|
{
|
|
@@ -1330,8 +1356,7 @@ var Message = memo2(({
|
|
|
1330
1356
|
onClick: handleToggleExpanded,
|
|
1331
1357
|
children: isCollapsed ? showMoreLabel : showLessLabel
|
|
1332
1358
|
}
|
|
1333
|
-
) })
|
|
1334
|
-
message.attachments && message.attachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-3 space-y-2", children: message.attachments.map((attachment, index) => /* @__PURE__ */ jsx9(MediaRenderer, { attachment }, index)) })
|
|
1359
|
+
) })
|
|
1335
1360
|
] }) }),
|
|
1336
1361
|
!isEditing && (enableCopy || canEdit) && /* @__PURE__ */ jsxs5(
|
|
1337
1362
|
"div",
|
|
@@ -5970,72 +5995,27 @@ var getMessageSpeakerKey = (message) => {
|
|
|
5970
5995
|
}
|
|
5971
5996
|
return message.role;
|
|
5972
5997
|
};
|
|
5973
|
-
var getAssistantSpeakerTokens = (message) => {
|
|
5974
|
-
if (!message || message.role !== "assistant") return [];
|
|
5975
|
-
if (message.sender) {
|
|
5976
|
-
return Array.from(new Set([
|
|
5977
|
-
`${message.sender.type}:${message.sender.id}`,
|
|
5978
|
-
message.sender.agentId ? `agent:${message.sender.agentId}` : "",
|
|
5979
|
-
message.sender.externalId ? `external:${message.sender.externalId}` : ""
|
|
5980
|
-
].filter(Boolean).map((value) => value.toLowerCase())));
|
|
5981
|
-
}
|
|
5982
|
-
return ["assistant"];
|
|
5983
|
-
};
|
|
5984
|
-
var hasAssistantContent = (message) => message.role === "assistant" && (message.content.trim().length > 0 || Boolean(message.attachments?.length));
|
|
5985
|
-
var hasActivity = (message) => Boolean(message.activity?.items.length);
|
|
5986
5998
|
var canGroupMessages = (previous, next) => {
|
|
5987
5999
|
if (previous.role !== next.role) {
|
|
5988
6000
|
return false;
|
|
5989
6001
|
}
|
|
5990
6002
|
if (previous.role !== "assistant") {
|
|
5991
|
-
return
|
|
5992
|
-
}
|
|
5993
|
-
const previousTokens = getAssistantSpeakerTokens(previous);
|
|
5994
|
-
const nextTokens = getAssistantSpeakerTokens(next);
|
|
5995
|
-
if (!previousTokens.some((token) => nextTokens.includes(token))) return false;
|
|
5996
|
-
return !(hasAssistantContent(previous) && hasActivity(next));
|
|
5997
|
-
};
|
|
5998
|
-
var mergeGroupActivity = (messages) => {
|
|
5999
|
-
const merged = /* @__PURE__ */ new Map();
|
|
6000
|
-
for (const activity of messages.map((message) => message.activity).filter((activity2) => Boolean(activity2))) {
|
|
6001
|
-
for (const item of activity.items) merged.set(item.id, item);
|
|
6002
|
-
}
|
|
6003
|
-
return merged.size > 0 ? { items: Array.from(merged.values()) } : void 0;
|
|
6004
|
-
};
|
|
6005
|
-
var mergeMessageGroup = (messages) => {
|
|
6006
|
-
if (messages.length === 1) {
|
|
6007
|
-
return messages[0];
|
|
6003
|
+
return false;
|
|
6008
6004
|
}
|
|
6009
|
-
|
|
6010
|
-
const lastMessage = messages[messages.length - 1];
|
|
6011
|
-
const content = messages.map((message) => message.content.trim()).filter((value) => value.length > 0).join("\n\n");
|
|
6012
|
-
const attachments = messages.flatMap((message) => message.attachments ?? []);
|
|
6013
|
-
return {
|
|
6014
|
-
...lastMessage,
|
|
6015
|
-
id: lastMessage.id,
|
|
6016
|
-
content,
|
|
6017
|
-
timestamp: firstMessage.timestamp,
|
|
6018
|
-
attachments: attachments.length > 0 ? attachments : void 0,
|
|
6019
|
-
isStreaming: lastMessage.isStreaming,
|
|
6020
|
-
isComplete: lastMessage.isComplete,
|
|
6021
|
-
isEdited: messages.some((message) => message.isEdited),
|
|
6022
|
-
originalContent: void 0,
|
|
6023
|
-
editedAt: lastMessage.editedAt,
|
|
6024
|
-
activity: mergeGroupActivity(messages),
|
|
6025
|
-
sender: lastMessage.sender ?? firstMessage.sender,
|
|
6026
|
-
metadata: lastMessage.metadata
|
|
6027
|
-
};
|
|
6005
|
+
return getMessageSpeakerKey(previous) === getMessageSpeakerKey(next);
|
|
6028
6006
|
};
|
|
6029
6007
|
var groupMessagesForRender = (messages) => {
|
|
6030
6008
|
if (messages.length === 0) return [];
|
|
6031
6009
|
const groups = [];
|
|
6032
6010
|
let currentGroup = [messages[0]];
|
|
6033
6011
|
const flushGroup = () => {
|
|
6034
|
-
const
|
|
6012
|
+
const firstMessage = currentGroup[0];
|
|
6013
|
+
const lastMessage = currentGroup[currentGroup.length - 1];
|
|
6035
6014
|
groups.push({
|
|
6036
|
-
id:
|
|
6037
|
-
|
|
6038
|
-
|
|
6015
|
+
id: firstMessage.id,
|
|
6016
|
+
messages: currentGroup,
|
|
6017
|
+
primaryMessage: lastMessage,
|
|
6018
|
+
suggestionMessageId: lastMessage.id
|
|
6039
6019
|
});
|
|
6040
6020
|
};
|
|
6041
6021
|
for (let index = 1; index < messages.length; index++) {
|
|
@@ -6686,7 +6666,7 @@ var ChatUI = ({
|
|
|
6686
6666
|
},
|
|
6687
6667
|
children: virtualizer.getVirtualItems().map((virtualRow) => {
|
|
6688
6668
|
const group = groupedMessages[virtualRow.index];
|
|
6689
|
-
const message = group.
|
|
6669
|
+
const message = group.primaryMessage;
|
|
6690
6670
|
return /* @__PURE__ */ jsx28(
|
|
6691
6671
|
"div",
|
|
6692
6672
|
{
|
|
@@ -6708,6 +6688,7 @@ var ChatUI = ({
|
|
|
6708
6688
|
Message,
|
|
6709
6689
|
{
|
|
6710
6690
|
message,
|
|
6691
|
+
fragments: group.messages,
|
|
6711
6692
|
...messageProps,
|
|
6712
6693
|
isExpanded: Boolean(
|
|
6713
6694
|
expandedMessageIds[message.id]
|