@coze/realtime-api 0.0.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/cjs/index.cjs +223 -77
- package/dist/esm/index.js +223 -77
- package/dist/types/client.d.ts +8 -2
- package/dist/types/error.d.ts +10 -2
- package/dist/types/event-handler.d.ts +26 -1
- package/dist/types/index.d.ts +7 -1
- package/dist/types/utils.d.ts +6 -1
- package/dist/umd/index.js +223 -77
- package/package.json +14 -3
package/dist/umd/index.js
CHANGED
@@ -6,8 +6,30 @@
|
|
6
6
|
else root["CozeRealtimeApi"] = factory();
|
7
7
|
})(self, ()=>(()=>{
|
8
8
|
"use strict";
|
9
|
-
|
10
|
-
|
9
|
+
var __webpack_modules__ = {
|
10
|
+
"?d7f0": function() {
|
11
|
+
/* (ignored) */ },
|
12
|
+
"?fcd3": function() {
|
13
|
+
/* (ignored) */ },
|
14
|
+
"?d2d5": function() {
|
15
|
+
/* (ignored) */ }
|
16
|
+
};
|
17
|
+
/************************************************************************/ // The module cache
|
18
|
+
var __webpack_module_cache__ = {};
|
19
|
+
// The require function
|
20
|
+
function __webpack_require__(moduleId) {
|
21
|
+
// Check if module is in cache
|
22
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
23
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
24
|
+
// Create a new module (and put it into the cache)
|
25
|
+
var module1 = __webpack_module_cache__[moduleId] = {
|
26
|
+
exports: {}
|
27
|
+
};
|
28
|
+
// Execute the module function
|
29
|
+
__webpack_modules__[moduleId](module1, module1.exports, __webpack_require__);
|
30
|
+
// Return the exports of the module
|
31
|
+
return module1.exports;
|
32
|
+
}
|
11
33
|
/************************************************************************/ // webpack/runtime/define_property_getters
|
12
34
|
(()=>{
|
13
35
|
__webpack_require__.d = function(exports1, definition) {
|
@@ -1068,14 +1090,14 @@
|
|
1068
1090
|
*/ const hasStandardBrowserWebWorkerEnv = (()=>'undefined' != typeof WorkerGlobalScope && // eslint-disable-next-line no-undef
|
1069
1091
|
self instanceof WorkerGlobalScope && 'function' == typeof self.importScripts)();
|
1070
1092
|
const origin = hasBrowserEnv && window.location.href || 'http://localhost';
|
1071
|
-
/* ESM default export */ const
|
1093
|
+
/* ESM default export */ const lib_platform = {
|
1072
1094
|
...common_utils_namespaceObject,
|
1073
1095
|
...browser
|
1074
1096
|
};
|
1075
1097
|
function toURLEncodedForm(data, options) {
|
1076
|
-
return toFormData(data, new
|
1098
|
+
return toFormData(data, new lib_platform.classes.URLSearchParams(), Object.assign({
|
1077
1099
|
visitor: function(value, key, path, helpers) {
|
1078
|
-
if (
|
1100
|
+
if (lib_platform.isNode && utils.isBuffer(value)) {
|
1079
1101
|
this.append(key, value.toString('base64'));
|
1080
1102
|
return false;
|
1081
1103
|
}
|
@@ -1236,8 +1258,8 @@
|
|
1236
1258
|
maxContentLength: -1,
|
1237
1259
|
maxBodyLength: -1,
|
1238
1260
|
env: {
|
1239
|
-
FormData:
|
1240
|
-
Blob:
|
1261
|
+
FormData: lib_platform.classes.FormData,
|
1262
|
+
Blob: lib_platform.classes.Blob
|
1241
1263
|
},
|
1242
1264
|
validateStatus: function(status) {
|
1243
1265
|
return status >= 200 && status < 300;
|
@@ -1671,10 +1693,10 @@
|
|
1671
1693
|
];
|
1672
1694
|
};
|
1673
1695
|
const asyncDecorator = (fn)=>(...args)=>utils.asap(()=>fn(...args));
|
1674
|
-
/* ESM default export */ const helpers_isURLSameOrigin =
|
1696
|
+
/* ESM default export */ const helpers_isURLSameOrigin = lib_platform.hasStandardBrowserEnv ? // Standard browser envs have full support of the APIs needed to test
|
1675
1697
|
// whether the request URL is of the same origin as current location.
|
1676
1698
|
function() {
|
1677
|
-
const msie =
|
1699
|
+
const msie = lib_platform.navigator && /(msie|trident)/i.test(lib_platform.navigator.userAgent);
|
1678
1700
|
const urlParsingNode = document.createElement('a');
|
1679
1701
|
let originURL;
|
1680
1702
|
/**
|
@@ -1718,7 +1740,7 @@
|
|
1718
1740
|
return true;
|
1719
1741
|
};
|
1720
1742
|
}();
|
1721
|
-
/* ESM default export */ const cookies =
|
1743
|
+
/* ESM default export */ const cookies = lib_platform.hasStandardBrowserEnv ? // Standard browser envs support document.cookie
|
1722
1744
|
{
|
1723
1745
|
write (name, value, expires, path, domain, secure) {
|
1724
1746
|
const cookie = [
|
@@ -1869,7 +1891,7 @@
|
|
1869
1891
|
if (auth) headers.set('Authorization', 'Basic ' + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')));
|
1870
1892
|
let contentType;
|
1871
1893
|
if (utils.isFormData(data)) {
|
1872
|
-
if (
|
1894
|
+
if (lib_platform.hasStandardBrowserEnv || lib_platform.hasStandardBrowserWebWorkerEnv) headers.setContentType(void 0); // Let the browser set it
|
1873
1895
|
else if (false !== (contentType = headers.getContentType())) {
|
1874
1896
|
// fix semicolon duplication issue for ReactNative FormData implementation
|
1875
1897
|
const [type, ...tokens] = contentType ? contentType.split(';').map((token)=>token.trim()).filter(Boolean) : [];
|
@@ -1882,7 +1904,7 @@
|
|
1882
1904
|
// Add xsrf header
|
1883
1905
|
// This is only done if running in a standard browser environment.
|
1884
1906
|
// Specifically not if we're in a web worker, or react-native.
|
1885
|
-
if (
|
1907
|
+
if (lib_platform.hasStandardBrowserEnv) {
|
1886
1908
|
withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));
|
1887
1909
|
if (withXSRFToken || false !== withXSRFToken && helpers_isURLSameOrigin(newConfig.url)) {
|
1888
1910
|
// Add xsrf header
|
@@ -2007,7 +2029,7 @@
|
|
2007
2029
|
if (_config.signal) _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);
|
2008
2030
|
}
|
2009
2031
|
const protocol = parseProtocol(_config.url);
|
2010
|
-
if (protocol && -1 ===
|
2032
|
+
if (protocol && -1 === lib_platform.protocols.indexOf(protocol)) {
|
2011
2033
|
reject(new core_AxiosError('Unsupported protocol ' + protocol + ':', core_AxiosError.ERR_BAD_REQUEST, config));
|
2012
2034
|
return;
|
2013
2035
|
}
|
@@ -2133,7 +2155,7 @@
|
|
2133
2155
|
};
|
2134
2156
|
const supportsRequestStream = isReadableStreamSupported && test(()=>{
|
2135
2157
|
let duplexAccessed = false;
|
2136
|
-
const hasContentType = new Request(
|
2158
|
+
const hasContentType = new Request(lib_platform.origin, {
|
2137
2159
|
body: new ReadableStream(),
|
2138
2160
|
method: 'POST',
|
2139
2161
|
get duplex () {
|
@@ -2165,7 +2187,7 @@
|
|
2165
2187
|
if (null == body) return 0;
|
2166
2188
|
if (utils.isBlob(body)) return body.size;
|
2167
2189
|
if (utils.isSpecCompliantForm(body)) {
|
2168
|
-
const _request = new Request(
|
2190
|
+
const _request = new Request(lib_platform.origin, {
|
2169
2191
|
method: 'POST',
|
2170
2192
|
body
|
2171
2193
|
});
|
@@ -2840,26 +2862,12 @@
|
|
2840
2862
|
// Keep top-level export same with static properties
|
2841
2863
|
// so that it can keep same with es module or cjs
|
2842
2864
|
const { Axios: axios_Axios, AxiosError: axios_AxiosError, CanceledError: axios_CanceledError, isCancel: axios_isCancel, CancelToken: axios_CancelToken, VERSION: axios_VERSION, all: axios_all, Cancel, isAxiosError: axios_isAxiosError, spread: axios_spread, toFormData: axios_toFormData, AxiosHeaders: axios_AxiosHeaders, HttpStatusCode: axios_HttpStatusCode, formToJSON, getAdapter, mergeConfig: axios_mergeConfig } = lib_axios;
|
2843
|
-
|
2844
|
-
|
2845
|
-
|
2846
|
-
|
2847
|
-
|
2848
|
-
|
2849
|
-
// The require function
|
2850
|
-
function __nested_webpack_require_293__(moduleId) {
|
2851
|
-
// Check if module is in cache
|
2852
|
-
var cachedModule = __webpack_module_cache__[moduleId];
|
2853
|
-
if (void 0 !== cachedModule) return cachedModule.exports;
|
2854
|
-
// Create a new module (and put it into the cache)
|
2855
|
-
var module1 = __webpack_module_cache__[moduleId] = {
|
2856
|
-
exports: {}
|
2857
|
-
};
|
2858
|
-
// Execute the module function
|
2859
|
-
__webpack_modules__[moduleId](module1, module1.exports, __nested_webpack_require_293__);
|
2860
|
-
// Return the exports of the module
|
2861
|
-
return module1.exports;
|
2862
|
-
} /************************************************************************/
|
2865
|
+
// EXTERNAL MODULE: os (ignored)
|
2866
|
+
var os_ignored_ = __webpack_require__("?d2d5");
|
2867
|
+
// EXTERNAL MODULE: crypto (ignored)
|
2868
|
+
__webpack_require__("?d7f0");
|
2869
|
+
// EXTERNAL MODULE: jsonwebtoken (ignored)
|
2870
|
+
__webpack_require__("?fcd3");
|
2863
2871
|
class APIResource {
|
2864
2872
|
constructor(client){
|
2865
2873
|
this._client = client;
|
@@ -3622,6 +3630,56 @@
|
|
3622
3630
|
super(...args), this.rooms = new Rooms(this._client), this.voices = new Voices(this._client), this.speech = new Speech(this._client);
|
3623
3631
|
}
|
3624
3632
|
}
|
3633
|
+
var package_namespaceObject = JSON.parse('{"name":"@coze/api","version":"1.0.10","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":{".":{"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","browser":{"crypto":false,"os":false,"jsonwebtoken":false},"types":"dist/types/index.d.ts","files":["dist","LICENSE","README.md","!**/*.tsbuildinfo"],"scripts":{"build":"rm -rf dist && rslib build","format":"prettier --write .","lint":"eslint ./ --cache --quiet","prepublishOnly":"npm run build","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"}}'); // CONCATENATED MODULE: ./src/version.ts
|
3634
|
+
const { version: esm_version } = package_namespaceObject;
|
3635
|
+
const getEnv = ()=>{
|
3636
|
+
const nodeVersion = process.version.slice(1); // Remove 'v' prefix
|
3637
|
+
const { platform } = process;
|
3638
|
+
let osName = platform.toLowerCase();
|
3639
|
+
let osVersion = os_ignored_.release();
|
3640
|
+
if ('darwin' === platform) {
|
3641
|
+
osName = 'macos';
|
3642
|
+
// Try to parse the macOS version
|
3643
|
+
try {
|
3644
|
+
const darwinVersion = os_ignored_.release().split('.');
|
3645
|
+
if (darwinVersion.length >= 2) {
|
3646
|
+
const majorVersion = parseInt(darwinVersion[0], 10);
|
3647
|
+
if (!isNaN(majorVersion) && majorVersion >= 9) {
|
3648
|
+
const macVersion = majorVersion - 9;
|
3649
|
+
osVersion = `10.${macVersion}.${darwinVersion[1]}`;
|
3650
|
+
}
|
3651
|
+
}
|
3652
|
+
} catch (error) {
|
3653
|
+
// Keep the default os.release() value if parsing fails
|
3654
|
+
}
|
3655
|
+
} else if ('win32' === platform) {
|
3656
|
+
osName = 'windows';
|
3657
|
+
osVersion = os_ignored_.release();
|
3658
|
+
} else if ('linux' === platform) {
|
3659
|
+
osName = 'linux';
|
3660
|
+
osVersion = os_ignored_.release();
|
3661
|
+
}
|
3662
|
+
return {
|
3663
|
+
osName,
|
3664
|
+
osVersion,
|
3665
|
+
nodeVersion
|
3666
|
+
};
|
3667
|
+
};
|
3668
|
+
const getUserAgent = ()=>{
|
3669
|
+
const { nodeVersion, osName, osVersion } = getEnv();
|
3670
|
+
return `coze-js/${esm_version} node/${nodeVersion} ${osName}/${osVersion}`.toLowerCase();
|
3671
|
+
};
|
3672
|
+
const getNodeClientUserAgent = ()=>{
|
3673
|
+
const { osVersion, nodeVersion, osName } = getEnv();
|
3674
|
+
const ua = {
|
3675
|
+
version: esm_version,
|
3676
|
+
lang: 'node',
|
3677
|
+
lang_version: nodeVersion,
|
3678
|
+
os_name: osName,
|
3679
|
+
os_version: osVersion
|
3680
|
+
};
|
3681
|
+
return JSON.stringify(ua);
|
3682
|
+
};
|
3625
3683
|
/* eslint-disable @typescript-eslint/no-explicit-any */ const esm_handleError = (error)=>{
|
3626
3684
|
if (!error.isAxiosError && (!error.code || !error.message)) return new CozeError(`Unexpected error: ${error.message}`);
|
3627
3685
|
if ('ECONNABORTED' === error.code && error.message.includes('timeout') || 'ETIMEDOUT' === error.code) {
|
@@ -3694,10 +3752,10 @@
|
|
3694
3752
|
const headers = {
|
3695
3753
|
authorization: `Bearer ${this.token}`
|
3696
3754
|
};
|
3697
|
-
|
3698
|
-
|
3699
|
-
|
3700
|
-
|
3755
|
+
if (!isBrowser()) {
|
3756
|
+
headers['User-Agent'] = getUserAgent();
|
3757
|
+
headers['X-Coze-Client-User-Agent'] = getNodeClientUserAgent();
|
3758
|
+
}
|
3701
3759
|
const config = esm_mergeConfig(this.axiosOptions, options, {
|
3702
3760
|
headers
|
3703
3761
|
});
|
@@ -3778,8 +3836,6 @@
|
|
3778
3836
|
APIClient.GatewayError = GatewayError;
|
3779
3837
|
APIClient.TimeoutError = TimeoutError;
|
3780
3838
|
APIClient.UserAbortError = APIUserAbortError;
|
3781
|
-
// EXTERNAL MODULE: crypto (ignored)
|
3782
|
-
__nested_webpack_require_293__("?6728");
|
3783
3839
|
class CozeAPI extends APIClient {
|
3784
3840
|
constructor(...args){
|
3785
3841
|
super(...args), this.bots = new Bots(this), this.chat = new Chat(this), this.conversations = new Conversations(this), this.files = new Files(this), this.knowledge = new Knowledge(this), this.workflows = new Workflows(this), this.workspaces = new WorkSpaces(this), this.audio = new esm_Audio(this);
|
@@ -38173,10 +38229,19 @@
|
|
38173
38229
|
};
|
38174
38230
|
/**
|
38175
38231
|
* Check microphone permission,return boolean
|
38176
|
-
*/ const checkPermission = async ()
|
38177
|
-
|
38178
|
-
|
38179
|
-
|
38232
|
+
*/ const checkPermission = async function() {
|
38233
|
+
let { audio = true, video = false } = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
|
38234
|
+
try {
|
38235
|
+
const result = await index_esm_min_index.enableDevices({
|
38236
|
+
audio,
|
38237
|
+
video
|
38238
|
+
});
|
38239
|
+
return result.audio;
|
38240
|
+
} catch (error) {
|
38241
|
+
console.error('Failed to check device permissions:', error);
|
38242
|
+
return false;
|
38243
|
+
}
|
38244
|
+
};
|
38180
38245
|
/**
|
38181
38246
|
* Get audio devices
|
38182
38247
|
* @returns Promise<AudioDevices> Object containing arrays of audio input and output devices
|
@@ -38184,11 +38249,15 @@
|
|
38184
38249
|
const devices = await index_esm_min_index.enumerateDevices();
|
38185
38250
|
if (!(null == devices ? void 0 : devices.length)) return {
|
38186
38251
|
audioInputs: [],
|
38187
|
-
audioOutputs: []
|
38252
|
+
audioOutputs: [],
|
38253
|
+
videoInputs: [],
|
38254
|
+
videoOutputs: []
|
38188
38255
|
};
|
38189
38256
|
return {
|
38190
38257
|
audioInputs: devices.filter((i)=>i.deviceId && 'audioinput' === i.kind),
|
38191
|
-
audioOutputs: devices.filter((i)=>i.deviceId && 'audiooutput' === i.kind)
|
38258
|
+
audioOutputs: devices.filter((i)=>i.deviceId && 'audiooutput' === i.kind),
|
38259
|
+
videoInputs: devices.filter((i)=>i.deviceId && 'videoinput' === i.kind),
|
38260
|
+
videoOutputs: devices.filter((i)=>i.deviceId && 'videooutput' === i.kind)
|
38192
38261
|
};
|
38193
38262
|
};
|
38194
38263
|
var error_RealtimeError = /*#__PURE__*/ function(RealtimeError) {
|
@@ -38202,12 +38271,20 @@
|
|
38202
38271
|
RealtimeError["NETWORK_ERROR"] = "NETWORK_ERROR";
|
38203
38272
|
RealtimeError["INVALID_STATE"] = "INVALID_STATE";
|
38204
38273
|
RealtimeError["CREATE_ROOM_ERROR"] = "CREATE_ROOM_ERROR";
|
38274
|
+
RealtimeError["PARSE_MESSAGE_ERROR"] = "PARSE_MESSAGE_ERROR";
|
38275
|
+
RealtimeError["HANDLER_MESSAGE_ERROR"] = "HANDLER_MESSAGE_ERROR";
|
38205
38276
|
return RealtimeError;
|
38206
38277
|
}({});
|
38207
38278
|
class RealtimeAPIError extends Error {
|
38208
|
-
|
38209
|
-
|
38279
|
+
/**
|
38280
|
+
* @param code - Error code
|
38281
|
+
* @param message - Error message
|
38282
|
+
* @param error - Error object
|
38283
|
+
*/ constructor(code, message, error){
|
38284
|
+
super(`[${code}] ${message}`);
|
38210
38285
|
this.name = 'RealtimeAPIError';
|
38286
|
+
this.code = code;
|
38287
|
+
this.error = error;
|
38211
38288
|
}
|
38212
38289
|
}
|
38213
38290
|
var event_handler_EventNames = /*#__PURE__*/ function(EventNames) {
|
@@ -38244,6 +38321,18 @@
|
|
38244
38321
|
* zh: 客户端音频静音
|
38245
38322
|
*/ EventNames["AUDIO_MUTED"] = "client.audio.muted";
|
38246
38323
|
/**
|
38324
|
+
* en: Client video on
|
38325
|
+
* zh: 客户端视频开启
|
38326
|
+
*/ EventNames["VIDEO_ON"] = "client.video.on";
|
38327
|
+
/**
|
38328
|
+
* en: Client video off
|
38329
|
+
* zh: 客户端视频关闭
|
38330
|
+
*/ EventNames["VIDEO_OFF"] = "client.video.off";
|
38331
|
+
/**
|
38332
|
+
* en: Client video event
|
38333
|
+
* zh: 客户端视频事件
|
38334
|
+
*/ EventNames["PLAYER_EVENT"] = "client.video.event";
|
38335
|
+
/**
|
38247
38336
|
* en: Client error
|
38248
38337
|
* zh: 客户端错误
|
38249
38338
|
*/ EventNames["ERROR"] = "client.error";
|
@@ -38263,6 +38352,14 @@
|
|
38263
38352
|
* en: Audio output device changed
|
38264
38353
|
* zh: 音频输出设备改变
|
38265
38354
|
*/ EventNames["AUDIO_OUTPUT_DEVICE_CHANGED"] = "client.output.device.changed";
|
38355
|
+
/**
|
38356
|
+
* en: Bot joined
|
38357
|
+
* zh: Bot 加入
|
38358
|
+
*/ EventNames["BOT_JOIN"] = "server.bot.join";
|
38359
|
+
/**
|
38360
|
+
* en: Bot left
|
38361
|
+
* zh: Bot 离开
|
38362
|
+
*/ EventNames["BOT_LEAVE"] = "server.bot.leave";
|
38266
38363
|
return EventNames;
|
38267
38364
|
}({});
|
38268
38365
|
class RealtimeEventHandler {
|
@@ -38286,7 +38383,11 @@
|
|
38286
38383
|
}
|
38287
38384
|
// eslint-disable-next-line max-params
|
38288
38385
|
_dispatchToHandlers(eventName, event, handlers, prefix) {
|
38289
|
-
for (const handler of handlers)if (!prefix || eventName.startsWith(prefix))
|
38386
|
+
for (const handler of handlers)if (!prefix || eventName.startsWith(prefix)) try {
|
38387
|
+
handler(eventName, event);
|
38388
|
+
} catch (e) {
|
38389
|
+
throw new RealtimeAPIError(error_RealtimeError.HANDLER_MESSAGE_ERROR, `Failed to handle message: ${eventName}`);
|
38390
|
+
}
|
38290
38391
|
}
|
38291
38392
|
dispatch(eventName, event) {
|
38292
38393
|
this._log(`dispatch ${eventName} event`);
|
@@ -41558,6 +41659,7 @@
|
|
41558
41659
|
this.engine.on(index_esm_min_index.events.onUserJoined, this.handleUserJoin);
|
41559
41660
|
this.engine.on(index_esm_min_index.events.onUserLeave, this.handleUserLeave);
|
41560
41661
|
this.engine.on(index_esm_min_index.events.onError, this.handleEventError);
|
41662
|
+
this.engine.on(index_esm_min_index.events.onPlayerEvent, this.handlePlayerEvent);
|
41561
41663
|
if (this._debug) {
|
41562
41664
|
this.engine.on(index_esm_min_index.events.onLocalAudioPropertiesReport, this.handleLocalAudioPropertiesReport);
|
41563
41665
|
this.engine.on(index_esm_min_index.events.onRemoteAudioPropertiesReport, this.handleRemoteAudioPropertiesReport);
|
@@ -41568,45 +41670,62 @@
|
|
41568
41670
|
this.engine.off(index_esm_min_index.events.onUserJoined, this.handleUserJoin);
|
41569
41671
|
this.engine.off(index_esm_min_index.events.onUserLeave, this.handleUserLeave);
|
41570
41672
|
this.engine.off(index_esm_min_index.events.onError, this.handleEventError);
|
41673
|
+
this.engine.off(index_esm_min_index.events.onPlayerEvent, this.handlePlayerEvent);
|
41571
41674
|
if (this._debug) {
|
41572
41675
|
this.engine.off(index_esm_min_index.events.onLocalAudioPropertiesReport, this.handleLocalAudioPropertiesReport);
|
41573
41676
|
this.engine.off(index_esm_min_index.events.onRemoteAudioPropertiesReport, this.handleRemoteAudioPropertiesReport);
|
41574
41677
|
}
|
41575
41678
|
}
|
41679
|
+
_parseMessage(event) {
|
41680
|
+
try {
|
41681
|
+
return JSON.parse(event.message);
|
41682
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
41683
|
+
} catch (e) {
|
41684
|
+
throw new RealtimeAPIError(error_RealtimeError.PARSE_MESSAGE_ERROR, (null == e ? void 0 : e.message) || 'Unknown error');
|
41685
|
+
}
|
41686
|
+
}
|
41576
41687
|
handleMessage(event) {
|
41577
41688
|
try {
|
41578
|
-
const message =
|
41689
|
+
const message = this._parseMessage(event);
|
41579
41690
|
this.dispatch(`server.${message.event_type}`, message);
|
41580
41691
|
} catch (e) {
|
41581
|
-
|
41582
|
-
|
41583
|
-
|
41584
|
-
|
41692
|
+
if (e instanceof RealtimeAPIError) {
|
41693
|
+
if (e.code === error_RealtimeError.PARSE_MESSAGE_ERROR) this.dispatch(event_handler_EventNames.ERROR, {
|
41694
|
+
message: `Failed to parse message: ${event.message}`,
|
41695
|
+
error: e
|
41696
|
+
});
|
41697
|
+
else if (e.code === error_RealtimeError.HANDLER_MESSAGE_ERROR) this.dispatch(event_handler_EventNames.ERROR, {
|
41698
|
+
message: `Failed to handle message: ${event.message}`,
|
41699
|
+
error: e
|
41700
|
+
});
|
41701
|
+
} else this.dispatch(event_handler_EventNames.ERROR, e);
|
41585
41702
|
}
|
41586
41703
|
}
|
41587
41704
|
handleEventError(e) {
|
41588
|
-
this.dispatch(
|
41705
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41589
41706
|
}
|
41590
41707
|
handleUserJoin(event) {
|
41591
41708
|
this.joinUserId = event.userInfo.userId;
|
41592
|
-
this.dispatch(
|
41709
|
+
this.dispatch(event_handler_EventNames.BOT_JOIN, event);
|
41593
41710
|
}
|
41594
41711
|
handleUserLeave(event) {
|
41595
|
-
this.dispatch(
|
41712
|
+
this.dispatch(event_handler_EventNames.BOT_LEAVE, event);
|
41713
|
+
}
|
41714
|
+
handlePlayerEvent(event) {
|
41715
|
+
this.dispatch(event_handler_EventNames.PLAYER_EVENT, event);
|
41596
41716
|
}
|
41597
41717
|
async joinRoom(options) {
|
41598
|
-
const { token, roomId, uid, audioMutedDefault
|
41718
|
+
const { token, roomId, uid, audioMutedDefault, videoOnDefault } = options;
|
41599
41719
|
try {
|
41600
41720
|
await this.engine.joinRoom(token, roomId, {
|
41601
41721
|
userId: uid
|
41602
41722
|
}, {
|
41603
41723
|
isAutoPublish: !audioMutedDefault,
|
41604
41724
|
isAutoSubscribeAudio: true,
|
41605
|
-
isAutoSubscribeVideo:
|
41725
|
+
isAutoSubscribeVideo: this._isSupportVideo && videoOnDefault
|
41606
41726
|
});
|
41607
41727
|
} catch (e) {
|
41608
41728
|
if (e instanceof Error) throw new RealtimeAPIError(error_RealtimeError.CONNECTION_ERROR, e.message);
|
41609
|
-
throw new RealtimeAPIError(error_RealtimeError.CONNECTION_ERROR, 'Unknown error');
|
41610
41729
|
}
|
41611
41730
|
}
|
41612
41731
|
async setAudioInputDevice(deviceId) {
|
@@ -41620,19 +41739,26 @@
|
|
41620
41739
|
if (-1 === devices.audioOutputs.findIndex((i)=>i.deviceId === deviceId)) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, `Audio output device not found: ${deviceId}`);
|
41621
41740
|
await this.engine.setAudioPlaybackDevice(deviceId);
|
41622
41741
|
}
|
41623
|
-
async createLocalStream() {
|
41742
|
+
async createLocalStream(userId, videoConfig) {
|
41624
41743
|
const devices = await getAudioDevices();
|
41625
41744
|
if (!devices.audioInputs.length) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, 'Failed to get devices');
|
41745
|
+
if (this._isSupportVideo && !devices.videoInputs.length) throw new RealtimeAPIError(error_RealtimeError.DEVICE_ACCESS_ERROR, 'Failed to get devices');
|
41626
41746
|
await this.engine.startAudioCapture(devices.audioInputs[0].deviceId);
|
41747
|
+
if (this._isSupportVideo && (null == videoConfig ? void 0 : videoConfig.videoOnDefault)) await this.engine.startVideoCapture(devices.videoInputs[0].deviceId);
|
41748
|
+
if (this._isSupportVideo) this.engine.setLocalVideoPlayer(StreamIndex$1.STREAM_INDEX_MAIN, {
|
41749
|
+
renderDom: (null == videoConfig ? void 0 : videoConfig.renderDom) || 'local-player',
|
41750
|
+
userId
|
41751
|
+
});
|
41627
41752
|
}
|
41628
41753
|
async disconnect() {
|
41629
41754
|
try {
|
41755
|
+
if (this._isSupportVideo) await this.engine.stopVideoCapture();
|
41630
41756
|
await this.engine.stopAudioCapture();
|
41631
41757
|
await this.engine.unpublishStream(MediaType$1.AUDIO);
|
41632
41758
|
await this.engine.leaveRoom();
|
41633
41759
|
this.removeEventListener();
|
41634
41760
|
} catch (e) {
|
41635
|
-
this.dispatch(
|
41761
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41636
41762
|
throw e;
|
41637
41763
|
}
|
41638
41764
|
}
|
@@ -41641,7 +41767,16 @@
|
|
41641
41767
|
if (isMicOn) await this.engine.publishStream(MediaType$1.AUDIO);
|
41642
41768
|
else await this.engine.unpublishStream(MediaType$1.AUDIO);
|
41643
41769
|
} catch (e) {
|
41644
|
-
this.dispatch(
|
41770
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41771
|
+
throw e;
|
41772
|
+
}
|
41773
|
+
}
|
41774
|
+
async changeVideoState(isVideoOn) {
|
41775
|
+
try {
|
41776
|
+
if (isVideoOn) await this.engine.startVideoCapture();
|
41777
|
+
else await this.engine.stopVideoCapture();
|
41778
|
+
} catch (e) {
|
41779
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41645
41780
|
throw e;
|
41646
41781
|
}
|
41647
41782
|
}
|
@@ -41654,7 +41789,7 @@
|
|
41654
41789
|
}));
|
41655
41790
|
this._log(`interrupt ${this.joinUserId} ${result}`);
|
41656
41791
|
} catch (e) {
|
41657
|
-
this.dispatch(
|
41792
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41658
41793
|
throw e;
|
41659
41794
|
}
|
41660
41795
|
}
|
@@ -41663,7 +41798,7 @@
|
|
41663
41798
|
const result = await this.engine.sendUserMessage(this.joinUserId, JSON.stringify(message));
|
41664
41799
|
this._log(`sendMessage ${this.joinUserId} ${JSON.stringify(message)} ${result}`);
|
41665
41800
|
} catch (e) {
|
41666
|
-
this.dispatch(
|
41801
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41667
41802
|
throw e;
|
41668
41803
|
}
|
41669
41804
|
}
|
@@ -41704,7 +41839,7 @@
|
|
41704
41839
|
try {
|
41705
41840
|
await this.engine.startAudioPlaybackDeviceTest('audio-test.wav', 200);
|
41706
41841
|
} catch (e) {
|
41707
|
-
this.dispatch(
|
41842
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41708
41843
|
throw e;
|
41709
41844
|
}
|
41710
41845
|
}
|
@@ -41712,12 +41847,13 @@
|
|
41712
41847
|
try {
|
41713
41848
|
this.engine.stopAudioPlaybackDeviceTest();
|
41714
41849
|
} catch (e) {
|
41715
|
-
this.dispatch(
|
41850
|
+
this.dispatch(event_handler_EventNames.ERROR, e);
|
41716
41851
|
throw e;
|
41717
41852
|
}
|
41718
41853
|
}
|
41719
|
-
|
41720
|
-
|
41854
|
+
// eslint-disable-next-line max-params
|
41855
|
+
constructor(appId, debug = false, isTestEnv = false, isSupportVideo = false){
|
41856
|
+
super(debug), this.joinUserId = '', this._AIAnsExtension = null, this._isSupportVideo = false;
|
41721
41857
|
if (isTestEnv) index_esm_min_index.setParameter('ICE_CONFIG_REQUEST_URLS', [
|
41722
41858
|
'rtc-test.bytedance.com'
|
41723
41859
|
]);
|
@@ -41726,9 +41862,11 @@
|
|
41726
41862
|
this.handleUserJoin = this.handleUserJoin.bind(this);
|
41727
41863
|
this.handleUserLeave = this.handleUserLeave.bind(this);
|
41728
41864
|
this.handleEventError = this.handleEventError.bind(this);
|
41865
|
+
this.handlePlayerEvent = this.handlePlayerEvent.bind(this);
|
41729
41866
|
// Debug only
|
41730
41867
|
this.handleLocalAudioPropertiesReport = this.handleLocalAudioPropertiesReport.bind(this);
|
41731
41868
|
this.handleRemoteAudioPropertiesReport = this.handleRemoteAudioPropertiesReport.bind(this);
|
41869
|
+
this._isSupportVideo = isSupportVideo;
|
41732
41870
|
}
|
41733
41871
|
}
|
41734
41872
|
class RealtimeClient extends RealtimeEventHandler {
|
@@ -41737,6 +41875,7 @@
|
|
41737
41875
|
*
|
41738
41876
|
* zh: 建立与 Coze API 的连接并加入房间
|
41739
41877
|
*/ async connect() {
|
41878
|
+
var _this__config_videoConfig;
|
41740
41879
|
const { botId, conversationId, voiceId } = this._config;
|
41741
41880
|
let roomInfo;
|
41742
41881
|
try {
|
@@ -41749,11 +41888,10 @@
|
|
41749
41888
|
});
|
41750
41889
|
} catch (error) {
|
41751
41890
|
this.dispatch(event_handler_EventNames.ERROR, error);
|
41752
|
-
throw new RealtimeAPIError(error_RealtimeError.CREATE_ROOM_ERROR, error instanceof Error ? error.message : 'Unknown error');
|
41891
|
+
throw new RealtimeAPIError(error_RealtimeError.CREATE_ROOM_ERROR, error instanceof Error ? error.message : 'Unknown error', error);
|
41753
41892
|
}
|
41754
|
-
this._roomInfo = roomInfo;
|
41755
41893
|
// Step2 create engine
|
41756
|
-
this._client = new EngineClient(roomInfo.app_id, this._config.debug, this._isTestEnv);
|
41894
|
+
this._client = new EngineClient(roomInfo.app_id, this._config.debug, this._isTestEnv, this._isSupportVideo);
|
41757
41895
|
// Step3 bind engine events
|
41758
41896
|
this._client.bindEngineEvents();
|
41759
41897
|
this._client.on(event_handler_EventNames.ALL, (eventName, data)=>{
|
@@ -41768,16 +41906,17 @@
|
|
41768
41906
|
this._client.changeAIAnsExtension(true);
|
41769
41907
|
this.dispatch(event_handler_EventNames.SUPPRESS_NON_STATIONARY_NOISE, {});
|
41770
41908
|
}
|
41771
|
-
var _this__config_audioMutedDefault;
|
41909
|
+
var _this__config_audioMutedDefault, _this__config_videoConfig_videoOnDefault;
|
41772
41910
|
// Step4 join room
|
41773
41911
|
await this._client.joinRoom({
|
41774
41912
|
token: roomInfo.token,
|
41775
41913
|
roomId: roomInfo.room_id,
|
41776
41914
|
uid: roomInfo.uid,
|
41777
|
-
audioMutedDefault: null !== (_this__config_audioMutedDefault = this._config.audioMutedDefault) && void 0 !== _this__config_audioMutedDefault && _this__config_audioMutedDefault
|
41915
|
+
audioMutedDefault: null !== (_this__config_audioMutedDefault = this._config.audioMutedDefault) && void 0 !== _this__config_audioMutedDefault && _this__config_audioMutedDefault,
|
41916
|
+
videoOnDefault: null === (_this__config_videoConfig_videoOnDefault = null === (_this__config_videoConfig = this._config.videoConfig) || void 0 === _this__config_videoConfig ? void 0 : _this__config_videoConfig.videoOnDefault) || void 0 === _this__config_videoConfig_videoOnDefault || _this__config_videoConfig_videoOnDefault
|
41778
41917
|
});
|
41779
41918
|
// Step5 create local stream
|
41780
|
-
await this._client.createLocalStream();
|
41919
|
+
await this._client.createLocalStream(roomInfo.uid, this._config.videoConfig);
|
41781
41920
|
// step6 set connected and dispatch connected event
|
41782
41921
|
this.isConnected = true;
|
41783
41922
|
this.dispatch(event_handler_EventNames.CONNECTED, {
|
@@ -41828,6 +41967,12 @@
|
|
41828
41967
|
if (isEnable) this.dispatch(event_handler_EventNames.AUDIO_UNMUTED, {});
|
41829
41968
|
else this.dispatch(event_handler_EventNames.AUDIO_MUTED, {});
|
41830
41969
|
}
|
41970
|
+
async setVideoEnable(isEnable) {
|
41971
|
+
var _this__client;
|
41972
|
+
await (null === (_this__client = this._client) || void 0 === _this__client ? void 0 : _this__client.changeVideoState(isEnable));
|
41973
|
+
if (isEnable) this.dispatch(event_handler_EventNames.VIDEO_ON, {});
|
41974
|
+
else this.dispatch(event_handler_EventNames.VIDEO_OFF, {});
|
41975
|
+
}
|
41831
41976
|
/**
|
41832
41977
|
* en: Enable audio properties reporting (debug mode only)
|
41833
41978
|
*
|
@@ -41913,7 +42058,7 @@
|
|
41913
42058
|
* @param config.suppressNonStationaryNoise - Optional, suppress non-stationary noise, defaults to false. |
|
41914
42059
|
* 可选,默认是否抑制非静态噪声,默认值为 false。
|
41915
42060
|
*/ constructor(config){
|
41916
|
-
super(config.debug), this._client = null, this.
|
42061
|
+
super(config.debug), this._client = null, this.isConnected = false, this._isTestEnv = false, this._isSupportVideo = false;
|
41917
42062
|
this._config = config;
|
41918
42063
|
var _this__config_baseURL;
|
41919
42064
|
const defaultBaseURL = null !== (_this__config_baseURL = this._config.baseURL) && void 0 !== _this__config_baseURL ? _this__config_baseURL : 'https://api.coze.cn';
|
@@ -41925,6 +42070,7 @@
|
|
41925
42070
|
allowPersonalAccessTokenInBrowser: this._config.allowPersonalAccessTokenInBrowser
|
41926
42071
|
});
|
41927
42072
|
this._isTestEnv = 'https://api.coze.cn' !== defaultBaseURL;
|
42073
|
+
this._isSupportVideo = !!config.videoConfig;
|
41928
42074
|
}
|
41929
42075
|
}
|
41930
42076
|
return __webpack_exports__;
|
package/package.json
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
{
|
2
2
|
"name": "@coze/realtime-api",
|
3
|
-
"version": "0.0
|
4
|
-
"description": "Coze
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "A powerful real-time communication SDK for voice interactions with Coze AI bots | 扣子官方实时通信 SDK,用于与 Coze AI bots 进行语音交互",
|
5
|
+
"keywords": [
|
6
|
+
"coze",
|
7
|
+
"ai",
|
8
|
+
"realtime",
|
9
|
+
"voice",
|
10
|
+
"rtc",
|
11
|
+
"asr",
|
12
|
+
"tts",
|
13
|
+
"ai-agent",
|
14
|
+
"voice-synthesis"
|
15
|
+
],
|
5
16
|
"homepage": "https://github.com/coze-dev/coze-js/packages/realtime-api",
|
6
17
|
"repository": {
|
7
18
|
"type": "git",
|
@@ -40,7 +51,7 @@
|
|
40
51
|
"test:cov": "vitest --coverage --run"
|
41
52
|
},
|
42
53
|
"dependencies": {
|
43
|
-
"@coze/api": "1.0.
|
54
|
+
"@coze/api": "1.0.10",
|
44
55
|
"@volcengine/rtc": "^4.62.1"
|
45
56
|
},
|
46
57
|
"devDependencies": {
|