agora-appbuilder-core 4.1.0-beta-10 → 4.1.0-beta-12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agora-appbuilder-core",
3
- "version": "4.1.0-beta-10",
3
+ "version": "4.1.0-beta-12",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -894,13 +894,13 @@ export default class RtcEngine {
894
894
 
895
895
  /* Recieve Captions */
896
896
  this.client.on('stream-message', (uid: UID, payload: UInt8Array) => {
897
- logger.debug(
898
- LogSource.AgoraSDK,
899
- 'Event',
900
- 'RTC [stream-message](stt-web: onStreamMessageCallback)',
901
- uid,
902
- payload,
903
- );
897
+ // logger.debug(
898
+ // LogSource.AgoraSDK,
899
+ // 'Event',
900
+ // 'RTC [stream-message](stt-web: onStreamMessageCallback)',
901
+ // uid,
902
+ // payload,
903
+ // );
904
904
  (this.eventsMap.get('onStreamMessage') as callbackType)(uid, payload);
905
905
  });
906
906
 
@@ -76,8 +76,8 @@ const DefaultConfig = {
76
76
  CHAT_ORG_NAME: '',
77
77
  CHAT_APP_NAME: '',
78
78
  CHAT_URL: '',
79
- CLI_VERSION: '3.1.0-beta-10',
80
- CORE_VERSION: '4.1.0-beta-10',
79
+ CLI_VERSION: '3.1.0-beta-12',
80
+ CORE_VERSION: '4.1.0-beta-12',
81
81
  DISABLE_LANDSCAPE_MODE: false,
82
82
  STT_AUTO_START: false,
83
83
  CLOUD_RECORDING_AUTO_START: false,
@@ -9,6 +9,7 @@ import {
9
9
  useRoomInfo,
10
10
  Toast,
11
11
  useRtc,
12
+ isWebInternal,
12
13
  } from 'customization-api';
13
14
  import LocalEventEmitter, {
14
15
  LocalEventsEnum,
@@ -81,34 +82,6 @@ export const AgentContext = createContext<AgentContextInterface>({
81
82
  clearChatHistory: () => {},
82
83
  });
83
84
 
84
- /**
85
- * Helper function to find the correct insertion index for a new item using binary search.
86
- * Ensures that the array remains sorted by the `time` property after insertion.
87
- *
88
- * @param array The array to search within.
89
- * @param time The `time` value of the new item to insert.
90
- * @returns The index where the new item should be inserted.
91
- */
92
- const findInsertionIndex = (array: ChatItem[], time: number): number => {
93
- let low = 0;
94
- let high = array.length;
95
-
96
- // Perform binary search to find the insertion index
97
- while (low < high) {
98
- const mid = Math.floor((low + high) / 2);
99
-
100
- // If the middle item's time is less than the new time, search the upper half
101
- if (array[mid].time < time) {
102
- low = mid + 1;
103
- } else {
104
- // Otherwise, search the lower half
105
- high = mid;
106
- }
107
- }
108
-
109
- return low; // The correct index for insertion
110
- };
111
-
112
85
  export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
113
86
  children,
114
87
  }) => {
@@ -152,7 +125,11 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
152
125
  React.useEffect(() => {
153
126
  if (!isSubscribedForStreams) {
154
127
  RtcEngineUnsafe.addListener('onStreamMessage', (...args: any[]) => {
155
- messageService?.handleStreamMessage(args[1]);
128
+ if (isWebInternal()) {
129
+ messageService?.handleStreamMessage(args[1]);
130
+ } else {
131
+ messageService?.handleStreamMessage(args[3]);
132
+ }
156
133
  });
157
134
  setIsSubscribedForStreams(true);
158
135
  }
@@ -161,7 +138,7 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
161
138
  React.useEffect(() => {
162
139
  const getChatHistoryFromEvent = (event: MessageEvent) => {
163
140
  const {data} = event;
164
- console.log('get chat history from event', data);
141
+ // console.log('get chat history from event', data);
165
142
  if (data.type === 'message') {
166
143
  setChatHistory(prevChatHistory => [...(data?.chatHistory || [])]);
167
144
  }
@@ -179,13 +156,6 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
179
156
  }, []);
180
157
 
181
158
  useEffect(() => {
182
- console.log(
183
- 'debugging users agent contrl',
184
- agentConnectionState,
185
- {users},
186
- agentUID,
187
- );
188
-
189
159
  // welcome agent
190
160
  const aiAgentUID = users.filter(item => item === agentUID);
191
161
 
@@ -259,19 +229,20 @@ export const AgentProvider: React.FC<{children: React.ReactNode}> = ({
259
229
  try {
260
230
  setAgentConnectionState(AgentState.REQUEST_SENT);
261
231
  setStartAPICalled(true);
232
+ const params = {
233
+ agent_id: agentId,
234
+ prompt: prompt,
235
+ voice: agents?.find(a => a.id === agentId)?.config?.tts?.params
236
+ ?.voice_name,
237
+ enable_interruption_handling: isInterruptionHandlingEnabled,
238
+ language: language,
239
+ };
262
240
  const data = await connectToAIAgent(
263
241
  'start',
264
242
  channel_name,
265
243
  localUid,
266
244
  store.token,
267
- {
268
- agent_id: agentId || agents?.length ? agents[0].id : null,
269
- prompt: prompt,
270
- voice: agents.find(a => a.id === agentId)?.config?.tts?.params
271
- ?.voice_name,
272
- enable_interruption_handling: isInterruptionHandlingEnabled,
273
- language: language,
274
- },
245
+ params,
275
246
  );
276
247
  // console.log("response X-Client-ID", newClientId, typeof newClientId)
277
248
  // @ts-ignore
@@ -18,12 +18,6 @@ export const AgentControl: React.FC = () => {
18
18
  const isAwaitingLeave = agentConnectionState === AgentState.AWAITING_LEAVE;
19
19
  const isAgentAvailable = useIsAgentAvailable();
20
20
 
21
- console.log(
22
- 'Agent Control--',
23
- {agentConnectionState},
24
- {bth: AI_AGENT_STATE[agentConnectionState]},
25
- );
26
-
27
21
  const isLoading =
28
22
  agentConnectionState === AgentState.REQUEST_SENT ||
29
23
  agentConnectionState === AgentState.AGENT_DISCONNECT_REQUEST ||
@@ -3,6 +3,7 @@ import {LogSource, logger} from '../../../logger/AppBuilderLogger';
3
3
  import LocalEventEmitter, {
4
4
  LocalEventsEnum,
5
5
  } from '../../../rtm-events-api/LocalEvents';
6
+ import {Buffer} from 'buffer';
6
7
 
7
8
  const DEFAULT_MESSAGE_CACHE_TIMEOUT = 1000 * 60 * 5; // 5 minutes
8
9
  const DEFAULT_INTERVAL = 200; // milliseconds
@@ -446,12 +447,12 @@ export class MessageEngine {
446
447
  }
447
448
 
448
449
  public handleMessageInterrupt(message: IMessageInterrupt) {
449
- logger.debug(
450
- LogSource.AgoraSDK,
451
- 'AI_AGENT',
452
- 'handleMessageInterrupt',
453
- message,
454
- );
450
+ // logger.debug(
451
+ // LogSource.AgoraSDK,
452
+ // 'AI_AGENT',
453
+ // 'handleMessageInterrupt',
454
+ // message,
455
+ // );
455
456
  const turn_id = message.turn_id;
456
457
  const start_ms = message.start_ms;
457
458
  this._interruptQueue({
@@ -662,21 +663,24 @@ export class MessageEngine {
662
663
  .join('');
663
664
 
664
665
  // decode message
665
- logger.debug(
666
- LogSource.AgoraSDK,
667
- 'AI_AGENT',
668
- '[message]',
669
- Base64.atob(message),
666
+ // logger.debug(
667
+ // LogSource.AgoraSDK,
668
+ // 'AI_AGENT',
669
+ // '[message]',
670
+ // atob(message),
671
+ // );
672
+
673
+ // const decodedMessage = JSON.parse(atob(message));
674
+ const decodedMessage = JSON.parse(
675
+ Buffer.from(message, 'base64').toString('utf-8'),
670
676
  );
671
677
 
672
- const decodedMessage = JSON.parse(Base64.atob(message));
673
-
674
- logger.debug(
675
- LogSource.AgoraSDK,
676
- 'AI_AGENT',
677
- '[decodedMessage]',
678
- decodedMessage,
679
- );
678
+ // logger.debug(
679
+ // LogSource.AgoraSDK,
680
+ // 'AI_AGENT',
681
+ // '[decodedMessage]',
682
+ // decodedMessage,
683
+ // );
680
684
 
681
685
  // callback
682
686
  callback?.(decodedMessage);
@@ -830,12 +834,12 @@ export class MessageEngine {
830
834
  item => item.turn_id === turn_id,
831
835
  );
832
836
  if (!correspondingQueueItem) {
833
- logger.debug(
834
- LogSource.AgoraSDK,
835
- 'AI_AGENT',
836
- 'No corresponding queue item found',
837
- options,
838
- );
837
+ // logger.debug(
838
+ // LogSource.AgoraSDK,
839
+ // 'AI_AGENT',
840
+ // 'No corresponding queue item found',
841
+ // options,
842
+ // );
839
843
  return;
840
844
  }
841
845
  // if correspondingQueueItem exists, update its status to interrupted
@@ -962,15 +966,15 @@ export class MessageEngine {
962
966
 
963
967
  private _mutateChatHistory() {
964
968
  // logger.debug(LogSource.AgoraSDK,'AI_AGENT', 'Mutate messageList', this.messageList)
965
- logger.debug(
966
- LogSource.AgoraSDK,
967
- 'AI_AGENT',
968
- 'Mutate messageList',
969
- this._pts,
970
- this.messageList
971
- .map(item => `${item.text}[status: ${item.status}]`)
972
- .join('\n'),
973
- );
969
+ // logger.debug(
970
+ // LogSource.AgoraSDK,
971
+ // 'AI_AGENT',
972
+ // 'Mutate messageList',
973
+ // this._pts,
974
+ // this.messageList
975
+ // .map(item => `${item.text}[status: ${item.status}]`)
976
+ // .join('\n'),
977
+ // );
974
978
  this.onMessageListUpdate?.(this.messageList as IMessageListItem[]);
975
979
  }
976
980
  }
@@ -70,7 +70,7 @@ const InfoSection = () => {
70
70
  <View style={[styles.flex1, styles.alignEnd]}>
71
71
  <Text style={[styles.infoRowValue]}>
72
72
  {formatVoiceName(
73
- agents.find(a => a.id === agentId)?.config?.tts?.params
73
+ agents?.find(a => a.id === agentId)?.config?.tts?.params
74
74
  ?.voice_name,
75
75
  )}
76
76
  </Text>
@@ -123,7 +123,7 @@ const AdvancedSettings = () => {
123
123
 
124
124
  //when user switchs agent then update the toggle value for that agent
125
125
  useEffect(() => {
126
- if (agentId) {
126
+ if (agentId && agents?.length) {
127
127
  setIsInterruptionHandlingEnabled(
128
128
  agents?.find(a => a?.id === agentId)?.config?.enable_aivad,
129
129
  );
@@ -49,7 +49,7 @@ const SelectAiAgent = () => {
49
49
  ? 'No AI Agent available'
50
50
  : !agentId
51
51
  ? 'Select AI Agent'
52
- : data.find(d => d.value === agentId)?.label
52
+ : data?.find(d => d.value === agentId)?.label
53
53
  }
54
54
  data={data}
55
55
  onSelect={async ({label, value}) => {
@@ -20,11 +20,11 @@ const SelectAiAgentVoice = () => {
20
20
  });
21
21
 
22
22
  useEffect(() => {
23
- if (agentId && !agentVoice) {
23
+ if (agentId && !agentVoice && agents?.length) {
24
24
  //@ts-ignore
25
- setAgentVoice(agents.find((agent: any) => agent.id === agentId)?.voice);
25
+ setAgentVoice(agents?.find((agent: any) => agent.id === agentId)?.voice);
26
26
  }
27
- }, [agentId]);
27
+ }, [agentId, agents]);
28
28
 
29
29
  return (
30
30
  <View>
@@ -21,10 +21,11 @@ const SelectUserLanguage = () => {
21
21
  });
22
22
 
23
23
  useEffect(() => {
24
- if (agentId) {
24
+ if (agentId && agents?.length) {
25
25
  //@ts-ignore
26
26
  setLanguage(
27
- agents.find((agent: any) => agent.id === agentId)?.config?.asr_language,
27
+ agents?.find((agent: any) => agent.id === agentId)?.config
28
+ ?.asr_language,
28
29
  );
29
30
  }
30
31
  }, [agentId, setLanguage, agents]);
@@ -39,7 +39,7 @@ const UserPrompt = () => {
39
39
  }, [prompt]);
40
40
 
41
41
  useEffect(() => {
42
- if (agentId) {
42
+ if (agentId && agents?.length) {
43
43
  setPrompt(agents?.find(a => a?.id === agentId)?.config?.llm?.prompt);
44
44
  }
45
45
  }, [agentId, agents, setPrompt]);
@@ -27,7 +27,6 @@ const MobileLayoutComponent: LayoutComponent = () => {
27
27
  const {getLocalAudioStream, getRemoteAudioStream} = useLocalAudio();
28
28
  const isAudioEnabled = useIsAudioEnabled();
29
29
  const connected = activeUids.includes(agentUID);
30
- console.log({activeUids}, 'active uids');
31
30
 
32
31
  useEffect(() => {
33
32
  if (getLocalAudioStream()) {
@@ -62,17 +62,10 @@ const DesktopLayoutComponent: LayoutComponent = () => {
62
62
  const {getLocalAudioStream, getRemoteAudioStream} = useLocalAudio();
63
63
 
64
64
  const connected = activeUids.includes(agentUID);
65
- console.log({activeUids}, 'active uids');
66
65
 
67
66
  // this state occurs when agent_stop is successful, but
68
67
  // user is still not disconnected from the RTC channel - state-of-wait
69
68
  const isAwaitingLeave = agentConnectionState === AgentState.AWAITING_LEAVE;
70
- console.log(
71
- {isAwaitingLeave},
72
- {connected},
73
- 'what is going on',
74
- agentConnectionState,
75
- );
76
69
  useEffect(() => {
77
70
  if (getLocalAudioStream()) {
78
71
  setLocalTrack(getLocalAudioStream());
@@ -132,8 +132,6 @@ export const ConversationalAI: LayoutComponent = () => {
132
132
  // save the app in a ref for later use
133
133
  // spline.current = splineApp;
134
134
  // sphere.current = splineApp.findObjectByName('Sphere');
135
- // console.log('debugging animation main', spline.current);
136
- // console.log('debugging animation sphere', sphere.current);
137
135
  }
138
136
 
139
137
  const isLoading =
@@ -26,17 +26,11 @@ export const DefaultAIOnly: LayoutComponent = () => {
26
26
  const {getLocalAudioStream, getRemoteAudioStream} = useLocalAudio();
27
27
 
28
28
  const connected = activeUids.includes(agentUID);
29
- console.log({activeUids}, 'active uids');
30
29
 
31
30
  // this state occurs when agent_stop is successful, but
32
31
  // user is still not disconnected from the RTC channel - state-of-wait
33
32
  const isAwaitingLeave = agentConnectionState === AgentState.AWAITING_LEAVE;
34
- console.log(
35
- {isAwaitingLeave},
36
- {connected},
37
- 'what is going on',
38
- agentConnectionState,
39
- );
33
+
40
34
  useEffect(() => {
41
35
  if (getLocalAudioStream()) {
42
36
  setLocalTrack(getLocalAudioStream());
@@ -30,6 +30,7 @@ export interface StoreInterface {
30
30
  >;
31
31
  activeDeviceId: Record<MediaDeviceInfo['kind'], string>;
32
32
  whiteboardNativeInfoToast?: boolean;
33
+ projectId: string;
33
34
  }
34
35
 
35
36
  export interface StorageContextInterface {
@@ -52,6 +53,7 @@ export const initStoreValue: StoreInterface = {
52
53
  audiooutput: '',
53
54
  videoinput: '',
54
55
  },
56
+ projectId: $config.PROJECT_ID,
55
57
  };
56
58
 
57
59
  const initStorageContextValue = {
@@ -97,6 +99,13 @@ export const StorageProvider = (props: {children: React.ReactNode}) => {
97
99
  if (!ENABLE_AUTH && !$config.ENABLE_CONVERSATIONAL_AI) {
98
100
  storeFromStorage['token'] = null;
99
101
  }
102
+ const projectId = $config.PROJECT_ID;
103
+ //if project id different then we should not use the previous session token.
104
+ //so setting into null and updating new project id
105
+ if (storeFromStorage['projectId'] !== projectId) {
106
+ storeFromStorage['token'] = null;
107
+ storeFromStorage['projectId'] = projectId;
108
+ }
100
109
  storeFromStorage['whiteboardNativeInfoToast'] = false;
101
110
  setStore(storeFromStorage);
102
111
  logger.log(
@@ -133,6 +142,13 @@ export const StorageProvider = (props: {children: React.ReactNode}) => {
133
142
  if (!ENABLE_AUTH && !$config.ENABLE_CONVERSATIONAL_AI) {
134
143
  tempStore['token'] = null;
135
144
  }
145
+ const projectId = $config.PROJECT_ID;
146
+ //if project id different then we should not use the previous session token.
147
+ //so setting into null and updating new project id
148
+ if (tempStore['projectId'] !== projectId) {
149
+ tempStore['token'] = null;
150
+ tempStore['projectId'] = projectId;
151
+ }
136
152
  await AsyncStorage.setItem('store', JSON.stringify(tempStore));
137
153
  logger.log(
138
154
  LogSource.Internals,