@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
@@ -83,8 +83,8 @@ __export(Popup_exports, {
83
83
  });
84
84
  module.exports = __toCommonJS(Popup_exports);
85
85
 
86
- // src/components/chat/Chat.tsx
87
- var import_react8 = __toESM(require("react"));
86
+ // src/components/chat/Modal.tsx
87
+ var import_react10 = __toESM(require("react"));
88
88
 
89
89
  // src/components/chat/ChatContext.tsx
90
90
  var import_react = __toESM(require("react"));
@@ -190,6 +190,40 @@ var SpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
190
190
  ]
191
191
  }
192
192
  );
193
+ var SmallSpinnerIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
194
+ "svg",
195
+ {
196
+ style: {
197
+ animation: "copilotKitSpinAnimation 1s linear infinite"
198
+ },
199
+ width: "13",
200
+ height: "13",
201
+ xmlns: "http://www.w3.org/2000/svg",
202
+ fill: "none",
203
+ viewBox: "0 0 24 24",
204
+ children: [
205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
206
+ "circle",
207
+ {
208
+ style: { opacity: 0.25 },
209
+ cx: "12",
210
+ cy: "12",
211
+ r: "10",
212
+ stroke: "currentColor",
213
+ strokeWidth: "4"
214
+ }
215
+ ),
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
217
+ "path",
218
+ {
219
+ style: { opacity: 0.75 },
220
+ fill: "currentColor",
221
+ 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"
222
+ }
223
+ )
224
+ ]
225
+ }
226
+ );
193
227
  var ActivityIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
194
228
  "svg",
195
229
  {
@@ -275,6 +309,25 @@ var RegenerateIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
275
309
  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" })
276
310
  }
277
311
  );
312
+ var PushToTalkIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
313
+ "svg",
314
+ {
315
+ xmlns: "http://www.w3.org/2000/svg",
316
+ fill: "none",
317
+ viewBox: "0 0 24 24",
318
+ strokeWidth: 1.5,
319
+ stroke: "currentColor",
320
+ className: "w-6 h-6",
321
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
322
+ "path",
323
+ {
324
+ strokeLinecap: "round",
325
+ strokeLinejoin: "round",
326
+ 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"
327
+ }
328
+ )
329
+ }
330
+ );
278
331
 
279
332
  // src/components/chat/ChatContext.tsx
280
333
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -298,40 +351,34 @@ var ChatContextProvider = ({
298
351
  open,
299
352
  setOpen
300
353
  }) => {
301
- const context = (0, import_react.useMemo)(
302
- () => ({
303
- labels: __spreadValues(__spreadValues({}, {
304
- initial: "",
305
- title: "CopilotKit",
306
- placeholder: "Type a message...",
307
- thinking: "Thinking...",
308
- error: "\u274C An error occurred. Please try again.",
309
- stopGenerating: "Stop generating",
310
- regenerateResponse: "Regenerate response"
311
- }), labels),
312
- icons: __spreadProps(__spreadValues({}, {
313
- openIcon: OpenIcon,
314
- closeIcon: CloseIcon,
315
- headerCloseIcon: HeaderCloseIcon,
316
- sendIcon: SendIcon,
317
- activityIcon: ActivityIcon,
318
- spinnerIcon: SpinnerIcon,
319
- stopIcon: StopIcon,
320
- regenerateIcon: RegenerateIcon
321
- }), {
322
- icons
323
- }),
324
- open,
325
- setOpen
354
+ const context = {
355
+ labels: __spreadValues(__spreadValues({}, {
356
+ initial: "",
357
+ title: "CopilotKit",
358
+ placeholder: "Type a message...",
359
+ error: "\u274C An error occurred. Please try again.",
360
+ stopGenerating: "Stop generating",
361
+ regenerateResponse: "Regenerate response"
362
+ }), labels),
363
+ icons: __spreadProps(__spreadValues({}, {
364
+ openIcon: OpenIcon,
365
+ closeIcon: CloseIcon,
366
+ headerCloseIcon: HeaderCloseIcon,
367
+ sendIcon: SendIcon,
368
+ activityIcon: ActivityIcon,
369
+ spinnerIcon: SpinnerIcon,
370
+ stopIcon: StopIcon,
371
+ regenerateIcon: RegenerateIcon,
372
+ pushToTalkIcon: PushToTalkIcon
373
+ }), {
374
+ icons
326
375
  }),
327
- [labels, icons, open, setOpen]
328
- );
376
+ open,
377
+ setOpen
378
+ };
329
379
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatContext.Provider, { value: context, children });
330
380
  };
331
381
 
332
- // src/components/chat/Chat.tsx
333
- var import_react_core2 = require("@copilotkit/react-core");
334
-
335
382
  // src/components/chat/Window.tsx
336
383
  var import_react2 = __toESM(require("react"));
337
384
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -941,7 +988,7 @@ var components = {
941
988
  // src/components/chat/Messages.tsx
942
989
  var import_react_core = require("@copilotkit/react-core");
943
990
  var import_jsx_runtime8 = require("react/jsx-runtime");
944
- var Messages = ({ messages, inProgress }) => {
991
+ var Messages = ({ messages, inProgress, children }) => {
945
992
  const { chatComponentsCache } = (0, import_react_core.useCopilotContext)();
946
993
  const context = useChatContext();
947
994
  const initialMessages = (0, import_react5.useMemo)(
@@ -1027,7 +1074,7 @@ var Messages = ({ messages, inProgress }) => {
1027
1074
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Markdown, { content: message.content }) }, index);
1028
1075
  }
1029
1076
  }),
1030
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: messagesEndRef })
1077
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { ref: messagesEndRef, children })
1031
1078
  ] });
1032
1079
  };
1033
1080
  function makeInitialMessages(initial) {
@@ -1047,7 +1094,7 @@ function makeInitialMessages(initial) {
1047
1094
  }
1048
1095
 
1049
1096
  // src/components/chat/Input.tsx
1050
- var import_react7 = require("react");
1097
+ var import_react8 = require("react");
1051
1098
 
1052
1099
  // src/components/chat/Textarea.tsx
1053
1100
  var import_react6 = require("react");
@@ -1087,7 +1134,7 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1087
1134
  onKeyDown,
1088
1135
  placeholder,
1089
1136
  style: {
1090
- overflow: "hidden",
1137
+ overflow: "auto",
1091
1138
  resize: "none",
1092
1139
  maxHeight: `${maxHeight}px`
1093
1140
  },
@@ -1098,18 +1145,121 @@ var AutoResizingTextarea = (0, import_react6.forwardRef)(
1098
1145
  );
1099
1146
  var Textarea_default = AutoResizingTextarea;
1100
1147
 
1148
+ // src/hooks/use-push-to-talk.tsx
1149
+ var import_react_core2 = require("@copilotkit/react-core");
1150
+ var import_react7 = require("react");
1151
+ var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
1152
+ if (!mediaStreamRef.current || !audioContextRef.current) {
1153
+ mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
1154
+ audioContextRef.current = new window.AudioContext();
1155
+ yield audioContextRef.current.resume();
1156
+ }
1157
+ mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
1158
+ mediaRecorderRef.current.start(1e3);
1159
+ mediaRecorderRef.current.ondataavailable = (event) => {
1160
+ recordedChunks.push(event.data);
1161
+ };
1162
+ mediaRecorderRef.current.onstop = onStop;
1163
+ });
1164
+ var stopRecording = (mediaRecorderRef) => {
1165
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
1166
+ mediaRecorderRef.current.stop();
1167
+ }
1168
+ };
1169
+ var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
1170
+ const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
1171
+ const formData = new FormData();
1172
+ formData.append("file", completeBlob, "recording.mp4");
1173
+ const response = yield fetch(transcribeAudioUrl, {
1174
+ method: "POST",
1175
+ body: formData
1176
+ });
1177
+ if (!response.ok) {
1178
+ throw new Error(`Error: ${response.statusText}`);
1179
+ }
1180
+ const transcription = yield response.json();
1181
+ return transcription.text;
1182
+ });
1183
+ var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
1184
+ const encodedText = encodeURIComponent(text);
1185
+ const url = `${textToSpeechUrl}?text=${encodedText}`;
1186
+ fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
1187
+ const source = audioContext.createBufferSource();
1188
+ source.buffer = audioBuffer;
1189
+ source.connect(audioContext.destination);
1190
+ source.start(0);
1191
+ }).catch((error) => {
1192
+ console.error("Error with decoding audio data", error);
1193
+ });
1194
+ };
1195
+ var usePushToTalk = ({
1196
+ sendFunction,
1197
+ inProgress
1198
+ }) => {
1199
+ const [pushToTalkState, setPushToTalkState] = (0, import_react7.useState)("idle");
1200
+ const mediaStreamRef = (0, import_react7.useRef)(null);
1201
+ const audioContextRef = (0, import_react7.useRef)(null);
1202
+ const mediaRecorderRef = (0, import_react7.useRef)(null);
1203
+ const recordedChunks = (0, import_react7.useRef)([]);
1204
+ const context = (0, import_react_core2.useCopilotContext)();
1205
+ const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react7.useState)(null);
1206
+ (0, import_react7.useEffect)(() => {
1207
+ if (pushToTalkState === "recording") {
1208
+ startRecording(
1209
+ mediaStreamRef,
1210
+ mediaRecorderRef,
1211
+ audioContextRef,
1212
+ recordedChunks.current,
1213
+ () => {
1214
+ setPushToTalkState("transcribing");
1215
+ }
1216
+ );
1217
+ } else {
1218
+ stopRecording(mediaRecorderRef);
1219
+ if (pushToTalkState === "transcribing") {
1220
+ transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
1221
+ (transcription) => __async(void 0, null, function* () {
1222
+ recordedChunks.current = [];
1223
+ setPushToTalkState("idle");
1224
+ const message = yield sendFunction(transcription);
1225
+ setStartReadingFromMessageId(message.id);
1226
+ })
1227
+ );
1228
+ }
1229
+ }
1230
+ return () => {
1231
+ stopRecording(mediaRecorderRef);
1232
+ };
1233
+ }, [pushToTalkState]);
1234
+ (0, import_react7.useEffect)(() => {
1235
+ if (inProgress === false && startReadingFromMessageId) {
1236
+ const lastMessageIndex = context.messages.findIndex(
1237
+ (message) => message.id === startReadingFromMessageId
1238
+ );
1239
+ const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant" && message.content);
1240
+ const text = messagesAfterLast.map((message) => message.content).join("\n");
1241
+ playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
1242
+ setStartReadingFromMessageId(null);
1243
+ }
1244
+ }, [startReadingFromMessageId, inProgress]);
1245
+ return { pushToTalkState, setPushToTalkState };
1246
+ };
1247
+
1101
1248
  // src/components/chat/Input.tsx
1249
+ var import_react_core3 = require("@copilotkit/react-core");
1102
1250
  var import_jsx_runtime10 = require("react/jsx-runtime");
1103
- var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1251
+ var Input = ({ inProgress, onSend, isVisible = false }) => {
1104
1252
  const context = useChatContext();
1105
- const textareaRef = (0, import_react7.useRef)(null);
1253
+ const copilotContext = (0, import_react_core3.useCopilotContext)();
1254
+ const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
1255
+ const textareaRef = (0, import_react8.useRef)(null);
1106
1256
  const handleDivClick = (event) => {
1107
1257
  var _a;
1108
1258
  if (event.target !== event.currentTarget)
1109
1259
  return;
1110
1260
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1111
1261
  };
1112
- const [text, setText] = (0, import_react7.useState)("");
1262
+ const [text, setText] = (0, import_react8.useState)("");
1113
1263
  const send = () => {
1114
1264
  var _a;
1115
1265
  if (inProgress)
@@ -1118,17 +1268,20 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1118
1268
  setText("");
1119
1269
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1120
1270
  };
1121
- (0, import_react7.useEffect)(() => {
1271
+ (0, import_react8.useEffect)(() => {
1122
1272
  var _a;
1123
1273
  if (isVisible) {
1124
1274
  (_a = textareaRef.current) == null ? void 0 : _a.focus();
1125
1275
  }
1126
1276
  }, [isVisible]);
1127
- const icon = inProgress ? context.icons.activityIcon : context.icons.sendIcon;
1128
- const disabled = inProgress || text.length === 0;
1277
+ const { pushToTalkState, setPushToTalkState } = usePushToTalk({
1278
+ sendFunction: onSend,
1279
+ inProgress
1280
+ });
1281
+ const sendIcon = inProgress || pushToTalkState === "transcribing" ? context.icons.activityIcon : context.icons.sendIcon;
1282
+ const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
1283
+ const sendDisabled = inProgress || text.length === 0 || pushToTalkState !== "idle";
1129
1284
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
1130
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children }),
1131
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "copilotKitSendButton", disabled, onClick: send, children: icon }),
1132
1285
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1133
1286
  Textarea_default,
1134
1287
  {
@@ -1145,13 +1298,21 @@ var Input = ({ inProgress, onSend, children, isVisible = false }) => {
1145
1298
  }
1146
1299
  }
1147
1300
  }
1148
- )
1301
+ ),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitInputControls", children: [
1303
+ showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1304
+ "button",
1305
+ {
1306
+ onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
1307
+ className: pushToTalkState === "recording" ? "copilotKitPushToTalkRecording" : "",
1308
+ children: context.icons.pushToTalkIcon
1309
+ }
1310
+ ),
1311
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { disabled: sendDisabled, onClick: send, children: sendIcon })
1312
+ ] })
1149
1313
  ] });
1150
1314
  };
1151
1315
 
1152
- // src/components/chat/Chat.tsx
1153
- var import_nanoid2 = require("nanoid");
1154
-
1155
1316
  // src/components/chat/Response.tsx
1156
1317
  var import_jsx_runtime11 = require("react/jsx-runtime");
1157
1318
  var ResponseButton = ({ onClick, inProgress }) => {
@@ -1162,9 +1323,203 @@ var ResponseButton = ({ onClick, inProgress }) => {
1162
1323
  ] });
1163
1324
  };
1164
1325
 
1165
- // src/components/chat/Chat.tsx
1326
+ // src/components/chat/Suggestion.tsx
1327
+ var import_react_core4 = require("@copilotkit/react-core");
1166
1328
  var import_jsx_runtime12 = require("react/jsx-runtime");
1167
- var CopilotChat = ({
1329
+ function Suggestion({ title, message, onClick, partial, className }) {
1330
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1331
+ "button",
1332
+ {
1333
+ disabled: partial,
1334
+ onClick: (e) => {
1335
+ e.preventDefault();
1336
+ onClick(message);
1337
+ },
1338
+ className: className || "suggestion",
1339
+ children: [
1340
+ partial && SmallSpinnerIcon,
1341
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: title })
1342
+ ]
1343
+ }
1344
+ );
1345
+ }
1346
+ var reloadSuggestions = (context, chatSuggestionConfiguration, setCurrentSuggestions, abortControllerRef) => __async(void 0, null, function* () {
1347
+ const abortController = abortControllerRef.current;
1348
+ const tools = JSON.stringify(context.getChatCompletionFunctionDescriptions(context.entryPoints));
1349
+ const allSuggestions = [];
1350
+ for (const config of Object.values(chatSuggestionConfiguration)) {
1351
+ try {
1352
+ 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.`;
1353
+ const result = yield (0, import_react_core4.extract)({
1354
+ context,
1355
+ instructions: "Suggest what the user could say next. Provide clear, highly relevant suggestions. Do not literally suggest function calls. " + config.instructions + "\n\n" + numOfSuggestionsInstructions,
1356
+ data: "Available tools: " + tools + "\n\n",
1357
+ parameters: [
1358
+ {
1359
+ name: "suggestions",
1360
+ type: "object[]",
1361
+ attributes: [
1362
+ {
1363
+ name: "title",
1364
+ description: "The title of the suggestion. This is shown as a button and should be short.",
1365
+ type: "string"
1366
+ },
1367
+ {
1368
+ name: "message",
1369
+ 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.",
1370
+ type: "string"
1371
+ }
1372
+ ]
1373
+ }
1374
+ ],
1375
+ include: {
1376
+ messages: true,
1377
+ readable: true
1378
+ },
1379
+ abortSignal: abortController == null ? void 0 : abortController.signal,
1380
+ stream: ({ status, args }) => {
1381
+ const suggestions = args.suggestions || [];
1382
+ const newSuggestions = [];
1383
+ for (let i = 0; i < suggestions.length; i++) {
1384
+ if (config.maxSuggestions !== void 0 && i >= config.maxSuggestions) {
1385
+ break;
1386
+ }
1387
+ const { title, message } = suggestions[i];
1388
+ const partial = i == suggestions.length - 1 && status !== "complete";
1389
+ newSuggestions.push({
1390
+ title,
1391
+ message,
1392
+ partial,
1393
+ className: config.className
1394
+ });
1395
+ }
1396
+ setCurrentSuggestions([...allSuggestions, ...newSuggestions]);
1397
+ }
1398
+ });
1399
+ allSuggestions.push(...result.suggestions);
1400
+ } catch (error) {
1401
+ console.error("Error loading suggestions", error);
1402
+ }
1403
+ }
1404
+ if (abortControllerRef.current === abortController) {
1405
+ abortControllerRef.current = null;
1406
+ }
1407
+ });
1408
+
1409
+ // src/components/chat/Chat.tsx
1410
+ var import_react9 = __toESM(require("react"));
1411
+ var import_react_core5 = require("@copilotkit/react-core");
1412
+ var import_nanoid2 = require("nanoid");
1413
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1414
+ function CopilotChat({
1415
+ instructions,
1416
+ onSubmitMessage,
1417
+ icons,
1418
+ labels,
1419
+ makeSystemMessage,
1420
+ showResponseButton = true,
1421
+ onInProgress,
1422
+ Messages: Messages2 = Messages,
1423
+ Input: Input2 = Input,
1424
+ ResponseButton: ResponseButton2 = ResponseButton,
1425
+ className
1426
+ }) {
1427
+ const { visibleMessages, isLoading, currentSuggestions, sendMessage, stop, reload } = useCopilotChatLogic(instructions, makeSystemMessage, onInProgress, onSubmitMessage);
1428
+ const context = import_react9.default.useContext(ChatContext);
1429
+ let open = true;
1430
+ let setOpen = () => {
1431
+ };
1432
+ if (context) {
1433
+ icons = context.icons;
1434
+ labels = context.labels;
1435
+ open = context.open;
1436
+ setOpen = context.setOpen;
1437
+ }
1438
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChatContextProvider, { icons, labels, open, setOpen, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `copilotKitPanel ${className}`, children: [
1439
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Messages2, { messages: visibleMessages, inProgress: isLoading, children: [
1440
+ currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
1441
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h6", { children: "Suggested:" }),
1442
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1443
+ Suggestion,
1444
+ {
1445
+ title: suggestion.title,
1446
+ message: suggestion.message,
1447
+ partial: suggestion.partial,
1448
+ className: suggestion.className,
1449
+ onClick: (message) => sendMessage(message)
1450
+ },
1451
+ index
1452
+ )) })
1453
+ ] }),
1454
+ showResponseButton && visibleMessages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ResponseButton2, { onClick: isLoading ? stop : reload, inProgress: isLoading })
1455
+ ] }),
1456
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Input2, { inProgress: isLoading, onSend: sendMessage, isVisible: true })
1457
+ ] }) });
1458
+ }
1459
+ var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3;
1460
+ var useCopilotChatLogic = (instructions, makeSystemMessage, onInProgress, onSubmitMessage) => {
1461
+ const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core5.useCopilotChat)({
1462
+ id: (0, import_nanoid2.nanoid)(),
1463
+ makeSystemMessage,
1464
+ additionalInstructions: instructions
1465
+ });
1466
+ const [currentSuggestions, setCurrentSuggestions] = (0, import_react9.useState)([]);
1467
+ const suggestionsAbortControllerRef = (0, import_react9.useRef)(null);
1468
+ const debounceTimerRef = (0, import_react9.useRef)();
1469
+ const abortSuggestions = () => {
1470
+ var _a;
1471
+ (_a = suggestionsAbortControllerRef.current) == null ? void 0 : _a.abort();
1472
+ suggestionsAbortControllerRef.current = null;
1473
+ };
1474
+ const context = (0, import_react_core5.useCopilotContext)();
1475
+ (0, import_react9.useEffect)(() => {
1476
+ onInProgress == null ? void 0 : onInProgress(isLoading);
1477
+ abortSuggestions();
1478
+ debounceTimerRef.current = setTimeout(
1479
+ () => {
1480
+ if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) {
1481
+ suggestionsAbortControllerRef.current = new AbortController();
1482
+ reloadSuggestions(
1483
+ context,
1484
+ context.chatSuggestionConfiguration,
1485
+ setCurrentSuggestions,
1486
+ suggestionsAbortControllerRef
1487
+ );
1488
+ }
1489
+ },
1490
+ currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT
1491
+ );
1492
+ return () => {
1493
+ clearTimeout(debounceTimerRef.current);
1494
+ };
1495
+ }, [isLoading, context.chatSuggestionConfiguration]);
1496
+ const sendMessage = (messageContent) => __async(void 0, null, function* () {
1497
+ abortSuggestions();
1498
+ setCurrentSuggestions([]);
1499
+ onSubmitMessage == null ? void 0 : onSubmitMessage(messageContent);
1500
+ const message = {
1501
+ id: (0, import_nanoid2.nanoid)(),
1502
+ content: messageContent,
1503
+ role: "user"
1504
+ };
1505
+ append(message);
1506
+ return message;
1507
+ });
1508
+ return {
1509
+ visibleMessages,
1510
+ isLoading,
1511
+ currentSuggestions,
1512
+ sendMessage,
1513
+ stop,
1514
+ reload,
1515
+ input,
1516
+ setInput
1517
+ };
1518
+ };
1519
+
1520
+ // src/components/chat/Modal.tsx
1521
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1522
+ var CopilotModal = ({
1168
1523
  instructions,
1169
1524
  defaultOpen = false,
1170
1525
  clickOutsideToClose = true,
@@ -1186,32 +1541,16 @@ var CopilotChat = ({
1186
1541
  className,
1187
1542
  children
1188
1543
  }) => {
1189
- const { visibleMessages, append, reload, stop, isLoading, input, setInput } = (0, import_react_core2.useCopilotChat)({
1190
- id: (0, import_nanoid2.nanoid)(),
1191
- makeSystemMessage,
1192
- additionalInstructions: instructions
1193
- });
1194
- (0, import_react8.useEffect)(() => {
1195
- onInProgress == null ? void 0 : onInProgress(isLoading);
1196
- }, [isLoading]);
1197
- const [openState, setOpenState] = import_react8.default.useState(defaultOpen);
1544
+ const [openState, setOpenState] = import_react10.default.useState(defaultOpen);
1198
1545
  const setOpen = (open) => {
1199
1546
  onSetOpen == null ? void 0 : onSetOpen(open);
1200
1547
  setOpenState(open);
1201
1548
  };
1202
- const sendMessage = (message) => __async(void 0, null, function* () {
1203
- onSubmitMessage == null ? void 0 : onSubmitMessage(message);
1204
- append({
1205
- id: (0, import_nanoid2.nanoid)(),
1206
- content: message,
1207
- role: "user"
1208
- });
1209
- });
1210
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(ChatContextProvider, { icons, labels, open: openState, setOpen: setOpenState, children: [
1549
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(ChatContextProvider, { icons, labels, open: openState, setOpen: setOpenState, children: [
1211
1550
  children,
1212
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className, children: [
1213
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button2, { open: openState, setOpen }),
1214
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1551
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className, children: [
1552
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button2, { open: openState, setOpen }),
1553
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1215
1554
  Window2,
1216
1555
  {
1217
1556
  open: openState,
@@ -1220,9 +1559,20 @@ var CopilotChat = ({
1220
1559
  shortcut,
1221
1560
  hitEscapeToClose,
1222
1561
  children: [
1223
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Header2, { open: openState, setOpen }),
1224
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Messages2, { messages: visibleMessages, inProgress: isLoading }),
1225
- /* @__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 }) })
1562
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Header2, { open: openState, setOpen }),
1563
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1564
+ CopilotChat,
1565
+ {
1566
+ instructions,
1567
+ makeSystemMessage,
1568
+ onInProgress,
1569
+ onSubmitMessage,
1570
+ showResponseButton,
1571
+ Messages: Messages2,
1572
+ Input: Input2,
1573
+ ResponseButton: ResponseButton2
1574
+ }
1575
+ )
1226
1576
  ]
1227
1577
  }
1228
1578
  )
@@ -1231,13 +1581,13 @@ var CopilotChat = ({
1231
1581
  };
1232
1582
 
1233
1583
  // src/components/chat/Popup.tsx
1234
- var import_jsx_runtime13 = require("react/jsx-runtime");
1235
- var CopilotPopup = (props) => {
1584
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1585
+ function CopilotPopup(props) {
1236
1586
  props = __spreadProps(__spreadValues({}, props), {
1237
1587
  className: props.className ? props.className + " copilotKitPopup" : "copilotKitPopup"
1238
1588
  });
1239
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CopilotChat, __spreadProps(__spreadValues({}, props), { children: props.children }));
1240
- };
1589
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CopilotModal, __spreadProps(__spreadValues({}, props), { children: props.children }));
1590
+ }
1241
1591
  // Annotate the CommonJS export names for ESM import in node:
1242
1592
  0 && (module.exports = {
1243
1593
  CopilotPopup