@bdky/aaas-pilot-kit 1.0.4 → 1.0.5

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.
Files changed (26) hide show
  1. package/dist/http.cjs.js +1 -1
  2. package/dist/http.esm.js +1 -1
  3. package/dist/http.umd.js +1 -1
  4. package/dist/index.cjs.js +30 -21
  5. package/dist/index.esm.js +29 -20
  6. package/dist/index.umd.js +30 -21
  7. package/dist/ky-aaas-pilot-kit.umd.js +30 -21
  8. package/dist/libs/aaas-pilot-kit/src/index.d.ts +2 -0
  9. package/dist/libs/aaas-pilot-kit/src/lib/controller.d.ts +40 -2
  10. package/dist/libs/aaas-pilot-kit/src/lib/error/codes.d.ts +6 -0
  11. package/dist/libs/aaas-pilot-kit/src/lib/error/services/AsrError.d.ts +18 -0
  12. package/dist/libs/aaas-pilot-kit/src/lib/service/agent/agentResponse.d.ts +174 -0
  13. package/dist/libs/aaas-pilot-kit/src/lib/service/agent/aiobAgentService.d.ts +1 -1
  14. package/dist/libs/aaas-pilot-kit/src/lib/service/agent/baseAgentService.d.ts +20 -2
  15. package/dist/libs/aaas-pilot-kit/src/lib/service/agent/cspAgentService.d.ts +1 -1
  16. package/dist/libs/aaas-pilot-kit/src/lib/service/digital-human/BaseDigitalHumanService.d.ts +16 -0
  17. package/dist/libs/aaas-pilot-kit/src/lib/service/digital-human/CloudDigitalHumanService.d.ts +12 -0
  18. package/dist/libs/aaas-pilot-kit/src/lib/service/digital-human/CloudNativeDigitalHumanService.d.ts +134 -0
  19. package/dist/libs/aaas-pilot-kit/src/lib/service/digital-human/PictureClientDigitalHumanService.d.ts +18 -0
  20. package/dist/libs/aaas-pilot-kit/src/lib/service/rtc-asr/asr/baseAsrService.d.ts +38 -3
  21. package/dist/libs/aaas-pilot-kit/src/lib/service/rtc-asr/asr/brtcAsrService.d.ts +2 -2
  22. package/dist/libs/aaas-pilot-kit/src/lib/utils/AudioDeviceDetector.d.ts +138 -0
  23. package/dist/libs/aaas-pilot-kit/src/lib/utils/agentResponseHelper.d.ts +42 -0
  24. package/dist/libs/aaas-pilot-kit/src/lib/utils/language-mapper.d.ts +70 -0
  25. package/dist/libs/aaas-pilot-kit/src/types/config.d.ts +175 -21
  26. package/package.json +7 -4
@@ -0,0 +1,138 @@
1
+ /**
2
+ * WebRTC 音频设备严谨检测工具类
3
+ *
4
+ * 实现了 4 层渐进式检测逻辑,从基础 API 支持到实际音频流获取验证
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const detector = new AudioDeviceDetector();
9
+ * const result = await detector.checkAudioDevice();
10
+ *
11
+ * if (result.available) {
12
+ * console.log('设备可用,可以开始录音');
13
+ * // 调用 getUserMedia
14
+ * } else {
15
+ * console.error('设备不可用:', result.error, result.message);
16
+ * // 根据错误类型给用户提示
17
+ * }
18
+ * ```
19
+ */
20
+ /**
21
+ * 音频设备检测错误类型枚举
22
+ */
23
+ export declare enum AudioDeviceError {
24
+ /** 浏览器不支持 MediaDevices API */
25
+ NO_API_SUPPORT = "NO_API_SUPPORT",
26
+ /** 非 HTTPS 安全上下文 (localhost 除外) */
27
+ INSECURE_CONTEXT = "INSECURE_CONTEXT",
28
+ /** 通过 enumerateDevices 未找到音频输入设备 */
29
+ NO_DEVICE_FOUND = "NO_DEVICE_FOUND",
30
+ /** 用户拒绝麦克风权限 */
31
+ PERMISSION_DENIED = "PERMISSION_DENIED",
32
+ /** 用户关闭/忽略权限弹窗 */
33
+ PERMISSION_DISMISSED = "PERMISSION_DISMISSED",
34
+ /** 设备被其他程序占用 */
35
+ DEVICE_IN_USE = "DEVICE_IN_USE",
36
+ /** 检测超时 */
37
+ TIMEOUT = "TIMEOUT",
38
+ /** 未知错误 */
39
+ UNKNOWN_ERROR = "UNKNOWN_ERROR"
40
+ }
41
+ /**
42
+ * 音频设备检测结果
43
+ */
44
+ export interface AudioDeviceCheckResult {
45
+ /** 设备是否可用 */
46
+ available: boolean;
47
+ /** 错误类型 (仅在 available = false 时存在) */
48
+ error?: AudioDeviceError;
49
+ /** 错误详细信息 */
50
+ message?: string;
51
+ /** 检测通过的层级 (1-4) */
52
+ passedLevel?: number;
53
+ /** 找到的音频设备列表 */
54
+ devices?: MediaDeviceInfo[];
55
+ /** 权限状态 (如果浏览器支持) */
56
+ permissionState?: PermissionState;
57
+ }
58
+ /**
59
+ * 检测配置选项
60
+ */
61
+ export interface AudioDetectorOptions {
62
+ /** 超时时间 (毫秒),默认 5000ms */
63
+ timeout?: number;
64
+ /** 是否在检测完成后自动释放资源,默认 true */
65
+ autoCleanup?: boolean;
66
+ }
67
+ /**
68
+ * WebRTC 音频设备检测器
69
+ */
70
+ export declare class AudioDeviceDetector {
71
+ private mediaStream;
72
+ private readonly options;
73
+ constructor(options?: AudioDetectorOptions);
74
+ /**
75
+ * 手动释放资源
76
+ *
77
+ * 注意: 如果 autoCleanup = true,会在 checkAudioDevice 完成后自动调用
78
+ */
79
+ cleanup(): void;
80
+ /**
81
+ * 执行完整的音频设备检测
82
+ *
83
+ * @returns 检测结果
84
+ */
85
+ checkAudioDevice(): Promise<AudioDeviceCheckResult>;
86
+ /**
87
+ * 执行实际的检测流程
88
+ */
89
+ private performCheck;
90
+ /**
91
+ * Level 1: 检查浏览器 API 支持
92
+ */
93
+ private checkAPISupport;
94
+ /**
95
+ * Level 2: 检查设备枚举
96
+ */
97
+ private checkDeviceEnumeration;
98
+ /**
99
+ * Level 3: 检查权限状态 (可选,Safari 不支持)
100
+ */
101
+ private checkPermissionState;
102
+ /**
103
+ * Level 4: 获取实际音频流
104
+ */
105
+ private checkMediaStream;
106
+ /**
107
+ * 创建错误结果
108
+ */
109
+ private createErrorResult;
110
+ /**
111
+ * 添加超时控制
112
+ */
113
+ private withTimeout;
114
+ }
115
+ /**
116
+ * 快捷函数:执行音频设备检测
117
+ *
118
+ * @param options 检测选项
119
+ * @returns 检测结果
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const result = await checkAudioDevice();
124
+ * if (result.available) {
125
+ * // 开始录音
126
+ * } else {
127
+ * alert(result.message);
128
+ * }
129
+ * ```
130
+ */
131
+ export declare function checkAudioDevice(options?: AudioDetectorOptions): Promise<AudioDeviceCheckResult>;
132
+ /**
133
+ * 根据错误类型获取用户友好的提示信息
134
+ *
135
+ * @param error 错误类型
136
+ * @returns 用户提示信息
137
+ */
138
+ export declare const getErrorMessage: (error: AudioDeviceError) => string;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @file AgentResponse 工具函数
3
+ * @description 简化 AgentResponse 的订阅和使用
4
+ */
5
+ import { type AgentResponse } from '../service/agent/agentResponse';
6
+ export interface ISubscribeAgentResponseOptions<T> {
7
+ /**
8
+ * 当响应更新时的回调
9
+ */
10
+ onUpdate?: (response: AgentResponse<T>) => void;
11
+ /**
12
+ * 当响应完成时的回调
13
+ */
14
+ onComplete?: (response: AgentResponse<T>) => void;
15
+ }
16
+ /**
17
+ * 订阅 AgentResponse 的更新
18
+ * 自动处理已完成和未完成的情况,在完成时自动取消订阅
19
+ *
20
+ * @param agentResponse - Agent 响应对象
21
+ * @param options - 订阅选项
22
+ * @returns 取消订阅函数
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const unsubscribe = subscribeAgentResponse(
27
+ * agentResponse,
28
+ * {
29
+ * onUpdate: response => {
30
+ * console.log('更新:', response.getChunks());
31
+ * },
32
+ * onComplete: response => {
33
+ * console.log('完成:', response.getFullText());
34
+ * }
35
+ * }
36
+ * );
37
+ *
38
+ * // 手动取消订阅(通常不需要,完成时会自动取消)
39
+ * unsubscribe();
40
+ * ```
41
+ */
42
+ export declare function subscribeAgentResponse<T = unknown>(agentResponse: AgentResponse<T> | null | undefined, options: ISubscribeAgentResponseOptions<T>): () => void;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 语言映射工具
3
+ *
4
+ * 用于将 SDK 统一语言代码映射为不同服务的语言格式
5
+ */
6
+ /**
7
+ * 统一语言代码常量
8
+ *
9
+ * 用于配置 ASR 识别语言和 TTS 合成语言
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import {Language} from '@bdky/aaas-pilot-kit';
14
+ *
15
+ * const kit = createAaaSPilotKit({
16
+ * lang: Language.ENGLISH, // 使用常量
17
+ * // 或
18
+ * lang: 'en', // 直接使用字符串
19
+ * // ...
20
+ * });
21
+ * ```
22
+ */
23
+ export declare const Language: {
24
+ /** 中文(普通话) - Chinese (Mandarin) */
25
+ readonly CHINESE: "zh";
26
+ /** 英语 - English */
27
+ readonly ENGLISH: "en";
28
+ /** 日语 - Japanese */
29
+ readonly JAPANESE: "ja";
30
+ /** 西班牙语 - Spanish */
31
+ readonly SPANISH: "es";
32
+ /** 俄语 - Russian */
33
+ readonly RUSSIAN: "ru";
34
+ /** 韩语 - Korean */
35
+ readonly KOREAN: "ko";
36
+ /** 越南语 - Vietnamese */
37
+ readonly VIETNAMESE: "vi";
38
+ /** 德语 - German */
39
+ readonly GERMAN: "de";
40
+ /** 印尼语 - Indonesian */
41
+ readonly INDONESIAN: "id";
42
+ /** 泰语 - Thai */
43
+ readonly THAI: "th";
44
+ };
45
+ /**
46
+ * 语言代码类型
47
+ */
48
+ export type LanguageCode = typeof Language[keyof typeof Language];
49
+ /**
50
+ * 将 SDK 统一语言代码映射为 BRTC 语言代码
51
+ *
52
+ * @param sdkLang SDK 语言代码
53
+ * @returns BRTC 语言代码
54
+ */
55
+ export declare const mapLangToBRTC: (sdkLang?: string) => string;
56
+ /**
57
+ * 将 SDK 统一语言代码映射为数字人 ttsLang
58
+ *
59
+ * @param sdkLang SDK 语言代码
60
+ * @returns 数字人 ttsLang 值
61
+ */
62
+ export declare const mapLangToDigitalHuman: (sdkLang?: string) => string;
63
+ /**
64
+ * 检查语言代码是否被 BRTC 支持
65
+ */
66
+ export declare const isBRTCLangSupported: (sdkLang: string) => boolean;
67
+ /**
68
+ * 检查语言代码是否被数字人支持
69
+ */
70
+ export declare const isDigitalHumanLangSupported: (sdkLang: string) => boolean;
@@ -8,9 +8,12 @@ import Emittery from 'emittery';
8
8
  import { AnyConversation, type IConversationBeanSnapshot } from '../lib/service/conversation';
9
9
  import type { IErrorEventPayload } from '../lib/error';
10
10
  import { NAbstractDigitalHumanService } from '../lib/service/digital-human/BaseDigitalHumanService';
11
- import { IAsrMessageEventPayload, IBusyEventPayload, IInterruptEventPayload } from '../lib/controller';
11
+ import { IAsrMessageEventPayload, IBusyEventPayload, IInterruptEventPayload, IReplyStartEventPayload } from '../lib/controller';
12
12
  import { NDigitalHumanService } from '../lib/service/digital-human/CloudDigitalHumanService';
13
+ import { Language, type LanguageCode } from '../lib/utils/language-mapper';
13
14
  type TFormatter = (input: string) => string;
15
+ export { Language };
16
+ export type { LanguageCode };
14
17
  export interface IOptions<AS extends BaseAgentService = BaseAgentService> {
15
18
  /**
16
19
  * 🆔【必填】数字员工形象 ID —— 从平台获取的唯一形象资源标识
@@ -39,11 +42,21 @@ export interface IOptions<AS extends BaseAgentService = BaseAgentService> {
39
42
  */
40
43
  ttsSample?: number;
41
44
  /**
42
- * 🖥️【选填】渲染模式:云端推流 or 本地2D渲染
43
- * - 'cloud'(默认)→ 高保真动态形象,需网络 + RTC 支持(推荐)
44
- * - 'client' 本地静态图+口型动画 2D 渲染,低资源消耗,离线可用
45
+ * 🖥️【选填】渲染模式:选择数字人服务的技术实现方式
46
+ *
47
+ * - 'cloud'(默认)→ 云端推流渲染(iframe 方式)
48
+ * - 适用场景:PC 端
49
+ * - 特点:高保真动态形象,需网络 + RTC 支持
50
+ *
51
+ * - 'cloud-native' → 云端推流渲染(原生 SDK 集成)
52
+ * - 适用场景:移动端(规避 iframe 点击限制)
53
+ * - 特点:高保真动态形象,需网络 + RTC 支持
54
+ *
55
+ * - 'client' → 本地 2D 渲染(静态图 + 口型动画)
56
+ * - 适用场景:离线场景或低资源消耗需求
57
+ * - 特点:低资源消耗,离线可用
45
58
  */
46
- rendererMode?: 'cloud' | 'client';
59
+ rendererMode?: 'cloud' | 'cloud-native' | 'client';
47
60
  /**
48
61
  * 🖼️【选填】仅 rendererMode='client' 时生效 —— 配置本地渲染参数
49
62
  * 包含形象资源路径、口型映射、TTS 驱动参数等
@@ -179,25 +192,46 @@ export interface IOptions<AS extends BaseAgentService = BaseAgentService> {
179
192
  /**
180
193
  * ⚡【选填】TTS 模型版本
181
194
  * - undefined → 标准版(稳定,低延迟)
182
- * - '02-turbo' → 加速版(响应更快,适合实时对话)
195
+ * - 'turbo_v2' → 加速版(响应更快,适合实时对话)
196
+ * - 'quality_v2' → 质量版(质量优先,声音的音频质量更高,时间延迟会有提升)
183
197
  */
184
- ttsModel?: '02-turbo' | undefined;
198
+ ttsModel?: 'turbo_v2' | undefined;
185
199
  /**
186
200
  * ASR 语音端点检测(VAD)的静音超时时长(单位:毫秒)
187
- * —— 用于判断用户“说完一句话”的停顿阈值。
201
+ * —— 用于判断用户"说完一句话"的停顿阈值。
188
202
  *
189
203
  * 🎯 通俗理解:你停顿多久,系统就认为你说完了,开始识别。
190
- * - 值越大 → 越“耐心”,适合语速慢/爱思考的用户;
191
- * - 值越小 → 越“灵敏”,适合语速快/想快速响应的场景。
204
+ * - 值越大 → 越"耐心",适合语速慢/爱思考的用户;
205
+ * - 值越小 → 越"灵敏",适合语速快/想快速响应的场景。
192
206
  *
193
207
  * ✅ 推荐值:
194
208
  * - 默认 600ms(适合大多数对话场景)
195
209
  * - 快速问答可设 300~400ms
196
210
  * - 慢速/英文教学场景可设 800~1000ms
197
211
  *
198
- * ⚠️ 注意:过小可能导致话没说完就被打断,过大会让用户觉得“反应迟钝”。
212
+ * ⚠️ 注意:过小可能导致话没说完就被打断,过大会让用户觉得"反应迟钝"。
199
213
  */
200
214
  asrVad?: number;
215
+ /**
216
+ * 🎙️【选填】ASR 启动前检查音频设备可用性
217
+ * —— 执行 4 层渐进式检测(API 支持、HTTPS、设备枚举、权限、流获取)
218
+ *
219
+ * ✅ 开启后(默认 false):
220
+ * - 在 ASR 启动前自动调用 checkAudioDevice()
221
+ * - 如果检测失败,直接阻止 ASR 启动并上报详细错误
222
+ * - 用户可通过监听 device_check_completed 事件获取诊断结果
223
+ *
224
+ * ⚠️ 性能影响:
225
+ * - 首次检测增加 ~100-500ms(主要是 getUserMedia)
226
+ * - 5 秒内缓存结果,重复调用 <1ms
227
+ *
228
+ * 💡 推荐场景:
229
+ * - 对用户体验要求高的场景(提前发现问题)
230
+ * - 需要精准错误提示的场景(区分「无设备」「权限拒绝」「设备占用」)
231
+ *
232
+ * @default true
233
+ */
234
+ checkAudioDeviceBeforeStart?: boolean;
201
235
  /**
202
236
  * 🌐【选填】运行环境
203
237
  * - 'development' → 开发调试(日志全开)
@@ -243,6 +277,42 @@ export interface IOptions<AS extends BaseAgentService = BaseAgentService> {
243
277
  * ❌ 设为 false → 保留原始背景(适合已有透明通道的素材)
244
278
  */
245
279
  autoChromaKey?: boolean;
280
+ /**
281
+ * 🌐【选填】语言配置
282
+ *
283
+ * 用于配置 ASR 语音识别和 TTS 语音合成的语言
284
+ *
285
+ * **支持的语言:**
286
+ * - `Language.CHINESE` / `'zh'` - 中文(普通话)
287
+ * - `Language.ENGLISH` / `'en'` - 英语
288
+ * - `Language.JAPANESE` / `'ja'` - 日语
289
+ * - `Language.SPANISH` / `'es'` - 西班牙语
290
+ * - `Language.RUSSIAN` / `'ru'` - 俄语
291
+ * - `Language.KOREAN` / `'ko'` - 韩语
292
+ * - `Language.VIETNAMESE` / `'vi'` - 越南语
293
+ * - `Language.GERMAN` / `'de'` - 德语
294
+ * - `Language.INDONESIAN` / `'id'` - 印尼语
295
+ * - `Language.THAI` / `'th'` - 泰语
296
+ *
297
+ * **注意:**
298
+ * - 影响 ASR 语音识别的语言模型
299
+ * - 影响 TTS 语音合成的发音效果
300
+ * - 不支持的语言代码会自动回退到中文
301
+ *
302
+ * @default 'zh'
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * import {Language} from '@bdky/aaas-pilot-kit';
307
+ *
308
+ * // 使用常量
309
+ * {lang: Language.ENGLISH}
310
+ *
311
+ * // 使用字符串
312
+ * {lang: 'en'}
313
+ * ```
314
+ */
315
+ lang?: LanguageCode;
246
316
  /**
247
317
  * 🔌【隐藏参数】RTC 应用 ID(内部使用)
248
318
  * ✅ 默认:'apprjff5d4wek7t'
@@ -253,7 +323,7 @@ export interface IOptions<AS extends BaseAgentService = BaseAgentService> {
253
323
  export declare const DEFAULT_OPTIONS: {
254
324
  readonly enableDebugMode: false;
255
325
  readonly minSplitLen: 5;
256
- readonly ttsModel: "02-turbo";
326
+ readonly ttsModel: "turbo_v2";
257
327
  readonly env: "production";
258
328
  readonly asrVad: 600;
259
329
  readonly interruptible: true;
@@ -261,14 +331,16 @@ export declare const DEFAULT_OPTIONS: {
261
331
  readonly autoChromaKey: true;
262
332
  readonly typeDelay: 163;
263
333
  readonly enTypeDelay: 45;
334
+ readonly lang: "zh";
264
335
  readonly inactivityPrompt: "您这么久没讲话,是不是有其它事情要忙,那我先挂断了";
265
336
  readonly getMountContainer: () => HTMLElement;
266
337
  readonly hotWordReplacementRules: ReplacementRule[];
338
+ readonly checkAudioDeviceBeforeStart: true;
267
339
  readonly rtcID: "appreimunmd7utp";
268
340
  };
269
341
  type DefaultedOptionKeys = keyof typeof DEFAULT_OPTIONS;
270
342
  export type IResolvedOptions<AS extends BaseAgentService = BaseAgentService> = IOptions<AS> & Required<Pick<IOptions<AS>, DefaultedOptionKeys>>;
271
- export interface IAaaSPilotKitEmitter {
343
+ export interface IAaaSPilotKitEmitter<AS extends BaseAgentService = BaseAgentService> {
272
344
  /**
273
345
  * 🔇【状态事件】静音状态变更
274
346
  * —— 当调用 .mute(true/false) 时触发
@@ -377,6 +449,10 @@ export interface IAaaSPilotKitEmitter {
377
449
  * @payload { text: string; sessionId: string; timestamp: number }
378
450
  */
379
451
  render_start: NAbstractDigitalHumanService.IEmitter['render_subtitle'] & NBaseAgentService.IEventWithSessionIdPayload;
452
+ /**
453
+ * TODO: 命名和注释待完善
454
+ */
455
+ reply_start: IReplyStartEventPayload<AS>;
380
456
  /**
381
457
  * ⏸️【低频】用户长时间无交互(触发 opts.inactivityPrompt)
382
458
  * —— 在配置的不活跃时间后触发,数字人将播报提醒语
@@ -407,10 +483,10 @@ export interface IAaaSPilotKitEmitter {
407
483
  */
408
484
  interrupt: IInterruptEventPayload;
409
485
  /**
410
- * 🖼️【状态同步】数字员工渲染/播报状态变更 —— 实时反映是否“正在说话中”
486
+ * 🖼️【状态同步】数字员工渲染/播报状态变更 —— 实时反映是否"正在说话中"
411
487
  *
412
488
  * 💡 核心用途:
413
- * - 控制 UI:显示“正在播报…”加载态、禁用发送按钮
489
+ * - 控制 UI:显示"正在播报…"加载态、禁用发送按钮
414
490
  * - 体验优化:避免用户在播报中途误操作导致体验割裂
415
491
  * - ...
416
492
  *
@@ -419,12 +495,62 @@ export interface IAaaSPilotKitEmitter {
419
495
  * - false → **播报完成,空闲可交互**(此时可安全输入或执行后续动作)
420
496
  *
421
497
  * ⚠️ 注意:
422
- * - 此状态仅反映“数字员工是否在播报”,不反映 ASR 或 Agent 是否在工作
498
+ * - 此状态仅反映"数字员工是否在播报",不反映 ASR 或 Agent 是否在工作
423
499
  */
424
500
  is_rendering_change: boolean;
501
+ /**
502
+ * 🎙️【设备检测】麦克风设备可用性检测结果
503
+ * —— 执行音频设备检测后触发,提供用户友好的错误提示
504
+ *
505
+ * 💡 触发时机:
506
+ * - 调用 controller.checkAudioDevice() 时
507
+ * - ASR 启动前(如果配置了 checkAudioDeviceBeforeStart: true)
508
+ *
509
+ * 🎯 使用场景:
510
+ * - 实时显示设备状态提示:"麦克风不可用,请检查设备"
511
+ * - 根据不同错误类型展示针对性解决方案
512
+ * - 采集设备统计数据(设备数量、权限状态等)
513
+ *
514
+ * @payload {
515
+ * available: boolean; // 设备是否可用
516
+ * error?: AudioDeviceError; // 错误类型(仅当 available=false 时)
517
+ * userMessage?: string; // 用户友好的错误提示文案
518
+ * devices?: MediaDeviceInfo[]; // 检测到的音频设备列表
519
+ * permissionState?: PermissionState; // 权限状态('granted'|'denied'|'prompt')
520
+ * }
521
+ *
522
+ * ⚠️ 注意:
523
+ * - userMessage 是经过优化的用户提示,可直接用于 UI 展示
524
+ * - 如果 available=true,error 和 userMessage 为 undefined
525
+ * - permissionState 可能为 undefined(Safari 不支持 Permissions API)
526
+ *
527
+ * @example 监听设备检测结果
528
+ * ```typescript
529
+ * controller.emitter.on('microphone_available', (result) => {
530
+ * if (!result.available) {
531
+ * // 显示用户友好的错误提示
532
+ * showToast(result.userMessage);
533
+ *
534
+ * // 或根据错误类型做特殊处理
535
+ * if (result.error === 'PERMISSION_DENIED') {
536
+ * showPermissionGuide(); // 引导用户开启权限
537
+ * }
538
+ * } else {
539
+ * console.log('设备可用,找到', result.devices?.length, '个音频设备');
540
+ * }
541
+ * });
542
+ * ```
543
+ */
544
+ microphone_available: {
545
+ available: boolean;
546
+ error?: import('../lib/utils/AudioDeviceDetector').AudioDeviceError;
547
+ userMessage?: string;
548
+ devices?: MediaDeviceInfo[];
549
+ permissionState?: PermissionState;
550
+ };
425
551
  }
426
- export interface IAaaSPilotKitController {
427
- emitter: Emittery<IAaaSPilotKitEmitter>;
552
+ export interface IAaaSPilotKitController<AS extends BaseAgentService = BaseAgentService> {
553
+ emitter: Emittery<IAaaSPilotKitEmitter<AS>>;
428
554
  /**
429
555
  * 🧩 挂载数字员工到指定 DOM 容器
430
556
  *
@@ -535,7 +661,7 @@ export interface IAaaSPilotKitController {
535
661
  */
536
662
  input(text: string): IAaaSPilotKitController;
537
663
  /**
538
- * 🔄 动态切换“是否允许打断”
664
+ * 🔄 动态切换"是否允许打断"
539
665
  * —— 可在对话中随时调整,立即生效
540
666
  *
541
667
  * @param interruptible - 是否允许打断
@@ -543,7 +669,36 @@ export interface IAaaSPilotKitController {
543
669
  */
544
670
  setInterruptible(interruptible: boolean): IAaaSPilotKitController;
545
671
  /**
546
- * 🚦 检测是否需要“手动激活”(如浏览器策略阻止自动播放)
672
+ * 🎙️ 检查音频设备可用性
673
+ *
674
+ * 执行 4 层渐进式检测:
675
+ * - Level 1: API 支持检查 (MediaDevices API)
676
+ * - Level 2: 设备枚举 (enumerateDevices)
677
+ * - Level 3: 权限状态查询 (Permissions API, Safari 可能不支持)
678
+ * - Level 4: 实际流获取 (getUserMedia + 轨道状态检查)
679
+ *
680
+ * 🚀 性能优化:5 秒内缓存结果,避免重复检测
681
+ *
682
+ * @param options - 检测配置选项
683
+ * @returns 检测结果
684
+ *
685
+ * @example
686
+ * ```typescript
687
+ * const result = await controller.checkAudioDevice();
688
+ * if (!result.available) {
689
+ * // 根据 result.error 显示不同的用户提示
690
+ * import { getErrorMessage } from '@bdky/aaas-pilot-kit';
691
+ * alert(getErrorMessage(result.error));
692
+ * }
693
+ * ```
694
+ */
695
+ checkAudioDevice(options?: {
696
+ timeout?: number;
697
+ autoCleanup?: boolean;
698
+ forceCheck?: boolean;
699
+ }): Promise<import('../lib/utils/AudioDeviceDetector').AudioDeviceCheckResult>;
700
+ /**
701
+ * 🚦 检测是否需要"手动激活"(如浏览器策略阻止自动播放)
547
702
  *
548
703
  * 🔹 返回 true 时,必须调用 activateManually() 用户交互后才能播放音频
549
704
  * —— 常见于移动端/静音浏览器首次播放
@@ -575,4 +730,3 @@ export interface IAaaSPilotKitController {
575
730
  */
576
731
  keepAlive(): IAaaSPilotKitController;
577
732
  }
578
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdky/aaas-pilot-kit",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "license": "MIT",
5
5
  "contributors": [
6
6
  {
@@ -33,21 +33,24 @@
33
33
  },
34
34
  "scripts": {
35
35
  "build": "npx rslib build",
36
+ "watch": "npx rslib build --watch",
36
37
  "dev": "npx rsbuild dev --open",
37
38
  "analyze": "RSDOCTOR=true npx rslib build"
38
39
  },
39
40
  "dependencies": {
40
41
  "@bddh/starling-dh-picture-client": "^1.0.52",
41
42
  "@bddh/starling-dhiframe": "^2.1.9",
43
+ "@bddh/starling-realtime-client": "^2.0.8",
42
44
  "@types/ua-parser-js": "^0.7.39",
43
45
  "abort-signal-polyfill": "^1.0.0",
46
+ "baidurtc": "^1.2.21",
44
47
  "core-js": "^3.44.0",
45
48
  "emittery": "^1.2.0",
46
49
  "fast-xml-parser": "^5.2.5",
47
- "inversify": "^7.5.2",
48
- "ky": "^1.8.1",
50
+ "inversify": "^7.10.4",
51
+ "ky": "^1.14.0",
49
52
  "p-defer": "^4.0.1",
50
- "p-queue": "^8.1.0",
53
+ "p-queue": "^9.0.0",
51
54
  "reflect-metadata": "^0.2.2",
52
55
  "type-fest": "^4.41.0",
53
56
  "typewriter-effect": "^2.22.0",