@absolutejs/voice 0.0.22-beta.557 → 0.0.22-beta.559
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/types.d.ts +8 -0
- package/dist/index.js +32 -1
- package/dist/testing/index.js +32 -1
- package/package.json +1 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -923,6 +923,14 @@ export type CreateVoiceSessionOptions<TContext = unknown, TSession extends Voice
|
|
|
923
923
|
* Set to "" to opt out entirely.
|
|
924
924
|
*/
|
|
925
925
|
defaultSilentTurnAck?: string;
|
|
926
|
+
/**
|
|
927
|
+
* Hard timeout on a single `route.onTurn` call. If onTurn hasn't resolved
|
|
928
|
+
* in this many ms, it's rejected with a hard-timeout error which falls
|
|
929
|
+
* through to defaultSilentTurnAck. Default 45s — generous for normal
|
|
930
|
+
* conversational LLM calls (1-3s typical), but catches hangs where the
|
|
931
|
+
* model adapter's own timeout doesn't fire. Set to 0 to disable.
|
|
932
|
+
*/
|
|
933
|
+
routeOnTurnTimeoutMs?: number;
|
|
926
934
|
assistantMode?: import("./assistantMode").VoiceAssistantMode;
|
|
927
935
|
modalities?: ReadonlyArray<"audio" | "text">;
|
|
928
936
|
prosody?: VoiceTTSProsody;
|
package/dist/index.js
CHANGED
|
@@ -4273,6 +4273,17 @@ var createVoiceSession = (options) => {
|
|
|
4273
4273
|
turnId: cancelledTurnId
|
|
4274
4274
|
});
|
|
4275
4275
|
}
|
|
4276
|
+
try {
|
|
4277
|
+
ttsSession = null;
|
|
4278
|
+
ttsSessionPromise = null;
|
|
4279
|
+
await activeSession.close("post-cancel-reset");
|
|
4280
|
+
} catch (error) {
|
|
4281
|
+
logger.warn("voice tts adapter close-after-cancel failed", {
|
|
4282
|
+
error: toError(error).message,
|
|
4283
|
+
reason,
|
|
4284
|
+
sessionId: options.id
|
|
4285
|
+
});
|
|
4286
|
+
}
|
|
4276
4287
|
};
|
|
4277
4288
|
const sendAssistantAudio = async (chunk, input) => {
|
|
4278
4289
|
const normalizedChunk = chunk instanceof Uint8Array ? new Uint8Array(chunk) : chunk instanceof ArrayBuffer ? new Uint8Array(chunk.slice(0)) : new Uint8Array(chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength));
|
|
@@ -5313,10 +5324,11 @@ var createVoiceSession = (options) => {
|
|
|
5313
5324
|
});
|
|
5314
5325
|
}, fillerDelayMs);
|
|
5315
5326
|
}
|
|
5327
|
+
const onTurnTimeoutMs = options.routeOnTurnTimeoutMs ?? 45000;
|
|
5316
5328
|
let committedOutput;
|
|
5317
5329
|
const onTurnStartedAt = Date.now();
|
|
5318
5330
|
try {
|
|
5319
|
-
|
|
5331
|
+
const onTurnPromise = options.route.onTurn({
|
|
5320
5332
|
api,
|
|
5321
5333
|
context: options.context,
|
|
5322
5334
|
liveOps: liveOpsControl ? {
|
|
@@ -5327,6 +5339,25 @@ var createVoiceSession = (options) => {
|
|
|
5327
5339
|
session,
|
|
5328
5340
|
turn
|
|
5329
5341
|
});
|
|
5342
|
+
if (onTurnTimeoutMs > 0) {
|
|
5343
|
+
let timer = null;
|
|
5344
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
5345
|
+
timer = setTimeout(() => {
|
|
5346
|
+
reject(new Error(`route.onTurn hard-timeout after ${onTurnTimeoutMs}ms`));
|
|
5347
|
+
}, onTurnTimeoutMs);
|
|
5348
|
+
});
|
|
5349
|
+
try {
|
|
5350
|
+
committedOutput = await Promise.race([
|
|
5351
|
+
onTurnPromise,
|
|
5352
|
+
timeoutPromise
|
|
5353
|
+
]);
|
|
5354
|
+
} finally {
|
|
5355
|
+
if (timer)
|
|
5356
|
+
clearTimeout(timer);
|
|
5357
|
+
}
|
|
5358
|
+
} else {
|
|
5359
|
+
committedOutput = await onTurnPromise;
|
|
5360
|
+
}
|
|
5330
5361
|
} catch (error) {
|
|
5331
5362
|
const message = toError(error).message;
|
|
5332
5363
|
logger.warn("voice route.onTurn failed", {
|
package/dist/testing/index.js
CHANGED
|
@@ -6110,6 +6110,17 @@ var createVoiceSession = (options) => {
|
|
|
6110
6110
|
turnId: cancelledTurnId
|
|
6111
6111
|
});
|
|
6112
6112
|
}
|
|
6113
|
+
try {
|
|
6114
|
+
ttsSession = null;
|
|
6115
|
+
ttsSessionPromise = null;
|
|
6116
|
+
await activeSession.close("post-cancel-reset");
|
|
6117
|
+
} catch (error) {
|
|
6118
|
+
logger.warn("voice tts adapter close-after-cancel failed", {
|
|
6119
|
+
error: toError(error).message,
|
|
6120
|
+
reason,
|
|
6121
|
+
sessionId: options.id
|
|
6122
|
+
});
|
|
6123
|
+
}
|
|
6113
6124
|
};
|
|
6114
6125
|
const sendAssistantAudio = async (chunk, input) => {
|
|
6115
6126
|
const normalizedChunk = chunk instanceof Uint8Array ? new Uint8Array(chunk) : chunk instanceof ArrayBuffer ? new Uint8Array(chunk.slice(0)) : new Uint8Array(chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength));
|
|
@@ -7150,10 +7161,11 @@ var createVoiceSession = (options) => {
|
|
|
7150
7161
|
});
|
|
7151
7162
|
}, fillerDelayMs);
|
|
7152
7163
|
}
|
|
7164
|
+
const onTurnTimeoutMs = options.routeOnTurnTimeoutMs ?? 45000;
|
|
7153
7165
|
let committedOutput;
|
|
7154
7166
|
const onTurnStartedAt = Date.now();
|
|
7155
7167
|
try {
|
|
7156
|
-
|
|
7168
|
+
const onTurnPromise = options.route.onTurn({
|
|
7157
7169
|
api,
|
|
7158
7170
|
context: options.context,
|
|
7159
7171
|
liveOps: liveOpsControl ? {
|
|
@@ -7164,6 +7176,25 @@ var createVoiceSession = (options) => {
|
|
|
7164
7176
|
session,
|
|
7165
7177
|
turn
|
|
7166
7178
|
});
|
|
7179
|
+
if (onTurnTimeoutMs > 0) {
|
|
7180
|
+
let timer = null;
|
|
7181
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
7182
|
+
timer = setTimeout(() => {
|
|
7183
|
+
reject(new Error(`route.onTurn hard-timeout after ${onTurnTimeoutMs}ms`));
|
|
7184
|
+
}, onTurnTimeoutMs);
|
|
7185
|
+
});
|
|
7186
|
+
try {
|
|
7187
|
+
committedOutput = await Promise.race([
|
|
7188
|
+
onTurnPromise,
|
|
7189
|
+
timeoutPromise
|
|
7190
|
+
]);
|
|
7191
|
+
} finally {
|
|
7192
|
+
if (timer)
|
|
7193
|
+
clearTimeout(timer);
|
|
7194
|
+
}
|
|
7195
|
+
} else {
|
|
7196
|
+
committedOutput = await onTurnPromise;
|
|
7197
|
+
}
|
|
7167
7198
|
} catch (error) {
|
|
7168
7199
|
const message = toError(error).message;
|
|
7169
7200
|
logger.warn("voice route.onTurn failed", {
|