@kite-copilot/chat-panel 0.2.48 → 0.2.50

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/auto.cjs CHANGED
@@ -35,7 +35,7 @@ __export(auto_exports, {
35
35
  module.exports = __toCommonJS(auto_exports);
36
36
 
37
37
  // src/createKiteChat.tsx
38
- var import_react = __toESM(require("react"), 1);
38
+ var import_react2 = __toESM(require("react"), 1);
39
39
  var import_client = require("react-dom/client");
40
40
 
41
41
  // src/ChatPanel.tsx
@@ -348,28 +348,22 @@ function useUserAuth({
348
348
  }) {
349
349
  const [authState, setAuthState] = React4.useState({ status: "idle" });
350
350
  const lastSessionIdRef = React4.useRef(null);
351
+ const lastEnabledRef = React4.useRef(enabled);
351
352
  const fetchUser = React4.useCallback(async () => {
352
353
  if (!productBackendUrl || !enabled) {
353
- console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
354
354
  setAuthState({ status: "idle" });
355
355
  return;
356
356
  }
357
- console.log("[useUserAuth] Starting auth request to product backend...");
358
- console.log("[useUserAuth] Product backend URL:", productBackendUrl);
359
- console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
360
357
  setAuthState({ status: "loading" });
361
358
  try {
362
359
  const response = await fetch(`${productBackendUrl}/users/me`, {
363
360
  method: "GET",
364
361
  credentials: "include",
365
- // Include cookies for authentication
366
362
  headers: {
367
363
  "Accept": "application/json"
368
364
  }
369
365
  });
370
- console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
371
366
  if (!response.ok) {
372
- console.log("[useUserAuth] Auth request failed with status:", response.status);
373
367
  if (response.status === 401) {
374
368
  throw new Error("Please log in to use the chat assistant.");
375
369
  }
@@ -379,27 +373,36 @@ function useUserAuth({
379
373
  throw new Error(`Authentication failed (${response.status})`);
380
374
  }
381
375
  const user = await response.json();
382
- console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
383
- console.log("[useUserAuth] id:", user.id);
384
- console.log("[useUserAuth] email:", user.email);
385
- console.log("[useUserAuth] name:", user.name);
386
- console.log("[useUserAuth] role:", user.role);
387
- console.log("[useUserAuth] isInternal:", user.isInternal);
388
- console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
389
- console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
390
376
  setAuthState({ status: "authenticated", user });
391
377
  } catch (error) {
392
- console.log("[useUserAuth] Auth ERROR:", error);
378
+ if (error instanceof Error) {
379
+ const errorMessage = error.message.toLowerCase();
380
+ const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
381
+ const is404Error = errorMessage.includes("404");
382
+ if (isCorsError || is404Error) {
383
+ console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
384
+ setAuthState({ status: "idle" });
385
+ return;
386
+ }
387
+ }
393
388
  const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
394
389
  setAuthState({ status: "error", error: message });
395
390
  }
396
391
  }, [productBackendUrl, enabled]);
397
392
  React4.useEffect(() => {
398
- if (sessionId !== lastSessionIdRef.current) {
393
+ const sessionChanged = sessionId !== lastSessionIdRef.current;
394
+ const enabledChanged = enabled !== lastEnabledRef.current;
395
+ const becameEnabled = enabled && !lastEnabledRef.current;
396
+ if (sessionChanged) {
399
397
  lastSessionIdRef.current = sessionId;
398
+ }
399
+ if (enabledChanged) {
400
+ lastEnabledRef.current = enabled;
401
+ }
402
+ if (sessionChanged || becameEnabled) {
400
403
  fetchUser();
401
404
  }
402
- }, [sessionId, fetchUser]);
405
+ }, [sessionId, enabled, fetchUser]);
403
406
  const retry = React4.useCallback(() => {
404
407
  fetchUser();
405
408
  }, [fetchUser]);
@@ -416,13 +419,11 @@ function useOrgConfig({ agentUrl, orgId }) {
416
419
  });
417
420
  React5.useEffect(() => {
418
421
  if (!agentUrl || !orgId) {
419
- console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
420
422
  return;
421
423
  }
422
424
  const fetchConfig = async () => {
423
425
  setState({ status: "loading", config: null, error: null });
424
426
  const url = `${agentUrl}/org/${orgId}/config`;
425
- console.log("[useOrgConfig] Fetching org config from:", url);
426
427
  try {
427
428
  const response = await fetch(url, {
428
429
  method: "GET",
@@ -434,7 +435,6 @@ function useOrgConfig({ agentUrl, orgId }) {
434
435
  throw new Error(`Failed to fetch org config (${response.status})`);
435
436
  }
436
437
  const config = await response.json();
437
- console.log("[useOrgConfig] Received config:", config);
438
438
  setState({ status: "success", config, error: null });
439
439
  } catch (error) {
440
440
  const message = error instanceof Error ? error.message : "Failed to fetch org config";
@@ -447,6 +447,75 @@ function useOrgConfig({ agentUrl, orgId }) {
447
447
  return state;
448
448
  }
449
449
 
450
+ // src/hooks/useFrontendToolExecutor.ts
451
+ var import_react = require("react");
452
+ function useFrontendToolExecutor({
453
+ productBackendUrl,
454
+ agentUrl,
455
+ sessionId
456
+ }) {
457
+ const sendToolResult = (0, import_react.useCallback)(async (payload) => {
458
+ try {
459
+ await fetch(`${agentUrl}/chat/tool-result`, {
460
+ method: "POST",
461
+ headers: {
462
+ "Content-Type": "application/json"
463
+ },
464
+ body: JSON.stringify(payload)
465
+ });
466
+ } catch (error) {
467
+ console.error("[FrontendToolExecutor] Failed to send tool result:", error);
468
+ }
469
+ }, [agentUrl]);
470
+ const executeToolRequest = (0, import_react.useCallback)(async (toolRequest) => {
471
+ const { call_id, arguments: args, endpoint, method, path_params } = toolRequest;
472
+ try {
473
+ let url = endpoint;
474
+ for (const param of path_params) {
475
+ if (args[param]) {
476
+ url = url.replace(`{${param}}`, encodeURIComponent(args[param]));
477
+ }
478
+ }
479
+ const queryParams = new URLSearchParams();
480
+ for (const [key, value] of Object.entries(args)) {
481
+ if (!path_params.includes(key) && value !== void 0 && value !== null) {
482
+ queryParams.append(key, String(value));
483
+ }
484
+ }
485
+ const queryString = queryParams.toString();
486
+ const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
487
+ const response = await fetch(fullUrl, {
488
+ method,
489
+ credentials: "include",
490
+ headers: {
491
+ "Accept": "application/json",
492
+ "Content-Type": "application/json"
493
+ }
494
+ });
495
+ let result;
496
+ if (response.ok) {
497
+ result = await response.json();
498
+ } else {
499
+ const errorText = await response.text();
500
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
501
+ }
502
+ await sendToolResult({
503
+ session_id: sessionId,
504
+ call_id,
505
+ result
506
+ });
507
+ } catch (error) {
508
+ console.error("[FrontendToolExecutor] Tool execution failed:", error);
509
+ await sendToolResult({
510
+ session_id: sessionId,
511
+ call_id,
512
+ error: error instanceof Error ? error.message : "Unknown error"
513
+ });
514
+ }
515
+ }, [productBackendUrl, sessionId, sendToolResult]);
516
+ return { executeToolRequest };
517
+ }
518
+
450
519
  // src/components/ui/card.tsx
451
520
  var import_jsx_runtime7 = require("react/jsx-runtime");
452
521
  function Card({ className, ...props }) {
@@ -1024,7 +1093,6 @@ function TypingIndicator({ className = "" }) {
1024
1093
 
1025
1094
  // src/ChatPanel.tsx
1026
1095
  var import_jsx_runtime10 = require("react/jsx-runtime");
1027
- var CHAT_PANEL_VERSION = true ? "0.2.48" : "dev";
1028
1096
  var DEFAULT_AGENT_URL = "http://localhost:5002";
1029
1097
  var PANEL_WIDTH = 400;
1030
1098
  var PANEL_HEIGHT = 600;
@@ -1488,7 +1556,8 @@ function ChatPanel({
1488
1556
  supabaseAnonKey,
1489
1557
  initialCorner = "bottom-left",
1490
1558
  onCornerChange,
1491
- productBackendUrl
1559
+ productBackendUrl,
1560
+ getAuthHeaders
1492
1561
  } = {}) {
1493
1562
  const [messages, setMessages] = React6.useState(initialMessages);
1494
1563
  const [input, setInput] = React6.useState("");
@@ -1516,37 +1585,11 @@ function ChatPanel({
1516
1585
  enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
1517
1586
  // Only enable after config is fetched
1518
1587
  });
1519
- React6.useEffect(() => {
1520
- if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
1521
- return;
1522
- }
1523
- const testProductBackendEndpoint = async () => {
1524
- const url = `${effectiveProductBackendUrl}/getDocument/snowkite/categories/`;
1525
- console.log("[KiteChat TEST] Testing product backend connectivity...");
1526
- console.log("[KiteChat TEST] URL:", url);
1527
- try {
1528
- const response = await fetch(url, {
1529
- method: "GET",
1530
- // Note: not using credentials: 'include' to avoid CORS issues with wildcard
1531
- headers: {
1532
- "Accept": "application/json"
1533
- }
1534
- });
1535
- console.log("[KiteChat TEST] Response status:", response.status);
1536
- console.log("[KiteChat TEST] Response ok:", response.ok);
1537
- if (response.ok) {
1538
- const data = await response.json();
1539
- console.log("[KiteChat TEST] SUCCESS - product backend reachable, data:", data);
1540
- } else {
1541
- const errorText = await response.text();
1542
- console.log("[KiteChat TEST] FAILED - status:", response.status, "body:", errorText);
1543
- }
1544
- } catch (error) {
1545
- console.error("[KiteChat TEST] ERROR:", error);
1546
- }
1547
- };
1548
- testProductBackendEndpoint();
1549
- }, [effectiveProductBackendUrl, orgConfigState.status]);
1588
+ const { executeToolRequest } = useFrontendToolExecutor({
1589
+ productBackendUrl: effectiveProductBackendUrl || "",
1590
+ agentUrl,
1591
+ sessionId
1592
+ });
1550
1593
  const effectiveUser = React6.useMemo(() => {
1551
1594
  if (sessionUser) {
1552
1595
  return sessionUser;
@@ -1577,7 +1620,6 @@ function ChatPanel({
1577
1620
  userRole: authState.user.role,
1578
1621
  isInternal: authState.user.isInternal
1579
1622
  });
1580
- console.log("[ChatPanel] Session user captured:", authState.user.id);
1581
1623
  }
1582
1624
  }, [authState, sessionUser]);
1583
1625
  const isWaitingForAuth = React6.useMemo(() => {
@@ -1590,26 +1632,18 @@ function ChatPanel({
1590
1632
  const supabaseRef = React6.useRef(null);
1591
1633
  const typingChannelRef = React6.useRef(null);
1592
1634
  const typingTimeoutRef = React6.useRef(null);
1593
- React6.useEffect(() => {
1594
- console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
1595
- }, []);
1596
1635
  const resetSession = React6.useCallback(() => {
1597
- console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
1598
1636
  if (isEscalated && supabaseRef.current && sessionId) {
1599
- console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
1600
1637
  supabaseRef.current.from("escalations").update({
1601
1638
  customer_status: "disconnected",
1602
1639
  customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1603
1640
  }).eq("session_id", sessionId).then(
1604
- (result) => {
1605
- console.log("[KiteChat] Disconnect update result:", result);
1641
+ () => {
1606
1642
  },
1607
1643
  (err) => {
1608
1644
  console.error("[KiteChat] Disconnect update failed:", err);
1609
1645
  }
1610
1646
  );
1611
- } else {
1612
- console.log("[KiteChat] Skipping disconnect update - conditions not met");
1613
1647
  }
1614
1648
  setSessionUser(null);
1615
1649
  setSessionId(crypto.randomUUID());
@@ -1635,12 +1669,9 @@ function ChatPanel({
1635
1669
  }
1636
1670
  const channelName = `typing:${sessionId}`;
1637
1671
  const channel = supabaseRef.current.channel(channelName);
1638
- console.log(`[KiteChat] Subscribing to typing channel: ${channelName}`);
1639
1672
  channel.on("broadcast", { event: "typing" }, (payload) => {
1640
- console.log("[KiteChat] Received typing broadcast:", payload);
1641
1673
  const { sender, isTyping } = payload.payload;
1642
1674
  if (sender === "agent") {
1643
- console.log(`[KiteChat] Agent typing: ${isTyping}`);
1644
1675
  setAgentIsTyping(isTyping);
1645
1676
  if (isTyping) {
1646
1677
  if (typingTimeoutRef.current) {
@@ -1652,10 +1683,11 @@ function ChatPanel({
1652
1683
  }
1653
1684
  }
1654
1685
  }).subscribe((status) => {
1655
- console.log(`[KiteChat] Typing channel status: ${status}`);
1656
1686
  if (status === "SUBSCRIBED") {
1657
1687
  typingChannelRef.current = channel;
1658
- console.log("[KiteChat] Typing channel ready");
1688
+ console.log("[KiteChat] Typing channel subscribed successfully");
1689
+ } else if (status === "CHANNEL_ERROR") {
1690
+ console.error("[KiteChat] Typing channel subscription failed");
1659
1691
  }
1660
1692
  });
1661
1693
  return () => {
@@ -1666,6 +1698,20 @@ function ChatPanel({
1666
1698
  }
1667
1699
  };
1668
1700
  }, [isEscalated, sessionId]);
1701
+ React6.useEffect(() => {
1702
+ if (!isOpen && isEscalated && supabaseRef.current && sessionId) {
1703
+ console.log("[KiteChat] Panel closed during live chat, marking disconnected");
1704
+ supabaseRef.current.from("escalations").update({
1705
+ customer_status: "disconnected",
1706
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1707
+ }).eq("session_id", sessionId).then(
1708
+ () => console.log("[KiteChat] Successfully marked disconnected on panel close"),
1709
+ (err) => {
1710
+ console.error("[KiteChat] Failed to mark disconnected on panel close:", err);
1711
+ }
1712
+ );
1713
+ }
1714
+ }, [isOpen, isEscalated, sessionId]);
1669
1715
  const heartbeatIntervalRef = React6.useRef(null);
1670
1716
  const updateCustomerStatus = React6.useCallback(async (status) => {
1671
1717
  if (!supabaseRef.current || !sessionId) return;
@@ -1684,9 +1730,20 @@ function ChatPanel({
1684
1730
  }
1685
1731
  const currentSessionId = sessionId;
1686
1732
  const supabase = supabaseRef.current;
1687
- updateCustomerStatus("active");
1733
+ const markActive = () => {
1734
+ supabase.from("escalations").update({
1735
+ customer_status: "active",
1736
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1737
+ }).eq("session_id", currentSessionId).then(
1738
+ () => {
1739
+ },
1740
+ (err) => console.error("[KiteChat] Failed to update customer status:", err)
1741
+ );
1742
+ };
1743
+ console.log("[KiteChat] Starting presence heartbeat for live chat");
1744
+ markActive();
1688
1745
  heartbeatIntervalRef.current = window.setInterval(() => {
1689
- updateCustomerStatus("active");
1746
+ markActive();
1690
1747
  }, 6e4);
1691
1748
  const handleBeforeUnload = () => {
1692
1749
  supabase.from("escalations").update({
@@ -1701,7 +1758,7 @@ function ChatPanel({
1701
1758
  customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1702
1759
  }).eq("session_id", currentSessionId);
1703
1760
  } else if (document.visibilityState === "visible") {
1704
- updateCustomerStatus("active");
1761
+ markActive();
1705
1762
  }
1706
1763
  };
1707
1764
  window.addEventListener("beforeunload", handleBeforeUnload);
@@ -1709,13 +1766,12 @@ function ChatPanel({
1709
1766
  return () => {
1710
1767
  window.removeEventListener("beforeunload", handleBeforeUnload);
1711
1768
  document.removeEventListener("visibilitychange", handleVisibilityChange);
1769
+ console.log("[KiteChat] Escalation ended, marking disconnected");
1712
1770
  supabase.from("escalations").update({
1713
1771
  customer_status: "disconnected",
1714
1772
  customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1715
1773
  }).eq("session_id", currentSessionId).then(
1716
- () => {
1717
- console.log("[KiteChat] Marked customer as disconnected");
1718
- },
1774
+ () => console.log("[KiteChat] Successfully marked disconnected on escalation end"),
1719
1775
  (err) => {
1720
1776
  console.error("[KiteChat] Failed to mark disconnected:", err);
1721
1777
  }
@@ -1725,17 +1781,14 @@ function ChatPanel({
1725
1781
  heartbeatIntervalRef.current = null;
1726
1782
  }
1727
1783
  };
1728
- }, [isEscalated, sessionId, updateCustomerStatus]);
1784
+ }, [isEscalated, sessionId]);
1729
1785
  const sendTypingIndicator = React6.useCallback((isTyping) => {
1730
- if (!typingChannelRef.current) {
1731
- console.log("[KiteChat] Cannot send typing - channel not ready");
1732
- return;
1733
- }
1734
- if (!isEscalated) {
1735
- console.log("[KiteChat] Cannot send typing - not escalated");
1786
+ if (!typingChannelRef.current || !isEscalated) {
1787
+ if (isTyping) {
1788
+ console.warn("[KiteChat] Typing channel not ready, cannot send typing indicator");
1789
+ }
1736
1790
  return;
1737
1791
  }
1738
- console.log(`[KiteChat] Sending typing indicator: ${isTyping}`);
1739
1792
  typingChannelRef.current.send({
1740
1793
  type: "broadcast",
1741
1794
  event: "typing",
@@ -1744,16 +1797,23 @@ function ChatPanel({
1744
1797
  }, [isEscalated]);
1745
1798
  const userTypingTimeoutRef = React6.useRef(null);
1746
1799
  const handleTypingStart = React6.useCallback(() => {
1747
- if (!isEscalated || !supabaseRef.current) return;
1800
+ if (!isEscalated || !supabaseRef.current || !sessionId) return;
1748
1801
  sendTypingIndicator(true);
1749
- updateCustomerStatus("active");
1802
+ supabaseRef.current.from("escalations").update({
1803
+ customer_status: "active",
1804
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
1805
+ }).eq("session_id", sessionId).then(
1806
+ () => {
1807
+ },
1808
+ (err) => console.error("[KiteChat] Failed to update presence:", err)
1809
+ );
1750
1810
  if (userTypingTimeoutRef.current) {
1751
1811
  window.clearTimeout(userTypingTimeoutRef.current);
1752
1812
  }
1753
1813
  userTypingTimeoutRef.current = window.setTimeout(() => {
1754
1814
  sendTypingIndicator(false);
1755
1815
  }, 1500);
1756
- }, [isEscalated, sendTypingIndicator, updateCustomerStatus]);
1816
+ }, [isEscalated, sendTypingIndicator, sessionId]);
1757
1817
  const streamIntervals = React6.useRef({});
1758
1818
  const isEmpty = messages.length === 0;
1759
1819
  const [phase, setPhase] = React6.useState("idle");
@@ -1788,12 +1848,6 @@ function ChatPanel({
1788
1848
  const latestBulkSummaryNavigationRef = React6.useRef(null);
1789
1849
  const [guideComplete, setGuideComplete] = React6.useState(false);
1790
1850
  React6.useEffect(() => {
1791
- window.resetIntegrationNotification = () => {
1792
- localStorage.removeItem("gmailNotificationSeen");
1793
- console.log(
1794
- "Integration notification reset! Click the Integrations tab to see it again."
1795
- );
1796
- };
1797
1851
  const handleIntegrationTabClick = () => {
1798
1852
  const hasSeenNotification = localStorage.getItem("gmailNotificationSeen");
1799
1853
  if (!hasSeenNotification) {
@@ -1935,17 +1989,7 @@ function ChatPanel({
1935
1989
  return;
1936
1990
  }
1937
1991
  const currentBulkNav = latestBulkSummaryNavigationRef.current;
1938
- console.log(
1939
- "[DEBUG] Keyboard handler - latestBulkSummaryNavigation:",
1940
- currentBulkNav,
1941
- "onNavigate:",
1942
- !!onNavigate
1943
- );
1944
1992
  if (currentBulkNav && onNavigate) {
1945
- console.log(
1946
- "[DEBUG] Navigating via keyboard to:",
1947
- currentBulkNav.page
1948
- );
1949
1993
  e.preventDefault();
1950
1994
  e.stopPropagation();
1951
1995
  onNavigate(currentBulkNav.page, currentBulkNav.subtab);
@@ -1991,7 +2035,6 @@ function ChatPanel({
1991
2035
  const messageId = data.message_id;
1992
2036
  const isDuplicate = messageId ? prev.some((m) => m.serverMessageId === messageId) : prev.slice(-5).some((m) => m.content === content);
1993
2037
  if (isDuplicate) {
1994
- console.debug("[KiteChat] Skipping duplicate agent message:", messageId || content.slice(0, 30));
1995
2038
  return prev;
1996
2039
  }
1997
2040
  return [...prev, {
@@ -2014,7 +2057,6 @@ function ChatPanel({
2014
2057
  console.error("[KiteChat] Escalation WebSocket error:", err);
2015
2058
  };
2016
2059
  ws.onclose = () => {
2017
- console.log("[KiteChat] Escalation WebSocket closed");
2018
2060
  };
2019
2061
  escalationWsRef.current = ws;
2020
2062
  }, [agentUrl]);
@@ -2028,13 +2070,22 @@ function ChatPanel({
2028
2070
  type: "user_message",
2029
2071
  content
2030
2072
  }));
2031
- updateCustomerStatus("active");
2073
+ if (supabaseRef.current && sessionId) {
2074
+ supabaseRef.current.from("escalations").update({
2075
+ customer_status: "active",
2076
+ customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
2077
+ }).eq("session_id", sessionId).then(
2078
+ () => {
2079
+ },
2080
+ (err) => console.error("[KiteChat] Failed to update presence:", err)
2081
+ );
2082
+ }
2032
2083
  return true;
2033
2084
  } catch (err) {
2034
2085
  console.error("[KiteChat] Failed to send escalated message:", err);
2035
2086
  return false;
2036
2087
  }
2037
- }, [updateCustomerStatus]);
2088
+ }, [sessionId]);
2038
2089
  React6.useEffect(() => {
2039
2090
  return () => {
2040
2091
  if (escalationWsRef.current) {
@@ -2308,14 +2359,6 @@ function ChatPanel({
2308
2359
  try {
2309
2360
  const controller = new AbortController();
2310
2361
  const timeoutId = setTimeout(() => controller.abort(), 6e4);
2311
- console.log("[ChatPanel] Sending chat request to agent backend...");
2312
- console.log("[ChatPanel] Agent URL:", agentUrl);
2313
- console.log("[ChatPanel] User data being sent:");
2314
- console.log("[ChatPanel] user_id:", effectiveUser.userId);
2315
- console.log("[ChatPanel] user_name:", effectiveUser.userName);
2316
- console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
2317
- console.log("[ChatPanel] org_id:", orgId);
2318
- console.log("[ChatPanel] authState.status:", authState.status);
2319
2362
  const response = await fetch(`${agentUrl}/chat/stream`, {
2320
2363
  method: "POST",
2321
2364
  headers: {
@@ -2530,6 +2573,11 @@ function ChatPanel({
2530
2573
  content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
2531
2574
  };
2532
2575
  setMessages((prev) => [...prev, escalationMessage]);
2576
+ } else if (eventType === "tool_request") {
2577
+ const toolRequest = data;
2578
+ executeToolRequest(toolRequest).catch((err) => {
2579
+ console.error("[KiteChat] Tool execution failed:", err);
2580
+ });
2533
2581
  } else if (eventType === "token") {
2534
2582
  }
2535
2583
  } catch (parseError) {
@@ -2844,11 +2892,6 @@ ${userText}`
2844
2892
  }
2845
2893
  });
2846
2894
  } else if (eventType === "summary") {
2847
- console.log("[DEBUG] Received summary event - data:", data);
2848
- console.log(
2849
- "[DEBUG] navigationPage from backend:",
2850
- data.navigationPage
2851
- );
2852
2895
  setPhase("idle");
2853
2896
  setProgressSteps([]);
2854
2897
  setPendingBulkSession(null);
@@ -2868,7 +2911,6 @@ ${userText}`
2868
2911
  navigationPage: data.navigationPage
2869
2912
  }
2870
2913
  };
2871
- console.log("[DEBUG] Creating bulkSummary message:", newMsg);
2872
2914
  return [...filtered, newMsg];
2873
2915
  });
2874
2916
  setTimeout(() => {
@@ -4439,28 +4481,11 @@ ${userText}`
4439
4481
  onClick: (e) => {
4440
4482
  e.preventDefault();
4441
4483
  e.stopPropagation();
4442
- console.log(
4443
- "[DEBUG] Button clicked - navigationPage:",
4444
- navigationPage,
4445
- "onNavigate:",
4446
- !!onNavigate
4447
- );
4448
4484
  if (onNavigate && navigationPage.page) {
4449
- console.log(
4450
- "[DEBUG] Calling onNavigate with page:",
4451
- navigationPage.page
4452
- );
4453
4485
  onNavigate(
4454
4486
  navigationPage.page,
4455
4487
  navigationPage.subtab
4456
4488
  );
4457
- } else {
4458
- console.log(
4459
- "[DEBUG] Condition failed - onNavigate:",
4460
- !!onNavigate,
4461
- "navigationPage.page:",
4462
- navigationPage.page
4463
- );
4464
4489
  }
4465
4490
  },
4466
4491
  className: "flex items-center gap-2 text-xs text-gray-500 hover:text-gray-700 transition-colors group cursor-pointer",
@@ -4720,7 +4745,8 @@ function ChatPanelWithToggle({
4720
4745
  supabaseAnonKey,
4721
4746
  initialCorner,
4722
4747
  onCornerChange,
4723
- productBackendUrl
4748
+ productBackendUrl,
4749
+ getAuthHeaders
4724
4750
  }) {
4725
4751
  const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
4726
4752
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
@@ -4750,7 +4776,8 @@ function ChatPanelWithToggle({
4750
4776
  supabaseAnonKey,
4751
4777
  initialCorner,
4752
4778
  onCornerChange,
4753
- productBackendUrl
4779
+ productBackendUrl,
4780
+ getAuthHeaders
4754
4781
  }
4755
4782
  );
4756
4783
  }
@@ -4762,14 +4789,14 @@ function KiteChatWrapper({
4762
4789
  onConfigUpdate,
4763
4790
  onStateUpdate
4764
4791
  }) {
4765
- const [config, setConfig] = import_react.default.useState(initialConfig);
4766
- const [currentPage, setCurrentPage] = import_react.default.useState(initialConfig.currentPage || "dashboard");
4767
- const [isOpen, setIsOpen] = import_react.default.useState(false);
4768
- const isOpenRef = import_react.default.useRef(false);
4769
- import_react.default.useEffect(() => {
4792
+ const [config, setConfig] = import_react2.default.useState(initialConfig);
4793
+ const [currentPage, setCurrentPage] = import_react2.default.useState(initialConfig.currentPage || "dashboard");
4794
+ const [isOpen, setIsOpen] = import_react2.default.useState(false);
4795
+ const isOpenRef = import_react2.default.useRef(false);
4796
+ import_react2.default.useEffect(() => {
4770
4797
  isOpenRef.current = isOpen;
4771
4798
  }, [isOpen]);
4772
- import_react.default.useEffect(() => {
4799
+ import_react2.default.useEffect(() => {
4773
4800
  onConfigUpdate((newConfig) => {
4774
4801
  if (newConfig.currentPage !== void 0) {
4775
4802
  setCurrentPage(newConfig.currentPage);
@@ -4781,7 +4808,7 @@ function KiteChatWrapper({
4781
4808
  getIsOpen: () => isOpenRef.current
4782
4809
  });
4783
4810
  }, [onConfigUpdate, onStateUpdate]);
4784
- import_react.default.useEffect(() => {
4811
+ import_react2.default.useEffect(() => {
4785
4812
  const container = document.getElementById("kite-chat-root");
4786
4813
  if (!container) return;
4787
4814
  if (config.theme === "dark") {
@@ -4810,7 +4837,8 @@ function KiteChatWrapper({
4810
4837
  userEmail: config.userEmail,
4811
4838
  supabaseUrl: config.supabaseUrl,
4812
4839
  supabaseAnonKey: config.supabaseAnonKey,
4813
- productBackendUrl: config.productBackendUrl
4840
+ productBackendUrl: config.productBackendUrl,
4841
+ getAuthHeaders: config.getAuthHeaders
4814
4842
  }
4815
4843
  );
4816
4844
  }
@@ -4853,7 +4881,6 @@ function createKiteChat(config) {
4853
4881
  }
4854
4882
  )
4855
4883
  );
4856
- console.log("[KiteChat] Mounted");
4857
4884
  },
4858
4885
  unmount() {
4859
4886
  if (!root) {
@@ -4865,7 +4892,6 @@ function createKiteChat(config) {
4865
4892
  containerElement = null;
4866
4893
  configUpdater = null;
4867
4894
  stateUpdaters = null;
4868
- console.log("[KiteChat] Unmounted");
4869
4895
  },
4870
4896
  open() {
4871
4897
  stateUpdaters?.setIsOpen(true);
package/dist/auto.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-e6BnJS6T.cjs';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-DeQKgFyx.cjs';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-e6BnJS6T.js';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-DeQKgFyx.js';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKiteChat
3
- } from "./chunk-LOTJ3U5L.js";
3
+ } from "./chunk-BLSVIF7H.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {