@usecrow/ui 0.1.32 → 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
  }
@@ -3388,7 +3394,8 @@ function CrowCopilot({
3388
3394
  isLoading: isLoadingStyles,
3389
3395
  agentName: agentNameFromAPI,
3390
3396
  persistAnonymousConversations,
3391
- welcomeMessage: welcomeMessageFromAPI
3397
+ welcomeMessage: welcomeMessageFromAPI,
3398
+ selectedModel
3392
3399
  } = useCopilotStyles({
3393
3400
  productId,
3394
3401
  apiUrl,
@@ -3400,6 +3407,7 @@ function CrowCopilot({
3400
3407
  const messagesContainerRef = React3.useRef(null);
3401
3408
  const tabsScrollRef = React3.useRef(null);
3402
3409
  const executeClientToolRef = React3.useRef(null);
3410
+ const submitToolResultRef = React3.useRef(null);
3403
3411
  const [showConversationList, setShowConversationList] = React3.useState(false);
3404
3412
  const [isVerifiedUser, setIsVerifiedUser] = React3.useState(false);
3405
3413
  const [localTabs, setLocalTabs] = React3.useState([
@@ -3418,24 +3426,71 @@ function CrowCopilot({
3418
3426
  apiUrl,
3419
3427
  persistAnonymousConversations,
3420
3428
  welcomeMessage,
3429
+ selectedModel,
3421
3430
  onVerificationStatus: (isVerified) => {
3422
3431
  setIsVerifiedUser(isVerified);
3423
3432
  },
3424
3433
  onConversationId: () => {
3425
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
+ },
3426
3455
  onToolResult,
3427
- onToolCall: (event) => {
3428
- if (event.type === "client_call" && event.toolName) {
3429
- console.log(
3430
- "[Crow Copilot] Executing client tool:",
3431
- event.toolName,
3432
- event.arguments
3433
- );
3434
- const result = executeClientToolRef.current?.(
3435
- event.toolName,
3436
- event.arguments || {}
3437
- );
3438
- 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
+ }
3439
3494
  }
3440
3495
  },
3441
3496
  onRestoredConversation: () => {
@@ -3457,6 +3512,30 @@ function CrowCopilot({
3457
3512
  injectCopilotBodyStyles();
3458
3513
  }
3459
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
+ });
3460
3539
  const { executeClientTool } = useCrowAPI({
3461
3540
  onIdentified: async () => {
3462
3541
  setIsVerifiedUser(true);
@@ -3468,6 +3547,7 @@ function CrowCopilot({
3468
3547
  }
3469
3548
  });
3470
3549
  executeClientToolRef.current = executeClientTool;
3550
+ submitToolResultRef.current = chat.submitToolResult;
3471
3551
  const handleBrowserConfirmation = React3.useCallback(
3472
3552
  (instruction) => {
3473
3553
  return new Promise((resolve) => {
@@ -3484,6 +3564,9 @@ function CrowCopilot({
3484
3564
  },
3485
3565
  []
3486
3566
  );
3567
+ const handleExitWorkflow = async () => {
3568
+ await exitWorkflow();
3569
+ };
3487
3570
  React3.useEffect(() => {
3488
3571
  window.__crow_browser_callbacks = {
3489
3572
  onConfirmation: handleBrowserConfirmation,
@@ -3809,6 +3892,13 @@ function CrowCopilot({
3809
3892
  ),
3810
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." }) })
3811
3894
  ] }),
3895
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsxRuntime.jsx(
3896
+ WorkflowPanel,
3897
+ {
3898
+ workflow: activeWorkflow,
3899
+ onExit: handleExitWorkflow
3900
+ }
3901
+ ) }),
3812
3902
  /* @__PURE__ */ jsxRuntime.jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
3813
3903
  /* @__PURE__ */ jsxRuntime.jsx(
3814
3904
  MessageList,