@copilotkit/react-ui 1.55.3 → 1.56.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.
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import * as React$1 from "react";
4
4
  import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { defaultCopilotContextCategories, shouldShowDevConsole, useCopilotChatInternal, useCopilotChatSuggestions as useCopilotChatSuggestions$1, useCopilotContext, useCopilotMessagesContext } from "@copilotkit/react-core";
7
- import { COPILOTKIT_VERSION, CopilotKitError, CopilotKitErrorCode, ErrorVisibility, Severity, exceedsMaxSize, formatFileSize, formatFileSize as formatFileSize$1, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, isMacOS, matchesAcceptFilter, randomUUID, readFileAsBase64, styledConsole } from "@copilotkit/shared";
7
+ import { COPILOTKIT_VERSION, CopilotKitError, CopilotKitErrorCode, ErrorVisibility, Severity, copyToClipboard, exceedsMaxSize, formatFileSize, formatFileSize as formatFileSize$1, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, isMacOS, matchesAcceptFilter, randomUUID, readFileAsBase64, styledConsole } from "@copilotkit/shared";
8
8
  import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
9
9
  import ReactMarkdown from "react-markdown";
10
10
  import { Light, Prism } from "react-syntax-highlighter";
@@ -761,10 +761,11 @@ function CopilotDevConsole() {
761
761
  });
762
762
  };
763
763
  useEffect(() => {
764
+ if (!showDevConsole) return;
764
765
  if (dontRunTwiceInDevMode.current === true) return;
765
766
  dontRunTwiceInDevMode.current = true;
766
767
  checkForUpdates();
767
- }, []);
768
+ }, [showDevConsole]);
768
769
  if (!showDevConsole) return null;
769
770
  return /* @__PURE__ */ jsxs("div", {
770
771
  ref: consoleRef,
@@ -806,11 +807,11 @@ function VersionInfo({ showDevConsole, versionStatus, currentVersion, latestVers
806
807
  `@copilotkit/react-textarea@${latestVersion}`,
807
808
  `&& npm install @copilotkit/runtime@${latestVersion}`
808
809
  ].join(" ");
809
- const handleCopyClick = () => {
810
- navigator.clipboard.writeText(installCommand.trim()).then(() => {
810
+ const handleCopyClick = async () => {
811
+ if (await copyToClipboard(installCommand.trim())) {
811
812
  setCopyStatus("Command copied to clipboard!");
812
813
  setTimeout(() => setCopyStatus(""), 1e3);
813
- });
814
+ }
814
815
  };
815
816
  if (versionStatus === "update-available" || versionStatus === "outdated") return /* @__PURE__ */ jsxs("div", {
816
817
  className: "copilotKitVersionInfo",
@@ -1306,7 +1307,7 @@ const defaultComponents = {
1306
1307
  language: match && match[1] || "",
1307
1308
  value: String(children).replace(/\n$/, ""),
1308
1309
  ...props
1309
- }, Math.random());
1310
+ });
1310
1311
  },
1311
1312
  h1: ({ children, ...props }) => /* @__PURE__ */ jsx("h1", {
1312
1313
  className: "copilotKitMarkdownElement",
@@ -1338,8 +1339,8 @@ const defaultComponents = {
1338
1339
  ...props,
1339
1340
  children
1340
1341
  }),
1341
- p: ({ children, ...props }) => /* @__PURE__ */ jsx("p", {
1342
- className: "copilotKitMarkdownElement",
1342
+ p: ({ children, ...props }) => /* @__PURE__ */ jsx("div", {
1343
+ className: "copilotKitMarkdownElement copilotKitParagraph",
1343
1344
  ...props,
1344
1345
  children
1345
1346
  }),
@@ -1364,8 +1365,8 @@ const defaultComponents = {
1364
1365
  children
1365
1366
  })
1366
1367
  };
1367
- const MemoizedReactMarkdown = memo(ReactMarkdown, (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components);
1368
- const Markdown = ({ content, components }) => {
1368
+ const MemoizedReactMarkdown = memo(ReactMarkdown, (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components && prevProps.urlTransform === nextProps.urlTransform);
1369
+ const Markdown = ({ content, components, urlTransform }) => {
1369
1370
  return /* @__PURE__ */ jsx("div", {
1370
1371
  className: "copilotKitMarkdown",
1371
1372
  children: /* @__PURE__ */ jsx(MemoizedReactMarkdown, {
@@ -1375,6 +1376,7 @@ const Markdown = ({ content, components }) => {
1375
1376
  }), [components]),
1376
1377
  remarkPlugins: [remarkGfm, [remarkMath, { singleDollarTextMath: false }]],
1377
1378
  rehypePlugins: [rehypeRaw],
1379
+ ...urlTransform !== void 0 ? { urlTransform } : {},
1378
1380
  children: content
1379
1381
  })
1380
1382
  });
@@ -1386,16 +1388,12 @@ const AssistantMessage = (props) => {
1386
1388
  const { icons, labels } = useChatContext();
1387
1389
  const { message, isLoading, onRegenerate, onCopy, onThumbsUp, onThumbsDown, isCurrentMessage, feedback, markdownTagRenderers } = props;
1388
1390
  const [copied, setCopied] = useState(false);
1389
- const handleCopy = () => {
1391
+ const handleCopy = async () => {
1390
1392
  const content = message?.content || "";
1391
- if (content && onCopy) {
1392
- navigator.clipboard.writeText(content);
1393
- setCopied(true);
1394
- onCopy(content);
1395
- setTimeout(() => setCopied(false), 2e3);
1396
- } else if (content) {
1397
- navigator.clipboard.writeText(content);
1393
+ if (!content) return;
1394
+ if (await copyToClipboard(content)) {
1398
1395
  setCopied(true);
1396
+ if (onCopy) onCopy(content);
1399
1397
  setTimeout(() => setCopied(false), 2e3);
1400
1398
  }
1401
1399
  };
@@ -1673,7 +1671,7 @@ const Messages = ({ inProgress, children, RenderMessage, AssistantMessage, UserM
1673
1671
  markdownTagRenderers
1674
1672
  }, index);
1675
1673
  }),
1676
- messages[messages.length - 1]?.role === "user" && inProgress && /* @__PURE__ */ jsx(LoadingIcon, {}),
1674
+ inProgress && (messages[messages.length - 1]?.role === "user" || messages[messages.length - 1]?.role === "tool") && /* @__PURE__ */ jsx(LoadingIcon, {}),
1677
1675
  interrupt,
1678
1676
  chatError && ErrorMessage && /* @__PURE__ */ jsx(ErrorMessage, {
1679
1677
  error: chatError,
@@ -1812,13 +1810,18 @@ const startRecording = async (mediaStreamRef, mediaRecorderRef, audioContextRef,
1812
1810
  };
1813
1811
  mediaRecorderRef.current.onstop = onStop;
1814
1812
  };
1815
- const stopRecording = (mediaRecorderRef) => {
1813
+ const stopRecording = (mediaRecorderRef, mediaStreamRef) => {
1816
1814
  if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") mediaRecorderRef.current.stop();
1815
+ if (mediaStreamRef?.current) {
1816
+ mediaStreamRef.current.getTracks().forEach((track) => track.stop());
1817
+ mediaStreamRef.current = null;
1818
+ }
1817
1819
  };
1818
- const transcribeAudio = async (recordedChunks, transcribeAudioUrl) => {
1819
- const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
1820
+ const transcribeAudio = async (recordedChunks, transcribeAudioUrl, mediaType = "audio/mp4") => {
1821
+ const extension = mediaType.split("/")[1] || "mp4";
1822
+ const completeBlob = new Blob(recordedChunks, { type: mediaType });
1820
1823
  const formData = new FormData();
1821
- formData.append("file", completeBlob, "recording.mp4");
1824
+ formData.append("file", completeBlob, `recording.${extension}`);
1822
1825
  const response = await fetch(transcribeAudioUrl, {
1823
1826
  method: "POST",
1824
1827
  body: formData
@@ -1837,7 +1840,7 @@ const playAudioResponse = (text, textToSpeechUrl, audioContext) => {
1837
1840
  console.error("Error with decoding audio data", error);
1838
1841
  });
1839
1842
  };
1840
- const usePushToTalk = ({ sendFunction, inProgress }) => {
1843
+ const usePushToTalk = ({ sendFunction, inProgress, mediaType = "audio/mp4" }) => {
1841
1844
  const [pushToTalkState, setPushToTalkState] = useState("idle");
1842
1845
  const mediaStreamRef = useRef(null);
1843
1846
  const audioContextRef = useRef(null);
@@ -1855,15 +1858,16 @@ const usePushToTalk = ({ sendFunction, inProgress }) => {
1855
1858
  setPushToTalkState("transcribing");
1856
1859
  });
1857
1860
  else {
1858
- stopRecording(mediaRecorderRef);
1859
- if (pushToTalkState === "transcribing") transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(async (transcription) => {
1861
+ stopRecording(mediaRecorderRef, mediaStreamRef);
1862
+ if (pushToTalkState === "transcribing") transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl, mediaType).then(async (transcription) => {
1860
1863
  recordedChunks.current = [];
1861
1864
  setPushToTalkState("idle");
1862
- setStartReadingFromMessageId((await sendFunction(transcription)).id);
1865
+ const message = await sendFunction(transcription);
1866
+ if (message) setStartReadingFromMessageId(message.id);
1863
1867
  });
1864
1868
  }
1865
1869
  return () => {
1866
- stopRecording(mediaRecorderRef);
1870
+ stopRecording(mediaRecorderRef, mediaStreamRef);
1867
1871
  };
1868
1872
  }, [pushToTalkState]);
1869
1873
  useEffect(() => {
@@ -2938,5 +2942,5 @@ function useCopilotChatSuggestions(config, dependencies = []) {
2938
2942
  }
2939
2943
 
2940
2944
  //#endregion
2941
- export { AssistantMessage, CopilotChat, CopilotDevConsole, CopilotPopup, CopilotSidebar, ImageRenderer, Markdown, Suggestion as RenderSuggestion, Suggestions as RenderSuggestionsList, UserMessage, shouldShowDevConsole, suppressDeprecationWarnings, useChatContext, useCopilotChatSuggestions };
2945
+ export { AssistantMessage, CopilotChat, CopilotDevConsole, CopilotModal, CopilotPopup, CopilotSidebar, ImageRenderer, Markdown, Suggestion as RenderSuggestion, Suggestions as RenderSuggestionsList, UserMessage, shouldShowDevConsole, suppressDeprecationWarnings, useChatContext, useCopilotChatSuggestions };
2942
2946
  //# sourceMappingURL=index.mjs.map