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