@absolutejs/voice 0.0.22-beta.604 → 0.0.22-beta.606
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 +31 -19
- package/dist/testing/index.js +31 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3756,7 +3756,7 @@ var STREAM_CLAUSE_BOUNDARY = /[,;:]\s/g;
|
|
|
3756
3756
|
var MAX_TTS_CHUNK_CHARS = 320;
|
|
3757
3757
|
var STREAM_SENTENCE_END = /[.!?\u2026]['")\]]*$/;
|
|
3758
3758
|
var STREAM_IDLE_FLUSH_MS = 350;
|
|
3759
|
-
var SPECULATIVE_DELAY_MS =
|
|
3759
|
+
var SPECULATIVE_DELAY_MS = 500;
|
|
3760
3760
|
var nextSpeakableBoundary = (buffer) => {
|
|
3761
3761
|
const match = STREAM_SENTENCE_BOUNDARY.exec(buffer);
|
|
3762
3762
|
return match ? match.index + match[0].length : -1;
|
|
@@ -3940,9 +3940,8 @@ var createVoiceSession = (options) => {
|
|
|
3940
3940
|
const complete = Math.max(0, Math.min(1, lastTurnCompleteConfidence));
|
|
3941
3941
|
return Math.round(minSilenceMs + (silenceMs - minSilenceMs) * (1 - complete));
|
|
3942
3942
|
};
|
|
3943
|
-
let
|
|
3943
|
+
let speculation = null;
|
|
3944
3944
|
let speculationAttempted = false;
|
|
3945
|
-
console.info(`[voice][p3dbg] session ${options.id} route.speculate wired=${Boolean(options.route.speculate)}`);
|
|
3946
3945
|
const sttFallback = options.sttFallback ? {
|
|
3947
3946
|
adapter: options.sttFallback.adapter,
|
|
3948
3947
|
completionTimeoutMs: options.sttFallback.completionTimeoutMs ?? DEFAULT_FALLBACK_COMPLETION_TIMEOUT_MS,
|
|
@@ -4476,11 +4475,11 @@ var createVoiceSession = (options) => {
|
|
|
4476
4475
|
}, delayMs);
|
|
4477
4476
|
};
|
|
4478
4477
|
const clearSpeculation = () => {
|
|
4479
|
-
|
|
4478
|
+
speculation = null;
|
|
4480
4479
|
speculationAttempted = false;
|
|
4481
4480
|
};
|
|
4482
4481
|
const runSpeculation = async () => {
|
|
4483
|
-
if (!options.route.speculate ||
|
|
4482
|
+
if (!options.route.speculate || speculation) {
|
|
4484
4483
|
return;
|
|
4485
4484
|
}
|
|
4486
4485
|
const session = await readSession();
|
|
@@ -4497,20 +4496,21 @@ var createVoiceSession = (options) => {
|
|
|
4497
4496
|
text: pendingText,
|
|
4498
4497
|
transcripts: session.currentTurn.transcripts
|
|
4499
4498
|
};
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
} catch (error) {
|
|
4499
|
+
const startedAt = Date.now();
|
|
4500
|
+
const speculate = options.route.speculate;
|
|
4501
|
+
const promise = Promise.resolve(speculate({
|
|
4502
|
+
api,
|
|
4503
|
+
context: options.context,
|
|
4504
|
+
session,
|
|
4505
|
+
turn: provisionalTurn
|
|
4506
|
+
})).then((result) => {
|
|
4507
|
+
console.info(`[voice][p3] speculate done session=${session.id} -> ${result?.text ? `${result.text.length} chars` : "null"} in ${Date.now() - startedAt}ms for "${pendingText.slice(0, 30)}"`);
|
|
4508
|
+
return result && result.text.trim() ? { text: result.text } : null;
|
|
4509
|
+
}).catch((error) => {
|
|
4512
4510
|
console.info(`[voice][p3] speculate error: ${error instanceof Error ? error.message : String(error)}`);
|
|
4513
|
-
|
|
4511
|
+
return null;
|
|
4512
|
+
});
|
|
4513
|
+
speculation = { pendingText, promise };
|
|
4514
4514
|
};
|
|
4515
4515
|
const scheduleSilenceCommit = (delayMs = adaptiveSilenceMs(), reset = true) => {
|
|
4516
4516
|
scheduleTurnCommit(delayMs, "silence", reset);
|
|
@@ -5696,8 +5696,20 @@ var createVoiceSession = (options) => {
|
|
|
5696
5696
|
let committedOutput;
|
|
5697
5697
|
const onTurnStartedAt = Date.now();
|
|
5698
5698
|
logVoiceTiming(session.id, "session.commit-to-onturn", onTurnStartedAt - (turn.committedAt || onTurnStartedAt), { fillerScheduled: fillerTimer !== null });
|
|
5699
|
-
const
|
|
5699
|
+
const pendingSpeculation = speculation;
|
|
5700
5700
|
clearSpeculation();
|
|
5701
|
+
let reusableSpeculation;
|
|
5702
|
+
if (pendingSpeculation && pendingSpeculation.pendingText === turn.text) {
|
|
5703
|
+
const speculated = await pendingSpeculation.promise;
|
|
5704
|
+
if (speculated?.text) {
|
|
5705
|
+
reusableSpeculation = { text: speculated.text };
|
|
5706
|
+
logVoiceTiming(session.id, "p3.adopted-speculation", 0, {
|
|
5707
|
+
chars: speculated.text.length
|
|
5708
|
+
});
|
|
5709
|
+
}
|
|
5710
|
+
} else {
|
|
5711
|
+
pendingSpeculation?.promise;
|
|
5712
|
+
}
|
|
5701
5713
|
try {
|
|
5702
5714
|
const onTurnPromise = options.route.onTurn({
|
|
5703
5715
|
api,
|
package/dist/testing/index.js
CHANGED
|
@@ -5983,7 +5983,7 @@ var STREAM_CLAUSE_BOUNDARY = /[,;:]\s/g;
|
|
|
5983
5983
|
var MAX_TTS_CHUNK_CHARS = 320;
|
|
5984
5984
|
var STREAM_SENTENCE_END = /[.!?\u2026]['")\]]*$/;
|
|
5985
5985
|
var STREAM_IDLE_FLUSH_MS = 350;
|
|
5986
|
-
var SPECULATIVE_DELAY_MS =
|
|
5986
|
+
var SPECULATIVE_DELAY_MS = 500;
|
|
5987
5987
|
var nextSpeakableBoundary = (buffer) => {
|
|
5988
5988
|
const match = STREAM_SENTENCE_BOUNDARY.exec(buffer);
|
|
5989
5989
|
return match ? match.index + match[0].length : -1;
|
|
@@ -6167,9 +6167,8 @@ var createVoiceSession = (options) => {
|
|
|
6167
6167
|
const complete = Math.max(0, Math.min(1, lastTurnCompleteConfidence));
|
|
6168
6168
|
return Math.round(minSilenceMs + (silenceMs - minSilenceMs) * (1 - complete));
|
|
6169
6169
|
};
|
|
6170
|
-
let
|
|
6170
|
+
let speculation = null;
|
|
6171
6171
|
let speculationAttempted = false;
|
|
6172
|
-
console.info(`[voice][p3dbg] session ${options.id} route.speculate wired=${Boolean(options.route.speculate)}`);
|
|
6173
6172
|
const sttFallback = options.sttFallback ? {
|
|
6174
6173
|
adapter: options.sttFallback.adapter,
|
|
6175
6174
|
completionTimeoutMs: options.sttFallback.completionTimeoutMs ?? DEFAULT_FALLBACK_COMPLETION_TIMEOUT_MS,
|
|
@@ -6703,11 +6702,11 @@ var createVoiceSession = (options) => {
|
|
|
6703
6702
|
}, delayMs);
|
|
6704
6703
|
};
|
|
6705
6704
|
const clearSpeculation = () => {
|
|
6706
|
-
|
|
6705
|
+
speculation = null;
|
|
6707
6706
|
speculationAttempted = false;
|
|
6708
6707
|
};
|
|
6709
6708
|
const runSpeculation = async () => {
|
|
6710
|
-
if (!options.route.speculate ||
|
|
6709
|
+
if (!options.route.speculate || speculation) {
|
|
6711
6710
|
return;
|
|
6712
6711
|
}
|
|
6713
6712
|
const session = await readSession();
|
|
@@ -6724,20 +6723,21 @@ var createVoiceSession = (options) => {
|
|
|
6724
6723
|
text: pendingText,
|
|
6725
6724
|
transcripts: session.currentTurn.transcripts
|
|
6726
6725
|
};
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
} catch (error) {
|
|
6726
|
+
const startedAt = Date.now();
|
|
6727
|
+
const speculate = options.route.speculate;
|
|
6728
|
+
const promise = Promise.resolve(speculate({
|
|
6729
|
+
api,
|
|
6730
|
+
context: options.context,
|
|
6731
|
+
session,
|
|
6732
|
+
turn: provisionalTurn
|
|
6733
|
+
})).then((result) => {
|
|
6734
|
+
console.info(`[voice][p3] speculate done session=${session.id} -> ${result?.text ? `${result.text.length} chars` : "null"} in ${Date.now() - startedAt}ms for "${pendingText.slice(0, 30)}"`);
|
|
6735
|
+
return result && result.text.trim() ? { text: result.text } : null;
|
|
6736
|
+
}).catch((error) => {
|
|
6739
6737
|
console.info(`[voice][p3] speculate error: ${error instanceof Error ? error.message : String(error)}`);
|
|
6740
|
-
|
|
6738
|
+
return null;
|
|
6739
|
+
});
|
|
6740
|
+
speculation = { pendingText, promise };
|
|
6741
6741
|
};
|
|
6742
6742
|
const scheduleSilenceCommit = (delayMs = adaptiveSilenceMs(), reset = true) => {
|
|
6743
6743
|
scheduleTurnCommit(delayMs, "silence", reset);
|
|
@@ -7923,8 +7923,20 @@ var createVoiceSession = (options) => {
|
|
|
7923
7923
|
let committedOutput;
|
|
7924
7924
|
const onTurnStartedAt = Date.now();
|
|
7925
7925
|
logVoiceTiming(session.id, "session.commit-to-onturn", onTurnStartedAt - (turn.committedAt || onTurnStartedAt), { fillerScheduled: fillerTimer !== null });
|
|
7926
|
-
const
|
|
7926
|
+
const pendingSpeculation = speculation;
|
|
7927
7927
|
clearSpeculation();
|
|
7928
|
+
let reusableSpeculation;
|
|
7929
|
+
if (pendingSpeculation && pendingSpeculation.pendingText === turn.text) {
|
|
7930
|
+
const speculated = await pendingSpeculation.promise;
|
|
7931
|
+
if (speculated?.text) {
|
|
7932
|
+
reusableSpeculation = { text: speculated.text };
|
|
7933
|
+
logVoiceTiming(session.id, "p3.adopted-speculation", 0, {
|
|
7934
|
+
chars: speculated.text.length
|
|
7935
|
+
});
|
|
7936
|
+
}
|
|
7937
|
+
} else {
|
|
7938
|
+
pendingSpeculation?.promise;
|
|
7939
|
+
}
|
|
7928
7940
|
try {
|
|
7929
7941
|
const onTurnPromise = options.route.onTurn({
|
|
7930
7942
|
api,
|