@sendbird/ai-agent-messenger-react-native 1.6.0 → 1.7.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 +481 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +266 -5
- package/dist/index.js +2692 -2537
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -51,16 +51,15 @@ declare interface ActionbookInfo {
|
|
|
51
51
|
*/
|
|
52
52
|
declare interface ActiveChannel {
|
|
53
53
|
url: string;
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated Use `conversationStatus` instead. This field always returns 'open' or 'closed' for backward compatibility.
|
|
56
|
+
* */
|
|
57
|
+
status: 'open' | 'closed';
|
|
54
58
|
/**
|
|
55
59
|
* @description Conversation status of the active channel.
|
|
56
60
|
* If the conversation is not started, this will be undefined.
|
|
57
61
|
* */
|
|
58
62
|
conversationStatus?: ConversationStatus;
|
|
59
|
-
/**
|
|
60
|
-
* @description Status of the active channel. This will be 'closed' if the conversation is closed. otherwise, 'open'.
|
|
61
|
-
* @deprecated Please use `conversationStatus` field instead.
|
|
62
|
-
* */
|
|
63
|
-
status: 'open' | 'closed';
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
declare interface ActiveChannelUpdatedParams {
|
|
@@ -98,6 +97,94 @@ declare interface AgentMessageTemplateInfo {
|
|
|
98
97
|
};
|
|
99
98
|
}
|
|
100
99
|
|
|
100
|
+
declare abstract class AIAgentBaseStats {
|
|
101
|
+
protected timers: Map<string, TimerData> = new Map();
|
|
102
|
+
protected committed: boolean = false;
|
|
103
|
+
protected commitCallback: StatsAppendCallback | null = null;
|
|
104
|
+
protected conversationId: number | null = null;
|
|
105
|
+
protected channelUrl: string | null = null;
|
|
106
|
+
protected errorCode: number | null = null;
|
|
107
|
+
protected errorDescription: string | null = null;
|
|
108
|
+
protected extraData: Record<string, unknown> = {};
|
|
109
|
+
|
|
110
|
+
setCommitCallback(callback: StatsAppendCallback): this {
|
|
111
|
+
this.commitCallback = callback;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
setConversationId(id: number): this {
|
|
116
|
+
this.conversationId = id;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
setChannelUrl(url: string): this {
|
|
121
|
+
this.setExtra('channel_url', url);
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setError(code: number | undefined, description: string): this {
|
|
126
|
+
this.errorCode = code ?? DEFAULT_ERROR_CODE;
|
|
127
|
+
this.errorDescription = description;
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
setExtra(key: string, value: unknown): this {
|
|
132
|
+
if (value !== null && value !== undefined) {
|
|
133
|
+
this.extraData[key] = value;
|
|
134
|
+
}
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
startTimer(key: string): this {
|
|
139
|
+
if (this.committed) return this;
|
|
140
|
+
|
|
141
|
+
const existing = this.timers.get(key);
|
|
142
|
+
if (existing?.startTime !== null && existing?.startTime !== undefined) return this;
|
|
143
|
+
|
|
144
|
+
this.timers.set(key, { startTime: Date.now(), endTime: null });
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
stopTimer(key: string): this {
|
|
149
|
+
if (this.committed) return this;
|
|
150
|
+
|
|
151
|
+
const existing = this.timers.get(key);
|
|
152
|
+
if (!existing || existing.startTime === null || existing.endTime !== null) return this;
|
|
153
|
+
|
|
154
|
+
this.timers.set(key, { ...existing, endTime: Date.now() });
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
protected getDuration(key: string): number | null {
|
|
159
|
+
const timer = this.timers.get(key);
|
|
160
|
+
if (!timer || timer.startTime === null || timer.endTime === null) return null;
|
|
161
|
+
return timer.endTime - timer.startTime;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
isCommitted(): boolean {
|
|
165
|
+
return this.committed;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected abstract buildPayload(): AIAgentStatPayload | null;
|
|
169
|
+
protected abstract getMetricKey(): string;
|
|
170
|
+
|
|
171
|
+
commit(): boolean {
|
|
172
|
+
if (this.committed || !this.commitCallback) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const payload = this.buildPayload();
|
|
177
|
+
|
|
178
|
+
if (!payload) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
this.committed = true;
|
|
183
|
+
const result = this.commitCallback(AI_AGENT_STAT_TYPE, payload);
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
101
188
|
declare interface AIAgentCache {
|
|
102
189
|
template: MessageTemplateCache;
|
|
103
190
|
messenger: MessengerSessionCache;
|
|
@@ -152,6 +239,11 @@ declare interface AIAgentConfig {
|
|
|
152
239
|
* */
|
|
153
240
|
fileEnabled?: boolean;
|
|
154
241
|
};
|
|
242
|
+
/**
|
|
243
|
+
* (React only) Whether to play an alert sound when a message is received from the AI agent while the browser is not focused.
|
|
244
|
+
* @default false
|
|
245
|
+
* */
|
|
246
|
+
messageAlertSoundEnabled?: boolean;
|
|
155
247
|
/**
|
|
156
248
|
* (React only) File viewer configuration.
|
|
157
249
|
* */
|
|
@@ -284,6 +376,7 @@ declare interface AIAgentMessengerSessionContextValue {
|
|
|
284
376
|
userSession: null | UserSession;
|
|
285
377
|
aiAgentInfo: null | AIAgentInfo;
|
|
286
378
|
launcherInfo: null | LauncherInfo;
|
|
379
|
+
presentMethod: PresentMethod;
|
|
287
380
|
|
|
288
381
|
connectionError?: Error;
|
|
289
382
|
|
|
@@ -298,6 +391,12 @@ declare interface AIAgentMessengerSessionContextValue {
|
|
|
298
391
|
deauthenticate: () => Promise<void>;
|
|
299
392
|
|
|
300
393
|
createAttachmentRules: (params: { channel?: GroupChannel; uploadSizeLimit?: number }) => AttachmentRules;
|
|
394
|
+
/**
|
|
395
|
+
* @internal
|
|
396
|
+
*/
|
|
397
|
+
statsTrackers: {
|
|
398
|
+
initialRender: ConversationInitialRenderStatsTracker;
|
|
399
|
+
};
|
|
301
400
|
}
|
|
302
401
|
|
|
303
402
|
declare interface AIAgentMessengerSessionRef {
|
|
@@ -389,6 +488,10 @@ queryParams?: AIAgentQueryParams;
|
|
|
389
488
|
* @description AIAgent global default config.
|
|
390
489
|
* */
|
|
391
490
|
config?: AIAgentConfig;
|
|
491
|
+
/**
|
|
492
|
+
* @internal Used for conversation initial render stat tracking.
|
|
493
|
+
*/
|
|
494
|
+
presentMethod?: PresentMethod;
|
|
392
495
|
} & {
|
|
393
496
|
children?: ReactNode | undefined;
|
|
394
497
|
} & RefAttributes<AIAgentMessengerSessionRef>>;
|
|
@@ -404,6 +507,15 @@ declare interface AIAgentSessionHandler extends SessionHandler {
|
|
|
404
507
|
onExternalAuthTokenExpired?: (data: ExternalAuthTokenExpiredData) => void;
|
|
405
508
|
}
|
|
406
509
|
|
|
510
|
+
declare interface AIAgentStatPayload {
|
|
511
|
+
key: string;
|
|
512
|
+
value?: string;
|
|
513
|
+
conversation_id?: number;
|
|
514
|
+
error_code?: number;
|
|
515
|
+
error_description?: string;
|
|
516
|
+
extra?: Record<string, unknown>;
|
|
517
|
+
}
|
|
518
|
+
|
|
407
519
|
/**
|
|
408
520
|
* Common string set interface shared between react and react-native packages
|
|
409
521
|
* These are the base strings that both packages use
|
|
@@ -710,6 +822,146 @@ declare interface ConversationHeaderTemplateProps {
|
|
|
710
822
|
titleAlign?: 'start' | 'center' | 'end';
|
|
711
823
|
}
|
|
712
824
|
|
|
825
|
+
declare class ConversationInitialRenderStats extends AIAgentBaseStats {
|
|
826
|
+
private presentMethod: PresentMethod;
|
|
827
|
+
|
|
828
|
+
constructor(presentMethod: PresentMethod) {
|
|
829
|
+
super();
|
|
830
|
+
this.presentMethod = presentMethod;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
protected getMetricKey(): string {
|
|
834
|
+
return METRIC_KEY_CONVERSATION_INITIAL_RENDER;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
protected buildPayload(): AIAgentStatPayload | null {
|
|
838
|
+
const authDuration = this.getDuration(DurationKey.AUTH);
|
|
839
|
+
const getChannelDuration = this.getDuration(DurationKey.GET_CHANNEL);
|
|
840
|
+
const getMessagesDuration = this.getDuration(DurationKey.GET_MESSAGES);
|
|
841
|
+
const totalDurationFromCache = this.getDuration(DurationKey.TOTAL_DURATION_FROM_CACHE);
|
|
842
|
+
const totalDuration = this.getDuration(DurationKey.TOTAL_DURATION);
|
|
843
|
+
|
|
844
|
+
const extra: Record<string, unknown> = {
|
|
845
|
+
...this.extraData,
|
|
846
|
+
present_method: this.presentMethod,
|
|
847
|
+
...(authDuration !== null && { auth_duration: authDuration }),
|
|
848
|
+
...(getChannelDuration !== null && { get_channel_duration: getChannelDuration }),
|
|
849
|
+
...(getMessagesDuration !== null && { get_messages_duration: getMessagesDuration }),
|
|
850
|
+
...(totalDurationFromCache !== null && { total_duration_from_cache: totalDurationFromCache }),
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
const payload: AIAgentStatPayload = {
|
|
854
|
+
key: this.getMetricKey(),
|
|
855
|
+
// Use "0" when totalDuration is null (error case)
|
|
856
|
+
value: totalDuration !== null ? String(totalDuration) : '0',
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
if (this.conversationId !== null) payload.conversation_id = this.conversationId;
|
|
860
|
+
if (this.errorCode !== null) payload.error_code = this.errorCode;
|
|
861
|
+
if (this.errorDescription !== null) payload.error_description = this.errorDescription;
|
|
862
|
+
if (Object.keys(extra).length > 0) payload.extra = extra;
|
|
863
|
+
|
|
864
|
+
return payload;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* Manages ConversationInitialRenderStats lifecycle and encapsulates tracking logic.
|
|
870
|
+
*/
|
|
871
|
+
declare class ConversationInitialRenderStatsTracker {
|
|
872
|
+
private readonly commitCallback: StatsAppendCallback;
|
|
873
|
+
private readonly presentMethod: PresentMethod;
|
|
874
|
+
private stats: ConversationInitialRenderStats | null = null;
|
|
875
|
+
|
|
876
|
+
constructor(commitCallback: StatsAppendCallback, presentMethod: PresentMethod) {
|
|
877
|
+
this.commitCallback = commitCallback;
|
|
878
|
+
this.presentMethod = presentMethod;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
private getOrCreateStats(): ConversationInitialRenderStats {
|
|
882
|
+
if (!this.stats || this.stats.isCommitted()) {
|
|
883
|
+
this.stats = new ConversationInitialRenderStats(this.presentMethod);
|
|
884
|
+
this.stats.setCommitCallback(this.commitCallback);
|
|
885
|
+
}
|
|
886
|
+
return this.stats;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
onAuthStart(): void {
|
|
890
|
+
this.getOrCreateStats()
|
|
891
|
+
.startTimer(DurationKey.TOTAL_DURATION)
|
|
892
|
+
.startTimer(DurationKey.TOTAL_DURATION_FROM_CACHE)
|
|
893
|
+
.startTimer(DurationKey.AUTH);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
onAuthComplete(): void {
|
|
897
|
+
this.stats?.stopTimer(DurationKey.AUTH);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
onAuthError(error: Error): void {
|
|
901
|
+
if (this.stats && !this.stats.isCommitted()) {
|
|
902
|
+
this.stats
|
|
903
|
+
.stopTimer(DurationKey.AUTH)
|
|
904
|
+
.setError(error instanceof SendbirdError ? error.code : undefined, error.message)
|
|
905
|
+
.stopTimer(DurationKey.TOTAL_DURATION)
|
|
906
|
+
.commit();
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
onGetChannelStart(): void {
|
|
911
|
+
this.stats?.startTimer(DurationKey.GET_CHANNEL);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
onGetChannelComplete(conversationId?: number): void {
|
|
915
|
+
if (this.stats) {
|
|
916
|
+
this.stats.stopTimer(DurationKey.GET_CHANNEL);
|
|
917
|
+
if (conversationId !== undefined) {
|
|
918
|
+
this.stats.setConversationId(conversationId);
|
|
919
|
+
}
|
|
920
|
+
this.stats.startTimer(DurationKey.GET_MESSAGES);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
onGetChannelError(error: Error): void {
|
|
925
|
+
if (this.stats && !this.stats.isCommitted()) {
|
|
926
|
+
this.stats
|
|
927
|
+
.stopTimer(DurationKey.GET_CHANNEL)
|
|
928
|
+
.setError(error instanceof SendbirdError ? error.code : undefined, error.message)
|
|
929
|
+
.stopTimer(DurationKey.TOTAL_DURATION)
|
|
930
|
+
.commit();
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
onCacheResult(error: Error | null): void {
|
|
935
|
+
if (this.stats && !this.stats.isCommitted()) {
|
|
936
|
+
if (error) {
|
|
937
|
+
this.stats.setError(error instanceof SendbirdError ? error.code : undefined, error.message);
|
|
938
|
+
}
|
|
939
|
+
this.stats.stopTimer(DurationKey.TOTAL_DURATION_FROM_CACHE);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
onApiResult(error: Error | null): void {
|
|
944
|
+
if (this.stats && !this.stats.isCommitted()) {
|
|
945
|
+
if (error) {
|
|
946
|
+
this.stats.setError(error instanceof SendbirdError ? error.code : undefined, error.message);
|
|
947
|
+
}
|
|
948
|
+
this.stats.stopTimer(DurationKey.TOTAL_DURATION).stopTimer(DurationKey.GET_MESSAGES).commit();
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
setChannelUrl(url: string): void {
|
|
953
|
+
this.stats?.setChannelUrl(url);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
cleanup(): void {
|
|
957
|
+
this.stats?.commit();
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
clear(): void {
|
|
961
|
+
this.stats = null;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
713
965
|
export declare const ConversationLayout: {
|
|
714
966
|
(props: PropsWithChildren): ReactNode;
|
|
715
967
|
defaults: {
|
|
@@ -2464,6 +2716,8 @@ declare type PositionHorizontal = 'start' | 'end';
|
|
|
2464
2716
|
|
|
2465
2717
|
declare type PositionVertical = 'top' | 'bottom';
|
|
2466
2718
|
|
|
2719
|
+
declare type PresentMethod = 'launcher_toggle' | 'direct_present';
|
|
2720
|
+
|
|
2467
2721
|
declare type RNPermissionsModule = typeof RNPermissions;
|
|
2468
2722
|
|
|
2469
2723
|
export declare type ScrollToBottomButtonProps = {
|
|
@@ -2487,6 +2741,8 @@ declare type SingleSelectField = {
|
|
|
2487
2741
|
layout: 'default';
|
|
2488
2742
|
};
|
|
2489
2743
|
|
|
2744
|
+
declare type StatsAppendCallback = (type: string, data: AIAgentStatPayload) => boolean;
|
|
2745
|
+
|
|
2490
2746
|
/**
|
|
2491
2747
|
* Strings type for React Native components
|
|
2492
2748
|
* Uses nested structure with lowercase keys
|
|
@@ -2575,6 +2831,11 @@ declare type TextField = {
|
|
|
2575
2831
|
};
|
|
2576
2832
|
};
|
|
2577
2833
|
|
|
2834
|
+
declare interface TimerData {
|
|
2835
|
+
startTime: number | null;
|
|
2836
|
+
endTime: number | null;
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2578
2839
|
declare interface TypographyShape {
|
|
2579
2840
|
h1: TypographyVariant;
|
|
2580
2841
|
h2: TypographyVariant;
|