@usecrow/ui 0.1.31 → 0.1.33

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
@@ -1277,6 +1277,9 @@ function useCopilotStyles({
1277
1277
  const [welcomeMessage, setWelcomeMessage] = React3.useState(
1278
1278
  styleCache.get(key)?.welcomeMessage ?? void 0
1279
1279
  );
1280
+ const [selectedModel, setSelectedModel] = React3.useState(
1281
+ styleCache.get(key)?.model ?? void 0
1282
+ );
1280
1283
  const hasFetchedRef = React3.useRef(false);
1281
1284
  const fetchStyles = async () => {
1282
1285
  if (skip) return;
@@ -1289,6 +1292,7 @@ function useCopilotStyles({
1289
1292
  setAgentName(config.agentName || "Assistant");
1290
1293
  setPersistAnonymousConversations(config.persistAnonymousConversations ?? true);
1291
1294
  setWelcomeMessage(config.welcomeMessage ?? void 0);
1295
+ setSelectedModel(config.model ?? void 0);
1292
1296
  } catch (err) {
1293
1297
  console.error("[CrowCopilot] Failed to fetch styles:", err);
1294
1298
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1304,6 +1308,7 @@ function useCopilotStyles({
1304
1308
  setAgentName(cached.agentName || "Assistant");
1305
1309
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
1306
1310
  setWelcomeMessage(cached.welcomeMessage ?? void 0);
1311
+ setSelectedModel(cached.model ?? void 0);
1307
1312
  setIsLoading(false);
1308
1313
  return;
1309
1314
  }
@@ -1318,6 +1323,7 @@ function useCopilotStyles({
1318
1323
  agentName,
1319
1324
  persistAnonymousConversations,
1320
1325
  welcomeMessage,
1326
+ selectedModel,
1321
1327
  refetch: fetchStyles
1322
1328
  };
1323
1329
  }
@@ -1632,16 +1638,27 @@ function StreamingText({
1632
1638
  ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "crow-list-decimal crow-pl-5 crow-my-1.5", children }),
1633
1639
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "crow-mb-0.5 last:crow-mb-0", children }),
1634
1640
  p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "crow-mb-1.5 last:crow-mb-0", children }),
1635
- a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx(
1636
- "a",
1637
- {
1638
- href,
1639
- className: "crow-underline hover:crow-text-blue-300",
1640
- target: "_blank",
1641
- rel: "noopener noreferrer",
1642
- children
1643
- }
1644
- ),
1641
+ a: ({ href, children }) => {
1642
+ const isInternal = href?.startsWith("/");
1643
+ return /* @__PURE__ */ jsxRuntime.jsx(
1644
+ "a",
1645
+ {
1646
+ href,
1647
+ className: "crow-underline hover:crow-text-blue-300",
1648
+ ...!isInternal && { target: "_blank", rel: "noopener noreferrer" },
1649
+ onClick: isInternal ? (e) => {
1650
+ e.preventDefault();
1651
+ const a = document.createElement("a");
1652
+ a.href = href;
1653
+ a.style.display = "none";
1654
+ document.body.appendChild(a);
1655
+ a.click();
1656
+ document.body.removeChild(a);
1657
+ } : void 0,
1658
+ children
1659
+ }
1660
+ );
1661
+ },
1645
1662
  code: ({ className, children, ...props }) => {
1646
1663
  const isInline = !className;
1647
1664
  return isInline ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1969,16 +1986,27 @@ function MessageBubble({
1969
1986
  ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "crow-list-decimal crow-pl-5 crow-my-1.5", children }),
1970
1987
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "crow-mb-0.5 last:crow-mb-0", children }),
1971
1988
  p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "crow-mb-1.5 last:crow-mb-0", children }),
1972
- a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx(
1973
- "a",
1974
- {
1975
- href,
1976
- className: "crow-underline hover:crow-text-blue-300",
1977
- target: "_blank",
1978
- rel: "noopener noreferrer",
1979
- children
1980
- }
1981
- )
1989
+ a: ({ href, children }) => {
1990
+ const isInternal = href?.startsWith("/");
1991
+ return /* @__PURE__ */ jsxRuntime.jsx(
1992
+ "a",
1993
+ {
1994
+ href,
1995
+ className: "crow-underline hover:crow-text-blue-300",
1996
+ ...!isInternal && { target: "_blank", rel: "noopener noreferrer" },
1997
+ onClick: isInternal ? (e) => {
1998
+ e.preventDefault();
1999
+ const a = document.createElement("a");
2000
+ a.href = href;
2001
+ a.style.display = "none";
2002
+ document.body.appendChild(a);
2003
+ a.click();
2004
+ document.body.removeChild(a);
2005
+ } : void 0,
2006
+ children
2007
+ }
2008
+ );
2009
+ }
1982
2010
  },
1983
2011
  children: message.content
1984
2012
  }
@@ -3366,7 +3394,8 @@ function CrowCopilot({
3366
3394
  isLoading: isLoadingStyles,
3367
3395
  agentName: agentNameFromAPI,
3368
3396
  persistAnonymousConversations,
3369
- welcomeMessage: welcomeMessageFromAPI
3397
+ welcomeMessage: welcomeMessageFromAPI,
3398
+ selectedModel
3370
3399
  } = useCopilotStyles({
3371
3400
  productId,
3372
3401
  apiUrl,
@@ -3378,6 +3407,7 @@ function CrowCopilot({
3378
3407
  const messagesContainerRef = React3.useRef(null);
3379
3408
  const tabsScrollRef = React3.useRef(null);
3380
3409
  const executeClientToolRef = React3.useRef(null);
3410
+ const submitToolResultRef = React3.useRef(null);
3381
3411
  const [showConversationList, setShowConversationList] = React3.useState(false);
3382
3412
  const [isVerifiedUser, setIsVerifiedUser] = React3.useState(false);
3383
3413
  const [localTabs, setLocalTabs] = React3.useState([
@@ -3396,24 +3426,71 @@ function CrowCopilot({
3396
3426
  apiUrl,
3397
3427
  persistAnonymousConversations,
3398
3428
  welcomeMessage,
3429
+ selectedModel,
3399
3430
  onVerificationStatus: (isVerified) => {
3400
3431
  setIsVerifiedUser(isVerified);
3401
3432
  },
3402
3433
  onConversationId: () => {
3403
3434
  },
3435
+ onWorkflowEvent: (event) => {
3436
+ switch (event.type) {
3437
+ case "started":
3438
+ if (event.name && event.todos) {
3439
+ startWorkflow(event.name, event.todos);
3440
+ }
3441
+ break;
3442
+ case "todo_updated":
3443
+ if (event.todoId && event.todoStatus) {
3444
+ updateTodo(event.todoId, event.todoStatus);
3445
+ }
3446
+ break;
3447
+ case "ended":
3448
+ endWorkflow(2e3);
3449
+ break;
3450
+ case "complete_prompt":
3451
+ markComplete();
3452
+ break;
3453
+ }
3454
+ },
3404
3455
  onToolResult,
3405
- onToolCall: (event) => {
3406
- if (event.type === "client_call" && event.toolName) {
3407
- console.log(
3408
- "[Crow Copilot] Executing client tool:",
3409
- event.toolName,
3410
- event.arguments
3411
- );
3412
- const result = executeClientToolRef.current?.(
3413
- event.toolName,
3414
- event.arguments || {}
3415
- );
3416
- result?.then((r) => console.log("[Crow Copilot] Tool result:", r)).catch((e) => console.error("[Crow Copilot] Tool error:", e));
3456
+ onToolCall: async (event) => {
3457
+ if (event.type === "client_call" && event.toolName && event.toolCallId) {
3458
+ try {
3459
+ const result = await executeClientToolRef.current?.(
3460
+ event.toolName,
3461
+ event.arguments || {}
3462
+ );
3463
+ const resultObj = result;
3464
+ const dataObj = resultObj?.data;
3465
+ const wasUserCancelled = dataObj?.declined === true || typeof resultObj?.error === "string" && resultObj.error.includes("cancelled by user") || typeof resultObj?.error === "string" && resultObj.error.includes("declined");
3466
+ if (wasUserCancelled) {
3467
+ console.log("[Crow Copilot] Tool was cancelled by user");
3468
+ if (submitToolResultRef.current) {
3469
+ await submitToolResultRef.current(
3470
+ event.toolCallId,
3471
+ event.toolName,
3472
+ { success: false, cancelled: true, error: "Action was cancelled by the user." }
3473
+ );
3474
+ }
3475
+ return;
3476
+ }
3477
+ if (result && submitToolResultRef.current) {
3478
+ await submitToolResultRef.current(
3479
+ event.toolCallId,
3480
+ event.toolName,
3481
+ result
3482
+ );
3483
+ }
3484
+ } catch (e) {
3485
+ console.error("[Crow Copilot] Tool error:", e);
3486
+ if (submitToolResultRef.current) {
3487
+ await submitToolResultRef.current(
3488
+ event.toolCallId,
3489
+ event.toolName,
3490
+ { success: false, error: String(e) }
3491
+ );
3492
+ }
3493
+ }
3417
3494
  }
3418
3495
  },
3419
3496
  onRestoredConversation: () => {
@@ -3435,6 +3512,30 @@ function CrowCopilot({
3435
3512
  injectCopilotBodyStyles();
3436
3513
  }
3437
3514
  }, [variant]);
3515
+ const {
3516
+ activeWorkflow,
3517
+ startWorkflow,
3518
+ updateTodo,
3519
+ markComplete,
3520
+ endWorkflow,
3521
+ exitWorkflow
3522
+ } = useWorkflow({
3523
+ productId,
3524
+ apiUrl,
3525
+ conversationId: chat.conversationId,
3526
+ selectedModel: chat.selectedModel,
3527
+ onMessage: (content) => {
3528
+ chat.loadMessages([
3529
+ ...chat.messages,
3530
+ {
3531
+ id: `bot-${Date.now()}`,
3532
+ content,
3533
+ isBot: true,
3534
+ timestamp: /* @__PURE__ */ new Date()
3535
+ }
3536
+ ]);
3537
+ }
3538
+ });
3438
3539
  const { executeClientTool } = useCrowAPI({
3439
3540
  onIdentified: async () => {
3440
3541
  setIsVerifiedUser(true);
@@ -3446,6 +3547,7 @@ function CrowCopilot({
3446
3547
  }
3447
3548
  });
3448
3549
  executeClientToolRef.current = executeClientTool;
3550
+ submitToolResultRef.current = chat.submitToolResult;
3449
3551
  const handleBrowserConfirmation = React3.useCallback(
3450
3552
  (instruction) => {
3451
3553
  return new Promise((resolve) => {
@@ -3462,6 +3564,9 @@ function CrowCopilot({
3462
3564
  },
3463
3565
  []
3464
3566
  );
3567
+ const handleExitWorkflow = async () => {
3568
+ await exitWorkflow();
3569
+ };
3465
3570
  React3.useEffect(() => {
3466
3571
  window.__crow_browser_callbacks = {
3467
3572
  onConfirmation: handleBrowserConfirmation,
@@ -3787,6 +3892,13 @@ function CrowCopilot({
3787
3892
  ),
3788
3893
  showConversationList && !isVerifiedUser && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-mb-3 crow-rounded-xl crow-bg-gray-50 crow-border crow-border-gray-200 crow-p-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-text-sm crow-text-gray-600", children: "Sign in to view conversation history." }) })
3789
3894
  ] }),
3895
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsxRuntime.jsx(
3896
+ WorkflowPanel,
3897
+ {
3898
+ workflow: activeWorkflow,
3899
+ onExit: handleExitWorkflow
3900
+ }
3901
+ ) }),
3790
3902
  /* @__PURE__ */ jsxRuntime.jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
3791
3903
  /* @__PURE__ */ jsxRuntime.jsx(
3792
3904
  MessageList,