@usecrow/ui 0.1.41 → 0.1.42

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
@@ -1305,6 +1305,9 @@ function useCopilotStyles({
1305
1305
  const [agentName, setAgentName] = React3.useState(
1306
1306
  styleCache.get(key)?.agentName || "Assistant"
1307
1307
  );
1308
+ const [browserUseEnabled, setBrowserUseEnabled] = React3.useState(
1309
+ styleCache.get(key)?.browserUseEnabled || false
1310
+ );
1308
1311
  const [pageNavigationEnabled, setPageNavigationEnabled] = React3.useState(
1309
1312
  styleCache.get(key)?.pageNavigationEnabled || false
1310
1313
  );
@@ -1328,6 +1331,7 @@ function useCopilotStyles({
1328
1331
  styleCache.set(key, config);
1329
1332
  setDbStyles(config.copilotStyles);
1330
1333
  setAgentName(config.agentName || "Assistant");
1334
+ setBrowserUseEnabled(config.browserUseEnabled || false);
1331
1335
  setPageNavigationEnabled(config.pageNavigationEnabled || false);
1332
1336
  setPageNavigationRoutes(config.pageNavigationRoutes || []);
1333
1337
  setPersistAnonymousConversations(config.persistAnonymousConversations ?? true);
@@ -1346,6 +1350,7 @@ function useCopilotStyles({
1346
1350
  if (cached) {
1347
1351
  setDbStyles(cached.copilotStyles);
1348
1352
  setAgentName(cached.agentName || "Assistant");
1353
+ setBrowserUseEnabled(cached.browserUseEnabled || false);
1349
1354
  setPageNavigationEnabled(cached.pageNavigationEnabled || false);
1350
1355
  setPageNavigationRoutes(cached.pageNavigationRoutes || []);
1351
1356
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
@@ -1363,6 +1368,7 @@ function useCopilotStyles({
1363
1368
  isLoading,
1364
1369
  error,
1365
1370
  agentName,
1371
+ browserUseEnabled,
1366
1372
  pageNavigationEnabled,
1367
1373
  pageNavigationRoutes,
1368
1374
  persistAnonymousConversations,
@@ -1848,7 +1854,14 @@ function ReasoningTrace({
1848
1854
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-justify-start crow-mb-2 crow-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "crow-w-full crow-space-y-1.5", children: [
1849
1855
  isWaiting && !hasThinking && /* @__PURE__ */ jsxRuntime.jsx(WaitingIndicator, {}),
1850
1856
  hasThinking && /* @__PURE__ */ jsxRuntime.jsx(ThinkingBlock, { thinking, isComplete }),
1851
- toolCalls.map((tool) => /* @__PURE__ */ jsxRuntime.jsx(ToolCallBlock, { toolCall: tool, toolRenderers }, tool.id))
1857
+ toolCalls.map((tool) => /* @__PURE__ */ jsxRuntime.jsx(
1858
+ ToolCallBlock,
1859
+ {
1860
+ toolCall: tool,
1861
+ toolRenderers
1862
+ },
1863
+ tool.id
1864
+ ))
1852
1865
  ] }) });
1853
1866
  }
1854
1867
  function WaitingIndicator() {
@@ -3502,6 +3515,7 @@ function CrowCopilot({
3502
3515
  styles,
3503
3516
  isLoading: isLoadingStyles,
3504
3517
  agentName: agentNameFromAPI,
3518
+ browserUseEnabled,
3505
3519
  pageNavigationEnabled,
3506
3520
  pageNavigationRoutes,
3507
3521
  persistAnonymousConversations,
@@ -3516,6 +3530,20 @@ function CrowCopilot({
3516
3530
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
3517
3531
  const welcomeMessage = welcomeMessageProp ?? welcomeMessageFromAPI;
3518
3532
  const [autoTools, setAutoTools] = React3.useState({});
3533
+ const browserUseLoaded = autoTools.browser_use;
3534
+ React3.useEffect(() => {
3535
+ if (browserUseEnabled && !isLoadingStyles && !browserUseLoaded) {
3536
+ import('@usecrow/client/browser').then(({ createBrowserUseTool }) => {
3537
+ setAutoTools((prev) => ({
3538
+ ...prev,
3539
+ browser_use: createBrowserUseTool({ productId, apiUrl })
3540
+ }));
3541
+ console.log("[Crow] browser_use tool auto-loaded");
3542
+ }).catch((err) => {
3543
+ console.warn("[Crow] Failed to load browser_use:", err);
3544
+ });
3545
+ }
3546
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, browserUseLoaded]);
3519
3547
  React3.useEffect(() => {
3520
3548
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3521
3549
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3548,8 +3576,10 @@ function CrowCopilot({
3548
3576
  const [activeLocalTabId, setActiveLocalTabId] = React3.useState("local-1");
3549
3577
  const [localTabMessages, setLocalTabMessages] = React3.useState({});
3550
3578
  const [localTabCounter, setLocalTabCounter] = React3.useState(1);
3579
+ const [isBrowserUseActive, setIsBrowserUseActive] = React3.useState(false);
3551
3580
  const [pendingConfirmation, setPendingConfirmation] = React3.useState(null);
3552
- const [pendingQuestion, setPendingQuestion] = React3.useState(null);
3581
+ const [askUserResolver, setAskUserResolver] = React3.useState(null);
3582
+ const [browserQuestion, setBrowserQuestion] = React3.useState(null);
3553
3583
  const conversations = useConversations({ productId, apiUrl });
3554
3584
  const [shouldRestoreHistory, setShouldRestoreHistory] = React3.useState(false);
3555
3585
  const hasRestoredHistoryRef = React3.useRef(false);
@@ -3690,10 +3720,25 @@ function CrowCopilot({
3690
3720
  );
3691
3721
  const handleBrowserQuestion = React3.useCallback(
3692
3722
  (question) => {
3693
- return new Promise((resolve) => {
3694
- setPendingQuestion({ question, resolve });
3723
+ return new Promise((resolve, reject) => {
3724
+ setAskUserResolver((prev) => {
3725
+ if (prev) {
3726
+ prev.reject(new Error("Superseded by new browser question"));
3727
+ }
3728
+ return { resolve, reject };
3729
+ });
3730
+ setBrowserQuestion(question);
3731
+ chat.addMessage("assistant", question);
3695
3732
  });
3696
3733
  },
3734
+ [chat]
3735
+ );
3736
+ const handleBrowserProgress = React3.useCallback(
3737
+ (step, maxSteps) => {
3738
+ if (step >= maxSteps || step === -1) {
3739
+ setIsBrowserUseActive(false);
3740
+ }
3741
+ },
3697
3742
  []
3698
3743
  );
3699
3744
  const handleExitWorkflow = async () => {
@@ -3702,12 +3747,13 @@ function CrowCopilot({
3702
3747
  React3.useEffect(() => {
3703
3748
  window.__crow_browser_callbacks = {
3704
3749
  onConfirmation: handleBrowserConfirmation,
3705
- onQuestion: handleBrowserQuestion
3750
+ onQuestion: handleBrowserQuestion,
3751
+ onProgress: handleBrowserProgress
3706
3752
  };
3707
3753
  return () => {
3708
3754
  delete window.__crow_browser_callbacks;
3709
3755
  };
3710
- }, [handleBrowserConfirmation, handleBrowserQuestion]);
3756
+ }, [handleBrowserConfirmation, handleBrowserQuestion, handleBrowserProgress]);
3711
3757
  React3.useEffect(() => {
3712
3758
  if (!isLoadingStyles) {
3713
3759
  onReady?.();
@@ -3744,8 +3790,36 @@ function CrowCopilot({
3744
3790
  }, [context]);
3745
3791
  const handleSend = (message) => {
3746
3792
  if (!message.trim()) return;
3793
+ if (askUserResolver) {
3794
+ chat.addMessage("user", message);
3795
+ askUserResolver.resolve(message);
3796
+ setAskUserResolver(null);
3797
+ setBrowserQuestion(null);
3798
+ return;
3799
+ }
3747
3800
  chat.sendMessage(message);
3748
3801
  };
3802
+ const handleStop = () => {
3803
+ chat.stopGeneration();
3804
+ const currentResolver = askUserResolver;
3805
+ setAskUserResolver(null);
3806
+ setBrowserQuestion(null);
3807
+ if (browserUseEnabled && isBrowserUseActive) {
3808
+ import('@usecrow/client/browser').then(({ stopActiveBrowserUse }) => {
3809
+ stopActiveBrowserUse();
3810
+ currentResolver?.reject(new Error("Stopped by user"));
3811
+ }).catch(() => {
3812
+ currentResolver?.reject(new Error("Stopped by user"));
3813
+ });
3814
+ setIsBrowserUseActive(false);
3815
+ } else if (currentResolver) {
3816
+ currentResolver.reject(new Error("Stopped by user"));
3817
+ }
3818
+ if (pendingConfirmation) {
3819
+ pendingConfirmation.resolve(false);
3820
+ setPendingConfirmation(null);
3821
+ }
3822
+ };
3749
3823
  const handleNewChat = () => {
3750
3824
  if (!isVerifiedUser) {
3751
3825
  setLocalTabMessages((prev) => ({
@@ -4085,13 +4159,14 @@ function CrowCopilot({
4085
4159
  }
4086
4160
  }
4087
4161
  ) }),
4088
- pendingQuestion && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4162
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4089
4163
  BrowserUseQuestion,
4090
4164
  {
4091
- question: pendingQuestion.question,
4165
+ question: browserQuestion,
4092
4166
  onSubmit: (answer) => {
4093
- pendingQuestion.resolve(answer);
4094
- setPendingQuestion(null);
4167
+ askUserResolver.resolve(answer);
4168
+ setAskUserResolver(null);
4169
+ setBrowserQuestion(null);
4095
4170
  }
4096
4171
  }
4097
4172
  ) })
@@ -4107,7 +4182,7 @@ function CrowCopilot({
4107
4182
  PromptInputBox,
4108
4183
  {
4109
4184
  onSend: handleSend,
4110
- onStop: chat.stopGeneration,
4185
+ onStop: handleStop,
4111
4186
  placeholder: "Ask anything...",
4112
4187
  isLoading: chat.isLoading
4113
4188
  }