@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
package/README.md
CHANGED
|
@@ -52,6 +52,12 @@ const chat = createKiteChat({
|
|
|
52
52
|
// Optional: Pass user info for session tracking in control center
|
|
53
53
|
userName: 'John Doe',
|
|
54
54
|
userEmail: 'john@example.com',
|
|
55
|
+
// Optional: Provide authentication headers for API requests
|
|
56
|
+
getAuthHeaders: async () => {
|
|
57
|
+
return {
|
|
58
|
+
Authorization: `Bearer ${await getCurrentToken()}`
|
|
59
|
+
};
|
|
60
|
+
},
|
|
55
61
|
onNavigate: (page, subtab) => {
|
|
56
62
|
router.push(`/${page}${subtab ? `?tab=${subtab}` : ''}`);
|
|
57
63
|
},
|
|
@@ -320,6 +326,7 @@ Creates a new chat instance with explicit lifecycle control.
|
|
|
320
326
|
| `theme` | `'light' \| 'dark' \| 'system'` | No | Theme preference |
|
|
321
327
|
| `startingQuestions` | `StartingQuestion[]` | No | Custom starting questions |
|
|
322
328
|
| `startingQuestionsEndpoint` | `string` | No | URL to fetch per-user questions |
|
|
329
|
+
| `getAuthHeaders` | `() => Promise<Record<string, string>>` | No | Async function to provide auth headers |
|
|
323
330
|
| `onNavigate` | `(page: string, subtab?: string) => void` | No | Navigation callback |
|
|
324
331
|
| `onActionComplete` | `(actionType: string, data: any) => void` | No | Action completion callback |
|
|
325
332
|
|
|
@@ -360,6 +367,7 @@ import { ChatPanelWithToggle } from '@kite-copilot/chat-panel';
|
|
|
360
367
|
| `onOpenChange` | `(isOpen: boolean) => void` | - | Called when open state changes |
|
|
361
368
|
| `startingQuestions` | `StartingQuestion[]` | - | Custom starting questions |
|
|
362
369
|
| `startingQuestionsEndpoint` | `string` | - | URL to fetch questions |
|
|
370
|
+
| `getAuthHeaders` | `() => Promise<Record<string, string>>` | - | Async function to provide auth headers |
|
|
363
371
|
| `onNavigate` | `(page, subtab?) => void` | - | Navigation callback |
|
|
364
372
|
| `onActionComplete` | `(type, data) => void` | - | Action completion callback |
|
|
365
373
|
|
package/dist/auto.cjs
CHANGED
|
@@ -348,28 +348,22 @@ function useUserAuth({
|
|
|
348
348
|
}) {
|
|
349
349
|
const [authState, setAuthState] = React4.useState({ status: "idle" });
|
|
350
350
|
const lastSessionIdRef = React4.useRef(null);
|
|
351
|
+
const lastEnabledRef = React4.useRef(enabled);
|
|
351
352
|
const fetchUser = React4.useCallback(async () => {
|
|
352
353
|
if (!productBackendUrl || !enabled) {
|
|
353
|
-
console.log("[useUserAuth] Skipping auth - productBackendUrl:", productBackendUrl, "enabled:", enabled);
|
|
354
354
|
setAuthState({ status: "idle" });
|
|
355
355
|
return;
|
|
356
356
|
}
|
|
357
|
-
console.log("[useUserAuth] Starting auth request to product backend...");
|
|
358
|
-
console.log("[useUserAuth] Product backend URL:", productBackendUrl);
|
|
359
|
-
console.log("[useUserAuth] Full request URL:", `${productBackendUrl}/users/me`);
|
|
360
357
|
setAuthState({ status: "loading" });
|
|
361
358
|
try {
|
|
362
359
|
const response = await fetch(`${productBackendUrl}/users/me`, {
|
|
363
360
|
method: "GET",
|
|
364
361
|
credentials: "include",
|
|
365
|
-
// Include cookies for authentication
|
|
366
362
|
headers: {
|
|
367
363
|
"Accept": "application/json"
|
|
368
364
|
}
|
|
369
365
|
});
|
|
370
|
-
console.log("[useUserAuth] Response received - status:", response.status, "ok:", response.ok);
|
|
371
366
|
if (!response.ok) {
|
|
372
|
-
console.log("[useUserAuth] Auth request failed with status:", response.status);
|
|
373
367
|
if (response.status === 401) {
|
|
374
368
|
throw new Error("Please log in to use the chat assistant.");
|
|
375
369
|
}
|
|
@@ -379,27 +373,36 @@ function useUserAuth({
|
|
|
379
373
|
throw new Error(`Authentication failed (${response.status})`);
|
|
380
374
|
}
|
|
381
375
|
const user = await response.json();
|
|
382
|
-
console.log("[useUserAuth] Auth SUCCESS - parsed user data:");
|
|
383
|
-
console.log("[useUserAuth] id:", user.id);
|
|
384
|
-
console.log("[useUserAuth] email:", user.email);
|
|
385
|
-
console.log("[useUserAuth] name:", user.name);
|
|
386
|
-
console.log("[useUserAuth] role:", user.role);
|
|
387
|
-
console.log("[useUserAuth] isInternal:", user.isInternal);
|
|
388
|
-
console.log("[useUserAuth] agreementsSigned:", user.agreementsSigned);
|
|
389
|
-
console.log("[useUserAuth] lastLoginTime:", user.lastLoginTime);
|
|
390
376
|
setAuthState({ status: "authenticated", user });
|
|
391
377
|
} catch (error) {
|
|
392
|
-
|
|
378
|
+
if (error instanceof Error) {
|
|
379
|
+
const errorMessage = error.message.toLowerCase();
|
|
380
|
+
const isCorsError = errorMessage.includes("cors") || errorMessage.includes("network");
|
|
381
|
+
const is404Error = errorMessage.includes("404");
|
|
382
|
+
if (isCorsError || is404Error) {
|
|
383
|
+
console.warn("[useUserAuth] Auth endpoint unavailable, falling back to unauthenticated mode:", error.message);
|
|
384
|
+
setAuthState({ status: "idle" });
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
393
388
|
const message = error instanceof Error ? error.message : "Unable to verify your identity. Please try again.";
|
|
394
389
|
setAuthState({ status: "error", error: message });
|
|
395
390
|
}
|
|
396
391
|
}, [productBackendUrl, enabled]);
|
|
397
392
|
React4.useEffect(() => {
|
|
398
|
-
|
|
393
|
+
const sessionChanged = sessionId !== lastSessionIdRef.current;
|
|
394
|
+
const enabledChanged = enabled !== lastEnabledRef.current;
|
|
395
|
+
const becameEnabled = enabled && !lastEnabledRef.current;
|
|
396
|
+
if (sessionChanged) {
|
|
399
397
|
lastSessionIdRef.current = sessionId;
|
|
398
|
+
}
|
|
399
|
+
if (enabledChanged) {
|
|
400
|
+
lastEnabledRef.current = enabled;
|
|
401
|
+
}
|
|
402
|
+
if (sessionChanged || becameEnabled) {
|
|
400
403
|
fetchUser();
|
|
401
404
|
}
|
|
402
|
-
}, [sessionId, fetchUser]);
|
|
405
|
+
}, [sessionId, enabled, fetchUser]);
|
|
403
406
|
const retry = React4.useCallback(() => {
|
|
404
407
|
fetchUser();
|
|
405
408
|
}, [fetchUser]);
|
|
@@ -416,13 +419,11 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
416
419
|
});
|
|
417
420
|
React5.useEffect(() => {
|
|
418
421
|
if (!agentUrl || !orgId) {
|
|
419
|
-
console.log("[useOrgConfig] Skipping - missing agentUrl or orgId", { agentUrl, orgId });
|
|
420
422
|
return;
|
|
421
423
|
}
|
|
422
424
|
const fetchConfig = async () => {
|
|
423
425
|
setState({ status: "loading", config: null, error: null });
|
|
424
426
|
const url = `${agentUrl}/org/${orgId}/config`;
|
|
425
|
-
console.log("[useOrgConfig] Fetching org config from:", url);
|
|
426
427
|
try {
|
|
427
428
|
const response = await fetch(url, {
|
|
428
429
|
method: "GET",
|
|
@@ -434,7 +435,6 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
434
435
|
throw new Error(`Failed to fetch org config (${response.status})`);
|
|
435
436
|
}
|
|
436
437
|
const config = await response.json();
|
|
437
|
-
console.log("[useOrgConfig] Received config:", config);
|
|
438
438
|
setState({ status: "success", config, error: null });
|
|
439
439
|
} catch (error) {
|
|
440
440
|
const message = error instanceof Error ? error.message : "Failed to fetch org config";
|
|
@@ -468,8 +468,7 @@ function useFrontendToolExecutor({
|
|
|
468
468
|
}
|
|
469
469
|
}, [agentUrl]);
|
|
470
470
|
const executeToolRequest = (0, import_react.useCallback)(async (toolRequest) => {
|
|
471
|
-
const { call_id,
|
|
472
|
-
console.log("[FrontendToolExecutor] Executing tool:", tool_name, "with args:", args);
|
|
471
|
+
const { call_id, arguments: args, endpoint, method, path_params } = toolRequest;
|
|
473
472
|
try {
|
|
474
473
|
let url = endpoint;
|
|
475
474
|
for (const param of path_params) {
|
|
@@ -485,7 +484,6 @@ function useFrontendToolExecutor({
|
|
|
485
484
|
}
|
|
486
485
|
const queryString = queryParams.toString();
|
|
487
486
|
const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
|
|
488
|
-
console.log("[FrontendToolExecutor] Fetching:", fullUrl);
|
|
489
487
|
const response = await fetch(fullUrl, {
|
|
490
488
|
method,
|
|
491
489
|
credentials: "include",
|
|
@@ -497,7 +495,6 @@ function useFrontendToolExecutor({
|
|
|
497
495
|
let result;
|
|
498
496
|
if (response.ok) {
|
|
499
497
|
result = await response.json();
|
|
500
|
-
console.log("[FrontendToolExecutor] Tool result:", result);
|
|
501
498
|
} else {
|
|
502
499
|
const errorText = await response.text();
|
|
503
500
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
@@ -1096,7 +1093,6 @@ function TypingIndicator({ className = "" }) {
|
|
|
1096
1093
|
|
|
1097
1094
|
// src/ChatPanel.tsx
|
|
1098
1095
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1099
|
-
var CHAT_PANEL_VERSION = true ? "0.2.49" : "dev";
|
|
1100
1096
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1101
1097
|
var PANEL_WIDTH = 400;
|
|
1102
1098
|
var PANEL_HEIGHT = 600;
|
|
@@ -1560,7 +1556,8 @@ function ChatPanel({
|
|
|
1560
1556
|
supabaseAnonKey,
|
|
1561
1557
|
initialCorner = "bottom-left",
|
|
1562
1558
|
onCornerChange,
|
|
1563
|
-
productBackendUrl
|
|
1559
|
+
productBackendUrl,
|
|
1560
|
+
getAuthHeaders
|
|
1564
1561
|
} = {}) {
|
|
1565
1562
|
const [messages, setMessages] = React6.useState(initialMessages);
|
|
1566
1563
|
const [input, setInput] = React6.useState("");
|
|
@@ -1593,37 +1590,6 @@ function ChatPanel({
|
|
|
1593
1590
|
agentUrl,
|
|
1594
1591
|
sessionId
|
|
1595
1592
|
});
|
|
1596
|
-
React6.useEffect(() => {
|
|
1597
|
-
if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
|
|
1598
|
-
return;
|
|
1599
|
-
}
|
|
1600
|
-
const testProductBackendEndpoint = async () => {
|
|
1601
|
-
const url = `${effectiveProductBackendUrl}/getDocument/snowkite/categories/`;
|
|
1602
|
-
console.log("[KiteChat TEST] Testing product backend connectivity...");
|
|
1603
|
-
console.log("[KiteChat TEST] URL:", url);
|
|
1604
|
-
try {
|
|
1605
|
-
const response = await fetch(url, {
|
|
1606
|
-
method: "GET",
|
|
1607
|
-
// Note: not using credentials: 'include' to avoid CORS issues with wildcard
|
|
1608
|
-
headers: {
|
|
1609
|
-
"Accept": "application/json"
|
|
1610
|
-
}
|
|
1611
|
-
});
|
|
1612
|
-
console.log("[KiteChat TEST] Response status:", response.status);
|
|
1613
|
-
console.log("[KiteChat TEST] Response ok:", response.ok);
|
|
1614
|
-
if (response.ok) {
|
|
1615
|
-
const data = await response.json();
|
|
1616
|
-
console.log("[KiteChat TEST] SUCCESS - product backend reachable, data:", data);
|
|
1617
|
-
} else {
|
|
1618
|
-
const errorText = await response.text();
|
|
1619
|
-
console.log("[KiteChat TEST] FAILED - status:", response.status, "body:", errorText);
|
|
1620
|
-
}
|
|
1621
|
-
} catch (error) {
|
|
1622
|
-
console.error("[KiteChat TEST] ERROR:", error);
|
|
1623
|
-
}
|
|
1624
|
-
};
|
|
1625
|
-
testProductBackendEndpoint();
|
|
1626
|
-
}, [effectiveProductBackendUrl, orgConfigState.status]);
|
|
1627
1593
|
const effectiveUser = React6.useMemo(() => {
|
|
1628
1594
|
if (sessionUser) {
|
|
1629
1595
|
return sessionUser;
|
|
@@ -1654,7 +1620,6 @@ function ChatPanel({
|
|
|
1654
1620
|
userRole: authState.user.role,
|
|
1655
1621
|
isInternal: authState.user.isInternal
|
|
1656
1622
|
});
|
|
1657
|
-
console.log("[ChatPanel] Session user captured:", authState.user.id);
|
|
1658
1623
|
}
|
|
1659
1624
|
}, [authState, sessionUser]);
|
|
1660
1625
|
const isWaitingForAuth = React6.useMemo(() => {
|
|
@@ -1667,26 +1632,18 @@ function ChatPanel({
|
|
|
1667
1632
|
const supabaseRef = React6.useRef(null);
|
|
1668
1633
|
const typingChannelRef = React6.useRef(null);
|
|
1669
1634
|
const typingTimeoutRef = React6.useRef(null);
|
|
1670
|
-
React6.useEffect(() => {
|
|
1671
|
-
console.log(`[KiteChat] Chat Panel v${CHAT_PANEL_VERSION} loaded`);
|
|
1672
|
-
}, []);
|
|
1673
1635
|
const resetSession = React6.useCallback(() => {
|
|
1674
|
-
console.log("[KiteChat] resetSession called", { isEscalated, hasSupabase: !!supabaseRef.current, sessionId });
|
|
1675
1636
|
if (isEscalated && supabaseRef.current && sessionId) {
|
|
1676
|
-
console.log("[KiteChat] Updating customer_status to disconnected for session:", sessionId);
|
|
1677
1637
|
supabaseRef.current.from("escalations").update({
|
|
1678
1638
|
customer_status: "disconnected",
|
|
1679
1639
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1680
1640
|
}).eq("session_id", sessionId).then(
|
|
1681
|
-
(
|
|
1682
|
-
console.log("[KiteChat] Disconnect update result:", result);
|
|
1641
|
+
() => {
|
|
1683
1642
|
},
|
|
1684
1643
|
(err) => {
|
|
1685
1644
|
console.error("[KiteChat] Disconnect update failed:", err);
|
|
1686
1645
|
}
|
|
1687
1646
|
);
|
|
1688
|
-
} else {
|
|
1689
|
-
console.log("[KiteChat] Skipping disconnect update - conditions not met");
|
|
1690
1647
|
}
|
|
1691
1648
|
setSessionUser(null);
|
|
1692
1649
|
setSessionId(crypto.randomUUID());
|
|
@@ -1712,12 +1669,9 @@ function ChatPanel({
|
|
|
1712
1669
|
}
|
|
1713
1670
|
const channelName = `typing:${sessionId}`;
|
|
1714
1671
|
const channel = supabaseRef.current.channel(channelName);
|
|
1715
|
-
console.log(`[KiteChat] Subscribing to typing channel: ${channelName}`);
|
|
1716
1672
|
channel.on("broadcast", { event: "typing" }, (payload) => {
|
|
1717
|
-
console.log("[KiteChat] Received typing broadcast:", payload);
|
|
1718
1673
|
const { sender, isTyping } = payload.payload;
|
|
1719
1674
|
if (sender === "agent") {
|
|
1720
|
-
console.log(`[KiteChat] Agent typing: ${isTyping}`);
|
|
1721
1675
|
setAgentIsTyping(isTyping);
|
|
1722
1676
|
if (isTyping) {
|
|
1723
1677
|
if (typingTimeoutRef.current) {
|
|
@@ -1729,10 +1683,11 @@ function ChatPanel({
|
|
|
1729
1683
|
}
|
|
1730
1684
|
}
|
|
1731
1685
|
}).subscribe((status) => {
|
|
1732
|
-
console.log(`[KiteChat] Typing channel status: ${status}`);
|
|
1733
1686
|
if (status === "SUBSCRIBED") {
|
|
1734
1687
|
typingChannelRef.current = channel;
|
|
1735
|
-
console.log("[KiteChat] Typing channel
|
|
1688
|
+
console.log("[KiteChat] Typing channel subscribed successfully");
|
|
1689
|
+
} else if (status === "CHANNEL_ERROR") {
|
|
1690
|
+
console.error("[KiteChat] Typing channel subscription failed");
|
|
1736
1691
|
}
|
|
1737
1692
|
});
|
|
1738
1693
|
return () => {
|
|
@@ -1743,6 +1698,20 @@ function ChatPanel({
|
|
|
1743
1698
|
}
|
|
1744
1699
|
};
|
|
1745
1700
|
}, [isEscalated, sessionId]);
|
|
1701
|
+
React6.useEffect(() => {
|
|
1702
|
+
if (!isOpen && isEscalated && supabaseRef.current && sessionId) {
|
|
1703
|
+
console.log("[KiteChat] Panel closed during live chat, marking disconnected");
|
|
1704
|
+
supabaseRef.current.from("escalations").update({
|
|
1705
|
+
customer_status: "disconnected",
|
|
1706
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1707
|
+
}).eq("session_id", sessionId).then(
|
|
1708
|
+
() => console.log("[KiteChat] Successfully marked disconnected on panel close"),
|
|
1709
|
+
(err) => {
|
|
1710
|
+
console.error("[KiteChat] Failed to mark disconnected on panel close:", err);
|
|
1711
|
+
}
|
|
1712
|
+
);
|
|
1713
|
+
}
|
|
1714
|
+
}, [isOpen, isEscalated, sessionId]);
|
|
1746
1715
|
const heartbeatIntervalRef = React6.useRef(null);
|
|
1747
1716
|
const updateCustomerStatus = React6.useCallback(async (status) => {
|
|
1748
1717
|
if (!supabaseRef.current || !sessionId) return;
|
|
@@ -1761,9 +1730,20 @@ function ChatPanel({
|
|
|
1761
1730
|
}
|
|
1762
1731
|
const currentSessionId = sessionId;
|
|
1763
1732
|
const supabase = supabaseRef.current;
|
|
1764
|
-
|
|
1733
|
+
const markActive = () => {
|
|
1734
|
+
supabase.from("escalations").update({
|
|
1735
|
+
customer_status: "active",
|
|
1736
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1737
|
+
}).eq("session_id", currentSessionId).then(
|
|
1738
|
+
() => {
|
|
1739
|
+
},
|
|
1740
|
+
(err) => console.error("[KiteChat] Failed to update customer status:", err)
|
|
1741
|
+
);
|
|
1742
|
+
};
|
|
1743
|
+
console.log("[KiteChat] Starting presence heartbeat for live chat");
|
|
1744
|
+
markActive();
|
|
1765
1745
|
heartbeatIntervalRef.current = window.setInterval(() => {
|
|
1766
|
-
|
|
1746
|
+
markActive();
|
|
1767
1747
|
}, 6e4);
|
|
1768
1748
|
const handleBeforeUnload = () => {
|
|
1769
1749
|
supabase.from("escalations").update({
|
|
@@ -1778,7 +1758,7 @@ function ChatPanel({
|
|
|
1778
1758
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1779
1759
|
}).eq("session_id", currentSessionId);
|
|
1780
1760
|
} else if (document.visibilityState === "visible") {
|
|
1781
|
-
|
|
1761
|
+
markActive();
|
|
1782
1762
|
}
|
|
1783
1763
|
};
|
|
1784
1764
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1786,13 +1766,12 @@ function ChatPanel({
|
|
|
1786
1766
|
return () => {
|
|
1787
1767
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
1788
1768
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1769
|
+
console.log("[KiteChat] Escalation ended, marking disconnected");
|
|
1789
1770
|
supabase.from("escalations").update({
|
|
1790
1771
|
customer_status: "disconnected",
|
|
1791
1772
|
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1792
1773
|
}).eq("session_id", currentSessionId).then(
|
|
1793
|
-
() =>
|
|
1794
|
-
console.log("[KiteChat] Marked customer as disconnected");
|
|
1795
|
-
},
|
|
1774
|
+
() => console.log("[KiteChat] Successfully marked disconnected on escalation end"),
|
|
1796
1775
|
(err) => {
|
|
1797
1776
|
console.error("[KiteChat] Failed to mark disconnected:", err);
|
|
1798
1777
|
}
|
|
@@ -1802,17 +1781,14 @@ function ChatPanel({
|
|
|
1802
1781
|
heartbeatIntervalRef.current = null;
|
|
1803
1782
|
}
|
|
1804
1783
|
};
|
|
1805
|
-
}, [isEscalated, sessionId
|
|
1784
|
+
}, [isEscalated, sessionId]);
|
|
1806
1785
|
const sendTypingIndicator = React6.useCallback((isTyping) => {
|
|
1807
|
-
if (!typingChannelRef.current) {
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
if (!isEscalated) {
|
|
1812
|
-
console.log("[KiteChat] Cannot send typing - not escalated");
|
|
1786
|
+
if (!typingChannelRef.current || !isEscalated) {
|
|
1787
|
+
if (isTyping) {
|
|
1788
|
+
console.warn("[KiteChat] Typing channel not ready, cannot send typing indicator");
|
|
1789
|
+
}
|
|
1813
1790
|
return;
|
|
1814
1791
|
}
|
|
1815
|
-
console.log(`[KiteChat] Sending typing indicator: ${isTyping}`);
|
|
1816
1792
|
typingChannelRef.current.send({
|
|
1817
1793
|
type: "broadcast",
|
|
1818
1794
|
event: "typing",
|
|
@@ -1821,16 +1797,23 @@ function ChatPanel({
|
|
|
1821
1797
|
}, [isEscalated]);
|
|
1822
1798
|
const userTypingTimeoutRef = React6.useRef(null);
|
|
1823
1799
|
const handleTypingStart = React6.useCallback(() => {
|
|
1824
|
-
if (!isEscalated || !supabaseRef.current) return;
|
|
1800
|
+
if (!isEscalated || !supabaseRef.current || !sessionId) return;
|
|
1825
1801
|
sendTypingIndicator(true);
|
|
1826
|
-
|
|
1802
|
+
supabaseRef.current.from("escalations").update({
|
|
1803
|
+
customer_status: "active",
|
|
1804
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
1805
|
+
}).eq("session_id", sessionId).then(
|
|
1806
|
+
() => {
|
|
1807
|
+
},
|
|
1808
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
1809
|
+
);
|
|
1827
1810
|
if (userTypingTimeoutRef.current) {
|
|
1828
1811
|
window.clearTimeout(userTypingTimeoutRef.current);
|
|
1829
1812
|
}
|
|
1830
1813
|
userTypingTimeoutRef.current = window.setTimeout(() => {
|
|
1831
1814
|
sendTypingIndicator(false);
|
|
1832
1815
|
}, 1500);
|
|
1833
|
-
}, [isEscalated, sendTypingIndicator,
|
|
1816
|
+
}, [isEscalated, sendTypingIndicator, sessionId]);
|
|
1834
1817
|
const streamIntervals = React6.useRef({});
|
|
1835
1818
|
const isEmpty = messages.length === 0;
|
|
1836
1819
|
const [phase, setPhase] = React6.useState("idle");
|
|
@@ -1865,12 +1848,6 @@ function ChatPanel({
|
|
|
1865
1848
|
const latestBulkSummaryNavigationRef = React6.useRef(null);
|
|
1866
1849
|
const [guideComplete, setGuideComplete] = React6.useState(false);
|
|
1867
1850
|
React6.useEffect(() => {
|
|
1868
|
-
window.resetIntegrationNotification = () => {
|
|
1869
|
-
localStorage.removeItem("gmailNotificationSeen");
|
|
1870
|
-
console.log(
|
|
1871
|
-
"Integration notification reset! Click the Integrations tab to see it again."
|
|
1872
|
-
);
|
|
1873
|
-
};
|
|
1874
1851
|
const handleIntegrationTabClick = () => {
|
|
1875
1852
|
const hasSeenNotification = localStorage.getItem("gmailNotificationSeen");
|
|
1876
1853
|
if (!hasSeenNotification) {
|
|
@@ -2012,17 +1989,7 @@ function ChatPanel({
|
|
|
2012
1989
|
return;
|
|
2013
1990
|
}
|
|
2014
1991
|
const currentBulkNav = latestBulkSummaryNavigationRef.current;
|
|
2015
|
-
console.log(
|
|
2016
|
-
"[DEBUG] Keyboard handler - latestBulkSummaryNavigation:",
|
|
2017
|
-
currentBulkNav,
|
|
2018
|
-
"onNavigate:",
|
|
2019
|
-
!!onNavigate
|
|
2020
|
-
);
|
|
2021
1992
|
if (currentBulkNav && onNavigate) {
|
|
2022
|
-
console.log(
|
|
2023
|
-
"[DEBUG] Navigating via keyboard to:",
|
|
2024
|
-
currentBulkNav.page
|
|
2025
|
-
);
|
|
2026
1993
|
e.preventDefault();
|
|
2027
1994
|
e.stopPropagation();
|
|
2028
1995
|
onNavigate(currentBulkNav.page, currentBulkNav.subtab);
|
|
@@ -2068,7 +2035,6 @@ function ChatPanel({
|
|
|
2068
2035
|
const messageId = data.message_id;
|
|
2069
2036
|
const isDuplicate = messageId ? prev.some((m) => m.serverMessageId === messageId) : prev.slice(-5).some((m) => m.content === content);
|
|
2070
2037
|
if (isDuplicate) {
|
|
2071
|
-
console.debug("[KiteChat] Skipping duplicate agent message:", messageId || content.slice(0, 30));
|
|
2072
2038
|
return prev;
|
|
2073
2039
|
}
|
|
2074
2040
|
return [...prev, {
|
|
@@ -2091,7 +2057,6 @@ function ChatPanel({
|
|
|
2091
2057
|
console.error("[KiteChat] Escalation WebSocket error:", err);
|
|
2092
2058
|
};
|
|
2093
2059
|
ws.onclose = () => {
|
|
2094
|
-
console.log("[KiteChat] Escalation WebSocket closed");
|
|
2095
2060
|
};
|
|
2096
2061
|
escalationWsRef.current = ws;
|
|
2097
2062
|
}, [agentUrl]);
|
|
@@ -2105,13 +2070,22 @@ function ChatPanel({
|
|
|
2105
2070
|
type: "user_message",
|
|
2106
2071
|
content
|
|
2107
2072
|
}));
|
|
2108
|
-
|
|
2073
|
+
if (supabaseRef.current && sessionId) {
|
|
2074
|
+
supabaseRef.current.from("escalations").update({
|
|
2075
|
+
customer_status: "active",
|
|
2076
|
+
customer_last_seen: (/* @__PURE__ */ new Date()).toISOString()
|
|
2077
|
+
}).eq("session_id", sessionId).then(
|
|
2078
|
+
() => {
|
|
2079
|
+
},
|
|
2080
|
+
(err) => console.error("[KiteChat] Failed to update presence:", err)
|
|
2081
|
+
);
|
|
2082
|
+
}
|
|
2109
2083
|
return true;
|
|
2110
2084
|
} catch (err) {
|
|
2111
2085
|
console.error("[KiteChat] Failed to send escalated message:", err);
|
|
2112
2086
|
return false;
|
|
2113
2087
|
}
|
|
2114
|
-
}, [
|
|
2088
|
+
}, [sessionId]);
|
|
2115
2089
|
React6.useEffect(() => {
|
|
2116
2090
|
return () => {
|
|
2117
2091
|
if (escalationWsRef.current) {
|
|
@@ -2385,14 +2359,6 @@ function ChatPanel({
|
|
|
2385
2359
|
try {
|
|
2386
2360
|
const controller = new AbortController();
|
|
2387
2361
|
const timeoutId = setTimeout(() => controller.abort(), 6e4);
|
|
2388
|
-
console.log("[ChatPanel] Sending chat request to agent backend...");
|
|
2389
|
-
console.log("[ChatPanel] Agent URL:", agentUrl);
|
|
2390
|
-
console.log("[ChatPanel] User data being sent:");
|
|
2391
|
-
console.log("[ChatPanel] user_id:", effectiveUser.userId);
|
|
2392
|
-
console.log("[ChatPanel] user_name:", effectiveUser.userName);
|
|
2393
|
-
console.log("[ChatPanel] user_email:", effectiveUser.userEmail);
|
|
2394
|
-
console.log("[ChatPanel] org_id:", orgId);
|
|
2395
|
-
console.log("[ChatPanel] authState.status:", authState.status);
|
|
2396
2362
|
const response = await fetch(`${agentUrl}/chat/stream`, {
|
|
2397
2363
|
method: "POST",
|
|
2398
2364
|
headers: {
|
|
@@ -2609,7 +2575,6 @@ function ChatPanel({
|
|
|
2609
2575
|
setMessages((prev) => [...prev, escalationMessage]);
|
|
2610
2576
|
} else if (eventType === "tool_request") {
|
|
2611
2577
|
const toolRequest = data;
|
|
2612
|
-
console.log("[KiteChat] Received tool_request:", toolRequest);
|
|
2613
2578
|
executeToolRequest(toolRequest).catch((err) => {
|
|
2614
2579
|
console.error("[KiteChat] Tool execution failed:", err);
|
|
2615
2580
|
});
|
|
@@ -2927,11 +2892,6 @@ ${userText}`
|
|
|
2927
2892
|
}
|
|
2928
2893
|
});
|
|
2929
2894
|
} else if (eventType === "summary") {
|
|
2930
|
-
console.log("[DEBUG] Received summary event - data:", data);
|
|
2931
|
-
console.log(
|
|
2932
|
-
"[DEBUG] navigationPage from backend:",
|
|
2933
|
-
data.navigationPage
|
|
2934
|
-
);
|
|
2935
2895
|
setPhase("idle");
|
|
2936
2896
|
setProgressSteps([]);
|
|
2937
2897
|
setPendingBulkSession(null);
|
|
@@ -2951,7 +2911,6 @@ ${userText}`
|
|
|
2951
2911
|
navigationPage: data.navigationPage
|
|
2952
2912
|
}
|
|
2953
2913
|
};
|
|
2954
|
-
console.log("[DEBUG] Creating bulkSummary message:", newMsg);
|
|
2955
2914
|
return [...filtered, newMsg];
|
|
2956
2915
|
});
|
|
2957
2916
|
setTimeout(() => {
|
|
@@ -4522,28 +4481,11 @@ ${userText}`
|
|
|
4522
4481
|
onClick: (e) => {
|
|
4523
4482
|
e.preventDefault();
|
|
4524
4483
|
e.stopPropagation();
|
|
4525
|
-
console.log(
|
|
4526
|
-
"[DEBUG] Button clicked - navigationPage:",
|
|
4527
|
-
navigationPage,
|
|
4528
|
-
"onNavigate:",
|
|
4529
|
-
!!onNavigate
|
|
4530
|
-
);
|
|
4531
4484
|
if (onNavigate && navigationPage.page) {
|
|
4532
|
-
console.log(
|
|
4533
|
-
"[DEBUG] Calling onNavigate with page:",
|
|
4534
|
-
navigationPage.page
|
|
4535
|
-
);
|
|
4536
4485
|
onNavigate(
|
|
4537
4486
|
navigationPage.page,
|
|
4538
4487
|
navigationPage.subtab
|
|
4539
4488
|
);
|
|
4540
|
-
} else {
|
|
4541
|
-
console.log(
|
|
4542
|
-
"[DEBUG] Condition failed - onNavigate:",
|
|
4543
|
-
!!onNavigate,
|
|
4544
|
-
"navigationPage.page:",
|
|
4545
|
-
navigationPage.page
|
|
4546
|
-
);
|
|
4547
4489
|
}
|
|
4548
4490
|
},
|
|
4549
4491
|
className: "flex items-center gap-2 text-xs text-gray-500 hover:text-gray-700 transition-colors group cursor-pointer",
|
|
@@ -4803,7 +4745,8 @@ function ChatPanelWithToggle({
|
|
|
4803
4745
|
supabaseAnonKey,
|
|
4804
4746
|
initialCorner,
|
|
4805
4747
|
onCornerChange,
|
|
4806
|
-
productBackendUrl
|
|
4748
|
+
productBackendUrl,
|
|
4749
|
+
getAuthHeaders
|
|
4807
4750
|
}) {
|
|
4808
4751
|
const [internalIsOpen, setInternalIsOpen] = React6.useState(defaultOpen);
|
|
4809
4752
|
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
@@ -4833,7 +4776,8 @@ function ChatPanelWithToggle({
|
|
|
4833
4776
|
supabaseAnonKey,
|
|
4834
4777
|
initialCorner,
|
|
4835
4778
|
onCornerChange,
|
|
4836
|
-
productBackendUrl
|
|
4779
|
+
productBackendUrl,
|
|
4780
|
+
getAuthHeaders
|
|
4837
4781
|
}
|
|
4838
4782
|
);
|
|
4839
4783
|
}
|
|
@@ -4893,7 +4837,8 @@ function KiteChatWrapper({
|
|
|
4893
4837
|
userEmail: config.userEmail,
|
|
4894
4838
|
supabaseUrl: config.supabaseUrl,
|
|
4895
4839
|
supabaseAnonKey: config.supabaseAnonKey,
|
|
4896
|
-
productBackendUrl: config.productBackendUrl
|
|
4840
|
+
productBackendUrl: config.productBackendUrl,
|
|
4841
|
+
getAuthHeaders: config.getAuthHeaders
|
|
4897
4842
|
}
|
|
4898
4843
|
);
|
|
4899
4844
|
}
|
|
@@ -4936,7 +4881,6 @@ function createKiteChat(config) {
|
|
|
4936
4881
|
}
|
|
4937
4882
|
)
|
|
4938
4883
|
);
|
|
4939
|
-
console.log("[KiteChat] Mounted");
|
|
4940
4884
|
},
|
|
4941
4885
|
unmount() {
|
|
4942
4886
|
if (!root) {
|
|
@@ -4948,7 +4892,6 @@ function createKiteChat(config) {
|
|
|
4948
4892
|
containerElement = null;
|
|
4949
4893
|
configUpdater = null;
|
|
4950
4894
|
stateUpdaters = null;
|
|
4951
|
-
console.log("[KiteChat] Unmounted");
|
|
4952
4895
|
},
|
|
4953
4896
|
open() {
|
|
4954
4897
|
stateUpdaters?.setIsOpen(true);
|
package/dist/auto.d.cts
CHANGED
package/dist/auto.d.ts
CHANGED