@absolutejs/voice 0.0.22-beta.497 → 0.0.22-beta.499

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.js CHANGED
@@ -3413,6 +3413,39 @@ var encodePcmAsWav = (pcm, format) => {
3413
3413
  output.set(pcm, 44);
3414
3414
  return output;
3415
3415
  };
3416
+ var interleaveStereoPcm = (input) => {
3417
+ const leftSamples = new Int16Array(input.left.buffer, input.left.byteOffset, Math.floor(input.left.byteLength / 2));
3418
+ const rightSamples = new Int16Array(input.right.buffer, input.right.byteOffset, Math.floor(input.right.byteLength / 2));
3419
+ const frameCount = Math.max(leftSamples.length, rightSamples.length);
3420
+ const output = new Int16Array(frameCount * 2);
3421
+ for (let frame = 0;frame < frameCount; frame += 1) {
3422
+ output[frame * 2] = leftSamples[frame] ?? 0;
3423
+ output[frame * 2 + 1] = rightSamples[frame] ?? 0;
3424
+ }
3425
+ return new Uint8Array(output.buffer);
3426
+ };
3427
+ var encodeStereoWav = ({
3428
+ format,
3429
+ left,
3430
+ right
3431
+ }) => {
3432
+ if (format.container !== "raw" || format.encoding !== "pcm_s16le") {
3433
+ throw new Error("encodeStereoWav requires raw pcm_s16le format on each channel");
3434
+ }
3435
+ if (format.channels !== 1) {
3436
+ throw new Error("encodeStereoWav expects mono input channels");
3437
+ }
3438
+ const interleaved = interleaveStereoPcm({ left, right });
3439
+ return encodePcmAsWav(interleaved, { ...format, channels: 2 });
3440
+ };
3441
+ var createVoiceWavRecordingEncoder = () => ({
3442
+ encode: ({ format, pcm }) => ({
3443
+ bytes: encodePcmAsWav(pcm, format),
3444
+ contentType: "audio/wav",
3445
+ extension: "wav"
3446
+ }),
3447
+ kind: "wav"
3448
+ });
3416
3449
  var computePcmDurationMs = (pcmByteLength, format) => {
3417
3450
  if (format.container !== "raw" || format.encoding !== "pcm_s16le") {
3418
3451
  return 0;
@@ -35232,6 +35265,44 @@ var createVoiceTranscriptRedactor = (options = {}) => {
35232
35265
  };
35233
35266
  };
35234
35267
  var redactVoiceTranscript = (transcript, patterns = DEFAULT_VOICE_REDACTION_PATTERNS) => createVoiceTranscriptRedactor({ patterns })(transcript);
35268
+ // src/recordingRedaction.ts
35269
+ var matchesAnyPattern = (text, patterns) => {
35270
+ for (const pattern of patterns) {
35271
+ pattern.regex.lastIndex = 0;
35272
+ if (pattern.regex.test(text)) {
35273
+ pattern.regex.lastIndex = 0;
35274
+ return pattern;
35275
+ }
35276
+ }
35277
+ return;
35278
+ };
35279
+ var deriveVoiceRecordingRedactionRanges = (input) => {
35280
+ const patterns = input.patterns ?? DEFAULT_VOICE_REDACTION_PATTERNS;
35281
+ const padding = Math.max(0, input.paddingMs ?? 100);
35282
+ const baseEpoch = input.recordingStartedAtEpochMs;
35283
+ const out = [];
35284
+ for (const transcript of input.transcripts) {
35285
+ if (!transcript.isFinal)
35286
+ continue;
35287
+ if (typeof transcript.startedAtMs !== "number")
35288
+ continue;
35289
+ if (typeof transcript.endedAtMs !== "number")
35290
+ continue;
35291
+ const matched = matchesAnyPattern(transcript.text, patterns);
35292
+ if (!matched)
35293
+ continue;
35294
+ const absStart = transcript.startedAtMs;
35295
+ const absEnd = transcript.endedAtMs;
35296
+ const start = typeof baseEpoch === "number" && absStart >= baseEpoch ? absStart - baseEpoch : absStart;
35297
+ const end = typeof baseEpoch === "number" && absEnd >= baseEpoch ? absEnd - baseEpoch : absEnd;
35298
+ out.push({
35299
+ endMs: end + padding,
35300
+ label: matched.label,
35301
+ startMs: Math.max(0, start - padding)
35302
+ });
35303
+ }
35304
+ return out;
35305
+ };
35235
35306
  // src/costAccounting.ts
35236
35307
  var DEFAULT_VOICE_PRICE_BOOK = {
35237
35308
  "anthropic:claude-opus-4-5": {
@@ -36481,6 +36552,524 @@ var createVoiceApiRequestTool = (options) => {
36481
36552
  resultToMessage: options.formatResult ?? ((result) => result.ok ? `API request ${options.name} succeeded (${String(result.status)}).` : `API request ${options.name} failed with status ${String(result.status)}.`)
36482
36553
  });
36483
36554
  };
36555
+ // src/defineVoiceAssistant.ts
36556
+ var DEFAULT_SPEECH_THRESHOLD2 = 0.015;
36557
+ var DEFAULT_SILENCE_MS2 = 700;
36558
+ var DEFAULT_TRANSCRIPT_STABILITY_MS2 = 200;
36559
+ var resolveTurnDetection = (input) => ({
36560
+ profile: input?.profile ?? "balanced",
36561
+ qualityProfile: input?.qualityProfile ?? "general",
36562
+ silenceMs: input?.silenceMs ?? DEFAULT_SILENCE_MS2,
36563
+ speechThreshold: input?.speechThreshold ?? DEFAULT_SPEECH_THRESHOLD2,
36564
+ transcriptStabilityMs: input?.transcriptStabilityMs ?? DEFAULT_TRANSCRIPT_STABILITY_MS2
36565
+ });
36566
+ var resolveReconnect = (input) => ({
36567
+ maxAttempts: input?.maxAttempts ?? 3,
36568
+ strategy: input?.strategy ?? "resume-last-turn",
36569
+ timeout: input?.timeout ?? 30000
36570
+ });
36571
+ var buildAssistantOptions = (def) => ({
36572
+ ...def.agent,
36573
+ guardrails: def.guardrails,
36574
+ id: def.id,
36575
+ memory: def.memory,
36576
+ memoryLifecycle: def.memoryLifecycle,
36577
+ ops: def.ops
36578
+ });
36579
+ var defineVoiceAssistant = (definition) => {
36580
+ const assistantOptions = buildAssistantOptions(definition);
36581
+ const assistant = createVoiceAssistant(assistantOptions);
36582
+ return {
36583
+ assistant,
36584
+ definition,
36585
+ id: definition.id,
36586
+ toSessionOptions: (input) => {
36587
+ const route = assistant.route(definition.route ?? {});
36588
+ const observability = definition.observability ?? {};
36589
+ return {
36590
+ amd: definition.amd,
36591
+ assistantMode: definition.assistantMode,
36592
+ audioConditioning: definition.audioConditioning,
36593
+ callSilenceTimeoutMs: definition.callSilenceTimeoutMs,
36594
+ context: input.context,
36595
+ costAccountant: observability.costAccountant,
36596
+ costTelephony: observability.costTelephony,
36597
+ id: input.id,
36598
+ languageStrategy: definition.languageStrategy,
36599
+ lexicon: definition.lexicon,
36600
+ modalities: definition.modalities,
36601
+ phraseHints: definition.phraseHints,
36602
+ prosody: definition.voice.prosody,
36603
+ realtime: definition.voice.realtime,
36604
+ realtimeInputFormat: definition.voice.realtimeInputFormat,
36605
+ reconnect: resolveReconnect(input.reconnect),
36606
+ recording: observability.recording,
36607
+ redact: definition.redact,
36608
+ route,
36609
+ scenarioId: input.scenarioId,
36610
+ semanticTurnDetector: definition.semanticTurnDetector,
36611
+ sessionMetadata: { ...definition.metadata, ...input.sessionMetadata },
36612
+ socket: input.socket,
36613
+ store: input.store,
36614
+ stt: definition.voice.stt,
36615
+ sttFallback: definition.voice.sttFallback,
36616
+ sttLifecycle: input.sttLifecycle ?? "continuous",
36617
+ trace: observability.trace,
36618
+ tts: definition.voice.tts,
36619
+ turnDetection: resolveTurnDetection(definition.turnDetection)
36620
+ };
36621
+ }
36622
+ };
36623
+ };
36624
+ // src/callQuota.ts
36625
+ var monthBucketKey = (epochMs) => {
36626
+ const date = new Date(epochMs);
36627
+ return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}`;
36628
+ };
36629
+ var createInMemoryVoiceCallQuota = (options) => {
36630
+ const tiers = new Map(options.tiers.map((tier) => [tier.customerId, tier]));
36631
+ const activeCalls = new Map;
36632
+ const monthlyUsage = new Map;
36633
+ const usageFor = (customerId) => {
36634
+ const key = monthBucketKey(Date.now());
36635
+ let bucket = monthlyUsage.get(customerId);
36636
+ if (!bucket) {
36637
+ bucket = new Map;
36638
+ monthlyUsage.set(customerId, bucket);
36639
+ }
36640
+ return { bucket, key };
36641
+ };
36642
+ return {
36643
+ describe: (customerId) => {
36644
+ const tier = tiers.get(customerId);
36645
+ if (!tier)
36646
+ return;
36647
+ const active = activeCalls.get(customerId)?.size ?? 0;
36648
+ const { bucket, key } = usageFor(customerId);
36649
+ return {
36650
+ activeCalls: active,
36651
+ burstAllowance: tier.burstAllowance ?? 0,
36652
+ monthlyMinutesUsed: bucket.get(key) ?? 0,
36653
+ reservedConcurrent: tier.reservedConcurrent,
36654
+ tier
36655
+ };
36656
+ },
36657
+ recordMinutes: ({ customerId, minutes }) => {
36658
+ const { bucket, key } = usageFor(customerId);
36659
+ bucket.set(key, (bucket.get(key) ?? 0) + Math.max(0, minutes));
36660
+ },
36661
+ reserve: ({ callId, customerId }) => {
36662
+ const tier = tiers.get(customerId);
36663
+ if (!tier) {
36664
+ if (options.strict) {
36665
+ return {
36666
+ ok: false,
36667
+ rejection: { customerId, reason: "customer-not-found" }
36668
+ };
36669
+ }
36670
+ return {
36671
+ ok: true,
36672
+ reservation: {
36673
+ callId,
36674
+ customerId,
36675
+ release: () => {},
36676
+ reservedAt: Date.now()
36677
+ }
36678
+ };
36679
+ }
36680
+ const limit = tier.reservedConcurrent + (tier.burstAllowance ?? 0);
36681
+ const set = activeCalls.get(customerId) ?? new Set;
36682
+ if (set.size >= limit) {
36683
+ return {
36684
+ ok: false,
36685
+ rejection: {
36686
+ customerId,
36687
+ reason: "concurrency-exceeded",
36688
+ retryAfterMs: 30000
36689
+ }
36690
+ };
36691
+ }
36692
+ if (typeof tier.monthlyMinutes === "number") {
36693
+ const { bucket, key } = usageFor(customerId);
36694
+ if ((bucket.get(key) ?? 0) >= tier.monthlyMinutes) {
36695
+ return {
36696
+ ok: false,
36697
+ rejection: {
36698
+ customerId,
36699
+ reason: "monthly-minutes-exceeded"
36700
+ }
36701
+ };
36702
+ }
36703
+ }
36704
+ set.add(callId);
36705
+ activeCalls.set(customerId, set);
36706
+ return {
36707
+ ok: true,
36708
+ reservation: {
36709
+ callId,
36710
+ customerId,
36711
+ release: () => {
36712
+ set.delete(callId);
36713
+ if (set.size === 0)
36714
+ activeCalls.delete(customerId);
36715
+ },
36716
+ reservedAt: Date.now()
36717
+ }
36718
+ };
36719
+ }
36720
+ };
36721
+ };
36722
+ // src/routeAuth.ts
36723
+ import { Elysia as Elysia53 } from "elysia";
36724
+ var createVoiceBearerAuthVerifier = (input) => {
36725
+ const headerName = (input.headerName ?? "authorization").toLowerCase();
36726
+ const expected = `Bearer ${input.expectedToken}`;
36727
+ return ({ headers }) => {
36728
+ const value = headers.get(headerName);
36729
+ if (!value) {
36730
+ return { allow: false, reason: "missing-bearer", status: 401 };
36731
+ }
36732
+ if (value !== expected) {
36733
+ return { allow: false, reason: "bearer-mismatch", status: 401 };
36734
+ }
36735
+ return { allow: true };
36736
+ };
36737
+ };
36738
+ var createVoiceHMACAuthVerifier = (input) => {
36739
+ return async ({ body, headers }) => {
36740
+ const { signature, timestamp } = extractVoiceWebhookSignatureFromHeaders(headers);
36741
+ const result = await verifyVoiceWebhookSignature({
36742
+ body: body ?? "",
36743
+ secret: input.secret,
36744
+ signature,
36745
+ timestamp,
36746
+ toleranceMs: input.toleranceMs
36747
+ });
36748
+ if (!result.ok) {
36749
+ return { allow: false, reason: result.reason, status: 401 };
36750
+ }
36751
+ return { allow: true };
36752
+ };
36753
+ };
36754
+ var isBypassed = (bypassPaths, url) => {
36755
+ for (const path of bypassPaths) {
36756
+ if (url.includes(path))
36757
+ return true;
36758
+ }
36759
+ return false;
36760
+ };
36761
+ var createVoiceRouteAuth = (options) => {
36762
+ const bypassPaths = options.bypassPaths ?? [];
36763
+ return new Elysia53({ name: options.name ?? "voice-route-auth" }).onRequest(async ({ request, set }) => {
36764
+ const url = request.url;
36765
+ if (isBypassed(bypassPaths, url))
36766
+ return;
36767
+ const cloned = request.clone();
36768
+ const body = request.method === "GET" || request.method === "HEAD" ? "" : await cloned.text().catch(() => "");
36769
+ const decision = await Promise.resolve(options.verify({
36770
+ body,
36771
+ headers: request.headers,
36772
+ method: request.method,
36773
+ url
36774
+ }));
36775
+ if (!decision.allow) {
36776
+ set.status = decision.status ?? 401;
36777
+ return new Response(JSON.stringify({ error: decision.reason, ok: false }), {
36778
+ headers: { "content-type": "application/json" },
36779
+ status: decision.status ?? 401
36780
+ });
36781
+ }
36782
+ });
36783
+ };
36784
+ // src/client/costDashboard.ts
36785
+ var padTwo = (value) => String(value).padStart(2, "0");
36786
+ var formatBucketKey = (epochMs, bucketBy) => {
36787
+ const date = new Date(epochMs);
36788
+ const y = date.getUTCFullYear();
36789
+ const m = padTwo(date.getUTCMonth() + 1);
36790
+ const d = padTwo(date.getUTCDate());
36791
+ const h = padTwo(date.getUTCHours());
36792
+ if (bucketBy === "month")
36793
+ return `${y}-${m}`;
36794
+ if (bucketBy === "day")
36795
+ return `${y}-${m}-${d}`;
36796
+ return `${y}-${m}-${d}T${h}`;
36797
+ };
36798
+ var isCostBreakdown = (value) => Boolean(value) && typeof value === "object" && typeof value.totalUsd === "number";
36799
+ var emptyBucket = (bucketKey2) => ({
36800
+ bucketKey: bucketKey2,
36801
+ callCount: 0,
36802
+ llmUsd: 0,
36803
+ sttUsd: 0,
36804
+ telephonyMinutes: 0,
36805
+ telephonyUsd: 0,
36806
+ totalUsd: 0,
36807
+ ttsUsd: 0
36808
+ });
36809
+ var accumulate = (bucket, payload) => {
36810
+ bucket.callCount += 1;
36811
+ bucket.llmUsd += payload.llm.usd;
36812
+ bucket.sttUsd += payload.stt.usd;
36813
+ bucket.ttsUsd += payload.tts.usd;
36814
+ bucket.telephonyUsd += payload.telephony.usd;
36815
+ bucket.telephonyMinutes += payload.telephony.minutes;
36816
+ bucket.totalUsd += payload.totalUsd;
36817
+ };
36818
+ var roundCurrency = (bucket) => {
36819
+ bucket.llmUsd = Math.round(bucket.llmUsd * 1e6) / 1e6;
36820
+ bucket.sttUsd = Math.round(bucket.sttUsd * 1e6) / 1e6;
36821
+ bucket.ttsUsd = Math.round(bucket.ttsUsd * 1e6) / 1e6;
36822
+ bucket.telephonyUsd = Math.round(bucket.telephonyUsd * 1e6) / 1e6;
36823
+ bucket.totalUsd = Math.round(bucket.totalUsd * 1e6) / 1e6;
36824
+ };
36825
+ var buildVoiceCostDashboardReport = (options) => {
36826
+ const bucketBy = options.bucketBy ?? "day";
36827
+ const fromMs = options.fromMs ?? Number.NEGATIVE_INFINITY;
36828
+ const toMs = options.toMs ?? Number.POSITIVE_INFINITY;
36829
+ const buckets = new Map;
36830
+ const grandTotal = emptyBucket("total");
36831
+ let minMs = Number.POSITIVE_INFINITY;
36832
+ let maxMs = Number.NEGATIVE_INFINITY;
36833
+ for (const event of options.events) {
36834
+ if (event.type !== "cost.ready")
36835
+ continue;
36836
+ if (event.at < fromMs || event.at > toMs)
36837
+ continue;
36838
+ if (!isCostBreakdown(event.payload))
36839
+ continue;
36840
+ minMs = Math.min(minMs, event.at);
36841
+ maxMs = Math.max(maxMs, event.at);
36842
+ const bucketKey2 = formatBucketKey(event.at, bucketBy);
36843
+ let bucket = buckets.get(bucketKey2);
36844
+ if (!bucket) {
36845
+ bucket = emptyBucket(bucketKey2);
36846
+ buckets.set(bucketKey2, bucket);
36847
+ }
36848
+ accumulate(bucket, event.payload);
36849
+ accumulate(grandTotal, event.payload);
36850
+ }
36851
+ for (const bucket of buckets.values()) {
36852
+ roundCurrency(bucket);
36853
+ }
36854
+ roundCurrency(grandTotal);
36855
+ return {
36856
+ buckets: Array.from(buckets.values()).sort((a, b) => a.bucketKey.localeCompare(b.bucketKey)),
36857
+ generatedAt: Date.now(),
36858
+ grandTotal,
36859
+ windowEndMs: Number.isFinite(maxMs) ? maxMs : 0,
36860
+ windowStartMs: Number.isFinite(minMs) ? minMs : 0
36861
+ };
36862
+ };
36863
+ // src/client/liveCallViewer.ts
36864
+ var EVENT_BUFFER_LIMIT = 200;
36865
+ var createLiveCallViewer = (options) => {
36866
+ const bufferLimit = options.bufferLimit ?? EVENT_BUFFER_LIMIT;
36867
+ const subscribers = new Set;
36868
+ let state = {
36869
+ agentState: "idle",
36870
+ callDurationMs: 0,
36871
+ events: [],
36872
+ isConnected: true,
36873
+ isLiveListening: true,
36874
+ partialTranscript: "",
36875
+ sessionId: options.sessionId
36876
+ };
36877
+ const startedAt = options.startedAt ?? Date.now();
36878
+ const notify = () => {
36879
+ for (const subscriber of subscribers)
36880
+ subscriber();
36881
+ };
36882
+ const update = (next) => {
36883
+ state = { ...state, ...next };
36884
+ state.callDurationMs = Math.max(0, Date.now() - startedAt);
36885
+ state.agentState = deriveVoiceAgentUIState({
36886
+ hasActivePartial: state.partialTranscript.length > 0,
36887
+ isConnected: state.isConnected,
36888
+ isPlaying: false,
36889
+ isRecording: state.isLiveListening,
36890
+ lastAssistantAt: state.lastAssistantAt,
36891
+ lastTranscriptAt: state.lastTranscriptAt
36892
+ });
36893
+ notify();
36894
+ };
36895
+ const pushEvent = (event) => {
36896
+ const next = state.events.concat(event);
36897
+ if (next.length > bufferLimit) {
36898
+ next.splice(0, next.length - bufferLimit);
36899
+ }
36900
+ update({ events: next });
36901
+ };
36902
+ return {
36903
+ applyControl: (control) => {
36904
+ pushEvent({
36905
+ at: Date.now(),
36906
+ detail: control.reason,
36907
+ kind: "lifecycle",
36908
+ title: `control:${control.type}`
36909
+ });
36910
+ },
36911
+ applyEvent: pushEvent,
36912
+ applyMonitorEvent: ({ payload, type }) => {
36913
+ pushEvent({
36914
+ at: Date.now(),
36915
+ detail: JSON.stringify(payload).slice(0, 240),
36916
+ kind: type === "call.lifecycle" ? "lifecycle" : "lifecycle",
36917
+ title: type
36918
+ });
36919
+ },
36920
+ getState: () => state,
36921
+ noteAgentAudio: (at) => {
36922
+ const ts = at ?? Date.now();
36923
+ update({ lastAssistantAt: ts });
36924
+ pushEvent({
36925
+ at: ts,
36926
+ kind: "agent_audio",
36927
+ title: "Agent audio frame"
36928
+ });
36929
+ },
36930
+ notePartial: (text, at) => {
36931
+ update({ partialTranscript: text });
36932
+ if (text) {
36933
+ pushEvent({
36934
+ at: at ?? Date.now(),
36935
+ detail: text,
36936
+ kind: "transcript",
36937
+ title: "Partial"
36938
+ });
36939
+ }
36940
+ },
36941
+ noteTranscript: (text, at) => {
36942
+ const ts = at ?? Date.now();
36943
+ update({ lastTranscriptAt: ts, partialTranscript: "" });
36944
+ pushEvent({
36945
+ at: ts,
36946
+ detail: text,
36947
+ kind: "transcript",
36948
+ title: "Final transcript"
36949
+ });
36950
+ },
36951
+ reset: (sessionId, startedAtOverride) => {
36952
+ state = {
36953
+ agentState: "idle",
36954
+ callDurationMs: 0,
36955
+ events: [],
36956
+ isConnected: true,
36957
+ isLiveListening: true,
36958
+ partialTranscript: "",
36959
+ sessionId
36960
+ };
36961
+ if (typeof startedAtOverride === "number") {}
36962
+ notify();
36963
+ },
36964
+ subscribe: (subscriber) => {
36965
+ subscribers.add(subscriber);
36966
+ return () => subscribers.delete(subscriber);
36967
+ }
36968
+ };
36969
+ };
36970
+ // src/client/replayTimeline.ts
36971
+ var categorize = (entry) => {
36972
+ const event = entry.event.toLowerCase();
36973
+ if (event.startsWith("stt.") || event.includes("user"))
36974
+ return "user";
36975
+ if (event.startsWith("tts.") || event.includes("assistant") || event.includes("agent"))
36976
+ return "agent";
36977
+ if (event.startsWith("tool.") || event.includes("tool"))
36978
+ return "tool";
36979
+ return "lifecycle";
36980
+ };
36981
+ var buildReplayTimelineReport = (input) => {
36982
+ const events = [];
36983
+ let summaryAgentTurns = 0;
36984
+ let summaryUserTurns = 0;
36985
+ let summaryToolCalls = 0;
36986
+ for (const entry of input.artifact.timeline ?? []) {
36987
+ const category = categorize(entry);
36988
+ if (category === "user")
36989
+ summaryUserTurns += 1;
36990
+ if (category === "agent")
36991
+ summaryAgentTurns += 1;
36992
+ if (category === "tool")
36993
+ summaryToolCalls += 1;
36994
+ events.push({
36995
+ at: entry.atMs,
36996
+ category,
36997
+ detail: entry.text ?? entry.reason,
36998
+ durationMs: entry.chunkDurationMs,
36999
+ label: entry.event
37000
+ });
37001
+ }
37002
+ events.sort((a, b) => a.at - b.at);
37003
+ const first = events[0]?.at ?? 0;
37004
+ const last = events.at(-1)?.at ?? first;
37005
+ return {
37006
+ duration: last - first,
37007
+ events,
37008
+ metadata: {
37009
+ artifactId: input.artifact.id ?? "",
37010
+ title: input.artifact.title
37011
+ },
37012
+ startedAt: first,
37013
+ summary: {
37014
+ agentTurns: summaryAgentTurns,
37015
+ toolCalls: summaryToolCalls,
37016
+ userTurns: summaryUserTurns
37017
+ }
37018
+ };
37019
+ };
37020
+ // src/retention.ts
37021
+ var defaultResolveAt = (event) => {
37022
+ if (!event || typeof event !== "object")
37023
+ return;
37024
+ const value = event.at;
37025
+ return typeof value === "number" ? value : undefined;
37026
+ };
37027
+ var purgeVoiceRetentionStore = async (store, options, now = Date.now()) => {
37028
+ const resolveAt = options.resolveAt ?? defaultResolveAt;
37029
+ const cutoff = now - Math.max(0, options.maxAgeMs);
37030
+ const records = await Promise.resolve(store.list());
37031
+ const purgedIds = [];
37032
+ let attempted = 0;
37033
+ let removed = 0;
37034
+ let failed = 0;
37035
+ for (const record of records) {
37036
+ const at = resolveAt(record);
37037
+ if (typeof at !== "number" || at >= cutoff)
37038
+ continue;
37039
+ attempted += 1;
37040
+ try {
37041
+ await Promise.resolve(store.remove(record.id));
37042
+ purgedIds.push(record.id);
37043
+ removed += 1;
37044
+ } catch {
37045
+ failed += 1;
37046
+ }
37047
+ }
37048
+ return { attempted, failed, purgedIds, reason: "expired", removed };
37049
+ };
37050
+ var createVoiceRetentionScheduler = (options) => {
37051
+ const intervalMs = Math.max(60000, options.intervalMs ?? 6 * 60 * 60000);
37052
+ let timer;
37053
+ const run = async () => {
37054
+ const report = await purgeVoiceRetentionStore(options.store, options.policy);
37055
+ options.onReport?.(report);
37056
+ };
37057
+ return {
37058
+ start: () => {
37059
+ if (timer)
37060
+ return;
37061
+ timer = setInterval(() => {
37062
+ run();
37063
+ }, intervalMs);
37064
+ },
37065
+ stop: () => {
37066
+ if (!timer)
37067
+ return;
37068
+ clearInterval(timer);
37069
+ timer = undefined;
37070
+ }
37071
+ };
37072
+ };
36484
37073
  // src/vapiAdapter.ts
36485
37074
  var VAPI_BUILT_IN_VARIABLES = {
36486
37075
  date: () => new Date().toISOString().slice(0, 10),
@@ -37064,7 +37653,7 @@ var assertVoiceAgentSquadContractEvidence = (reports, input = {}) => {
37064
37653
  return report;
37065
37654
  };
37066
37655
  // src/turnLatency.ts
37067
- import { Elysia as Elysia53 } from "elysia";
37656
+ import { Elysia as Elysia54 } from "elysia";
37068
37657
  var DEFAULT_WARN_AFTER_MS2 = 1800;
37069
37658
  var DEFAULT_FAIL_AFTER_MS2 = 3200;
37070
37659
  var escapeHtml50 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
@@ -37224,7 +37813,7 @@ var createVoiceTurnLatencyHTMLHandler = (options) => async () => {
37224
37813
  var createVoiceTurnLatencyRoutes = (options) => {
37225
37814
  const path = options.path ?? "/api/turn-latency";
37226
37815
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
37227
- const routes = new Elysia53({
37816
+ const routes = new Elysia54({
37228
37817
  name: options.name ?? "absolutejs-voice-turn-latency"
37229
37818
  }).get(path, createVoiceTurnLatencyJSONHandler(options));
37230
37819
  if (htmlPath) {
@@ -37233,7 +37822,7 @@ var createVoiceTurnLatencyRoutes = (options) => {
37233
37822
  return routes;
37234
37823
  };
37235
37824
  // src/liveLatency.ts
37236
- import { Elysia as Elysia54 } from "elysia";
37825
+ import { Elysia as Elysia55 } from "elysia";
37237
37826
  var escapeHtml51 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37238
37827
  var percentile6 = (values, percentileValue) => {
37239
37828
  if (values.length === 0) {
@@ -37307,7 +37896,7 @@ await traceStore.append({
37307
37896
  var createVoiceLiveLatencyRoutes = (options) => {
37308
37897
  const path = options.path ?? "/api/live-latency";
37309
37898
  const htmlPath = options.htmlPath === undefined ? "/live-latency" : options.htmlPath;
37310
- const routes = new Elysia54({
37899
+ const routes = new Elysia55({
37311
37900
  name: options.name ?? "absolutejs-voice-live-latency"
37312
37901
  }).get(path, () => summarizeVoiceLiveLatency(options));
37313
37902
  if (htmlPath) {
@@ -37324,7 +37913,7 @@ var createVoiceLiveLatencyRoutes = (options) => {
37324
37913
  return routes;
37325
37914
  };
37326
37915
  // src/turnQuality.ts
37327
- import { Elysia as Elysia55 } from "elysia";
37916
+ import { Elysia as Elysia56 } from "elysia";
37328
37917
  var DEFAULT_CONFIDENCE_WARN_THRESHOLD = 0.72;
37329
37918
  var escapeHtml52 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
37330
37919
  var getTurnLatencyMs = (turn) => {
@@ -37430,7 +38019,7 @@ var createVoiceTurnQualityHTMLHandler = (options) => async () => {
37430
38019
  var createVoiceTurnQualityRoutes = (options) => {
37431
38020
  const path = options.path ?? "/api/turn-quality";
37432
38021
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
37433
- const routes = new Elysia55({
38022
+ const routes = new Elysia56({
37434
38023
  name: options.name ?? "absolutejs-voice-turn-quality"
37435
38024
  }).get(path, createVoiceTurnQualityJSONHandler(options));
37436
38025
  if (htmlPath) {
@@ -37439,10 +38028,10 @@ var createVoiceTurnQualityRoutes = (options) => {
37439
38028
  return routes;
37440
38029
  };
37441
38030
  // src/phoneAgent.ts
37442
- import { Elysia as Elysia57 } from "elysia";
38031
+ import { Elysia as Elysia58 } from "elysia";
37443
38032
 
37444
38033
  // src/phoneAgentProductionSmoke.ts
37445
- import { Elysia as Elysia56 } from "elysia";
38034
+ import { Elysia as Elysia57 } from "elysia";
37446
38035
  var defaultRequirements = [
37447
38036
  "media-started",
37448
38037
  "transcript",
@@ -37585,7 +38174,7 @@ var createVoicePhoneAgentProductionSmokeHTMLHandler = (options) => async ({
37585
38174
  var createVoicePhoneAgentProductionSmokeRoutes = (options) => {
37586
38175
  const path = options.path ?? "/api/voice/phone/smoke-contract";
37587
38176
  const htmlPath = options.htmlPath === undefined ? "/voice/phone/smoke-contract" : options.htmlPath;
37588
- const routes = new Elysia56({
38177
+ const routes = new Elysia57({
37589
38178
  name: options.name ?? "absolutejs-voice-phone-smoke-contract"
37590
38179
  }).get(path, createVoicePhoneAgentProductionSmokeJSONHandler(options));
37591
38180
  if (htmlPath) {
@@ -37916,7 +38505,7 @@ var createVoicePhoneAgent = (options) => {
37916
38505
  setupPath: resolveSetupPath(carrier),
37917
38506
  smokePath: resolveSmokePath(carrier)
37918
38507
  }));
37919
- const app = new Elysia57({
38508
+ const app = new Elysia58({
37920
38509
  name: options.name ?? "absolutejs-voice-phone-agent"
37921
38510
  });
37922
38511
  for (const carrier of options.carriers) {
@@ -39725,7 +40314,7 @@ var createOpenAIVoiceTTS = (options) => {
39725
40314
  };
39726
40315
  };
39727
40316
  // src/providerCapabilities.ts
39728
- import { Elysia as Elysia58 } from "elysia";
40317
+ import { Elysia as Elysia59 } from "elysia";
39729
40318
  var escapeHtml55 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
39730
40319
  var fromProviderList = (kind, providers, options) => (providers ?? []).map((provider) => ({
39731
40320
  configured: true,
@@ -39828,7 +40417,7 @@ var createVoiceProviderCapabilityHTMLHandler = (options) => async () => {
39828
40417
  var createVoiceProviderCapabilityRoutes = (options) => {
39829
40418
  const path = options.path ?? "/api/provider-capabilities";
39830
40419
  const htmlPath = options.htmlPath === undefined ? `${path}/htmx` : options.htmlPath;
39831
- const routes = new Elysia58({
40420
+ const routes = new Elysia59({
39832
40421
  name: options.name ?? "absolutejs-voice-provider-capabilities"
39833
40422
  }).get(path, createVoiceProviderCapabilityJSONHandler(options));
39834
40423
  if (htmlPath) {
@@ -39837,7 +40426,7 @@ var createVoiceProviderCapabilityRoutes = (options) => {
39837
40426
  return routes;
39838
40427
  };
39839
40428
  // src/providerOrchestration.ts
39840
- import { Elysia as Elysia59 } from "elysia";
40429
+ import { Elysia as Elysia60 } from "elysia";
39841
40430
  var defaultRequirement = {
39842
40431
  minProviders: 1,
39843
40432
  requireBudgetPolicy: false,
@@ -40013,7 +40602,7 @@ var createVoiceProviderOrchestrationRoutes = (options) => {
40013
40602
  const path = options.path ?? "/api/voice/provider-orchestration";
40014
40603
  const htmlPath = options.htmlPath === undefined ? "/voice/provider-orchestration" : options.htmlPath;
40015
40604
  const markdownPath = options.markdownPath === undefined ? "/voice/provider-orchestration.md" : options.markdownPath;
40016
- const routes = new Elysia59({
40605
+ const routes = new Elysia60({
40017
40606
  name: options.name ?? "absolutejs-voice-provider-orchestration"
40018
40607
  }).get(path, () => buildVoiceProviderOrchestrationReport(options));
40019
40608
  if (htmlPath) {
@@ -40186,7 +40775,7 @@ var assertVoiceProviderRoutingContractEvidence = (reports, input = {}) => {
40186
40775
  return report;
40187
40776
  };
40188
40777
  // src/voiceMonitoring.ts
40189
- import { Elysia as Elysia60 } from "elysia";
40778
+ import { Elysia as Elysia61 } from "elysia";
40190
40779
  var escapeHtml57 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40191
40780
  var issueIdForRun = (run) => `voice-monitor:${run.id}:${run.impactedSessions?.[0] ?? "global"}`;
40192
40781
  var rollupStatus5 = (runs) => runs.some((run) => run.status === "fail") ? "fail" : runs.some((run) => run.status === "warn") ? "warn" : "pass";
@@ -40471,7 +41060,7 @@ var createVoiceMonitorRoutes = (options) => {
40471
41060
  monitors: options.monitors,
40472
41061
  now: options.now
40473
41062
  });
40474
- const routes = new Elysia60({
41063
+ const routes = new Elysia61({
40475
41064
  name: options.name ?? "absolutejs-voice-monitoring"
40476
41065
  }).get(path, report).get(`${path}.md`, async () => {
40477
41066
  return new Response(renderVoiceMonitorMarkdown(await report()), {
@@ -40518,7 +41107,7 @@ var createVoiceMonitorRoutes = (options) => {
40518
41107
  };
40519
41108
  var createVoiceMonitorRunnerRoutes = (options) => {
40520
41109
  const path = options.path ?? "/api/voice/monitor-runner";
40521
- return new Elysia60({
41110
+ return new Elysia61({
40522
41111
  name: options.name ?? "absolutejs-voice-monitor-runner"
40523
41112
  }).get(path, () => ({
40524
41113
  isRunning: options.runner.isRunning()
@@ -40906,7 +41495,7 @@ var recommendVoiceReadinessProfile = (options) => {
40906
41495
  };
40907
41496
  };
40908
41497
  // src/providerStackRecommendations.ts
40909
- import { Elysia as Elysia61 } from "elysia";
41498
+ import { Elysia as Elysia62 } from "elysia";
40910
41499
  var escapeHtml58 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
40911
41500
  var profileProviderPriorities = {
40912
41501
  "meeting-recorder": {
@@ -41268,7 +41857,7 @@ var createVoiceProviderContractMatrixHTMLHandler = (options) => async () => {
41268
41857
  var createVoiceProviderContractMatrixRoutes = (options) => {
41269
41858
  const path = options.path ?? "/api/provider-contracts";
41270
41859
  const htmlPath = options.htmlPath ?? "/provider-contracts";
41271
- const routes = new Elysia61({
41860
+ const routes = new Elysia62({
41272
41861
  name: options.name ?? "absolutejs-voice-provider-contract-matrix"
41273
41862
  });
41274
41863
  const jsonHandler = createVoiceProviderContractMatrixJSONHandler(options.matrix);
@@ -41386,7 +41975,7 @@ var assertVoiceProviderStackEvidence = (report, input = {}) => {
41386
41975
  return assertion;
41387
41976
  };
41388
41977
  // src/opsConsoleRoutes.ts
41389
- import { Elysia as Elysia62 } from "elysia";
41978
+ import { Elysia as Elysia63 } from "elysia";
41390
41979
  var DEFAULT_LINKS = [
41391
41980
  {
41392
41981
  description: "Quality gates for CI, deploy checks, and production readiness.",
@@ -41503,7 +42092,7 @@ var renderVoiceOpsConsoleHTML = (report, options = {}) => {
41503
42092
  };
41504
42093
  var createVoiceOpsConsoleRoutes = (options) => {
41505
42094
  const path = options.path ?? "/ops-console";
41506
- const routes = new Elysia62({
42095
+ const routes = new Elysia63({
41507
42096
  name: options.name ?? "absolutejs-voice-ops-console"
41508
42097
  });
41509
42098
  const getReport = () => buildVoiceOpsConsoleReport(options);
@@ -41520,7 +42109,7 @@ var createVoiceOpsConsoleRoutes = (options) => {
41520
42109
  return routes;
41521
42110
  };
41522
42111
  // src/incidentBundle.ts
41523
- import { Elysia as Elysia63 } from "elysia";
42112
+ import { Elysia as Elysia64 } from "elysia";
41524
42113
  var filterIncidentBundleArtifacts = (artifacts, filter = {}) => artifacts.filter((artifact) => {
41525
42114
  if (filter.sessionId && artifact.sessionId !== filter.sessionId) {
41526
42115
  return false;
@@ -41737,7 +42326,7 @@ var buildVoiceIncidentBundle = async (options) => {
41737
42326
  var createVoiceIncidentBundleRoutes = (options) => {
41738
42327
  const path = options.path ?? "/api/voice-incidents/:sessionId";
41739
42328
  const markdownPath = options.markdownPath === undefined ? "/voice-incidents/:sessionId/markdown" : options.markdownPath;
41740
- const routes = new Elysia63({
42329
+ const routes = new Elysia64({
41741
42330
  name: options.name ?? "absolutejs-voice-incident-bundle"
41742
42331
  });
41743
42332
  const getSessionId = (params) => params.sessionId ?? "";
@@ -41938,7 +42527,7 @@ var summarizeVoiceOpsStatus = async (options) => {
41938
42527
  };
41939
42528
  };
41940
42529
  // src/opsStatusRoutes.ts
41941
- import { Elysia as Elysia64 } from "elysia";
42530
+ import { Elysia as Elysia65 } from "elysia";
41942
42531
  var escapeHtml60 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
41943
42532
  var renderVoiceOpsStatusHTML = (report, options = {}) => {
41944
42533
  const title = options.title ?? "AbsoluteJS Voice Ops Status";
@@ -41950,7 +42539,7 @@ var renderVoiceOpsStatusHTML = (report, options = {}) => {
41950
42539
  };
41951
42540
  var createVoiceOpsStatusRoutes = (options) => {
41952
42541
  const path = options.path ?? "/api/voice/ops-status";
41953
- const routes = new Elysia64({
42542
+ const routes = new Elysia65({
41954
42543
  name: options.name ?? "absolutejs-voice-ops-status"
41955
42544
  });
41956
42545
  routes.get(path, async () => summarizeVoiceOpsStatus(options));
@@ -42383,7 +42972,7 @@ var createVoiceTTSProviderRouter = (options) => {
42383
42972
  };
42384
42973
  };
42385
42974
  // src/traceDeliveryRoutes.ts
42386
- import { Elysia as Elysia65 } from "elysia";
42975
+ import { Elysia as Elysia66 } from "elysia";
42387
42976
  var escapeHtml61 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
42388
42977
  var getString20 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
42389
42978
  var getNumber12 = (value) => {
@@ -42492,7 +43081,7 @@ var createVoiceTraceDeliveryRoutes = (options) => {
42492
43081
  const path = options.path ?? "/api/voice-trace-deliveries";
42493
43082
  const htmlPath = options.htmlPath === undefined ? "/traces/deliveries" : options.htmlPath;
42494
43083
  const workerPath = options.workerPath === undefined ? `${path}/drain` : options.workerPath;
42495
- const routes = new Elysia65({
43084
+ const routes = new Elysia66({
42496
43085
  name: options.name ?? "absolutejs-voice-trace-deliveries"
42497
43086
  }).get(path, createVoiceTraceDeliveryJSONHandler(options));
42498
43087
  if (htmlPath !== false) {
@@ -42645,7 +43234,7 @@ var createVoiceMemoryStore = () => {
42645
43234
  return { get, getOrCreate, list, remove, set };
42646
43235
  };
42647
43236
  // src/opsWebhook.ts
42648
- import { Elysia as Elysia66 } from "elysia";
43237
+ import { Elysia as Elysia67 } from "elysia";
42649
43238
  var toHex7 = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
42650
43239
  var signVoiceOpsWebhookBody = async (input) => {
42651
43240
  const encoder2 = new TextEncoder;
@@ -42775,7 +43364,7 @@ var verifyVoiceOpsWebhookSignature = async (input) => {
42775
43364
  };
42776
43365
  var createVoiceOpsWebhookReceiverRoutes = (options = {}) => {
42777
43366
  const path = options.path ?? "/api/voice-ops/webhook";
42778
- return new Elysia66().post(path, async ({ body, request, set }) => {
43367
+ return new Elysia67().post(path, async ({ body, request, set }) => {
42779
43368
  const bodyText = typeof body === "string" ? body : JSON.stringify(body);
42780
43369
  if (options.signingSecret) {
42781
43370
  const verification = await verifyVoiceOpsWebhookSignature({
@@ -43230,7 +43819,7 @@ var resolveVoiceOpsPreset = (name, overrides = {}) => {
43230
43819
  };
43231
43820
  };
43232
43821
  // src/postCallAnalysis.ts
43233
- import { Elysia as Elysia67 } from "elysia";
43822
+ import { Elysia as Elysia68 } from "elysia";
43234
43823
  var isStore = (value) => Boolean(value) && typeof value === "object" && value !== null && ("list" in value);
43235
43824
  var asArray = async (value) => Array.isArray(value) ? value : isStore(value) ? await value.list() : [];
43236
43825
  var getPathValue3 = (source, path) => {
@@ -43409,7 +43998,7 @@ var resolvePostCallAnalysisReport = async (options, input) => {
43409
43998
  };
43410
43999
  var createVoicePostCallAnalysisRoutes = (options = {}) => {
43411
44000
  const path = options.path ?? "/api/voice/post-call-analysis";
43412
- const routes = new Elysia67({
44001
+ const routes = new Elysia68({
43413
44002
  name: options.name ?? "absolutejs-voice-post-call-analysis"
43414
44003
  });
43415
44004
  routes.get(path, async ({ query }) => {
@@ -43434,7 +44023,7 @@ var createVoicePostCallAnalysisRoutes = (options = {}) => {
43434
44023
  return routes;
43435
44024
  };
43436
44025
  // src/guardrails.ts
43437
- import { Elysia as Elysia68 } from "elysia";
44026
+ import { Elysia as Elysia69 } from "elysia";
43438
44027
  var stringifyContent = (value) => typeof value === "string" ? value : JSON.stringify(value) ?? "";
43439
44028
  var appliesToStage = (rule, stage) => !rule.stages || rule.stages.length === 0 || rule.stages.includes(stage);
43440
44029
  var matchesRule = async (rule, input) => {
@@ -43736,7 +44325,7 @@ var resolveGuardrailReport = async (options, input) => {
43736
44325
  };
43737
44326
  var createVoiceGuardrailRoutes = (options = {}) => {
43738
44327
  const path = options.path ?? "/api/voice/guardrails";
43739
- const routes = new Elysia68({
44328
+ const routes = new Elysia69({
43740
44329
  name: options.name ?? "absolutejs-voice-guardrails"
43741
44330
  });
43742
44331
  routes.all(path, async ({ request }) => {
@@ -44515,7 +45104,7 @@ var shapeTelephonyAssistantText = (text, options = {}) => {
44515
45104
  return ensureTerminalPunctuation(normalizeWhitespace(limitedChars));
44516
45105
  };
44517
45106
  // src/proofPack.ts
44518
- import { Elysia as Elysia69 } from "elysia";
45107
+ import { Elysia as Elysia70 } from "elysia";
44519
45108
  import { mkdir as mkdir5 } from "fs/promises";
44520
45109
  import { dirname as dirname3, join as join4 } from "path";
44521
45110
  var toGeneratedAt = (value) => value === undefined ? new Date().toISOString() : typeof value === "number" ? new Date(value).toISOString() : value;
@@ -45101,7 +45690,7 @@ var createVoiceProofPackArtifacts = (input) => [
45101
45690
  var createVoiceProofPackRoutes = (options) => {
45102
45691
  const jsonPath = options.jsonPath ?? "/api/voice/proof-pack";
45103
45692
  const markdownPath = options.markdownPath ?? "/voice/proof-pack.md";
45104
- const app = new Elysia69({ name: options.name ?? "voice-proof-pack" });
45693
+ const app = new Elysia70({ name: options.name ?? "voice-proof-pack" });
45105
45694
  if (jsonPath !== false) {
45106
45695
  app.get(jsonPath, async () => new Response(JSON.stringify(await resolveProofPack(options.source), null, 2), {
45107
45696
  headers: {
@@ -46202,7 +46791,7 @@ var buildVoiceMultilingualProofReadinessCheck = (report, options = {}) => {
46202
46791
  };
46203
46792
  };
46204
46793
  // src/monitor.ts
46205
- import { Elysia as Elysia70 } from "elysia";
46794
+ import { Elysia as Elysia71 } from "elysia";
46206
46795
  var buildAudioFanout = () => {
46207
46796
  const handlers = new Set;
46208
46797
  return {
@@ -46491,7 +47080,7 @@ var createVoiceLiveMonitorRoutes = (options) => {
46491
47080
  transfer: options.controlHandlers?.transfer ?? buildDefaultControlHandler("transfer"),
46492
47081
  voicemail: options.controlHandlers?.voicemail ?? buildDefaultControlHandler("voicemail")
46493
47082
  };
46494
- const app = new Elysia70({ name: "absolutejs-voice-monitor" });
47083
+ const app = new Elysia71({ name: "absolutejs-voice-monitor" });
46495
47084
  const unsubscribers = new WeakMap;
46496
47085
  if (listenPath !== false && listenPath.length > 0) {
46497
47086
  app.ws(`/${listenPath.replace(/^\/+/, "")}`, {
@@ -46889,6 +47478,7 @@ export {
46889
47478
  recommendVoiceProviderStack,
46890
47479
  recommendVoiceProfileSwitch,
46891
47480
  readVoiceProofTrendReportFile,
47481
+ purgeVoiceRetentionStore,
46892
47482
  pruneVoiceTraceEvents,
46893
47483
  pruneVoiceIncidentBundleArtifacts,
46894
47484
  parseVoiceTelephonyWebhookEvent,
@@ -46908,6 +47498,7 @@ export {
46908
47498
  isWithinCampaignWindow,
46909
47499
  isVoiceOpsTaskOverdue,
46910
47500
  isPhoneOnDNC,
47501
+ interleaveStereoPcm,
46911
47502
  importVoiceCampaignRecipients,
46912
47503
  heartbeatVoiceOpsTask,
46913
47504
  hasVoiceOpsTaskSLABreach,
@@ -46965,10 +47556,12 @@ export {
46965
47556
  evaluateVoiceBrowserCallProfileEvidence,
46966
47557
  evaluateVoiceAgentSquadContractEvidence,
46967
47558
  encodeTwilioMulawBase64,
47559
+ encodeStereoWav,
46968
47560
  encodePcmAsWav,
46969
47561
  describeVoiceIVRPlan,
46970
47562
  describeVoiceAssistantMode,
46971
47563
  describeVoiceAgentUIState,
47564
+ deriveVoiceRecordingRedactionRanges,
46972
47565
  deriveVoiceAgentUIState,
46973
47566
  deliverVoiceTraceEventsToSinks,
46974
47567
  deliverVoiceObservabilityExport,
@@ -46978,6 +47571,7 @@ export {
46978
47571
  deliverVoiceHandoffDelivery,
46979
47572
  deliverVoiceHandoff,
46980
47573
  deliverVoiceAuditEventsToSinks,
47574
+ defineVoiceAssistant,
46981
47575
  decodeTwilioMulawBase64,
46982
47576
  deadLetterVoiceOpsTask,
46983
47577
  createVoiceZeroRetentionPolicy,
@@ -46992,6 +47586,7 @@ export {
46992
47586
  createVoiceWebhookDeliveryWorkerLoop,
46993
47587
  createVoiceWebhookDeliveryWorker,
46994
47588
  createVoiceWebhookDeliverySink,
47589
+ createVoiceWavRecordingEncoder,
46995
47590
  createVoiceVoicemailDetectionTool,
46996
47591
  createVoiceTwilioRedirectHandoffAdapter,
46997
47592
  createVoiceTwilioCampaignDialer,
@@ -47077,7 +47672,9 @@ export {
47077
47672
  createVoiceS3RecordingStore,
47078
47673
  createVoiceS3DeliverySink,
47079
47674
  createVoiceRoutingDecisionSummary,
47675
+ createVoiceRouteAuth,
47080
47676
  createVoiceReviewSavedEvent,
47677
+ createVoiceRetentionScheduler,
47081
47678
  createVoiceResilienceRoutes,
47082
47679
  createVoiceRedisTelnyxWebhookEventStore,
47083
47680
  createVoiceRedisTelephonyWebhookIdempotencyStore,
@@ -47226,6 +47823,7 @@ export {
47226
47823
  createVoiceHandoffDeliveryWorkerLoop,
47227
47824
  createVoiceHandoffDeliveryWorker,
47228
47825
  createVoiceHandoffDeliveryRecord,
47826
+ createVoiceHMACAuthVerifier,
47229
47827
  createVoiceGuardrailRuntime,
47230
47828
  createVoiceGuardrailRoutes,
47231
47829
  createVoiceGuardrailPolicy,
@@ -47280,6 +47878,7 @@ export {
47280
47878
  createVoiceCRMActivitySink,
47281
47879
  createVoiceBrowserMediaRoutes,
47282
47880
  createVoiceBrowserCallProfileRoutes,
47881
+ createVoiceBearerAuthVerifier,
47283
47882
  createVoiceBargeInRoutes,
47284
47883
  createVoiceBackchannelDriver,
47285
47884
  createVoiceAuditTrailRoutes,
@@ -47330,7 +47929,9 @@ export {
47330
47929
  createMemoryVoiceTelnyxWebhookEventStore,
47331
47930
  createMemoryVoiceTelephonyWebhookIdempotencyStore,
47332
47931
  createMemoryVoicePlivoWebhookNonceStore,
47932
+ createLiveCallViewer,
47333
47933
  createJSONVoiceAssistantModel,
47934
+ createInMemoryVoiceCallQuota,
47334
47935
  createInMemoryDNCList,
47335
47936
  createId,
47336
47937
  createGeminiVoiceAssistantModel,
@@ -47424,6 +48025,7 @@ export {
47424
48025
  buildVoiceDeliveryRuntimeReport,
47425
48026
  buildVoiceDataRetentionPlan,
47426
48027
  buildVoiceDataControlReport,
48028
+ buildVoiceCostDashboardReport,
47427
48029
  buildVoiceCompetitiveCoverageReport,
47428
48030
  buildVoiceCampaignObservabilityReport,
47429
48031
  buildVoiceCallerMemoryNamespace,
@@ -47432,6 +48034,7 @@ export {
47432
48034
  buildVoiceAuditTrailReport,
47433
48035
  buildVoiceAuditExport,
47434
48036
  buildVoiceAuditDeliveryReport,
48037
+ buildReplayTimelineReport,
47435
48038
  buildOTELTraceId,
47436
48039
  buildOTELSpanId,
47437
48040
  buildEmptyVoiceProofTrendReport,