@anganyai/voice-sdk 0.0.6 → 0.0.8
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 +149 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +160 -127
- package/dist/index.d.ts +160 -127
- package/dist/index.js +149 -1
- package/dist/index.js.map +1 -1
- package/package.json +18 -28
package/dist/index.js
CHANGED
|
@@ -16421,6 +16421,18 @@ var SipManager = class extends EventEmitter {
|
|
|
16421
16421
|
}
|
|
16422
16422
|
const inviter = new Inviter(this.userAgent, uri, inviterOptions);
|
|
16423
16423
|
this.currentSession = inviter;
|
|
16424
|
+
let rejectionReason;
|
|
16425
|
+
inviter.delegate = {
|
|
16426
|
+
onReject: (response) => {
|
|
16427
|
+
const statusCode = response.message.statusCode;
|
|
16428
|
+
const reasonPhrase = response.message.reasonPhrase;
|
|
16429
|
+
this.logger.warn("Call rejected", { statusCode, reasonPhrase });
|
|
16430
|
+
rejectionReason = {
|
|
16431
|
+
code: statusCode,
|
|
16432
|
+
reason: this.mapSipErrorToMessage(statusCode, reasonPhrase)
|
|
16433
|
+
};
|
|
16434
|
+
}
|
|
16435
|
+
};
|
|
16424
16436
|
inviter.stateChange.addListener((state) => {
|
|
16425
16437
|
this.logger.debug("Call state changed", { state });
|
|
16426
16438
|
switch (state) {
|
|
@@ -16434,6 +16446,9 @@ var SipManager = class extends EventEmitter {
|
|
|
16434
16446
|
break;
|
|
16435
16447
|
case SessionState2.Terminated:
|
|
16436
16448
|
this.setState("registered");
|
|
16449
|
+
if (rejectionReason) {
|
|
16450
|
+
this.emit("error", new Error(rejectionReason.reason));
|
|
16451
|
+
}
|
|
16437
16452
|
this.emit("callEnded");
|
|
16438
16453
|
this.cleanupAudioResources();
|
|
16439
16454
|
delete this.currentSession;
|
|
@@ -16899,6 +16914,50 @@ var SipManager = class extends EventEmitter {
|
|
|
16899
16914
|
}
|
|
16900
16915
|
}, delay);
|
|
16901
16916
|
}
|
|
16917
|
+
/**
|
|
16918
|
+
* Map SIP error codes to user-friendly messages
|
|
16919
|
+
*/
|
|
16920
|
+
mapSipErrorToMessage(statusCode, reasonPhrase) {
|
|
16921
|
+
const errorMessages = {
|
|
16922
|
+
// 4xx Client Errors
|
|
16923
|
+
400: "Invalid request",
|
|
16924
|
+
401: "Authentication required",
|
|
16925
|
+
403: "Access denied",
|
|
16926
|
+
404: "Agent not found",
|
|
16927
|
+
408: "Request timeout",
|
|
16928
|
+
480: "Agent unavailable",
|
|
16929
|
+
486: "Agent is busy",
|
|
16930
|
+
487: "Call cancelled",
|
|
16931
|
+
488: "Not acceptable",
|
|
16932
|
+
// 5xx Server Errors
|
|
16933
|
+
500: "Server error",
|
|
16934
|
+
502: "Bad gateway",
|
|
16935
|
+
503: "Service unavailable",
|
|
16936
|
+
504: "Gateway timeout",
|
|
16937
|
+
// 6xx Global Failures
|
|
16938
|
+
600: "Agent is busy",
|
|
16939
|
+
603: "Agent declined the call",
|
|
16940
|
+
604: "Agent does not exist",
|
|
16941
|
+
606: "Not acceptable"
|
|
16942
|
+
};
|
|
16943
|
+
const message = errorMessages[statusCode];
|
|
16944
|
+
if (message) {
|
|
16945
|
+
return message;
|
|
16946
|
+
}
|
|
16947
|
+
if (reasonPhrase) {
|
|
16948
|
+
return reasonPhrase;
|
|
16949
|
+
}
|
|
16950
|
+
if (statusCode >= 400 && statusCode < 500) {
|
|
16951
|
+
return "Call failed";
|
|
16952
|
+
}
|
|
16953
|
+
if (statusCode >= 500 && statusCode < 600) {
|
|
16954
|
+
return "Server error";
|
|
16955
|
+
}
|
|
16956
|
+
if (statusCode >= 600) {
|
|
16957
|
+
return "Agent unavailable";
|
|
16958
|
+
}
|
|
16959
|
+
return "Unknown error";
|
|
16960
|
+
}
|
|
16902
16961
|
};
|
|
16903
16962
|
|
|
16904
16963
|
// src/services/TranscriptionService.ts
|
|
@@ -16910,8 +16969,18 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
16910
16969
|
this.maxReconnectAttempts = 5;
|
|
16911
16970
|
this.reconnectDelay = 1e3;
|
|
16912
16971
|
this.isIntentionallyClosed = false;
|
|
16972
|
+
this.useEventSource = false;
|
|
16913
16973
|
this.apiUrl = apiUrl;
|
|
16914
16974
|
}
|
|
16975
|
+
/**
|
|
16976
|
+
* Set EventSource factory for React Native environments
|
|
16977
|
+
* Call this before start() to use EventSource instead of fetch streams
|
|
16978
|
+
*/
|
|
16979
|
+
setEventSourceFactory(factory) {
|
|
16980
|
+
this.eventSourceFactory = factory;
|
|
16981
|
+
this.useEventSource = true;
|
|
16982
|
+
this.logger.debug("EventSource factory set - will use EventSource mode");
|
|
16983
|
+
}
|
|
16915
16984
|
/**
|
|
16916
16985
|
* Set token refresh callback for handling expired tokens
|
|
16917
16986
|
*/
|
|
@@ -16941,7 +17010,10 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
16941
17010
|
*/
|
|
16942
17011
|
async connectToSSE(accessToken, isRetry = false) {
|
|
16943
17012
|
const sseUrl = `${this.apiUrl}/api/v1/events?event_types=transcription,call_event`;
|
|
16944
|
-
this.logger.debug("Connecting to SSE endpoint", { url: sseUrl, isRetry });
|
|
17013
|
+
this.logger.debug("Connecting to SSE endpoint", { url: sseUrl, isRetry, useEventSource: this.useEventSource });
|
|
17014
|
+
if (this.useEventSource && this.eventSourceFactory) {
|
|
17015
|
+
return this.connectWithEventSource(sseUrl, accessToken);
|
|
17016
|
+
}
|
|
16945
17017
|
const response = await fetch(sseUrl, {
|
|
16946
17018
|
method: "GET",
|
|
16947
17019
|
headers: {
|
|
@@ -16979,6 +17051,65 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
16979
17051
|
this.reader = response.body.getReader();
|
|
16980
17052
|
this.processStream();
|
|
16981
17053
|
}
|
|
17054
|
+
/**
|
|
17055
|
+
* Connect using EventSource (for React Native)
|
|
17056
|
+
*/
|
|
17057
|
+
connectWithEventSource(sseUrl, accessToken) {
|
|
17058
|
+
if (!this.eventSourceFactory) {
|
|
17059
|
+
throw new Error("EventSource factory not set");
|
|
17060
|
+
}
|
|
17061
|
+
this.logger.debug("Connecting with EventSource", { url: sseUrl });
|
|
17062
|
+
if (this.eventSource) {
|
|
17063
|
+
this.eventSource.removeAllEventListeners();
|
|
17064
|
+
this.eventSource.close();
|
|
17065
|
+
}
|
|
17066
|
+
this.eventSource = this.eventSourceFactory(sseUrl, {
|
|
17067
|
+
headers: {
|
|
17068
|
+
Authorization: `Bearer ${accessToken}`,
|
|
17069
|
+
Accept: "text/event-stream",
|
|
17070
|
+
"Cache-Control": "no-cache"
|
|
17071
|
+
}
|
|
17072
|
+
});
|
|
17073
|
+
this.eventSource.addEventListener("open", () => {
|
|
17074
|
+
this.logger.info("EventSource SSE connection established");
|
|
17075
|
+
this.reconnectAttempts = 0;
|
|
17076
|
+
this.emit("connected");
|
|
17077
|
+
});
|
|
17078
|
+
this.eventSource.addEventListener("message", (event) => {
|
|
17079
|
+
this.logger.debug("EventSource message received", { data: event.data });
|
|
17080
|
+
try {
|
|
17081
|
+
const data = JSON.parse(event.data);
|
|
17082
|
+
this.handleMessage(data);
|
|
17083
|
+
} catch (error) {
|
|
17084
|
+
this.logger.error("Error parsing EventSource message", { error, data: event.data });
|
|
17085
|
+
}
|
|
17086
|
+
});
|
|
17087
|
+
this.eventSource.addEventListener("error", (event) => {
|
|
17088
|
+
this.logger.error("EventSource error", { event });
|
|
17089
|
+
if (!this.isIntentionallyClosed) {
|
|
17090
|
+
this.emit("disconnected");
|
|
17091
|
+
this.handleReconnection();
|
|
17092
|
+
}
|
|
17093
|
+
});
|
|
17094
|
+
this.eventSource.addEventListener("transcription", (event) => {
|
|
17095
|
+
this.logger.debug("EventSource transcription event", { data: event.data });
|
|
17096
|
+
try {
|
|
17097
|
+
const data = JSON.parse(event.data);
|
|
17098
|
+
this.handleMessage({ ...data, type: "transcription" });
|
|
17099
|
+
} catch (error) {
|
|
17100
|
+
this.logger.error("Error parsing transcription event", { error, data: event.data });
|
|
17101
|
+
}
|
|
17102
|
+
});
|
|
17103
|
+
this.eventSource.addEventListener("call_event", (event) => {
|
|
17104
|
+
this.logger.debug("EventSource call_event", { data: event.data });
|
|
17105
|
+
try {
|
|
17106
|
+
const data = JSON.parse(event.data);
|
|
17107
|
+
this.handleMessage(data);
|
|
17108
|
+
} catch (error) {
|
|
17109
|
+
this.logger.error("Error parsing call_event", { error, data: event.data });
|
|
17110
|
+
}
|
|
17111
|
+
});
|
|
17112
|
+
}
|
|
16982
17113
|
/**
|
|
16983
17114
|
* Stop the SSE connection
|
|
16984
17115
|
*/
|
|
@@ -16989,6 +17120,11 @@ var TranscriptionService = class extends EventEmitter {
|
|
|
16989
17120
|
clearTimeout(this.reconnectTimeout);
|
|
16990
17121
|
delete this.reconnectTimeout;
|
|
16991
17122
|
}
|
|
17123
|
+
if (this.eventSource) {
|
|
17124
|
+
this.eventSource.removeAllEventListeners();
|
|
17125
|
+
this.eventSource.close();
|
|
17126
|
+
delete this.eventSource;
|
|
17127
|
+
}
|
|
16992
17128
|
if (this.reader) {
|
|
16993
17129
|
this.reader.cancel();
|
|
16994
17130
|
delete this.reader;
|
|
@@ -17402,6 +17538,14 @@ var Conversation = class extends EventEmitter {
|
|
|
17402
17538
|
sipUrl: urls.sipUrl || "will be derived"
|
|
17403
17539
|
});
|
|
17404
17540
|
}
|
|
17541
|
+
/**
|
|
17542
|
+
* Set EventSource factory for React Native environments
|
|
17543
|
+
* Call this before initialize() to use EventSource instead of fetch streams for SSE
|
|
17544
|
+
*/
|
|
17545
|
+
setEventSourceFactory(factory) {
|
|
17546
|
+
this.transcriptionService.setEventSourceFactory(factory);
|
|
17547
|
+
this.logger.debug("EventSource factory configured for transcription service");
|
|
17548
|
+
}
|
|
17405
17549
|
/**
|
|
17406
17550
|
* Initialize and start the conversation
|
|
17407
17551
|
*/
|
|
@@ -18099,6 +18243,10 @@ var AnganyVoice = class extends EventEmitter {
|
|
|
18099
18243
|
this.conversations.delete(conversationId);
|
|
18100
18244
|
this.emit("conversationEnded", conversationId);
|
|
18101
18245
|
});
|
|
18246
|
+
if (this.config.eventSourceFactory) {
|
|
18247
|
+
this.logger.debug("Setting EventSource factory for conversation");
|
|
18248
|
+
conversation.setEventSourceFactory(this.config.eventSourceFactory);
|
|
18249
|
+
}
|
|
18102
18250
|
try {
|
|
18103
18251
|
this.logger.debug("Initializing conversation...");
|
|
18104
18252
|
await conversation.initialize();
|