@layercode/js-sdk 2.3.3 → 2.5.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.
@@ -505,12 +505,37 @@ class WavStreamPlayer {
505
505
  this.sampleRate = sampleRate;
506
506
  this.context = null;
507
507
  this.stream = null;
508
+ this.gainNode = null;
508
509
  this.analyser = null;
509
510
  this.trackSampleOffsets = {};
510
511
  this.interruptedTrackIds = {};
511
512
  this.finishedPlayingCallback = finishedPlayingCallback;
512
513
  this.isPlaying = false;
513
514
  this.amplitudeMonitorRaf = undefined;
515
+ this.muted = false;
516
+ }
517
+
518
+ _ensureGainNode() {
519
+ if (!this.context) {
520
+ return null;
521
+ }
522
+ if (!this.gainNode) {
523
+ this.gainNode = this.context.createGain();
524
+ this._applyGain();
525
+ }
526
+ return this.gainNode;
527
+ }
528
+
529
+ _applyGain() {
530
+ if (!this.gainNode || !this.context) {
531
+ return;
532
+ }
533
+ const target = this.muted ? 0 : 1;
534
+ try {
535
+ this.gainNode.gain.setTargetAtTime(target, this.context.currentTime, 0.01);
536
+ } catch {
537
+ this.gainNode.gain.value = target;
538
+ }
514
539
  }
515
540
 
516
541
  /**
@@ -550,6 +575,7 @@ class WavStreamPlayer {
550
575
  analyser.fftSize = 8192;
551
576
  analyser.smoothingTimeConstant = 0.1;
552
577
  this.analyser = analyser;
578
+ this._ensureGainNode();
553
579
  this.isPlaying = true;
554
580
  return true;
555
581
  }
@@ -619,12 +645,19 @@ class WavStreamPlayer {
619
645
  */
620
646
  _start() {
621
647
  const streamNode = new AudioWorkletNode(this.context, "stream_processor");
622
- streamNode.connect(this.context.destination);
648
+ const gainNode = this._ensureGainNode();
649
+ if (!gainNode) {
650
+ throw new Error("GainNode not initialized");
651
+ }
623
652
  streamNode.port.onmessage = (e) => {
624
653
  const { event } = e.data;
625
654
  if (event === "stop") {
626
655
  streamNode.disconnect();
656
+ gainNode.disconnect();
627
657
  this.stream = null;
658
+ if (this.analyser) {
659
+ this.analyser.disconnect();
660
+ }
628
661
  this.isPlaying = false;
629
662
  this.finishedPlayingCallback();
630
663
  } else if (event === "offset") {
@@ -633,8 +666,15 @@ class WavStreamPlayer {
633
666
  this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };
634
667
  }
635
668
  };
636
- this.analyser.disconnect();
637
- streamNode.connect(this.analyser);
669
+ if (this.analyser) {
670
+ this.analyser.disconnect();
671
+ streamNode.connect(gainNode);
672
+ gainNode.connect(this.analyser);
673
+ this.analyser.connect(this.context.destination);
674
+ } else {
675
+ streamNode.connect(gainNode);
676
+ gainNode.connect(this.context.destination);
677
+ }
638
678
  this.stream = streamNode;
639
679
  this.isPlaying = true;
640
680
  return true;
@@ -764,6 +804,16 @@ class WavStreamPlayer {
764
804
  }
765
805
  }
766
806
 
807
+ mute() {
808
+ this.muted = true;
809
+ this._applyGain();
810
+ }
811
+
812
+ unmute() {
813
+ this.muted = false;
814
+ this._applyGain();
815
+ }
816
+
767
817
  /**
768
818
  * Disconnects the audio context and cleans up resources
769
819
  * @returns {void}
@@ -775,6 +825,11 @@ class WavStreamPlayer {
775
825
  this.stream = null;
776
826
  }
777
827
 
828
+ if (this.gainNode) {
829
+ this.gainNode.disconnect();
830
+ this.gainNode = null;
831
+ }
832
+
778
833
  if (this.analyser) {
779
834
  this.analyser.disconnect();
780
835
  }
@@ -3625,7 +3680,7 @@ class LayercodeClient {
3625
3680
  * @param {Object} options - Configuration options
3626
3681
  */
3627
3682
  constructor(options) {
3628
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
3683
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
3629
3684
  this.deviceId = null;
3630
3685
  this.options = {
3631
3686
  agentId: options.agentId,
@@ -3636,22 +3691,25 @@ class LayercodeClient {
3636
3691
  vadResumeDelay: (_c = options.vadResumeDelay) !== null && _c !== void 0 ? _c : 500,
3637
3692
  audioInput: (_d = options.audioInput) !== null && _d !== void 0 ? _d : true,
3638
3693
  audioInputChanged: (_e = options.audioInputChanged) !== null && _e !== void 0 ? _e : NOOP,
3639
- onConnect: (_f = options.onConnect) !== null && _f !== void 0 ? _f : NOOP,
3640
- onDisconnect: (_g = options.onDisconnect) !== null && _g !== void 0 ? _g : NOOP,
3641
- onError: (_h = options.onError) !== null && _h !== void 0 ? _h : NOOP,
3642
- onDeviceSwitched: (_j = options.onDeviceSwitched) !== null && _j !== void 0 ? _j : NOOP,
3643
- onDevicesChanged: (_k = options.onDevicesChanged) !== null && _k !== void 0 ? _k : NOOP,
3644
- onDataMessage: (_l = options.onDataMessage) !== null && _l !== void 0 ? _l : NOOP,
3645
- onMessage: (_m = options.onMessage) !== null && _m !== void 0 ? _m : NOOP,
3646
- onUserAmplitudeChange: (_o = options.onUserAmplitudeChange) !== null && _o !== void 0 ? _o : NOOP,
3647
- onAgentAmplitudeChange: (_p = options.onAgentAmplitudeChange) !== null && _p !== void 0 ? _p : NOOP,
3648
- onStatusChange: (_q = options.onStatusChange) !== null && _q !== void 0 ? _q : NOOP,
3649
- onUserIsSpeakingChange: (_r = options.onUserIsSpeakingChange) !== null && _r !== void 0 ? _r : NOOP,
3650
- onAgentSpeakingChange: (_s = options.onAgentSpeakingChange) !== null && _s !== void 0 ? _s : NOOP,
3651
- onMuteStateChange: (_t = options.onMuteStateChange) !== null && _t !== void 0 ? _t : NOOP,
3652
- enableAmplitudeMonitoring: (_u = options.enableAmplitudeMonitoring) !== null && _u !== void 0 ? _u : true,
3694
+ audioOutput: (_f = options.audioOutput) !== null && _f !== void 0 ? _f : true,
3695
+ audioOutputChanged: (_g = options.audioOutputChanged) !== null && _g !== void 0 ? _g : NOOP,
3696
+ onConnect: (_h = options.onConnect) !== null && _h !== void 0 ? _h : NOOP,
3697
+ onDisconnect: (_j = options.onDisconnect) !== null && _j !== void 0 ? _j : NOOP,
3698
+ onError: (_k = options.onError) !== null && _k !== void 0 ? _k : NOOP,
3699
+ onDeviceSwitched: (_l = options.onDeviceSwitched) !== null && _l !== void 0 ? _l : NOOP,
3700
+ onDevicesChanged: (_m = options.onDevicesChanged) !== null && _m !== void 0 ? _m : NOOP,
3701
+ onDataMessage: (_o = options.onDataMessage) !== null && _o !== void 0 ? _o : NOOP,
3702
+ onMessage: (_p = options.onMessage) !== null && _p !== void 0 ? _p : NOOP,
3703
+ onUserAmplitudeChange: (_q = options.onUserAmplitudeChange) !== null && _q !== void 0 ? _q : NOOP,
3704
+ onAgentAmplitudeChange: (_r = options.onAgentAmplitudeChange) !== null && _r !== void 0 ? _r : NOOP,
3705
+ onStatusChange: (_s = options.onStatusChange) !== null && _s !== void 0 ? _s : NOOP,
3706
+ onUserIsSpeakingChange: (_t = options.onUserIsSpeakingChange) !== null && _t !== void 0 ? _t : NOOP,
3707
+ onAgentSpeakingChange: (_u = options.onAgentSpeakingChange) !== null && _u !== void 0 ? _u : NOOP,
3708
+ onMuteStateChange: (_v = options.onMuteStateChange) !== null && _v !== void 0 ? _v : NOOP,
3709
+ enableAmplitudeMonitoring: (_w = options.enableAmplitudeMonitoring) !== null && _w !== void 0 ? _w : true,
3653
3710
  };
3654
- this.audioInput = (_v = options.audioInput) !== null && _v !== void 0 ? _v : true;
3711
+ this.audioInput = (_x = options.audioInput) !== null && _x !== void 0 ? _x : true;
3712
+ this.audioOutput = (_y = options.audioOutput) !== null && _y !== void 0 ? _y : true;
3655
3713
  this._emitAudioInput();
3656
3714
  this.AMPLITUDE_MONITORING_SAMPLE_RATE = 2;
3657
3715
  this._websocketUrl = DEFAULT_WS_URL;
@@ -3842,6 +3900,9 @@ class LayercodeClient {
3842
3900
  await this._clientInterruptAgentReplay();
3843
3901
  this._wsSend({ type: 'client.response.text', content: text });
3844
3902
  }
3903
+ async sendClientResponseData(data) {
3904
+ this._wsSend({ type: 'client.response.data', data: data });
3905
+ }
3845
3906
  /**
3846
3907
  * Handles incoming WebSocket messages
3847
3908
  * @param {MessageEvent} event - The WebSocket message event
@@ -4076,10 +4137,25 @@ class LayercodeClient {
4076
4137
  }
4077
4138
  }
4078
4139
  }
4140
+ async setAudioOutput(state) {
4141
+ if (this.audioOutput !== state) {
4142
+ this.audioOutput = state;
4143
+ this._emitAudioOutput();
4144
+ if (state) {
4145
+ this.wavPlayer.unmute();
4146
+ }
4147
+ else {
4148
+ this.wavPlayer.mute();
4149
+ }
4150
+ }
4151
+ }
4079
4152
  /** Emitters for audio flags */
4080
4153
  _emitAudioInput() {
4081
4154
  this.options.audioInputChanged(this.audioInput);
4082
4155
  }
4156
+ _emitAudioOutput() {
4157
+ this.options.audioOutputChanged(this.audioOutput);
4158
+ }
4083
4159
  get audioInputEnabled() {
4084
4160
  return this.audioInput;
4085
4161
  }
@@ -4205,6 +4281,12 @@ class LayercodeClient {
4205
4281
  if (!this.options.enableAmplitudeMonitoring) {
4206
4282
  this.agentAudioAmplitude = 0;
4207
4283
  }
4284
+ if (this.audioOutput) {
4285
+ this.wavPlayer.unmute();
4286
+ }
4287
+ else {
4288
+ this.wavPlayer.mute();
4289
+ }
4208
4290
  }
4209
4291
  async connectToAudioInput() {
4210
4292
  if (!this.audioInput) {