@absolutejs/voice 0.0.22-beta.546 → 0.0.22-beta.548
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 +6 -2
- package/dist/index.js +21 -2
- package/dist/telephony/twilio.d.ts +8 -0
- package/dist/testing/index.js +58 -26
- package/package.json +1 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -745,7 +745,9 @@ export type VoiceSurfaceConfig<O> = false | O | (Record<string, never> extends O
|
|
|
745
745
|
export type VoicePluginConfig<TContext = unknown, TSession extends VoiceSessionRecord = VoiceSessionRecord, TResult = unknown> = {
|
|
746
746
|
costTelemetry?: VoiceCostTelemetryConfig<TContext, TSession, TResult>;
|
|
747
747
|
path: string;
|
|
748
|
-
greeting?: string | ((
|
|
748
|
+
greeting?: string | ((input: {
|
|
749
|
+
session: TSession;
|
|
750
|
+
}) => string | Promise<string>);
|
|
749
751
|
languageStrategy?: VoiceLanguageStrategy;
|
|
750
752
|
lexicon?: VoiceLexiconEntry[] | VoiceLexiconResolver<TContext>;
|
|
751
753
|
phraseHints?: VoicePhraseHint[] | VoicePhraseHintResolver<TContext>;
|
|
@@ -859,7 +861,9 @@ export type CreateVoiceSessionOptions<TContext = unknown, TSession extends Voice
|
|
|
859
861
|
id: string;
|
|
860
862
|
context: TContext;
|
|
861
863
|
socket: VoiceSocket;
|
|
862
|
-
greeting?: string | ((
|
|
864
|
+
greeting?: string | ((input: {
|
|
865
|
+
session: TSession;
|
|
866
|
+
}) => string | Promise<string>);
|
|
863
867
|
stt?: STTAdapter;
|
|
864
868
|
realtime?: RealtimeAdapter;
|
|
865
869
|
realtimeInputFormat?: AudioFormat;
|
package/dist/index.js
CHANGED
|
@@ -5721,7 +5721,7 @@ var createVoiceSession = (options) => {
|
|
|
5721
5721
|
kickCallSilenceWatchdog();
|
|
5722
5722
|
startAmdEvaluationTimer();
|
|
5723
5723
|
if (shouldFireOnSession && options.greeting && session.turns.length === 0) {
|
|
5724
|
-
const greetingText = typeof options.greeting === "function" ? await options.greeting() : options.greeting;
|
|
5724
|
+
const greetingText = typeof options.greeting === "function" ? await options.greeting({ session }) : options.greeting;
|
|
5725
5725
|
const greetingTurnId = createId();
|
|
5726
5726
|
await send({
|
|
5727
5727
|
text: greetingText,
|
|
@@ -24302,8 +24302,23 @@ var createTwilioSocketAdapter = (socket, getState) => ({
|
|
|
24302
24302
|
if (!state.streamSid) {
|
|
24303
24303
|
return;
|
|
24304
24304
|
}
|
|
24305
|
+
const clearMessage = { event: "clear", streamSid: state.streamSid };
|
|
24305
24306
|
state.reviewRecorder?.recordTwilioOutbound({ event: "clear" });
|
|
24306
|
-
await
|
|
24307
|
+
await state.trace?.append({
|
|
24308
|
+
at: Date.now(),
|
|
24309
|
+
payload: {
|
|
24310
|
+
callSid: state.callSid ?? undefined,
|
|
24311
|
+
carrier: state.carrier,
|
|
24312
|
+
direction: "outbound",
|
|
24313
|
+
envelope: clearMessage,
|
|
24314
|
+
event: "clear",
|
|
24315
|
+
streamId: state.streamSid
|
|
24316
|
+
},
|
|
24317
|
+
scenarioId: state.scenarioId ?? undefined,
|
|
24318
|
+
sessionId: state.sessionId ?? state.streamSid,
|
|
24319
|
+
type: "client.telephony_media"
|
|
24320
|
+
});
|
|
24321
|
+
await Promise.resolve(socket.send(JSON.stringify(clearMessage)));
|
|
24307
24322
|
},
|
|
24308
24323
|
close: async (code, reason) => {
|
|
24309
24324
|
await Promise.resolve(socket.close(code, reason));
|
|
@@ -24506,7 +24521,9 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
24506
24521
|
sessionHandle = createVoiceSession({
|
|
24507
24522
|
audioConditioning,
|
|
24508
24523
|
context: options.context,
|
|
24524
|
+
costAccountant: options.costAccountant,
|
|
24509
24525
|
costTelemetry: options.costTelemetry,
|
|
24526
|
+
costTelephony: options.costTelephony,
|
|
24510
24527
|
greeting: options.greeting,
|
|
24511
24528
|
id: bridgeState.sessionId,
|
|
24512
24529
|
languageStrategy: options.languageStrategy,
|
|
@@ -24514,6 +24531,7 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
24514
24531
|
logger,
|
|
24515
24532
|
phraseHints,
|
|
24516
24533
|
reconnect,
|
|
24534
|
+
recording: options.recording,
|
|
24517
24535
|
route,
|
|
24518
24536
|
scenarioId: bridgeState.scenarioId ?? undefined,
|
|
24519
24537
|
socket: voiceSocket,
|
|
@@ -24521,6 +24539,7 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
24521
24539
|
stt: options.stt,
|
|
24522
24540
|
sttFallback: resolveSTTFallbackConfig(options.sttFallback),
|
|
24523
24541
|
sttLifecycle: options.sttLifecycle ?? runtimePreset.sttLifecycle,
|
|
24542
|
+
trace: options.trace,
|
|
24524
24543
|
tts: options.tts,
|
|
24525
24544
|
turnDetection
|
|
24526
24545
|
});
|
|
@@ -107,6 +107,14 @@ export type TwilioMediaStreamBridgeOptions<TContext = unknown, TSession extends
|
|
|
107
107
|
sessionId?: string;
|
|
108
108
|
stt: STTAdapter;
|
|
109
109
|
telephonyMediaCarrier?: "plivo" | "telnyx" | "twilio";
|
|
110
|
+
/** Capture call audio (per-channel) to a recording store. */
|
|
111
|
+
recording?: import("../core/types").VoiceSessionRecordingConfig;
|
|
112
|
+
/** Per-call cost accounting (STT/LLM/TTS) — emits turn.cost/cost.ready traces. */
|
|
113
|
+
costAccountant?: import("../core/costAccounting").VoiceCostAccountant;
|
|
114
|
+
/** Telephony cost provider for the accountant (e.g. "twilio"). */
|
|
115
|
+
costTelephony?: {
|
|
116
|
+
provider?: string;
|
|
117
|
+
};
|
|
110
118
|
};
|
|
111
119
|
export type TwilioMediaStreamBridge = {
|
|
112
120
|
close: (reason?: string) => Promise<void>;
|
package/dist/testing/index.js
CHANGED
|
@@ -7538,7 +7538,7 @@ var createVoiceSession = (options) => {
|
|
|
7538
7538
|
kickCallSilenceWatchdog();
|
|
7539
7539
|
startAmdEvaluationTimer();
|
|
7540
7540
|
if (shouldFireOnSession && options.greeting && session.turns.length === 0) {
|
|
7541
|
-
const greetingText = typeof options.greeting === "function" ? await options.greeting() : options.greeting;
|
|
7541
|
+
const greetingText = typeof options.greeting === "function" ? await options.greeting({ session }) : options.greeting;
|
|
7542
7542
|
const greetingTurnId = createId();
|
|
7543
7543
|
await send({
|
|
7544
7544
|
text: greetingText,
|
|
@@ -12838,8 +12838,23 @@ var createTwilioSocketAdapter = (socket, getState) => ({
|
|
|
12838
12838
|
if (!state.streamSid) {
|
|
12839
12839
|
return;
|
|
12840
12840
|
}
|
|
12841
|
+
const clearMessage = { event: "clear", streamSid: state.streamSid };
|
|
12841
12842
|
state.reviewRecorder?.recordTwilioOutbound({ event: "clear" });
|
|
12842
|
-
await
|
|
12843
|
+
await state.trace?.append({
|
|
12844
|
+
at: Date.now(),
|
|
12845
|
+
payload: {
|
|
12846
|
+
callSid: state.callSid ?? undefined,
|
|
12847
|
+
carrier: state.carrier,
|
|
12848
|
+
direction: "outbound",
|
|
12849
|
+
envelope: clearMessage,
|
|
12850
|
+
event: "clear",
|
|
12851
|
+
streamId: state.streamSid
|
|
12852
|
+
},
|
|
12853
|
+
scenarioId: state.scenarioId ?? undefined,
|
|
12854
|
+
sessionId: state.sessionId ?? state.streamSid,
|
|
12855
|
+
type: "client.telephony_media"
|
|
12856
|
+
});
|
|
12857
|
+
await Promise.resolve(socket.send(JSON.stringify(clearMessage)));
|
|
12843
12858
|
},
|
|
12844
12859
|
close: async (code, reason) => {
|
|
12845
12860
|
await Promise.resolve(socket.close(code, reason));
|
|
@@ -13042,7 +13057,9 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
13042
13057
|
sessionHandle = createVoiceSession({
|
|
13043
13058
|
audioConditioning,
|
|
13044
13059
|
context: options.context,
|
|
13060
|
+
costAccountant: options.costAccountant,
|
|
13045
13061
|
costTelemetry: options.costTelemetry,
|
|
13062
|
+
costTelephony: options.costTelephony,
|
|
13046
13063
|
greeting: options.greeting,
|
|
13047
13064
|
id: bridgeState.sessionId,
|
|
13048
13065
|
languageStrategy: options.languageStrategy,
|
|
@@ -13050,6 +13067,7 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
13050
13067
|
logger,
|
|
13051
13068
|
phraseHints,
|
|
13052
13069
|
reconnect,
|
|
13070
|
+
recording: options.recording,
|
|
13053
13071
|
route,
|
|
13054
13072
|
scenarioId: bridgeState.scenarioId ?? undefined,
|
|
13055
13073
|
socket: voiceSocket,
|
|
@@ -13057,6 +13075,7 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
13057
13075
|
stt: options.stt,
|
|
13058
13076
|
sttFallback: resolveSTTFallbackConfig(options.sttFallback),
|
|
13059
13077
|
sttLifecycle: options.sttLifecycle ?? runtimePreset.sttLifecycle,
|
|
13078
|
+
trace: options.trace,
|
|
13060
13079
|
tts: options.tts,
|
|
13061
13080
|
turnDetection
|
|
13062
13081
|
});
|
|
@@ -13361,7 +13380,7 @@ var createFakeSTTAdapter = (inputSpy, sttDelayMs) => ({
|
|
|
13361
13380
|
final: new Set,
|
|
13362
13381
|
partial: new Set
|
|
13363
13382
|
};
|
|
13364
|
-
let
|
|
13383
|
+
let sendCount = 0;
|
|
13365
13384
|
return {
|
|
13366
13385
|
close: async () => {
|
|
13367
13386
|
for (const handler of listeners.close) {
|
|
@@ -13376,31 +13395,44 @@ var createFakeSTTAdapter = (inputSpy, sttDelayMs) => ({
|
|
|
13376
13395
|
},
|
|
13377
13396
|
send: async (audio) => {
|
|
13378
13397
|
inputSpy.push(toUint8Array2(audio));
|
|
13379
|
-
|
|
13398
|
+
sendCount += 1;
|
|
13399
|
+
if (sendCount === 1) {
|
|
13400
|
+
if (sttDelayMs > 0) {
|
|
13401
|
+
await Bun.sleep(sttDelayMs);
|
|
13402
|
+
}
|
|
13403
|
+
const receivedAt = Date.now();
|
|
13404
|
+
for (const handler of listeners.final) {
|
|
13405
|
+
handler({
|
|
13406
|
+
receivedAt,
|
|
13407
|
+
transcript: {
|
|
13408
|
+
id: "telephony-benchmark-final",
|
|
13409
|
+
isFinal: true,
|
|
13410
|
+
text: "hello from twilio"
|
|
13411
|
+
},
|
|
13412
|
+
type: "final"
|
|
13413
|
+
});
|
|
13414
|
+
}
|
|
13415
|
+
for (const handler of listeners.endOfTurn) {
|
|
13416
|
+
handler({
|
|
13417
|
+
reason: "vendor",
|
|
13418
|
+
receivedAt,
|
|
13419
|
+
type: "endOfTurn"
|
|
13420
|
+
});
|
|
13421
|
+
}
|
|
13380
13422
|
return;
|
|
13381
13423
|
}
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
},
|
|
13395
|
-
type: "final"
|
|
13396
|
-
});
|
|
13397
|
-
}
|
|
13398
|
-
for (const handler of listeners.endOfTurn) {
|
|
13399
|
-
handler({
|
|
13400
|
-
reason: "vendor",
|
|
13401
|
-
receivedAt,
|
|
13402
|
-
type: "endOfTurn"
|
|
13403
|
-
});
|
|
13424
|
+
if (sendCount === 2) {
|
|
13425
|
+
for (const handler of listeners.partial) {
|
|
13426
|
+
handler({
|
|
13427
|
+
receivedAt: Date.now(),
|
|
13428
|
+
transcript: {
|
|
13429
|
+
id: "telephony-benchmark-partial",
|
|
13430
|
+
isFinal: false,
|
|
13431
|
+
text: "actually wait"
|
|
13432
|
+
},
|
|
13433
|
+
type: "partial"
|
|
13434
|
+
});
|
|
13435
|
+
}
|
|
13404
13436
|
}
|
|
13405
13437
|
}
|
|
13406
13438
|
};
|