@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.d.cts CHANGED
@@ -699,6 +699,8 @@ interface UseCopilotStylesResult {
699
699
  persistAnonymousConversations: boolean | undefined;
700
700
  /** Custom welcome message (undefined uses SDK default) */
701
701
  welcomeMessage: string | undefined;
702
+ /** AI model configured for this product */
703
+ selectedModel: string | undefined;
702
704
  /** Refetch styles from API */
703
705
  refetch: () => Promise<void>;
704
706
  }
package/dist/index.d.ts CHANGED
@@ -699,6 +699,8 @@ interface UseCopilotStylesResult {
699
699
  persistAnonymousConversations: boolean | undefined;
700
700
  /** Custom welcome message (undefined uses SDK default) */
701
701
  welcomeMessage: string | undefined;
702
+ /** AI model configured for this product */
703
+ selectedModel: string | undefined;
702
704
  /** Refetch styles from API */
703
705
  refetch: () => Promise<void>;
704
706
  }
package/dist/index.js CHANGED
@@ -1251,6 +1251,9 @@ function useCopilotStyles({
1251
1251
  const [welcomeMessage, setWelcomeMessage] = useState(
1252
1252
  styleCache.get(key)?.welcomeMessage ?? void 0
1253
1253
  );
1254
+ const [selectedModel, setSelectedModel] = useState(
1255
+ styleCache.get(key)?.model ?? void 0
1256
+ );
1254
1257
  const hasFetchedRef = useRef(false);
1255
1258
  const fetchStyles = async () => {
1256
1259
  if (skip) return;
@@ -1263,6 +1266,7 @@ function useCopilotStyles({
1263
1266
  setAgentName(config.agentName || "Assistant");
1264
1267
  setPersistAnonymousConversations(config.persistAnonymousConversations ?? true);
1265
1268
  setWelcomeMessage(config.welcomeMessage ?? void 0);
1269
+ setSelectedModel(config.model ?? void 0);
1266
1270
  } catch (err) {
1267
1271
  console.error("[CrowCopilot] Failed to fetch styles:", err);
1268
1272
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1278,6 +1282,7 @@ function useCopilotStyles({
1278
1282
  setAgentName(cached.agentName || "Assistant");
1279
1283
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
1280
1284
  setWelcomeMessage(cached.welcomeMessage ?? void 0);
1285
+ setSelectedModel(cached.model ?? void 0);
1281
1286
  setIsLoading(false);
1282
1287
  return;
1283
1288
  }
@@ -1292,6 +1297,7 @@ function useCopilotStyles({
1292
1297
  agentName,
1293
1298
  persistAnonymousConversations,
1294
1299
  welcomeMessage,
1300
+ selectedModel,
1295
1301
  refetch: fetchStyles
1296
1302
  };
1297
1303
  }
@@ -1606,16 +1612,27 @@ function StreamingText({
1606
1612
  ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "crow-list-decimal crow-pl-5 crow-my-1.5", children }),
1607
1613
  li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "crow-mb-0.5 last:crow-mb-0", children }),
1608
1614
  p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "crow-mb-1.5 last:crow-mb-0", children }),
1609
- a: ({ href, children }) => /* @__PURE__ */ jsx(
1610
- "a",
1611
- {
1612
- href,
1613
- className: "crow-underline hover:crow-text-blue-300",
1614
- target: "_blank",
1615
- rel: "noopener noreferrer",
1616
- children
1617
- }
1618
- ),
1615
+ a: ({ href, children }) => {
1616
+ const isInternal = href?.startsWith("/");
1617
+ return /* @__PURE__ */ jsx(
1618
+ "a",
1619
+ {
1620
+ href,
1621
+ className: "crow-underline hover:crow-text-blue-300",
1622
+ ...!isInternal && { target: "_blank", rel: "noopener noreferrer" },
1623
+ onClick: isInternal ? (e) => {
1624
+ e.preventDefault();
1625
+ const a = document.createElement("a");
1626
+ a.href = href;
1627
+ a.style.display = "none";
1628
+ document.body.appendChild(a);
1629
+ a.click();
1630
+ document.body.removeChild(a);
1631
+ } : void 0,
1632
+ children
1633
+ }
1634
+ );
1635
+ },
1619
1636
  code: ({ className, children, ...props }) => {
1620
1637
  const isInline = !className;
1621
1638
  return isInline ? /* @__PURE__ */ jsx(
@@ -1943,16 +1960,27 @@ function MessageBubble({
1943
1960
  ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "crow-list-decimal crow-pl-5 crow-my-1.5", children }),
1944
1961
  li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "crow-mb-0.5 last:crow-mb-0", children }),
1945
1962
  p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "crow-mb-1.5 last:crow-mb-0", children }),
1946
- a: ({ href, children }) => /* @__PURE__ */ jsx(
1947
- "a",
1948
- {
1949
- href,
1950
- className: "crow-underline hover:crow-text-blue-300",
1951
- target: "_blank",
1952
- rel: "noopener noreferrer",
1953
- children
1954
- }
1955
- )
1963
+ a: ({ href, children }) => {
1964
+ const isInternal = href?.startsWith("/");
1965
+ return /* @__PURE__ */ jsx(
1966
+ "a",
1967
+ {
1968
+ href,
1969
+ className: "crow-underline hover:crow-text-blue-300",
1970
+ ...!isInternal && { target: "_blank", rel: "noopener noreferrer" },
1971
+ onClick: isInternal ? (e) => {
1972
+ e.preventDefault();
1973
+ const a = document.createElement("a");
1974
+ a.href = href;
1975
+ a.style.display = "none";
1976
+ document.body.appendChild(a);
1977
+ a.click();
1978
+ document.body.removeChild(a);
1979
+ } : void 0,
1980
+ children
1981
+ }
1982
+ );
1983
+ }
1956
1984
  },
1957
1985
  children: message.content
1958
1986
  }
@@ -3340,7 +3368,8 @@ function CrowCopilot({
3340
3368
  isLoading: isLoadingStyles,
3341
3369
  agentName: agentNameFromAPI,
3342
3370
  persistAnonymousConversations,
3343
- welcomeMessage: welcomeMessageFromAPI
3371
+ welcomeMessage: welcomeMessageFromAPI,
3372
+ selectedModel
3344
3373
  } = useCopilotStyles({
3345
3374
  productId,
3346
3375
  apiUrl,
@@ -3352,6 +3381,7 @@ function CrowCopilot({
3352
3381
  const messagesContainerRef = useRef(null);
3353
3382
  const tabsScrollRef = useRef(null);
3354
3383
  const executeClientToolRef = useRef(null);
3384
+ const submitToolResultRef = useRef(null);
3355
3385
  const [showConversationList, setShowConversationList] = useState(false);
3356
3386
  const [isVerifiedUser, setIsVerifiedUser] = useState(false);
3357
3387
  const [localTabs, setLocalTabs] = useState([
@@ -3370,24 +3400,71 @@ function CrowCopilot({
3370
3400
  apiUrl,
3371
3401
  persistAnonymousConversations,
3372
3402
  welcomeMessage,
3403
+ selectedModel,
3373
3404
  onVerificationStatus: (isVerified) => {
3374
3405
  setIsVerifiedUser(isVerified);
3375
3406
  },
3376
3407
  onConversationId: () => {
3377
3408
  },
3409
+ onWorkflowEvent: (event) => {
3410
+ switch (event.type) {
3411
+ case "started":
3412
+ if (event.name && event.todos) {
3413
+ startWorkflow(event.name, event.todos);
3414
+ }
3415
+ break;
3416
+ case "todo_updated":
3417
+ if (event.todoId && event.todoStatus) {
3418
+ updateTodo(event.todoId, event.todoStatus);
3419
+ }
3420
+ break;
3421
+ case "ended":
3422
+ endWorkflow(2e3);
3423
+ break;
3424
+ case "complete_prompt":
3425
+ markComplete();
3426
+ break;
3427
+ }
3428
+ },
3378
3429
  onToolResult,
3379
- onToolCall: (event) => {
3380
- if (event.type === "client_call" && event.toolName) {
3381
- console.log(
3382
- "[Crow Copilot] Executing client tool:",
3383
- event.toolName,
3384
- event.arguments
3385
- );
3386
- const result = executeClientToolRef.current?.(
3387
- event.toolName,
3388
- event.arguments || {}
3389
- );
3390
- result?.then((r) => console.log("[Crow Copilot] Tool result:", r)).catch((e) => console.error("[Crow Copilot] Tool error:", e));
3430
+ onToolCall: async (event) => {
3431
+ if (event.type === "client_call" && event.toolName && event.toolCallId) {
3432
+ try {
3433
+ const result = await executeClientToolRef.current?.(
3434
+ event.toolName,
3435
+ event.arguments || {}
3436
+ );
3437
+ const resultObj = result;
3438
+ const dataObj = resultObj?.data;
3439
+ const wasUserCancelled = dataObj?.declined === true || typeof resultObj?.error === "string" && resultObj.error.includes("cancelled by user") || typeof resultObj?.error === "string" && resultObj.error.includes("declined");
3440
+ if (wasUserCancelled) {
3441
+ console.log("[Crow Copilot] Tool was cancelled by user");
3442
+ if (submitToolResultRef.current) {
3443
+ await submitToolResultRef.current(
3444
+ event.toolCallId,
3445
+ event.toolName,
3446
+ { success: false, cancelled: true, error: "Action was cancelled by the user." }
3447
+ );
3448
+ }
3449
+ return;
3450
+ }
3451
+ if (result && submitToolResultRef.current) {
3452
+ await submitToolResultRef.current(
3453
+ event.toolCallId,
3454
+ event.toolName,
3455
+ result
3456
+ );
3457
+ }
3458
+ } catch (e) {
3459
+ console.error("[Crow Copilot] Tool error:", e);
3460
+ if (submitToolResultRef.current) {
3461
+ await submitToolResultRef.current(
3462
+ event.toolCallId,
3463
+ event.toolName,
3464
+ { success: false, error: String(e) }
3465
+ );
3466
+ }
3467
+ }
3391
3468
  }
3392
3469
  },
3393
3470
  onRestoredConversation: () => {
@@ -3409,6 +3486,30 @@ function CrowCopilot({
3409
3486
  injectCopilotBodyStyles();
3410
3487
  }
3411
3488
  }, [variant]);
3489
+ const {
3490
+ activeWorkflow,
3491
+ startWorkflow,
3492
+ updateTodo,
3493
+ markComplete,
3494
+ endWorkflow,
3495
+ exitWorkflow
3496
+ } = useWorkflow({
3497
+ productId,
3498
+ apiUrl,
3499
+ conversationId: chat.conversationId,
3500
+ selectedModel: chat.selectedModel,
3501
+ onMessage: (content) => {
3502
+ chat.loadMessages([
3503
+ ...chat.messages,
3504
+ {
3505
+ id: `bot-${Date.now()}`,
3506
+ content,
3507
+ isBot: true,
3508
+ timestamp: /* @__PURE__ */ new Date()
3509
+ }
3510
+ ]);
3511
+ }
3512
+ });
3412
3513
  const { executeClientTool } = useCrowAPI({
3413
3514
  onIdentified: async () => {
3414
3515
  setIsVerifiedUser(true);
@@ -3420,6 +3521,7 @@ function CrowCopilot({
3420
3521
  }
3421
3522
  });
3422
3523
  executeClientToolRef.current = executeClientTool;
3524
+ submitToolResultRef.current = chat.submitToolResult;
3423
3525
  const handleBrowserConfirmation = useCallback(
3424
3526
  (instruction) => {
3425
3527
  return new Promise((resolve) => {
@@ -3436,6 +3538,9 @@ function CrowCopilot({
3436
3538
  },
3437
3539
  []
3438
3540
  );
3541
+ const handleExitWorkflow = async () => {
3542
+ await exitWorkflow();
3543
+ };
3439
3544
  useEffect(() => {
3440
3545
  window.__crow_browser_callbacks = {
3441
3546
  onConfirmation: handleBrowserConfirmation,
@@ -3761,6 +3866,13 @@ function CrowCopilot({
3761
3866
  ),
3762
3867
  showConversationList && !isVerifiedUser && /* @__PURE__ */ jsx("div", { className: "crow-mb-3 crow-rounded-xl crow-bg-gray-50 crow-border crow-border-gray-200 crow-p-4", children: /* @__PURE__ */ jsx("div", { className: "crow-text-sm crow-text-gray-600", children: "Sign in to view conversation history." }) })
3763
3868
  ] }),
3869
+ /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsx(
3870
+ WorkflowPanel,
3871
+ {
3872
+ workflow: activeWorkflow,
3873
+ onExit: handleExitWorkflow
3874
+ }
3875
+ ) }),
3764
3876
  /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
3765
3877
  /* @__PURE__ */ jsx(
3766
3878
  MessageList,