@elqnt/chat 3.0.2 → 3.1.0
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 +27 -0
- package/dist/api/index.d.mts +53 -2
- package/dist/api/index.d.ts +53 -2
- package/dist/api/index.js +79 -9
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +65 -9
- package/dist/api/index.mjs.map +1 -1
- package/dist/hooks/index.d.mts +134 -2
- package/dist/hooks/index.d.ts +134 -2
- package/dist/hooks/index.js +713 -8
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +706 -7
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +722 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +712 -7
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.mts +78 -3
- package/dist/models/index.d.ts +78 -3
- 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/dist/transport/index.js +2 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +2 -1
- package/dist/transport/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -159,6 +159,7 @@ __export(index_exports, {
|
|
|
159
159
|
ChatStatusActive: () => ChatStatusActive,
|
|
160
160
|
ChatStatusArchived: () => ChatStatusArchived,
|
|
161
161
|
ChatStatusClosed: () => ChatStatusClosed,
|
|
162
|
+
ChatStatusCompleted: () => ChatStatusCompleted,
|
|
162
163
|
ChatStatusDisconnected: () => ChatStatusDisconnected,
|
|
163
164
|
ChatTypeCustomerSupport: () => ChatTypeCustomerSupport,
|
|
164
165
|
ChatTypeDirect: () => ChatTypeDirect,
|
|
@@ -171,6 +172,7 @@ __export(index_exports, {
|
|
|
171
172
|
EndAgentSessionSubject: () => EndAgentSessionSubject,
|
|
172
173
|
GetActiveChatCountSubject: () => GetActiveChatCountSubject,
|
|
173
174
|
GetActiveChatsSubject: () => GetActiveChatsSubject,
|
|
175
|
+
GetAgentContextSubject: () => GetAgentContextSubject,
|
|
174
176
|
GetAgentQueuesSubject: () => GetAgentQueuesSubject,
|
|
175
177
|
GetAgentSessionSubject: () => GetAgentSessionSubject,
|
|
176
178
|
GetChatSubject: () => GetChatSubject,
|
|
@@ -196,6 +198,7 @@ __export(index_exports, {
|
|
|
196
198
|
SetupOrgSubject: () => SetupOrgSubject,
|
|
197
199
|
StartAgentSessionSubject: () => StartAgentSessionSubject,
|
|
198
200
|
TriggerAnalyticsScanSubject: () => TriggerAnalyticsScanSubject,
|
|
201
|
+
TriggerMemorySummarizationSubject: () => TriggerMemorySummarizationSubject,
|
|
199
202
|
UpdateAgentLastActivitySubject: () => UpdateAgentLastActivitySubject,
|
|
200
203
|
UpdateAgentQueueSubject: () => UpdateAgentQueueSubject,
|
|
201
204
|
UpdateAgentStatusSubject: () => UpdateAgentStatusSubject,
|
|
@@ -204,7 +207,13 @@ __export(index_exports, {
|
|
|
204
207
|
UserStatusBusy: () => UserStatusBusy,
|
|
205
208
|
UserStatusOffline: () => UserStatusOffline,
|
|
206
209
|
UserStatusOnline: () => UserStatusOnline,
|
|
207
|
-
|
|
210
|
+
useApiAsync: () => import_hooks4.useApiAsync,
|
|
211
|
+
useChat: () => useChat,
|
|
212
|
+
useChatHistory: () => useChatHistory,
|
|
213
|
+
useChatMonitoring: () => useChatMonitoring,
|
|
214
|
+
useHumanAgentSessions: () => useHumanAgentSessions,
|
|
215
|
+
useMemory: () => useMemory,
|
|
216
|
+
useOptionsRef: () => useOptionsRef
|
|
208
217
|
});
|
|
209
218
|
module.exports = __toCommonJS(index_exports);
|
|
210
219
|
|
|
@@ -440,6 +449,383 @@ function createSSETransport(options = {}) {
|
|
|
440
449
|
state = "disconnected";
|
|
441
450
|
retryCount = 0;
|
|
442
451
|
},
|
|
452
|
+
async send(event) {
|
|
453
|
+
if (!config) {
|
|
454
|
+
throw new Error("Transport not connected");
|
|
455
|
+
}
|
|
456
|
+
switch (event.type) {
|
|
457
|
+
case "message":
|
|
458
|
+
await sendRest("send", {
|
|
459
|
+
orgId: event.orgId,
|
|
460
|
+
chatKey: event.chatKey,
|
|
461
|
+
userId: event.userId,
|
|
462
|
+
message: event.message,
|
|
463
|
+
...event.data ? { data: event.data } : {}
|
|
464
|
+
});
|
|
465
|
+
break;
|
|
466
|
+
case "typing":
|
|
467
|
+
await sendRest("typing", {
|
|
468
|
+
orgId: event.orgId,
|
|
469
|
+
chatKey: event.chatKey,
|
|
470
|
+
userId: event.userId,
|
|
471
|
+
typing: true
|
|
472
|
+
});
|
|
473
|
+
break;
|
|
474
|
+
case "stopped_typing":
|
|
475
|
+
await sendRest("typing", {
|
|
476
|
+
orgId: event.orgId,
|
|
477
|
+
chatKey: event.chatKey,
|
|
478
|
+
userId: event.userId,
|
|
479
|
+
typing: false
|
|
480
|
+
});
|
|
481
|
+
break;
|
|
482
|
+
case "load_chat":
|
|
483
|
+
await sendRest("load", {
|
|
484
|
+
orgId: event.orgId,
|
|
485
|
+
chatKey: event.chatKey,
|
|
486
|
+
userId: event.userId
|
|
487
|
+
});
|
|
488
|
+
break;
|
|
489
|
+
case "new_chat":
|
|
490
|
+
await sendRest("create", {
|
|
491
|
+
orgId: event.orgId,
|
|
492
|
+
userId: event.userId,
|
|
493
|
+
metadata: event.data
|
|
494
|
+
});
|
|
495
|
+
break;
|
|
496
|
+
case "end_chat":
|
|
497
|
+
await sendRest("end", {
|
|
498
|
+
orgId: event.orgId,
|
|
499
|
+
chatKey: event.chatKey,
|
|
500
|
+
userId: event.userId,
|
|
501
|
+
data: event.data
|
|
502
|
+
});
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
await sendRest("event", {
|
|
506
|
+
type: event.type,
|
|
507
|
+
orgId: event.orgId,
|
|
508
|
+
chatKey: event.chatKey,
|
|
509
|
+
userId: event.userId,
|
|
510
|
+
data: event.data
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
metrics.messagesSent++;
|
|
514
|
+
},
|
|
515
|
+
async sendMessage(message) {
|
|
516
|
+
if (!config) {
|
|
517
|
+
throw new Error("Transport not connected");
|
|
518
|
+
}
|
|
519
|
+
await sendRest("send", {
|
|
520
|
+
orgId: config.orgId,
|
|
521
|
+
chatKey: config.chatKey,
|
|
522
|
+
userId: config.userId,
|
|
523
|
+
message
|
|
524
|
+
});
|
|
525
|
+
metrics.messagesSent++;
|
|
526
|
+
},
|
|
527
|
+
async createChat(options2) {
|
|
528
|
+
if (!config) {
|
|
529
|
+
throw new Error("Transport not connected");
|
|
530
|
+
}
|
|
531
|
+
const response = await sendRest("create", {
|
|
532
|
+
orgId: options2.orgId,
|
|
533
|
+
userId: options2.userId,
|
|
534
|
+
metadata: options2.metadata
|
|
535
|
+
});
|
|
536
|
+
if (!response?.chatKey) {
|
|
537
|
+
throw new Error("Failed to create chat: no chatKey returned");
|
|
538
|
+
}
|
|
539
|
+
return { chatKey: response.chatKey };
|
|
540
|
+
},
|
|
541
|
+
async loadChatData(options2) {
|
|
542
|
+
if (!config) {
|
|
543
|
+
throw new Error("Transport not connected");
|
|
544
|
+
}
|
|
545
|
+
const response = await sendRest("load", {
|
|
546
|
+
orgId: options2.orgId,
|
|
547
|
+
chatKey: options2.chatKey,
|
|
548
|
+
userId: options2.userId
|
|
549
|
+
});
|
|
550
|
+
if (!response?.chat) {
|
|
551
|
+
throw new Error("Failed to load chat: no chat data returned");
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
chat: response.chat,
|
|
555
|
+
agentId: response.agentId
|
|
556
|
+
};
|
|
557
|
+
},
|
|
558
|
+
onMessage(handler) {
|
|
559
|
+
globalHandlers.add(handler);
|
|
560
|
+
return () => globalHandlers.delete(handler);
|
|
561
|
+
},
|
|
562
|
+
on(eventType, handler) {
|
|
563
|
+
if (!typeHandlers.has(eventType)) {
|
|
564
|
+
typeHandlers.set(eventType, /* @__PURE__ */ new Set());
|
|
565
|
+
}
|
|
566
|
+
typeHandlers.get(eventType).add(handler);
|
|
567
|
+
return () => {
|
|
568
|
+
const handlers = typeHandlers.get(eventType);
|
|
569
|
+
if (handlers) {
|
|
570
|
+
handlers.delete(handler);
|
|
571
|
+
if (handlers.size === 0) {
|
|
572
|
+
typeHandlers.delete(eventType);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
},
|
|
577
|
+
getState() {
|
|
578
|
+
return state;
|
|
579
|
+
},
|
|
580
|
+
getMetrics() {
|
|
581
|
+
return { ...metrics };
|
|
582
|
+
},
|
|
583
|
+
getError() {
|
|
584
|
+
return error;
|
|
585
|
+
},
|
|
586
|
+
clearError() {
|
|
587
|
+
error = void 0;
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
return transport;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// transport/sse-fetch.ts
|
|
594
|
+
function createFetchSSETransport(options = {}) {
|
|
595
|
+
const {
|
|
596
|
+
retryConfig = DEFAULT_RETRY_CONFIG,
|
|
597
|
+
debug = false,
|
|
598
|
+
logger = createLogger(debug),
|
|
599
|
+
customFetch = fetch
|
|
600
|
+
} = options;
|
|
601
|
+
let abortController;
|
|
602
|
+
let config;
|
|
603
|
+
let state = "disconnected";
|
|
604
|
+
let error;
|
|
605
|
+
let retryCount = 0;
|
|
606
|
+
let reconnectTimeout;
|
|
607
|
+
let intentionalDisconnect = false;
|
|
608
|
+
const metrics = {
|
|
609
|
+
latency: 0,
|
|
610
|
+
messagesSent: 0,
|
|
611
|
+
messagesReceived: 0,
|
|
612
|
+
messagesQueued: 0,
|
|
613
|
+
reconnectCount: 0,
|
|
614
|
+
transportType: "sse-fetch"
|
|
615
|
+
};
|
|
616
|
+
const globalHandlers = /* @__PURE__ */ new Set();
|
|
617
|
+
const typeHandlers = /* @__PURE__ */ new Map();
|
|
618
|
+
function emit(event) {
|
|
619
|
+
metrics.messagesReceived++;
|
|
620
|
+
metrics.lastMessageAt = Date.now();
|
|
621
|
+
globalHandlers.forEach((handler) => {
|
|
622
|
+
try {
|
|
623
|
+
handler(event);
|
|
624
|
+
} catch (err) {
|
|
625
|
+
logger.error("Error in message handler:", err);
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
const handlers = typeHandlers.get(event.type);
|
|
629
|
+
if (handlers) {
|
|
630
|
+
handlers.forEach((handler) => {
|
|
631
|
+
try {
|
|
632
|
+
handler(event);
|
|
633
|
+
} catch (err) {
|
|
634
|
+
logger.error(`Error in ${event.type} handler:`, err);
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
async function sendRest(endpoint, body) {
|
|
640
|
+
if (!config) {
|
|
641
|
+
throw new Error("Transport not connected");
|
|
642
|
+
}
|
|
643
|
+
const url = `${config.baseUrl}/${endpoint}`;
|
|
644
|
+
logger.debug(`POST ${endpoint}`, body);
|
|
645
|
+
const response = await customFetch(url, {
|
|
646
|
+
method: "POST",
|
|
647
|
+
headers: { "Content-Type": "application/json" },
|
|
648
|
+
body: JSON.stringify(body)
|
|
649
|
+
});
|
|
650
|
+
if (!response.ok) {
|
|
651
|
+
const errorText = await response.text();
|
|
652
|
+
throw new Error(`API error: ${response.status} - ${errorText}`);
|
|
653
|
+
}
|
|
654
|
+
const json = await response.json();
|
|
655
|
+
if (json && typeof json === "object" && "data" in json) {
|
|
656
|
+
return json.data;
|
|
657
|
+
}
|
|
658
|
+
return json;
|
|
659
|
+
}
|
|
660
|
+
function parseSSEChunk(chunk) {
|
|
661
|
+
const events = [];
|
|
662
|
+
const lines = chunk.split("\n");
|
|
663
|
+
let eventType = "message";
|
|
664
|
+
let data = "";
|
|
665
|
+
for (const line of lines) {
|
|
666
|
+
if (line.startsWith("event:")) {
|
|
667
|
+
eventType = line.slice(6).trim();
|
|
668
|
+
} else if (line.startsWith("data:")) {
|
|
669
|
+
data = line.slice(5).trim();
|
|
670
|
+
} else if (line === "" && data) {
|
|
671
|
+
try {
|
|
672
|
+
const parsed = JSON.parse(data);
|
|
673
|
+
events.push(parsed);
|
|
674
|
+
} catch {
|
|
675
|
+
logger.warn("Failed to parse SSE data:", data);
|
|
676
|
+
}
|
|
677
|
+
eventType = "message";
|
|
678
|
+
data = "";
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return events;
|
|
682
|
+
}
|
|
683
|
+
async function startStream(cfg) {
|
|
684
|
+
const url = `${cfg.baseUrl}/stream?orgId=${cfg.orgId}&userId=${cfg.userId}&clientType=${cfg.clientType}${cfg.chatKey ? `&chatId=${cfg.chatKey}` : ""}`;
|
|
685
|
+
logger.debug("Connecting to:", url);
|
|
686
|
+
abortController = new AbortController();
|
|
687
|
+
const response = await customFetch(url, {
|
|
688
|
+
method: "GET",
|
|
689
|
+
headers: {
|
|
690
|
+
Accept: "text/event-stream",
|
|
691
|
+
"Cache-Control": "no-cache"
|
|
692
|
+
},
|
|
693
|
+
signal: abortController.signal
|
|
694
|
+
});
|
|
695
|
+
if (!response.ok) {
|
|
696
|
+
throw new Error(`Stream connection failed: ${response.status}`);
|
|
697
|
+
}
|
|
698
|
+
if (!response.body) {
|
|
699
|
+
throw new Error("Response body is null - ReadableStream not supported");
|
|
700
|
+
}
|
|
701
|
+
const reader = response.body.getReader();
|
|
702
|
+
const decoder = new TextDecoder();
|
|
703
|
+
let buffer = "";
|
|
704
|
+
const readStream = async () => {
|
|
705
|
+
try {
|
|
706
|
+
while (true) {
|
|
707
|
+
const { done, value } = await reader.read();
|
|
708
|
+
if (done) {
|
|
709
|
+
logger.info("Stream ended");
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
712
|
+
buffer += decoder.decode(value, { stream: true });
|
|
713
|
+
const lastNewline = buffer.lastIndexOf("\n\n");
|
|
714
|
+
if (lastNewline !== -1) {
|
|
715
|
+
const complete = buffer.slice(0, lastNewline + 2);
|
|
716
|
+
buffer = buffer.slice(lastNewline + 2);
|
|
717
|
+
const events = parseSSEChunk(complete);
|
|
718
|
+
events.forEach(emit);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
} catch (err) {
|
|
722
|
+
if (err.name === "AbortError") {
|
|
723
|
+
logger.debug("Stream aborted");
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
logger.error("Stream error:", err);
|
|
727
|
+
throw err;
|
|
728
|
+
}
|
|
729
|
+
if (!intentionalDisconnect) {
|
|
730
|
+
state = "disconnected";
|
|
731
|
+
scheduleReconnect();
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
readStream().catch((err) => {
|
|
735
|
+
if (!intentionalDisconnect) {
|
|
736
|
+
error = {
|
|
737
|
+
code: "CONNECTION_FAILED",
|
|
738
|
+
message: err.message,
|
|
739
|
+
retryable: true,
|
|
740
|
+
timestamp: Date.now(),
|
|
741
|
+
originalError: err
|
|
742
|
+
};
|
|
743
|
+
metrics.lastError = error;
|
|
744
|
+
state = "disconnected";
|
|
745
|
+
scheduleReconnect();
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
function scheduleReconnect() {
|
|
750
|
+
if (intentionalDisconnect || !config) return;
|
|
751
|
+
const maxRetries = retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries;
|
|
752
|
+
if (retryCount >= maxRetries) {
|
|
753
|
+
logger.error(`Max retries (${maxRetries}) exceeded`);
|
|
754
|
+
error = {
|
|
755
|
+
code: "CONNECTION_FAILED",
|
|
756
|
+
message: `Max retries (${maxRetries}) exceeded`,
|
|
757
|
+
retryable: false,
|
|
758
|
+
timestamp: Date.now()
|
|
759
|
+
};
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
const interval = calculateRetryInterval(retryCount, retryConfig);
|
|
763
|
+
retryCount++;
|
|
764
|
+
metrics.reconnectCount++;
|
|
765
|
+
logger.info(`Reconnecting in ${interval}ms (attempt ${retryCount})`);
|
|
766
|
+
state = "reconnecting";
|
|
767
|
+
reconnectTimeout = setTimeout(() => {
|
|
768
|
+
if (config) {
|
|
769
|
+
transport.connect(config).catch((err) => {
|
|
770
|
+
logger.error("Reconnect failed:", err);
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
}, interval);
|
|
774
|
+
}
|
|
775
|
+
const transport = {
|
|
776
|
+
async connect(cfg) {
|
|
777
|
+
config = cfg;
|
|
778
|
+
intentionalDisconnect = false;
|
|
779
|
+
if (abortController) {
|
|
780
|
+
abortController.abort();
|
|
781
|
+
abortController = void 0;
|
|
782
|
+
}
|
|
783
|
+
if (reconnectTimeout) {
|
|
784
|
+
clearTimeout(reconnectTimeout);
|
|
785
|
+
reconnectTimeout = void 0;
|
|
786
|
+
}
|
|
787
|
+
state = retryCount > 0 ? "reconnecting" : "connecting";
|
|
788
|
+
const connectionStart = Date.now();
|
|
789
|
+
try {
|
|
790
|
+
await startStream(cfg);
|
|
791
|
+
const connectionTime = Date.now() - connectionStart;
|
|
792
|
+
logger.info(`Connected in ${connectionTime}ms`);
|
|
793
|
+
state = "connected";
|
|
794
|
+
error = void 0;
|
|
795
|
+
retryCount = 0;
|
|
796
|
+
metrics.connectedAt = Date.now();
|
|
797
|
+
metrics.latency = connectionTime;
|
|
798
|
+
} catch (err) {
|
|
799
|
+
const connectError = {
|
|
800
|
+
code: "CONNECTION_FAILED",
|
|
801
|
+
message: err.message,
|
|
802
|
+
retryable: true,
|
|
803
|
+
timestamp: Date.now(),
|
|
804
|
+
originalError: err
|
|
805
|
+
};
|
|
806
|
+
error = connectError;
|
|
807
|
+
metrics.lastError = connectError;
|
|
808
|
+
state = "disconnected";
|
|
809
|
+
if (!intentionalDisconnect) {
|
|
810
|
+
scheduleReconnect();
|
|
811
|
+
}
|
|
812
|
+
throw connectError;
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
disconnect(intentional = true) {
|
|
816
|
+
logger.info("Disconnecting", { intentional });
|
|
817
|
+
intentionalDisconnect = intentional;
|
|
818
|
+
if (reconnectTimeout) {
|
|
819
|
+
clearTimeout(reconnectTimeout);
|
|
820
|
+
reconnectTimeout = void 0;
|
|
821
|
+
}
|
|
822
|
+
if (abortController) {
|
|
823
|
+
abortController.abort();
|
|
824
|
+
abortController = void 0;
|
|
825
|
+
}
|
|
826
|
+
state = "disconnected";
|
|
827
|
+
retryCount = 0;
|
|
828
|
+
},
|
|
443
829
|
async send(event) {
|
|
444
830
|
if (!config) {
|
|
445
831
|
throw new Error("Transport not connected");
|
|
@@ -582,6 +968,16 @@ function createSSETransport(options = {}) {
|
|
|
582
968
|
|
|
583
969
|
// hooks/use-chat.ts
|
|
584
970
|
function getDefaultTransport(type, debug) {
|
|
971
|
+
if (type === "sse-fetch") {
|
|
972
|
+
return createFetchSSETransport({ debug });
|
|
973
|
+
}
|
|
974
|
+
if (type === "sse") {
|
|
975
|
+
return createSSETransport({ debug });
|
|
976
|
+
}
|
|
977
|
+
const isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
978
|
+
if (isReactNative || typeof EventSource === "undefined") {
|
|
979
|
+
return createFetchSSETransport({ debug });
|
|
980
|
+
}
|
|
585
981
|
return createSSETransport({ debug });
|
|
586
982
|
}
|
|
587
983
|
function useChat(options) {
|
|
@@ -692,6 +1088,7 @@ function useChat(options) {
|
|
|
692
1088
|
throw err;
|
|
693
1089
|
}
|
|
694
1090
|
setConnectionState("connecting");
|
|
1091
|
+
onConnectionChange?.("connecting");
|
|
695
1092
|
try {
|
|
696
1093
|
const unsubscribe = transport.onMessage(handleEvent);
|
|
697
1094
|
await transport.connect({
|
|
@@ -710,6 +1107,7 @@ function useChat(options) {
|
|
|
710
1107
|
} catch (err) {
|
|
711
1108
|
const transportError = err;
|
|
712
1109
|
setConnectionState("disconnected");
|
|
1110
|
+
onConnectionChange?.("disconnected");
|
|
713
1111
|
setError(transportError);
|
|
714
1112
|
onErrorRef.current?.(transportError);
|
|
715
1113
|
throw err;
|
|
@@ -739,7 +1137,7 @@ function useChat(options) {
|
|
|
739
1137
|
},
|
|
740
1138
|
[orgId, userId]
|
|
741
1139
|
);
|
|
742
|
-
const
|
|
1140
|
+
const loadChat2 = (0, import_react.useCallback)(
|
|
743
1141
|
async (key) => {
|
|
744
1142
|
const transport = transportRef.current;
|
|
745
1143
|
if (!transport) {
|
|
@@ -792,7 +1190,7 @@ function useChat(options) {
|
|
|
792
1190
|
},
|
|
793
1191
|
[orgId, chatKey, userId]
|
|
794
1192
|
);
|
|
795
|
-
const
|
|
1193
|
+
const endChat2 = (0, import_react.useCallback)(
|
|
796
1194
|
async (reason) => {
|
|
797
1195
|
const transport = transportRef.current;
|
|
798
1196
|
if (!transport) {
|
|
@@ -814,7 +1212,7 @@ function useChat(options) {
|
|
|
814
1212
|
},
|
|
815
1213
|
[orgId, chatKey, userId]
|
|
816
1214
|
);
|
|
817
|
-
const
|
|
1215
|
+
const sendEvent2 = (0, import_react.useCallback)(
|
|
818
1216
|
async (event) => {
|
|
819
1217
|
const transport = transportRef.current;
|
|
820
1218
|
if (!transport) {
|
|
@@ -899,10 +1297,10 @@ function useChat(options) {
|
|
|
899
1297
|
isConnected,
|
|
900
1298
|
// Chat operations
|
|
901
1299
|
startChat,
|
|
902
|
-
loadChat,
|
|
1300
|
+
loadChat: loadChat2,
|
|
903
1301
|
sendMessage,
|
|
904
|
-
sendEvent,
|
|
905
|
-
endChat,
|
|
1302
|
+
sendEvent: sendEvent2,
|
|
1303
|
+
endChat: endChat2,
|
|
906
1304
|
// Typing
|
|
907
1305
|
startTyping,
|
|
908
1306
|
stopTyping,
|
|
@@ -918,12 +1316,317 @@ function useChat(options) {
|
|
|
918
1316
|
};
|
|
919
1317
|
}
|
|
920
1318
|
|
|
1319
|
+
// hooks/use-chat-history.ts
|
|
1320
|
+
var import_react3 = require("react");
|
|
1321
|
+
|
|
1322
|
+
// api/index.ts
|
|
1323
|
+
var import_browser2 = require("@elqnt/api-client/browser");
|
|
1324
|
+
|
|
1325
|
+
// api/memory.ts
|
|
1326
|
+
var import_browser = require("@elqnt/api-client/browser");
|
|
1327
|
+
var patchProfileApi = (patch, o) => (0, import_browser.browserApiRequest)("/api/v1/memory/profile", { method: "PATCH", body: patch, ...o });
|
|
1328
|
+
var replaceProfileApi = (p, o) => (0, import_browser.browserApiRequest)("/api/v1/memory/profile", { method: "PUT", body: p, ...o });
|
|
1329
|
+
var clearProfileApi = (o) => (0, import_browser.browserApiRequest)("/api/v1/memory/profile", { method: "DELETE", ...o });
|
|
1330
|
+
var deleteContactApi = (name, o) => (0, import_browser.browserApiRequest)(`/api/v1/memory/profile/contacts/${encodeURIComponent(name)}`, { method: "DELETE", ...o });
|
|
1331
|
+
var deleteNoteApi = (index, o) => (0, import_browser.browserApiRequest)(`/api/v1/memory/profile/notes/${index}`, { method: "DELETE", ...o });
|
|
1332
|
+
var clearSummaryApi = (chatKey, o) => (0, import_browser.browserApiRequest)(`/api/v1/chats/${chatKey}/summary`, { method: "DELETE", ...o });
|
|
1333
|
+
var regenerateSummaryApi = (chatKey, o) => (0, import_browser.browserApiRequest)(`/api/v1/chats/${chatKey}/summary/regenerate`, { method: "POST", ...o });
|
|
1334
|
+
|
|
1335
|
+
// api/index.ts
|
|
1336
|
+
async function getChatHistoryApi(options) {
|
|
1337
|
+
return (0, import_browser2.browserApiRequest)("/api/v1/chats", {
|
|
1338
|
+
method: "POST",
|
|
1339
|
+
body: {
|
|
1340
|
+
limit: options.limit || 15,
|
|
1341
|
+
offset: options.offset || 0,
|
|
1342
|
+
...options.skipCache ? { skipCache: true } : {}
|
|
1343
|
+
},
|
|
1344
|
+
...options
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
async function getChatApi(chatKey, options) {
|
|
1348
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/chats/${chatKey}`, {
|
|
1349
|
+
method: "GET",
|
|
1350
|
+
...options
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
async function updateChatApi(chatKey, updates, options) {
|
|
1354
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/chats/${chatKey}`, {
|
|
1355
|
+
method: "PATCH",
|
|
1356
|
+
body: updates,
|
|
1357
|
+
...options
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
async function deleteChatApi(chatKey, options) {
|
|
1361
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/chats/${chatKey}`, {
|
|
1362
|
+
method: "DELETE",
|
|
1363
|
+
...options
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
async function getActiveChatsCountApi(options) {
|
|
1367
|
+
return (0, import_browser2.browserApiRequest)("/api/v1/chats/active/count", {
|
|
1368
|
+
method: "GET",
|
|
1369
|
+
...options
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
async function getActiveChatsApi(options) {
|
|
1373
|
+
const params = new URLSearchParams();
|
|
1374
|
+
if (options.pastHours) params.set("pastHours", String(options.pastHours));
|
|
1375
|
+
const queryString = params.toString();
|
|
1376
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/chats/active${queryString ? `?${queryString}` : ""}`, {
|
|
1377
|
+
method: "GET",
|
|
1378
|
+
...options
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
async function getWaitingChatsCountApi(options) {
|
|
1382
|
+
return (0, import_browser2.browserApiRequest)("/api/v1/chats/waiting/count", {
|
|
1383
|
+
method: "GET",
|
|
1384
|
+
...options
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
async function getChatsByUserApi(userEmail, options) {
|
|
1388
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/chats/user/${encodeURIComponent(userEmail)}`, {
|
|
1389
|
+
method: "GET",
|
|
1390
|
+
...options
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
async function listQueuesApi(options) {
|
|
1394
|
+
return (0, import_browser2.browserApiRequest)("/api/v1/queues", {
|
|
1395
|
+
method: "GET",
|
|
1396
|
+
...options
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
async function getOnlineSessionsApi(options) {
|
|
1400
|
+
return (0, import_browser2.browserApiRequest)("/api/v1/agents/sessions/online", {
|
|
1401
|
+
method: "GET",
|
|
1402
|
+
...options
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
async function getAgentSessionApi(agentId, options) {
|
|
1406
|
+
return (0, import_browser2.browserApiRequest)(`/api/v1/agents/sessions/${agentId}`, {
|
|
1407
|
+
method: "GET",
|
|
1408
|
+
...options
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// hooks/use-chat-history.ts
|
|
1413
|
+
var import_hooks = require("@elqnt/api-client/hooks");
|
|
1414
|
+
|
|
1415
|
+
// hooks/use-options-ref.ts
|
|
1416
|
+
var import_react2 = require("react");
|
|
1417
|
+
function useOptionsRef(options) {
|
|
1418
|
+
const optionsRef = (0, import_react2.useRef)(options);
|
|
1419
|
+
(0, import_react2.useEffect)(() => {
|
|
1420
|
+
optionsRef.current = options;
|
|
1421
|
+
}, [options]);
|
|
1422
|
+
return optionsRef;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// hooks/use-chat-history.ts
|
|
1426
|
+
function useChatHistory(options) {
|
|
1427
|
+
const optionsRef = useOptionsRef(options);
|
|
1428
|
+
const { execute: getChatHistory, loading: listLoading, error: listError } = (0, import_hooks.useApiAsync)(
|
|
1429
|
+
(params) => getChatHistoryApi({ ...optionsRef.current, ...params }),
|
|
1430
|
+
(data) => ({
|
|
1431
|
+
chats: data.chats,
|
|
1432
|
+
total: data.total,
|
|
1433
|
+
hasMore: data.hasMore
|
|
1434
|
+
}),
|
|
1435
|
+
{ chats: [], total: 0, hasMore: false }
|
|
1436
|
+
);
|
|
1437
|
+
const { execute: getChat, loading: getLoading, error: getError } = (0, import_hooks.useApiAsync)(
|
|
1438
|
+
(chatKey) => getChatApi(chatKey, optionsRef.current),
|
|
1439
|
+
(data) => data.chat || null,
|
|
1440
|
+
null
|
|
1441
|
+
);
|
|
1442
|
+
const { execute: updateChat, loading: updateLoading, error: updateError } = (0, import_hooks.useApiAsync)(
|
|
1443
|
+
(chatKey, updates) => updateChatApi(chatKey, updates, optionsRef.current),
|
|
1444
|
+
(data) => !!data.chatKey,
|
|
1445
|
+
false
|
|
1446
|
+
);
|
|
1447
|
+
const { execute: deleteChat, loading: deleteLoading, error: deleteError } = (0, import_hooks.useApiAsync)(
|
|
1448
|
+
(chatKey) => deleteChatApi(chatKey, optionsRef.current),
|
|
1449
|
+
(data) => data.success,
|
|
1450
|
+
false
|
|
1451
|
+
);
|
|
1452
|
+
const { execute: getChatsByUser, loading: userChatsLoading, error: userChatsError } = (0, import_hooks.useApiAsync)(
|
|
1453
|
+
(userEmail) => getChatsByUserApi(userEmail, optionsRef.current),
|
|
1454
|
+
(data) => data.chats,
|
|
1455
|
+
[]
|
|
1456
|
+
);
|
|
1457
|
+
const loading = listLoading || getLoading || updateLoading || deleteLoading || userChatsLoading;
|
|
1458
|
+
const error = listError || getError || updateError || deleteError || userChatsError;
|
|
1459
|
+
return (0, import_react3.useMemo)(
|
|
1460
|
+
() => ({
|
|
1461
|
+
loading,
|
|
1462
|
+
error,
|
|
1463
|
+
getChatHistory,
|
|
1464
|
+
getChat,
|
|
1465
|
+
updateChat,
|
|
1466
|
+
deleteChat,
|
|
1467
|
+
getChatsByUser
|
|
1468
|
+
}),
|
|
1469
|
+
[loading, error, getChatHistory, getChat, updateChat, deleteChat, getChatsByUser]
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
// hooks/use-chat-monitoring.ts
|
|
1474
|
+
var import_react4 = require("react");
|
|
1475
|
+
var import_hooks2 = require("@elqnt/api-client/hooks");
|
|
1476
|
+
function useChatMonitoring(options) {
|
|
1477
|
+
const optionsRef = useOptionsRef(options);
|
|
1478
|
+
const { execute: getActiveChats, loading: activeLoading, error: activeError } = (0, import_hooks2.useApiAsync)(
|
|
1479
|
+
(pastHours) => getActiveChatsApi({ ...optionsRef.current, pastHours }),
|
|
1480
|
+
(data) => data.chats,
|
|
1481
|
+
[]
|
|
1482
|
+
);
|
|
1483
|
+
const { execute: getActiveChatsCount, loading: activeCountLoading, error: activeCountError } = (0, import_hooks2.useApiAsync)(
|
|
1484
|
+
() => getActiveChatsCountApi(optionsRef.current),
|
|
1485
|
+
(data) => data.count,
|
|
1486
|
+
0
|
|
1487
|
+
);
|
|
1488
|
+
const { execute: getWaitingChatsCount, loading: waitingCountLoading, error: waitingCountError } = (0, import_hooks2.useApiAsync)(
|
|
1489
|
+
() => getWaitingChatsCountApi(optionsRef.current),
|
|
1490
|
+
(data) => data.count,
|
|
1491
|
+
0
|
|
1492
|
+
);
|
|
1493
|
+
const { execute: listQueues, loading: queuesLoading, error: queuesError } = (0, import_hooks2.useApiAsync)(
|
|
1494
|
+
() => listQueuesApi(optionsRef.current),
|
|
1495
|
+
(data) => data.queues,
|
|
1496
|
+
[]
|
|
1497
|
+
);
|
|
1498
|
+
const loading = activeLoading || activeCountLoading || waitingCountLoading || queuesLoading;
|
|
1499
|
+
const error = activeError || activeCountError || waitingCountError || queuesError;
|
|
1500
|
+
return (0, import_react4.useMemo)(
|
|
1501
|
+
() => ({
|
|
1502
|
+
loading,
|
|
1503
|
+
error,
|
|
1504
|
+
getActiveChats,
|
|
1505
|
+
getActiveChatsCount,
|
|
1506
|
+
getWaitingChatsCount,
|
|
1507
|
+
listQueues
|
|
1508
|
+
}),
|
|
1509
|
+
[loading, error, getActiveChats, getActiveChatsCount, getWaitingChatsCount, listQueues]
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// hooks/use-human-agent-sessions.ts
|
|
1514
|
+
var import_react5 = require("react");
|
|
1515
|
+
var import_hooks3 = require("@elqnt/api-client/hooks");
|
|
1516
|
+
function useHumanAgentSessions(options) {
|
|
1517
|
+
const optionsRef = useOptionsRef(options);
|
|
1518
|
+
const { execute: getOnlineSessions, loading: onlineLoading, error: onlineError } = (0, import_hooks3.useApiAsync)(
|
|
1519
|
+
() => getOnlineSessionsApi(optionsRef.current),
|
|
1520
|
+
(data) => data.sessions,
|
|
1521
|
+
[]
|
|
1522
|
+
);
|
|
1523
|
+
const { execute: getAgentSession, loading: sessionLoading, error: sessionError } = (0, import_hooks3.useApiAsync)(
|
|
1524
|
+
(agentId) => getAgentSessionApi(agentId, optionsRef.current),
|
|
1525
|
+
(data) => data.session || null,
|
|
1526
|
+
null
|
|
1527
|
+
);
|
|
1528
|
+
const loading = onlineLoading || sessionLoading;
|
|
1529
|
+
const error = onlineError || sessionError;
|
|
1530
|
+
return (0, import_react5.useMemo)(
|
|
1531
|
+
() => ({
|
|
1532
|
+
loading,
|
|
1533
|
+
error,
|
|
1534
|
+
getOnlineSessions,
|
|
1535
|
+
getAgentSession
|
|
1536
|
+
}),
|
|
1537
|
+
[loading, error, getOnlineSessions, getAgentSession]
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
// hooks/use-memory.ts
|
|
1542
|
+
var import_react6 = require("react");
|
|
1543
|
+
function useMemory(options, initialProfile = null) {
|
|
1544
|
+
const [profile, setProfile] = (0, import_react6.useState)(initialProfile);
|
|
1545
|
+
const [loading, setLoading] = (0, import_react6.useState)(false);
|
|
1546
|
+
const requestCountRef = (0, import_react6.useRef)(0);
|
|
1547
|
+
const runProfileMutation = (0, import_react6.useCallback)(
|
|
1548
|
+
async (fn) => {
|
|
1549
|
+
requestCountRef.current += 1;
|
|
1550
|
+
setLoading(true);
|
|
1551
|
+
try {
|
|
1552
|
+
const response = await fn();
|
|
1553
|
+
if (!response.error && response.data) {
|
|
1554
|
+
setProfile(response.data);
|
|
1555
|
+
return response.data;
|
|
1556
|
+
}
|
|
1557
|
+
return null;
|
|
1558
|
+
} catch {
|
|
1559
|
+
return null;
|
|
1560
|
+
} finally {
|
|
1561
|
+
requestCountRef.current -= 1;
|
|
1562
|
+
if (requestCountRef.current === 0) {
|
|
1563
|
+
setLoading(false);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
},
|
|
1567
|
+
[]
|
|
1568
|
+
);
|
|
1569
|
+
const optionsRef = (0, import_react6.useRef)(options);
|
|
1570
|
+
optionsRef.current = options;
|
|
1571
|
+
const patchProfile = (0, import_react6.useCallback)(
|
|
1572
|
+
(patch) => runProfileMutation(() => patchProfileApi(patch, optionsRef.current)),
|
|
1573
|
+
[runProfileMutation]
|
|
1574
|
+
);
|
|
1575
|
+
const replaceProfile = (0, import_react6.useCallback)(
|
|
1576
|
+
(p) => runProfileMutation(() => replaceProfileApi(p, optionsRef.current)),
|
|
1577
|
+
[runProfileMutation]
|
|
1578
|
+
);
|
|
1579
|
+
const clearProfile = (0, import_react6.useCallback)(
|
|
1580
|
+
() => runProfileMutation(() => clearProfileApi(optionsRef.current)),
|
|
1581
|
+
[runProfileMutation]
|
|
1582
|
+
);
|
|
1583
|
+
const deleteContact = (0, import_react6.useCallback)(
|
|
1584
|
+
(name) => runProfileMutation(() => deleteContactApi(name, optionsRef.current)),
|
|
1585
|
+
[runProfileMutation]
|
|
1586
|
+
);
|
|
1587
|
+
const deleteNote = (0, import_react6.useCallback)(
|
|
1588
|
+
(index) => runProfileMutation(() => deleteNoteApi(index, optionsRef.current)),
|
|
1589
|
+
[runProfileMutation]
|
|
1590
|
+
);
|
|
1591
|
+
const clearSummary = (0, import_react6.useCallback)(
|
|
1592
|
+
async (chatKey) => {
|
|
1593
|
+
await clearSummaryApi(chatKey, optionsRef.current);
|
|
1594
|
+
},
|
|
1595
|
+
[]
|
|
1596
|
+
);
|
|
1597
|
+
const regenerateSummary = (0, import_react6.useCallback)(
|
|
1598
|
+
async (chatKey) => {
|
|
1599
|
+
const response = await regenerateSummaryApi(chatKey, optionsRef.current);
|
|
1600
|
+
if (!response.error && response.data) {
|
|
1601
|
+
return response.data;
|
|
1602
|
+
}
|
|
1603
|
+
return null;
|
|
1604
|
+
},
|
|
1605
|
+
[]
|
|
1606
|
+
);
|
|
1607
|
+
return {
|
|
1608
|
+
profile,
|
|
1609
|
+
loading,
|
|
1610
|
+
patchProfile,
|
|
1611
|
+
replaceProfile,
|
|
1612
|
+
clearProfile,
|
|
1613
|
+
deleteContact,
|
|
1614
|
+
deleteNote,
|
|
1615
|
+
clearSummary,
|
|
1616
|
+
regenerateSummary
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
// hooks/index.ts
|
|
1621
|
+
var import_hooks4 = require("@elqnt/api-client/hooks");
|
|
1622
|
+
|
|
921
1623
|
// models/chat-models.ts
|
|
922
1624
|
var ChatStatusActive = "active";
|
|
923
1625
|
var ChatStatusDisconnected = "disconnected";
|
|
924
1626
|
var ChatStatusAbandoned = "abandoned";
|
|
925
1627
|
var ChatStatusClosed = "closed";
|
|
926
1628
|
var ChatStatusArchived = "archived";
|
|
1629
|
+
var ChatStatusCompleted = "completed";
|
|
927
1630
|
var ChatTypeCustomerSupport = "customer_support";
|
|
928
1631
|
var ChatTypePublicRoom = "public_room";
|
|
929
1632
|
var ChatTypePrivateRoom = "private_room";
|
|
@@ -1107,6 +1810,8 @@ var UpdateUserStatusSubject = "chat.user.status.update";
|
|
|
1107
1810
|
var GetOnlineUsersSubject = "chat.users.online.get";
|
|
1108
1811
|
var TriggerAnalyticsScanSubject = "chat.analytics.trigger-scan";
|
|
1109
1812
|
var SetupOrgSubject = "chat.org.setup";
|
|
1813
|
+
var GetAgentContextSubject = "chat.agent-context.get";
|
|
1814
|
+
var TriggerMemorySummarizationSubject = "chat.memory.summarize.nightly";
|
|
1110
1815
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1111
1816
|
0 && (module.exports = {
|
|
1112
1817
|
AgentStatusAway,
|
|
@@ -1247,6 +1952,7 @@ var SetupOrgSubject = "chat.org.setup";
|
|
|
1247
1952
|
ChatStatusActive,
|
|
1248
1953
|
ChatStatusArchived,
|
|
1249
1954
|
ChatStatusClosed,
|
|
1955
|
+
ChatStatusCompleted,
|
|
1250
1956
|
ChatStatusDisconnected,
|
|
1251
1957
|
ChatTypeCustomerSupport,
|
|
1252
1958
|
ChatTypeDirect,
|
|
@@ -1259,6 +1965,7 @@ var SetupOrgSubject = "chat.org.setup";
|
|
|
1259
1965
|
EndAgentSessionSubject,
|
|
1260
1966
|
GetActiveChatCountSubject,
|
|
1261
1967
|
GetActiveChatsSubject,
|
|
1968
|
+
GetAgentContextSubject,
|
|
1262
1969
|
GetAgentQueuesSubject,
|
|
1263
1970
|
GetAgentSessionSubject,
|
|
1264
1971
|
GetChatSubject,
|
|
@@ -1284,6 +1991,7 @@ var SetupOrgSubject = "chat.org.setup";
|
|
|
1284
1991
|
SetupOrgSubject,
|
|
1285
1992
|
StartAgentSessionSubject,
|
|
1286
1993
|
TriggerAnalyticsScanSubject,
|
|
1994
|
+
TriggerMemorySummarizationSubject,
|
|
1287
1995
|
UpdateAgentLastActivitySubject,
|
|
1288
1996
|
UpdateAgentQueueSubject,
|
|
1289
1997
|
UpdateAgentStatusSubject,
|
|
@@ -1292,6 +2000,12 @@ var SetupOrgSubject = "chat.org.setup";
|
|
|
1292
2000
|
UserStatusBusy,
|
|
1293
2001
|
UserStatusOffline,
|
|
1294
2002
|
UserStatusOnline,
|
|
1295
|
-
|
|
2003
|
+
useApiAsync,
|
|
2004
|
+
useChat,
|
|
2005
|
+
useChatHistory,
|
|
2006
|
+
useChatMonitoring,
|
|
2007
|
+
useHumanAgentSessions,
|
|
2008
|
+
useMemory,
|
|
2009
|
+
useOptionsRef
|
|
1296
2010
|
});
|
|
1297
2011
|
//# sourceMappingURL=index.js.map
|