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

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 (159) hide show
  1. package/.turbo/turbo-build.log +174 -167
  2. package/CHANGELOG.md +12 -0
  3. package/dist/{chunk-DMAQBCTX.mjs → chunk-4MKP23AD.mjs} +6 -4
  4. package/dist/chunk-4MKP23AD.mjs.map +1 -0
  5. package/dist/{chunk-UVMROYDT.mjs → chunk-6XLZXLM5.mjs} +5 -5
  6. package/dist/{chunk-UVMROYDT.mjs.map → chunk-6XLZXLM5.mjs.map} +1 -1
  7. package/dist/{chunk-XYM43AHP.mjs → chunk-7FES2IQA.mjs} +3 -3
  8. package/dist/chunk-ANO23V2M.mjs +135 -0
  9. package/dist/chunk-ANO23V2M.mjs.map +1 -0
  10. package/dist/{chunk-DRNCOXZO.mjs → chunk-BL65ZC6L.mjs} +28 -7
  11. package/dist/chunk-BL65ZC6L.mjs.map +1 -0
  12. package/dist/{chunk-PGZDQT74.mjs → chunk-CE7PJAAO.mjs} +2 -2
  13. package/dist/{chunk-FWTPMPSN.mjs → chunk-FZC7X5PK.mjs} +23 -3
  14. package/dist/{chunk-FWTPMPSN.mjs.map → chunk-FZC7X5PK.mjs.map} +1 -1
  15. package/dist/{chunk-Z45ZEXJW.mjs → chunk-LTCJCXCP.mjs} +5 -8
  16. package/dist/chunk-LTCJCXCP.mjs.map +1 -0
  17. package/dist/chunk-MRFF7GSQ.mjs +1 -0
  18. package/dist/{chunk-SKC7AJIV.mjs → chunk-MRXNTQOX.mjs} +1 -3
  19. package/dist/{chunk-MWFHYCQB.mjs → chunk-PAQWLSA4.mjs} +2 -2
  20. package/dist/chunk-RT2XG2T7.mjs +25 -0
  21. package/dist/chunk-RT2XG2T7.mjs.map +1 -0
  22. package/dist/chunk-T3JTSIHT.mjs +93 -0
  23. package/dist/chunk-T3JTSIHT.mjs.map +1 -0
  24. package/dist/{chunk-A7J4KGLP.mjs → chunk-UPTB2MVO.mjs} +2 -2
  25. package/dist/{chunk-KZME7C5S.mjs → chunk-VUZA5AFH.mjs} +8 -11
  26. package/dist/chunk-VUZA5AFH.mjs.map +1 -0
  27. package/dist/{chunk-XWWMYJJF.mjs → chunk-XRODMID5.mjs} +5 -5
  28. package/dist/{chunk-XWWMYJJF.mjs.map → chunk-XRODMID5.mjs.map} +1 -1
  29. package/dist/{chunk-ZKLK3M77.mjs → chunk-YQ3D5IQV.mjs} +3 -3
  30. package/dist/{chunk-WM6BS77F.mjs → chunk-YQFVRDNC.mjs} +2 -2
  31. package/dist/{chunk-WM6BS77F.mjs.map → chunk-YQFVRDNC.mjs.map} +1 -1
  32. package/dist/chunk-ZO3GLN23.mjs +137 -0
  33. package/dist/chunk-ZO3GLN23.mjs.map +1 -0
  34. package/dist/components/chat/Button.d.ts +1 -1
  35. package/dist/components/chat/Button.js +2 -30
  36. package/dist/components/chat/Button.js.map +1 -1
  37. package/dist/components/chat/Button.mjs +4 -4
  38. package/dist/components/chat/Chat.d.ts +66 -47
  39. package/dist/components/chat/Chat.js +274 -430
  40. package/dist/components/chat/Chat.js.map +1 -1
  41. package/dist/components/chat/Chat.mjs +16 -17
  42. package/dist/components/chat/ChatContext.d.ts +17 -22
  43. package/dist/components/chat/ChatContext.js +23 -8
  44. package/dist/components/chat/ChatContext.js.map +1 -1
  45. package/dist/components/chat/ChatContext.mjs +3 -3
  46. package/dist/components/chat/CodeBlock.js.map +1 -1
  47. package/dist/components/chat/CodeBlock.mjs +3 -3
  48. package/dist/components/chat/Header.js.map +1 -1
  49. package/dist/components/chat/Header.mjs +4 -4
  50. package/dist/components/chat/Icons.d.ts +6 -5
  51. package/dist/components/chat/Icons.js +21 -0
  52. package/dist/components/chat/Icons.js.map +1 -1
  53. package/dist/components/chat/Icons.mjs +4 -2
  54. package/dist/components/chat/Input.js +147 -9
  55. package/dist/components/chat/Input.js.map +1 -1
  56. package/dist/components/chat/Input.mjs +6 -5
  57. package/dist/components/chat/Markdown.js.map +1 -1
  58. package/dist/components/chat/Markdown.mjs +4 -4
  59. package/dist/components/chat/Messages.js.map +1 -1
  60. package/dist/components/chat/Messages.mjs +6 -6
  61. package/dist/components/chat/Modal.d.ts +50 -0
  62. package/dist/components/chat/Modal.js +1584 -0
  63. package/dist/components/chat/Modal.js.map +1 -0
  64. package/dist/components/chat/Modal.mjs +23 -0
  65. package/dist/components/chat/Popup.d.ts +6 -5
  66. package/dist/components/chat/Popup.js +288 -249
  67. package/dist/components/chat/Popup.js.map +1 -1
  68. package/dist/components/chat/Popup.mjs +16 -15
  69. package/dist/components/chat/Response.js.map +1 -1
  70. package/dist/components/chat/Response.mjs +4 -4
  71. package/dist/components/chat/Sidebar.d.ts +6 -5
  72. package/dist/components/chat/Sidebar.js +290 -251
  73. package/dist/components/chat/Sidebar.js.map +1 -1
  74. package/dist/components/chat/Sidebar.mjs +16 -15
  75. package/dist/components/chat/Suggestion.d.ts +1 -2
  76. package/dist/components/chat/Suggestion.js.map +1 -1
  77. package/dist/components/chat/Suggestion.mjs +3 -3
  78. package/dist/components/chat/Textarea.d.ts +4 -4
  79. package/dist/components/chat/Textarea.js +1 -1
  80. package/dist/components/chat/Textarea.js.map +1 -1
  81. package/dist/components/chat/Textarea.mjs +2 -2
  82. package/dist/components/chat/Window.mjs +1 -1
  83. package/dist/components/chat/index.d.ts +2 -1
  84. package/dist/components/chat/index.js +294 -253
  85. package/dist/components/chat/index.js.map +1 -1
  86. package/dist/components/chat/index.mjs +23 -19
  87. package/dist/components/chat/props.d.ts +1 -3
  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 +294 -253
  91. package/dist/components/index.js.map +1 -1
  92. package/dist/components/index.mjs +23 -19
  93. package/dist/hooks/index.d.ts +0 -1
  94. package/dist/hooks/index.js +6 -31
  95. package/dist/hooks/index.js.map +1 -1
  96. package/dist/hooks/index.mjs +2 -22
  97. package/dist/hooks/use-copilot-chat-suggestions.d.ts +26 -4
  98. package/dist/hooks/use-copilot-chat-suggestions.js +6 -31
  99. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -1
  100. package/dist/hooks/use-copilot-chat-suggestions.mjs +2 -22
  101. package/dist/hooks/use-copy-to-clipboard.mjs +1 -1
  102. package/dist/hooks/use-push-to-talk.d.ts +19 -0
  103. package/dist/hooks/use-push-to-talk.js +177 -0
  104. package/dist/hooks/use-push-to-talk.js.map +1 -0
  105. package/dist/hooks/use-push-to-talk.mjs +12 -0
  106. package/dist/hooks/use-push-to-talk.mjs.map +1 -0
  107. package/dist/index.css +60 -8
  108. package/dist/index.css.map +1 -1
  109. package/dist/index.d.ts +2 -1
  110. package/dist/index.js +300 -258
  111. package/dist/index.js.map +1 -1
  112. package/dist/index.mjs +28 -24
  113. package/dist/lib/utils.mjs +1 -1
  114. package/dist/types/suggestions.d.ts +1 -21
  115. package/dist/types/suggestions.js.map +1 -1
  116. package/package.json +6 -6
  117. package/src/components/chat/Button.tsx +2 -35
  118. package/src/components/chat/Chat.tsx +126 -255
  119. package/src/components/chat/ChatContext.tsx +8 -22
  120. package/src/components/chat/Icons.tsx +17 -0
  121. package/src/components/chat/Input.tsx +37 -5
  122. package/src/components/chat/Modal.tsx +115 -0
  123. package/src/components/chat/Popup.tsx +3 -3
  124. package/src/components/chat/Sidebar.tsx +4 -4
  125. package/src/components/chat/Suggestion.tsx +6 -2
  126. package/src/components/chat/Textarea.tsx +1 -1
  127. package/src/components/chat/index.tsx +1 -0
  128. package/src/components/chat/props.ts +1 -3
  129. package/src/css/input.css +18 -8
  130. package/src/css/panel.css +38 -0
  131. package/src/css/window.css +3 -1
  132. package/src/hooks/use-copilot-chat-suggestions.tsx +31 -5
  133. package/src/hooks/use-push-to-talk.tsx +162 -0
  134. package/src/styles.css +1 -0
  135. package/src/types/suggestions.ts +0 -24
  136. package/dist/chunk-5ASYNEHX.mjs +0 -53
  137. package/dist/chunk-5ASYNEHX.mjs.map +0 -1
  138. package/dist/chunk-DMAQBCTX.mjs.map +0 -1
  139. package/dist/chunk-DRNCOXZO.mjs.map +0 -1
  140. package/dist/chunk-JPX5ODUX.mjs +0 -266
  141. package/dist/chunk-JPX5ODUX.mjs.map +0 -1
  142. package/dist/chunk-KZME7C5S.mjs.map +0 -1
  143. package/dist/chunk-PEDSZYHE.mjs +0 -36
  144. package/dist/chunk-PEDSZYHE.mjs.map +0 -1
  145. package/dist/chunk-UGQQ4WEQ.mjs +0 -1
  146. package/dist/chunk-Z45ZEXJW.mjs.map +0 -1
  147. package/dist/components/chat/audio.d.ts +0 -7
  148. package/dist/components/chat/audio.js +0 -77
  149. package/dist/components/chat/audio.js.map +0 -1
  150. package/dist/components/chat/audio.mjs +0 -10
  151. package/src/components/chat/audio.ts +0 -26
  152. /package/dist/{chunk-XYM43AHP.mjs.map → chunk-7FES2IQA.mjs.map} +0 -0
  153. /package/dist/{chunk-PGZDQT74.mjs.map → chunk-CE7PJAAO.mjs.map} +0 -0
  154. /package/dist/{chunk-SKC7AJIV.mjs.map → chunk-MRFF7GSQ.mjs.map} +0 -0
  155. /package/dist/{chunk-UGQQ4WEQ.mjs.map → chunk-MRXNTQOX.mjs.map} +0 -0
  156. /package/dist/{chunk-MWFHYCQB.mjs.map → chunk-PAQWLSA4.mjs.map} +0 -0
  157. /package/dist/{chunk-A7J4KGLP.mjs.map → chunk-UPTB2MVO.mjs.map} +0 -0
  158. /package/dist/{chunk-ZKLK3M77.mjs.map → chunk-YQ3D5IQV.mjs.map} +0 -0
  159. /package/dist/components/chat/{audio.mjs.map → Modal.mjs.map} +0 -0
@@ -22,7 +22,6 @@ 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 + "";
26
25
  var __objRest = (source, exclude) => {
27
26
  var target = {};
28
27
  for (var prop in source)
@@ -80,10 +79,10 @@ var __async = (__this, __arguments, generator) => {
80
79
  // src/components/chat/Chat.tsx
81
80
  var Chat_exports = {};
82
81
  __export(Chat_exports, {
83
- CopilotChat: () => CopilotChat
82
+ CopilotChat: () => CopilotChat,
83
+ useCopilotChatLogic: () => useCopilotChatLogic
84
84
  });
85
85
  module.exports = __toCommonJS(Chat_exports);
86
- var import_react9 = __toESM(require("react"));
87
86
 
88
87
  // src/components/chat/ChatContext.tsx
89
88
  var import_react = __toESM(require("react"));
@@ -308,6 +307,25 @@ var RegenerateIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
308
307
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M197.67 186.37a8 8 0 0 1 0 11.29C196.58 198.73 170.82 224 128 224c-37.39 0-64.53-22.4-80-39.85V208a8 8 0 0 1-16 0v-48a8 8 0 0 1 8-8h48a8 8 0 0 1 0 16H55.44C67.76 183.35 93 208 128 208c36 0 58.14-21.46 58.36-21.68a8 8 0 0 1 11.31.05ZM216 40a8 8 0 0 0-8 8v23.85C192.53 54.4 165.39 32 128 32c-42.82 0-68.58 25.27-69.66 26.34a8 8 0 0 0 11.3 11.34C69.86 69.46 92 48 128 48c35 0 60.24 24.65 72.56 40H168a8 8 0 0 0 0 16h48a8 8 0 0 0 8-8V48a8 8 0 0 0-8-8Z" })
309
308
  }
310
309
  );
310
+ var PushToTalkIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
311
+ "svg",
312
+ {
313
+ xmlns: "http://www.w3.org/2000/svg",
314
+ fill: "none",
315
+ viewBox: "0 0 24 24",
316
+ strokeWidth: 1.5,
317
+ stroke: "currentColor",
318
+ className: "w-6 h-6",
319
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
320
+ "path",
321
+ {
322
+ strokeLinecap: "round",
323
+ strokeLinejoin: "round",
324
+ d: "M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z"
325
+ }
326
+ )
327
+ }
328
+ );
311
329
 
312
330
  // src/components/chat/ChatContext.tsx
313
331
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -329,16 +347,13 @@ var ChatContextProvider = ({
329
347
  icons,
330
348
  children,
331
349
  open,
332
- setOpen,
333
- addChatSuggestionConfiguration,
334
- removeChatSuggestionConfiguration
350
+ setOpen
335
351
  }) => {
336
352
  const context = {
337
353
  labels: __spreadValues(__spreadValues({}, {
338
354
  initial: "",
339
355
  title: "CopilotKit",
340
356
  placeholder: "Type a message...",
341
- thinking: "Thinking...",
342
357
  error: "\u274C An error occurred. Please try again.",
343
358
  stopGenerating: "Stop generating",
344
359
  regenerateResponse: "Regenerate response"
@@ -351,199 +366,34 @@ var ChatContextProvider = ({
351
366
  activityIcon: ActivityIcon,
352
367
  spinnerIcon: SpinnerIcon,
353
368
  stopIcon: StopIcon,
354
- regenerateIcon: RegenerateIcon
369
+ regenerateIcon: RegenerateIcon,
370
+ pushToTalkIcon: PushToTalkIcon
355
371
  }), {
356
372
  icons
357
373
  }),
358
374
  open,
359
- setOpen,
360
- addChatSuggestionConfiguration,
361
- removeChatSuggestionConfiguration
375
+ setOpen
362
376
  };
363
377
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children });
364
378
  };
365
379
 
366
- // src/components/chat/Chat.tsx
367
- var import_react_core3 = require("@copilotkit/react-core");
368
-
369
- // src/components/chat/Window.tsx
370
- var import_react2 = __toESM(require("react"));
371
- var import_jsx_runtime3 = require("react/jsx-runtime");
372
- var Window = ({
373
- open,
374
- setOpen,
375
- children,
376
- clickOutsideToClose,
377
- shortcut,
378
- hitEscapeToClose
379
- }) => {
380
- const windowRef = import_react2.default.useRef(null);
381
- const handleClickOutside = (0, import_react2.useCallback)(
382
- (event) => {
383
- var _a;
384
- if (!clickOutsideToClose) {
385
- return;
386
- }
387
- const parentElement = (_a = windowRef.current) == null ? void 0 : _a.parentElement;
388
- if (open && parentElement && !parentElement.contains(event.target)) {
389
- setOpen(false);
390
- }
391
- },
392
- [clickOutsideToClose, open, setOpen]
393
- );
394
- const handleKeyDown = (0, import_react2.useCallback)(
395
- (event) => {
396
- var _a;
397
- const target = event.target;
398
- const isInput = target.tagName === "INPUT" || target.tagName === "SELECT" || target.tagName === "TEXTAREA" || target.isContentEditable;
399
- const isDescendantOfWrapper = (_a = windowRef.current) == null ? void 0 : _a.contains(target);
400
- if (open && event.key === "Escape" && (!isInput || isDescendantOfWrapper) && hitEscapeToClose) {
401
- setOpen(false);
402
- } else if (event.key === shortcut && (isMacOS() && event.metaKey || !isMacOS() && event.ctrlKey) && (!isInput || isDescendantOfWrapper)) {
403
- setOpen(!open);
404
- }
405
- },
406
- [hitEscapeToClose, shortcut, open, setOpen]
407
- );
408
- const adjustForMobile = (0, import_react2.useCallback)(() => {
409
- const copilotKitWindow = windowRef.current;
410
- const vv = window.visualViewport;
411
- if (!copilotKitWindow || !vv) {
412
- return;
413
- }
414
- if (window.innerWidth < 640 && open) {
415
- copilotKitWindow.style.height = `${vv.height}px`;
416
- copilotKitWindow.style.left = `${vv.offsetLeft}px`;
417
- copilotKitWindow.style.top = `${vv.offsetTop}px`;
418
- document.body.style.position = "fixed";
419
- document.body.style.width = "100%";
420
- document.body.style.height = `${window.innerHeight}px`;
421
- document.body.style.overflow = "hidden";
422
- document.body.style.touchAction = "none";
423
- document.body.addEventListener("touchmove", preventScroll, {
424
- passive: false
425
- });
426
- } else {
427
- copilotKitWindow.style.height = "";
428
- copilotKitWindow.style.left = "";
429
- copilotKitWindow.style.top = "";
430
- document.body.style.position = "";
431
- document.body.style.height = "";
432
- document.body.style.width = "";
433
- document.body.style.overflow = "";
434
- document.body.style.top = "";
435
- document.body.style.touchAction = "";
436
- document.body.removeEventListener("touchmove", preventScroll);
437
- }
438
- }, [open]);
439
- (0, import_react2.useEffect)(() => {
440
- document.addEventListener("mousedown", handleClickOutside);
441
- document.addEventListener("keydown", handleKeyDown);
442
- if (window.visualViewport) {
443
- window.visualViewport.addEventListener("resize", adjustForMobile);
444
- adjustForMobile();
445
- }
446
- return () => {
447
- document.removeEventListener("mousedown", handleClickOutside);
448
- document.removeEventListener("keydown", handleKeyDown);
449
- if (window.visualViewport) {
450
- window.visualViewport.removeEventListener("resize", adjustForMobile);
451
- }
452
- };
453
- }, [adjustForMobile, handleClickOutside, handleKeyDown]);
454
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `copilotKitWindow${open ? " open" : ""}`, ref: windowRef, children });
455
- };
456
- var preventScroll = (event) => {
457
- let targetElement = event.target;
458
- const hasParentWithClass = (element, className) => {
459
- while (element && element !== document.body) {
460
- if (element.classList.contains(className)) {
461
- return true;
462
- }
463
- element = element.parentElement;
464
- }
465
- return false;
466
- };
467
- if (!hasParentWithClass(targetElement, "copilotKitMessages")) {
468
- event.preventDefault();
469
- }
470
- };
471
- function isMacOS() {
472
- return /Mac|iMac|Macintosh/i.test(navigator.userAgent);
473
- }
474
-
475
- // src/components/chat/Button.tsx
476
- var import_react3 = require("react");
477
- var import_jsx_runtime4 = require("react/jsx-runtime");
478
- var Button = ({ open, setOpen, pushToTalk, setPushToTalk }) => {
479
- const context = useChatContext();
480
- const timerRef = (0, import_react3.useRef)(null);
481
- const [isLongPress, setIsLongPress] = (0, import_react3.useState)(false);
482
- const handleMouseDown = () => {
483
- timerRef.current = setTimeout(() => {
484
- setPushToTalk(true);
485
- setIsLongPress(true);
486
- }, 500);
487
- };
488
- const handleMouseUp = () => {
489
- if (timerRef.current) {
490
- clearTimeout(timerRef.current);
491
- setPushToTalk(false);
492
- }
493
- };
494
- const handleClick = () => {
495
- if (!isLongPress) {
496
- setOpen(!open);
497
- } else {
498
- setIsLongPress(false);
499
- }
500
- };
501
- (0, import_react3.useEffect)(() => {
502
- document.addEventListener("mouseup", handleMouseUp);
503
- return () => {
504
- document.removeEventListener("mouseup", handleMouseUp);
505
- };
506
- }, []);
507
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: handleClick, onMouseDown: handleMouseDown, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
508
- "button",
509
- {
510
- className: `copilotKitButton ${open ? "open" : ""}`,
511
- "aria-label": open ? "Close Chat" : "Open Chat",
512
- children: [
513
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "copilotKitButtonIcon copilotKitButtonIconOpen", children: context.icons.openIcon }),
514
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "copilotKitButtonIcon copilotKitButtonIconClose", children: context.icons.closeIcon })
515
- ]
516
- }
517
- ) });
518
- };
519
-
520
- // src/components/chat/Header.tsx
521
- var import_jsx_runtime5 = require("react/jsx-runtime");
522
- var Header = ({ setOpen }) => {
523
- const context = useChatContext();
524
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitHeader", children: [
525
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: context.labels.title }),
526
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => setOpen(false), "aria-label": "Close", children: context.icons.headerCloseIcon })
527
- ] });
528
- };
529
-
530
380
  // src/components/chat/Messages.tsx
531
- var import_react6 = __toESM(require("react"));
381
+ var import_react4 = __toESM(require("react"));
532
382
  var import_nanoid = require("nanoid");
533
383
  var import_shared = require("@copilotkit/shared");
534
384
 
535
385
  // src/components/chat/Markdown.tsx
536
- var import_react5 = require("react");
386
+ var import_react3 = require("react");
537
387
  var import_react_markdown = __toESM(require("react-markdown"));
538
388
 
539
389
  // src/components/chat/CodeBlock.tsx
540
- var import_react4 = require("react");
390
+ var import_react2 = require("react");
541
391
  var import_react_syntax_highlighter = require("react-syntax-highlighter");
542
392
 
543
393
  // src/hooks/use-copy-to-clipboard.tsx
544
- var React3 = __toESM(require("react"));
394
+ var React2 = __toESM(require("react"));
545
395
  function useCopyToClipboard({ timeout = 2e3 }) {
546
- const [isCopied, setIsCopied] = React3.useState(false);
396
+ const [isCopied, setIsCopied] = React2.useState(false);
547
397
  const copyToClipboard = (value) => {
548
398
  var _a;
549
399
  if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
@@ -563,7 +413,7 @@ function useCopyToClipboard({ timeout = 2e3 }) {
563
413
  }
564
414
 
565
415
  // src/components/chat/CodeBlock.tsx
566
- var import_jsx_runtime6 = require("react/jsx-runtime");
416
+ var import_jsx_runtime3 = require("react/jsx-runtime");
567
417
  var programmingLanguages = {
568
418
  javascript: ".js",
569
419
  python: ".py",
@@ -598,7 +448,7 @@ var generateRandomString = (length, lowercase = false) => {
598
448
  }
599
449
  return lowercase ? result.toLowerCase() : result;
600
450
  };
601
- var CodeBlock = (0, import_react4.memo)(({ language, value }) => {
451
+ var CodeBlock = (0, import_react2.memo)(({ language, value }) => {
602
452
  const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
603
453
  const downloadAsFile = () => {
604
454
  if (typeof window === "undefined") {
@@ -626,21 +476,21 @@ var CodeBlock = (0, import_react4.memo)(({ language, value }) => {
626
476
  return;
627
477
  copyToClipboard(value);
628
478
  };
629
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlock", children: [
630
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
631
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
632
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
633
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: [
634
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DownloadIcon, {}),
635
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Download" })
479
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitCodeBlock", children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
482
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
483
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: [
484
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DownloadIcon, {}),
485
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "sr-only", children: "Download" })
636
486
  ] }),
637
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: [
638
- isCopied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyIcon, {}),
639
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Copy code" })
487
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: [
488
+ isCopied ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CopyIcon, {}),
489
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "sr-only", children: "Copy code" })
640
490
  ] })
641
491
  ] })
642
492
  ] }),
643
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
493
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
644
494
  import_react_syntax_highlighter.Prism,
645
495
  {
646
496
  language,
@@ -943,21 +793,21 @@ var highlightStyle = {
943
793
  // src/components/chat/Markdown.tsx
944
794
  var import_remark_gfm = __toESM(require("remark-gfm"));
945
795
  var import_remark_math = __toESM(require("remark-math"));
946
- var import_jsx_runtime7 = require("react/jsx-runtime");
947
- var MemoizedReactMarkdown = (0, import_react5.memo)(
796
+ var import_jsx_runtime4 = require("react/jsx-runtime");
797
+ var MemoizedReactMarkdown = (0, import_react3.memo)(
948
798
  import_react_markdown.default,
949
799
  (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className
950
800
  );
951
801
  var Markdown = ({ content }) => {
952
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MemoizedReactMarkdown, { components, remarkPlugins: [import_remark_gfm.default, import_remark_math.default], children: content }) });
802
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MemoizedReactMarkdown, { components, remarkPlugins: [import_remark_gfm.default, import_remark_math.default], children: content }) });
953
803
  };
954
804
  var components = {
955
805
  p({ children }) {
956
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children });
806
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children });
957
807
  },
958
808
  a(_a) {
959
809
  var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
960
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
810
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
961
811
  "a",
962
812
  __spreadProps(__spreadValues({
963
813
  style: { color: "blue", textDecoration: "underline" }
@@ -972,7 +822,7 @@ var components = {
972
822
  var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
973
823
  if (children.length) {
974
824
  if (children[0] == "\u258D") {
975
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
825
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
976
826
  "span",
977
827
  {
978
828
  style: {
@@ -987,9 +837,9 @@ var components = {
987
837
  }
988
838
  const match = /language-(\w+)/.exec(className || "");
989
839
  if (inline) {
990
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", __spreadProps(__spreadValues({ className }, props), { children }));
840
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("code", __spreadProps(__spreadValues({ className }, props), { children }));
991
841
  }
992
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
842
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
993
843
  CodeBlock,
994
844
  __spreadValues({
995
845
  language: match && match[1] || "",
@@ -1002,11 +852,11 @@ var components = {
1002
852
 
1003
853
  // src/components/chat/Messages.tsx
1004
854
  var import_react_core = require("@copilotkit/react-core");
1005
- var import_jsx_runtime8 = require("react/jsx-runtime");
855
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1006
856
  var Messages = ({ messages, inProgress, children }) => {
1007
857
  const { chatComponentsCache } = (0, import_react_core.useCopilotContext)();
1008
858
  const context = useChatContext();
1009
- const initialMessages = (0, import_react6.useMemo)(
859
+ const initialMessages = (0, import_react4.useMemo)(
1010
860
  () => makeInitialMessages(context.labels.initial),
1011
861
  [context.labels.initial]
1012
862
  );
@@ -1020,7 +870,7 @@ var Messages = ({ messages, inProgress, children }) => {
1020
870
  }
1021
871
  }
1022
872
  }
1023
- const messagesEndRef = import_react6.default.useRef(null);
873
+ const messagesEndRef = import_react4.default.useRef(null);
1024
874
  const scrollToBottom = () => {
1025
875
  if (messagesEndRef.current) {
1026
876
  messagesEndRef.current.scrollIntoView({
@@ -1028,28 +878,28 @@ var Messages = ({ messages, inProgress, children }) => {
1028
878
  });
1029
879
  }
1030
880
  };
1031
- (0, import_react6.useEffect)(() => {
881
+ (0, import_react4.useEffect)(() => {
1032
882
  scrollToBottom();
1033
883
  }, [messages]);
1034
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitMessages", children: [
884
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitMessages", children: [
1035
885
  messages.map((message, index) => {
1036
886
  var _a, _b, _c;
1037
887
  const isCurrentMessage = index === messages.length - 1;
1038
888
  if (message.role === "user") {
1039
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message.content }, index);
889
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message.content }, index);
1040
890
  } else if (message.role == "assistant") {
1041
891
  if (isCurrentMessage && inProgress && !message.content && !message.partialFunctionCall) {
1042
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: context.icons.spinnerIcon }, index);
892
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: context.icons.spinnerIcon }, index);
1043
893
  } else if (message.function_call || message.partialFunctionCall) {
1044
894
  const functionCallName = ((_a = message.function_call) == null ? void 0 : _a.name) || ((_b = message.partialFunctionCall) == null ? void 0 : _b.name);
1045
895
  if (chatComponentsCache.current !== null && chatComponentsCache.current[functionCallName]) {
1046
896
  const render = chatComponentsCache.current[functionCallName];
1047
897
  if (typeof render === "string") {
1048
898
  if (isCurrentMessage && inProgress) {
1049
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: [
899
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: [
1050
900
  context.icons.spinnerIcon,
1051
901
  " ",
1052
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inProgressLabel", children: render })
902
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "inProgressLabel", children: render })
1053
903
  ] }, index);
1054
904
  } else {
1055
905
  return null;
@@ -1071,25 +921,25 @@ var Messages = ({ messages, inProgress, children }) => {
1071
921
  return null;
1072
922
  }
1073
923
  if (typeof toRender === "string") {
1074
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: [
924
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: [
1075
925
  isCurrentMessage && inProgress && context.icons.spinnerIcon,
1076
926
  " ",
1077
927
  toRender
1078
928
  ] }, index);
1079
929
  } else {
1080
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "copilotKitCustomAssistantMessage", children: toRender }, index);
930
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "copilotKitCustomAssistantMessage", children: toRender }, index);
1081
931
  }
1082
932
  }
1083
933
  } else if ((!inProgress || !isCurrentMessage) && message.function_call) {
1084
934
  return null;
1085
935
  } else {
1086
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: context.icons.spinnerIcon }, index);
936
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: context.icons.spinnerIcon }, index);
1087
937
  }
1088
938
  }
1089
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Markdown, { content: message.content }) }, index);
939
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Markdown, { content: message.content }) }, index);
1090
940
  }
1091
941
  }),
1092
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { ref: messagesEndRef, children })
942
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("footer", { ref: messagesEndRef, children })
1093
943
  ] });
1094
944
  };
1095
945
  function makeInitialMessages(initial) {
@@ -1109,17 +959,17 @@ function makeInitialMessages(initial) {
1109
959
  }
1110
960
 
1111
961
  // src/components/chat/Input.tsx
1112
- var import_react8 = require("react");
962
+ var import_react7 = require("react");
1113
963
 
1114
964
  // src/components/chat/Textarea.tsx
1115
- var import_react7 = require("react");
1116
- var import_jsx_runtime9 = require("react/jsx-runtime");
1117
- var AutoResizingTextarea = (0, import_react7.forwardRef)(
965
+ var import_react5 = require("react");
966
+ var import_jsx_runtime6 = require("react/jsx-runtime");
967
+ var AutoResizingTextarea = (0, import_react5.forwardRef)(
1118
968
  ({ maxRows = 1, placeholder, value, onChange, onKeyDown, autoFocus }, ref) => {
1119
- const internalTextareaRef = (0, import_react7.useRef)(null);
1120
- const [maxHeight, setMaxHeight] = (0, import_react7.useState)(0);
1121
- (0, import_react7.useImperativeHandle)(ref, () => internalTextareaRef.current);
1122
- (0, import_react7.useEffect)(() => {
969
+ const internalTextareaRef = (0, import_react5.useRef)(null);
970
+ const [maxHeight, setMaxHeight] = (0, import_react5.useState)(0);
971
+ (0, import_react5.useImperativeHandle)(ref, () => internalTextareaRef.current);
972
+ (0, import_react5.useEffect)(() => {
1123
973
  const calculateMaxHeight = () => {
1124
974
  const textarea = internalTextareaRef.current;
1125
975
  if (textarea) {
@@ -1133,14 +983,14 @@ var AutoResizingTextarea = (0, import_react7.forwardRef)(
1133
983
  };
1134
984
  calculateMaxHeight();
1135
985
  }, [maxRows]);
1136
- (0, import_react7.useEffect)(() => {
986
+ (0, import_react5.useEffect)(() => {
1137
987
  const textarea = internalTextareaRef.current;
1138
988
  if (textarea) {
1139
989
  textarea.style.height = "auto";
1140
990
  textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
1141
991
  }
1142
992
  }, [value, maxHeight]);
1143
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
993
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1144
994
  "textarea",
1145
995
  {
1146
996
  ref: internalTextareaRef,
@@ -1149,7 +999,7 @@ var AutoResizingTextarea = (0, import_react7.forwardRef)(
1149
999
  onKeyDown,
1150
1000
  placeholder,
1151
1001
  style: {
1152
- overflow: "hidden",
1002
+ overflow: "auto",
1153
1003
  resize: "none",
1154
1004
  maxHeight: `${maxHeight}px`
1155
1005
  },
@@ -1160,18 +1010,121 @@ var AutoResizingTextarea = (0, import_react7.forwardRef)(
1160
1010
  );
1161
1011
  var Textarea_default = AutoResizingTextarea;
1162
1012
 
1013
+ // src/hooks/use-push-to-talk.tsx
1014
+ var import_react_core2 = require("@copilotkit/react-core");
1015
+ var import_react6 = require("react");
1016
+ var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
1017
+ if (!mediaStreamRef.current || !audioContextRef.current) {
1018
+ mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
1019
+ audioContextRef.current = new window.AudioContext();
1020
+ yield audioContextRef.current.resume();
1021
+ }
1022
+ mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
1023
+ mediaRecorderRef.current.start(1e3);
1024
+ mediaRecorderRef.current.ondataavailable = (event) => {
1025
+ recordedChunks.push(event.data);
1026
+ };
1027
+ mediaRecorderRef.current.onstop = onStop;
1028
+ });
1029
+ var stopRecording = (mediaRecorderRef) => {
1030
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1031
+ mediaRecorderRef.current.stop();
1032
+ }
1033
+ };
1034
+ var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
1035
+ const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
1036
+ const formData = new FormData();
1037
+ formData.append("file", completeBlob, "recording.mp4");
1038
+ const response = yield fetch(transcribeAudioUrl, {
1039
+ method: "POST",
1040
+ body: formData
1041
+ });
1042
+ if (!response.ok) {
1043
+ throw new Error(`Error: ${response.statusText}`);
1044
+ }
1045
+ const transcription = yield response.json();
1046
+ return transcription.text;
1047
+ });
1048
+ var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
1049
+ const encodedText = encodeURIComponent(text);
1050
+ const url = `${textToSpeechUrl}?text=${encodedText}`;
1051
+ fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
1052
+ const source = audioContext.createBufferSource();
1053
+ source.buffer = audioBuffer;
1054
+ source.connect(audioContext.destination);
1055
+ source.start(0);
1056
+ }).catch((error) => {
1057
+ console.error("Error with decoding audio data", error);
1058
+ });
1059
+ };
1060
+ var usePushToTalk = ({
1061
+ sendFunction,
1062
+ inProgress
1063
+ }) => {
1064
+ const [pushToTalkState, setPushToTalkState] = (0, import_react6.useState)("idle");
1065
+ const mediaStreamRef = (0, import_react6.useRef)(null);
1066
+ const audioContextRef = (0, import_react6.useRef)(null);
1067
+ const mediaRecorderRef = (0, import_react6.useRef)(null);
1068
+ const recordedChunks = (0, import_react6.useRef)([]);
1069
+ const context = (0, import_react_core2.useCopilotContext)();
1070
+ const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react6.useState)(null);
1071
+ (0, import_react6.useEffect)(() => {
1072
+ if (pushToTalkState === "recording") {
1073
+ startRecording(
1074
+ mediaStreamRef,
1075
+ mediaRecorderRef,
1076
+ audioContextRef,
1077
+ recordedChunks.current,
1078
+ () => {
1079
+ setPushToTalkState("transcribing");
1080
+ }
1081
+ );
1082
+ } else {
1083
+ stopRecording(mediaRecorderRef);
1084
+ if (pushToTalkState === "transcribing") {
1085
+ transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
1086
+ (transcription) => __async(void 0, null, function* () {
1087
+ recordedChunks.current = [];
1088
+ setPushToTalkState("idle");
1089
+ const message = yield sendFunction(transcription);
1090
+ setStartReadingFromMessageId(message.id);
1091
+ })
1092
+ );
1093
+ }
1094
+ }
1095
+ return () => {
1096
+ stopRecording(mediaRecorderRef);
1097
+ };
1098
+ }, [pushToTalkState]);
1099
+ (0, import_react6.useEffect)(() => {
1100
+ if (inProgress === false && startReadingFromMessageId) {
1101
+ const lastMessageIndex = context.messages.findIndex(
1102
+ (message) => message.id === startReadingFromMessageId
1103
+ );
1104
+ const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant" && message.content);
1105
+ const text = messagesAfterLast.map((message) => message.content).join("\n");
1106
+ playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
1107
+ setStartReadingFromMessageId(null);
1108
+ }
1109
+ }, [startReadingFromMessageId, inProgress]);
1110
+ return { pushToTalkState, setPushToTalkState };
1111
+ };
1112
+
1163
1113
  // src/components/chat/Input.tsx
1164
- var import_jsx_runtime10 = require("react/jsx-runtime");
1114
+ var import_react_core3 = require("@copilotkit/react-core");
1115
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1165
1116
  var Input = ({ inProgress, onSend, isVisible = false }) => {
1166
1117
  const context = useChatContext();
1167
- const textareaRef = (0, import_react8.useRef)(null);
1118
+ const copilotContext = (0, import_react_core3.useCopilotContext)();
1119
+ const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
1120
+ const textareaRef = (0, import_react7.useRef)(null);
1168
1121
  const handleDivClick = (event) => {
1169
1122
  var _a;
1170
1123
  if (event.target !== event.currentTarget)
1171
1124
  return;
1172
1125
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1173
1126
  };
1174
- const [text, setText] = (0, import_react8.useState)("");
1127
+ const [text, setText] = (0, import_react7.useState)("");
1175
1128
  const send = () => {
1176
1129
  var _a;
1177
1130
  if (inProgress)
@@ -1180,17 +1133,21 @@ var Input = ({ inProgress, onSend, isVisible = false }) => {
1180
1133
  setText("");
1181
1134
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1182
1135
  };
1183
- (0, import_react8.useEffect)(() => {
1136
+ (0, import_react7.useEffect)(() => {
1184
1137
  var _a;
1185
1138
  if (isVisible) {
1186
1139
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1187
1140
  }
1188
1141
  }, [isVisible]);
1189
- const icon = inProgress ? context.icons.activityIcon : context.icons.sendIcon;
1190
- const disabled = inProgress || text.length === 0;
1191
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
1192
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitSendButton", disabled, onClick: send, children: icon }),
1193
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1142
+ const { pushToTalkState, setPushToTalkState } = usePushToTalk({
1143
+ sendFunction: onSend,
1144
+ inProgress
1145
+ });
1146
+ const sendIcon = inProgress || pushToTalkState === "transcribing" ? context.icons.activityIcon : context.icons.sendIcon;
1147
+ const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
1148
+ const sendDisabled = inProgress || text.length === 0 || pushToTalkState !== "idle";
1149
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
1150
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1194
1151
  Textarea_default,
1195
1152
  {
1196
1153
  ref: textareaRef,
@@ -1206,28 +1163,36 @@ var Input = ({ inProgress, onSend, isVisible = false }) => {
1206
1163
  }
1207
1164
  }
1208
1165
  }
1209
- )
1166
+ ),
1167
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "copilotKitInputControls", children: [
1168
+ showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1169
+ "button",
1170
+ {
1171
+ onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
1172
+ className: pushToTalkState === "recording" ? "copilotKitPushToTalkRecording" : "",
1173
+ children: context.icons.pushToTalkIcon
1174
+ }
1175
+ ),
1176
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { disabled: sendDisabled, onClick: send, children: sendIcon })
1177
+ ] })
1210
1178
  ] });
1211
1179
  };
1212
1180
 
1213
- // src/components/chat/Chat.tsx
1214
- var import_nanoid2 = require("nanoid");
1215
-
1216
1181
  // src/components/chat/Response.tsx
1217
- var import_jsx_runtime11 = require("react/jsx-runtime");
1182
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1218
1183
  var ResponseButton = ({ onClick, inProgress }) => {
1219
1184
  const context = useChatContext();
1220
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { onClick, className: "copilotKitResponseButton", children: [
1221
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: inProgress ? context.icons.stopIcon : context.icons.regenerateIcon }),
1185
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { onClick, className: "copilotKitResponseButton", children: [
1186
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: inProgress ? context.icons.stopIcon : context.icons.regenerateIcon }),
1222
1187
  inProgress ? context.labels.stopGenerating : context.labels.regenerateResponse
1223
1188
  ] });
1224
1189
  };
1225
1190
 
1226
1191
  // src/components/chat/Suggestion.tsx
1227
- var import_react_core2 = require("@copilotkit/react-core");
1228
- var import_jsx_runtime12 = require("react/jsx-runtime");
1192
+ var import_react_core4 = require("@copilotkit/react-core");
1193
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1229
1194
  function Suggestion({ title, message, onClick, partial, className }) {
1230
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1195
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1231
1196
  "button",
1232
1197
  {
1233
1198
  disabled: partial,
@@ -1238,7 +1203,7 @@ function Suggestion({ title, message, onClick, partial, className }) {
1238
1203
  className: className || "suggestion",
1239
1204
  children: [
1240
1205
  partial && SmallSpinnerIcon,
1241
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: title })
1206
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: title })
1242
1207
  ]
1243
1208
  }
1244
1209
  );
@@ -1250,7 +1215,7 @@ var reloadSuggestions = (context, chatSuggestionConfiguration, setCurrentSuggest
1250
1215
  for (const config of Object.values(chatSuggestionConfiguration)) {
1251
1216
  try {
1252
1217
  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.`;
1253
- const result = yield (0, import_react_core2.extract)({
1218
+ const result = yield (0, import_react_core4.extract)({
1254
1219
  context,
1255
1220
  instructions: "Suggest what the user could say next. Provide clear, highly relevant suggestions. Do not literally suggest function calls. " + config.instructions + "\n\n" + numOfSuggestionsInstructions,
1256
1221
  data: "Available tools: " + tools + "\n\n",
@@ -1306,78 +1271,82 @@ var reloadSuggestions = (context, chatSuggestionConfiguration, setCurrentSuggest
1306
1271
  }
1307
1272
  });
1308
1273
 
1309
- // src/components/chat/audio.ts
1310
- var requestMicAndPlaybackPermission = () => __async(void 0, null, function* () {
1311
- try {
1312
- const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
1313
- const audioContext = new window.AudioContext();
1314
- yield audioContext.resume();
1315
- return { stream, audioContext };
1316
- } catch (err) {
1317
- console.error("Error requesting microphone and playback permissions", err);
1318
- return null;
1319
- }
1320
- });
1321
-
1322
1274
  // src/components/chat/Chat.tsx
1323
- var import_jsx_runtime13 = require("react/jsx-runtime");
1324
- var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3;
1325
- var CopilotChat = ({
1275
+ var import_react8 = __toESM(require("react"));
1276
+ var import_react_core5 = require("@copilotkit/react-core");
1277
+ var import_nanoid2 = require("nanoid");
1278
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1279
+ function CopilotChat({
1326
1280
  instructions,
1327
- defaultOpen = false,
1328
- clickOutsideToClose = true,
1329
- hitEscapeToClose = true,
1330
- onSetOpen,
1331
1281
  onSubmitMessage,
1332
- shortcut = "/",
1333
1282
  icons,
1334
1283
  labels,
1335
1284
  makeSystemMessage,
1336
1285
  showResponseButton = true,
1337
1286
  onInProgress,
1338
- Window: Window2 = Window,
1339
- Button: Button2 = Button,
1340
- Header: Header2 = Header,
1341
1287
  Messages: Messages2 = Messages,
1342
1288
  Input: Input2 = Input,
1343
1289
  ResponseButton: ResponseButton2 = ResponseButton,
1344
- className,
1345
- children
1346
- }) => {
1347
- const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core3.useCopilotChat)({
1290
+ className
1291
+ }) {
1292
+ const { visibleMessages, isLoading, currentSuggestions, sendMessage, stop, reload } = useCopilotChatLogic(instructions, makeSystemMessage, onInProgress, onSubmitMessage);
1293
+ const context = import_react8.default.useContext(ChatContext);
1294
+ let open = true;
1295
+ let setOpen = () => {
1296
+ };
1297
+ if (context) {
1298
+ icons = context.icons;
1299
+ labels = context.labels;
1300
+ open = context.open;
1301
+ setOpen = context.setOpen;
1302
+ }
1303
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatContextProvider, { icons, labels, open, setOpen, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `copilotKitPanel ${className}`, children: [
1304
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Messages2, { messages: visibleMessages, inProgress: isLoading, children: [
1305
+ currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1306
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h6", { children: "Suggested:" }),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1308
+ Suggestion,
1309
+ {
1310
+ title: suggestion.title,
1311
+ message: suggestion.message,
1312
+ partial: suggestion.partial,
1313
+ className: suggestion.className,
1314
+ onClick: (message) => sendMessage(message)
1315
+ },
1316
+ index
1317
+ )) })
1318
+ ] }),
1319
+ showResponseButton && visibleMessages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ResponseButton2, { onClick: isLoading ? stop : reload, inProgress: isLoading })
1320
+ ] }),
1321
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Input2, { inProgress: isLoading, onSend: sendMessage, isVisible: true })
1322
+ ] }) });
1323
+ }
1324
+ var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3;
1325
+ var useCopilotChatLogic = (instructions, makeSystemMessage, onInProgress, onSubmitMessage) => {
1326
+ const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core5.useCopilotChat)({
1348
1327
  id: (0, import_nanoid2.nanoid)(),
1349
1328
  makeSystemMessage,
1350
1329
  additionalInstructions: instructions
1351
1330
  });
1352
- const [currentSuggestions, setCurrentSuggestions] = import_react9.default.useState([]);
1353
- const suggestionsAbortControllerRef = (0, import_react9.useRef)(null);
1354
- const debounceTimerRef = (0, import_react9.useRef)();
1331
+ const [currentSuggestions, setCurrentSuggestions] = (0, import_react8.useState)([]);
1332
+ const suggestionsAbortControllerRef = (0, import_react8.useRef)(null);
1333
+ const debounceTimerRef = (0, import_react8.useRef)();
1355
1334
  const abortSuggestions = () => {
1356
1335
  var _a;
1357
1336
  (_a = suggestionsAbortControllerRef.current) == null ? void 0 : _a.abort();
1358
1337
  suggestionsAbortControllerRef.current = null;
1359
1338
  };
1360
- const context = (0, import_react_core3.useCopilotContext)();
1361
- const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = (0, import_react9.useState)({});
1362
- const addChatSuggestionConfiguration = (id, suggestion) => {
1363
- setChatSuggestionConfiguration((prev) => __spreadProps(__spreadValues({}, prev), { [id]: suggestion }));
1364
- };
1365
- const removeChatSuggestion = (id) => {
1366
- setChatSuggestionConfiguration((prev) => {
1367
- const _a = prev, { [id]: _ } = _a, rest = __objRest(_a, [__restKey(id)]);
1368
- return rest;
1369
- });
1370
- };
1371
- (0, import_react9.useEffect)(() => {
1339
+ const context = (0, import_react_core5.useCopilotContext)();
1340
+ (0, import_react8.useEffect)(() => {
1372
1341
  onInProgress == null ? void 0 : onInProgress(isLoading);
1373
1342
  abortSuggestions();
1374
1343
  debounceTimerRef.current = setTimeout(
1375
1344
  () => {
1376
- if (!isLoading && Object.keys(chatSuggestionConfiguration).length !== 0) {
1345
+ if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) {
1377
1346
  suggestionsAbortControllerRef.current = new AbortController();
1378
1347
  reloadSuggestions(
1379
1348
  context,
1380
- chatSuggestionConfiguration,
1349
+ context.chatSuggestionConfiguration,
1381
1350
  setCurrentSuggestions,
1382
1351
  suggestionsAbortControllerRef
1383
1352
  );
@@ -1388,11 +1357,7 @@ var CopilotChat = ({
1388
1357
  return () => {
1389
1358
  clearTimeout(debounceTimerRef.current);
1390
1359
  };
1391
- }, [isLoading, chatSuggestionConfiguration]);
1392
- const setOpen = (open) => {
1393
- onSetOpen == null ? void 0 : onSetOpen(open);
1394
- setOpenState(open);
1395
- };
1360
+ }, [isLoading, context.chatSuggestionConfiguration]);
1396
1361
  const sendMessage = (messageContent) => __async(void 0, null, function* () {
1397
1362
  abortSuggestions();
1398
1363
  setCurrentSuggestions([]);
@@ -1405,141 +1370,20 @@ var CopilotChat = ({
1405
1370
  append(message);
1406
1371
  return message;
1407
1372
  });
1408
- const [openState, setOpenState] = import_react9.default.useState(defaultOpen);
1409
- const [pushToTalkState, setPushToTalkState] = import_react9.default.useState(false);
1410
- const mediaStreamRef = (0, import_react9.useRef)(null);
1411
- const audioContextRef = (0, import_react9.useRef)(null);
1412
- const mediaRecorderRef = (0, import_react9.useRef)(null);
1413
- const [lastMessageIdBeforeAudio, setLastMessageIdBeforeAudio] = (0, import_react9.useState)(null);
1414
- (0, import_react9.useEffect)(() => {
1415
- if (pushToTalkState) {
1416
- console.log("HERE");
1417
- if (!mediaStreamRef.current || !audioContextRef.current) {
1418
- setPushToTalkState(false);
1419
- requestMicAndPlaybackPermission().then((res) => {
1420
- if (res) {
1421
- mediaStreamRef.current = res.stream;
1422
- audioContextRef.current = res.audioContext;
1423
- }
1424
- });
1425
- } else {
1426
- console.log("Recording started");
1427
- const recordedChunks = [];
1428
- mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
1429
- mediaRecorderRef.current.start(1e3);
1430
- mediaRecorderRef.current.ondataavailable = (event) => __async(void 0, null, function* () {
1431
- console.log("Recorded audio: ", event.data);
1432
- recordedChunks.push(event.data);
1433
- });
1434
- mediaRecorderRef.current.onstop = () => __async(void 0, null, function* () {
1435
- console.log("Recording stopped");
1436
- const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
1437
- const formData = new FormData();
1438
- formData.append("file", completeBlob, "recording.mp4");
1439
- const response = yield fetch(context.copilotApiConfig.transcribeAudioUrl, {
1440
- method: "POST",
1441
- body: formData
1442
- });
1443
- if (!response.ok) {
1444
- throw new Error(`Error: ${response.statusText}`);
1445
- }
1446
- const transcription = yield response.json();
1447
- const message = yield sendMessage(transcription.text);
1448
- setLastMessageIdBeforeAudio(message.id);
1449
- });
1450
- }
1451
- } else {
1452
- if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1453
- mediaRecorderRef.current.stop();
1454
- }
1455
- }
1456
- return () => {
1457
- if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1458
- mediaRecorderRef.current.stop();
1459
- }
1460
- };
1461
- }, [pushToTalkState]);
1462
- (0, import_react9.useEffect)(() => {
1463
- if (lastMessageIdBeforeAudio && !isLoading) {
1464
- if (audioContextRef.current) {
1465
- const lastMessageIndex = context.messages.findIndex(
1466
- (message) => message.id === lastMessageIdBeforeAudio
1467
- );
1468
- const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant" && message.content);
1469
- const text = messagesAfterLast.map((message) => message.content).join("\n");
1470
- const encodedText = encodeURIComponent(text);
1471
- const url = `${context.copilotApiConfig.textToSpeechUrl}?text=${encodedText}`;
1472
- fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContextRef.current.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
1473
- const source = audioContextRef.current.createBufferSource();
1474
- source.buffer = audioBuffer;
1475
- source.connect(audioContextRef.current.destination);
1476
- source.start(0);
1477
- }).catch((error) => {
1478
- console.error("Error with decoding audio data", error);
1479
- });
1480
- setLastMessageIdBeforeAudio(null);
1481
- }
1482
- }
1483
- }, [isLoading]);
1484
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1485
- ChatContextProvider,
1486
- {
1487
- icons,
1488
- labels,
1489
- open: openState,
1490
- setOpen: setOpenState,
1491
- addChatSuggestionConfiguration,
1492
- removeChatSuggestionConfiguration: removeChatSuggestion,
1493
- children: [
1494
- children,
1495
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className, children: [
1496
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1497
- Button2,
1498
- {
1499
- open: openState,
1500
- setOpen,
1501
- pushToTalk: pushToTalkState,
1502
- setPushToTalk: setPushToTalkState
1503
- }
1504
- ),
1505
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1506
- Window2,
1507
- {
1508
- open: openState,
1509
- setOpen,
1510
- clickOutsideToClose,
1511
- shortcut,
1512
- hitEscapeToClose,
1513
- children: [
1514
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Header2, { open: openState, setOpen }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Messages2, { messages: visibleMessages, inProgress: isLoading, children: [
1516
- currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
1517
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h6", { children: "Suggested:" }),
1518
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1519
- Suggestion,
1520
- {
1521
- title: suggestion.title,
1522
- message: suggestion.message,
1523
- partial: suggestion.partial,
1524
- className: suggestion.className,
1525
- onClick: (message) => sendMessage(message)
1526
- },
1527
- index
1528
- )) })
1529
- ] }),
1530
- showResponseButton && visibleMessages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ResponseButton2, { onClick: isLoading ? stop : reload, inProgress: isLoading })
1531
- ] }),
1532
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Input2, { inProgress: isLoading, onSend: sendMessage, isVisible: openState })
1533
- ]
1534
- }
1535
- )
1536
- ] })
1537
- ]
1538
- }
1539
- );
1373
+ return {
1374
+ visibleMessages,
1375
+ isLoading,
1376
+ currentSuggestions,
1377
+ sendMessage,
1378
+ stop,
1379
+ reload,
1380
+ input,
1381
+ setInput
1382
+ };
1540
1383
  };
1541
1384
  // Annotate the CommonJS export names for ESM import in node:
1542
1385
  0 && (module.exports = {
1543
- CopilotChat
1386
+ CopilotChat,
1387
+ useCopilotChatLogic
1544
1388
  });
1545
1389
  //# sourceMappingURL=Chat.js.map