@absolutejs/voice 0.0.22-beta.640 → 0.0.22-beta.642
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 +18 -20
- package/dist/testing/index.js +32 -23
- package/package.json +1 -1
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
|
}
|
|
@@ -5030,7 +5022,7 @@ var createVoiceSession = (options) => {
|
|
|
5030
5022
|
}
|
|
5031
5023
|
await commitTurnInternal(reason);
|
|
5032
5024
|
};
|
|
5033
|
-
const failInternal = async (error) => {
|
|
5025
|
+
const failInternal = async (error, code) => {
|
|
5034
5026
|
clearSilenceTimer();
|
|
5035
5027
|
let didFail = false;
|
|
5036
5028
|
const session = await writeSession((currentSession) => {
|
|
@@ -5054,6 +5046,7 @@ var createVoiceSession = (options) => {
|
|
|
5054
5046
|
const resolvedError = toError(error);
|
|
5055
5047
|
await appendTrace({
|
|
5056
5048
|
payload: {
|
|
5049
|
+
...code === undefined ? {} : { code },
|
|
5057
5050
|
error: resolvedError.message,
|
|
5058
5051
|
recoverable: false
|
|
5059
5052
|
},
|
|
@@ -5369,6 +5362,10 @@ var createVoiceSession = (options) => {
|
|
|
5369
5362
|
});
|
|
5370
5363
|
};
|
|
5371
5364
|
const handleError = async (event) => {
|
|
5365
|
+
if (!event.recoverable) {
|
|
5366
|
+
await failInternal(event.error, event.code);
|
|
5367
|
+
return;
|
|
5368
|
+
}
|
|
5372
5369
|
await appendTrace({
|
|
5373
5370
|
payload: {
|
|
5374
5371
|
code: event.code,
|
|
@@ -5382,9 +5379,6 @@ var createVoiceSession = (options) => {
|
|
|
5382
5379
|
recoverable: event.recoverable,
|
|
5383
5380
|
type: "error"
|
|
5384
5381
|
});
|
|
5385
|
-
if (!event.recoverable) {
|
|
5386
|
-
await failInternal(event.error);
|
|
5387
|
-
}
|
|
5388
5382
|
};
|
|
5389
5383
|
const handleClose = async (event) => {
|
|
5390
5384
|
const session = await readSession();
|
|
@@ -5673,6 +5667,7 @@ var createVoiceSession = (options) => {
|
|
|
5673
5667
|
};
|
|
5674
5668
|
};
|
|
5675
5669
|
const handlePartial = async (transcript) => {
|
|
5670
|
+
sttDeafConfirmedAt = 0;
|
|
5676
5671
|
if (transcript.text.trim()) {
|
|
5677
5672
|
kickStuckCloseWatchdog();
|
|
5678
5673
|
kickIdleRepromptWatchdog(true);
|
|
@@ -5771,6 +5766,7 @@ var createVoiceSession = (options) => {
|
|
|
5771
5766
|
};
|
|
5772
5767
|
const handleFinal = async (transcript) => {
|
|
5773
5768
|
sttReconnectCount = 0;
|
|
5769
|
+
sttDeafConfirmedAt = 0;
|
|
5774
5770
|
if (backchannelBargeInGuard && backchannelSuppressedAt !== null && Date.now() - backchannelSuppressedAt < BACKCHANNEL_DROP_WINDOW_MS && isBackchannelUtterance(transcript.text.trim())) {
|
|
5775
5771
|
backchannelSuppressedAt = null;
|
|
5776
5772
|
return;
|
|
@@ -6985,6 +6981,7 @@ var createVoiceSession = (options) => {
|
|
|
6985
6981
|
lastSpeechEnergyAt = nowMs;
|
|
6986
6982
|
const lastTranscriptAt = latest.currentTurn.lastTranscriptAt ?? 0;
|
|
6987
6983
|
if (!options.realtime && sttSession && lastTranscriptAt < sttHealthPhaseStart && nowMs - sttHealthPhaseStart >= STT_HEALTH_STALE_MS) {
|
|
6984
|
+
sttDeafConfirmedAt = nowMs;
|
|
6988
6985
|
sttReconnectCount = nowMs - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
|
|
6989
6986
|
lastSttReconnectAt = nowMs;
|
|
6990
6987
|
sttHealthPhaseStart = nowMs;
|
|
@@ -6994,6 +6991,7 @@ var createVoiceSession = (options) => {
|
|
|
6994
6991
|
payload: {
|
|
6995
6992
|
action: "stt-health-reconnect",
|
|
6996
6993
|
attempt: sttReconnectCount,
|
|
6994
|
+
classification: "stt-deaf",
|
|
6997
6995
|
reason: `no transcript for ${STT_HEALTH_STALE_MS}ms of continuous speech`
|
|
6998
6996
|
},
|
|
6999
6997
|
session: latest,
|
package/dist/testing/index.js
CHANGED
|
@@ -328,7 +328,12 @@ var applyVoiceAudioCondition = (fixture, condition) => {
|
|
|
328
328
|
for (let index = 0;index < output.length; index += 1)
|
|
329
329
|
output[index] = clamp(output[index] + random() * Math.sqrt(3) * noiseRms);
|
|
330
330
|
}
|
|
331
|
-
return {
|
|
331
|
+
return {
|
|
332
|
+
...fixture,
|
|
333
|
+
audio: bytes(output),
|
|
334
|
+
id: `${fixture.id}--${condition.id}`,
|
|
335
|
+
tags: [...fixture.tags ?? [], "conditioned", condition.id]
|
|
336
|
+
};
|
|
332
337
|
};
|
|
333
338
|
var buildVoiceAudioMatrix = (fixtures, conditions) => fixtures.flatMap((fixture) => conditions.map((condition) => applyVoiceAudioCondition(fixture, condition)));
|
|
334
339
|
// src/testing/stt.ts
|
|
@@ -6005,9 +6010,15 @@ var stableBenchmarkJson = (value) => {
|
|
|
6005
6010
|
};
|
|
6006
6011
|
var buildVoiceBenchmarkArtifact = (manifest, report) => {
|
|
6007
6012
|
const payload = { manifest, report };
|
|
6008
|
-
return {
|
|
6013
|
+
return {
|
|
6014
|
+
...payload,
|
|
6015
|
+
artifactSha256: sha256Bytes(stableBenchmarkJson(payload))
|
|
6016
|
+
};
|
|
6009
6017
|
};
|
|
6010
|
-
var verifyVoiceBenchmarkArtifact = (artifact) => artifact.artifactSha256 === sha256Bytes(stableBenchmarkJson({
|
|
6018
|
+
var verifyVoiceBenchmarkArtifact = (artifact) => artifact.artifactSha256 === sha256Bytes(stableBenchmarkJson({
|
|
6019
|
+
manifest: artifact.manifest,
|
|
6020
|
+
report: artifact.report
|
|
6021
|
+
}));
|
|
6011
6022
|
// src/core/memoryStore.ts
|
|
6012
6023
|
var createVoiceMemoryStore = () => {
|
|
6013
6024
|
const sessions = new Map;
|
|
@@ -6929,6 +6940,7 @@ var createVoiceSession = (options) => {
|
|
|
6929
6940
|
let lastSttReconnectAt = 0;
|
|
6930
6941
|
let lastSpeechEnergyAt = 0;
|
|
6931
6942
|
let sttHealthPhaseStart = 0;
|
|
6943
|
+
let sttDeafConfirmedAt = 0;
|
|
6932
6944
|
let lastSttRecoverySpokenAt = 0;
|
|
6933
6945
|
let activeTTSTurnId;
|
|
6934
6946
|
let assistantSpeechEndsAt = 0;
|
|
@@ -7063,30 +7075,21 @@ var createVoiceSession = (options) => {
|
|
|
7063
7075
|
stuckCloseFired = true;
|
|
7064
7076
|
const reason = `no caller progress for ${stuckCloseAfterMs}ms`;
|
|
7065
7077
|
const { lastSpeechAt, lastTranscriptAt } = snapshot.currentTurn;
|
|
7066
|
-
const
|
|
7078
|
+
const sttDeafConfirmed = sttDeafConfirmedAt > 0 && (lastTranscriptAt === undefined || sttDeafConfirmedAt > lastTranscriptAt);
|
|
7067
7079
|
const diagnostic = {
|
|
7068
7080
|
action: "stuck-call-close",
|
|
7069
|
-
classification:
|
|
7081
|
+
classification: sttDeafConfirmed ? "stt-deaf" : "caller-idle",
|
|
7070
7082
|
lastAudioAt: snapshot.currentTurn.lastAudioAt,
|
|
7071
7083
|
lastSpeechAt,
|
|
7072
7084
|
lastTranscriptAt,
|
|
7073
7085
|
reason,
|
|
7074
7086
|
turnCount: snapshot.turns.length
|
|
7075
7087
|
};
|
|
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
|
-
}
|
|
7088
|
+
await appendTrace({
|
|
7089
|
+
payload: diagnostic,
|
|
7090
|
+
session: snapshot,
|
|
7091
|
+
type: "call.lifecycle"
|
|
7092
|
+
});
|
|
7090
7093
|
if (stuckCloseConfig?.line) {
|
|
7091
7094
|
await speakResolvedLine(stuckCloseConfig.line, snapshot);
|
|
7092
7095
|
}
|
|
@@ -7662,7 +7665,7 @@ var createVoiceSession = (options) => {
|
|
|
7662
7665
|
}
|
|
7663
7666
|
await commitTurnInternal(reason);
|
|
7664
7667
|
};
|
|
7665
|
-
const failInternal = async (error) => {
|
|
7668
|
+
const failInternal = async (error, code) => {
|
|
7666
7669
|
clearSilenceTimer();
|
|
7667
7670
|
let didFail = false;
|
|
7668
7671
|
const session = await writeSession((currentSession) => {
|
|
@@ -7686,6 +7689,7 @@ var createVoiceSession = (options) => {
|
|
|
7686
7689
|
const resolvedError = toError(error);
|
|
7687
7690
|
await appendTrace({
|
|
7688
7691
|
payload: {
|
|
7692
|
+
...code === undefined ? {} : { code },
|
|
7689
7693
|
error: resolvedError.message,
|
|
7690
7694
|
recoverable: false
|
|
7691
7695
|
},
|
|
@@ -8001,6 +8005,10 @@ var createVoiceSession = (options) => {
|
|
|
8001
8005
|
});
|
|
8002
8006
|
};
|
|
8003
8007
|
const handleError = async (event) => {
|
|
8008
|
+
if (!event.recoverable) {
|
|
8009
|
+
await failInternal(event.error, event.code);
|
|
8010
|
+
return;
|
|
8011
|
+
}
|
|
8004
8012
|
await appendTrace({
|
|
8005
8013
|
payload: {
|
|
8006
8014
|
code: event.code,
|
|
@@ -8014,9 +8022,6 @@ var createVoiceSession = (options) => {
|
|
|
8014
8022
|
recoverable: event.recoverable,
|
|
8015
8023
|
type: "error"
|
|
8016
8024
|
});
|
|
8017
|
-
if (!event.recoverable) {
|
|
8018
|
-
await failInternal(event.error);
|
|
8019
|
-
}
|
|
8020
8025
|
};
|
|
8021
8026
|
const handleClose = async (event) => {
|
|
8022
8027
|
const session = await readSession();
|
|
@@ -8305,6 +8310,7 @@ var createVoiceSession = (options) => {
|
|
|
8305
8310
|
};
|
|
8306
8311
|
};
|
|
8307
8312
|
const handlePartial = async (transcript) => {
|
|
8313
|
+
sttDeafConfirmedAt = 0;
|
|
8308
8314
|
if (transcript.text.trim()) {
|
|
8309
8315
|
kickStuckCloseWatchdog();
|
|
8310
8316
|
kickIdleRepromptWatchdog(true);
|
|
@@ -8403,6 +8409,7 @@ var createVoiceSession = (options) => {
|
|
|
8403
8409
|
};
|
|
8404
8410
|
const handleFinal = async (transcript) => {
|
|
8405
8411
|
sttReconnectCount = 0;
|
|
8412
|
+
sttDeafConfirmedAt = 0;
|
|
8406
8413
|
if (backchannelBargeInGuard && backchannelSuppressedAt !== null && Date.now() - backchannelSuppressedAt < BACKCHANNEL_DROP_WINDOW_MS && isBackchannelUtterance(transcript.text.trim())) {
|
|
8407
8414
|
backchannelSuppressedAt = null;
|
|
8408
8415
|
return;
|
|
@@ -9617,6 +9624,7 @@ var createVoiceSession = (options) => {
|
|
|
9617
9624
|
lastSpeechEnergyAt = nowMs;
|
|
9618
9625
|
const lastTranscriptAt = latest.currentTurn.lastTranscriptAt ?? 0;
|
|
9619
9626
|
if (!options.realtime && sttSession && lastTranscriptAt < sttHealthPhaseStart && nowMs - sttHealthPhaseStart >= STT_HEALTH_STALE_MS) {
|
|
9627
|
+
sttDeafConfirmedAt = nowMs;
|
|
9620
9628
|
sttReconnectCount = nowMs - lastSttReconnectAt < STT_RECONNECT_FLAP_WINDOW_MS ? sttReconnectCount + 1 : 1;
|
|
9621
9629
|
lastSttReconnectAt = nowMs;
|
|
9622
9630
|
sttHealthPhaseStart = nowMs;
|
|
@@ -9626,6 +9634,7 @@ var createVoiceSession = (options) => {
|
|
|
9626
9634
|
payload: {
|
|
9627
9635
|
action: "stt-health-reconnect",
|
|
9628
9636
|
attempt: sttReconnectCount,
|
|
9637
|
+
classification: "stt-deaf",
|
|
9629
9638
|
reason: `no transcript for ${STT_HEALTH_STALE_MS}ms of continuous speech`
|
|
9630
9639
|
},
|
|
9631
9640
|
session: latest,
|