@elqnt/chat 1.0.8 → 1.0.11
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/hooks/use-websocket-chat-admin.js +345 -8
- package/dist/hooks/use-websocket-chat-admin.js.map +1 -1
- package/dist/hooks/use-websocket-chat-admin.mjs +345 -8
- package/dist/hooks/use-websocket-chat-admin.mjs.map +1 -1
- package/dist/hooks/use-websocket-chat-base.d.mts +13 -2
- package/dist/hooks/use-websocket-chat-base.d.ts +13 -2
- package/dist/hooks/use-websocket-chat-base.js +345 -8
- package/dist/hooks/use-websocket-chat-base.js.map +1 -1
- package/dist/hooks/use-websocket-chat-base.mjs +345 -8
- package/dist/hooks/use-websocket-chat-base.mjs.map +1 -1
- package/dist/hooks/use-websocket-chat-customer.js +345 -8
- package/dist/hooks/use-websocket-chat-customer.js.map +1 -1
- package/dist/hooks/use-websocket-chat-customer.mjs +345 -8
- package/dist/hooks/use-websocket-chat-customer.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +354 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +351 -8
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.mts +18 -7
- package/dist/models/index.d.ts +18 -7
- package/dist/models/index.js +9 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/index.mjs +6 -0
- package/dist/models/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -324,6 +324,9 @@ var ChatEventTypeNewChat = "new_chat";
|
|
|
324
324
|
var ChatEventTypeNewChatCreated = "new_chat_created";
|
|
325
325
|
var ChatEventTypePing = "ping";
|
|
326
326
|
var ChatEventTypePong = "pong";
|
|
327
|
+
var ChatEventTypeSkillActivate = "skill_activate";
|
|
328
|
+
var ChatEventTypeSkillDeactivate = "skill_deactivate";
|
|
329
|
+
var ChatEventTypeSkillsChanged = "skills_changed";
|
|
327
330
|
var MessageStatusSending = "sending";
|
|
328
331
|
var MessageStatusSent = "sent";
|
|
329
332
|
var MessageStatusDelivered = "delivered";
|
|
@@ -411,6 +414,7 @@ var DEFAULT_QUEUE_CONFIG = {
|
|
|
411
414
|
};
|
|
412
415
|
var DEFAULT_HEARTBEAT_INTERVAL = 3e4;
|
|
413
416
|
var DEFAULT_HEARTBEAT_TIMEOUT = 5e3;
|
|
417
|
+
var DEFAULT_TRANSPORT = "websocket";
|
|
414
418
|
function isChatEvent(data) {
|
|
415
419
|
return data && typeof data === "object" && (typeof data.type === "string" || data.message);
|
|
416
420
|
}
|
|
@@ -425,7 +429,8 @@ var useWebSocketChatBase = ({
|
|
|
425
429
|
debug = false,
|
|
426
430
|
logger = createDefaultLogger(debug),
|
|
427
431
|
heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,
|
|
428
|
-
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT
|
|
432
|
+
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT,
|
|
433
|
+
transport = DEFAULT_TRANSPORT
|
|
429
434
|
}) => {
|
|
430
435
|
const [connectionState, setConnectionState] = useState("disconnected");
|
|
431
436
|
const [error, setError] = useState(void 0);
|
|
@@ -435,9 +440,15 @@ var useWebSocketChatBase = ({
|
|
|
435
440
|
messagesSent: 0,
|
|
436
441
|
messagesReceived: 0,
|
|
437
442
|
messagesQueued: 0,
|
|
438
|
-
reconnectCount: 0
|
|
443
|
+
reconnectCount: 0,
|
|
444
|
+
transportType: transport
|
|
439
445
|
});
|
|
440
446
|
const wsRef = useRef(void 0);
|
|
447
|
+
const sseRef = useRef(void 0);
|
|
448
|
+
const transportRef = useRef(transport);
|
|
449
|
+
useEffect(() => {
|
|
450
|
+
transportRef.current = transport;
|
|
451
|
+
}, [transport]);
|
|
441
452
|
const reconnectTimeoutRef = useRef(void 0);
|
|
442
453
|
const retryCountRef = useRef(0);
|
|
443
454
|
const messageQueueRef = useRef([]);
|
|
@@ -567,6 +578,10 @@ var useWebSocketChatBase = ({
|
|
|
567
578
|
wsRef.current.close(1e3, "Cleanup");
|
|
568
579
|
}
|
|
569
580
|
wsRef.current = void 0;
|
|
581
|
+
if (sseRef.current) {
|
|
582
|
+
sseRef.current.close();
|
|
583
|
+
sseRef.current = void 0;
|
|
584
|
+
}
|
|
570
585
|
if (reconnectTimeoutRef.current) {
|
|
571
586
|
clearTimeout(reconnectTimeoutRef.current);
|
|
572
587
|
reconnectTimeoutRef.current = void 0;
|
|
@@ -584,6 +599,35 @@ var useWebSocketChatBase = ({
|
|
|
584
599
|
});
|
|
585
600
|
loadChatRetryMapRef.current.clear();
|
|
586
601
|
}, [stopHeartbeat]);
|
|
602
|
+
const getRestApiUrl = useCallback((endpoint) => {
|
|
603
|
+
const httpUrl = serverBaseUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:");
|
|
604
|
+
return `${httpUrl}/${endpoint}`;
|
|
605
|
+
}, [serverBaseUrl]);
|
|
606
|
+
const sendRestMessage = useCallback(
|
|
607
|
+
async (endpoint, body) => {
|
|
608
|
+
const url = getRestApiUrl(endpoint);
|
|
609
|
+
logger.debug(`SSE REST API call: POST ${endpoint}`, body);
|
|
610
|
+
try {
|
|
611
|
+
const response = await fetch(url, {
|
|
612
|
+
method: "POST",
|
|
613
|
+
headers: {
|
|
614
|
+
"Content-Type": "application/json"
|
|
615
|
+
},
|
|
616
|
+
body: JSON.stringify(body)
|
|
617
|
+
});
|
|
618
|
+
if (!response.ok) {
|
|
619
|
+
const errorText = await response.text();
|
|
620
|
+
throw new Error(`REST API error: ${response.status} - ${errorText}`);
|
|
621
|
+
}
|
|
622
|
+
const data = await response.json();
|
|
623
|
+
return data;
|
|
624
|
+
} catch (error2) {
|
|
625
|
+
logger.error(`SSE REST API error for ${endpoint}:`, error2);
|
|
626
|
+
throw error2;
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
[getRestApiUrl, logger]
|
|
630
|
+
);
|
|
587
631
|
const connect = useCallback(
|
|
588
632
|
async (userId) => {
|
|
589
633
|
if (!mountedRef.current) {
|
|
@@ -601,7 +645,11 @@ var useWebSocketChatBase = ({
|
|
|
601
645
|
return Promise.reject(error2);
|
|
602
646
|
}
|
|
603
647
|
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
|
604
|
-
logger.debug("Already connected");
|
|
648
|
+
logger.debug("Already connected (WebSocket)");
|
|
649
|
+
return Promise.resolve();
|
|
650
|
+
}
|
|
651
|
+
if (sseRef.current?.readyState === EventSource.OPEN) {
|
|
652
|
+
logger.debug("Already connected (SSE)");
|
|
605
653
|
return Promise.resolve();
|
|
606
654
|
}
|
|
607
655
|
if (connectionState === "connecting" || connectionState === "reconnecting") {
|
|
@@ -627,8 +675,169 @@ var useWebSocketChatBase = ({
|
|
|
627
675
|
intentionalDisconnectRef.current = false;
|
|
628
676
|
return new Promise((resolve, reject) => {
|
|
629
677
|
try {
|
|
630
|
-
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
631
678
|
const connectionStartTime = Date.now();
|
|
679
|
+
logger.info(`\u{1F504} Connecting with transport: ${transportRef.current}`);
|
|
680
|
+
if (transportRef.current === "sse") {
|
|
681
|
+
const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || ""}`);
|
|
682
|
+
logger.debug("Connecting to SSE:", sseUrl);
|
|
683
|
+
console.log(`\u23F3 Initiating SSE connection to ${serverBaseUrl}...`);
|
|
684
|
+
const eventSource = new EventSource(sseUrl);
|
|
685
|
+
eventSource.onopen = () => {
|
|
686
|
+
if (!mountedRef.current) {
|
|
687
|
+
eventSource.close();
|
|
688
|
+
reject(new Error("Component unmounted"));
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const connectionTimeMs = Date.now() - connectionStartTime;
|
|
692
|
+
const connectionTimeSec = (connectionTimeMs / 1e3).toFixed(2);
|
|
693
|
+
logger.info("\u2705 SSE connected", {
|
|
694
|
+
userId,
|
|
695
|
+
retryCount: retryCountRef.current,
|
|
696
|
+
connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`
|
|
697
|
+
});
|
|
698
|
+
console.log(`\u{1F50C} SSE connection established in ${connectionTimeSec} seconds`);
|
|
699
|
+
setConnectionState("connected");
|
|
700
|
+
setError(void 0);
|
|
701
|
+
const wasReconnecting = retryCountRef.current > 0;
|
|
702
|
+
retryCountRef.current = 0;
|
|
703
|
+
updateMetrics({
|
|
704
|
+
connectedAt: Date.now(),
|
|
705
|
+
latency: connectionTimeMs,
|
|
706
|
+
transportType: "sse",
|
|
707
|
+
reconnectCount: wasReconnecting ? metrics.reconnectCount + 1 : metrics.reconnectCount
|
|
708
|
+
});
|
|
709
|
+
currentUserIdRef.current = userId;
|
|
710
|
+
if (currentChatKeyRef.current) {
|
|
711
|
+
logger.info("Loading chat after SSE reconnection:", currentChatKeyRef.current);
|
|
712
|
+
sendRestMessage("load", {
|
|
713
|
+
orgId,
|
|
714
|
+
chatKey: currentChatKeyRef.current,
|
|
715
|
+
userId
|
|
716
|
+
}).then((response) => {
|
|
717
|
+
if (response.success && response.data?.chat) {
|
|
718
|
+
const chatEvent = {
|
|
719
|
+
type: "load_chat_response",
|
|
720
|
+
orgId,
|
|
721
|
+
chatKey: currentChatKeyRef.current,
|
|
722
|
+
userId,
|
|
723
|
+
timestamp: Date.now(),
|
|
724
|
+
data: response.data
|
|
725
|
+
};
|
|
726
|
+
emit("load_chat_response", chatEvent);
|
|
727
|
+
if (onMessageRef.current) {
|
|
728
|
+
onMessageRef.current(chatEvent);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}).catch((err) => {
|
|
732
|
+
logger.error("Failed to load chat after SSE reconnection:", err);
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
emit("connected", { userId, wasReconnecting, transport: "sse" });
|
|
736
|
+
resolve();
|
|
737
|
+
};
|
|
738
|
+
const handleSSEMessage = (event) => {
|
|
739
|
+
if (!mountedRef.current) return;
|
|
740
|
+
try {
|
|
741
|
+
const data = JSON.parse(event.data);
|
|
742
|
+
if (!isChatEvent(data)) {
|
|
743
|
+
logger.warn("Received invalid SSE message format:", data);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const chatEvent = data;
|
|
747
|
+
logger.debug("SSE message received:", chatEvent.type);
|
|
748
|
+
updateMetrics({
|
|
749
|
+
messagesReceived: metrics.messagesReceived + 1,
|
|
750
|
+
lastMessageAt: Date.now()
|
|
751
|
+
});
|
|
752
|
+
switch (chatEvent.type) {
|
|
753
|
+
case "new_chat_created":
|
|
754
|
+
const newChatKey = chatEvent.data?.chatKey;
|
|
755
|
+
if (newChatKey) {
|
|
756
|
+
logger.info("New chat created with key:", newChatKey);
|
|
757
|
+
currentChatKeyRef.current = newChatKey;
|
|
758
|
+
if (chatCreationPromiseRef.current) {
|
|
759
|
+
chatCreationPromiseRef.current.resolve(newChatKey);
|
|
760
|
+
chatCreationPromiseRef.current = null;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
break;
|
|
764
|
+
case "load_chat_response":
|
|
765
|
+
const chat = chatEvent.data?.chat;
|
|
766
|
+
if (chat && chat.key) {
|
|
767
|
+
logger.info("Chat loaded with key:", chat.key);
|
|
768
|
+
currentChatKeyRef.current = chat.key;
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
case "chat_ended":
|
|
772
|
+
logger.info("Chat ended, clearing key");
|
|
773
|
+
currentChatKeyRef.current = void 0;
|
|
774
|
+
break;
|
|
775
|
+
}
|
|
776
|
+
emit(chatEvent.type || "message", chatEvent);
|
|
777
|
+
if (onMessageRef.current) {
|
|
778
|
+
onMessageRef.current(chatEvent);
|
|
779
|
+
}
|
|
780
|
+
} catch (error2) {
|
|
781
|
+
logger.error("Failed to parse SSE message:", error2);
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
eventSource.addEventListener("message", handleSSEMessage);
|
|
785
|
+
eventSource.addEventListener("reconnected", handleSSEMessage);
|
|
786
|
+
eventSource.addEventListener("typing", handleSSEMessage);
|
|
787
|
+
eventSource.addEventListener("stopped_typing", handleSSEMessage);
|
|
788
|
+
eventSource.addEventListener("waiting", handleSSEMessage);
|
|
789
|
+
eventSource.addEventListener("waiting_for_agent", handleSSEMessage);
|
|
790
|
+
eventSource.addEventListener("human_agent_joined", handleSSEMessage);
|
|
791
|
+
eventSource.addEventListener("human_agent_left", handleSSEMessage);
|
|
792
|
+
eventSource.addEventListener("chat_ended", handleSSEMessage);
|
|
793
|
+
eventSource.addEventListener("chat_updated", handleSSEMessage);
|
|
794
|
+
eventSource.addEventListener("load_chat_response", handleSSEMessage);
|
|
795
|
+
eventSource.addEventListener("new_chat_created", handleSSEMessage);
|
|
796
|
+
eventSource.addEventListener("error", handleSSEMessage);
|
|
797
|
+
eventSource.addEventListener("show_csat_survey", handleSSEMessage);
|
|
798
|
+
eventSource.addEventListener("csat_response", handleSSEMessage);
|
|
799
|
+
eventSource.addEventListener("user_suggested_actions", handleSSEMessage);
|
|
800
|
+
eventSource.addEventListener("agent_execution_started", handleSSEMessage);
|
|
801
|
+
eventSource.addEventListener("agent_execution_ended", handleSSEMessage);
|
|
802
|
+
eventSource.addEventListener("agent_context_update", handleSSEMessage);
|
|
803
|
+
eventSource.addEventListener("plan_pending_approval", handleSSEMessage);
|
|
804
|
+
eventSource.addEventListener("step_started", handleSSEMessage);
|
|
805
|
+
eventSource.addEventListener("step_completed", handleSSEMessage);
|
|
806
|
+
eventSource.addEventListener("step_failed", handleSSEMessage);
|
|
807
|
+
eventSource.addEventListener("plan_completed", handleSSEMessage);
|
|
808
|
+
eventSource.addEventListener("skills_changed", handleSSEMessage);
|
|
809
|
+
eventSource.addEventListener("summary_update", handleSSEMessage);
|
|
810
|
+
eventSource.onerror = (error2) => {
|
|
811
|
+
logger.error("SSE error:", error2);
|
|
812
|
+
if (!mountedRef.current) return;
|
|
813
|
+
if (eventSource.readyState === EventSource.CLOSED) {
|
|
814
|
+
const sseError = {
|
|
815
|
+
code: "CONNECTION_FAILED",
|
|
816
|
+
message: "SSE connection failed",
|
|
817
|
+
retryable: true,
|
|
818
|
+
timestamp: Date.now()
|
|
819
|
+
};
|
|
820
|
+
setError(sseError);
|
|
821
|
+
updateMetrics({ lastError: sseError });
|
|
822
|
+
setConnectionState("disconnected");
|
|
823
|
+
emit("disconnected", { reason: "SSE error" });
|
|
824
|
+
if (!intentionalDisconnectRef.current && mountedRef.current) {
|
|
825
|
+
const retryInterval = calculateRetryInterval(retryCountRef.current);
|
|
826
|
+
retryCountRef.current++;
|
|
827
|
+
logger.info(`SSE reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`);
|
|
828
|
+
if (reconnectTimeoutRef.current) {
|
|
829
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
830
|
+
}
|
|
831
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
832
|
+
connect(userId);
|
|
833
|
+
}, retryInterval);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
sseRef.current = eventSource;
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
632
841
|
logger.debug("Connecting to WebSocket:", wsUrl);
|
|
633
842
|
console.log(`\u23F3 Initiating WebSocket connection to ${serverBaseUrl}...`);
|
|
634
843
|
const ws = new WebSocket(wsUrl);
|
|
@@ -900,7 +1109,7 @@ var useWebSocketChatBase = ({
|
|
|
900
1109
|
);
|
|
901
1110
|
const sendMessage = useCallback(
|
|
902
1111
|
(event, overrideUserId) => {
|
|
903
|
-
return new Promise((resolve, reject) => {
|
|
1112
|
+
return new Promise(async (resolve, reject) => {
|
|
904
1113
|
if (!mountedRef.current) {
|
|
905
1114
|
reject(new Error("Component not mounted"));
|
|
906
1115
|
return;
|
|
@@ -909,8 +1118,139 @@ var useWebSocketChatBase = ({
|
|
|
909
1118
|
...event,
|
|
910
1119
|
timestamp: Date.now()
|
|
911
1120
|
};
|
|
912
|
-
const messageId = `${fullEvent.type}_${fullEvent.timestamp}_${Math.random()}`;
|
|
913
1121
|
logger.debug("Sending message:", fullEvent.type);
|
|
1122
|
+
if (transportRef.current === "sse") {
|
|
1123
|
+
if (!sseRef.current || sseRef.current.readyState !== EventSource.OPEN) {
|
|
1124
|
+
logger.debug("SSE not connected, attempting to connect");
|
|
1125
|
+
if (connectionState === "disconnected" && overrideUserId) {
|
|
1126
|
+
try {
|
|
1127
|
+
await connect(overrideUserId);
|
|
1128
|
+
} catch (error2) {
|
|
1129
|
+
reject(error2);
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
} else {
|
|
1133
|
+
reject(new Error("SSE not connected"));
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
try {
|
|
1138
|
+
switch (fullEvent.type) {
|
|
1139
|
+
case "message":
|
|
1140
|
+
await sendRestMessage("send", {
|
|
1141
|
+
orgId: fullEvent.orgId,
|
|
1142
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1143
|
+
userId: fullEvent.userId,
|
|
1144
|
+
message: fullEvent.message
|
|
1145
|
+
});
|
|
1146
|
+
break;
|
|
1147
|
+
case "typing":
|
|
1148
|
+
await sendRestMessage("typing", {
|
|
1149
|
+
orgId: fullEvent.orgId,
|
|
1150
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1151
|
+
userId: fullEvent.userId,
|
|
1152
|
+
typing: true
|
|
1153
|
+
});
|
|
1154
|
+
break;
|
|
1155
|
+
case "stopped_typing":
|
|
1156
|
+
await sendRestMessage("typing", {
|
|
1157
|
+
orgId: fullEvent.orgId,
|
|
1158
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1159
|
+
userId: fullEvent.userId,
|
|
1160
|
+
typing: false
|
|
1161
|
+
});
|
|
1162
|
+
break;
|
|
1163
|
+
case "load_chat":
|
|
1164
|
+
const loadResponse = await sendRestMessage("load", {
|
|
1165
|
+
orgId: fullEvent.orgId,
|
|
1166
|
+
chatKey: fullEvent.chatKey,
|
|
1167
|
+
userId: fullEvent.userId
|
|
1168
|
+
});
|
|
1169
|
+
if (loadResponse.success && loadResponse.data?.chat) {
|
|
1170
|
+
currentChatKeyRef.current = loadResponse.data.chat.key;
|
|
1171
|
+
const chatEvent = {
|
|
1172
|
+
type: "load_chat_response",
|
|
1173
|
+
orgId: fullEvent.orgId,
|
|
1174
|
+
chatKey: loadResponse.data.chat.key,
|
|
1175
|
+
userId: fullEvent.userId,
|
|
1176
|
+
timestamp: Date.now(),
|
|
1177
|
+
data: loadResponse.data
|
|
1178
|
+
};
|
|
1179
|
+
emit("load_chat_response", chatEvent);
|
|
1180
|
+
if (onMessageRef.current) {
|
|
1181
|
+
onMessageRef.current(chatEvent);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
break;
|
|
1185
|
+
case "new_chat":
|
|
1186
|
+
const createResponse = await sendRestMessage("create", {
|
|
1187
|
+
orgId: fullEvent.orgId,
|
|
1188
|
+
userId: fullEvent.userId,
|
|
1189
|
+
metadata: fullEvent.data
|
|
1190
|
+
});
|
|
1191
|
+
if (createResponse.success && createResponse.data?.chatKey) {
|
|
1192
|
+
currentChatKeyRef.current = createResponse.data.chatKey;
|
|
1193
|
+
const newChatEvent = {
|
|
1194
|
+
type: "new_chat_created",
|
|
1195
|
+
orgId: fullEvent.orgId,
|
|
1196
|
+
chatKey: createResponse.data.chatKey,
|
|
1197
|
+
userId: fullEvent.userId,
|
|
1198
|
+
timestamp: Date.now(),
|
|
1199
|
+
data: { chatKey: createResponse.data.chatKey }
|
|
1200
|
+
};
|
|
1201
|
+
emit("new_chat_created", newChatEvent);
|
|
1202
|
+
if (onMessageRef.current) {
|
|
1203
|
+
onMessageRef.current(newChatEvent);
|
|
1204
|
+
}
|
|
1205
|
+
if (chatCreationPromiseRef.current) {
|
|
1206
|
+
chatCreationPromiseRef.current.resolve(createResponse.data.chatKey);
|
|
1207
|
+
chatCreationPromiseRef.current = null;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
break;
|
|
1211
|
+
case "end_chat":
|
|
1212
|
+
await sendRestMessage("end", {
|
|
1213
|
+
orgId: fullEvent.orgId,
|
|
1214
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1215
|
+
userId: fullEvent.userId,
|
|
1216
|
+
data: fullEvent.data
|
|
1217
|
+
});
|
|
1218
|
+
break;
|
|
1219
|
+
case "human_agent_join":
|
|
1220
|
+
await sendRestMessage("agent-join", {
|
|
1221
|
+
orgId: fullEvent.orgId,
|
|
1222
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1223
|
+
user: fullEvent.data?.user
|
|
1224
|
+
});
|
|
1225
|
+
break;
|
|
1226
|
+
case "human_agent_leave":
|
|
1227
|
+
await sendRestMessage("agent-leave", {
|
|
1228
|
+
orgId: fullEvent.orgId,
|
|
1229
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
1230
|
+
user: fullEvent.data?.user
|
|
1231
|
+
});
|
|
1232
|
+
break;
|
|
1233
|
+
default:
|
|
1234
|
+
logger.warn("Unrecognized event type for SSE REST:", fullEvent.type);
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
updateMetrics({ messagesSent: metrics.messagesSent + 1 });
|
|
1238
|
+
logger.debug("SSE REST message sent successfully");
|
|
1239
|
+
resolve();
|
|
1240
|
+
} catch (error2) {
|
|
1241
|
+
logger.error("Failed to send SSE REST message:", error2);
|
|
1242
|
+
const sendError = {
|
|
1243
|
+
code: "SEND_FAILED",
|
|
1244
|
+
message: error2 instanceof Error ? error2.message : "Failed to send message",
|
|
1245
|
+
retryable: true,
|
|
1246
|
+
timestamp: Date.now()
|
|
1247
|
+
};
|
|
1248
|
+
setError(sendError);
|
|
1249
|
+
updateMetrics({ lastError: sendError });
|
|
1250
|
+
reject(sendError);
|
|
1251
|
+
}
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
914
1254
|
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
|
|
915
1255
|
if (addToQueue(fullEvent)) {
|
|
916
1256
|
logger.debug("Message queued, attempting to connect");
|
|
@@ -947,7 +1287,7 @@ var useWebSocketChatBase = ({
|
|
|
947
1287
|
}
|
|
948
1288
|
});
|
|
949
1289
|
},
|
|
950
|
-
[connectionState, connect, addToQueue, logger, metrics, updateMetrics]
|
|
1290
|
+
[connectionState, connect, addToQueue, logger, metrics, updateMetrics, sendRestMessage, emit]
|
|
951
1291
|
);
|
|
952
1292
|
const startNewChat = useCallback(
|
|
953
1293
|
(userId, data) => {
|
|
@@ -985,7 +1325,7 @@ var useWebSocketChatBase = ({
|
|
|
985
1325
|
);
|
|
986
1326
|
const disconnect = useCallback(
|
|
987
1327
|
(intentional = true) => {
|
|
988
|
-
logger.info("Disconnecting
|
|
1328
|
+
logger.info("Disconnecting", { intentional, transport: transportRef.current });
|
|
989
1329
|
intentionalDisconnectRef.current = intentional;
|
|
990
1330
|
cleanup();
|
|
991
1331
|
setConnectionState("disconnected");
|
|
@@ -3662,6 +4002,9 @@ export {
|
|
|
3662
4002
|
ChatEventTypeRoomUserJoined,
|
|
3663
4003
|
ChatEventTypeRoomUserLeft,
|
|
3664
4004
|
ChatEventTypeRoomsResponse,
|
|
4005
|
+
ChatEventTypeSkillActivate,
|
|
4006
|
+
ChatEventTypeSkillDeactivate,
|
|
4007
|
+
ChatEventTypeSkillsChanged,
|
|
3665
4008
|
ChatEventTypeStepCompleted,
|
|
3666
4009
|
ChatEventTypeStepFailed,
|
|
3667
4010
|
ChatEventTypeStepStarted,
|