@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.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() {
@@ -3181,6 +3194,19 @@ function CrowWidget({
3181
3194
  });
3182
3195
  }
3183
3196
  }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3197
+ React3.useEffect(() => {
3198
+ if (browserUseEnabled && !isLoadingStyles && !autoTools.execute_recorded_workflow) {
3199
+ import('@usecrow/client/browser').then(({ createExecuteRecordedWorkflowTool }) => {
3200
+ setAutoTools((prev) => ({
3201
+ ...prev,
3202
+ execute_recorded_workflow: createExecuteRecordedWorkflowTool({ productId, apiUrl })
3203
+ }));
3204
+ console.log("[Crow] execute_recorded_workflow tool auto-loaded");
3205
+ }).catch((err) => {
3206
+ console.warn("[Crow] Failed to load execute_recorded_workflow:", err);
3207
+ });
3208
+ }
3209
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3184
3210
  React3.useEffect(() => {
3185
3211
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3186
3212
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3502,6 +3528,7 @@ function CrowCopilot({
3502
3528
  styles,
3503
3529
  isLoading: isLoadingStyles,
3504
3530
  agentName: agentNameFromAPI,
3531
+ browserUseEnabled,
3505
3532
  pageNavigationEnabled,
3506
3533
  pageNavigationRoutes,
3507
3534
  persistAnonymousConversations,
@@ -3516,6 +3543,20 @@ function CrowCopilot({
3516
3543
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
3517
3544
  const welcomeMessage = welcomeMessageProp ?? welcomeMessageFromAPI;
3518
3545
  const [autoTools, setAutoTools] = React3.useState({});
3546
+ const browserUseLoaded = autoTools.browser_use;
3547
+ React3.useEffect(() => {
3548
+ if (browserUseEnabled && !isLoadingStyles && !browserUseLoaded) {
3549
+ import('@usecrow/client/browser').then(({ createBrowserUseTool }) => {
3550
+ setAutoTools((prev) => ({
3551
+ ...prev,
3552
+ browser_use: createBrowserUseTool({ productId, apiUrl })
3553
+ }));
3554
+ console.log("[Crow] browser_use tool auto-loaded");
3555
+ }).catch((err) => {
3556
+ console.warn("[Crow] Failed to load browser_use:", err);
3557
+ });
3558
+ }
3559
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, browserUseLoaded]);
3519
3560
  React3.useEffect(() => {
3520
3561
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3521
3562
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3548,8 +3589,10 @@ function CrowCopilot({
3548
3589
  const [activeLocalTabId, setActiveLocalTabId] = React3.useState("local-1");
3549
3590
  const [localTabMessages, setLocalTabMessages] = React3.useState({});
3550
3591
  const [localTabCounter, setLocalTabCounter] = React3.useState(1);
3592
+ const [isBrowserUseActive, setIsBrowserUseActive] = React3.useState(false);
3551
3593
  const [pendingConfirmation, setPendingConfirmation] = React3.useState(null);
3552
- const [pendingQuestion, setPendingQuestion] = React3.useState(null);
3594
+ const [askUserResolver, setAskUserResolver] = React3.useState(null);
3595
+ const [browserQuestion, setBrowserQuestion] = React3.useState(null);
3553
3596
  const conversations = useConversations({ productId, apiUrl });
3554
3597
  const [shouldRestoreHistory, setShouldRestoreHistory] = React3.useState(false);
3555
3598
  const hasRestoredHistoryRef = React3.useRef(false);
@@ -3690,10 +3733,25 @@ function CrowCopilot({
3690
3733
  );
3691
3734
  const handleBrowserQuestion = React3.useCallback(
3692
3735
  (question) => {
3693
- return new Promise((resolve) => {
3694
- setPendingQuestion({ question, resolve });
3736
+ return new Promise((resolve, reject) => {
3737
+ setAskUserResolver((prev) => {
3738
+ if (prev) {
3739
+ prev.reject(new Error("Superseded by new browser question"));
3740
+ }
3741
+ return { resolve, reject };
3742
+ });
3743
+ setBrowserQuestion(question);
3744
+ chat.addMessage("assistant", question);
3695
3745
  });
3696
3746
  },
3747
+ [chat]
3748
+ );
3749
+ const handleBrowserProgress = React3.useCallback(
3750
+ (step, maxSteps) => {
3751
+ if (step >= maxSteps || step === -1) {
3752
+ setIsBrowserUseActive(false);
3753
+ }
3754
+ },
3697
3755
  []
3698
3756
  );
3699
3757
  const handleExitWorkflow = async () => {
@@ -3702,12 +3760,13 @@ function CrowCopilot({
3702
3760
  React3.useEffect(() => {
3703
3761
  window.__crow_browser_callbacks = {
3704
3762
  onConfirmation: handleBrowserConfirmation,
3705
- onQuestion: handleBrowserQuestion
3763
+ onQuestion: handleBrowserQuestion,
3764
+ onProgress: handleBrowserProgress
3706
3765
  };
3707
3766
  return () => {
3708
3767
  delete window.__crow_browser_callbacks;
3709
3768
  };
3710
- }, [handleBrowserConfirmation, handleBrowserQuestion]);
3769
+ }, [handleBrowserConfirmation, handleBrowserQuestion, handleBrowserProgress]);
3711
3770
  React3.useEffect(() => {
3712
3771
  if (!isLoadingStyles) {
3713
3772
  onReady?.();
@@ -3744,8 +3803,36 @@ function CrowCopilot({
3744
3803
  }, [context]);
3745
3804
  const handleSend = (message) => {
3746
3805
  if (!message.trim()) return;
3806
+ if (askUserResolver) {
3807
+ chat.addMessage("user", message);
3808
+ askUserResolver.resolve(message);
3809
+ setAskUserResolver(null);
3810
+ setBrowserQuestion(null);
3811
+ return;
3812
+ }
3747
3813
  chat.sendMessage(message);
3748
3814
  };
3815
+ const handleStop = () => {
3816
+ chat.stopGeneration();
3817
+ const currentResolver = askUserResolver;
3818
+ setAskUserResolver(null);
3819
+ setBrowserQuestion(null);
3820
+ if (browserUseEnabled && isBrowserUseActive) {
3821
+ import('@usecrow/client/browser').then(({ stopActiveBrowserUse }) => {
3822
+ stopActiveBrowserUse();
3823
+ currentResolver?.reject(new Error("Stopped by user"));
3824
+ }).catch(() => {
3825
+ currentResolver?.reject(new Error("Stopped by user"));
3826
+ });
3827
+ setIsBrowserUseActive(false);
3828
+ } else if (currentResolver) {
3829
+ currentResolver.reject(new Error("Stopped by user"));
3830
+ }
3831
+ if (pendingConfirmation) {
3832
+ pendingConfirmation.resolve(false);
3833
+ setPendingConfirmation(null);
3834
+ }
3835
+ };
3749
3836
  const handleNewChat = () => {
3750
3837
  if (!isVerifiedUser) {
3751
3838
  setLocalTabMessages((prev) => ({
@@ -4085,13 +4172,14 @@ function CrowCopilot({
4085
4172
  }
4086
4173
  }
4087
4174
  ) }),
4088
- pendingQuestion && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4175
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
4089
4176
  BrowserUseQuestion,
4090
4177
  {
4091
- question: pendingQuestion.question,
4178
+ question: browserQuestion,
4092
4179
  onSubmit: (answer) => {
4093
- pendingQuestion.resolve(answer);
4094
- setPendingQuestion(null);
4180
+ askUserResolver.resolve(answer);
4181
+ setAskUserResolver(null);
4182
+ setBrowserQuestion(null);
4095
4183
  }
4096
4184
  }
4097
4185
  ) })
@@ -4107,7 +4195,7 @@ function CrowCopilot({
4107
4195
  PromptInputBox,
4108
4196
  {
4109
4197
  onSend: handleSend,
4110
- onStop: chat.stopGeneration,
4198
+ onStop: handleStop,
4111
4199
  placeholder: "Ask anything...",
4112
4200
  isLoading: chat.isLoading
4113
4201
  }