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

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