@sendbird/ai-agent-messenger-react 1.19.1 → 1.20.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/dist/cjs/7UVs65zS.cjs +1 -0
- package/dist/cjs/BMS5Zb7W.cjs +1 -0
- package/dist/cjs/BRnfdIkb.cjs +1 -0
- package/dist/cjs/D2Opuq0j.cjs +1 -0
- package/dist/cjs/DFmkiYPE.cjs +1 -0
- package/dist/cjs/DTCJ6-eC.cjs +1 -0
- package/dist/cjs/DbxUqtQc.cjs +1 -0
- package/dist/cjs/DfRVurNO.cjs +1 -0
- package/dist/cjs/Dl0262MS.cjs +1 -0
- package/dist/cjs/JLk8Bvao.cjs +1 -0
- package/dist/es/{DGBsXgND.js → BB3d9QYh.js} +1 -1
- package/dist/es/{BrmYafuu.js → BELIKAJm.js} +1 -1
- package/dist/es/{Bnz_J6Ij.js → BdQuAUPe.js} +1 -1
- package/dist/es/{BQt0I0G7.js → C5TioO5h.js} +1 -1
- package/dist/es/{CTiYbbZ0.js → CNnV1uD8.js} +1 -1
- package/dist/es/{C0ROszna.js → CT9vVq3h.js} +1 -1
- package/dist/es/{B328z7Yh.js → D_jawtL2.js} +1 -1
- package/dist/es/{DLrmbQi7.js → DlJqMPv3.js} +1 -1
- package/dist/es/{3MMW9yZj.js → DqTYCLQ3.js} +1 -1
- package/dist/es/{DKppAyK1.js → ETHHqHi2.js} +1 -1
- package/dist/index.cjs +330 -1
- package/dist/index.d.ts +625 -4
- package/dist/index.js +7370 -37
- package/package.json +10 -4
- package/dist/cjs/6Zr7tYRh.cjs +0 -330
- package/dist/cjs/CNK70fWM.cjs +0 -1
- package/dist/cjs/CQd8GuWE.cjs +0 -1
- package/dist/cjs/CXfbOeBS.cjs +0 -1
- package/dist/cjs/Ct1aEvl9.cjs +0 -1
- package/dist/cjs/DQCOoJ_z.cjs +0 -1
- package/dist/cjs/DZS61iww.cjs +0 -1
- package/dist/cjs/D___JlpJ.cjs +0 -1
- package/dist/cjs/DghGvqtY.cjs +0 -1
- package/dist/cjs/DlQtWfBS.cjs +0 -1
- package/dist/cjs/eRuO6jKx.cjs +0 -1
- package/dist/es/DbmXdAKl.js +0 -6761
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Action } from '@sendbird/uikit-message-template';
|
|
2
2
|
import { AIAgentChannelFilter } from '@sendbird/chat/aiAgent';
|
|
3
|
+
import { AIAgentGroupChannelListQuery } from '@sendbird/chat/aiAgent';
|
|
3
4
|
import { AIAgentModule } from '@sendbird/chat/aiAgent';
|
|
5
|
+
import { BaseChannel } from '@sendbird/chat';
|
|
4
6
|
import { BaseMessage } from '@sendbird/chat/message';
|
|
5
7
|
import { ComponentType } from 'react';
|
|
8
|
+
import { ConnectionHandler } from '@sendbird/chat';
|
|
6
9
|
import { Context } from 'react';
|
|
7
10
|
import { Conversation as Conversation_2 } from '@sendbird/chat/aiAgent';
|
|
8
11
|
import { ConversationStatus } from '@sendbird/chat/aiAgent';
|
|
@@ -14,6 +17,9 @@ import { FileMessageCreateParams } from '@sendbird/chat/message';
|
|
|
14
17
|
import { format } from 'date-fns';
|
|
15
18
|
import { ForwardRefExoticComponent } from 'react';
|
|
16
19
|
import { GroupChannel } from '@sendbird/chat/groupChannel';
|
|
20
|
+
import { GroupChannelChangelogs } from '@sendbird/chat/aiAgent';
|
|
21
|
+
import { GroupChannelHandler } from '@sendbird/chat/groupChannel';
|
|
22
|
+
import { GroupChannelListOrder } from '@sendbird/chat/groupChannel';
|
|
17
23
|
import { GroupChannelModule } from '@sendbird/chat/groupChannel';
|
|
18
24
|
import { JSX } from 'react/jsx-runtime';
|
|
19
25
|
import { LazyExoticComponent } from 'react';
|
|
@@ -229,6 +235,10 @@ queryParams?: AIAgentQueryParams;
|
|
|
229
235
|
* @description AIAgent global default config.
|
|
230
236
|
* */
|
|
231
237
|
config?: AIAgentConfig;
|
|
238
|
+
/** @internal */
|
|
239
|
+
deskParams?: {
|
|
240
|
+
customApiHost?: string;
|
|
241
|
+
};
|
|
232
242
|
/**
|
|
233
243
|
* @internal
|
|
234
244
|
* @description Preview configurations for the ai agent client.
|
|
@@ -370,7 +380,7 @@ declare interface AIAgentCache {
|
|
|
370
380
|
messenger: MessengerSessionCache;
|
|
371
381
|
}
|
|
372
382
|
|
|
373
|
-
declare interface AIAgentConfig {
|
|
383
|
+
export declare interface AIAgentConfig {
|
|
374
384
|
conversation?: {
|
|
375
385
|
/**
|
|
376
386
|
* Whether to show the "Start new conversation" button at the end of the message list.
|
|
@@ -440,7 +450,11 @@ declare interface AIAgentConfig {
|
|
|
440
450
|
declare interface AIAgentContextValue {
|
|
441
451
|
appId: string;
|
|
442
452
|
aiAgentId: string;
|
|
453
|
+
|
|
454
|
+
/** @internal Do not use directly. This is an internal SDK instance. */
|
|
455
|
+
_aiAgentSDK: AIAgentInterface;
|
|
443
456
|
chatSDK: SendbirdChatWith<[GroupChannelModule, AIAgentModule]>;
|
|
457
|
+
deskClient: DeskClientInterface;
|
|
444
458
|
|
|
445
459
|
language: string;
|
|
446
460
|
countryCode?: string;
|
|
@@ -552,6 +566,80 @@ declare interface AIAgentInfo {
|
|
|
552
566
|
isUserFeedbackCommentOptionEnabled: boolean;
|
|
553
567
|
}
|
|
554
568
|
|
|
569
|
+
/**
|
|
570
|
+
* Public interface for AIAgent SDK instance.
|
|
571
|
+
* This interface exposes the public API of the AIAgent class.
|
|
572
|
+
*/
|
|
573
|
+
declare interface AIAgentInterface {
|
|
574
|
+
/** Sendbird application ID */
|
|
575
|
+
readonly appId: string;
|
|
576
|
+
/** AI Agent ID */
|
|
577
|
+
readonly aiAgentId: string;
|
|
578
|
+
|
|
579
|
+
/** The underlying Sendbird Chat SDK instance */
|
|
580
|
+
readonly chatSDK: ChatSDKType;
|
|
581
|
+
/** The current authenticated session. `null` if not authenticated */
|
|
582
|
+
readonly session: AIAgentSession | null;
|
|
583
|
+
/** The Desk client. Available after authenticate(). */
|
|
584
|
+
readonly deskClient: DeskClientInterface;
|
|
585
|
+
// TODO: Change to `AIAgentConfig` (non-optional) once the context migration lands and all usages are updated
|
|
586
|
+
/** The AI Agent configuration */
|
|
587
|
+
config: AIAgentConfig | undefined;
|
|
588
|
+
/** The query parameters for AI Agent */
|
|
589
|
+
queryParams?: AIAgentQueryParams;
|
|
590
|
+
/** The adapter for detecting online/offline network state */
|
|
591
|
+
readonly networkStateAdapter: NetworkStateAdapter | undefined;
|
|
592
|
+
/** The logger instance */
|
|
593
|
+
readonly logger: Loggable;
|
|
594
|
+
/** The event dispatcher */
|
|
595
|
+
readonly dispatcher: Dispatcher;
|
|
596
|
+
/** The cache instance */
|
|
597
|
+
readonly cache: AIAgentCache;
|
|
598
|
+
/** The language setting */
|
|
599
|
+
language: string;
|
|
600
|
+
/** The country code setting */
|
|
601
|
+
countryCode?: string;
|
|
602
|
+
/** The context object for AI Agent */
|
|
603
|
+
context?: Record<string, string>;
|
|
604
|
+
|
|
605
|
+
/** @internal Stats trackers for performance monitoring */
|
|
606
|
+
readonly statsTrackers: {
|
|
607
|
+
initialRender: ConversationInitialRenderStatsTracker;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
/** Authenticates with the AI Agent server and establishes a session */
|
|
611
|
+
authenticate: (sessionInfo: ManualSessionInfo | AnonymousSessionInfo) => Promise<MessengerSettingsResponse>;
|
|
612
|
+
/** Disconnects from the AI Agent server and clears the session */
|
|
613
|
+
deauthenticate: () => Promise<void>;
|
|
614
|
+
/** Creates a new conversation with the AI Agent */
|
|
615
|
+
createConversation: (params: ConversationCreateParams) => Promise<string>;
|
|
616
|
+
/** Searches for open conversations that match the specified context */
|
|
617
|
+
searchConversation: (params: SearchConversationParams) => Promise<string[]>;
|
|
618
|
+
/** Closes an open conversation */
|
|
619
|
+
closeConversation: (channelUrl: string) => Promise<void>;
|
|
620
|
+
/** Creates a collection for paginating through conversations */
|
|
621
|
+
createConversationListCollection: (params?: ConversationListCollectionParams) => ConversationListCollection;
|
|
622
|
+
/** Patches (merges) context data for the specified channel */
|
|
623
|
+
patchContext: (channelUrl: string, context: Record<string, string>) => Promise<ContextObject>;
|
|
624
|
+
/** Replaces the entire context data for the specified channel */
|
|
625
|
+
updateContext: (channelUrl: string, context: Record<string, string>) => Promise<ContextObject>;
|
|
626
|
+
/** Retrieves the context data for the specified channel */
|
|
627
|
+
getContextObject: (channelUrl: string) => Promise<ContextObject>;
|
|
628
|
+
|
|
629
|
+
/** @internal Refreshes the active channel by re-requesting messenger settings */
|
|
630
|
+
refreshActiveChannel: (options?: { useKnownActiveChannelUrl?: boolean }) => Promise<string>;
|
|
631
|
+
|
|
632
|
+
/** Disposes all resources held by this instance (WebSocket, desk auth, event handlers). */
|
|
633
|
+
dispose: () => void;
|
|
634
|
+
|
|
635
|
+
/** Registers a handler for messenger settings updates */
|
|
636
|
+
onMessengerSettingsUpdated: (handler: (params: MessengerSettingsUpdatedParams) => void) => () => void;
|
|
637
|
+
/** Registers a handler for active channel updates */
|
|
638
|
+
onActiveChannelUpdated: (handler: (params: ActiveChannelUpdatedParams) => void) => () => void;
|
|
639
|
+
/** Registers a handler for auth token refresh events */
|
|
640
|
+
onAuthTokenRefreshed: (handler: (params: AuthTokenRefreshedParams) => void) => () => void;
|
|
641
|
+
}
|
|
642
|
+
|
|
555
643
|
/**
|
|
556
644
|
* Language set interface that includes strings and locale
|
|
557
645
|
* T can be any shape - doesn't have to extend AIAgentCommonStrings
|
|
@@ -713,6 +801,10 @@ export declare type AIAgentProps = PropsWithChildren<{
|
|
|
713
801
|
* @description AIAgent global default config.
|
|
714
802
|
* */
|
|
715
803
|
config?: AIAgentConfig;
|
|
804
|
+
/** @internal */
|
|
805
|
+
deskParams?: {
|
|
806
|
+
customApiHost?: string;
|
|
807
|
+
};
|
|
716
808
|
/**
|
|
717
809
|
* @internal
|
|
718
810
|
* @description Preview configurations for the ai agent client.
|
|
@@ -757,10 +849,72 @@ export declare type AIAgentProps = PropsWithChildren<{
|
|
|
757
849
|
};
|
|
758
850
|
}>;
|
|
759
851
|
|
|
760
|
-
declare interface AIAgentQueryParams {
|
|
852
|
+
export declare interface AIAgentQueryParams {
|
|
761
853
|
conversationListParams?: ConversationListCollectionParams;
|
|
762
854
|
}
|
|
763
855
|
|
|
856
|
+
/**
|
|
857
|
+
* @description Represents an authenticated session state. Created after successful authentication.
|
|
858
|
+
*/
|
|
859
|
+
declare class AIAgentSession {
|
|
860
|
+
private readonly _sdkUser: User;
|
|
861
|
+
private readonly _userSession: UserSession;
|
|
862
|
+
private readonly _dispatcher: Dispatcher;
|
|
863
|
+
private _activeChannel: ActiveChannel;
|
|
864
|
+
|
|
865
|
+
constructor(params: AIAgentSessionParams) {
|
|
866
|
+
this._sdkUser = params.sdkUser;
|
|
867
|
+
this._userSession = params.userSession;
|
|
868
|
+
this._dispatcher = params.dispatcher;
|
|
869
|
+
this._activeChannel = params.activeChannel;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* The authenticated Sendbird user.
|
|
874
|
+
*/
|
|
875
|
+
get sdkUser(): User {
|
|
876
|
+
return this._sdkUser;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* The current user session containing userId and authToken.
|
|
881
|
+
*/
|
|
882
|
+
get userSession(): UserSession {
|
|
883
|
+
return this._userSession;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* The currently active channel.
|
|
888
|
+
*/
|
|
889
|
+
get activeChannel(): ActiveChannel {
|
|
890
|
+
return this._activeChannel;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Updates the active channel and dispatches ActiveChannelUpdated event.
|
|
895
|
+
* @internal
|
|
896
|
+
*/
|
|
897
|
+
_updateActiveChannel = (channel: ActiveChannel): void => {
|
|
898
|
+
this._activeChannel = channel;
|
|
899
|
+
this._dispatcher.send(
|
|
900
|
+
DispatcherCommands.ActiveChannelUpdated({
|
|
901
|
+
channelUrl: channel.url,
|
|
902
|
+
status: channel.status,
|
|
903
|
+
conversationStatus: channel.conversationStatus,
|
|
904
|
+
}),
|
|
905
|
+
);
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Updates the auth token when session is refreshed.
|
|
910
|
+
* @internal
|
|
911
|
+
*/
|
|
912
|
+
_updateAuthToken = (authToken: string): void => {
|
|
913
|
+
this._userSession.authToken = authToken;
|
|
914
|
+
this._dispatcher.send(DispatcherCommands.AuthTokenRefreshed());
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
764
918
|
/**
|
|
765
919
|
* AI Agent session handler.
|
|
766
920
|
* */
|
|
@@ -768,6 +922,13 @@ declare interface AIAgentSessionHandler extends SessionHandler {
|
|
|
768
922
|
onExternalAuthTokenExpired?: (data: ExternalAuthTokenExpiredData) => void;
|
|
769
923
|
}
|
|
770
924
|
|
|
925
|
+
declare interface AIAgentSessionParams {
|
|
926
|
+
sdkUser: User;
|
|
927
|
+
userSession: UserSession;
|
|
928
|
+
activeChannel: ActiveChannel;
|
|
929
|
+
dispatcher: Dispatcher;
|
|
930
|
+
}
|
|
931
|
+
|
|
771
932
|
declare interface AIAgentStatPayload {
|
|
772
933
|
key: string;
|
|
773
934
|
value?: string;
|
|
@@ -884,6 +1045,8 @@ declare interface AttachmentRules {
|
|
|
884
1045
|
getUploadSizeLimitInMB: (mimeType: string) => number;
|
|
885
1046
|
}
|
|
886
1047
|
|
|
1048
|
+
declare interface AuthTokenRefreshedParams {}
|
|
1049
|
+
|
|
887
1050
|
declare abstract class BaseCommand {
|
|
888
1051
|
abstract type: CommandType;
|
|
889
1052
|
payload: any;
|
|
@@ -915,6 +1078,8 @@ declare type BaseMessageProps<T> = T & {
|
|
|
915
1078
|
children?: ReactNode;
|
|
916
1079
|
};
|
|
917
1080
|
|
|
1081
|
+
declare type ChatSDKType = SendbirdChatWith<[GroupChannelModule, AIAgentModule]>;
|
|
1082
|
+
|
|
918
1083
|
export declare interface CitationInfo {
|
|
919
1084
|
embedding_id: number;
|
|
920
1085
|
source_type: string;
|
|
@@ -932,6 +1097,7 @@ declare interface CommandPayloads {
|
|
|
932
1097
|
[CommandType.MessengerSettingsUpdated]: MessengerSettingsUpdatedParams;
|
|
933
1098
|
[CommandType.ActiveChannelUpdated]: ActiveChannelUpdatedParams;
|
|
934
1099
|
[CommandType.AnonymousSessionTokenExpired]: undefined;
|
|
1100
|
+
[CommandType.AuthTokenRefreshed]: AuthTokenRefreshedParams;
|
|
935
1101
|
}
|
|
936
1102
|
|
|
937
1103
|
export declare const Commands = {
|
|
@@ -939,6 +1105,7 @@ export declare const Commands = {
|
|
|
939
1105
|
MessengerSettingsUpdated: (params: MessengerSettingsUpdatedParams) => new MessengerSettingsUpdatedCommand(params),
|
|
940
1106
|
ActiveChannelUpdated: (params: ActiveChannelUpdatedParams) => new ActiveChannelUpdatedCommand(params),
|
|
941
1107
|
AnonymousSessionTokenExpired: () => new AnonymousSessionTokenExpiredCommand(),
|
|
1108
|
+
AuthTokenRefreshed: () => new AuthTokenRefreshedCommand(),
|
|
942
1109
|
};
|
|
943
1110
|
|
|
944
1111
|
declare enum CommandType {
|
|
@@ -946,6 +1113,7 @@ declare enum CommandType {
|
|
|
946
1113
|
MessengerSettingsUpdated = 'messenger.settings.updated',
|
|
947
1114
|
ActiveChannelUpdated = 'active.channel.updated',
|
|
948
1115
|
AnonymousSessionTokenExpired = 'anon.token.expired',
|
|
1116
|
+
AuthTokenRefreshed = 'auth.token.refreshed',
|
|
949
1117
|
}
|
|
950
1118
|
|
|
951
1119
|
declare interface ContextObject {
|
|
@@ -1239,6 +1407,385 @@ export declare const ConversationLayout: {
|
|
|
1239
1407
|
|
|
1240
1408
|
export declare const ConversationList: ({ conversationListLimit, conversationListFilter, children, onOpenConversationView, style, }: Props_4) => JSX.Element;
|
|
1241
1409
|
|
|
1410
|
+
/**
|
|
1411
|
+
* A collection for managing AI agent group channels with real-time updates and pagination.
|
|
1412
|
+
* Automatically separates pinned and non-pinned channels, with pinned channels prioritized at the top.
|
|
1413
|
+
*/
|
|
1414
|
+
declare class ConversationListCollection {
|
|
1415
|
+
/** The filter configuration used for this collection */
|
|
1416
|
+
readonly filter?: AIAgentGroupChannelFilter;
|
|
1417
|
+
|
|
1418
|
+
private _sdk: ChatSDKType;
|
|
1419
|
+
private _pinnedChannels: GroupChannel[];
|
|
1420
|
+
private _channels: GroupChannel[];
|
|
1421
|
+
|
|
1422
|
+
private _isDisposed = false;
|
|
1423
|
+
private _handlerId = `handler-id-${Date.now()}`;
|
|
1424
|
+
private _order: GroupChannelListOrder = GroupChannelListOrder.LATEST_LAST_MESSAGE;
|
|
1425
|
+
|
|
1426
|
+
private _limit: number;
|
|
1427
|
+
private _query: AIAgentGroupChannelListQuery;
|
|
1428
|
+
|
|
1429
|
+
private _token: string;
|
|
1430
|
+
private _timestamp: number;
|
|
1431
|
+
private _isSyncing: boolean;
|
|
1432
|
+
|
|
1433
|
+
private _channelHandler: GroupChannelHandler;
|
|
1434
|
+
private _connectionHandler: ConnectionHandler;
|
|
1435
|
+
private _collectionEventHandler?: ConversationListCollectionEventHandler;
|
|
1436
|
+
private _throttledOnChannelChanged: ThrottledFunction<(channel: BaseChannel) => void>;
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Creates a new ConversationListCollection instance.
|
|
1440
|
+
* @param sdk - The Sendbird Chat SDK instance
|
|
1441
|
+
* @param params - Configuration parameters for the collection
|
|
1442
|
+
*/
|
|
1443
|
+
constructor(sdk: ChatSDKType, { filter, limit = 20 }: ConversationListCollectionParams) {
|
|
1444
|
+
this.filter = filter;
|
|
1445
|
+
|
|
1446
|
+
this._sdk = sdk;
|
|
1447
|
+
this._pinnedChannels = [];
|
|
1448
|
+
this._channels = [];
|
|
1449
|
+
|
|
1450
|
+
this._limit = limit;
|
|
1451
|
+
this._query = this._sdk.aiAgent.createMyGroupChannelListQuery({
|
|
1452
|
+
aiAgentChannelFilter: this.filter?.aiAgentChannelFilter,
|
|
1453
|
+
aiAgentConversationStatusFilter: this.filter?.aiAgentConversationStatusFilter,
|
|
1454
|
+
aiAgentIds: this.filter?.aiAgentIds,
|
|
1455
|
+
deskChannelFilter: this.filter?.deskChannelFilter,
|
|
1456
|
+
pinnedChannelUrls: this.filter?.pinnedChannelUrls,
|
|
1457
|
+
copilotConversationOnly: this.filter?.copilotConversationOnly,
|
|
1458
|
+
copilotSupportChannelUrl: this.filter?.copilotSupportChannelUrl,
|
|
1459
|
+
limit: this._limit,
|
|
1460
|
+
});
|
|
1461
|
+
|
|
1462
|
+
this._token = '';
|
|
1463
|
+
this._timestamp = Number.MAX_SAFE_INTEGER;
|
|
1464
|
+
this._isSyncing = false;
|
|
1465
|
+
|
|
1466
|
+
this._throttledOnChannelChanged = throttle(
|
|
1467
|
+
(channel: GroupChannel) => {
|
|
1468
|
+
if (this._query.belongsTo(channel)) {
|
|
1469
|
+
this._addChannelsToView([channel], false);
|
|
1470
|
+
} else {
|
|
1471
|
+
this._removeChannelsFromView([channel.url]);
|
|
1472
|
+
}
|
|
1473
|
+
},
|
|
1474
|
+
250,
|
|
1475
|
+
{ trailing: false, leading: true },
|
|
1476
|
+
);
|
|
1477
|
+
|
|
1478
|
+
this._channelHandler = new GroupChannelHandler({
|
|
1479
|
+
onChannelChanged: (channel) => {
|
|
1480
|
+
if (!channel.isGroupChannel()) return;
|
|
1481
|
+
this._throttledOnChannelChanged(channel);
|
|
1482
|
+
},
|
|
1483
|
+
onChannelDeleted: (channelUrl) => {
|
|
1484
|
+
this._removeChannelsFromView([channelUrl]);
|
|
1485
|
+
},
|
|
1486
|
+
});
|
|
1487
|
+
|
|
1488
|
+
this._connectionHandler = new ConnectionHandler({
|
|
1489
|
+
onReconnectSucceeded: () => {
|
|
1490
|
+
if (this._isDefaultChangelogSyncTimestampUpdated) this._syncChannelChangelogs();
|
|
1491
|
+
},
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
this._sdk.addConnectionHandler(this._handlerId, this._connectionHandler);
|
|
1495
|
+
this._sdk.groupChannel.addGroupChannelHandler(this._handlerId, this._channelHandler);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* Checks if the default changelog sync timestamp has been updated.
|
|
1500
|
+
*/
|
|
1501
|
+
private get _isDefaultChangelogSyncTimestampUpdated() {
|
|
1502
|
+
return this._timestamp !== Number.MAX_SAFE_INTEGER;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* Sets the default changelog sync timestamp based on the first non-pinned channel.
|
|
1507
|
+
* @param channels - Array of channels to analyze
|
|
1508
|
+
*/
|
|
1509
|
+
private _setDefaultChangelogsSyncTimestamp(channels: GroupChannel[]) {
|
|
1510
|
+
const pinnedUrlsSet = new Set(this.filter?.pinnedChannelUrls ?? []);
|
|
1511
|
+
const firstChannel = channels.find((it) => {
|
|
1512
|
+
return !pinnedUrlsSet.has(it.url);
|
|
1513
|
+
});
|
|
1514
|
+
|
|
1515
|
+
let candidate: number;
|
|
1516
|
+
if (firstChannel) {
|
|
1517
|
+
candidate = firstChannel.lastMessage?.createdAt ?? firstChannel.createdAt;
|
|
1518
|
+
} else {
|
|
1519
|
+
candidate = this._query.lastResponseAt;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
if (this._timestamp > candidate) {
|
|
1523
|
+
this._timestamp = candidate;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
/**
|
|
1528
|
+
* Synchronizes channel changelogs to keep the collection up-to-date.
|
|
1529
|
+
* @returns Promise that resolves to an empty array
|
|
1530
|
+
*/
|
|
1531
|
+
private async _syncChannelChangelogs(): Promise<GroupChannel[]> {
|
|
1532
|
+
if (this._isDisposed) return [];
|
|
1533
|
+
if (this._isSyncing) return [];
|
|
1534
|
+
|
|
1535
|
+
try {
|
|
1536
|
+
this._isSyncing = true;
|
|
1537
|
+
let response: GroupChannelChangelogs;
|
|
1538
|
+
|
|
1539
|
+
if (this._token) {
|
|
1540
|
+
response = await this._sdk.aiAgent.getMyGroupChannelChangeLogsByToken(this._token, this.filter);
|
|
1541
|
+
} else {
|
|
1542
|
+
response = await this._sdk.aiAgent.getMyGroupChannelChangeLogsByTimestamp(this._timestamp, this.filter);
|
|
1543
|
+
}
|
|
1544
|
+
this._token = response.token;
|
|
1545
|
+
this._addChannelsToView(response.updatedChannels);
|
|
1546
|
+
this._removeChannelsFromView(response.deletedChannelUrls);
|
|
1547
|
+
|
|
1548
|
+
while (response.hasMore && !!response.token) {
|
|
1549
|
+
response = await this._sdk.aiAgent.getMyGroupChannelChangeLogsByToken(this._token, this.filter);
|
|
1550
|
+
this._token = response.token;
|
|
1551
|
+
this._addChannelsToView(response.updatedChannels);
|
|
1552
|
+
this._removeChannelsFromView(response.deletedChannelUrls);
|
|
1553
|
+
}
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
// Silently handle changelog sync errors to prevent disrupting the collection
|
|
1556
|
+
// The collection will continue to work with existing data
|
|
1557
|
+
} finally {
|
|
1558
|
+
this._isSyncing = false;
|
|
1559
|
+
}
|
|
1560
|
+
return [];
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Upserts pinned channels maintaining the order specified in pinnedChannelUrls.
|
|
1565
|
+
* @param channels - Pinned channels to upsert
|
|
1566
|
+
* @returns Object containing added, updated channels and unmatched URLs
|
|
1567
|
+
*/
|
|
1568
|
+
private _upsertPinnedChannelsToArray(channels: GroupChannel[]): {
|
|
1569
|
+
addedChannels: GroupChannel[];
|
|
1570
|
+
updatedChannels: GroupChannel[];
|
|
1571
|
+
unmatchedChannelUrls: string[];
|
|
1572
|
+
} {
|
|
1573
|
+
const pinnedUrls = this.filter?.pinnedChannelUrls ?? [];
|
|
1574
|
+
const pinnedIndexMap = new Map(pinnedUrls.map((url, index) => [url, index]));
|
|
1575
|
+
|
|
1576
|
+
const addedChannels: GroupChannel[] = [];
|
|
1577
|
+
const updatedChannels: GroupChannel[] = [];
|
|
1578
|
+
const unmatchedChannelUrls: string[] = [];
|
|
1579
|
+
|
|
1580
|
+
for (const channel of channels) {
|
|
1581
|
+
if (!this._query.belongsTo(channel)) {
|
|
1582
|
+
unmatchedChannelUrls.push(channel.url);
|
|
1583
|
+
continue;
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
const targetIndex = pinnedIndexMap.get(channel.url);
|
|
1587
|
+
if (targetIndex === undefined) continue;
|
|
1588
|
+
|
|
1589
|
+
const existingPosition = indexOfChannel(this._pinnedChannels, channel);
|
|
1590
|
+
const isExisting = existingPosition >= 0;
|
|
1591
|
+
|
|
1592
|
+
if (isExisting) {
|
|
1593
|
+
this._pinnedChannels.splice(existingPosition, 1);
|
|
1594
|
+
updatedChannels.push(channel);
|
|
1595
|
+
} else {
|
|
1596
|
+
addedChannels.push(channel);
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
const insertPosition = this._pinnedChannels.findIndex((existingChannel) => {
|
|
1600
|
+
const existingIndex = pinnedIndexMap.get(existingChannel.url) ?? Infinity;
|
|
1601
|
+
return existingIndex > targetIndex;
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
const finalPosition = insertPosition === -1 ? this._pinnedChannels.length : insertPosition;
|
|
1605
|
+
this._pinnedChannels.splice(finalPosition, 0, channel);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
return { addedChannels, updatedChannels, unmatchedChannelUrls };
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
/**
|
|
1612
|
+
* Upserts regular (non-pinned) channels with time-based sorting.
|
|
1613
|
+
* @param channels - Regular channels to upsert
|
|
1614
|
+
* @param forceAppend - Whether to force append channels at the end regardless of hasMore status
|
|
1615
|
+
* @returns Object containing added, updated channels and unmatched URLs
|
|
1616
|
+
*/
|
|
1617
|
+
private _upsertRegularChannelsToArray(
|
|
1618
|
+
channels: GroupChannel[],
|
|
1619
|
+
forceAppend = false,
|
|
1620
|
+
): { addedChannels: GroupChannel[]; updatedChannels: GroupChannel[]; unmatchedChannelUrls: string[] } {
|
|
1621
|
+
const unmatchedChannelUrls: string[] = [];
|
|
1622
|
+
|
|
1623
|
+
const addedChannels: GroupChannel[] = [];
|
|
1624
|
+
const updatedChannels: GroupChannel[] = [];
|
|
1625
|
+
|
|
1626
|
+
for (const channel of channels) {
|
|
1627
|
+
if (!this._query.belongsTo(channel)) {
|
|
1628
|
+
unmatchedChannelUrls.push(channel.url);
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
const oldPosition = indexOfChannel(this._channels, channel);
|
|
1633
|
+
const isNewChannel = oldPosition < 0;
|
|
1634
|
+
const shouldRemoveBeforeInsert = !isNewChannel;
|
|
1635
|
+
|
|
1636
|
+
if (shouldRemoveBeforeInsert) {
|
|
1637
|
+
this._channels.splice(oldPosition, 1);
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
const insertionIndex = placeOfChannel(this._channels, channel, this._order).place;
|
|
1641
|
+
const isAtEnd = insertionIndex === this._channels.length;
|
|
1642
|
+
|
|
1643
|
+
if (isNewChannel) {
|
|
1644
|
+
if (isAtEnd) {
|
|
1645
|
+
if (forceAppend || !this.hasMore) {
|
|
1646
|
+
this._channels.push(channel);
|
|
1647
|
+
addedChannels.push(channel);
|
|
1648
|
+
}
|
|
1649
|
+
} else {
|
|
1650
|
+
this._channels.splice(insertionIndex, 0, channel);
|
|
1651
|
+
addedChannels.push(channel);
|
|
1652
|
+
}
|
|
1653
|
+
} else {
|
|
1654
|
+
this._channels.splice(insertionIndex, 0, channel);
|
|
1655
|
+
updatedChannels.push(channel);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
return { addedChannels, updatedChannels, unmatchedChannelUrls };
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
/**
|
|
1663
|
+
* Adds or updates channels in the collection, separating pinned and non-pinned channels.
|
|
1664
|
+
* @param channels - Channels to add or update
|
|
1665
|
+
* @param forceAppend - Whether to force append channels at the end
|
|
1666
|
+
*/
|
|
1667
|
+
private _addChannelsToView(channels: GroupChannel[], forceAppend = false): void {
|
|
1668
|
+
const pinnedUrlsSet = new Set(this.filter?.pinnedChannelUrls ?? []);
|
|
1669
|
+
|
|
1670
|
+
const pinnedChannels: GroupChannel[] = [];
|
|
1671
|
+
const regularChannels: GroupChannel[] = [];
|
|
1672
|
+
|
|
1673
|
+
for (const channel of channels) {
|
|
1674
|
+
if (pinnedUrlsSet.has(channel.url)) {
|
|
1675
|
+
pinnedChannels.push(channel);
|
|
1676
|
+
} else {
|
|
1677
|
+
regularChannels.push(channel);
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
const pinnedResult = this._upsertPinnedChannelsToArray(pinnedChannels);
|
|
1682
|
+
const regularResult = this._upsertRegularChannelsToArray(regularChannels, forceAppend);
|
|
1683
|
+
|
|
1684
|
+
const addedChannels = pinnedResult.addedChannels.concat(regularResult.addedChannels);
|
|
1685
|
+
const updatedChannels = pinnedResult.updatedChannels.concat(regularResult.updatedChannels);
|
|
1686
|
+
const unmatchedChannelUrls = pinnedResult.unmatchedChannelUrls.concat(regularResult.unmatchedChannelUrls);
|
|
1687
|
+
|
|
1688
|
+
if (addedChannels.length > 0) this._collectionEventHandler?.onChannelsAdded?.({}, addedChannels);
|
|
1689
|
+
if (updatedChannels.length > 0) this._collectionEventHandler?.onChannelsUpdated?.({}, updatedChannels);
|
|
1690
|
+
if (unmatchedChannelUrls.length > 0) this._removeChannelsFromView(unmatchedChannelUrls);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
/**
|
|
1694
|
+
* Removes channels from the collection by their URLs.
|
|
1695
|
+
* @param channelUrls - Array of channel URLs to remove
|
|
1696
|
+
*/
|
|
1697
|
+
private _removeChannelsFromView(channelUrls: string[]) {
|
|
1698
|
+
const pinnedUrlsSet = new Set(this.filter?.pinnedChannelUrls ?? []);
|
|
1699
|
+
const removedChannelUrls: string[] = [];
|
|
1700
|
+
|
|
1701
|
+
for (const channelUrl of channelUrls) {
|
|
1702
|
+
if (pinnedUrlsSet.has(channelUrl)) {
|
|
1703
|
+
const index = this._pinnedChannels.findIndex((channel) => channel.url === channelUrl);
|
|
1704
|
+
if (index >= 0) {
|
|
1705
|
+
removedChannelUrls.push(channelUrl);
|
|
1706
|
+
this._pinnedChannels.splice(index, 1);
|
|
1707
|
+
}
|
|
1708
|
+
} else {
|
|
1709
|
+
const index = this._channels.findIndex((channel) => channel.url === channelUrl);
|
|
1710
|
+
if (index >= 0) {
|
|
1711
|
+
removedChannelUrls.push(channelUrl);
|
|
1712
|
+
this._channels.splice(index, 1);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
if (removedChannelUrls.length > 0) this._collectionEventHandler?.onChannelsDeleted?.({}, removedChannelUrls);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Gets all channels in the collection.
|
|
1722
|
+
* Pinned channels are always returned first, followed by non-pinned channels.
|
|
1723
|
+
* @returns Array of GroupChannel objects
|
|
1724
|
+
*/
|
|
1725
|
+
public get channels(): GroupChannel[] {
|
|
1726
|
+
return this._isDisposed ? [] : [...this._pinnedChannels, ...this._channels];
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
/**
|
|
1730
|
+
* Indicates whether the collection has more channels to load.
|
|
1731
|
+
* @returns True if more channels can be loaded, false otherwise
|
|
1732
|
+
*/
|
|
1733
|
+
public get hasMore(): boolean {
|
|
1734
|
+
return this._isDisposed ? false : this._query.hasNext;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
/**
|
|
1738
|
+
* Loads the next batch of channels from the server.
|
|
1739
|
+
* @returns Promise that resolves to an array of newly loaded channels
|
|
1740
|
+
*/
|
|
1741
|
+
public async loadMore(): Promise<GroupChannel[]> {
|
|
1742
|
+
if (this._isDisposed) return [];
|
|
1743
|
+
|
|
1744
|
+
if (this.hasMore) {
|
|
1745
|
+
const channels = await this._query.next();
|
|
1746
|
+
|
|
1747
|
+
this._setDefaultChangelogsSyncTimestamp(channels);
|
|
1748
|
+
this._addChannelsToView(channels, true);
|
|
1749
|
+
return channels;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
return [];
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* Sets the event handler for collection updates.
|
|
1757
|
+
* @param handler - Event handler for channel collection changes
|
|
1758
|
+
*/
|
|
1759
|
+
public setConversationListCollectionHandler(handler: ConversationListCollectionEventHandler): void {
|
|
1760
|
+
this._collectionEventHandler = handler;
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
/**
|
|
1764
|
+
* Disposes the collection and cleans up all resources.
|
|
1765
|
+
* Stops all event handlers and clears all channels.
|
|
1766
|
+
*/
|
|
1767
|
+
public dispose(): void {
|
|
1768
|
+
if (this._isDisposed) return;
|
|
1769
|
+
|
|
1770
|
+
this._isDisposed = true;
|
|
1771
|
+
this._throttledOnChannelChanged.cancel();
|
|
1772
|
+
this._collectionEventHandler = undefined;
|
|
1773
|
+
this._sdk.removeConnectionHandler(this._handlerId);
|
|
1774
|
+
this._sdk.groupChannel.removeGroupChannelHandler(this._handlerId);
|
|
1775
|
+
this._pinnedChannels.length = 0;
|
|
1776
|
+
this._channels.length = 0;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
declare interface ConversationListCollectionEventHandler {
|
|
1781
|
+
/** Called when there are newly added {@link GroupChannel}s. */
|
|
1782
|
+
onChannelsAdded?: (context: ConversationListContext_2, channels: GroupChannel[]) => void;
|
|
1783
|
+
/** Called when there's an update in one or more of the {@link GroupChannel}s that `GroupChannelCollection` holds. */
|
|
1784
|
+
onChannelsUpdated?: (context: ConversationListContext_2, channels: GroupChannel[]) => void;
|
|
1785
|
+
/** Called when one or more of the {@link GroupChannel}s that `GroupChannelCollection` holds has been deleted. */
|
|
1786
|
+
onChannelsDeleted?: (context: ConversationListContext_2, channelUrls: string[]) => void;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1242
1789
|
/**
|
|
1243
1790
|
* Parameters for creating a ConversationListCollection instance.
|
|
1244
1791
|
*/
|
|
@@ -1251,6 +1798,8 @@ declare interface ConversationListCollectionParams {
|
|
|
1251
1798
|
|
|
1252
1799
|
export declare const ConversationListContext: Context<ConversationListContextValue | null>;
|
|
1253
1800
|
|
|
1801
|
+
declare interface ConversationListContext_2 {}
|
|
1802
|
+
|
|
1254
1803
|
declare interface ConversationListContextProps {
|
|
1255
1804
|
conversationListLimit?: number;
|
|
1256
1805
|
conversationListFilter?: Partial<AIAgentGroupChannelFilter>;
|
|
@@ -1481,6 +2030,68 @@ export declare type DateSeparatorProps = SBUFoundationProps<{
|
|
|
1481
2030
|
|
|
1482
2031
|
export declare const DefaultMessenger: ForwardRefExoticComponent<MessengerProps & RefAttributes<MessengerSessionRef>>;
|
|
1483
2032
|
|
|
2033
|
+
export declare interface DeskClientInterface {
|
|
2034
|
+
/** Gets a ticket by its ID. */
|
|
2035
|
+
getTicket(id: number): Promise<DeskTicketInterface>;
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
export declare interface DeskTicketAgent {
|
|
2039
|
+
/** The agent's user ID. */
|
|
2040
|
+
readonly userId: string;
|
|
2041
|
+
/** The agent's display name. */
|
|
2042
|
+
readonly name: string;
|
|
2043
|
+
/** The agent's profile image URL. */
|
|
2044
|
+
readonly profileUrl: string;
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
export declare interface DeskTicketInterface {
|
|
2048
|
+
/** The ticket ID. */
|
|
2049
|
+
readonly id: number;
|
|
2050
|
+
/** The ticket title. */
|
|
2051
|
+
readonly title: string | null;
|
|
2052
|
+
/** The ticket status. Corresponds to the Desk Ticket's `status2` value. */
|
|
2053
|
+
readonly status: DeskTicketStatus;
|
|
2054
|
+
/** The agent assigned to this ticket. */
|
|
2055
|
+
readonly agent: DeskTicketAgent | null;
|
|
2056
|
+
/** The ticket priority. */
|
|
2057
|
+
readonly priority: DeskTicketPriority;
|
|
2058
|
+
/** The ticket group. */
|
|
2059
|
+
readonly group: number;
|
|
2060
|
+
/** The first response time in seconds. Returns -1 if there is no response. */
|
|
2061
|
+
readonly firstResponseTime: number;
|
|
2062
|
+
/** The timestamp when the ticket was issued. */
|
|
2063
|
+
readonly issuedAt: string | null;
|
|
2064
|
+
/** Custom fields set on this ticket. */
|
|
2065
|
+
readonly customFields: Record<string, string>;
|
|
2066
|
+
/** Refreshes all the data of this ticket from the server. */
|
|
2067
|
+
refresh(): Promise<DeskTicketInterface>;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
export declare enum DeskTicketPriority {
|
|
2071
|
+
URGENT = 'URGENT',
|
|
2072
|
+
HIGH = 'HIGH',
|
|
2073
|
+
/** This is the default. */
|
|
2074
|
+
MEDIUM = 'MEDIUM',
|
|
2075
|
+
LOW = 'LOW',
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
export declare enum DeskTicketStatus {
|
|
2079
|
+
/** Ticket has been created, but the customer has not started chatting yet. */
|
|
2080
|
+
INITIALIZED = 'INITIALIZED',
|
|
2081
|
+
/** Ticket created via proactive chat. */
|
|
2082
|
+
PROACTIVE = 'PROACTIVE',
|
|
2083
|
+
/** No agent has been assigned yet. */
|
|
2084
|
+
PENDING = 'PENDING',
|
|
2085
|
+
/** An agent has been assigned and the ticket is being handled. */
|
|
2086
|
+
ACTIVE = 'ACTIVE',
|
|
2087
|
+
/** The ticket has been closed. */
|
|
2088
|
+
CLOSED = 'CLOSED',
|
|
2089
|
+
/** The ticket is in progress. */
|
|
2090
|
+
WORK_IN_PROGRESS = 'WORK_IN_PROGRESS',
|
|
2091
|
+
/** The assignment is in an idle state. */
|
|
2092
|
+
IDLE = 'IDLE',
|
|
2093
|
+
}
|
|
2094
|
+
|
|
1484
2095
|
declare interface Dispatcher {
|
|
1485
2096
|
send(command: BaseCommand): Promise<void>;
|
|
1486
2097
|
subscribe<E extends CommandType>(eventType: E, callback: (payload: CommandPayloads[E]) => void | Promise<void>): void;
|
|
@@ -3106,6 +3717,8 @@ declare interface MessengerSettingsResponse {
|
|
|
3106
3717
|
supported_file_mime_types: string[];
|
|
3107
3718
|
max_attachment_count?: number;
|
|
3108
3719
|
};
|
|
3720
|
+
language: string | null;
|
|
3721
|
+
country: string | null;
|
|
3109
3722
|
}
|
|
3110
3723
|
|
|
3111
3724
|
declare interface MessengerSettingsUpdatedParams {
|
|
@@ -3669,6 +4282,11 @@ declare type TextField = {
|
|
|
3669
4282
|
};
|
|
3670
4283
|
};
|
|
3671
4284
|
|
|
4285
|
+
declare interface ThrottledFunction<T extends (...args: any[]) => any> {
|
|
4286
|
+
(...args: Parameters<T>): void;
|
|
4287
|
+
cancel: () => void;
|
|
4288
|
+
}
|
|
4289
|
+
|
|
3672
4290
|
declare interface TimerData {
|
|
3673
4291
|
startTime: number | null;
|
|
3674
4292
|
endTime: number | null;
|
|
@@ -3739,10 +4357,13 @@ export declare type UserActionStatus = 'action_requested' | 'action_started' | '
|
|
|
3739
4357
|
|
|
3740
4358
|
export declare const useRefreshActiveChannel: (updater: () => Promise<void>) => () => Promise<void>;
|
|
3741
4359
|
|
|
3742
|
-
|
|
4360
|
+
/**
|
|
4361
|
+
* User session containing authentication credentials.
|
|
4362
|
+
*/
|
|
4363
|
+
declare interface UserSession {
|
|
3743
4364
|
userId: string;
|
|
3744
4365
|
authToken: string;
|
|
3745
|
-
}
|
|
4366
|
+
}
|
|
3746
4367
|
|
|
3747
4368
|
/**
|
|
3748
4369
|
* @deprecated Please use `ManualSessionInfo` or `AnonymousSessionInfo` instead.
|