@anganyai/voice-sdk 0.0.9 → 0.0.11
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/dist/index.cjs +89 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +89 -32
- package/dist/index.js.map +1 -1
- package/package.json +28 -18
package/dist/index.cjs
CHANGED
|
@@ -16322,8 +16322,9 @@ var SipManager = class extends EventEmitter {
|
|
|
16322
16322
|
{ urls: "stun:stun1.l.google.com:19302" }
|
|
16323
16323
|
]
|
|
16324
16324
|
},
|
|
16325
|
-
|
|
16326
|
-
|
|
16325
|
+
// Reduced timeouts for faster connection (was 2000ms/5000ms)
|
|
16326
|
+
iceGatheringTimeout: 500,
|
|
16327
|
+
iceCheckingTimeout: 2e3
|
|
16327
16328
|
},
|
|
16328
16329
|
delegate: {
|
|
16329
16330
|
onConnect: () => {
|
|
@@ -16488,7 +16489,7 @@ var SipManager = class extends EventEmitter {
|
|
|
16488
16489
|
this.logger.debug("No active session to hang up");
|
|
16489
16490
|
return;
|
|
16490
16491
|
}
|
|
16491
|
-
this.logger.info("
|
|
16492
|
+
this.logger.info("Hanging up call...");
|
|
16492
16493
|
try {
|
|
16493
16494
|
const sessionState = this.currentSession.state;
|
|
16494
16495
|
if (sessionState === "Established" || sessionState === "Establishing") {
|
|
@@ -16497,7 +16498,7 @@ var SipManager = class extends EventEmitter {
|
|
|
16497
16498
|
this.logger.debug("Session already terminated, skipping BYE", { state: sessionState });
|
|
16498
16499
|
}
|
|
16499
16500
|
} catch (error) {
|
|
16500
|
-
this.logger.warn("
|
|
16501
|
+
this.logger.warn("Error sending BYE", { error });
|
|
16501
16502
|
}
|
|
16502
16503
|
delete this.currentSession;
|
|
16503
16504
|
this.cleanupAudioResources();
|
|
@@ -16733,13 +16734,48 @@ var SipManager = class extends EventEmitter {
|
|
|
16733
16734
|
}
|
|
16734
16735
|
}
|
|
16735
16736
|
/**
|
|
16736
|
-
* Mute or unmute the remote audio
|
|
16737
|
+
* Mute or unmute the remote audio (output/speaker)
|
|
16737
16738
|
*/
|
|
16738
16739
|
setMuted(muted) {
|
|
16739
16740
|
if (this.audioElement) {
|
|
16740
16741
|
this.audioElement.muted = muted;
|
|
16741
|
-
this.logger.debug("
|
|
16742
|
+
this.logger.debug("Remote audio mute state changed", { muted });
|
|
16743
|
+
}
|
|
16744
|
+
}
|
|
16745
|
+
/**
|
|
16746
|
+
* Mute or unmute the local audio (microphone input)
|
|
16747
|
+
* This actually disables the audio tracks to prevent sending audio
|
|
16748
|
+
*/
|
|
16749
|
+
setLocalAudioEnabled(enabled) {
|
|
16750
|
+
if (this.localStream) {
|
|
16751
|
+
this.localStream.getAudioTracks().forEach((track) => {
|
|
16752
|
+
track.enabled = enabled;
|
|
16753
|
+
this.logger.debug("Local audio track enabled state changed", {
|
|
16754
|
+
trackId: track.id,
|
|
16755
|
+
enabled: track.enabled
|
|
16756
|
+
});
|
|
16757
|
+
});
|
|
16758
|
+
}
|
|
16759
|
+
if (this.preAcquiredStream && this.preAcquiredStream !== this.localStream) {
|
|
16760
|
+
this.preAcquiredStream.getAudioTracks().forEach((track) => {
|
|
16761
|
+
track.enabled = enabled;
|
|
16762
|
+
this.logger.debug("Pre-acquired audio track enabled state changed", {
|
|
16763
|
+
trackId: track.id,
|
|
16764
|
+
enabled: track.enabled
|
|
16765
|
+
});
|
|
16766
|
+
});
|
|
16767
|
+
}
|
|
16768
|
+
this.logger.info("Local audio (microphone) " + (enabled ? "enabled" : "disabled"));
|
|
16769
|
+
}
|
|
16770
|
+
/**
|
|
16771
|
+
* Check if local audio is enabled
|
|
16772
|
+
*/
|
|
16773
|
+
isLocalAudioEnabled() {
|
|
16774
|
+
if (this.localStream) {
|
|
16775
|
+
const tracks = this.localStream.getAudioTracks();
|
|
16776
|
+
return tracks.length > 0 && tracks.every((track) => track.enabled);
|
|
16742
16777
|
}
|
|
16778
|
+
return false;
|
|
16743
16779
|
}
|
|
16744
16780
|
startAudioMonitoring() {
|
|
16745
16781
|
if (!this.localStream || this.audioMonitorInterval) {
|
|
@@ -16792,16 +16828,16 @@ var SipManager = class extends EventEmitter {
|
|
|
16792
16828
|
delete this.audioAnalyser;
|
|
16793
16829
|
}
|
|
16794
16830
|
cleanupAudioResources() {
|
|
16795
|
-
this.logger.debug("
|
|
16831
|
+
this.logger.debug("Performing audio resource cleanup", {
|
|
16796
16832
|
platform: isReactNative() ? "react-native" : "browser"
|
|
16797
16833
|
});
|
|
16798
16834
|
this.stopAudioMonitoring();
|
|
16799
16835
|
if (this.audioElement && isBrowser()) {
|
|
16800
|
-
this.logger.debug("
|
|
16836
|
+
this.logger.debug("Cleaning up audio element");
|
|
16801
16837
|
if (this.audioElement.srcObject) {
|
|
16802
16838
|
const tracks = this.audioElement.srcObject.getTracks();
|
|
16803
16839
|
tracks.forEach((track) => {
|
|
16804
|
-
this.logger.debug("
|
|
16840
|
+
this.logger.debug("Stopping remote track", { kind: track.kind });
|
|
16805
16841
|
track.stop();
|
|
16806
16842
|
});
|
|
16807
16843
|
this.audioElement.srcObject = null;
|
|
@@ -16814,29 +16850,29 @@ var SipManager = class extends EventEmitter {
|
|
|
16814
16850
|
this.logger.debug("Audio element cleaned up");
|
|
16815
16851
|
}
|
|
16816
16852
|
if (this.localStream) {
|
|
16817
|
-
this.logger.debug("
|
|
16853
|
+
this.logger.debug("Cleaning up local stream");
|
|
16818
16854
|
const tracks = this.localStream.getTracks();
|
|
16819
16855
|
tracks.forEach((track) => {
|
|
16820
|
-
this.logger.debug("
|
|
16856
|
+
this.logger.debug("Stopping local track", { kind: track.kind });
|
|
16821
16857
|
track.stop();
|
|
16822
16858
|
});
|
|
16823
16859
|
delete this.localStream;
|
|
16824
16860
|
}
|
|
16825
16861
|
if (this.preAcquiredStream) {
|
|
16826
|
-
this.logger.debug("
|
|
16862
|
+
this.logger.debug("Stopping pre-acquired microphone stream");
|
|
16827
16863
|
const tracks = this.preAcquiredStream.getTracks();
|
|
16828
16864
|
tracks.forEach((track) => {
|
|
16829
|
-
this.logger.debug("
|
|
16865
|
+
this.logger.debug("Stopping pre-acquired track", { kind: track.kind });
|
|
16830
16866
|
track.stop();
|
|
16831
16867
|
});
|
|
16832
16868
|
delete this.preAcquiredStream;
|
|
16833
16869
|
}
|
|
16834
16870
|
if (this.remoteStream) {
|
|
16835
|
-
this.logger.debug("
|
|
16871
|
+
this.logger.debug("Cleaning up remote stream");
|
|
16836
16872
|
try {
|
|
16837
16873
|
const tracks = this.remoteStream.getTracks();
|
|
16838
16874
|
tracks.forEach((track) => {
|
|
16839
|
-
this.logger.debug("
|
|
16875
|
+
this.logger.debug("Stopping remote track", { kind: track.kind });
|
|
16840
16876
|
track.stop();
|
|
16841
16877
|
});
|
|
16842
16878
|
} catch (error) {
|
|
@@ -16846,15 +16882,15 @@ var SipManager = class extends EventEmitter {
|
|
|
16846
16882
|
}
|
|
16847
16883
|
if (this.audioContext) {
|
|
16848
16884
|
try {
|
|
16849
|
-
this.logger.debug("
|
|
16885
|
+
this.logger.debug("Closing audio context");
|
|
16850
16886
|
this.audioContext.close();
|
|
16851
16887
|
delete this.audioContext;
|
|
16852
16888
|
} catch (error) {
|
|
16853
|
-
this.logger.warn("
|
|
16889
|
+
this.logger.warn("Error closing audio context", { error });
|
|
16854
16890
|
}
|
|
16855
16891
|
}
|
|
16856
16892
|
delete this.audioAnalyser;
|
|
16857
|
-
this.logger.
|
|
16893
|
+
this.logger.debug("Audio resources cleanup completed");
|
|
16858
16894
|
}
|
|
16859
16895
|
startKeepAlive() {
|
|
16860
16896
|
this.stopKeepAlive();
|
|
@@ -17077,7 +17113,10 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
17077
17113
|
}
|
|
17078
17114
|
});
|
|
17079
17115
|
const handleSSEEvent = (eventType, event) => {
|
|
17080
|
-
this.logger.debug(`EventSource [${eventType}] received`, {
|
|
17116
|
+
this.logger.debug(`EventSource [${eventType}] received`, {
|
|
17117
|
+
data: event.data,
|
|
17118
|
+
type: event.type
|
|
17119
|
+
});
|
|
17081
17120
|
if (!event.data) {
|
|
17082
17121
|
this.logger.debug(`EventSource [${eventType}] has no data, skipping`);
|
|
17083
17122
|
return;
|
|
@@ -17105,13 +17144,31 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
17105
17144
|
}
|
|
17106
17145
|
});
|
|
17107
17146
|
this.eventSource.addEventListener("message", (event) => handleSSEEvent("message", event));
|
|
17108
|
-
this.eventSource.addEventListener(
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
this.eventSource.addEventListener(
|
|
17147
|
+
this.eventSource.addEventListener(
|
|
17148
|
+
"transcription",
|
|
17149
|
+
(event) => handleSSEEvent("transcription", event)
|
|
17150
|
+
);
|
|
17151
|
+
this.eventSource.addEventListener(
|
|
17152
|
+
"call_event",
|
|
17153
|
+
(event) => handleSSEEvent("call_event", event)
|
|
17154
|
+
);
|
|
17155
|
+
this.eventSource.addEventListener(
|
|
17156
|
+
"call_started",
|
|
17157
|
+
(event) => handleSSEEvent("call_started", event)
|
|
17158
|
+
);
|
|
17159
|
+
this.eventSource.addEventListener(
|
|
17160
|
+
"call_ended",
|
|
17161
|
+
(event) => handleSSEEvent("call_ended", event)
|
|
17162
|
+
);
|
|
17163
|
+
this.eventSource.addEventListener(
|
|
17164
|
+
"connected",
|
|
17165
|
+
(event) => handleSSEEvent("connected", event)
|
|
17166
|
+
);
|
|
17113
17167
|
this.eventSource.addEventListener("welcome", (event) => handleSSEEvent("welcome", event));
|
|
17114
|
-
this.eventSource.addEventListener(
|
|
17168
|
+
this.eventSource.addEventListener(
|
|
17169
|
+
"heartbeat",
|
|
17170
|
+
(event) => handleSSEEvent("heartbeat", event)
|
|
17171
|
+
);
|
|
17115
17172
|
}
|
|
17116
17173
|
/**
|
|
17117
17174
|
* Stop the SSE connection
|
|
@@ -17553,11 +17610,10 @@ var Conversation = class extends EventEmitter {
|
|
|
17553
17610
|
* Initialize and start the conversation
|
|
17554
17611
|
*/
|
|
17555
17612
|
async initialize() {
|
|
17556
|
-
this.logger.debug("
|
|
17613
|
+
this.logger.debug("Initializing conversation");
|
|
17557
17614
|
try {
|
|
17558
17615
|
this.setState("connecting");
|
|
17559
17616
|
this.startTime = /* @__PURE__ */ new Date();
|
|
17560
|
-
this.logger.debug("=== STEP 1: CHECKING AUTHENTICATION ===");
|
|
17561
17617
|
const authStatus = this.authManager.getAuthStatus();
|
|
17562
17618
|
this.logger.debug("Auth status received", {
|
|
17563
17619
|
authenticated: authStatus.authenticated,
|
|
@@ -17569,8 +17625,7 @@ var Conversation = class extends EventEmitter {
|
|
|
17569
17625
|
this.logger.error("Authentication check failed", { authStatus });
|
|
17570
17626
|
throw new AuthenticationError("Not authenticated");
|
|
17571
17627
|
}
|
|
17572
|
-
this.logger.debug("
|
|
17573
|
-
this.logger.debug("=== STEP 2: GETTING ACCESS TOKEN (OPTIONAL) ===");
|
|
17628
|
+
this.logger.debug("Authentication check passed");
|
|
17574
17629
|
let accessToken = authStatus.tokens?.accessToken;
|
|
17575
17630
|
this.logger.debug("OAuth access token", { hasOAuthToken: !!accessToken });
|
|
17576
17631
|
if (!accessToken) {
|
|
@@ -17595,11 +17650,10 @@ var Conversation = class extends EventEmitter {
|
|
|
17595
17650
|
);
|
|
17596
17651
|
} else {
|
|
17597
17652
|
this.accessToken = accessToken;
|
|
17598
|
-
this.logger.debug("
|
|
17653
|
+
this.logger.debug("Access token obtained for API calls", {
|
|
17599
17654
|
tokenLength: accessToken.length
|
|
17600
17655
|
});
|
|
17601
17656
|
}
|
|
17602
|
-
this.logger.debug("=== STEP 3: ENSURING EPHEMERAL CREDENTIALS ===");
|
|
17603
17657
|
if (!this.ephemeralCredentials) {
|
|
17604
17658
|
this.logger.debug("Getting ephemeral credentials");
|
|
17605
17659
|
this.ephemeralCredentials = this.authManager.getCachedEphemeralCredentials();
|
|
@@ -17615,7 +17669,7 @@ var Conversation = class extends EventEmitter {
|
|
|
17615
17669
|
uriCount: this.ephemeralCredentials.sip?.uris?.length || 0
|
|
17616
17670
|
});
|
|
17617
17671
|
} else {
|
|
17618
|
-
this.logger.debug("
|
|
17672
|
+
this.logger.debug("Ephemeral credentials already available");
|
|
17619
17673
|
}
|
|
17620
17674
|
this.logger.debug("Raw ephemeral credentials", {
|
|
17621
17675
|
sip: {
|
|
@@ -17739,6 +17793,7 @@ var Conversation = class extends EventEmitter {
|
|
|
17739
17793
|
}
|
|
17740
17794
|
}
|
|
17741
17795
|
await this.sipManager.makeCall(callOptions);
|
|
17796
|
+
this.logger.debug("Conversation initialization complete");
|
|
17742
17797
|
} catch (error) {
|
|
17743
17798
|
this.logger.error("Failed to initialize conversation", { error });
|
|
17744
17799
|
this.setState("error");
|
|
@@ -17794,10 +17849,12 @@ var Conversation = class extends EventEmitter {
|
|
|
17794
17849
|
}
|
|
17795
17850
|
/**
|
|
17796
17851
|
* Mute or unmute the user's microphone
|
|
17852
|
+
* This actually disables the local audio tracks to prevent sending audio
|
|
17797
17853
|
*/
|
|
17798
17854
|
mute(muted) {
|
|
17799
17855
|
this.logger.debug("Setting user mute", { muted });
|
|
17800
17856
|
this.userMuted = muted;
|
|
17857
|
+
this.sipManager.setLocalAudioEnabled(!muted);
|
|
17801
17858
|
this.emit("userMuted", muted);
|
|
17802
17859
|
}
|
|
17803
17860
|
/**
|