@csntgao/ai-employee-client 0.15.5 → 0.15.7
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/index.d.ts +2 -0
- package/dist/index.js +67 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ declare class AiEmployeeClient {
|
|
|
171
171
|
private socketAuthenticationFailure;
|
|
172
172
|
private availabilityReconnectAttempt;
|
|
173
173
|
private pendingFirstMessage;
|
|
174
|
+
private sessionListResolved;
|
|
174
175
|
constructor(options: AiEmployeeClientOptions);
|
|
175
176
|
get connectionState(): AiEmployeeConnectionState;
|
|
176
177
|
get sessionId(): string | null;
|
|
@@ -419,6 +420,7 @@ declare class CustomerSupportClient {
|
|
|
419
420
|
private readonly readCursorStates;
|
|
420
421
|
private readLifecycleGeneration;
|
|
421
422
|
private requestedSessionId;
|
|
423
|
+
private sessionListResolved;
|
|
422
424
|
constructor(options: CustomerSupportClientOptions);
|
|
423
425
|
get session(): CustomerSupportSession | null;
|
|
424
426
|
get messages(): readonly CustomerSupportMessage[];
|
package/dist/index.js
CHANGED
|
@@ -502,6 +502,7 @@ var AiEmployeeClient = class {
|
|
|
502
502
|
socketAuthenticationFailure = null;
|
|
503
503
|
availabilityReconnectAttempt = 0;
|
|
504
504
|
pendingFirstMessage = null;
|
|
505
|
+
sessionListResolved;
|
|
505
506
|
constructor(options) {
|
|
506
507
|
this.realtimeUrl = validateRealtimeUrl(options.realtimeUrl);
|
|
507
508
|
this.aeCode = requiredText(options.aeCode, "aeCode");
|
|
@@ -517,6 +518,7 @@ var AiEmployeeClient = class {
|
|
|
517
518
|
}
|
|
518
519
|
this.transport = options.transport;
|
|
519
520
|
this.currentSessionId = normalizeSessionId(options.sessionId);
|
|
521
|
+
this.sessionListResolved = Boolean(this.currentSessionId) || typeof options.transport.listSessions !== "function";
|
|
520
522
|
this.reconnectOptions = normalizeReconnectOptions(options.reconnect);
|
|
521
523
|
this.minimumHeartbeatMs = Math.max(1, options.minimumHeartbeatMs ?? 5e3);
|
|
522
524
|
this.requestIdFactory = options.requestIdFactory ?? createRequestId;
|
|
@@ -573,6 +575,7 @@ var AiEmployeeClient = class {
|
|
|
573
575
|
const lifecycle = ++this.lifecycleGeneration;
|
|
574
576
|
this.stopConnection(false);
|
|
575
577
|
this.currentSessionId = target;
|
|
578
|
+
this.sessionListResolved = true;
|
|
576
579
|
this.currentMessages = [];
|
|
577
580
|
this.seenMessageIds.clear();
|
|
578
581
|
this.pendingLocalMessages.clear();
|
|
@@ -596,6 +599,7 @@ var AiEmployeeClient = class {
|
|
|
596
599
|
this.lifecycleGeneration += 1;
|
|
597
600
|
this.stopConnection(false);
|
|
598
601
|
this.currentSessionId = null;
|
|
602
|
+
this.sessionListResolved = true;
|
|
599
603
|
this.currentMessages = [];
|
|
600
604
|
this.seenMessageIds.clear();
|
|
601
605
|
this.pendingLocalMessages.clear();
|
|
@@ -622,12 +626,18 @@ var AiEmployeeClient = class {
|
|
|
622
626
|
if (!normalizedContent) {
|
|
623
627
|
throw new AiEmployeeClientError("EMPTY_MESSAGE", "\u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A\u3002");
|
|
624
628
|
}
|
|
625
|
-
if (this.sending) {
|
|
629
|
+
if (this.sending || this.processing) {
|
|
626
630
|
throw new AiEmployeeClientError("SEND_IN_PROGRESS", "\u4E0A\u4E00\u6761\u6D88\u606F\u4ECD\u5728\u53D1\u9001\u4E2D\u3002");
|
|
627
631
|
}
|
|
628
632
|
this.sending = true;
|
|
629
633
|
try {
|
|
630
634
|
const sessionId = this.currentSessionId;
|
|
635
|
+
if (!sessionId && !this.sessionListResolved) {
|
|
636
|
+
throw new AiEmployeeClientError(
|
|
637
|
+
"SESSION_UNAVAILABLE",
|
|
638
|
+
"\u6700\u8FD1\u4E00\u6761\u6570\u5B57\u5458\u5DE5\u4F1A\u8BDD\u5C1A\u672A\u6062\u590D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"
|
|
639
|
+
);
|
|
640
|
+
}
|
|
631
641
|
return sessionId ? await this.sendFollowUp(sessionId, normalizedContent) : await this.sendFirstMessage(normalizedContent, options);
|
|
632
642
|
} catch (error) {
|
|
633
643
|
if (error instanceof AiEmployeeClientError) throw error;
|
|
@@ -671,8 +681,14 @@ var AiEmployeeClient = class {
|
|
|
671
681
|
}
|
|
672
682
|
async sendFollowUp(sessionId, content) {
|
|
673
683
|
this.assistantReceivedInCurrentTurn = false;
|
|
674
|
-
|
|
675
|
-
|
|
684
|
+
this.rememberPendingLocalMessage(content);
|
|
685
|
+
try {
|
|
686
|
+
await this.transport.sendMessage(sessionId, content);
|
|
687
|
+
this.assertUsable();
|
|
688
|
+
} catch (error) {
|
|
689
|
+
this.pendingLocalMessages.delete(content);
|
|
690
|
+
throw error;
|
|
691
|
+
}
|
|
676
692
|
const now = /* @__PURE__ */ new Date();
|
|
677
693
|
const message = {
|
|
678
694
|
id: `local:${now.getTime()}:${++this.localMessageSequence}`,
|
|
@@ -681,7 +697,6 @@ var AiEmployeeClient = class {
|
|
|
681
697
|
content,
|
|
682
698
|
createdAt: now.toISOString()
|
|
683
699
|
};
|
|
684
|
-
this.rememberPendingLocalMessage(content);
|
|
685
700
|
this.appendMessage(message, "local");
|
|
686
701
|
this.setProcessing(true);
|
|
687
702
|
return message;
|
|
@@ -737,6 +752,17 @@ var AiEmployeeClient = class {
|
|
|
737
752
|
return message;
|
|
738
753
|
}
|
|
739
754
|
async initialize(lifecycle) {
|
|
755
|
+
const listSessions = this.transport.listSessions;
|
|
756
|
+
if (!this.currentSessionId && listSessions && !this.sessionListResolved) {
|
|
757
|
+
const sessions = await listSessions.call(this.transport);
|
|
758
|
+
this.assertUsable();
|
|
759
|
+
if (!this.isCurrentLifecycle(lifecycle)) {
|
|
760
|
+
throw new AiEmployeeClientError("SESSION_UNAVAILABLE", "\u4F1A\u8BDD\u6062\u590D\u5DF2\u88AB\u65B0\u7684\u64CD\u4F5C\u66FF\u4EE3\u3002");
|
|
761
|
+
}
|
|
762
|
+
this.currentSessionId = latestAiEmployeeSession(sessions)?.sessionId ?? null;
|
|
763
|
+
this.sessionListResolved = true;
|
|
764
|
+
if (this.currentSessionId) await this.clearStoredFirstMessageRequest();
|
|
765
|
+
}
|
|
740
766
|
if (!this.currentSessionId) {
|
|
741
767
|
this.shouldReconnect = true;
|
|
742
768
|
this.openSocket(false);
|
|
@@ -1182,6 +1208,21 @@ var AiEmployeeClient = class {
|
|
|
1182
1208
|
}
|
|
1183
1209
|
}
|
|
1184
1210
|
};
|
|
1211
|
+
function latestAiEmployeeSession(sessions) {
|
|
1212
|
+
return latestUpdatedSession(sessions, (session) => session.updatedAt);
|
|
1213
|
+
}
|
|
1214
|
+
function latestUpdatedSession(sessions, updatedAt) {
|
|
1215
|
+
let latest = null;
|
|
1216
|
+
let latestTimestamp = Number.NEGATIVE_INFINITY;
|
|
1217
|
+
for (const session of sessions) {
|
|
1218
|
+
const timestamp = Date.parse(updatedAt(session));
|
|
1219
|
+
if (latest === null || Number.isFinite(timestamp) && timestamp > latestTimestamp) {
|
|
1220
|
+
latest = session;
|
|
1221
|
+
latestTimestamp = Number.isFinite(timestamp) ? timestamp : latestTimestamp;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
return latest;
|
|
1225
|
+
}
|
|
1185
1226
|
function safeAssistantStreamContent(content) {
|
|
1186
1227
|
const parsed = parseAiEmployeeAssistantContent(content);
|
|
1187
1228
|
if (parsed.actions.length > 0 || parsed.rejectedActionTypes?.length) return parsed.content;
|
|
@@ -1521,6 +1562,7 @@ var CustomerSupportClient = class {
|
|
|
1521
1562
|
readCursorStates = /* @__PURE__ */ new Map();
|
|
1522
1563
|
readLifecycleGeneration = 0;
|
|
1523
1564
|
requestedSessionId;
|
|
1565
|
+
sessionListResolved = false;
|
|
1524
1566
|
constructor(options) {
|
|
1525
1567
|
this.realtimeUrl = validateRealtimeUrl2(options.realtimeUrl);
|
|
1526
1568
|
if (!options.transport) {
|
|
@@ -1564,10 +1606,9 @@ var CustomerSupportClient = class {
|
|
|
1564
1606
|
const sessions = await this.transport.listSessions();
|
|
1565
1607
|
this.assertUsable();
|
|
1566
1608
|
this.replaceSessions(sessions);
|
|
1609
|
+
this.sessionListResolved = true;
|
|
1567
1610
|
const requested = this.requestedSessionId;
|
|
1568
|
-
this.currentSession = requested ? sessions.find((session) => session.id === requested) ?? null : sessions
|
|
1569
|
-
(session) => session.status !== "closed" && hasCustomerSupportMessages(session)
|
|
1570
|
-
) ?? sessions.find(hasCustomerSupportMessages) ?? null;
|
|
1611
|
+
this.currentSession = requested ? sessions.find((session) => session.id === requested) ?? null : latestCustomerSupportSession(sessions);
|
|
1571
1612
|
if (this.currentSession) {
|
|
1572
1613
|
this.emit("session", { session: this.currentSession });
|
|
1573
1614
|
await this.refreshHistory();
|
|
@@ -1585,12 +1626,14 @@ var CustomerSupportClient = class {
|
|
|
1585
1626
|
this.currentSession = null;
|
|
1586
1627
|
this.requestedSessionId = null;
|
|
1587
1628
|
this.currentMessages = [];
|
|
1629
|
+
this.sessionListResolved = true;
|
|
1588
1630
|
}
|
|
1589
1631
|
async bindSession(sessionId) {
|
|
1590
1632
|
this.assertUsable();
|
|
1591
1633
|
const normalized = requiredText2(sessionId, "sessionId");
|
|
1592
1634
|
const sessions = await this.transport.listSessions();
|
|
1593
1635
|
this.replaceSessions(sessions);
|
|
1636
|
+
this.sessionListResolved = true;
|
|
1594
1637
|
const session = sessions.find((candidate) => candidate.id === normalized);
|
|
1595
1638
|
if (!session) {
|
|
1596
1639
|
throw new CustomerSupportClientError("SESSION_UNAVAILABLE", "\u5BA2\u670D\u4F1A\u8BDD\u4E0D\u5B58\u5728\u3002");
|
|
@@ -1610,6 +1653,12 @@ var CustomerSupportClient = class {
|
|
|
1610
1653
|
this.sending = true;
|
|
1611
1654
|
try {
|
|
1612
1655
|
if (!this.currentSession) {
|
|
1656
|
+
if (!this.sessionListResolved) {
|
|
1657
|
+
throw new CustomerSupportClientError(
|
|
1658
|
+
"SESSION_UNAVAILABLE",
|
|
1659
|
+
"\u6700\u8FD1\u4E00\u6761\u4EBA\u5DE5\u5BA2\u670D\u4F1A\u8BDD\u5C1A\u672A\u6062\u590D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1613
1662
|
const result = await this.transport.createSession({
|
|
1614
1663
|
clientRequestId: requiredRequestId2(this.requestIdFactory()),
|
|
1615
1664
|
title: normalized.slice(0, 30),
|
|
@@ -2187,8 +2236,17 @@ function compareReadCursors(left, right) {
|
|
|
2187
2236
|
function maxReadCursor(left, right) {
|
|
2188
2237
|
return left && compareReadCursors(left, right) >= 0 ? left : right;
|
|
2189
2238
|
}
|
|
2190
|
-
function
|
|
2191
|
-
|
|
2239
|
+
function latestCustomerSupportSession(sessions) {
|
|
2240
|
+
let latest = null;
|
|
2241
|
+
let latestTimestamp = Number.NEGATIVE_INFINITY;
|
|
2242
|
+
for (const session of sessions) {
|
|
2243
|
+
const timestamp = Date.parse(session.updatedAt);
|
|
2244
|
+
if (latest === null || Number.isFinite(timestamp) && timestamp > latestTimestamp) {
|
|
2245
|
+
latest = session;
|
|
2246
|
+
latestTimestamp = Number.isFinite(timestamp) ? timestamp : latestTimestamp;
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return latest;
|
|
2192
2250
|
}
|
|
2193
2251
|
function requiredText2(value, field) {
|
|
2194
2252
|
const normalized = normalizedText(value);
|