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