@absolutejs/voice 0.0.22-beta.608 → 0.0.22-beta.609
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/agent.d.ts +2 -0
- package/dist/core/types.d.ts +1 -0
- package/dist/index.js +20 -7
- package/dist/testing/index.js +18 -6
- package/package.json +1 -1
package/dist/core/agent.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ export type VoiceAgentModelInput<TContext = unknown, TSession extends VoiceSessi
|
|
|
63
63
|
onTextDelta?: (delta: string) => void;
|
|
64
64
|
session: TSession;
|
|
65
65
|
system?: string;
|
|
66
|
+
signal?: AbortSignal;
|
|
66
67
|
tools: Array<{
|
|
67
68
|
description?: string;
|
|
68
69
|
name: string;
|
|
@@ -148,6 +149,7 @@ export type VoiceAgent<TContext = unknown, TSession extends VoiceSessionRecord =
|
|
|
148
149
|
session: TSession;
|
|
149
150
|
system?: string;
|
|
150
151
|
turn: VoiceTurnRecord;
|
|
152
|
+
signal?: AbortSignal;
|
|
151
153
|
}) => Promise<{
|
|
152
154
|
text: string;
|
|
153
155
|
} | null>;
|
package/dist/core/types.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -3851,6 +3851,7 @@ var MAX_TTS_CHUNK_CHARS = 320;
|
|
|
3851
3851
|
var STREAM_SENTENCE_END = /[.!?\u2026]['")\]]*$/;
|
|
3852
3852
|
var STREAM_IDLE_FLUSH_MS = 350;
|
|
3853
3853
|
var SPECULATIVE_DELAY_MS = 500;
|
|
3854
|
+
var SPECULATION_ADOPT_TIMEOUT_MS = 6000;
|
|
3854
3855
|
var BACKCHANNEL_DROP_WINDOW_MS = 2000;
|
|
3855
3856
|
var nextSpeakableBoundary = (buffer) => {
|
|
3856
3857
|
const match = STREAM_SENTENCE_BOUNDARY.exec(buffer);
|
|
@@ -4572,6 +4573,7 @@ var createVoiceSession = (options) => {
|
|
|
4572
4573
|
}, delayMs);
|
|
4573
4574
|
};
|
|
4574
4575
|
const clearSpeculation = () => {
|
|
4576
|
+
speculation?.controller.abort();
|
|
4575
4577
|
speculation = null;
|
|
4576
4578
|
speculationAttempted = false;
|
|
4577
4579
|
};
|
|
@@ -4594,16 +4596,18 @@ var createVoiceSession = (options) => {
|
|
|
4594
4596
|
transcripts: session.currentTurn.transcripts
|
|
4595
4597
|
};
|
|
4596
4598
|
const speculate = options.route.speculate;
|
|
4599
|
+
const controller = new AbortController;
|
|
4597
4600
|
const promise = Promise.resolve(speculate({
|
|
4598
4601
|
api,
|
|
4599
4602
|
context: options.context,
|
|
4600
4603
|
session,
|
|
4601
|
-
turn: provisionalTurn
|
|
4604
|
+
turn: provisionalTurn,
|
|
4605
|
+
signal: controller.signal
|
|
4602
4606
|
})).then((result) => result && result.text.trim() ? { text: result.text } : null).catch((error) => {
|
|
4603
4607
|
console.info(`[voice][p3] speculate error session=${session.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
4604
4608
|
return null;
|
|
4605
4609
|
});
|
|
4606
|
-
speculation = { pendingText, promise };
|
|
4610
|
+
speculation = { controller, pendingText, promise };
|
|
4607
4611
|
};
|
|
4608
4612
|
const scheduleSilenceCommit = (delayMs = adaptiveSilenceMs(), reset = true) => {
|
|
4609
4613
|
scheduleTurnCommit(delayMs, "silence", reset);
|
|
@@ -5807,18 +5811,26 @@ var createVoiceSession = (options) => {
|
|
|
5807
5811
|
const onTurnStartedAt = Date.now();
|
|
5808
5812
|
logVoiceTiming(session.id, "session.commit-to-onturn", onTurnStartedAt - (turn.committedAt || onTurnStartedAt), { fillerScheduled: fillerTimer !== null });
|
|
5809
5813
|
const pendingSpeculation = speculation;
|
|
5810
|
-
|
|
5814
|
+
speculation = null;
|
|
5815
|
+
speculationAttempted = false;
|
|
5811
5816
|
let reusableSpeculation;
|
|
5812
5817
|
if (pendingSpeculation && pendingSpeculation.pendingText === turn.text) {
|
|
5813
|
-
const speculated = await
|
|
5818
|
+
const speculated = await Promise.race([
|
|
5819
|
+
pendingSpeculation.promise,
|
|
5820
|
+
new Promise((resolve) => {
|
|
5821
|
+
setTimeout(() => resolve(null), SPECULATION_ADOPT_TIMEOUT_MS);
|
|
5822
|
+
})
|
|
5823
|
+
]);
|
|
5814
5824
|
if (speculated?.text) {
|
|
5815
5825
|
reusableSpeculation = { text: speculated.text };
|
|
5816
5826
|
logVoiceTiming(session.id, "p3.adopted-speculation", 0, {
|
|
5817
5827
|
chars: speculated.text.length
|
|
5818
5828
|
});
|
|
5829
|
+
} else {
|
|
5830
|
+
pendingSpeculation.controller.abort();
|
|
5819
5831
|
}
|
|
5820
|
-
} else {
|
|
5821
|
-
pendingSpeculation
|
|
5832
|
+
} else if (pendingSpeculation) {
|
|
5833
|
+
pendingSpeculation.controller.abort();
|
|
5822
5834
|
}
|
|
5823
5835
|
try {
|
|
5824
5836
|
const onTurnPromise = options.route.onTurn({
|
|
@@ -8103,6 +8115,7 @@ var createVoiceAgent = (options) => {
|
|
|
8103
8115
|
context: input.context,
|
|
8104
8116
|
messages,
|
|
8105
8117
|
session: input.session,
|
|
8118
|
+
signal: input.signal,
|
|
8106
8119
|
system,
|
|
8107
8120
|
tools: [...LIFECYCLE_TOOLS, ...toolMap.values()].map((tool) => ({
|
|
8108
8121
|
description: tool.description,
|
|
@@ -41372,7 +41385,7 @@ var createAIVoiceModel = (options) => ({
|
|
|
41372
41385
|
const stream = options.provider.stream({
|
|
41373
41386
|
messages: toProviderMessages(input.messages),
|
|
41374
41387
|
model: options.model,
|
|
41375
|
-
signal: options.signal,
|
|
41388
|
+
signal: input.signal ?? options.signal,
|
|
41376
41389
|
systemPrompt,
|
|
41377
41390
|
tools: toProviderTools(input.tools)
|
|
41378
41391
|
});
|
package/dist/testing/index.js
CHANGED
|
@@ -6078,6 +6078,7 @@ var MAX_TTS_CHUNK_CHARS = 320;
|
|
|
6078
6078
|
var STREAM_SENTENCE_END = /[.!?\u2026]['")\]]*$/;
|
|
6079
6079
|
var STREAM_IDLE_FLUSH_MS = 350;
|
|
6080
6080
|
var SPECULATIVE_DELAY_MS = 500;
|
|
6081
|
+
var SPECULATION_ADOPT_TIMEOUT_MS = 6000;
|
|
6081
6082
|
var BACKCHANNEL_DROP_WINDOW_MS = 2000;
|
|
6082
6083
|
var nextSpeakableBoundary = (buffer) => {
|
|
6083
6084
|
const match = STREAM_SENTENCE_BOUNDARY.exec(buffer);
|
|
@@ -6799,6 +6800,7 @@ var createVoiceSession = (options) => {
|
|
|
6799
6800
|
}, delayMs);
|
|
6800
6801
|
};
|
|
6801
6802
|
const clearSpeculation = () => {
|
|
6803
|
+
speculation?.controller.abort();
|
|
6802
6804
|
speculation = null;
|
|
6803
6805
|
speculationAttempted = false;
|
|
6804
6806
|
};
|
|
@@ -6821,16 +6823,18 @@ var createVoiceSession = (options) => {
|
|
|
6821
6823
|
transcripts: session.currentTurn.transcripts
|
|
6822
6824
|
};
|
|
6823
6825
|
const speculate = options.route.speculate;
|
|
6826
|
+
const controller = new AbortController;
|
|
6824
6827
|
const promise = Promise.resolve(speculate({
|
|
6825
6828
|
api,
|
|
6826
6829
|
context: options.context,
|
|
6827
6830
|
session,
|
|
6828
|
-
turn: provisionalTurn
|
|
6831
|
+
turn: provisionalTurn,
|
|
6832
|
+
signal: controller.signal
|
|
6829
6833
|
})).then((result) => result && result.text.trim() ? { text: result.text } : null).catch((error) => {
|
|
6830
6834
|
console.info(`[voice][p3] speculate error session=${session.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
6831
6835
|
return null;
|
|
6832
6836
|
});
|
|
6833
|
-
speculation = { pendingText, promise };
|
|
6837
|
+
speculation = { controller, pendingText, promise };
|
|
6834
6838
|
};
|
|
6835
6839
|
const scheduleSilenceCommit = (delayMs = adaptiveSilenceMs(), reset = true) => {
|
|
6836
6840
|
scheduleTurnCommit(delayMs, "silence", reset);
|
|
@@ -8034,18 +8038,26 @@ var createVoiceSession = (options) => {
|
|
|
8034
8038
|
const onTurnStartedAt = Date.now();
|
|
8035
8039
|
logVoiceTiming(session.id, "session.commit-to-onturn", onTurnStartedAt - (turn.committedAt || onTurnStartedAt), { fillerScheduled: fillerTimer !== null });
|
|
8036
8040
|
const pendingSpeculation = speculation;
|
|
8037
|
-
|
|
8041
|
+
speculation = null;
|
|
8042
|
+
speculationAttempted = false;
|
|
8038
8043
|
let reusableSpeculation;
|
|
8039
8044
|
if (pendingSpeculation && pendingSpeculation.pendingText === turn.text) {
|
|
8040
|
-
const speculated = await
|
|
8045
|
+
const speculated = await Promise.race([
|
|
8046
|
+
pendingSpeculation.promise,
|
|
8047
|
+
new Promise((resolve2) => {
|
|
8048
|
+
setTimeout(() => resolve2(null), SPECULATION_ADOPT_TIMEOUT_MS);
|
|
8049
|
+
})
|
|
8050
|
+
]);
|
|
8041
8051
|
if (speculated?.text) {
|
|
8042
8052
|
reusableSpeculation = { text: speculated.text };
|
|
8043
8053
|
logVoiceTiming(session.id, "p3.adopted-speculation", 0, {
|
|
8044
8054
|
chars: speculated.text.length
|
|
8045
8055
|
});
|
|
8056
|
+
} else {
|
|
8057
|
+
pendingSpeculation.controller.abort();
|
|
8046
8058
|
}
|
|
8047
|
-
} else {
|
|
8048
|
-
pendingSpeculation
|
|
8059
|
+
} else if (pendingSpeculation) {
|
|
8060
|
+
pendingSpeculation.controller.abort();
|
|
8049
8061
|
}
|
|
8050
8062
|
try {
|
|
8051
8063
|
const onTurnPromise = options.route.onTurn({
|