@elqnt/chat 1.0.9 → 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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +345 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +345 -8
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.mts +1 -1
- package/dist/models/index.d.ts +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@ var DEFAULT_QUEUE_CONFIG = {
|
|
|
28
28
|
};
|
|
29
29
|
var DEFAULT_HEARTBEAT_INTERVAL = 3e4;
|
|
30
30
|
var DEFAULT_HEARTBEAT_TIMEOUT = 5e3;
|
|
31
|
+
var DEFAULT_TRANSPORT = "websocket";
|
|
31
32
|
function isChatEvent(data) {
|
|
32
33
|
return data && typeof data === "object" && (typeof data.type === "string" || data.message);
|
|
33
34
|
}
|
|
@@ -42,7 +43,8 @@ var useWebSocketChatBase = ({
|
|
|
42
43
|
debug = false,
|
|
43
44
|
logger = createDefaultLogger(debug),
|
|
44
45
|
heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL,
|
|
45
|
-
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT
|
|
46
|
+
heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT,
|
|
47
|
+
transport = DEFAULT_TRANSPORT
|
|
46
48
|
}) => {
|
|
47
49
|
const [connectionState, setConnectionState] = useState("disconnected");
|
|
48
50
|
const [error, setError] = useState(void 0);
|
|
@@ -52,9 +54,15 @@ var useWebSocketChatBase = ({
|
|
|
52
54
|
messagesSent: 0,
|
|
53
55
|
messagesReceived: 0,
|
|
54
56
|
messagesQueued: 0,
|
|
55
|
-
reconnectCount: 0
|
|
57
|
+
reconnectCount: 0,
|
|
58
|
+
transportType: transport
|
|
56
59
|
});
|
|
57
60
|
const wsRef = useRef(void 0);
|
|
61
|
+
const sseRef = useRef(void 0);
|
|
62
|
+
const transportRef = useRef(transport);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
transportRef.current = transport;
|
|
65
|
+
}, [transport]);
|
|
58
66
|
const reconnectTimeoutRef = useRef(void 0);
|
|
59
67
|
const retryCountRef = useRef(0);
|
|
60
68
|
const messageQueueRef = useRef([]);
|
|
@@ -184,6 +192,10 @@ var useWebSocketChatBase = ({
|
|
|
184
192
|
wsRef.current.close(1e3, "Cleanup");
|
|
185
193
|
}
|
|
186
194
|
wsRef.current = void 0;
|
|
195
|
+
if (sseRef.current) {
|
|
196
|
+
sseRef.current.close();
|
|
197
|
+
sseRef.current = void 0;
|
|
198
|
+
}
|
|
187
199
|
if (reconnectTimeoutRef.current) {
|
|
188
200
|
clearTimeout(reconnectTimeoutRef.current);
|
|
189
201
|
reconnectTimeoutRef.current = void 0;
|
|
@@ -201,6 +213,35 @@ var useWebSocketChatBase = ({
|
|
|
201
213
|
});
|
|
202
214
|
loadChatRetryMapRef.current.clear();
|
|
203
215
|
}, [stopHeartbeat]);
|
|
216
|
+
const getRestApiUrl = useCallback((endpoint) => {
|
|
217
|
+
const httpUrl = serverBaseUrl.replace(/^wss:/, "https:").replace(/^ws:/, "http:");
|
|
218
|
+
return `${httpUrl}/${endpoint}`;
|
|
219
|
+
}, [serverBaseUrl]);
|
|
220
|
+
const sendRestMessage = useCallback(
|
|
221
|
+
async (endpoint, body) => {
|
|
222
|
+
const url = getRestApiUrl(endpoint);
|
|
223
|
+
logger.debug(`SSE REST API call: POST ${endpoint}`, body);
|
|
224
|
+
try {
|
|
225
|
+
const response = await fetch(url, {
|
|
226
|
+
method: "POST",
|
|
227
|
+
headers: {
|
|
228
|
+
"Content-Type": "application/json"
|
|
229
|
+
},
|
|
230
|
+
body: JSON.stringify(body)
|
|
231
|
+
});
|
|
232
|
+
if (!response.ok) {
|
|
233
|
+
const errorText = await response.text();
|
|
234
|
+
throw new Error(`REST API error: ${response.status} - ${errorText}`);
|
|
235
|
+
}
|
|
236
|
+
const data = await response.json();
|
|
237
|
+
return data;
|
|
238
|
+
} catch (error2) {
|
|
239
|
+
logger.error(`SSE REST API error for ${endpoint}:`, error2);
|
|
240
|
+
throw error2;
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
[getRestApiUrl, logger]
|
|
244
|
+
);
|
|
204
245
|
const connect = useCallback(
|
|
205
246
|
async (userId) => {
|
|
206
247
|
if (!mountedRef.current) {
|
|
@@ -218,7 +259,11 @@ var useWebSocketChatBase = ({
|
|
|
218
259
|
return Promise.reject(error2);
|
|
219
260
|
}
|
|
220
261
|
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
|
221
|
-
logger.debug("Already connected");
|
|
262
|
+
logger.debug("Already connected (WebSocket)");
|
|
263
|
+
return Promise.resolve();
|
|
264
|
+
}
|
|
265
|
+
if (sseRef.current?.readyState === EventSource.OPEN) {
|
|
266
|
+
logger.debug("Already connected (SSE)");
|
|
222
267
|
return Promise.resolve();
|
|
223
268
|
}
|
|
224
269
|
if (connectionState === "connecting" || connectionState === "reconnecting") {
|
|
@@ -244,8 +289,169 @@ var useWebSocketChatBase = ({
|
|
|
244
289
|
intentionalDisconnectRef.current = false;
|
|
245
290
|
return new Promise((resolve, reject) => {
|
|
246
291
|
try {
|
|
247
|
-
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
248
292
|
const connectionStartTime = Date.now();
|
|
293
|
+
logger.info(`\u{1F504} Connecting with transport: ${transportRef.current}`);
|
|
294
|
+
if (transportRef.current === "sse") {
|
|
295
|
+
const sseUrl = getRestApiUrl(`stream?orgId=${orgId}&userId=${userId}&clientType=${clientType}&chatId=${currentChatKeyRef.current || ""}`);
|
|
296
|
+
logger.debug("Connecting to SSE:", sseUrl);
|
|
297
|
+
console.log(`\u23F3 Initiating SSE connection to ${serverBaseUrl}...`);
|
|
298
|
+
const eventSource = new EventSource(sseUrl);
|
|
299
|
+
eventSource.onopen = () => {
|
|
300
|
+
if (!mountedRef.current) {
|
|
301
|
+
eventSource.close();
|
|
302
|
+
reject(new Error("Component unmounted"));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const connectionTimeMs = Date.now() - connectionStartTime;
|
|
306
|
+
const connectionTimeSec = (connectionTimeMs / 1e3).toFixed(2);
|
|
307
|
+
logger.info("\u2705 SSE connected", {
|
|
308
|
+
userId,
|
|
309
|
+
retryCount: retryCountRef.current,
|
|
310
|
+
connectionTime: `${connectionTimeSec}s (${connectionTimeMs}ms)`
|
|
311
|
+
});
|
|
312
|
+
console.log(`\u{1F50C} SSE connection established in ${connectionTimeSec} seconds`);
|
|
313
|
+
setConnectionState("connected");
|
|
314
|
+
setError(void 0);
|
|
315
|
+
const wasReconnecting = retryCountRef.current > 0;
|
|
316
|
+
retryCountRef.current = 0;
|
|
317
|
+
updateMetrics({
|
|
318
|
+
connectedAt: Date.now(),
|
|
319
|
+
latency: connectionTimeMs,
|
|
320
|
+
transportType: "sse",
|
|
321
|
+
reconnectCount: wasReconnecting ? metrics.reconnectCount + 1 : metrics.reconnectCount
|
|
322
|
+
});
|
|
323
|
+
currentUserIdRef.current = userId;
|
|
324
|
+
if (currentChatKeyRef.current) {
|
|
325
|
+
logger.info("Loading chat after SSE reconnection:", currentChatKeyRef.current);
|
|
326
|
+
sendRestMessage("load", {
|
|
327
|
+
orgId,
|
|
328
|
+
chatKey: currentChatKeyRef.current,
|
|
329
|
+
userId
|
|
330
|
+
}).then((response) => {
|
|
331
|
+
if (response.success && response.data?.chat) {
|
|
332
|
+
const chatEvent = {
|
|
333
|
+
type: "load_chat_response",
|
|
334
|
+
orgId,
|
|
335
|
+
chatKey: currentChatKeyRef.current,
|
|
336
|
+
userId,
|
|
337
|
+
timestamp: Date.now(),
|
|
338
|
+
data: response.data
|
|
339
|
+
};
|
|
340
|
+
emit("load_chat_response", chatEvent);
|
|
341
|
+
if (onMessageRef.current) {
|
|
342
|
+
onMessageRef.current(chatEvent);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}).catch((err) => {
|
|
346
|
+
logger.error("Failed to load chat after SSE reconnection:", err);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
emit("connected", { userId, wasReconnecting, transport: "sse" });
|
|
350
|
+
resolve();
|
|
351
|
+
};
|
|
352
|
+
const handleSSEMessage = (event) => {
|
|
353
|
+
if (!mountedRef.current) return;
|
|
354
|
+
try {
|
|
355
|
+
const data = JSON.parse(event.data);
|
|
356
|
+
if (!isChatEvent(data)) {
|
|
357
|
+
logger.warn("Received invalid SSE message format:", data);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const chatEvent = data;
|
|
361
|
+
logger.debug("SSE message received:", chatEvent.type);
|
|
362
|
+
updateMetrics({
|
|
363
|
+
messagesReceived: metrics.messagesReceived + 1,
|
|
364
|
+
lastMessageAt: Date.now()
|
|
365
|
+
});
|
|
366
|
+
switch (chatEvent.type) {
|
|
367
|
+
case "new_chat_created":
|
|
368
|
+
const newChatKey = chatEvent.data?.chatKey;
|
|
369
|
+
if (newChatKey) {
|
|
370
|
+
logger.info("New chat created with key:", newChatKey);
|
|
371
|
+
currentChatKeyRef.current = newChatKey;
|
|
372
|
+
if (chatCreationPromiseRef.current) {
|
|
373
|
+
chatCreationPromiseRef.current.resolve(newChatKey);
|
|
374
|
+
chatCreationPromiseRef.current = null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
break;
|
|
378
|
+
case "load_chat_response":
|
|
379
|
+
const chat = chatEvent.data?.chat;
|
|
380
|
+
if (chat && chat.key) {
|
|
381
|
+
logger.info("Chat loaded with key:", chat.key);
|
|
382
|
+
currentChatKeyRef.current = chat.key;
|
|
383
|
+
}
|
|
384
|
+
break;
|
|
385
|
+
case "chat_ended":
|
|
386
|
+
logger.info("Chat ended, clearing key");
|
|
387
|
+
currentChatKeyRef.current = void 0;
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
emit(chatEvent.type || "message", chatEvent);
|
|
391
|
+
if (onMessageRef.current) {
|
|
392
|
+
onMessageRef.current(chatEvent);
|
|
393
|
+
}
|
|
394
|
+
} catch (error2) {
|
|
395
|
+
logger.error("Failed to parse SSE message:", error2);
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
eventSource.addEventListener("message", handleSSEMessage);
|
|
399
|
+
eventSource.addEventListener("reconnected", handleSSEMessage);
|
|
400
|
+
eventSource.addEventListener("typing", handleSSEMessage);
|
|
401
|
+
eventSource.addEventListener("stopped_typing", handleSSEMessage);
|
|
402
|
+
eventSource.addEventListener("waiting", handleSSEMessage);
|
|
403
|
+
eventSource.addEventListener("waiting_for_agent", handleSSEMessage);
|
|
404
|
+
eventSource.addEventListener("human_agent_joined", handleSSEMessage);
|
|
405
|
+
eventSource.addEventListener("human_agent_left", handleSSEMessage);
|
|
406
|
+
eventSource.addEventListener("chat_ended", handleSSEMessage);
|
|
407
|
+
eventSource.addEventListener("chat_updated", handleSSEMessage);
|
|
408
|
+
eventSource.addEventListener("load_chat_response", handleSSEMessage);
|
|
409
|
+
eventSource.addEventListener("new_chat_created", handleSSEMessage);
|
|
410
|
+
eventSource.addEventListener("error", handleSSEMessage);
|
|
411
|
+
eventSource.addEventListener("show_csat_survey", handleSSEMessage);
|
|
412
|
+
eventSource.addEventListener("csat_response", handleSSEMessage);
|
|
413
|
+
eventSource.addEventListener("user_suggested_actions", handleSSEMessage);
|
|
414
|
+
eventSource.addEventListener("agent_execution_started", handleSSEMessage);
|
|
415
|
+
eventSource.addEventListener("agent_execution_ended", handleSSEMessage);
|
|
416
|
+
eventSource.addEventListener("agent_context_update", handleSSEMessage);
|
|
417
|
+
eventSource.addEventListener("plan_pending_approval", handleSSEMessage);
|
|
418
|
+
eventSource.addEventListener("step_started", handleSSEMessage);
|
|
419
|
+
eventSource.addEventListener("step_completed", handleSSEMessage);
|
|
420
|
+
eventSource.addEventListener("step_failed", handleSSEMessage);
|
|
421
|
+
eventSource.addEventListener("plan_completed", handleSSEMessage);
|
|
422
|
+
eventSource.addEventListener("skills_changed", handleSSEMessage);
|
|
423
|
+
eventSource.addEventListener("summary_update", handleSSEMessage);
|
|
424
|
+
eventSource.onerror = (error2) => {
|
|
425
|
+
logger.error("SSE error:", error2);
|
|
426
|
+
if (!mountedRef.current) return;
|
|
427
|
+
if (eventSource.readyState === EventSource.CLOSED) {
|
|
428
|
+
const sseError = {
|
|
429
|
+
code: "CONNECTION_FAILED",
|
|
430
|
+
message: "SSE connection failed",
|
|
431
|
+
retryable: true,
|
|
432
|
+
timestamp: Date.now()
|
|
433
|
+
};
|
|
434
|
+
setError(sseError);
|
|
435
|
+
updateMetrics({ lastError: sseError });
|
|
436
|
+
setConnectionState("disconnected");
|
|
437
|
+
emit("disconnected", { reason: "SSE error" });
|
|
438
|
+
if (!intentionalDisconnectRef.current && mountedRef.current) {
|
|
439
|
+
const retryInterval = calculateRetryInterval(retryCountRef.current);
|
|
440
|
+
retryCountRef.current++;
|
|
441
|
+
logger.info(`SSE reconnecting in ${retryInterval}ms (attempt ${retryCountRef.current})`);
|
|
442
|
+
if (reconnectTimeoutRef.current) {
|
|
443
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
444
|
+
}
|
|
445
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
446
|
+
connect(userId);
|
|
447
|
+
}, retryInterval);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
sseRef.current = eventSource;
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const wsUrl = `${serverBaseUrl}?orgId=${orgId}&userId=${userId}&clientType=${clientType}&product=${product}`;
|
|
249
455
|
logger.debug("Connecting to WebSocket:", wsUrl);
|
|
250
456
|
console.log(`\u23F3 Initiating WebSocket connection to ${serverBaseUrl}...`);
|
|
251
457
|
const ws = new WebSocket(wsUrl);
|
|
@@ -517,7 +723,7 @@ var useWebSocketChatBase = ({
|
|
|
517
723
|
);
|
|
518
724
|
const sendMessage = useCallback(
|
|
519
725
|
(event, overrideUserId) => {
|
|
520
|
-
return new Promise((resolve, reject) => {
|
|
726
|
+
return new Promise(async (resolve, reject) => {
|
|
521
727
|
if (!mountedRef.current) {
|
|
522
728
|
reject(new Error("Component not mounted"));
|
|
523
729
|
return;
|
|
@@ -526,8 +732,139 @@ var useWebSocketChatBase = ({
|
|
|
526
732
|
...event,
|
|
527
733
|
timestamp: Date.now()
|
|
528
734
|
};
|
|
529
|
-
const messageId = `${fullEvent.type}_${fullEvent.timestamp}_${Math.random()}`;
|
|
530
735
|
logger.debug("Sending message:", fullEvent.type);
|
|
736
|
+
if (transportRef.current === "sse") {
|
|
737
|
+
if (!sseRef.current || sseRef.current.readyState !== EventSource.OPEN) {
|
|
738
|
+
logger.debug("SSE not connected, attempting to connect");
|
|
739
|
+
if (connectionState === "disconnected" && overrideUserId) {
|
|
740
|
+
try {
|
|
741
|
+
await connect(overrideUserId);
|
|
742
|
+
} catch (error2) {
|
|
743
|
+
reject(error2);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
} else {
|
|
747
|
+
reject(new Error("SSE not connected"));
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
try {
|
|
752
|
+
switch (fullEvent.type) {
|
|
753
|
+
case "message":
|
|
754
|
+
await sendRestMessage("send", {
|
|
755
|
+
orgId: fullEvent.orgId,
|
|
756
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
757
|
+
userId: fullEvent.userId,
|
|
758
|
+
message: fullEvent.message
|
|
759
|
+
});
|
|
760
|
+
break;
|
|
761
|
+
case "typing":
|
|
762
|
+
await sendRestMessage("typing", {
|
|
763
|
+
orgId: fullEvent.orgId,
|
|
764
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
765
|
+
userId: fullEvent.userId,
|
|
766
|
+
typing: true
|
|
767
|
+
});
|
|
768
|
+
break;
|
|
769
|
+
case "stopped_typing":
|
|
770
|
+
await sendRestMessage("typing", {
|
|
771
|
+
orgId: fullEvent.orgId,
|
|
772
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
773
|
+
userId: fullEvent.userId,
|
|
774
|
+
typing: false
|
|
775
|
+
});
|
|
776
|
+
break;
|
|
777
|
+
case "load_chat":
|
|
778
|
+
const loadResponse = await sendRestMessage("load", {
|
|
779
|
+
orgId: fullEvent.orgId,
|
|
780
|
+
chatKey: fullEvent.chatKey,
|
|
781
|
+
userId: fullEvent.userId
|
|
782
|
+
});
|
|
783
|
+
if (loadResponse.success && loadResponse.data?.chat) {
|
|
784
|
+
currentChatKeyRef.current = loadResponse.data.chat.key;
|
|
785
|
+
const chatEvent = {
|
|
786
|
+
type: "load_chat_response",
|
|
787
|
+
orgId: fullEvent.orgId,
|
|
788
|
+
chatKey: loadResponse.data.chat.key,
|
|
789
|
+
userId: fullEvent.userId,
|
|
790
|
+
timestamp: Date.now(),
|
|
791
|
+
data: loadResponse.data
|
|
792
|
+
};
|
|
793
|
+
emit("load_chat_response", chatEvent);
|
|
794
|
+
if (onMessageRef.current) {
|
|
795
|
+
onMessageRef.current(chatEvent);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
break;
|
|
799
|
+
case "new_chat":
|
|
800
|
+
const createResponse = await sendRestMessage("create", {
|
|
801
|
+
orgId: fullEvent.orgId,
|
|
802
|
+
userId: fullEvent.userId,
|
|
803
|
+
metadata: fullEvent.data
|
|
804
|
+
});
|
|
805
|
+
if (createResponse.success && createResponse.data?.chatKey) {
|
|
806
|
+
currentChatKeyRef.current = createResponse.data.chatKey;
|
|
807
|
+
const newChatEvent = {
|
|
808
|
+
type: "new_chat_created",
|
|
809
|
+
orgId: fullEvent.orgId,
|
|
810
|
+
chatKey: createResponse.data.chatKey,
|
|
811
|
+
userId: fullEvent.userId,
|
|
812
|
+
timestamp: Date.now(),
|
|
813
|
+
data: { chatKey: createResponse.data.chatKey }
|
|
814
|
+
};
|
|
815
|
+
emit("new_chat_created", newChatEvent);
|
|
816
|
+
if (onMessageRef.current) {
|
|
817
|
+
onMessageRef.current(newChatEvent);
|
|
818
|
+
}
|
|
819
|
+
if (chatCreationPromiseRef.current) {
|
|
820
|
+
chatCreationPromiseRef.current.resolve(createResponse.data.chatKey);
|
|
821
|
+
chatCreationPromiseRef.current = null;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
break;
|
|
825
|
+
case "end_chat":
|
|
826
|
+
await sendRestMessage("end", {
|
|
827
|
+
orgId: fullEvent.orgId,
|
|
828
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
829
|
+
userId: fullEvent.userId,
|
|
830
|
+
data: fullEvent.data
|
|
831
|
+
});
|
|
832
|
+
break;
|
|
833
|
+
case "human_agent_join":
|
|
834
|
+
await sendRestMessage("agent-join", {
|
|
835
|
+
orgId: fullEvent.orgId,
|
|
836
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
837
|
+
user: fullEvent.data?.user
|
|
838
|
+
});
|
|
839
|
+
break;
|
|
840
|
+
case "human_agent_leave":
|
|
841
|
+
await sendRestMessage("agent-leave", {
|
|
842
|
+
orgId: fullEvent.orgId,
|
|
843
|
+
chatKey: fullEvent.chatKey || currentChatKeyRef.current,
|
|
844
|
+
user: fullEvent.data?.user
|
|
845
|
+
});
|
|
846
|
+
break;
|
|
847
|
+
default:
|
|
848
|
+
logger.warn("Unrecognized event type for SSE REST:", fullEvent.type);
|
|
849
|
+
break;
|
|
850
|
+
}
|
|
851
|
+
updateMetrics({ messagesSent: metrics.messagesSent + 1 });
|
|
852
|
+
logger.debug("SSE REST message sent successfully");
|
|
853
|
+
resolve();
|
|
854
|
+
} catch (error2) {
|
|
855
|
+
logger.error("Failed to send SSE REST message:", error2);
|
|
856
|
+
const sendError = {
|
|
857
|
+
code: "SEND_FAILED",
|
|
858
|
+
message: error2 instanceof Error ? error2.message : "Failed to send message",
|
|
859
|
+
retryable: true,
|
|
860
|
+
timestamp: Date.now()
|
|
861
|
+
};
|
|
862
|
+
setError(sendError);
|
|
863
|
+
updateMetrics({ lastError: sendError });
|
|
864
|
+
reject(sendError);
|
|
865
|
+
}
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
531
868
|
if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
|
|
532
869
|
if (addToQueue(fullEvent)) {
|
|
533
870
|
logger.debug("Message queued, attempting to connect");
|
|
@@ -564,7 +901,7 @@ var useWebSocketChatBase = ({
|
|
|
564
901
|
}
|
|
565
902
|
});
|
|
566
903
|
},
|
|
567
|
-
[connectionState, connect, addToQueue, logger, metrics, updateMetrics]
|
|
904
|
+
[connectionState, connect, addToQueue, logger, metrics, updateMetrics, sendRestMessage, emit]
|
|
568
905
|
);
|
|
569
906
|
const startNewChat = useCallback(
|
|
570
907
|
(userId, data) => {
|
|
@@ -602,7 +939,7 @@ var useWebSocketChatBase = ({
|
|
|
602
939
|
);
|
|
603
940
|
const disconnect = useCallback(
|
|
604
941
|
(intentional = true) => {
|
|
605
|
-
logger.info("Disconnecting
|
|
942
|
+
logger.info("Disconnecting", { intentional, transport: transportRef.current });
|
|
606
943
|
intentionalDisconnectRef.current = intentional;
|
|
607
944
|
cleanup();
|
|
608
945
|
setConnectionState("disconnected");
|