@kite-copilot/chat-panel 0.2.47 → 0.2.49
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 +30 -0
- package/dist/auto.cjs +115 -11
- package/dist/auto.js +1 -1
- package/dist/{chunk-XMIO4GMW.js → chunk-YZXB3LLU.js} +107 -3
- package/dist/embed.global.js +24 -24
- package/dist/index.cjs +115 -11
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -548,6 +548,36 @@ If upgrading from a previous version with overlay/floating panel:
|
|
|
548
548
|
<ChatPanelWithToggle />
|
|
549
549
|
```
|
|
550
550
|
|
|
551
|
+
## Local Development with Test Page
|
|
552
|
+
|
|
553
|
+
To test the embed script locally using the included test page:
|
|
554
|
+
|
|
555
|
+
1. **Install dependencies:**
|
|
556
|
+
```bash
|
|
557
|
+
npm install
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
2. **Build the embed script:**
|
|
561
|
+
```bash
|
|
562
|
+
npm run build
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
3. **Serve the test page:**
|
|
566
|
+
```bash
|
|
567
|
+
npx serve .
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
4. **Open in browser:**
|
|
571
|
+
Navigate to `http://localhost:3000/test/test-embed.html`
|
|
572
|
+
|
|
573
|
+
The test page (`test/test-embed.html`) provides:
|
|
574
|
+
- Interactive controls to open/close/toggle the panel
|
|
575
|
+
- Page context switching buttons
|
|
576
|
+
- Backend URL toggle (localhost vs production)
|
|
577
|
+
- Event logging for navigation and action callbacks
|
|
578
|
+
|
|
579
|
+
**Note:** Make sure your backend agent is running on `http://localhost:5002` (or toggle to production in the test page).
|
|
580
|
+
|
|
551
581
|
## License
|
|
552
582
|
|
|
553
583
|
MIT © Kite
|
package/dist/auto.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(auto_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(auto_exports);
|
|
36
36
|
|
|
37
37
|
// src/createKiteChat.tsx
|
|
38
|
-
var
|
|
38
|
+
var import_react2 = __toESM(require("react"), 1);
|
|
39
39
|
var import_client = require("react-dom/client");
|
|
40
40
|
|
|
41
41
|
// src/ChatPanel.tsx
|
|
@@ -447,6 +447,78 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
447
447
|
return state;
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
+
// src/hooks/useFrontendToolExecutor.ts
|
|
451
|
+
var import_react = require("react");
|
|
452
|
+
function useFrontendToolExecutor({
|
|
453
|
+
productBackendUrl,
|
|
454
|
+
agentUrl,
|
|
455
|
+
sessionId
|
|
456
|
+
}) {
|
|
457
|
+
const sendToolResult = (0, import_react.useCallback)(async (payload) => {
|
|
458
|
+
try {
|
|
459
|
+
await fetch(`${agentUrl}/chat/tool-result`, {
|
|
460
|
+
method: "POST",
|
|
461
|
+
headers: {
|
|
462
|
+
"Content-Type": "application/json"
|
|
463
|
+
},
|
|
464
|
+
body: JSON.stringify(payload)
|
|
465
|
+
});
|
|
466
|
+
} catch (error) {
|
|
467
|
+
console.error("[FrontendToolExecutor] Failed to send tool result:", error);
|
|
468
|
+
}
|
|
469
|
+
}, [agentUrl]);
|
|
470
|
+
const executeToolRequest = (0, import_react.useCallback)(async (toolRequest) => {
|
|
471
|
+
const { call_id, tool_name, arguments: args, endpoint, method, path_params } = toolRequest;
|
|
472
|
+
console.log("[FrontendToolExecutor] Executing tool:", tool_name, "with args:", args);
|
|
473
|
+
try {
|
|
474
|
+
let url = endpoint;
|
|
475
|
+
for (const param of path_params) {
|
|
476
|
+
if (args[param]) {
|
|
477
|
+
url = url.replace(`{${param}}`, encodeURIComponent(args[param]));
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
const queryParams = new URLSearchParams();
|
|
481
|
+
for (const [key, value] of Object.entries(args)) {
|
|
482
|
+
if (!path_params.includes(key) && value !== void 0 && value !== null) {
|
|
483
|
+
queryParams.append(key, String(value));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const queryString = queryParams.toString();
|
|
487
|
+
const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
|
|
488
|
+
console.log("[FrontendToolExecutor] Fetching:", fullUrl);
|
|
489
|
+
const response = await fetch(fullUrl, {
|
|
490
|
+
method,
|
|
491
|
+
credentials: "include",
|
|
492
|
+
headers: {
|
|
493
|
+
"Accept": "application/json",
|
|
494
|
+
"Content-Type": "application/json"
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
let result;
|
|
498
|
+
if (response.ok) {
|
|
499
|
+
result = await response.json();
|
|
500
|
+
console.log("[FrontendToolExecutor] Tool result:", result);
|
|
501
|
+
} else {
|
|
502
|
+
const errorText = await response.text();
|
|
503
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
504
|
+
}
|
|
505
|
+
await sendToolResult({
|
|
506
|
+
session_id: sessionId,
|
|
507
|
+
call_id,
|
|
508
|
+
result
|
|
509
|
+
});
|
|
510
|
+
} catch (error) {
|
|
511
|
+
console.error("[FrontendToolExecutor] Tool execution failed:", error);
|
|
512
|
+
await sendToolResult({
|
|
513
|
+
session_id: sessionId,
|
|
514
|
+
call_id,
|
|
515
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}, [productBackendUrl, sessionId, sendToolResult]);
|
|
519
|
+
return { executeToolRequest };
|
|
520
|
+
}
|
|
521
|
+
|
|
450
522
|
// src/components/ui/card.tsx
|
|
451
523
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
452
524
|
function Card({ className, ...props }) {
|
|
@@ -1024,7 +1096,7 @@ function TypingIndicator({ className = "" }) {
|
|
|
1024
1096
|
|
|
1025
1097
|
// src/ChatPanel.tsx
|
|
1026
1098
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1027
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
1099
|
+
var CHAT_PANEL_VERSION = true ? "0.2.49" : "dev";
|
|
1028
1100
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1029
1101
|
var PANEL_WIDTH = 400;
|
|
1030
1102
|
var PANEL_HEIGHT = 600;
|
|
@@ -1507,6 +1579,7 @@ function ChatPanel({
|
|
|
1507
1579
|
}
|
|
1508
1580
|
}, [corner, onCornerChange, dragControls]);
|
|
1509
1581
|
const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
|
|
1582
|
+
const [sessionUser, setSessionUser] = React6.useState(null);
|
|
1510
1583
|
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1511
1584
|
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
1512
1585
|
const { authState, retry: retryAuth } = useUserAuth({
|
|
@@ -1515,6 +1588,11 @@ function ChatPanel({
|
|
|
1515
1588
|
enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
|
|
1516
1589
|
// Only enable after config is fetched
|
|
1517
1590
|
});
|
|
1591
|
+
const { executeToolRequest } = useFrontendToolExecutor({
|
|
1592
|
+
productBackendUrl: effectiveProductBackendUrl || "",
|
|
1593
|
+
agentUrl,
|
|
1594
|
+
sessionId
|
|
1595
|
+
});
|
|
1518
1596
|
React6.useEffect(() => {
|
|
1519
1597
|
if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
|
|
1520
1598
|
return;
|
|
@@ -1547,6 +1625,9 @@ function ChatPanel({
|
|
|
1547
1625
|
testProductBackendEndpoint();
|
|
1548
1626
|
}, [effectiveProductBackendUrl, orgConfigState.status]);
|
|
1549
1627
|
const effectiveUser = React6.useMemo(() => {
|
|
1628
|
+
if (sessionUser) {
|
|
1629
|
+
return sessionUser;
|
|
1630
|
+
}
|
|
1550
1631
|
if (authState.status === "authenticated") {
|
|
1551
1632
|
return {
|
|
1552
1633
|
userId: authState.user.id,
|
|
@@ -1563,7 +1644,23 @@ function ChatPanel({
|
|
|
1563
1644
|
userRole: void 0,
|
|
1564
1645
|
isInternal: false
|
|
1565
1646
|
};
|
|
1566
|
-
}, [authState, userId, userName, userEmail]);
|
|
1647
|
+
}, [sessionUser, authState, userId, userName, userEmail]);
|
|
1648
|
+
React6.useEffect(() => {
|
|
1649
|
+
if (authState.status === "authenticated" && sessionUser === null) {
|
|
1650
|
+
setSessionUser({
|
|
1651
|
+
userId: authState.user.id,
|
|
1652
|
+
userName: authState.user.name,
|
|
1653
|
+
userEmail: authState.user.email,
|
|
1654
|
+
userRole: authState.user.role,
|
|
1655
|
+
isInternal: authState.user.isInternal
|
|
1656
|
+
});
|
|
1657
|
+
console.log("[ChatPanel] Session user captured:", authState.user.id);
|
|
1658
|
+
}
|
|
1659
|
+
}, [authState, sessionUser]);
|
|
1660
|
+
const isWaitingForAuth = React6.useMemo(() => {
|
|
1661
|
+
if (!effectiveProductBackendUrl) return false;
|
|
1662
|
+
return authState.status === "loading" || authState.status === "idle";
|
|
1663
|
+
}, [effectiveProductBackendUrl, authState.status]);
|
|
1567
1664
|
const [isEscalated, setIsEscalated] = React6.useState(false);
|
|
1568
1665
|
const escalationWsRef = React6.useRef(null);
|
|
1569
1666
|
const [agentIsTyping, setAgentIsTyping] = React6.useState(false);
|
|
@@ -1591,6 +1688,7 @@ function ChatPanel({
|
|
|
1591
1688
|
} else {
|
|
1592
1689
|
console.log("[KiteChat] Skipping disconnect update - conditions not met");
|
|
1593
1690
|
}
|
|
1691
|
+
setSessionUser(null);
|
|
1594
1692
|
setSessionId(crypto.randomUUID());
|
|
1595
1693
|
setIsEscalated(false);
|
|
1596
1694
|
if (escalationWsRef.current) {
|
|
@@ -2509,6 +2607,12 @@ function ChatPanel({
|
|
|
2509
2607
|
content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
|
|
2510
2608
|
};
|
|
2511
2609
|
setMessages((prev) => [...prev, escalationMessage]);
|
|
2610
|
+
} else if (eventType === "tool_request") {
|
|
2611
|
+
const toolRequest = data;
|
|
2612
|
+
console.log("[KiteChat] Received tool_request:", toolRequest);
|
|
2613
|
+
executeToolRequest(toolRequest).catch((err) => {
|
|
2614
|
+
console.error("[KiteChat] Tool execution failed:", err);
|
|
2615
|
+
});
|
|
2512
2616
|
} else if (eventType === "token") {
|
|
2513
2617
|
}
|
|
2514
2618
|
} catch (parseError) {
|
|
@@ -4660,7 +4764,7 @@ ${userText}`
|
|
|
4660
4764
|
{
|
|
4661
4765
|
type: "submit",
|
|
4662
4766
|
size: "icon",
|
|
4663
|
-
disabled: !input.trim() && !pendingFile,
|
|
4767
|
+
disabled: !input.trim() && !pendingFile || isWaitingForAuth,
|
|
4664
4768
|
className: "h-6 w-6 rounded-full bg-gray-900 hover:bg-gray-800 disabled:bg-gray-300",
|
|
4665
4769
|
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react4.ArrowUp, { className: "h-2.5 w-2.5" })
|
|
4666
4770
|
}
|
|
@@ -4741,14 +4845,14 @@ function KiteChatWrapper({
|
|
|
4741
4845
|
onConfigUpdate,
|
|
4742
4846
|
onStateUpdate
|
|
4743
4847
|
}) {
|
|
4744
|
-
const [config, setConfig] =
|
|
4745
|
-
const [currentPage, setCurrentPage] =
|
|
4746
|
-
const [isOpen, setIsOpen] =
|
|
4747
|
-
const isOpenRef =
|
|
4748
|
-
|
|
4848
|
+
const [config, setConfig] = import_react2.default.useState(initialConfig);
|
|
4849
|
+
const [currentPage, setCurrentPage] = import_react2.default.useState(initialConfig.currentPage || "dashboard");
|
|
4850
|
+
const [isOpen, setIsOpen] = import_react2.default.useState(false);
|
|
4851
|
+
const isOpenRef = import_react2.default.useRef(false);
|
|
4852
|
+
import_react2.default.useEffect(() => {
|
|
4749
4853
|
isOpenRef.current = isOpen;
|
|
4750
4854
|
}, [isOpen]);
|
|
4751
|
-
|
|
4855
|
+
import_react2.default.useEffect(() => {
|
|
4752
4856
|
onConfigUpdate((newConfig) => {
|
|
4753
4857
|
if (newConfig.currentPage !== void 0) {
|
|
4754
4858
|
setCurrentPage(newConfig.currentPage);
|
|
@@ -4760,7 +4864,7 @@ function KiteChatWrapper({
|
|
|
4760
4864
|
getIsOpen: () => isOpenRef.current
|
|
4761
4865
|
});
|
|
4762
4866
|
}, [onConfigUpdate, onStateUpdate]);
|
|
4763
|
-
|
|
4867
|
+
import_react2.default.useEffect(() => {
|
|
4764
4868
|
const container = document.getElementById("kite-chat-root");
|
|
4765
4869
|
if (!container) return;
|
|
4766
4870
|
if (config.theme === "dark") {
|
package/dist/auto.js
CHANGED
|
@@ -995,6 +995,78 @@ function useOrgConfig({ agentUrl, orgId }) {
|
|
|
995
995
|
return state;
|
|
996
996
|
}
|
|
997
997
|
|
|
998
|
+
// src/hooks/useFrontendToolExecutor.ts
|
|
999
|
+
import { useCallback as useCallback3 } from "react";
|
|
1000
|
+
function useFrontendToolExecutor({
|
|
1001
|
+
productBackendUrl,
|
|
1002
|
+
agentUrl,
|
|
1003
|
+
sessionId
|
|
1004
|
+
}) {
|
|
1005
|
+
const sendToolResult = useCallback3(async (payload) => {
|
|
1006
|
+
try {
|
|
1007
|
+
await fetch(`${agentUrl}/chat/tool-result`, {
|
|
1008
|
+
method: "POST",
|
|
1009
|
+
headers: {
|
|
1010
|
+
"Content-Type": "application/json"
|
|
1011
|
+
},
|
|
1012
|
+
body: JSON.stringify(payload)
|
|
1013
|
+
});
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
console.error("[FrontendToolExecutor] Failed to send tool result:", error);
|
|
1016
|
+
}
|
|
1017
|
+
}, [agentUrl]);
|
|
1018
|
+
const executeToolRequest = useCallback3(async (toolRequest) => {
|
|
1019
|
+
const { call_id, tool_name, arguments: args, endpoint, method, path_params } = toolRequest;
|
|
1020
|
+
console.log("[FrontendToolExecutor] Executing tool:", tool_name, "with args:", args);
|
|
1021
|
+
try {
|
|
1022
|
+
let url = endpoint;
|
|
1023
|
+
for (const param of path_params) {
|
|
1024
|
+
if (args[param]) {
|
|
1025
|
+
url = url.replace(`{${param}}`, encodeURIComponent(args[param]));
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
const queryParams = new URLSearchParams();
|
|
1029
|
+
for (const [key, value] of Object.entries(args)) {
|
|
1030
|
+
if (!path_params.includes(key) && value !== void 0 && value !== null) {
|
|
1031
|
+
queryParams.append(key, String(value));
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
const queryString = queryParams.toString();
|
|
1035
|
+
const fullUrl = `${productBackendUrl}${url}${queryString ? "?" + queryString : ""}`;
|
|
1036
|
+
console.log("[FrontendToolExecutor] Fetching:", fullUrl);
|
|
1037
|
+
const response = await fetch(fullUrl, {
|
|
1038
|
+
method,
|
|
1039
|
+
credentials: "include",
|
|
1040
|
+
headers: {
|
|
1041
|
+
"Accept": "application/json",
|
|
1042
|
+
"Content-Type": "application/json"
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
let result;
|
|
1046
|
+
if (response.ok) {
|
|
1047
|
+
result = await response.json();
|
|
1048
|
+
console.log("[FrontendToolExecutor] Tool result:", result);
|
|
1049
|
+
} else {
|
|
1050
|
+
const errorText = await response.text();
|
|
1051
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
1052
|
+
}
|
|
1053
|
+
await sendToolResult({
|
|
1054
|
+
session_id: sessionId,
|
|
1055
|
+
call_id,
|
|
1056
|
+
result
|
|
1057
|
+
});
|
|
1058
|
+
} catch (error) {
|
|
1059
|
+
console.error("[FrontendToolExecutor] Tool execution failed:", error);
|
|
1060
|
+
await sendToolResult({
|
|
1061
|
+
session_id: sessionId,
|
|
1062
|
+
call_id,
|
|
1063
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
}, [productBackendUrl, sessionId, sendToolResult]);
|
|
1067
|
+
return { executeToolRequest };
|
|
1068
|
+
}
|
|
1069
|
+
|
|
998
1070
|
// src/components/TypingIndicator.tsx
|
|
999
1071
|
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1000
1072
|
function TypingIndicator({ className = "" }) {
|
|
@@ -1025,7 +1097,7 @@ function TypingIndicator({ className = "" }) {
|
|
|
1025
1097
|
|
|
1026
1098
|
// src/ChatPanel.tsx
|
|
1027
1099
|
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1028
|
-
var CHAT_PANEL_VERSION = true ? "0.2.
|
|
1100
|
+
var CHAT_PANEL_VERSION = true ? "0.2.49" : "dev";
|
|
1029
1101
|
var DEFAULT_AGENT_URL = "http://localhost:5002";
|
|
1030
1102
|
var PANEL_WIDTH = 400;
|
|
1031
1103
|
var PANEL_HEIGHT = 600;
|
|
@@ -1508,6 +1580,7 @@ function ChatPanel({
|
|
|
1508
1580
|
}
|
|
1509
1581
|
}, [corner, onCornerChange, dragControls]);
|
|
1510
1582
|
const [sessionId, setSessionId] = React6.useState(() => crypto.randomUUID());
|
|
1583
|
+
const [sessionUser, setSessionUser] = React6.useState(null);
|
|
1511
1584
|
const orgConfigState = useOrgConfig({ agentUrl, orgId: orgId || "" });
|
|
1512
1585
|
const effectiveProductBackendUrl = orgConfigState.config?.productBackendUrl || productBackendUrl;
|
|
1513
1586
|
const { authState, retry: retryAuth } = useUserAuth({
|
|
@@ -1516,6 +1589,11 @@ function ChatPanel({
|
|
|
1516
1589
|
enabled: !!effectiveProductBackendUrl && orgConfigState.status === "success"
|
|
1517
1590
|
// Only enable after config is fetched
|
|
1518
1591
|
});
|
|
1592
|
+
const { executeToolRequest } = useFrontendToolExecutor({
|
|
1593
|
+
productBackendUrl: effectiveProductBackendUrl || "",
|
|
1594
|
+
agentUrl,
|
|
1595
|
+
sessionId
|
|
1596
|
+
});
|
|
1519
1597
|
React6.useEffect(() => {
|
|
1520
1598
|
if (!effectiveProductBackendUrl || orgConfigState.status !== "success") {
|
|
1521
1599
|
return;
|
|
@@ -1548,6 +1626,9 @@ function ChatPanel({
|
|
|
1548
1626
|
testProductBackendEndpoint();
|
|
1549
1627
|
}, [effectiveProductBackendUrl, orgConfigState.status]);
|
|
1550
1628
|
const effectiveUser = React6.useMemo(() => {
|
|
1629
|
+
if (sessionUser) {
|
|
1630
|
+
return sessionUser;
|
|
1631
|
+
}
|
|
1551
1632
|
if (authState.status === "authenticated") {
|
|
1552
1633
|
return {
|
|
1553
1634
|
userId: authState.user.id,
|
|
@@ -1564,7 +1645,23 @@ function ChatPanel({
|
|
|
1564
1645
|
userRole: void 0,
|
|
1565
1646
|
isInternal: false
|
|
1566
1647
|
};
|
|
1567
|
-
}, [authState, userId, userName, userEmail]);
|
|
1648
|
+
}, [sessionUser, authState, userId, userName, userEmail]);
|
|
1649
|
+
React6.useEffect(() => {
|
|
1650
|
+
if (authState.status === "authenticated" && sessionUser === null) {
|
|
1651
|
+
setSessionUser({
|
|
1652
|
+
userId: authState.user.id,
|
|
1653
|
+
userName: authState.user.name,
|
|
1654
|
+
userEmail: authState.user.email,
|
|
1655
|
+
userRole: authState.user.role,
|
|
1656
|
+
isInternal: authState.user.isInternal
|
|
1657
|
+
});
|
|
1658
|
+
console.log("[ChatPanel] Session user captured:", authState.user.id);
|
|
1659
|
+
}
|
|
1660
|
+
}, [authState, sessionUser]);
|
|
1661
|
+
const isWaitingForAuth = React6.useMemo(() => {
|
|
1662
|
+
if (!effectiveProductBackendUrl) return false;
|
|
1663
|
+
return authState.status === "loading" || authState.status === "idle";
|
|
1664
|
+
}, [effectiveProductBackendUrl, authState.status]);
|
|
1568
1665
|
const [isEscalated, setIsEscalated] = React6.useState(false);
|
|
1569
1666
|
const escalationWsRef = React6.useRef(null);
|
|
1570
1667
|
const [agentIsTyping, setAgentIsTyping] = React6.useState(false);
|
|
@@ -1592,6 +1689,7 @@ function ChatPanel({
|
|
|
1592
1689
|
} else {
|
|
1593
1690
|
console.log("[KiteChat] Skipping disconnect update - conditions not met");
|
|
1594
1691
|
}
|
|
1692
|
+
setSessionUser(null);
|
|
1595
1693
|
setSessionId(crypto.randomUUID());
|
|
1596
1694
|
setIsEscalated(false);
|
|
1597
1695
|
if (escalationWsRef.current) {
|
|
@@ -2510,6 +2608,12 @@ function ChatPanel({
|
|
|
2510
2608
|
content: data.message || "You've been connected to our support queue. An agent will be with you shortly."
|
|
2511
2609
|
};
|
|
2512
2610
|
setMessages((prev) => [...prev, escalationMessage]);
|
|
2611
|
+
} else if (eventType === "tool_request") {
|
|
2612
|
+
const toolRequest = data;
|
|
2613
|
+
console.log("[KiteChat] Received tool_request:", toolRequest);
|
|
2614
|
+
executeToolRequest(toolRequest).catch((err) => {
|
|
2615
|
+
console.error("[KiteChat] Tool execution failed:", err);
|
|
2616
|
+
});
|
|
2513
2617
|
} else if (eventType === "token") {
|
|
2514
2618
|
}
|
|
2515
2619
|
} catch (parseError) {
|
|
@@ -4661,7 +4765,7 @@ ${userText}`
|
|
|
4661
4765
|
{
|
|
4662
4766
|
type: "submit",
|
|
4663
4767
|
size: "icon",
|
|
4664
|
-
disabled: !input.trim() && !pendingFile,
|
|
4768
|
+
disabled: !input.trim() && !pendingFile || isWaitingForAuth,
|
|
4665
4769
|
className: "h-6 w-6 rounded-full bg-gray-900 hover:bg-gray-800 disabled:bg-gray-300",
|
|
4666
4770
|
children: /* @__PURE__ */ jsx10(ArrowUp, { className: "h-2.5 w-2.5" })
|
|
4667
4771
|
}
|