@absolutejs/voice 0.0.22-beta.325 → 0.0.22-beta.327
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.d.ts +2 -2
- package/dist/index.js +95 -7
- package/dist/productionReadiness.d.ts +1 -0
- package/dist/telephony/twilio.d.ts +1 -0
- package/dist/telephonyMediaRoutes.d.ts +7 -0
- package/dist/testing/index.js +31 -0
- package/dist/trace.d.ts +1 -1
- package/dist/vue/useVoiceReadinessFailures.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,10 +16,10 @@ export { assertVoiceRealtimeProviderContractEvidence, buildVoiceRealtimeProvider
|
|
|
16
16
|
export type { VoiceRealtimeProviderContractAssertionInput, VoiceRealtimeProviderContractAssertionReport, VoiceRealtimeProviderContractCapability, VoiceRealtimeProviderContractCheck, VoiceRealtimeProviderContractDefinition, VoiceRealtimeProviderContractMatrixPresetOptions, VoiceRealtimeProviderContractMatrixInput, VoiceRealtimeProviderContractMatrixReport, VoiceRealtimeProviderContractRoutesOptions, VoiceRealtimeProviderContractRow, VoiceRealtimeProviderPresetProvider, VoiceRealtimeProviderContractStatus } from './realtimeProviderContracts';
|
|
17
17
|
export { buildVoiceDiagnosticsMarkdown, createVoiceDiagnosticsRoutes, resolveVoiceDiagnosticsTraceFilter } from './diagnosticsRoutes';
|
|
18
18
|
export { assertVoiceMediaPipelineEvidence, buildVoiceMediaPipelineReport, createVoiceMediaPipelineRoutes, evaluateVoiceMediaPipelineEvidence, renderVoiceMediaPipelineHTML, renderVoiceMediaPipelineMarkdown } from './mediaPipelineRoutes';
|
|
19
|
-
export { buildVoiceTelephonyMediaReport, createVoiceTelephonyMediaRoutes, renderVoiceTelephonyMediaHTML } from './telephonyMediaRoutes';
|
|
19
|
+
export { buildVoiceTelephonyMediaReport, createVoiceTelephonyMediaRoutes, getLatestVoiceTelephonyMediaReport, renderVoiceTelephonyMediaHTML } from './telephonyMediaRoutes';
|
|
20
20
|
export { createVoiceBrowserMediaRoutes, getLatestVoiceBrowserMediaReport, renderVoiceBrowserMediaHTML, summarizeVoiceBrowserMedia } from './browserMediaRoutes';
|
|
21
21
|
export type { VoiceMediaPipelineAssertionInput, VoiceMediaPipelineAssertionReport, VoiceMediaPipelineReport, VoiceMediaPipelineReportOptions, VoiceMediaPipelineRoutesOptions } from './mediaPipelineRoutes';
|
|
22
|
-
export type { VoiceTelephonyMediaCarrierInput, VoiceTelephonyMediaCarrierReport, VoiceTelephonyMediaReport, VoiceTelephonyMediaRoutesOptions, VoiceTelephonyMediaStatus } from './telephonyMediaRoutes';
|
|
22
|
+
export type { VoiceTelephonyMediaCarrierInput, VoiceTelephonyMediaCarrierReport, VoiceTelephonyMediaReport, VoiceTelephonyMediaRoutesOptions, VoiceTelephonyMediaTraceReportOptions, VoiceTelephonyMediaStatus } from './telephonyMediaRoutes';
|
|
23
23
|
export type { VoiceBrowserMediaReport, VoiceBrowserMediaRoutesOptions, VoiceBrowserMediaSample, VoiceBrowserMediaStatus } from './browserMediaRoutes';
|
|
24
24
|
export { buildVoiceDemoReadyReport, createVoiceDemoReadyRoutes, renderVoiceDemoReadyHTML } from './demoReadyRoutes';
|
|
25
25
|
export { buildVoiceDeliverySinkReport, createVoiceDeliverySinkDescriptor, createVoiceDeliverySinkPair, createVoiceDeliverySinkRoutes, createVoiceFileDeliverySink, createVoicePostgresDeliverySink, createVoiceS3DeliverySink, createVoiceSQLiteDeliverySink, createVoiceWebhookDeliverySink, renderVoiceDeliverySinkHTML } from './deliverySinkRoutes';
|
package/dist/index.js
CHANGED
|
@@ -12666,6 +12666,32 @@ var buildVoiceTelephonyMediaReport = (input = {}) => {
|
|
|
12666
12666
|
status: issues.length === 0 ? "pass" : "fail"
|
|
12667
12667
|
};
|
|
12668
12668
|
};
|
|
12669
|
+
var getLatestVoiceTelephonyMediaReport = async (options) => {
|
|
12670
|
+
const events = (await options.store.list({ type: "client.telephony_media" })).filter((event) => {
|
|
12671
|
+
const carrier = event.payload.carrier;
|
|
12672
|
+
return typeof carrier === "string" && (!options.carriers || options.carriers.includes(carrier)) && event.payload.envelope && typeof event.payload.envelope === "object";
|
|
12673
|
+
}).sort((left, right) => left.at - right.at);
|
|
12674
|
+
if (events.length === 0) {
|
|
12675
|
+
return;
|
|
12676
|
+
}
|
|
12677
|
+
const byCarrier = new Map;
|
|
12678
|
+
for (const event of events) {
|
|
12679
|
+
const carrier = event.payload.carrier;
|
|
12680
|
+
const envelopes = byCarrier.get(carrier) ?? [];
|
|
12681
|
+
envelopes.push(event.payload.envelope);
|
|
12682
|
+
byCarrier.set(carrier, envelopes);
|
|
12683
|
+
}
|
|
12684
|
+
return buildVoiceTelephonyMediaReport({
|
|
12685
|
+
carriers: [...byCarrier.entries()].map(([carrier, lifecycleEnvelopes]) => ({
|
|
12686
|
+
carrier,
|
|
12687
|
+
envelope: lifecycleEnvelopes.find((envelope) => {
|
|
12688
|
+
const event = envelope.event;
|
|
12689
|
+
return typeof event === "string" && event.toLowerCase() === "media";
|
|
12690
|
+
}),
|
|
12691
|
+
lifecycleEnvelopes
|
|
12692
|
+
}))
|
|
12693
|
+
});
|
|
12694
|
+
};
|
|
12669
12695
|
var renderVoiceTelephonyMediaHTML = (report, options = {}) => {
|
|
12670
12696
|
const title = options.title ?? "Voice Telephony Media Proof";
|
|
12671
12697
|
const rows = report.carriers.map((carrier) => `<tr><td>${escapeHtml16(carrier.carrier)}</td><td>${escapeHtml16(carrier.status)}</td><td>${String(carrier.audioBytes)}</td><td>${String(carrier.lifecycle.mediaEvents)}</td><td>${escapeHtml16(carrier.lifecycle.started ? "yes" : "no")}</td><td>${escapeHtml16(carrier.lifecycle.stopped ? "yes" : "no")}</td><td>${escapeHtml16(carrier.frame?.kind ?? "missing")}</td><td>${escapeHtml16(carrier.frame?.format?.encoding ?? "missing")}</td><td>${escapeHtml16(carrier.issues.join(" ") || "none")}</td></tr>`).join("");
|
|
@@ -12677,10 +12703,14 @@ var createVoiceTelephonyMediaRoutes = (options = {}) => {
|
|
|
12677
12703
|
const routes = new Elysia13({
|
|
12678
12704
|
name: options.name ?? "absolutejs-voice-telephony-media"
|
|
12679
12705
|
});
|
|
12680
|
-
routes.get(path, () =>
|
|
12706
|
+
routes.get(path, async () => options.store ? await getLatestVoiceTelephonyMediaReport({
|
|
12707
|
+
store: options.store
|
|
12708
|
+
}) ?? buildVoiceTelephonyMediaReport({ carriers: options.carriers }) : buildVoiceTelephonyMediaReport({ carriers: options.carriers }));
|
|
12681
12709
|
if (htmlPath) {
|
|
12682
|
-
routes.get(htmlPath, () => {
|
|
12683
|
-
const report =
|
|
12710
|
+
routes.get(htmlPath, async () => {
|
|
12711
|
+
const report = options.store ? await getLatestVoiceTelephonyMediaReport({
|
|
12712
|
+
store: options.store
|
|
12713
|
+
}) ?? buildVoiceTelephonyMediaReport({ carriers: options.carriers }) : buildVoiceTelephonyMediaReport({
|
|
12684
12714
|
carriers: options.carriers
|
|
12685
12715
|
});
|
|
12686
12716
|
return new Response(renderVoiceTelephonyMediaHTML(report, options), {
|
|
@@ -21764,6 +21794,25 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
21764
21794
|
};
|
|
21765
21795
|
let sessionHandle = null;
|
|
21766
21796
|
let reviewArtifactDelivered = false;
|
|
21797
|
+
const telephonyMediaCarrier = options.telephonyMediaCarrier ?? "twilio";
|
|
21798
|
+
const appendTelephonyMediaTrace = async (message, override) => {
|
|
21799
|
+
const trace = options.trace;
|
|
21800
|
+
const sessionId = override?.sessionId ?? bridgeState.sessionId ?? (message.event === "start" ? message.start.customParameters?.sessionId : undefined) ?? (message.event === "start" ? message.start.streamSid : "telephony-media");
|
|
21801
|
+
const streamSid = override?.streamSid ?? (message.event === "start" ? message.start.streamSid : ("streamSid" in message) ? message.streamSid : undefined);
|
|
21802
|
+
await trace?.append({
|
|
21803
|
+
at: Date.now(),
|
|
21804
|
+
payload: {
|
|
21805
|
+
callSid: message.event === "start" ? message.start.callSid : message.event === "stop" ? message.stop?.callSid : bridgeState.callSid ?? undefined,
|
|
21806
|
+
carrier: telephonyMediaCarrier,
|
|
21807
|
+
envelope: message,
|
|
21808
|
+
event: message.event,
|
|
21809
|
+
streamId: streamSid
|
|
21810
|
+
},
|
|
21811
|
+
scenarioId: bridgeState.scenarioId ?? undefined,
|
|
21812
|
+
sessionId,
|
|
21813
|
+
type: "client.telephony_media"
|
|
21814
|
+
});
|
|
21815
|
+
};
|
|
21767
21816
|
const resolveLexicon2 = async () => {
|
|
21768
21817
|
if (typeof options.lexicon === "function") {
|
|
21769
21818
|
return normalizeLexicon2(await options.lexicon({
|
|
@@ -21864,6 +21913,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
21864
21913
|
reason: message.start.callSid,
|
|
21865
21914
|
text: bridgeState.sessionId ?? undefined
|
|
21866
21915
|
});
|
|
21916
|
+
await appendTelephonyMediaTrace(message, {
|
|
21917
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
21918
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
21919
|
+
});
|
|
21867
21920
|
await ensureSession();
|
|
21868
21921
|
return;
|
|
21869
21922
|
}
|
|
@@ -21884,6 +21937,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
21884
21937
|
})));
|
|
21885
21938
|
}
|
|
21886
21939
|
bridgeState.hasOutboundAudioSinceLastInbound = false;
|
|
21940
|
+
await appendTelephonyMediaTrace(message, {
|
|
21941
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
21942
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
21943
|
+
});
|
|
21887
21944
|
await activeSession.receiveAudio(transcodeTwilioInboundPayloadToPCM16(message.media.payload));
|
|
21888
21945
|
return;
|
|
21889
21946
|
}
|
|
@@ -21898,6 +21955,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
21898
21955
|
event: "stop",
|
|
21899
21956
|
reason: message.stop?.callSid
|
|
21900
21957
|
});
|
|
21958
|
+
await appendTelephonyMediaTrace(message, {
|
|
21959
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
21960
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
21961
|
+
});
|
|
21901
21962
|
await sessionHandle?.close("twilio-stop");
|
|
21902
21963
|
return;
|
|
21903
21964
|
}
|
|
@@ -22198,6 +22259,7 @@ var createPlivoTwilioSocketAdapter = (socket) => ({
|
|
|
22198
22259
|
var createPlivoMediaStreamBridge = (socket, options) => {
|
|
22199
22260
|
const bridge = createTwilioMediaStreamBridge(createPlivoTwilioSocketAdapter(socket), {
|
|
22200
22261
|
...options,
|
|
22262
|
+
telephonyMediaCarrier: "plivo",
|
|
22201
22263
|
onVoiceMessage: options.onVoiceMessage ? (input) => options.onVoiceMessage?.({
|
|
22202
22264
|
callId: input.callSid,
|
|
22203
22265
|
message: input.message,
|
|
@@ -22825,6 +22887,7 @@ var createTelnyxTwilioSocketAdapter = (socket) => ({
|
|
|
22825
22887
|
var createTelnyxMediaStreamBridge = (socket, options) => {
|
|
22826
22888
|
const bridge = createTwilioMediaStreamBridge(createTelnyxTwilioSocketAdapter(socket), {
|
|
22827
22889
|
...options,
|
|
22890
|
+
telephonyMediaCarrier: "telnyx",
|
|
22828
22891
|
onVoiceMessage: options.onVoiceMessage ? (input) => options.onVoiceMessage?.({
|
|
22829
22892
|
callControlId: input.callSid,
|
|
22830
22893
|
message: input.message,
|
|
@@ -30278,6 +30341,21 @@ var buildOperationsRecordLinks = (input) => {
|
|
|
30278
30341
|
sessionId,
|
|
30279
30342
|
status: "fail"
|
|
30280
30343
|
})) : [];
|
|
30344
|
+
const telephonyMedia = input.telephonyMedia && input.telephonyMedia.status !== "pass" ? input.telephonyMedia.carriers.filter((carrier) => carrier.status !== "pass").flatMap((carrier) => {
|
|
30345
|
+
const sessionIds = [
|
|
30346
|
+
...carrier.lifecycle.streamIds,
|
|
30347
|
+
carrier.frame?.sessionId
|
|
30348
|
+
].filter((value, index, values) => typeof value === "string" && value.length > 0 && values.indexOf(value) === index);
|
|
30349
|
+
const fallbackSessionId = `${carrier.carrier}-telephony-media`;
|
|
30350
|
+
const ids = sessionIds.length > 0 ? sessionIds : [fallbackSessionId];
|
|
30351
|
+
return ids.map((sessionId) => ({
|
|
30352
|
+
detail: carrier.issues[0] ?? `${carrier.lifecycle.issues.length} telephony media lifecycle issue(s)`,
|
|
30353
|
+
href: voiceOperationsRecordHref(input.base, sessionId),
|
|
30354
|
+
label: "Open telephony media operations record",
|
|
30355
|
+
sessionId,
|
|
30356
|
+
status: "fail"
|
|
30357
|
+
}));
|
|
30358
|
+
}) : [];
|
|
30281
30359
|
return {
|
|
30282
30360
|
failedSessions: input.failedSessionIds.map((sessionId) => ({
|
|
30283
30361
|
href: voiceOperationsRecordHref(input.base, sessionId),
|
|
@@ -30287,7 +30365,8 @@ var buildOperationsRecordLinks = (input) => {
|
|
|
30287
30365
|
})),
|
|
30288
30366
|
failingLatency,
|
|
30289
30367
|
mediaQuality,
|
|
30290
|
-
providerErrors
|
|
30368
|
+
providerErrors,
|
|
30369
|
+
telephonyMedia
|
|
30291
30370
|
};
|
|
30292
30371
|
};
|
|
30293
30372
|
var firstOperationsRecordHref = (links) => links[0]?.href;
|
|
@@ -30388,7 +30467,8 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
30388
30467
|
liveLatencyFailAfterMs: options.liveLatencyFailAfterMs ?? 3200,
|
|
30389
30468
|
liveLatencyMaxAgeMs: options.liveLatencyMaxAgeMs,
|
|
30390
30469
|
liveLatencyWarnAfterMs: options.liveLatencyWarnAfterMs ?? 1800,
|
|
30391
|
-
mediaPipeline
|
|
30470
|
+
mediaPipeline,
|
|
30471
|
+
telephonyMedia
|
|
30392
30472
|
});
|
|
30393
30473
|
const checks = [
|
|
30394
30474
|
{
|
|
@@ -30671,11 +30751,11 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
30671
30751
|
const firstIssue = telephonyMedia.issues[0];
|
|
30672
30752
|
checks.push({
|
|
30673
30753
|
detail: telephonyMediaSummary.status === "pass" ? `Telephony media serializers are passing for ${telephonyMediaSummary.passed}/${telephonyMediaSummary.carriers} carrier(s) with ${telephonyMediaSummary.audioBytes} audio byte(s), ${telephonyMediaSummary.mediaEvents} media event(s), and valid start/media/stop lifecycle sequencing.` : firstIssue ?? `${telephonyMediaSummary.issues} telephony media serializer issue(s) need review.`,
|
|
30674
|
-
href: options.links?.telephonyMedia ?? "/voice/telephony-media",
|
|
30754
|
+
href: firstOperationsRecordHref(operationsRecords.telephonyMedia) ?? options.links?.telephonyMedia ?? "/voice/telephony-media",
|
|
30675
30755
|
label: "Telephony media serializers",
|
|
30676
30756
|
proofSource: proofSource("telephonyMedia", "carrierMediaSerializers"),
|
|
30677
30757
|
gateExplanation: telephonyMediaSummary.status === "pass" ? undefined : {
|
|
30678
|
-
evidenceHref: options.links?.telephonyMedia ?? "/voice/telephony-media",
|
|
30758
|
+
evidenceHref: firstOperationsRecordHref(operationsRecords.telephonyMedia) ?? options.links?.telephonyMedia ?? "/voice/telephony-media",
|
|
30679
30759
|
observed: firstIssue ?? `${telephonyMediaSummary.issues} issue(s)`,
|
|
30680
30760
|
remediation: "Inspect carrier media proof, fix start/media/stop sequencing, payload parsing, byte flow, or outbound envelope serialization, then rerun readiness proof.",
|
|
30681
30761
|
thresholdLabel: "Telephony media serializer and lifecycle status",
|
|
@@ -30684,6 +30764,13 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
|
|
|
30684
30764
|
status: telephonyMediaSummary.status,
|
|
30685
30765
|
value: telephonyMediaSummary.status === "pass" ? `${telephonyMediaSummary.passed}/${telephonyMediaSummary.carriers}` : `${telephonyMediaSummary.failed}/${telephonyMediaSummary.carriers} failing`,
|
|
30686
30766
|
actions: telephonyMediaSummary.status === "pass" ? [] : [
|
|
30767
|
+
...firstOperationsRecordHref(operationsRecords.telephonyMedia) ? [
|
|
30768
|
+
{
|
|
30769
|
+
description: "Open the exact call/session operations record for the first telephony media lifecycle issue.",
|
|
30770
|
+
href: firstOperationsRecordHref(operationsRecords.telephonyMedia),
|
|
30771
|
+
label: "Open telephony media operations record"
|
|
30772
|
+
}
|
|
30773
|
+
] : [],
|
|
30687
30774
|
{
|
|
30688
30775
|
description: "Open telephony media proof and inspect carrier media lifecycle sequencing, payload parsing, MediaFrame shape, byte flow, and outbound envelope serialization.",
|
|
30689
30776
|
href: options.links?.telephonyMedia ?? "/voice/telephony-media",
|
|
@@ -35518,6 +35605,7 @@ export {
|
|
|
35518
35605
|
hasVoiceOpsTaskSLABreach,
|
|
35519
35606
|
getVoiceLiveOpsControlStatus,
|
|
35520
35607
|
getVoiceCampaignDialerProofStatus,
|
|
35608
|
+
getLatestVoiceTelephonyMediaReport,
|
|
35521
35609
|
getLatestVoiceBrowserMediaReport,
|
|
35522
35610
|
formatVoiceProofTrendAge,
|
|
35523
35611
|
filterVoiceTraceEvents,
|
|
@@ -351,6 +351,7 @@ export type VoiceProductionReadinessOperationsRecordLinks = {
|
|
|
351
351
|
failingLatency: VoiceProductionReadinessOperationsRecordLink[];
|
|
352
352
|
mediaQuality: VoiceProductionReadinessOperationsRecordLink[];
|
|
353
353
|
providerErrors: VoiceProductionReadinessOperationsRecordLink[];
|
|
354
|
+
telephonyMedia: VoiceProductionReadinessOperationsRecordLink[];
|
|
354
355
|
};
|
|
355
356
|
export type VoiceProductionReadinessAuditRequirement = {
|
|
356
357
|
label?: string;
|
|
@@ -98,6 +98,7 @@ export type TwilioMediaStreamBridgeOptions<TContext = unknown, TSession extends
|
|
|
98
98
|
scenarioId?: string;
|
|
99
99
|
sessionId?: string;
|
|
100
100
|
stt: STTAdapter;
|
|
101
|
+
telephonyMediaCarrier?: 'plivo' | 'telnyx' | 'twilio';
|
|
101
102
|
};
|
|
102
103
|
export type TwilioMediaStreamBridge = {
|
|
103
104
|
close: (reason?: string) => Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import type { MediaFrame, MediaTelephonyCarrier, MediaTelephonyEnvelope, MediaTelephonyStreamLifecycleReport } from '@absolutejs/media';
|
|
3
|
+
import type { VoiceTraceEventStore } from './trace';
|
|
3
4
|
export type VoiceTelephonyMediaStatus = 'fail' | 'pass';
|
|
4
5
|
export type VoiceTelephonyMediaCarrierInput = {
|
|
5
6
|
carrier: MediaTelephonyCarrier;
|
|
@@ -27,11 +28,17 @@ export type VoiceTelephonyMediaRoutesOptions = {
|
|
|
27
28
|
htmlPath?: false | string;
|
|
28
29
|
name?: string;
|
|
29
30
|
path?: string;
|
|
31
|
+
store?: VoiceTraceEventStore;
|
|
30
32
|
title?: string;
|
|
31
33
|
};
|
|
34
|
+
export type VoiceTelephonyMediaTraceReportOptions = {
|
|
35
|
+
carriers?: readonly MediaTelephonyCarrier[];
|
|
36
|
+
store: VoiceTraceEventStore;
|
|
37
|
+
};
|
|
32
38
|
export declare const buildVoiceTelephonyMediaReport: (input?: {
|
|
33
39
|
carriers?: readonly VoiceTelephonyMediaCarrierInput[];
|
|
34
40
|
}) => VoiceTelephonyMediaReport;
|
|
41
|
+
export declare const getLatestVoiceTelephonyMediaReport: (options: VoiceTelephonyMediaTraceReportOptions) => Promise<VoiceTelephonyMediaReport | undefined>;
|
|
35
42
|
export declare const renderVoiceTelephonyMediaHTML: (report: VoiceTelephonyMediaReport, options?: {
|
|
36
43
|
title?: string;
|
|
37
44
|
}) => string;
|
package/dist/testing/index.js
CHANGED
|
@@ -10202,6 +10202,25 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
10202
10202
|
};
|
|
10203
10203
|
let sessionHandle = null;
|
|
10204
10204
|
let reviewArtifactDelivered = false;
|
|
10205
|
+
const telephonyMediaCarrier = options.telephonyMediaCarrier ?? "twilio";
|
|
10206
|
+
const appendTelephonyMediaTrace = async (message, override) => {
|
|
10207
|
+
const trace = options.trace;
|
|
10208
|
+
const sessionId = override?.sessionId ?? bridgeState.sessionId ?? (message.event === "start" ? message.start.customParameters?.sessionId : undefined) ?? (message.event === "start" ? message.start.streamSid : "telephony-media");
|
|
10209
|
+
const streamSid = override?.streamSid ?? (message.event === "start" ? message.start.streamSid : ("streamSid" in message) ? message.streamSid : undefined);
|
|
10210
|
+
await trace?.append({
|
|
10211
|
+
at: Date.now(),
|
|
10212
|
+
payload: {
|
|
10213
|
+
callSid: message.event === "start" ? message.start.callSid : message.event === "stop" ? message.stop?.callSid : bridgeState.callSid ?? undefined,
|
|
10214
|
+
carrier: telephonyMediaCarrier,
|
|
10215
|
+
envelope: message,
|
|
10216
|
+
event: message.event,
|
|
10217
|
+
streamId: streamSid
|
|
10218
|
+
},
|
|
10219
|
+
scenarioId: bridgeState.scenarioId ?? undefined,
|
|
10220
|
+
sessionId,
|
|
10221
|
+
type: "client.telephony_media"
|
|
10222
|
+
});
|
|
10223
|
+
};
|
|
10205
10224
|
const resolveLexicon = async () => {
|
|
10206
10225
|
if (typeof options.lexicon === "function") {
|
|
10207
10226
|
return normalizeLexicon(await options.lexicon({
|
|
@@ -10302,6 +10321,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
10302
10321
|
reason: message.start.callSid,
|
|
10303
10322
|
text: bridgeState.sessionId ?? undefined
|
|
10304
10323
|
});
|
|
10324
|
+
await appendTelephonyMediaTrace(message, {
|
|
10325
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
10326
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
10327
|
+
});
|
|
10305
10328
|
await ensureSession();
|
|
10306
10329
|
return;
|
|
10307
10330
|
}
|
|
@@ -10322,6 +10345,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
10322
10345
|
})));
|
|
10323
10346
|
}
|
|
10324
10347
|
bridgeState.hasOutboundAudioSinceLastInbound = false;
|
|
10348
|
+
await appendTelephonyMediaTrace(message, {
|
|
10349
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
10350
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
10351
|
+
});
|
|
10325
10352
|
await activeSession.receiveAudio(transcodeTwilioInboundPayloadToPCM16(message.media.payload));
|
|
10326
10353
|
return;
|
|
10327
10354
|
}
|
|
@@ -10336,6 +10363,10 @@ var createTwilioMediaStreamBridge = (socket, options) => {
|
|
|
10336
10363
|
event: "stop",
|
|
10337
10364
|
reason: message.stop?.callSid
|
|
10338
10365
|
});
|
|
10366
|
+
await appendTelephonyMediaTrace(message, {
|
|
10367
|
+
sessionId: bridgeState.sessionId ?? undefined,
|
|
10368
|
+
streamSid: bridgeState.streamSid ?? undefined
|
|
10369
|
+
});
|
|
10339
10370
|
await sessionHandle?.close("twilio-stop");
|
|
10340
10371
|
return;
|
|
10341
10372
|
}
|
package/dist/trace.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { S3Client, S3Options } from 'bun';
|
|
2
|
-
export type VoiceTraceEventType = 'assistant.guardrail' | 'assistant.memory' | 'assistant.run' | 'agent.context' | 'agent.handoff' | 'agent.model' | 'agent.result' | 'agent.tool' | 'call.handoff' | 'call.lifecycle' | 'client.barge_in' | 'client.browser_media' | 'client.live_latency' | 'client.reconnect' | 'operator.action' | 'provider.decision' | 'session.error' | 'turn.assistant' | 'turn.committed' | 'turn.cost' | 'turn_latency.stage' | 'turn.transcript' | 'workflow.contract';
|
|
2
|
+
export type VoiceTraceEventType = 'assistant.guardrail' | 'assistant.memory' | 'assistant.run' | 'agent.context' | 'agent.handoff' | 'agent.model' | 'agent.result' | 'agent.tool' | 'call.handoff' | 'call.lifecycle' | 'client.barge_in' | 'client.browser_media' | 'client.live_latency' | 'client.reconnect' | 'client.telephony_media' | 'operator.action' | 'provider.decision' | 'session.error' | 'turn.assistant' | 'turn.committed' | 'turn.cost' | 'turn_latency.stage' | 'turn.transcript' | 'workflow.contract';
|
|
3
3
|
export type VoiceTraceEvent<TPayload extends Record<string, unknown> = Record<string, unknown>> = {
|
|
4
4
|
at: number;
|
|
5
5
|
id?: string;
|
|
@@ -118,6 +118,13 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
|
|
|
118
118
|
readonly sessionId: string;
|
|
119
119
|
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
120
120
|
}[];
|
|
121
|
+
readonly telephonyMedia: readonly {
|
|
122
|
+
readonly detail?: string | undefined;
|
|
123
|
+
readonly href: string;
|
|
124
|
+
readonly label: string;
|
|
125
|
+
readonly sessionId: string;
|
|
126
|
+
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
127
|
+
}[];
|
|
121
128
|
} | undefined;
|
|
122
129
|
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
123
130
|
readonly summary: {
|
|
@@ -543,6 +550,13 @@ export declare const useVoiceReadinessFailures: (path?: string, options?: VoiceR
|
|
|
543
550
|
readonly sessionId: string;
|
|
544
551
|
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
545
552
|
}[];
|
|
553
|
+
readonly telephonyMedia: readonly {
|
|
554
|
+
readonly detail?: string | undefined;
|
|
555
|
+
readonly href: string;
|
|
556
|
+
readonly label: string;
|
|
557
|
+
readonly sessionId: string;
|
|
558
|
+
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
559
|
+
}[];
|
|
546
560
|
} | undefined;
|
|
547
561
|
readonly status: import("..").VoiceProductionReadinessStatus;
|
|
548
562
|
readonly summary: {
|