@absolutejs/voice 0.0.22-beta.641 → 0.0.22-beta.643
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/core/hardenedFetch.d.ts +1 -3
- package/dist/index.js +27 -26
- package/dist/testing/index.js +27 -26
- package/package.json +3 -3
|
@@ -1,3 +1 @@
|
|
|
1
|
-
export declare const hardenFetch: (baseFetch?: typeof fetch) => (
|
|
2
|
-
preconnect: typeof fetch.preconnect;
|
|
3
|
-
};
|
|
1
|
+
export declare const hardenFetch: (baseFetch?: typeof fetch) => (input: Parameters<typeof fetch>[0], init: Parameters<typeof fetch>[1]) => Promise<Response>;
|
package/dist/index.js
CHANGED
|
@@ -4297,6 +4297,7 @@ var createVoiceSession = (options) => {
|
|
|
4297
4297
|
let lastSttReconnectAt = 0;
|
|
4298
4298
|
let lastSpeechEnergyAt = 0;
|
|
4299
4299
|
let sttHealthPhaseStart = 0;
|
|
4300
|
+
let sttDeafConfirmedAt = 0;
|
|
4300
4301
|
let lastSttRecoverySpokenAt = 0;
|
|
4301
4302
|
let activeTTSTurnId;
|
|
4302
4303
|
let assistantSpeechEndsAt = 0;
|
|
@@ -4431,30 +4432,21 @@ var createVoiceSession = (options) => {
|
|
|
4431
4432
|
stuckCloseFired = true;
|
|
4432
4433
|
const reason = `no caller progress for ${stuckCloseAfterMs}ms`;
|
|
4433
4434
|
const { lastSpeechAt, lastTranscriptAt } = snapshot.currentTurn;
|
|
4434
|
-
const
|
|
4435
|
+
const sttDeafConfirmed = sttDeafConfirmedAt > 0 && (lastTranscriptAt === undefined || sttDeafConfirmedAt > lastTranscriptAt);
|
|
4435
4436
|
const diagnostic = {
|
|
4436
4437
|
action: "stuck-call-close",
|
|
4437
|
-
classification:
|
|
4438
|
+
classification: sttDeafConfirmed ? "stt-deaf" : "caller-idle",
|
|
4438
4439
|
lastAudioAt: snapshot.currentTurn.lastAudioAt,
|
|
4439
4440
|
lastSpeechAt,
|
|
4440
4441
|
lastTranscriptAt,
|
|
4441
4442
|
reason,
|
|
4442
4443
|
turnCount: snapshot.turns.length
|
|
4443
4444
|
};
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
type: "session.error"
|
|
4450
|
-
});
|
|
4451
|
-
} else {
|
|
4452
|
-
await appendTrace({
|
|
4453
|
-
payload: diagnostic,
|
|
4454
|
-
session: snapshot,
|
|
4455
|
-
type: "call.lifecycle"
|
|
4456
|
-
});
|
|
4457
|
-
}
|
|
4445
|
+
await appendTrace({
|
|
4446
|
+
payload: diagnostic,
|
|
4447
|
+
session: snapshot,
|
|
4448
|
+
type: "call.lifecycle"
|
|
4449
|
+
});
|
|
4458
4450
|
if (stuckCloseConfig?.line) {
|
|
4459
4451
|
await speakResolvedLine(stuckCloseConfig.line, snapshot);
|
|
4460
4452
|
}
|
|
@@ -5675,6 +5667,7 @@ var createVoiceSession = (options) => {
|
|
|
5675
5667
|
};
|
|
5676
5668
|
};
|
|
5677
5669
|
const handlePartial = async (transcript) => {
|
|
5670
|
+
sttDeafConfirmedAt = 0;
|
|
5678
5671
|
if (transcript.text.trim()) {
|
|
5679
5672
|
kickStuckCloseWatchdog();
|
|
5680
5673
|
kickIdleRepromptWatchdog(true);
|
|
@@ -5773,6 +5766,7 @@ var createVoiceSession = (options) => {
|
|
|
5773
5766
|
};
|
|
5774
5767
|
const handleFinal = async (transcript) => {
|
|
5775
5768
|
sttReconnectCount = 0;
|
|
5769
|
+
sttDeafConfirmedAt = 0;
|
|
5776
5770
|
if (backchannelBargeInGuard && backchannelSuppressedAt !== null && Date.now() - backchannelSuppressedAt < BACKCHANNEL_DROP_WINDOW_MS && isBackchannelUtterance(transcript.text.trim())) {
|
|
5777
5771
|
backchannelSuppressedAt = null;
|
|
5778
5772
|
return;
|
|
@@ -6987,6 +6981,7 @@ var createVoiceSession = (options) => {
|
|
|
6987
6981
|
lastSpeechEnergyAt = nowMs;
|
|
6988
6982
|
const lastTranscriptAt = latest.currentTurn.lastTranscriptAt ?? 0;
|
|
6989
6983
|
if (!options.realtime && sttSession && lastTranscriptAt < sttHealthPhaseStart && nowMs - sttHealthPhaseStart >= STT_HEALTH_STALE_MS) {
|
|
6984
|
+
sttDeafConfirmedAt = nowMs;
|
|
6990
6985
|
sttReconnectCount = nowMs - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
|
|
6991
6986
|
lastSttReconnectAt = nowMs;
|
|
6992
6987
|
sttHealthPhaseStart = nowMs;
|
|
@@ -6996,6 +6991,7 @@ var createVoiceSession = (options) => {
|
|
|
6996
6991
|
payload: {
|
|
6997
6992
|
action: "stt-health-reconnect",
|
|
6998
6993
|
attempt: sttReconnectCount,
|
|
6994
|
+
classification: "stt-deaf",
|
|
6999
6995
|
reason: `no transcript for ${STT_HEALTH_STALE_MS}ms of continuous speech`
|
|
7000
6996
|
},
|
|
7001
6997
|
session: latest,
|
|
@@ -41824,16 +41820,21 @@ var oneAttempt = async (baseFetch, input, init) => {
|
|
|
41824
41820
|
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
41825
41821
|
}
|
|
41826
41822
|
};
|
|
41827
|
-
var hardenFetch = (baseFetch = globalThis.fetch) =>
|
|
41828
|
-
|
|
41829
|
-
|
|
41830
|
-
|
|
41831
|
-
|
|
41832
|
-
|
|
41833
|
-
|
|
41834
|
-
|
|
41835
|
-
|
|
41836
|
-
}
|
|
41823
|
+
var hardenFetch = (baseFetch = globalThis.fetch) => {
|
|
41824
|
+
const hardenedFetch = async (input, init) => {
|
|
41825
|
+
try {
|
|
41826
|
+
return await oneAttempt(baseFetch, input, init);
|
|
41827
|
+
} catch (error) {
|
|
41828
|
+
if (init?.signal?.aborted)
|
|
41829
|
+
throw error;
|
|
41830
|
+
console.warn(`[voice] hardened fetch retrying on a fresh connection: ${error instanceof Error ? error.message : String(error)}`);
|
|
41831
|
+
return oneAttempt(baseFetch, input, init);
|
|
41832
|
+
}
|
|
41833
|
+
};
|
|
41834
|
+
return typeof baseFetch.preconnect === "function" ? Object.assign(hardenedFetch, {
|
|
41835
|
+
preconnect: baseFetch.preconnect.bind(baseFetch)
|
|
41836
|
+
}) : hardenedFetch;
|
|
41837
|
+
};
|
|
41837
41838
|
// src/core/mcpToolset.ts
|
|
41838
41839
|
var flattenContent = (result) => {
|
|
41839
41840
|
const blocks = result.content ?? [];
|
package/dist/testing/index.js
CHANGED
|
@@ -4754,16 +4754,21 @@ var oneAttempt = async (baseFetch, input, init) => {
|
|
|
4754
4754
|
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
4755
4755
|
}
|
|
4756
4756
|
};
|
|
4757
|
-
var hardenFetch = (baseFetch = globalThis.fetch) =>
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
}
|
|
4757
|
+
var hardenFetch = (baseFetch = globalThis.fetch) => {
|
|
4758
|
+
const hardenedFetch = async (input, init) => {
|
|
4759
|
+
try {
|
|
4760
|
+
return await oneAttempt(baseFetch, input, init);
|
|
4761
|
+
} catch (error) {
|
|
4762
|
+
if (init?.signal?.aborted)
|
|
4763
|
+
throw error;
|
|
4764
|
+
console.warn(`[voice] hardened fetch retrying on a fresh connection: ${error instanceof Error ? error.message : String(error)}`);
|
|
4765
|
+
return oneAttempt(baseFetch, input, init);
|
|
4766
|
+
}
|
|
4767
|
+
};
|
|
4768
|
+
return typeof baseFetch.preconnect === "function" ? Object.assign(hardenedFetch, {
|
|
4769
|
+
preconnect: baseFetch.preconnect.bind(baseFetch)
|
|
4770
|
+
}) : hardenedFetch;
|
|
4771
|
+
};
|
|
4767
4772
|
|
|
4768
4773
|
// src/core/modelAdapters.ts
|
|
4769
4774
|
var normalizeVoiceUsage = (provider, model, raw) => {
|
|
@@ -6929,6 +6934,7 @@ var createVoiceSession = (options) => {
|
|
|
6929
6934
|
let lastSttReconnectAt = 0;
|
|
6930
6935
|
let lastSpeechEnergyAt = 0;
|
|
6931
6936
|
let sttHealthPhaseStart = 0;
|
|
6937
|
+
let sttDeafConfirmedAt = 0;
|
|
6932
6938
|
let lastSttRecoverySpokenAt = 0;
|
|
6933
6939
|
let activeTTSTurnId;
|
|
6934
6940
|
let assistantSpeechEndsAt = 0;
|
|
@@ -7063,30 +7069,21 @@ var createVoiceSession = (options) => {
|
|
|
7063
7069
|
stuckCloseFired = true;
|
|
7064
7070
|
const reason = `no caller progress for ${stuckCloseAfterMs}ms`;
|
|
7065
7071
|
const { lastSpeechAt, lastTranscriptAt } = snapshot.currentTurn;
|
|
7066
|
-
const
|
|
7072
|
+
const sttDeafConfirmed = sttDeafConfirmedAt > 0 && (lastTranscriptAt === undefined || sttDeafConfirmedAt > lastTranscriptAt);
|
|
7067
7073
|
const diagnostic = {
|
|
7068
7074
|
action: "stuck-call-close",
|
|
7069
|
-
classification:
|
|
7075
|
+
classification: sttDeafConfirmed ? "stt-deaf" : "caller-idle",
|
|
7070
7076
|
lastAudioAt: snapshot.currentTurn.lastAudioAt,
|
|
7071
7077
|
lastSpeechAt,
|
|
7072
7078
|
lastTranscriptAt,
|
|
7073
7079
|
reason,
|
|
7074
7080
|
turnCount: snapshot.turns.length
|
|
7075
7081
|
};
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
type: "session.error"
|
|
7082
|
-
});
|
|
7083
|
-
} else {
|
|
7084
|
-
await appendTrace({
|
|
7085
|
-
payload: diagnostic,
|
|
7086
|
-
session: snapshot,
|
|
7087
|
-
type: "call.lifecycle"
|
|
7088
|
-
});
|
|
7089
|
-
}
|
|
7082
|
+
await appendTrace({
|
|
7083
|
+
payload: diagnostic,
|
|
7084
|
+
session: snapshot,
|
|
7085
|
+
type: "call.lifecycle"
|
|
7086
|
+
});
|
|
7090
7087
|
if (stuckCloseConfig?.line) {
|
|
7091
7088
|
await speakResolvedLine(stuckCloseConfig.line, snapshot);
|
|
7092
7089
|
}
|
|
@@ -8307,6 +8304,7 @@ var createVoiceSession = (options) => {
|
|
|
8307
8304
|
};
|
|
8308
8305
|
};
|
|
8309
8306
|
const handlePartial = async (transcript) => {
|
|
8307
|
+
sttDeafConfirmedAt = 0;
|
|
8310
8308
|
if (transcript.text.trim()) {
|
|
8311
8309
|
kickStuckCloseWatchdog();
|
|
8312
8310
|
kickIdleRepromptWatchdog(true);
|
|
@@ -8405,6 +8403,7 @@ var createVoiceSession = (options) => {
|
|
|
8405
8403
|
};
|
|
8406
8404
|
const handleFinal = async (transcript) => {
|
|
8407
8405
|
sttReconnectCount = 0;
|
|
8406
|
+
sttDeafConfirmedAt = 0;
|
|
8408
8407
|
if (backchannelBargeInGuard && backchannelSuppressedAt !== null && Date.now() - backchannelSuppressedAt < BACKCHANNEL_DROP_WINDOW_MS && isBackchannelUtterance(transcript.text.trim())) {
|
|
8409
8408
|
backchannelSuppressedAt = null;
|
|
8410
8409
|
return;
|
|
@@ -9619,6 +9618,7 @@ var createVoiceSession = (options) => {
|
|
|
9619
9618
|
lastSpeechEnergyAt = nowMs;
|
|
9620
9619
|
const lastTranscriptAt = latest.currentTurn.lastTranscriptAt ?? 0;
|
|
9621
9620
|
if (!options.realtime && sttSession && lastTranscriptAt < sttHealthPhaseStart && nowMs - sttHealthPhaseStart >= STT_HEALTH_STALE_MS) {
|
|
9621
|
+
sttDeafConfirmedAt = nowMs;
|
|
9622
9622
|
sttReconnectCount = nowMs - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
|
|
9623
9623
|
lastSttReconnectAt = nowMs;
|
|
9624
9624
|
sttHealthPhaseStart = nowMs;
|
|
@@ -9628,6 +9628,7 @@ var createVoiceSession = (options) => {
|
|
|
9628
9628
|
payload: {
|
|
9629
9629
|
action: "stt-health-reconnect",
|
|
9630
9630
|
attempt: sttReconnectCount,
|
|
9631
|
+
classification: "stt-deaf",
|
|
9631
9632
|
reason: `no transcript for ${STT_HEALTH_STALE_MS}ms of continuous speech`
|
|
9632
9633
|
},
|
|
9633
9634
|
session: latest,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absolutejs/voice",
|
|
3
|
-
"version": "0.0.22-beta.
|
|
3
|
+
"version": "0.0.22-beta.643",
|
|
4
4
|
"description": "Voice primitives and Elysia plugin for AbsoluteJS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"@absolutejs/absolute": ">=0.19.0-beta.646",
|
|
118
118
|
"@absolutejs/ai": ">=0.0.5",
|
|
119
119
|
"@angular/core": ">=21.0.0",
|
|
120
|
-
"drizzle-orm": ">=1.0.0-rc.
|
|
120
|
+
"drizzle-orm": ">=1.0.0-rc.4 <2",
|
|
121
121
|
"elysia": ">=1.4.18",
|
|
122
122
|
"react": ">=19.0.0",
|
|
123
123
|
"vue": ">=3.5.0"
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
"@types/bun": "1.3.9",
|
|
155
155
|
"@types/react": "19.2.0",
|
|
156
156
|
"@typescript-eslint/parser": "^8.57.2",
|
|
157
|
-
"drizzle-orm": "1.0.0-rc.
|
|
157
|
+
"drizzle-orm": "1.0.0-rc.4",
|
|
158
158
|
"elysia": "1.4.18",
|
|
159
159
|
"eslint": "^10.1.0",
|
|
160
160
|
"eslint-plugin-absolute": "0.11.0-beta.3",
|