@coze/realtime-api 1.0.4-beta.1 → 1.0.4-beta.2

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.
@@ -1,4 +1,4 @@
1
- import { type AudioPropertiesConfig } from '@volcengine/rtc';
1
+ import { type ScreenConfig, type AudioPropertiesConfig, type IRTCEngine } from '@volcengine/rtc';
2
2
  import { type GetToken } from '@coze/api';
3
3
  import * as RealtimeUtils from './utils';
4
4
  import { RealtimeEventHandler, EventNames } from './event-handler';
@@ -6,12 +6,15 @@ import { RealtimeAPIError, RealtimeError } from './error';
6
6
  export interface VideoConfig {
7
7
  videoOnDefault?: boolean /** optional, Whether to turn on video by default, defaults to true */;
8
8
  renderDom?: string /** optional, The DOM element to render the video stream to */;
9
+ videoInputDeviceId?: string /** optional, The device ID of the video input device to use */;
10
+ screenConfig?: ScreenConfig;
9
11
  }
10
12
  export interface RealtimeClientConfig {
11
13
  accessToken: GetToken /** required, Access Token */;
12
14
  botId: string /** required, Bot Id */;
13
15
  voiceId?: string /** optional, Voice Id */;
14
16
  conversationId?: string /** optional, Conversation Id */;
17
+ userId?: string /** optional, User Id */;
15
18
  baseURL?: string /** optional, defaults to "https://api.coze.cn" */;
16
19
  debug?: boolean /** optional, defaults to false */;
17
20
  /** Whether Personal Access Tokens (PAT) are allowed in browser environments */
@@ -46,6 +49,8 @@ declare class RealtimeClient extends RealtimeEventHandler {
46
49
  * 可选,音色Id。
47
50
  * @param config.conversationId - Optional, Conversation Id. |
48
51
  * 可选,会话Id。
52
+ * @param config.userId - Optional, User Id. |
53
+ * 可选,用户Id。
49
54
  * @param config.baseURL - Optional, defaults to "https://api.coze.cn". |
50
55
  * 可选,默认值为 "https://api.coze.cn"。
51
56
  * @param config.debug - Optional, defaults to false.
@@ -62,6 +67,16 @@ declare class RealtimeClient extends RealtimeEventHandler {
62
67
  * @param config.suppressNonStationaryNoise - Optional, suppress non-stationary noise, defaults to false. |
63
68
  * 可选,默认是否抑制非静态噪声,默认值为 false。
64
69
  * @param config.isAutoSubscribeAudio - Optional, whether to automatically subscribe to bot reply audio streams, defaults to true. |
70
+ * @param config.videoConfig - Optional, Video configuration. |
71
+ * 可选,视频配置。
72
+ * @param config.videoConfig.videoOnDefault - Optional, Whether to turn on video by default, defaults to true. |
73
+ * 可选,默认是否开启视频,默认值为 true。
74
+ * @param config.videoConfig.renderDom - Optional, The DOM element to render the video stream to. |
75
+ * 可选,渲染视频流的 DOM 元素。
76
+ * @param config.videoConfig.videoInputDeviceId - Optional, The device ID of the video input device to use. |
77
+ * 可选,视频输入设备的设备 ID。
78
+ * @param config.videoConfig.screenConfig - Optional, Screen share configuration if videoInputDeviceId is 'screenShare' see https://www.volcengine.com/docs/6348/104481#screenconfig for more details. |
79
+ * 可选,屏幕共享配置,如果 videoInputDeviceId 是 'screenShare',请参考 https://www.volcengine.com/docs/6348/104481#screenconfig 了解更多详情。
65
80
  */
66
81
  constructor(config: RealtimeClientConfig);
67
82
  /**
@@ -125,5 +140,12 @@ declare class RealtimeClient extends RealtimeEventHandler {
125
140
  * zh: 设置音频输出设备
126
141
  */
127
142
  setAudioOutputDevice(deviceId: string): Promise<void>;
143
+ setVideoInputDevice(deviceId: string): Promise<void>;
144
+ /**
145
+ * en: Get the RTC engine instance, for detail visit https://www.volcengine.com/docs/6348/104481
146
+ *
147
+ * zh: 获取 RTC 引擎实例,详情请访问 https://www.volcengine.com/docs/6348/104481
148
+ */
149
+ getRtcEngine(): IRTCEngine | undefined;
128
150
  }
129
151
  export { RealtimeUtils, RealtimeClient, RealtimeAPIError, RealtimeError, EventNames, };
@@ -13,6 +13,11 @@ export declare const checkPermission: ({ audio, video, }?: {
13
13
  audio?: boolean;
14
14
  video?: boolean;
15
15
  }) => Promise<boolean>;
16
+ /**
17
+ * Checks device permissions for audio and video
18
+ * @param checkVideo Whether to check video permissions (default: false)
19
+ * @returns Promise that resolves with the device permission status
20
+ */
16
21
  export declare const checkDevicePermission: (checkVideo?: boolean) => Promise<{
17
22
  video: boolean;
18
23
  audio: boolean;
@@ -30,3 +35,9 @@ export declare const getAudioDevices: ({ video, }?: {
30
35
  audioOutputs: MediaDeviceInfo[];
31
36
  videoInputs: MediaDeviceInfo[];
32
37
  }>;
38
+ export declare const isScreenShareDevice: (deviceId?: string) => boolean;
39
+ /**
40
+ * Check if browser supports screen sharing
41
+ * 检查浏览器是否支持屏幕共享
42
+ */
43
+ export declare function isScreenShareSupported(): boolean;
package/dist/umd/index.js CHANGED
@@ -101,7 +101,7 @@
101
101
  hasBrowserEnv: ()=>hasBrowserEnv,
102
102
  hasStandardBrowserEnv: ()=>hasStandardBrowserEnv,
103
103
  hasStandardBrowserWebWorkerEnv: ()=>hasStandardBrowserWebWorkerEnv,
104
- navigator: ()=>_navigator,
104
+ navigator: ()=>utils_navigator,
105
105
  origin: ()=>origin
106
106
  });
107
107
  // NAMESPACE OBJECT: ./src/utils.ts
@@ -111,6 +111,8 @@
111
111
  checkDevicePermission: ()=>checkDevicePermission,
112
112
  checkPermission: ()=>checkPermission,
113
113
  getAudioDevices: ()=>getAudioDevices,
114
+ isScreenShareDevice: ()=>isScreenShareDevice,
115
+ isScreenShareSupported: ()=>isScreenShareSupported,
114
116
  sleep: ()=>src_utils_sleep
115
117
  });
116
118
  class APIResource {
@@ -1634,7 +1636,7 @@
1634
1636
  ]
1635
1637
  };
1636
1638
  const hasBrowserEnv = 'undefined' != typeof window && 'undefined' != typeof document;
1637
- const _navigator = 'object' == typeof navigator && navigator || void 0;
1639
+ const utils_navigator = 'object' == typeof navigator && navigator || void 0;
1638
1640
  /**
1639
1641
  * Determine if we're running in a standard browser environment
1640
1642
  *
@@ -1651,11 +1653,11 @@
1651
1653
  * navigator.product -> 'NativeScript' or 'NS'
1652
1654
  *
1653
1655
  * @returns {boolean}
1654
- */ const hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || [
1656
+ */ const hasStandardBrowserEnv = hasBrowserEnv && (!utils_navigator || [
1655
1657
  'ReactNative',
1656
1658
  'NativeScript',
1657
1659
  'NS'
1658
- ].indexOf(_navigator.product) < 0);
1660
+ ].indexOf(utils_navigator.product) < 0);
1659
1661
  /**
1660
1662
  * Determine if we're running in a standard browser webWorker environment
1661
1663
  *
@@ -3677,9 +3679,9 @@
3677
3679
  * @param params.page - Optional The page number for paginated queries. Default is 1. | 可选 分页查询时的页码。默认为 1。
3678
3680
  * @param params.page_size - Optional The size of pagination. Default is 10. | 可选 分页大小。默认为 10。
3679
3681
  * @returns ListDocumentData | 知识库文件列表
3680
- */ list(params, options) {
3682
+ */ async list(params, options) {
3681
3683
  const apiUrl = '/open_api/knowledge/document/list';
3682
- const response = this._client.get(apiUrl, params, false, mergeConfig(options, {
3684
+ const response = await this._client.get(apiUrl, params, false, mergeConfig(options, {
3683
3685
  headers: documents_documents_headers
3684
3686
  }));
3685
3687
  return response;
@@ -3728,9 +3730,104 @@
3728
3730
  }));
3729
3731
  }
3730
3732
  }
3733
+ class Images extends APIResource {
3734
+ /**
3735
+ * Update the description of an image in the knowledge base | 更新知识库中的图片描述
3736
+ * @docs en: https://www.coze.com/docs/developer_guides/developer_guides/update_image_caption?_lang=en
3737
+ * @docs zh: https://www.coze.cn/docs/developer_guides/developer_guides/update_image_caption?_lang=zh
3738
+ * @param datasetId - The ID of the dataset | 必选 知识库 ID
3739
+ * @param documentId - The ID of the document | 必选 知识库文件 ID
3740
+ * @param params - The parameters for updating the image
3741
+ * @param params.caption - Required. The description of the image | 必选 图片的描述信息
3742
+ * @returns undefined
3743
+ */ // eslint-disable-next-line max-params
3744
+ async update(datasetId, documentId, params, options) {
3745
+ const apiUrl = `/v1/datasets/${datasetId}/images/${documentId}`;
3746
+ await this._client.put(apiUrl, params, false, options);
3747
+ }
3748
+ /**
3749
+ * List images in the knowledge base | 列出知识库中的图片
3750
+ * @docs en: https://www.coze.com/docs/developer_guides/developer_guides/get_images?_lang=en
3751
+ * @docs zh: https://www.coze.cn/docs/developer_guides/developer_guides/get_images?_lang=zh
3752
+ * @param datasetId - The ID of the dataset | 必选 知识库 ID
3753
+ * @param params - The parameters for listing images
3754
+ * @param params.page_num - Optional. Page number for pagination, minimum value is 1, defaults to 1 | 可选 分页查询时的页码。默认为 1。
3755
+ * @param params.page_size - Optional. Number of items per page, range 1-299, defaults to 10 | 可选 分页大小。默认为 10。
3756
+ * @param params.keyword - Optional. Search keyword for image descriptions | 可选 图片描述的搜索关键词。
3757
+ * @param params.has_caption - Optional. Filter for images with/without captions | 可选 是否过滤有/无描述的图片。
3758
+ */ async list(datasetId, params, options) {
3759
+ const apiUrl = `/v1/datasets/${datasetId}/images`;
3760
+ const response = await this._client.get(apiUrl, params, false, options);
3761
+ return response.data;
3762
+ }
3763
+ }
3731
3764
  class Datasets extends APIResource {
3765
+ /**
3766
+ * Creates a new dataset | 创建数据集
3767
+ * @docs en: https://www.coze.com/docs/developer_guides/create_dataset?_lang=en
3768
+ * @docs zh: https://www.coze.cn/docs/developer_guides/create_dataset?_lang=zh
3769
+ * @param params - The parameters for creating a dataset
3770
+ * @param {string} params.name - Required. Dataset name, maximum length of 100 characters | 必选 数据集名称,最大长度为 100 个字符
3771
+ * @param {string} params.space_id - Required. Space ID where the dataset belongs | 必选 数据集所属的空间 ID
3772
+ * @param {number} params.format_type - Required. Dataset type (0: Text type, 2: Image type) | 必选 数据集类型 (0: 文本类型, 2: 图片类型)
3773
+ * @param {string} [params.description] - Optional. Dataset description | 可选 数据集描述
3774
+ * @param {string} [params.file_id] - Optional. Dataset icon file ID from file upload
3775
+ */ async create(params, options) {
3776
+ const apiUrl = '/v1/datasets';
3777
+ const response = await this._client.post(apiUrl, params, false, options);
3778
+ return response.data;
3779
+ }
3780
+ /**
3781
+ * Lists all datasets in a space | 列出空间中的所有数据集
3782
+ * @docs en: https://www.coze.com/docs/developer_guides/list_dataset?_lang=en
3783
+ * @docs zh: https://www.coze.cn/docs/developer_guides/list_dataset?_lang=zh
3784
+ * @param params - The parameters for listing datasets | 列出数据集的参数
3785
+ * @param {string} params.space_id - Required. Space ID where the datasets belong | 必选 数据集所属的空间 ID
3786
+ * @param {string} [params.name] - Optional. Dataset name for fuzzy search | 可选 数据集名称用于模糊搜索
3787
+ * @param {number} [params.format_type] - Optional. Dataset type (0: Text type, 2: Image type) | 可选 数据集类型 (0: 文本类型, 2: 图片类型)
3788
+ * @param {number} [params.page_num] - Optional. Page number for pagination (default: 1) | 可选 分页查询时的页码。默认为 1。
3789
+ * @param {number} [params.page_size] - Optional. Number of items per page (default: 10) | 可选 分页大小。默认为 10。
3790
+ */ async list(params, options) {
3791
+ const apiUrl = '/v1/datasets';
3792
+ const response = await this._client.get(apiUrl, params, false, options);
3793
+ return response.data;
3794
+ }
3795
+ /**
3796
+ * Updates a dataset | 更新数据集
3797
+ * @docs en: https://www.coze.com/docs/developer_guides/update_dataset?_lang=en
3798
+ * @docs zh: https://www.coze.cn/docs/developer_guides/update_dataset?_lang=zh
3799
+ * @param dataset_id - Required. The ID of the dataset to update | 必选 数据集 ID
3800
+ * @param params - Required. The parameters for updating the dataset | 必选 更新数据集的参数
3801
+ * @param params.name - Required. Dataset name, maximum length of 100 characters. | 必选 数据集名称,最大长度为 100 个字符。
3802
+ * @param params.file_id - Optional. Dataset icon, should pass the file_id obtained from the file upload interface. | 可选 数据集图标,应传递从文件上传接口获取的 file_id。
3803
+ * @param params.description - Optional. Dataset description. | 可选 数据集描述。
3804
+ */ async update(dataset_id, params, options) {
3805
+ const apiUrl = `/v1/datasets/${dataset_id}`;
3806
+ await this._client.put(apiUrl, params, false, options);
3807
+ }
3808
+ /**
3809
+ * Deletes a dataset | 删除数据集
3810
+ * @docs en: https://www.coze.com/docs/developer_guides/delete_dataset?_lang=en
3811
+ * @docs zh: https://www.coze.cn/docs/developer_guides/delete_dataset?_lang=zh
3812
+ * @param dataset_id - Required. The ID of the dataset to delete | 必选 数据集 ID
3813
+ */ async delete(dataset_id, options) {
3814
+ const apiUrl = `/v1/datasets/${dataset_id}`;
3815
+ await this._client.delete(apiUrl, false, options);
3816
+ }
3817
+ /**
3818
+ * Views the progress of dataset upload | 查看数据集上传进度
3819
+ * @docs en: https://www.coze.com/docs/developer_guides/get_dataset_progress?_lang=en
3820
+ * @docs zh: https://www.coze.cn/docs/developer_guides/get_dataset_progress?_lang=zh
3821
+ * @param dataset_id - Required. The ID of the dataset to process | 必选 数据集 ID
3822
+ * @param params - Required. The parameters for processing the dataset | 必选 处理数据集的参数
3823
+ * @param params.dataset_ids - Required. List of dataset IDs | 必选 数据集 ID 列表
3824
+ */ async process(dataset_id, params, options) {
3825
+ const apiUrl = `/v1/datasets/${dataset_id}/process`;
3826
+ const response = await this._client.post(apiUrl, params, false, options);
3827
+ return response.data;
3828
+ }
3732
3829
  constructor(...args){
3733
- super(...args), this.documents = new documents_Documents(this._client);
3830
+ super(...args), this.documents = new documents_Documents(this._client), this.images = new Images(this._client);
3734
3831
  }
3735
3832
  }
3736
3833
  class Voices extends APIResource {
@@ -3750,6 +3847,8 @@
3750
3847
  * | 如果传入会基于该文本生成预览音频,否则使用默认的文本
3751
3848
  * @param params.text - Optional. Users can read this text, service will compare audio with text. Returns error if difference is too large
3752
3849
  * | 可以让用户按照该文本念诵,服务会对比音频与该文本的差异。若差异过大会返回错误
3850
+ * @param params.space_id - Optional. The space id of the voice. | 空间ID
3851
+ * @param params.description- Optional. The description of the voice. | 音色描述
3753
3852
  * @param options - Request options
3754
3853
  * @returns Clone voice data
3755
3854
  */ async clone(params, options) {
@@ -3774,6 +3873,17 @@
3774
3873
  return response.data;
3775
3874
  }
3776
3875
  }
3876
+ class Transcriptions extends APIResource {
3877
+ /**
3878
+ * ASR voice to text | ASR 语音转文本
3879
+ * @param params - Required The parameters for file upload | 上传文件所需的参数
3880
+ * @param params.file - Required The audio file to be uploaded. | 需要上传的音频文件。
3881
+ */ async create(params, options) {
3882
+ const apiUrl = '/v1/audio/transcriptions';
3883
+ const response = await this._client.post(apiUrl, axios_toFormData(params), false, options);
3884
+ return response.data;
3885
+ }
3886
+ }
3777
3887
  class Speech extends APIResource {
3778
3888
  /**
3779
3889
  * @description Speech synthesis | 语音合成
@@ -3787,7 +3897,10 @@
3787
3897
  * @returns Speech synthesis data
3788
3898
  */ async create(params, options) {
3789
3899
  const apiUrl = '/v1/audio/speech';
3790
- const response = await this._client.post(apiUrl, params, false, mergeConfig(options, {
3900
+ const response = await this._client.post(apiUrl, {
3901
+ ...params,
3902
+ sample_rate: params.sample_rate || 24000
3903
+ }, false, mergeConfig(options, {
3791
3904
  responseType: 'arraybuffer'
3792
3905
  }));
3793
3906
  return response;
@@ -3802,13 +3915,27 @@
3802
3915
  }
3803
3916
  class audio_Audio extends APIResource {
3804
3917
  constructor(...args){
3805
- super(...args), this.rooms = new Rooms(this._client), this.voices = new Voices(this._client), this.speech = new Speech(this._client);
3918
+ super(...args), this.rooms = new Rooms(this._client), this.voices = new Voices(this._client), this.speech = new Speech(this._client), this.transcriptions = new Transcriptions(this._client);
3919
+ }
3920
+ }
3921
+ class Templates extends APIResource {
3922
+ /**
3923
+ * Duplicate a template. | 复制一个模板。
3924
+ * @param templateId - Required. The ID of the template to duplicate. | 要复制的模板的 ID。
3925
+ * @param params - Optional. The parameters for the duplicate operation. | 可选参数,用于复制操作。
3926
+ * @param params.workspace_id - Required. The ID of the workspace to duplicate the template into. | 要复制到的目标工作空间的 ID。
3927
+ * @param params.name - Optional. The name of the new template. | 新模板的名称。
3928
+ * @returns TemplateDuplicateRes | 复制模板结果
3929
+ */ async duplicate(templateId, params, options) {
3930
+ const apiUrl = `/v1/templates/${templateId}/duplicate`;
3931
+ const response = await this._client.post(apiUrl, params, false, options);
3932
+ return response.data;
3806
3933
  }
3807
3934
  }
3808
3935
  // EXTERNAL MODULE: os (ignored)
3809
3936
  var os_ignored_ = __webpack_require__("?9050");
3810
3937
  var os_ignored_default = /*#__PURE__*/ __webpack_require__.n(os_ignored_);
3811
- var package_namespaceObject = JSON.parse('{"name":"@coze/api","version":"1.0.16-beta.1","description":"Official Coze Node.js SDK for seamless AI integration into your applications | 扣子官方 Node.js SDK,助您轻松集成 AI 能力到应用中","keywords":["coze","ai","nodejs","sdk","chatbot","typescript"],"homepage":"https://github.com/coze-dev/coze-js/tree/main/packages/coze-js","bugs":{"url":"https://github.com/coze-dev/coze-js/issues"},"repository":{"type":"git","url":"https://github.com/coze-dev/coze-js.git","directory":"packages/coze-js"},"license":"MIT","author":"Leeight <leeight@gmail.com>","type":"module","main":"src/index.ts","browser":{"crypto":false,"os":false,"jsonwebtoken":false},"types":"src/index.ts","files":["dist","LICENSE","README.md"],"scripts":{"build":"rm -rf dist && rslib build","format":"prettier --write .","lint":"eslint ./ --cache --quiet","start":"rm -rf dist && rslib build -w","test":"vitest","test:cov":"vitest --coverage --run"},"dependencies":{"jsonwebtoken":"^9.0.2"},"devDependencies":{"@coze-infra/eslint-config":"workspace:*","@coze-infra/ts-config":"workspace:*","@coze-infra/vitest-config":"workspace:*","@rslib/core":"0.0.18","@swc/core":"^1.3.14","@types/jsonwebtoken":"^9.0.0","@types/node":"^20","@types/uuid":"^9.0.1","@types/whatwg-fetch":"^0.0.33","@vitest/coverage-v8":"~2.1.4","axios":"^1.7.7","typescript":"^5.5.3","vitest":"~2.1.4"},"peerDependencies":{"axios":"^1.7.1"},"cozePublishConfig":{"exports":{".":{"require":"./dist/cjs/index.cjs","import":"./dist/esm/index.js","types":"./dist/types/index.d.ts"}},"main":"dist/cjs/index.cjs","module":"dist/esm/index.js","types":"dist/types/index.d.ts"}}'); // CONCATENATED MODULE: ../coze-js/src/version.ts
3938
+ var package_namespaceObject = JSON.parse('{"name":"@coze/api","version":"1.0.16","description":"Official Coze Node.js SDK for seamless AI integration into your applications | 扣子官方 Node.js SDK,助您轻松集成 AI 能力到应用中","keywords":["coze","ai","nodejs","sdk","chatbot","typescript"],"homepage":"https://github.com/coze-dev/coze-js/tree/main/packages/coze-js","bugs":{"url":"https://github.com/coze-dev/coze-js/issues"},"repository":{"type":"git","url":"https://github.com/coze-dev/coze-js.git","directory":"packages/coze-js"},"license":"MIT","author":"Leeight <leeight@gmail.com>","type":"module","exports":{".":"./src/index.ts"},"main":"src/index.ts","module":"src/index.ts","browser":{"crypto":false,"os":false,"jsonwebtoken":false},"types":"src/index.ts","files":["dist","LICENSE","README.md","README.zh-CN.md"],"scripts":{"build":"rm -rf dist && rslib build","format":"prettier --write .","lint":"eslint ./ --cache --quiet","start":"rm -rf dist && rslib build -w","test":"vitest","test:cov":"vitest --coverage --run"},"dependencies":{"jsonwebtoken":"^9.0.2"},"devDependencies":{"@coze-infra/eslint-config":"workspace:*","@coze-infra/ts-config":"workspace:*","@coze-infra/vitest-config":"workspace:*","@rslib/core":"0.0.18","@swc/core":"^1.3.14","@types/jsonwebtoken":"^9.0.0","@types/node":"^20","@types/uuid":"^9.0.1","@types/whatwg-fetch":"^0.0.33","@vitest/coverage-v8":"~2.1.4","axios":"^1.7.7","typescript":"^5.5.3","vitest":"~2.1.4"},"peerDependencies":{"axios":"^1.7.1"},"cozePublishConfig":{"exports":{".":{"require":"./dist/cjs/index.cjs","import":"./dist/esm/index.js","types":"./dist/types/index.d.ts"}},"main":"dist/cjs/index.cjs","module":"dist/esm/index.js","types":"dist/types/index.d.ts"}}'); // CONCATENATED MODULE: ../coze-js/src/version.ts
3812
3939
  const { version: version_version } = package_namespaceObject;
3813
3940
  const getEnv = ()=>{
3814
3941
  const nodeVersion = process.version.slice(1); // Remove 'v' prefix
@@ -3858,6 +3985,55 @@
3858
3985
  };
3859
3986
  return JSON.stringify(ua);
3860
3987
  };
3988
+ const getBrowserClientUserAgent = ()=>{
3989
+ const browserInfo = {
3990
+ name: 'unknown',
3991
+ version: 'unknown'
3992
+ };
3993
+ const osInfo = {
3994
+ name: 'unknown',
3995
+ version: 'unknown'
3996
+ };
3997
+ const { userAgent } = navigator;
3998
+ // 检测操作系统及版本
3999
+ if (userAgent.indexOf('Windows') > -1) {
4000
+ var _userAgent_match;
4001
+ osInfo.name = 'windows';
4002
+ const windowsVersion = (null === (_userAgent_match = userAgent.match(/Windows NT ([0-9.]+)/)) || void 0 === _userAgent_match ? void 0 : _userAgent_match[1]) || 'unknown';
4003
+ osInfo.version = windowsVersion;
4004
+ } else if (userAgent.indexOf('Mac OS X') > -1) {
4005
+ var _userAgent_match1;
4006
+ osInfo.name = 'macos';
4007
+ // 将 10_15_7 格式转换为 10.15.7
4008
+ osInfo.version = ((null === (_userAgent_match1 = userAgent.match(/Mac OS X ([0-9_]+)/)) || void 0 === _userAgent_match1 ? void 0 : _userAgent_match1[1]) || 'unknown').replace(/_/g, '.');
4009
+ } else if (userAgent.indexOf('Linux') > -1) {
4010
+ var _userAgent_match2;
4011
+ osInfo.name = 'linux';
4012
+ osInfo.version = (null === (_userAgent_match2 = userAgent.match(/Linux ([0-9.]+)/)) || void 0 === _userAgent_match2 ? void 0 : _userAgent_match2[1]) || 'unknown';
4013
+ }
4014
+ // 检测浏览器及版本
4015
+ if (userAgent.indexOf('Chrome') > -1) {
4016
+ var _userAgent_match3;
4017
+ browserInfo.name = 'chrome';
4018
+ browserInfo.version = (null === (_userAgent_match3 = userAgent.match(/Chrome\/([0-9.]+)/)) || void 0 === _userAgent_match3 ? void 0 : _userAgent_match3[1]) || 'unknown';
4019
+ } else if (userAgent.indexOf('Firefox') > -1) {
4020
+ var _userAgent_match4;
4021
+ browserInfo.name = 'firefox';
4022
+ browserInfo.version = (null === (_userAgent_match4 = userAgent.match(/Firefox\/([0-9.]+)/)) || void 0 === _userAgent_match4 ? void 0 : _userAgent_match4[1]) || 'unknown';
4023
+ } else if (userAgent.indexOf('Safari') > -1) {
4024
+ var _userAgent_match5;
4025
+ browserInfo.name = 'safari';
4026
+ browserInfo.version = (null === (_userAgent_match5 = userAgent.match(/Version\/([0-9.]+)/)) || void 0 === _userAgent_match5 ? void 0 : _userAgent_match5[1]) || 'unknown';
4027
+ }
4028
+ const ua = {
4029
+ version: version_version,
4030
+ browser: browserInfo.name,
4031
+ browser_version: browserInfo.version,
4032
+ os_name: osInfo.name,
4033
+ os_version: osInfo.version
4034
+ };
4035
+ return JSON.stringify(ua);
4036
+ };
3861
4037
  /* eslint-disable @typescript-eslint/no-explicit-any */ const fetcher_handleError = (error)=>{
3862
4038
  if (!error.isAxiosError && (!error.code || !error.message)) return new CozeError(`Unexpected error: ${error.message}`);
3863
4039
  if ('ECONNABORTED' === error.code && error.message.includes('timeout') || 'ETIMEDOUT' === error.code) {
@@ -3957,12 +4133,15 @@
3957
4133
  const headers = {
3958
4134
  authorization: `Bearer ${token}`
3959
4135
  };
3960
- if (!utils_isBrowser()) {
4136
+ if (utils_isBrowser()) headers['X-Coze-Client-User-Agent'] = getBrowserClientUserAgent();
4137
+ else {
3961
4138
  headers['User-Agent'] = getUserAgent();
3962
4139
  headers['X-Coze-Client-User-Agent'] = getNodeClientUserAgent();
3963
4140
  }
3964
4141
  const config = mergeConfig(this.axiosOptions, options, {
3965
4142
  headers
4143
+ }, {
4144
+ headers: this.headers || {}
3966
4145
  });
3967
4146
  config.method = method;
3968
4147
  config.data = body;
@@ -3973,11 +4152,11 @@
3973
4152
  const fetchOptions = await this.buildOptions(method, body, options);
3974
4153
  fetchOptions.isStreaming = isStream;
3975
4154
  fetchOptions.axiosInstance = this.axiosInstance;
3976
- this.debugLog(`--- request url: ${fullUrl}`);
3977
- this.debugLog('--- request options:', fetchOptions);
4155
+ this.debugLog(null == options ? void 0 : options.debug, `--- request url: ${fullUrl}`);
4156
+ this.debugLog(null == options ? void 0 : options.debug, '--- request options:', fetchOptions);
3978
4157
  const { response, stream, json } = await fetchAPI(fullUrl, fetchOptions);
3979
- this.debugLog(`--- response status: ${response.status}`);
3980
- this.debugLog('--- response headers: ', response.headers);
4158
+ this.debugLog(null == options ? void 0 : options.debug, `--- response status: ${response.status}`);
4159
+ this.debugLog(null == options ? void 0 : options.debug, '--- response headers: ', response.headers);
3981
4160
  var _response_headers;
3982
4161
  // Taro use `header`
3983
4162
  const contentType = (null !== (_response_headers = response.headers) && void 0 !== _response_headers ? _response_headers : response.header)['content-type'];
@@ -4020,8 +4199,9 @@
4020
4199
  }
4021
4200
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4022
4201
  debugLog() {
4023
- for(var _len = arguments.length, msgs = new Array(_len), _key = 0; _key < _len; _key++)msgs[_key] = arguments[_key];
4024
- if (this.debug) console.debug(...msgs);
4202
+ let forceDebug = arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
4203
+ for(var _len = arguments.length, msgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++)msgs[_key - 1] = arguments[_key];
4204
+ if (this.debug || forceDebug) console.debug(...msgs);
4025
4205
  }
4026
4206
  constructor(config){
4027
4207
  this._config = config;
@@ -4053,7 +4233,7 @@
4053
4233
  constructor(...args){
4054
4234
  super(...args), this.bots = new Bots(this), this.chat = new Chat(this), this.conversations = new Conversations(this), this.files = new Files(this), /**
4055
4235
  * @deprecated
4056
- */ this.knowledge = new Knowledge(this), this.datasets = new Datasets(this), this.workflows = new Workflows(this), this.workspaces = new WorkSpaces(this), this.audio = new audio_Audio(this);
4236
+ */ this.knowledge = new Knowledge(this), this.datasets = new Datasets(this), this.workflows = new Workflows(this), this.workspaces = new WorkSpaces(this), this.audio = new audio_Audio(this), this.templates = new Templates(this);
4057
4237
  }
4058
4238
  }
4059
4239
  /**
@@ -38458,7 +38638,11 @@
38458
38638
  return false;
38459
38639
  }
38460
38640
  };
38461
- const checkDevicePermission = async function() {
38641
+ /**
38642
+ * Checks device permissions for audio and video
38643
+ * @param checkVideo Whether to check video permissions (default: false)
38644
+ * @returns Promise that resolves with the device permission status
38645
+ */ const checkDevicePermission = async function() {
38462
38646
  let checkVideo = arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
38463
38647
  return await index_esm_min_index.enableDevices({
38464
38648
  audio: true,
@@ -38471,7 +38655,16 @@
38471
38655
  */ const getAudioDevices = async function() {
38472
38656
  let { video = false } = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
38473
38657
  let devices = [];
38474
- devices = video ? await index_esm_min_index.enumerateDevices() : await [
38658
+ if (video) {
38659
+ devices = await index_esm_min_index.enumerateDevices();
38660
+ if (isScreenShareSupported()) // @ts-expect-error - add screenShare device to devices
38661
+ devices.push({
38662
+ deviceId: 'screenShare',
38663
+ kind: 'videoinput',
38664
+ label: 'Screen Share',
38665
+ groupId: 'screenShare'
38666
+ });
38667
+ } else devices = await [
38475
38668
  ...await index_esm_min_index.enumerateAudioCaptureDevices(),
38476
38669
  ...await index_esm_min_index.enumerateAudioPlaybackDevices()
38477
38670
  ];
@@ -38486,6 +38679,14 @@
38486
38679
  videoInputs: devices.filter((i)=>i.deviceId && 'videoinput' === i.kind)
38487
38680
  };
38488
38681
  };
38682
+ const isScreenShareDevice = (deviceId)=>'screenShare' === deviceId;
38683
+ /**
38684
+ * Check if browser supports screen sharing
38685
+ * 检查浏览器是否支持屏幕共享
38686
+ */ function isScreenShareSupported() {
38687
+ var _navigator_mediaDevices, _navigator;
38688
+ return !!(null === (_navigator = navigator) || void 0 === _navigator ? void 0 : null === (_navigator_mediaDevices = _navigator.mediaDevices) || void 0 === _navigator_mediaDevices ? void 0 : _navigator_mediaDevices.getDisplayMedia);
38689
+ }
38489
38690
  var error_RealtimeError = /*#__PURE__*/ function(RealtimeError) {
38490
38691
  RealtimeError["DEVICE_ACCESS_ERROR"] = "DEVICE_ACCESS_ERROR";
38491
38692
  RealtimeError["STREAM_CREATION_ERROR"] = "STREAM_CREATION_ERROR";
@@ -38579,6 +38780,10 @@
38579
38780
  * zh: 音频输出设备改变
38580
38781
  */ EventNames["AUDIO_OUTPUT_DEVICE_CHANGED"] = "client.output.device.changed";
38581
38782
  /**
38783
+ * en: Video input device changed
38784
+ * zh: 视频输入设备改变
38785
+ */ EventNames["VIDEO_INPUT_DEVICE_CHANGED"] = "client.video.input.device.changed";
38786
+ /**
38582
38787
  * en: Bot joined
38583
38788
  * zh: Bot 加入
38584
38789
  */ EventNames["BOT_JOIN"] = "server.bot.join";
@@ -41996,23 +42201,47 @@
41996
42201
  if (-1 === devices.audioOutputs.findIndex((i)=>i.deviceId === deviceId)) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, `Audio output device not found: ${deviceId}`);
41997
42202
  await this.engine.setAudioPlaybackDevice(deviceId);
41998
42203
  }
42204
+ async setVideoInputDevice(deviceId) {
42205
+ let isAutoCapture = !(arguments.length > 1) || void 0 === arguments[1] || arguments[1];
42206
+ var _this__videoConfig;
42207
+ const devices = await getAudioDevices({
42208
+ video: true
42209
+ });
42210
+ if (-1 === devices.videoInputs.findIndex((i)=>i.deviceId === deviceId)) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, `Video input device not found: ${deviceId}`);
42211
+ await this.changeVideoState(false);
42212
+ if (isScreenShareDevice(deviceId)) {
42213
+ if (this._streamIndex === StreamIndex$1.STREAM_INDEX_MAIN) this.engine.setLocalVideoPlayer(StreamIndex$1.STREAM_INDEX_MAIN);
42214
+ if (isAutoCapture) {
42215
+ var _this__videoConfig1;
42216
+ this.engine.setVideoSourceType(StreamIndex$1.STREAM_INDEX_SCREEN, VideoSourceType.VIDEO_SOURCE_TYPE_INTERNAL);
42217
+ await this.engine.startScreenCapture(null === (_this__videoConfig1 = this._videoConfig) || void 0 === _this__videoConfig1 ? void 0 : _this__videoConfig1.screenConfig);
42218
+ await this.engine.publishScreen(MediaType$1.VIDEO);
42219
+ }
42220
+ this._streamIndex = StreamIndex$1.STREAM_INDEX_SCREEN;
42221
+ } else {
42222
+ if (this._streamIndex === StreamIndex$1.STREAM_INDEX_SCREEN) this.engine.setLocalVideoPlayer(StreamIndex$1.STREAM_INDEX_SCREEN);
42223
+ if (isAutoCapture) await this.engine.startVideoCapture(deviceId);
42224
+ this._streamIndex = StreamIndex$1.STREAM_INDEX_MAIN;
42225
+ }
42226
+ this.engine.setLocalVideoPlayer(this._streamIndex, {
42227
+ renderDom: (null === (_this__videoConfig = this._videoConfig) || void 0 === _this__videoConfig ? void 0 : _this__videoConfig.renderDom) || 'local-player',
42228
+ userId: this._roomUserId
42229
+ });
42230
+ }
41999
42231
  async createLocalStream(userId, videoConfig) {
42232
+ this._roomUserId = userId;
42000
42233
  const devices = await getAudioDevices({
42001
42234
  video: this._isSupportVideo
42002
42235
  });
42003
42236
  if (!devices.audioInputs.length) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, 'Failed to get audio devices');
42004
42237
  if (this._isSupportVideo && !devices.videoInputs.length) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, 'Failed to get video devices');
42005
42238
  await this.engine.startAudioCapture(devices.audioInputs[0].deviceId);
42006
- if (this._isSupportVideo && (null == videoConfig ? void 0 : videoConfig.videoOnDefault)) await this.engine.startVideoCapture(devices.videoInputs[0].deviceId);
42007
- if (this._isSupportVideo) this.engine.setLocalVideoPlayer(StreamIndex$1.STREAM_INDEX_MAIN, {
42008
- renderDom: (null == videoConfig ? void 0 : videoConfig.renderDom) || 'local-player',
42009
- userId
42010
- });
42239
+ if (this._isSupportVideo) this.setVideoInputDevice((null == videoConfig ? void 0 : videoConfig.videoInputDeviceId) || devices.videoInputs[0].deviceId, null == videoConfig ? void 0 : videoConfig.videoOnDefault);
42011
42240
  }
42012
42241
  async disconnect() {
42013
42242
  try {
42014
- if (this._isSupportVideo) await this.engine.stopVideoCapture();
42015
- await this.engine.stopAudioCapture();
42243
+ if (this._isSupportVideo) await this.changeVideoState(false);
42244
+ await this.changeAudioState(false);
42016
42245
  await this.engine.unpublishStream(MediaType$1.AUDIO);
42017
42246
  await this.engine.leaveRoom();
42018
42247
  this.removeEventListener();
@@ -42032,8 +42261,19 @@
42032
42261
  }
42033
42262
  async changeVideoState(isVideoOn) {
42034
42263
  try {
42035
- if (isVideoOn) await this.engine.startVideoCapture();
42036
- else await this.engine.stopVideoCapture();
42264
+ if (isVideoOn) {
42265
+ if (this._streamIndex === StreamIndex$1.STREAM_INDEX_MAIN) await this.engine.startVideoCapture();
42266
+ else {
42267
+ var _this__videoConfig;
42268
+ this.engine.setVideoSourceType(StreamIndex$1.STREAM_INDEX_SCREEN, VideoSourceType.VIDEO_SOURCE_TYPE_INTERNAL);
42269
+ await this.engine.startScreenCapture(null === (_this__videoConfig = this._videoConfig) || void 0 === _this__videoConfig ? void 0 : _this__videoConfig.screenConfig);
42270
+ await this.engine.publishScreen(MediaType$1.VIDEO);
42271
+ }
42272
+ } else if (this._streamIndex === StreamIndex$1.STREAM_INDEX_MAIN) await this.engine.stopVideoCapture();
42273
+ else {
42274
+ await this.engine.stopScreenCapture();
42275
+ await this.engine.unpublishScreen(MediaType$1.VIDEO);
42276
+ }
42037
42277
  } catch (e) {
42038
42278
  this.dispatch(event_handler_EventNames.ERROR, e);
42039
42279
  throw e;
@@ -42110,8 +42350,11 @@
42110
42350
  throw e;
42111
42351
  }
42112
42352
  }
42353
+ getRtcEngine() {
42354
+ return this.engine;
42355
+ }
42113
42356
  // eslint-disable-next-line max-params
42114
- constructor(appId, debug = false, isTestEnv = false, isSupportVideo = false){
42357
+ constructor(appId, debug = false, isTestEnv = false, isSupportVideo = false, videoConfig){
42115
42358
  super(debug), this.joinUserId = '', this._AIAnsExtension = null, this._isSupportVideo = false;
42116
42359
  if (isTestEnv) index_esm_min_index.setParameter('ICE_CONFIG_REQUEST_URLS', [
42117
42360
  'rtc-test.bytedance.com'
@@ -42126,6 +42369,7 @@
42126
42369
  this.handleLocalAudioPropertiesReport = this.handleLocalAudioPropertiesReport.bind(this);
42127
42370
  this.handleRemoteAudioPropertiesReport = this.handleRemoteAudioPropertiesReport.bind(this);
42128
42371
  this._isSupportVideo = isSupportVideo;
42372
+ this._videoConfig = videoConfig;
42129
42373
  }
42130
42374
  }
42131
42375
  class RealtimeClient extends RealtimeEventHandler {
@@ -42141,16 +42385,17 @@
42141
42385
  // Step1 get token
42142
42386
  roomInfo = await this._api.audio.rooms.create({
42143
42387
  bot_id: botId,
42144
- conversation_id: conversationId,
42388
+ conversation_id: conversationId || void 0,
42145
42389
  voice_id: voiceId && voiceId.length > 0 ? voiceId : void 0,
42146
- connector_id: this._config.connectorId
42390
+ connector_id: this._config.connectorId,
42391
+ uid: this._config.userId || void 0
42147
42392
  });
42148
42393
  } catch (error) {
42149
42394
  this.dispatch(event_handler_EventNames.ERROR, error);
42150
42395
  throw new RealtimeAPIError(error_RealtimeError.CREATE_ROOM_ERROR, error instanceof Error ? error.message : 'Unknown error', error);
42151
42396
  }
42152
42397
  // Step2 create engine
42153
- this._client = new EngineClient(roomInfo.app_id, this._config.debug, this._isTestEnv, this._isSupportVideo);
42398
+ this._client = new EngineClient(roomInfo.app_id, this._config.debug, this._isTestEnv, this._isSupportVideo, this._config.videoConfig);
42154
42399
  // Step3 bind engine events
42155
42400
  this._client.bindEngineEvents();
42156
42401
  this._client.on(event_handler_EventNames.ALL, (eventName, data)=>{
@@ -42286,6 +42531,21 @@
42286
42531
  deviceId
42287
42532
  });
42288
42533
  }
42534
+ async setVideoInputDevice(deviceId) {
42535
+ var _this__client;
42536
+ await (null === (_this__client = this._client) || void 0 === _this__client ? void 0 : _this__client.setVideoInputDevice(deviceId));
42537
+ this.dispatch(event_handler_EventNames.VIDEO_INPUT_DEVICE_CHANGED, {
42538
+ deviceId
42539
+ });
42540
+ }
42541
+ /**
42542
+ * en: Get the RTC engine instance, for detail visit https://www.volcengine.com/docs/6348/104481
42543
+ *
42544
+ * zh: 获取 RTC 引擎实例,详情请访问 https://www.volcengine.com/docs/6348/104481
42545
+ */ getRtcEngine() {
42546
+ var _this__client;
42547
+ return null === (_this__client = this._client) || void 0 === _this__client ? void 0 : _this__client.getRtcEngine();
42548
+ }
42289
42549
  /**
42290
42550
  * Constructor for initializing a RealtimeClient instance.
42291
42551
  *
@@ -42300,6 +42560,8 @@
42300
42560
  * 可选,音色Id。
42301
42561
  * @param config.conversationId - Optional, Conversation Id. |
42302
42562
  * 可选,会话Id。
42563
+ * @param config.userId - Optional, User Id. |
42564
+ * 可选,用户Id。
42303
42565
  * @param config.baseURL - Optional, defaults to "https://api.coze.cn". |
42304
42566
  * 可选,默认值为 "https://api.coze.cn"。
42305
42567
  * @param config.debug - Optional, defaults to false.
@@ -42316,6 +42578,16 @@
42316
42578
  * @param config.suppressNonStationaryNoise - Optional, suppress non-stationary noise, defaults to false. |
42317
42579
  * 可选,默认是否抑制非静态噪声,默认值为 false。
42318
42580
  * @param config.isAutoSubscribeAudio - Optional, whether to automatically subscribe to bot reply audio streams, defaults to true. |
42581
+ * @param config.videoConfig - Optional, Video configuration. |
42582
+ * 可选,视频配置。
42583
+ * @param config.videoConfig.videoOnDefault - Optional, Whether to turn on video by default, defaults to true. |
42584
+ * 可选,默认是否开启视频,默认值为 true。
42585
+ * @param config.videoConfig.renderDom - Optional, The DOM element to render the video stream to. |
42586
+ * 可选,渲染视频流的 DOM 元素。
42587
+ * @param config.videoConfig.videoInputDeviceId - Optional, The device ID of the video input device to use. |
42588
+ * 可选,视频输入设备的设备 ID。
42589
+ * @param config.videoConfig.screenConfig - Optional, Screen share configuration if videoInputDeviceId is 'screenShare' see https://www.volcengine.com/docs/6348/104481#screenconfig for more details. |
42590
+ * 可选,屏幕共享配置,如果 videoInputDeviceId 是 'screenShare',请参考 https://www.volcengine.com/docs/6348/104481#screenconfig 了解更多详情。
42319
42591
  */ constructor(config){
42320
42592
  super(config.debug), this._client = null, this.isConnected = false, this._isTestEnv = false, this._isSupportVideo = false;
42321
42593
  this._config = config;