@absolutejs/voice 0.0.22-beta.451 → 0.0.22-beta.453

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
@@ -16525,6 +16525,7 @@ var readString2 = (value) => typeof value === "string" && value.trim() ? value :
16525
16525
  var readNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
16526
16526
  var readProofTrendMaxLiveP95 = (report) => report.summary.maxLiveP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.liveLatency?.p95Ms));
16527
16527
  var readProofTrendMaxProviderP95 = (report) => report.summary.maxProviderP95Ms ?? maxNumber((report.summary.providers ?? []).map((provider) => provider.p95Ms)) ?? maxNumber(report.cycles.flatMap((cycle) => (cycle.providers ?? []).map((provider) => provider.p95Ms)));
16528
+ var readProofTrendMaxReconnectP95 = (report) => report.summary.maxReconnectP95Ms ?? report.summary.reconnect?.resumeLatencyP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.reconnect?.resumeLatencyP95Ms));
16528
16529
  var readProofTrendMaxTurnP95 = (report) => report.summary.maxTurnP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.turnLatency?.p95Ms));
16529
16530
  var readRuntimeChannelMetric = (report, key) => {
16530
16531
  const summaryValue = report.summary.runtimeChannel?.[key];
@@ -16586,6 +16587,42 @@ var aggregateProofTrendRuntimeChannel = (channels) => {
16586
16587
  status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
16587
16588
  };
16588
16589
  };
16590
+ var aggregateProofTrendReconnect = (reconnects) => {
16591
+ if (reconnects.length === 0) {
16592
+ return;
16593
+ }
16594
+ const hasFailure = reconnects.some((reconnect) => reconnect.status === "fail" || reconnect.exhausted === true || reconnect.reconnected === false || reconnect.resumed === false);
16595
+ return {
16596
+ attempts: maxNumber(reconnects.map((reconnect) => reconnect.attempts)),
16597
+ exhausted: reconnects.some((reconnect) => reconnect.exhausted === true),
16598
+ maxAttempts: maxNumber(reconnects.map((reconnect) => reconnect.maxAttempts)),
16599
+ resumeLatencyP95Ms: maxNumber(reconnects.map((reconnect) => reconnect.resumeLatencyP95Ms)),
16600
+ reconnected: reconnects.some((reconnect) => reconnect.reconnected === true),
16601
+ resumed: reconnects.some((reconnect) => reconnect.resumed === true),
16602
+ samples: reconnects.reduce((total, reconnect) => total + (reconnect.samples ?? 0), 0),
16603
+ snapshotCount: reconnects.reduce((total, reconnect) => total + (reconnect.snapshotCount ?? 0), 0),
16604
+ status: hasFailure ? "fail" : reconnects.some((reconnect) => reconnect.status === "warn") ? "warn" : "pass"
16605
+ };
16606
+ };
16607
+ var summarizeReconnectTraceEvidence = (events) => {
16608
+ const reconnectEvents = events.filter((event) => event.type === "client.reconnect");
16609
+ if (reconnectEvents.length === 0) {
16610
+ return;
16611
+ }
16612
+ const statuses = reconnectEvents.map((event) => readString2(readTraceRecord(event).status)).filter((status) => status !== undefined);
16613
+ const reconnectPayloads = reconnectEvents.map((event) => readTraceRecord(event));
16614
+ return {
16615
+ attempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.attempts))),
16616
+ exhausted: statuses.includes("exhausted"),
16617
+ maxAttempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.maxAttempts))),
16618
+ resumeLatencyP95Ms: percentile2(reconnectPayloads.map((payload) => readNumber2(payload.resumeLatencyP95Ms) ?? readNumber2(payload.resumeLatencyMs)).filter((value) => value !== undefined), 95),
16619
+ reconnected: statuses.includes("reconnecting"),
16620
+ resumed: statuses.includes("resumed") || statuses.includes("pass"),
16621
+ samples: reconnectEvents.length,
16622
+ snapshotCount: reconnectEvents.length,
16623
+ status: reconnectEvents.some((event) => isFailingTraceStatus(readTraceStatus(readTraceRecord(event)))) ? "fail" : "pass"
16624
+ };
16625
+ };
16589
16626
  var readTraceRecord = (event) => event.payload;
16590
16627
  var readTraceProfileId = (events, options) => {
16591
16628
  for (const event of events) {
@@ -16733,6 +16770,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
16733
16770
  }).filter((value) => value !== undefined);
16734
16771
  const turnP95Ms = summarizeTurnTraceP95(sessionEvents);
16735
16772
  const providerP95Ms = maxNumber(providers.map((provider) => provider.p95Ms));
16773
+ const reconnect = summarizeReconnectTraceEvidence(sessionEvents);
16736
16774
  const runtimeChannel = summarizeRuntimeChannelTraceEvidence(sessionEvents);
16737
16775
  const surfaces = readRealCallProfileTraceSurfaces(sessionEvents);
16738
16776
  if (providers.length === 0 && runtimeChannel === undefined && liveLatencies.length === 0 && surfaces.length === 0) {
@@ -16748,6 +16786,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
16748
16786
  profileLabel: options.profileLabels?.[profileId] ?? (profileId === options.defaultProfileId ? options.defaultProfileLabel : undefined),
16749
16787
  providerP95Ms,
16750
16788
  providers,
16789
+ reconnect,
16751
16790
  runtimeChannel,
16752
16791
  sessionId,
16753
16792
  surfaces: surfaces.length > 0 ? surfaces : undefined,
@@ -16755,11 +16794,46 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
16755
16794
  };
16756
16795
  }).filter((evidence) => evidence !== undefined);
16757
16796
  };
16797
+ var normalizeReconnectReport = (report) => ("contract" in report) ? report.contract : report;
16798
+ var buildVoiceRealCallProfileEvidenceFromReconnectProofReports = (input, options = {}) => {
16799
+ const reports = Array.isArray(input) ? input : [input];
16800
+ const profileId = options.profileId ?? "reconnect-resume";
16801
+ return reports.map((report, index) => {
16802
+ const contract = normalizeReconnectReport(report);
16803
+ const generatedAt = "generatedAt" in report ? report.generatedAt : new Date(contract.checkedAt).toISOString();
16804
+ const ok = "ok" in report ? report.ok : contract.pass;
16805
+ const operationsRecordHref = typeof options.operationsRecordHref === "function" ? options.operationsRecordHref(report, index) : options.operationsRecordHref;
16806
+ const sessionId = typeof options.sessionId === "function" ? options.sessionId(report, index) : options.sessionId ?? `reconnect-proof-${String(index + 1)}-${String(contract.checkedAt)}`;
16807
+ return {
16808
+ generatedAt,
16809
+ ok,
16810
+ operationsRecordHref,
16811
+ profileDescription: options.profileDescription,
16812
+ profileId,
16813
+ profileLabel: options.profileLabel,
16814
+ reconnect: {
16815
+ attempts: contract.summary.attempts,
16816
+ exhausted: contract.summary.exhausted,
16817
+ maxAttempts: contract.summary.maxAttempts,
16818
+ resumeLatencyP95Ms: contract.resumeLatencyP95Ms,
16819
+ reconnected: contract.summary.reconnected,
16820
+ resumed: contract.summary.resumed,
16821
+ samples: 1,
16822
+ snapshotCount: contract.snapshotCount,
16823
+ status: ok ? "pass" : "fail"
16824
+ },
16825
+ sessionId,
16826
+ surfaces: [...new Set(["reconnect", ...options.surfaces ?? []])].sort()
16827
+ };
16828
+ });
16829
+ };
16758
16830
  var loadVoiceRealCallProfileEvidenceFromTraceStore = async (options) => buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.store.list({ limit: options.limit ?? 5000 }), options);
16831
+ var loadVoiceRealCallProfileEvidenceFromStore = async (options) => options.store.list(options);
16759
16832
  var realCallProfileTraceSignalTypes = new Set([
16760
16833
  "client.barge_in",
16761
16834
  "client.browser_media",
16762
16835
  "client.live_latency",
16836
+ "client.reconnect",
16763
16837
  "client.telephony_media",
16764
16838
  "provider.decision",
16765
16839
  "session.error",
@@ -16822,15 +16896,16 @@ var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.
16822
16896
  var exceedsProofTrendBudget = (value, budget) => value !== undefined && (!Number.isFinite(value) || value > budget);
16823
16897
  var readProofTrendProfileStatus = (profile, budgets) => {
16824
16898
  const runtimeChannel = profile.runtimeChannel;
16825
- const hasBudgetEvidence = profile.maxLiveP95Ms !== undefined || profile.maxProviderP95Ms !== undefined || profile.maxTurnP95Ms !== undefined || profile.providers?.some((provider) => provider.p95Ms !== undefined) === true || runtimeChannel?.maxFirstAudioLatencyMs !== undefined || runtimeChannel?.maxInterruptionP95Ms !== undefined || runtimeChannel?.maxJitterMs !== undefined || runtimeChannel?.maxTimestampDriftMs !== undefined || runtimeChannel?.maxBackpressureEvents !== undefined;
16826
- const budgetFailed = exceedsProofTrendBudget(profile.maxLiveP95Ms, budgets.maxLiveP95Ms) || exceedsProofTrendBudget(profile.maxProviderP95Ms, budgets.maxProviderP95Ms) || exceedsProofTrendBudget(profile.maxTurnP95Ms, budgets.maxTurnP95Ms) || exceedsProofTrendBudget(runtimeChannel?.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) || exceedsProofTrendBudget(runtimeChannel?.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) || exceedsProofTrendBudget(runtimeChannel?.maxJitterMs, budgets.maxRuntimeJitterMs) || exceedsProofTrendBudget(runtimeChannel?.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) || exceedsProofTrendBudget(runtimeChannel?.maxBackpressureEvents, 0);
16899
+ const reconnect = profile.reconnect;
16900
+ const hasBudgetEvidence = profile.maxLiveP95Ms !== undefined || profile.maxProviderP95Ms !== undefined || profile.maxReconnectP95Ms !== undefined || profile.maxTurnP95Ms !== undefined || profile.providers?.some((provider) => provider.p95Ms !== undefined) === true || runtimeChannel?.maxFirstAudioLatencyMs !== undefined || runtimeChannel?.maxInterruptionP95Ms !== undefined || runtimeChannel?.maxJitterMs !== undefined || runtimeChannel?.maxTimestampDriftMs !== undefined || runtimeChannel?.maxBackpressureEvents !== undefined || reconnect?.resumeLatencyP95Ms !== undefined || reconnect?.samples !== undefined;
16901
+ const budgetFailed = exceedsProofTrendBudget(profile.maxLiveP95Ms, budgets.maxLiveP95Ms) || exceedsProofTrendBudget(profile.maxProviderP95Ms, budgets.maxProviderP95Ms) || exceedsProofTrendBudget(profile.maxReconnectP95Ms ?? reconnect?.resumeLatencyP95Ms, budgets.maxReconnectP95Ms) || exceedsProofTrendBudget(profile.maxTurnP95Ms, budgets.maxTurnP95Ms) || exceedsProofTrendBudget(runtimeChannel?.maxFirstAudioLatencyMs, budgets.maxRuntimeFirstAudioLatencyMs) || exceedsProofTrendBudget(runtimeChannel?.maxInterruptionP95Ms, budgets.maxRuntimeInterruptionP95Ms) || exceedsProofTrendBudget(runtimeChannel?.maxJitterMs, budgets.maxRuntimeJitterMs) || exceedsProofTrendBudget(runtimeChannel?.maxTimestampDriftMs, budgets.maxRuntimeTimestampDriftMs) || exceedsProofTrendBudget(runtimeChannel?.maxBackpressureEvents, 0) || reconnect?.status === "fail";
16827
16902
  if (budgetFailed || !hasBudgetEvidence && profile.status === "fail") {
16828
16903
  return "fail";
16829
16904
  }
16830
- if (profile.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
16905
+ if (profile.status === "warn" || reconnect?.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
16831
16906
  return "warn";
16832
16907
  }
16833
- if (hasBudgetEvidence || profile.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
16908
+ if (hasBudgetEvidence || profile.status === "pass" || reconnect?.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
16834
16909
  return "pass";
16835
16910
  }
16836
16911
  return;
@@ -16840,6 +16915,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
16840
16915
  const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
16841
16916
  const providerCap = options.maxProviderP95Ms ?? 1000;
16842
16917
  const liveCap = options.maxLiveP95Ms ?? 800;
16918
+ const reconnectCap = options.maxReconnectP95Ms ?? 1500;
16843
16919
  const turnCap = options.maxTurnP95Ms ?? 700;
16844
16920
  const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
16845
16921
  const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
@@ -16848,6 +16924,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
16848
16924
  const budgets = {
16849
16925
  maxLiveP95Ms: liveCap,
16850
16926
  maxProviderP95Ms: providerCap,
16927
+ maxReconnectP95Ms: reconnectCap,
16851
16928
  maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
16852
16929
  maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
16853
16930
  maxRuntimeJitterMs: runtimeJitterCap,
@@ -16870,8 +16947,10 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
16870
16947
  label: definition.label ?? profiles.find(Boolean)?.label,
16871
16948
  maxLiveP95Ms: maxNumber(profiles.map((profile) => profile.maxLiveP95Ms)),
16872
16949
  maxProviderP95Ms: maxNumber(profiles.map((profile) => profile.maxProviderP95Ms)),
16950
+ maxReconnectP95Ms: maxNumber(profiles.map((profile) => profile.maxReconnectP95Ms)),
16873
16951
  maxTurnP95Ms: maxNumber(profiles.map((profile) => profile.maxTurnP95Ms)),
16874
16952
  providers: aggregateProofTrendProviders(profiles.flatMap((profile) => profile.providers ?? [])),
16953
+ reconnect: aggregateProofTrendReconnect(profiles.map((profile) => profile.reconnect).filter((reconnect) => reconnect !== undefined)),
16875
16954
  runtimeChannel: aggregateProofTrendRuntimeChannel(profiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
16876
16955
  sessionCount: profiles.reduce((total, profile) => total + (profile.sessionCount ?? 0), 0),
16877
16956
  surfaces: [
@@ -16911,6 +16990,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
16911
16990
  var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
16912
16991
  const providerCap = options.maxProviderP95Ms ?? 1000;
16913
16992
  const liveCap = options.maxLiveP95Ms ?? 800;
16993
+ const reconnectCap = options.maxReconnectP95Ms ?? 1500;
16914
16994
  const turnCap = options.maxTurnP95Ms ?? 700;
16915
16995
  const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
16916
16996
  const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
@@ -16919,6 +16999,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
16919
16999
  const budgets = {
16920
17000
  maxLiveP95Ms: liveCap,
16921
17001
  maxProviderP95Ms: providerCap,
17002
+ maxReconnectP95Ms: reconnectCap,
16922
17003
  maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
16923
17004
  maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
16924
17005
  maxRuntimeJitterMs: runtimeJitterCap,
@@ -16948,8 +17029,10 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
16948
17029
  label: definition.label ?? matchingEvidence.find((evidence) => evidence.profileLabel)?.profileLabel,
16949
17030
  maxLiveP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.liveP95Ms)),
16950
17031
  maxProviderP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.providerP95Ms)),
17032
+ maxReconnectP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
16951
17033
  maxTurnP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.turnP95Ms)),
16952
17034
  providers: aggregateProofTrendProviders(matchingEvidence.flatMap((evidence) => evidence.providers ?? [])),
17035
+ reconnect: aggregateProofTrendReconnect(matchingEvidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
16953
17036
  runtimeChannel: aggregateProofTrendRuntimeChannel(matchingEvidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined)),
16954
17037
  sessionCount: new Set(matchingEvidence.map((evidence) => evidence.sessionId)).size,
16955
17038
  surfaces: [
@@ -16968,6 +17051,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
16968
17051
  ok: evidence.ok !== false,
16969
17052
  providers: evidence.providers,
16970
17053
  runtimeChannel: evidence.runtimeChannel,
17054
+ reconnect: evidence.reconnect,
16971
17055
  turnLatency: evidence.turnP95Ms === undefined ? undefined : {
16972
17056
  p95Ms: evidence.turnP95Ms,
16973
17057
  samples: 1,
@@ -16978,9 +17062,11 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
16978
17062
  cycles: options.evidence.length,
16979
17063
  maxLiveP95Ms: maxNumber(options.evidence.map((evidence) => evidence.liveP95Ms)),
16980
17064
  maxProviderP95Ms: maxNumber(options.evidence.map((evidence) => evidence.providerP95Ms)),
17065
+ maxReconnectP95Ms: maxNumber(options.evidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
16981
17066
  maxTurnP95Ms: maxNumber(options.evidence.map((evidence) => evidence.turnP95Ms)),
16982
17067
  profiles,
16983
17068
  providers: aggregateProofTrendProviders(options.evidence.flatMap((evidence) => evidence.providers ?? [])),
17069
+ reconnect: aggregateProofTrendReconnect(options.evidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
16984
17070
  runtimeChannel: aggregateProofTrendRuntimeChannel(options.evidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined))
16985
17071
  };
16986
17072
  return buildVoiceProofTrendReport({
@@ -17585,6 +17671,74 @@ var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
17585
17671
  }
17586
17672
  };
17587
17673
  };
17674
+ var normalizeRealCallProfileEvidenceTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_evidence";
17675
+ var parseRealCallProfileEvidenceBoundary = (value) => value === undefined ? undefined : value instanceof Date ? value.getTime() : typeof value === "number" ? value : Date.parse(value);
17676
+ var readRealCallProfileEvidenceSortTime = (evidence, fallback) => Date.parse(evidence.generatedAt ?? fallback) || Date.parse(fallback);
17677
+ var createVoiceSQLiteRealCallProfileEvidenceStore = (options = {}) => {
17678
+ const { Database: SQLiteDatabase } = __require("bun:sqlite");
17679
+ const database = options.database ?? new SQLiteDatabase(options.path ?? ":memory:", {
17680
+ create: true
17681
+ });
17682
+ const tableName = normalizeRealCallProfileEvidenceTableName(options.tableName ?? "voice_real_call_profile_evidence");
17683
+ const now = () => (options.now ?? (() => new Date))().toISOString();
17684
+ const createId3 = () => `${options.idPrefix ?? "voice-profile-evidence"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
17685
+ database.exec("PRAGMA journal_mode = WAL;");
17686
+ database.exec("PRAGMA synchronous = NORMAL;");
17687
+ database.exec("PRAGMA busy_timeout = 5000;");
17688
+ database.exec(`CREATE TABLE IF NOT EXISTS "${tableName}" (
17689
+ id TEXT PRIMARY KEY,
17690
+ sort_at INTEGER NOT NULL,
17691
+ profile_id TEXT NOT NULL,
17692
+ session_id TEXT NOT NULL,
17693
+ created_at TEXT NOT NULL,
17694
+ payload TEXT NOT NULL
17695
+ )`);
17696
+ const selectStatement = database.query(`SELECT payload FROM "${tableName}" WHERE id = ?1 LIMIT 1`);
17697
+ const listStatement = database.query(`SELECT payload FROM "${tableName}" ORDER BY sort_at DESC, id DESC`);
17698
+ const upsertStatement = database.query(`INSERT INTO "${tableName}" (id, sort_at, profile_id, session_id, created_at, payload)
17699
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6)
17700
+ ON CONFLICT(id) DO UPDATE SET
17701
+ sort_at = excluded.sort_at,
17702
+ profile_id = excluded.profile_id,
17703
+ session_id = excluded.session_id,
17704
+ created_at = excluded.created_at,
17705
+ payload = excluded.payload`);
17706
+ const deleteStatement = database.query(`DELETE FROM "${tableName}" WHERE id = ?1`);
17707
+ const writeEvidence = (record) => {
17708
+ upsertStatement.run(record.id, readRealCallProfileEvidenceSortTime(record, record.createdAt), record.profileId, record.sessionId, record.createdAt, JSON.stringify(record));
17709
+ return record;
17710
+ };
17711
+ const readEvidence = (id) => {
17712
+ const row = selectStatement.get(id);
17713
+ return row ? JSON.parse(row.payload) : undefined;
17714
+ };
17715
+ const matchesListOptions = (record, input) => {
17716
+ const evidenceTime = readRealCallProfileEvidenceSortTime(record, record.createdAt);
17717
+ const since = parseRealCallProfileEvidenceBoundary(input.since);
17718
+ const until = parseRealCallProfileEvidenceBoundary(input.until);
17719
+ return (!input.profileId || record.profileId === input.profileId) && (!input.sessionId || record.sessionId === input.sessionId) && (since === undefined || Number.isNaN(since) || evidenceTime >= since) && (until === undefined || Number.isNaN(until) || evidenceTime <= until);
17720
+ };
17721
+ return {
17722
+ append(input) {
17723
+ const createdAt = input.createdAt ?? now();
17724
+ return writeEvidence({
17725
+ ...input,
17726
+ createdAt,
17727
+ id: input.id ?? createId3()
17728
+ });
17729
+ },
17730
+ get(id) {
17731
+ return readEvidence(id);
17732
+ },
17733
+ list(input = {}) {
17734
+ const limit = Number.isFinite(input.limit) && input.limit !== undefined && input.limit > 0 ? Math.floor(input.limit) : 500;
17735
+ return listStatement.all().map((row) => JSON.parse(row.payload)).filter((record) => matchesListOptions(record, input)).slice(0, limit);
17736
+ },
17737
+ remove(id) {
17738
+ deleteStatement.run(id);
17739
+ }
17740
+ };
17741
+ };
17588
17742
  var normalizeRealCallRecoveryJobTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_recovery_jobs";
17589
17743
  var createVoiceSQLiteRealCallProfileRecoveryJobStore = (options = {}) => {
17590
17744
  const { Database: SQLiteDatabase } = __require("bun:sqlite");
@@ -17799,10 +17953,12 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
17799
17953
  failedReports: history.filter((report) => report.ok !== true).length,
17800
17954
  maxLiveP95Ms: maxNumber(profileHistory.map(readProofTrendMaxLiveP95)),
17801
17955
  maxProviderP95Ms: maxNumber(profileHistory.map(readProofTrendMaxProviderP95)),
17956
+ maxReconnectP95Ms: maxNumber(profileHistory.map(readProofTrendMaxReconnectP95)),
17802
17957
  maxTurnP95Ms: maxNumber(profileHistory.map(readProofTrendMaxTurnP95)),
17803
17958
  profileCount: profiles.length,
17804
17959
  profiles,
17805
17960
  providers: readProofTrendProviders(profileHistory),
17961
+ reconnect: aggregateProofTrendReconnect(profileHistory.map((report) => report.summary.reconnect).filter((reconnect) => reconnect !== undefined)),
17806
17962
  runtimeChannel: aggregateProofTrendRuntimeChannel(profileHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
17807
17963
  };
17808
17964
  const trend = buildVoiceProofTrendReport({
@@ -17836,6 +17992,13 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
17836
17992
  trend
17837
17993
  };
17838
17994
  };
17995
+ var buildVoiceRealCallProfileHistoryReportFromStore = async (options) => {
17996
+ const evidence = await options.store.list(options);
17997
+ return buildVoiceRealCallProfileHistoryReport({
17998
+ ...options,
17999
+ evidence
18000
+ });
18001
+ };
17839
18002
  var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
17840
18003
  var providerSortScore = (provider) => [
17841
18004
  recommendationStatusRank[provider.status],
@@ -20505,6 +20668,7 @@ var normalizeSample = (input) => {
20505
20668
  interruptionP95Ms: input.summary.runtimeChannel?.maxInterruptionP95Ms,
20506
20669
  ok: input.ok,
20507
20670
  providerP95Ms: input.summary.maxProviderP95Ms,
20671
+ reconnectP95Ms: input.summary.maxReconnectP95Ms ?? input.summary.reconnect?.resumeLatencyP95Ms,
20508
20672
  runId: input.runId,
20509
20673
  source: input.source || input.outputDir,
20510
20674
  turnP95Ms: input.summary.maxTurnP95Ms
@@ -42219,6 +42383,7 @@ export {
42219
42383
  markVoiceOpsTaskSLABreached,
42220
42384
  mapVoiceProofTargetsWithConcurrency,
42221
42385
  loadVoiceRealCallProfileEvidenceFromTraceStore,
42386
+ loadVoiceRealCallProfileEvidenceFromStore,
42222
42387
  loadVoiceObservabilityExportReplaySource,
42223
42388
  listVoiceRoutingEvents,
42224
42389
  listVoiceProviderDecisionTraces,
@@ -42366,6 +42531,7 @@ export {
42366
42531
  createVoiceSQLiteRuntimeStorage,
42367
42532
  createVoiceSQLiteReviewStore,
42368
42533
  createVoiceSQLiteRealCallProfileRecoveryJobStore,
42534
+ createVoiceSQLiteRealCallProfileEvidenceStore,
42369
42535
  createVoiceSQLitePlivoWebhookNonceStore,
42370
42536
  createVoiceSQLiteIntegrationEventStore,
42371
42537
  createVoiceSQLiteExternalObjectMapStore,
@@ -42629,8 +42795,10 @@ export {
42629
42795
  buildVoiceRealCallProfileRecoveryJobHistoryCheck,
42630
42796
  buildVoiceRealCallProfileRecoveryActions,
42631
42797
  buildVoiceRealCallProfileReadinessCheck,
42798
+ buildVoiceRealCallProfileHistoryReportFromStore,
42632
42799
  buildVoiceRealCallProfileHistoryReport,
42633
42800
  buildVoiceRealCallProfileEvidenceFromTraceEvents,
42801
+ buildVoiceRealCallProfileEvidenceFromReconnectProofReports,
42634
42802
  buildVoiceRealCallProfileDefaults,
42635
42803
  buildVoiceReadinessRecoveryActions,
42636
42804
  buildVoiceProviderSloReport,
@@ -2,14 +2,17 @@ import { Elysia } from "elysia";
2
2
  import type { Database } from "bun:sqlite";
3
3
  import { type VoiceProviderDecisionStatus } from "./providerDecisionTraces";
4
4
  import type { VoiceProductionReadinessAction, VoiceProductionReadinessCheck, VoiceReadinessRecoveryAction } from "./productionReadiness";
5
+ import type { VoiceReconnectContractReport, VoiceReconnectProofReport } from "./reconnectContract";
5
6
  import { StoredVoiceTraceEvent, VoiceTraceEventStore } from "./trace";
6
7
  export type VoiceProofTrendStatus = "empty" | "fail" | "pass" | "stale";
7
8
  export type VoiceProofTrendSummary = {
8
9
  cycles?: number;
9
10
  maxLiveP95Ms?: number;
10
11
  maxProviderP95Ms?: number;
12
+ maxReconnectP95Ms?: number;
11
13
  profiles?: VoiceProofTrendProfileSummary[];
12
14
  providers?: VoiceProofTrendProviderSummary[];
15
+ reconnect?: VoiceProofTrendReconnectSummary;
13
16
  runtimeChannel?: VoiceProofTrendRuntimeChannelSummary;
14
17
  maxTurnP95Ms?: number;
15
18
  };
@@ -20,8 +23,10 @@ export type VoiceProofTrendProfileSummary = {
20
23
  label?: string;
21
24
  maxLiveP95Ms?: number;
22
25
  maxProviderP95Ms?: number;
26
+ maxReconnectP95Ms?: number;
23
27
  maxTurnP95Ms?: number;
24
28
  providers?: VoiceProofTrendProviderSummary[];
29
+ reconnect?: VoiceProofTrendReconnectSummary;
25
30
  runtimeChannel?: VoiceProofTrendRuntimeChannelSummary;
26
31
  sessionCount?: number;
27
32
  status?: string;
@@ -34,6 +39,7 @@ export type VoiceProofTrendProfileDefinition = {
34
39
  liveOffsetMs?: number;
35
40
  maxLiveP95Ms?: number;
36
41
  maxProviderP95Ms?: number;
42
+ maxReconnectP95Ms?: number;
37
43
  maxRuntimeFirstAudioLatencyMs?: number;
38
44
  maxRuntimeInterruptionP95Ms?: number;
39
45
  maxRuntimeJitterMs?: number;
@@ -62,6 +68,17 @@ export type VoiceProofTrendRuntimeChannelSummary = {
62
68
  samples?: number;
63
69
  status?: string;
64
70
  };
71
+ export type VoiceProofTrendReconnectSummary = {
72
+ attempts?: number;
73
+ exhausted?: boolean;
74
+ maxAttempts?: number;
75
+ resumeLatencyP95Ms?: number;
76
+ reconnected?: boolean;
77
+ resumed?: boolean;
78
+ samples?: number;
79
+ snapshotCount?: number;
80
+ status?: string;
81
+ };
65
82
  export type VoiceProofTrendCycle = {
66
83
  at?: string;
67
84
  cycle?: number;
@@ -83,6 +100,7 @@ export type VoiceProofTrendCycle = {
83
100
  status?: string;
84
101
  };
85
102
  providers?: VoiceProofTrendProviderSummary[];
103
+ reconnect?: VoiceProofTrendReconnectSummary;
86
104
  runtimeChannel?: VoiceProofTrendRuntimeChannelSummary;
87
105
  turnLatency?: {
88
106
  p95Ms?: number;
@@ -120,6 +138,7 @@ export type VoiceProofTrendReport = {
120
138
  export type VoiceProofTrendProfileSummaryOptions = {
121
139
  maxLiveP95Ms?: number;
122
140
  maxProviderP95Ms?: number;
141
+ maxReconnectP95Ms?: number;
123
142
  maxRuntimeFirstAudioLatencyMs?: number;
124
143
  maxRuntimeInterruptionP95Ms?: number;
125
144
  maxRuntimeJitterMs?: number;
@@ -137,11 +156,48 @@ export type VoiceProofTrendRealCallProfileEvidence = {
137
156
  profileLabel?: string;
138
157
  providerP95Ms?: number;
139
158
  providers?: VoiceProofTrendProviderSummary[];
159
+ reconnect?: VoiceProofTrendReconnectSummary;
140
160
  runtimeChannel?: VoiceProofTrendRuntimeChannelSummary;
141
161
  sessionId: string;
142
162
  surfaces?: string[];
143
163
  turnP95Ms?: number;
144
164
  };
165
+ export type VoiceRealCallProfileEvidenceRecord = VoiceProofTrendRealCallProfileEvidence & {
166
+ createdAt: string;
167
+ id: string;
168
+ };
169
+ export type VoiceRealCallProfileEvidenceCreateInput = VoiceProofTrendRealCallProfileEvidence & {
170
+ createdAt?: string;
171
+ id?: string;
172
+ };
173
+ export type VoiceRealCallProfileEvidenceListOptions = {
174
+ limit?: number;
175
+ profileId?: string;
176
+ sessionId?: string;
177
+ since?: Date | number | string;
178
+ until?: Date | number | string;
179
+ };
180
+ export type VoiceRealCallProfileEvidenceStore = {
181
+ append(input: VoiceRealCallProfileEvidenceCreateInput): Promise<VoiceRealCallProfileEvidenceRecord> | VoiceRealCallProfileEvidenceRecord;
182
+ get(id: string): Promise<VoiceRealCallProfileEvidenceRecord | undefined> | VoiceRealCallProfileEvidenceRecord | undefined;
183
+ list(options?: VoiceRealCallProfileEvidenceListOptions): Promise<VoiceRealCallProfileEvidenceRecord[]> | VoiceRealCallProfileEvidenceRecord[];
184
+ remove(id: string): Promise<void> | void;
185
+ };
186
+ export type VoiceSQLiteRealCallProfileEvidenceStoreOptions = {
187
+ database?: Database;
188
+ idPrefix?: string;
189
+ now?: () => Date;
190
+ path?: string;
191
+ tableName?: string;
192
+ };
193
+ export type VoiceReconnectRealCallProfileEvidenceOptions = {
194
+ operationsRecordHref?: string | ((report: VoiceReconnectProofReport | VoiceReconnectContractReport, index: number) => string | undefined);
195
+ profileDescription?: string;
196
+ profileId?: string;
197
+ profileLabel?: string;
198
+ sessionId?: string | ((report: VoiceReconnectProofReport | VoiceReconnectContractReport, index: number) => string);
199
+ surfaces?: readonly string[];
200
+ };
145
201
  export type VoiceRealCallProfileTraceEvidenceOptions = {
146
202
  defaultProfileId?: string;
147
203
  defaultProfileLabel?: string;
@@ -577,7 +633,11 @@ export declare const readVoiceProofTrendReportFile: (path: string, options?: {
577
633
  maxAgeMs?: number;
578
634
  }) => Promise<VoiceProofTrendReport>;
579
635
  export declare const buildVoiceRealCallProfileEvidenceFromTraceEvents: (events: readonly StoredVoiceTraceEvent[], options?: VoiceRealCallProfileTraceEvidenceOptions) => VoiceProofTrendRealCallProfileEvidence[];
636
+ export declare const buildVoiceRealCallProfileEvidenceFromReconnectProofReports: (input: VoiceReconnectProofReport | VoiceReconnectContractReport | readonly (VoiceReconnectProofReport | VoiceReconnectContractReport)[], options?: VoiceReconnectRealCallProfileEvidenceOptions) => VoiceProofTrendRealCallProfileEvidence[];
580
637
  export declare const loadVoiceRealCallProfileEvidenceFromTraceStore: (options: VoiceRealCallProfileTraceStoreEvidenceOptions) => Promise<VoiceProofTrendRealCallProfileEvidence[]>;
638
+ export declare const loadVoiceRealCallProfileEvidenceFromStore: (options: VoiceRealCallProfileEvidenceListOptions & {
639
+ store: VoiceRealCallProfileEvidenceStore;
640
+ }) => Promise<VoiceRealCallProfileEvidenceRecord[]>;
581
641
  export declare const createVoiceRealCallProfileTraceCollector: <TEvent extends StoredVoiceTraceEvent = StoredVoiceTraceEvent>(options: VoiceRealCallProfileTraceCollectorOptions<TEvent>) => VoiceRealCallProfileTraceCollector<TEvent>;
582
642
  export declare const buildVoiceProofTrendProfileSummaries: (input: VoiceProofTrendReport | readonly VoiceProofTrendReport[], options?: VoiceProofTrendProfileSummaryOptions) => VoiceProofTrendProfileSummary[];
583
643
  export declare const buildVoiceProofTrendReportFromRealCallProfiles: (options: VoiceProofTrendRealCallProfileReportOptions) => VoiceProofTrendReport;
@@ -589,11 +649,15 @@ export declare const createVoiceInMemoryRealCallProfileRecoveryJobStore: (option
589
649
  idPrefix?: string;
590
650
  now?: () => Date;
591
651
  }) => VoiceRealCallProfileRecoveryJobStore;
652
+ export declare const createVoiceSQLiteRealCallProfileEvidenceStore: (options?: VoiceSQLiteRealCallProfileEvidenceStoreOptions) => VoiceRealCallProfileEvidenceStore;
592
653
  export declare const createVoiceSQLiteRealCallProfileRecoveryJobStore: (options?: VoiceSQLiteRealCallProfileRecoveryJobStoreOptions) => VoiceRealCallProfileRecoveryJobStore;
593
654
  export declare const buildVoiceRealCallProfileReadinessCheck: (report: VoiceRealCallProfileHistoryReport, options?: VoiceRealCallProfileReadinessCheckOptions) => VoiceProductionReadinessCheck;
594
655
  export declare const buildVoiceRealCallProfileRecoveryJobHistoryCheck: (store: Pick<VoiceRealCallProfileRecoveryJobStore, "list"> | undefined, options?: VoiceRealCallProfileRecoveryJobHistoryCheckOptions) => Promise<VoiceProductionReadinessCheck>;
595
656
  export declare const resolveVoiceRealCallProfileProviderRoute: <TProvider extends string = string>(options: VoiceRealCallProfileProviderRouteOptions<TProvider>) => TProvider | undefined;
596
657
  export declare const buildVoiceRealCallProfileHistoryReport: (options?: VoiceRealCallProfileHistoryOptions) => VoiceRealCallProfileHistoryReport;
658
+ export declare const buildVoiceRealCallProfileHistoryReportFromStore: (options: Omit<VoiceRealCallProfileHistoryOptions, "evidence"> & VoiceRealCallProfileEvidenceListOptions & {
659
+ store: VoiceRealCallProfileEvidenceStore;
660
+ }) => Promise<VoiceRealCallProfileHistoryReport>;
597
661
  export declare const evaluateVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
598
662
  export declare const assertVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
599
663
  export declare const buildVoiceProofTrendRecommendationReport: (report: VoiceProofTrendReport, options?: VoiceProofTrendRecommendationOptions) => VoiceProofTrendRecommendationReport;