@absolutejs/voice 0.0.22-beta.585 → 0.0.22-beta.586

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.js CHANGED
@@ -3721,6 +3721,8 @@ var FALLBACK_CONFIDENCE_SELECTION_DELTA = 0.05;
3721
3721
  var FALLBACK_WORD_COUNT_SELECTION_MARGIN_RATIO = 0.12;
3722
3722
  var EXTENDED_VENDOR_COMMIT_SILENCE_THRESHOLD_MS = 200;
3723
3723
  var MAX_VENDOR_COMMIT_GRACE_MS = 1200;
3724
+ var STT_RECONNECT_FLAP_WINDOW_MS = 4000;
3725
+ var MAX_STT_RECONNECTS_IN_FLAP_WINDOW = 3;
3724
3726
  var DEFAULT_FORMAT = {
3725
3727
  channels: 1,
3726
3728
  container: "raw",
@@ -3961,6 +3963,8 @@ var createVoiceSession = (options) => {
3961
3963
  let operationQueue = Promise.resolve();
3962
3964
  let adapterGenerationCounter = 0;
3963
3965
  let activeAdapterGeneration = 0;
3966
+ let sttReconnectCount = 0;
3967
+ let lastSttReconnectAt = 0;
3964
3968
  let activeTTSTurnId;
3965
3969
  let assistantSpeechEndsAt = 0;
3966
3970
  let lastAssistantAudioAt = 0;
@@ -4847,6 +4851,27 @@ var createVoiceSession = (options) => {
4847
4851
  }
4848
4852
  };
4849
4853
  const handleClose = async (event) => {
4854
+ const session = await readSession();
4855
+ const callLive = session.status !== "completed" && session.status !== "failed";
4856
+ if (callLive && (options.stt || options.realtime)) {
4857
+ const now = Date.now();
4858
+ sttReconnectCount = now - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
4859
+ lastSttReconnectAt = now;
4860
+ if (sttReconnectCount <= MAX_STT_RECONNECTS_IN_FLAP_WINDOW) {
4861
+ await appendTrace({
4862
+ payload: {
4863
+ action: "stt-reconnect",
4864
+ attempt: sttReconnectCount,
4865
+ reason: event.reason ?? "stt stream closed",
4866
+ recoverable: event.recoverable
4867
+ },
4868
+ session,
4869
+ type: "session.error"
4870
+ });
4871
+ await closeAdapter(event.reason ?? "stt stream closed; reconnecting");
4872
+ return;
4873
+ }
4874
+ }
4850
4875
  if (event.recoverable === false) {
4851
4876
  await failInternal(new Error(event.reason ?? "Speech-to-text session closed"));
4852
4877
  return;
@@ -5171,6 +5196,7 @@ var createVoiceSession = (options) => {
5171
5196
  });
5172
5197
  };
5173
5198
  const handleFinal = async (transcript) => {
5199
+ sttReconnectCount = 0;
5174
5200
  const session = await writeSession((session2) => {
5175
5201
  const alreadyPresent = session2.currentTurn.transcripts.some((existing) => existing.id === transcript.id);
5176
5202
  if (!alreadyPresent) {
@@ -5919,6 +5919,8 @@ var FALLBACK_CONFIDENCE_SELECTION_DELTA = 0.05;
5919
5919
  var FALLBACK_WORD_COUNT_SELECTION_MARGIN_RATIO = 0.12;
5920
5920
  var EXTENDED_VENDOR_COMMIT_SILENCE_THRESHOLD_MS = 200;
5921
5921
  var MAX_VENDOR_COMMIT_GRACE_MS = 1200;
5922
+ var STT_RECONNECT_FLAP_WINDOW_MS = 4000;
5923
+ var MAX_STT_RECONNECTS_IN_FLAP_WINDOW = 3;
5922
5924
  var DEFAULT_FORMAT = {
5923
5925
  channels: 1,
5924
5926
  container: "raw",
@@ -6159,6 +6161,8 @@ var createVoiceSession = (options) => {
6159
6161
  let operationQueue = Promise.resolve();
6160
6162
  let adapterGenerationCounter = 0;
6161
6163
  let activeAdapterGeneration = 0;
6164
+ let sttReconnectCount = 0;
6165
+ let lastSttReconnectAt = 0;
6162
6166
  let activeTTSTurnId;
6163
6167
  let assistantSpeechEndsAt = 0;
6164
6168
  let lastAssistantAudioAt = 0;
@@ -7045,6 +7049,27 @@ var createVoiceSession = (options) => {
7045
7049
  }
7046
7050
  };
7047
7051
  const handleClose = async (event) => {
7052
+ const session = await readSession();
7053
+ const callLive = session.status !== "completed" && session.status !== "failed";
7054
+ if (callLive && (options.stt || options.realtime)) {
7055
+ const now = Date.now();
7056
+ sttReconnectCount = now - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
7057
+ lastSttReconnectAt = now;
7058
+ if (sttReconnectCount <= MAX_STT_RECONNECTS_IN_FLAP_WINDOW) {
7059
+ await appendTrace({
7060
+ payload: {
7061
+ action: "stt-reconnect",
7062
+ attempt: sttReconnectCount,
7063
+ reason: event.reason ?? "stt stream closed",
7064
+ recoverable: event.recoverable
7065
+ },
7066
+ session,
7067
+ type: "session.error"
7068
+ });
7069
+ await closeAdapter(event.reason ?? "stt stream closed; reconnecting");
7070
+ return;
7071
+ }
7072
+ }
7048
7073
  if (event.recoverable === false) {
7049
7074
  await failInternal(new Error(event.reason ?? "Speech-to-text session closed"));
7050
7075
  return;
@@ -7369,6 +7394,7 @@ var createVoiceSession = (options) => {
7369
7394
  });
7370
7395
  };
7371
7396
  const handleFinal = async (transcript) => {
7397
+ sttReconnectCount = 0;
7372
7398
  const session = await writeSession((session2) => {
7373
7399
  const alreadyPresent = session2.currentTurn.transcripts.some((existing) => existing.id === transcript.id);
7374
7400
  if (!alreadyPresent) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.585",
3
+ "version": "0.0.22-beta.586",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",