@absolutejs/voice 0.0.22-beta.326 → 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 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, () => buildVoiceTelephonyMediaReport({ carriers: options.carriers }));
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 = buildVoiceTelephonyMediaReport({
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,
@@ -35542,6 +35605,7 @@ export {
35542
35605
  hasVoiceOpsTaskSLABreach,
35543
35606
  getVoiceLiveOpsControlStatus,
35544
35607
  getVoiceCampaignDialerProofStatus,
35608
+ getLatestVoiceTelephonyMediaReport,
35545
35609
  getLatestVoiceBrowserMediaReport,
35546
35610
  formatVoiceProofTrendAge,
35547
35611
  filterVoiceTraceEvents,
@@ -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;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.326",
3
+ "version": "0.0.22-beta.327",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",