@absolutejs/voice 0.0.22-beta.322 → 0.0.22-beta.323

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.
@@ -5050,6 +5050,63 @@ var stringStat = (stat, key) => {
5050
5050
  };
5051
5051
  var statKey = (stat) => String(stat.id ?? stringStat(stat, "ssrc") ?? numericStat(stat, "ssrc") ?? stringStat(stat, "trackIdentifier") ?? stringStat(stat, "mid") ?? "unknown");
5052
5052
  var secondsToMs = (value) => value === undefined ? undefined : value * 1000;
5053
+ var DEFAULT_TELEPHONY_FORMAT = {
5054
+ channels: 1,
5055
+ container: "raw",
5056
+ encoding: "mulaw",
5057
+ sampleRateHz: 8000
5058
+ };
5059
+ var bytesToBase64 = (audio) => {
5060
+ const bytes = audio instanceof ArrayBuffer ? new Uint8Array(audio) : new Uint8Array(audio.buffer, audio.byteOffset, audio.byteLength);
5061
+ return Buffer.from(bytes).toString("base64");
5062
+ };
5063
+ var base64ToBytes = (value) => new Uint8Array(Buffer.from(value, "base64"));
5064
+ var unknownRecord = (value) => value && typeof value === "object" ? value : {};
5065
+ var firstString = (records, keys) => {
5066
+ for (const record of records) {
5067
+ for (const key of keys) {
5068
+ const value = record[key];
5069
+ if (typeof value === "string" && value.length > 0) {
5070
+ return value;
5071
+ }
5072
+ if (typeof value === "number" && Number.isFinite(value)) {
5073
+ return String(value);
5074
+ }
5075
+ }
5076
+ }
5077
+ return;
5078
+ };
5079
+ var firstNumber = (records, keys) => {
5080
+ for (const record of records) {
5081
+ for (const key of keys) {
5082
+ const value = record[key];
5083
+ if (typeof value === "number" && Number.isFinite(value)) {
5084
+ return value;
5085
+ }
5086
+ if (typeof value === "string") {
5087
+ const parsed = Number(value);
5088
+ if (Number.isFinite(parsed)) {
5089
+ return parsed;
5090
+ }
5091
+ }
5092
+ }
5093
+ }
5094
+ return;
5095
+ };
5096
+ var telephonyDirection = (track) => {
5097
+ const normalized = track?.toLowerCase();
5098
+ if (!normalized) {
5099
+ return "unknown";
5100
+ }
5101
+ if (normalized.includes("inbound") || normalized.includes("caller") || normalized.includes("in")) {
5102
+ return "inbound";
5103
+ }
5104
+ if (normalized.includes("outbound") || normalized.includes("assistant") || normalized.includes("out")) {
5105
+ return "outbound";
5106
+ }
5107
+ return "unknown";
5108
+ };
5109
+ var telephonyFrameKind = (direction) => direction === "outbound" ? "assistant-audio" : "input-audio";
5053
5110
  var normalizeWebRTCStat = (stat) => {
5054
5111
  const sample = {};
5055
5112
  for (const [key, value] of Object.entries(stat)) {
@@ -5059,6 +5116,113 @@ var normalizeWebRTCStat = (stat) => {
5059
5116
  }
5060
5117
  return sample;
5061
5118
  };
5119
+ var parseTelephonyMediaFrame = (input) => {
5120
+ const envelope = input.envelope;
5121
+ const media = unknownRecord(envelope.media);
5122
+ const payload = firstString([media, envelope], ["payload", "audio", "data"]) ?? firstString([unknownRecord(envelope.message)], ["payload"]);
5123
+ if (!payload) {
5124
+ return;
5125
+ }
5126
+ const carrier = input.carrier ?? firstString([envelope], ["provider"]) ?? "telephony";
5127
+ const streamId = firstString([media, envelope], ["streamSid", "stream_id", "streamId", "streamId", "callSid", "call_id"]);
5128
+ const sequenceNumber = firstString([media, envelope], ["sequenceNumber", "sequence_number", "chunk"]);
5129
+ const track = firstString([media, envelope], ["track", "direction"]);
5130
+ const direction = telephonyDirection(track);
5131
+ const timestamp = firstNumber([media, envelope], ["timestamp", "time", "startedAt"]);
5132
+ return {
5133
+ at: timestamp,
5134
+ audio: base64ToBytes(payload),
5135
+ format: input.format ?? DEFAULT_TELEPHONY_FORMAT,
5136
+ id: [
5137
+ carrier,
5138
+ streamId ?? input.sessionId ?? "stream",
5139
+ sequenceNumber ?? timestamp ?? Date.now()
5140
+ ].join(":"),
5141
+ kind: telephonyFrameKind(direction),
5142
+ metadata: {
5143
+ carrier,
5144
+ direction,
5145
+ event: firstString([envelope], ["event", "type"]),
5146
+ sequenceNumber,
5147
+ streamId,
5148
+ track
5149
+ },
5150
+ sessionId: input.sessionId ?? streamId,
5151
+ source: "telephony"
5152
+ };
5153
+ };
5154
+ var serializeTelephonyMediaFrame = (input) => {
5155
+ const carrier = input.carrier ?? input.frame.metadata?.carrier ?? "telephony";
5156
+ const streamId = input.streamId ?? (typeof input.frame.metadata?.streamId === "string" ? input.frame.metadata.streamId : input.frame.sessionId);
5157
+ const sequenceNumber = input.sequenceNumber ?? (typeof input.frame.metadata?.sequenceNumber === "string" || typeof input.frame.metadata?.sequenceNumber === "number" ? input.frame.metadata.sequenceNumber : undefined);
5158
+ const direction = input.frame.kind === "assistant-audio" ? "outbound" : "inbound";
5159
+ const payload = input.frame.audio ? bytesToBase64(input.frame.audio) : "";
5160
+ if (carrier === "twilio") {
5161
+ return {
5162
+ event: "media",
5163
+ sequenceNumber,
5164
+ streamSid: streamId,
5165
+ media: {
5166
+ payload,
5167
+ timestamp: input.frame.at,
5168
+ track: direction
5169
+ }
5170
+ };
5171
+ }
5172
+ if (carrier === "telnyx") {
5173
+ return {
5174
+ event: "media",
5175
+ stream_id: streamId,
5176
+ sequence_number: sequenceNumber,
5177
+ media: {
5178
+ payload,
5179
+ timestamp: input.frame.at,
5180
+ track: direction
5181
+ }
5182
+ };
5183
+ }
5184
+ if (carrier === "plivo") {
5185
+ return {
5186
+ event: "media",
5187
+ streamId,
5188
+ sequenceNumber,
5189
+ media: {
5190
+ payload,
5191
+ timestamp: input.frame.at,
5192
+ track: direction
5193
+ }
5194
+ };
5195
+ }
5196
+ return {
5197
+ event: "media",
5198
+ provider: carrier,
5199
+ sequenceNumber,
5200
+ streamId,
5201
+ media: {
5202
+ payload,
5203
+ timestamp: input.frame.at,
5204
+ track: direction
5205
+ }
5206
+ };
5207
+ };
5208
+ var createTelephonyMediaSerializer = (input) => {
5209
+ const format = input.format ?? DEFAULT_TELEPHONY_FORMAT;
5210
+ return {
5211
+ carrier: input.carrier,
5212
+ format,
5213
+ parse: (envelope) => parseTelephonyMediaFrame({
5214
+ carrier: input.carrier,
5215
+ envelope,
5216
+ format,
5217
+ sessionId: input.sessionId ?? input.streamId
5218
+ }),
5219
+ serialize: (frame) => serializeTelephonyMediaFrame({
5220
+ carrier: input.carrier,
5221
+ frame,
5222
+ streamId: input.streamId
5223
+ })
5224
+ };
5225
+ };
5062
5226
  var buildMediaResamplingPlan = (input) => {
5063
5227
  const required = !formatMatches(input.inputFormat, input.outputFormat);
5064
5228
  return {
@@ -3384,6 +3384,63 @@ var stringStat = (stat, key) => {
3384
3384
  };
3385
3385
  var statKey = (stat) => String(stat.id ?? stringStat(stat, "ssrc") ?? numericStat(stat, "ssrc") ?? stringStat(stat, "trackIdentifier") ?? stringStat(stat, "mid") ?? "unknown");
3386
3386
  var secondsToMs = (value) => value === undefined ? undefined : value * 1000;
3387
+ var DEFAULT_TELEPHONY_FORMAT = {
3388
+ channels: 1,
3389
+ container: "raw",
3390
+ encoding: "mulaw",
3391
+ sampleRateHz: 8000
3392
+ };
3393
+ var bytesToBase64 = (audio) => {
3394
+ const bytes = audio instanceof ArrayBuffer ? new Uint8Array(audio) : new Uint8Array(audio.buffer, audio.byteOffset, audio.byteLength);
3395
+ return Buffer.from(bytes).toString("base64");
3396
+ };
3397
+ var base64ToBytes = (value) => new Uint8Array(Buffer.from(value, "base64"));
3398
+ var unknownRecord = (value) => value && typeof value === "object" ? value : {};
3399
+ var firstString = (records, keys) => {
3400
+ for (const record of records) {
3401
+ for (const key of keys) {
3402
+ const value = record[key];
3403
+ if (typeof value === "string" && value.length > 0) {
3404
+ return value;
3405
+ }
3406
+ if (typeof value === "number" && Number.isFinite(value)) {
3407
+ return String(value);
3408
+ }
3409
+ }
3410
+ }
3411
+ return;
3412
+ };
3413
+ var firstNumber = (records, keys) => {
3414
+ for (const record of records) {
3415
+ for (const key of keys) {
3416
+ const value = record[key];
3417
+ if (typeof value === "number" && Number.isFinite(value)) {
3418
+ return value;
3419
+ }
3420
+ if (typeof value === "string") {
3421
+ const parsed = Number(value);
3422
+ if (Number.isFinite(parsed)) {
3423
+ return parsed;
3424
+ }
3425
+ }
3426
+ }
3427
+ }
3428
+ return;
3429
+ };
3430
+ var telephonyDirection = (track) => {
3431
+ const normalized = track?.toLowerCase();
3432
+ if (!normalized) {
3433
+ return "unknown";
3434
+ }
3435
+ if (normalized.includes("inbound") || normalized.includes("caller") || normalized.includes("in")) {
3436
+ return "inbound";
3437
+ }
3438
+ if (normalized.includes("outbound") || normalized.includes("assistant") || normalized.includes("out")) {
3439
+ return "outbound";
3440
+ }
3441
+ return "unknown";
3442
+ };
3443
+ var telephonyFrameKind = (direction) => direction === "outbound" ? "assistant-audio" : "input-audio";
3387
3444
  var normalizeWebRTCStat = (stat) => {
3388
3445
  const sample = {};
3389
3446
  for (const [key, value] of Object.entries(stat)) {
@@ -3393,6 +3450,113 @@ var normalizeWebRTCStat = (stat) => {
3393
3450
  }
3394
3451
  return sample;
3395
3452
  };
3453
+ var parseTelephonyMediaFrame = (input) => {
3454
+ const envelope = input.envelope;
3455
+ const media = unknownRecord(envelope.media);
3456
+ const payload = firstString([media, envelope], ["payload", "audio", "data"]) ?? firstString([unknownRecord(envelope.message)], ["payload"]);
3457
+ if (!payload) {
3458
+ return;
3459
+ }
3460
+ const carrier = input.carrier ?? firstString([envelope], ["provider"]) ?? "telephony";
3461
+ const streamId = firstString([media, envelope], ["streamSid", "stream_id", "streamId", "streamId", "callSid", "call_id"]);
3462
+ const sequenceNumber = firstString([media, envelope], ["sequenceNumber", "sequence_number", "chunk"]);
3463
+ const track = firstString([media, envelope], ["track", "direction"]);
3464
+ const direction = telephonyDirection(track);
3465
+ const timestamp = firstNumber([media, envelope], ["timestamp", "time", "startedAt"]);
3466
+ return {
3467
+ at: timestamp,
3468
+ audio: base64ToBytes(payload),
3469
+ format: input.format ?? DEFAULT_TELEPHONY_FORMAT,
3470
+ id: [
3471
+ carrier,
3472
+ streamId ?? input.sessionId ?? "stream",
3473
+ sequenceNumber ?? timestamp ?? Date.now()
3474
+ ].join(":"),
3475
+ kind: telephonyFrameKind(direction),
3476
+ metadata: {
3477
+ carrier,
3478
+ direction,
3479
+ event: firstString([envelope], ["event", "type"]),
3480
+ sequenceNumber,
3481
+ streamId,
3482
+ track
3483
+ },
3484
+ sessionId: input.sessionId ?? streamId,
3485
+ source: "telephony"
3486
+ };
3487
+ };
3488
+ var serializeTelephonyMediaFrame = (input) => {
3489
+ const carrier = input.carrier ?? input.frame.metadata?.carrier ?? "telephony";
3490
+ const streamId = input.streamId ?? (typeof input.frame.metadata?.streamId === "string" ? input.frame.metadata.streamId : input.frame.sessionId);
3491
+ const sequenceNumber = input.sequenceNumber ?? (typeof input.frame.metadata?.sequenceNumber === "string" || typeof input.frame.metadata?.sequenceNumber === "number" ? input.frame.metadata.sequenceNumber : undefined);
3492
+ const direction = input.frame.kind === "assistant-audio" ? "outbound" : "inbound";
3493
+ const payload = input.frame.audio ? bytesToBase64(input.frame.audio) : "";
3494
+ if (carrier === "twilio") {
3495
+ return {
3496
+ event: "media",
3497
+ sequenceNumber,
3498
+ streamSid: streamId,
3499
+ media: {
3500
+ payload,
3501
+ timestamp: input.frame.at,
3502
+ track: direction
3503
+ }
3504
+ };
3505
+ }
3506
+ if (carrier === "telnyx") {
3507
+ return {
3508
+ event: "media",
3509
+ stream_id: streamId,
3510
+ sequence_number: sequenceNumber,
3511
+ media: {
3512
+ payload,
3513
+ timestamp: input.frame.at,
3514
+ track: direction
3515
+ }
3516
+ };
3517
+ }
3518
+ if (carrier === "plivo") {
3519
+ return {
3520
+ event: "media",
3521
+ streamId,
3522
+ sequenceNumber,
3523
+ media: {
3524
+ payload,
3525
+ timestamp: input.frame.at,
3526
+ track: direction
3527
+ }
3528
+ };
3529
+ }
3530
+ return {
3531
+ event: "media",
3532
+ provider: carrier,
3533
+ sequenceNumber,
3534
+ streamId,
3535
+ media: {
3536
+ payload,
3537
+ timestamp: input.frame.at,
3538
+ track: direction
3539
+ }
3540
+ };
3541
+ };
3542
+ var createTelephonyMediaSerializer = (input) => {
3543
+ const format = input.format ?? DEFAULT_TELEPHONY_FORMAT;
3544
+ return {
3545
+ carrier: input.carrier,
3546
+ format,
3547
+ parse: (envelope) => parseTelephonyMediaFrame({
3548
+ carrier: input.carrier,
3549
+ envelope,
3550
+ format,
3551
+ sessionId: input.sessionId ?? input.streamId
3552
+ }),
3553
+ serialize: (frame) => serializeTelephonyMediaFrame({
3554
+ carrier: input.carrier,
3555
+ frame,
3556
+ streamId: input.streamId
3557
+ })
3558
+ };
3559
+ };
3396
3560
  var buildMediaResamplingPlan = (input) => {
3397
3561
  const required = !formatMatches(input.inputFormat, input.outputFormat);
3398
3562
  return {
@@ -0,0 +1,63 @@
1
+ import { Elysia } from 'elysia';
2
+ import type { MediaFrame, MediaTelephonyCarrier, MediaTelephonyEnvelope } from '@absolutejs/media';
3
+ export type VoiceTelephonyMediaStatus = 'fail' | 'pass';
4
+ export type VoiceTelephonyMediaCarrierInput = {
5
+ carrier: MediaTelephonyCarrier;
6
+ envelope?: MediaTelephonyEnvelope;
7
+ };
8
+ export type VoiceTelephonyMediaCarrierReport = {
9
+ audioBytes: number;
10
+ carrier: MediaTelephonyCarrier;
11
+ frame?: MediaFrame;
12
+ issues: string[];
13
+ serialized?: MediaTelephonyEnvelope;
14
+ status: VoiceTelephonyMediaStatus;
15
+ };
16
+ export type VoiceTelephonyMediaReport = {
17
+ carriers: readonly VoiceTelephonyMediaCarrierReport[];
18
+ checkedAt: number;
19
+ issues: string[];
20
+ status: VoiceTelephonyMediaStatus;
21
+ };
22
+ export type VoiceTelephonyMediaRoutesOptions = {
23
+ carriers?: readonly VoiceTelephonyMediaCarrierInput[];
24
+ headers?: HeadersInit;
25
+ htmlPath?: false | string;
26
+ name?: string;
27
+ path?: string;
28
+ title?: string;
29
+ };
30
+ export declare const buildVoiceTelephonyMediaReport: (input?: {
31
+ carriers?: readonly VoiceTelephonyMediaCarrierInput[];
32
+ }) => VoiceTelephonyMediaReport;
33
+ export declare const renderVoiceTelephonyMediaHTML: (report: VoiceTelephonyMediaReport, options?: {
34
+ title?: string;
35
+ }) => string;
36
+ export declare const createVoiceTelephonyMediaRoutes: (options?: VoiceTelephonyMediaRoutesOptions) => Elysia<"", {
37
+ decorator: {};
38
+ store: {};
39
+ derive: {};
40
+ resolve: {};
41
+ }, {
42
+ typebox: {};
43
+ error: {};
44
+ }, {
45
+ schema: {};
46
+ standaloneSchema: {};
47
+ macro: {};
48
+ macroFn: {};
49
+ parser: {};
50
+ response: {};
51
+ }, {}, {
52
+ derive: {};
53
+ resolve: {};
54
+ schema: {};
55
+ standaloneSchema: {};
56
+ response: {};
57
+ }, {
58
+ derive: {};
59
+ resolve: {};
60
+ schema: {};
61
+ standaloneSchema: {};
62
+ response: {};
63
+ }>;
@@ -2186,6 +2186,63 @@ var stringStat = (stat, key) => {
2186
2186
  };
2187
2187
  var statKey = (stat) => String(stat.id ?? stringStat(stat, "ssrc") ?? numericStat(stat, "ssrc") ?? stringStat(stat, "trackIdentifier") ?? stringStat(stat, "mid") ?? "unknown");
2188
2188
  var secondsToMs = (value) => value === undefined ? undefined : value * 1000;
2189
+ var DEFAULT_TELEPHONY_FORMAT = {
2190
+ channels: 1,
2191
+ container: "raw",
2192
+ encoding: "mulaw",
2193
+ sampleRateHz: 8000
2194
+ };
2195
+ var bytesToBase64 = (audio) => {
2196
+ const bytes = audio instanceof ArrayBuffer ? new Uint8Array(audio) : new Uint8Array(audio.buffer, audio.byteOffset, audio.byteLength);
2197
+ return Buffer.from(bytes).toString("base64");
2198
+ };
2199
+ var base64ToBytes = (value) => new Uint8Array(Buffer.from(value, "base64"));
2200
+ var unknownRecord = (value) => value && typeof value === "object" ? value : {};
2201
+ var firstString = (records, keys) => {
2202
+ for (const record of records) {
2203
+ for (const key of keys) {
2204
+ const value = record[key];
2205
+ if (typeof value === "string" && value.length > 0) {
2206
+ return value;
2207
+ }
2208
+ if (typeof value === "number" && Number.isFinite(value)) {
2209
+ return String(value);
2210
+ }
2211
+ }
2212
+ }
2213
+ return;
2214
+ };
2215
+ var firstNumber = (records, keys) => {
2216
+ for (const record of records) {
2217
+ for (const key of keys) {
2218
+ const value = record[key];
2219
+ if (typeof value === "number" && Number.isFinite(value)) {
2220
+ return value;
2221
+ }
2222
+ if (typeof value === "string") {
2223
+ const parsed = Number(value);
2224
+ if (Number.isFinite(parsed)) {
2225
+ return parsed;
2226
+ }
2227
+ }
2228
+ }
2229
+ }
2230
+ return;
2231
+ };
2232
+ var telephonyDirection = (track) => {
2233
+ const normalized = track?.toLowerCase();
2234
+ if (!normalized) {
2235
+ return "unknown";
2236
+ }
2237
+ if (normalized.includes("inbound") || normalized.includes("caller") || normalized.includes("in")) {
2238
+ return "inbound";
2239
+ }
2240
+ if (normalized.includes("outbound") || normalized.includes("assistant") || normalized.includes("out")) {
2241
+ return "outbound";
2242
+ }
2243
+ return "unknown";
2244
+ };
2245
+ var telephonyFrameKind = (direction) => direction === "outbound" ? "assistant-audio" : "input-audio";
2189
2246
  var normalizeWebRTCStat = (stat) => {
2190
2247
  const sample = {};
2191
2248
  for (const [key, value] of Object.entries(stat)) {
@@ -2195,6 +2252,113 @@ var normalizeWebRTCStat = (stat) => {
2195
2252
  }
2196
2253
  return sample;
2197
2254
  };
2255
+ var parseTelephonyMediaFrame = (input) => {
2256
+ const envelope = input.envelope;
2257
+ const media = unknownRecord(envelope.media);
2258
+ const payload = firstString([media, envelope], ["payload", "audio", "data"]) ?? firstString([unknownRecord(envelope.message)], ["payload"]);
2259
+ if (!payload) {
2260
+ return;
2261
+ }
2262
+ const carrier = input.carrier ?? firstString([envelope], ["provider"]) ?? "telephony";
2263
+ const streamId = firstString([media, envelope], ["streamSid", "stream_id", "streamId", "streamId", "callSid", "call_id"]);
2264
+ const sequenceNumber = firstString([media, envelope], ["sequenceNumber", "sequence_number", "chunk"]);
2265
+ const track = firstString([media, envelope], ["track", "direction"]);
2266
+ const direction = telephonyDirection(track);
2267
+ const timestamp = firstNumber([media, envelope], ["timestamp", "time", "startedAt"]);
2268
+ return {
2269
+ at: timestamp,
2270
+ audio: base64ToBytes(payload),
2271
+ format: input.format ?? DEFAULT_TELEPHONY_FORMAT,
2272
+ id: [
2273
+ carrier,
2274
+ streamId ?? input.sessionId ?? "stream",
2275
+ sequenceNumber ?? timestamp ?? Date.now()
2276
+ ].join(":"),
2277
+ kind: telephonyFrameKind(direction),
2278
+ metadata: {
2279
+ carrier,
2280
+ direction,
2281
+ event: firstString([envelope], ["event", "type"]),
2282
+ sequenceNumber,
2283
+ streamId,
2284
+ track
2285
+ },
2286
+ sessionId: input.sessionId ?? streamId,
2287
+ source: "telephony"
2288
+ };
2289
+ };
2290
+ var serializeTelephonyMediaFrame = (input) => {
2291
+ const carrier = input.carrier ?? input.frame.metadata?.carrier ?? "telephony";
2292
+ const streamId = input.streamId ?? (typeof input.frame.metadata?.streamId === "string" ? input.frame.metadata.streamId : input.frame.sessionId);
2293
+ const sequenceNumber = input.sequenceNumber ?? (typeof input.frame.metadata?.sequenceNumber === "string" || typeof input.frame.metadata?.sequenceNumber === "number" ? input.frame.metadata.sequenceNumber : undefined);
2294
+ const direction = input.frame.kind === "assistant-audio" ? "outbound" : "inbound";
2295
+ const payload = input.frame.audio ? bytesToBase64(input.frame.audio) : "";
2296
+ if (carrier === "twilio") {
2297
+ return {
2298
+ event: "media",
2299
+ sequenceNumber,
2300
+ streamSid: streamId,
2301
+ media: {
2302
+ payload,
2303
+ timestamp: input.frame.at,
2304
+ track: direction
2305
+ }
2306
+ };
2307
+ }
2308
+ if (carrier === "telnyx") {
2309
+ return {
2310
+ event: "media",
2311
+ stream_id: streamId,
2312
+ sequence_number: sequenceNumber,
2313
+ media: {
2314
+ payload,
2315
+ timestamp: input.frame.at,
2316
+ track: direction
2317
+ }
2318
+ };
2319
+ }
2320
+ if (carrier === "plivo") {
2321
+ return {
2322
+ event: "media",
2323
+ streamId,
2324
+ sequenceNumber,
2325
+ media: {
2326
+ payload,
2327
+ timestamp: input.frame.at,
2328
+ track: direction
2329
+ }
2330
+ };
2331
+ }
2332
+ return {
2333
+ event: "media",
2334
+ provider: carrier,
2335
+ sequenceNumber,
2336
+ streamId,
2337
+ media: {
2338
+ payload,
2339
+ timestamp: input.frame.at,
2340
+ track: direction
2341
+ }
2342
+ };
2343
+ };
2344
+ var createTelephonyMediaSerializer = (input) => {
2345
+ const format = input.format ?? DEFAULT_TELEPHONY_FORMAT;
2346
+ return {
2347
+ carrier: input.carrier,
2348
+ format,
2349
+ parse: (envelope) => parseTelephonyMediaFrame({
2350
+ carrier: input.carrier,
2351
+ envelope,
2352
+ format,
2353
+ sessionId: input.sessionId ?? input.streamId
2354
+ }),
2355
+ serialize: (frame) => serializeTelephonyMediaFrame({
2356
+ carrier: input.carrier,
2357
+ frame,
2358
+ streamId: input.streamId
2359
+ })
2360
+ };
2361
+ };
2198
2362
  var buildMediaResamplingPlan = (input) => {
2199
2363
  const required = !formatMatches(input.inputFormat, input.outputFormat);
2200
2364
  return {
@@ -8899,7 +9063,7 @@ var assertVoiceTelephonyWebhookNormalizationEvidence = (input = {}) => {
8899
9063
  return assertion;
8900
9064
  };
8901
9065
  var normalizeToken = (value) => typeof value === "string" ? value.trim().toLowerCase().replace(/\s+/g, "-").replace(/_+/g, "-") : undefined;
8902
- var firstString = (source, keys) => {
9066
+ var firstString2 = (source, keys) => {
8903
9067
  for (const key of keys) {
8904
9068
  const value = source[key];
8905
9069
  if (typeof value === "string" && value.trim()) {
@@ -8910,7 +9074,7 @@ var firstString = (source, keys) => {
8910
9074
  }
8911
9075
  }
8912
9076
  };
8913
- var firstNumber = (source, keys) => {
9077
+ var firstNumber2 = (source, keys) => {
8914
9078
  for (const key of keys) {
8915
9079
  const value = source[key];
8916
9080
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -9271,8 +9435,8 @@ var verifyVoiceTelephonyWebhook = async (input) => {
9271
9435
  var durationMsFromSeconds = (value) => typeof value === "number" ? value * 1000 : undefined;
9272
9436
  var parseVoiceTelephonyWebhookEvent = (input) => {
9273
9437
  const payload = flattenPayload(input.body);
9274
- const provider = firstString(payload, ["provider", "Provider"]) ?? input.provider;
9275
- const status = firstString(payload, [
9438
+ const provider = firstString2(payload, ["provider", "Provider"]) ?? input.provider;
9439
+ const status = firstString2(payload, [
9276
9440
  "CallStatus",
9277
9441
  "call_status",
9278
9442
  "callStatus",
@@ -9282,7 +9446,7 @@ var parseVoiceTelephonyWebhookEvent = (input) => {
9282
9446
  "event_type",
9283
9447
  "type"
9284
9448
  ]);
9285
- const durationMs = firstNumber(payload, ["durationMs", "duration_ms"]) ?? durationMsFromSeconds(firstNumber(payload, [
9449
+ const durationMs = firstNumber2(payload, ["durationMs", "duration_ms"]) ?? durationMsFromSeconds(firstNumber2(payload, [
9286
9450
  "CallDuration",
9287
9451
  "call_duration",
9288
9452
  "callDuration",
@@ -9290,16 +9454,16 @@ var parseVoiceTelephonyWebhookEvent = (input) => {
9290
9454
  "dial_call_duration",
9291
9455
  "duration"
9292
9456
  ]));
9293
- const sipCode = firstNumber(payload, [
9457
+ const sipCode = firstNumber2(payload, [
9294
9458
  "SipResponseCode",
9295
9459
  "sip_response_code",
9296
9460
  "sipCode",
9297
9461
  "sip_code",
9298
9462
  "hangupCauseCode"
9299
9463
  ]);
9300
- const from = firstString(payload, ["From", "from", "caller_id", "callerId"]);
9301
- const to = firstString(payload, ["To", "to", "called_number", "calledNumber"]);
9302
- const target = firstString(payload, [
9464
+ const from = firstString2(payload, ["From", "from", "caller_id", "callerId"]);
9465
+ const to = firstString2(payload, ["To", "to", "called_number", "calledNumber"]);
9466
+ const target = firstString2(payload, [
9303
9467
  "transferTarget",
9304
9468
  "TransferTarget",
9305
9469
  "target",
@@ -9307,7 +9471,7 @@ var parseVoiceTelephonyWebhookEvent = (input) => {
9307
9471
  "department"
9308
9472
  ]);
9309
9473
  return {
9310
- answeredBy: firstString(payload, [
9474
+ answeredBy: firstString2(payload, [
9311
9475
  "AnsweredBy",
9312
9476
  "answered_by",
9313
9477
  "answeredBy",
@@ -9321,7 +9485,7 @@ var parseVoiceTelephonyWebhookEvent = (input) => {
9321
9485
  ...payload
9322
9486
  },
9323
9487
  provider,
9324
- reason: firstString(payload, [
9488
+ reason: firstString2(payload, [
9325
9489
  "Reason",
9326
9490
  "reason",
9327
9491
  "HangupCause",
@@ -9337,7 +9501,7 @@ var parseVoiceTelephonyWebhookEvent = (input) => {
9337
9501
  var defaultSessionId = (input) => {
9338
9502
  const payload = flattenPayload(input.body);
9339
9503
  const metadataSessionId = input.event.metadata?.sessionId;
9340
- return firstString(input.query, ["sessionId", "session_id"]) ?? firstString(payload, [
9504
+ return firstString2(input.query, ["sessionId", "session_id"]) ?? firstString2(payload, [
9341
9505
  "sessionId",
9342
9506
  "session_id",
9343
9507
  "SessionId",
@@ -9352,7 +9516,7 @@ var defaultSessionId = (input) => {
9352
9516
  };
9353
9517
  var defaultIdempotencyKey = (input) => {
9354
9518
  const payload = flattenPayload(input.body);
9355
- const eventId = firstString(payload, [
9519
+ const eventId = firstString2(payload, [
9356
9520
  "id",
9357
9521
  "event_id",
9358
9522
  "eventId",