@usecrow/ui 0.1.12 → 0.1.14

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.cjs CHANGED
@@ -1036,6 +1036,12 @@ function useWidgetStyles({
1036
1036
  const [agentName, setAgentName] = React3.useState(
1037
1037
  styleCache.get(key)?.agentName || "Assistant"
1038
1038
  );
1039
+ const [browserUseEnabled, setBrowserUseEnabled] = React3.useState(
1040
+ styleCache.get(key)?.browserUseEnabled || false
1041
+ );
1042
+ const [showThinking, setShowThinking] = React3.useState(
1043
+ styleCache.get(key)?.showThinking ?? true
1044
+ );
1039
1045
  const hasFetchedRef = React3.useRef(false);
1040
1046
  const fetchStyles = async () => {
1041
1047
  if (skip) return;
@@ -1046,6 +1052,8 @@ function useWidgetStyles({
1046
1052
  styleCache.set(key, config);
1047
1053
  setDbStyles(config.widgetStyles);
1048
1054
  setAgentName(config.agentName || "Assistant");
1055
+ setBrowserUseEnabled(config.browserUseEnabled || false);
1056
+ setShowThinking(config.showThinking ?? true);
1049
1057
  } catch (err) {
1050
1058
  console.error("[CrowWidget] Failed to fetch styles:", err);
1051
1059
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1059,6 +1067,8 @@ function useWidgetStyles({
1059
1067
  if (cached) {
1060
1068
  setDbStyles(cached.widgetStyles);
1061
1069
  setAgentName(cached.agentName || "Assistant");
1070
+ setBrowserUseEnabled(cached.browserUseEnabled || false);
1071
+ setShowThinking(cached.showThinking ?? true);
1062
1072
  setIsLoading(false);
1063
1073
  return;
1064
1074
  }
@@ -1071,6 +1081,8 @@ function useWidgetStyles({
1071
1081
  isLoading,
1072
1082
  error,
1073
1083
  agentName,
1084
+ browserUseEnabled,
1085
+ showThinking,
1074
1086
  refetch: fetchStyles
1075
1087
  };
1076
1088
  }
@@ -1151,11 +1163,12 @@ function WidgetStyleProvider({
1151
1163
  styles,
1152
1164
  agentName = "Assistant",
1153
1165
  isLoading = false,
1154
- variant = "floating"
1166
+ variant = "floating",
1167
+ showThinking = true
1155
1168
  }) {
1156
1169
  const value = React3.useMemo(
1157
- () => ({ styles, agentName, isLoading, variant }),
1158
- [styles, agentName, isLoading, variant]
1170
+ () => ({ styles, agentName, isLoading, variant, showThinking }),
1171
+ [styles, agentName, isLoading, variant, showThinking]
1159
1172
  );
1160
1173
  return /* @__PURE__ */ jsxRuntime.jsx(WidgetStyleContext.Provider, { value, children });
1161
1174
  }
@@ -1172,6 +1185,10 @@ function useWidgetStyles2() {
1172
1185
  const context = React3.useContext(WidgetStyleContext);
1173
1186
  return context?.styles ?? DEFAULT_WIDGET_STYLES;
1174
1187
  }
1188
+ function useShowThinking() {
1189
+ const context = React3.useContext(WidgetStyleContext);
1190
+ return context?.showThinking ?? true;
1191
+ }
1175
1192
  var CopilotStyleContext = React3.createContext(
1176
1193
  null
1177
1194
  );
@@ -1545,10 +1562,6 @@ var THINKING_MESSAGES = [
1545
1562
  "Connecting",
1546
1563
  "Synthesizing"
1547
1564
  ];
1548
- function getRandomThinkingMessage() {
1549
- const idx = Math.floor(Math.random() * THINKING_MESSAGES.length);
1550
- return THINKING_MESSAGES[idx] + "...";
1551
- }
1552
1565
  function ShimmeringContent({ children }) {
1553
1566
  return /* @__PURE__ */ jsxRuntime.jsxs(
1554
1567
  "span",
@@ -1578,11 +1591,17 @@ function ReasoningTrace({
1578
1591
  thinking,
1579
1592
  isComplete,
1580
1593
  toolCalls = [],
1581
- isWaiting = false
1594
+ isWaiting = false,
1595
+ showDetails = true
1582
1596
  }) {
1583
1597
  const hasThinking = !!thinking && thinking.trim().length > 0;
1584
1598
  const hasToolCalls = toolCalls.length > 0;
1599
+ const isActive = isWaiting || hasThinking && !isComplete || toolCalls.some((t) => t.status === "executing");
1585
1600
  if (!isWaiting && !hasThinking && !hasToolCalls) return null;
1601
+ if (!showDetails) {
1602
+ if (!isActive) return null;
1603
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-justify-start crow-mb-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-max-w-[90%]", children: /* @__PURE__ */ jsxRuntime.jsx(WaitingIndicator, {}) }) });
1604
+ }
1586
1605
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-justify-start crow-mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "crow-max-w-[90%] crow-space-y-1.5", children: [
1587
1606
  isWaiting && !hasThinking && /* @__PURE__ */ jsxRuntime.jsx(WaitingIndicator, {}),
1588
1607
  hasThinking && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlock, { thinking, isComplete }),
@@ -1590,9 +1609,19 @@ function ReasoningTrace({
1590
1609
  ] }) });
1591
1610
  }
1592
1611
  function WaitingIndicator() {
1612
+ const [messageIndex, setMessageIndex] = React3.useState(
1613
+ () => Math.floor(Math.random() * THINKING_MESSAGES.length)
1614
+ );
1615
+ React3.useEffect(() => {
1616
+ const interval = setInterval(() => {
1617
+ setMessageIndex((i) => (i + 1) % THINKING_MESSAGES.length);
1618
+ }, 3e3);
1619
+ return () => clearInterval(interval);
1620
+ }, []);
1621
+ const message = THINKING_MESSAGES[messageIndex] + "...";
1593
1622
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "crow-flex crow-items-center crow-gap-1.5 crow-text-xs crow-text-gray-500", children: [
1594
1623
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-items-center crow-justify-center crow-w-4 crow-h-4", children: /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Brain, { className: "crow-w-3.5 crow-h-3.5" }) }) }),
1595
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-font-medium", children: /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: getRandomThinkingMessage() }) })
1624
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-font-medium", children: /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: message }) })
1596
1625
  ] });
1597
1626
  }
1598
1627
  function ThinkingBlock({
@@ -1600,10 +1629,21 @@ function ThinkingBlock({
1600
1629
  isComplete
1601
1630
  }) {
1602
1631
  const [isExpanded, setIsExpanded] = React3.useState(!isComplete);
1632
+ const [messageIndex, setMessageIndex] = React3.useState(
1633
+ () => Math.floor(Math.random() * THINKING_MESSAGES.length)
1634
+ );
1603
1635
  React3.useLayoutEffect(() => {
1604
1636
  setIsExpanded(!isComplete);
1605
1637
  }, [isComplete]);
1638
+ React3.useEffect(() => {
1639
+ if (isComplete) return;
1640
+ const interval = setInterval(() => {
1641
+ setMessageIndex((i) => (i + 1) % THINKING_MESSAGES.length);
1642
+ }, 3e3);
1643
+ return () => clearInterval(interval);
1644
+ }, [isComplete]);
1606
1645
  const isInProgress = !isComplete;
1646
+ const message = THINKING_MESSAGES[messageIndex] + "...";
1607
1647
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "crow-flex crow-flex-col crow-gap-1 crow-text-xs", children: [
1608
1648
  /* @__PURE__ */ jsxRuntime.jsxs(
1609
1649
  "button",
@@ -1612,7 +1652,7 @@ function ThinkingBlock({
1612
1652
  className: `crow-flex crow-items-center crow-gap-1.5 crow-select-none crow-transition-colors ${isInProgress ? "crow-text-gray-500" : "crow-text-gray-600 hover:crow-text-gray-800"} crow-cursor-pointer`,
1613
1653
  children: [
1614
1654
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-items-center crow-justify-center crow-w-4 crow-h-4", children: isInProgress ? /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Brain, { className: "crow-w-3.5 crow-h-3.5" }) }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Brain, { className: "crow-w-3.5 crow-h-3.5" }) }),
1615
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-font-medium", children: isInProgress ? /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: getRandomThinkingMessage() }) : "Thought" }),
1655
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-font-medium", children: isInProgress ? /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: message }) : "Thought" }),
1616
1656
  /* @__PURE__ */ jsxRuntime.jsx(
1617
1657
  framerMotion.motion.div,
1618
1658
  {
@@ -1698,6 +1738,7 @@ function MessageBubble({
1698
1738
  isLoading = false
1699
1739
  }) {
1700
1740
  const styles = useWidgetStyles2();
1741
+ const showThinkingSetting = useShowThinking();
1701
1742
  const isWaiting = message.content === "Thinking..." || message.isBot && isLoading && !message.content;
1702
1743
  const hasThinking = message.isBot && message.thinking;
1703
1744
  const hasContent = message.content && message.content !== "Thinking...";
@@ -1716,7 +1757,8 @@ function MessageBubble({
1716
1757
  thinking: message.thinking,
1717
1758
  isComplete: message.thinkingComplete,
1718
1759
  toolCalls,
1719
- isWaiting: isWaiting && !hasThinking
1760
+ isWaiting: isWaiting && !hasThinking,
1761
+ showDetails: showThinkingSetting
1720
1762
  }
1721
1763
  ),
1722
1764
  hasContent && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2406,16 +2448,19 @@ function CrowWidget({
2406
2448
  variant = "floating",
2407
2449
  styles: propStyles,
2408
2450
  previewMode = false,
2451
+ showThinking: showThinkingProp,
2409
2452
  onReady,
2410
2453
  onIdentify,
2411
2454
  tools
2412
2455
  }) {
2413
- const { styles, isLoading: isLoadingStyles, agentName } = useWidgetStyles({
2456
+ const { styles, isLoading: isLoadingStyles, agentName, browserUseEnabled, showThinking: showThinkingFromAPI } = useWidgetStyles({
2414
2457
  productId,
2415
2458
  apiUrl,
2416
2459
  propStyles,
2417
2460
  skip: previewMode
2418
2461
  });
2462
+ const showThinking = showThinkingProp ?? showThinkingFromAPI;
2463
+ const [autoTools, setAutoTools] = React3.useState({});
2419
2464
  const cssVars = stylesToCssVars(styles);
2420
2465
  const messagesContainerRef = React3.useRef(null);
2421
2466
  const executeClientToolRef = React3.useRef(null);
@@ -2554,10 +2599,23 @@ function CrowWidget({
2554
2599
  }
2555
2600
  }, [isLoadingStyles, onIdentify]);
2556
2601
  React3.useEffect(() => {
2557
- if (tools && Object.keys(tools).length > 0) {
2558
- window.crow?.("registerTools", tools);
2602
+ if (browserUseEnabled && !isLoadingStyles && Object.keys(autoTools).length === 0) {
2603
+ import('@usecrow/client/browser').then(({ createBrowserUseTool }) => {
2604
+ setAutoTools({
2605
+ browser_use: createBrowserUseTool({ productId, apiUrl })
2606
+ });
2607
+ console.log("[Crow] browser_use tool auto-loaded");
2608
+ }).catch((err) => {
2609
+ console.warn("[Crow] Failed to load browser_use:", err);
2610
+ });
2611
+ }
2612
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
2613
+ const mergedTools = { ...autoTools, ...tools };
2614
+ React3.useEffect(() => {
2615
+ if (Object.keys(mergedTools).length > 0) {
2616
+ window.crow?.("registerTools", mergedTools);
2559
2617
  }
2560
- }, [tools]);
2618
+ }, [mergedTools]);
2561
2619
  const handleSend = (message) => {
2562
2620
  if (!message.trim()) return;
2563
2621
  setIsCollapsed(false);
@@ -2648,6 +2706,7 @@ function CrowWidget({
2648
2706
  agentName,
2649
2707
  isLoading: isLoadingStyles,
2650
2708
  variant,
2709
+ showThinking,
2651
2710
  children: [
2652
2711
  variant === "floating" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2653
2712
  /* @__PURE__ */ jsxRuntime.jsx(ChatBubble, { isExpanded: !isCollapsed, onClick: handleBubbleClick }),