@copilotkit/react-ui 1.10.0-next.8 → 1.10.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/CHANGELOG.md +132 -0
- package/dist/{chunk-U5ATIGWH.mjs → chunk-BJHJBS5M.mjs} +45 -5
- package/dist/chunk-BJHJBS5M.mjs.map +1 -0
- package/dist/{chunk-KLV4ERV6.mjs → chunk-GBP47ONN.mjs} +2 -2
- package/dist/{chunk-3DVMCBME.mjs → chunk-GJ4SX4JE.mjs} +97 -35
- package/dist/chunk-GJ4SX4JE.mjs.map +1 -0
- package/dist/{chunk-APLX7E54.mjs → chunk-J5ZZR6YB.mjs} +2 -2
- package/dist/chunk-MIVUCSGO.mjs +126 -0
- package/dist/chunk-MIVUCSGO.mjs.map +1 -0
- package/dist/{chunk-JHUTTP5C.mjs → chunk-T5QU6KSB.mjs} +5 -1
- package/dist/chunk-T5QU6KSB.mjs.map +1 -0
- package/dist/{chunk-BPU3FDT4.mjs → chunk-Y44VLEUH.mjs} +30 -11
- package/dist/chunk-Y44VLEUH.mjs.map +1 -0
- package/dist/components/chat/Chat.d.ts +32 -2
- package/dist/components/chat/Chat.js +1084 -865
- package/dist/components/chat/Chat.js.map +1 -1
- package/dist/components/chat/Chat.mjs +7 -6
- package/dist/components/chat/Messages.d.ts +1 -1
- package/dist/components/chat/Messages.js +984 -23
- package/dist/components/chat/Messages.js.map +1 -1
- package/dist/components/chat/Messages.mjs +9 -1
- package/dist/components/chat/Modal.js +1107 -875
- package/dist/components/chat/Modal.js.map +1 -1
- package/dist/components/chat/Modal.mjs +8 -7
- package/dist/components/chat/Popup.js +1109 -877
- package/dist/components/chat/Popup.js.map +1 -1
- package/dist/components/chat/Popup.mjs +9 -8
- package/dist/components/chat/Sidebar.js +1109 -877
- package/dist/components/chat/Sidebar.js.map +1 -1
- package/dist/components/chat/Sidebar.mjs +9 -8
- package/dist/components/chat/index.js +1111 -879
- package/dist/components/chat/index.js.map +1 -1
- package/dist/components/chat/index.mjs +16 -15
- package/dist/components/chat/messages/LegacyRenderMessage.d.ts +28 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js +980 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs +17 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs.map +1 -0
- package/dist/components/chat/messages/RenderMessage.js +4 -0
- package/dist/components/chat/messages/RenderMessage.js.map +1 -1
- package/dist/components/chat/messages/RenderMessage.mjs +1 -1
- package/dist/components/chat/props.d.ts +55 -1
- package/dist/components/chat/props.js.map +1 -1
- package/dist/components/index.js +1111 -879
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +16 -15
- package/dist/index.js +1113 -881
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -15
- package/package.json +4 -4
- package/src/components/chat/Chat.tsx +144 -21
- package/src/components/chat/Messages.tsx +56 -3
- package/src/components/chat/Modal.tsx +24 -3
- package/src/components/chat/messages/LegacyRenderMessage.tsx +143 -0
- package/src/components/chat/messages/RenderMessage.tsx +3 -0
- package/src/components/chat/props.ts +64 -1
- package/dist/chunk-3DVMCBME.mjs.map +0 -1
- package/dist/chunk-BPU3FDT4.mjs.map +0 -1
- package/dist/chunk-JHUTTP5C.mjs.map +0 -1
- package/dist/chunk-U5ATIGWH.mjs.map +0 -1
- /package/dist/{chunk-KLV4ERV6.mjs.map → chunk-GBP47ONN.mjs.map} +0 -0
- /package/dist/{chunk-APLX7E54.mjs.map → chunk-J5ZZR6YB.mjs.map} +0 -0
|
@@ -1026,559 +1026,137 @@ var Header = ({}) => {
|
|
|
1026
1026
|
};
|
|
1027
1027
|
|
|
1028
1028
|
// src/components/chat/Messages.tsx
|
|
1029
|
-
var
|
|
1029
|
+
var import_react10 = require("react");
|
|
1030
1030
|
var import_react_core5 = require("@copilotkit/react-core");
|
|
1031
|
+
|
|
1032
|
+
// src/components/chat/messages/UserMessage.tsx
|
|
1031
1033
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1032
|
-
var
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
onRegenerate,
|
|
1039
|
-
onCopy,
|
|
1040
|
-
onThumbsUp,
|
|
1041
|
-
onThumbsDown,
|
|
1042
|
-
markdownTagRenderers
|
|
1043
|
-
}) => {
|
|
1044
|
-
const { labels } = useChatContext();
|
|
1045
|
-
const { visibleMessages, interrupt } = (0, import_react_core5.useCopilotChatInternal)();
|
|
1046
|
-
const initialMessages = (0, import_react6.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
1047
|
-
const messages = [...initialMessages, ...visibleMessages];
|
|
1048
|
-
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
1049
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
1050
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
1051
|
-
messages.map((message, index) => {
|
|
1052
|
-
const isCurrentMessage = index === messages.length - 1;
|
|
1053
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1054
|
-
RenderMessage2,
|
|
1055
|
-
{
|
|
1056
|
-
message,
|
|
1057
|
-
inProgress,
|
|
1058
|
-
index,
|
|
1059
|
-
isCurrentMessage,
|
|
1060
|
-
AssistantMessage: AssistantMessage2,
|
|
1061
|
-
UserMessage: UserMessage2,
|
|
1062
|
-
onRegenerate,
|
|
1063
|
-
onCopy,
|
|
1064
|
-
onThumbsUp,
|
|
1065
|
-
onThumbsDown,
|
|
1066
|
-
markdownTagRenderers
|
|
1067
|
-
},
|
|
1068
|
-
index
|
|
1069
|
-
);
|
|
1070
|
-
}),
|
|
1071
|
-
interrupt
|
|
1072
|
-
] }),
|
|
1073
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
1074
|
-
] });
|
|
1075
|
-
};
|
|
1076
|
-
function makeInitialMessages(initial) {
|
|
1077
|
-
if (!initial)
|
|
1078
|
-
return [];
|
|
1079
|
-
if (Array.isArray(initial)) {
|
|
1080
|
-
return initial.map((message) => {
|
|
1081
|
-
return {
|
|
1082
|
-
id: message,
|
|
1083
|
-
role: "assistant",
|
|
1084
|
-
content: message
|
|
1085
|
-
};
|
|
1086
|
-
});
|
|
1034
|
+
var UserMessage = (props) => {
|
|
1035
|
+
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
1036
|
+
const isImageMessage = message && "image" in message && message.image;
|
|
1037
|
+
if (isImageMessage) {
|
|
1038
|
+
const imageMessage = message;
|
|
1039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
1087
1040
|
}
|
|
1088
|
-
return
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
};
|
|
1107
|
-
const handleScroll = () => {
|
|
1108
|
-
if (isProgrammaticScrollRef.current) {
|
|
1109
|
-
isProgrammaticScrollRef.current = false;
|
|
1041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
// src/components/chat/Markdown.tsx
|
|
1045
|
+
var import_react7 = require("react");
|
|
1046
|
+
var import_react_markdown = __toESM(require("react-markdown"));
|
|
1047
|
+
|
|
1048
|
+
// src/components/chat/CodeBlock.tsx
|
|
1049
|
+
var import_react6 = require("react");
|
|
1050
|
+
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
1051
|
+
|
|
1052
|
+
// src/hooks/use-copy-to-clipboard.tsx
|
|
1053
|
+
var React5 = __toESM(require("react"));
|
|
1054
|
+
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
1055
|
+
const [isCopied, setIsCopied] = React5.useState(false);
|
|
1056
|
+
const copyToClipboard = (value) => {
|
|
1057
|
+
var _a;
|
|
1058
|
+
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
1110
1059
|
return;
|
|
1111
1060
|
}
|
|
1112
|
-
if (
|
|
1113
|
-
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
1114
|
-
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
1115
|
-
}
|
|
1116
|
-
};
|
|
1117
|
-
(0, import_react6.useEffect)(() => {
|
|
1118
|
-
const container = messagesContainerRef.current;
|
|
1119
|
-
if (container) {
|
|
1120
|
-
container.addEventListener("scroll", handleScroll);
|
|
1121
|
-
}
|
|
1122
|
-
return () => {
|
|
1123
|
-
if (container) {
|
|
1124
|
-
container.removeEventListener("scroll", handleScroll);
|
|
1125
|
-
}
|
|
1126
|
-
};
|
|
1127
|
-
}, []);
|
|
1128
|
-
(0, import_react6.useEffect)(() => {
|
|
1129
|
-
const container = messagesContainerRef.current;
|
|
1130
|
-
if (!container) {
|
|
1061
|
+
if (!value) {
|
|
1131
1062
|
return;
|
|
1132
1063
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
mutationObserver.observe(container, {
|
|
1139
|
-
childList: true,
|
|
1140
|
-
subtree: true,
|
|
1141
|
-
characterData: true
|
|
1064
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
1065
|
+
setIsCopied(true);
|
|
1066
|
+
setTimeout(() => {
|
|
1067
|
+
setIsCopied(false);
|
|
1068
|
+
}, timeout);
|
|
1142
1069
|
});
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
};
|
|
1146
|
-
}, []);
|
|
1147
|
-
(0, import_react6.useEffect)(() => {
|
|
1148
|
-
isUserScrollUpRef.current = false;
|
|
1149
|
-
scrollToBottom();
|
|
1150
|
-
}, [messages.filter((m) => m.role === "user").length]);
|
|
1151
|
-
return { messagesEndRef, messagesContainerRef };
|
|
1070
|
+
};
|
|
1071
|
+
return { isCopied, copyToClipboard };
|
|
1152
1072
|
}
|
|
1153
1073
|
|
|
1154
|
-
// src/components/chat/
|
|
1155
|
-
var import_react9 = require("react");
|
|
1156
|
-
|
|
1157
|
-
// src/components/chat/Textarea.tsx
|
|
1158
|
-
var import_react7 = require("react");
|
|
1074
|
+
// src/components/chat/CodeBlock.tsx
|
|
1159
1075
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1160
|
-
var
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1076
|
+
var programmingLanguages = {
|
|
1077
|
+
javascript: ".js",
|
|
1078
|
+
python: ".py",
|
|
1079
|
+
java: ".java",
|
|
1080
|
+
c: ".c",
|
|
1081
|
+
cpp: ".cpp",
|
|
1082
|
+
"c++": ".cpp",
|
|
1083
|
+
"c#": ".cs",
|
|
1084
|
+
ruby: ".rb",
|
|
1085
|
+
php: ".php",
|
|
1086
|
+
swift: ".swift",
|
|
1087
|
+
"objective-c": ".m",
|
|
1088
|
+
kotlin: ".kt",
|
|
1089
|
+
typescript: ".ts",
|
|
1090
|
+
go: ".go",
|
|
1091
|
+
perl: ".pl",
|
|
1092
|
+
rust: ".rs",
|
|
1093
|
+
scala: ".scala",
|
|
1094
|
+
haskell: ".hs",
|
|
1095
|
+
lua: ".lua",
|
|
1096
|
+
shell: ".sh",
|
|
1097
|
+
sql: ".sql",
|
|
1098
|
+
html: ".html",
|
|
1099
|
+
css: ".css"
|
|
1100
|
+
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
1101
|
+
};
|
|
1102
|
+
var generateRandomString = (length, lowercase = false) => {
|
|
1103
|
+
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
1104
|
+
let result = "";
|
|
1105
|
+
for (let i = 0; i < length; i++) {
|
|
1106
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
1107
|
+
}
|
|
1108
|
+
return lowercase ? result.toLowerCase() : result;
|
|
1109
|
+
};
|
|
1110
|
+
var CodeBlock = (0, import_react6.memo)(({ language, value }) => {
|
|
1111
|
+
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
1112
|
+
const downloadAsFile = () => {
|
|
1113
|
+
if (typeof window === "undefined") {
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
const fileExtension = programmingLanguages[language] || ".file";
|
|
1117
|
+
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
1118
|
+
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
1119
|
+
if (!fileName) {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
const blob = new Blob([value], { type: "text/plain" });
|
|
1123
|
+
const url = URL.createObjectURL(blob);
|
|
1124
|
+
const link = document.createElement("a");
|
|
1125
|
+
link.download = fileName;
|
|
1126
|
+
link.href = url;
|
|
1127
|
+
link.style.display = "none";
|
|
1128
|
+
document.body.appendChild(link);
|
|
1129
|
+
link.click();
|
|
1130
|
+
document.body.removeChild(link);
|
|
1131
|
+
URL.revokeObjectURL(url);
|
|
1132
|
+
};
|
|
1133
|
+
const onCopy = () => {
|
|
1134
|
+
if (isCopied)
|
|
1135
|
+
return;
|
|
1136
|
+
copyToClipboard(value);
|
|
1137
|
+
};
|
|
1138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
1141
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
1142
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
1144
|
+
] })
|
|
1145
|
+
] }),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1147
|
+
import_react_syntax_highlighter.Prism,
|
|
1197
1148
|
{
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
style: {
|
|
1206
|
-
overflow: "auto",
|
|
1207
|
-
resize: "none",
|
|
1208
|
-
maxHeight: `${maxHeight}px`
|
|
1149
|
+
language,
|
|
1150
|
+
style: highlightStyle,
|
|
1151
|
+
PreTag: "div",
|
|
1152
|
+
customStyle: {
|
|
1153
|
+
margin: 0,
|
|
1154
|
+
borderBottomLeftRadius: "0.375rem",
|
|
1155
|
+
borderBottomRightRadius: "0.375rem"
|
|
1209
1156
|
},
|
|
1210
|
-
|
|
1157
|
+
children: value
|
|
1211
1158
|
}
|
|
1212
|
-
)
|
|
1213
|
-
}
|
|
1214
|
-
);
|
|
1215
|
-
var Textarea_default = AutoResizingTextarea;
|
|
1216
|
-
|
|
1217
|
-
// src/hooks/use-push-to-talk.tsx
|
|
1218
|
-
var import_react_core6 = require("@copilotkit/react-core");
|
|
1219
|
-
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
1220
|
-
var import_react8 = require("react");
|
|
1221
|
-
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
1222
|
-
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
1223
|
-
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1224
|
-
audioContextRef.current = new window.AudioContext();
|
|
1225
|
-
yield audioContextRef.current.resume();
|
|
1226
|
-
}
|
|
1227
|
-
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
1228
|
-
mediaRecorderRef.current.start(1e3);
|
|
1229
|
-
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
1230
|
-
recordedChunks.push(event.data);
|
|
1231
|
-
};
|
|
1232
|
-
mediaRecorderRef.current.onstop = onStop;
|
|
1233
|
-
});
|
|
1234
|
-
var stopRecording = (mediaRecorderRef) => {
|
|
1235
|
-
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
1236
|
-
mediaRecorderRef.current.stop();
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1239
|
-
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
1240
|
-
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
1241
|
-
const formData = new FormData();
|
|
1242
|
-
formData.append("file", completeBlob, "recording.mp4");
|
|
1243
|
-
const response = yield fetch(transcribeAudioUrl, {
|
|
1244
|
-
method: "POST",
|
|
1245
|
-
body: formData
|
|
1246
|
-
});
|
|
1247
|
-
if (!response.ok) {
|
|
1248
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
1249
|
-
}
|
|
1250
|
-
const transcription = yield response.json();
|
|
1251
|
-
return transcription.text;
|
|
1252
|
-
});
|
|
1253
|
-
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
1254
|
-
const encodedText = encodeURIComponent(text);
|
|
1255
|
-
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
1256
|
-
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
1257
|
-
const source = audioContext.createBufferSource();
|
|
1258
|
-
source.buffer = audioBuffer;
|
|
1259
|
-
source.connect(audioContext.destination);
|
|
1260
|
-
source.start(0);
|
|
1261
|
-
}).catch((error) => {
|
|
1262
|
-
console.error("Error with decoding audio data", error);
|
|
1263
|
-
});
|
|
1264
|
-
};
|
|
1265
|
-
var usePushToTalk = ({
|
|
1266
|
-
sendFunction,
|
|
1267
|
-
inProgress
|
|
1268
|
-
}) => {
|
|
1269
|
-
const [pushToTalkState, setPushToTalkState] = (0, import_react8.useState)("idle");
|
|
1270
|
-
const mediaStreamRef = (0, import_react8.useRef)(null);
|
|
1271
|
-
const audioContextRef = (0, import_react8.useRef)(null);
|
|
1272
|
-
const mediaRecorderRef = (0, import_react8.useRef)(null);
|
|
1273
|
-
const recordedChunks = (0, import_react8.useRef)([]);
|
|
1274
|
-
const generalContext = (0, import_react_core6.useCopilotContext)();
|
|
1275
|
-
const messagesContext = (0, import_react_core6.useCopilotMessagesContext)();
|
|
1276
|
-
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
1277
|
-
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react8.useState)(null);
|
|
1278
|
-
(0, import_react8.useEffect)(() => {
|
|
1279
|
-
if (pushToTalkState === "recording") {
|
|
1280
|
-
startRecording(
|
|
1281
|
-
mediaStreamRef,
|
|
1282
|
-
mediaRecorderRef,
|
|
1283
|
-
audioContextRef,
|
|
1284
|
-
recordedChunks.current,
|
|
1285
|
-
() => {
|
|
1286
|
-
setPushToTalkState("transcribing");
|
|
1287
|
-
}
|
|
1288
|
-
);
|
|
1289
|
-
} else {
|
|
1290
|
-
stopRecording(mediaRecorderRef);
|
|
1291
|
-
if (pushToTalkState === "transcribing") {
|
|
1292
|
-
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
1293
|
-
(transcription) => __async(void 0, null, function* () {
|
|
1294
|
-
recordedChunks.current = [];
|
|
1295
|
-
setPushToTalkState("idle");
|
|
1296
|
-
const message = yield sendFunction(transcription);
|
|
1297
|
-
setStartReadingFromMessageId(message.id);
|
|
1298
|
-
})
|
|
1299
|
-
);
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
return () => {
|
|
1303
|
-
stopRecording(mediaRecorderRef);
|
|
1304
|
-
};
|
|
1305
|
-
}, [pushToTalkState]);
|
|
1306
|
-
(0, import_react8.useEffect)(() => {
|
|
1307
|
-
if (inProgress === false && startReadingFromMessageId) {
|
|
1308
|
-
const lastMessageIndex = context.messages.findIndex(
|
|
1309
|
-
(message) => message.id === startReadingFromMessageId
|
|
1310
|
-
);
|
|
1311
|
-
const aguiMessages = (0, import_runtime_client_gql.gqlToAGUI)(context.messages);
|
|
1312
|
-
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
1313
|
-
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
1314
|
-
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
1315
|
-
setStartReadingFromMessageId(null);
|
|
1316
|
-
}
|
|
1317
|
-
}, [startReadingFromMessageId, inProgress]);
|
|
1318
|
-
return { pushToTalkState, setPushToTalkState };
|
|
1319
|
-
};
|
|
1320
|
-
|
|
1321
|
-
// src/components/chat/Input.tsx
|
|
1322
|
-
var import_react_core7 = require("@copilotkit/react-core");
|
|
1323
|
-
|
|
1324
|
-
// src/hooks/use-dark-mode.ts
|
|
1325
|
-
var useDarkMode = () => {
|
|
1326
|
-
if (typeof window === "undefined")
|
|
1327
|
-
return false;
|
|
1328
|
-
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
1329
|
-
};
|
|
1330
|
-
|
|
1331
|
-
// src/components/chat/PoweredByTag.tsx
|
|
1332
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1333
|
-
function PoweredByTag({ showPoweredBy = true }) {
|
|
1334
|
-
const isDark = useDarkMode();
|
|
1335
|
-
if (!showPoweredBy) {
|
|
1336
|
-
return null;
|
|
1337
|
-
}
|
|
1338
|
-
const poweredByStyle = {
|
|
1339
|
-
visibility: "visible",
|
|
1340
|
-
display: "block",
|
|
1341
|
-
position: "static",
|
|
1342
|
-
textAlign: "center",
|
|
1343
|
-
fontSize: "12px",
|
|
1344
|
-
padding: "3px 0",
|
|
1345
|
-
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
1346
|
-
};
|
|
1347
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
|
-
// src/components/chat/Input.tsx
|
|
1351
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1352
|
-
var MAX_NEWLINES = 6;
|
|
1353
|
-
var Input = ({
|
|
1354
|
-
inProgress,
|
|
1355
|
-
onSend,
|
|
1356
|
-
isVisible = false,
|
|
1357
|
-
onStop,
|
|
1358
|
-
onUpload,
|
|
1359
|
-
hideStopButton = false
|
|
1360
|
-
}) => {
|
|
1361
|
-
var _a, _b;
|
|
1362
|
-
const context = useChatContext();
|
|
1363
|
-
const copilotContext = (0, import_react_core7.useCopilotContext)();
|
|
1364
|
-
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
1365
|
-
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
1366
|
-
const textareaRef = (0, import_react9.useRef)(null);
|
|
1367
|
-
const [isComposing, setIsComposing] = (0, import_react9.useState)(false);
|
|
1368
|
-
const handleDivClick = (event) => {
|
|
1369
|
-
var _a2;
|
|
1370
|
-
const target = event.target;
|
|
1371
|
-
if (target.closest("button"))
|
|
1372
|
-
return;
|
|
1373
|
-
if (target.tagName === "TEXTAREA")
|
|
1374
|
-
return;
|
|
1375
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1376
|
-
};
|
|
1377
|
-
const [text, setText] = (0, import_react9.useState)("");
|
|
1378
|
-
const send = () => {
|
|
1379
|
-
var _a2;
|
|
1380
|
-
if (inProgress)
|
|
1381
|
-
return;
|
|
1382
|
-
onSend(text);
|
|
1383
|
-
setText("");
|
|
1384
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1385
|
-
};
|
|
1386
|
-
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
1387
|
-
sendFunction: onSend,
|
|
1388
|
-
inProgress
|
|
1389
|
-
});
|
|
1390
|
-
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
1391
|
-
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
1392
|
-
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
1393
|
-
const canSend = (0, import_react9.useMemo)(() => {
|
|
1394
|
-
var _a2;
|
|
1395
|
-
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
1396
|
-
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
1397
|
-
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
1398
|
-
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
1399
|
-
const canStop = (0, import_react9.useMemo)(() => {
|
|
1400
|
-
return isInProgress && !hideStopButton;
|
|
1401
|
-
}, [isInProgress, hideStopButton]);
|
|
1402
|
-
const sendDisabled = !canSend && !canStop;
|
|
1403
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
1404
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
1405
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1406
|
-
Textarea_default,
|
|
1407
|
-
{
|
|
1408
|
-
ref: textareaRef,
|
|
1409
|
-
placeholder: context.labels.placeholder,
|
|
1410
|
-
autoFocus: false,
|
|
1411
|
-
maxRows: MAX_NEWLINES,
|
|
1412
|
-
value: text,
|
|
1413
|
-
onChange: (event) => setText(event.target.value),
|
|
1414
|
-
onCompositionStart: () => setIsComposing(true),
|
|
1415
|
-
onCompositionEnd: () => setIsComposing(false),
|
|
1416
|
-
onKeyDown: (event) => {
|
|
1417
|
-
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
1418
|
-
event.preventDefault();
|
|
1419
|
-
if (canSend) {
|
|
1420
|
-
send();
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
),
|
|
1426
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
1427
|
-
onUpload && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
1428
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flexGrow: 1 } }),
|
|
1429
|
-
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1430
|
-
"button",
|
|
1431
|
-
{
|
|
1432
|
-
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
1433
|
-
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
1434
|
-
children: context.icons.pushToTalkIcon
|
|
1435
|
-
}
|
|
1436
|
-
),
|
|
1437
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1438
|
-
"button",
|
|
1439
|
-
{
|
|
1440
|
-
disabled: sendDisabled,
|
|
1441
|
-
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
1442
|
-
"data-copilotkit-in-progress": inProgress,
|
|
1443
|
-
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
1444
|
-
className: "copilotKitInputControlButton",
|
|
1445
|
-
children: buttonIcon
|
|
1446
|
-
}
|
|
1447
|
-
)
|
|
1448
|
-
] })
|
|
1449
|
-
] }),
|
|
1450
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PoweredByTag, { showPoweredBy })
|
|
1451
|
-
] });
|
|
1452
|
-
};
|
|
1453
|
-
|
|
1454
|
-
// src/components/chat/messages/UserMessage.tsx
|
|
1455
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1456
|
-
var UserMessage = (props) => {
|
|
1457
|
-
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
1458
|
-
const isImageMessage = message && "image" in message && message.image;
|
|
1459
|
-
if (isImageMessage) {
|
|
1460
|
-
const imageMessage = message;
|
|
1461
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
1462
|
-
}
|
|
1463
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
1464
|
-
};
|
|
1465
|
-
|
|
1466
|
-
// src/components/chat/Markdown.tsx
|
|
1467
|
-
var import_react11 = require("react");
|
|
1468
|
-
var import_react_markdown = __toESM(require("react-markdown"));
|
|
1469
|
-
|
|
1470
|
-
// src/components/chat/CodeBlock.tsx
|
|
1471
|
-
var import_react10 = require("react");
|
|
1472
|
-
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
1473
|
-
|
|
1474
|
-
// src/hooks/use-copy-to-clipboard.tsx
|
|
1475
|
-
var React7 = __toESM(require("react"));
|
|
1476
|
-
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
1477
|
-
const [isCopied, setIsCopied] = React7.useState(false);
|
|
1478
|
-
const copyToClipboard = (value) => {
|
|
1479
|
-
var _a;
|
|
1480
|
-
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
1481
|
-
return;
|
|
1482
|
-
}
|
|
1483
|
-
if (!value) {
|
|
1484
|
-
return;
|
|
1485
|
-
}
|
|
1486
|
-
navigator.clipboard.writeText(value).then(() => {
|
|
1487
|
-
setIsCopied(true);
|
|
1488
|
-
setTimeout(() => {
|
|
1489
|
-
setIsCopied(false);
|
|
1490
|
-
}, timeout);
|
|
1491
|
-
});
|
|
1492
|
-
};
|
|
1493
|
-
return { isCopied, copyToClipboard };
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
// src/components/chat/CodeBlock.tsx
|
|
1497
|
-
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1498
|
-
var programmingLanguages = {
|
|
1499
|
-
javascript: ".js",
|
|
1500
|
-
python: ".py",
|
|
1501
|
-
java: ".java",
|
|
1502
|
-
c: ".c",
|
|
1503
|
-
cpp: ".cpp",
|
|
1504
|
-
"c++": ".cpp",
|
|
1505
|
-
"c#": ".cs",
|
|
1506
|
-
ruby: ".rb",
|
|
1507
|
-
php: ".php",
|
|
1508
|
-
swift: ".swift",
|
|
1509
|
-
"objective-c": ".m",
|
|
1510
|
-
kotlin: ".kt",
|
|
1511
|
-
typescript: ".ts",
|
|
1512
|
-
go: ".go",
|
|
1513
|
-
perl: ".pl",
|
|
1514
|
-
rust: ".rs",
|
|
1515
|
-
scala: ".scala",
|
|
1516
|
-
haskell: ".hs",
|
|
1517
|
-
lua: ".lua",
|
|
1518
|
-
shell: ".sh",
|
|
1519
|
-
sql: ".sql",
|
|
1520
|
-
html: ".html",
|
|
1521
|
-
css: ".css"
|
|
1522
|
-
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
1523
|
-
};
|
|
1524
|
-
var generateRandomString = (length, lowercase = false) => {
|
|
1525
|
-
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
1526
|
-
let result = "";
|
|
1527
|
-
for (let i = 0; i < length; i++) {
|
|
1528
|
-
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
1529
|
-
}
|
|
1530
|
-
return lowercase ? result.toLowerCase() : result;
|
|
1531
|
-
};
|
|
1532
|
-
var CodeBlock = (0, import_react10.memo)(({ language, value }) => {
|
|
1533
|
-
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
1534
|
-
const downloadAsFile = () => {
|
|
1535
|
-
if (typeof window === "undefined") {
|
|
1536
|
-
return;
|
|
1537
|
-
}
|
|
1538
|
-
const fileExtension = programmingLanguages[language] || ".file";
|
|
1539
|
-
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
1540
|
-
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
1541
|
-
if (!fileName) {
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
const blob = new Blob([value], { type: "text/plain" });
|
|
1545
|
-
const url = URL.createObjectURL(blob);
|
|
1546
|
-
const link = document.createElement("a");
|
|
1547
|
-
link.download = fileName;
|
|
1548
|
-
link.href = url;
|
|
1549
|
-
link.style.display = "none";
|
|
1550
|
-
document.body.appendChild(link);
|
|
1551
|
-
link.click();
|
|
1552
|
-
document.body.removeChild(link);
|
|
1553
|
-
URL.revokeObjectURL(url);
|
|
1554
|
-
};
|
|
1555
|
-
const onCopy = () => {
|
|
1556
|
-
if (isCopied)
|
|
1557
|
-
return;
|
|
1558
|
-
copyToClipboard(value);
|
|
1559
|
-
};
|
|
1560
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
1561
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
1562
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
1563
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
1564
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
1565
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
1566
|
-
] })
|
|
1567
|
-
] }),
|
|
1568
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1569
|
-
import_react_syntax_highlighter.Prism,
|
|
1570
|
-
{
|
|
1571
|
-
language,
|
|
1572
|
-
style: highlightStyle,
|
|
1573
|
-
PreTag: "div",
|
|
1574
|
-
customStyle: {
|
|
1575
|
-
margin: 0,
|
|
1576
|
-
borderBottomLeftRadius: "0.375rem",
|
|
1577
|
-
borderBottomRightRadius: "0.375rem"
|
|
1578
|
-
},
|
|
1579
|
-
children: value
|
|
1580
|
-
}
|
|
1581
|
-
)
|
|
1159
|
+
)
|
|
1582
1160
|
] });
|
|
1583
1161
|
});
|
|
1584
1162
|
CodeBlock.displayName = "CodeBlock";
|
|
@@ -1863,308 +1441,887 @@ var highlightStyle = {
|
|
|
1863
1441
|
boxShadow: "inset 5px 0 0 #f7d87c",
|
|
1864
1442
|
zIndex: "0"
|
|
1865
1443
|
}
|
|
1866
|
-
};
|
|
1444
|
+
};
|
|
1445
|
+
|
|
1446
|
+
// src/components/chat/Markdown.tsx
|
|
1447
|
+
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
1448
|
+
var import_remark_math = __toESM(require("remark-math"));
|
|
1449
|
+
var import_rehype_raw = __toESM(require("rehype-raw"));
|
|
1450
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1451
|
+
var defaultComponents = {
|
|
1452
|
+
a(_a) {
|
|
1453
|
+
var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
|
|
1454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { target: "_blank", rel: "noopener noreferrer", children }));
|
|
1455
|
+
},
|
|
1456
|
+
// @ts-expect-error -- inline
|
|
1457
|
+
code(_c) {
|
|
1458
|
+
var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
|
|
1459
|
+
if (Array.isArray(children) && children.length) {
|
|
1460
|
+
if (children[0] == "\u258D") {
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1462
|
+
"span",
|
|
1463
|
+
{
|
|
1464
|
+
style: {
|
|
1465
|
+
animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
|
|
1466
|
+
marginTop: "0.25rem"
|
|
1467
|
+
},
|
|
1468
|
+
children: "\u258D"
|
|
1469
|
+
}
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
1473
|
+
}
|
|
1474
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
1475
|
+
const hasLanguage = match && match[1];
|
|
1476
|
+
const content = String(children);
|
|
1477
|
+
const hasNewlines = content.includes("\n");
|
|
1478
|
+
const isInline = !hasLanguage && !hasNewlines;
|
|
1479
|
+
if (isInline) {
|
|
1480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1481
|
+
"code",
|
|
1482
|
+
__spreadProps(__spreadValues({
|
|
1483
|
+
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
1484
|
+
}, props), {
|
|
1485
|
+
children
|
|
1486
|
+
})
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1490
|
+
CodeBlock,
|
|
1491
|
+
__spreadValues({
|
|
1492
|
+
language: match && match[1] || "",
|
|
1493
|
+
value: String(children).replace(/\n$/, "")
|
|
1494
|
+
}, props),
|
|
1495
|
+
Math.random()
|
|
1496
|
+
);
|
|
1497
|
+
},
|
|
1498
|
+
h1: (_e) => {
|
|
1499
|
+
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
1500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1501
|
+
},
|
|
1502
|
+
h2: (_g) => {
|
|
1503
|
+
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
1504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1505
|
+
},
|
|
1506
|
+
h3: (_i) => {
|
|
1507
|
+
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
1508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1509
|
+
},
|
|
1510
|
+
h4: (_k) => {
|
|
1511
|
+
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
1512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1513
|
+
},
|
|
1514
|
+
h5: (_m) => {
|
|
1515
|
+
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
1516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1517
|
+
},
|
|
1518
|
+
h6: (_o) => {
|
|
1519
|
+
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
1520
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1521
|
+
},
|
|
1522
|
+
p: (_q) => {
|
|
1523
|
+
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
1524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1525
|
+
},
|
|
1526
|
+
pre: (_s) => {
|
|
1527
|
+
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
1528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1529
|
+
},
|
|
1530
|
+
blockquote: (_u) => {
|
|
1531
|
+
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
1532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1533
|
+
},
|
|
1534
|
+
ul: (_w) => {
|
|
1535
|
+
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
1536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1537
|
+
},
|
|
1538
|
+
li: (_y) => {
|
|
1539
|
+
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
1540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1543
|
+
var MemoizedReactMarkdown = (0, import_react7.memo)(
|
|
1544
|
+
import_react_markdown.default,
|
|
1545
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components
|
|
1546
|
+
);
|
|
1547
|
+
var Markdown = ({ content, components }) => {
|
|
1548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1549
|
+
MemoizedReactMarkdown,
|
|
1550
|
+
{
|
|
1551
|
+
components: __spreadValues(__spreadValues({}, defaultComponents), components),
|
|
1552
|
+
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
1553
|
+
rehypePlugins: [import_rehype_raw.default],
|
|
1554
|
+
children: content
|
|
1555
|
+
}
|
|
1556
|
+
) });
|
|
1557
|
+
};
|
|
1558
|
+
|
|
1559
|
+
// src/components/chat/messages/AssistantMessage.tsx
|
|
1560
|
+
var import_react8 = require("react");
|
|
1561
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1562
|
+
var AssistantMessage = (props) => {
|
|
1563
|
+
var _a;
|
|
1564
|
+
const { icons, labels } = useChatContext();
|
|
1565
|
+
const {
|
|
1566
|
+
message,
|
|
1567
|
+
isLoading,
|
|
1568
|
+
onRegenerate,
|
|
1569
|
+
onCopy,
|
|
1570
|
+
onThumbsUp,
|
|
1571
|
+
onThumbsDown,
|
|
1572
|
+
isCurrentMessage,
|
|
1573
|
+
markdownTagRenderers
|
|
1574
|
+
} = props;
|
|
1575
|
+
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
1576
|
+
const handleCopy = () => {
|
|
1577
|
+
const content2 = (message == null ? void 0 : message.content) || "";
|
|
1578
|
+
if (content2 && onCopy) {
|
|
1579
|
+
navigator.clipboard.writeText(content2);
|
|
1580
|
+
setCopied(true);
|
|
1581
|
+
onCopy(content2);
|
|
1582
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1583
|
+
} else if (content2) {
|
|
1584
|
+
navigator.clipboard.writeText(content2);
|
|
1585
|
+
setCopied(true);
|
|
1586
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
const handleRegenerate = () => {
|
|
1590
|
+
if (onRegenerate)
|
|
1591
|
+
onRegenerate();
|
|
1592
|
+
};
|
|
1593
|
+
const handleThumbsUp = () => {
|
|
1594
|
+
if (onThumbsUp && message)
|
|
1595
|
+
onThumbsUp(message);
|
|
1596
|
+
};
|
|
1597
|
+
const handleThumbsDown = () => {
|
|
1598
|
+
if (onThumbsDown && message)
|
|
1599
|
+
onThumbsDown(message);
|
|
1600
|
+
};
|
|
1601
|
+
const LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: icons.activityIcon });
|
|
1602
|
+
const content = (message == null ? void 0 : message.content) || "";
|
|
1603
|
+
const subComponent = (_a = message == null ? void 0 : message.generativeUI) == null ? void 0 : _a.call(message);
|
|
1604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1605
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitMessage copilotKitAssistantMessage", children: [
|
|
1606
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Markdown, { content, components: markdownTagRenderers }),
|
|
1607
|
+
content && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1608
|
+
"div",
|
|
1609
|
+
{
|
|
1610
|
+
className: `copilotKitMessageControls ${isCurrentMessage ? "currentMessage" : ""}`,
|
|
1611
|
+
children: [
|
|
1612
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1613
|
+
"button",
|
|
1614
|
+
{
|
|
1615
|
+
className: "copilotKitMessageControlButton",
|
|
1616
|
+
onClick: handleRegenerate,
|
|
1617
|
+
"aria-label": labels.regenerateResponse,
|
|
1618
|
+
title: labels.regenerateResponse,
|
|
1619
|
+
children: icons.regenerateIcon
|
|
1620
|
+
}
|
|
1621
|
+
),
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1623
|
+
"button",
|
|
1624
|
+
{
|
|
1625
|
+
className: "copilotKitMessageControlButton",
|
|
1626
|
+
onClick: handleCopy,
|
|
1627
|
+
"aria-label": labels.copyToClipboard,
|
|
1628
|
+
title: labels.copyToClipboard,
|
|
1629
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
1630
|
+
}
|
|
1631
|
+
),
|
|
1632
|
+
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1633
|
+
"button",
|
|
1634
|
+
{
|
|
1635
|
+
className: "copilotKitMessageControlButton",
|
|
1636
|
+
onClick: handleThumbsUp,
|
|
1637
|
+
"aria-label": labels.thumbsUp,
|
|
1638
|
+
title: labels.thumbsUp,
|
|
1639
|
+
children: icons.thumbsUpIcon
|
|
1640
|
+
}
|
|
1641
|
+
),
|
|
1642
|
+
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1643
|
+
"button",
|
|
1644
|
+
{
|
|
1645
|
+
className: "copilotKitMessageControlButton",
|
|
1646
|
+
onClick: handleThumbsDown,
|
|
1647
|
+
"aria-label": labels.thumbsDown,
|
|
1648
|
+
title: labels.thumbsDown,
|
|
1649
|
+
children: icons.thumbsDownIcon
|
|
1650
|
+
}
|
|
1651
|
+
)
|
|
1652
|
+
]
|
|
1653
|
+
}
|
|
1654
|
+
)
|
|
1655
|
+
] }),
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { marginBottom: "0.5rem" }, children: subComponent }),
|
|
1657
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LoadingIcon, {})
|
|
1658
|
+
] });
|
|
1659
|
+
};
|
|
1660
|
+
|
|
1661
|
+
// src/components/chat/messages/ImageRenderer.tsx
|
|
1662
|
+
var import_react9 = require("react");
|
|
1663
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1664
|
+
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
1665
|
+
const [imageError, setImageError] = (0, import_react9.useState)(false);
|
|
1666
|
+
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
1667
|
+
const altText = content || "User uploaded image";
|
|
1668
|
+
const handleImageError = () => {
|
|
1669
|
+
setImageError(true);
|
|
1670
|
+
};
|
|
1671
|
+
if (imageError) {
|
|
1672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
1673
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
1674
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1675
|
+
] });
|
|
1676
|
+
}
|
|
1677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1679
|
+
"img",
|
|
1680
|
+
{
|
|
1681
|
+
src: imageSrc,
|
|
1682
|
+
alt: altText,
|
|
1683
|
+
className: "copilotKitImageRenderingImage",
|
|
1684
|
+
onError: handleImageError
|
|
1685
|
+
}
|
|
1686
|
+
),
|
|
1687
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1688
|
+
] });
|
|
1689
|
+
};
|
|
1690
|
+
|
|
1691
|
+
// src/components/chat/messages/RenderMessage.tsx
|
|
1692
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1693
|
+
function RenderMessage(_a) {
|
|
1694
|
+
var _b = _a, {
|
|
1695
|
+
UserMessage: UserMessage2 = UserMessage,
|
|
1696
|
+
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
1697
|
+
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
1698
|
+
} = _b, props = __objRest(_b, [
|
|
1699
|
+
"UserMessage",
|
|
1700
|
+
"AssistantMessage",
|
|
1701
|
+
"ImageRenderer"
|
|
1702
|
+
]);
|
|
1703
|
+
var _a2;
|
|
1704
|
+
const {
|
|
1705
|
+
message,
|
|
1706
|
+
inProgress,
|
|
1707
|
+
index,
|
|
1708
|
+
isCurrentMessage,
|
|
1709
|
+
onRegenerate,
|
|
1710
|
+
onCopy,
|
|
1711
|
+
onThumbsUp,
|
|
1712
|
+
onThumbsDown,
|
|
1713
|
+
markdownTagRenderers
|
|
1714
|
+
} = props;
|
|
1715
|
+
switch (message.role) {
|
|
1716
|
+
case "user":
|
|
1717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1718
|
+
UserMessage2,
|
|
1719
|
+
{
|
|
1720
|
+
rawData: message,
|
|
1721
|
+
"data-message-role": "user",
|
|
1722
|
+
message,
|
|
1723
|
+
ImageRenderer: ImageRenderer2
|
|
1724
|
+
},
|
|
1725
|
+
index
|
|
1726
|
+
);
|
|
1727
|
+
case "assistant":
|
|
1728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1729
|
+
AssistantMessage2,
|
|
1730
|
+
{
|
|
1731
|
+
"data-message-role": "assistant",
|
|
1732
|
+
subComponent: (_a2 = message.generativeUI) == null ? void 0 : _a2.call(message),
|
|
1733
|
+
rawData: message,
|
|
1734
|
+
message,
|
|
1735
|
+
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
1736
|
+
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
1737
|
+
isCurrentMessage,
|
|
1738
|
+
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
1739
|
+
onCopy,
|
|
1740
|
+
onThumbsUp,
|
|
1741
|
+
onThumbsDown,
|
|
1742
|
+
markdownTagRenderers,
|
|
1743
|
+
ImageRenderer: ImageRenderer2
|
|
1744
|
+
},
|
|
1745
|
+
index
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// src/components/chat/messages/LegacyRenderMessage.tsx
|
|
1751
|
+
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
1752
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1753
|
+
var LegacyRenderMessage = ({
|
|
1754
|
+
message,
|
|
1755
|
+
inProgress,
|
|
1756
|
+
index,
|
|
1757
|
+
isCurrentMessage,
|
|
1758
|
+
actionResult,
|
|
1759
|
+
AssistantMessage: AssistantMessage2,
|
|
1760
|
+
UserMessage: UserMessage2,
|
|
1761
|
+
ImageRenderer: ImageRenderer2,
|
|
1762
|
+
onRegenerate,
|
|
1763
|
+
onCopy,
|
|
1764
|
+
onThumbsUp,
|
|
1765
|
+
onThumbsDown,
|
|
1766
|
+
markdownTagRenderers,
|
|
1767
|
+
legacyProps
|
|
1768
|
+
}) => {
|
|
1769
|
+
var _a;
|
|
1770
|
+
const {
|
|
1771
|
+
RenderTextMessage,
|
|
1772
|
+
RenderActionExecutionMessage,
|
|
1773
|
+
RenderAgentStateMessage,
|
|
1774
|
+
RenderResultMessage,
|
|
1775
|
+
RenderImageMessage
|
|
1776
|
+
} = legacyProps;
|
|
1777
|
+
const deprecatedMessage = (_a = (0, import_runtime_client_gql.aguiToGQL)(message)[0]) != null ? _a : void 0;
|
|
1778
|
+
if (deprecatedMessage.isTextMessage() && RenderTextMessage) {
|
|
1779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1780
|
+
RenderTextMessage,
|
|
1781
|
+
{
|
|
1782
|
+
message,
|
|
1783
|
+
inProgress,
|
|
1784
|
+
index,
|
|
1785
|
+
isCurrentMessage,
|
|
1786
|
+
AssistantMessage: AssistantMessage2,
|
|
1787
|
+
UserMessage: UserMessage2,
|
|
1788
|
+
onRegenerate,
|
|
1789
|
+
onCopy,
|
|
1790
|
+
onThumbsUp,
|
|
1791
|
+
onThumbsDown,
|
|
1792
|
+
markdownTagRenderers
|
|
1793
|
+
}
|
|
1794
|
+
);
|
|
1795
|
+
}
|
|
1796
|
+
if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {
|
|
1797
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1798
|
+
RenderActionExecutionMessage,
|
|
1799
|
+
{
|
|
1800
|
+
message,
|
|
1801
|
+
inProgress,
|
|
1802
|
+
index,
|
|
1803
|
+
isCurrentMessage,
|
|
1804
|
+
actionResult,
|
|
1805
|
+
AssistantMessage: AssistantMessage2,
|
|
1806
|
+
UserMessage: UserMessage2
|
|
1807
|
+
}
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {
|
|
1811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1812
|
+
RenderAgentStateMessage,
|
|
1813
|
+
{
|
|
1814
|
+
message,
|
|
1815
|
+
inProgress,
|
|
1816
|
+
index,
|
|
1817
|
+
isCurrentMessage,
|
|
1818
|
+
AssistantMessage: AssistantMessage2,
|
|
1819
|
+
UserMessage: UserMessage2
|
|
1820
|
+
}
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1823
|
+
if (deprecatedMessage.isResultMessage() && RenderResultMessage) {
|
|
1824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1825
|
+
RenderResultMessage,
|
|
1826
|
+
{
|
|
1827
|
+
message,
|
|
1828
|
+
inProgress,
|
|
1829
|
+
index,
|
|
1830
|
+
isCurrentMessage,
|
|
1831
|
+
AssistantMessage: AssistantMessage2,
|
|
1832
|
+
UserMessage: UserMessage2
|
|
1833
|
+
}
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
if (deprecatedMessage.isImageMessage() && RenderImageMessage) {
|
|
1837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1838
|
+
RenderImageMessage,
|
|
1839
|
+
{
|
|
1840
|
+
message,
|
|
1841
|
+
inProgress,
|
|
1842
|
+
index,
|
|
1843
|
+
isCurrentMessage,
|
|
1844
|
+
AssistantMessage: AssistantMessage2,
|
|
1845
|
+
UserMessage: UserMessage2
|
|
1846
|
+
}
|
|
1847
|
+
);
|
|
1848
|
+
}
|
|
1849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1850
|
+
RenderMessage,
|
|
1851
|
+
{
|
|
1852
|
+
message,
|
|
1853
|
+
inProgress,
|
|
1854
|
+
index,
|
|
1855
|
+
isCurrentMessage,
|
|
1856
|
+
AssistantMessage: AssistantMessage2,
|
|
1857
|
+
UserMessage: UserMessage2,
|
|
1858
|
+
ImageRenderer: ImageRenderer2,
|
|
1859
|
+
onRegenerate,
|
|
1860
|
+
onCopy,
|
|
1861
|
+
onThumbsUp,
|
|
1862
|
+
onThumbsDown,
|
|
1863
|
+
markdownTagRenderers
|
|
1864
|
+
}
|
|
1865
|
+
);
|
|
1866
|
+
};
|
|
1867
|
+
|
|
1868
|
+
// src/components/chat/Messages.tsx
|
|
1869
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1870
|
+
var Messages = ({
|
|
1871
|
+
inProgress,
|
|
1872
|
+
children,
|
|
1873
|
+
RenderMessage: RenderMessage2,
|
|
1874
|
+
AssistantMessage: AssistantMessage2,
|
|
1875
|
+
UserMessage: UserMessage2,
|
|
1876
|
+
ImageRenderer: ImageRenderer2,
|
|
1877
|
+
onRegenerate,
|
|
1878
|
+
onCopy,
|
|
1879
|
+
onThumbsUp,
|
|
1880
|
+
onThumbsDown,
|
|
1881
|
+
markdownTagRenderers,
|
|
1882
|
+
// Legacy props
|
|
1883
|
+
RenderTextMessage,
|
|
1884
|
+
RenderActionExecutionMessage,
|
|
1885
|
+
RenderAgentStateMessage,
|
|
1886
|
+
RenderResultMessage,
|
|
1887
|
+
RenderImageMessage
|
|
1888
|
+
}) => {
|
|
1889
|
+
const { labels } = useChatContext();
|
|
1890
|
+
const { messages: visibleMessages, interrupt } = (0, import_react_core5.useCopilotChatInternal)();
|
|
1891
|
+
const initialMessages = (0, import_react10.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
1892
|
+
const messages = [...initialMessages, ...visibleMessages];
|
|
1893
|
+
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
1894
|
+
const hasLegacyProps = !!(RenderTextMessage || RenderActionExecutionMessage || RenderAgentStateMessage || RenderResultMessage || RenderImageMessage);
|
|
1895
|
+
(0, import_react10.useEffect)(() => {
|
|
1896
|
+
if (hasLegacyProps) {
|
|
1897
|
+
console.warn(
|
|
1898
|
+
"[CopilotKit] Legacy message render props (RenderTextMessage, RenderActionExecutionMessage, etc.) are deprecated. Please use the unified 'RenderMessage' prop instead. See migration guide: https://docs.copilotkit.ai/migration/render-message"
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
}, [hasLegacyProps]);
|
|
1902
|
+
const legacyProps = (0, import_react10.useMemo)(
|
|
1903
|
+
() => ({
|
|
1904
|
+
RenderTextMessage,
|
|
1905
|
+
RenderActionExecutionMessage,
|
|
1906
|
+
RenderAgentStateMessage,
|
|
1907
|
+
RenderResultMessage,
|
|
1908
|
+
RenderImageMessage
|
|
1909
|
+
}),
|
|
1910
|
+
[
|
|
1911
|
+
RenderTextMessage,
|
|
1912
|
+
RenderActionExecutionMessage,
|
|
1913
|
+
RenderAgentStateMessage,
|
|
1914
|
+
RenderResultMessage,
|
|
1915
|
+
RenderImageMessage
|
|
1916
|
+
]
|
|
1917
|
+
);
|
|
1918
|
+
const MessageRenderer = hasLegacyProps ? (props) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LegacyRenderMessage, __spreadProps(__spreadValues({}, props), { legacyProps })) : RenderMessage2;
|
|
1919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
1921
|
+
messages.map((message, index) => {
|
|
1922
|
+
const isCurrentMessage = index === messages.length - 1;
|
|
1923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1924
|
+
MessageRenderer,
|
|
1925
|
+
{
|
|
1926
|
+
message,
|
|
1927
|
+
inProgress,
|
|
1928
|
+
index,
|
|
1929
|
+
isCurrentMessage,
|
|
1930
|
+
AssistantMessage: AssistantMessage2,
|
|
1931
|
+
UserMessage: UserMessage2,
|
|
1932
|
+
ImageRenderer: ImageRenderer2,
|
|
1933
|
+
onRegenerate,
|
|
1934
|
+
onCopy,
|
|
1935
|
+
onThumbsUp,
|
|
1936
|
+
onThumbsDown,
|
|
1937
|
+
markdownTagRenderers
|
|
1938
|
+
},
|
|
1939
|
+
index
|
|
1940
|
+
);
|
|
1941
|
+
}),
|
|
1942
|
+
interrupt
|
|
1943
|
+
] }),
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
1945
|
+
] });
|
|
1946
|
+
};
|
|
1947
|
+
function makeInitialMessages(initial) {
|
|
1948
|
+
if (!initial)
|
|
1949
|
+
return [];
|
|
1950
|
+
if (Array.isArray(initial)) {
|
|
1951
|
+
return initial.map((message) => {
|
|
1952
|
+
return {
|
|
1953
|
+
id: message,
|
|
1954
|
+
role: "assistant",
|
|
1955
|
+
content: message
|
|
1956
|
+
};
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
return [
|
|
1960
|
+
{
|
|
1961
|
+
id: initial,
|
|
1962
|
+
role: "assistant",
|
|
1963
|
+
content: initial
|
|
1964
|
+
}
|
|
1965
|
+
];
|
|
1966
|
+
}
|
|
1967
|
+
function useScrollToBottom(messages) {
|
|
1968
|
+
const messagesEndRef = (0, import_react10.useRef)(null);
|
|
1969
|
+
const messagesContainerRef = (0, import_react10.useRef)(null);
|
|
1970
|
+
const isProgrammaticScrollRef = (0, import_react10.useRef)(false);
|
|
1971
|
+
const isUserScrollUpRef = (0, import_react10.useRef)(false);
|
|
1972
|
+
const scrollToBottom = () => {
|
|
1973
|
+
if (messagesContainerRef.current && messagesEndRef.current) {
|
|
1974
|
+
isProgrammaticScrollRef.current = true;
|
|
1975
|
+
messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
|
|
1976
|
+
}
|
|
1977
|
+
};
|
|
1978
|
+
const handleScroll = () => {
|
|
1979
|
+
if (isProgrammaticScrollRef.current) {
|
|
1980
|
+
isProgrammaticScrollRef.current = false;
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
if (messagesContainerRef.current) {
|
|
1984
|
+
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
1985
|
+
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
(0, import_react10.useEffect)(() => {
|
|
1989
|
+
const container = messagesContainerRef.current;
|
|
1990
|
+
if (container) {
|
|
1991
|
+
container.addEventListener("scroll", handleScroll);
|
|
1992
|
+
}
|
|
1993
|
+
return () => {
|
|
1994
|
+
if (container) {
|
|
1995
|
+
container.removeEventListener("scroll", handleScroll);
|
|
1996
|
+
}
|
|
1997
|
+
};
|
|
1998
|
+
}, []);
|
|
1999
|
+
(0, import_react10.useEffect)(() => {
|
|
2000
|
+
const container = messagesContainerRef.current;
|
|
2001
|
+
if (!container) {
|
|
2002
|
+
return;
|
|
2003
|
+
}
|
|
2004
|
+
const mutationObserver = new MutationObserver(() => {
|
|
2005
|
+
if (!isUserScrollUpRef.current) {
|
|
2006
|
+
scrollToBottom();
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
2009
|
+
mutationObserver.observe(container, {
|
|
2010
|
+
childList: true,
|
|
2011
|
+
subtree: true,
|
|
2012
|
+
characterData: true
|
|
2013
|
+
});
|
|
2014
|
+
return () => {
|
|
2015
|
+
mutationObserver.disconnect();
|
|
2016
|
+
};
|
|
2017
|
+
}, []);
|
|
2018
|
+
(0, import_react10.useEffect)(() => {
|
|
2019
|
+
isUserScrollUpRef.current = false;
|
|
2020
|
+
scrollToBottom();
|
|
2021
|
+
}, [messages.filter((m) => m.role === "user").length]);
|
|
2022
|
+
return { messagesEndRef, messagesContainerRef };
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
// src/components/chat/Input.tsx
|
|
2026
|
+
var import_react13 = require("react");
|
|
2027
|
+
|
|
2028
|
+
// src/components/chat/Textarea.tsx
|
|
2029
|
+
var import_react11 = require("react");
|
|
2030
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2031
|
+
var AutoResizingTextarea = (0, import_react11.forwardRef)(
|
|
2032
|
+
({
|
|
2033
|
+
maxRows = 1,
|
|
2034
|
+
placeholder,
|
|
2035
|
+
value,
|
|
2036
|
+
onChange,
|
|
2037
|
+
onKeyDown,
|
|
2038
|
+
onCompositionStart,
|
|
2039
|
+
onCompositionEnd,
|
|
2040
|
+
autoFocus
|
|
2041
|
+
}, ref) => {
|
|
2042
|
+
const internalTextareaRef = (0, import_react11.useRef)(null);
|
|
2043
|
+
const [maxHeight, setMaxHeight] = (0, import_react11.useState)(0);
|
|
2044
|
+
(0, import_react11.useImperativeHandle)(ref, () => internalTextareaRef.current);
|
|
2045
|
+
(0, import_react11.useEffect)(() => {
|
|
2046
|
+
const calculateMaxHeight = () => {
|
|
2047
|
+
const textarea = internalTextareaRef.current;
|
|
2048
|
+
if (textarea) {
|
|
2049
|
+
textarea.style.height = "auto";
|
|
2050
|
+
const singleRowHeight = textarea.scrollHeight;
|
|
2051
|
+
setMaxHeight(singleRowHeight * maxRows);
|
|
2052
|
+
if (autoFocus) {
|
|
2053
|
+
textarea.focus();
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
};
|
|
2057
|
+
calculateMaxHeight();
|
|
2058
|
+
}, [maxRows]);
|
|
2059
|
+
(0, import_react11.useEffect)(() => {
|
|
2060
|
+
const textarea = internalTextareaRef.current;
|
|
2061
|
+
if (textarea) {
|
|
2062
|
+
textarea.style.height = "auto";
|
|
2063
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
2064
|
+
}
|
|
2065
|
+
}, [value, maxHeight]);
|
|
2066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2067
|
+
"textarea",
|
|
2068
|
+
{
|
|
2069
|
+
ref: internalTextareaRef,
|
|
2070
|
+
value,
|
|
2071
|
+
onChange,
|
|
2072
|
+
onKeyDown,
|
|
2073
|
+
onCompositionStart,
|
|
2074
|
+
onCompositionEnd,
|
|
2075
|
+
placeholder,
|
|
2076
|
+
style: {
|
|
2077
|
+
overflow: "auto",
|
|
2078
|
+
resize: "none",
|
|
2079
|
+
maxHeight: `${maxHeight}px`
|
|
2080
|
+
},
|
|
2081
|
+
rows: 1
|
|
2082
|
+
}
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
2085
|
+
);
|
|
2086
|
+
var Textarea_default = AutoResizingTextarea;
|
|
1867
2087
|
|
|
1868
|
-
// src/
|
|
1869
|
-
var
|
|
1870
|
-
var
|
|
1871
|
-
var
|
|
1872
|
-
var
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
2088
|
+
// src/hooks/use-push-to-talk.tsx
|
|
2089
|
+
var import_react_core6 = require("@copilotkit/react-core");
|
|
2090
|
+
var import_runtime_client_gql2 = require("@copilotkit/runtime-client-gql");
|
|
2091
|
+
var import_react12 = require("react");
|
|
2092
|
+
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
2093
|
+
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
2094
|
+
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
2095
|
+
audioContextRef.current = new window.AudioContext();
|
|
2096
|
+
yield audioContextRef.current.resume();
|
|
2097
|
+
}
|
|
2098
|
+
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
2099
|
+
mediaRecorderRef.current.start(1e3);
|
|
2100
|
+
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
2101
|
+
recordedChunks.push(event.data);
|
|
2102
|
+
};
|
|
2103
|
+
mediaRecorderRef.current.onstop = onStop;
|
|
2104
|
+
});
|
|
2105
|
+
var stopRecording = (mediaRecorderRef) => {
|
|
2106
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
2107
|
+
mediaRecorderRef.current.stop();
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
2111
|
+
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
2112
|
+
const formData = new FormData();
|
|
2113
|
+
formData.append("file", completeBlob, "recording.mp4");
|
|
2114
|
+
const response = yield fetch(transcribeAudioUrl, {
|
|
2115
|
+
method: "POST",
|
|
2116
|
+
body: formData
|
|
2117
|
+
});
|
|
2118
|
+
if (!response.ok) {
|
|
2119
|
+
throw new Error(`Error: ${response.statusText}`);
|
|
2120
|
+
}
|
|
2121
|
+
const transcription = yield response.json();
|
|
2122
|
+
return transcription.text;
|
|
2123
|
+
});
|
|
2124
|
+
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
2125
|
+
const encodedText = encodeURIComponent(text);
|
|
2126
|
+
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
2127
|
+
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
2128
|
+
const source = audioContext.createBufferSource();
|
|
2129
|
+
source.buffer = audioBuffer;
|
|
2130
|
+
source.connect(audioContext.destination);
|
|
2131
|
+
source.start(0);
|
|
2132
|
+
}).catch((error) => {
|
|
2133
|
+
console.error("Error with decoding audio data", error);
|
|
2134
|
+
});
|
|
2135
|
+
};
|
|
2136
|
+
var usePushToTalk = ({
|
|
2137
|
+
sendFunction,
|
|
2138
|
+
inProgress
|
|
2139
|
+
}) => {
|
|
2140
|
+
const [pushToTalkState, setPushToTalkState] = (0, import_react12.useState)("idle");
|
|
2141
|
+
const mediaStreamRef = (0, import_react12.useRef)(null);
|
|
2142
|
+
const audioContextRef = (0, import_react12.useRef)(null);
|
|
2143
|
+
const mediaRecorderRef = (0, import_react12.useRef)(null);
|
|
2144
|
+
const recordedChunks = (0, import_react12.useRef)([]);
|
|
2145
|
+
const generalContext = (0, import_react_core6.useCopilotContext)();
|
|
2146
|
+
const messagesContext = (0, import_react_core6.useCopilotMessagesContext)();
|
|
2147
|
+
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
2148
|
+
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react12.useState)(null);
|
|
2149
|
+
(0, import_react12.useEffect)(() => {
|
|
2150
|
+
if (pushToTalkState === "recording") {
|
|
2151
|
+
startRecording(
|
|
2152
|
+
mediaStreamRef,
|
|
2153
|
+
mediaRecorderRef,
|
|
2154
|
+
audioContextRef,
|
|
2155
|
+
recordedChunks.current,
|
|
2156
|
+
() => {
|
|
2157
|
+
setPushToTalkState("transcribing");
|
|
2158
|
+
}
|
|
2159
|
+
);
|
|
2160
|
+
} else {
|
|
2161
|
+
stopRecording(mediaRecorderRef);
|
|
2162
|
+
if (pushToTalkState === "transcribing") {
|
|
2163
|
+
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
2164
|
+
(transcription) => __async(void 0, null, function* () {
|
|
2165
|
+
recordedChunks.current = [];
|
|
2166
|
+
setPushToTalkState("idle");
|
|
2167
|
+
const message = yield sendFunction(transcription);
|
|
2168
|
+
setStartReadingFromMessageId(message.id);
|
|
2169
|
+
})
|
|
1892
2170
|
);
|
|
1893
2171
|
}
|
|
1894
|
-
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
1895
2172
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
if (
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
__spreadProps(__spreadValues({
|
|
1905
|
-
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
1906
|
-
}, props), {
|
|
1907
|
-
children
|
|
1908
|
-
})
|
|
2173
|
+
return () => {
|
|
2174
|
+
stopRecording(mediaRecorderRef);
|
|
2175
|
+
};
|
|
2176
|
+
}, [pushToTalkState]);
|
|
2177
|
+
(0, import_react12.useEffect)(() => {
|
|
2178
|
+
if (inProgress === false && startReadingFromMessageId) {
|
|
2179
|
+
const lastMessageIndex = context.messages.findIndex(
|
|
2180
|
+
(message) => message.id === startReadingFromMessageId
|
|
1909
2181
|
);
|
|
2182
|
+
const aguiMessages = (0, import_runtime_client_gql2.gqlToAGUI)(context.messages);
|
|
2183
|
+
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
2184
|
+
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
2185
|
+
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
2186
|
+
setStartReadingFromMessageId(null);
|
|
1910
2187
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
__spreadValues({
|
|
1914
|
-
language: match && match[1] || "",
|
|
1915
|
-
value: String(children).replace(/\n$/, "")
|
|
1916
|
-
}, props),
|
|
1917
|
-
Math.random()
|
|
1918
|
-
);
|
|
1919
|
-
},
|
|
1920
|
-
h1: (_e) => {
|
|
1921
|
-
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
1922
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1923
|
-
},
|
|
1924
|
-
h2: (_g) => {
|
|
1925
|
-
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
1926
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1927
|
-
},
|
|
1928
|
-
h3: (_i) => {
|
|
1929
|
-
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
1930
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1931
|
-
},
|
|
1932
|
-
h4: (_k) => {
|
|
1933
|
-
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
1934
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1935
|
-
},
|
|
1936
|
-
h5: (_m) => {
|
|
1937
|
-
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
1938
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1939
|
-
},
|
|
1940
|
-
h6: (_o) => {
|
|
1941
|
-
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
1942
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1943
|
-
},
|
|
1944
|
-
p: (_q) => {
|
|
1945
|
-
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
1946
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1947
|
-
},
|
|
1948
|
-
pre: (_s) => {
|
|
1949
|
-
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
1950
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1951
|
-
},
|
|
1952
|
-
blockquote: (_u) => {
|
|
1953
|
-
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
1954
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1955
|
-
},
|
|
1956
|
-
ul: (_w) => {
|
|
1957
|
-
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
1958
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1959
|
-
},
|
|
1960
|
-
li: (_y) => {
|
|
1961
|
-
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
1962
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1963
|
-
}
|
|
2188
|
+
}, [startReadingFromMessageId, inProgress]);
|
|
2189
|
+
return { pushToTalkState, setPushToTalkState };
|
|
1964
2190
|
};
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
1975
|
-
rehypePlugins: [import_rehype_raw.default],
|
|
1976
|
-
children: content
|
|
1977
|
-
}
|
|
1978
|
-
) });
|
|
2191
|
+
|
|
2192
|
+
// src/components/chat/Input.tsx
|
|
2193
|
+
var import_react_core7 = require("@copilotkit/react-core");
|
|
2194
|
+
|
|
2195
|
+
// src/hooks/use-dark-mode.ts
|
|
2196
|
+
var useDarkMode = () => {
|
|
2197
|
+
if (typeof window === "undefined")
|
|
2198
|
+
return false;
|
|
2199
|
+
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
1979
2200
|
};
|
|
1980
2201
|
|
|
1981
|
-
// src/components/chat/
|
|
1982
|
-
var
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
} = props;
|
|
1997
|
-
const [copied, setCopied] = (0, import_react12.useState)(false);
|
|
1998
|
-
const handleCopy = () => {
|
|
1999
|
-
const content2 = (message == null ? void 0 : message.content) || "";
|
|
2000
|
-
if (content2 && onCopy) {
|
|
2001
|
-
navigator.clipboard.writeText(content2);
|
|
2002
|
-
setCopied(true);
|
|
2003
|
-
onCopy(content2);
|
|
2004
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
2005
|
-
} else if (content2) {
|
|
2006
|
-
navigator.clipboard.writeText(content2);
|
|
2007
|
-
setCopied(true);
|
|
2008
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
2009
|
-
}
|
|
2010
|
-
};
|
|
2011
|
-
const handleRegenerate = () => {
|
|
2012
|
-
if (onRegenerate)
|
|
2013
|
-
onRegenerate();
|
|
2202
|
+
// src/components/chat/PoweredByTag.tsx
|
|
2203
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2204
|
+
function PoweredByTag({ showPoweredBy = true }) {
|
|
2205
|
+
const isDark = useDarkMode();
|
|
2206
|
+
if (!showPoweredBy) {
|
|
2207
|
+
return null;
|
|
2208
|
+
}
|
|
2209
|
+
const poweredByStyle = {
|
|
2210
|
+
visibility: "visible",
|
|
2211
|
+
display: "block",
|
|
2212
|
+
position: "static",
|
|
2213
|
+
textAlign: "center",
|
|
2214
|
+
fontSize: "12px",
|
|
2215
|
+
padding: "3px 0",
|
|
2216
|
+
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
2014
2217
|
};
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
// src/components/chat/Input.tsx
|
|
2222
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2223
|
+
var MAX_NEWLINES = 6;
|
|
2224
|
+
var Input = ({
|
|
2225
|
+
inProgress,
|
|
2226
|
+
onSend,
|
|
2227
|
+
isVisible = false,
|
|
2228
|
+
onStop,
|
|
2229
|
+
onUpload,
|
|
2230
|
+
hideStopButton = false
|
|
2231
|
+
}) => {
|
|
2232
|
+
var _a, _b;
|
|
2233
|
+
const context = useChatContext();
|
|
2234
|
+
const copilotContext = (0, import_react_core7.useCopilotContext)();
|
|
2235
|
+
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
2236
|
+
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
2237
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
|
2238
|
+
const [isComposing, setIsComposing] = (0, import_react13.useState)(false);
|
|
2239
|
+
const handleDivClick = (event) => {
|
|
2240
|
+
var _a2;
|
|
2241
|
+
const target = event.target;
|
|
2242
|
+
if (target.closest("button"))
|
|
2243
|
+
return;
|
|
2244
|
+
if (target.tagName === "TEXTAREA")
|
|
2245
|
+
return;
|
|
2246
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
2018
2247
|
};
|
|
2019
|
-
const
|
|
2020
|
-
|
|
2021
|
-
|
|
2248
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
2249
|
+
const send = () => {
|
|
2250
|
+
var _a2;
|
|
2251
|
+
if (inProgress)
|
|
2252
|
+
return;
|
|
2253
|
+
onSend(text);
|
|
2254
|
+
setText("");
|
|
2255
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
2022
2256
|
};
|
|
2023
|
-
const
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2257
|
+
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
2258
|
+
sendFunction: onSend,
|
|
2259
|
+
inProgress
|
|
2260
|
+
});
|
|
2261
|
+
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
2262
|
+
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
2263
|
+
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
2264
|
+
const canSend = (0, import_react13.useMemo)(() => {
|
|
2265
|
+
var _a2;
|
|
2266
|
+
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
2267
|
+
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
2268
|
+
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
2269
|
+
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
2270
|
+
const canStop = (0, import_react13.useMemo)(() => {
|
|
2271
|
+
return isInProgress && !hideStopButton;
|
|
2272
|
+
}, [isInProgress, hideStopButton]);
|
|
2273
|
+
const sendDisabled = !canSend && !canStop;
|
|
2274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
2276
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2277
|
+
Textarea_default,
|
|
2031
2278
|
{
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
"button",
|
|
2046
|
-
{
|
|
2047
|
-
className: "copilotKitMessageControlButton",
|
|
2048
|
-
onClick: handleCopy,
|
|
2049
|
-
"aria-label": labels.copyToClipboard,
|
|
2050
|
-
title: labels.copyToClipboard,
|
|
2051
|
-
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
2052
|
-
}
|
|
2053
|
-
),
|
|
2054
|
-
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2055
|
-
"button",
|
|
2056
|
-
{
|
|
2057
|
-
className: "copilotKitMessageControlButton",
|
|
2058
|
-
onClick: handleThumbsUp,
|
|
2059
|
-
"aria-label": labels.thumbsUp,
|
|
2060
|
-
title: labels.thumbsUp,
|
|
2061
|
-
children: icons.thumbsUpIcon
|
|
2062
|
-
}
|
|
2063
|
-
),
|
|
2064
|
-
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2065
|
-
"button",
|
|
2066
|
-
{
|
|
2067
|
-
className: "copilotKitMessageControlButton",
|
|
2068
|
-
onClick: handleThumbsDown,
|
|
2069
|
-
"aria-label": labels.thumbsDown,
|
|
2070
|
-
title: labels.thumbsDown,
|
|
2071
|
-
children: icons.thumbsDownIcon
|
|
2279
|
+
ref: textareaRef,
|
|
2280
|
+
placeholder: context.labels.placeholder,
|
|
2281
|
+
autoFocus: false,
|
|
2282
|
+
maxRows: MAX_NEWLINES,
|
|
2283
|
+
value: text,
|
|
2284
|
+
onChange: (event) => setText(event.target.value),
|
|
2285
|
+
onCompositionStart: () => setIsComposing(true),
|
|
2286
|
+
onCompositionEnd: () => setIsComposing(false),
|
|
2287
|
+
onKeyDown: (event) => {
|
|
2288
|
+
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
2289
|
+
event.preventDefault();
|
|
2290
|
+
if (canSend) {
|
|
2291
|
+
send();
|
|
2072
2292
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2075
2295
|
}
|
|
2076
|
-
)
|
|
2296
|
+
),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
2298
|
+
onUpload && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
2299
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flexGrow: 1 } }),
|
|
2300
|
+
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2301
|
+
"button",
|
|
2302
|
+
{
|
|
2303
|
+
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
2304
|
+
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
2305
|
+
children: context.icons.pushToTalkIcon
|
|
2306
|
+
}
|
|
2307
|
+
),
|
|
2308
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2309
|
+
"button",
|
|
2310
|
+
{
|
|
2311
|
+
disabled: sendDisabled,
|
|
2312
|
+
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
2313
|
+
"data-copilotkit-in-progress": inProgress,
|
|
2314
|
+
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
2315
|
+
className: "copilotKitInputControlButton",
|
|
2316
|
+
children: buttonIcon
|
|
2317
|
+
}
|
|
2318
|
+
)
|
|
2319
|
+
] })
|
|
2077
2320
|
] }),
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
2079
|
-
isLoading && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LoadingIcon, {})
|
|
2080
|
-
] });
|
|
2081
|
-
};
|
|
2082
|
-
|
|
2083
|
-
// src/components/chat/messages/ImageRenderer.tsx
|
|
2084
|
-
var import_react13 = require("react");
|
|
2085
|
-
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2086
|
-
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
2087
|
-
const [imageError, setImageError] = (0, import_react13.useState)(false);
|
|
2088
|
-
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
2089
|
-
const altText = content || "User uploaded image";
|
|
2090
|
-
const handleImageError = () => {
|
|
2091
|
-
setImageError(true);
|
|
2092
|
-
};
|
|
2093
|
-
if (imageError) {
|
|
2094
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
2095
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
2096
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
2097
|
-
] });
|
|
2098
|
-
}
|
|
2099
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
2100
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2101
|
-
"img",
|
|
2102
|
-
{
|
|
2103
|
-
src: imageSrc,
|
|
2104
|
-
alt: altText,
|
|
2105
|
-
className: "copilotKitImageRenderingImage",
|
|
2106
|
-
onError: handleImageError
|
|
2107
|
-
}
|
|
2108
|
-
),
|
|
2109
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
2321
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PoweredByTag, { showPoweredBy })
|
|
2110
2322
|
] });
|
|
2111
2323
|
};
|
|
2112
2324
|
|
|
2113
|
-
// src/components/chat/messages/RenderMessage.tsx
|
|
2114
|
-
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2115
|
-
function RenderMessage(_a) {
|
|
2116
|
-
var _b = _a, {
|
|
2117
|
-
UserMessage: UserMessage2 = UserMessage,
|
|
2118
|
-
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
2119
|
-
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
2120
|
-
} = _b, props = __objRest(_b, [
|
|
2121
|
-
"UserMessage",
|
|
2122
|
-
"AssistantMessage",
|
|
2123
|
-
"ImageRenderer"
|
|
2124
|
-
]);
|
|
2125
|
-
const {
|
|
2126
|
-
message,
|
|
2127
|
-
inProgress,
|
|
2128
|
-
index,
|
|
2129
|
-
isCurrentMessage,
|
|
2130
|
-
onRegenerate,
|
|
2131
|
-
onCopy,
|
|
2132
|
-
onThumbsUp,
|
|
2133
|
-
onThumbsDown,
|
|
2134
|
-
markdownTagRenderers
|
|
2135
|
-
} = props;
|
|
2136
|
-
switch (message.role) {
|
|
2137
|
-
case "user":
|
|
2138
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2139
|
-
UserMessage2,
|
|
2140
|
-
{
|
|
2141
|
-
"data-message-role": "user",
|
|
2142
|
-
message,
|
|
2143
|
-
ImageRenderer: ImageRenderer2
|
|
2144
|
-
},
|
|
2145
|
-
index
|
|
2146
|
-
);
|
|
2147
|
-
case "assistant":
|
|
2148
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2149
|
-
AssistantMessage2,
|
|
2150
|
-
{
|
|
2151
|
-
"data-message-role": "assistant",
|
|
2152
|
-
message,
|
|
2153
|
-
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
2154
|
-
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
2155
|
-
isCurrentMessage,
|
|
2156
|
-
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
2157
|
-
onCopy,
|
|
2158
|
-
onThumbsUp,
|
|
2159
|
-
onThumbsDown,
|
|
2160
|
-
markdownTagRenderers,
|
|
2161
|
-
ImageRenderer: ImageRenderer2
|
|
2162
|
-
},
|
|
2163
|
-
index
|
|
2164
|
-
);
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
2325
|
// src/components/chat/Chat.tsx
|
|
2169
2326
|
var import_react14 = __toESM(require("react"));
|
|
2170
2327
|
var import_react_core9 = require("@copilotkit/react-core");
|
|
@@ -2173,7 +2330,7 @@ var import_shared4 = require("@copilotkit/shared");
|
|
|
2173
2330
|
var import_react_core10 = require("@copilotkit/react-core");
|
|
2174
2331
|
|
|
2175
2332
|
// src/components/chat/ImageUploadQueue.tsx
|
|
2176
|
-
var
|
|
2333
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2177
2334
|
var ImageUploadQueue = ({
|
|
2178
2335
|
images,
|
|
2179
2336
|
onRemoveImage,
|
|
@@ -2181,7 +2338,7 @@ var ImageUploadQueue = ({
|
|
|
2181
2338
|
}) => {
|
|
2182
2339
|
if (images.length === 0)
|
|
2183
2340
|
return null;
|
|
2184
|
-
return /* @__PURE__ */ (0,
|
|
2341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2185
2342
|
"div",
|
|
2186
2343
|
{
|
|
2187
2344
|
className: `copilotKitImageUploadQueue ${className}`,
|
|
@@ -2192,7 +2349,7 @@ var ImageUploadQueue = ({
|
|
|
2192
2349
|
margin: "8px",
|
|
2193
2350
|
padding: "8px"
|
|
2194
2351
|
},
|
|
2195
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
2352
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2196
2353
|
"div",
|
|
2197
2354
|
{
|
|
2198
2355
|
className: "copilotKitImageUploadQueueItem",
|
|
@@ -2205,7 +2362,7 @@ var ImageUploadQueue = ({
|
|
|
2205
2362
|
overflow: "hidden"
|
|
2206
2363
|
},
|
|
2207
2364
|
children: [
|
|
2208
|
-
/* @__PURE__ */ (0,
|
|
2365
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2209
2366
|
"img",
|
|
2210
2367
|
{
|
|
2211
2368
|
src: `data:${image.contentType};base64,${image.bytes}`,
|
|
@@ -2217,7 +2374,7 @@ var ImageUploadQueue = ({
|
|
|
2217
2374
|
}
|
|
2218
2375
|
}
|
|
2219
2376
|
),
|
|
2220
|
-
/* @__PURE__ */ (0,
|
|
2377
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2221
2378
|
"button",
|
|
2222
2379
|
{
|
|
2223
2380
|
onClick: () => onRemoveImage(index),
|
|
@@ -2252,12 +2409,12 @@ var ImageUploadQueue = ({
|
|
|
2252
2409
|
|
|
2253
2410
|
// src/components/chat/Suggestion.tsx
|
|
2254
2411
|
var import_react_core8 = require("@copilotkit/react-core");
|
|
2255
|
-
var
|
|
2412
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2256
2413
|
function Suggestion({ title, onClick, partial, className }) {
|
|
2257
2414
|
if (!title)
|
|
2258
2415
|
return null;
|
|
2259
2416
|
const { isLoading } = (0, import_react_core8.useCopilotChatInternal)();
|
|
2260
|
-
return /* @__PURE__ */ (0,
|
|
2417
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2261
2418
|
"button",
|
|
2262
2419
|
{
|
|
2263
2420
|
disabled: partial || isLoading,
|
|
@@ -2267,15 +2424,15 @@ function Suggestion({ title, onClick, partial, className }) {
|
|
|
2267
2424
|
},
|
|
2268
2425
|
className: className || (partial ? "suggestion loading" : "suggestion"),
|
|
2269
2426
|
"data-test-id": "suggestion",
|
|
2270
|
-
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0,
|
|
2427
|
+
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: title })
|
|
2271
2428
|
}
|
|
2272
2429
|
);
|
|
2273
2430
|
}
|
|
2274
2431
|
|
|
2275
2432
|
// src/components/chat/Suggestions.tsx
|
|
2276
|
-
var
|
|
2433
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2277
2434
|
function Suggestions({ suggestions, onSuggestionClick }) {
|
|
2278
|
-
return /* @__PURE__ */ (0,
|
|
2435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "suggestions", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2279
2436
|
Suggestion,
|
|
2280
2437
|
{
|
|
2281
2438
|
title: suggestion.title,
|
|
@@ -2289,7 +2446,7 @@ function Suggestions({ suggestions, onSuggestionClick }) {
|
|
|
2289
2446
|
}
|
|
2290
2447
|
|
|
2291
2448
|
// src/components/chat/Chat.tsx
|
|
2292
|
-
var
|
|
2449
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2293
2450
|
function CopilotChat({
|
|
2294
2451
|
instructions,
|
|
2295
2452
|
suggestions = "auto",
|
|
@@ -2316,17 +2473,26 @@ function CopilotChat({
|
|
|
2316
2473
|
imageUploadsEnabled,
|
|
2317
2474
|
inputFileAccept = "image/*",
|
|
2318
2475
|
hideStopButton,
|
|
2319
|
-
observabilityHooks
|
|
2476
|
+
observabilityHooks,
|
|
2477
|
+
renderError,
|
|
2478
|
+
// Legacy props - deprecated
|
|
2479
|
+
RenderTextMessage,
|
|
2480
|
+
RenderActionExecutionMessage,
|
|
2481
|
+
RenderAgentStateMessage,
|
|
2482
|
+
RenderResultMessage,
|
|
2483
|
+
RenderImageMessage
|
|
2320
2484
|
}) {
|
|
2321
2485
|
const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } = (0, import_react_core9.useCopilotContext)();
|
|
2486
|
+
const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
|
|
2322
2487
|
const [selectedImages, setSelectedImages] = (0, import_react14.useState)([]);
|
|
2488
|
+
const [chatError, setChatError] = (0, import_react14.useState)(null);
|
|
2323
2489
|
const fileInputRef = (0, import_react14.useRef)(null);
|
|
2324
2490
|
const triggerObservabilityHook = (0, import_react14.useCallback)(
|
|
2325
2491
|
(hookName, ...args) => {
|
|
2326
|
-
if (
|
|
2492
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks[hookName])) {
|
|
2327
2493
|
observabilityHooks[hookName](...args);
|
|
2328
2494
|
}
|
|
2329
|
-
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !
|
|
2495
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !publicApiKey) {
|
|
2330
2496
|
setBannerError(
|
|
2331
2497
|
new import_shared3.CopilotKitError({
|
|
2332
2498
|
message: "observabilityHooks requires a publicApiKey to function.",
|
|
@@ -2338,7 +2504,50 @@ function CopilotChat({
|
|
|
2338
2504
|
import_shared3.styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
2339
2505
|
}
|
|
2340
2506
|
},
|
|
2341
|
-
[
|
|
2507
|
+
[publicApiKey, observabilityHooks, setBannerError]
|
|
2508
|
+
);
|
|
2509
|
+
const triggerChatError = (0, import_react14.useCallback)(
|
|
2510
|
+
(error, operation, originalError) => {
|
|
2511
|
+
const errorMessage = (error == null ? void 0 : error.message) || (error == null ? void 0 : error.toString()) || "An error occurred";
|
|
2512
|
+
setChatError({
|
|
2513
|
+
message: errorMessage,
|
|
2514
|
+
operation,
|
|
2515
|
+
timestamp: Date.now()
|
|
2516
|
+
});
|
|
2517
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks.onError)) {
|
|
2518
|
+
const errorEvent = {
|
|
2519
|
+
type: "error",
|
|
2520
|
+
timestamp: Date.now(),
|
|
2521
|
+
context: {
|
|
2522
|
+
source: "ui",
|
|
2523
|
+
request: {
|
|
2524
|
+
operation,
|
|
2525
|
+
url: chatApiEndpoint,
|
|
2526
|
+
startTime: Date.now()
|
|
2527
|
+
},
|
|
2528
|
+
technical: {
|
|
2529
|
+
environment: "browser",
|
|
2530
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
|
|
2531
|
+
stackTrace: originalError instanceof Error ? originalError.stack : void 0
|
|
2532
|
+
}
|
|
2533
|
+
},
|
|
2534
|
+
error
|
|
2535
|
+
};
|
|
2536
|
+
observabilityHooks.onError(errorEvent);
|
|
2537
|
+
}
|
|
2538
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks.onError) && !publicApiKey) {
|
|
2539
|
+
setBannerError(
|
|
2540
|
+
new import_shared3.CopilotKitError({
|
|
2541
|
+
message: "observabilityHooks.onError requires a publicApiKey to function.",
|
|
2542
|
+
code: import_shared3.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
2543
|
+
severity: import_shared3.Severity.CRITICAL,
|
|
2544
|
+
visibility: import_shared3.ErrorVisibility.BANNER
|
|
2545
|
+
})
|
|
2546
|
+
);
|
|
2547
|
+
import_shared3.styledConsole.publicApiKeyRequired("observabilityHooks.onError");
|
|
2548
|
+
}
|
|
2549
|
+
},
|
|
2550
|
+
[publicApiKey, chatApiEndpoint, observabilityHooks, setBannerError]
|
|
2342
2551
|
);
|
|
2343
2552
|
(0, import_react14.useEffect)(() => {
|
|
2344
2553
|
if (!imageUploadsEnabled)
|
|
@@ -2379,12 +2588,13 @@ function CopilotChat({
|
|
|
2379
2588
|
const loadedImages = (yield Promise.all(imagePromises)).filter((img) => img !== null);
|
|
2380
2589
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
2381
2590
|
} catch (error) {
|
|
2591
|
+
triggerChatError(error, "processClipboardImages", error);
|
|
2382
2592
|
console.error("Error processing pasted images:", error);
|
|
2383
2593
|
}
|
|
2384
2594
|
});
|
|
2385
2595
|
document.addEventListener("paste", handlePaste);
|
|
2386
2596
|
return () => document.removeEventListener("paste", handlePaste);
|
|
2387
|
-
}, [imageUploadsEnabled]);
|
|
2597
|
+
}, [imageUploadsEnabled, triggerChatError]);
|
|
2388
2598
|
(0, import_react14.useEffect)(() => {
|
|
2389
2599
|
if (!(additionalInstructions == null ? void 0 : additionalInstructions.length)) {
|
|
2390
2600
|
setChatInstructions(instructions || "");
|
|
@@ -2398,7 +2608,7 @@ function CopilotChat({
|
|
|
2398
2608
|
setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
|
|
2399
2609
|
}, [instructions, additionalInstructions]);
|
|
2400
2610
|
const {
|
|
2401
|
-
|
|
2611
|
+
messages,
|
|
2402
2612
|
isLoading,
|
|
2403
2613
|
sendMessage,
|
|
2404
2614
|
stopGeneration,
|
|
@@ -2475,6 +2685,7 @@ function CopilotChat({
|
|
|
2475
2685
|
const loadedImages = yield Promise.all(fileReadPromises);
|
|
2476
2686
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
2477
2687
|
} catch (error) {
|
|
2688
|
+
triggerChatError(error, "processUploadedImages", error);
|
|
2478
2689
|
console.error("Error reading files:", error);
|
|
2479
2690
|
}
|
|
2480
2691
|
});
|
|
@@ -2493,14 +2704,20 @@ function CopilotChat({
|
|
|
2493
2704
|
}
|
|
2494
2705
|
triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
|
|
2495
2706
|
};
|
|
2496
|
-
return /* @__PURE__ */ (0,
|
|
2497
|
-
|
|
2707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
|
|
2708
|
+
chatError && renderError && renderError(__spreadProps(__spreadValues({}, chatError), {
|
|
2709
|
+
onDismiss: () => setChatError(null),
|
|
2710
|
+
onRetry: () => {
|
|
2711
|
+
setChatError(null);
|
|
2712
|
+
}
|
|
2713
|
+
})),
|
|
2714
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2498
2715
|
Messages2,
|
|
2499
2716
|
{
|
|
2500
2717
|
AssistantMessage: AssistantMessage2,
|
|
2501
2718
|
UserMessage: UserMessage2,
|
|
2502
2719
|
RenderMessage: RenderMessage2,
|
|
2503
|
-
messages
|
|
2720
|
+
messages,
|
|
2504
2721
|
inProgress: isLoading,
|
|
2505
2722
|
onRegenerate: handleRegenerate,
|
|
2506
2723
|
onCopy: handleCopy,
|
|
@@ -2508,7 +2725,12 @@ function CopilotChat({
|
|
|
2508
2725
|
onThumbsDown: handleThumbsDown,
|
|
2509
2726
|
markdownTagRenderers,
|
|
2510
2727
|
ImageRenderer: ImageRenderer2,
|
|
2511
|
-
|
|
2728
|
+
RenderTextMessage,
|
|
2729
|
+
RenderActionExecutionMessage,
|
|
2730
|
+
RenderAgentStateMessage,
|
|
2731
|
+
RenderResultMessage,
|
|
2732
|
+
RenderImageMessage,
|
|
2733
|
+
children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2512
2734
|
RenderSuggestionsList,
|
|
2513
2735
|
{
|
|
2514
2736
|
onSuggestionClick: handleSendMessage,
|
|
@@ -2517,9 +2739,9 @@ function CopilotChat({
|
|
|
2517
2739
|
)
|
|
2518
2740
|
}
|
|
2519
2741
|
),
|
|
2520
|
-
imageUploadsEnabled && /* @__PURE__ */ (0,
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2522
|
-
/* @__PURE__ */ (0,
|
|
2742
|
+
imageUploadsEnabled && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }),
|
|
2744
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2523
2745
|
"input",
|
|
2524
2746
|
{
|
|
2525
2747
|
type: "file",
|
|
@@ -2531,7 +2753,7 @@ function CopilotChat({
|
|
|
2531
2753
|
}
|
|
2532
2754
|
)
|
|
2533
2755
|
] }),
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2756
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2535
2757
|
Input2,
|
|
2536
2758
|
{
|
|
2537
2759
|
inProgress: isLoading,
|
|
@@ -2555,16 +2777,16 @@ function WrappedCopilotChat({
|
|
|
2555
2777
|
}) {
|
|
2556
2778
|
const chatContext = import_react14.default.useContext(ChatContext);
|
|
2557
2779
|
if (!chatContext) {
|
|
2558
|
-
return /* @__PURE__ */ (0,
|
|
2559
|
-
}, children: /* @__PURE__ */ (0,
|
|
2780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
|
|
2781
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: `copilotKitChat ${className != null ? className : ""}`, children }) });
|
|
2560
2782
|
}
|
|
2561
|
-
return /* @__PURE__ */ (0,
|
|
2783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children });
|
|
2562
2784
|
}
|
|
2563
2785
|
var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => {
|
|
2564
2786
|
var _a;
|
|
2565
2787
|
const {
|
|
2566
|
-
|
|
2567
|
-
|
|
2788
|
+
messages,
|
|
2789
|
+
sendMessage,
|
|
2568
2790
|
setMessages,
|
|
2569
2791
|
reloadMessages: defaultReloadMessages,
|
|
2570
2792
|
stopGeneration: defaultStopGeneration,
|
|
@@ -2610,12 +2832,12 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2610
2832
|
if (Object.keys(generalContext.chatSuggestionConfiguration).length === 0) {
|
|
2611
2833
|
return;
|
|
2612
2834
|
}
|
|
2613
|
-
if (
|
|
2835
|
+
if (messages.length === 0 && !hasGeneratedInitialSuggestions.current) {
|
|
2614
2836
|
hasGeneratedInitialSuggestions.current = true;
|
|
2615
2837
|
generateSuggestionsWithErrorHandling("initial");
|
|
2616
2838
|
return;
|
|
2617
2839
|
}
|
|
2618
|
-
if (
|
|
2840
|
+
if (messages.length > 0 && suggestions.length === 0) {
|
|
2619
2841
|
generateSuggestionsWithErrorHandling("post-message");
|
|
2620
2842
|
return;
|
|
2621
2843
|
}
|
|
@@ -2623,7 +2845,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2623
2845
|
chatSuggestions,
|
|
2624
2846
|
isLoadingSuggestions,
|
|
2625
2847
|
suggestionsFailed,
|
|
2626
|
-
|
|
2848
|
+
messages.length,
|
|
2627
2849
|
isLoading,
|
|
2628
2850
|
suggestions.length,
|
|
2629
2851
|
Object.keys(generalContext.chatSuggestionConfiguration).join(","),
|
|
@@ -2653,7 +2875,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2653
2875
|
(0, import_react14.useEffect)(() => {
|
|
2654
2876
|
onInProgress == null ? void 0 : onInProgress(isLoading);
|
|
2655
2877
|
}, [onInProgress, isLoading]);
|
|
2656
|
-
const
|
|
2878
|
+
const safelySendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
|
|
2657
2879
|
const images = imagesToUse || [];
|
|
2658
2880
|
if (chatSuggestions === "auto" || chatSuggestions === "manual") {
|
|
2659
2881
|
setSuggestions([]);
|
|
@@ -2672,7 +2894,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2672
2894
|
console.error("Error in onSubmitMessage:", error);
|
|
2673
2895
|
}
|
|
2674
2896
|
}
|
|
2675
|
-
yield
|
|
2897
|
+
yield sendMessage(textMessage, {
|
|
2676
2898
|
followUp: images.length === 0,
|
|
2677
2899
|
clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual"
|
|
2678
2900
|
});
|
|
@@ -2690,7 +2912,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2690
2912
|
bytes: images[i].bytes
|
|
2691
2913
|
}
|
|
2692
2914
|
};
|
|
2693
|
-
yield
|
|
2915
|
+
yield sendMessage(imageMessage, { followUp: i === images.length - 1 });
|
|
2694
2916
|
if (!firstMessage) {
|
|
2695
2917
|
firstMessage = imageMessage;
|
|
2696
2918
|
}
|
|
@@ -2701,7 +2923,6 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2701
2923
|
}
|
|
2702
2924
|
return firstMessage;
|
|
2703
2925
|
});
|
|
2704
|
-
const messages = visibleMessages;
|
|
2705
2926
|
const currentAgentName = (_a = generalContext.agentSession) == null ? void 0 : _a.agentName;
|
|
2706
2927
|
const restartCurrentAgent = (hint) => __async(void 0, null, function* () {
|
|
2707
2928
|
if (generalContext.agentSession) {
|
|
@@ -2726,9 +2947,8 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2726
2947
|
generalContext.agentSession.agentName,
|
|
2727
2948
|
stableContext,
|
|
2728
2949
|
messagesContext.messages,
|
|
2729
|
-
|
|
2730
|
-
runChatCompletion
|
|
2731
|
-
hint
|
|
2950
|
+
sendMessage,
|
|
2951
|
+
runChatCompletion
|
|
2732
2952
|
);
|
|
2733
2953
|
}
|
|
2734
2954
|
});
|
|
@@ -2784,10 +3004,9 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2784
3004
|
}
|
|
2785
3005
|
return {
|
|
2786
3006
|
messages,
|
|
2787
|
-
visibleMessages,
|
|
2788
3007
|
isLoading,
|
|
2789
3008
|
suggestions,
|
|
2790
|
-
sendMessage,
|
|
3009
|
+
sendMessage: safelySendMessage,
|
|
2791
3010
|
stopGeneration,
|
|
2792
3011
|
reloadMessages,
|
|
2793
3012
|
resetSuggestions,
|
|
@@ -2798,7 +3017,8 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2798
3017
|
|
|
2799
3018
|
// src/components/chat/Modal.tsx
|
|
2800
3019
|
var import_react_core11 = require("@copilotkit/react-core");
|
|
2801
|
-
var
|
|
3020
|
+
var import_shared5 = require("@copilotkit/shared");
|
|
3021
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2802
3022
|
var CopilotModalInner = (_a) => {
|
|
2803
3023
|
var _b = _a, {
|
|
2804
3024
|
observabilityHooks,
|
|
@@ -2823,14 +3043,26 @@ var CopilotModalInner = (_a) => {
|
|
|
2823
3043
|
"Button",
|
|
2824
3044
|
"Header"
|
|
2825
3045
|
]);
|
|
2826
|
-
const { copilotApiConfig } = (0, import_react_core11.useCopilotContext)();
|
|
3046
|
+
const { copilotApiConfig, setBannerError } = (0, import_react_core11.useCopilotContext)();
|
|
3047
|
+
const { publicApiKey } = copilotApiConfig;
|
|
2827
3048
|
const triggerObservabilityHook = (0, import_react15.useCallback)(
|
|
2828
3049
|
(hookName, ...args) => {
|
|
2829
|
-
if (
|
|
3050
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks[hookName])) {
|
|
2830
3051
|
observabilityHooks[hookName](...args);
|
|
2831
3052
|
}
|
|
3053
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !publicApiKey) {
|
|
3054
|
+
setBannerError(
|
|
3055
|
+
new import_shared5.CopilotKitError({
|
|
3056
|
+
message: "observabilityHooks requires a publicApiKey to function.",
|
|
3057
|
+
code: import_shared5.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
3058
|
+
severity: import_shared5.Severity.CRITICAL,
|
|
3059
|
+
visibility: import_shared5.ErrorVisibility.BANNER
|
|
3060
|
+
})
|
|
3061
|
+
);
|
|
3062
|
+
import_shared5.styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
3063
|
+
}
|
|
2832
3064
|
},
|
|
2833
|
-
[
|
|
3065
|
+
[publicApiKey, observabilityHooks, setBannerError]
|
|
2834
3066
|
);
|
|
2835
3067
|
const { open } = useChatContext();
|
|
2836
3068
|
const prevOpen = (0, import_react15.useRef)(open);
|
|
@@ -2845,13 +3077,13 @@ var CopilotModalInner = (_a) => {
|
|
|
2845
3077
|
prevOpen.current = open;
|
|
2846
3078
|
}
|
|
2847
3079
|
}, [open, onSetOpen, triggerObservabilityHook]);
|
|
2848
|
-
const memoizedHeader = (0, import_react15.useMemo)(() => /* @__PURE__ */ (0,
|
|
3080
|
+
const memoizedHeader = (0, import_react15.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Header2, {}), [Header2]);
|
|
2849
3081
|
const memoizedChildren = (0, import_react15.useMemo)(() => children, [children]);
|
|
2850
|
-
return /* @__PURE__ */ (0,
|
|
3082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
2851
3083
|
memoizedChildren,
|
|
2852
|
-
/* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
3084
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className, children: [
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button2, {}),
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
2855
3087
|
Window2,
|
|
2856
3088
|
{
|
|
2857
3089
|
clickOutsideToClose,
|
|
@@ -2859,7 +3091,7 @@ var CopilotModalInner = (_a) => {
|
|
|
2859
3091
|
hitEscapeToClose,
|
|
2860
3092
|
children: [
|
|
2861
3093
|
memoizedHeader,
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
3094
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CopilotChat, __spreadProps(__spreadValues({}, chatProps), { observabilityHooks }))
|
|
2863
3095
|
]
|
|
2864
3096
|
}
|
|
2865
3097
|
)
|
|
@@ -2927,7 +3159,7 @@ var CopilotModal = (_a) => {
|
|
|
2927
3159
|
"observabilityHooks"
|
|
2928
3160
|
]);
|
|
2929
3161
|
const [openState, setOpenState] = import_react15.default.useState(defaultOpen);
|
|
2930
|
-
return /* @__PURE__ */ (0,
|
|
3162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ChatContextProvider, { icons, labels, open: openState, setOpen: setOpenState, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2931
3163
|
CopilotModalInner,
|
|
2932
3164
|
__spreadProps(__spreadValues({
|
|
2933
3165
|
observabilityHooks,
|
|
@@ -2961,7 +3193,7 @@ var CopilotModal = (_a) => {
|
|
|
2961
3193
|
};
|
|
2962
3194
|
|
|
2963
3195
|
// src/components/chat/Sidebar.tsx
|
|
2964
|
-
var
|
|
3196
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2965
3197
|
function CopilotSidebar(props) {
|
|
2966
3198
|
props = __spreadProps(__spreadValues({}, props), {
|
|
2967
3199
|
className: props.className ? props.className + " copilotKitSidebar" : "copilotKitSidebar"
|
|
@@ -2974,7 +3206,7 @@ function CopilotSidebar(props) {
|
|
|
2974
3206
|
(_a = props.onSetOpen) == null ? void 0 : _a.call(props, open);
|
|
2975
3207
|
setExpandedClassName(open ? "sidebarExpanded" : "");
|
|
2976
3208
|
};
|
|
2977
|
-
return /* @__PURE__ */ (0,
|
|
3209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: `copilotKitSidebarContentWrapper ${expandedClassName}`, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CopilotModal, __spreadProps(__spreadValues(__spreadValues({}, props), { onSetOpen }), { children: props.children })) });
|
|
2978
3210
|
}
|
|
2979
3211
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2980
3212
|
0 && (module.exports = {
|