@kite-copilot/chat-panel 0.2.39 → 0.2.42
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 +235 -71
- package/dist/auto.d.cts +1 -1
- package/dist/auto.d.ts +1 -1
- package/dist/auto.js +1 -1
- package/dist/{chunk-D4Z7O3Y7.js → chunk-XP6Y7EP7.js} +243 -79
- package/dist/{createKiteChat-jmAPjuv_.d.cts → createKiteChat-o5u-5Sor.d.cts} +8 -2
- package/dist/{createKiteChat-jmAPjuv_.d.ts → createKiteChat-o5u-5Sor.d.ts} +8 -2
- package/dist/embed.global.js +24 -59
- package/dist/index.cjs +235 -71
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
|
@@ -882,10 +882,62 @@ function DataRenderer({ type, data }) {
|
|
|
882
882
|
}
|
|
883
883
|
|
|
884
884
|
// src/ChatPanel.tsx
|
|
885
|
-
import * as
|
|
885
|
+
import * as React5 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
|
|
|
889
|
+
// src/hooks/useUserAuth.ts
|
|
890
|
+
import * as React4 from "react";
|
|
891
|
+
function useUserAuth({
|
|
892
|
+
productBackendUrl,
|
|
893
|
+
sessionId,
|
|
894
|
+
enabled = true
|
|
895
|
+
}) {
|
|
896
|
+
const [authState, setAuthState] = React4.useState({ status: "idle" });
|
|
897
|
+
const lastSessionIdRef = React4.useRef(null);
|
|
898
|
+
const fetchUser = React4.useCallback(async () => {
|
|
899
|
+
if (!productBackendUrl || !enabled) {
|
|
900
|
+
setAuthState({ status: "idle" });
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
setAuthState({ status: "loading" });
|
|
904
|
+
try {
|
|
905
|
+
const response = await fetch(`${productBackendUrl}/users/me`, {
|
|
906
|
+
method: "GET",
|
|
907
|
+
credentials: "include",
|
|
908
|
+
// Include cookies for authentication
|
|
909
|
+
headers: {
|
|
910
|
+
"Accept": "application/json"
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
if (!response.ok) {
|
|
914
|
+
if (response.status === 401) {
|
|
915
|
+
throw new Error("Please log in to use the chat assistant.");
|
|
916
|
+
}
|
|
917
|
+
if (response.status === 403) {
|
|
918
|
+
throw new Error("You do not have permission to access this feature.");
|
|
919
|
+
}
|
|
920
|
+
throw new Error(`Authentication failed (${response.status})`);
|
|
921
|
+
}
|
|
922
|
+
const user = await response.json();
|
|
923
|
+
setAuthState({ status: "authenticated", user });
|
|
924
|
+
} catch (error) {
|
|
925
|
+
const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
|
|
926
|
+
setAuthState({ status: "error", error: message });
|
|
927
|
+
}
|
|
928
|
+
}, [productBackendUrl, enabled]);
|
|
929
|
+
React4.useEffect(() => {
|
|
930
|
+
if (sessionId !== lastSessionIdRef.current) {
|
|
931
|
+
lastSessionIdRef.current = sessionId;
|
|
932
|
+
fetchUser();
|
|
933
|
+
}
|
|
934
|
+
}, [sessionId, fetchUser]);
|
|
935
|
+
const retry = React4.useCallback(() => {
|
|
936
|
+
fetchUser();
|
|
937
|
+
}, [fetchUser]);
|
|
938
|
+
return { authState, retry };
|
|
939
|
+
}
|
|
940
|
+
|
|
889
941
|
// src/components/TypingIndicator.tsx
|
|
890
942
|
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
891
943
|
function TypingIndicator({ className = "" }) {
|
|
@@ -916,7 +968,7 @@ function TypingIndicator({ className = "" }) {
|
|
|
916
968
|
|
|
917
969
|
// src/ChatPanel.tsx
|
|
918
970
|
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
919
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
971
|
+
var CHAT_PANEL_VERSION = true ? "0.2.42" : "dev";
|
|
920
972
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
921
973
|
var PANEL_WIDTH = 340;
|
|
922
974
|
function unescapeJsonString(str) {
|
|
@@ -1334,6 +1386,32 @@ var guides = {
|
|
|
1334
1386
|
}
|
|
1335
1387
|
};
|
|
1336
1388
|
var initialMessages = [];
|
|
1389
|
+
function AuthLoadingState() {
|
|
1390
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center h-full p-6", children: [
|
|
1391
|
+
/* @__PURE__ */ jsx10(Loader22, { className: "h-8 w-8 animate-spin text-gray-400 mb-3" }),
|
|
1392
|
+
/* @__PURE__ */ jsx10("p", { className: "text-xs text-gray-500", children: "Verifying your identity..." })
|
|
1393
|
+
] });
|
|
1394
|
+
}
|
|
1395
|
+
function AuthErrorState({
|
|
1396
|
+
error,
|
|
1397
|
+
onRetry
|
|
1398
|
+
}) {
|
|
1399
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center h-full p-6 text-center", children: [
|
|
1400
|
+
/* @__PURE__ */ jsx10("div", { className: "w-12 h-12 rounded-full bg-red-100 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx10(X, { className: "h-6 w-6 text-red-600" }) }),
|
|
1401
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-900 mb-2", children: "Unable to Start Chat" }),
|
|
1402
|
+
/* @__PURE__ */ jsx10("p", { className: "text-xs text-gray-500 mb-4 max-w-[240px]", children: error }),
|
|
1403
|
+
/* @__PURE__ */ jsx10(
|
|
1404
|
+
Button,
|
|
1405
|
+
{
|
|
1406
|
+
variant: "secondary",
|
|
1407
|
+
size: "sm",
|
|
1408
|
+
onClick: onRetry,
|
|
1409
|
+
className: "h-8 px-4 text-xs",
|
|
1410
|
+
children: "Try Again"
|
|
1411
|
+
}
|
|
1412
|
+
)
|
|
1413
|
+
] });
|
|
1414
|
+
}
|
|
1337
1415
|
function ChatPanel({
|
|
1338
1416
|
isOpen = true,
|
|
1339
1417
|
onClose,
|
|
@@ -1351,21 +1429,46 @@ function ChatPanel({
|
|
|
1351
1429
|
userEmail,
|
|
1352
1430
|
userOrganization,
|
|
1353
1431
|
supabaseUrl,
|
|
1354
|
-
supabaseAnonKey
|
|
1432
|
+
supabaseAnonKey,
|
|
1433
|
+
productBackendUrl
|
|
1355
1434
|
} = {}) {
|
|
1356
|
-
const [messages, setMessages] =
|
|
1357
|
-
const [input, setInput] =
|
|
1358
|
-
const [sessionId, setSessionId] =
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1435
|
+
const [messages, setMessages] = React5.useState(initialMessages);
|
|
1436
|
+
const [input, setInput] = React5.useState("");
|
|
1437
|
+
const [sessionId, setSessionId] = React5.useState(() => crypto.randomUUID());
|
|
1438
|
+
const { authState, retry: retryAuth } = useUserAuth({
|
|
1439
|
+
productBackendUrl,
|
|
1440
|
+
sessionId,
|
|
1441
|
+
enabled: !!productBackendUrl
|
|
1442
|
+
// Only enable if URL is provided
|
|
1443
|
+
});
|
|
1444
|
+
const effectiveUser = React5.useMemo(() => {
|
|
1445
|
+
if (authState.status === "authenticated") {
|
|
1446
|
+
return {
|
|
1447
|
+
userId: authState.user.id,
|
|
1448
|
+
userName: authState.user.name,
|
|
1449
|
+
userEmail: authState.user.email,
|
|
1450
|
+
userRole: authState.user.role,
|
|
1451
|
+
isInternal: authState.user.isInternal
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
return {
|
|
1455
|
+
userId: userId || "anonymous",
|
|
1456
|
+
userName: userName || "Anonymous User",
|
|
1457
|
+
userEmail: userEmail || "Not provided",
|
|
1458
|
+
userRole: void 0,
|
|
1459
|
+
isInternal: false
|
|
1460
|
+
};
|
|
1461
|
+
}, [authState, userId, userName, userEmail]);
|
|
1462
|
+
const [isEscalated, setIsEscalated] = React5.useState(false);
|
|
1463
|
+
const escalationWsRef = React5.useRef(null);
|
|
1464
|
+
const [agentIsTyping, setAgentIsTyping] = React5.useState(false);
|
|
1465
|
+
const supabaseRef = React5.useRef(null);
|
|
1466
|
+
const typingChannelRef = React5.useRef(null);
|
|
1467
|
+
const typingTimeoutRef = React5.useRef(null);
|
|
1468
|
+
React5.useEffect(() => {
|
|
1366
1469
|
console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
|
|
1367
1470
|
}, []);
|
|
1368
|
-
const resetSession =
|
|
1471
|
+
const resetSession = React5.useCallback(() => {
|
|
1369
1472
|
console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
|
|
1370
1473
|
if (isEscalated && supabaseRef.current && sessionId) {
|
|
1371
1474
|
console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
|
|
@@ -1395,12 +1498,12 @@ function ChatPanel({
|
|
|
1395
1498
|
typingChannelRef.current = null;
|
|
1396
1499
|
}
|
|
1397
1500
|
}, [isEscalated, sessionId]);
|
|
1398
|
-
|
|
1501
|
+
React5.useEffect(() => {
|
|
1399
1502
|
if (supabaseUrl && supabaseAnonKey && !supabaseRef.current) {
|
|
1400
1503
|
supabaseRef.current = createClient(supabaseUrl, supabaseAnonKey);
|
|
1401
1504
|
}
|
|
1402
1505
|
}, [supabaseUrl, supabaseAnonKey]);
|
|
1403
|
-
|
|
1506
|
+
React5.useEffect(() => {
|
|
1404
1507
|
if (!isEscalated || !sessionId || !supabaseRef.current) {
|
|
1405
1508
|
return;
|
|
1406
1509
|
}
|
|
@@ -1437,8 +1540,8 @@ function ChatPanel({
|
|
|
1437
1540
|
}
|
|
1438
1541
|
};
|
|
1439
1542
|
}, [isEscalated, sessionId]);
|
|
1440
|
-
const heartbeatIntervalRef =
|
|
1441
|
-
const updateCustomerStatus =
|
|
1543
|
+
const heartbeatIntervalRef = React5.useRef(null);
|
|
1544
|
+
const updateCustomerStatus = React5.useCallback(async (status) => {
|
|
1442
1545
|
if (!supabaseRef.current || !sessionId) return;
|
|
1443
1546
|
try {
|
|
1444
1547
|
await supabaseRef.current.from("escalations").update({
|
|
@@ -1449,7 +1552,7 @@ function ChatPanel({
|
|
|
1449
1552
|
console.error("[KiteChat] Failed to update customer status:", err);
|
|
1450
1553
|
}
|
|
1451
1554
|
}, [sessionId]);
|
|
1452
|
-
|
|
1555
|
+
React5.useEffect(() => {
|
|
1453
1556
|
if (!isEscalated || !sessionId || !supabaseRef.current) {
|
|
1454
1557
|
return;
|
|
1455
1558
|
}
|
|
@@ -1497,7 +1600,7 @@ function ChatPanel({
|
|
|
1497
1600
|
}
|
|
1498
1601
|
};
|
|
1499
1602
|
}, [isEscalated, sessionId, updateCustomerStatus]);
|
|
1500
|
-
const sendTypingIndicator =
|
|
1603
|
+
const sendTypingIndicator = React5.useCallback((isTyping) => {
|
|
1501
1604
|
if (!typingChannelRef.current) {
|
|
1502
1605
|
console.log("[KiteChat] Cannot send typing - channel not ready");
|
|
1503
1606
|
return;
|
|
@@ -1513,8 +1616,8 @@ function ChatPanel({
|
|
|
1513
1616
|
payload: { sender: "user", isTyping }
|
|
1514
1617
|
});
|
|
1515
1618
|
}, [isEscalated]);
|
|
1516
|
-
const userTypingTimeoutRef =
|
|
1517
|
-
const handleTypingStart =
|
|
1619
|
+
const userTypingTimeoutRef = React5.useRef(null);
|
|
1620
|
+
const handleTypingStart = React5.useCallback(() => {
|
|
1518
1621
|
if (!isEscalated || !supabaseRef.current) return;
|
|
1519
1622
|
sendTypingIndicator(true);
|
|
1520
1623
|
updateCustomerStatus("active");
|
|
@@ -1525,19 +1628,19 @@ function ChatPanel({
|
|
|
1525
1628
|
sendTypingIndicator(false);
|
|
1526
1629
|
}, 1500);
|
|
1527
1630
|
}, [isEscalated, sendTypingIndicator, updateCustomerStatus]);
|
|
1528
|
-
const streamIntervals =
|
|
1631
|
+
const streamIntervals = React5.useRef({});
|
|
1529
1632
|
const isEmpty = messages.length === 0;
|
|
1530
|
-
const [phase, setPhase] =
|
|
1531
|
-
const [progressSteps, setProgressSteps] =
|
|
1532
|
-
const phaseTimers =
|
|
1633
|
+
const [phase, setPhase] = React5.useState("idle");
|
|
1634
|
+
const [progressSteps, setProgressSteps] = React5.useState([]);
|
|
1635
|
+
const phaseTimers = React5.useRef([]);
|
|
1533
1636
|
const lastRole = messages.length ? messages[messages.length - 1].role : void 0;
|
|
1534
|
-
const [panelView, setPanelView] =
|
|
1637
|
+
const [panelView, setPanelView] = React5.useState(
|
|
1535
1638
|
"landing"
|
|
1536
1639
|
);
|
|
1537
|
-
const [currentFolderId, setCurrentFolderId] =
|
|
1538
|
-
const [startingQuestions, setStartingQuestions] =
|
|
1539
|
-
const [loadingQuestions, setLoadingQuestions] =
|
|
1540
|
-
|
|
1640
|
+
const [currentFolderId, setCurrentFolderId] = React5.useState(void 0);
|
|
1641
|
+
const [startingQuestions, setStartingQuestions] = React5.useState(startingQuestionsProp || defaultStartingQuestions);
|
|
1642
|
+
const [loadingQuestions, setLoadingQuestions] = React5.useState(false);
|
|
1643
|
+
React5.useEffect(() => {
|
|
1541
1644
|
if (startingQuestionsEndpoint && !startingQuestionsProp) {
|
|
1542
1645
|
setLoadingQuestions(true);
|
|
1543
1646
|
fetch(startingQuestionsEndpoint).then((res) => res.json()).then((data) => {
|
|
@@ -1549,16 +1652,16 @@ function ChatPanel({
|
|
|
1549
1652
|
}).finally(() => setLoadingQuestions(false));
|
|
1550
1653
|
}
|
|
1551
1654
|
}, [startingQuestionsEndpoint, startingQuestionsProp]);
|
|
1552
|
-
|
|
1655
|
+
React5.useEffect(() => {
|
|
1553
1656
|
if (startingQuestionsProp) {
|
|
1554
1657
|
setStartingQuestions(startingQuestionsProp);
|
|
1555
1658
|
}
|
|
1556
1659
|
}, [startingQuestionsProp]);
|
|
1557
|
-
const [activeGuide, setActiveGuide] =
|
|
1558
|
-
const activeGuideRef =
|
|
1559
|
-
const latestBulkSummaryNavigationRef =
|
|
1560
|
-
const [guideComplete, setGuideComplete] =
|
|
1561
|
-
|
|
1660
|
+
const [activeGuide, setActiveGuide] = React5.useState(void 0);
|
|
1661
|
+
const activeGuideRef = React5.useRef(void 0);
|
|
1662
|
+
const latestBulkSummaryNavigationRef = React5.useRef(null);
|
|
1663
|
+
const [guideComplete, setGuideComplete] = React5.useState(false);
|
|
1664
|
+
React5.useEffect(() => {
|
|
1562
1665
|
window.resetIntegrationNotification = () => {
|
|
1563
1666
|
localStorage.removeItem("gmailNotificationSeen");
|
|
1564
1667
|
console.log(
|
|
@@ -1592,7 +1695,7 @@ function ChatPanel({
|
|
|
1592
1695
|
);
|
|
1593
1696
|
};
|
|
1594
1697
|
}, []);
|
|
1595
|
-
|
|
1698
|
+
React5.useEffect(() => {
|
|
1596
1699
|
if (activeGuide) {
|
|
1597
1700
|
if (!activeGuideRef.current || activeGuideRef.current.id !== activeGuide.id || activeGuideRef.current.stepIndex !== activeGuide.stepIndex) {
|
|
1598
1701
|
activeGuideRef.current = activeGuide;
|
|
@@ -1601,21 +1704,21 @@ function ChatPanel({
|
|
|
1601
1704
|
activeGuideRef.current = void 0;
|
|
1602
1705
|
}
|
|
1603
1706
|
}, [activeGuide]);
|
|
1604
|
-
const [pendingNavigation, setPendingNavigation] =
|
|
1605
|
-
const [pendingAction, setPendingAction] =
|
|
1606
|
-
const [actionFormData, setActionFormData] =
|
|
1607
|
-
const messagesEndRef =
|
|
1608
|
-
const messagesContainerRef =
|
|
1609
|
-
const currentStepRef =
|
|
1707
|
+
const [pendingNavigation, setPendingNavigation] = React5.useState(null);
|
|
1708
|
+
const [pendingAction, setPendingAction] = React5.useState(null);
|
|
1709
|
+
const [actionFormData, setActionFormData] = React5.useState({});
|
|
1710
|
+
const messagesEndRef = React5.useRef(null);
|
|
1711
|
+
const messagesContainerRef = React5.useRef(null);
|
|
1712
|
+
const currentStepRef = React5.useRef(null);
|
|
1610
1713
|
const { cursorState, moveTo, hide } = useGuideCursor();
|
|
1611
|
-
const [pendingFile, setPendingFile] =
|
|
1612
|
-
const [pendingBulkSession, setPendingBulkSession] =
|
|
1613
|
-
const pendingBulkSessionRef =
|
|
1614
|
-
const fileInputRef =
|
|
1615
|
-
const [searchExpanded, setSearchExpanded] =
|
|
1616
|
-
const [searchInput, setSearchInput] =
|
|
1617
|
-
const searchInputRef =
|
|
1618
|
-
|
|
1714
|
+
const [pendingFile, setPendingFile] = React5.useState(null);
|
|
1715
|
+
const [pendingBulkSession, setPendingBulkSession] = React5.useState(null);
|
|
1716
|
+
const pendingBulkSessionRef = React5.useRef(null);
|
|
1717
|
+
const fileInputRef = React5.useRef(null);
|
|
1718
|
+
const [searchExpanded, setSearchExpanded] = React5.useState(false);
|
|
1719
|
+
const [searchInput, setSearchInput] = React5.useState("");
|
|
1720
|
+
const searchInputRef = React5.useRef(null);
|
|
1721
|
+
React5.useEffect(() => {
|
|
1619
1722
|
if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
|
|
1620
1723
|
return;
|
|
1621
1724
|
}
|
|
@@ -1641,7 +1744,7 @@ function ChatPanel({
|
|
|
1641
1744
|
const interval = setInterval(checkForDialogOpen, 300);
|
|
1642
1745
|
return () => clearInterval(interval);
|
|
1643
1746
|
}, [activeGuide, hide]);
|
|
1644
|
-
|
|
1747
|
+
React5.useEffect(() => {
|
|
1645
1748
|
return () => {
|
|
1646
1749
|
Object.values(streamIntervals.current).forEach(
|
|
1647
1750
|
(id) => window.clearInterval(id)
|
|
@@ -1651,7 +1754,7 @@ function ChatPanel({
|
|
|
1651
1754
|
phaseTimers.current = [];
|
|
1652
1755
|
};
|
|
1653
1756
|
}, []);
|
|
1654
|
-
|
|
1757
|
+
React5.useEffect(() => {
|
|
1655
1758
|
if (activeGuide && messages.length > 0) {
|
|
1656
1759
|
const lastMessage = messages[messages.length - 1];
|
|
1657
1760
|
if (lastMessage.kind === "guideStep" || lastMessage.kind === "guideComplete") {
|
|
@@ -1668,7 +1771,7 @@ function ChatPanel({
|
|
|
1668
1771
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1669
1772
|
}
|
|
1670
1773
|
}, [messages, phase, activeGuide]);
|
|
1671
|
-
const latestBulkSummaryNavigation =
|
|
1774
|
+
const latestBulkSummaryNavigation = React5.useMemo(() => {
|
|
1672
1775
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1673
1776
|
const msg = messages[i];
|
|
1674
1777
|
if (msg.kind === "bulkSummary" && msg.bulkSummary?.navigationPage && msg.bulkSummary.successes > 0) {
|
|
@@ -1677,13 +1780,13 @@ function ChatPanel({
|
|
|
1677
1780
|
}
|
|
1678
1781
|
return null;
|
|
1679
1782
|
}, [messages]);
|
|
1680
|
-
|
|
1783
|
+
React5.useEffect(() => {
|
|
1681
1784
|
latestBulkSummaryNavigationRef.current = latestBulkSummaryNavigation;
|
|
1682
1785
|
}, [latestBulkSummaryNavigation]);
|
|
1683
|
-
|
|
1786
|
+
React5.useEffect(() => {
|
|
1684
1787
|
pendingBulkSessionRef.current = pendingBulkSession;
|
|
1685
1788
|
}, [pendingBulkSession]);
|
|
1686
|
-
|
|
1789
|
+
React5.useEffect(() => {
|
|
1687
1790
|
const handleKeyDown = (e) => {
|
|
1688
1791
|
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
1689
1792
|
const currentBulkSession = pendingBulkSessionRef.current;
|
|
@@ -1746,7 +1849,7 @@ function ChatPanel({
|
|
|
1746
1849
|
guideComplete,
|
|
1747
1850
|
onNavigate
|
|
1748
1851
|
]);
|
|
1749
|
-
const connectToEscalationWs =
|
|
1852
|
+
const connectToEscalationWs = React5.useCallback((currentSessionId) => {
|
|
1750
1853
|
if (!agentUrl) return;
|
|
1751
1854
|
if (escalationWsRef.current) {
|
|
1752
1855
|
escalationWsRef.current.close();
|
|
@@ -1789,7 +1892,7 @@ function ChatPanel({
|
|
|
1789
1892
|
};
|
|
1790
1893
|
escalationWsRef.current = ws;
|
|
1791
1894
|
}, [agentUrl]);
|
|
1792
|
-
const sendEscalatedMessage =
|
|
1895
|
+
const sendEscalatedMessage = React5.useCallback(async (content) => {
|
|
1793
1896
|
if (!escalationWsRef.current || escalationWsRef.current.readyState !== WebSocket.OPEN) {
|
|
1794
1897
|
console.error("[KiteChat] Escalation WebSocket not connected");
|
|
1795
1898
|
return false;
|
|
@@ -1806,14 +1909,14 @@ function ChatPanel({
|
|
|
1806
1909
|
return false;
|
|
1807
1910
|
}
|
|
1808
1911
|
}, [updateCustomerStatus]);
|
|
1809
|
-
|
|
1912
|
+
React5.useEffect(() => {
|
|
1810
1913
|
return () => {
|
|
1811
1914
|
if (escalationWsRef.current) {
|
|
1812
1915
|
escalationWsRef.current.close();
|
|
1813
1916
|
}
|
|
1814
1917
|
};
|
|
1815
1918
|
}, []);
|
|
1816
|
-
|
|
1919
|
+
React5.useEffect(() => {
|
|
1817
1920
|
if (isEscalated && sessionId) {
|
|
1818
1921
|
connectToEscalationWs(sessionId);
|
|
1819
1922
|
}
|
|
@@ -2088,9 +2191,9 @@ function ChatPanel({
|
|
|
2088
2191
|
session_id: sessionId,
|
|
2089
2192
|
message: userText,
|
|
2090
2193
|
current_page: currentPage || "dashboard",
|
|
2091
|
-
user_id: userId,
|
|
2092
|
-
user_name: userName,
|
|
2093
|
-
user_email: userEmail,
|
|
2194
|
+
user_id: effectiveUser.userId,
|
|
2195
|
+
user_name: effectiveUser.userName,
|
|
2196
|
+
user_email: effectiveUser.userEmail,
|
|
2094
2197
|
user_organization: userOrganization,
|
|
2095
2198
|
org_id: orgId
|
|
2096
2199
|
}),
|
|
@@ -3033,6 +3136,64 @@ ${userText}`
|
|
|
3033
3136
|
] })
|
|
3034
3137
|
] }) }) });
|
|
3035
3138
|
}
|
|
3139
|
+
if (productBackendUrl) {
|
|
3140
|
+
if (authState.status === "loading") {
|
|
3141
|
+
return /* @__PURE__ */ jsxs6(
|
|
3142
|
+
"section",
|
|
3143
|
+
{
|
|
3144
|
+
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"}`,
|
|
3145
|
+
style: { width: `${PANEL_WIDTH}px` },
|
|
3146
|
+
children: [
|
|
3147
|
+
/* @__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: [
|
|
3148
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2.5", children: [
|
|
3149
|
+
/* @__PURE__ */ jsx10(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
|
|
3150
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
|
|
3151
|
+
] }),
|
|
3152
|
+
/* @__PURE__ */ jsx10(
|
|
3153
|
+
Button,
|
|
3154
|
+
{
|
|
3155
|
+
variant: "ghost",
|
|
3156
|
+
size: "sm",
|
|
3157
|
+
className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
|
|
3158
|
+
onClick: () => onClose?.(),
|
|
3159
|
+
children: /* @__PURE__ */ jsx10(Minus, { className: "h-3.5 w-3.5" })
|
|
3160
|
+
}
|
|
3161
|
+
)
|
|
3162
|
+
] }),
|
|
3163
|
+
/* @__PURE__ */ jsx10(AuthLoadingState, {})
|
|
3164
|
+
]
|
|
3165
|
+
}
|
|
3166
|
+
);
|
|
3167
|
+
}
|
|
3168
|
+
if (authState.status === "error") {
|
|
3169
|
+
return /* @__PURE__ */ jsxs6(
|
|
3170
|
+
"section",
|
|
3171
|
+
{
|
|
3172
|
+
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"}`,
|
|
3173
|
+
style: { width: `${PANEL_WIDTH}px` },
|
|
3174
|
+
children: [
|
|
3175
|
+
/* @__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: [
|
|
3176
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2.5", children: [
|
|
3177
|
+
/* @__PURE__ */ jsx10(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" }),
|
|
3178
|
+
/* @__PURE__ */ jsx10("h3", { className: "text-sm font-semibold text-gray-800", children: "Copilot" })
|
|
3179
|
+
] }),
|
|
3180
|
+
/* @__PURE__ */ jsx10(
|
|
3181
|
+
Button,
|
|
3182
|
+
{
|
|
3183
|
+
variant: "ghost",
|
|
3184
|
+
size: "sm",
|
|
3185
|
+
className: "h-7 w-7 p-0 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-full",
|
|
3186
|
+
onClick: () => onClose?.(),
|
|
3187
|
+
children: /* @__PURE__ */ jsx10(Minus, { className: "h-3.5 w-3.5" })
|
|
3188
|
+
}
|
|
3189
|
+
)
|
|
3190
|
+
] }),
|
|
3191
|
+
/* @__PURE__ */ jsx10(AuthErrorState, { error: authState.error, onRetry: retryAuth })
|
|
3192
|
+
]
|
|
3193
|
+
}
|
|
3194
|
+
);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3036
3197
|
return /* @__PURE__ */ jsxs6(
|
|
3037
3198
|
"section",
|
|
3038
3199
|
{
|
|
@@ -4150,7 +4311,7 @@ ${userText}`
|
|
|
4150
4311
|
message.id
|
|
4151
4312
|
);
|
|
4152
4313
|
}
|
|
4153
|
-
return /* @__PURE__ */ jsx10(
|
|
4314
|
+
return /* @__PURE__ */ jsx10(React5.Fragment, { children: /* @__PURE__ */ jsxs6(
|
|
4154
4315
|
"div",
|
|
4155
4316
|
{
|
|
4156
4317
|
ref: isCurrentGuideStep ? currentStepRef : null,
|
|
@@ -4404,9 +4565,10 @@ function ChatPanelWithToggle({
|
|
|
4404
4565
|
userEmail,
|
|
4405
4566
|
userOrganization,
|
|
4406
4567
|
supabaseUrl,
|
|
4407
|
-
supabaseAnonKey
|
|
4568
|
+
supabaseAnonKey,
|
|
4569
|
+
productBackendUrl
|
|
4408
4570
|
}) {
|
|
4409
|
-
const [internalIsOpen, setInternalIsOpen] =
|
|
4571
|
+
const [internalIsOpen, setInternalIsOpen] = React5.useState(defaultOpen);
|
|
4410
4572
|
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
4411
4573
|
const setIsOpen = (open) => {
|
|
4412
4574
|
if (controlledIsOpen === void 0) {
|
|
@@ -4414,7 +4576,7 @@ function ChatPanelWithToggle({
|
|
|
4414
4576
|
}
|
|
4415
4577
|
onOpenChange?.(open);
|
|
4416
4578
|
};
|
|
4417
|
-
|
|
4579
|
+
React5.useEffect(() => {
|
|
4418
4580
|
const originalPadding = document.body.style.paddingRight;
|
|
4419
4581
|
const originalTransition = document.body.style.transition;
|
|
4420
4582
|
document.body.style.transition = "padding-right 0.3s ease";
|
|
@@ -4442,7 +4604,8 @@ function ChatPanelWithToggle({
|
|
|
4442
4604
|
userEmail,
|
|
4443
4605
|
userOrganization,
|
|
4444
4606
|
supabaseUrl,
|
|
4445
|
-
supabaseAnonKey
|
|
4607
|
+
supabaseAnonKey,
|
|
4608
|
+
productBackendUrl
|
|
4446
4609
|
}
|
|
4447
4610
|
);
|
|
4448
4611
|
}
|
|
@@ -4460,7 +4623,7 @@ function HelpButton({ onClick, className = "" }) {
|
|
|
4460
4623
|
}
|
|
4461
4624
|
|
|
4462
4625
|
// src/createKiteChat.tsx
|
|
4463
|
-
import
|
|
4626
|
+
import React6 from "react";
|
|
4464
4627
|
import { createRoot } from "react-dom/client";
|
|
4465
4628
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
4466
4629
|
function KiteChatWrapper({
|
|
@@ -4468,14 +4631,14 @@ function KiteChatWrapper({
|
|
|
4468
4631
|
onConfigUpdate,
|
|
4469
4632
|
onStateUpdate
|
|
4470
4633
|
}) {
|
|
4471
|
-
const [config, setConfig] =
|
|
4472
|
-
const [currentPage, setCurrentPage] =
|
|
4473
|
-
const [isOpen, setIsOpen] =
|
|
4474
|
-
const isOpenRef =
|
|
4475
|
-
|
|
4634
|
+
const [config, setConfig] = React6.useState(initialConfig);
|
|
4635
|
+
const [currentPage, setCurrentPage] = React6.useState(initialConfig.currentPage || "dashboard");
|
|
4636
|
+
const [isOpen, setIsOpen] = React6.useState(false);
|
|
4637
|
+
const isOpenRef = React6.useRef(false);
|
|
4638
|
+
React6.useEffect(() => {
|
|
4476
4639
|
isOpenRef.current = isOpen;
|
|
4477
4640
|
}, [isOpen]);
|
|
4478
|
-
|
|
4641
|
+
React6.useEffect(() => {
|
|
4479
4642
|
onConfigUpdate((newConfig) => {
|
|
4480
4643
|
if (newConfig.currentPage !== void 0) {
|
|
4481
4644
|
setCurrentPage(newConfig.currentPage);
|
|
@@ -4487,7 +4650,7 @@ function KiteChatWrapper({
|
|
|
4487
4650
|
getIsOpen: () => isOpenRef.current
|
|
4488
4651
|
});
|
|
4489
4652
|
}, [onConfigUpdate, onStateUpdate]);
|
|
4490
|
-
|
|
4653
|
+
React6.useEffect(() => {
|
|
4491
4654
|
const container = document.getElementById("kite-chat-root");
|
|
4492
4655
|
if (!container) return;
|
|
4493
4656
|
if (config.theme === "dark") {
|
|
@@ -4516,7 +4679,8 @@ function KiteChatWrapper({
|
|
|
4516
4679
|
userEmail: config.userEmail,
|
|
4517
4680
|
userOrganization: config.userOrganization,
|
|
4518
4681
|
supabaseUrl: config.supabaseUrl,
|
|
4519
|
-
supabaseAnonKey: config.supabaseAnonKey
|
|
4682
|
+
supabaseAnonKey: config.supabaseAnonKey,
|
|
4683
|
+
productBackendUrl: config.productBackendUrl
|
|
4520
4684
|
}
|
|
4521
4685
|
);
|
|
4522
4686
|
}
|
|
@@ -112,8 +112,10 @@ interface ChatPanelProps {
|
|
|
112
112
|
supabaseUrl?: string;
|
|
113
113
|
/** Supabase anonymous key for realtime features */
|
|
114
114
|
supabaseAnonKey?: string;
|
|
115
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
116
|
+
productBackendUrl?: string;
|
|
115
117
|
}
|
|
116
|
-
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
118
|
+
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, productBackendUrl, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
117
119
|
/**
|
|
118
120
|
* PanelToggle - An arrow button on the right edge that toggles the side panel
|
|
119
121
|
* Shows left arrow when closed (click to open), right arrow when open (click to close)
|
|
@@ -172,8 +174,10 @@ interface ChatPanelWithToggleProps {
|
|
|
172
174
|
supabaseUrl?: string;
|
|
173
175
|
/** Supabase anonymous key for realtime features */
|
|
174
176
|
supabaseAnonKey?: string;
|
|
177
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
178
|
+
productBackendUrl?: string;
|
|
175
179
|
}
|
|
176
|
-
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
180
|
+
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, productBackendUrl, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
177
181
|
/**
|
|
178
182
|
* @deprecated Use ChatPanelWithToggle instead for the new side panel UX
|
|
179
183
|
*/
|
|
@@ -244,6 +248,8 @@ interface KiteChatConfig {
|
|
|
244
248
|
supabaseUrl?: string;
|
|
245
249
|
/** Supabase anonymous key for realtime features */
|
|
246
250
|
supabaseAnonKey?: string;
|
|
251
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
252
|
+
productBackendUrl?: string;
|
|
247
253
|
}
|
|
248
254
|
/**
|
|
249
255
|
* Instance returned by createKiteChat with lifecycle control methods.
|
|
@@ -112,8 +112,10 @@ interface ChatPanelProps {
|
|
|
112
112
|
supabaseUrl?: string;
|
|
113
113
|
/** Supabase anonymous key for realtime features */
|
|
114
114
|
supabaseAnonKey?: string;
|
|
115
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
116
|
+
productBackendUrl?: string;
|
|
115
117
|
}
|
|
116
|
-
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
118
|
+
declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, productBackendUrl, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
|
|
117
119
|
/**
|
|
118
120
|
* PanelToggle - An arrow button on the right edge that toggles the side panel
|
|
119
121
|
* Shows left arrow when closed (click to open), right arrow when open (click to close)
|
|
@@ -172,8 +174,10 @@ interface ChatPanelWithToggleProps {
|
|
|
172
174
|
supabaseUrl?: string;
|
|
173
175
|
/** Supabase anonymous key for realtime features */
|
|
174
176
|
supabaseAnonKey?: string;
|
|
177
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
178
|
+
productBackendUrl?: string;
|
|
175
179
|
}
|
|
176
|
-
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
180
|
+
declare function ChatPanelWithToggle({ onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions, startingQuestionsEndpoint, defaultOpen, isOpen: controlledIsOpen, onOpenChange, userId, orgId, userName, userEmail, userOrganization, supabaseUrl, supabaseAnonKey, productBackendUrl, }: ChatPanelWithToggleProps): react_jsx_runtime.JSX.Element;
|
|
177
181
|
/**
|
|
178
182
|
* @deprecated Use ChatPanelWithToggle instead for the new side panel UX
|
|
179
183
|
*/
|
|
@@ -244,6 +248,8 @@ interface KiteChatConfig {
|
|
|
244
248
|
supabaseUrl?: string;
|
|
245
249
|
/** Supabase anonymous key for realtime features */
|
|
246
250
|
supabaseAnonKey?: string;
|
|
251
|
+
/** Product backend URL for user authentication (e.g., https://dev.api.rocketalumnisolutions.com) */
|
|
252
|
+
productBackendUrl?: string;
|
|
247
253
|
}
|
|
248
254
|
/**
|
|
249
255
|
* Instance returned by createKiteChat with lifecycle control methods.
|