@copilotkit/react-ui 0.22.0 → 0.36.0-mme-push-to-talk.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/.turbo/turbo-build.log +204 -178
  2. package/CHANGELOG.md +12 -0
  3. package/dist/chunk-5ASYNEHX.mjs +53 -0
  4. package/dist/chunk-5ASYNEHX.mjs.map +1 -0
  5. package/dist/{chunk-MBYUBR3F.mjs → chunk-A7J4KGLP.mjs} +2 -2
  6. package/dist/chunk-DMAQBCTX.mjs +95 -0
  7. package/dist/chunk-DMAQBCTX.mjs.map +1 -0
  8. package/dist/{chunk-KE3N45ZY.mjs → chunk-DRNCOXZO.mjs} +3 -4
  9. package/dist/chunk-DRNCOXZO.mjs.map +1 -0
  10. package/dist/{chunk-7YXG7D47.mjs → chunk-FWTPMPSN.mjs} +37 -2
  11. package/dist/chunk-FWTPMPSN.mjs.map +1 -0
  12. package/dist/chunk-JPX5ODUX.mjs +266 -0
  13. package/dist/chunk-JPX5ODUX.mjs.map +1 -0
  14. package/dist/chunk-KZME7C5S.mjs +76 -0
  15. package/dist/chunk-KZME7C5S.mjs.map +1 -0
  16. package/dist/{chunk-7JYUCW7H.mjs → chunk-MWFHYCQB.mjs} +2 -2
  17. package/dist/chunk-PEDSZYHE.mjs +36 -0
  18. package/dist/chunk-PEDSZYHE.mjs.map +1 -0
  19. package/dist/{chunk-YEHO5VMA.mjs → chunk-PGZDQT74.mjs} +2 -2
  20. package/dist/{chunk-MRXNTQOX.mjs → chunk-SKC7AJIV.mjs} +3 -1
  21. package/dist/chunk-T26KLXLH.mjs +1 -0
  22. package/dist/{chunk-T3WYKWNC.mjs → chunk-UVMROYDT.mjs} +5 -5
  23. package/dist/chunk-UVMROYDT.mjs.map +1 -0
  24. package/dist/{chunk-YAORLSQ3.mjs → chunk-XWWMYJJF.mjs} +5 -5
  25. package/dist/chunk-XWWMYJJF.mjs.map +1 -0
  26. package/dist/{chunk-73EBDGYK.mjs → chunk-XYM43AHP.mjs} +5 -5
  27. package/dist/chunk-XYM43AHP.mjs.map +1 -0
  28. package/dist/chunk-Z45ZEXJW.mjs +32 -0
  29. package/dist/chunk-Z45ZEXJW.mjs.map +1 -0
  30. package/dist/{chunk-WDHLWSSU.mjs → chunk-ZKLK3M77.mjs} +3 -3
  31. package/dist/components/chat/Button.d.ts +1 -1
  32. package/dist/components/chat/Button.js +30 -2
  33. package/dist/components/chat/Button.js.map +1 -1
  34. package/dist/components/chat/Button.mjs +4 -4
  35. package/dist/components/chat/Chat.d.ts +3 -2
  36. package/dist/components/chat/Chat.js +397 -86
  37. package/dist/components/chat/Chat.js.map +1 -1
  38. package/dist/components/chat/Chat.mjs +13 -11
  39. package/dist/components/chat/ChatContext.d.ts +6 -1
  40. package/dist/components/chat/ChatContext.js +29 -28
  41. package/dist/components/chat/ChatContext.js.map +1 -1
  42. package/dist/components/chat/ChatContext.mjs +3 -3
  43. package/dist/components/chat/CodeBlock.js.map +1 -1
  44. package/dist/components/chat/CodeBlock.mjs +3 -3
  45. package/dist/components/chat/Header.js.map +1 -1
  46. package/dist/components/chat/Header.mjs +4 -4
  47. package/dist/components/chat/Icons.d.ts +2 -1
  48. package/dist/components/chat/Icons.js +36 -0
  49. package/dist/components/chat/Icons.js.map +1 -1
  50. package/dist/components/chat/Icons.mjs +4 -2
  51. package/dist/components/chat/Input.d.ts +1 -1
  52. package/dist/components/chat/Input.js +1 -2
  53. package/dist/components/chat/Input.js.map +1 -1
  54. package/dist/components/chat/Input.mjs +4 -4
  55. package/dist/components/chat/Markdown.js.map +1 -1
  56. package/dist/components/chat/Markdown.mjs +4 -4
  57. package/dist/components/chat/Messages.d.ts +1 -1
  58. package/dist/components/chat/Messages.js +2 -2
  59. package/dist/components/chat/Messages.js.map +1 -1
  60. package/dist/components/chat/Messages.mjs +6 -6
  61. package/dist/components/chat/Popup.d.ts +52 -1
  62. package/dist/components/chat/Popup.js +401 -90
  63. package/dist/components/chat/Popup.js.map +1 -1
  64. package/dist/components/chat/Popup.mjs +14 -12
  65. package/dist/components/chat/Response.js.map +1 -1
  66. package/dist/components/chat/Response.mjs +4 -4
  67. package/dist/components/chat/Sidebar.d.ts +3 -5
  68. package/dist/components/chat/Sidebar.js +403 -92
  69. package/dist/components/chat/Sidebar.js.map +1 -1
  70. package/dist/components/chat/Sidebar.mjs +14 -12
  71. package/dist/components/chat/Suggestion.d.ts +14 -0
  72. package/dist/components/chat/Suggestion.js +172 -0
  73. package/dist/components/chat/Suggestion.js.map +1 -0
  74. package/dist/components/chat/Suggestion.mjs +11 -0
  75. package/dist/components/chat/Suggestion.mjs.map +1 -0
  76. package/dist/components/chat/Textarea.mjs +1 -1
  77. package/dist/components/chat/Window.mjs +1 -1
  78. package/dist/components/chat/audio.d.ts +7 -0
  79. package/dist/components/chat/audio.js +77 -0
  80. package/dist/components/chat/audio.js.map +1 -0
  81. package/dist/components/chat/audio.mjs +10 -0
  82. package/dist/components/chat/audio.mjs.map +1 -0
  83. package/dist/components/chat/index.d.ts +2 -1
  84. package/dist/components/chat/index.js +407 -96
  85. package/dist/components/chat/index.js.map +1 -1
  86. package/dist/components/chat/index.mjs +15 -13
  87. package/dist/components/chat/props.d.ts +11 -2
  88. package/dist/components/chat/props.js.map +1 -1
  89. package/dist/components/index.d.ts +2 -1
  90. package/dist/components/index.js +407 -96
  91. package/dist/components/index.js.map +1 -1
  92. package/dist/components/index.mjs +15 -13
  93. package/dist/hooks/index.d.ts +2 -2
  94. package/dist/hooks/index.js +61 -0
  95. package/dist/hooks/index.js.map +1 -1
  96. package/dist/hooks/index.mjs +28 -1
  97. package/dist/hooks/use-copilot-chat-suggestions.d.ts +65 -0
  98. package/dist/hooks/use-copilot-chat-suggestions.js +78 -0
  99. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -0
  100. package/dist/hooks/use-copilot-chat-suggestions.mjs +28 -0
  101. package/dist/hooks/use-copilot-chat-suggestions.mjs.map +1 -0
  102. package/dist/hooks/use-copy-to-clipboard.mjs +1 -1
  103. package/dist/index.css +41 -5
  104. package/dist/index.css.map +1 -1
  105. package/dist/index.d.ts +3 -1
  106. package/dist/index.js +435 -98
  107. package/dist/index.js.map +1 -1
  108. package/dist/index.mjs +23 -17
  109. package/dist/lib/utils.mjs +1 -1
  110. package/dist/types/suggestions.d.ts +28 -0
  111. package/dist/types/suggestions.js +19 -0
  112. package/dist/types/suggestions.js.map +1 -0
  113. package/dist/types/suggestions.mjs +1 -0
  114. package/dist/types/suggestions.mjs.map +1 -0
  115. package/package.json +6 -6
  116. package/src/components/chat/Button.tsx +36 -4
  117. package/src/components/chat/Chat.tsx +204 -16
  118. package/src/components/chat/ChatContext.tsx +44 -32
  119. package/src/components/chat/Icons.tsx +27 -0
  120. package/src/components/chat/Input.tsx +1 -2
  121. package/src/components/chat/Messages.tsx +3 -3
  122. package/src/components/chat/Popup.tsx +52 -6
  123. package/src/components/chat/Sidebar.tsx +59 -6
  124. package/src/components/chat/Suggestion.tsx +105 -0
  125. package/src/components/chat/audio.ts +26 -0
  126. package/src/components/chat/props.ts +11 -1
  127. package/src/css/messages.css +7 -1
  128. package/src/css/response.css +1 -4
  129. package/src/css/suggestions.css +35 -0
  130. package/src/hooks/index.ts +1 -1
  131. package/src/hooks/use-copilot-chat-suggestions.tsx +91 -0
  132. package/src/styles.css +1 -0
  133. package/src/types/suggestions.ts +30 -0
  134. package/typedoc.json +4 -0
  135. package/dist/chunk-6U3O2JZP.mjs +0 -100
  136. package/dist/chunk-6U3O2JZP.mjs.map +0 -1
  137. package/dist/chunk-73EBDGYK.mjs.map +0 -1
  138. package/dist/chunk-7LMXXGJT.mjs +0 -75
  139. package/dist/chunk-7LMXXGJT.mjs.map +0 -1
  140. package/dist/chunk-7YXG7D47.mjs.map +0 -1
  141. package/dist/chunk-H4VKQGVU.mjs +0 -1
  142. package/dist/chunk-KE3N45ZY.mjs.map +0 -1
  143. package/dist/chunk-T3WYKWNC.mjs.map +0 -1
  144. package/dist/chunk-YAORLSQ3.mjs.map +0 -1
  145. package/dist/chunk-YTIGBBTC.mjs +0 -25
  146. package/dist/chunk-YTIGBBTC.mjs.map +0 -1
  147. /package/dist/{chunk-MBYUBR3F.mjs.map → chunk-A7J4KGLP.mjs.map} +0 -0
  148. /package/dist/{chunk-7JYUCW7H.mjs.map → chunk-MWFHYCQB.mjs.map} +0 -0
  149. /package/dist/{chunk-YEHO5VMA.mjs.map → chunk-PGZDQT74.mjs.map} +0 -0
  150. /package/dist/{chunk-H4VKQGVU.mjs.map → chunk-SKC7AJIV.mjs.map} +0 -0
  151. /package/dist/{chunk-MRXNTQOX.mjs.map → chunk-T26KLXLH.mjs.map} +0 -0
  152. /package/dist/{chunk-WDHLWSSU.mjs.map → chunk-ZKLK3M77.mjs.map} +0 -0
@@ -22,6 +22,7 @@ var __spreadValues = (a, b) => {
22
22
  return a;
23
23
  };
24
24
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __restKey = (key) => typeof key === "symbol" ? key : key + "";
25
26
  var __objRest = (source, exclude) => {
26
27
  var target = {};
27
28
  for (var prop in source)
@@ -86,7 +87,7 @@ __export(chat_exports, {
86
87
  module.exports = __toCommonJS(chat_exports);
87
88
 
88
89
  // src/components/chat/Chat.tsx
89
- var import_react8 = __toESM(require("react"));
90
+ var import_react9 = __toESM(require("react"));
90
91
 
91
92
  // src/components/chat/ChatContext.tsx
92
93
  var import_react = __toESM(require("react"));
@@ -192,6 +193,40 @@ var SpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
192
193
  ]
193
194
  }
194
195
  );
196
+ var SmallSpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
197
+ "svg",
198
+ {
199
+ style: {
200
+ animation: "copilotKitSpinAnimation 1s linear infinite"
201
+ },
202
+ width: "13",
203
+ height: "13",
204
+ xmlns: "http://www.w3.org/2000/svg",
205
+ fill: "none",
206
+ viewBox: "0 0 24 24",
207
+ children: [
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
209
+ "circle",
210
+ {
211
+ style: { opacity: 0.25 },
212
+ cx: "12",
213
+ cy: "12",
214
+ r: "10",
215
+ stroke: "currentColor",
216
+ strokeWidth: "4"
217
+ }
218
+ ),
219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
220
+ "path",
221
+ {
222
+ style: { opacity: 0.75 },
223
+ fill: "currentColor",
224
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
225
+ }
226
+ )
227
+ ]
228
+ }
229
+ );
195
230
  var ActivityIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
196
231
  "svg",
197
232
  {
@@ -298,41 +333,42 @@ var ChatContextProvider = ({
298
333
  icons,
299
334
  children,
300
335
  open,
301
- setOpen
336
+ setOpen,
337
+ addChatSuggestionConfiguration,
338
+ removeChatSuggestionConfiguration
302
339
  }) => {
303
- const context = (0, import_react.useMemo)(
304
- () => ({
305
- labels: __spreadValues(__spreadValues({}, {
306
- initial: "",
307
- title: "CopilotKit",
308
- placeholder: "Type a message...",
309
- thinking: "Thinking...",
310
- error: "\u274C An error occurred. Please try again.",
311
- stopGenerating: "Stop generating",
312
- regenerateResponse: "Regenerate response"
313
- }), labels),
314
- icons: __spreadProps(__spreadValues({}, {
315
- openIcon: OpenIcon,
316
- closeIcon: CloseIcon,
317
- headerCloseIcon: HeaderCloseIcon,
318
- sendIcon: SendIcon,
319
- activityIcon: ActivityIcon,
320
- spinnerIcon: SpinnerIcon,
321
- stopIcon: StopIcon,
322
- regenerateIcon: RegenerateIcon
323
- }), {
324
- icons
325
- }),
326
- open,
327
- setOpen
340
+ const context = {
341
+ labels: __spreadValues(__spreadValues({}, {
342
+ initial: "",
343
+ title: "CopilotKit",
344
+ placeholder: "Type a message...",
345
+ thinking: "Thinking...",
346
+ error: "\u274C An error occurred. Please try again.",
347
+ stopGenerating: "Stop generating",
348
+ regenerateResponse: "Regenerate response"
349
+ }), labels),
350
+ icons: __spreadProps(__spreadValues({}, {
351
+ openIcon: OpenIcon,
352
+ closeIcon: CloseIcon,
353
+ headerCloseIcon: HeaderCloseIcon,
354
+ sendIcon: SendIcon,
355
+ activityIcon: ActivityIcon,
356
+ spinnerIcon: SpinnerIcon,
357
+ stopIcon: StopIcon,
358
+ regenerateIcon: RegenerateIcon
359
+ }), {
360
+ icons
328
361
  }),
329
- [labels, icons, open, setOpen]
330
- );
362
+ open,
363
+ setOpen,
364
+ addChatSuggestionConfiguration,
365
+ removeChatSuggestionConfiguration
366
+ };
331
367
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children });
332
368
  };
333
369
 
334
370
  // src/components/chat/Chat.tsx
335
- var import_react_core2 = require("@copilotkit/react-core");
371
+ var import_react_core3 = require("@copilotkit/react-core");
336
372
 
337
373
  // src/components/chat/Window.tsx
338
374
  var import_react2 = __toESM(require("react"));
@@ -441,10 +477,38 @@ function isMacOS() {
441
477
  }
442
478
 
443
479
  // src/components/chat/Button.tsx
480
+ var import_react3 = require("react");
444
481
  var import_jsx_runtime4 = require("react/jsx-runtime");
445
- var Button = ({ open, setOpen }) => {
482
+ var Button = ({ open, setOpen, pushToTalk, setPushToTalk }) => {
446
483
  const context = useChatContext();
447
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: () => setOpen(!open), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
484
+ const timerRef = (0, import_react3.useRef)(null);
485
+ const [isLongPress, setIsLongPress] = (0, import_react3.useState)(false);
486
+ const handleMouseDown = () => {
487
+ timerRef.current = setTimeout(() => {
488
+ setPushToTalk(true);
489
+ setIsLongPress(true);
490
+ }, 500);
491
+ };
492
+ const handleMouseUp = () => {
493
+ if (timerRef.current) {
494
+ clearTimeout(timerRef.current);
495
+ setPushToTalk(false);
496
+ }
497
+ };
498
+ const handleClick = () => {
499
+ if (!isLongPress) {
500
+ setOpen(!open);
501
+ } else {
502
+ setIsLongPress(false);
503
+ }
504
+ };
505
+ (0, import_react3.useEffect)(() => {
506
+ document.addEventListener("mouseup", handleMouseUp);
507
+ return () => {
508
+ document.removeEventListener("mouseup", handleMouseUp);
509
+ };
510
+ }, []);
511
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: handleClick, onMouseDown: handleMouseDown, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
448
512
  "button",
449
513
  {
450
514
  className: `copilotKitButton ${open ? "open" : ""}`,
@@ -468,16 +532,16 @@ var Header = ({ setOpen }) => {
468
532
  };
469
533
 
470
534
  // src/components/chat/Messages.tsx
471
- var import_react5 = __toESM(require("react"));
535
+ var import_react6 = __toESM(require("react"));
472
536
  var import_nanoid = require("nanoid");
473
537
  var import_shared = require("@copilotkit/shared");
474
538
 
475
539
  // src/components/chat/Markdown.tsx
476
- var import_react4 = require("react");
540
+ var import_react5 = require("react");
477
541
  var import_react_markdown = __toESM(require("react-markdown"));
478
542
 
479
543
  // src/components/chat/CodeBlock.tsx
480
- var import_react3 = require("react");
544
+ var import_react4 = require("react");
481
545
  var import_react_syntax_highlighter = require("react-syntax-highlighter");
482
546
 
483
547
  // src/hooks/use-copy-to-clipboard.tsx
@@ -538,7 +602,7 @@ var generateRandomString = (length, lowercase = false) => {
538
602
  }
539
603
  return lowercase ? result.toLowerCase() : result;
540
604
  };
541
- var CodeBlock = (0, import_react3.memo)(({ language, value }) => {
605
+ var CodeBlock = (0, import_react4.memo)(({ language, value }) => {
542
606
  const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
543
607
  const downloadAsFile = () => {
544
608
  if (typeof window === "undefined") {
@@ -884,7 +948,7 @@ var highlightStyle = {
884
948
  var import_remark_gfm = __toESM(require("remark-gfm"));
885
949
  var import_remark_math = __toESM(require("remark-math"));
886
950
  var import_jsx_runtime7 = require("react/jsx-runtime");
887
- var MemoizedReactMarkdown = (0, import_react4.memo)(
951
+ var MemoizedReactMarkdown = (0, import_react5.memo)(
888
952
  import_react_markdown.default,
889
953
  (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className
890
954
  );
@@ -943,10 +1007,10 @@ var components = {
943
1007
  // src/components/chat/Messages.tsx
944
1008
  var import_react_core = require("@copilotkit/react-core");
945
1009
  var import_jsx_runtime8 = require("react/jsx-runtime");
946
- var Messages = ({ messages, inProgress }) => {
1010
+ var Messages = ({ messages, inProgress, children }) => {
947
1011
  const { chatComponentsCache } = (0, import_react_core.useCopilotContext)();
948
1012
  const context = useChatContext();
949
- const initialMessages = (0, import_react5.useMemo)(
1013
+ const initialMessages = (0, import_react6.useMemo)(
950
1014
  () => makeInitialMessages(context.labels.initial),
951
1015
  [context.labels.initial]
952
1016
  );
@@ -960,7 +1024,7 @@ var Messages = ({ messages, inProgress }) => {
960
1024
  }
961
1025
  }
962
1026
  }
963
- const messagesEndRef = import_react5.default.useRef(null);
1027
+ const messagesEndRef = import_react6.default.useRef(null);
964
1028
  const scrollToBottom = () => {
965
1029
  if (messagesEndRef.current) {
966
1030
  messagesEndRef.current.scrollIntoView({
@@ -968,7 +1032,7 @@ var Messages = ({ messages, inProgress }) => {
968
1032
  });
969
1033
  }
970
1034
  };
971
- (0, import_react5.useEffect)(() => {
1035
+ (0, import_react6.useEffect)(() => {
972
1036
  scrollToBottom();
973
1037
  }, [messages]);
974
1038
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitMessages", children: [
@@ -1029,7 +1093,7 @@ var Messages = ({ messages, inProgress }) => {
1029
1093
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Markdown, { content: message.content }) }, index);
1030
1094
  }
1031
1095
  }),
1032
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: messagesEndRef })
1096
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { ref: messagesEndRef, children })
1033
1097
  ] });
1034
1098
  };
1035
1099
  function makeInitialMessages(initial) {
@@ -1049,17 +1113,17 @@ function makeInitialMessages(initial) {
1049
1113
  }
1050
1114
 
1051
1115
  // src/components/chat/Input.tsx
1052
- var import_react7 = require("react");
1116
+ var import_react8 = require("react");
1053
1117
 
1054
1118
  // src/components/chat/Textarea.tsx
1055
- var import_react6 = require("react");
1119
+ var import_react7 = require("react");
1056
1120
  var import_jsx_runtime9 = require("react/jsx-runtime");
1057
- var AutoResizingTextarea = (0, import_react6.forwardRef)(
1121
+ var AutoResizingTextarea = (0, import_react7.forwardRef)(
1058
1122
  ({ maxRows = 1, placeholder, value, onChange, onKeyDown, autoFocus }, ref) => {
1059
- const internalTextareaRef = (0, import_react6.useRef)(null);
1060
- const [maxHeight, setMaxHeight] = (0, import_react6.useState)(0);
1061
- (0, import_react6.useImperativeHandle)(ref, () => internalTextareaRef.current);
1062
- (0, import_react6.useEffect)(() => {
1123
+ const internalTextareaRef = (0, import_react7.useRef)(null);
1124
+ const [maxHeight, setMaxHeight] = (0, import_react7.useState)(0);
1125
+ (0, import_react7.useImperativeHandle)(ref, () => internalTextareaRef.current);
1126
+ (0, import_react7.useEffect)(() => {
1063
1127
  const calculateMaxHeight = () => {
1064
1128
  const textarea = internalTextareaRef.current;
1065
1129
  if (textarea) {
@@ -1073,7 +1137,7 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1073
1137
  };
1074
1138
  calculateMaxHeight();
1075
1139
  }, [maxRows]);
1076
- (0, import_react6.useEffect)(() => {
1140
+ (0, import_react7.useEffect)(() => {
1077
1141
  const textarea = internalTextareaRef.current;
1078
1142
  if (textarea) {
1079
1143
  textarea.style.height = "auto";
@@ -1102,16 +1166,16 @@ var Textarea_default = AutoResizingTextarea;
1102
1166
 
1103
1167
  // src/components/chat/Input.tsx
1104
1168
  var import_jsx_runtime10 = require("react/jsx-runtime");
1105
- var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1169
+ var Input = ({ inProgress, onSend, isVisible = false }) => {
1106
1170
  const context = useChatContext();
1107
- const textareaRef = (0, import_react7.useRef)(null);
1171
+ const textareaRef = (0, import_react8.useRef)(null);
1108
1172
  const handleDivClick = (event) => {
1109
1173
  var _a;
1110
1174
  if (event.target !== event.currentTarget)
1111
1175
  return;
1112
1176
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1113
1177
  };
1114
- const [text, setText] = (0, import_react7.useState)("");
1178
+ const [text, setText] = (0, import_react8.useState)("");
1115
1179
  const send = () => {
1116
1180
  var _a;
1117
1181
  if (inProgress)
@@ -1120,7 +1184,7 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1120
1184
  setText("");
1121
1185
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1122
1186
  };
1123
- (0, import_react7.useEffect)(() => {
1187
+ (0, import_react8.useEffect)(() => {
1124
1188
  var _a;
1125
1189
  if (isVisible) {
1126
1190
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
@@ -1129,7 +1193,6 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1129
1193
  const icon = inProgress ? context.icons.activityIcon : context.icons.sendIcon;
1130
1194
  const disabled = inProgress || text.length === 0;
1131
1195
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
1132
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children }),
1133
1196
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitSendButton", disabled, onClick: send, children: icon }),
1134
1197
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1135
1198
  Textarea_default,
@@ -1164,8 +1227,105 @@ var ResponseButton = ({ onClick, inProgress }) => {
1164
1227
  ] });
1165
1228
  };
1166
1229
 
1167
- // src/components/chat/Chat.tsx
1230
+ // src/components/chat/Suggestion.tsx
1231
+ var import_react_core2 = require("@copilotkit/react-core");
1168
1232
  var import_jsx_runtime12 = require("react/jsx-runtime");
1233
+ function Suggestion({ title, message, onClick, partial, className }) {
1234
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1235
+ "button",
1236
+ {
1237
+ disabled: partial,
1238
+ onClick: (e) => {
1239
+ e.preventDefault();
1240
+ onClick(message);
1241
+ },
1242
+ className: className || "suggestion",
1243
+ children: [
1244
+ partial && SmallSpinnerIcon,
1245
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: title })
1246
+ ]
1247
+ }
1248
+ );
1249
+ }
1250
+ var reloadSuggestions = (context, chatSuggestionConfiguration, setCurrentSuggestions, abortControllerRef) => __async(void 0, null, function* () {
1251
+ const abortController = abortControllerRef.current;
1252
+ const tools = JSON.stringify(context.getChatCompletionFunctionDescriptions(context.entryPoints));
1253
+ const allSuggestions = [];
1254
+ for (const config of Object.values(chatSuggestionConfiguration)) {
1255
+ try {
1256
+ const numOfSuggestionsInstructions = config.minSuggestions === 0 ? `Produce up to ${config.maxSuggestions} suggestions. If there are no highly relevant suggestions you can think of, provide an empty array.` : `Produce between ${config.minSuggestions} and ${config.maxSuggestions} suggestions.`;
1257
+ const result = yield (0, import_react_core2.extract)({
1258
+ context,
1259
+ instructions: "Suggest what the user could say next. Provide clear, highly relevant suggestions. Do not literally suggest function calls. " + config.instructions + "\n\n" + numOfSuggestionsInstructions,
1260
+ data: "Available tools: " + tools + "\n\n",
1261
+ parameters: [
1262
+ {
1263
+ name: "suggestions",
1264
+ type: "object[]",
1265
+ attributes: [
1266
+ {
1267
+ name: "title",
1268
+ description: "The title of the suggestion. This is shown as a button and should be short.",
1269
+ type: "string"
1270
+ },
1271
+ {
1272
+ name: "message",
1273
+ description: "The message to send when the suggestion is clicked. This should be a clear, complete sentence and will be sent as an instruction to the AI.",
1274
+ type: "string"
1275
+ }
1276
+ ]
1277
+ }
1278
+ ],
1279
+ include: {
1280
+ messages: true,
1281
+ readable: true
1282
+ },
1283
+ abortSignal: abortController == null ? void 0 : abortController.signal,
1284
+ stream: ({ status, args }) => {
1285
+ const suggestions = args.suggestions || [];
1286
+ const newSuggestions = [];
1287
+ for (let i = 0; i < suggestions.length; i++) {
1288
+ if (config.maxSuggestions !== void 0 && i >= config.maxSuggestions) {
1289
+ break;
1290
+ }
1291
+ const { title, message } = suggestions[i];
1292
+ const partial = i == suggestions.length - 1 && status !== "complete";
1293
+ newSuggestions.push({
1294
+ title,
1295
+ message,
1296
+ partial,
1297
+ className: config.className
1298
+ });
1299
+ }
1300
+ setCurrentSuggestions([...allSuggestions, ...newSuggestions]);
1301
+ }
1302
+ });
1303
+ allSuggestions.push(...result.suggestions);
1304
+ } catch (error) {
1305
+ console.error("Error loading suggestions", error);
1306
+ }
1307
+ }
1308
+ if (abortControllerRef.current === abortController) {
1309
+ abortControllerRef.current = null;
1310
+ }
1311
+ });
1312
+
1313
+ // src/components/chat/audio.ts
1314
+ var requestMicAndPlaybackPermission = () => __async(void 0, null, function* () {
1315
+ try {
1316
+ const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
1317
+ const audioContext = new window.AudioContext();
1318
+ yield audioContext.resume();
1319
+ return { stream, audioContext };
1320
+ } catch (err) {
1321
+ console.error("Error requesting microphone and playback permissions", err);
1322
+ return null;
1323
+ }
1324
+ });
1325
+
1326
+ // src/components/chat/Chat.tsx
1327
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1328
+ var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3;
1169
1329
  var CopilotChat = ({
1170
1330
  instructions,
1171
1331
  defaultOpen = false,
@@ -1188,67 +1348,218 @@ var CopilotChat = ({
1188
1348
  className,
1189
1349
  children
1190
1350
  }) => {
1191
- const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core2.useCopilotChat)({
1351
+ const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core3.useCopilotChat)({
1192
1352
  id: (0, import_nanoid2.nanoid)(),
1193
1353
  makeSystemMessage,
1194
1354
  additionalInstructions: instructions
1195
1355
  });
1196
- (0, import_react8.useEffect)(() => {
1356
+ const [currentSuggestions, setCurrentSuggestions] = import_react9.default.useState([]);
1357
+ const suggestionsAbortControllerRef = (0, import_react9.useRef)(null);
1358
+ const debounceTimerRef = (0, import_react9.useRef)();
1359
+ const abortSuggestions = () => {
1360
+ var _a;
1361
+ (_a = suggestionsAbortControllerRef.current) == null ? void 0 : _a.abort();
1362
+ suggestionsAbortControllerRef.current = null;
1363
+ };
1364
+ const context = (0, import_react_core3.useCopilotContext)();
1365
+ const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = (0, import_react9.useState)({});
1366
+ const addChatSuggestionConfiguration = (id, suggestion) => {
1367
+ setChatSuggestionConfiguration((prev) => __spreadProps(__spreadValues({}, prev), { [id]: suggestion }));
1368
+ };
1369
+ const removeChatSuggestion = (id) => {
1370
+ setChatSuggestionConfiguration((prev) => {
1371
+ const _a = prev, { [id]: _ } = _a, rest = __objRest(_a, [__restKey(id)]);
1372
+ return rest;
1373
+ });
1374
+ };
1375
+ (0, import_react9.useEffect)(() => {
1197
1376
  onInProgress == null ? void 0 : onInProgress(isLoading);
1198
- }, [isLoading]);
1199
- const [openState, setOpenState] = import_react8.default.useState(defaultOpen);
1377
+ abortSuggestions();
1378
+ debounceTimerRef.current = setTimeout(
1379
+ () => {
1380
+ if (!isLoading && Object.keys(chatSuggestionConfiguration).length !== 0) {
1381
+ suggestionsAbortControllerRef.current = new AbortController();
1382
+ reloadSuggestions(
1383
+ context,
1384
+ chatSuggestionConfiguration,
1385
+ setCurrentSuggestions,
1386
+ suggestionsAbortControllerRef
1387
+ );
1388
+ }
1389
+ },
1390
+ currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT
1391
+ );
1392
+ return () => {
1393
+ clearTimeout(debounceTimerRef.current);
1394
+ };
1395
+ }, [isLoading, chatSuggestionConfiguration]);
1200
1396
  const setOpen = (open) => {
1201
1397
  onSetOpen == null ? void 0 : onSetOpen(open);
1202
1398
  setOpenState(open);
1203
1399
  };
1204
- const sendMessage = (message) => __async(void 0, null, function* () {
1205
- onSubmitMessage == null ? void 0 : onSubmitMessage(message);
1206
- append({
1400
+ const sendMessage = (messageContent) => __async(void 0, null, function* () {
1401
+ abortSuggestions();
1402
+ setCurrentSuggestions([]);
1403
+ onSubmitMessage == null ? void 0 : onSubmitMessage(messageContent);
1404
+ const message = {
1207
1405
  id: (0, import_nanoid2.nanoid)(),
1208
- content: message,
1406
+ content: messageContent,
1209
1407
  role: "user"
1210
- });
1408
+ };
1409
+ append(message);
1410
+ return message;
1211
1411
  });
1212
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ChatContextProvider, { icons, labels, open: openState, setOpen: setOpenState, children: [
1213
- children,
1214
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className, children: [
1215
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button2, { open: openState, setOpen }),
1216
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1217
- Window2,
1218
- {
1219
- open: openState,
1220
- setOpen,
1221
- clickOutsideToClose,
1222
- shortcut,
1223
- hitEscapeToClose,
1224
- children: [
1225
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Header2, { open: openState, setOpen }),
1226
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Messages2, { messages: visibleMessages, inProgress: isLoading }),
1227
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Input2, { inProgress: isLoading, onSend: sendMessage, isVisible: openState, children: showResponseButton && visibleMessages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ResponseButton2, { onClick: isLoading ? stop : reload, inProgress: isLoading }) })
1228
- ]
1229
- }
1230
- )
1231
- ] })
1232
- ] });
1412
+ const [openState, setOpenState] = import_react9.default.useState(defaultOpen);
1413
+ const [pushToTalkState, setPushToTalkState] = import_react9.default.useState(false);
1414
+ const mediaStreamRef = (0, import_react9.useRef)(null);
1415
+ const audioContextRef = (0, import_react9.useRef)(null);
1416
+ const mediaRecorderRef = (0, import_react9.useRef)(null);
1417
+ const [lastMessageIdBeforeAudio, setLastMessageIdBeforeAudio] = (0, import_react9.useState)(null);
1418
+ (0, import_react9.useEffect)(() => {
1419
+ if (pushToTalkState) {
1420
+ console.log("HERE");
1421
+ if (!mediaStreamRef.current || !audioContextRef.current) {
1422
+ setPushToTalkState(false);
1423
+ requestMicAndPlaybackPermission().then((res) => {
1424
+ if (res) {
1425
+ mediaStreamRef.current = res.stream;
1426
+ audioContextRef.current = res.audioContext;
1427
+ }
1428
+ });
1429
+ } else {
1430
+ console.log("Recording started");
1431
+ const recordedChunks = [];
1432
+ mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
1433
+ mediaRecorderRef.current.start(1e3);
1434
+ mediaRecorderRef.current.ondataavailable = (event) => __async(void 0, null, function* () {
1435
+ console.log("Recorded audio: ", event.data);
1436
+ recordedChunks.push(event.data);
1437
+ });
1438
+ mediaRecorderRef.current.onstop = () => __async(void 0, null, function* () {
1439
+ console.log("Recording stopped");
1440
+ const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
1441
+ const formData = new FormData();
1442
+ formData.append("file", completeBlob, "recording.mp4");
1443
+ const response = yield fetch(context.copilotApiConfig.transcribeAudioUrl, {
1444
+ method: "POST",
1445
+ body: formData
1446
+ });
1447
+ if (!response.ok) {
1448
+ throw new Error(`Error: ${response.statusText}`);
1449
+ }
1450
+ const transcription = yield response.json();
1451
+ const message = yield sendMessage(transcription.text);
1452
+ setLastMessageIdBeforeAudio(message.id);
1453
+ });
1454
+ }
1455
+ } else {
1456
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1457
+ mediaRecorderRef.current.stop();
1458
+ }
1459
+ }
1460
+ return () => {
1461
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1462
+ mediaRecorderRef.current.stop();
1463
+ }
1464
+ };
1465
+ }, [pushToTalkState]);
1466
+ (0, import_react9.useEffect)(() => {
1467
+ if (lastMessageIdBeforeAudio && !isLoading) {
1468
+ if (audioContextRef.current) {
1469
+ const lastMessageIndex = context.messages.findIndex(
1470
+ (message) => message.id === lastMessageIdBeforeAudio
1471
+ );
1472
+ const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant" && message.content);
1473
+ const text = messagesAfterLast.map((message) => message.content).join("\n");
1474
+ const encodedText = encodeURIComponent(text);
1475
+ const url = `${context.copilotApiConfig.textToSpeechUrl}?text=${encodedText}`;
1476
+ fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContextRef.current.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
1477
+ const source = audioContextRef.current.createBufferSource();
1478
+ source.buffer = audioBuffer;
1479
+ source.connect(audioContextRef.current.destination);
1480
+ source.start(0);
1481
+ }).catch((error) => {
1482
+ console.error("Error with decoding audio data", error);
1483
+ });
1484
+ setLastMessageIdBeforeAudio(null);
1485
+ }
1486
+ }
1487
+ }, [isLoading]);
1488
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1489
+ ChatContextProvider,
1490
+ {
1491
+ icons,
1492
+ labels,
1493
+ open: openState,
1494
+ setOpen: setOpenState,
1495
+ addChatSuggestionConfiguration,
1496
+ removeChatSuggestionConfiguration: removeChatSuggestion,
1497
+ children: [
1498
+ children,
1499
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className, children: [
1500
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1501
+ Button2,
1502
+ {
1503
+ open: openState,
1504
+ setOpen,
1505
+ pushToTalk: pushToTalkState,
1506
+ setPushToTalk: setPushToTalkState
1507
+ }
1508
+ ),
1509
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1510
+ Window2,
1511
+ {
1512
+ open: openState,
1513
+ setOpen,
1514
+ clickOutsideToClose,
1515
+ shortcut,
1516
+ hitEscapeToClose,
1517
+ children: [
1518
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Header2, { open: openState, setOpen }),
1519
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Messages2, { messages: visibleMessages, inProgress: isLoading, children: [
1520
+ currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
1521
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h6", { children: "Suggested:" }),
1522
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1523
+ Suggestion,
1524
+ {
1525
+ title: suggestion.title,
1526
+ message: suggestion.message,
1527
+ partial: suggestion.partial,
1528
+ className: suggestion.className,
1529
+ onClick: (message) => sendMessage(message)
1530
+ },
1531
+ index
1532
+ )) })
1533
+ ] }),
1534
+ showResponseButton && visibleMessages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ResponseButton2, { onClick: isLoading ? stop : reload, inProgress: isLoading })
1535
+ ] }),
1536
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Input2, { inProgress: isLoading, onSend: sendMessage, isVisible: openState })
1537
+ ]
1538
+ }
1539
+ )
1540
+ ] })
1541
+ ]
1542
+ }
1543
+ );
1233
1544
  };
1234
1545
 
1235
1546
  // src/components/chat/Popup.tsx
1236
- var import_jsx_runtime13 = require("react/jsx-runtime");
1237
- var CopilotPopup = (props) => {
1547
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1548
+ function CopilotPopup(props) {
1238
1549
  props = __spreadProps(__spreadValues({}, props), {
1239
1550
  className: props.className ? props.className + " copilotKitPopup" : "copilotKitPopup"
1240
1551
  });
1241
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CopilotChat, __spreadProps(__spreadValues({}, props), { children: props.children }));
1242
- };
1552
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CopilotChat, __spreadProps(__spreadValues({}, props), { children: props.children }));
1553
+ }
1243
1554
 
1244
1555
  // src/components/chat/Sidebar.tsx
1245
- var import_react9 = require("react");
1246
- var import_jsx_runtime14 = require("react/jsx-runtime");
1247
- var CopilotSidebar = (props) => {
1556
+ var import_react10 = require("react");
1557
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1558
+ function CopilotSidebar(props) {
1248
1559
  props = __spreadProps(__spreadValues({}, props), {
1249
1560
  className: props.className ? props.className + " copilotKitSidebar" : "copilotKitSidebar"
1250
1561
  });
1251
- const [expandedClassName, setExpandedClassName] = (0, import_react9.useState)(
1562
+ const [expandedClassName, setExpandedClassName] = (0, import_react10.useState)(
1252
1563
  props.defaultOpen ? "sidebarExpanded" : ""
1253
1564
  );
1254
1565
  const onSetOpen = (open) => {
@@ -1256,8 +1567,8 @@ var CopilotSidebar = (props) => {
1256
1567
  (_a = props.onSetOpen) == null ? void 0 : _a.call(props, open);
1257
1568
  setExpandedClassName(open ? "sidebarExpanded" : "");
1258
1569
  };
1259
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: `copilotKitSidebarContentWrapper ${expandedClassName}`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CopilotChat, __spreadProps(__spreadValues(__spreadValues({}, props), { onSetOpen }), { children: props.children })) });
1260
- };
1570
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `copilotKitSidebarContentWrapper ${expandedClassName}`, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CopilotChat, __spreadProps(__spreadValues(__spreadValues({}, props), { onSetOpen }), { children: props.children })) });
1571
+ }
1261
1572
  // Annotate the CommonJS export names for ESM import in node:
1262
1573
  0 && (module.exports = {
1263
1574
  CopilotPopup,