@vivix-ai/ivi-frontend-sdk 0.3.1 → 0.3.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.
package/dist/index.d.cts CHANGED
@@ -62,6 +62,31 @@ interface IviRuntimeLogEntry {
62
62
  data?: unknown;
63
63
  }
64
64
  type IviRuntimeLogCallback = (entry: IviRuntimeLogEntry) => void;
65
+ type IviRuntimeTrtcEventType = "remote_video_available" | "remote_video_unavailable" | "remote_audio_available" | "remote_audio_unavailable";
66
+ interface IviRuntimeTrtcEvent {
67
+ sourceId: string;
68
+ type: IviRuntimeTrtcEventType;
69
+ rawType: string;
70
+ payload: unknown;
71
+ userId?: string;
72
+ streamType?: unknown;
73
+ }
74
+ type IviRuntimeTrtcEventListener = (event: IviRuntimeTrtcEvent) => void;
75
+ type IviRuntimeTrtcAIDenoiserMode = "normal" | "far_field_reduction";
76
+ interface IviRuntimeTrtcAIDenoiserOptions {
77
+ /**
78
+ * 是否启用 TRTC AIDenoiser 插件,默认 true。
79
+ */
80
+ enabled?: boolean;
81
+ /**
82
+ * 降噪模式,默认 "normal"。
83
+ */
84
+ mode?: IviRuntimeTrtcAIDenoiserMode;
85
+ /**
86
+ * TRTC AIDenoiser 资源路径;未配置时使用 TRTC SDK 默认加载逻辑。
87
+ */
88
+ assetsPath?: string;
89
+ }
65
90
  type IviRuntimeConversationLifecycle = "added" | "done";
66
91
  type IviRuntimeConversationStatus = "in_progress" | "completed" | "incomplete";
67
92
  interface IviRuntimeConversationItem {
@@ -89,6 +114,14 @@ interface IviRuntimeCoordinatorConfig {
89
114
  * Runtime 内部链路日志回调;未传入时不输出日志。
90
115
  */
91
116
  onLog?: IviRuntimeLogCallback;
117
+ /**
118
+ * TRTC SDK 原始事件回调;可用于业务监听远端音视频可用性等底层事件。
119
+ */
120
+ onTrtcEvent?: IviRuntimeTrtcEventListener;
121
+ /**
122
+ * TRTC SDK AIDenoiser 降噪配置。默认开启;传 false 可关闭。
123
+ */
124
+ trtcAIDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions;
92
125
  }
93
126
  /**
94
127
  * 用户输入触发回复链路配置。
@@ -162,9 +195,11 @@ interface TrtcSourceSnapshot {
162
195
  type TrtcSourceListener = (snapshot: TrtcSourceSnapshot) => void;
163
196
  declare class TrtcSourceManager {
164
197
  private readonly onLog?;
198
+ private readonly onTrtcEvent?;
199
+ private readonly aiDenoiser?;
165
200
  private readonly sessions;
166
201
  private readonly listeners;
167
- constructor(onLog?: IviRuntimeLogCallback | undefined);
202
+ constructor(onLog?: IviRuntimeLogCallback | undefined, onTrtcEvent?: IviRuntimeTrtcEventListener | undefined, aiDenoiser?: (boolean | IviRuntimeTrtcAIDenoiserOptions) | undefined);
168
203
  /**
169
204
  * 将 runtime 当前 sources 与 TRTC 会话池对齐:
170
205
  * - 对 ready + trtc 的 source 进行 upsert(必要时建立连接)
@@ -175,7 +210,7 @@ declare class TrtcSourceManager {
175
210
  * 按 sourceId 注册/更新 TRTC 配置。
176
211
  * 若配置发生变化,会先销毁旧会话再按新参数重建连接。
177
212
  */
178
- upsertSource(sourceId: string, trtc: IviSourcePlaybackTrtc): void;
213
+ upsertSource(sourceId: string, trtc: IviSourcePlaybackTrtc, aiDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions): void;
179
214
  /**
180
215
  * 删除指定 source 的 TRTC 会话并释放连接资源。
181
216
  * 该操作通常由 source.deleted 或会话重置触发。
@@ -217,6 +252,7 @@ declare class TrtcSourceManager {
217
252
  * - 至少一个 view 需出声 -> 对可用远端用户解除静音
218
253
  */
219
254
  private applyAudioPolicy;
255
+ private applyAIDenoiserPolicy;
220
256
  /**
221
257
  * 销毁单个 source 会话:
222
258
  * 解绑事件、停止远端视频、退出房间并销毁客户端。
@@ -224,6 +260,7 @@ declare class TrtcSourceManager {
224
260
  private disposeSession;
225
261
  private emitSnapshot;
226
262
  private log;
263
+ private emitTrtcEvent;
227
264
  }
228
265
 
229
266
  /**
@@ -380,6 +417,7 @@ declare class IviRuntimeCoordinator {
380
417
  private readonly conversationHandler;
381
418
  private readonly stateListeners;
382
419
  private readonly eventListeners;
420
+ private readonly trtcEventListeners;
383
421
  private readonly pendingUserTextToResponseFlows;
384
422
  private userTextFlowCounter;
385
423
  private waitingTracksListValidation;
@@ -402,6 +440,7 @@ declare class IviRuntimeCoordinator {
402
440
  getState(): IviRuntimeState;
403
441
  onStateChange(listener: (state: IviRuntimeState) => void): () => void;
404
442
  onEvent(listener: IviRuntimeEventListener): () => void;
443
+ onTrtcEvent(listener: IviRuntimeTrtcEventListener): () => void;
405
444
  emitLog(entry: IviRuntimeLogEntry): void;
406
445
  /**
407
446
  * 编排一次"用户文本输入 -> 触发模型回复"链路。
@@ -440,6 +479,7 @@ declare class IviRuntimeCoordinator {
440
479
  private onConversationsChanged;
441
480
  private setState;
442
481
  private emitEvent;
482
+ private emitTrtcEvent;
443
483
  private resetStoppedState;
444
484
  private ensureSourcesSyncedForTracks;
445
485
  private validateSourcesListRefreshed;
@@ -527,6 +567,11 @@ interface IVITrtcPlayerProps {
527
567
  loadingFallback?: ReactNode;
528
568
  errorFallback?: ReactNode;
529
569
  muted?: boolean;
570
+ /**
571
+ * 独立使用 IVITrtcPlayer(未传 runtime)时的 TRTC AIDenoiser 降噪配置。
572
+ * 默认开启;传 false 可关闭。
573
+ */
574
+ trtcAIDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions;
530
575
  }
531
576
  /**
532
577
  * 默认 TRTC 播放器:挂载即加入房间并拉流,连接由 TrtcSourceManager 统一复用。
@@ -705,4 +750,4 @@ declare function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRunti
705
750
 
706
751
  declare function useIviStageView(): IviStageViewContextValue;
707
752
 
708
- export { EMPTY_RUNTIME_STATE, IVILivekitPlayer, type IVILivekitPlayerProps, IVIStageView, type IVIStageViewProps, IVISubtitleOverlay, type IVISubtitleOverlayProps, type IVISubtitleOverlayStyle, IVITrackSlot, type IVITrackSlotProps, IVITrtcPlayer, type IVITrtcPlayerProps, type IviFrontendClientConfig, IviFrontendSdk, type IviManagedRuntimeConfig, type IviManagedRuntimeLogCallback, type IviManagedRuntimeLogEntry, type IviManagedRuntimeLogLevel, type IviManagedRuntimeLogSource, type IviRuntimeConversationItem, type IviRuntimeConversationLifecycle, type IviRuntimeConversationStatus, IviRuntimeCoordinator, type IviRuntimeCoordinatorConfig, IviRuntimeDispatcher, type IviRuntimeDispatcherConfig, type IviRuntimeEventListener, type IviRuntimeLogCallback, type IviRuntimeLogEntry, type IviRuntimeLogLevel, type IviRuntimeSource, type IviRuntimeSourcePreloadState, type IviRuntimeState, type IviRuntimeStatus, type IviRuntimeStream, type IviRuntimeUserTextToResponseCallbacks, type IviRuntimeUserTextToResponseOptions, type IviRuntimeUserTextToResponseResult, type IviSourcePlaybackLivekit, type IviSourcePlaybackLivekitDescriptor, type IviStageSlotBinding, type IviStageViewContextValue, type IviSubtitleItem, type IviSubtitleRole, type IviUseSubtitlesOptions, LivekitSourceManager, TrtcSourceManager, isLivekitSourcePlayback, isReadyLivekitRuntimeSource, isSameLivekitConfig, useIviStageView, useIviSubtitles, useManagedIviRuntime, useRuntimeState };
753
+ export { EMPTY_RUNTIME_STATE, IVILivekitPlayer, type IVILivekitPlayerProps, IVIStageView, type IVIStageViewProps, IVISubtitleOverlay, type IVISubtitleOverlayProps, type IVISubtitleOverlayStyle, IVITrackSlot, type IVITrackSlotProps, IVITrtcPlayer, type IVITrtcPlayerProps, type IviFrontendClientConfig, IviFrontendSdk, type IviManagedRuntimeConfig, type IviManagedRuntimeLogCallback, type IviManagedRuntimeLogEntry, type IviManagedRuntimeLogLevel, type IviManagedRuntimeLogSource, type IviRuntimeConversationItem, type IviRuntimeConversationLifecycle, type IviRuntimeConversationStatus, IviRuntimeCoordinator, type IviRuntimeCoordinatorConfig, IviRuntimeDispatcher, type IviRuntimeDispatcherConfig, type IviRuntimeEventListener, type IviRuntimeLogCallback, type IviRuntimeLogEntry, type IviRuntimeLogLevel, type IviRuntimeSource, type IviRuntimeSourcePreloadState, type IviRuntimeState, type IviRuntimeStatus, type IviRuntimeStream, type IviRuntimeTrtcAIDenoiserMode, type IviRuntimeTrtcAIDenoiserOptions, type IviRuntimeTrtcEvent, type IviRuntimeTrtcEventListener, type IviRuntimeTrtcEventType, type IviRuntimeUserTextToResponseCallbacks, type IviRuntimeUserTextToResponseOptions, type IviRuntimeUserTextToResponseResult, type IviSourcePlaybackLivekit, type IviSourcePlaybackLivekitDescriptor, type IviStageSlotBinding, type IviStageViewContextValue, type IviSubtitleItem, type IviSubtitleRole, type IviUseSubtitlesOptions, LivekitSourceManager, TrtcSourceManager, isLivekitSourcePlayback, isReadyLivekitRuntimeSource, isSameLivekitConfig, useIviStageView, useIviSubtitles, useManagedIviRuntime, useRuntimeState };
package/dist/index.d.ts CHANGED
@@ -62,6 +62,31 @@ interface IviRuntimeLogEntry {
62
62
  data?: unknown;
63
63
  }
64
64
  type IviRuntimeLogCallback = (entry: IviRuntimeLogEntry) => void;
65
+ type IviRuntimeTrtcEventType = "remote_video_available" | "remote_video_unavailable" | "remote_audio_available" | "remote_audio_unavailable";
66
+ interface IviRuntimeTrtcEvent {
67
+ sourceId: string;
68
+ type: IviRuntimeTrtcEventType;
69
+ rawType: string;
70
+ payload: unknown;
71
+ userId?: string;
72
+ streamType?: unknown;
73
+ }
74
+ type IviRuntimeTrtcEventListener = (event: IviRuntimeTrtcEvent) => void;
75
+ type IviRuntimeTrtcAIDenoiserMode = "normal" | "far_field_reduction";
76
+ interface IviRuntimeTrtcAIDenoiserOptions {
77
+ /**
78
+ * 是否启用 TRTC AIDenoiser 插件,默认 true。
79
+ */
80
+ enabled?: boolean;
81
+ /**
82
+ * 降噪模式,默认 "normal"。
83
+ */
84
+ mode?: IviRuntimeTrtcAIDenoiserMode;
85
+ /**
86
+ * TRTC AIDenoiser 资源路径;未配置时使用 TRTC SDK 默认加载逻辑。
87
+ */
88
+ assetsPath?: string;
89
+ }
65
90
  type IviRuntimeConversationLifecycle = "added" | "done";
66
91
  type IviRuntimeConversationStatus = "in_progress" | "completed" | "incomplete";
67
92
  interface IviRuntimeConversationItem {
@@ -89,6 +114,14 @@ interface IviRuntimeCoordinatorConfig {
89
114
  * Runtime 内部链路日志回调;未传入时不输出日志。
90
115
  */
91
116
  onLog?: IviRuntimeLogCallback;
117
+ /**
118
+ * TRTC SDK 原始事件回调;可用于业务监听远端音视频可用性等底层事件。
119
+ */
120
+ onTrtcEvent?: IviRuntimeTrtcEventListener;
121
+ /**
122
+ * TRTC SDK AIDenoiser 降噪配置。默认开启;传 false 可关闭。
123
+ */
124
+ trtcAIDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions;
92
125
  }
93
126
  /**
94
127
  * 用户输入触发回复链路配置。
@@ -162,9 +195,11 @@ interface TrtcSourceSnapshot {
162
195
  type TrtcSourceListener = (snapshot: TrtcSourceSnapshot) => void;
163
196
  declare class TrtcSourceManager {
164
197
  private readonly onLog?;
198
+ private readonly onTrtcEvent?;
199
+ private readonly aiDenoiser?;
165
200
  private readonly sessions;
166
201
  private readonly listeners;
167
- constructor(onLog?: IviRuntimeLogCallback | undefined);
202
+ constructor(onLog?: IviRuntimeLogCallback | undefined, onTrtcEvent?: IviRuntimeTrtcEventListener | undefined, aiDenoiser?: (boolean | IviRuntimeTrtcAIDenoiserOptions) | undefined);
168
203
  /**
169
204
  * 将 runtime 当前 sources 与 TRTC 会话池对齐:
170
205
  * - 对 ready + trtc 的 source 进行 upsert(必要时建立连接)
@@ -175,7 +210,7 @@ declare class TrtcSourceManager {
175
210
  * 按 sourceId 注册/更新 TRTC 配置。
176
211
  * 若配置发生变化,会先销毁旧会话再按新参数重建连接。
177
212
  */
178
- upsertSource(sourceId: string, trtc: IviSourcePlaybackTrtc): void;
213
+ upsertSource(sourceId: string, trtc: IviSourcePlaybackTrtc, aiDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions): void;
179
214
  /**
180
215
  * 删除指定 source 的 TRTC 会话并释放连接资源。
181
216
  * 该操作通常由 source.deleted 或会话重置触发。
@@ -217,6 +252,7 @@ declare class TrtcSourceManager {
217
252
  * - 至少一个 view 需出声 -> 对可用远端用户解除静音
218
253
  */
219
254
  private applyAudioPolicy;
255
+ private applyAIDenoiserPolicy;
220
256
  /**
221
257
  * 销毁单个 source 会话:
222
258
  * 解绑事件、停止远端视频、退出房间并销毁客户端。
@@ -224,6 +260,7 @@ declare class TrtcSourceManager {
224
260
  private disposeSession;
225
261
  private emitSnapshot;
226
262
  private log;
263
+ private emitTrtcEvent;
227
264
  }
228
265
 
229
266
  /**
@@ -380,6 +417,7 @@ declare class IviRuntimeCoordinator {
380
417
  private readonly conversationHandler;
381
418
  private readonly stateListeners;
382
419
  private readonly eventListeners;
420
+ private readonly trtcEventListeners;
383
421
  private readonly pendingUserTextToResponseFlows;
384
422
  private userTextFlowCounter;
385
423
  private waitingTracksListValidation;
@@ -402,6 +440,7 @@ declare class IviRuntimeCoordinator {
402
440
  getState(): IviRuntimeState;
403
441
  onStateChange(listener: (state: IviRuntimeState) => void): () => void;
404
442
  onEvent(listener: IviRuntimeEventListener): () => void;
443
+ onTrtcEvent(listener: IviRuntimeTrtcEventListener): () => void;
405
444
  emitLog(entry: IviRuntimeLogEntry): void;
406
445
  /**
407
446
  * 编排一次"用户文本输入 -> 触发模型回复"链路。
@@ -440,6 +479,7 @@ declare class IviRuntimeCoordinator {
440
479
  private onConversationsChanged;
441
480
  private setState;
442
481
  private emitEvent;
482
+ private emitTrtcEvent;
443
483
  private resetStoppedState;
444
484
  private ensureSourcesSyncedForTracks;
445
485
  private validateSourcesListRefreshed;
@@ -527,6 +567,11 @@ interface IVITrtcPlayerProps {
527
567
  loadingFallback?: ReactNode;
528
568
  errorFallback?: ReactNode;
529
569
  muted?: boolean;
570
+ /**
571
+ * 独立使用 IVITrtcPlayer(未传 runtime)时的 TRTC AIDenoiser 降噪配置。
572
+ * 默认开启;传 false 可关闭。
573
+ */
574
+ trtcAIDenoiser?: boolean | IviRuntimeTrtcAIDenoiserOptions;
530
575
  }
531
576
  /**
532
577
  * 默认 TRTC 播放器:挂载即加入房间并拉流,连接由 TrtcSourceManager 统一复用。
@@ -705,4 +750,4 @@ declare function useManagedIviRuntime(config: IviManagedRuntimeConfig): IviRunti
705
750
 
706
751
  declare function useIviStageView(): IviStageViewContextValue;
707
752
 
708
- export { EMPTY_RUNTIME_STATE, IVILivekitPlayer, type IVILivekitPlayerProps, IVIStageView, type IVIStageViewProps, IVISubtitleOverlay, type IVISubtitleOverlayProps, type IVISubtitleOverlayStyle, IVITrackSlot, type IVITrackSlotProps, IVITrtcPlayer, type IVITrtcPlayerProps, type IviFrontendClientConfig, IviFrontendSdk, type IviManagedRuntimeConfig, type IviManagedRuntimeLogCallback, type IviManagedRuntimeLogEntry, type IviManagedRuntimeLogLevel, type IviManagedRuntimeLogSource, type IviRuntimeConversationItem, type IviRuntimeConversationLifecycle, type IviRuntimeConversationStatus, IviRuntimeCoordinator, type IviRuntimeCoordinatorConfig, IviRuntimeDispatcher, type IviRuntimeDispatcherConfig, type IviRuntimeEventListener, type IviRuntimeLogCallback, type IviRuntimeLogEntry, type IviRuntimeLogLevel, type IviRuntimeSource, type IviRuntimeSourcePreloadState, type IviRuntimeState, type IviRuntimeStatus, type IviRuntimeStream, type IviRuntimeUserTextToResponseCallbacks, type IviRuntimeUserTextToResponseOptions, type IviRuntimeUserTextToResponseResult, type IviSourcePlaybackLivekit, type IviSourcePlaybackLivekitDescriptor, type IviStageSlotBinding, type IviStageViewContextValue, type IviSubtitleItem, type IviSubtitleRole, type IviUseSubtitlesOptions, LivekitSourceManager, TrtcSourceManager, isLivekitSourcePlayback, isReadyLivekitRuntimeSource, isSameLivekitConfig, useIviStageView, useIviSubtitles, useManagedIviRuntime, useRuntimeState };
753
+ export { EMPTY_RUNTIME_STATE, IVILivekitPlayer, type IVILivekitPlayerProps, IVIStageView, type IVIStageViewProps, IVISubtitleOverlay, type IVISubtitleOverlayProps, type IVISubtitleOverlayStyle, IVITrackSlot, type IVITrackSlotProps, IVITrtcPlayer, type IVITrtcPlayerProps, type IviFrontendClientConfig, IviFrontendSdk, type IviManagedRuntimeConfig, type IviManagedRuntimeLogCallback, type IviManagedRuntimeLogEntry, type IviManagedRuntimeLogLevel, type IviManagedRuntimeLogSource, type IviRuntimeConversationItem, type IviRuntimeConversationLifecycle, type IviRuntimeConversationStatus, IviRuntimeCoordinator, type IviRuntimeCoordinatorConfig, IviRuntimeDispatcher, type IviRuntimeDispatcherConfig, type IviRuntimeEventListener, type IviRuntimeLogCallback, type IviRuntimeLogEntry, type IviRuntimeLogLevel, type IviRuntimeSource, type IviRuntimeSourcePreloadState, type IviRuntimeState, type IviRuntimeStatus, type IviRuntimeStream, type IviRuntimeTrtcAIDenoiserMode, type IviRuntimeTrtcAIDenoiserOptions, type IviRuntimeTrtcEvent, type IviRuntimeTrtcEventListener, type IviRuntimeTrtcEventType, type IviRuntimeUserTextToResponseCallbacks, type IviRuntimeUserTextToResponseOptions, type IviRuntimeUserTextToResponseResult, type IviSourcePlaybackLivekit, type IviSourcePlaybackLivekitDescriptor, type IviStageSlotBinding, type IviStageViewContextValue, type IviSubtitleItem, type IviSubtitleRole, type IviUseSubtitlesOptions, LivekitSourceManager, TrtcSourceManager, isLivekitSourcePlayback, isReadyLivekitRuntimeSource, isSameLivekitConfig, useIviStageView, useIviSubtitles, useManagedIviRuntime, useRuntimeState };
package/dist/index.js CHANGED
@@ -1105,9 +1105,15 @@ var ConversationManager = class {
1105
1105
 
1106
1106
  // src/runtime/managers/trtc-source-manager.ts
1107
1107
  var TAG = "[IVI-TRTC]";
1108
+ var DEFAULT_DENOISER_OPTIONS = {
1109
+ enabled: true,
1110
+ mode: "normal"
1111
+ };
1108
1112
  var TrtcSourceManager = class {
1109
- constructor(onLog) {
1113
+ constructor(onLog, onTrtcEvent, aiDenoiser) {
1110
1114
  this.onLog = onLog;
1115
+ this.onTrtcEvent = onTrtcEvent;
1116
+ this.aiDenoiser = aiDenoiser;
1111
1117
  this.sessions = /* @__PURE__ */ new Map();
1112
1118
  this.listeners = /* @__PURE__ */ new Map();
1113
1119
  }
@@ -1134,21 +1140,21 @@ var TrtcSourceManager = class {
1134
1140
  * 按 sourceId 注册/更新 TRTC 配置。
1135
1141
  * 若配置发生变化,会先销毁旧会话再按新参数重建连接。
1136
1142
  */
1137
- upsertSource(sourceId, trtc) {
1143
+ upsertSource(sourceId, trtc, aiDenoiser) {
1138
1144
  const existing = this.sessions.get(sourceId);
1139
1145
  if (!existing) {
1140
1146
  this.log("info", `\u65B0\u5EFA\u4F1A\u8BDD source=${sourceId} room=${getTrtcString(trtc, "room_id")} user=${getTrtcString(trtc, "user_id")}`);
1141
- const session2 = this.createSession(sourceId, trtc);
1147
+ const session2 = this.createSession(sourceId, trtc, aiDenoiser);
1142
1148
  this.sessions.set(sourceId, session2);
1143
1149
  void this.ensureConnected(session2);
1144
1150
  return;
1145
1151
  }
1146
- if (isSameTrtcConfig(existing.trtc, trtc)) {
1152
+ if (isSameTrtcConfig(existing.trtc, trtc) && isSameAIDenoiserOptions(existing.aiDenoiser, aiDenoiser)) {
1147
1153
  return;
1148
1154
  }
1149
1155
  this.log("info", `\u914D\u7F6E\u53D8\u66F4\uFF0C\u91CD\u5EFA\u4F1A\u8BDD source=${sourceId} room=${getTrtcString(trtc, "room_id")}`);
1150
1156
  void this.disposeSession(existing);
1151
- const session = this.createSession(sourceId, trtc);
1157
+ const session = this.createSession(sourceId, trtc, aiDenoiser);
1152
1158
  this.sessions.set(sourceId, session);
1153
1159
  void this.ensureConnected(session);
1154
1160
  }
@@ -1285,10 +1291,11 @@ var TrtcSourceManager = class {
1285
1291
  binding.muted = muted;
1286
1292
  void this.applyAudioPolicy(session);
1287
1293
  }
1288
- createSession(sourceId, trtc) {
1294
+ createSession(sourceId, trtc, aiDenoiser) {
1289
1295
  return {
1290
1296
  sourceId,
1291
1297
  trtc,
1298
+ aiDenoiser,
1292
1299
  TRTC: null,
1293
1300
  client: null,
1294
1301
  connectPromise: null,
@@ -1343,6 +1350,7 @@ var TrtcSourceManager = class {
1343
1350
  session.views.forEach((binding) => {
1344
1351
  void this.startRemoteVideoForBinding(client, event.userId, event.streamType, binding, remoteVideoKey);
1345
1352
  });
1353
+ this.emitTrtcEvent(session.sourceId, "remote_video_available", TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, event);
1346
1354
  };
1347
1355
  const onRemoteVideoUnavailable = (event) => {
1348
1356
  this.log("info", `\u8FDC\u7AEF\u89C6\u9891\u4E0D\u53EF\u7528 source=${session.sourceId} userId=${event.userId} streamType=${event.streamType}`);
@@ -1356,16 +1364,19 @@ var TrtcSourceManager = class {
1356
1364
  userId: event.userId,
1357
1365
  streamType: event.streamType
1358
1366
  }).catch(() => void 0);
1367
+ this.emitTrtcEvent(session.sourceId, "remote_video_unavailable", TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, event);
1359
1368
  };
1360
1369
  const onRemoteAudioAvailable = (event) => {
1361
1370
  this.log("info", `\u8FDC\u7AEF\u97F3\u9891\u53EF\u7528 source=${session.sourceId} userId=${event.userId}`);
1362
1371
  session.remoteAudioUsers.add(event.userId);
1363
1372
  void this.applyAudioPolicy(session);
1373
+ this.emitTrtcEvent(session.sourceId, "remote_audio_available", TRTC.EVENT.REMOTE_AUDIO_AVAILABLE, event);
1364
1374
  };
1365
1375
  const onRemoteAudioUnavailable = (event) => {
1366
1376
  this.log("info", `\u8FDC\u7AEF\u97F3\u9891\u4E0D\u53EF\u7528 source=${session.sourceId} userId=${event.userId}`);
1367
1377
  session.remoteAudioUsers.delete(event.userId);
1368
1378
  void this.applyAudioPolicy(session);
1379
+ this.emitTrtcEvent(session.sourceId, "remote_audio_unavailable", TRTC.EVENT.REMOTE_AUDIO_UNAVAILABLE, event);
1369
1380
  };
1370
1381
  session.onRemoteVideoAvailable = onRemoteVideoAvailable;
1371
1382
  session.onRemoteVideoUnavailable = onRemoteVideoUnavailable;
@@ -1390,6 +1401,7 @@ var TrtcSourceManager = class {
1390
1401
  session.status = "connected";
1391
1402
  session.error = void 0;
1392
1403
  this.log("info", `\u8FDB\u623F\u6210\u529F source=${session.sourceId} room=${roomId}`);
1404
+ await this.applyAIDenoiserPolicy(session, client, sdkAppId, userId, userSig);
1393
1405
  this.emitSnapshot(session.sourceId, {
1394
1406
  status: session.status
1395
1407
  });
@@ -1475,6 +1487,25 @@ var TrtcSourceManager = class {
1475
1487
  await client.muteRemoteAudio(userId, false);
1476
1488
  }
1477
1489
  }
1490
+ async applyAIDenoiserPolicy(session, client, sdkAppId, userId, userSig) {
1491
+ const options = resolveAIDenoiserOptions(session.aiDenoiser ?? this.aiDenoiser);
1492
+ if (!options.enabled) {
1493
+ this.log("info", `TRTC AIDenoiser \u5DF2\u5173\u95ED source=${session.sourceId}`);
1494
+ return;
1495
+ }
1496
+ try {
1497
+ await client.startPlugin("AIDenoiser", {
1498
+ sdkAppId,
1499
+ userId,
1500
+ userSig,
1501
+ mode: getAIDenoiserModeValue(options.mode),
1502
+ ...options.assetsPath ? { assetsPath: options.assetsPath } : {}
1503
+ });
1504
+ this.log("info", `TRTC AIDenoiser \u5DF2\u5F00\u542F source=${session.sourceId} mode=${options.mode}`);
1505
+ } catch (error) {
1506
+ this.log("warn", `TRTC AIDenoiser \u5F00\u542F\u5931\u8D25 source=${session.sourceId}`, error);
1507
+ }
1508
+ }
1478
1509
  /**
1479
1510
  * 销毁单个 source 会话:
1480
1511
  * 解绑事件、停止远端视频、退出房间并销毁客户端。
@@ -1538,6 +1569,17 @@ var TrtcSourceManager = class {
1538
1569
  data: extra.length > 0 ? { message, extra } : { message }
1539
1570
  });
1540
1571
  }
1572
+ emitTrtcEvent(sourceId, type, rawType, payload) {
1573
+ const event = {
1574
+ sourceId,
1575
+ type,
1576
+ rawType: String(rawType),
1577
+ payload,
1578
+ userId: payload.userId,
1579
+ streamType: payload.streamType
1580
+ };
1581
+ this.onTrtcEvent?.(event);
1582
+ }
1541
1583
  };
1542
1584
  function isRuntimeTrtcSource(source) {
1543
1585
  return source.status === "ready" && source.playback?.type === "trtc" && typeof source.playback.trtc === "object" && source.playback.trtc !== null;
@@ -1545,6 +1587,11 @@ function isRuntimeTrtcSource(source) {
1545
1587
  function isSameTrtcConfig(a, b) {
1546
1588
  return a.app_id === b.app_id && a.user_id === b.user_id && a.user_sig === b.user_sig && a.room_id === b.room_id;
1547
1589
  }
1590
+ function isSameAIDenoiserOptions(a, b) {
1591
+ const left = resolveAIDenoiserOptions(a);
1592
+ const right = resolveAIDenoiserOptions(b);
1593
+ return left.enabled === right.enabled && left.mode === right.mode && left.assetsPath === right.assetsPath;
1594
+ }
1548
1595
  function shouldUseStringRoomId(roomId) {
1549
1596
  if (!/^\d+$/.test(roomId)) {
1550
1597
  return true;
@@ -1556,6 +1603,26 @@ function getTrtcString(trtc, key) {
1556
1603
  const value = trtc[key];
1557
1604
  return typeof value === "string" ? value : "";
1558
1605
  }
1606
+ function resolveAIDenoiserOptions(options) {
1607
+ if (options === false) {
1608
+ return {
1609
+ ...DEFAULT_DENOISER_OPTIONS,
1610
+ enabled: false
1611
+ };
1612
+ }
1613
+ if (options === true || options === void 0) {
1614
+ return DEFAULT_DENOISER_OPTIONS;
1615
+ }
1616
+ return {
1617
+ ...DEFAULT_DENOISER_OPTIONS,
1618
+ ...options,
1619
+ enabled: options.enabled ?? DEFAULT_DENOISER_OPTIONS.enabled,
1620
+ mode: options.mode ?? DEFAULT_DENOISER_OPTIONS.mode
1621
+ };
1622
+ }
1623
+ function getAIDenoiserModeValue(mode) {
1624
+ return mode === "far_field_reduction" ? 1 : 0;
1625
+ }
1559
1626
  function buildRemoteVideoKey(userId, streamType) {
1560
1627
  return `${userId}::${streamType}`;
1561
1628
  }
@@ -2036,6 +2103,7 @@ var IviRuntimeCoordinator = class {
2036
2103
  this.conversationManager = new ConversationManager();
2037
2104
  this.stateListeners = /* @__PURE__ */ new Set();
2038
2105
  this.eventListeners = /* @__PURE__ */ new Set();
2106
+ this.trtcEventListeners = /* @__PURE__ */ new Set();
2039
2107
  this.pendingUserTextToResponseFlows = /* @__PURE__ */ new Map();
2040
2108
  this.userTextFlowCounter = 0;
2041
2109
  this.waitingTracksListValidation = false;
@@ -2055,7 +2123,11 @@ var IviRuntimeCoordinator = class {
2055
2123
  syncStageOnSessionCreated: true,
2056
2124
  ...config
2057
2125
  };
2058
- this.trtcSourceManager = new TrtcSourceManager(this.config.onLog);
2126
+ this.trtcSourceManager = new TrtcSourceManager(
2127
+ this.config.onLog,
2128
+ (event) => this.emitTrtcEvent(event),
2129
+ this.config.trtcAIDenoiser
2130
+ );
2059
2131
  this.livekitSourceManager = new LivekitSourceManager(this.config.onLog);
2060
2132
  this.sessionHandler = new SessionEventHandler(this.sessionManager, {
2061
2133
  onSessionCreated: (event) => this.onSessionCreated(event),
@@ -2128,6 +2200,12 @@ var IviRuntimeCoordinator = class {
2128
2200
  this.eventListeners.delete(listener);
2129
2201
  };
2130
2202
  }
2203
+ onTrtcEvent(listener) {
2204
+ this.trtcEventListeners.add(listener);
2205
+ return () => {
2206
+ this.trtcEventListeners.delete(listener);
2207
+ };
2208
+ }
2131
2209
  emitLog(entry) {
2132
2210
  this.config.onLog?.(entry);
2133
2211
  }
@@ -2382,6 +2460,10 @@ var IviRuntimeCoordinator = class {
2382
2460
  this.progressUserTextToResponseFlows(event);
2383
2461
  this.eventListeners.forEach((listener) => listener(event, this.state));
2384
2462
  }
2463
+ emitTrtcEvent(event) {
2464
+ this.config.onTrtcEvent?.(event);
2465
+ this.trtcEventListeners.forEach((listener) => listener(event));
2466
+ }
2385
2467
  resetStoppedState() {
2386
2468
  this.rejectPendingUserTextToResponseFlows(
2387
2469
  new Error("Runtime stopped before user text to response flow completed.")
@@ -3124,7 +3206,8 @@ function IVITrtcPlayer(props) {
3124
3206
  style,
3125
3207
  loadingFallback = null,
3126
3208
  errorFallback = null,
3127
- muted = false
3209
+ muted = false,
3210
+ trtcAIDenoiser
3128
3211
  } = props;
3129
3212
  const containerRef = useRef(null);
3130
3213
  const viewIdRef = useRef(`trtc-view-${Math.random().toString(36).slice(2, 10)}`);
@@ -3145,7 +3228,7 @@ function IVITrtcPlayer(props) {
3145
3228
  }
3146
3229
  let disposed = false;
3147
3230
  if (shouldManageSourceLifecycle) {
3148
- manager.upsertSource(resolvedSourceId, trtc);
3231
+ manager.upsertSource(resolvedSourceId, trtc, trtcAIDenoiser);
3149
3232
  }
3150
3233
  const unsubscribe = manager.subscribe(resolvedSourceId, (snapshot) => {
3151
3234
  if (disposed) {
@@ -3176,7 +3259,8 @@ function IVITrtcPlayer(props) {
3176
3259
  trtc.app_id,
3177
3260
  trtc.room_id,
3178
3261
  trtc.user_id,
3179
- trtc.user_sig
3262
+ trtc.user_sig,
3263
+ trtcAIDenoiser
3180
3264
  ]);
3181
3265
  useEffect(() => {
3182
3266
  manager.updateViewMuted(resolvedSourceId, viewIdRef.current, muted);