@copilotkit/react-ui 0.22.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 (165) hide show
  1. package/.turbo/turbo-build.log +211 -178
  2. package/CHANGELOG.md +24 -0
  3. package/dist/chunk-4MKP23AD.mjs +97 -0
  4. package/dist/chunk-4MKP23AD.mjs.map +1 -0
  5. package/dist/{chunk-T3WYKWNC.mjs → chunk-6XLZXLM5.mjs} +6 -6
  6. package/dist/chunk-6XLZXLM5.mjs.map +1 -0
  7. package/dist/{chunk-73EBDGYK.mjs → chunk-7FES2IQA.mjs} +5 -5
  8. package/dist/chunk-7FES2IQA.mjs.map +1 -0
  9. package/dist/chunk-ANO23V2M.mjs +135 -0
  10. package/dist/chunk-ANO23V2M.mjs.map +1 -0
  11. package/dist/chunk-BL65ZC6L.mjs +83 -0
  12. package/dist/chunk-BL65ZC6L.mjs.map +1 -0
  13. package/dist/{chunk-YEHO5VMA.mjs → chunk-CE7PJAAO.mjs} +2 -2
  14. package/dist/{chunk-7YXG7D47.mjs → chunk-FZC7X5PK.mjs} +57 -2
  15. package/dist/chunk-FZC7X5PK.mjs.map +1 -0
  16. package/dist/chunk-LTCJCXCP.mjs +29 -0
  17. package/dist/chunk-LTCJCXCP.mjs.map +1 -0
  18. package/dist/chunk-MRFF7GSQ.mjs +1 -0
  19. package/dist/{chunk-7JYUCW7H.mjs → chunk-PAQWLSA4.mjs} +2 -2
  20. package/dist/{chunk-YTIGBBTC.mjs → chunk-RT2XG2T7.mjs} +2 -2
  21. package/dist/chunk-RT2XG2T7.mjs.map +1 -0
  22. package/dist/chunk-T26KLXLH.mjs +1 -0
  23. package/dist/{chunk-6U3O2JZP.mjs → chunk-T3JTSIHT.mjs} +32 -39
  24. package/dist/chunk-T3JTSIHT.mjs.map +1 -0
  25. package/dist/{chunk-MBYUBR3F.mjs → chunk-UPTB2MVO.mjs} +2 -2
  26. package/dist/chunk-VUZA5AFH.mjs +73 -0
  27. package/dist/chunk-VUZA5AFH.mjs.map +1 -0
  28. package/dist/{chunk-YAORLSQ3.mjs → chunk-XRODMID5.mjs} +6 -6
  29. package/dist/chunk-XRODMID5.mjs.map +1 -0
  30. package/dist/{chunk-WDHLWSSU.mjs → chunk-YQ3D5IQV.mjs} +2 -2
  31. package/dist/{chunk-WM6BS77F.mjs → chunk-YQFVRDNC.mjs} +2 -2
  32. package/dist/{chunk-WM6BS77F.mjs.map → chunk-YQFVRDNC.mjs.map} +1 -1
  33. package/dist/chunk-ZO3GLN23.mjs +137 -0
  34. package/dist/chunk-ZO3GLN23.mjs.map +1 -0
  35. package/dist/components/chat/Button.js.map +1 -1
  36. package/dist/components/chat/Button.mjs +3 -3
  37. package/dist/components/chat/Chat.d.ts +66 -46
  38. package/dist/components/chat/Chat.js +433 -278
  39. package/dist/components/chat/Chat.js.map +1 -1
  40. package/dist/components/chat/Chat.mjs +15 -14
  41. package/dist/components/chat/ChatContext.d.ts +16 -16
  42. package/dist/components/chat/ChatContext.js +43 -27
  43. package/dist/components/chat/ChatContext.js.map +1 -1
  44. package/dist/components/chat/ChatContext.mjs +2 -2
  45. package/dist/components/chat/CodeBlock.js.map +1 -1
  46. package/dist/components/chat/CodeBlock.mjs +2 -2
  47. package/dist/components/chat/Header.js.map +1 -1
  48. package/dist/components/chat/Header.mjs +3 -3
  49. package/dist/components/chat/Icons.d.ts +7 -5
  50. package/dist/components/chat/Icons.js +57 -0
  51. package/dist/components/chat/Icons.js.map +1 -1
  52. package/dist/components/chat/Icons.mjs +5 -1
  53. package/dist/components/chat/Input.d.ts +1 -1
  54. package/dist/components/chat/Input.js +148 -11
  55. package/dist/components/chat/Input.js.map +1 -1
  56. package/dist/components/chat/Input.mjs +5 -4
  57. package/dist/components/chat/Markdown.js.map +1 -1
  58. package/dist/components/chat/Markdown.mjs +3 -3
  59. package/dist/components/chat/Messages.d.ts +1 -1
  60. package/dist/components/chat/Messages.js +2 -2
  61. package/dist/components/chat/Messages.js.map +1 -1
  62. package/dist/components/chat/Messages.mjs +5 -5
  63. package/dist/components/chat/Modal.d.ts +50 -0
  64. package/dist/components/chat/Modal.js +1584 -0
  65. package/dist/components/chat/Modal.js.map +1 -0
  66. package/dist/components/chat/Modal.mjs +23 -0
  67. package/dist/components/chat/Modal.mjs.map +1 -0
  68. package/dist/components/chat/Popup.d.ts +56 -4
  69. package/dist/components/chat/Popup.js +428 -78
  70. package/dist/components/chat/Popup.js.map +1 -1
  71. package/dist/components/chat/Popup.mjs +15 -12
  72. package/dist/components/chat/Response.js.map +1 -1
  73. package/dist/components/chat/Response.mjs +3 -3
  74. package/dist/components/chat/Sidebar.d.ts +7 -8
  75. package/dist/components/chat/Sidebar.js +430 -80
  76. package/dist/components/chat/Sidebar.js.map +1 -1
  77. package/dist/components/chat/Sidebar.mjs +15 -12
  78. package/dist/components/chat/Suggestion.d.ts +13 -0
  79. package/dist/components/chat/Suggestion.js +172 -0
  80. package/dist/components/chat/Suggestion.js.map +1 -0
  81. package/dist/components/chat/Suggestion.mjs +11 -0
  82. package/dist/components/chat/Suggestion.mjs.map +1 -0
  83. package/dist/components/chat/Textarea.d.ts +4 -4
  84. package/dist/components/chat/Textarea.js +1 -1
  85. package/dist/components/chat/Textarea.js.map +1 -1
  86. package/dist/components/chat/Textarea.mjs +1 -1
  87. package/dist/components/chat/index.d.ts +4 -2
  88. package/dist/components/chat/index.js +436 -84
  89. package/dist/components/chat/index.js.map +1 -1
  90. package/dist/components/chat/index.mjs +22 -16
  91. package/dist/components/chat/props.d.ts +10 -3
  92. package/dist/components/chat/props.js.map +1 -1
  93. package/dist/components/index.d.ts +4 -2
  94. package/dist/components/index.js +436 -84
  95. package/dist/components/index.js.map +1 -1
  96. package/dist/components/index.mjs +22 -16
  97. package/dist/hooks/index.d.ts +1 -2
  98. package/dist/hooks/index.js +36 -0
  99. package/dist/hooks/index.js.map +1 -1
  100. package/dist/hooks/index.mjs +8 -1
  101. package/dist/hooks/use-copilot-chat-suggestions.d.ts +87 -0
  102. package/dist/hooks/use-copilot-chat-suggestions.js +53 -0
  103. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -0
  104. package/dist/hooks/use-copilot-chat-suggestions.mjs +8 -0
  105. package/dist/hooks/use-copilot-chat-suggestions.mjs.map +1 -0
  106. package/dist/hooks/use-push-to-talk.d.ts +19 -0
  107. package/dist/hooks/use-push-to-talk.js +177 -0
  108. package/dist/hooks/use-push-to-talk.js.map +1 -0
  109. package/dist/hooks/use-push-to-talk.mjs +12 -0
  110. package/dist/hooks/use-push-to-talk.mjs.map +1 -0
  111. package/dist/index.css +101 -13
  112. package/dist/index.css.map +1 -1
  113. package/dist/index.d.ts +5 -2
  114. package/dist/index.js +465 -86
  115. package/dist/index.js.map +1 -1
  116. package/dist/index.mjs +29 -19
  117. package/dist/types/suggestions.d.ts +8 -0
  118. package/dist/types/suggestions.js +19 -0
  119. package/dist/types/suggestions.js.map +1 -0
  120. package/dist/types/suggestions.mjs +1 -0
  121. package/dist/types/suggestions.mjs.map +1 -0
  122. package/package.json +6 -6
  123. package/src/components/chat/Button.tsx +1 -2
  124. package/src/components/chat/Chat.tsx +163 -104
  125. package/src/components/chat/ChatContext.tsx +36 -38
  126. package/src/components/chat/Icons.tsx +44 -0
  127. package/src/components/chat/Input.tsx +38 -7
  128. package/src/components/chat/Messages.tsx +3 -3
  129. package/src/components/chat/Modal.tsx +115 -0
  130. package/src/components/chat/Popup.tsx +53 -7
  131. package/src/components/chat/Sidebar.tsx +62 -9
  132. package/src/components/chat/Suggestion.tsx +109 -0
  133. package/src/components/chat/Textarea.tsx +1 -1
  134. package/src/components/chat/index.tsx +1 -0
  135. package/src/components/chat/props.ts +10 -2
  136. package/src/css/input.css +18 -8
  137. package/src/css/messages.css +7 -1
  138. package/src/css/panel.css +38 -0
  139. package/src/css/response.css +1 -4
  140. package/src/css/suggestions.css +35 -0
  141. package/src/css/window.css +3 -1
  142. package/src/hooks/index.ts +1 -1
  143. package/src/hooks/use-copilot-chat-suggestions.tsx +117 -0
  144. package/src/hooks/use-push-to-talk.tsx +162 -0
  145. package/src/styles.css +2 -0
  146. package/src/types/suggestions.ts +6 -0
  147. package/typedoc.json +4 -0
  148. package/dist/chunk-6U3O2JZP.mjs.map +0 -1
  149. package/dist/chunk-73EBDGYK.mjs.map +0 -1
  150. package/dist/chunk-7LMXXGJT.mjs +0 -75
  151. package/dist/chunk-7LMXXGJT.mjs.map +0 -1
  152. package/dist/chunk-7YXG7D47.mjs.map +0 -1
  153. package/dist/chunk-H4VKQGVU.mjs +0 -1
  154. package/dist/chunk-KE3N45ZY.mjs +0 -63
  155. package/dist/chunk-KE3N45ZY.mjs.map +0 -1
  156. package/dist/chunk-T3WYKWNC.mjs.map +0 -1
  157. package/dist/chunk-UGQQ4WEQ.mjs +0 -1
  158. package/dist/chunk-YAORLSQ3.mjs.map +0 -1
  159. package/dist/chunk-YTIGBBTC.mjs.map +0 -1
  160. /package/dist/{chunk-YEHO5VMA.mjs.map → chunk-CE7PJAAO.mjs.map} +0 -0
  161. /package/dist/{chunk-H4VKQGVU.mjs.map → chunk-MRFF7GSQ.mjs.map} +0 -0
  162. /package/dist/{chunk-7JYUCW7H.mjs.map → chunk-PAQWLSA4.mjs.map} +0 -0
  163. /package/dist/{chunk-UGQQ4WEQ.mjs.map → chunk-T26KLXLH.mjs.map} +0 -0
  164. /package/dist/{chunk-MBYUBR3F.mjs.map → chunk-UPTB2MVO.mjs.map} +0 -0
  165. /package/dist/{chunk-WDHLWSSU.mjs.map → chunk-YQ3D5IQV.mjs.map} +0 -0
@@ -79,10 +79,10 @@ var __async = (__this, __arguments, generator) => {
79
79
  // src/components/chat/Chat.tsx
80
80
  var Chat_exports = {};
81
81
  __export(Chat_exports, {
82
- CopilotChat: () => CopilotChat
82
+ CopilotChat: () => CopilotChat,
83
+ useCopilotChatLogic: () => useCopilotChatLogic
83
84
  });
84
85
  module.exports = __toCommonJS(Chat_exports);
85
- var import_react8 = __toESM(require("react"));
86
86
 
87
87
  // src/components/chat/ChatContext.tsx
88
88
  var import_react = __toESM(require("react"));
@@ -188,6 +188,40 @@ var SpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
188
188
  ]
189
189
  }
190
190
  );
191
+ var SmallSpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
192
+ "svg",
193
+ {
194
+ style: {
195
+ animation: "copilotKitSpinAnimation 1s linear infinite"
196
+ },
197
+ width: "13",
198
+ height: "13",
199
+ xmlns: "http://www.w3.org/2000/svg",
200
+ fill: "none",
201
+ viewBox: "0 0 24 24",
202
+ children: [
203
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
204
+ "circle",
205
+ {
206
+ style: { opacity: 0.25 },
207
+ cx: "12",
208
+ cy: "12",
209
+ r: "10",
210
+ stroke: "currentColor",
211
+ strokeWidth: "4"
212
+ }
213
+ ),
214
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
215
+ "path",
216
+ {
217
+ style: { opacity: 0.75 },
218
+ fill: "currentColor",
219
+ 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"
220
+ }
221
+ )
222
+ ]
223
+ }
224
+ );
191
225
  var ActivityIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
192
226
  "svg",
193
227
  {
@@ -273,6 +307,25 @@ var RegenerateIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
273
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" })
274
308
  }
275
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
+ );
276
329
 
277
330
  // src/components/chat/ChatContext.tsx
278
331
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -296,190 +349,51 @@ var ChatContextProvider = ({
296
349
  open,
297
350
  setOpen
298
351
  }) => {
299
- const context = (0, import_react.useMemo)(
300
- () => ({
301
- labels: __spreadValues(__spreadValues({}, {
302
- initial: "",
303
- title: "CopilotKit",
304
- placeholder: "Type a message...",
305
- thinking: "Thinking...",
306
- error: "\u274C An error occurred. Please try again.",
307
- stopGenerating: "Stop generating",
308
- regenerateResponse: "Regenerate response"
309
- }), labels),
310
- icons: __spreadProps(__spreadValues({}, {
311
- openIcon: OpenIcon,
312
- closeIcon: CloseIcon,
313
- headerCloseIcon: HeaderCloseIcon,
314
- sendIcon: SendIcon,
315
- activityIcon: ActivityIcon,
316
- spinnerIcon: SpinnerIcon,
317
- stopIcon: StopIcon,
318
- regenerateIcon: RegenerateIcon
319
- }), {
320
- icons
321
- }),
322
- open,
323
- setOpen
352
+ const context = {
353
+ labels: __spreadValues(__spreadValues({}, {
354
+ initial: "",
355
+ title: "CopilotKit",
356
+ placeholder: "Type a message...",
357
+ error: "\u274C An error occurred. Please try again.",
358
+ stopGenerating: "Stop generating",
359
+ regenerateResponse: "Regenerate response"
360
+ }), labels),
361
+ icons: __spreadProps(__spreadValues({}, {
362
+ openIcon: OpenIcon,
363
+ closeIcon: CloseIcon,
364
+ headerCloseIcon: HeaderCloseIcon,
365
+ sendIcon: SendIcon,
366
+ activityIcon: ActivityIcon,
367
+ spinnerIcon: SpinnerIcon,
368
+ stopIcon: StopIcon,
369
+ regenerateIcon: RegenerateIcon,
370
+ pushToTalkIcon: PushToTalkIcon
371
+ }), {
372
+ icons
324
373
  }),
325
- [labels, icons, open, setOpen]
326
- );
327
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children });
328
- };
329
-
330
- // src/components/chat/Chat.tsx
331
- var import_react_core2 = require("@copilotkit/react-core");
332
-
333
- // src/components/chat/Window.tsx
334
- var import_react2 = __toESM(require("react"));
335
- var import_jsx_runtime3 = require("react/jsx-runtime");
336
- var Window = ({
337
- open,
338
- setOpen,
339
- children,
340
- clickOutsideToClose,
341
- shortcut,
342
- hitEscapeToClose
343
- }) => {
344
- const windowRef = import_react2.default.useRef(null);
345
- const handleClickOutside = (0, import_react2.useCallback)(
346
- (event) => {
347
- var _a;
348
- if (!clickOutsideToClose) {
349
- return;
350
- }
351
- const parentElement = (_a = windowRef.current) == null ? void 0 : _a.parentElement;
352
- if (open && parentElement && !parentElement.contains(event.target)) {
353
- setOpen(false);
354
- }
355
- },
356
- [clickOutsideToClose, open, setOpen]
357
- );
358
- const handleKeyDown = (0, import_react2.useCallback)(
359
- (event) => {
360
- var _a;
361
- const target = event.target;
362
- const isInput = target.tagName === "INPUT" || target.tagName === "SELECT" || target.tagName === "TEXTAREA" || target.isContentEditable;
363
- const isDescendantOfWrapper = (_a = windowRef.current) == null ? void 0 : _a.contains(target);
364
- if (open && event.key === "Escape" && (!isInput || isDescendantOfWrapper) && hitEscapeToClose) {
365
- setOpen(false);
366
- } else if (event.key === shortcut && (isMacOS() && event.metaKey || !isMacOS() && event.ctrlKey) && (!isInput || isDescendantOfWrapper)) {
367
- setOpen(!open);
368
- }
369
- },
370
- [hitEscapeToClose, shortcut, open, setOpen]
371
- );
372
- const adjustForMobile = (0, import_react2.useCallback)(() => {
373
- const copilotKitWindow = windowRef.current;
374
- const vv = window.visualViewport;
375
- if (!copilotKitWindow || !vv) {
376
- return;
377
- }
378
- if (window.innerWidth < 640 && open) {
379
- copilotKitWindow.style.height = `${vv.height}px`;
380
- copilotKitWindow.style.left = `${vv.offsetLeft}px`;
381
- copilotKitWindow.style.top = `${vv.offsetTop}px`;
382
- document.body.style.position = "fixed";
383
- document.body.style.width = "100%";
384
- document.body.style.height = `${window.innerHeight}px`;
385
- document.body.style.overflow = "hidden";
386
- document.body.style.touchAction = "none";
387
- document.body.addEventListener("touchmove", preventScroll, {
388
- passive: false
389
- });
390
- } else {
391
- copilotKitWindow.style.height = "";
392
- copilotKitWindow.style.left = "";
393
- copilotKitWindow.style.top = "";
394
- document.body.style.position = "";
395
- document.body.style.height = "";
396
- document.body.style.width = "";
397
- document.body.style.overflow = "";
398
- document.body.style.top = "";
399
- document.body.style.touchAction = "";
400
- document.body.removeEventListener("touchmove", preventScroll);
401
- }
402
- }, [open]);
403
- (0, import_react2.useEffect)(() => {
404
- document.addEventListener("mousedown", handleClickOutside);
405
- document.addEventListener("keydown", handleKeyDown);
406
- if (window.visualViewport) {
407
- window.visualViewport.addEventListener("resize", adjustForMobile);
408
- adjustForMobile();
409
- }
410
- return () => {
411
- document.removeEventListener("mousedown", handleClickOutside);
412
- document.removeEventListener("keydown", handleKeyDown);
413
- if (window.visualViewport) {
414
- window.visualViewport.removeEventListener("resize", adjustForMobile);
415
- }
416
- };
417
- }, [adjustForMobile, handleClickOutside, handleKeyDown]);
418
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `copilotKitWindow${open ? " open" : ""}`, ref: windowRef, children });
419
- };
420
- var preventScroll = (event) => {
421
- let targetElement = event.target;
422
- const hasParentWithClass = (element, className) => {
423
- while (element && element !== document.body) {
424
- if (element.classList.contains(className)) {
425
- return true;
426
- }
427
- element = element.parentElement;
428
- }
429
- return false;
374
+ open,
375
+ setOpen
430
376
  };
431
- if (!hasParentWithClass(targetElement, "copilotKitMessages")) {
432
- event.preventDefault();
433
- }
434
- };
435
- function isMacOS() {
436
- return /Mac|iMac|Macintosh/i.test(navigator.userAgent);
437
- }
438
-
439
- // src/components/chat/Button.tsx
440
- var import_jsx_runtime4 = require("react/jsx-runtime");
441
- var Button = ({ open, setOpen }) => {
442
- const context = useChatContext();
443
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: () => setOpen(!open), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
444
- "button",
445
- {
446
- className: `copilotKitButton ${open ? "open" : ""}`,
447
- "aria-label": open ? "Close Chat" : "Open Chat",
448
- children: [
449
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "copilotKitButtonIcon copilotKitButtonIconOpen", children: context.icons.openIcon }),
450
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "copilotKitButtonIcon copilotKitButtonIconClose", children: context.icons.closeIcon })
451
- ]
452
- }
453
- ) });
454
- };
455
-
456
- // src/components/chat/Header.tsx
457
- var import_jsx_runtime5 = require("react/jsx-runtime");
458
- var Header = ({ setOpen }) => {
459
- const context = useChatContext();
460
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitHeader", children: [
461
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: context.labels.title }),
462
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => setOpen(false), "aria-label": "Close", children: context.icons.headerCloseIcon })
463
- ] });
377
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children });
464
378
  };
465
379
 
466
380
  // src/components/chat/Messages.tsx
467
- var import_react5 = __toESM(require("react"));
381
+ var import_react4 = __toESM(require("react"));
468
382
  var import_nanoid = require("nanoid");
469
383
  var import_shared = require("@copilotkit/shared");
470
384
 
471
385
  // src/components/chat/Markdown.tsx
472
- var import_react4 = require("react");
386
+ var import_react3 = require("react");
473
387
  var import_react_markdown = __toESM(require("react-markdown"));
474
388
 
475
389
  // src/components/chat/CodeBlock.tsx
476
- var import_react3 = require("react");
390
+ var import_react2 = require("react");
477
391
  var import_react_syntax_highlighter = require("react-syntax-highlighter");
478
392
 
479
393
  // src/hooks/use-copy-to-clipboard.tsx
480
- var React3 = __toESM(require("react"));
394
+ var React2 = __toESM(require("react"));
481
395
  function useCopyToClipboard({ timeout = 2e3 }) {
482
- const [isCopied, setIsCopied] = React3.useState(false);
396
+ const [isCopied, setIsCopied] = React2.useState(false);
483
397
  const copyToClipboard = (value) => {
484
398
  var _a;
485
399
  if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
@@ -499,7 +413,7 @@ function useCopyToClipboard({ timeout = 2e3 }) {
499
413
  }
500
414
 
501
415
  // src/components/chat/CodeBlock.tsx
502
- var import_jsx_runtime6 = require("react/jsx-runtime");
416
+ var import_jsx_runtime3 = require("react/jsx-runtime");
503
417
  var programmingLanguages = {
504
418
  javascript: ".js",
505
419
  python: ".py",
@@ -534,7 +448,7 @@ var generateRandomString = (length, lowercase = false) => {
534
448
  }
535
449
  return lowercase ? result.toLowerCase() : result;
536
450
  };
537
- var CodeBlock = (0, import_react3.memo)(({ language, value }) => {
451
+ var CodeBlock = (0, import_react2.memo)(({ language, value }) => {
538
452
  const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
539
453
  const downloadAsFile = () => {
540
454
  if (typeof window === "undefined") {
@@ -562,21 +476,21 @@ var CodeBlock = (0, import_react3.memo)(({ language, value }) => {
562
476
  return;
563
477
  copyToClipboard(value);
564
478
  };
565
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlock", children: [
566
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
567
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
568
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
569
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: [
570
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DownloadIcon, {}),
571
- /* @__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" })
572
486
  ] }),
573
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: [
574
- isCopied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CopyIcon, {}),
575
- /* @__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" })
576
490
  ] })
577
491
  ] })
578
492
  ] }),
579
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
493
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
580
494
  import_react_syntax_highlighter.Prism,
581
495
  {
582
496
  language,
@@ -879,21 +793,21 @@ var highlightStyle = {
879
793
  // src/components/chat/Markdown.tsx
880
794
  var import_remark_gfm = __toESM(require("remark-gfm"));
881
795
  var import_remark_math = __toESM(require("remark-math"));
882
- var import_jsx_runtime7 = require("react/jsx-runtime");
883
- var MemoizedReactMarkdown = (0, import_react4.memo)(
796
+ var import_jsx_runtime4 = require("react/jsx-runtime");
797
+ var MemoizedReactMarkdown = (0, import_react3.memo)(
884
798
  import_react_markdown.default,
885
799
  (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className
886
800
  );
887
801
  var Markdown = ({ content }) => {
888
- 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 }) });
889
803
  };
890
804
  var components = {
891
805
  p({ children }) {
892
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children });
806
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children });
893
807
  },
894
808
  a(_a) {
895
809
  var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
896
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
810
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
897
811
  "a",
898
812
  __spreadProps(__spreadValues({
899
813
  style: { color: "blue", textDecoration: "underline" }
@@ -908,7 +822,7 @@ var components = {
908
822
  var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
909
823
  if (children.length) {
910
824
  if (children[0] == "\u258D") {
911
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
825
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
912
826
  "span",
913
827
  {
914
828
  style: {
@@ -923,9 +837,9 @@ var components = {
923
837
  }
924
838
  const match = /language-(\w+)/.exec(className || "");
925
839
  if (inline) {
926
- 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 }));
927
841
  }
928
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
842
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
929
843
  CodeBlock,
930
844
  __spreadValues({
931
845
  language: match && match[1] || "",
@@ -938,11 +852,11 @@ var components = {
938
852
 
939
853
  // src/components/chat/Messages.tsx
940
854
  var import_react_core = require("@copilotkit/react-core");
941
- var import_jsx_runtime8 = require("react/jsx-runtime");
942
- var Messages = ({ messages, inProgress }) => {
855
+ var import_jsx_runtime5 = require("react/jsx-runtime");
856
+ var Messages = ({ messages, inProgress, children }) => {
943
857
  const { chatComponentsCache } = (0, import_react_core.useCopilotContext)();
944
858
  const context = useChatContext();
945
- const initialMessages = (0, import_react5.useMemo)(
859
+ const initialMessages = (0, import_react4.useMemo)(
946
860
  () => makeInitialMessages(context.labels.initial),
947
861
  [context.labels.initial]
948
862
  );
@@ -956,7 +870,7 @@ var Messages = ({ messages, inProgress }) => {
956
870
  }
957
871
  }
958
872
  }
959
- const messagesEndRef = import_react5.default.useRef(null);
873
+ const messagesEndRef = import_react4.default.useRef(null);
960
874
  const scrollToBottom = () => {
961
875
  if (messagesEndRef.current) {
962
876
  messagesEndRef.current.scrollIntoView({
@@ -964,28 +878,28 @@ var Messages = ({ messages, inProgress }) => {
964
878
  });
965
879
  }
966
880
  };
967
- (0, import_react5.useEffect)(() => {
881
+ (0, import_react4.useEffect)(() => {
968
882
  scrollToBottom();
969
883
  }, [messages]);
970
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitMessages", children: [
884
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitMessages", children: [
971
885
  messages.map((message, index) => {
972
886
  var _a, _b, _c;
973
887
  const isCurrentMessage = index === messages.length - 1;
974
888
  if (message.role === "user") {
975
- 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);
976
890
  } else if (message.role == "assistant") {
977
891
  if (isCurrentMessage && inProgress && !message.content && !message.partialFunctionCall) {
978
- 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);
979
893
  } else if (message.function_call || message.partialFunctionCall) {
980
894
  const functionCallName = ((_a = message.function_call) == null ? void 0 : _a.name) || ((_b = message.partialFunctionCall) == null ? void 0 : _b.name);
981
895
  if (chatComponentsCache.current !== null && chatComponentsCache.current[functionCallName]) {
982
896
  const render = chatComponentsCache.current[functionCallName];
983
897
  if (typeof render === "string") {
984
898
  if (isCurrentMessage && inProgress) {
985
- 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: [
986
900
  context.icons.spinnerIcon,
987
901
  " ",
988
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inProgressLabel", children: render })
902
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "inProgressLabel", children: render })
989
903
  ] }, index);
990
904
  } else {
991
905
  return null;
@@ -1007,25 +921,25 @@ var Messages = ({ messages, inProgress }) => {
1007
921
  return null;
1008
922
  }
1009
923
  if (typeof toRender === "string") {
1010
- 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: [
1011
925
  isCurrentMessage && inProgress && context.icons.spinnerIcon,
1012
926
  " ",
1013
927
  toRender
1014
928
  ] }, index);
1015
929
  } else {
1016
- 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);
1017
931
  }
1018
932
  }
1019
933
  } else if ((!inProgress || !isCurrentMessage) && message.function_call) {
1020
934
  return null;
1021
935
  } else {
1022
- 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);
1023
937
  }
1024
938
  }
1025
- 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);
1026
940
  }
1027
941
  }),
1028
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: messagesEndRef })
942
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("footer", { ref: messagesEndRef, children })
1029
943
  ] });
1030
944
  };
1031
945
  function makeInitialMessages(initial) {
@@ -1048,14 +962,14 @@ function makeInitialMessages(initial) {
1048
962
  var import_react7 = require("react");
1049
963
 
1050
964
  // src/components/chat/Textarea.tsx
1051
- var import_react6 = require("react");
1052
- var import_jsx_runtime9 = require("react/jsx-runtime");
1053
- var AutoResizingTextarea = (0, import_react6.forwardRef)(
965
+ var import_react5 = require("react");
966
+ var import_jsx_runtime6 = require("react/jsx-runtime");
967
+ var AutoResizingTextarea = (0, import_react5.forwardRef)(
1054
968
  ({ maxRows = 1, placeholder, value, onChange, onKeyDown, autoFocus }, ref) => {
1055
- const internalTextareaRef = (0, import_react6.useRef)(null);
1056
- const [maxHeight, setMaxHeight] = (0, import_react6.useState)(0);
1057
- (0, import_react6.useImperativeHandle)(ref, () => internalTextareaRef.current);
1058
- (0, import_react6.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)(() => {
1059
973
  const calculateMaxHeight = () => {
1060
974
  const textarea = internalTextareaRef.current;
1061
975
  if (textarea) {
@@ -1069,14 +983,14 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1069
983
  };
1070
984
  calculateMaxHeight();
1071
985
  }, [maxRows]);
1072
- (0, import_react6.useEffect)(() => {
986
+ (0, import_react5.useEffect)(() => {
1073
987
  const textarea = internalTextareaRef.current;
1074
988
  if (textarea) {
1075
989
  textarea.style.height = "auto";
1076
990
  textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
1077
991
  }
1078
992
  }, [value, maxHeight]);
1079
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
993
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1080
994
  "textarea",
1081
995
  {
1082
996
  ref: internalTextareaRef,
@@ -1085,7 +999,7 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1085
999
  onKeyDown,
1086
1000
  placeholder,
1087
1001
  style: {
1088
- overflow: "hidden",
1002
+ overflow: "auto",
1089
1003
  resize: "none",
1090
1004
  maxHeight: `${maxHeight}px`
1091
1005
  },
@@ -1096,10 +1010,113 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1096
1010
  );
1097
1011
  var Textarea_default = AutoResizingTextarea;
1098
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
+
1099
1113
  // src/components/chat/Input.tsx
1100
- var import_jsx_runtime10 = require("react/jsx-runtime");
1101
- var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1114
+ var import_react_core3 = require("@copilotkit/react-core");
1115
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1116
+ var Input = ({ inProgress, onSend, isVisible = false }) => {
1102
1117
  const context = useChatContext();
1118
+ const copilotContext = (0, import_react_core3.useCopilotContext)();
1119
+ const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
1103
1120
  const textareaRef = (0, import_react7.useRef)(null);
1104
1121
  const handleDivClick = (event) => {
1105
1122
  var _a;
@@ -1122,12 +1139,15 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1122
1139
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1123
1140
  }
1124
1141
  }, [isVisible]);
1125
- const icon = inProgress ? context.icons.activityIcon : context.icons.sendIcon;
1126
- const disabled = inProgress || text.length === 0;
1127
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
1128
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children }),
1129
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitSendButton", disabled, onClick: send, children: icon }),
1130
- /* @__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)(
1131
1151
  Textarea_default,
1132
1152
  {
1133
1153
  ref: textareaRef,
@@ -1143,92 +1163,227 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1143
1163
  }
1144
1164
  }
1145
1165
  }
1146
- )
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
+ ] })
1147
1178
  ] });
1148
1179
  };
1149
1180
 
1150
- // src/components/chat/Chat.tsx
1151
- var import_nanoid2 = require("nanoid");
1152
-
1153
1181
  // src/components/chat/Response.tsx
1154
- var import_jsx_runtime11 = require("react/jsx-runtime");
1182
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1155
1183
  var ResponseButton = ({ onClick, inProgress }) => {
1156
1184
  const context = useChatContext();
1157
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { onClick, className: "copilotKitResponseButton", children: [
1158
- /* @__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 }),
1159
1187
  inProgress ? context.labels.stopGenerating : context.labels.regenerateResponse
1160
1188
  ] });
1161
1189
  };
1162
1190
 
1191
+ // src/components/chat/Suggestion.tsx
1192
+ var import_react_core4 = require("@copilotkit/react-core");
1193
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1194
+ function Suggestion({ title, message, onClick, partial, className }) {
1195
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1196
+ "button",
1197
+ {
1198
+ disabled: partial,
1199
+ onClick: (e) => {
1200
+ e.preventDefault();
1201
+ onClick(message);
1202
+ },
1203
+ className: className || "suggestion",
1204
+ children: [
1205
+ partial && SmallSpinnerIcon,
1206
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: title })
1207
+ ]
1208
+ }
1209
+ );
1210
+ }
1211
+ var reloadSuggestions = (context, chatSuggestionConfiguration, setCurrentSuggestions, abortControllerRef) => __async(void 0, null, function* () {
1212
+ const abortController = abortControllerRef.current;
1213
+ const tools = JSON.stringify(context.getChatCompletionFunctionDescriptions(context.entryPoints));
1214
+ const allSuggestions = [];
1215
+ for (const config of Object.values(chatSuggestionConfiguration)) {
1216
+ try {
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.`;
1218
+ const result = yield (0, import_react_core4.extract)({
1219
+ context,
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,
1221
+ data: "Available tools: " + tools + "\n\n",
1222
+ parameters: [
1223
+ {
1224
+ name: "suggestions",
1225
+ type: "object[]",
1226
+ attributes: [
1227
+ {
1228
+ name: "title",
1229
+ description: "The title of the suggestion. This is shown as a button and should be short.",
1230
+ type: "string"
1231
+ },
1232
+ {
1233
+ name: "message",
1234
+ 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.",
1235
+ type: "string"
1236
+ }
1237
+ ]
1238
+ }
1239
+ ],
1240
+ include: {
1241
+ messages: true,
1242
+ readable: true
1243
+ },
1244
+ abortSignal: abortController == null ? void 0 : abortController.signal,
1245
+ stream: ({ status, args }) => {
1246
+ const suggestions = args.suggestions || [];
1247
+ const newSuggestions = [];
1248
+ for (let i = 0; i < suggestions.length; i++) {
1249
+ if (config.maxSuggestions !== void 0 && i >= config.maxSuggestions) {
1250
+ break;
1251
+ }
1252
+ const { title, message } = suggestions[i];
1253
+ const partial = i == suggestions.length - 1 && status !== "complete";
1254
+ newSuggestions.push({
1255
+ title,
1256
+ message,
1257
+ partial,
1258
+ className: config.className
1259
+ });
1260
+ }
1261
+ setCurrentSuggestions([...allSuggestions, ...newSuggestions]);
1262
+ }
1263
+ });
1264
+ allSuggestions.push(...result.suggestions);
1265
+ } catch (error) {
1266
+ console.error("Error loading suggestions", error);
1267
+ }
1268
+ }
1269
+ if (abortControllerRef.current === abortController) {
1270
+ abortControllerRef.current = null;
1271
+ }
1272
+ });
1273
+
1163
1274
  // src/components/chat/Chat.tsx
1164
- var import_jsx_runtime12 = require("react/jsx-runtime");
1165
- 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({
1166
1280
  instructions,
1167
- defaultOpen = false,
1168
- clickOutsideToClose = true,
1169
- hitEscapeToClose = true,
1170
- onSetOpen,
1171
1281
  onSubmitMessage,
1172
- shortcut = "/",
1173
1282
  icons,
1174
1283
  labels,
1175
1284
  makeSystemMessage,
1176
1285
  showResponseButton = true,
1177
1286
  onInProgress,
1178
- Window: Window2 = Window,
1179
- Button: Button2 = Button,
1180
- Header: Header2 = Header,
1181
1287
  Messages: Messages2 = Messages,
1182
1288
  Input: Input2 = Input,
1183
1289
  ResponseButton: ResponseButton2 = ResponseButton,
1184
- className,
1185
- children
1186
- }) => {
1187
- const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core2.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)({
1188
1327
  id: (0, import_nanoid2.nanoid)(),
1189
1328
  makeSystemMessage,
1190
1329
  additionalInstructions: instructions
1191
1330
  });
1331
+ const [currentSuggestions, setCurrentSuggestions] = (0, import_react8.useState)([]);
1332
+ const suggestionsAbortControllerRef = (0, import_react8.useRef)(null);
1333
+ const debounceTimerRef = (0, import_react8.useRef)();
1334
+ const abortSuggestions = () => {
1335
+ var _a;
1336
+ (_a = suggestionsAbortControllerRef.current) == null ? void 0 : _a.abort();
1337
+ suggestionsAbortControllerRef.current = null;
1338
+ };
1339
+ const context = (0, import_react_core5.useCopilotContext)();
1192
1340
  (0, import_react8.useEffect)(() => {
1193
1341
  onInProgress == null ? void 0 : onInProgress(isLoading);
1194
- }, [isLoading]);
1195
- const [openState, setOpenState] = import_react8.default.useState(defaultOpen);
1196
- const setOpen = (open) => {
1197
- onSetOpen == null ? void 0 : onSetOpen(open);
1198
- setOpenState(open);
1199
- };
1200
- const sendMessage = (message) => __async(void 0, null, function* () {
1201
- onSubmitMessage == null ? void 0 : onSubmitMessage(message);
1202
- append({
1342
+ abortSuggestions();
1343
+ debounceTimerRef.current = setTimeout(
1344
+ () => {
1345
+ if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) {
1346
+ suggestionsAbortControllerRef.current = new AbortController();
1347
+ reloadSuggestions(
1348
+ context,
1349
+ context.chatSuggestionConfiguration,
1350
+ setCurrentSuggestions,
1351
+ suggestionsAbortControllerRef
1352
+ );
1353
+ }
1354
+ },
1355
+ currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT
1356
+ );
1357
+ return () => {
1358
+ clearTimeout(debounceTimerRef.current);
1359
+ };
1360
+ }, [isLoading, context.chatSuggestionConfiguration]);
1361
+ const sendMessage = (messageContent) => __async(void 0, null, function* () {
1362
+ abortSuggestions();
1363
+ setCurrentSuggestions([]);
1364
+ onSubmitMessage == null ? void 0 : onSubmitMessage(messageContent);
1365
+ const message = {
1203
1366
  id: (0, import_nanoid2.nanoid)(),
1204
- content: message,
1367
+ content: messageContent,
1205
1368
  role: "user"
1206
- });
1369
+ };
1370
+ append(message);
1371
+ return message;
1207
1372
  });
1208
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ChatContextProvider, { icons, labels, open: openState, setOpen: setOpenState, children: [
1209
- children,
1210
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className, children: [
1211
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button2, { open: openState, setOpen }),
1212
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1213
- Window2,
1214
- {
1215
- open: openState,
1216
- setOpen,
1217
- clickOutsideToClose,
1218
- shortcut,
1219
- hitEscapeToClose,
1220
- children: [
1221
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Header2, { open: openState, setOpen }),
1222
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Messages2, { messages: visibleMessages, inProgress: isLoading }),
1223
- /* @__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 }) })
1224
- ]
1225
- }
1226
- )
1227
- ] })
1228
- ] });
1373
+ return {
1374
+ visibleMessages,
1375
+ isLoading,
1376
+ currentSuggestions,
1377
+ sendMessage,
1378
+ stop,
1379
+ reload,
1380
+ input,
1381
+ setInput
1382
+ };
1229
1383
  };
1230
1384
  // Annotate the CommonJS export names for ESM import in node:
1231
1385
  0 && (module.exports = {
1232
- CopilotChat
1386
+ CopilotChat,
1387
+ useCopilotChatLogic
1233
1388
  });
1234
1389
  //# sourceMappingURL=Chat.js.map