@copilotkit/react-ui 1.10.0-next.1 → 1.10.0-next.11

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