@kite-copilot/chat-panel 0.2.42 → 0.2.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto.cjs +167 -69
- package/dist/auto.js +1 -1
- package/dist/{chunk-XP6Y7EP7.js → chunk-G74XTXWW.js} +175 -77
- package/dist/embed.global.js +20 -20
- package/dist/index.cjs +167 -69
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -882,7 +882,7 @@ function DataRenderer({ type, data }) {
|
|
|
882
882
|
}
|
|
883
883
|
|
|
884
884
|
// src/ChatPanel.tsx
|
|
885
|
-
import * as
|
|
885
|
+
import * as React6 from "react";
|
|
886
886
|
import { createClient } from "@supabase/supabase-js";
|
|
887
887
|
import { ArrowLeft, ArrowUp, Command, CornerDownLeft, CheckCircle2 as CheckCircle23, SquarePen, Paperclip, X, FileSpreadsheet, Loader2 as Loader22, ChevronLeft, ChevronRight, Sparkles, Minus } from "lucide-react";
|
|
888
888
|
|
|
@@ -897,9 +897,13 @@ function useUserAuth({
|
|
|
897
897
|
const lastSessionIdRef = React4.useRef(null);
|
|
898
898
|
const fetchUser = React4.useCallback(async () => {
|
|
899
899
|
if (!productBackendUrl || !enabled) {
|
|
900
|
+
console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
|
|
900
901
|
setAuthState({ status: "idle" });
|
|
901
902
|
return;
|
|
902
903
|
}
|
|
904
|
+
console.log("[useUserAuth] Starting auth request to product backend...");
|
|
905
|
+
console.log("[useUserAuth] Product backend URL:", productBackendUrl);
|
|
906
|
+
console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
|
|
903
907
|
setAuthState({ status: "loading" });
|
|
904
908
|
try {
|
|
905
909
|
const response = await fetch(`${productBackendUrl}/users/me`, {
|
|
@@ -910,7 +914,9 @@ function useUserAuth({
|
|
|
910
914
|
"Accept": "application/json"
|
|
911
915
|
}
|
|
912
916
|
});
|
|
917
|
+
console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
|
|
913
918
|
if (!response.ok) {
|
|
919
|
+
console.log("[useUserAuth] Auth request failed with status:", response.status);
|
|
914
920
|
if (response.status === 401) {
|
|
915
921
|
throw new Error("Please log in to use the chat assistant.");
|
|
916
922
|
}
|
|
@@ -920,8 +926,17 @@ function useUserAuth({
|
|
|
920
926
|
throw new Error(`Authentication failed (${response.status})`);
|
|
921
927
|
}
|
|
922
928
|
const user = await response.json();
|
|
929
|
+
console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
|
|
930
|
+
console.log("[useUserAuth] id:", user.id);
|
|
931
|
+
console.log("[useUserAuth] email:", user.email);
|
|
932
|
+
console.log("[useUserAuth] name:", user.name);
|
|
933
|
+
console.log("[useUserAuth] role:", user.role);
|
|
934
|
+
console.log("[useUserAuth] isInternal:", user.isInternal);
|
|
935
|
+
console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
|
|
936
|
+
console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
|
|
923
937
|
setAuthState({ status: "authenticated", user });
|
|
924
938
|
} catch (error) {
|
|
939
|
+
console.log("[useUserAuth] Auth ERROR:", error);
|
|
925
940
|
const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
|
|
926
941
|
setAuthState({ status: "error", error: message });
|
|
927
942
|
}
|
|
@@ -938,6 +953,47 @@ function useUserAuth({
|
|
|
938
953
|
return { authState, retry };
|
|
939
954
|
}
|
|
940
955
|
|
|
956
|
+
// src/hooks/useOrgConfig.ts
|
|
957
|
+
import * as React5 from "react";
|
|
958
|
+
function useOrgConfig({ agentUrl, orgId }) {
|
|
959
|
+
const [state, setState] = React5.useState({
|
|
960
|
+
status: "idle",
|
|
961
|
+
config: null,
|
|
962
|
+
error: null
|
|
963
|
+
});
|
|
964
|
+
React5.useEffect(() => {
|
|
965
|
+
if (!agentUrl || !orgId) {
|
|
966
|
+
console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
const fetchConfig = async () => {
|
|
970
|
+
setState({ status: "loading", config: null, error: null });
|
|
971
|
+
const url = `${agentUrl}/org/${orgId}/config`;
|
|
972
|
+
console.log("[useOrgConfig] Fetching org config from:", url);
|
|
973
|
+
try {
|
|
974
|
+
const response = await fetch(url, {
|
|
975
|
+
method: "GET",
|
|
976
|
+
headers: {
|
|
977
|
+
"Accept": "application/json"
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
if (!response.ok) {
|
|
981
|
+
throw new Error(`Failed to fetch org config (${response.status})`);
|
|
982
|
+
}
|
|
983
|
+
const config = await response.json();
|
|
984
|
+
console.log("[useOrgConfig] Received config:", config);
|
|
985
|
+
setState({ status: "success", config, error: null });
|
|
986
|
+
} catch (error) {
|
|
987
|
+
const message = error instanceof Error ? error.message : "Failed to fetch org config";
|
|
988
|
+
console.error("[useOrgConfig] Error:", message);
|
|
989
|
+
setState({ status: "error", config: null, error: message });
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
fetchConfig();
|
|
993
|
+
}, [agentUrl, orgId]);
|
|
994
|
+
return state;
|
|
995
|
+
}
|
|
996
|
+
|
|
941
997
|
// src/components/TypingIndicator.tsx
|
|
942
998
|
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
943
999
|
function TypingIndicator({ className = "" }) {
|
|
@@ -968,7 +1024,7 @@ function TypingIndicator({ className = "" }) {
|
|
|
968
1024
|
|
|
969
1025
|
// src/ChatPanel.tsx
|
|
970
1026
|
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
971
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
1027
|
+
var CHAT_PANEL_VERSION = true ? "0.2.44" : "dev";
|
|
972
1028
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
973
1029
|
var PANEL_WIDTH = 340;
|
|
974
1030
|
function unescapeJsonString(str) {
|
|
@@ -1432,16 +1488,18 @@ function ChatPanel({
|
|
|
1432
1488
|
supabaseAnonKey,
|
|
1433
1489
|
productBackendUrl
|
|
1434
1490
|
} = {}) {
|
|
1435
|
-
const [messages, setMessages] =
|
|
1436
|
-
const [input, setInput] =
|
|
1437
|
-
const [sessionId, setSessionId] =
|
|
1491
|
+
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1492
|
+
const [input, setInput] = React6.useState("");
|
|
1493
|
+
const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
|
|
1494
|
+
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1495
|
+
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
1438
1496
|
const { authState, retry: retryAuth } = useUserAuth({
|
|
1439
|
-
productBackendUrl,
|
|
1497
|
+
productBackendUrl: effectiveProductBackendUrl,
|
|
1440
1498
|
sessionId,
|
|
1441
|
-
enabled: !!
|
|
1442
|
-
// Only enable
|
|
1499
|
+
enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
|
|
1500
|
+
// Only enable after config is fetched
|
|
1443
1501
|
});
|
|
1444
|
-
const effectiveUser =
|
|
1502
|
+
const effectiveUser = React6.useMemo(() => {
|
|
1445
1503
|
if (authState.status === "authenticated") {
|
|
1446
1504
|
return {
|
|
1447
1505
|
userId: authState.user.id,
|
|
@@ -1459,16 +1517,16 @@ function ChatPanel({
|
|
|
1459
1517
|
isInternal: false
|
|
1460
1518
|
};
|
|
1461
1519
|
}, [authState, userId, userName, userEmail]);
|
|
1462
|
-
const [isEscalated, setIsEscalated] =
|
|
1463
|
-
const escalationWsRef =
|
|
1464
|
-
const [agentIsTyping, setAgentIsTyping] =
|
|
1465
|
-
const supabaseRef =
|
|
1466
|
-
const typingChannelRef =
|
|
1467
|
-
const typingTimeoutRef =
|
|
1468
|
-
|
|
1520
|
+
const [isEscalated, setIsEscalated] = React6.useState(false);
|
|
1521
|
+
const escalationWsRef = React6.useRef(null);
|
|
1522
|
+
const [agentIsTyping, setAgentIsTyping] = React6.useState(false);
|
|
1523
|
+
const supabaseRef = React6.useRef(null);
|
|
1524
|
+
const typingChannelRef = React6.useRef(null);
|
|
1525
|
+
const typingTimeoutRef = React6.useRef(null);
|
|
1526
|
+
React6.useEffect(() => {
|
|
1469
1527
|
console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
|
|
1470
1528
|
}, []);
|
|
1471
|
-
const resetSession =
|
|
1529
|
+
const resetSession = React6.useCallback(() => {
|
|
1472
1530
|
console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
|
|
1473
1531
|
if (isEscalated && supabaseRef.current && sessionId) {
|
|
1474
1532
|
console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
|
|
@@ -1498,12 +1556,12 @@ function ChatPanel({
|
|
|
1498
1556
|
typingChannelRef.current = null;
|
|
1499
1557
|
}
|
|
1500
1558
|
}, [isEscalated, sessionId]);
|
|
1501
|
-
|
|
1559
|
+
React6.useEffect(() => {
|
|
1502
1560
|
if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
|
|
1503
1561
|
supabaseRef.current = createClient(supabaseUrl, supabaseAnonKey);
|
|
1504
1562
|
}
|
|
1505
1563
|
}, [supabaseUrl, supabaseAnonKey]);
|
|
1506
|
-
|
|
1564
|
+
React6.useEffect(() => {
|
|
1507
1565
|
if (!isEscalated || !sessionId || !supabaseRef.current) {
|
|
1508
1566
|
return;
|
|
1509
1567
|
}
|
|
@@ -1540,8 +1598,8 @@ function ChatPanel({
|
|
|
1540
1598
|
}
|
|
1541
1599
|
};
|
|
1542
1600
|
}, [isEscalated, sessionId]);
|
|
1543
|
-
const heartbeatIntervalRef =
|
|
1544
|
-
const updateCustomerStatus =
|
|
1601
|
+
const heartbeatIntervalRef = React6.useRef(null);
|
|
1602
|
+
const updateCustomerStatus = React6.useCallback(async (status) => {
|
|
1545
1603
|
if (!supabaseRef.current || !sessionId) return;
|
|
1546
1604
|
try {
|
|
1547
1605
|
await supabaseRef.current.from("escalations").update({
|
|
@@ -1552,7 +1610,7 @@ function ChatPanel({
|
|
|
1552
1610
|
console.error("[KiteChat] Failed to update customer status:", err);
|
|
1553
1611
|
}
|
|
1554
1612
|
}, [sessionId]);
|
|
1555
|
-
|
|
1613
|
+
React6.useEffect(() => {
|
|
1556
1614
|
if (!isEscalated || !sessionId || !supabaseRef.current) {
|
|
1557
1615
|
return;
|
|
1558
1616
|
}
|
|
@@ -1600,7 +1658,7 @@ function ChatPanel({
|
|
|
1600
1658
|
}
|
|
1601
1659
|
};
|
|
1602
1660
|
}, [isEscalated, sessionId, updateCustomerStatus]);
|
|
1603
|
-
const sendTypingIndicator =
|
|
1661
|
+
const sendTypingIndicator = React6.useCallback((isTyping) => {
|
|
1604
1662
|
if (!typingChannelRef.current) {
|
|
1605
1663
|
console.log("[KiteChat] Cannot send typing - channel not ready");
|
|
1606
1664
|
return;
|
|
@@ -1616,8 +1674,8 @@ function ChatPanel({
|
|
|
1616
1674
|
payload: { sender: "user", isTyping }
|
|
1617
1675
|
});
|
|
1618
1676
|
}, [isEscalated]);
|
|
1619
|
-
const userTypingTimeoutRef =
|
|
1620
|
-
const handleTypingStart =
|
|
1677
|
+
const userTypingTimeoutRef = React6.useRef(null);
|
|
1678
|
+
const handleTypingStart = React6.useCallback(() => {
|
|
1621
1679
|
if (!isEscalated || !supabaseRef.current) return;
|
|
1622
1680
|
sendTypingIndicator(true);
|
|
1623
1681
|
updateCustomerStatus("active");
|
|
@@ -1628,19 +1686,19 @@ function ChatPanel({
|
|
|
1628
1686
|
sendTypingIndicator(false);
|
|
1629
1687
|
}, 1500);
|
|
1630
1688
|
}, [isEscalated, sendTypingIndicator, updateCustomerStatus]);
|
|
1631
|
-
const streamIntervals =
|
|
1689
|
+
const streamIntervals = React6.useRef({});
|
|
1632
1690
|
const isEmpty = messages.length === 0;
|
|
1633
|
-
const [phase, setPhase] =
|
|
1634
|
-
const [progressSteps, setProgressSteps] =
|
|
1635
|
-
const phaseTimers =
|
|
1691
|
+
const [phase, setPhase] = React6.useState("idle");
|
|
1692
|
+
const [progressSteps, setProgressSteps] = React6.useState([]);
|
|
1693
|
+
const phaseTimers = React6.useRef([]);
|
|
1636
1694
|
const lastRole = messages.length ? messages[messages.length - 1].role : void 0;
|
|
1637
|
-
const [panelView, setPanelView] =
|
|
1695
|
+
const [panelView, setPanelView] = React6.useState(
|
|
1638
1696
|
"landing"
|
|
1639
1697
|
);
|
|
1640
|
-
const [currentFolderId, setCurrentFolderId] =
|
|
1641
|
-
const [startingQuestions, setStartingQuestions] =
|
|
1642
|
-
const [loadingQuestions, setLoadingQuestions] =
|
|
1643
|
-
|
|
1698
|
+
const [currentFolderId, setCurrentFolderId] = React6.useState(void 0);
|
|
1699
|
+
const [startingQuestions, setStartingQuestions] = React6.useState(startingQuestionsProp || defaultStartingQuestions);
|
|
1700
|
+
const [loadingQuestions, setLoadingQuestions] = React6.useState(false);
|
|
1701
|
+
React6.useEffect(() => {
|
|
1644
1702
|
if (startingQuestionsEndpoint && !startingQuestionsProp) {
|
|
1645
1703
|
setLoadingQuestions(true);
|
|
1646
1704
|
fetch(startingQuestionsEndpoint).then((res) => res.json()).then((data) => {
|
|
@@ -1652,16 +1710,16 @@ function ChatPanel({
|
|
|
1652
1710
|
}).finally(() => setLoadingQuestions(false));
|
|
1653
1711
|
}
|
|
1654
1712
|
}, [startingQuestionsEndpoint, startingQuestionsProp]);
|
|
1655
|
-
|
|
1713
|
+
React6.useEffect(() => {
|
|
1656
1714
|
if (startingQuestionsProp) {
|
|
1657
1715
|
setStartingQuestions(startingQuestionsProp);
|
|
1658
1716
|
}
|
|
1659
1717
|
}, [startingQuestionsProp]);
|
|
1660
|
-
const [activeGuide, setActiveGuide] =
|
|
1661
|
-
const activeGuideRef =
|
|
1662
|
-
const latestBulkSummaryNavigationRef =
|
|
1663
|
-
const [guideComplete, setGuideComplete] =
|
|
1664
|
-
|
|
1718
|
+
const [activeGuide, setActiveGuide] = React6.useState(void 0);
|
|
1719
|
+
const activeGuideRef = React6.useRef(void 0);
|
|
1720
|
+
const latestBulkSummaryNavigationRef = React6.useRef(null);
|
|
1721
|
+
const [guideComplete, setGuideComplete] = React6.useState(false);
|
|
1722
|
+
React6.useEffect(() => {
|
|
1665
1723
|
window.resetIntegrationNotification = () => {
|
|
1666
1724
|
localStorage.removeItem("gmailNotificationSeen");
|
|
1667
1725
|
console.log(
|
|
@@ -1695,7 +1753,7 @@ function ChatPanel({
|
|
|
1695
1753
|
);
|
|
1696
1754
|
};
|
|
1697
1755
|
}, []);
|
|
1698
|
-
|
|
1756
|
+
React6.useEffect(() => {
|
|
1699
1757
|
if (activeGuide) {
|
|
1700
1758
|
if (!activeGuideRef.current || activeGuideRef.current.id !== activeGuide.id || activeGuideRef.current.stepIndex !== activeGuide.stepIndex) {
|
|
1701
1759
|
activeGuideRef.current = activeGuide;
|
|
@@ -1704,21 +1762,21 @@ function ChatPanel({
|
|
|
1704
1762
|
activeGuideRef.current = void 0;
|
|
1705
1763
|
}
|
|
1706
1764
|
}, [activeGuide]);
|
|
1707
|
-
const [pendingNavigation, setPendingNavigation] =
|
|
1708
|
-
const [pendingAction, setPendingAction] =
|
|
1709
|
-
const [actionFormData, setActionFormData] =
|
|
1710
|
-
const messagesEndRef =
|
|
1711
|
-
const messagesContainerRef =
|
|
1712
|
-
const currentStepRef =
|
|
1765
|
+
const [pendingNavigation, setPendingNavigation] = React6.useState(null);
|
|
1766
|
+
const [pendingAction, setPendingAction] = React6.useState(null);
|
|
1767
|
+
const [actionFormData, setActionFormData] = React6.useState({});
|
|
1768
|
+
const messagesEndRef = React6.useRef(null);
|
|
1769
|
+
const messagesContainerRef = React6.useRef(null);
|
|
1770
|
+
const currentStepRef = React6.useRef(null);
|
|
1713
1771
|
const { cursorState, moveTo, hide } = useGuideCursor();
|
|
1714
|
-
const [pendingFile, setPendingFile] =
|
|
1715
|
-
const [pendingBulkSession, setPendingBulkSession] =
|
|
1716
|
-
const pendingBulkSessionRef =
|
|
1717
|
-
const fileInputRef =
|
|
1718
|
-
const [searchExpanded, setSearchExpanded] =
|
|
1719
|
-
const [searchInput, setSearchInput] =
|
|
1720
|
-
const searchInputRef =
|
|
1721
|
-
|
|
1772
|
+
const [pendingFile, setPendingFile] = React6.useState(null);
|
|
1773
|
+
const [pendingBulkSession, setPendingBulkSession] = React6.useState(null);
|
|
1774
|
+
const pendingBulkSessionRef = React6.useRef(null);
|
|
1775
|
+
const fileInputRef = React6.useRef(null);
|
|
1776
|
+
const [searchExpanded, setSearchExpanded] = React6.useState(false);
|
|
1777
|
+
const [searchInput, setSearchInput] = React6.useState("");
|
|
1778
|
+
const searchInputRef = React6.useRef(null);
|
|
1779
|
+
React6.useEffect(() => {
|
|
1722
1780
|
if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
|
|
1723
1781
|
return;
|
|
1724
1782
|
}
|
|
@@ -1744,7 +1802,7 @@ function ChatPanel({
|
|
|
1744
1802
|
const interval = setInterval(checkForDialogOpen, 300);
|
|
1745
1803
|
return () => clearInterval(interval);
|
|
1746
1804
|
}, [activeGuide, hide]);
|
|
1747
|
-
|
|
1805
|
+
React6.useEffect(() => {
|
|
1748
1806
|
return () => {
|
|
1749
1807
|
Object.values(streamIntervals.current).forEach(
|
|
1750
1808
|
(id) => window.clearInterval(id)
|
|
@@ -1754,7 +1812,7 @@ function ChatPanel({
|
|
|
1754
1812
|
phaseTimers.current = [];
|
|
1755
1813
|
};
|
|
1756
1814
|
}, []);
|
|
1757
|
-
|
|
1815
|
+
React6.useEffect(() => {
|
|
1758
1816
|
if (activeGuide && messages.length > 0) {
|
|
1759
1817
|
const lastMessage = messages[messages.length - 1];
|
|
1760
1818
|
if (lastMessage.kind === "guideStep" || lastMessage.kind === "guideComplete") {
|
|
@@ -1771,7 +1829,7 @@ function ChatPanel({
|
|
|
1771
1829
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1772
1830
|
}
|
|
1773
1831
|
}, [messages, phase, activeGuide]);
|
|
1774
|
-
const latestBulkSummaryNavigation =
|
|
1832
|
+
const latestBulkSummaryNavigation = React6.useMemo(() => {
|
|
1775
1833
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1776
1834
|
const msg = messages[i];
|
|
1777
1835
|
if (msg.kind === "bulkSummary" && msg.bulkSummary?.navigationPage && msg.bulkSummary.successes > 0) {
|
|
@@ -1780,13 +1838,13 @@ function ChatPanel({
|
|
|
1780
1838
|
}
|
|
1781
1839
|
return null;
|
|
1782
1840
|
}, [messages]);
|
|
1783
|
-
|
|
1841
|
+
React6.useEffect(() => {
|
|
1784
1842
|
latestBulkSummaryNavigationRef.current = latestBulkSummaryNavigation;
|
|
1785
1843
|
}, [latestBulkSummaryNavigation]);
|
|
1786
|
-
|
|
1844
|
+
React6.useEffect(() => {
|
|
1787
1845
|
pendingBulkSessionRef.current = pendingBulkSession;
|
|
1788
1846
|
}, [pendingBulkSession]);
|
|
1789
|
-
|
|
1847
|
+
React6.useEffect(() => {
|
|
1790
1848
|
const handleKeyDown = (e) => {
|
|
1791
1849
|
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
1792
1850
|
const currentBulkSession = pendingBulkSessionRef.current;
|
|
@@ -1849,7 +1907,7 @@ function ChatPanel({
|
|
|
1849
1907
|
guideComplete,
|
|
1850
1908
|
onNavigate
|
|
1851
1909
|
]);
|
|
1852
|
-
const connectToEscalationWs =
|
|
1910
|
+
const connectToEscalationWs = React6.useCallback((currentSessionId) => {
|
|
1853
1911
|
if (!agentUrl) return;
|
|
1854
1912
|
if (escalationWsRef.current) {
|
|
1855
1913
|
escalationWsRef.current.close();
|
|
@@ -1892,7 +1950,7 @@ function ChatPanel({
|
|
|
1892
1950
|
};
|
|
1893
1951
|
escalationWsRef.current = ws;
|
|
1894
1952
|
}, [agentUrl]);
|
|
1895
|
-
const sendEscalatedMessage =
|
|
1953
|
+
const sendEscalatedMessage = React6.useCallback(async (content) => {
|
|
1896
1954
|
if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
|
|
1897
1955
|
console.error("[KiteChat] Escalation WebSocket not connected");
|
|
1898
1956
|
return false;
|
|
@@ -1909,14 +1967,14 @@ function ChatPanel({
|
|
|
1909
1967
|
return false;
|
|
1910
1968
|
}
|
|
1911
1969
|
}, [updateCustomerStatus]);
|
|
1912
|
-
|
|
1970
|
+
React6.useEffect(() => {
|
|
1913
1971
|
return () => {
|
|
1914
1972
|
if (escalationWsRef.current) {
|
|
1915
1973
|
escalationWsRef.current.close();
|
|
1916
1974
|
}
|
|
1917
1975
|
};
|
|
1918
1976
|
}, []);
|
|
1919
|
-
|
|
1977
|
+
React6.useEffect(() => {
|
|
1920
1978
|
if (isEscalated && sessionId) {
|
|
1921
1979
|
connectToEscalationWs(sessionId);
|
|
1922
1980
|
}
|
|
@@ -2182,6 +2240,15 @@ function ChatPanel({
|
|
|
2182
2240
|
try {
|
|
2183
2241
|
const controller = new AbortController();
|
|
2184
2242
|
const timeoutId = setTimeout(() => controller.abort(), 6e4);
|
|
2243
|
+
console.log("[ChatPanel] Sending chat request to agent backend...");
|
|
2244
|
+
console.log("[ChatPanel] Agent URL:", agentUrl);
|
|
2245
|
+
console.log("[ChatPanel] User data being sent:");
|
|
2246
|
+
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2247
|
+
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2248
|
+
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2249
|
+
console.log("[ChatPanel] user_organization:", userOrganization);
|
|
2250
|
+
console.log("[ChatPanel] org_id:", orgId);
|
|
2251
|
+
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2185
2252
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
2186
2253
|
method: "POST",
|
|
2187
2254
|
headers: {
|
|
@@ -3136,7 +3203,38 @@ ${userText}`
|
|
|
3136
3203
|
] })
|
|
3137
3204
|
] }) }) });
|
|
3138
3205
|
}
|
|
3139
|
-
if (
|
|
3206
|
+
if (orgConfigState.status === "loading") {
|
|
3207
|
+
return /* @__PURE__ */ jsxs6(
|
|
3208
|
+
"section",
|
|
3209
|
+
{
|
|
3210
|
+
className: `fixed top-0 right-0 z-40 flex flex-col bg-white border-l border-gray-200 h-full overflow-hidden transition-transform duration-300 ${isOpen ? "translate-x-0" : "translate-x-full"}`,
|
|
3211
|
+
style: { width: `${PANEL_WIDTH}px` },
|
|
3212
|
+
children: [
|
|
3213
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100 bg-gradient-to-r from-gray-50 to-white shrink-0", children: [
|
|
3214
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2.5", children: [
|
|
3215
|
+
/* @__PURE__ */ jsx10(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
|
|
3216
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
|
|
3217
|
+
] }),
|
|
3218
|
+
/* @__PURE__ */ jsx10(
|
|
3219
|
+
Button,
|
|
3220
|
+
{
|
|
3221
|
+
variant: "ghost",
|
|
3222
|
+
size: "sm",
|
|
3223
|
+
className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
|
|
3224
|
+
onClick: () => onClose?.(),
|
|
3225
|
+
children: /* @__PURE__ */ jsx10(X, { className: "h-4 w-4" })
|
|
3226
|
+
}
|
|
3227
|
+
)
|
|
3228
|
+
] }),
|
|
3229
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs6("div", { className: "text-center", children: [
|
|
3230
|
+
/* @__PURE__ */ jsx10(Loader22, { className: "h-8 w-8 animate-spin text-gray-400 mx-auto mb-3" }),
|
|
3231
|
+
/* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-500", children: "Loading..." })
|
|
3232
|
+
] }) })
|
|
3233
|
+
]
|
|
3234
|
+
}
|
|
3235
|
+
);
|
|
3236
|
+
}
|
|
3237
|
+
if (effectiveProductBackendUrl) {
|
|
3140
3238
|
if (authState.status === "loading") {
|
|
3141
3239
|
return /* @__PURE__ */ jsxs6(
|
|
3142
3240
|
"section",
|
|
@@ -4311,7 +4409,7 @@ ${userText}`
|
|
|
4311
4409
|
message.id
|
|
4312
4410
|
);
|
|
4313
4411
|
}
|
|
4314
|
-
return /* @__PURE__ */ jsx10(
|
|
4412
|
+
return /* @__PURE__ */ jsx10(React6.Fragment, { children: /* @__PURE__ */ jsxs6(
|
|
4315
4413
|
"div",
|
|
4316
4414
|
{
|
|
4317
4415
|
ref: isCurrentGuideStep ? currentStepRef : null,
|
|
@@ -4568,7 +4666,7 @@ function ChatPanelWithToggle({
|
|
|
4568
4666
|
supabaseAnonKey,
|
|
4569
4667
|
productBackendUrl
|
|
4570
4668
|
}) {
|
|
4571
|
-
const [internalIsOpen, setInternalIsOpen] =
|
|
4669
|
+
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
4572
4670
|
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
4573
4671
|
const setIsOpen = (open) => {
|
|
4574
4672
|
if (controlledIsOpen === void 0) {
|
|
@@ -4576,7 +4674,7 @@ function ChatPanelWithToggle({
|
|
|
4576
4674
|
}
|
|
4577
4675
|
onOpenChange?.(open);
|
|
4578
4676
|
};
|
|
4579
|
-
|
|
4677
|
+
React6.useEffect(() => {
|
|
4580
4678
|
const originalPadding = document.body.style.paddingRight;
|
|
4581
4679
|
const originalTransition = document.body.style.transition;
|
|
4582
4680
|
document.body.style.transition = "padding-right 0.3s ease";
|
|
@@ -4623,7 +4721,7 @@ function HelpButton({ onClick, className = "" }) {
|
|
|
4623
4721
|
}
|
|
4624
4722
|
|
|
4625
4723
|
// src/createKiteChat.tsx
|
|
4626
|
-
import
|
|
4724
|
+
import React7 from "react";
|
|
4627
4725
|
import { createRoot } from "react-dom/client";
|
|
4628
4726
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
4629
4727
|
function KiteChatWrapper({
|
|
@@ -4631,14 +4729,14 @@ function KiteChatWrapper({
|
|
|
4631
4729
|
onConfigUpdate,
|
|
4632
4730
|
onStateUpdate
|
|
4633
4731
|
}) {
|
|
4634
|
-
const [config, setConfig] =
|
|
4635
|
-
const [currentPage, setCurrentPage] =
|
|
4636
|
-
const [isOpen, setIsOpen] =
|
|
4637
|
-
const isOpenRef =
|
|
4638
|
-
|
|
4732
|
+
const [config, setConfig] = React7.useState(initialConfig);
|
|
4733
|
+
const [currentPage, setCurrentPage] = React7.useState(initialConfig.currentPage || "dashboard");
|
|
4734
|
+
const [isOpen, setIsOpen] = React7.useState(false);
|
|
4735
|
+
const isOpenRef = React7.useRef(false);
|
|
4736
|
+
React7.useEffect(() => {
|
|
4639
4737
|
isOpenRef.current = isOpen;
|
|
4640
4738
|
}, [isOpen]);
|
|
4641
|
-
|
|
4739
|
+
React7.useEffect(() => {
|
|
4642
4740
|
onConfigUpdate((newConfig) => {
|
|
4643
4741
|
if (newConfig.currentPage !== void 0) {
|
|
4644
4742
|
setCurrentPage(newConfig.currentPage);
|
|
@@ -4650,7 +4748,7 @@ function KiteChatWrapper({
|
|
|
4650
4748
|
getIsOpen: () => isOpenRef.current
|
|
4651
4749
|
});
|
|
4652
4750
|
}, [onConfigUpdate, onStateUpdate]);
|
|
4653
|
-
|
|
4751
|
+
React7.useEffect(() => {
|
|
4654
4752
|
const container = document.getElementById("kite-chat-root");
|
|
4655
4753
|
if (!container) return;
|
|
4656
4754
|
if (config.theme === "dark") {
|