@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.d.cts CHANGED
@@ -778,6 +778,8 @@ interface UseCopilotStylesResult {
778
778
  error: Error | null;
779
779
  /** Agent name from product config */
780
780
  agentName: string;
781
+ /** Whether browser_use is enabled for this product */
782
+ browserUseEnabled: boolean;
781
783
  /** Whether page navigation is enabled for this product */
782
784
  pageNavigationEnabled: boolean;
783
785
  /** Route definitions for page navigation */
package/dist/index.d.ts CHANGED
@@ -778,6 +778,8 @@ interface UseCopilotStylesResult {
778
778
  error: Error | null;
779
779
  /** Agent name from product config */
780
780
  agentName: string;
781
+ /** Whether browser_use is enabled for this product */
782
+ browserUseEnabled: boolean;
781
783
  /** Whether page navigation is enabled for this product */
782
784
  pageNavigationEnabled: boolean;
783
785
  /** Route definitions for page navigation */
package/dist/index.js CHANGED
@@ -1279,6 +1279,9 @@ function useCopilotStyles({
1279
1279
  const [agentName, setAgentName] = useState(
1280
1280
  styleCache.get(key)?.agentName || "Assistant"
1281
1281
  );
1282
+ const [browserUseEnabled, setBrowserUseEnabled] = useState(
1283
+ styleCache.get(key)?.browserUseEnabled || false
1284
+ );
1282
1285
  const [pageNavigationEnabled, setPageNavigationEnabled] = useState(
1283
1286
  styleCache.get(key)?.pageNavigationEnabled || false
1284
1287
  );
@@ -1302,6 +1305,7 @@ function useCopilotStyles({
1302
1305
  styleCache.set(key, config);
1303
1306
  setDbStyles(config.copilotStyles);
1304
1307
  setAgentName(config.agentName || "Assistant");
1308
+ setBrowserUseEnabled(config.browserUseEnabled || false);
1305
1309
  setPageNavigationEnabled(config.pageNavigationEnabled || false);
1306
1310
  setPageNavigationRoutes(config.pageNavigationRoutes || []);
1307
1311
  setPersistAnonymousConversations(config.persistAnonymousConversations ?? true);
@@ -1320,6 +1324,7 @@ function useCopilotStyles({
1320
1324
  if (cached) {
1321
1325
  setDbStyles(cached.copilotStyles);
1322
1326
  setAgentName(cached.agentName || "Assistant");
1327
+ setBrowserUseEnabled(cached.browserUseEnabled || false);
1323
1328
  setPageNavigationEnabled(cached.pageNavigationEnabled || false);
1324
1329
  setPageNavigationRoutes(cached.pageNavigationRoutes || []);
1325
1330
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
@@ -1337,6 +1342,7 @@ function useCopilotStyles({
1337
1342
  isLoading,
1338
1343
  error,
1339
1344
  agentName,
1345
+ browserUseEnabled,
1340
1346
  pageNavigationEnabled,
1341
1347
  pageNavigationRoutes,
1342
1348
  persistAnonymousConversations,
@@ -1822,7 +1828,14 @@ function ReasoningTrace({
1822
1828
  return /* @__PURE__ */ jsx("div", { className: "crow-flex crow-justify-start crow-mb-2 crow-w-full", children: /* @__PURE__ */ jsxs("div", { className: "crow-w-full crow-space-y-1.5", children: [
1823
1829
  isWaiting && !hasThinking && /* @__PURE__ */ jsx(WaitingIndicator, {}),
1824
1830
  hasThinking && /* @__PURE__ */ jsx(ThinkingBlock, { thinking, isComplete }),
1825
- toolCalls.map((tool) => /* @__PURE__ */ jsx(ToolCallBlock, { toolCall: tool, toolRenderers }, tool.id))
1831
+ toolCalls.map((tool) => /* @__PURE__ */ jsx(
1832
+ ToolCallBlock,
1833
+ {
1834
+ toolCall: tool,
1835
+ toolRenderers
1836
+ },
1837
+ tool.id
1838
+ ))
1826
1839
  ] }) });
1827
1840
  }
1828
1841
  function WaitingIndicator() {
@@ -3476,6 +3489,7 @@ function CrowCopilot({
3476
3489
  styles,
3477
3490
  isLoading: isLoadingStyles,
3478
3491
  agentName: agentNameFromAPI,
3492
+ browserUseEnabled,
3479
3493
  pageNavigationEnabled,
3480
3494
  pageNavigationRoutes,
3481
3495
  persistAnonymousConversations,
@@ -3490,6 +3504,20 @@ function CrowCopilot({
3490
3504
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
3491
3505
  const welcomeMessage = welcomeMessageProp ?? welcomeMessageFromAPI;
3492
3506
  const [autoTools, setAutoTools] = useState({});
3507
+ const browserUseLoaded = autoTools.browser_use;
3508
+ useEffect(() => {
3509
+ if (browserUseEnabled && !isLoadingStyles && !browserUseLoaded) {
3510
+ import('@usecrow/client/browser').then(({ createBrowserUseTool }) => {
3511
+ setAutoTools((prev) => ({
3512
+ ...prev,
3513
+ browser_use: createBrowserUseTool({ productId, apiUrl })
3514
+ }));
3515
+ console.log("[Crow] browser_use tool auto-loaded");
3516
+ }).catch((err) => {
3517
+ console.warn("[Crow] Failed to load browser_use:", err);
3518
+ });
3519
+ }
3520
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, browserUseLoaded]);
3493
3521
  useEffect(() => {
3494
3522
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3495
3523
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3522,8 +3550,10 @@ function CrowCopilot({
3522
3550
  const [activeLocalTabId, setActiveLocalTabId] = useState("local-1");
3523
3551
  const [localTabMessages, setLocalTabMessages] = useState({});
3524
3552
  const [localTabCounter, setLocalTabCounter] = useState(1);
3553
+ const [isBrowserUseActive, setIsBrowserUseActive] = useState(false);
3525
3554
  const [pendingConfirmation, setPendingConfirmation] = useState(null);
3526
- const [pendingQuestion, setPendingQuestion] = useState(null);
3555
+ const [askUserResolver, setAskUserResolver] = useState(null);
3556
+ const [browserQuestion, setBrowserQuestion] = useState(null);
3527
3557
  const conversations = useConversations({ productId, apiUrl });
3528
3558
  const [shouldRestoreHistory, setShouldRestoreHistory] = useState(false);
3529
3559
  const hasRestoredHistoryRef = useRef(false);
@@ -3664,10 +3694,25 @@ function CrowCopilot({
3664
3694
  );
3665
3695
  const handleBrowserQuestion = useCallback(
3666
3696
  (question) => {
3667
- return new Promise((resolve) => {
3668
- setPendingQuestion({ question, resolve });
3697
+ return new Promise((resolve, reject) => {
3698
+ setAskUserResolver((prev) => {
3699
+ if (prev) {
3700
+ prev.reject(new Error("Superseded by new browser question"));
3701
+ }
3702
+ return { resolve, reject };
3703
+ });
3704
+ setBrowserQuestion(question);
3705
+ chat.addMessage("assistant", question);
3669
3706
  });
3670
3707
  },
3708
+ [chat]
3709
+ );
3710
+ const handleBrowserProgress = useCallback(
3711
+ (step, maxSteps) => {
3712
+ if (step >= maxSteps || step === -1) {
3713
+ setIsBrowserUseActive(false);
3714
+ }
3715
+ },
3671
3716
  []
3672
3717
  );
3673
3718
  const handleExitWorkflow = async () => {
@@ -3676,12 +3721,13 @@ function CrowCopilot({
3676
3721
  useEffect(() => {
3677
3722
  window.__crow_browser_callbacks = {
3678
3723
  onConfirmation: handleBrowserConfirmation,
3679
- onQuestion: handleBrowserQuestion
3724
+ onQuestion: handleBrowserQuestion,
3725
+ onProgress: handleBrowserProgress
3680
3726
  };
3681
3727
  return () => {
3682
3728
  delete window.__crow_browser_callbacks;
3683
3729
  };
3684
- }, [handleBrowserConfirmation, handleBrowserQuestion]);
3730
+ }, [handleBrowserConfirmation, handleBrowserQuestion, handleBrowserProgress]);
3685
3731
  useEffect(() => {
3686
3732
  if (!isLoadingStyles) {
3687
3733
  onReady?.();
@@ -3718,8 +3764,36 @@ function CrowCopilot({
3718
3764
  }, [context]);
3719
3765
  const handleSend = (message) => {
3720
3766
  if (!message.trim()) return;
3767
+ if (askUserResolver) {
3768
+ chat.addMessage("user", message);
3769
+ askUserResolver.resolve(message);
3770
+ setAskUserResolver(null);
3771
+ setBrowserQuestion(null);
3772
+ return;
3773
+ }
3721
3774
  chat.sendMessage(message);
3722
3775
  };
3776
+ const handleStop = () => {
3777
+ chat.stopGeneration();
3778
+ const currentResolver = askUserResolver;
3779
+ setAskUserResolver(null);
3780
+ setBrowserQuestion(null);
3781
+ if (browserUseEnabled && isBrowserUseActive) {
3782
+ import('@usecrow/client/browser').then(({ stopActiveBrowserUse }) => {
3783
+ stopActiveBrowserUse();
3784
+ currentResolver?.reject(new Error("Stopped by user"));
3785
+ }).catch(() => {
3786
+ currentResolver?.reject(new Error("Stopped by user"));
3787
+ });
3788
+ setIsBrowserUseActive(false);
3789
+ } else if (currentResolver) {
3790
+ currentResolver.reject(new Error("Stopped by user"));
3791
+ }
3792
+ if (pendingConfirmation) {
3793
+ pendingConfirmation.resolve(false);
3794
+ setPendingConfirmation(null);
3795
+ }
3796
+ };
3723
3797
  const handleNewChat = () => {
3724
3798
  if (!isVerifiedUser) {
3725
3799
  setLocalTabMessages((prev) => ({
@@ -4059,13 +4133,14 @@ function CrowCopilot({
4059
4133
  }
4060
4134
  }
4061
4135
  ) }),
4062
- pendingQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
4136
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
4063
4137
  BrowserUseQuestion,
4064
4138
  {
4065
- question: pendingQuestion.question,
4139
+ question: browserQuestion,
4066
4140
  onSubmit: (answer) => {
4067
- pendingQuestion.resolve(answer);
4068
- setPendingQuestion(null);
4141
+ askUserResolver.resolve(answer);
4142
+ setAskUserResolver(null);
4143
+ setBrowserQuestion(null);
4069
4144
  }
4070
4145
  }
4071
4146
  ) })
@@ -4081,7 +4156,7 @@ function CrowCopilot({
4081
4156
  PromptInputBox,
4082
4157
  {
4083
4158
  onSend: handleSend,
4084
- onStop: chat.stopGeneration,
4159
+ onStop: handleStop,
4085
4160
  placeholder: "Ask anything...",
4086
4161
  isLoading: chat.isLoading
4087
4162
  }