@usecrow/ui 0.1.41 → 0.1.43

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() {
@@ -3155,6 +3168,19 @@ function CrowWidget({
3155
3168
  });
3156
3169
  }
3157
3170
  }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3171
+ useEffect(() => {
3172
+ if (browserUseEnabled && !isLoadingStyles && !autoTools.execute_recorded_workflow) {
3173
+ import('@usecrow/client/browser').then(({ createExecuteRecordedWorkflowTool }) => {
3174
+ setAutoTools((prev) => ({
3175
+ ...prev,
3176
+ execute_recorded_workflow: createExecuteRecordedWorkflowTool({ productId, apiUrl })
3177
+ }));
3178
+ console.log("[Crow] execute_recorded_workflow tool auto-loaded");
3179
+ }).catch((err) => {
3180
+ console.warn("[Crow] Failed to load execute_recorded_workflow:", err);
3181
+ });
3182
+ }
3183
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3158
3184
  useEffect(() => {
3159
3185
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3160
3186
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3476,6 +3502,7 @@ function CrowCopilot({
3476
3502
  styles,
3477
3503
  isLoading: isLoadingStyles,
3478
3504
  agentName: agentNameFromAPI,
3505
+ browserUseEnabled,
3479
3506
  pageNavigationEnabled,
3480
3507
  pageNavigationRoutes,
3481
3508
  persistAnonymousConversations,
@@ -3490,6 +3517,20 @@ function CrowCopilot({
3490
3517
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
3491
3518
  const welcomeMessage = welcomeMessageProp ?? welcomeMessageFromAPI;
3492
3519
  const [autoTools, setAutoTools] = useState({});
3520
+ const browserUseLoaded = autoTools.browser_use;
3521
+ useEffect(() => {
3522
+ if (browserUseEnabled && !isLoadingStyles && !browserUseLoaded) {
3523
+ import('@usecrow/client/browser').then(({ createBrowserUseTool }) => {
3524
+ setAutoTools((prev) => ({
3525
+ ...prev,
3526
+ browser_use: createBrowserUseTool({ productId, apiUrl })
3527
+ }));
3528
+ console.log("[Crow] browser_use tool auto-loaded");
3529
+ }).catch((err) => {
3530
+ console.warn("[Crow] Failed to load browser_use:", err);
3531
+ });
3532
+ }
3533
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, browserUseLoaded]);
3493
3534
  useEffect(() => {
3494
3535
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3495
3536
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3522,8 +3563,10 @@ function CrowCopilot({
3522
3563
  const [activeLocalTabId, setActiveLocalTabId] = useState("local-1");
3523
3564
  const [localTabMessages, setLocalTabMessages] = useState({});
3524
3565
  const [localTabCounter, setLocalTabCounter] = useState(1);
3566
+ const [isBrowserUseActive, setIsBrowserUseActive] = useState(false);
3525
3567
  const [pendingConfirmation, setPendingConfirmation] = useState(null);
3526
- const [pendingQuestion, setPendingQuestion] = useState(null);
3568
+ const [askUserResolver, setAskUserResolver] = useState(null);
3569
+ const [browserQuestion, setBrowserQuestion] = useState(null);
3527
3570
  const conversations = useConversations({ productId, apiUrl });
3528
3571
  const [shouldRestoreHistory, setShouldRestoreHistory] = useState(false);
3529
3572
  const hasRestoredHistoryRef = useRef(false);
@@ -3664,10 +3707,25 @@ function CrowCopilot({
3664
3707
  );
3665
3708
  const handleBrowserQuestion = useCallback(
3666
3709
  (question) => {
3667
- return new Promise((resolve) => {
3668
- setPendingQuestion({ question, resolve });
3710
+ return new Promise((resolve, reject) => {
3711
+ setAskUserResolver((prev) => {
3712
+ if (prev) {
3713
+ prev.reject(new Error("Superseded by new browser question"));
3714
+ }
3715
+ return { resolve, reject };
3716
+ });
3717
+ setBrowserQuestion(question);
3718
+ chat.addMessage("assistant", question);
3669
3719
  });
3670
3720
  },
3721
+ [chat]
3722
+ );
3723
+ const handleBrowserProgress = useCallback(
3724
+ (step, maxSteps) => {
3725
+ if (step >= maxSteps || step === -1) {
3726
+ setIsBrowserUseActive(false);
3727
+ }
3728
+ },
3671
3729
  []
3672
3730
  );
3673
3731
  const handleExitWorkflow = async () => {
@@ -3676,12 +3734,13 @@ function CrowCopilot({
3676
3734
  useEffect(() => {
3677
3735
  window.__crow_browser_callbacks = {
3678
3736
  onConfirmation: handleBrowserConfirmation,
3679
- onQuestion: handleBrowserQuestion
3737
+ onQuestion: handleBrowserQuestion,
3738
+ onProgress: handleBrowserProgress
3680
3739
  };
3681
3740
  return () => {
3682
3741
  delete window.__crow_browser_callbacks;
3683
3742
  };
3684
- }, [handleBrowserConfirmation, handleBrowserQuestion]);
3743
+ }, [handleBrowserConfirmation, handleBrowserQuestion, handleBrowserProgress]);
3685
3744
  useEffect(() => {
3686
3745
  if (!isLoadingStyles) {
3687
3746
  onReady?.();
@@ -3718,8 +3777,36 @@ function CrowCopilot({
3718
3777
  }, [context]);
3719
3778
  const handleSend = (message) => {
3720
3779
  if (!message.trim()) return;
3780
+ if (askUserResolver) {
3781
+ chat.addMessage("user", message);
3782
+ askUserResolver.resolve(message);
3783
+ setAskUserResolver(null);
3784
+ setBrowserQuestion(null);
3785
+ return;
3786
+ }
3721
3787
  chat.sendMessage(message);
3722
3788
  };
3789
+ const handleStop = () => {
3790
+ chat.stopGeneration();
3791
+ const currentResolver = askUserResolver;
3792
+ setAskUserResolver(null);
3793
+ setBrowserQuestion(null);
3794
+ if (browserUseEnabled && isBrowserUseActive) {
3795
+ import('@usecrow/client/browser').then(({ stopActiveBrowserUse }) => {
3796
+ stopActiveBrowserUse();
3797
+ currentResolver?.reject(new Error("Stopped by user"));
3798
+ }).catch(() => {
3799
+ currentResolver?.reject(new Error("Stopped by user"));
3800
+ });
3801
+ setIsBrowserUseActive(false);
3802
+ } else if (currentResolver) {
3803
+ currentResolver.reject(new Error("Stopped by user"));
3804
+ }
3805
+ if (pendingConfirmation) {
3806
+ pendingConfirmation.resolve(false);
3807
+ setPendingConfirmation(null);
3808
+ }
3809
+ };
3723
3810
  const handleNewChat = () => {
3724
3811
  if (!isVerifiedUser) {
3725
3812
  setLocalTabMessages((prev) => ({
@@ -4059,13 +4146,14 @@ function CrowCopilot({
4059
4146
  }
4060
4147
  }
4061
4148
  ) }),
4062
- pendingQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
4149
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
4063
4150
  BrowserUseQuestion,
4064
4151
  {
4065
- question: pendingQuestion.question,
4152
+ question: browserQuestion,
4066
4153
  onSubmit: (answer) => {
4067
- pendingQuestion.resolve(answer);
4068
- setPendingQuestion(null);
4154
+ askUserResolver.resolve(answer);
4155
+ setAskUserResolver(null);
4156
+ setBrowserQuestion(null);
4069
4157
  }
4070
4158
  }
4071
4159
  ) })
@@ -4081,7 +4169,7 @@ function CrowCopilot({
4081
4169
  PromptInputBox,
4082
4170
  {
4083
4171
  onSend: handleSend,
4084
- onStop: chat.stopGeneration,
4172
+ onStop: handleStop,
4085
4173
  placeholder: "Ask anything...",
4086
4174
  isLoading: chat.isLoading
4087
4175
  }