@csntgao/ai-employee-client 0.14.3

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.
@@ -0,0 +1,680 @@
1
+ type AiEmployeeMessageRole = 'user' | 'assistant' | 'system' | 'error';
2
+ interface AiEmployeeMessage {
3
+ id: string;
4
+ sessionId: string;
5
+ role: AiEmployeeMessageRole;
6
+ content: string;
7
+ createdAt: string;
8
+ }
9
+ interface AiEmployeeSessionSummary {
10
+ sessionId: string;
11
+ title: string;
12
+ latestMessage: string;
13
+ latestMessageId?: string;
14
+ updatedAt: string;
15
+ unreadCount: number;
16
+ }
17
+ interface AiEmployeeAttachmentReference {
18
+ transactionId: string;
19
+ fspath: string;
20
+ }
21
+ interface AiEmployeeFirstMessageOptions {
22
+ attachments?: readonly AiEmployeeAttachmentReference[];
23
+ trustedContext?: Readonly<Record<string, unknown>> | null;
24
+ }
25
+ interface AiEmployeeFirstMessageRequest {
26
+ requestId: string;
27
+ aeCode: string;
28
+ agentCode: string;
29
+ content: string;
30
+ attachments: readonly AiEmployeeAttachmentReference[];
31
+ trustedContext: Readonly<Record<string, unknown>> | null;
32
+ }
33
+ interface AiEmployeeFirstMessageResult {
34
+ sessionId: string;
35
+ messageId: string;
36
+ executionId: string;
37
+ status: 'running' | 'queued';
38
+ startedAt: string;
39
+ aeCode: string;
40
+ agentCode: string;
41
+ conversationType: string;
42
+ title?: string;
43
+ createdAt?: string;
44
+ }
45
+ interface AiEmployeeFirstMessageRequestState {
46
+ fingerprint: string;
47
+ requestId: string;
48
+ }
49
+ interface AiEmployeeFirstMessageRequestStore {
50
+ load(scope: string): AiEmployeeFirstMessageRequestState | null | Promise<AiEmployeeFirstMessageRequestState | null>;
51
+ save(scope: string, state: AiEmployeeFirstMessageRequestState): void | Promise<void>;
52
+ clear(scope: string): void | Promise<void>;
53
+ }
54
+ interface AiEmployeeTransport {
55
+ createSessionWithFirstMessage(request: AiEmployeeFirstMessageRequest): Promise<AiEmployeeFirstMessageResult>;
56
+ listSessions?(): Promise<AiEmployeeSessionSummary[]>;
57
+ markSessionRead?(sessionId: string, latestMessageId: string): Promise<void>;
58
+ listMessages(sessionId: string): Promise<AiEmployeeMessage[]>;
59
+ sendMessage(sessionId: string, content: string): Promise<void>;
60
+ getAccessToken(): Promise<string>;
61
+ }
62
+ type AiEmployeeTransportErrorCode = 'UNAUTHORIZED' | 'ACCESS_DENIED' | 'AI_EMPLOYEE_NOT_AVAILABLE' | 'APPLICATION_NOT_SUPPORTED' | 'ORGANIZATION_CONTEXT_REQUIRED' | 'INVALID_ARGUMENT' | 'IDEMPOTENCY_CONFLICT' | 'REALTIME_UNAVAILABLE' | 'TOO_MANY_REQUESTS';
63
+ type AiEmployeeConnectionState = 'idle' | 'connecting' | 'authenticating' | 'subscribing' | 'connected' | 'reconnecting' | 'disconnected' | 'destroyed';
64
+ type AiEmployeeErrorCode = 'INVALID_CONFIGURATION' | 'SESSION_UNAVAILABLE' | 'HISTORY_LOAD_FAILED' | 'TOKEN_UNAVAILABLE' | 'WEBSOCKET_UNAVAILABLE' | 'WEBSOCKET_ERROR' | 'AUTHENTICATION_FAILED' | 'ORGANIZATION_CONTEXT_REQUIRED' | 'REALTIME_UNAVAILABLE' | 'CHANNEL_UNAVAILABLE' | 'SESSION_NOT_FOUND' | 'PROTOCOL_ERROR' | 'SEND_FAILED' | 'FIRST_MESSAGE_CONFLICT' | 'RATE_LIMITED' | 'SEND_IN_PROGRESS' | 'EMPTY_MESSAGE' | 'SOURCE_SESSION_NOT_FOUND' | 'SOURCE_SESSION_ACCESS_DENIED' | 'HANDOFF_ACTION_NOT_FOUND' | 'HANDOFF_ACTION_MISMATCH' | 'CUSTOMER_SUPPORT_UNAVAILABLE' | 'CUSTOMER_SUPPORT_HANDOFF_FAILED' | 'CLIENT_DESTROYED';
65
+ interface AiEmployeeClientErrorDetail {
66
+ code: AiEmployeeErrorCode;
67
+ message: string;
68
+ recoverable: boolean;
69
+ }
70
+ interface AiEmployeeClientEventMap {
71
+ ready: {
72
+ sessionId: string;
73
+ };
74
+ history: {
75
+ sessionId: string;
76
+ messages: readonly AiEmployeeMessage[];
77
+ };
78
+ message: {
79
+ sessionId: string;
80
+ message: AiEmployeeMessage;
81
+ source: 'local' | 'realtime';
82
+ };
83
+ title: {
84
+ sessionId: string;
85
+ title: string;
86
+ };
87
+ 'connection-state-change': {
88
+ previous: AiEmployeeConnectionState;
89
+ current: AiEmployeeConnectionState;
90
+ };
91
+ 'processing-state-change': {
92
+ processing: boolean;
93
+ };
94
+ error: AiEmployeeClientErrorDetail;
95
+ }
96
+ interface AiEmployeeReconnectOptions {
97
+ initialDelayMs: number;
98
+ maximumDelayMs: number;
99
+ factor: number;
100
+ jitter: number;
101
+ }
102
+ type AiEmployeeWebSocketFactory = (url: string) => WebSocket;
103
+ interface AiEmployeeClientOptions {
104
+ realtimeUrl: string;
105
+ aeCode: string;
106
+ agentCode: string;
107
+ transport: AiEmployeeTransport;
108
+ sessionId?: string;
109
+ reconnect?: Partial<AiEmployeeReconnectOptions>;
110
+ webSocketFactory?: AiEmployeeWebSocketFactory;
111
+ requestIdFactory?: () => string;
112
+ firstMessageRequestStore?: AiEmployeeFirstMessageRequestStore | null;
113
+ /** Primarily useful for deterministic tests. Production heartbeats are never faster than 5s. */
114
+ minimumHeartbeatMs?: number;
115
+ }
116
+ interface AiEmployeeClientStartResult {
117
+ sessionId: string | null;
118
+ messages: readonly AiEmployeeMessage[];
119
+ }
120
+ type AiEmployeeClientListener<K extends keyof AiEmployeeClientEventMap> = (detail: AiEmployeeClientEventMap[K]) => void;
121
+
122
+ declare class AiEmployeeClientError extends Error {
123
+ readonly code: AiEmployeeErrorCode;
124
+ constructor(code: AiEmployeeErrorCode, message: string);
125
+ }
126
+ declare class AiEmployeeTransportError extends Error {
127
+ readonly code: AiEmployeeTransportErrorCode;
128
+ constructor(code: AiEmployeeTransportErrorCode);
129
+ }
130
+ declare class AiEmployeeClient {
131
+ readonly aeCode: string;
132
+ readonly agentCode: string;
133
+ private readonly realtimeUrl;
134
+ private readonly transport;
135
+ private readonly webSocketFactory;
136
+ private readonly reconnectOptions;
137
+ private readonly minimumHeartbeatMs;
138
+ private readonly requestIdFactory;
139
+ private readonly firstMessageRequestStore;
140
+ private readonly firstMessageRequestScope;
141
+ private readonly listeners;
142
+ private readonly seenMessageIds;
143
+ private readonly pendingLocalMessages;
144
+ private assistantReceivedInCurrentTurn;
145
+ private socket;
146
+ private reconnectTimer;
147
+ private heartbeatTimer;
148
+ private initializePromise;
149
+ private currentMessages;
150
+ private currentSessionId;
151
+ private currentState;
152
+ private reconnectAttempt;
153
+ private socketGeneration;
154
+ private lifecycleGeneration;
155
+ private shouldReconnect;
156
+ private destroyed;
157
+ private sending;
158
+ private processing;
159
+ private localMessageSequence;
160
+ private replayHistoryOnNextSubscription;
161
+ private socketAuthenticationFailure;
162
+ private availabilityReconnectAttempt;
163
+ private pendingFirstMessage;
164
+ constructor(options: AiEmployeeClientOptions);
165
+ get connectionState(): AiEmployeeConnectionState;
166
+ get sessionId(): string | null;
167
+ get messages(): readonly AiEmployeeMessage[];
168
+ get isProcessing(): boolean;
169
+ get isDestroyed(): boolean;
170
+ on<K extends keyof AiEmployeeClientEventMap>(type: K, listener: AiEmployeeClientListener<K>): () => void;
171
+ connect(): Promise<AiEmployeeClientStartResult>;
172
+ start(): Promise<AiEmployeeClientStartResult>;
173
+ bindSession(sessionId: string): Promise<AiEmployeeClientStartResult>;
174
+ startNewConversation(): Promise<AiEmployeeClientStartResult>;
175
+ refreshMessages(): Promise<readonly AiEmployeeMessage[]>;
176
+ sendMessage(content: string, options?: AiEmployeeFirstMessageOptions): Promise<AiEmployeeMessage>;
177
+ disconnect(): void;
178
+ destroy(): void;
179
+ private sendFollowUp;
180
+ private sendFirstMessage;
181
+ private initialize;
182
+ private loadStoredFirstMessageRequest;
183
+ private saveStoredFirstMessageRequest;
184
+ private clearStoredFirstMessageRequest;
185
+ private refreshHistory;
186
+ private replaceHistory;
187
+ private openSocket;
188
+ private authenticateSocket;
189
+ private handleSocketData;
190
+ private handleServerMessage;
191
+ private handleAiEmployeeEvent;
192
+ private subscribeCurrentSession;
193
+ private rememberPendingLocalMessage;
194
+ /**
195
+ * 本地已渲染的用户消息会被服务端以 replay 和实时事件多次回送,且不保证复用
196
+ * 同一个消息 ID。窗口期内不消费该条目,多次回声都要挡住;本地发送本身每次都
197
+ * 会追加气泡,所以重复发送同样内容不会因此丢消息。
198
+ */
199
+ private matchesPendingLocalMessage;
200
+ private appendMessage;
201
+ private rememberMessageId;
202
+ private handleChannelError;
203
+ private startHeartbeat;
204
+ private handleSocketClose;
205
+ private scheduleAvailabilityReconnect;
206
+ private scheduleReconnect;
207
+ private recoverAndReconnect;
208
+ private stopConnection;
209
+ private closeCurrentSocket;
210
+ private clearReconnectTimer;
211
+ private clearHeartbeatTimer;
212
+ private setState;
213
+ private setProcessing;
214
+ private emitError;
215
+ private emit;
216
+ private isCurrentSocket;
217
+ private isCurrentLifecycle;
218
+ private assertUsable;
219
+ }
220
+
221
+ interface OpenCustomerSupportAssistantAction {
222
+ type: 'assistant_action';
223
+ action: 'open_customer_support';
224
+ transactionId: string;
225
+ trigger: 'out_of_scope';
226
+ entry: 'help_and_support';
227
+ }
228
+ type AiEmployeeAssistantAction = OpenCustomerSupportAssistantAction;
229
+ interface ParsedAiEmployeeAssistantContent {
230
+ content: string;
231
+ actions: readonly AiEmployeeAssistantAction[];
232
+ }
233
+ /**
234
+ * Parses a trusted platform action from the final standalone JSON block of an
235
+ * assistant response. Invalid or ambiguous input is returned unchanged and is
236
+ * never made executable.
237
+ */
238
+ declare function parseAiEmployeeAssistantContent(content: string): ParsedAiEmployeeAssistantContent;
239
+ declare function isUuidV4(value: unknown): value is string;
240
+
241
+ type CustomerSupportSessionStatus = 'waiting' | 'active' | 'closed';
242
+ type CustomerSupportSenderType = 'customer' | 'agent' | 'system';
243
+ interface CustomerSupportAgent {
244
+ id: string;
245
+ name: string;
246
+ avatarUrl: string;
247
+ roleName: string;
248
+ }
249
+ interface CustomerSupportMessage {
250
+ id: string;
251
+ sessionId: string;
252
+ sequence: string;
253
+ clientMessageId: string;
254
+ senderType: CustomerSupportSenderType;
255
+ senderName: string;
256
+ content: string;
257
+ createdAt: string;
258
+ }
259
+ interface CustomerSupportSession {
260
+ id: string;
261
+ sessionNo: string;
262
+ title: string;
263
+ status: CustomerSupportSessionStatus;
264
+ statusText: string;
265
+ primaryAgent: CustomerSupportAgent | null;
266
+ lastMessage: string;
267
+ unreadCount: number;
268
+ openedAt: string;
269
+ updatedAt: string;
270
+ version: string;
271
+ }
272
+ interface CustomerSupportMessagePage {
273
+ messages: readonly CustomerSupportMessage[];
274
+ latestSequence: string;
275
+ sessionVersion: string;
276
+ }
277
+ interface CustomerSupportCreateSessionRequest {
278
+ clientRequestId: string;
279
+ title?: string;
280
+ initialMessage?: string;
281
+ }
282
+ interface CustomerSupportCreateSessionResult {
283
+ session: CustomerSupportSession;
284
+ initialMessage?: CustomerSupportMessage;
285
+ }
286
+ interface CustomerSupportHandoffRequest {
287
+ sourceSessionId: string;
288
+ actionTransactionId: string;
289
+ }
290
+ interface CustomerSupportHandoffResult {
291
+ session: CustomerSupportSession;
292
+ initialMessage: CustomerSupportMessage;
293
+ created: boolean;
294
+ repaired: boolean;
295
+ }
296
+ interface CustomerSupportTransport {
297
+ getAccessToken(): Promise<string>;
298
+ listSessions(): Promise<readonly CustomerSupportSession[]>;
299
+ getSession?(sessionId: string): Promise<CustomerSupportSession>;
300
+ createSession(request: CustomerSupportCreateSessionRequest): Promise<CustomerSupportCreateSessionResult>;
301
+ createHandoffSession?(request: CustomerSupportHandoffRequest): Promise<CustomerSupportHandoffResult>;
302
+ listMessages(sessionId: string): Promise<CustomerSupportMessagePage>;
303
+ sendMessage(sessionId: string, clientMessageId: string, content: string): Promise<CustomerSupportMessage>;
304
+ markRead?(sessionId: string, lastReadSequence: string): Promise<void>;
305
+ }
306
+ interface CustomerSupportClientOptions {
307
+ realtimeUrl: string;
308
+ transport: CustomerSupportTransport;
309
+ sessionId?: string;
310
+ reconnect?: Partial<AiEmployeeReconnectOptions>;
311
+ webSocketFactory?: (url: string) => WebSocket;
312
+ requestIdFactory?: () => string;
313
+ minimumHeartbeatMs?: number;
314
+ }
315
+ type CustomerSupportErrorCode = 'INVALID_CONFIGURATION' | 'SESSION_UNAVAILABLE' | 'HISTORY_LOAD_FAILED' | 'TOKEN_UNAVAILABLE' | 'WEBSOCKET_UNAVAILABLE' | 'WEBSOCKET_ERROR' | 'AUTHENTICATION_FAILED' | 'ORGANIZATION_CONTEXT_REQUIRED' | 'REALTIME_UNAVAILABLE' | 'CHANNEL_UNAVAILABLE' | 'PROTOCOL_ERROR' | 'SEND_FAILED' | 'SEND_IN_PROGRESS' | 'EMPTY_MESSAGE' | 'CLIENT_DESTROYED';
316
+ interface CustomerSupportErrorDetail {
317
+ code: CustomerSupportErrorCode;
318
+ message: string;
319
+ recoverable: boolean;
320
+ }
321
+ interface CustomerSupportClientEventMap {
322
+ ready: {
323
+ sessionId: string | null;
324
+ };
325
+ sessions: {
326
+ sessions: readonly CustomerSupportSession[];
327
+ };
328
+ session: {
329
+ session: CustomerSupportSession;
330
+ };
331
+ history: {
332
+ sessionId: string;
333
+ messages: readonly CustomerSupportMessage[];
334
+ };
335
+ message: {
336
+ sessionId: string;
337
+ message: CustomerSupportMessage;
338
+ source: 'local' | 'realtime';
339
+ };
340
+ 'connection-state-change': {
341
+ previous: AiEmployeeConnectionState;
342
+ current: AiEmployeeConnectionState;
343
+ };
344
+ error: CustomerSupportErrorDetail;
345
+ }
346
+ type CustomerSupportClientListener<K extends keyof CustomerSupportClientEventMap> = (detail: CustomerSupportClientEventMap[K]) => void;
347
+
348
+ declare class CustomerSupportClientError extends Error {
349
+ readonly code: CustomerSupportErrorCode;
350
+ constructor(code: CustomerSupportErrorCode, message: string);
351
+ }
352
+ declare class CustomerSupportClient {
353
+ private readonly realtimeUrl;
354
+ private readonly transport;
355
+ private readonly webSocketFactory;
356
+ private readonly requestIdFactory;
357
+ private readonly reconnectOptions;
358
+ private readonly minimumHeartbeatMs;
359
+ private readonly listeners;
360
+ private currentSession;
361
+ private currentSessions;
362
+ private currentMessages;
363
+ private currentState;
364
+ private socket;
365
+ private heartbeatTimer;
366
+ private reconnectTimer;
367
+ private reconnectAttempt;
368
+ private tokenReconnectAttempt;
369
+ private availabilityReconnectAttempt;
370
+ private socketGeneration;
371
+ private socketAuthenticationFailure;
372
+ private destroyed;
373
+ private shouldReconnect;
374
+ private sending;
375
+ private historyRefresh;
376
+ private sessionsRefresh;
377
+ private readonly readCursorStates;
378
+ private readLifecycleGeneration;
379
+ private requestedSessionId;
380
+ constructor(options: CustomerSupportClientOptions);
381
+ get session(): CustomerSupportSession | null;
382
+ get messages(): readonly CustomerSupportMessage[];
383
+ get connectionState(): AiEmployeeConnectionState;
384
+ on<K extends keyof CustomerSupportClientEventMap>(type: K, listener: CustomerSupportClientListener<K>): () => void;
385
+ start(): Promise<void>;
386
+ prepareNewConversation(): void;
387
+ bindSession(sessionId: string): Promise<void>;
388
+ sendMessage(content: string): Promise<CustomerSupportMessage>;
389
+ listSessions(): Promise<readonly CustomerSupportSession[]>;
390
+ destroy(): void;
391
+ private refreshHistory;
392
+ private markReadIfNeeded;
393
+ private submitReadCursor;
394
+ private readCursorState;
395
+ private isCurrentReadRequest;
396
+ private openSocket;
397
+ private authenticate;
398
+ private handleSocketData;
399
+ private handleServerMessage;
400
+ private handleCustomerSupportEvent;
401
+ private refreshFromRealtime;
402
+ private refreshSessions;
403
+ private refreshSessionsFromRealtime;
404
+ private replaceSessions;
405
+ private upsertSession;
406
+ private refreshSessionFromRealtime;
407
+ private appendMessage;
408
+ private startHeartbeat;
409
+ private handleSocketClose;
410
+ private scheduleAvailabilityReconnect;
411
+ private scheduleReconnect;
412
+ private clearTimers;
413
+ private isCurrentSocket;
414
+ private setState;
415
+ private emitError;
416
+ private emit;
417
+ private assertUsable;
418
+ }
419
+
420
+ type NotificationReadStatus = 'unread' | 'read';
421
+ type NotificationContentType = 'text' | 'markdown';
422
+ interface NotificationSource {
423
+ type: string;
424
+ code: string;
425
+ id: string;
426
+ name: string;
427
+ avatarUrl: string;
428
+ }
429
+ interface NotificationResource {
430
+ type: string;
431
+ id: string;
432
+ title: string;
433
+ aeCode: string;
434
+ }
435
+ interface NotificationAttachment {
436
+ fileId: string;
437
+ versionId: string;
438
+ name: string;
439
+ sizeBytes: number;
440
+ mimeType: string;
441
+ }
442
+ interface NotificationDto {
443
+ id: string;
444
+ type: string;
445
+ typeName: string;
446
+ title: string;
447
+ summary: string;
448
+ content: string;
449
+ contentType: NotificationContentType;
450
+ priority: string;
451
+ source: NotificationSource | null;
452
+ resources: readonly NotificationResource[];
453
+ attachments: readonly NotificationAttachment[];
454
+ readStatus: NotificationReadStatus;
455
+ readAt: string | null;
456
+ archivedAt: string | null;
457
+ createdAt: string;
458
+ expiresAt: string | null;
459
+ }
460
+ /** 分类目录条目:稳定 code 加后端字典给出的展示名(可能为空)。 */
461
+ interface NotificationTypeSummary {
462
+ type: string;
463
+ name: string;
464
+ }
465
+ interface NotificationInboxQuery {
466
+ pageSize: number;
467
+ beforeId?: string | null;
468
+ includeTypeFacets?: boolean;
469
+ notificationTypes?: readonly string[];
470
+ readStatus?: 'all' | 'unread' | 'read';
471
+ includeArchived?: boolean;
472
+ applicationName: string;
473
+ }
474
+ interface NotificationInboxResult {
475
+ items: readonly NotificationDto[];
476
+ hasMore: boolean;
477
+ nextId: string | null;
478
+ types?: readonly NotificationTypeSummary[];
479
+ }
480
+ interface NotificationMarkReadResult {
481
+ unreadCount: number;
482
+ readAt: string | null;
483
+ }
484
+ interface NotificationMarkAllReadResult {
485
+ markedCount: number;
486
+ unreadCount: number;
487
+ }
488
+ type NotificationRealtimeChange = {
489
+ kind: 'created';
490
+ notification: NotificationDto;
491
+ unreadCount?: number;
492
+ } | {
493
+ kind: 'read';
494
+ notificationIds: readonly string[];
495
+ unreadCount?: number;
496
+ readAt?: string | null;
497
+ } | {
498
+ kind: 'archived';
499
+ notificationIds: readonly string[];
500
+ unreadCount?: number;
501
+ };
502
+ interface NotificationCenterTransport {
503
+ listInbox(query: NotificationInboxQuery): Promise<NotificationInboxResult>;
504
+ getUnreadCount(params: {
505
+ applicationName: string;
506
+ }): Promise<{
507
+ unreadCount: number;
508
+ }>;
509
+ markRead(params: {
510
+ notificationId: string;
511
+ applicationName: string;
512
+ }): Promise<NotificationMarkReadResult>;
513
+ markAllRead(params: {
514
+ beforeId?: string | null;
515
+ notificationTypes?: readonly string[];
516
+ applicationName: string;
517
+ }): Promise<NotificationMarkAllReadResult>;
518
+ downloadAttachment(params: {
519
+ fileId: string;
520
+ name?: string;
521
+ }): Promise<Blob>;
522
+ archive?(params: {
523
+ notificationId: string;
524
+ applicationName: string;
525
+ }): Promise<{
526
+ unreadCount: number;
527
+ }>;
528
+ parseRealtimeEvent?(event: unknown): NotificationRealtimeChange | null;
529
+ }
530
+ interface NotificationCenterClientOptions {
531
+ transport: NotificationCenterTransport;
532
+ applicationName: string;
533
+ pageSize?: number;
534
+ readStatus?: 'all' | 'unread' | 'read';
535
+ preferredTypeOrder?: readonly string[];
536
+ }
537
+ type NotificationCenterErrorCode = 'INVALID_CONFIGURATION' | 'INBOX_LOAD_FAILED' | 'MARK_READ_FAILED' | 'DOWNLOAD_FAILED' | 'CLIENT_DESTROYED';
538
+ interface NotificationCenterErrorDetail {
539
+ code: NotificationCenterErrorCode;
540
+ message: string;
541
+ recoverable: boolean;
542
+ }
543
+ interface NotificationCenterClientEventMap {
544
+ ready: Record<string, never>;
545
+ inbox: NotificationInboxResult;
546
+ 'types-change': {
547
+ types: readonly NotificationTypeSummary[];
548
+ };
549
+ 'unread-count-change': {
550
+ unreadCount: number;
551
+ };
552
+ 'notification-read': {
553
+ notificationId: string;
554
+ };
555
+ error: NotificationCenterErrorDetail;
556
+ }
557
+ type NotificationCenterClientListener<K extends keyof NotificationCenterClientEventMap> = (detail: NotificationCenterClientEventMap[K]) => void;
558
+
559
+ declare class NotificationCenterClientError extends Error {
560
+ readonly code: NotificationCenterErrorCode;
561
+ constructor(code: NotificationCenterErrorCode, message: string);
562
+ }
563
+ /**
564
+ * Inbox store and HTTP orchestration for the notification center.
565
+ *
566
+ * The client owns no realtime connection. The host keeps the single
567
+ * `/api/user-realtime/ws` socket it already maintains for its other channels and
568
+ * hands notification events in through {@link applyRealtimeEvent}; cursors,
569
+ * heartbeats, authentication and reconnect stay on the host side.
570
+ */
571
+ declare class NotificationCenterClient {
572
+ private readonly transport;
573
+ private readonly applicationName;
574
+ private readonly pageSize;
575
+ private readonly readStatus;
576
+ private readonly preferredTypeOrder;
577
+ private readonly listeners;
578
+ private items;
579
+ private hasMore;
580
+ private nextId;
581
+ private unreadCount;
582
+ private notificationTypes;
583
+ private availableTypes;
584
+ private typeCatalogFromBackend;
585
+ private inboxGeneration;
586
+ private destroyed;
587
+ private loadingInbox;
588
+ private pendingResync;
589
+ constructor(options: NotificationCenterClientOptions);
590
+ get notifications(): readonly NotificationDto[];
591
+ get unread(): number;
592
+ /** 数据中实际存在的通知分类,供 UI 渲染页签;不是写死的枚举。 */
593
+ get types(): readonly NotificationTypeSummary[];
594
+ on<K extends keyof NotificationCenterClientEventMap>(type: K, listener: NotificationCenterClientListener<K>): () => void;
595
+ start(): Promise<void>;
596
+ setTypeFilter(types: readonly string[]): Promise<void>;
597
+ getTypeFilter(): readonly string[];
598
+ loadMore(): Promise<void>;
599
+ refresh(): Promise<void>;
600
+ /**
601
+ * Consume a notification realtime event captured by the host socket.
602
+ *
603
+ * The raw event is mapped through the transport so the DTO contract stays in
604
+ * this SDK; anything that cannot be mapped degrades to a full refresh. Events
605
+ * that arrive while an inbox request is in flight are replaced by a resync so a
606
+ * late server page cannot drop them.
607
+ */
608
+ applyRealtimeEvent(event: unknown): void;
609
+ markRead(notificationId: string): Promise<void>;
610
+ markAllRead(): Promise<void>;
611
+ downloadAttachment(fileId: string, name?: string): Promise<Blob>;
612
+ destroy(): void;
613
+ private reloadInbox;
614
+ private finishInboxLoad;
615
+ /**
616
+ * 分类页签的数据来源。
617
+ *
618
+ * `notification_type` 是后端自由文本列,展示名来自后端字典(`notification_type_name`),
619
+ * 前端不维护 code 到中文名的映射。权威目录是 `inbox` 在 `includeTypeFacets` 下返回的
620
+ * `types`(后端按收件人可见范围统计,忽略类型筛选与分页);后端未提供时退回累积已加载
621
+ * 页面里出现过的分类——这在分页深处才出现的分类上会暂时缺页签,属已知取舍。
622
+ */
623
+ private applyTypeCatalog;
624
+ private rememberTypes;
625
+ private setAvailableTypes;
626
+ private refreshUnreadCount;
627
+ private applyRealtimeChange;
628
+ private syncRealtimeUnreadCount;
629
+ private applyRead;
630
+ private refreshFromRealtime;
631
+ private emitInbox;
632
+ private setUnreadCount;
633
+ private emitError;
634
+ private emit;
635
+ private assertUsable;
636
+ }
637
+
638
+ type JsonRecord = Record<string, unknown>;
639
+ interface AuthenticateFrame {
640
+ type: 'authenticate';
641
+ protocol_version: 1;
642
+ access_token: string;
643
+ requested_channels: ['ai_employee'];
644
+ cursors: Record<string, never>;
645
+ }
646
+ interface SessionSubscriptionFrame {
647
+ action: 'subscribe' | 'unsubscribe';
648
+ channel: 'ai_employee';
649
+ resource_type: 'session';
650
+ resource_id: string;
651
+ replay_history?: boolean;
652
+ }
653
+ interface PingFrame {
654
+ action: 'ping';
655
+ timestamp: string;
656
+ }
657
+ interface ParsedSessionMessage {
658
+ messages: AiEmployeeMessage[];
659
+ fallbackResult?: AiEmployeeMessage;
660
+ processing?: boolean;
661
+ }
662
+ type ParsedAiEmployeeEvent = {
663
+ kind: 'session-message';
664
+ sessionId: string;
665
+ result: ParsedSessionMessage;
666
+ } | {
667
+ kind: 'session-title';
668
+ sessionId: string;
669
+ title: string;
670
+ } | {
671
+ kind: 'ignored';
672
+ };
673
+ declare function createAuthenticateFrame(accessToken: string): AuthenticateFrame;
674
+ declare function createSubscriptionFrame(sessionId: string, action?: 'subscribe' | 'unsubscribe', replayHistory?: boolean): SessionSubscriptionFrame;
675
+ declare function createPingFrame(now?: Date): PingFrame;
676
+ declare function parseJsonRecord(raw: string): JsonRecord | null;
677
+ declare function parseAiEmployeeEvent(raw: unknown): ParsedAiEmployeeEvent;
678
+ declare function hashText(value: string): string;
679
+
680
+ export { type AiEmployeeAssistantAction, type AiEmployeeAttachmentReference, AiEmployeeClient, AiEmployeeClientError, type AiEmployeeClientErrorDetail, type AiEmployeeClientEventMap, type AiEmployeeClientListener, type AiEmployeeClientOptions, type AiEmployeeClientStartResult, type AiEmployeeConnectionState, type AiEmployeeErrorCode, type AiEmployeeFirstMessageOptions, type AiEmployeeFirstMessageRequest, type AiEmployeeFirstMessageRequestState, type AiEmployeeFirstMessageRequestStore, type AiEmployeeFirstMessageResult, type AiEmployeeMessage, type AiEmployeeMessageRole, type AiEmployeeReconnectOptions, type AiEmployeeSessionSummary, type AiEmployeeTransport, AiEmployeeTransportError, type AiEmployeeTransportErrorCode, type AiEmployeeWebSocketFactory, type AuthenticateFrame, type CustomerSupportAgent, CustomerSupportClient, CustomerSupportClientError, type CustomerSupportClientEventMap, type CustomerSupportClientListener, type CustomerSupportClientOptions, type CustomerSupportCreateSessionRequest, type CustomerSupportCreateSessionResult, type CustomerSupportErrorCode, type CustomerSupportErrorDetail, type CustomerSupportHandoffRequest, type CustomerSupportHandoffResult, type CustomerSupportMessage, type CustomerSupportMessagePage, type CustomerSupportSenderType, type CustomerSupportSession, type CustomerSupportSessionStatus, type CustomerSupportTransport, type NotificationAttachment, NotificationCenterClient, NotificationCenterClientError, type NotificationCenterClientEventMap, type NotificationCenterClientListener, type NotificationCenterClientOptions, type NotificationCenterErrorCode, type NotificationCenterErrorDetail, type NotificationCenterTransport, type NotificationContentType, type NotificationDto, type NotificationInboxQuery, type NotificationInboxResult, type NotificationMarkAllReadResult, type NotificationMarkReadResult, type NotificationReadStatus, type NotificationRealtimeChange, type NotificationResource, type NotificationSource, type NotificationTypeSummary, type OpenCustomerSupportAssistantAction, type ParsedAiEmployeeAssistantContent, type ParsedAiEmployeeEvent, type ParsedSessionMessage, type PingFrame, type SessionSubscriptionFrame, createAuthenticateFrame, createPingFrame, createSubscriptionFrame, hashText, isUuidV4, parseAiEmployeeAssistantContent, parseAiEmployeeEvent, parseJsonRecord };