@kite-copilot/chat-panel 0.2.49 → 0.2.51
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 +118 -158
- 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-VBCGW333.js} +118 -158
- 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 +118 -158
- 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
package/dist/index.cjs
CHANGED
|
@@ -379,28 +379,22 @@ function useUserAuth({
|
|
|
379
379
|
}) {
|
|
380
380
|
const [authState, setAuthState] = React4.useState({ status: "idle" });
|
|
381
381
|
const lastSessionIdRef = React4.useRef(null);
|
|
382
|
+
const lastEnabledRef = React4.useRef(enabled);
|
|
382
383
|
const fetchUser = React4.useCallback(async () => {
|
|
383
384
|
if (!productBackendUrl || !enabled) {
|
|
384
|
-
console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
|
|
385
385
|
setAuthState({ status: "idle" });
|
|
386
386
|
return;
|
|
387
387
|
}
|
|
388
|
-
console.log("[useUserAuth] Starting auth request to product backend...");
|
|
389
|
-
console.log("[useUserAuth] Product backend URL:", productBackendUrl);
|
|
390
|
-
console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
|
|
391
388
|
setAuthState({ status: "loading" });
|
|
392
389
|
try {
|
|
393
390
|
const response = await fetch(`${productBackendUrl}/users/me`, {
|
|
394
391
|
method: "GET",
|
|
395
392
|
credentials: "include",
|
|
396
|
-
// Include cookies for authentication
|
|
397
393
|
headers: {
|
|
398
394
|
"Accept": "application/json"
|
|
399
395
|
}
|
|
400
396
|
});
|
|
401
|
-
console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
|
|
402
397
|
if (!response.ok) {
|
|
403
|
-
console.log("[useUserAuth] Auth request failed with status:", response.status);
|
|
404
398
|
if (response.status === 401) {
|
|
405
399
|
throw new Error("Please log in to use the chat assistant.");
|
|
406
400
|
}
|
|
@@ -410,27 +404,36 @@ function useUserAuth({
|
|
|
410
404
|
throw new Error(`Authentication failed (${response.status})`);
|
|
411
405
|
}
|
|
412
406
|
const user = await response.json();
|
|
413
|
-
console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
|
|
414
|
-
console.log("[useUserAuth] id:", user.id);
|
|
415
|
-
console.log("[useUserAuth] email:", user.email);
|
|
416
|
-
console.log("[useUserAuth] name:", user.name);
|
|
417
|
-
console.log("[useUserAuth] role:", user.role);
|
|
418
|
-
console.log("[useUserAuth] isInternal:", user.isInternal);
|
|
419
|
-
console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
|
|
420
|
-
console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
|
|
421
407
|
setAuthState({ status: "authenticated", user });
|
|
422
408
|
} catch (error) {
|
|
423
|
-
|
|
409
|
+
if (error instanceof Error) {
|
|
410
|
+
const errorMessage = error.message.toLowerCase();
|
|
411
|
+
const isNetworkError = error instanceof TypeError || errorMessage.includes("failed to fetch") || errorMessage.includes("network");
|
|
412
|
+
const is404Error = errorMessage.includes("404");
|
|
413
|
+
if (isNetworkError || is404Error) {
|
|
414
|
+
console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
|
|
415
|
+
setAuthState({ status: "idle" });
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
424
419
|
const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
|
|
425
420
|
setAuthState({ status: "error", error: message });
|
|
426
421
|
}
|
|
427
422
|
}, [productBackendUrl, enabled]);
|
|
428
423
|
React4.useEffect(() => {
|
|
429
|
-
|
|
424
|
+
const sessionChanged = sessionId !== lastSessionIdRef.current;
|
|
425
|
+
const enabledChanged = enabled !== lastEnabledRef.current;
|
|
426
|
+
const becameEnabled = enabled && !lastEnabledRef.current;
|
|
427
|
+
if (sessionChanged) {
|
|
430
428
|
lastSessionIdRef.current = sessionId;
|
|
429
|
+
}
|
|
430
|
+
if (enabledChanged) {
|
|
431
|
+
lastEnabledRef.current = enabled;
|
|
432
|
+
}
|
|
433
|
+
if (sessionChanged || becameEnabled) {
|
|
431
434
|
fetchUser();
|
|
432
435
|
}
|
|
433
|
-
}, [sessionId, fetchUser]);
|
|
436
|
+
}, [sessionId, enabled, fetchUser]);
|
|
434
437
|
const retry = React4.useCallback(() => {
|
|
435
438
|
fetchUser();
|
|
436
439
|
}, [fetchUser]);
|
|
@@ -447,13 +450,11 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
447
450
|
});
|
|
448
451
|
React5.useEffect(() => {
|
|
449
452
|
if (!agentUrl || !orgId) {
|
|
450
|
-
console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
|
|
451
453
|
return;
|
|
452
454
|
}
|
|
453
455
|
const fetchConfig = async () => {
|
|
454
456
|
setState({ status: "loading", config: null, error: null });
|
|
455
457
|
const url = `${agentUrl}/org/${orgId}/config`;
|
|
456
|
-
console.log("[useOrgConfig] Fetching org config from:", url);
|
|
457
458
|
try {
|
|
458
459
|
const response = await fetch(url, {
|
|
459
460
|
method: "GET",
|
|
@@ -465,7 +466,6 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
465
466
|
throw new Error(`Failed to fetch org config (${response.status})`);
|
|
466
467
|
}
|
|
467
468
|
const config = await response.json();
|
|
468
|
-
console.log("[useOrgConfig] Received config:", config);
|
|
469
469
|
setState({ status: "success", config, error: null });
|
|
470
470
|
} catch (error) {
|
|
471
471
|
const message = error instanceof Error ? error.message : "Failed to fetch org config";
|
|
@@ -499,8 +499,7 @@ function useFrontendToolExecutor({
|
|
|
499
499
|
}
|
|
500
500
|
}, [agentUrl]);
|
|
501
501
|
const executeToolRequest = (0, import_react.useCallback)(async (toolRequest) => {
|
|
502
|
-
const { call_id,
|
|
503
|
-
console.log("[FrontendToolExecutor] Executing tool:", tool_name, "with args:", args);
|
|
502
|
+
const { call_id, arguments: args, endpoint, method, path_params } = toolRequest;
|
|
504
503
|
try {
|
|
505
504
|
let url = endpoint;
|
|
506
505
|
for (const param of path_params) {
|
|
@@ -516,7 +515,6 @@ function useFrontendToolExecutor({
|
|
|
516
515
|
}
|
|
517
516
|
const queryString = queryParams.toString();
|
|
518
517
|
const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
|
|
519
|
-
console.log("[FrontendToolExecutor] Fetching:", fullUrl);
|
|
520
518
|
const response = await fetch(fullUrl, {
|
|
521
519
|
method,
|
|
522
520
|
credentials: "include",
|
|
@@ -528,7 +526,6 @@ function useFrontendToolExecutor({
|
|
|
528
526
|
let result;
|
|
529
527
|
if (response.ok) {
|
|
530
528
|
result = await response.json();
|
|
531
|
-
console.log("[FrontendToolExecutor] Tool result:", result);
|
|
532
529
|
} else {
|
|
533
530
|
const errorText = await response.text();
|
|
534
531
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
@@ -1150,7 +1147,6 @@ function TypingIndicator({ className = "" }) {
|
|
|
1150
1147
|
|
|
1151
1148
|
// src/ChatPanel.tsx
|
|
1152
1149
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1153
|
-
var CHAT_PANEL_VERSION = true ? "0.2.49" : "dev";
|
|
1154
1150
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1155
1151
|
var PANEL_WIDTH = 400;
|
|
1156
1152
|
var PANEL_HEIGHT = 600;
|
|
@@ -1614,7 +1610,8 @@ function ChatPanel({
|
|
|
1614
1610
|
supabaseAnonKey,
|
|
1615
1611
|
initialCorner = "bottom-left",
|
|
1616
1612
|
onCornerChange,
|
|
1617
|
-
productBackendUrl
|
|
1613
|
+
productBackendUrl,
|
|
1614
|
+
getAuthHeaders
|
|
1618
1615
|
} = {}) {
|
|
1619
1616
|
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1620
1617
|
const [input, setInput] = React6.useState("");
|
|
@@ -1636,6 +1633,8 @@ function ChatPanel({
|
|
|
1636
1633
|
const [sessionUser, setSessionUser] = React6.useState(null);
|
|
1637
1634
|
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1638
1635
|
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
1636
|
+
const effectiveSupabaseUrl = orgConfigState.config?.supabaseUrl || supabaseUrl;
|
|
1637
|
+
const effectiveSupabaseAnonKey = orgConfigState.config?.supabaseAnonKey || supabaseAnonKey;
|
|
1639
1638
|
const { authState, retry: retryAuth } = useUserAuth({
|
|
1640
1639
|
productBackendUrl: effectiveProductBackendUrl,
|
|
1641
1640
|
sessionId,
|
|
@@ -1647,37 +1646,6 @@ function ChatPanel({
|
|
|
1647
1646
|
agentUrl,
|
|
1648
1647
|
sessionId
|
|
1649
1648
|
});
|
|
1650
|
-
React6.useEffect(() => {
|
|
1651
|
-
if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
|
|
1652
|
-
return;
|
|
1653
|
-
}
|
|
1654
|
-
const testProductBackendEndpoint = async () => {
|
|
1655
|
-
const url = `${effectiveProductBackendUrl}/getDocument/snowkite/categories/`;
|
|
1656
|
-
console.log("[KiteChat TEST] Testing product backend connectivity...");
|
|
1657
|
-
console.log("[KiteChat TEST] URL:", url);
|
|
1658
|
-
try {
|
|
1659
|
-
const response = await fetch(url, {
|
|
1660
|
-
method: "GET",
|
|
1661
|
-
// Note: not using credentials: 'include' to avoid CORS issues with wildcard
|
|
1662
|
-
headers: {
|
|
1663
|
-
"Accept": "application/json"
|
|
1664
|
-
}
|
|
1665
|
-
});
|
|
1666
|
-
console.log("[KiteChat TEST] Response status:", response.status);
|
|
1667
|
-
console.log("[KiteChat TEST] Response ok:", response.ok);
|
|
1668
|
-
if (response.ok) {
|
|
1669
|
-
const data = await response.json();
|
|
1670
|
-
console.log("[KiteChat TEST] SUCCESS - product backend reachable, data:", data);
|
|
1671
|
-
} else {
|
|
1672
|
-
const errorText = await response.text();
|
|
1673
|
-
console.log("[KiteChat TEST] FAILED - status:", response.status, "body:", errorText);
|
|
1674
|
-
}
|
|
1675
|
-
} catch (error) {
|
|
1676
|
-
console.error("[KiteChat TEST] ERROR:", error);
|
|
1677
|
-
}
|
|
1678
|
-
};
|
|
1679
|
-
testProductBackendEndpoint();
|
|
1680
|
-
}, [effectiveProductBackendUrl, orgConfigState.status]);
|
|
1681
1649
|
const effectiveUser = React6.useMemo(() => {
|
|
1682
1650
|
if (sessionUser) {
|
|
1683
1651
|
return sessionUser;
|
|
@@ -1708,7 +1676,6 @@ function ChatPanel({
|
|
|
1708
1676
|
userRole: authState.user.role,
|
|
1709
1677
|
isInternal: authState.user.isInternal
|
|
1710
1678
|
});
|
|
1711
|
-
console.log("[ChatPanel] Session user captured:", authState.user.id);
|
|
1712
1679
|
}
|
|
1713
1680
|
}, [authState, sessionUser]);
|
|
1714
1681
|
const isWaitingForAuth = React6.useMemo(() => {
|
|
@@ -1721,26 +1688,18 @@ function ChatPanel({
|
|
|
1721
1688
|
const supabaseRef = React6.useRef(null);
|
|
1722
1689
|
const typingChannelRef = React6.useRef(null);
|
|
1723
1690
|
const typingTimeoutRef = React6.useRef(null);
|
|
1724
|
-
React6.useEffect(() => {
|
|
1725
|
-
console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
|
|
1726
|
-
}, []);
|
|
1727
1691
|
const resetSession = React6.useCallback(() => {
|
|
1728
|
-
console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
|
|
1729
1692
|
if (isEscalated && supabaseRef.current && sessionId) {
|
|
1730
|
-
console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
|
|
1731
1693
|
supabaseRef.current.from("escalations").update({
|
|
1732
1694
|
customer_status: "disconnected",
|
|
1733
1695
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1734
1696
|
}).eq("session_id", sessionId).then(
|
|
1735
|
-
(
|
|
1736
|
-
console.log("[KiteChat] Disconnect update result:", result);
|
|
1697
|
+
() => {
|
|
1737
1698
|
},
|
|
1738
1699
|
(err) => {
|
|
1739
1700
|
console.error("[KiteChat] Disconnect update failed:", err);
|
|
1740
1701
|
}
|
|
1741
1702
|
);
|
|
1742
|
-
} else {
|
|
1743
|
-
console.log("[KiteChat] Skipping disconnect update - conditions not met");
|
|
1744
1703
|
}
|
|
1745
1704
|
setSessionUser(null);
|
|
1746
1705
|
setSessionId(crypto.randomUUID());
|
|
@@ -1756,22 +1715,19 @@ function ChatPanel({
|
|
|
1756
1715
|
}
|
|
1757
1716
|
}, [isEscalated, sessionId]);
|
|
1758
1717
|
React6.useEffect(() => {
|
|
1759
|
-
if (
|
|
1760
|
-
supabaseRef.current = (0, import_supabase_js.createClient)(
|
|
1718
|
+
if (effectiveSupabaseUrl && effectiveSupabaseAnonKey && !supabaseRef.current) {
|
|
1719
|
+
supabaseRef.current = (0, import_supabase_js.createClient)(effectiveSupabaseUrl, effectiveSupabaseAnonKey);
|
|
1761
1720
|
}
|
|
1762
|
-
}, [
|
|
1721
|
+
}, [effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
|
|
1763
1722
|
React6.useEffect(() => {
|
|
1764
1723
|
if (!isEscalated || !sessionId || !supabaseRef.current) {
|
|
1765
1724
|
return;
|
|
1766
1725
|
}
|
|
1767
1726
|
const channelName = `typing:${sessionId}`;
|
|
1768
1727
|
const channel = supabaseRef.current.channel(channelName);
|
|
1769
|
-
console.log(`[KiteChat] Subscribing to typing channel: ${channelName}`);
|
|
1770
1728
|
channel.on("broadcast", { event: "typing" }, (payload) => {
|
|
1771
|
-
console.log("[KiteChat] Received typing broadcast:", payload);
|
|
1772
1729
|
const { sender, isTyping } = payload.payload;
|
|
1773
1730
|
if (sender === "agent") {
|
|
1774
|
-
console.log(`[KiteChat] Agent typing: ${isTyping}`);
|
|
1775
1731
|
setAgentIsTyping(isTyping);
|
|
1776
1732
|
if (isTyping) {
|
|
1777
1733
|
if (typingTimeoutRef.current) {
|
|
@@ -1783,10 +1739,11 @@ function ChatPanel({
|
|
|
1783
1739
|
}
|
|
1784
1740
|
}
|
|
1785
1741
|
}).subscribe((status) => {
|
|
1786
|
-
console.log(`[KiteChat] Typing channel status: ${status}`);
|
|
1787
1742
|
if (status === "SUBSCRIBED") {
|
|
1788
1743
|
typingChannelRef.current = channel;
|
|
1789
|
-
console.log("[KiteChat] Typing channel
|
|
1744
|
+
console.log("[KiteChat] Typing channel subscribed successfully");
|
|
1745
|
+
} else if (status === "CHANNEL_ERROR") {
|
|
1746
|
+
console.error("[KiteChat] Typing channel subscription failed");
|
|
1790
1747
|
}
|
|
1791
1748
|
});
|
|
1792
1749
|
return () => {
|
|
@@ -1797,6 +1754,20 @@ function ChatPanel({
|
|
|
1797
1754
|
}
|
|
1798
1755
|
};
|
|
1799
1756
|
}, [isEscalated, sessionId]);
|
|
1757
|
+
React6.useEffect(() => {
|
|
1758
|
+
if (!isOpen && isEscalated && supabaseRef.current && sessionId) {
|
|
1759
|
+
console.log("[KiteChat] Panel closed during live chat, marking disconnected");
|
|
1760
|
+
supabaseRef.current.from("escalations").update({
|
|
1761
|
+
customer_status: "disconnected",
|
|
1762
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1763
|
+
}).eq("session_id", sessionId).then(
|
|
1764
|
+
() => console.log("[KiteChat] Successfully marked disconnected on panel close"),
|
|
1765
|
+
(err) => {
|
|
1766
|
+
console.error("[KiteChat] Failed to mark disconnected on panel close:", err);
|
|
1767
|
+
}
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
}, [isOpen, isEscalated, sessionId]);
|
|
1800
1771
|
const heartbeatIntervalRef = React6.useRef(null);
|
|
1801
1772
|
const updateCustomerStatus = React6.useCallback(async (status) => {
|
|
1802
1773
|
if (!supabaseRef.current || !sessionId) return;
|
|
@@ -1815,24 +1786,50 @@ function ChatPanel({
|
|
|
1815
1786
|
}
|
|
1816
1787
|
const currentSessionId = sessionId;
|
|
1817
1788
|
const supabase = supabaseRef.current;
|
|
1818
|
-
|
|
1789
|
+
const sbUrl = effectiveSupabaseUrl;
|
|
1790
|
+
const sbKey = effectiveSupabaseAnonKey;
|
|
1791
|
+
const markActive = () => {
|
|
1792
|
+
supabase.from("escalations").update({
|
|
1793
|
+
customer_status: "active",
|
|
1794
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1795
|
+
}).eq("session_id", currentSessionId).then(
|
|
1796
|
+
() => {
|
|
1797
|
+
},
|
|
1798
|
+
(err) => console.error("[KiteChat] Failed to update customer status:", err)
|
|
1799
|
+
);
|
|
1800
|
+
};
|
|
1801
|
+
const markDisconnectedWithKeepalive = () => {
|
|
1802
|
+
if (!sbUrl || !sbKey) return;
|
|
1803
|
+
const url = `${sbUrl}/rest/v1/escalations?session_id=eq.${currentSessionId}`;
|
|
1804
|
+
fetch(url, {
|
|
1805
|
+
method: "PATCH",
|
|
1806
|
+
headers: {
|
|
1807
|
+
"Content-Type": "application/json",
|
|
1808
|
+
"apikey": sbKey,
|
|
1809
|
+
"Authorization": `Bearer ${sbKey}`,
|
|
1810
|
+
"Prefer": "return=minimal"
|
|
1811
|
+
},
|
|
1812
|
+
body: JSON.stringify({
|
|
1813
|
+
customer_status: "disconnected",
|
|
1814
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1815
|
+
}),
|
|
1816
|
+
keepalive: true
|
|
1817
|
+
}).catch(() => {
|
|
1818
|
+
});
|
|
1819
|
+
};
|
|
1820
|
+
console.log("[KiteChat] Starting presence heartbeat for live chat");
|
|
1821
|
+
markActive();
|
|
1819
1822
|
heartbeatIntervalRef.current = window.setInterval(() => {
|
|
1820
|
-
|
|
1823
|
+
markActive();
|
|
1821
1824
|
}, 6e4);
|
|
1822
1825
|
const handleBeforeUnload = () => {
|
|
1823
|
-
|
|
1824
|
-
customer_status: "disconnected",
|
|
1825
|
-
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1826
|
-
}).eq("session_id", currentSessionId);
|
|
1826
|
+
markDisconnectedWithKeepalive();
|
|
1827
1827
|
};
|
|
1828
1828
|
const handleVisibilityChange = () => {
|
|
1829
1829
|
if (document.visibilityState === "hidden") {
|
|
1830
|
-
|
|
1831
|
-
customer_status: "disconnected",
|
|
1832
|
-
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1833
|
-
}).eq("session_id", currentSessionId);
|
|
1830
|
+
markDisconnectedWithKeepalive();
|
|
1834
1831
|
} else if (document.visibilityState === "visible") {
|
|
1835
|
-
|
|
1832
|
+
markActive();
|
|
1836
1833
|
}
|
|
1837
1834
|
};
|
|
1838
1835
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1840,13 +1837,12 @@ function ChatPanel({
|
|
|
1840
1837
|
return () => {
|
|
1841
1838
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
1842
1839
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1840
|
+
console.log("[KiteChat] Escalation ended, marking disconnected");
|
|
1843
1841
|
supabase.from("escalations").update({
|
|
1844
1842
|
customer_status: "disconnected",
|
|
1845
1843
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1846
1844
|
}).eq("session_id", currentSessionId).then(
|
|
1847
|
-
() =>
|
|
1848
|
-
console.log("[KiteChat] Marked customer as disconnected");
|
|
1849
|
-
},
|
|
1845
|
+
() => console.log("[KiteChat] Successfully marked disconnected on escalation end"),
|
|
1850
1846
|
(err) => {
|
|
1851
1847
|
console.error("[KiteChat] Failed to mark disconnected:", err);
|
|
1852
1848
|
}
|
|
@@ -1856,17 +1852,14 @@ function ChatPanel({
|
|
|
1856
1852
|
heartbeatIntervalRef.current = null;
|
|
1857
1853
|
}
|
|
1858
1854
|
};
|
|
1859
|
-
}, [isEscalated, sessionId,
|
|
1855
|
+
}, [isEscalated, sessionId, effectiveSupabaseUrl, effectiveSupabaseAnonKey]);
|
|
1860
1856
|
const sendTypingIndicator = React6.useCallback((isTyping) => {
|
|
1861
|
-
if (!typingChannelRef.current) {
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
if (!isEscalated) {
|
|
1866
|
-
console.log("[KiteChat] Cannot send typing - not escalated");
|
|
1857
|
+
if (!typingChannelRef.current || !isEscalated) {
|
|
1858
|
+
if (isTyping) {
|
|
1859
|
+
console.warn("[KiteChat] Typing channel not ready, cannot send typing indicator");
|
|
1860
|
+
}
|
|
1867
1861
|
return;
|
|
1868
1862
|
}
|
|
1869
|
-
console.log(`[KiteChat] Sending typing indicator: ${isTyping}`);
|
|
1870
1863
|
typingChannelRef.current.send({
|
|
1871
1864
|
type: "broadcast",
|
|
1872
1865
|
event: "typing",
|
|
@@ -1875,16 +1868,23 @@ function ChatPanel({
|
|
|
1875
1868
|
}, [isEscalated]);
|
|
1876
1869
|
const userTypingTimeoutRef = React6.useRef(null);
|
|
1877
1870
|
const handleTypingStart = React6.useCallback(() => {
|
|
1878
|
-
if (!isEscalated || !supabaseRef.current) return;
|
|
1871
|
+
if (!isEscalated || !supabaseRef.current || !sessionId) return;
|
|
1879
1872
|
sendTypingIndicator(true);
|
|
1880
|
-
|
|
1873
|
+
supabaseRef.current.from("escalations").update({
|
|
1874
|
+
customer_status: "active",
|
|
1875
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1876
|
+
}).eq("session_id", sessionId).then(
|
|
1877
|
+
() => {
|
|
1878
|
+
},
|
|
1879
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
1880
|
+
);
|
|
1881
1881
|
if (userTypingTimeoutRef.current) {
|
|
1882
1882
|
window.clearTimeout(userTypingTimeoutRef.current);
|
|
1883
1883
|
}
|
|
1884
1884
|
userTypingTimeoutRef.current = window.setTimeout(() => {
|
|
1885
1885
|
sendTypingIndicator(false);
|
|
1886
1886
|
}, 1500);
|
|
1887
|
-
}, [isEscalated, sendTypingIndicator,
|
|
1887
|
+
}, [isEscalated, sendTypingIndicator, sessionId]);
|
|
1888
1888
|
const streamIntervals = React6.useRef({});
|
|
1889
1889
|
const isEmpty = messages.length === 0;
|
|
1890
1890
|
const [phase, setPhase] = React6.useState("idle");
|
|
@@ -1919,12 +1919,6 @@ function ChatPanel({
|
|
|
1919
1919
|
const latestBulkSummaryNavigationRef = React6.useRef(null);
|
|
1920
1920
|
const [guideComplete, setGuideComplete] = React6.useState(false);
|
|
1921
1921
|
React6.useEffect(() => {
|
|
1922
|
-
window.resetIntegrationNotification = () => {
|
|
1923
|
-
localStorage.removeItem("gmailNotificationSeen");
|
|
1924
|
-
console.log(
|
|
1925
|
-
"Integration notification reset! Click the Integrations tab to see it again."
|
|
1926
|
-
);
|
|
1927
|
-
};
|
|
1928
1922
|
const handleIntegrationTabClick = () => {
|
|
1929
1923
|
const hasSeenNotification = localStorage.getItem("gmailNotificationSeen");
|
|
1930
1924
|
if (!hasSeenNotification) {
|
|
@@ -2066,17 +2060,7 @@ function ChatPanel({
|
|
|
2066
2060
|
return;
|
|
2067
2061
|
}
|
|
2068
2062
|
const currentBulkNav = latestBulkSummaryNavigationRef.current;
|
|
2069
|
-
console.log(
|
|
2070
|
-
"[DEBUG] Keyboard handler - latestBulkSummaryNavigation:",
|
|
2071
|
-
currentBulkNav,
|
|
2072
|
-
"onNavigate:",
|
|
2073
|
-
!!onNavigate
|
|
2074
|
-
);
|
|
2075
2063
|
if (currentBulkNav && onNavigate) {
|
|
2076
|
-
console.log(
|
|
2077
|
-
"[DEBUG] Navigating via keyboard to:",
|
|
2078
|
-
currentBulkNav.page
|
|
2079
|
-
);
|
|
2080
2064
|
e.preventDefault();
|
|
2081
2065
|
e.stopPropagation();
|
|
2082
2066
|
onNavigate(currentBulkNav.page, currentBulkNav.subtab);
|
|
@@ -2122,7 +2106,6 @@ function ChatPanel({
|
|
|
2122
2106
|
const messageId = data.message_id;
|
|
2123
2107
|
const isDuplicate = messageId ? prev.some((m) => m.serverMessageId === messageId) : prev.slice(-5).some((m) => m.content === content);
|
|
2124
2108
|
if (isDuplicate) {
|
|
2125
|
-
console.debug("[KiteChat] Skipping duplicate agent message:", messageId || content.slice(0, 30));
|
|
2126
2109
|
return prev;
|
|
2127
2110
|
}
|
|
2128
2111
|
return [...prev, {
|
|
@@ -2145,7 +2128,6 @@ function ChatPanel({
|
|
|
2145
2128
|
console.error("[KiteChat] Escalation WebSocket error:", err);
|
|
2146
2129
|
};
|
|
2147
2130
|
ws.onclose = () => {
|
|
2148
|
-
console.log("[KiteChat] Escalation WebSocket closed");
|
|
2149
2131
|
};
|
|
2150
2132
|
escalationWsRef.current = ws;
|
|
2151
2133
|
}, [agentUrl]);
|
|
@@ -2159,13 +2141,22 @@ function ChatPanel({
|
|
|
2159
2141
|
type: "user_message",
|
|
2160
2142
|
content
|
|
2161
2143
|
}));
|
|
2162
|
-
|
|
2144
|
+
if (supabaseRef.current && sessionId) {
|
|
2145
|
+
supabaseRef.current.from("escalations").update({
|
|
2146
|
+
customer_status: "active",
|
|
2147
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
2148
|
+
}).eq("session_id", sessionId).then(
|
|
2149
|
+
() => {
|
|
2150
|
+
},
|
|
2151
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2163
2154
|
return true;
|
|
2164
2155
|
} catch (err) {
|
|
2165
2156
|
console.error("[KiteChat] Failed to send escalated message:", err);
|
|
2166
2157
|
return false;
|
|
2167
2158
|
}
|
|
2168
|
-
}, [
|
|
2159
|
+
}, [sessionId]);
|
|
2169
2160
|
React6.useEffect(() => {
|
|
2170
2161
|
return () => {
|
|
2171
2162
|
if (escalationWsRef.current) {
|
|
@@ -2439,14 +2430,6 @@ function ChatPanel({
|
|
|
2439
2430
|
try {
|
|
2440
2431
|
const controller = new AbortController();
|
|
2441
2432
|
const timeoutId = setTimeout(() => controller.abort(), 6e4);
|
|
2442
|
-
console.log("[ChatPanel] Sending chat request to agent backend...");
|
|
2443
|
-
console.log("[ChatPanel] Agent URL:", agentUrl);
|
|
2444
|
-
console.log("[ChatPanel] User data being sent:");
|
|
2445
|
-
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2446
|
-
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2447
|
-
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2448
|
-
console.log("[ChatPanel] org_id:", orgId);
|
|
2449
|
-
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2450
2433
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
2451
2434
|
method: "POST",
|
|
2452
2435
|
headers: {
|
|
@@ -2663,7 +2646,6 @@ function ChatPanel({
|
|
|
2663
2646
|
setMessages((prev) => [...prev, escalationMessage]);
|
|
2664
2647
|
} else if (eventType === "tool_request") {
|
|
2665
2648
|
const toolRequest = data;
|
|
2666
|
-
console.log("[KiteChat] Received tool_request:", toolRequest);
|
|
2667
2649
|
executeToolRequest(toolRequest).catch((err) => {
|
|
2668
2650
|
console.error("[KiteChat] Tool execution failed:", err);
|
|
2669
2651
|
});
|
|
@@ -2981,11 +2963,6 @@ ${userText}`
|
|
|
2981
2963
|
}
|
|
2982
2964
|
});
|
|
2983
2965
|
} else if (eventType === "summary") {
|
|
2984
|
-
console.log("[DEBUG] Received summary event - data:", data);
|
|
2985
|
-
console.log(
|
|
2986
|
-
"[DEBUG] navigationPage from backend:",
|
|
2987
|
-
data.navigationPage
|
|
2988
|
-
);
|
|
2989
2966
|
setPhase("idle");
|
|
2990
2967
|
setProgressSteps([]);
|
|
2991
2968
|
setPendingBulkSession(null);
|
|
@@ -3005,7 +2982,6 @@ ${userText}`
|
|
|
3005
2982
|
navigationPage: data.navigationPage
|
|
3006
2983
|
}
|
|
3007
2984
|
};
|
|
3008
|
-
console.log("[DEBUG] Creating bulkSummary message:", newMsg);
|
|
3009
2985
|
return [...filtered, newMsg];
|
|
3010
2986
|
});
|
|
3011
2987
|
setTimeout(() => {
|
|
@@ -4576,28 +4552,11 @@ ${userText}`
|
|
|
4576
4552
|
onClick: (e) => {
|
|
4577
4553
|
e.preventDefault();
|
|
4578
4554
|
e.stopPropagation();
|
|
4579
|
-
console.log(
|
|
4580
|
-
"[DEBUG] Button clicked - navigationPage:",
|
|
4581
|
-
navigationPage,
|
|
4582
|
-
"onNavigate:",
|
|
4583
|
-
!!onNavigate
|
|
4584
|
-
);
|
|
4585
4555
|
if (onNavigate && navigationPage.page) {
|
|
4586
|
-
console.log(
|
|
4587
|
-
"[DEBUG] Calling onNavigate with page:",
|
|
4588
|
-
navigationPage.page
|
|
4589
|
-
);
|
|
4590
4556
|
onNavigate(
|
|
4591
4557
|
navigationPage.page,
|
|
4592
4558
|
navigationPage.subtab
|
|
4593
4559
|
);
|
|
4594
|
-
} else {
|
|
4595
|
-
console.log(
|
|
4596
|
-
"[DEBUG] Condition failed - onNavigate:",
|
|
4597
|
-
!!onNavigate,
|
|
4598
|
-
"navigationPage.page:",
|
|
4599
|
-
navigationPage.page
|
|
4600
|
-
);
|
|
4601
4560
|
}
|
|
4602
4561
|
},
|
|
4603
4562
|
className: "flex items-center gap-2 text-xs text-gray-500 hover:text-gray-700 transition-colors group cursor-pointer",
|
|
@@ -4877,7 +4836,8 @@ function ChatPanelWithToggle({
|
|
|
4877
4836
|
supabaseAnonKey,
|
|
4878
4837
|
initialCorner,
|
|
4879
4838
|
onCornerChange,
|
|
4880
|
-
productBackendUrl
|
|
4839
|
+
productBackendUrl,
|
|
4840
|
+
getAuthHeaders
|
|
4881
4841
|
}) {
|
|
4882
4842
|
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
4883
4843
|
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
@@ -4907,7 +4867,8 @@ function ChatPanelWithToggle({
|
|
|
4907
4867
|
supabaseAnonKey,
|
|
4908
4868
|
initialCorner,
|
|
4909
4869
|
onCornerChange,
|
|
4910
|
-
productBackendUrl
|
|
4870
|
+
productBackendUrl,
|
|
4871
|
+
getAuthHeaders
|
|
4911
4872
|
}
|
|
4912
4873
|
);
|
|
4913
4874
|
}
|
|
@@ -4979,7 +4940,8 @@ function KiteChatWrapper({
|
|
|
4979
4940
|
userEmail: config.userEmail,
|
|
4980
4941
|
supabaseUrl: config.supabaseUrl,
|
|
4981
4942
|
supabaseAnonKey: config.supabaseAnonKey,
|
|
4982
|
-
productBackendUrl: config.productBackendUrl
|
|
4943
|
+
productBackendUrl: config.productBackendUrl,
|
|
4944
|
+
getAuthHeaders: config.getAuthHeaders
|
|
4983
4945
|
}
|
|
4984
4946
|
);
|
|
4985
4947
|
}
|
|
@@ -5022,7 +4984,6 @@ function createKiteChat(config) {
|
|
|
5022
4984
|
}
|
|
5023
4985
|
)
|
|
5024
4986
|
);
|
|
5025
|
-
console.log("[KiteChat] Mounted");
|
|
5026
4987
|
},
|
|
5027
4988
|
unmount() {
|
|
5028
4989
|
if (!root) {
|
|
@@ -5034,7 +4995,6 @@ function createKiteChat(config) {
|
|
|
5034
4995
|
containerElement = null;
|
|
5035
4996
|
configUpdater = null;
|
|
5036
4997
|
stateUpdaters = null;
|
|
5037
|
-
console.log("[KiteChat] Unmounted");
|
|
5038
4998
|
},
|
|
5039
4999
|
open() {
|
|
5040
5000
|
stateUpdaters?.setIsOpen(true);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { i as ActionData, A as ActionType, C as ChatPanel, d as ChatPanelProps, b as ChatPanelWithToggle, e as ChatPanelWithToggleProps, H as HelpButton, g as HelpButtonProps, K as KiteChatConfig, a as KiteChatInstance, N as NavigationTarget, h as Page, k as PanelCorner, P as PanelToggle, f as PanelToggleProps, S as SettingsTab, j as StartingQuestion, c as createKiteChat } from './createKiteChat-
|
|
1
|
+
export { i as ActionData, A as ActionType, C as ChatPanel, d as ChatPanelProps, b as ChatPanelWithToggle, e as ChatPanelWithToggleProps, H as HelpButton, g as HelpButtonProps, K as KiteChatConfig, a as KiteChatInstance, N as NavigationTarget, h as Page, k as PanelCorner, P as PanelToggle, f as PanelToggleProps, S as SettingsTab, j as StartingQuestion, c as createKiteChat } from './createKiteChat-DeQKgFyx.cjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import * as React from 'react';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { i as ActionData, A as ActionType, C as ChatPanel, d as ChatPanelProps, b as ChatPanelWithToggle, e as ChatPanelWithToggleProps, H as HelpButton, g as HelpButtonProps, K as KiteChatConfig, a as KiteChatInstance, N as NavigationTarget, h as Page, k as PanelCorner, P as PanelToggle, f as PanelToggleProps, S as SettingsTab, j as StartingQuestion, c as createKiteChat } from './createKiteChat-
|
|
1
|
+
export { i as ActionData, A as ActionType, C as ChatPanel, d as ChatPanelProps, b as ChatPanelWithToggle, e as ChatPanelWithToggleProps, H as HelpButton, g as HelpButtonProps, K as KiteChatConfig, a as KiteChatInstance, N as NavigationTarget, h as Page, k as PanelCorner, P as PanelToggle, f as PanelToggleProps, S as SettingsTab, j as StartingQuestion, c as createKiteChat } from './createKiteChat-DeQKgFyx.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import * as React from 'react';
|
package/dist/index.js
CHANGED