@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/client/index.js +167 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +172 -4
- package/dist/proofTrends.d.ts +64 -0
- package/dist/react/index.js +167 -4
- package/dist/vue/index.js +167 -4
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -3430,6 +3430,7 @@ var readString = (value) => typeof value === "string" && value.trim() ? value :
|
|
|
3430
3430
|
var readNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
3431
3431
|
var readProofTrendMaxLiveP95 = (report) => report.summary.maxLiveP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.liveLatency?.p95Ms));
|
|
3432
3432
|
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)));
|
|
3433
|
+
var readProofTrendMaxReconnectP95 = (report) => report.summary.maxReconnectP95Ms ?? report.summary.reconnect?.resumeLatencyP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.reconnect?.resumeLatencyP95Ms));
|
|
3433
3434
|
var readProofTrendMaxTurnP95 = (report) => report.summary.maxTurnP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.turnLatency?.p95Ms));
|
|
3434
3435
|
var readRuntimeChannelMetric = (report, key) => {
|
|
3435
3436
|
const summaryValue = report.summary.runtimeChannel?.[key];
|
|
@@ -3491,6 +3492,42 @@ var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
|
3491
3492
|
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
3492
3493
|
};
|
|
3493
3494
|
};
|
|
3495
|
+
var aggregateProofTrendReconnect = (reconnects) => {
|
|
3496
|
+
if (reconnects.length === 0) {
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
const hasFailure = reconnects.some((reconnect) => reconnect.status === "fail" || reconnect.exhausted === true || reconnect.reconnected === false || reconnect.resumed === false);
|
|
3500
|
+
return {
|
|
3501
|
+
attempts: maxNumber(reconnects.map((reconnect) => reconnect.attempts)),
|
|
3502
|
+
exhausted: reconnects.some((reconnect) => reconnect.exhausted === true),
|
|
3503
|
+
maxAttempts: maxNumber(reconnects.map((reconnect) => reconnect.maxAttempts)),
|
|
3504
|
+
resumeLatencyP95Ms: maxNumber(reconnects.map((reconnect) => reconnect.resumeLatencyP95Ms)),
|
|
3505
|
+
reconnected: reconnects.some((reconnect) => reconnect.reconnected === true),
|
|
3506
|
+
resumed: reconnects.some((reconnect) => reconnect.resumed === true),
|
|
3507
|
+
samples: reconnects.reduce((total, reconnect) => total + (reconnect.samples ?? 0), 0),
|
|
3508
|
+
snapshotCount: reconnects.reduce((total, reconnect) => total + (reconnect.snapshotCount ?? 0), 0),
|
|
3509
|
+
status: hasFailure ? "fail" : reconnects.some((reconnect) => reconnect.status === "warn") ? "warn" : "pass"
|
|
3510
|
+
};
|
|
3511
|
+
};
|
|
3512
|
+
var summarizeReconnectTraceEvidence = (events) => {
|
|
3513
|
+
const reconnectEvents = events.filter((event) => event.type === "client.reconnect");
|
|
3514
|
+
if (reconnectEvents.length === 0) {
|
|
3515
|
+
return;
|
|
3516
|
+
}
|
|
3517
|
+
const statuses = reconnectEvents.map((event) => readString(readTraceRecord(event).status)).filter((status) => status !== undefined);
|
|
3518
|
+
const reconnectPayloads = reconnectEvents.map((event) => readTraceRecord(event));
|
|
3519
|
+
return {
|
|
3520
|
+
attempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.attempts))),
|
|
3521
|
+
exhausted: statuses.includes("exhausted"),
|
|
3522
|
+
maxAttempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.maxAttempts))),
|
|
3523
|
+
resumeLatencyP95Ms: percentile(reconnectPayloads.map((payload) => readNumber2(payload.resumeLatencyP95Ms) ?? readNumber2(payload.resumeLatencyMs)).filter((value) => value !== undefined), 95),
|
|
3524
|
+
reconnected: statuses.includes("reconnecting"),
|
|
3525
|
+
resumed: statuses.includes("resumed") || statuses.includes("pass"),
|
|
3526
|
+
samples: reconnectEvents.length,
|
|
3527
|
+
snapshotCount: reconnectEvents.length,
|
|
3528
|
+
status: reconnectEvents.some((event) => isFailingTraceStatus(readTraceStatus(readTraceRecord(event)))) ? "fail" : "pass"
|
|
3529
|
+
};
|
|
3530
|
+
};
|
|
3494
3531
|
var readTraceRecord = (event) => event.payload;
|
|
3495
3532
|
var readTraceProfileId = (events, options) => {
|
|
3496
3533
|
for (const event of events) {
|
|
@@ -3638,6 +3675,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3638
3675
|
}).filter((value) => value !== undefined);
|
|
3639
3676
|
const turnP95Ms = summarizeTurnTraceP95(sessionEvents);
|
|
3640
3677
|
const providerP95Ms = maxNumber(providers.map((provider) => provider.p95Ms));
|
|
3678
|
+
const reconnect = summarizeReconnectTraceEvidence(sessionEvents);
|
|
3641
3679
|
const runtimeChannel = summarizeRuntimeChannelTraceEvidence(sessionEvents);
|
|
3642
3680
|
const surfaces = readRealCallProfileTraceSurfaces(sessionEvents);
|
|
3643
3681
|
if (providers.length === 0 && runtimeChannel === undefined && liveLatencies.length === 0 && surfaces.length === 0) {
|
|
@@ -3653,6 +3691,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3653
3691
|
profileLabel: options.profileLabels?.[profileId] ?? (profileId === options.defaultProfileId ? options.defaultProfileLabel : undefined),
|
|
3654
3692
|
providerP95Ms,
|
|
3655
3693
|
providers,
|
|
3694
|
+
reconnect,
|
|
3656
3695
|
runtimeChannel,
|
|
3657
3696
|
sessionId,
|
|
3658
3697
|
surfaces: surfaces.length > 0 ? surfaces : undefined,
|
|
@@ -3660,11 +3699,46 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3660
3699
|
};
|
|
3661
3700
|
}).filter((evidence) => evidence !== undefined);
|
|
3662
3701
|
};
|
|
3702
|
+
var normalizeReconnectReport = (report) => ("contract" in report) ? report.contract : report;
|
|
3703
|
+
var buildVoiceRealCallProfileEvidenceFromReconnectProofReports = (input, options = {}) => {
|
|
3704
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
3705
|
+
const profileId = options.profileId ?? "reconnect-resume";
|
|
3706
|
+
return reports.map((report, index) => {
|
|
3707
|
+
const contract = normalizeReconnectReport(report);
|
|
3708
|
+
const generatedAt = "generatedAt" in report ? report.generatedAt : new Date(contract.checkedAt).toISOString();
|
|
3709
|
+
const ok = "ok" in report ? report.ok : contract.pass;
|
|
3710
|
+
const operationsRecordHref = typeof options.operationsRecordHref === "function" ? options.operationsRecordHref(report, index) : options.operationsRecordHref;
|
|
3711
|
+
const sessionId = typeof options.sessionId === "function" ? options.sessionId(report, index) : options.sessionId ?? `reconnect-proof-${String(index + 1)}-${String(contract.checkedAt)}`;
|
|
3712
|
+
return {
|
|
3713
|
+
generatedAt,
|
|
3714
|
+
ok,
|
|
3715
|
+
operationsRecordHref,
|
|
3716
|
+
profileDescription: options.profileDescription,
|
|
3717
|
+
profileId,
|
|
3718
|
+
profileLabel: options.profileLabel,
|
|
3719
|
+
reconnect: {
|
|
3720
|
+
attempts: contract.summary.attempts,
|
|
3721
|
+
exhausted: contract.summary.exhausted,
|
|
3722
|
+
maxAttempts: contract.summary.maxAttempts,
|
|
3723
|
+
resumeLatencyP95Ms: contract.resumeLatencyP95Ms,
|
|
3724
|
+
reconnected: contract.summary.reconnected,
|
|
3725
|
+
resumed: contract.summary.resumed,
|
|
3726
|
+
samples: 1,
|
|
3727
|
+
snapshotCount: contract.snapshotCount,
|
|
3728
|
+
status: ok ? "pass" : "fail"
|
|
3729
|
+
},
|
|
3730
|
+
sessionId,
|
|
3731
|
+
surfaces: [...new Set(["reconnect", ...options.surfaces ?? []])].sort()
|
|
3732
|
+
};
|
|
3733
|
+
});
|
|
3734
|
+
};
|
|
3663
3735
|
var loadVoiceRealCallProfileEvidenceFromTraceStore = async (options) => buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.store.list({ limit: options.limit ?? 5000 }), options);
|
|
3736
|
+
var loadVoiceRealCallProfileEvidenceFromStore = async (options) => options.store.list(options);
|
|
3664
3737
|
var realCallProfileTraceSignalTypes = new Set([
|
|
3665
3738
|
"client.barge_in",
|
|
3666
3739
|
"client.browser_media",
|
|
3667
3740
|
"client.live_latency",
|
|
3741
|
+
"client.reconnect",
|
|
3668
3742
|
"client.telephony_media",
|
|
3669
3743
|
"provider.decision",
|
|
3670
3744
|
"session.error",
|
|
@@ -3727,15 +3801,16 @@ var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.
|
|
|
3727
3801
|
var exceedsProofTrendBudget = (value, budget) => value !== undefined && (!Number.isFinite(value) || value > budget);
|
|
3728
3802
|
var readProofTrendProfileStatus = (profile, budgets) => {
|
|
3729
3803
|
const runtimeChannel = profile.runtimeChannel;
|
|
3730
|
-
const
|
|
3731
|
-
const
|
|
3804
|
+
const reconnect = profile.reconnect;
|
|
3805
|
+
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;
|
|
3806
|
+
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";
|
|
3732
3807
|
if (budgetFailed || !hasBudgetEvidence && profile.status === "fail") {
|
|
3733
3808
|
return "fail";
|
|
3734
3809
|
}
|
|
3735
|
-
if (profile.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
|
|
3810
|
+
if (profile.status === "warn" || reconnect?.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
|
|
3736
3811
|
return "warn";
|
|
3737
3812
|
}
|
|
3738
|
-
if (hasBudgetEvidence || profile.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
|
|
3813
|
+
if (hasBudgetEvidence || profile.status === "pass" || reconnect?.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
|
|
3739
3814
|
return "pass";
|
|
3740
3815
|
}
|
|
3741
3816
|
return;
|
|
@@ -3745,6 +3820,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3745
3820
|
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
3746
3821
|
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
3747
3822
|
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
3823
|
+
const reconnectCap = options.maxReconnectP95Ms ?? 1500;
|
|
3748
3824
|
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
3749
3825
|
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
3750
3826
|
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
@@ -3753,6 +3829,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3753
3829
|
const budgets = {
|
|
3754
3830
|
maxLiveP95Ms: liveCap,
|
|
3755
3831
|
maxProviderP95Ms: providerCap,
|
|
3832
|
+
maxReconnectP95Ms: reconnectCap,
|
|
3756
3833
|
maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
|
|
3757
3834
|
maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
|
|
3758
3835
|
maxRuntimeJitterMs: runtimeJitterCap,
|
|
@@ -3775,8 +3852,10 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3775
3852
|
label: definition.label ?? profiles.find(Boolean)?.label,
|
|
3776
3853
|
maxLiveP95Ms: maxNumber(profiles.map((profile) => profile.maxLiveP95Ms)),
|
|
3777
3854
|
maxProviderP95Ms: maxNumber(profiles.map((profile) => profile.maxProviderP95Ms)),
|
|
3855
|
+
maxReconnectP95Ms: maxNumber(profiles.map((profile) => profile.maxReconnectP95Ms)),
|
|
3778
3856
|
maxTurnP95Ms: maxNumber(profiles.map((profile) => profile.maxTurnP95Ms)),
|
|
3779
3857
|
providers: aggregateProofTrendProviders(profiles.flatMap((profile) => profile.providers ?? [])),
|
|
3858
|
+
reconnect: aggregateProofTrendReconnect(profiles.map((profile) => profile.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3780
3859
|
runtimeChannel: aggregateProofTrendRuntimeChannel(profiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
3781
3860
|
sessionCount: profiles.reduce((total, profile) => total + (profile.sessionCount ?? 0), 0),
|
|
3782
3861
|
surfaces: [
|
|
@@ -3816,6 +3895,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3816
3895
|
var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
3817
3896
|
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
3818
3897
|
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
3898
|
+
const reconnectCap = options.maxReconnectP95Ms ?? 1500;
|
|
3819
3899
|
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
3820
3900
|
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
3821
3901
|
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
@@ -3824,6 +3904,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3824
3904
|
const budgets = {
|
|
3825
3905
|
maxLiveP95Ms: liveCap,
|
|
3826
3906
|
maxProviderP95Ms: providerCap,
|
|
3907
|
+
maxReconnectP95Ms: reconnectCap,
|
|
3827
3908
|
maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
|
|
3828
3909
|
maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
|
|
3829
3910
|
maxRuntimeJitterMs: runtimeJitterCap,
|
|
@@ -3853,8 +3934,10 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3853
3934
|
label: definition.label ?? matchingEvidence.find((evidence) => evidence.profileLabel)?.profileLabel,
|
|
3854
3935
|
maxLiveP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.liveP95Ms)),
|
|
3855
3936
|
maxProviderP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.providerP95Ms)),
|
|
3937
|
+
maxReconnectP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
|
|
3856
3938
|
maxTurnP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.turnP95Ms)),
|
|
3857
3939
|
providers: aggregateProofTrendProviders(matchingEvidence.flatMap((evidence) => evidence.providers ?? [])),
|
|
3940
|
+
reconnect: aggregateProofTrendReconnect(matchingEvidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3858
3941
|
runtimeChannel: aggregateProofTrendRuntimeChannel(matchingEvidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
3859
3942
|
sessionCount: new Set(matchingEvidence.map((evidence) => evidence.sessionId)).size,
|
|
3860
3943
|
surfaces: [
|
|
@@ -3873,6 +3956,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3873
3956
|
ok: evidence.ok !== false,
|
|
3874
3957
|
providers: evidence.providers,
|
|
3875
3958
|
runtimeChannel: evidence.runtimeChannel,
|
|
3959
|
+
reconnect: evidence.reconnect,
|
|
3876
3960
|
turnLatency: evidence.turnP95Ms === undefined ? undefined : {
|
|
3877
3961
|
p95Ms: evidence.turnP95Ms,
|
|
3878
3962
|
samples: 1,
|
|
@@ -3883,9 +3967,11 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3883
3967
|
cycles: options.evidence.length,
|
|
3884
3968
|
maxLiveP95Ms: maxNumber(options.evidence.map((evidence) => evidence.liveP95Ms)),
|
|
3885
3969
|
maxProviderP95Ms: maxNumber(options.evidence.map((evidence) => evidence.providerP95Ms)),
|
|
3970
|
+
maxReconnectP95Ms: maxNumber(options.evidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
|
|
3886
3971
|
maxTurnP95Ms: maxNumber(options.evidence.map((evidence) => evidence.turnP95Ms)),
|
|
3887
3972
|
profiles,
|
|
3888
3973
|
providers: aggregateProofTrendProviders(options.evidence.flatMap((evidence) => evidence.providers ?? [])),
|
|
3974
|
+
reconnect: aggregateProofTrendReconnect(options.evidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3889
3975
|
runtimeChannel: aggregateProofTrendRuntimeChannel(options.evidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined))
|
|
3890
3976
|
};
|
|
3891
3977
|
return buildVoiceProofTrendReport({
|
|
@@ -4490,6 +4576,74 @@ var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
|
4490
4576
|
}
|
|
4491
4577
|
};
|
|
4492
4578
|
};
|
|
4579
|
+
var normalizeRealCallProfileEvidenceTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_evidence";
|
|
4580
|
+
var parseRealCallProfileEvidenceBoundary = (value) => value === undefined ? undefined : value instanceof Date ? value.getTime() : typeof value === "number" ? value : Date.parse(value);
|
|
4581
|
+
var readRealCallProfileEvidenceSortTime = (evidence, fallback) => Date.parse(evidence.generatedAt ?? fallback) || Date.parse(fallback);
|
|
4582
|
+
var createVoiceSQLiteRealCallProfileEvidenceStore = (options = {}) => {
|
|
4583
|
+
const { Database: SQLiteDatabase } = __require("bun:sqlite");
|
|
4584
|
+
const database = options.database ?? new SQLiteDatabase(options.path ?? ":memory:", {
|
|
4585
|
+
create: true
|
|
4586
|
+
});
|
|
4587
|
+
const tableName = normalizeRealCallProfileEvidenceTableName(options.tableName ?? "voice_real_call_profile_evidence");
|
|
4588
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
4589
|
+
const createId = () => `${options.idPrefix ?? "voice-profile-evidence"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
4590
|
+
database.exec("PRAGMA journal_mode = WAL;");
|
|
4591
|
+
database.exec("PRAGMA synchronous = NORMAL;");
|
|
4592
|
+
database.exec("PRAGMA busy_timeout = 5000;");
|
|
4593
|
+
database.exec(`CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
4594
|
+
id TEXT PRIMARY KEY,
|
|
4595
|
+
sort_at INTEGER NOT NULL,
|
|
4596
|
+
profile_id TEXT NOT NULL,
|
|
4597
|
+
session_id TEXT NOT NULL,
|
|
4598
|
+
created_at TEXT NOT NULL,
|
|
4599
|
+
payload TEXT NOT NULL
|
|
4600
|
+
)`);
|
|
4601
|
+
const selectStatement = database.query(`SELECT payload FROM "${tableName}" WHERE id = ?1 LIMIT 1`);
|
|
4602
|
+
const listStatement = database.query(`SELECT payload FROM "${tableName}" ORDER BY sort_at DESC, id DESC`);
|
|
4603
|
+
const upsertStatement = database.query(`INSERT INTO "${tableName}" (id, sort_at, profile_id, session_id, created_at, payload)
|
|
4604
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
|
|
4605
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
4606
|
+
sort_at = excluded.sort_at,
|
|
4607
|
+
profile_id = excluded.profile_id,
|
|
4608
|
+
session_id = excluded.session_id,
|
|
4609
|
+
created_at = excluded.created_at,
|
|
4610
|
+
payload = excluded.payload`);
|
|
4611
|
+
const deleteStatement = database.query(`DELETE FROM "${tableName}" WHERE id = ?1`);
|
|
4612
|
+
const writeEvidence = (record) => {
|
|
4613
|
+
upsertStatement.run(record.id, readRealCallProfileEvidenceSortTime(record, record.createdAt), record.profileId, record.sessionId, record.createdAt, JSON.stringify(record));
|
|
4614
|
+
return record;
|
|
4615
|
+
};
|
|
4616
|
+
const readEvidence = (id) => {
|
|
4617
|
+
const row = selectStatement.get(id);
|
|
4618
|
+
return row ? JSON.parse(row.payload) : undefined;
|
|
4619
|
+
};
|
|
4620
|
+
const matchesListOptions = (record, input) => {
|
|
4621
|
+
const evidenceTime = readRealCallProfileEvidenceSortTime(record, record.createdAt);
|
|
4622
|
+
const since = parseRealCallProfileEvidenceBoundary(input.since);
|
|
4623
|
+
const until = parseRealCallProfileEvidenceBoundary(input.until);
|
|
4624
|
+
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);
|
|
4625
|
+
};
|
|
4626
|
+
return {
|
|
4627
|
+
append(input) {
|
|
4628
|
+
const createdAt = input.createdAt ?? now();
|
|
4629
|
+
return writeEvidence({
|
|
4630
|
+
...input,
|
|
4631
|
+
createdAt,
|
|
4632
|
+
id: input.id ?? createId()
|
|
4633
|
+
});
|
|
4634
|
+
},
|
|
4635
|
+
get(id) {
|
|
4636
|
+
return readEvidence(id);
|
|
4637
|
+
},
|
|
4638
|
+
list(input = {}) {
|
|
4639
|
+
const limit = Number.isFinite(input.limit) && input.limit !== undefined && input.limit > 0 ? Math.floor(input.limit) : 500;
|
|
4640
|
+
return listStatement.all().map((row) => JSON.parse(row.payload)).filter((record) => matchesListOptions(record, input)).slice(0, limit);
|
|
4641
|
+
},
|
|
4642
|
+
remove(id) {
|
|
4643
|
+
deleteStatement.run(id);
|
|
4644
|
+
}
|
|
4645
|
+
};
|
|
4646
|
+
};
|
|
4493
4647
|
var normalizeRealCallRecoveryJobTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_recovery_jobs";
|
|
4494
4648
|
var createVoiceSQLiteRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
4495
4649
|
const { Database: SQLiteDatabase } = __require("bun:sqlite");
|
|
@@ -4704,10 +4858,12 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
|
|
|
4704
4858
|
failedReports: history.filter((report) => report.ok !== true).length,
|
|
4705
4859
|
maxLiveP95Ms: maxNumber(profileHistory.map(readProofTrendMaxLiveP95)),
|
|
4706
4860
|
maxProviderP95Ms: maxNumber(profileHistory.map(readProofTrendMaxProviderP95)),
|
|
4861
|
+
maxReconnectP95Ms: maxNumber(profileHistory.map(readProofTrendMaxReconnectP95)),
|
|
4707
4862
|
maxTurnP95Ms: maxNumber(profileHistory.map(readProofTrendMaxTurnP95)),
|
|
4708
4863
|
profileCount: profiles.length,
|
|
4709
4864
|
profiles,
|
|
4710
4865
|
providers: readProofTrendProviders(profileHistory),
|
|
4866
|
+
reconnect: aggregateProofTrendReconnect(profileHistory.map((report) => report.summary.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
4711
4867
|
runtimeChannel: aggregateProofTrendRuntimeChannel(profileHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
|
|
4712
4868
|
};
|
|
4713
4869
|
const trend = buildVoiceProofTrendReport({
|
|
@@ -4741,6 +4897,13 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
|
|
|
4741
4897
|
trend
|
|
4742
4898
|
};
|
|
4743
4899
|
};
|
|
4900
|
+
var buildVoiceRealCallProfileHistoryReportFromStore = async (options) => {
|
|
4901
|
+
const evidence = await options.store.list(options);
|
|
4902
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
4903
|
+
...options,
|
|
4904
|
+
evidence
|
|
4905
|
+
});
|
|
4906
|
+
};
|
|
4744
4907
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
4745
4908
|
var providerSortScore = (provider) => [
|
|
4746
4909
|
recommendationStatusRank[provider.status],
|
package/dist/vue/index.js
CHANGED
|
@@ -3351,6 +3351,7 @@ var readString = (value) => typeof value === "string" && value.trim() ? value :
|
|
|
3351
3351
|
var readNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
3352
3352
|
var readProofTrendMaxLiveP95 = (report) => report.summary.maxLiveP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.liveLatency?.p95Ms));
|
|
3353
3353
|
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)));
|
|
3354
|
+
var readProofTrendMaxReconnectP95 = (report) => report.summary.maxReconnectP95Ms ?? report.summary.reconnect?.resumeLatencyP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.reconnect?.resumeLatencyP95Ms));
|
|
3354
3355
|
var readProofTrendMaxTurnP95 = (report) => report.summary.maxTurnP95Ms ?? maxNumber(report.cycles.map((cycle) => cycle.turnLatency?.p95Ms));
|
|
3355
3356
|
var readRuntimeChannelMetric = (report, key) => {
|
|
3356
3357
|
const summaryValue = report.summary.runtimeChannel?.[key];
|
|
@@ -3412,6 +3413,42 @@ var aggregateProofTrendRuntimeChannel = (channels) => {
|
|
|
3412
3413
|
status: channels.some((channel) => channel.status === "fail") ? "fail" : channels.some((channel) => channel.status === "warn") ? "warn" : channels.every((channel) => channel.status === "pass") ? "pass" : undefined
|
|
3413
3414
|
};
|
|
3414
3415
|
};
|
|
3416
|
+
var aggregateProofTrendReconnect = (reconnects) => {
|
|
3417
|
+
if (reconnects.length === 0) {
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
const hasFailure = reconnects.some((reconnect) => reconnect.status === "fail" || reconnect.exhausted === true || reconnect.reconnected === false || reconnect.resumed === false);
|
|
3421
|
+
return {
|
|
3422
|
+
attempts: maxNumber(reconnects.map((reconnect) => reconnect.attempts)),
|
|
3423
|
+
exhausted: reconnects.some((reconnect) => reconnect.exhausted === true),
|
|
3424
|
+
maxAttempts: maxNumber(reconnects.map((reconnect) => reconnect.maxAttempts)),
|
|
3425
|
+
resumeLatencyP95Ms: maxNumber(reconnects.map((reconnect) => reconnect.resumeLatencyP95Ms)),
|
|
3426
|
+
reconnected: reconnects.some((reconnect) => reconnect.reconnected === true),
|
|
3427
|
+
resumed: reconnects.some((reconnect) => reconnect.resumed === true),
|
|
3428
|
+
samples: reconnects.reduce((total, reconnect) => total + (reconnect.samples ?? 0), 0),
|
|
3429
|
+
snapshotCount: reconnects.reduce((total, reconnect) => total + (reconnect.snapshotCount ?? 0), 0),
|
|
3430
|
+
status: hasFailure ? "fail" : reconnects.some((reconnect) => reconnect.status === "warn") ? "warn" : "pass"
|
|
3431
|
+
};
|
|
3432
|
+
};
|
|
3433
|
+
var summarizeReconnectTraceEvidence = (events) => {
|
|
3434
|
+
const reconnectEvents = events.filter((event) => event.type === "client.reconnect");
|
|
3435
|
+
if (reconnectEvents.length === 0) {
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3438
|
+
const statuses = reconnectEvents.map((event) => readString(readTraceRecord(event).status)).filter((status) => status !== undefined);
|
|
3439
|
+
const reconnectPayloads = reconnectEvents.map((event) => readTraceRecord(event));
|
|
3440
|
+
return {
|
|
3441
|
+
attempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.attempts))),
|
|
3442
|
+
exhausted: statuses.includes("exhausted"),
|
|
3443
|
+
maxAttempts: maxNumber(reconnectPayloads.map((payload) => readNumber2(payload.maxAttempts))),
|
|
3444
|
+
resumeLatencyP95Ms: percentile(reconnectPayloads.map((payload) => readNumber2(payload.resumeLatencyP95Ms) ?? readNumber2(payload.resumeLatencyMs)).filter((value) => value !== undefined), 95),
|
|
3445
|
+
reconnected: statuses.includes("reconnecting"),
|
|
3446
|
+
resumed: statuses.includes("resumed") || statuses.includes("pass"),
|
|
3447
|
+
samples: reconnectEvents.length,
|
|
3448
|
+
snapshotCount: reconnectEvents.length,
|
|
3449
|
+
status: reconnectEvents.some((event) => isFailingTraceStatus(readTraceStatus(readTraceRecord(event)))) ? "fail" : "pass"
|
|
3450
|
+
};
|
|
3451
|
+
};
|
|
3415
3452
|
var readTraceRecord = (event) => event.payload;
|
|
3416
3453
|
var readTraceProfileId = (events, options) => {
|
|
3417
3454
|
for (const event of events) {
|
|
@@ -3559,6 +3596,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3559
3596
|
}).filter((value) => value !== undefined);
|
|
3560
3597
|
const turnP95Ms = summarizeTurnTraceP95(sessionEvents);
|
|
3561
3598
|
const providerP95Ms = maxNumber(providers.map((provider) => provider.p95Ms));
|
|
3599
|
+
const reconnect = summarizeReconnectTraceEvidence(sessionEvents);
|
|
3562
3600
|
const runtimeChannel = summarizeRuntimeChannelTraceEvidence(sessionEvents);
|
|
3563
3601
|
const surfaces = readRealCallProfileTraceSurfaces(sessionEvents);
|
|
3564
3602
|
if (providers.length === 0 && runtimeChannel === undefined && liveLatencies.length === 0 && surfaces.length === 0) {
|
|
@@ -3574,6 +3612,7 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3574
3612
|
profileLabel: options.profileLabels?.[profileId] ?? (profileId === options.defaultProfileId ? options.defaultProfileLabel : undefined),
|
|
3575
3613
|
providerP95Ms,
|
|
3576
3614
|
providers,
|
|
3615
|
+
reconnect,
|
|
3577
3616
|
runtimeChannel,
|
|
3578
3617
|
sessionId,
|
|
3579
3618
|
surfaces: surfaces.length > 0 ? surfaces : undefined,
|
|
@@ -3581,11 +3620,46 @@ var buildVoiceRealCallProfileEvidenceFromTraceEvents = (events, options = {}) =>
|
|
|
3581
3620
|
};
|
|
3582
3621
|
}).filter((evidence) => evidence !== undefined);
|
|
3583
3622
|
};
|
|
3623
|
+
var normalizeReconnectReport = (report) => ("contract" in report) ? report.contract : report;
|
|
3624
|
+
var buildVoiceRealCallProfileEvidenceFromReconnectProofReports = (input, options = {}) => {
|
|
3625
|
+
const reports = Array.isArray(input) ? input : [input];
|
|
3626
|
+
const profileId = options.profileId ?? "reconnect-resume";
|
|
3627
|
+
return reports.map((report, index) => {
|
|
3628
|
+
const contract = normalizeReconnectReport(report);
|
|
3629
|
+
const generatedAt = "generatedAt" in report ? report.generatedAt : new Date(contract.checkedAt).toISOString();
|
|
3630
|
+
const ok = "ok" in report ? report.ok : contract.pass;
|
|
3631
|
+
const operationsRecordHref = typeof options.operationsRecordHref === "function" ? options.operationsRecordHref(report, index) : options.operationsRecordHref;
|
|
3632
|
+
const sessionId = typeof options.sessionId === "function" ? options.sessionId(report, index) : options.sessionId ?? `reconnect-proof-${String(index + 1)}-${String(contract.checkedAt)}`;
|
|
3633
|
+
return {
|
|
3634
|
+
generatedAt,
|
|
3635
|
+
ok,
|
|
3636
|
+
operationsRecordHref,
|
|
3637
|
+
profileDescription: options.profileDescription,
|
|
3638
|
+
profileId,
|
|
3639
|
+
profileLabel: options.profileLabel,
|
|
3640
|
+
reconnect: {
|
|
3641
|
+
attempts: contract.summary.attempts,
|
|
3642
|
+
exhausted: contract.summary.exhausted,
|
|
3643
|
+
maxAttempts: contract.summary.maxAttempts,
|
|
3644
|
+
resumeLatencyP95Ms: contract.resumeLatencyP95Ms,
|
|
3645
|
+
reconnected: contract.summary.reconnected,
|
|
3646
|
+
resumed: contract.summary.resumed,
|
|
3647
|
+
samples: 1,
|
|
3648
|
+
snapshotCount: contract.snapshotCount,
|
|
3649
|
+
status: ok ? "pass" : "fail"
|
|
3650
|
+
},
|
|
3651
|
+
sessionId,
|
|
3652
|
+
surfaces: [...new Set(["reconnect", ...options.surfaces ?? []])].sort()
|
|
3653
|
+
};
|
|
3654
|
+
});
|
|
3655
|
+
};
|
|
3584
3656
|
var loadVoiceRealCallProfileEvidenceFromTraceStore = async (options) => buildVoiceRealCallProfileEvidenceFromTraceEvents(await options.store.list({ limit: options.limit ?? 5000 }), options);
|
|
3657
|
+
var loadVoiceRealCallProfileEvidenceFromStore = async (options) => options.store.list(options);
|
|
3585
3658
|
var realCallProfileTraceSignalTypes = new Set([
|
|
3586
3659
|
"client.barge_in",
|
|
3587
3660
|
"client.browser_media",
|
|
3588
3661
|
"client.live_latency",
|
|
3662
|
+
"client.reconnect",
|
|
3589
3663
|
"client.telephony_media",
|
|
3590
3664
|
"provider.decision",
|
|
3591
3665
|
"session.error",
|
|
@@ -3648,15 +3722,16 @@ var readProofTrendProviders = (reports) => aggregateProofTrendProviders(reports.
|
|
|
3648
3722
|
var exceedsProofTrendBudget = (value, budget) => value !== undefined && (!Number.isFinite(value) || value > budget);
|
|
3649
3723
|
var readProofTrendProfileStatus = (profile, budgets) => {
|
|
3650
3724
|
const runtimeChannel = profile.runtimeChannel;
|
|
3651
|
-
const
|
|
3652
|
-
const
|
|
3725
|
+
const reconnect = profile.reconnect;
|
|
3726
|
+
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;
|
|
3727
|
+
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";
|
|
3653
3728
|
if (budgetFailed || !hasBudgetEvidence && profile.status === "fail") {
|
|
3654
3729
|
return "fail";
|
|
3655
3730
|
}
|
|
3656
|
-
if (profile.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
|
|
3731
|
+
if (profile.status === "warn" || reconnect?.status === "warn" || runtimeChannel?.status === "warn" || profile.providers?.some((provider) => provider.status === "warn") === true) {
|
|
3657
3732
|
return "warn";
|
|
3658
3733
|
}
|
|
3659
|
-
if (hasBudgetEvidence || profile.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
|
|
3734
|
+
if (hasBudgetEvidence || profile.status === "pass" || reconnect?.status === "pass" || runtimeChannel?.status === "pass" || profile.providers?.some((provider) => provider.status === "pass") === true) {
|
|
3660
3735
|
return "pass";
|
|
3661
3736
|
}
|
|
3662
3737
|
return;
|
|
@@ -3666,6 +3741,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3666
3741
|
const definitions = options.profiles ?? DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS;
|
|
3667
3742
|
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
3668
3743
|
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
3744
|
+
const reconnectCap = options.maxReconnectP95Ms ?? 1500;
|
|
3669
3745
|
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
3670
3746
|
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
3671
3747
|
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
@@ -3674,6 +3750,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3674
3750
|
const budgets = {
|
|
3675
3751
|
maxLiveP95Ms: liveCap,
|
|
3676
3752
|
maxProviderP95Ms: providerCap,
|
|
3753
|
+
maxReconnectP95Ms: reconnectCap,
|
|
3677
3754
|
maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
|
|
3678
3755
|
maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
|
|
3679
3756
|
maxRuntimeJitterMs: runtimeJitterCap,
|
|
@@ -3696,8 +3773,10 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3696
3773
|
label: definition.label ?? profiles.find(Boolean)?.label,
|
|
3697
3774
|
maxLiveP95Ms: maxNumber(profiles.map((profile) => profile.maxLiveP95Ms)),
|
|
3698
3775
|
maxProviderP95Ms: maxNumber(profiles.map((profile) => profile.maxProviderP95Ms)),
|
|
3776
|
+
maxReconnectP95Ms: maxNumber(profiles.map((profile) => profile.maxReconnectP95Ms)),
|
|
3699
3777
|
maxTurnP95Ms: maxNumber(profiles.map((profile) => profile.maxTurnP95Ms)),
|
|
3700
3778
|
providers: aggregateProofTrendProviders(profiles.flatMap((profile) => profile.providers ?? [])),
|
|
3779
|
+
reconnect: aggregateProofTrendReconnect(profiles.map((profile) => profile.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3701
3780
|
runtimeChannel: aggregateProofTrendRuntimeChannel(profiles.map((profile) => profile.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
3702
3781
|
sessionCount: profiles.reduce((total, profile) => total + (profile.sessionCount ?? 0), 0),
|
|
3703
3782
|
surfaces: [
|
|
@@ -3737,6 +3816,7 @@ var buildVoiceProofTrendProfileSummaries = (input, options = {}) => {
|
|
|
3737
3816
|
var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
3738
3817
|
const providerCap = options.maxProviderP95Ms ?? 1000;
|
|
3739
3818
|
const liveCap = options.maxLiveP95Ms ?? 800;
|
|
3819
|
+
const reconnectCap = options.maxReconnectP95Ms ?? 1500;
|
|
3740
3820
|
const turnCap = options.maxTurnP95Ms ?? 700;
|
|
3741
3821
|
const runtimeFirstAudioCap = options.maxRuntimeFirstAudioLatencyMs ?? 600;
|
|
3742
3822
|
const runtimeInterruptionCap = options.maxRuntimeInterruptionP95Ms ?? 300;
|
|
@@ -3745,6 +3825,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3745
3825
|
const budgets = {
|
|
3746
3826
|
maxLiveP95Ms: liveCap,
|
|
3747
3827
|
maxProviderP95Ms: providerCap,
|
|
3828
|
+
maxReconnectP95Ms: reconnectCap,
|
|
3748
3829
|
maxRuntimeFirstAudioLatencyMs: runtimeFirstAudioCap,
|
|
3749
3830
|
maxRuntimeInterruptionP95Ms: runtimeInterruptionCap,
|
|
3750
3831
|
maxRuntimeJitterMs: runtimeJitterCap,
|
|
@@ -3774,8 +3855,10 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3774
3855
|
label: definition.label ?? matchingEvidence.find((evidence) => evidence.profileLabel)?.profileLabel,
|
|
3775
3856
|
maxLiveP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.liveP95Ms)),
|
|
3776
3857
|
maxProviderP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.providerP95Ms)),
|
|
3858
|
+
maxReconnectP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
|
|
3777
3859
|
maxTurnP95Ms: maxNumber(matchingEvidence.map((evidence) => evidence.turnP95Ms)),
|
|
3778
3860
|
providers: aggregateProofTrendProviders(matchingEvidence.flatMap((evidence) => evidence.providers ?? [])),
|
|
3861
|
+
reconnect: aggregateProofTrendReconnect(matchingEvidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3779
3862
|
runtimeChannel: aggregateProofTrendRuntimeChannel(matchingEvidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined)),
|
|
3780
3863
|
sessionCount: new Set(matchingEvidence.map((evidence) => evidence.sessionId)).size,
|
|
3781
3864
|
surfaces: [
|
|
@@ -3794,6 +3877,7 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3794
3877
|
ok: evidence.ok !== false,
|
|
3795
3878
|
providers: evidence.providers,
|
|
3796
3879
|
runtimeChannel: evidence.runtimeChannel,
|
|
3880
|
+
reconnect: evidence.reconnect,
|
|
3797
3881
|
turnLatency: evidence.turnP95Ms === undefined ? undefined : {
|
|
3798
3882
|
p95Ms: evidence.turnP95Ms,
|
|
3799
3883
|
samples: 1,
|
|
@@ -3804,9 +3888,11 @@ var buildVoiceProofTrendReportFromRealCallProfiles = (options) => {
|
|
|
3804
3888
|
cycles: options.evidence.length,
|
|
3805
3889
|
maxLiveP95Ms: maxNumber(options.evidence.map((evidence) => evidence.liveP95Ms)),
|
|
3806
3890
|
maxProviderP95Ms: maxNumber(options.evidence.map((evidence) => evidence.providerP95Ms)),
|
|
3891
|
+
maxReconnectP95Ms: maxNumber(options.evidence.map((evidence) => evidence.reconnect?.resumeLatencyP95Ms)),
|
|
3807
3892
|
maxTurnP95Ms: maxNumber(options.evidence.map((evidence) => evidence.turnP95Ms)),
|
|
3808
3893
|
profiles,
|
|
3809
3894
|
providers: aggregateProofTrendProviders(options.evidence.flatMap((evidence) => evidence.providers ?? [])),
|
|
3895
|
+
reconnect: aggregateProofTrendReconnect(options.evidence.map((evidence) => evidence.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
3810
3896
|
runtimeChannel: aggregateProofTrendRuntimeChannel(options.evidence.map((evidence) => evidence.runtimeChannel).filter((channel) => channel !== undefined))
|
|
3811
3897
|
};
|
|
3812
3898
|
return buildVoiceProofTrendReport({
|
|
@@ -4411,6 +4497,74 @@ var createVoiceInMemoryRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
|
4411
4497
|
}
|
|
4412
4498
|
};
|
|
4413
4499
|
};
|
|
4500
|
+
var normalizeRealCallProfileEvidenceTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_evidence";
|
|
4501
|
+
var parseRealCallProfileEvidenceBoundary = (value) => value === undefined ? undefined : value instanceof Date ? value.getTime() : typeof value === "number" ? value : Date.parse(value);
|
|
4502
|
+
var readRealCallProfileEvidenceSortTime = (evidence, fallback) => Date.parse(evidence.generatedAt ?? fallback) || Date.parse(fallback);
|
|
4503
|
+
var createVoiceSQLiteRealCallProfileEvidenceStore = (options = {}) => {
|
|
4504
|
+
const { Database: SQLiteDatabase } = __require("bun:sqlite");
|
|
4505
|
+
const database = options.database ?? new SQLiteDatabase(options.path ?? ":memory:", {
|
|
4506
|
+
create: true
|
|
4507
|
+
});
|
|
4508
|
+
const tableName = normalizeRealCallProfileEvidenceTableName(options.tableName ?? "voice_real_call_profile_evidence");
|
|
4509
|
+
const now = () => (options.now ?? (() => new Date))().toISOString();
|
|
4510
|
+
const createId = () => `${options.idPrefix ?? "voice-profile-evidence"}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
4511
|
+
database.exec("PRAGMA journal_mode = WAL;");
|
|
4512
|
+
database.exec("PRAGMA synchronous = NORMAL;");
|
|
4513
|
+
database.exec("PRAGMA busy_timeout = 5000;");
|
|
4514
|
+
database.exec(`CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
4515
|
+
id TEXT PRIMARY KEY,
|
|
4516
|
+
sort_at INTEGER NOT NULL,
|
|
4517
|
+
profile_id TEXT NOT NULL,
|
|
4518
|
+
session_id TEXT NOT NULL,
|
|
4519
|
+
created_at TEXT NOT NULL,
|
|
4520
|
+
payload TEXT NOT NULL
|
|
4521
|
+
)`);
|
|
4522
|
+
const selectStatement = database.query(`SELECT payload FROM "${tableName}" WHERE id = ?1 LIMIT 1`);
|
|
4523
|
+
const listStatement = database.query(`SELECT payload FROM "${tableName}" ORDER BY sort_at DESC, id DESC`);
|
|
4524
|
+
const upsertStatement = database.query(`INSERT INTO "${tableName}" (id, sort_at, profile_id, session_id, created_at, payload)
|
|
4525
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6)
|
|
4526
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
4527
|
+
sort_at = excluded.sort_at,
|
|
4528
|
+
profile_id = excluded.profile_id,
|
|
4529
|
+
session_id = excluded.session_id,
|
|
4530
|
+
created_at = excluded.created_at,
|
|
4531
|
+
payload = excluded.payload`);
|
|
4532
|
+
const deleteStatement = database.query(`DELETE FROM "${tableName}" WHERE id = ?1`);
|
|
4533
|
+
const writeEvidence = (record) => {
|
|
4534
|
+
upsertStatement.run(record.id, readRealCallProfileEvidenceSortTime(record, record.createdAt), record.profileId, record.sessionId, record.createdAt, JSON.stringify(record));
|
|
4535
|
+
return record;
|
|
4536
|
+
};
|
|
4537
|
+
const readEvidence = (id) => {
|
|
4538
|
+
const row = selectStatement.get(id);
|
|
4539
|
+
return row ? JSON.parse(row.payload) : undefined;
|
|
4540
|
+
};
|
|
4541
|
+
const matchesListOptions = (record, input) => {
|
|
4542
|
+
const evidenceTime = readRealCallProfileEvidenceSortTime(record, record.createdAt);
|
|
4543
|
+
const since = parseRealCallProfileEvidenceBoundary(input.since);
|
|
4544
|
+
const until = parseRealCallProfileEvidenceBoundary(input.until);
|
|
4545
|
+
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);
|
|
4546
|
+
};
|
|
4547
|
+
return {
|
|
4548
|
+
append(input) {
|
|
4549
|
+
const createdAt = input.createdAt ?? now();
|
|
4550
|
+
return writeEvidence({
|
|
4551
|
+
...input,
|
|
4552
|
+
createdAt,
|
|
4553
|
+
id: input.id ?? createId()
|
|
4554
|
+
});
|
|
4555
|
+
},
|
|
4556
|
+
get(id) {
|
|
4557
|
+
return readEvidence(id);
|
|
4558
|
+
},
|
|
4559
|
+
list(input = {}) {
|
|
4560
|
+
const limit = Number.isFinite(input.limit) && input.limit !== undefined && input.limit > 0 ? Math.floor(input.limit) : 500;
|
|
4561
|
+
return listStatement.all().map((row) => JSON.parse(row.payload)).filter((record) => matchesListOptions(record, input)).slice(0, limit);
|
|
4562
|
+
},
|
|
4563
|
+
remove(id) {
|
|
4564
|
+
deleteStatement.run(id);
|
|
4565
|
+
}
|
|
4566
|
+
};
|
|
4567
|
+
};
|
|
4414
4568
|
var normalizeRealCallRecoveryJobTableName = (value) => value.trim().replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "") || "voice_real_call_profile_recovery_jobs";
|
|
4415
4569
|
var createVoiceSQLiteRealCallProfileRecoveryJobStore = (options = {}) => {
|
|
4416
4570
|
const { Database: SQLiteDatabase } = __require("bun:sqlite");
|
|
@@ -4625,10 +4779,12 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
|
|
|
4625
4779
|
failedReports: history.filter((report) => report.ok !== true).length,
|
|
4626
4780
|
maxLiveP95Ms: maxNumber(profileHistory.map(readProofTrendMaxLiveP95)),
|
|
4627
4781
|
maxProviderP95Ms: maxNumber(profileHistory.map(readProofTrendMaxProviderP95)),
|
|
4782
|
+
maxReconnectP95Ms: maxNumber(profileHistory.map(readProofTrendMaxReconnectP95)),
|
|
4628
4783
|
maxTurnP95Ms: maxNumber(profileHistory.map(readProofTrendMaxTurnP95)),
|
|
4629
4784
|
profileCount: profiles.length,
|
|
4630
4785
|
profiles,
|
|
4631
4786
|
providers: readProofTrendProviders(profileHistory),
|
|
4787
|
+
reconnect: aggregateProofTrendReconnect(profileHistory.map((report) => report.summary.reconnect).filter((reconnect) => reconnect !== undefined)),
|
|
4632
4788
|
runtimeChannel: aggregateProofTrendRuntimeChannel(profileHistory.map(readProofTrendRuntimeChannel).filter((channel) => channel !== undefined))
|
|
4633
4789
|
};
|
|
4634
4790
|
const trend = buildVoiceProofTrendReport({
|
|
@@ -4662,6 +4818,13 @@ var buildVoiceRealCallProfileHistoryReport = (options = {}) => {
|
|
|
4662
4818
|
trend
|
|
4663
4819
|
};
|
|
4664
4820
|
};
|
|
4821
|
+
var buildVoiceRealCallProfileHistoryReportFromStore = async (options) => {
|
|
4822
|
+
const evidence = await options.store.list(options);
|
|
4823
|
+
return buildVoiceRealCallProfileHistoryReport({
|
|
4824
|
+
...options,
|
|
4825
|
+
evidence
|
|
4826
|
+
});
|
|
4827
|
+
};
|
|
4665
4828
|
var normalizeProviderStatus = (status) => status === "pass" ? "pass" : status === "fail" ? "fail" : "warn";
|
|
4666
4829
|
var providerSortScore = (provider) => [
|
|
4667
4830
|
recommendationStatusRank[provider.status],
|