@layercode/js-sdk 2.1.6 → 2.2.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 +1 -1
- package/dist/layercode-js-sdk.esm.js +33 -60
- package/dist/layercode-js-sdk.esm.js.map +1 -1
- package/dist/layercode-js-sdk.min.js +33 -60
- package/dist/layercode-js-sdk.min.js.map +1 -1
- package/dist/types/index.d.ts +16 -0
- package/dist/types/interfaces.d.ts +6 -2
- package/package.json +2 -2
|
@@ -1309,54 +1309,14 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
1309
1309
|
* @returns {Promise<true>}
|
|
1310
1310
|
*/
|
|
1311
1311
|
async requestPermission() {
|
|
1312
|
-
const ensureUserMediaAccess = async () => {
|
|
1313
|
-
const stream = await navigator.mediaDevices.getUserMedia({
|
|
1314
|
-
audio: true,
|
|
1315
|
-
});
|
|
1316
|
-
const tracks = stream.getTracks();
|
|
1317
|
-
tracks.forEach((track) => track.stop());
|
|
1318
|
-
};
|
|
1319
|
-
|
|
1320
|
-
const permissionsUnsupported =
|
|
1321
|
-
!navigator.permissions ||
|
|
1322
|
-
typeof navigator.permissions.query !== 'function';
|
|
1323
|
-
|
|
1324
|
-
if (permissionsUnsupported) {
|
|
1325
|
-
try {
|
|
1326
|
-
await ensureUserMediaAccess();
|
|
1327
|
-
} catch (error) {
|
|
1328
|
-
window.alert('You must grant microphone access to use this feature.');
|
|
1329
|
-
throw error;
|
|
1330
|
-
}
|
|
1331
|
-
return true;
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
1312
|
try {
|
|
1335
|
-
|
|
1336
|
-
|
|
1313
|
+
console.log('ensureUserMediaAccess');
|
|
1314
|
+
await navigator.mediaDevices.getUserMedia({
|
|
1315
|
+
audio: true,
|
|
1337
1316
|
});
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
return true;
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
if (permissionStatus.state === 'prompt') {
|
|
1345
|
-
try {
|
|
1346
|
-
await ensureUserMediaAccess();
|
|
1347
|
-
} catch (error) {
|
|
1348
|
-
window.alert('You must grant microphone access to use this feature.');
|
|
1349
|
-
throw error;
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
} catch (error) {
|
|
1353
|
-
// Firefox rejects permissions.query with NotSupportedError – fall back to getUserMedia directly
|
|
1354
|
-
try {
|
|
1355
|
-
await ensureUserMediaAccess();
|
|
1356
|
-
} catch (fallbackError) {
|
|
1357
|
-
window.alert('You must grant microphone access to use this feature.');
|
|
1358
|
-
throw fallbackError;
|
|
1359
|
-
}
|
|
1317
|
+
} catch (fallbackError) {
|
|
1318
|
+
window.alert('You must grant microphone access to use this feature.');
|
|
1319
|
+
throw fallbackError;
|
|
1360
1320
|
}
|
|
1361
1321
|
return true;
|
|
1362
1322
|
}
|
|
@@ -1373,10 +1333,9 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
1373
1333
|
throw new Error('Could not request user devices');
|
|
1374
1334
|
}
|
|
1375
1335
|
await this.requestPermission();
|
|
1336
|
+
|
|
1376
1337
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
1377
|
-
const audioDevices = devices.filter(
|
|
1378
|
-
(device) => device.kind === 'audioinput',
|
|
1379
|
-
);
|
|
1338
|
+
const audioDevices = devices.filter((device) => device.kind === 'audioinput');
|
|
1380
1339
|
const defaultDeviceIndex = audioDevices.findIndex(
|
|
1381
1340
|
(device) => device.deviceId === 'default',
|
|
1382
1341
|
);
|
|
@@ -3661,7 +3620,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3661
3620
|
const NOOP = () => { };
|
|
3662
3621
|
const DEFAULT_WS_URL = 'wss://api.layercode.com/v1/agents/web/websocket';
|
|
3663
3622
|
// SDK version - updated when publishing
|
|
3664
|
-
const SDK_VERSION = '2.
|
|
3623
|
+
const SDK_VERSION = '2.2.0';
|
|
3665
3624
|
/**
|
|
3666
3625
|
* @class LayercodeClient
|
|
3667
3626
|
* @classdesc Core client for Layercode audio agent that manages audio recording, WebSocket communication, and speech processing.
|
|
@@ -3672,7 +3631,7 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3672
3631
|
* @param {Object} options - Configuration options
|
|
3673
3632
|
*/
|
|
3674
3633
|
constructor(options) {
|
|
3675
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
3634
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
3676
3635
|
this.deviceId = null;
|
|
3677
3636
|
this.options = {
|
|
3678
3637
|
agentId: options.agentId,
|
|
@@ -3684,13 +3643,14 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3684
3643
|
onDisconnect: (_e = options.onDisconnect) !== null && _e !== void 0 ? _e : NOOP,
|
|
3685
3644
|
onError: (_f = options.onError) !== null && _f !== void 0 ? _f : NOOP,
|
|
3686
3645
|
onDeviceSwitched: (_g = options.onDeviceSwitched) !== null && _g !== void 0 ? _g : NOOP,
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3646
|
+
onDevicesChanged: (_h = options.onDevicesChanged) !== null && _h !== void 0 ? _h : NOOP,
|
|
3647
|
+
onDataMessage: (_j = options.onDataMessage) !== null && _j !== void 0 ? _j : NOOP,
|
|
3648
|
+
onMessage: (_k = options.onMessage) !== null && _k !== void 0 ? _k : NOOP,
|
|
3649
|
+
onUserAmplitudeChange: (_l = options.onUserAmplitudeChange) !== null && _l !== void 0 ? _l : NOOP,
|
|
3650
|
+
onAgentAmplitudeChange: (_m = options.onAgentAmplitudeChange) !== null && _m !== void 0 ? _m : NOOP,
|
|
3651
|
+
onStatusChange: (_o = options.onStatusChange) !== null && _o !== void 0 ? _o : NOOP,
|
|
3652
|
+
onUserIsSpeakingChange: (_p = options.onUserIsSpeakingChange) !== null && _p !== void 0 ? _p : NOOP,
|
|
3653
|
+
onMuteStateChange: (_q = options.onMuteStateChange) !== null && _q !== void 0 ? _q : NOOP,
|
|
3694
3654
|
};
|
|
3695
3655
|
this.AMPLITUDE_MONITORING_SAMPLE_RATE = 2;
|
|
3696
3656
|
this._websocketUrl = DEFAULT_WS_URL;
|
|
@@ -3848,6 +3808,10 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
3848
3808
|
this._wsSend({ type: 'trigger.turn.end', role: 'user' });
|
|
3849
3809
|
}
|
|
3850
3810
|
}
|
|
3811
|
+
async sendClientResponseText(text) {
|
|
3812
|
+
await this._clientInterruptAssistantReplay();
|
|
3813
|
+
this._wsSend({ type: 'client.response.text', content: text });
|
|
3814
|
+
}
|
|
3851
3815
|
/**
|
|
3852
3816
|
* Handles incoming WebSocket messages
|
|
3853
3817
|
* @param {MessageEvent} event - The WebSocket message event
|
|
@@ -4032,7 +3996,6 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4032
3996
|
// Reset turn tracking for clean start
|
|
4033
3997
|
this._resetTurnTracking();
|
|
4034
3998
|
this._stopAmplitudeMonitoring();
|
|
4035
|
-
this._setupDeviceChangeListener();
|
|
4036
3999
|
// Get conversation key from server
|
|
4037
4000
|
let authorizeSessionRequestBody = {
|
|
4038
4001
|
agent_id: this.options.agentId,
|
|
@@ -4056,6 +4019,8 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4056
4019
|
const authorizeSessionResponseBody = await authorizeSessionResponse.json();
|
|
4057
4020
|
this.conversationId = authorizeSessionResponseBody.conversation_id; // Save the conversation_id for use in future reconnects
|
|
4058
4021
|
this.options.conversationId = this.conversationId;
|
|
4022
|
+
await this.wavRecorder.requestPermission();
|
|
4023
|
+
this._setupDeviceChangeListener();
|
|
4059
4024
|
// Connect WebSocket
|
|
4060
4025
|
this.ws = new WebSocket(`${this._websocketUrl}?${new URLSearchParams({
|
|
4061
4026
|
client_session_key: authorizeSessionResponseBody.client_session_key,
|
|
@@ -4108,7 +4073,6 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4108
4073
|
console.error('Error connecting to Layercode agent:', error);
|
|
4109
4074
|
this._setStatus('error');
|
|
4110
4075
|
this.options.onError(error instanceof Error ? error : new Error(String(error)));
|
|
4111
|
-
throw error;
|
|
4112
4076
|
}
|
|
4113
4077
|
}
|
|
4114
4078
|
_resetTurnTracking() {
|
|
@@ -4136,6 +4100,13 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4136
4100
|
getStream() {
|
|
4137
4101
|
return this.wavRecorder.getStream();
|
|
4138
4102
|
}
|
|
4103
|
+
/**
|
|
4104
|
+
* List all available audio input devices
|
|
4105
|
+
* @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}
|
|
4106
|
+
*/
|
|
4107
|
+
async listDevices() {
|
|
4108
|
+
return this.wavRecorder.listDevices();
|
|
4109
|
+
}
|
|
4139
4110
|
/**
|
|
4140
4111
|
* Switches the input device for the microphone and restarts recording
|
|
4141
4112
|
* @param {string} deviceId - The deviceId of the new microphone
|
|
@@ -4228,6 +4199,8 @@ registerProcessor('audio_processor', AudioProcessor);
|
|
|
4228
4199
|
if (!this.deviceChangeListener) {
|
|
4229
4200
|
this.deviceChangeListener = async (devices) => {
|
|
4230
4201
|
try {
|
|
4202
|
+
// Notify user that devices have changed
|
|
4203
|
+
this.options.onDevicesChanged(devices);
|
|
4231
4204
|
const defaultDevice = devices.find((device) => device.default);
|
|
4232
4205
|
const usingDefaultDevice = this.useSystemDefaultDevice;
|
|
4233
4206
|
const previousDefaultDeviceKey = this.lastKnownSystemDefaultDeviceKey;
|