@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
|
@@ -51,6 +51,7 @@ var DEFAULT_QUEUE_CONFIG = {
|
|
|
51
51
|
};
|
|
52
52
|
var DEFAULT_HEARTBEAT_INTERVAL = 3e4;
|
|
53
53
|
var DEFAULT_HEARTBEAT_TIMEOUT = 5e3;
|
|
54
|
+
var DEFAULT_TRANSPORT = "websocket";
|
|
54
55
|
function isChatEvent(data) {
|
|
55
56
|
return data && typeof data === "object" && (typeof data.type === "string" || data.message);
|
|
56
57
|
}
|
|
@@ -65,7 +66,8 @@ var useWebSocketChatBase = ({
|
|
|
65
66
|
debug = false,
|
|
66
67
|
logger = createDefaultLogger(debug),
|
|
67
68
|
heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,
|
|
68
|
-
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT
|
|
69
|
+
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT,
|
|
70
|
+
transport = DEFAULT_TRANSPORT
|
|
69
71
|
}) => {
|
|
70
72
|
const [connectionState, setConnectionState] = (0, import_react.useState)("disconnected");
|
|
71
73
|
const [error, setError] = (0, import_react.useState)(void 0);
|
|
@@ -75,9 +77,15 @@ var useWebSocketChatBase = ({
|
|
|
75
77
|
messagesSent: 0,
|
|
76
78
|
messagesReceived: 0,
|
|
77
79
|
messagesQueued: 0,
|
|
78
|
-
reconnectCount: 0
|
|
80
|
+
reconnectCount: 0,
|
|
81
|
+
transportType: transport
|
|
79
82
|
});
|
|
80
83
|
const wsRef = (0, import_react.useRef)(void 0);
|
|
84
|
+
const sseRef = (0, import_react.useRef)(void 0);
|
|
85
|
+
const transportRef = (0, import_react.useRef)(transport);
|
|
86
|
+
(0, import_react.useEffect)(() => {
|
|
87
|
+
transportRef.current = transport;
|
|
88
|
+
}, [transport]);
|
|
81
89
|
const reconnectTimeoutRef = (0, import_react.useRef)(void 0);
|
|
82
90
|
const retryCountRef = (0, import_react.useRef)(0);
|
|
83
91
|
const messageQueueRef = (0, import_react.useRef)([]);
|
|
@@ -207,6 +215,10 @@ var useWebSocketChatBase = ({
|
|
|
207
215
|
wsRef.current.close(1e3, "Cleanup");
|
|
208
216
|
}
|
|
209
217
|
wsRef.current = void 0;
|
|
218
|
+
if (sseRef.current) {
|
|
219
|
+
sseRef.current.close();
|
|
220
|
+
sseRef.current = void 0;
|
|
221
|
+
}
|
|
210
222
|
if (reconnectTimeoutRef.current) {
|
|
211
223
|
clearTimeout(reconnectTimeoutRef.current);
|
|
212
224
|
reconnectTimeoutRef.current = void 0;
|
|
@@ -224,6 +236,35 @@ var useWebSocketChatBase = ({
|
|
|
224
236
|
});
|
|
225
237
|
loadChatRetryMapRef.current.clear();
|
|
226
238
|
}, [stopHeartbeat]);
|
|
239
|
+
const getRestApiUrl = (0, import_react.useCallback)((endpoint) => {
|
|
240
|
+
const httpUrl = serverBaseUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:");
|
|
241
|
+
return `${httpUrl}/${endpoint}`;
|
|
242
|
+
}, [serverBaseUrl]);
|
|
243
|
+
const sendRestMessage = (0, import_react.useCallback)(
|
|
244
|
+
async (endpoint, body) => {
|
|
245
|
+
const url = getRestApiUrl(endpoint);
|
|
246
|
+
logger.debug(`SSE REST API call: POST ${endpoint}`, body);
|
|
247
|
+
try {
|
|
248
|
+
const response = await fetch(url, {
|
|
249
|
+
method: "POST",
|
|
250
|
+
headers: {
|
|
251
|
+
"Content-Type": "application/json"
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(body)
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const errorText = await response.text();
|
|
257
|
+
throw new Error(`REST API error: ${response.status} - ${errorText}`);
|
|
258
|
+
}
|
|
259
|
+
const data = await response.json();
|
|
260
|
+
return data;
|
|
261
|
+
} catch (error2) {
|
|
262
|
+
logger.error(`SSE REST API error for ${endpoint}:`, error2);
|
|
263
|
+
throw error2;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
[getRestApiUrl, logger]
|
|
267
|
+
);
|
|
227
268
|
const connect = (0, import_react.useCallback)(
|
|
228
269
|
async (userId) => {
|
|
229
270
|
if (!mountedRef.current) {
|
|
@@ -241,7 +282,11 @@ var useWebSocketChatBase = ({
|
|
|
241
282
|
return Promise.reject(error2);
|
|
242
283
|
}
|
|
243
284
|
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
|
244
|
-
logger.debug("Already connected");
|
|
285
|
+
logger.debug("Already connected (WebSocket)");
|
|
286
|
+
return Promise.resolve();
|
|
287
|
+
}
|
|
288
|
+
if (sseRef.current?.readyState === EventSource.OPEN) {
|
|
289
|
+
logger.debug("Already connected (SSE)");
|
|
245
290
|
return Promise.resolve();
|
|
246
291
|
}
|
|
247
292
|
if (connectionState === "connecting" || connectionState === "reconnecting") {
|
|
@@ -267,8 +312,169 @@ var useWebSocketChatBase = ({
|
|
|
267
312
|
intentionalDisconnectRef.current = false;
|
|
268
313
|
return new Promise((resolve, reject) => {
|
|
269
314
|
try {
|
|
270
|
-
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
271
315
|
const connectionStartTime = Date.now();
|
|
316
|
+
logger.info(`\u{1F504} Connecting with transport: ${transportRef.current}`);
|
|
317
|
+
if (transportRef.current === "sse") {
|
|
318
|
+
const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || ""}`);
|
|
319
|
+
logger.debug("Connecting to SSE:", sseUrl);
|
|
320
|
+
console.log(`\u23F3 Initiating SSE connection to ${serverBaseUrl}...`);
|
|
321
|
+
const eventSource = new EventSource(sseUrl);
|
|
322
|
+
eventSource.onopen = () => {
|
|
323
|
+
if (!mountedRef.current) {
|
|
324
|
+
eventSource.close();
|
|
325
|
+
reject(new Error("Component unmounted"));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const connectionTimeMs = Date.now() - connectionStartTime;
|
|
329
|
+
const connectionTimeSec = (connectionTimeMs / 1e3).toFixed(2);
|
|
330
|
+
logger.info("\u2705 SSE connected", {
|
|
331
|
+
userId,
|
|
332
|
+
retryCount: retryCountRef.current,
|
|
333
|
+
connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`
|
|
334
|
+
});
|
|
335
|
+
console.log(`\u{1F50C} SSE connection established in ${connectionTimeSec} seconds`);
|
|
336
|
+
setConnectionState("connected");
|
|
337
|
+
setError(void 0);
|
|
338
|
+
const wasReconnecting = retryCountRef.current > 0;
|
|
339
|
+
retryCountRef.current = 0;
|
|
340
|
+
updateMetrics({
|
|
341
|
+
connectedAt: Date.now(),
|
|
342
|
+
latency: connectionTimeMs,
|
|
343
|
+
transportType: "sse",
|
|
344
|
+
reconnectCount: wasReconnecting ? metrics.reconnectCount + 1 : metrics.reconnectCount
|
|
345
|
+
});
|
|
346
|
+
currentUserIdRef.current = userId;
|
|
347
|
+
if (currentChatKeyRef.current) {
|
|
348
|
+
logger.info("Loading chat after SSE reconnection:", currentChatKeyRef.current);
|
|
349
|
+
sendRestMessage("load", {
|
|
350
|
+
orgId,
|
|
351
|
+
chatKey: currentChatKeyRef.current,
|
|
352
|
+
userId
|
|
353
|
+
}).then((response) => {
|
|
354
|
+
if (response.success && response.data?.chat) {
|
|
355
|
+
const chatEvent = {
|
|
356
|
+
type: "load_chat_response",
|
|
357
|
+
orgId,
|
|
358
|
+
chatKey: currentChatKeyRef.current,
|
|
359
|
+
userId,
|
|
360
|
+
timestamp: Date.now(),
|
|
361
|
+
data: response.data
|
|
362
|
+
};
|
|
363
|
+
emit("load_chat_response", chatEvent);
|
|
364
|
+
if (onMessageRef.current) {
|
|
365
|
+
onMessageRef.current(chatEvent);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}).catch((err) => {
|
|
369
|
+
logger.error("Failed to load chat after SSE reconnection:", err);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
emit("connected", { userId, wasReconnecting, transport: "sse" });
|
|
373
|
+
resolve();
|
|
374
|
+
};
|
|
375
|
+
const handleSSEMessage = (event) => {
|
|
376
|
+
if (!mountedRef.current) return;
|
|
377
|
+
try {
|
|
378
|
+
const data = JSON.parse(event.data);
|
|
379
|
+
if (!isChatEvent(data)) {
|
|
380
|
+
logger.warn("Received invalid SSE message format:", data);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const chatEvent = data;
|
|
384
|
+
logger.debug("SSE message received:", chatEvent.type);
|
|
385
|
+
updateMetrics({
|
|
386
|
+
messagesReceived: metrics.messagesReceived + 1,
|
|
387
|
+
lastMessageAt: Date.now()
|
|
388
|
+
});
|
|
389
|
+
switch (chatEvent.type) {
|
|
390
|
+
case "new_chat_created":
|
|
391
|
+
const newChatKey = chatEvent.data?.chatKey;
|
|
392
|
+
if (newChatKey) {
|
|
393
|
+
logger.info("New chat created with key:", newChatKey);
|
|
394
|
+
currentChatKeyRef.current = newChatKey;
|
|
395
|
+
if (chatCreationPromiseRef.current) {
|
|
396
|
+
chatCreationPromiseRef.current.resolve(newChatKey);
|
|
397
|
+
chatCreationPromiseRef.current = null;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
break;
|
|
401
|
+
case "load_chat_response":
|
|
402
|
+
const chat = chatEvent.data?.chat;
|
|
403
|
+
if (chat && chat.key) {
|
|
404
|
+
logger.info("Chat loaded with key:", chat.key);
|
|
405
|
+
currentChatKeyRef.current = chat.key;
|
|
406
|
+
}
|
|
407
|
+
break;
|
|
408
|
+
case "chat_ended":
|
|
409
|
+
logger.info("Chat ended, clearing key");
|
|
410
|
+
currentChatKeyRef.current = void 0;
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
emit(chatEvent.type || "message", chatEvent);
|
|
414
|
+
if (onMessageRef.current) {
|
|
415
|
+
onMessageRef.current(chatEvent);
|
|
416
|
+
}
|
|
417
|
+
} catch (error2) {
|
|
418
|
+
logger.error("Failed to parse SSE message:", error2);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
eventSource.addEventListener("message", handleSSEMessage);
|
|
422
|
+
eventSource.addEventListener("reconnected", handleSSEMessage);
|
|
423
|
+
eventSource.addEventListener("typing", handleSSEMessage);
|
|
424
|
+
eventSource.addEventListener("stopped_typing", handleSSEMessage);
|
|
425
|
+
eventSource.addEventListener("waiting", handleSSEMessage);
|
|
426
|
+
eventSource.addEventListener("waiting_for_agent", handleSSEMessage);
|
|
427
|
+
eventSource.addEventListener("human_agent_joined", handleSSEMessage);
|
|
428
|
+
eventSource.addEventListener("human_agent_left", handleSSEMessage);
|
|
429
|
+
eventSource.addEventListener("chat_ended", handleSSEMessage);
|
|
430
|
+
eventSource.addEventListener("chat_updated", handleSSEMessage);
|
|
431
|
+
eventSource.addEventListener("load_chat_response", handleSSEMessage);
|
|
432
|
+
eventSource.addEventListener("new_chat_created", handleSSEMessage);
|
|
433
|
+
eventSource.addEventListener("error", handleSSEMessage);
|
|
434
|
+
eventSource.addEventListener("show_csat_survey", handleSSEMessage);
|
|
435
|
+
eventSource.addEventListener("csat_response", handleSSEMessage);
|
|
436
|
+
eventSource.addEventListener("user_suggested_actions", handleSSEMessage);
|
|
437
|
+
eventSource.addEventListener("agent_execution_started", handleSSEMessage);
|
|
438
|
+
eventSource.addEventListener("agent_execution_ended", handleSSEMessage);
|
|
439
|
+
eventSource.addEventListener("agent_context_update", handleSSEMessage);
|
|
440
|
+
eventSource.addEventListener("plan_pending_approval", handleSSEMessage);
|
|
441
|
+
eventSource.addEventListener("step_started", handleSSEMessage);
|
|
442
|
+
eventSource.addEventListener("step_completed", handleSSEMessage);
|
|
443
|
+
eventSource.addEventListener("step_failed", handleSSEMessage);
|
|
444
|
+
eventSource.addEventListener("plan_completed", handleSSEMessage);
|
|
445
|
+
eventSource.addEventListener("skills_changed", handleSSEMessage);
|
|
446
|
+
eventSource.addEventListener("summary_update", handleSSEMessage);
|
|
447
|
+
eventSource.onerror = (error2) => {
|
|
448
|
+
logger.error("SSE error:", error2);
|
|
449
|
+
if (!mountedRef.current) return;
|
|
450
|
+
if (eventSource.readyState === EventSource.CLOSED) {
|
|
451
|
+
const sseError = {
|
|
452
|
+
code: "CONNECTION_FAILED",
|
|
453
|
+
message: "SSE connection failed",
|
|
454
|
+
retryable: true,
|
|
455
|
+
timestamp: Date.now()
|
|
456
|
+
};
|
|
457
|
+
setError(sseError);
|
|
458
|
+
updateMetrics({ lastError: sseError });
|
|
459
|
+
setConnectionState("disconnected");
|
|
460
|
+
emit("disconnected", { reason: "SSE error" });
|
|
461
|
+
if (!intentionalDisconnectRef.current && mountedRef.current) {
|
|
462
|
+
const retryInterval = calculateRetryInterval(retryCountRef.current);
|
|
463
|
+
retryCountRef.current++;
|
|
464
|
+
logger.info(`SSE reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`);
|
|
465
|
+
if (reconnectTimeoutRef.current) {
|
|
466
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
467
|
+
}
|
|
468
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
469
|
+
connect(userId);
|
|
470
|
+
}, retryInterval);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
sseRef.current = eventSource;
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
272
478
|
logger.debug("Connecting to WebSocket:", wsUrl);
|
|
273
479
|
console.log(`\u23F3 Initiating WebSocket connection to ${serverBaseUrl}...`);
|
|
274
480
|
const ws = new WebSocket(wsUrl);
|
|
@@ -540,7 +746,7 @@ var useWebSocketChatBase = ({
|
|
|
540
746
|
);
|
|
541
747
|
const sendMessage = (0, import_react.useCallback)(
|
|
542
748
|
(event, overrideUserId) => {
|
|
543
|
-
return new Promise((resolve, reject) => {
|
|
749
|
+
return new Promise(async (resolve, reject) => {
|
|
544
750
|
if (!mountedRef.current) {
|
|
545
751
|
reject(new Error("Component not mounted"));
|
|
546
752
|
return;
|
|
@@ -549,8 +755,139 @@ var useWebSocketChatBase = ({
|
|
|
549
755
|
...event,
|
|
550
756
|
timestamp: Date.now()
|
|
551
757
|
};
|
|
552
|
-
const messageId = `${fullEvent.type}_${fullEvent.timestamp}_${Math.random()}`;
|
|
553
758
|
logger.debug("Sending message:", fullEvent.type);
|
|
759
|
+
if (transportRef.current === "sse") {
|
|
760
|
+
if (!sseRef.current || sseRef.current.readyState !== EventSource.OPEN) {
|
|
761
|
+
logger.debug("SSE not connected, attempting to connect");
|
|
762
|
+
if (connectionState === "disconnected" && overrideUserId) {
|
|
763
|
+
try {
|
|
764
|
+
await connect(overrideUserId);
|
|
765
|
+
} catch (error2) {
|
|
766
|
+
reject(error2);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
} else {
|
|
770
|
+
reject(new Error("SSE not connected"));
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
try {
|
|
775
|
+
switch (fullEvent.type) {
|
|
776
|
+
case "message":
|
|
777
|
+
await sendRestMessage("send", {
|
|
778
|
+
orgId: fullEvent.orgId,
|
|
779
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
780
|
+
userId: fullEvent.userId,
|
|
781
|
+
message: fullEvent.message
|
|
782
|
+
});
|
|
783
|
+
break;
|
|
784
|
+
case "typing":
|
|
785
|
+
await sendRestMessage("typing", {
|
|
786
|
+
orgId: fullEvent.orgId,
|
|
787
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
788
|
+
userId: fullEvent.userId,
|
|
789
|
+
typing: true
|
|
790
|
+
});
|
|
791
|
+
break;
|
|
792
|
+
case "stopped_typing":
|
|
793
|
+
await sendRestMessage("typing", {
|
|
794
|
+
orgId: fullEvent.orgId,
|
|
795
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
796
|
+
userId: fullEvent.userId,
|
|
797
|
+
typing: false
|
|
798
|
+
});
|
|
799
|
+
break;
|
|
800
|
+
case "load_chat":
|
|
801
|
+
const loadResponse = await sendRestMessage("load", {
|
|
802
|
+
orgId: fullEvent.orgId,
|
|
803
|
+
chatKey: fullEvent.chatKey,
|
|
804
|
+
userId: fullEvent.userId
|
|
805
|
+
});
|
|
806
|
+
if (loadResponse.success && loadResponse.data?.chat) {
|
|
807
|
+
currentChatKeyRef.current = loadResponse.data.chat.key;
|
|
808
|
+
const chatEvent = {
|
|
809
|
+
type: "load_chat_response",
|
|
810
|
+
orgId: fullEvent.orgId,
|
|
811
|
+
chatKey: loadResponse.data.chat.key,
|
|
812
|
+
userId: fullEvent.userId,
|
|
813
|
+
timestamp: Date.now(),
|
|
814
|
+
data: loadResponse.data
|
|
815
|
+
};
|
|
816
|
+
emit("load_chat_response", chatEvent);
|
|
817
|
+
if (onMessageRef.current) {
|
|
818
|
+
onMessageRef.current(chatEvent);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
break;
|
|
822
|
+
case "new_chat":
|
|
823
|
+
const createResponse = await sendRestMessage("create", {
|
|
824
|
+
orgId: fullEvent.orgId,
|
|
825
|
+
userId: fullEvent.userId,
|
|
826
|
+
metadata: fullEvent.data
|
|
827
|
+
});
|
|
828
|
+
if (createResponse.success && createResponse.data?.chatKey) {
|
|
829
|
+
currentChatKeyRef.current = createResponse.data.chatKey;
|
|
830
|
+
const newChatEvent = {
|
|
831
|
+
type: "new_chat_created",
|
|
832
|
+
orgId: fullEvent.orgId,
|
|
833
|
+
chatKey: createResponse.data.chatKey,
|
|
834
|
+
userId: fullEvent.userId,
|
|
835
|
+
timestamp: Date.now(),
|
|
836
|
+
data: { chatKey: createResponse.data.chatKey }
|
|
837
|
+
};
|
|
838
|
+
emit("new_chat_created", newChatEvent);
|
|
839
|
+
if (onMessageRef.current) {
|
|
840
|
+
onMessageRef.current(newChatEvent);
|
|
841
|
+
}
|
|
842
|
+
if (chatCreationPromiseRef.current) {
|
|
843
|
+
chatCreationPromiseRef.current.resolve(createResponse.data.chatKey);
|
|
844
|
+
chatCreationPromiseRef.current = null;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
break;
|
|
848
|
+
case "end_chat":
|
|
849
|
+
await sendRestMessage("end", {
|
|
850
|
+
orgId: fullEvent.orgId,
|
|
851
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
852
|
+
userId: fullEvent.userId,
|
|
853
|
+
data: fullEvent.data
|
|
854
|
+
});
|
|
855
|
+
break;
|
|
856
|
+
case "human_agent_join":
|
|
857
|
+
await sendRestMessage("agent-join", {
|
|
858
|
+
orgId: fullEvent.orgId,
|
|
859
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
860
|
+
user: fullEvent.data?.user
|
|
861
|
+
});
|
|
862
|
+
break;
|
|
863
|
+
case "human_agent_leave":
|
|
864
|
+
await sendRestMessage("agent-leave", {
|
|
865
|
+
orgId: fullEvent.orgId,
|
|
866
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
867
|
+
user: fullEvent.data?.user
|
|
868
|
+
});
|
|
869
|
+
break;
|
|
870
|
+
default:
|
|
871
|
+
logger.warn("Unrecognized event type for SSE REST:", fullEvent.type);
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
updateMetrics({ messagesSent: metrics.messagesSent + 1 });
|
|
875
|
+
logger.debug("SSE REST message sent successfully");
|
|
876
|
+
resolve();
|
|
877
|
+
} catch (error2) {
|
|
878
|
+
logger.error("Failed to send SSE REST message:", error2);
|
|
879
|
+
const sendError = {
|
|
880
|
+
code: "SEND_FAILED",
|
|
881
|
+
message: error2 instanceof Error ? error2.message : "Failed to send message",
|
|
882
|
+
retryable: true,
|
|
883
|
+
timestamp: Date.now()
|
|
884
|
+
};
|
|
885
|
+
setError(sendError);
|
|
886
|
+
updateMetrics({ lastError: sendError });
|
|
887
|
+
reject(sendError);
|
|
888
|
+
}
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
554
891
|
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
|
|
555
892
|
if (addToQueue(fullEvent)) {
|
|
556
893
|
logger.debug("Message queued, attempting to connect");
|
|
@@ -587,7 +924,7 @@ var useWebSocketChatBase = ({
|
|
|
587
924
|
}
|
|
588
925
|
});
|
|
589
926
|
},
|
|
590
|
-
[connectionState, connect, addToQueue, logger, metrics, updateMetrics]
|
|
927
|
+
[connectionState, connect, addToQueue, logger, metrics, updateMetrics, sendRestMessage, emit]
|
|
591
928
|
);
|
|
592
929
|
const startNewChat = (0, import_react.useCallback)(
|
|
593
930
|
(userId, data) => {
|
|
@@ -625,7 +962,7 @@ var useWebSocketChatBase = ({
|
|
|
625
962
|
);
|
|
626
963
|
const disconnect = (0, import_react.useCallback)(
|
|
627
964
|
(intentional = true) => {
|
|
628
|
-
logger.info("Disconnecting
|
|
965
|
+
logger.info("Disconnecting", { intentional, transport: transportRef.current });
|
|
629
966
|
intentionalDisconnectRef.current = intentional;
|
|
630
967
|
cleanup();
|
|
631
968
|
setConnectionState("disconnected");
|