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