@csntgao/ai-employee-client 0.15.5 → 0.15.6

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 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();
@@ -628,6 +632,12 @@ var AiEmployeeClient = class {
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;
@@ -737,6 +747,17 @@ var AiEmployeeClient = class {
737
747
  return message;
738
748
  }
739
749
  async initialize(lifecycle) {
750
+ const listSessions = this.transport.listSessions;
751
+ if (!this.currentSessionId && listSessions && !this.sessionListResolved) {
752
+ const sessions = await listSessions.call(this.transport);
753
+ this.assertUsable();
754
+ if (!this.isCurrentLifecycle(lifecycle)) {
755
+ throw new AiEmployeeClientError("SESSION_UNAVAILABLE", "\u4F1A\u8BDD\u6062\u590D\u5DF2\u88AB\u65B0\u7684\u64CD\u4F5C\u66FF\u4EE3\u3002");
756
+ }
757
+ this.currentSessionId = latestAiEmployeeSession(sessions)?.sessionId ?? null;
758
+ this.sessionListResolved = true;
759
+ if (this.currentSessionId) await this.clearStoredFirstMessageRequest();
760
+ }
740
761
  if (!this.currentSessionId) {
741
762
  this.shouldReconnect = true;
742
763
  this.openSocket(false);
@@ -1182,6 +1203,21 @@ var AiEmployeeClient = class {
1182
1203
  }
1183
1204
  }
1184
1205
  };
1206
+ function latestAiEmployeeSession(sessions) {
1207
+ return latestUpdatedSession(sessions, (session) => session.updatedAt);
1208
+ }
1209
+ function latestUpdatedSession(sessions, updatedAt) {
1210
+ let latest = null;
1211
+ let latestTimestamp = Number.NEGATIVE_INFINITY;
1212
+ for (const session of sessions) {
1213
+ const timestamp = Date.parse(updatedAt(session));
1214
+ if (latest === null || Number.isFinite(timestamp) && timestamp > latestTimestamp) {
1215
+ latest = session;
1216
+ latestTimestamp = Number.isFinite(timestamp) ? timestamp : latestTimestamp;
1217
+ }
1218
+ }
1219
+ return latest;
1220
+ }
1185
1221
  function safeAssistantStreamContent(content) {
1186
1222
  const parsed = parseAiEmployeeAssistantContent(content);
1187
1223
  if (parsed.actions.length > 0 || parsed.rejectedActionTypes?.length) return parsed.content;
@@ -1521,6 +1557,7 @@ var CustomerSupportClient = class {
1521
1557
  readCursorStates = /* @__PURE__ */ new Map();
1522
1558
  readLifecycleGeneration = 0;
1523
1559
  requestedSessionId;
1560
+ sessionListResolved = false;
1524
1561
  constructor(options) {
1525
1562
  this.realtimeUrl = validateRealtimeUrl2(options.realtimeUrl);
1526
1563
  if (!options.transport) {
@@ -1564,10 +1601,9 @@ var CustomerSupportClient = class {
1564
1601
  const sessions = await this.transport.listSessions();
1565
1602
  this.assertUsable();
1566
1603
  this.replaceSessions(sessions);
1604
+ this.sessionListResolved = true;
1567
1605
  const requested = this.requestedSessionId;
1568
- this.currentSession = requested ? sessions.find((session) => session.id === requested) ?? null : sessions.find(
1569
- (session) => session.status !== "closed" && hasCustomerSupportMessages(session)
1570
- ) ?? sessions.find(hasCustomerSupportMessages) ?? null;
1606
+ this.currentSession = requested ? sessions.find((session) => session.id === requested) ?? null : latestCustomerSupportSession(sessions);
1571
1607
  if (this.currentSession) {
1572
1608
  this.emit("session", { session: this.currentSession });
1573
1609
  await this.refreshHistory();
@@ -1585,12 +1621,14 @@ var CustomerSupportClient = class {
1585
1621
  this.currentSession = null;
1586
1622
  this.requestedSessionId = null;
1587
1623
  this.currentMessages = [];
1624
+ this.sessionListResolved = true;
1588
1625
  }
1589
1626
  async bindSession(sessionId) {
1590
1627
  this.assertUsable();
1591
1628
  const normalized = requiredText2(sessionId, "sessionId");
1592
1629
  const sessions = await this.transport.listSessions();
1593
1630
  this.replaceSessions(sessions);
1631
+ this.sessionListResolved = true;
1594
1632
  const session = sessions.find((candidate) => candidate.id === normalized);
1595
1633
  if (!session) {
1596
1634
  throw new CustomerSupportClientError("SESSION_UNAVAILABLE", "\u5BA2\u670D\u4F1A\u8BDD\u4E0D\u5B58\u5728\u3002");
@@ -1610,6 +1648,12 @@ var CustomerSupportClient = class {
1610
1648
  this.sending = true;
1611
1649
  try {
1612
1650
  if (!this.currentSession) {
1651
+ if (!this.sessionListResolved) {
1652
+ throw new CustomerSupportClientError(
1653
+ "SESSION_UNAVAILABLE",
1654
+ "\u6700\u8FD1\u4E00\u6761\u4EBA\u5DE5\u5BA2\u670D\u4F1A\u8BDD\u5C1A\u672A\u6062\u590D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"
1655
+ );
1656
+ }
1613
1657
  const result = await this.transport.createSession({
1614
1658
  clientRequestId: requiredRequestId2(this.requestIdFactory()),
1615
1659
  title: normalized.slice(0, 30),
@@ -2187,8 +2231,17 @@ function compareReadCursors(left, right) {
2187
2231
  function maxReadCursor(left, right) {
2188
2232
  return left && compareReadCursors(left, right) >= 0 ? left : right;
2189
2233
  }
2190
- function hasCustomerSupportMessages(session) {
2191
- return session.lastMessage.trim().length > 0;
2234
+ function latestCustomerSupportSession(sessions) {
2235
+ let latest = null;
2236
+ let latestTimestamp = Number.NEGATIVE_INFINITY;
2237
+ for (const session of sessions) {
2238
+ const timestamp = Date.parse(session.updatedAt);
2239
+ if (latest === null || Number.isFinite(timestamp) && timestamp > latestTimestamp) {
2240
+ latest = session;
2241
+ latestTimestamp = Number.isFinite(timestamp) ? timestamp : latestTimestamp;
2242
+ }
2243
+ }
2244
+ return latest;
2192
2245
  }
2193
2246
  function requiredText2(value, field) {
2194
2247
  const normalized = normalizedText(value);