@kite-copilot/chat-panel 0.2.49 → 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/README.md +8 -0
- package/dist/auto.cjs +90 -147
- package/dist/auto.d.cts +1 -1
- package/dist/auto.d.ts +1 -1
- package/dist/auto.js +1 -1
- package/dist/{chunk-YZXB3LLU.js → chunk-BLSVIF7H.js} +90 -147
- package/dist/{createKiteChat-e6BnJS6T.d.cts → createKiteChat-DeQKgFyx.d.cts} +8 -2
- package/dist/{createKiteChat-e6BnJS6T.d.ts → createKiteChat-DeQKgFyx.d.ts} +8 -2
- package/dist/embed.global.js +24 -59
- package/dist/index.cjs +90 -147
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -896,28 +896,22 @@ function useUserAuth({
|
|
|
896
896
|
}) {
|
|
897
897
|
const [authState, setAuthState] = React4.useState({ status: "idle" });
|
|
898
898
|
const lastSessionIdRef = React4.useRef(null);
|
|
899
|
+
const lastEnabledRef = React4.useRef(enabled);
|
|
899
900
|
const fetchUser = React4.useCallback(async () => {
|
|
900
901
|
if (!productBackendUrl || !enabled) {
|
|
901
|
-
console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
|
|
902
902
|
setAuthState({ status: "idle" });
|
|
903
903
|
return;
|
|
904
904
|
}
|
|
905
|
-
console.log("[useUserAuth] Starting auth request to product backend...");
|
|
906
|
-
console.log("[useUserAuth] Product backend URL:", productBackendUrl);
|
|
907
|
-
console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
|
|
908
905
|
setAuthState({ status: "loading" });
|
|
909
906
|
try {
|
|
910
907
|
const response = await fetch(`${productBackendUrl}/users/me`, {
|
|
911
908
|
method: "GET",
|
|
912
909
|
credentials: "include",
|
|
913
|
-
// Include cookies for authentication
|
|
914
910
|
headers: {
|
|
915
911
|
"Accept": "application/json"
|
|
916
912
|
}
|
|
917
913
|
});
|
|
918
|
-
console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
|
|
919
914
|
if (!response.ok) {
|
|
920
|
-
console.log("[useUserAuth] Auth request failed with status:", response.status);
|
|
921
915
|
if (response.status === 401) {
|
|
922
916
|
throw new Error("Please log in to use the chat assistant.");
|
|
923
917
|
}
|
|
@@ -927,27 +921,36 @@ function useUserAuth({
|
|
|
927
921
|
throw new Error(`Authentication failed (${response.status})`);
|
|
928
922
|
}
|
|
929
923
|
const user = await response.json();
|
|
930
|
-
console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
|
|
931
|
-
console.log("[useUserAuth] id:", user.id);
|
|
932
|
-
console.log("[useUserAuth] email:", user.email);
|
|
933
|
-
console.log("[useUserAuth] name:", user.name);
|
|
934
|
-
console.log("[useUserAuth] role:", user.role);
|
|
935
|
-
console.log("[useUserAuth] isInternal:", user.isInternal);
|
|
936
|
-
console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
|
|
937
|
-
console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
|
|
938
924
|
setAuthState({ status: "authenticated", user });
|
|
939
925
|
} catch (error) {
|
|
940
|
-
|
|
926
|
+
if (error instanceof Error) {
|
|
927
|
+
const errorMessage = error.message.toLowerCase();
|
|
928
|
+
const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
|
|
929
|
+
const is404Error = errorMessage.includes("404");
|
|
930
|
+
if (isCorsError || is404Error) {
|
|
931
|
+
console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
|
|
932
|
+
setAuthState({ status: "idle" });
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
941
936
|
const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
|
|
942
937
|
setAuthState({ status: "error", error: message });
|
|
943
938
|
}
|
|
944
939
|
}, [productBackendUrl, enabled]);
|
|
945
940
|
React4.useEffect(() => {
|
|
946
|
-
|
|
941
|
+
const sessionChanged = sessionId !== lastSessionIdRef.current;
|
|
942
|
+
const enabledChanged = enabled !== lastEnabledRef.current;
|
|
943
|
+
const becameEnabled = enabled && !lastEnabledRef.current;
|
|
944
|
+
if (sessionChanged) {
|
|
947
945
|
lastSessionIdRef.current = sessionId;
|
|
946
|
+
}
|
|
947
|
+
if (enabledChanged) {
|
|
948
|
+
lastEnabledRef.current = enabled;
|
|
949
|
+
}
|
|
950
|
+
if (sessionChanged || becameEnabled) {
|
|
948
951
|
fetchUser();
|
|
949
952
|
}
|
|
950
|
-
}, [sessionId, fetchUser]);
|
|
953
|
+
}, [sessionId, enabled, fetchUser]);
|
|
951
954
|
const retry = React4.useCallback(() => {
|
|
952
955
|
fetchUser();
|
|
953
956
|
}, [fetchUser]);
|
|
@@ -964,13 +967,11 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
964
967
|
});
|
|
965
968
|
React5.useEffect(() => {
|
|
966
969
|
if (!agentUrl || !orgId) {
|
|
967
|
-
console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
|
|
968
970
|
return;
|
|
969
971
|
}
|
|
970
972
|
const fetchConfig = async () => {
|
|
971
973
|
setState({ status: "loading", config: null, error: null });
|
|
972
974
|
const url = `${agentUrl}/org/${orgId}/config`;
|
|
973
|
-
console.log("[useOrgConfig] Fetching org config from:", url);
|
|
974
975
|
try {
|
|
975
976
|
const response = await fetch(url, {
|
|
976
977
|
method: "GET",
|
|
@@ -982,7 +983,6 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
982
983
|
throw new Error(`Failed to fetch org config (${response.status})`);
|
|
983
984
|
}
|
|
984
985
|
const config = await response.json();
|
|
985
|
-
console.log("[useOrgConfig] Received config:", config);
|
|
986
986
|
setState({ status: "success", config, error: null });
|
|
987
987
|
} catch (error) {
|
|
988
988
|
const message = error instanceof Error ? error.message : "Failed to fetch org config";
|
|
@@ -1016,8 +1016,7 @@ function useFrontendToolExecutor({
|
|
|
1016
1016
|
}
|
|
1017
1017
|
}, [agentUrl]);
|
|
1018
1018
|
const executeToolRequest = useCallback3(async (toolRequest) => {
|
|
1019
|
-
const { call_id,
|
|
1020
|
-
console.log("[FrontendToolExecutor] Executing tool:", tool_name, "with args:", args);
|
|
1019
|
+
const { call_id, arguments: args, endpoint, method, path_params } = toolRequest;
|
|
1021
1020
|
try {
|
|
1022
1021
|
let url = endpoint;
|
|
1023
1022
|
for (const param of path_params) {
|
|
@@ -1033,7 +1032,6 @@ function useFrontendToolExecutor({
|
|
|
1033
1032
|
}
|
|
1034
1033
|
const queryString = queryParams.toString();
|
|
1035
1034
|
const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
|
|
1036
|
-
console.log("[FrontendToolExecutor] Fetching:", fullUrl);
|
|
1037
1035
|
const response = await fetch(fullUrl, {
|
|
1038
1036
|
method,
|
|
1039
1037
|
credentials: "include",
|
|
@@ -1045,7 +1043,6 @@ function useFrontendToolExecutor({
|
|
|
1045
1043
|
let result;
|
|
1046
1044
|
if (response.ok) {
|
|
1047
1045
|
result = await response.json();
|
|
1048
|
-
console.log("[FrontendToolExecutor] Tool result:", result);
|
|
1049
1046
|
} else {
|
|
1050
1047
|
const errorText = await response.text();
|
|
1051
1048
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
@@ -1097,7 +1094,6 @@ function TypingIndicator({ className = "" }) {
|
|
|
1097
1094
|
|
|
1098
1095
|
// src/ChatPanel.tsx
|
|
1099
1096
|
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1100
|
-
var CHAT_PANEL_VERSION = true ? "0.2.49" : "dev";
|
|
1101
1097
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1102
1098
|
var PANEL_WIDTH = 400;
|
|
1103
1099
|
var PANEL_HEIGHT = 600;
|
|
@@ -1561,7 +1557,8 @@ function ChatPanel({
|
|
|
1561
1557
|
supabaseAnonKey,
|
|
1562
1558
|
initialCorner = "bottom-left",
|
|
1563
1559
|
onCornerChange,
|
|
1564
|
-
productBackendUrl
|
|
1560
|
+
productBackendUrl,
|
|
1561
|
+
getAuthHeaders
|
|
1565
1562
|
} = {}) {
|
|
1566
1563
|
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1567
1564
|
const [input, setInput] = React6.useState("");
|
|
@@ -1594,37 +1591,6 @@ function ChatPanel({
|
|
|
1594
1591
|
agentUrl,
|
|
1595
1592
|
sessionId
|
|
1596
1593
|
});
|
|
1597
|
-
React6.useEffect(() => {
|
|
1598
|
-
if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
|
|
1599
|
-
return;
|
|
1600
|
-
}
|
|
1601
|
-
const testProductBackendEndpoint = async () => {
|
|
1602
|
-
const url = `${effectiveProductBackendUrl}/getDocument/snowkite/categories/`;
|
|
1603
|
-
console.log("[KiteChat TEST] Testing product backend connectivity...");
|
|
1604
|
-
console.log("[KiteChat TEST] URL:", url);
|
|
1605
|
-
try {
|
|
1606
|
-
const response = await fetch(url, {
|
|
1607
|
-
method: "GET",
|
|
1608
|
-
// Note: not using credentials: 'include' to avoid CORS issues with wildcard
|
|
1609
|
-
headers: {
|
|
1610
|
-
"Accept": "application/json"
|
|
1611
|
-
}
|
|
1612
|
-
});
|
|
1613
|
-
console.log("[KiteChat TEST] Response status:", response.status);
|
|
1614
|
-
console.log("[KiteChat TEST] Response ok:", response.ok);
|
|
1615
|
-
if (response.ok) {
|
|
1616
|
-
const data = await response.json();
|
|
1617
|
-
console.log("[KiteChat TEST] SUCCESS - product backend reachable, data:", data);
|
|
1618
|
-
} else {
|
|
1619
|
-
const errorText = await response.text();
|
|
1620
|
-
console.log("[KiteChat TEST] FAILED - status:", response.status, "body:", errorText);
|
|
1621
|
-
}
|
|
1622
|
-
} catch (error) {
|
|
1623
|
-
console.error("[KiteChat TEST] ERROR:", error);
|
|
1624
|
-
}
|
|
1625
|
-
};
|
|
1626
|
-
testProductBackendEndpoint();
|
|
1627
|
-
}, [effectiveProductBackendUrl, orgConfigState.status]);
|
|
1628
1594
|
const effectiveUser = React6.useMemo(() => {
|
|
1629
1595
|
if (sessionUser) {
|
|
1630
1596
|
return sessionUser;
|
|
@@ -1655,7 +1621,6 @@ function ChatPanel({
|
|
|
1655
1621
|
userRole: authState.user.role,
|
|
1656
1622
|
isInternal: authState.user.isInternal
|
|
1657
1623
|
});
|
|
1658
|
-
console.log("[ChatPanel] Session user captured:", authState.user.id);
|
|
1659
1624
|
}
|
|
1660
1625
|
}, [authState, sessionUser]);
|
|
1661
1626
|
const isWaitingForAuth = React6.useMemo(() => {
|
|
@@ -1668,26 +1633,18 @@ function ChatPanel({
|
|
|
1668
1633
|
const supabaseRef = React6.useRef(null);
|
|
1669
1634
|
const typingChannelRef = React6.useRef(null);
|
|
1670
1635
|
const typingTimeoutRef = React6.useRef(null);
|
|
1671
|
-
React6.useEffect(() => {
|
|
1672
|
-
console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
|
|
1673
|
-
}, []);
|
|
1674
1636
|
const resetSession = React6.useCallback(() => {
|
|
1675
|
-
console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
|
|
1676
1637
|
if (isEscalated && supabaseRef.current && sessionId) {
|
|
1677
|
-
console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
|
|
1678
1638
|
supabaseRef.current.from("escalations").update({
|
|
1679
1639
|
customer_status: "disconnected",
|
|
1680
1640
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1681
1641
|
}).eq("session_id", sessionId).then(
|
|
1682
|
-
(
|
|
1683
|
-
console.log("[KiteChat] Disconnect update result:", result);
|
|
1642
|
+
() => {
|
|
1684
1643
|
},
|
|
1685
1644
|
(err) => {
|
|
1686
1645
|
console.error("[KiteChat] Disconnect update failed:", err);
|
|
1687
1646
|
}
|
|
1688
1647
|
);
|
|
1689
|
-
} else {
|
|
1690
|
-
console.log("[KiteChat] Skipping disconnect update - conditions not met");
|
|
1691
1648
|
}
|
|
1692
1649
|
setSessionUser(null);
|
|
1693
1650
|
setSessionId(crypto.randomUUID());
|
|
@@ -1713,12 +1670,9 @@ function ChatPanel({
|
|
|
1713
1670
|
}
|
|
1714
1671
|
const channelName = `typing:${sessionId}`;
|
|
1715
1672
|
const channel = supabaseRef.current.channel(channelName);
|
|
1716
|
-
console.log(`[KiteChat] Subscribing to typing channel: ${channelName}`);
|
|
1717
1673
|
channel.on("broadcast", { event: "typing" }, (payload) => {
|
|
1718
|
-
console.log("[KiteChat] Received typing broadcast:", payload);
|
|
1719
1674
|
const { sender, isTyping } = payload.payload;
|
|
1720
1675
|
if (sender === "agent") {
|
|
1721
|
-
console.log(`[KiteChat] Agent typing: ${isTyping}`);
|
|
1722
1676
|
setAgentIsTyping(isTyping);
|
|
1723
1677
|
if (isTyping) {
|
|
1724
1678
|
if (typingTimeoutRef.current) {
|
|
@@ -1730,10 +1684,11 @@ function ChatPanel({
|
|
|
1730
1684
|
}
|
|
1731
1685
|
}
|
|
1732
1686
|
}).subscribe((status) => {
|
|
1733
|
-
console.log(`[KiteChat] Typing channel status: ${status}`);
|
|
1734
1687
|
if (status === "SUBSCRIBED") {
|
|
1735
1688
|
typingChannelRef.current = channel;
|
|
1736
|
-
console.log("[KiteChat] Typing channel
|
|
1689
|
+
console.log("[KiteChat] Typing channel subscribed successfully");
|
|
1690
|
+
} else if (status === "CHANNEL_ERROR") {
|
|
1691
|
+
console.error("[KiteChat] Typing channel subscription failed");
|
|
1737
1692
|
}
|
|
1738
1693
|
});
|
|
1739
1694
|
return () => {
|
|
@@ -1744,6 +1699,20 @@ function ChatPanel({
|
|
|
1744
1699
|
}
|
|
1745
1700
|
};
|
|
1746
1701
|
}, [isEscalated, sessionId]);
|
|
1702
|
+
React6.useEffect(() => {
|
|
1703
|
+
if (!isOpen && isEscalated && supabaseRef.current && sessionId) {
|
|
1704
|
+
console.log("[KiteChat] Panel closed during live chat, marking disconnected");
|
|
1705
|
+
supabaseRef.current.from("escalations").update({
|
|
1706
|
+
customer_status: "disconnected",
|
|
1707
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1708
|
+
}).eq("session_id", sessionId).then(
|
|
1709
|
+
() => console.log("[KiteChat] Successfully marked disconnected on panel close"),
|
|
1710
|
+
(err) => {
|
|
1711
|
+
console.error("[KiteChat] Failed to mark disconnected on panel close:", err);
|
|
1712
|
+
}
|
|
1713
|
+
);
|
|
1714
|
+
}
|
|
1715
|
+
}, [isOpen, isEscalated, sessionId]);
|
|
1747
1716
|
const heartbeatIntervalRef = React6.useRef(null);
|
|
1748
1717
|
const updateCustomerStatus = React6.useCallback(async (status) => {
|
|
1749
1718
|
if (!supabaseRef.current || !sessionId) return;
|
|
@@ -1762,9 +1731,20 @@ function ChatPanel({
|
|
|
1762
1731
|
}
|
|
1763
1732
|
const currentSessionId = sessionId;
|
|
1764
1733
|
const supabase = supabaseRef.current;
|
|
1765
|
-
|
|
1734
|
+
const markActive = () => {
|
|
1735
|
+
supabase.from("escalations").update({
|
|
1736
|
+
customer_status: "active",
|
|
1737
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1738
|
+
}).eq("session_id", currentSessionId).then(
|
|
1739
|
+
() => {
|
|
1740
|
+
},
|
|
1741
|
+
(err) => console.error("[KiteChat] Failed to update customer status:", err)
|
|
1742
|
+
);
|
|
1743
|
+
};
|
|
1744
|
+
console.log("[KiteChat] Starting presence heartbeat for live chat");
|
|
1745
|
+
markActive();
|
|
1766
1746
|
heartbeatIntervalRef.current = window.setInterval(() => {
|
|
1767
|
-
|
|
1747
|
+
markActive();
|
|
1768
1748
|
}, 6e4);
|
|
1769
1749
|
const handleBeforeUnload = () => {
|
|
1770
1750
|
supabase.from("escalations").update({
|
|
@@ -1779,7 +1759,7 @@ function ChatPanel({
|
|
|
1779
1759
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1780
1760
|
}).eq("session_id", currentSessionId);
|
|
1781
1761
|
} else if (document.visibilityState === "visible") {
|
|
1782
|
-
|
|
1762
|
+
markActive();
|
|
1783
1763
|
}
|
|
1784
1764
|
};
|
|
1785
1765
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1787,13 +1767,12 @@ function ChatPanel({
|
|
|
1787
1767
|
return () => {
|
|
1788
1768
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
1789
1769
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1770
|
+
console.log("[KiteChat] Escalation ended, marking disconnected");
|
|
1790
1771
|
supabase.from("escalations").update({
|
|
1791
1772
|
customer_status: "disconnected",
|
|
1792
1773
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1793
1774
|
}).eq("session_id", currentSessionId).then(
|
|
1794
|
-
() =>
|
|
1795
|
-
console.log("[KiteChat] Marked customer as disconnected");
|
|
1796
|
-
},
|
|
1775
|
+
() => console.log("[KiteChat] Successfully marked disconnected on escalation end"),
|
|
1797
1776
|
(err) => {
|
|
1798
1777
|
console.error("[KiteChat] Failed to mark disconnected:", err);
|
|
1799
1778
|
}
|
|
@@ -1803,17 +1782,14 @@ function ChatPanel({
|
|
|
1803
1782
|
heartbeatIntervalRef.current = null;
|
|
1804
1783
|
}
|
|
1805
1784
|
};
|
|
1806
|
-
}, [isEscalated, sessionId
|
|
1785
|
+
}, [isEscalated, sessionId]);
|
|
1807
1786
|
const sendTypingIndicator = React6.useCallback((isTyping) => {
|
|
1808
|
-
if (!typingChannelRef.current) {
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
if (!isEscalated) {
|
|
1813
|
-
console.log("[KiteChat] Cannot send typing - not escalated");
|
|
1787
|
+
if (!typingChannelRef.current || !isEscalated) {
|
|
1788
|
+
if (isTyping) {
|
|
1789
|
+
console.warn("[KiteChat] Typing channel not ready, cannot send typing indicator");
|
|
1790
|
+
}
|
|
1814
1791
|
return;
|
|
1815
1792
|
}
|
|
1816
|
-
console.log(`[KiteChat] Sending typing indicator: ${isTyping}`);
|
|
1817
1793
|
typingChannelRef.current.send({
|
|
1818
1794
|
type: "broadcast",
|
|
1819
1795
|
event: "typing",
|
|
@@ -1822,16 +1798,23 @@ function ChatPanel({
|
|
|
1822
1798
|
}, [isEscalated]);
|
|
1823
1799
|
const userTypingTimeoutRef = React6.useRef(null);
|
|
1824
1800
|
const handleTypingStart = React6.useCallback(() => {
|
|
1825
|
-
if (!isEscalated || !supabaseRef.current) return;
|
|
1801
|
+
if (!isEscalated || !supabaseRef.current || !sessionId) return;
|
|
1826
1802
|
sendTypingIndicator(true);
|
|
1827
|
-
|
|
1803
|
+
supabaseRef.current.from("escalations").update({
|
|
1804
|
+
customer_status: "active",
|
|
1805
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1806
|
+
}).eq("session_id", sessionId).then(
|
|
1807
|
+
() => {
|
|
1808
|
+
},
|
|
1809
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
1810
|
+
);
|
|
1828
1811
|
if (userTypingTimeoutRef.current) {
|
|
1829
1812
|
window.clearTimeout(userTypingTimeoutRef.current);
|
|
1830
1813
|
}
|
|
1831
1814
|
userTypingTimeoutRef.current = window.setTimeout(() => {
|
|
1832
1815
|
sendTypingIndicator(false);
|
|
1833
1816
|
}, 1500);
|
|
1834
|
-
}, [isEscalated, sendTypingIndicator,
|
|
1817
|
+
}, [isEscalated, sendTypingIndicator, sessionId]);
|
|
1835
1818
|
const streamIntervals = React6.useRef({});
|
|
1836
1819
|
const isEmpty = messages.length === 0;
|
|
1837
1820
|
const [phase, setPhase] = React6.useState("idle");
|
|
@@ -1866,12 +1849,6 @@ function ChatPanel({
|
|
|
1866
1849
|
const latestBulkSummaryNavigationRef = React6.useRef(null);
|
|
1867
1850
|
const [guideComplete, setGuideComplete] = React6.useState(false);
|
|
1868
1851
|
React6.useEffect(() => {
|
|
1869
|
-
window.resetIntegrationNotification = () => {
|
|
1870
|
-
localStorage.removeItem("gmailNotificationSeen");
|
|
1871
|
-
console.log(
|
|
1872
|
-
"Integration notification reset! Click the Integrations tab to see it again."
|
|
1873
|
-
);
|
|
1874
|
-
};
|
|
1875
1852
|
const handleIntegrationTabClick = () => {
|
|
1876
1853
|
const hasSeenNotification = localStorage.getItem("gmailNotificationSeen");
|
|
1877
1854
|
if (!hasSeenNotification) {
|
|
@@ -2013,17 +1990,7 @@ function ChatPanel({
|
|
|
2013
1990
|
return;
|
|
2014
1991
|
}
|
|
2015
1992
|
const currentBulkNav = latestBulkSummaryNavigationRef.current;
|
|
2016
|
-
console.log(
|
|
2017
|
-
"[DEBUG] Keyboard handler - latestBulkSummaryNavigation:",
|
|
2018
|
-
currentBulkNav,
|
|
2019
|
-
"onNavigate:",
|
|
2020
|
-
!!onNavigate
|
|
2021
|
-
);
|
|
2022
1993
|
if (currentBulkNav && onNavigate) {
|
|
2023
|
-
console.log(
|
|
2024
|
-
"[DEBUG] Navigating via keyboard to:",
|
|
2025
|
-
currentBulkNav.page
|
|
2026
|
-
);
|
|
2027
1994
|
e.preventDefault();
|
|
2028
1995
|
e.stopPropagation();
|
|
2029
1996
|
onNavigate(currentBulkNav.page, currentBulkNav.subtab);
|
|
@@ -2069,7 +2036,6 @@ function ChatPanel({
|
|
|
2069
2036
|
const messageId = data.message_id;
|
|
2070
2037
|
const isDuplicate = messageId ? prev.some((m) => m.serverMessageId === messageId) : prev.slice(-5).some((m) => m.content === content);
|
|
2071
2038
|
if (isDuplicate) {
|
|
2072
|
-
console.debug("[KiteChat] Skipping duplicate agent message:", messageId || content.slice(0, 30));
|
|
2073
2039
|
return prev;
|
|
2074
2040
|
}
|
|
2075
2041
|
return [...prev, {
|
|
@@ -2092,7 +2058,6 @@ function ChatPanel({
|
|
|
2092
2058
|
console.error("[KiteChat] Escalation WebSocket error:", err);
|
|
2093
2059
|
};
|
|
2094
2060
|
ws.onclose = () => {
|
|
2095
|
-
console.log("[KiteChat] Escalation WebSocket closed");
|
|
2096
2061
|
};
|
|
2097
2062
|
escalationWsRef.current = ws;
|
|
2098
2063
|
}, [agentUrl]);
|
|
@@ -2106,13 +2071,22 @@ function ChatPanel({
|
|
|
2106
2071
|
type: "user_message",
|
|
2107
2072
|
content
|
|
2108
2073
|
}));
|
|
2109
|
-
|
|
2074
|
+
if (supabaseRef.current && sessionId) {
|
|
2075
|
+
supabaseRef.current.from("escalations").update({
|
|
2076
|
+
customer_status: "active",
|
|
2077
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
2078
|
+
}).eq("session_id", sessionId).then(
|
|
2079
|
+
() => {
|
|
2080
|
+
},
|
|
2081
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2110
2084
|
return true;
|
|
2111
2085
|
} catch (err) {
|
|
2112
2086
|
console.error("[KiteChat] Failed to send escalated message:", err);
|
|
2113
2087
|
return false;
|
|
2114
2088
|
}
|
|
2115
|
-
}, [
|
|
2089
|
+
}, [sessionId]);
|
|
2116
2090
|
React6.useEffect(() => {
|
|
2117
2091
|
return () => {
|
|
2118
2092
|
if (escalationWsRef.current) {
|
|
@@ -2386,14 +2360,6 @@ function ChatPanel({
|
|
|
2386
2360
|
try {
|
|
2387
2361
|
const controller = new AbortController();
|
|
2388
2362
|
const timeoutId = setTimeout(() => controller.abort(), 6e4);
|
|
2389
|
-
console.log("[ChatPanel] Sending chat request to agent backend...");
|
|
2390
|
-
console.log("[ChatPanel] Agent URL:", agentUrl);
|
|
2391
|
-
console.log("[ChatPanel] User data being sent:");
|
|
2392
|
-
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2393
|
-
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2394
|
-
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2395
|
-
console.log("[ChatPanel] org_id:", orgId);
|
|
2396
|
-
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2397
2363
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
2398
2364
|
method: "POST",
|
|
2399
2365
|
headers: {
|
|
@@ -2610,7 +2576,6 @@ function ChatPanel({
|
|
|
2610
2576
|
setMessages((prev) => [...prev, escalationMessage]);
|
|
2611
2577
|
} else if (eventType === "tool_request") {
|
|
2612
2578
|
const toolRequest = data;
|
|
2613
|
-
console.log("[KiteChat] Received tool_request:", toolRequest);
|
|
2614
2579
|
executeToolRequest(toolRequest).catch((err) => {
|
|
2615
2580
|
console.error("[KiteChat] Tool execution failed:", err);
|
|
2616
2581
|
});
|
|
@@ -2928,11 +2893,6 @@ ${userText}`
|
|
|
2928
2893
|
}
|
|
2929
2894
|
});
|
|
2930
2895
|
} else if (eventType === "summary") {
|
|
2931
|
-
console.log("[DEBUG] Received summary event - data:", data);
|
|
2932
|
-
console.log(
|
|
2933
|
-
"[DEBUG] navigationPage from backend:",
|
|
2934
|
-
data.navigationPage
|
|
2935
|
-
);
|
|
2936
2896
|
setPhase("idle");
|
|
2937
2897
|
setProgressSteps([]);
|
|
2938
2898
|
setPendingBulkSession(null);
|
|
@@ -2952,7 +2912,6 @@ ${userText}`
|
|
|
2952
2912
|
navigationPage: data.navigationPage
|
|
2953
2913
|
}
|
|
2954
2914
|
};
|
|
2955
|
-
console.log("[DEBUG] Creating bulkSummary message:", newMsg);
|
|
2956
2915
|
return [...filtered, newMsg];
|
|
2957
2916
|
});
|
|
2958
2917
|
setTimeout(() => {
|
|
@@ -4523,28 +4482,11 @@ ${userText}`
|
|
|
4523
4482
|
onClick: (e) => {
|
|
4524
4483
|
e.preventDefault();
|
|
4525
4484
|
e.stopPropagation();
|
|
4526
|
-
console.log(
|
|
4527
|
-
"[DEBUG] Button clicked - navigationPage:",
|
|
4528
|
-
navigationPage,
|
|
4529
|
-
"onNavigate:",
|
|
4530
|
-
!!onNavigate
|
|
4531
|
-
);
|
|
4532
4485
|
if (onNavigate && navigationPage.page) {
|
|
4533
|
-
console.log(
|
|
4534
|
-
"[DEBUG] Calling onNavigate with page:",
|
|
4535
|
-
navigationPage.page
|
|
4536
|
-
);
|
|
4537
4486
|
onNavigate(
|
|
4538
4487
|
navigationPage.page,
|
|
4539
4488
|
navigationPage.subtab
|
|
4540
4489
|
);
|
|
4541
|
-
} else {
|
|
4542
|
-
console.log(
|
|
4543
|
-
"[DEBUG] Condition failed - onNavigate:",
|
|
4544
|
-
!!onNavigate,
|
|
4545
|
-
"navigationPage.page:",
|
|
4546
|
-
navigationPage.page
|
|
4547
|
-
);
|
|
4548
4490
|
}
|
|
4549
4491
|
},
|
|
4550
4492
|
className: "flex items-center gap-2 text-xs text-gray-500 hover:text-gray-700 transition-colors group cursor-pointer",
|
|
@@ -4824,7 +4766,8 @@ function ChatPanelWithToggle({
|
|
|
4824
4766
|
supabaseAnonKey,
|
|
4825
4767
|
initialCorner,
|
|
4826
4768
|
onCornerChange,
|
|
4827
|
-
productBackendUrl
|
|
4769
|
+
productBackendUrl,
|
|
4770
|
+
getAuthHeaders
|
|
4828
4771
|
}) {
|
|
4829
4772
|
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
4830
4773
|
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
@@ -4854,7 +4797,8 @@ function ChatPanelWithToggle({
|
|
|
4854
4797
|
supabaseAnonKey,
|
|
4855
4798
|
initialCorner,
|
|
4856
4799
|
onCornerChange,
|
|
4857
|
-
productBackendUrl
|
|
4800
|
+
productBackendUrl,
|
|
4801
|
+
getAuthHeaders
|
|
4858
4802
|
}
|
|
4859
4803
|
);
|
|
4860
4804
|
}
|
|
@@ -4928,7 +4872,8 @@ function KiteChatWrapper({
|
|
|
4928
4872
|
userEmail: config.userEmail,
|
|
4929
4873
|
supabaseUrl: config.supabaseUrl,
|
|
4930
4874
|
supabaseAnonKey: config.supabaseAnonKey,
|
|
4931
|
-
productBackendUrl: config.productBackendUrl
|
|
4875
|
+
productBackendUrl: config.productBackendUrl,
|
|
4876
|
+
getAuthHeaders: config.getAuthHeaders
|
|
4932
4877
|
}
|
|
4933
4878
|
);
|
|
4934
4879
|
}
|
|
@@ -4971,7 +4916,6 @@ function createKiteChat(config) {
|
|
|
4971
4916
|
}
|
|
4972
4917
|
)
|
|
4973
4918
|
);
|
|
4974
|
-
console.log("[KiteChat] Mounted");
|
|
4975
4919
|
},
|
|
4976
4920
|
unmount() {
|
|
4977
4921
|
if (!root) {
|
|
@@ -4983,7 +4927,6 @@ function createKiteChat(config) {
|
|
|
4983
4927
|
containerElement = null;
|
|
4984
4928
|
configUpdater = null;
|
|
4985
4929
|
stateUpdaters = null;
|
|
4986
|
-
console.log("[KiteChat] Unmounted");
|
|
4987
4930
|
},
|
|
4988
4931
|
open() {
|
|
4989
4932
|
stateUpdaters?.setIsOpen(true);
|
|
@@ -118,8 +118,10 @@ interface ChatPanelProps {
|
|
|
118
118
|
onCornerChange?: (corner: PanelCorner) => void;
|
|
119
119
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
120
120
|
productBackendUrl?: string;
|
|
121
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
122
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
121
123
|
}
|
|
122
|
-
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
124
|
+
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, getAuthHeaders, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
123
125
|
/**
|
|
124
126
|
* PanelToggle - An arrow button on the right edge that toggles the side panel
|
|
125
127
|
* Shows left arrow when closed (click to open), right arrow when open (click to close)
|
|
@@ -182,8 +184,10 @@ interface ChatPanelWithToggleProps {
|
|
|
182
184
|
onCornerChange?: (corner: PanelCorner) => void;
|
|
183
185
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
184
186
|
productBackendUrl?: string;
|
|
187
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
188
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
185
189
|
}
|
|
186
|
-
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
190
|
+
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, getAuthHeaders, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
187
191
|
/**
|
|
188
192
|
* @deprecated Use ChatPanelWithToggle instead for the new side panel UX
|
|
189
193
|
*/
|
|
@@ -253,6 +257,8 @@ interface KiteChatConfig {
|
|
|
253
257
|
supabaseAnonKey?: string;
|
|
254
258
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
255
259
|
productBackendUrl?: string;
|
|
260
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
261
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
256
262
|
}
|
|
257
263
|
/**
|
|
258
264
|
* Instance returned by createKiteChat with lifecycle control methods.
|
|
@@ -118,8 +118,10 @@ interface ChatPanelProps {
|
|
|
118
118
|
onCornerChange?: (corner: PanelCorner) => void;
|
|
119
119
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
120
120
|
productBackendUrl?: string;
|
|
121
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
122
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
121
123
|
}
|
|
122
|
-
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
124
|
+
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, getAuthHeaders, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
123
125
|
/**
|
|
124
126
|
* PanelToggle - An arrow button on the right edge that toggles the side panel
|
|
125
127
|
* Shows left arrow when closed (click to open), right arrow when open (click to close)
|
|
@@ -182,8 +184,10 @@ interface ChatPanelWithToggleProps {
|
|
|
182
184
|
onCornerChange?: (corner: PanelCorner) => void;
|
|
183
185
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
184
186
|
productBackendUrl?: string;
|
|
187
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
188
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
185
189
|
}
|
|
186
|
-
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
190
|
+
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, supabaseUrl, supabaseAnonKey, initialCorner, onCornerChange, productBackendUrl, getAuthHeaders, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
187
191
|
/**
|
|
188
192
|
* @deprecated Use ChatPanelWithToggle instead for the new side panel UX
|
|
189
193
|
*/
|
|
@@ -253,6 +257,8 @@ interface KiteChatConfig {
|
|
|
253
257
|
supabaseAnonKey?: string;
|
|
254
258
|
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
255
259
|
productBackendUrl?: string;
|
|
260
|
+
/** Optional async function to provide authentication headers for API requests */
|
|
261
|
+
getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
256
262
|
}
|
|
257
263
|
/**
|
|
258
264
|
* Instance returned by createKiteChat with lifecycle control methods.
|