@kite-copilot/chat-panel 0.2.42 → 0.2.44

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
@@ -70,7 +70,7 @@ var import_react = __toESM(require("react"), 1);
70
70
  var import_client = require("react-dom/client");
71
71
 
72
72
  // src/ChatPanel.tsx
73
- var React5 = __toESM(require("react"), 1);
73
+ var React6 = __toESM(require("react"), 1);
74
74
  var import_supabase_js = require("@supabase/supabase-js");
75
75
 
76
76
  // src/lib/utils.ts
@@ -380,9 +380,13 @@ function useUserAuth({
380
380
  const lastSessionIdRef = React4.useRef(null);
381
381
  const fetchUser = React4.useCallback(async () => {
382
382
  if (!productBackendUrl || !enabled) {
383
+ console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
383
384
  setAuthState({ status: "idle" });
384
385
  return;
385
386
  }
387
+ console.log("[useUserAuth] Starting auth request to product backend...");
388
+ console.log("[useUserAuth] Product backend URL:", productBackendUrl);
389
+ console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
386
390
  setAuthState({ status: "loading" });
387
391
  try {
388
392
  const response = await fetch(`${productBackendUrl}/users/me`, {
@@ -393,7 +397,9 @@ function useUserAuth({
393
397
  "Accept": "application/json"
394
398
  }
395
399
  });
400
+ console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
396
401
  if (!response.ok) {
402
+ console.log("[useUserAuth] Auth request failed with status:", response.status);
397
403
  if (response.status === 401) {
398
404
  throw new Error("Please log in to use the chat assistant.");
399
405
  }
@@ -403,8 +409,17 @@ function useUserAuth({
403
409
  throw new Error(`Authentication failed (${response.status})`);
404
410
  }
405
411
  const user = await response.json();
412
+ console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
413
+ console.log("[useUserAuth] id:", user.id);
414
+ console.log("[useUserAuth] email:", user.email);
415
+ console.log("[useUserAuth] name:", user.name);
416
+ console.log("[useUserAuth] role:", user.role);
417
+ console.log("[useUserAuth] isInternal:", user.isInternal);
418
+ console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
419
+ console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
406
420
  setAuthState({ status: "authenticated", user });
407
421
  } catch (error) {
422
+ console.log("[useUserAuth] Auth ERROR:", error);
408
423
  const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
409
424
  setAuthState({ status: "error", error: message });
410
425
  }
@@ -421,6 +436,47 @@ function useUserAuth({
421
436
  return { authState, retry };
422
437
  }
423
438
 
439
+ // src/hooks/useOrgConfig.ts
440
+ var React5 = __toESM(require("react"), 1);
441
+ function useOrgConfig({ agentUrl, orgId }) {
442
+ const [state, setState] = React5.useState({
443
+ status: "idle",
444
+ config: null,
445
+ error: null
446
+ });
447
+ React5.useEffect(() => {
448
+ if (!agentUrl || !orgId) {
449
+ console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
450
+ return;
451
+ }
452
+ const fetchConfig = async () => {
453
+ setState({ status: "loading", config: null, error: null });
454
+ const url = `${agentUrl}/org/${orgId}/config`;
455
+ console.log("[useOrgConfig] Fetching org config from:", url);
456
+ try {
457
+ const response = await fetch(url, {
458
+ method: "GET",
459
+ headers: {
460
+ "Accept": "application/json"
461
+ }
462
+ });
463
+ if (!response.ok) {
464
+ throw new Error(`Failed to fetch org config (${response.status})`);
465
+ }
466
+ const config = await response.json();
467
+ console.log("[useOrgConfig] Received config:", config);
468
+ setState({ status: "success", config, error: null });
469
+ } catch (error) {
470
+ const message = error instanceof Error ? error.message : "Failed to fetch org config";
471
+ console.error("[useOrgConfig] Error:", message);
472
+ setState({ status: "error", config: null, error: message });
473
+ }
474
+ };
475
+ fetchConfig();
476
+ }, [agentUrl, orgId]);
477
+ return state;
478
+ }
479
+
424
480
  // src/components/ui/card.tsx
425
481
  var import_jsx_runtime7 = require("react/jsx-runtime");
426
482
  function Card({ className, ...props }) {
@@ -1021,7 +1077,7 @@ function TypingIndicator({ className = "" }) {
1021
1077
 
1022
1078
  // src/ChatPanel.tsx
1023
1079
  var import_jsx_runtime10 = require("react/jsx-runtime");
1024
- var CHAT_PANEL_VERSION = true ? "0.2.42" : "dev";
1080
+ var CHAT_PANEL_VERSION = true ? "0.2.44" : "dev";
1025
1081
  var DEFAULT_AGENT_URL = "http://localhost:5002";
1026
1082
  var PANEL_WIDTH = 340;
1027
1083
  function unescapeJsonString(str) {
@@ -1485,16 +1541,18 @@ function ChatPanel({
1485
1541
  supabaseAnonKey,
1486
1542
  productBackendUrl
1487
1543
  } = {}) {
1488
- const [messages, setMessages] = React5.useState(initialMessages);
1489
- const [input, setInput] = React5.useState("");
1490
- const [sessionId, setSessionId] = React5.useState(() => crypto.randomUUID());
1544
+ const [messages, setMessages] = React6.useState(initialMessages);
1545
+ const [input, setInput] = React6.useState("");
1546
+ const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
1547
+ const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
1548
+ const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
1491
1549
  const { authState, retry: retryAuth } = useUserAuth({
1492
- productBackendUrl,
1550
+ productBackendUrl: effectiveProductBackendUrl,
1493
1551
  sessionId,
1494
- enabled: !!productBackendUrl
1495
- // Only enable if URL is provided
1552
+ enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
1553
+ // Only enable after config is fetched
1496
1554
  });
1497
- const effectiveUser = React5.useMemo(() => {
1555
+ const effectiveUser = React6.useMemo(() => {
1498
1556
  if (authState.status === "authenticated") {
1499
1557
  return {
1500
1558
  userId: authState.user.id,
@@ -1512,16 +1570,16 @@ function ChatPanel({
1512
1570
  isInternal: false
1513
1571
  };
1514
1572
  }, [authState, userId, userName, userEmail]);
1515
- const [isEscalated, setIsEscalated] = React5.useState(false);
1516
- const escalationWsRef = React5.useRef(null);
1517
- const [agentIsTyping, setAgentIsTyping] = React5.useState(false);
1518
- const supabaseRef = React5.useRef(null);
1519
- const typingChannelRef = React5.useRef(null);
1520
- const typingTimeoutRef = React5.useRef(null);
1521
- React5.useEffect(() => {
1573
+ const [isEscalated, setIsEscalated] = React6.useState(false);
1574
+ const escalationWsRef = React6.useRef(null);
1575
+ const [agentIsTyping, setAgentIsTyping] = React6.useState(false);
1576
+ const supabaseRef = React6.useRef(null);
1577
+ const typingChannelRef = React6.useRef(null);
1578
+ const typingTimeoutRef = React6.useRef(null);
1579
+ React6.useEffect(() => {
1522
1580
  console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
1523
1581
  }, []);
1524
- const resetSession = React5.useCallback(() => {
1582
+ const resetSession = React6.useCallback(() => {
1525
1583
  console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
1526
1584
  if (isEscalated && supabaseRef.current && sessionId) {
1527
1585
  console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
@@ -1551,12 +1609,12 @@ function ChatPanel({
1551
1609
  typingChannelRef.current = null;
1552
1610
  }
1553
1611
  }, [isEscalated, sessionId]);
1554
- React5.useEffect(() => {
1612
+ React6.useEffect(() => {
1555
1613
  if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
1556
1614
  supabaseRef.current = (0, import_supabase_js.createClient)(supabaseUrl, supabaseAnonKey);
1557
1615
  }
1558
1616
  }, [supabaseUrl, supabaseAnonKey]);
1559
- React5.useEffect(() => {
1617
+ React6.useEffect(() => {
1560
1618
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1561
1619
  return;
1562
1620
  }
@@ -1593,8 +1651,8 @@ function ChatPanel({
1593
1651
  }
1594
1652
  };
1595
1653
  }, [isEscalated, sessionId]);
1596
- const heartbeatIntervalRef = React5.useRef(null);
1597
- const updateCustomerStatus = React5.useCallback(async (status) => {
1654
+ const heartbeatIntervalRef = React6.useRef(null);
1655
+ const updateCustomerStatus = React6.useCallback(async (status) => {
1598
1656
  if (!supabaseRef.current || !sessionId) return;
1599
1657
  try {
1600
1658
  await supabaseRef.current.from("escalations").update({
@@ -1605,7 +1663,7 @@ function ChatPanel({
1605
1663
  console.error("[KiteChat] Failed to update customer status:", err);
1606
1664
  }
1607
1665
  }, [sessionId]);
1608
- React5.useEffect(() => {
1666
+ React6.useEffect(() => {
1609
1667
  if (!isEscalated || !sessionId || !supabaseRef.current) {
1610
1668
  return;
1611
1669
  }
@@ -1653,7 +1711,7 @@ function ChatPanel({
1653
1711
  }
1654
1712
  };
1655
1713
  }, [isEscalated, sessionId, updateCustomerStatus]);
1656
- const sendTypingIndicator = React5.useCallback((isTyping) => {
1714
+ const sendTypingIndicator = React6.useCallback((isTyping) => {
1657
1715
  if (!typingChannelRef.current) {
1658
1716
  console.log("[KiteChat] Cannot send typing - channel not ready");
1659
1717
  return;
@@ -1669,8 +1727,8 @@ function ChatPanel({
1669
1727
  payload: { sender: "user", isTyping }
1670
1728
  });
1671
1729
  }, [isEscalated]);
1672
- const userTypingTimeoutRef = React5.useRef(null);
1673
- const handleTypingStart = React5.useCallback(() => {
1730
+ const userTypingTimeoutRef = React6.useRef(null);
1731
+ const handleTypingStart = React6.useCallback(() => {
1674
1732
  if (!isEscalated || !supabaseRef.current) return;
1675
1733
  sendTypingIndicator(true);
1676
1734
  updateCustomerStatus("active");
@@ -1681,19 +1739,19 @@ function ChatPanel({
1681
1739
  sendTypingIndicator(false);
1682
1740
  }, 1500);
1683
1741
  }, [isEscalated, sendTypingIndicator, updateCustomerStatus]);
1684
- const streamIntervals = React5.useRef({});
1742
+ const streamIntervals = React6.useRef({});
1685
1743
  const isEmpty = messages.length === 0;
1686
- const [phase, setPhase] = React5.useState("idle");
1687
- const [progressSteps, setProgressSteps] = React5.useState([]);
1688
- const phaseTimers = React5.useRef([]);
1744
+ const [phase, setPhase] = React6.useState("idle");
1745
+ const [progressSteps, setProgressSteps] = React6.useState([]);
1746
+ const phaseTimers = React6.useRef([]);
1689
1747
  const lastRole = messages.length ? messages[messages.length - 1].role : void 0;
1690
- const [panelView, setPanelView] = React5.useState(
1748
+ const [panelView, setPanelView] = React6.useState(
1691
1749
  "landing"
1692
1750
  );
1693
- const [currentFolderId, setCurrentFolderId] = React5.useState(void 0);
1694
- const [startingQuestions, setStartingQuestions] = React5.useState(startingQuestionsProp || defaultStartingQuestions);
1695
- const [loadingQuestions, setLoadingQuestions] = React5.useState(false);
1696
- React5.useEffect(() => {
1751
+ const [currentFolderId, setCurrentFolderId] = React6.useState(void 0);
1752
+ const [startingQuestions, setStartingQuestions] = React6.useState(startingQuestionsProp || defaultStartingQuestions);
1753
+ const [loadingQuestions, setLoadingQuestions] = React6.useState(false);
1754
+ React6.useEffect(() => {
1697
1755
  if (startingQuestionsEndpoint && !startingQuestionsProp) {
1698
1756
  setLoadingQuestions(true);
1699
1757
  fetch(startingQuestionsEndpoint).then((res) => res.json()).then((data) => {
@@ -1705,16 +1763,16 @@ function ChatPanel({
1705
1763
  }).finally(() => setLoadingQuestions(false));
1706
1764
  }
1707
1765
  }, [startingQuestionsEndpoint, startingQuestionsProp]);
1708
- React5.useEffect(() => {
1766
+ React6.useEffect(() => {
1709
1767
  if (startingQuestionsProp) {
1710
1768
  setStartingQuestions(startingQuestionsProp);
1711
1769
  }
1712
1770
  }, [startingQuestionsProp]);
1713
- const [activeGuide, setActiveGuide] = React5.useState(void 0);
1714
- const activeGuideRef = React5.useRef(void 0);
1715
- const latestBulkSummaryNavigationRef = React5.useRef(null);
1716
- const [guideComplete, setGuideComplete] = React5.useState(false);
1717
- React5.useEffect(() => {
1771
+ const [activeGuide, setActiveGuide] = React6.useState(void 0);
1772
+ const activeGuideRef = React6.useRef(void 0);
1773
+ const latestBulkSummaryNavigationRef = React6.useRef(null);
1774
+ const [guideComplete, setGuideComplete] = React6.useState(false);
1775
+ React6.useEffect(() => {
1718
1776
  window.resetIntegrationNotification = () => {
1719
1777
  localStorage.removeItem("gmailNotificationSeen");
1720
1778
  console.log(
@@ -1748,7 +1806,7 @@ function ChatPanel({
1748
1806
  );
1749
1807
  };
1750
1808
  }, []);
1751
- React5.useEffect(() => {
1809
+ React6.useEffect(() => {
1752
1810
  if (activeGuide) {
1753
1811
  if (!activeGuideRef.current || activeGuideRef.current.id !== activeGuide.id || activeGuideRef.current.stepIndex !== activeGuide.stepIndex) {
1754
1812
  activeGuideRef.current = activeGuide;
@@ -1757,21 +1815,21 @@ function ChatPanel({
1757
1815
  activeGuideRef.current = void 0;
1758
1816
  }
1759
1817
  }, [activeGuide]);
1760
- const [pendingNavigation, setPendingNavigation] = React5.useState(null);
1761
- const [pendingAction, setPendingAction] = React5.useState(null);
1762
- const [actionFormData, setActionFormData] = React5.useState({});
1763
- const messagesEndRef = React5.useRef(null);
1764
- const messagesContainerRef = React5.useRef(null);
1765
- const currentStepRef = React5.useRef(null);
1818
+ const [pendingNavigation, setPendingNavigation] = React6.useState(null);
1819
+ const [pendingAction, setPendingAction] = React6.useState(null);
1820
+ const [actionFormData, setActionFormData] = React6.useState({});
1821
+ const messagesEndRef = React6.useRef(null);
1822
+ const messagesContainerRef = React6.useRef(null);
1823
+ const currentStepRef = React6.useRef(null);
1766
1824
  const { cursorState, moveTo, hide } = useGuideCursor();
1767
- const [pendingFile, setPendingFile] = React5.useState(null);
1768
- const [pendingBulkSession, setPendingBulkSession] = React5.useState(null);
1769
- const pendingBulkSessionRef = React5.useRef(null);
1770
- const fileInputRef = React5.useRef(null);
1771
- const [searchExpanded, setSearchExpanded] = React5.useState(false);
1772
- const [searchInput, setSearchInput] = React5.useState("");
1773
- const searchInputRef = React5.useRef(null);
1774
- React5.useEffect(() => {
1825
+ const [pendingFile, setPendingFile] = React6.useState(null);
1826
+ const [pendingBulkSession, setPendingBulkSession] = React6.useState(null);
1827
+ const pendingBulkSessionRef = React6.useRef(null);
1828
+ const fileInputRef = React6.useRef(null);
1829
+ const [searchExpanded, setSearchExpanded] = React6.useState(false);
1830
+ const [searchInput, setSearchInput] = React6.useState("");
1831
+ const searchInputRef = React6.useRef(null);
1832
+ React6.useEffect(() => {
1775
1833
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1776
1834
  return;
1777
1835
  }
@@ -1797,7 +1855,7 @@ function ChatPanel({
1797
1855
  const interval = setInterval(checkForDialogOpen, 300);
1798
1856
  return () => clearInterval(interval);
1799
1857
  }, [activeGuide, hide]);
1800
- React5.useEffect(() => {
1858
+ React6.useEffect(() => {
1801
1859
  return () => {
1802
1860
  Object.values(streamIntervals.current).forEach(
1803
1861
  (id) => window.clearInterval(id)
@@ -1807,7 +1865,7 @@ function ChatPanel({
1807
1865
  phaseTimers.current = [];
1808
1866
  };
1809
1867
  }, []);
1810
- React5.useEffect(() => {
1868
+ React6.useEffect(() => {
1811
1869
  if (activeGuide && messages.length > 0) {
1812
1870
  const lastMessage = messages[messages.length - 1];
1813
1871
  if (lastMessage.kind === "guideStep" || lastMessage.kind === "guideComplete") {
@@ -1824,7 +1882,7 @@ function ChatPanel({
1824
1882
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1825
1883
  }
1826
1884
  }, [messages, phase, activeGuide]);
1827
- const latestBulkSummaryNavigation = React5.useMemo(() => {
1885
+ const latestBulkSummaryNavigation = React6.useMemo(() => {
1828
1886
  for (let i = messages.length - 1; i >= 0; i--) {
1829
1887
  const msg = messages[i];
1830
1888
  if (msg.kind === "bulkSummary" && msg.bulkSummary?.navigationPage && msg.bulkSummary.successes > 0) {
@@ -1833,13 +1891,13 @@ function ChatPanel({
1833
1891
  }
1834
1892
  return null;
1835
1893
  }, [messages]);
1836
- React5.useEffect(() => {
1894
+ React6.useEffect(() => {
1837
1895
  latestBulkSummaryNavigationRef.current = latestBulkSummaryNavigation;
1838
1896
  }, [latestBulkSummaryNavigation]);
1839
- React5.useEffect(() => {
1897
+ React6.useEffect(() => {
1840
1898
  pendingBulkSessionRef.current = pendingBulkSession;
1841
1899
  }, [pendingBulkSession]);
1842
- React5.useEffect(() => {
1900
+ React6.useEffect(() => {
1843
1901
  const handleKeyDown = (e) => {
1844
1902
  if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
1845
1903
  const currentBulkSession = pendingBulkSessionRef.current;
@@ -1902,7 +1960,7 @@ function ChatPanel({
1902
1960
  guideComplete,
1903
1961
  onNavigate
1904
1962
  ]);
1905
- const connectToEscalationWs = React5.useCallback((currentSessionId) => {
1963
+ const connectToEscalationWs = React6.useCallback((currentSessionId) => {
1906
1964
  if (!agentUrl) return;
1907
1965
  if (escalationWsRef.current) {
1908
1966
  escalationWsRef.current.close();
@@ -1945,7 +2003,7 @@ function ChatPanel({
1945
2003
  };
1946
2004
  escalationWsRef.current = ws;
1947
2005
  }, [agentUrl]);
1948
- const sendEscalatedMessage = React5.useCallback(async (content) => {
2006
+ const sendEscalatedMessage = React6.useCallback(async (content) => {
1949
2007
  if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
1950
2008
  console.error("[KiteChat] Escalation WebSocket not connected");
1951
2009
  return false;
@@ -1962,14 +2020,14 @@ function ChatPanel({
1962
2020
  return false;
1963
2021
  }
1964
2022
  }, [updateCustomerStatus]);
1965
- React5.useEffect(() => {
2023
+ React6.useEffect(() => {
1966
2024
  return () => {
1967
2025
  if (escalationWsRef.current) {
1968
2026
  escalationWsRef.current.close();
1969
2027
  }
1970
2028
  };
1971
2029
  }, []);
1972
- React5.useEffect(() => {
2030
+ React6.useEffect(() => {
1973
2031
  if (isEscalated && sessionId) {
1974
2032
  connectToEscalationWs(sessionId);
1975
2033
  }
@@ -2235,6 +2293,15 @@ function ChatPanel({
2235
2293
  try {
2236
2294
  const controller = new AbortController();
2237
2295
  const timeoutId = setTimeout(() => controller.abort(), 6e4);
2296
+ console.log("[ChatPanel] Sending chat request to agent backend...");
2297
+ console.log("[ChatPanel] Agent URL:", agentUrl);
2298
+ console.log("[ChatPanel] User data being sent:");
2299
+ console.log("[ChatPanel] user_id:", effectiveUser.userId);
2300
+ console.log("[ChatPanel] user_name:", effectiveUser.userName);
2301
+ console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
2302
+ console.log("[ChatPanel] user_organization:", userOrganization);
2303
+ console.log("[ChatPanel] org_id:", orgId);
2304
+ console.log("[ChatPanel] authState.status:", authState.status);
2238
2305
  const response = await fetch(`${agentUrl}/chat/stream`, {
2239
2306
  method: "POST",
2240
2307
  headers: {
@@ -3189,7 +3256,38 @@ ${userText}`
3189
3256
  ] })
3190
3257
  ] }) }) });
3191
3258
  }
3192
- if (productBackendUrl) {
3259
+ if (orgConfigState.status === "loading") {
3260
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3261
+ "section",
3262
+ {
3263
+ className: `fixed top-0 right-0 z-40 flex flex-col bg-white border-l border-gray-200 h-full overflow-hidden transition-transform duration-300 ${isOpen ? "translate-x-0" : "translate-x-full"}`,
3264
+ style: { width: `${PANEL_WIDTH}px` },
3265
+ children: [
3266
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white shrink-0", children: [
3267
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2.5", children: [
3268
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
3269
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
3270
+ ] }),
3271
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3272
+ Button,
3273
+ {
3274
+ variant: "ghost",
3275
+ size: "sm",
3276
+ className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
3277
+ onClick: () => onClose?.(),
3278
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.X, { className: "h-4 w-4" })
3279
+ }
3280
+ )
3281
+ ] }),
3282
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-center", children: [
3283
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.Loader2, { className: "h-8 w-8 animate-spin text-gray-400 mx-auto mb-3" }),
3284
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-gray-500", children: "Loading..." })
3285
+ ] }) })
3286
+ ]
3287
+ }
3288
+ );
3289
+ }
3290
+ if (effectiveProductBackendUrl) {
3193
3291
  if (authState.status === "loading") {
3194
3292
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3195
3293
  "section",
@@ -4364,7 +4462,7 @@ ${userText}`
4364
4462
  message.id
4365
4463
  );
4366
4464
  }
4367
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(React5.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4465
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(React6.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4368
4466
  "div",
4369
4467
  {
4370
4468
  ref: isCurrentGuideStep ? currentStepRef : null,
@@ -4621,7 +4719,7 @@ function ChatPanelWithToggle({
4621
4719
  supabaseAnonKey,
4622
4720
  productBackendUrl
4623
4721
  }) {
4624
- const [internalIsOpen, setInternalIsOpen] = React5.useState(defaultOpen);
4722
+ const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
4625
4723
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
4626
4724
  const setIsOpen = (open) => {
4627
4725
  if (controlledIsOpen === void 0) {
@@ -4629,7 +4727,7 @@ function ChatPanelWithToggle({
4629
4727
  }
4630
4728
  onOpenChange?.(open);
4631
4729
  };
4632
- React5.useEffect(() => {
4730
+ React6.useEffect(() => {
4633
4731
  const originalPadding = document.body.style.paddingRight;
4634
4732
  const originalTransition = document.body.style.transition;
4635
4733
  document.body.style.transition = "padding-right 0.3s ease";
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  cn,
32
32
  createKiteChat,
33
33
  useGuideCursor
34
- } from "./chunk-XP6Y7EP7.js";
34
+ } from "./chunk-G74XTXWW.js";
35
35
  export {
36
36
  ApiKeyList,
37
37
  AssistantActivity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kite-copilot/chat-panel",
3
- "version": "0.2.42",
3
+ "version": "0.2.44",
4
4
  "description": "AI-powered chat panel SDK with programmatic lifecycle control",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",